1 // Copyright (C) 2019 The Android Open Source Project
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //      http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 //
15 // This file is automatically generated by gen_amalgamated. Do not edit.
16 
17 // gen_amalgamated: predefined macros
18 #if !defined(GOOGLE_PROTOBUF_NO_RTTI)
19 #define GOOGLE_PROTOBUF_NO_RTTI
20 #endif
21 #if !defined(PERFETTO_IMPLEMENTATION)
22 #define PERFETTO_IMPLEMENTATION
23 #endif
24 #if !defined(GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER)
25 #define GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
26 #endif
27 #include "perfetto.h"
28 // gen_amalgamated begin source: src/base/android_utils.cc
29 // gen_amalgamated begin header: include/perfetto/ext/base/android_utils.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_ANDROID_UTILS_H_
47 #define INCLUDE_PERFETTO_EXT_BASE_ANDROID_UTILS_H_
48 
49 #include <string>
50 
51 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
52 
53 namespace perfetto {
54 namespace base {
55 
56 #if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
57 
58 // Returns the value of the Android system property named `name`. If the
59 // property does not exist, returns an empty string (a non-existing property is
60 // the same as a property with an empty value for this API).
61 std::string GetAndroidProp(const char* name);
62 
63 #endif  // PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
64 
65 }  // namespace base
66 }  // namespace perfetto
67 
68 #endif  // INCLUDE_PERFETTO_EXT_BASE_ANDROID_UTILS_H_
69 /*
70  * Copyright (C) 2021 The Android Open Source Project
71  *
72  * Licensed under the Apache License, Version 2.0 (the "License");
73  * you may not use this file except in compliance with the License.
74  * You may obtain a copy of the License at
75  *
76  *      http://www.apache.org/licenses/LICENSE-2.0
77  *
78  * Unless required by applicable law or agreed to in writing, software
79  * distributed under the License is distributed on an "AS IS" BASIS,
80  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
81  * See the License for the specific language governing permissions and
82  * limitations under the License.
83  */
84 
85 // gen_amalgamated expanded: #include "perfetto/ext/base/android_utils.h"
86 
87 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
88 
89 #include <string>
90 
91 #if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
92 #include <sys/system_properties.h>
93 #endif
94 
95 // gen_amalgamated expanded: #include "perfetto/base/compiler.h"
96 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
97 
98 namespace perfetto {
99 namespace base {
100 
101 #if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
102 
GetAndroidProp(const char * name)103 std::string GetAndroidProp(const char* name) {
104   std::string ret;
105 #if __ANDROID_API__ >= 26
106   const prop_info* pi = __system_property_find(name);
107   if (!pi) {
108     return ret;
109   }
110   __system_property_read_callback(
111       pi,
112       [](void* dst_void, const char*, const char* value, uint32_t) {
113         std::string& dst = *static_cast<std::string*>(dst_void);
114         dst = value;
115       },
116       &ret);
117 #else  // __ANDROID_API__ < 26
118   char value_buf[PROP_VALUE_MAX];
119   int len = __system_property_get(name, value_buf);
120   if (len > 0 && static_cast<size_t>(len) < sizeof(value_buf)) {
121     ret = std::string(value_buf, static_cast<size_t>(len));
122   }
123 #endif
124   return ret;
125 }
126 
127 #endif  // PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
128 
129 }  // namespace base
130 }  // namespace perfetto
131 // gen_amalgamated begin source: src/base/base64.cc
132 // gen_amalgamated begin header: include/perfetto/ext/base/base64.h
133 // gen_amalgamated begin header: include/perfetto/ext/base/optional.h
134 /*
135  * Copyright (C) 2018 The Android Open Source Project
136  *
137  * Licensed under the Apache License, Version 2.0 (the "License");
138  * you may not use this file except in compliance with the License.
139  * You may obtain a copy of the License at
140  *
141  *      http://www.apache.org/licenses/LICENSE-2.0
142  *
143  * Unless required by applicable law or agreed to in writing, software
144  * distributed under the License is distributed on an "AS IS" BASIS,
145  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
146  * See the License for the specific language governing permissions and
147  * limitations under the License.
148  */
149 
150 #ifndef INCLUDE_PERFETTO_EXT_BASE_OPTIONAL_H_
151 #define INCLUDE_PERFETTO_EXT_BASE_OPTIONAL_H_
152 
153 #include <functional>
154 #include <type_traits>
155 #include <utility>
156 
157 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
158 
159 namespace perfetto {
160 namespace base {
161 
162 // Specification:
163 // http://en.cppreference.com/w/cpp/utility/optional/in_place_t
164 struct in_place_t {};
165 
166 // Specification:
167 // http://en.cppreference.com/w/cpp/utility/optional/nullopt_t
168 struct nullopt_t {
nullopt_tperfetto::base::nullopt_t169   constexpr explicit nullopt_t(int) {}
170 };
171 
172 // Specification:
173 // http://en.cppreference.com/w/cpp/utility/optional/in_place
174 constexpr in_place_t in_place = {};
175 
176 // Specification:
177 // http://en.cppreference.com/w/cpp/utility/optional/nullopt
178 constexpr nullopt_t nullopt(0);
179 
180 // Forward declaration, which is referred by following helpers.
181 template <typename T>
182 class Optional;
183 
184 namespace internal {
185 
186 template <typename T, bool = std::is_trivially_destructible<T>::value>
187 struct OptionalStorageBase {
188   // Initializing |empty_| here instead of using default member initializing
189   // to avoid errors in g++ 4.8.
OptionalStorageBaseperfetto::base::internal::OptionalStorageBase190   constexpr OptionalStorageBase() : empty_('\0') {}
191 
192   template <class... Args>
OptionalStorageBaseperfetto::base::internal::OptionalStorageBase193   constexpr explicit OptionalStorageBase(in_place_t, Args&&... args)
194       : is_populated_(true), value_(std::forward<Args>(args)...) {}
195 
196   // When T is not trivially destructible we must call its
197   // destructor before deallocating its memory.
198   // Note that this hides the (implicitly declared) move constructor, which
199   // would be used for constexpr move constructor in OptionalStorage<T>.
200   // It is needed iff T is trivially move constructible. However, the current
201   // is_trivially_{copy,move}_constructible implementation requires
202   // is_trivially_destructible (which looks a bug, cf:
203   // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=51452 and
204   // http://cplusplus.github.io/LWG/lwg-active.html#2116), so it is not
205   // necessary for this case at the moment. Please see also the destructor
206   // comment in "is_trivially_destructible = true" specialization below.
~OptionalStorageBaseperfetto::base::internal::OptionalStorageBase207   ~OptionalStorageBase() {
208     if (is_populated_)
209       value_.~T();
210   }
211 
212   template <class... Args>
Initperfetto::base::internal::OptionalStorageBase213   void Init(Args&&... args) {
214     PERFETTO_DCHECK(!is_populated_);
215     ::new (&value_) T(std::forward<Args>(args)...);
216     is_populated_ = true;
217   }
218 
219   bool is_populated_ = false;
220   union {
221     // |empty_| exists so that the union will always be initialized, even when
222     // it doesn't contain a value. Union members must be initialized for the
223     // constructor to be 'constexpr'.
224     char empty_;
225     T value_;
226   };
227 };
228 
229 template <typename T>
230 struct OptionalStorageBase<T, true /* trivially destructible */> {
231   // Initializing |empty_| here instead of using default member initializing
232   // to avoid errors in g++ 4.8.
OptionalStorageBaseperfetto::base::internal::OptionalStorageBase233   constexpr OptionalStorageBase() : empty_('\0') {}
234 
235   template <class... Args>
OptionalStorageBaseperfetto::base::internal::OptionalStorageBase236   constexpr explicit OptionalStorageBase(in_place_t, Args&&... args)
237       : is_populated_(true), value_(std::forward<Args>(args)...) {}
238 
239   // When T is trivially destructible (i.e. its destructor does nothing) there
240   // is no need to call it. Implicitly defined destructor is trivial, because
241   // both members (bool and union containing only variants which are trivially
242   // destructible) are trivially destructible.
243   // Explicitly-defaulted destructor is also trivial, but do not use it here,
244   // because it hides the implicit move constructor. It is needed to implement
245   // constexpr move constructor in OptionalStorage iff T is trivially move
246   // constructible. Note that, if T is trivially move constructible, the move
247   // constructor of OptionalStorageBase<T> is also implicitly defined and it is
248   // trivially move constructor. If T is not trivially move constructible,
249   // "not declaring move constructor without destructor declaration" here means
250   // "delete move constructor", which works because any move constructor of
251   // OptionalStorage will not refer to it in that case.
252 
253   template <class... Args>
Initperfetto::base::internal::OptionalStorageBase254   void Init(Args&&... args) {
255     PERFETTO_DCHECK(!is_populated_);
256     ::new (&value_) T(std::forward<Args>(args)...);
257     is_populated_ = true;
258   }
259 
260   bool is_populated_ = false;
261   union {
262     // |empty_| exists so that the union will always be initialized, even when
263     // it doesn't contain a value. Union members must be initialized for the
264     // constructor to be 'constexpr'.
265     char empty_;
266     T value_;
267   };
268 };
269 
270 // Implement conditional constexpr copy and move constructors. These are
271 // constexpr if is_trivially_{copy,move}_constructible<T>::value is true
272 // respectively. If each is true, the corresponding constructor is defined as
273 // "= default;", which generates a constexpr constructor (In this case,
274 // the condition of constexpr-ness is satisfied because the base class also has
275 // compiler generated constexpr {copy,move} constructors). Note that
276 // placement-new is prohibited in constexpr.
277 template <typename T, bool = std::is_trivially_copy_constructible<T>::value>
278 struct OptionalStorage : OptionalStorageBase<T> {
279   // This is no trivially {copy,move} constructible case. Other cases are
280   // defined below as specializations.
281 
282   // Accessing the members of template base class requires explicit
283   // declaration.
284   using OptionalStorageBase<T>::is_populated_;
285   using OptionalStorageBase<T>::value_;
286   using OptionalStorageBase<T>::Init;
287 
288   // Inherit constructors (specifically, the in_place constructor).
289   using OptionalStorageBase<T>::OptionalStorageBase;
290 
291   // User defined constructor deletes the default constructor.
292   // Define it explicitly.
293   OptionalStorage() = default;
294 
OptionalStorageperfetto::base::internal::OptionalStorage295   OptionalStorage(const OptionalStorage& other) : OptionalStorageBase<T>() {
296     if (other.is_populated_)
297       Init(other.value_);
298   }
299 
OptionalStorageperfetto::base::internal::OptionalStorage300   OptionalStorage(OptionalStorage&& other) noexcept(
301       std::is_nothrow_move_constructible<T>::value) {
302     if (other.is_populated_)
303       Init(std::move(other.value_));
304   }
305 };
306 
307 template <typename T>
308 struct OptionalStorage<T, true /* trivially copy constructible */>
309     : OptionalStorageBase<T> {
310   using OptionalStorageBase<T>::is_populated_;
311   using OptionalStorageBase<T>::value_;
312   using OptionalStorageBase<T>::Init;
313   using OptionalStorageBase<T>::OptionalStorageBase;
314 
315   OptionalStorage() = default;
316   OptionalStorage(const OptionalStorage& other) = default;
317 
OptionalStorageperfetto::base::internal::OptionalStorage318   OptionalStorage(OptionalStorage&& other) noexcept(
319       std::is_nothrow_move_constructible<T>::value) {
320     if (other.is_populated_)
321       Init(std::move(other.value_));
322   }
323 };
324 
325 // Base class to support conditionally usable copy-/move- constructors
326 // and assign operators.
327 template <typename T>
328 class OptionalBase {
329   // This class provides implementation rather than public API, so everything
330   // should be hidden. Often we use composition, but we cannot in this case
331   // because of C++ language restriction.
332  protected:
333   constexpr OptionalBase() = default;
334   constexpr OptionalBase(const OptionalBase& other) = default;
335   constexpr OptionalBase(OptionalBase&& other) = default;
336 
337   template <class... Args>
OptionalBase(in_place_t,Args &&...args)338   constexpr explicit OptionalBase(in_place_t, Args&&... args)
339       : storage_(in_place, std::forward<Args>(args)...) {}
340 
341   // Implementation of converting constructors.
342   template <typename U>
OptionalBase(const OptionalBase<U> & other)343   explicit OptionalBase(const OptionalBase<U>& other) {
344     if (other.storage_.is_populated_)
345       storage_.Init(other.storage_.value_);
346   }
347 
348   template <typename U>
OptionalBase(OptionalBase<U> && other)349   explicit OptionalBase(OptionalBase<U>&& other) {
350     if (other.storage_.is_populated_)
351       storage_.Init(std::move(other.storage_.value_));
352   }
353 
354   ~OptionalBase() = default;
355 
operator =(const OptionalBase & other)356   OptionalBase& operator=(const OptionalBase& other) {
357     CopyAssign(other);
358     return *this;
359   }
360 
operator =(OptionalBase && other)361   OptionalBase& operator=(OptionalBase&& other) noexcept(
362       std::is_nothrow_move_assignable<T>::value&&
363           std::is_nothrow_move_constructible<T>::value) {
364     MoveAssign(std::move(other));
365     return *this;
366   }
367 
368   template <typename U>
CopyAssign(const OptionalBase<U> & other)369   void CopyAssign(const OptionalBase<U>& other) {
370     if (other.storage_.is_populated_)
371       InitOrAssign(other.storage_.value_);
372     else
373       FreeIfNeeded();
374   }
375 
376   template <typename U>
MoveAssign(OptionalBase<U> && other)377   void MoveAssign(OptionalBase<U>&& other) {
378     if (other.storage_.is_populated_)
379       InitOrAssign(std::move(other.storage_.value_));
380     else
381       FreeIfNeeded();
382   }
383 
384   template <typename U>
InitOrAssign(U && value)385   void InitOrAssign(U&& value) {
386     if (storage_.is_populated_)
387       storage_.value_ = std::forward<U>(value);
388     else
389       storage_.Init(std::forward<U>(value));
390   }
391 
FreeIfNeeded()392   void FreeIfNeeded() {
393     if (!storage_.is_populated_)
394       return;
395     storage_.value_.~T();
396     storage_.is_populated_ = false;
397   }
398 
399   // For implementing conversion, allow access to other typed OptionalBase
400   // class.
401   template <typename U>
402   friend class OptionalBase;
403 
404   OptionalStorage<T> storage_;
405 };
406 
407 // The following {Copy,Move}{Constructible,Assignable} structs are helpers to
408 // implement constructor/assign-operator overloading. Specifically, if T is
409 // is not movable but copyable, Optional<T>'s move constructor should not
410 // participate in overload resolution. This inheritance trick implements that.
411 template <bool is_copy_constructible>
412 struct CopyConstructible {};
413 
414 template <>
415 struct CopyConstructible<false> {
416   constexpr CopyConstructible() = default;
417   constexpr CopyConstructible(const CopyConstructible&) = delete;
418   constexpr CopyConstructible(CopyConstructible&&) = default;
419   CopyConstructible& operator=(const CopyConstructible&) = default;
420   CopyConstructible& operator=(CopyConstructible&&) = default;
421 };
422 
423 template <bool is_move_constructible>
424 struct MoveConstructible {};
425 
426 template <>
427 struct MoveConstructible<false> {
428   constexpr MoveConstructible() = default;
429   constexpr MoveConstructible(const MoveConstructible&) = default;
430   constexpr MoveConstructible(MoveConstructible&&) = delete;
431   MoveConstructible& operator=(const MoveConstructible&) = default;
432   MoveConstructible& operator=(MoveConstructible&&) = default;
433 };
434 
435 template <bool is_copy_assignable>
436 struct CopyAssignable {};
437 
438 template <>
439 struct CopyAssignable<false> {
440   constexpr CopyAssignable() = default;
441   constexpr CopyAssignable(const CopyAssignable&) = default;
442   constexpr CopyAssignable(CopyAssignable&&) = default;
443   CopyAssignable& operator=(const CopyAssignable&) = delete;
444   CopyAssignable& operator=(CopyAssignable&&) = default;
445 };
446 
447 template <bool is_move_assignable>
448 struct MoveAssignable {};
449 
450 template <>
451 struct MoveAssignable<false> {
452   constexpr MoveAssignable() = default;
453   constexpr MoveAssignable(const MoveAssignable&) = default;
454   constexpr MoveAssignable(MoveAssignable&&) = default;
455   MoveAssignable& operator=(const MoveAssignable&) = default;
456   MoveAssignable& operator=(MoveAssignable&&) = delete;
457 };
458 
459 // Helper to conditionally enable converting constructors and assign operators.
460 template <typename T, typename U>
461 struct IsConvertibleFromOptional
462     : std::integral_constant<
463           bool,
464           std::is_constructible<T, Optional<U>&>::value ||
465               std::is_constructible<T, const Optional<U>&>::value ||
466               std::is_constructible<T, Optional<U>&&>::value ||
467               std::is_constructible<T, const Optional<U>&&>::value ||
468               std::is_convertible<Optional<U>&, T>::value ||
469               std::is_convertible<const Optional<U>&, T>::value ||
470               std::is_convertible<Optional<U>&&, T>::value ||
471               std::is_convertible<const Optional<U>&&, T>::value> {};
472 
473 template <typename T, typename U>
474 struct IsAssignableFromOptional
475     : std::integral_constant<
476           bool,
477           IsConvertibleFromOptional<T, U>::value ||
478               std::is_assignable<T&, Optional<U>&>::value ||
479               std::is_assignable<T&, const Optional<U>&>::value ||
480               std::is_assignable<T&, Optional<U>&&>::value ||
481               std::is_assignable<T&, const Optional<U>&&>::value> {};
482 
483 // Forward compatibility for C++17.
484 // Introduce one more deeper nested namespace to avoid leaking using std::swap.
485 namespace swappable_impl {
486 using std::swap;
487 
488 struct IsSwappableImpl {
489   // Tests if swap can be called. Check<T&>(0) returns true_type iff swap is
490   // available for T. Otherwise, Check's overload resolution falls back to
491   // Check(...) declared below thanks to SFINAE, so returns false_type.
492   template <typename T>
493   static auto Check(int)
494       -> decltype(swap(std::declval<T>(), std::declval<T>()), std::true_type());
495 
496   template <typename T>
497   static std::false_type Check(...);
498 };
499 }  // namespace swappable_impl
500 
501 template <typename T>
502 struct IsSwappable : decltype(swappable_impl::IsSwappableImpl::Check<T&>(0)) {};
503 
504 // Forward compatibility for C++20.
505 template <typename T>
506 using RemoveCvRefT =
507     typename std::remove_cv<typename std::remove_reference<T>::type>::type;
508 
509 }  // namespace internal
510 
511 // On Windows, by default, empty-base class optimization does not work,
512 // which means even if the base class is empty struct, it still consumes one
513 // byte for its body. __declspec(empty_bases) enables the optimization.
514 // cf)
515 // https://blogs.msdn.microsoft.com/vcblog/2016/03/30/optimizing-the-layout-of-empty-base-classes-in-vs2015-update-2-3/
516 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) && \
517     !PERFETTO_BUILDFLAG(PERFETTO_COMPILER_GCC)
518 #define OPTIONAL_DECLSPEC_EMPTY_BASES __declspec(empty_bases)
519 #else
520 #define OPTIONAL_DECLSPEC_EMPTY_BASES
521 #endif
522 
523 // base::Optional is a Chromium version of the C++17 optional class:
524 // std::optional documentation:
525 // http://en.cppreference.com/w/cpp/utility/optional
526 // Chromium documentation:
527 // https://chromium.googlesource.com/chromium/src/+/master/docs/optional.md
528 //
529 // These are the differences between the specification and the implementation:
530 // - Constructors do not use 'constexpr' as it is a C++14 extension.
531 // - 'constexpr' might be missing in some places for reasons specified locally.
532 // - No exceptions are thrown, because they are banned from Chromium.
533 //   Marked noexcept for only move constructor and move assign operators.
534 // - All the non-members are in the 'base' namespace instead of 'std'.
535 //
536 // Note that T cannot have a constructor T(Optional<T>) etc. Optional<T>
537 // PERFETTO_CHECKs T's constructor (specifically via IsConvertibleFromOptional),
538 // and in the PERFETTO_CHECK whether T can be constructible from Optional<T>,
539 // which is recursive so it does not work. As of Feb 2018, std::optional C++17
540 // implementation in both clang and gcc has same limitation. MSVC SFINAE looks
541 // to have different behavior, but anyway it reports an error, too.
542 //
543 // This file is a modified version of optional.h from Chromium at revision
544 // 5e71bd454e60511c1293c0c686544aaa76094424. The changes remove C++14/C++17
545 // specific code and replace with C++11 counterparts.
546 template <typename T>
547 class OPTIONAL_DECLSPEC_EMPTY_BASES Optional
548     : public internal::OptionalBase<T>,
549       public internal::CopyConstructible<std::is_copy_constructible<T>::value>,
550       public internal::MoveConstructible<std::is_move_constructible<T>::value>,
551       public internal::CopyAssignable<std::is_copy_constructible<T>::value &&
552                                       std::is_copy_assignable<T>::value>,
553       public internal::MoveAssignable<std::is_move_constructible<T>::value &&
554                                       std::is_move_assignable<T>::value> {
555  public:
556 #undef OPTIONAL_DECLSPEC_EMPTY_BASES
557   using value_type = T;
558 
559   // Defer default/copy/move constructor implementation to OptionalBase.
560   constexpr Optional() = default;
561   constexpr Optional(const Optional& other) = default;
562   constexpr Optional(Optional&& other) noexcept(
563       std::is_nothrow_move_constructible<T>::value) = default;
564 
Optional(nullopt_t)565   constexpr Optional(nullopt_t) {}  // NOLINT(runtime/explicit)
566 
567   // Converting copy constructor. "explicit" only if
568   // std::is_convertible<const U&, T>::value is false. It is implemented by
569   // declaring two almost same constructors, but that condition in enable_if_t
570   // is different, so that either one is chosen, thanks to SFINAE.
571   template <typename U,
572             typename std::enable_if<
573                 std::is_constructible<T, const U&>::value &&
574                     !internal::IsConvertibleFromOptional<T, U>::value &&
575                     std::is_convertible<const U&, T>::value,
576                 bool>::type = false>
Optional(const Optional<U> & other)577   Optional(const Optional<U>& other) : internal::OptionalBase<T>(other) {}
578 
579   template <typename U,
580             typename std::enable_if<
581                 std::is_constructible<T, const U&>::value &&
582                     !internal::IsConvertibleFromOptional<T, U>::value &&
583                     !std::is_convertible<const U&, T>::value,
584                 bool>::type = false>
Optional(const Optional<U> & other)585   explicit Optional(const Optional<U>& other)
586       : internal::OptionalBase<T>(other) {}
587 
588   // Converting move constructor. Similar to converting copy constructor,
589   // declaring two (explicit and non-explicit) constructors.
590   template <typename U,
591             typename std::enable_if<
592                 std::is_constructible<T, U&&>::value &&
593                     !internal::IsConvertibleFromOptional<T, U>::value &&
594                     std::is_convertible<U&&, T>::value,
595                 bool>::type = false>
Optional(Optional<U> && other)596   Optional(Optional<U>&& other) : internal::OptionalBase<T>(std::move(other)) {}
597 
598   template <typename U,
599             typename std::enable_if<
600                 std::is_constructible<T, U&&>::value &&
601                     !internal::IsConvertibleFromOptional<T, U>::value &&
602                     !std::is_convertible<U&&, T>::value,
603                 bool>::type = false>
Optional(Optional<U> && other)604   explicit Optional(Optional<U>&& other)
605       : internal::OptionalBase<T>(std::move(other)) {}
606 
607   template <class... Args>
Optional(in_place_t,Args &&...args)608   constexpr explicit Optional(in_place_t, Args&&... args)
609       : internal::OptionalBase<T>(in_place, std::forward<Args>(args)...) {}
610 
611   template <class U,
612             class... Args,
613             class = typename std::enable_if<
614                 std::is_constructible<value_type,
615                                       std::initializer_list<U>&,
616                                       Args...>::value>::type>
Optional(in_place_t,std::initializer_list<U> il,Args &&...args)617   constexpr explicit Optional(in_place_t,
618                               std::initializer_list<U> il,
619                               Args&&... args)
620       : internal::OptionalBase<T>(in_place, il, std::forward<Args>(args)...) {}
621 
622   // Forward value constructor. Similar to converting constructors,
623   // conditionally explicit.
624   template <
625       typename U = value_type,
626       typename std::enable_if<
627           std::is_constructible<T, U&&>::value &&
628               !std::is_same<internal::RemoveCvRefT<U>, in_place_t>::value &&
629               !std::is_same<internal::RemoveCvRefT<U>, Optional<T>>::value &&
630               std::is_convertible<U&&, T>::value,
631           bool>::type = false>
Optional(U && value)632   constexpr Optional(U&& value)
633       : internal::OptionalBase<T>(in_place, std::forward<U>(value)) {}
634 
635   template <
636       typename U = value_type,
637       typename std::enable_if<
638           std::is_constructible<T, U&&>::value &&
639               !std::is_same<internal::RemoveCvRefT<U>, in_place_t>::value &&
640               !std::is_same<internal::RemoveCvRefT<U>, Optional<T>>::value &&
641               !std::is_convertible<U&&, T>::value,
642           bool>::type = false>
Optional(U && value)643   constexpr explicit Optional(U&& value)
644       : internal::OptionalBase<T>(in_place, std::forward<U>(value)) {}
645 
646   ~Optional() = default;
647 
648   // Defer copy-/move- assign operator implementation to OptionalBase.
649   Optional& operator=(const Optional& other) = default;
650   Optional& operator=(Optional&& other) noexcept(
651       std::is_nothrow_move_assignable<T>::value&&
652           std::is_nothrow_move_constructible<T>::value) = default;
653 
operator =(nullopt_t)654   Optional& operator=(nullopt_t) {
655     FreeIfNeeded();
656     return *this;
657   }
658 
659   // Perfect-forwarded assignment.
660   template <typename U>
661   typename std::enable_if<
662       !std::is_same<internal::RemoveCvRefT<U>, Optional<T>>::value &&
663           std::is_constructible<T, U>::value &&
664           std::is_assignable<T&, U>::value &&
665           (!std::is_scalar<T>::value ||
666            !std::is_same<typename std::decay<U>::type, T>::value),
667       Optional&>::type
operator =(U && value)668   operator=(U&& value) {
669     InitOrAssign(std::forward<U>(value));
670     return *this;
671   }
672 
673   // Copy assign the state of other.
674   template <typename U>
675   typename std::enable_if<!internal::IsAssignableFromOptional<T, U>::value &&
676                               std::is_constructible<T, const U&>::value &&
677                               std::is_assignable<T&, const U&>::value,
678                           Optional&>::type
operator =(const Optional<U> & other)679   operator=(const Optional<U>& other) {
680     CopyAssign(other);
681     return *this;
682   }
683 
684   // Move assign the state of other.
685   template <typename U>
686   typename std::enable_if<!internal::IsAssignableFromOptional<T, U>::value &&
687                               std::is_constructible<T, U>::value &&
688                               std::is_assignable<T&, U>::value,
689                           Optional&>::type
operator =(Optional<U> && other)690   operator=(Optional<U>&& other) {
691     MoveAssign(std::move(other));
692     return *this;
693   }
694 
operator ->() const695   const T* operator->() const {
696     PERFETTO_DCHECK(storage_.is_populated_);
697     return &storage_.value_;
698   }
699 
operator ->()700   T* operator->() {
701     PERFETTO_DCHECK(storage_.is_populated_);
702     return &storage_.value_;
703   }
704 
operator *() const705   const T& operator*() const& {
706     PERFETTO_DCHECK(storage_.is_populated_);
707     return storage_.value_;
708   }
709 
operator *()710   T& operator*() & {
711     PERFETTO_DCHECK(storage_.is_populated_);
712     return storage_.value_;
713   }
714 
operator *() const715   const T&& operator*() const&& {
716     PERFETTO_DCHECK(storage_.is_populated_);
717     return std::move(storage_.value_);
718   }
719 
operator *()720   T&& operator*() && {
721     PERFETTO_DCHECK(storage_.is_populated_);
722     return std::move(storage_.value_);
723   }
724 
operator bool() const725   constexpr explicit operator bool() const { return storage_.is_populated_; }
726 
has_value() const727   constexpr bool has_value() const { return storage_.is_populated_; }
728 
value()729   T& value() & {
730     PERFETTO_CHECK(storage_.is_populated_);
731     return storage_.value_;
732   }
733 
value() const734   const T& value() const& {
735     PERFETTO_CHECK(storage_.is_populated_);
736     return storage_.value_;
737   }
738 
value()739   T&& value() && {
740     PERFETTO_CHECK(storage_.is_populated_);
741     return std::move(storage_.value_);
742   }
743 
value() const744   const T&& value() const&& {
745     PERFETTO_CHECK(storage_.is_populated_);
746     return std::move(storage_.value_);
747   }
748 
749   template <class U>
value_or(U && default_value) const750   constexpr T value_or(U&& default_value) const& {
751     static_assert(std::is_convertible<U, T>::value,
752                   "U must be convertible to T");
753     return storage_.is_populated_
754                ? storage_.value_
755                : static_cast<T>(std::forward<U>(default_value));
756   }
757 
758   template <class U>
value_or(U && default_value)759   T value_or(U&& default_value) && {
760     static_assert(std::is_convertible<U, T>::value,
761                   "U must be convertible to T");
762     return storage_.is_populated_
763                ? std::move(storage_.value_)
764                : static_cast<T>(std::forward<U>(default_value));
765   }
766 
swap(Optional & other)767   void swap(Optional& other) {
768     if (!storage_.is_populated_ && !other.storage_.is_populated_)
769       return;
770 
771     if (storage_.is_populated_ != other.storage_.is_populated_) {
772       if (storage_.is_populated_) {
773         other.storage_.Init(std::move(storage_.value_));
774         FreeIfNeeded();
775       } else {
776         storage_.Init(std::move(other.storage_.value_));
777         other.FreeIfNeeded();
778       }
779       return;
780     }
781 
782     PERFETTO_DCHECK(storage_.is_populated_ && other.storage_.is_populated_);
783     using std::swap;
784     swap(**this, *other);
785   }
786 
reset()787   void reset() { FreeIfNeeded(); }
788 
789   template <class... Args>
emplace(Args &&...args)790   T& emplace(Args&&... args) {
791     FreeIfNeeded();
792     storage_.Init(std::forward<Args>(args)...);
793     return storage_.value_;
794   }
795 
796   template <class U, class... Args>
797   typename std::enable_if<
798       std::is_constructible<T, std::initializer_list<U>&, Args&&...>::value,
799       T&>::type
emplace(std::initializer_list<U> il,Args &&...args)800   emplace(std::initializer_list<U> il, Args&&... args) {
801     FreeIfNeeded();
802     storage_.Init(il, std::forward<Args>(args)...);
803     return storage_.value_;
804   }
805 
806  private:
807   // Accessing template base class's protected member needs explicit
808   // declaration to do so.
809   using internal::OptionalBase<T>::CopyAssign;
810   using internal::OptionalBase<T>::FreeIfNeeded;
811   using internal::OptionalBase<T>::InitOrAssign;
812   using internal::OptionalBase<T>::MoveAssign;
813   using internal::OptionalBase<T>::storage_;
814 };
815 
816 // Here after defines comparation operators. The definition follows
817 // http://en.cppreference.com/w/cpp/utility/optional/operator_cmp
818 // while bool() casting is replaced by has_value() to meet the chromium
819 // style guide.
820 template <class T, class U>
operator ==(const Optional<T> & lhs,const Optional<U> & rhs)821 bool operator==(const Optional<T>& lhs, const Optional<U>& rhs) {
822   if (lhs.has_value() != rhs.has_value())
823     return false;
824   if (!lhs.has_value())
825     return true;
826   return *lhs == *rhs;
827 }
828 
829 template <class T, class U>
operator !=(const Optional<T> & lhs,const Optional<U> & rhs)830 bool operator!=(const Optional<T>& lhs, const Optional<U>& rhs) {
831   if (lhs.has_value() != rhs.has_value())
832     return true;
833   if (!lhs.has_value())
834     return false;
835   return *lhs != *rhs;
836 }
837 
838 template <class T, class U>
operator <(const Optional<T> & lhs,const Optional<U> & rhs)839 bool operator<(const Optional<T>& lhs, const Optional<U>& rhs) {
840   if (!rhs.has_value())
841     return false;
842   if (!lhs.has_value())
843     return true;
844   return *lhs < *rhs;
845 }
846 
847 template <class T, class U>
operator <=(const Optional<T> & lhs,const Optional<U> & rhs)848 bool operator<=(const Optional<T>& lhs, const Optional<U>& rhs) {
849   if (!lhs.has_value())
850     return true;
851   if (!rhs.has_value())
852     return false;
853   return *lhs <= *rhs;
854 }
855 
856 template <class T, class U>
operator >(const Optional<T> & lhs,const Optional<U> & rhs)857 bool operator>(const Optional<T>& lhs, const Optional<U>& rhs) {
858   if (!lhs.has_value())
859     return false;
860   if (!rhs.has_value())
861     return true;
862   return *lhs > *rhs;
863 }
864 
865 template <class T, class U>
operator >=(const Optional<T> & lhs,const Optional<U> & rhs)866 bool operator>=(const Optional<T>& lhs, const Optional<U>& rhs) {
867   if (!rhs.has_value())
868     return true;
869   if (!lhs.has_value())
870     return false;
871   return *lhs >= *rhs;
872 }
873 
874 template <class T>
operator ==(const Optional<T> & opt,nullopt_t)875 constexpr bool operator==(const Optional<T>& opt, nullopt_t) {
876   return !opt;
877 }
878 
879 template <class T>
operator ==(nullopt_t,const Optional<T> & opt)880 constexpr bool operator==(nullopt_t, const Optional<T>& opt) {
881   return !opt;
882 }
883 
884 template <class T>
operator !=(const Optional<T> & opt,nullopt_t)885 constexpr bool operator!=(const Optional<T>& opt, nullopt_t) {
886   return opt.has_value();
887 }
888 
889 template <class T>
operator !=(nullopt_t,const Optional<T> & opt)890 constexpr bool operator!=(nullopt_t, const Optional<T>& opt) {
891   return opt.has_value();
892 }
893 
894 template <class T>
operator <(const Optional<T> &,nullopt_t)895 constexpr bool operator<(const Optional<T>&, nullopt_t) {
896   return false;
897 }
898 
899 template <class T>
operator <(nullopt_t,const Optional<T> & opt)900 constexpr bool operator<(nullopt_t, const Optional<T>& opt) {
901   return opt.has_value();
902 }
903 
904 template <class T>
operator <=(const Optional<T> & opt,nullopt_t)905 constexpr bool operator<=(const Optional<T>& opt, nullopt_t) {
906   return !opt;
907 }
908 
909 template <class T>
operator <=(nullopt_t,const Optional<T> &)910 constexpr bool operator<=(nullopt_t, const Optional<T>&) {
911   return true;
912 }
913 
914 template <class T>
operator >(const Optional<T> & opt,nullopt_t)915 constexpr bool operator>(const Optional<T>& opt, nullopt_t) {
916   return opt.has_value();
917 }
918 
919 template <class T>
operator >(nullopt_t,const Optional<T> &)920 constexpr bool operator>(nullopt_t, const Optional<T>&) {
921   return false;
922 }
923 
924 template <class T>
operator >=(const Optional<T> &,nullopt_t)925 constexpr bool operator>=(const Optional<T>&, nullopt_t) {
926   return true;
927 }
928 
929 template <class T>
operator >=(nullopt_t,const Optional<T> & opt)930 constexpr bool operator>=(nullopt_t, const Optional<T>& opt) {
931   return !opt;
932 }
933 
934 template <class T, class U>
operator ==(const Optional<T> & opt,const U & value)935 constexpr bool operator==(const Optional<T>& opt, const U& value) {
936   return opt.has_value() ? *opt == value : false;
937 }
938 
939 template <class T, class U>
operator ==(const U & value,const Optional<T> & opt)940 constexpr bool operator==(const U& value, const Optional<T>& opt) {
941   return opt.has_value() ? value == *opt : false;
942 }
943 
944 template <class T, class U>
operator !=(const Optional<T> & opt,const U & value)945 constexpr bool operator!=(const Optional<T>& opt, const U& value) {
946   return opt.has_value() ? *opt != value : true;
947 }
948 
949 template <class T, class U>
operator !=(const U & value,const Optional<T> & opt)950 constexpr bool operator!=(const U& value, const Optional<T>& opt) {
951   return opt.has_value() ? value != *opt : true;
952 }
953 
954 template <class T, class U>
operator <(const Optional<T> & opt,const U & value)955 constexpr bool operator<(const Optional<T>& opt, const U& value) {
956   return opt.has_value() ? *opt < value : true;
957 }
958 
959 template <class T, class U>
operator <(const U & value,const Optional<T> & opt)960 constexpr bool operator<(const U& value, const Optional<T>& opt) {
961   return opt.has_value() ? value < *opt : false;
962 }
963 
964 template <class T, class U>
operator <=(const Optional<T> & opt,const U & value)965 constexpr bool operator<=(const Optional<T>& opt, const U& value) {
966   return opt.has_value() ? *opt <= value : true;
967 }
968 
969 template <class T, class U>
operator <=(const U & value,const Optional<T> & opt)970 constexpr bool operator<=(const U& value, const Optional<T>& opt) {
971   return opt.has_value() ? value <= *opt : false;
972 }
973 
974 template <class T, class U>
operator >(const Optional<T> & opt,const U & value)975 constexpr bool operator>(const Optional<T>& opt, const U& value) {
976   return opt.has_value() ? *opt > value : false;
977 }
978 
979 template <class T, class U>
operator >(const U & value,const Optional<T> & opt)980 constexpr bool operator>(const U& value, const Optional<T>& opt) {
981   return opt.has_value() ? value > *opt : true;
982 }
983 
984 template <class T, class U>
operator >=(const Optional<T> & opt,const U & value)985 constexpr bool operator>=(const Optional<T>& opt, const U& value) {
986   return opt.has_value() ? *opt >= value : false;
987 }
988 
989 template <class T, class U>
operator >=(const U & value,const Optional<T> & opt)990 constexpr bool operator>=(const U& value, const Optional<T>& opt) {
991   return opt.has_value() ? value >= *opt : true;
992 }
993 
994 template <class T>
make_optional(T && value)995 constexpr Optional<typename std::decay<T>::type> make_optional(T&& value) {
996   return Optional<typename std::decay<T>::type>(std::forward<T>(value));
997 }
998 
999 template <class T, class... Args>
make_optional(Args &&...args)1000 constexpr Optional<T> make_optional(Args&&... args) {
1001   return Optional<T>(in_place, std::forward<Args>(args)...);
1002 }
1003 
1004 template <class T, class U, class... Args>
make_optional(std::initializer_list<U> il,Args &&...args)1005 constexpr Optional<T> make_optional(std::initializer_list<U> il,
1006                                     Args&&... args) {
1007   return Optional<T>(in_place, il, std::forward<Args>(args)...);
1008 }
1009 
1010 // Partial specialization for a function template is not allowed. Also, it is
1011 // not allowed to add overload function to std namespace, while it is allowed
1012 // to specialize the template in std. Thus, swap() (kind of) overloading is
1013 // defined in base namespace, instead.
1014 template <class T>
1015 typename std::enable_if<std::is_move_constructible<T>::value &&
1016                         internal::IsSwappable<T>::value>::type
swap(Optional<T> & lhs,Optional<T> & rhs)1017 swap(Optional<T>& lhs, Optional<T>& rhs) {
1018   lhs.swap(rhs);
1019 }
1020 
1021 }  // namespace base
1022 }  // namespace perfetto
1023 
1024 template <class T>
1025 struct std::hash<perfetto::base::Optional<T>> {
operator ()std::hash1026   size_t operator()(const perfetto::base::Optional<T>& opt) const {
1027     return opt == perfetto::base::nullopt ? 0 : std::hash<T>()(*opt);
1028   }
1029 };
1030 
1031 #endif  // INCLUDE_PERFETTO_EXT_BASE_OPTIONAL_H_
1032 // gen_amalgamated begin header: include/perfetto/ext/base/string_view.h
1033 // gen_amalgamated begin header: include/perfetto/ext/base/hash.h
1034 /*
1035  * Copyright (C) 2019 The Android Open Source Project
1036  *
1037  * Licensed under the Apache License, Version 2.0 (the "License");
1038  * you may not use this file except in compliance with the License.
1039  * You may obtain a copy of the License at
1040  *
1041  *      http://www.apache.org/licenses/LICENSE-2.0
1042  *
1043  * Unless required by applicable law or agreed to in writing, software
1044  * distributed under the License is distributed on an "AS IS" BASIS,
1045  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1046  * See the License for the specific language governing permissions and
1047  * limitations under the License.
1048  */
1049 
1050 #ifndef INCLUDE_PERFETTO_EXT_BASE_HASH_H_
1051 #define INCLUDE_PERFETTO_EXT_BASE_HASH_H_
1052 
1053 #include <stddef.h>
1054 #include <stdint.h>
1055 #include <type_traits>
1056 
1057 namespace perfetto {
1058 namespace base {
1059 
1060 // A helper class which computes a 64-bit hash of the input data.
1061 // The algorithm used is FNV-1a as it is fast and easy to implement and has
1062 // relatively few collisions.
1063 // WARNING: This hash function should not be used for any cryptographic purpose.
1064 class Hash {
1065  public:
1066   // Creates an empty hash object
Hash()1067   Hash() {}
1068 
1069   // Hashes a numeric value.
1070   template <
1071       typename T,
1072       typename std::enable_if<std::is_arithmetic<T>::value, bool>::type = true>
Update(T data)1073   void Update(T data) {
1074     Update(reinterpret_cast<const char*>(&data), sizeof(data));
1075   }
1076 
1077   // Hashes a byte array.
Update(const char * data,size_t size)1078   void Update(const char* data, size_t size) {
1079     for (size_t i = 0; i < size; i++) {
1080       result_ ^= static_cast<uint8_t>(data[i]);
1081       result_ *= kFnv1a64Prime;
1082     }
1083   }
1084 
digest()1085   uint64_t digest() { return result_; }
1086 
1087  private:
1088   static constexpr uint64_t kFnv1a64OffsetBasis = 0xcbf29ce484222325;
1089   static constexpr uint64_t kFnv1a64Prime = 0x100000001b3;
1090 
1091   uint64_t result_ = kFnv1a64OffsetBasis;
1092 };
1093 
1094 // This is for using already-hashed key into std::unordered_map and avoid the
1095 // cost of re-hashing. Example:
1096 // unordered_map<uint64_t, Value, AlreadyHashed> my_map.
1097 template <typename T>
1098 struct AlreadyHashed {
operator ()perfetto::base::AlreadyHashed1099   size_t operator()(const T& x) const { return static_cast<size_t>(x); }
1100 };
1101 
1102 }  // namespace base
1103 }  // namespace perfetto
1104 
1105 #endif  // INCLUDE_PERFETTO_EXT_BASE_HASH_H_
1106 /*
1107  * Copyright (C) 2018 The Android Open Source Project
1108  *
1109  * Licensed under the Apache License, Version 2.0 (the "License");
1110  * you may not use this file except in compliance with the License.
1111  * You may obtain a copy of the License at
1112  *
1113  *      http://www.apache.org/licenses/LICENSE-2.0
1114  *
1115  * Unless required by applicable law or agreed to in writing, software
1116  * distributed under the License is distributed on an "AS IS" BASIS,
1117  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1118  * See the License for the specific language governing permissions and
1119  * limitations under the License.
1120  */
1121 
1122 #ifndef INCLUDE_PERFETTO_EXT_BASE_STRING_VIEW_H_
1123 #define INCLUDE_PERFETTO_EXT_BASE_STRING_VIEW_H_
1124 
1125 #include <string.h>
1126 
1127 #include <algorithm>
1128 #include <string>
1129 
1130 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
1131 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
1132 // gen_amalgamated expanded: #include "perfetto/ext/base/hash.h"
1133 
1134 namespace perfetto {
1135 namespace base {
1136 
1137 // A string-like object that refers to a non-owned piece of memory.
1138 // Strings are internally NOT null terminated.
1139 class StringView {
1140  public:
1141   static constexpr size_t npos = static_cast<size_t>(-1);
1142 
StringView()1143   StringView() : data_(nullptr), size_(0) {}
1144   StringView(const StringView&) = default;
1145   StringView& operator=(const StringView&) = default;
StringView(const char * data,size_t size)1146   StringView(const char* data, size_t size) : data_(data), size_(size) {
1147     PERFETTO_DCHECK(size == 0 || data != nullptr);
1148   }
1149 
1150   // Allow implicit conversion from any class that has a |data| and |size| field
1151   // and has the kConvertibleToStringView trait (e.g., protozero::ConstChars).
1152   template <typename T, typename = std::enable_if<T::kConvertibleToStringView>>
StringView(const T & x)1153   StringView(const T& x) : StringView(x.data, x.size) {
1154     PERFETTO_DCHECK(x.size == 0 || x.data != nullptr);
1155   }
1156 
1157   // Creates a StringView from a null-terminated C string.
1158   // Deliberately not "explicit".
StringView(const char * cstr)1159   StringView(const char* cstr) : data_(cstr), size_(strlen(cstr)) {
1160     PERFETTO_DCHECK(cstr != nullptr);
1161   }
1162 
1163   // This instead has to be explicit, as creating a StringView out of a
1164   // std::string can be subtle.
StringView(const std::string & str)1165   explicit StringView(const std::string& str)
1166       : data_(str.data()), size_(str.size()) {}
1167 
empty() const1168   bool empty() const { return size_ == 0; }
size() const1169   size_t size() const { return size_; }
data() const1170   const char* data() const { return data_; }
begin() const1171   const char* begin() const { return data_; }
end() const1172   const char* end() const { return data_ + size_; }
1173 
at(size_t pos) const1174   char at(size_t pos) const {
1175     PERFETTO_DCHECK(pos < size_);
1176     return data_[pos];
1177   }
1178 
find(char c,size_t start_pos=0) const1179   size_t find(char c, size_t start_pos = 0) const {
1180     for (size_t i = start_pos; i < size_; ++i) {
1181       if (data_[i] == c)
1182         return i;
1183     }
1184     return npos;
1185   }
1186 
find(const StringView & str,size_t start_pos=0) const1187   size_t find(const StringView& str, size_t start_pos = 0) const {
1188     if (start_pos > size())
1189       return npos;
1190     auto it = std::search(begin() + start_pos, end(), str.begin(), str.end());
1191     size_t pos = static_cast<size_t>(it - begin());
1192     return pos + str.size() <= size() ? pos : npos;
1193   }
1194 
find(const char * str,size_t start_pos=0) const1195   size_t find(const char* str, size_t start_pos = 0) const {
1196     return find(StringView(str), start_pos);
1197   }
1198 
rfind(char c) const1199   size_t rfind(char c) const {
1200     for (size_t i = size_; i > 0; --i) {
1201       if (data_[i - 1] == c)
1202         return i - 1;
1203     }
1204     return npos;
1205   }
1206 
substr(size_t pos,size_t count=npos) const1207   StringView substr(size_t pos, size_t count = npos) const {
1208     if (pos >= size_)
1209       return StringView("", 0);
1210     size_t rcount = std::min(count, size_ - pos);
1211     return StringView(data_ + pos, rcount);
1212   }
1213 
CaseInsensitiveEq(const StringView & other) const1214   bool CaseInsensitiveEq(const StringView& other) const {
1215     if (size() != other.size())
1216       return false;
1217     if (size() == 0)
1218       return true;
1219 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
1220     return _strnicmp(data(), other.data(), size()) == 0;
1221 #else
1222     return strncasecmp(data(), other.data(), size()) == 0;
1223 #endif
1224   }
1225 
StartsWith(const StringView & other)1226   bool StartsWith(const StringView& other) {
1227     if (other.size() == 0)
1228       return true;
1229     if (size() == 0)
1230       return false;
1231     if (other.size() > size())
1232       return false;
1233     for (uint32_t i = 0; i < other.size(); ++i) {
1234       if (at(i) != other.at(i))
1235         return false;
1236     }
1237     return true;
1238   }
1239 
ToStdString() const1240   std::string ToStdString() const {
1241     return size_ == 0 ? "" : std::string(data_, size_);
1242   }
1243 
Hash() const1244   uint64_t Hash() const {
1245     base::Hash hasher;
1246     hasher.Update(data_, size_);
1247     return hasher.digest();
1248   }
1249 
1250  private:
1251   const char* data_ = nullptr;
1252   size_t size_ = 0;
1253 };
1254 
operator ==(const StringView & x,const StringView & y)1255 inline bool operator==(const StringView& x, const StringView& y) {
1256   if (x.size() != y.size())
1257     return false;
1258   if (x.size() == 0)
1259     return true;
1260   return memcmp(x.data(), y.data(), x.size()) == 0;
1261 }
1262 
operator !=(const StringView & x,const StringView & y)1263 inline bool operator!=(const StringView& x, const StringView& y) {
1264   return !(x == y);
1265 }
1266 
operator <(const StringView & x,const StringView & y)1267 inline bool operator<(const StringView& x, const StringView& y) {
1268   auto size = std::min(x.size(), y.size());
1269   if (size == 0)
1270     return x.size() < y.size();
1271   int result = memcmp(x.data(), y.data(), size);
1272   return result < 0 || (result == 0 && x.size() < y.size());
1273 }
1274 
operator >=(const StringView & x,const StringView & y)1275 inline bool operator>=(const StringView& x, const StringView& y) {
1276   return !(x < y);
1277 }
1278 
operator >(const StringView & x,const StringView & y)1279 inline bool operator>(const StringView& x, const StringView& y) {
1280   return y < x;
1281 }
1282 
operator <=(const StringView & x,const StringView & y)1283 inline bool operator<=(const StringView& x, const StringView& y) {
1284   return !(y < x);
1285 }
1286 
1287 }  // namespace base
1288 }  // namespace perfetto
1289 
1290 template <>
1291 struct std::hash<::perfetto::base::StringView> {
operator ()std::hash1292   size_t operator()(const ::perfetto::base::StringView& sv) const {
1293     return static_cast<size_t>(sv.Hash());
1294   }
1295 };
1296 
1297 #endif  // INCLUDE_PERFETTO_EXT_BASE_STRING_VIEW_H_
1298 // gen_amalgamated begin header: include/perfetto/ext/base/utils.h
1299 /*
1300  * Copyright (C) 2017 The Android Open Source Project
1301  *
1302  * Licensed under the Apache License, Version 2.0 (the "License");
1303  * you may not use this file except in compliance with the License.
1304  * You may obtain a copy of the License at
1305  *
1306  *      http://www.apache.org/licenses/LICENSE-2.0
1307  *
1308  * Unless required by applicable law or agreed to in writing, software
1309  * distributed under the License is distributed on an "AS IS" BASIS,
1310  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1311  * See the License for the specific language governing permissions and
1312  * limitations under the License.
1313  */
1314 
1315 #ifndef INCLUDE_PERFETTO_EXT_BASE_UTILS_H_
1316 #define INCLUDE_PERFETTO_EXT_BASE_UTILS_H_
1317 
1318 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
1319 // gen_amalgamated expanded: #include "perfetto/base/compiler.h"
1320 
1321 #include <errno.h>
1322 #include <stddef.h>
1323 #include <stdint.h>
1324 #include <stdlib.h>
1325 #include <sys/types.h>
1326 
1327 #include <atomic>
1328 #include <functional>
1329 #include <memory>
1330 #include <string>
1331 
1332 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
1333 // Even if Windows has errno.h, the all syscall-restart behavior does not apply.
1334 // Trying to handle EINTR can cause more harm than good if errno is left stale.
1335 // Chromium does the same.
1336 #define PERFETTO_EINTR(x) (x)
1337 #else
1338 #define PERFETTO_EINTR(x)                                   \
1339   ([&] {                                                    \
1340     decltype(x) eintr_wrapper_result;                       \
1341     do {                                                    \
1342       eintr_wrapper_result = (x);                           \
1343     } while (eintr_wrapper_result == -1 && errno == EINTR); \
1344     return eintr_wrapper_result;                            \
1345   }())
1346 #endif
1347 
1348 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
1349 using uid_t = unsigned int;
1350 #if !PERFETTO_BUILDFLAG(PERFETTO_COMPILER_GCC)
1351 using pid_t = unsigned int;
1352 #endif
1353 #if defined(_WIN64)
1354 using ssize_t = int64_t;
1355 #else
1356 using ssize_t = long;
1357 #endif
1358 #endif
1359 
1360 namespace perfetto {
1361 namespace base {
1362 
1363 constexpr uid_t kInvalidUid = static_cast<uid_t>(-1);
1364 constexpr pid_t kInvalidPid = static_cast<pid_t>(-1);
1365 
1366 // Do not add new usages of kPageSize, consider using GetSysPageSize() below.
1367 // TODO(primiano): over time the semantic of kPageSize became too ambiguous.
1368 // Strictly speaking, this constant is incorrect on some new devices where the
1369 // page size can be 16K (e.g., crbug.com/1116576). Unfortunately too much code
1370 // ended up depending on kPageSize for purposes that are not strictly related
1371 // with the kernel's mm subsystem.
1372 constexpr size_t kPageSize = 4096;
1373 
1374 // Returns the system's page size. Use this when dealing with mmap, madvise and
1375 // similar mm-related syscalls.
1376 uint32_t GetSysPageSize();
1377 
1378 template <typename T>
ArraySize(const T & array)1379 constexpr size_t ArraySize(const T& array) {
1380   return sizeof(array) / sizeof(array[0]);
1381 }
1382 
1383 // Function object which invokes 'free' on its parameter, which must be
1384 // a pointer. Can be used to store malloc-allocated pointers in std::unique_ptr:
1385 //
1386 // std::unique_ptr<int, base::FreeDeleter> foo_ptr(
1387 //     static_cast<int*>(malloc(sizeof(int))));
1388 struct FreeDeleter {
operator ()perfetto::base::FreeDeleter1389   inline void operator()(void* ptr) const { free(ptr); }
1390 };
1391 
1392 template <typename T>
AssumeLittleEndian(T value)1393 constexpr T AssumeLittleEndian(T value) {
1394 #if !PERFETTO_IS_LITTLE_ENDIAN()
1395   static_assert(false, "Unimplemented on big-endian archs");
1396 #endif
1397   return value;
1398 }
1399 
1400 // Round up |size| to a multiple of |alignment| (must be a power of two).
1401 template <size_t alignment>
AlignUp(size_t size)1402 constexpr size_t AlignUp(size_t size) {
1403   static_assert((alignment & (alignment - 1)) == 0, "alignment must be a pow2");
1404   return (size + alignment - 1) & ~(alignment - 1);
1405 }
1406 
IsAgain(int err)1407 inline bool IsAgain(int err) {
1408   return err == EAGAIN || err == EWOULDBLOCK;
1409 }
1410 
1411 // setenv(2)-equivalent. Deals with Windows vs Posix discrepancies.
1412 void SetEnv(const std::string& key, const std::string& value);
1413 
1414 // Calls mallopt(M_PURGE, 0) on Android. Does nothing on other platforms.
1415 // This forces the allocator to release freed memory. This is used to work
1416 // around various Scudo inefficiencies. See b/170217718.
1417 void MaybeReleaseAllocatorMemToOS();
1418 
1419 // geteuid() on POSIX OSes, returns 0 on Windows (See comment in utils.cc).
1420 uid_t GetCurrentUserId();
1421 
1422 // Forks the process.
1423 // Parent: prints the PID of the child, calls |parent_cb| and exits from the
1424 //         process with its return value.
1425 // Child: redirects stdio onto /dev/null, chdirs into / and returns.
1426 void Daemonize(std::function<int()> parent_cb);
1427 
1428 // Returns the path of the current executable, e.g. /foo/bar/exe.
1429 std::string GetCurExecutablePath();
1430 
1431 // Returns the directory where the current executable lives in, e.g. /foo/bar.
1432 // This is independent of cwd().
1433 std::string GetCurExecutableDir();
1434 
1435 // Memory returned by AlignedAlloc() must be freed via AlignedFree() not just
1436 // free. It makes a difference on Windows where _aligned_malloc() and
1437 // _aligned_free() must be paired.
1438 // Prefer using the AlignedAllocTyped() below which takes care of the pairing.
1439 void* AlignedAlloc(size_t alignment, size_t size);
1440 void AlignedFree(void*);
1441 
1442 // A RAII version of the above, which takes care of pairing Aligned{Alloc,Free}.
1443 template <typename T>
1444 struct AlignedDeleter {
operator ()perfetto::base::AlignedDeleter1445   inline void operator()(T* ptr) const { AlignedFree(ptr); }
1446 };
1447 
1448 // The remove_extent<T> here and below is to allow defining unique_ptr<T[]>.
1449 // As per https://en.cppreference.com/w/cpp/memory/unique_ptr the Deleter takes
1450 // always a T*, not a T[]*.
1451 template <typename T>
1452 using AlignedUniquePtr =
1453     std::unique_ptr<T, AlignedDeleter<typename std::remove_extent<T>::type>>;
1454 
1455 template <typename T>
AlignedAllocTyped(size_t n_membs)1456 AlignedUniquePtr<T> AlignedAllocTyped(size_t n_membs) {
1457   using TU = typename std::remove_extent<T>::type;
1458   return AlignedUniquePtr<T>(
1459       static_cast<TU*>(AlignedAlloc(alignof(TU), sizeof(TU) * n_membs)));
1460 }
1461 
1462 // A RAII wrapper to invoke a function when leaving a function/scope.
1463 template <typename Func>
1464 class OnScopeExitWrapper {
1465  public:
OnScopeExitWrapper(Func f)1466   explicit OnScopeExitWrapper(Func f) : f_(std::move(f)), active_(true) {}
OnScopeExitWrapper(OnScopeExitWrapper && other)1467   OnScopeExitWrapper(OnScopeExitWrapper&& other) noexcept
1468       : f_(std::move(other.f_)), active_(other.active_) {
1469     other.active_ = false;
1470   }
~OnScopeExitWrapper()1471   ~OnScopeExitWrapper() {
1472     if (active_)
1473       f_();
1474   }
1475 
1476  private:
1477   Func f_;
1478   bool active_;
1479 };
1480 
1481 template <typename Func>
OnScopeExit(Func f)1482 PERFETTO_WARN_UNUSED_RESULT OnScopeExitWrapper<Func> OnScopeExit(Func f) {
1483   return OnScopeExitWrapper<Func>(std::move(f));
1484 }
1485 
1486 // Returns a xxd-style hex dump (hex + ascii chars) of the input data.
1487 std::string HexDump(const void* data, size_t len, size_t bytes_per_line = 16);
HexDump(const std::string & data,size_t bytes_per_line=16)1488 inline std::string HexDump(const std::string& data,
1489                            size_t bytes_per_line = 16) {
1490   return HexDump(data.data(), data.size(), bytes_per_line);
1491 }
1492 
1493 }  // namespace base
1494 }  // namespace perfetto
1495 
1496 #endif  // INCLUDE_PERFETTO_EXT_BASE_UTILS_H_
1497 /*
1498  * Copyright (C) 2021 The Android Open Source Project
1499  *
1500  * Licensed under the Apache License, Version 2.0 (the "License");
1501  * you may not use this file except in compliance with the License.
1502  * You may obtain a copy of the License at
1503  *
1504  *      http://www.apache.org/licenses/LICENSE-2.0
1505  *
1506  * Unless required by applicable law or agreed to in writing, software
1507  * distributed under the License is distributed on an "AS IS" BASIS,
1508  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1509  * See the License for the specific language governing permissions and
1510  * limitations under the License.
1511  */
1512 
1513 #ifndef INCLUDE_PERFETTO_EXT_BASE_BASE64_H_
1514 #define INCLUDE_PERFETTO_EXT_BASE_BASE64_H_
1515 
1516 #include <string>
1517 
1518 // gen_amalgamated expanded: #include "perfetto/ext/base/optional.h"
1519 // gen_amalgamated expanded: #include "perfetto/ext/base/string_view.h"
1520 // gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"  // For ssize_t.
1521 
1522 namespace perfetto {
1523 namespace base {
1524 
1525 // Returns the length of the destination string (included '=' padding).
1526 // Does NOT include the size of the string null terminator.
Base64EncSize(size_t src_size)1527 inline size_t Base64EncSize(size_t src_size) {
1528   return (src_size + 2) / 3 * 4;
1529 }
1530 
1531 // Returns the upper bound on the length of the destination buffer.
1532 // The actual decoded length might be <= the number returned here.
Base64DecSize(size_t src_size)1533 inline size_t Base64DecSize(size_t src_size) {
1534   return (src_size + 3) / 4 * 3;
1535 }
1536 
1537 // Does NOT null-terminate |dst|.
1538 ssize_t Base64Encode(const void* src,
1539                      size_t src_size,
1540                      char* dst,
1541                      size_t dst_size);
1542 
1543 std::string Base64Encode(const void* src, size_t src_size);
1544 
Base64Encode(StringView sv)1545 inline std::string Base64Encode(StringView sv) {
1546   return Base64Encode(sv.data(), sv.size());
1547 }
1548 
1549 // Returns -1 in case of failure.
1550 ssize_t Base64Decode(const char* src,
1551                      size_t src_size,
1552                      uint8_t* dst,
1553                      size_t dst_size);
1554 
1555 Optional<std::string> Base64Decode(const char* src, size_t src_size);
1556 
Base64Decode(StringView sv)1557 inline Optional<std::string> Base64Decode(StringView sv) {
1558   return Base64Decode(sv.data(), sv.size());
1559 }
1560 
1561 }  // namespace base
1562 }  // namespace perfetto
1563 
1564 #endif  // INCLUDE_PERFETTO_EXT_BASE_BASE64_H_
1565 /*
1566  * Copyright (C) 2021 The Android Open Source Project
1567  *
1568  * Licensed under the Apache License, Version 2.0 (the "License");
1569  * you may not use this file except in compliance with the License.
1570  * You may obtain a copy of the License at
1571  *
1572  *      http://www.apache.org/licenses/LICENSE-2.0
1573  *
1574  * Unless required by applicable law or agreed to in writing, software
1575  * distributed under the License is distributed on an "AS IS" BASIS,
1576  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1577  * See the License for the specific language governing permissions and
1578  * limitations under the License.
1579  */
1580 
1581 // gen_amalgamated expanded: #include "perfetto/ext/base/base64.h"
1582 
1583 namespace perfetto {
1584 namespace base {
1585 
1586 namespace {
1587 
1588 constexpr char kPadding = '=';
1589 
1590 constexpr char kEncTable[] =
1591     "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
1592 static_assert(sizeof(kEncTable) == (1u << 6) + sizeof('\0'), "Bad table size");
1593 
1594 // Maps an ASCII character to its 6-bit value. It only contains translations
1595 // from '+' to 'z'. Supports the standard (+/) and URL-safe (-_) alphabets.
1596 constexpr uint8_t kX = 0xff;  // Value used for invalid characters
1597 constexpr uint8_t kDecTable[] = {
1598     62, kX, 62, kX, 63, 52, 53, 54, 55, 56,  // 00 - 09
1599     57, 58, 59, 60, 61, kX, kX, kX, 0,  kX,  // 10 - 19
1600     kX, kX, 0,  1,  2,  3,  4,  5,  6,  7,   // 20 - 29
1601     8,  9,  10, 11, 12, 13, 14, 15, 16, 17,  // 30 - 39
1602     18, 19, 20, 21, 22, 23, 24, 25, kX, kX,  // 40 - 49
1603     kX, kX, 63, kX, 26, 27, 28, 29, 30, 31,  // 50 - 59
1604     32, 33, 34, 35, 36, 37, 38, 39, 40, 41,  // 60 - 69
1605     42, 43, 44, 45, 46, 47, 48, 49, 50, 51,  // 70 - 79
1606 };
1607 constexpr char kMinDecChar = '+';
1608 constexpr char kMaxDecChar = 'z';
1609 static_assert(kMaxDecChar - kMinDecChar <= sizeof(kDecTable), "Bad table size");
1610 
DecodeChar(char c)1611 inline uint8_t DecodeChar(char c) {
1612   if (c < kMinDecChar || c > kMaxDecChar)
1613     return kX;
1614   return kDecTable[c - kMinDecChar];
1615 }
1616 
1617 }  // namespace
1618 
Base64Encode(const void * src,size_t src_size,char * dst,size_t dst_size)1619 ssize_t Base64Encode(const void* src,
1620                      size_t src_size,
1621                      char* dst,
1622                      size_t dst_size) {
1623   const size_t padded_dst_size = Base64EncSize(src_size);
1624   if (dst_size < padded_dst_size)
1625     return -1;  // Not enough space in output.
1626 
1627   const uint8_t* rd = static_cast<const uint8_t*>(src);
1628   const uint8_t* const end = rd + src_size;
1629   size_t wr_size = 0;
1630   while (rd < end) {
1631     uint8_t s[3]{};
1632     s[0] = *(rd++);
1633     dst[wr_size++] = kEncTable[s[0] >> 2];
1634 
1635     uint8_t carry0 = static_cast<uint8_t>((s[0] & 0x03) << 4);
1636     if (PERFETTO_LIKELY(rd < end)) {
1637       s[1] = *(rd++);
1638       dst[wr_size++] = kEncTable[carry0 | (s[1] >> 4)];
1639     } else {
1640       dst[wr_size++] = kEncTable[carry0];
1641       dst[wr_size++] = kPadding;
1642       dst[wr_size++] = kPadding;
1643       break;
1644     }
1645 
1646     uint8_t carry1 = static_cast<uint8_t>((s[1] & 0x0f) << 2);
1647     if (PERFETTO_LIKELY(rd < end)) {
1648       s[2] = *(rd++);
1649       dst[wr_size++] = kEncTable[carry1 | (s[2] >> 6)];
1650     } else {
1651       dst[wr_size++] = kEncTable[carry1];
1652       dst[wr_size++] = kPadding;
1653       break;
1654     }
1655 
1656     dst[wr_size++] = kEncTable[s[2] & 0x3f];
1657   }
1658   PERFETTO_DCHECK(wr_size == padded_dst_size);
1659   return static_cast<ssize_t>(padded_dst_size);
1660 }
1661 
Base64Encode(const void * src,size_t src_size)1662 std::string Base64Encode(const void* src, size_t src_size) {
1663   std::string dst;
1664   dst.resize(Base64EncSize(src_size));
1665   auto res = Base64Encode(src, src_size, &dst[0], dst.size());
1666   PERFETTO_CHECK(res == static_cast<ssize_t>(dst.size()));
1667   return dst;
1668 }
1669 
Base64Decode(const char * src,size_t src_size,uint8_t * dst,size_t dst_size)1670 ssize_t Base64Decode(const char* src,
1671                      size_t src_size,
1672                      uint8_t* dst,
1673                      size_t dst_size) {
1674   const size_t min_dst_size = Base64DecSize(src_size);
1675   if (dst_size < min_dst_size)
1676     return -1;
1677 
1678   const char* rd = src;
1679   const char* const end = src + src_size;
1680   size_t wr_size = 0;
1681 
1682   char s[4]{};
1683   while (rd < end) {
1684     uint8_t d[4];
1685     for (uint32_t j = 0; j < 4; j++) {
1686       // Padding is only feasible for the last 2 chars of each group of 4.
1687       s[j] = rd < end ? *(rd++) : (j < 2 ? '\0' : kPadding);
1688       d[j] = DecodeChar(s[j]);
1689       if (d[j] == kX)
1690         return -1;  // Invalid input char.
1691     }
1692     dst[wr_size] = static_cast<uint8_t>((d[0] << 2) | (d[1] >> 4));
1693     dst[wr_size + 1] = static_cast<uint8_t>((d[1] << 4) | (d[2] >> 2));
1694     dst[wr_size + 2] = static_cast<uint8_t>((d[2] << 6) | (d[3]));
1695     wr_size += 3;
1696   }
1697 
1698   PERFETTO_CHECK(wr_size <= dst_size);
1699   wr_size -= (s[3] == kPadding ? 1 : 0) + (s[2] == kPadding ? 1 : 0);
1700   return static_cast<ssize_t>(wr_size);
1701 }
1702 
Base64Decode(const char * src,size_t src_size)1703 Optional<std::string> Base64Decode(const char* src, size_t src_size) {
1704   std::string dst;
1705   dst.resize(Base64DecSize(src_size));
1706   auto res = Base64Decode(src, src_size, reinterpret_cast<uint8_t*>(&dst[0]),
1707                           dst.size());
1708   if (res < 0)
1709     return nullopt;  // Decoding error.
1710 
1711   PERFETTO_CHECK(res <= static_cast<ssize_t>(dst.size()));
1712   dst.resize(static_cast<size_t>(res));
1713   return base::make_optional(dst);
1714 }
1715 
1716 }  // namespace base
1717 }  // namespace perfetto
1718 // gen_amalgamated begin source: src/base/crash_keys.cc
1719 // gen_amalgamated begin header: include/perfetto/ext/base/crash_keys.h
1720 /*
1721  * Copyright (C) 2021 The Android Open Source Project
1722  *
1723  * Licensed under the Apache License, Version 2.0 (the "License");
1724  * you may not use this file except in compliance with the License.
1725  * You may obtain a copy of the License at
1726  *
1727  *      http://www.apache.org/licenses/LICENSE-2.0
1728  *
1729  * Unless required by applicable law or agreed to in writing, software
1730  * distributed under the License is distributed on an "AS IS" BASIS,
1731  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1732  * See the License for the specific language governing permissions and
1733  * limitations under the License.
1734  */
1735 
1736 #ifndef INCLUDE_PERFETTO_EXT_BASE_CRASH_KEYS_H_
1737 #define INCLUDE_PERFETTO_EXT_BASE_CRASH_KEYS_H_
1738 
1739 #include <algorithm>
1740 #include <atomic>
1741 
1742 #include <stdint.h>
1743 #include <string.h>
1744 
1745 // gen_amalgamated expanded: #include "perfetto/base/compiler.h"
1746 // gen_amalgamated expanded: #include "perfetto/ext/base/string_view.h"
1747 
1748 // Crash keys are very simple global variables with static-storage that
1749 // are reported on crash time for managed crashes (CHECK/FATAL/Watchdog).
1750 // - Translation units can define a CrashKey and register it at some point
1751 //   during initialization.
1752 // - CrashKey instances must be long-lived. They should really be just global
1753 //   static variable in the anonymous namespace.
1754 // Example:
1755 // subsystem_1.cc
1756 //   CrashKey g_client_id("ipc_client_id");
1757 //   ...
1758 //   OnIpcReceived(client_id) {
1759 //      g_client_id.Set(client_id);
1760 //      ... // Process the IPC
1761 //      g_client_id.Clear();
1762 //   }
1763 //   Or equivalently:
1764 //   OnIpcReceived(client_id) {
1765 //      auto scoped_key = g_client_id.SetScoped(client_id);
1766 //      ... // Process the IPC
1767 //   }
1768 //
1769 // If a crash happens while processing the IPC, the crash report will
1770 // have a line "ipc_client_id: 42".
1771 //
1772 // Thread safety considerations:
1773 // CrashKeys can be registered and set/cleared from any thread.
1774 // There is no compelling use-case to have full acquire/release consistency when
1775 // setting a key. This means that if a thread crashes immediately after a
1776 // crash key has been set on another thread, the value printed on the crash
1777 // report could be incomplete. The code guarantees defined behavior and does
1778 // not rely on null-terminated string (in the worst case 32 bytes of random
1779 // garbage will be printed out).
1780 
1781 // The tests live in logging_unittest.cc.
1782 
1783 namespace perfetto {
1784 namespace base {
1785 
1786 constexpr size_t kCrashKeyMaxStrSize = 32;
1787 
1788 // CrashKey instances must be long lived
1789 class CrashKey {
1790  public:
1791   class ScopedClear {
1792    public:
ScopedClear(CrashKey * k)1793     explicit ScopedClear(CrashKey* k) : key_(k) {}
~ScopedClear()1794     ~ScopedClear() {
1795       if (key_)
1796         key_->Clear();
1797     }
1798     ScopedClear(const ScopedClear&) = delete;
1799     ScopedClear& operator=(const ScopedClear&) = delete;
1800     ScopedClear& operator=(ScopedClear&&) = delete;
ScopedClear(ScopedClear && other)1801     ScopedClear(ScopedClear&& other) noexcept : key_(other.key_) {
1802       other.key_ = nullptr;
1803     }
1804 
1805    private:
1806     CrashKey* key_;
1807   };
1808 
1809   // constexpr so it can be used in the anon namespace without requiring a
1810   // global constructor.
1811   // |name| must be a long-lived string.
CrashKey(const char * name)1812   constexpr explicit CrashKey(const char* name)
1813       : registered_{}, type_(Type::kUnset), name_(name), str_value_{} {}
1814   CrashKey(const CrashKey&) = delete;
1815   CrashKey& operator=(const CrashKey&) = delete;
1816   CrashKey(CrashKey&&) = delete;
1817   CrashKey& operator=(CrashKey&&) = delete;
1818 
1819   enum class Type : uint8_t { kUnset = 0, kInt, kStr };
1820 
Clear()1821   void Clear() {
1822     int_value_.store(0, std::memory_order_relaxed);
1823     type_.store(Type::kUnset, std::memory_order_relaxed);
1824   }
1825 
Set(int64_t value)1826   void Set(int64_t value) {
1827     int_value_.store(value, std::memory_order_relaxed);
1828     type_.store(Type::kInt, std::memory_order_relaxed);
1829     if (PERFETTO_UNLIKELY(!registered_.load(std::memory_order_relaxed)))
1830       Register();
1831   }
1832 
Set(StringView sv)1833   void Set(StringView sv) {
1834     size_t len = std::min(sv.size(), sizeof(str_value_) - 1);
1835     for (size_t i = 0; i < len; ++i)
1836       str_value_[i].store(sv.data()[i], std::memory_order_relaxed);
1837     str_value_[len].store('\0', std::memory_order_relaxed);
1838     type_.store(Type::kStr, std::memory_order_relaxed);
1839     if (PERFETTO_UNLIKELY(!registered_.load(std::memory_order_relaxed)))
1840       Register();
1841   }
1842 
SetScoped(int64_t value)1843   ScopedClear SetScoped(int64_t value) PERFETTO_WARN_UNUSED_RESULT {
1844     Set(value);
1845     return ScopedClear(this);
1846   }
1847 
SetScoped(StringView sv)1848   ScopedClear SetScoped(StringView sv) PERFETTO_WARN_UNUSED_RESULT {
1849     Set(sv);
1850     return ScopedClear(this);
1851   }
1852 
1853   void Register();
1854 
int_value() const1855   int64_t int_value() const {
1856     return int_value_.load(std::memory_order_relaxed);
1857   }
1858   size_t ToString(char* dst, size_t len);
1859 
1860  private:
1861   std::atomic<bool> registered_;
1862   std::atomic<Type> type_;
1863   const char* const name_;
1864   union {
1865     std::atomic<char> str_value_[kCrashKeyMaxStrSize];
1866     std::atomic<int64_t> int_value_;
1867   };
1868 };
1869 
1870 // Fills |dst| with a string containing one line for each crash key
1871 // (excluding the unset ones).
1872 // Returns number of chars written, without counting the NUL terminator.
1873 // This is used in logging.cc when emitting the crash report abort message.
1874 size_t SerializeCrashKeys(char* dst, size_t len);
1875 
1876 void UnregisterAllCrashKeysForTesting();
1877 
1878 }  // namespace base
1879 }  // namespace perfetto
1880 
1881 #endif  // INCLUDE_PERFETTO_EXT_BASE_CRASH_KEYS_H_
1882 // gen_amalgamated begin header: include/perfetto/ext/base/string_utils.h
1883 /*
1884  * Copyright (C) 2018 The Android Open Source Project
1885  *
1886  * Licensed under the Apache License, Version 2.0 (the "License");
1887  * you may not use this file except in compliance with the License.
1888  * You may obtain a copy of the License at
1889  *
1890  *      http://www.apache.org/licenses/LICENSE-2.0
1891  *
1892  * Unless required by applicable law or agreed to in writing, software
1893  * distributed under the License is distributed on an "AS IS" BASIS,
1894  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1895  * See the License for the specific language governing permissions and
1896  * limitations under the License.
1897  */
1898 
1899 #ifndef INCLUDE_PERFETTO_EXT_BASE_STRING_UTILS_H_
1900 #define INCLUDE_PERFETTO_EXT_BASE_STRING_UTILS_H_
1901 
1902 #include <stdarg.h>
1903 #include <stdlib.h>
1904 #include <string.h>
1905 
1906 #include <cinttypes>
1907 #include <string>
1908 #include <vector>
1909 
1910 // gen_amalgamated expanded: #include "perfetto/ext/base/optional.h"
1911 // gen_amalgamated expanded: #include "perfetto/ext/base/string_view.h"
1912 
1913 namespace perfetto {
1914 namespace base {
1915 
Lowercase(char c)1916 inline char Lowercase(char c) {
1917   return ('A' <= c && c <= 'Z') ? static_cast<char>(c - ('A' - 'a')) : c;
1918 }
1919 
Uppercase(char c)1920 inline char Uppercase(char c) {
1921   return ('a' <= c && c <= 'z') ? static_cast<char>(c + ('A' - 'a')) : c;
1922 }
1923 
CStringToUInt32(const char * s,int base=10)1924 inline Optional<uint32_t> CStringToUInt32(const char* s, int base = 10) {
1925   char* endptr = nullptr;
1926   auto value = static_cast<uint32_t>(strtoul(s, &endptr, base));
1927   return (*s && !*endptr) ? base::make_optional(value) : base::nullopt;
1928 }
1929 
CStringToInt32(const char * s,int base=10)1930 inline Optional<int32_t> CStringToInt32(const char* s, int base = 10) {
1931   char* endptr = nullptr;
1932   auto value = static_cast<int32_t>(strtol(s, &endptr, base));
1933   return (*s && !*endptr) ? base::make_optional(value) : base::nullopt;
1934 }
1935 
1936 // Note: it saturates to 7fffffffffffffff if parsing a hex number >= 0x8000...
CStringToInt64(const char * s,int base=10)1937 inline Optional<int64_t> CStringToInt64(const char* s, int base = 10) {
1938   char* endptr = nullptr;
1939   auto value = static_cast<int64_t>(strtoll(s, &endptr, base));
1940   return (*s && !*endptr) ? base::make_optional(value) : base::nullopt;
1941 }
1942 
CStringToUInt64(const char * s,int base=10)1943 inline Optional<uint64_t> CStringToUInt64(const char* s, int base = 10) {
1944   char* endptr = nullptr;
1945   auto value = static_cast<uint64_t>(strtoull(s, &endptr, base));
1946   return (*s && !*endptr) ? base::make_optional(value) : base::nullopt;
1947 }
1948 
1949 double StrToD(const char* nptr, char** endptr);
1950 
CStringToDouble(const char * s)1951 inline Optional<double> CStringToDouble(const char* s) {
1952   char* endptr = nullptr;
1953   double value = StrToD(s, &endptr);
1954   Optional<double> result(base::nullopt);
1955   if (*s != '\0' && *endptr == '\0')
1956     result = value;
1957   return result;
1958 }
1959 
StringToUInt32(const std::string & s,int base=10)1960 inline Optional<uint32_t> StringToUInt32(const std::string& s, int base = 10) {
1961   return CStringToUInt32(s.c_str(), base);
1962 }
1963 
StringToInt32(const std::string & s,int base=10)1964 inline Optional<int32_t> StringToInt32(const std::string& s, int base = 10) {
1965   return CStringToInt32(s.c_str(), base);
1966 }
1967 
StringToUInt64(const std::string & s,int base=10)1968 inline Optional<uint64_t> StringToUInt64(const std::string& s, int base = 10) {
1969   return CStringToUInt64(s.c_str(), base);
1970 }
1971 
StringToInt64(const std::string & s,int base=10)1972 inline Optional<int64_t> StringToInt64(const std::string& s, int base = 10) {
1973   return CStringToInt64(s.c_str(), base);
1974 }
1975 
StringToDouble(const std::string & s)1976 inline Optional<double> StringToDouble(const std::string& s) {
1977   return CStringToDouble(s.c_str());
1978 }
1979 
1980 bool StartsWith(const std::string& str, const std::string& prefix);
1981 bool EndsWith(const std::string& str, const std::string& suffix);
1982 bool StartsWithAny(const std::string& str,
1983                    const std::vector<std::string>& prefixes);
1984 bool Contains(const std::string& haystack, const std::string& needle);
1985 bool Contains(const std::string& haystack, char needle);
1986 size_t Find(const StringView& needle, const StringView& haystack);
1987 bool CaseInsensitiveEqual(const std::string& first, const std::string& second);
1988 std::string Join(const std::vector<std::string>& parts,
1989                  const std::string& delim);
1990 std::vector<std::string> SplitString(const std::string& text,
1991                                      const std::string& delimiter);
1992 std::string StripPrefix(const std::string& str, const std::string& prefix);
1993 std::string StripSuffix(const std::string& str, const std::string& suffix);
1994 std::string ToLower(const std::string& str);
1995 std::string ToUpper(const std::string& str);
1996 std::string StripChars(const std::string& str,
1997                        const std::string& chars,
1998                        char replacement);
1999 std::string ToHex(const char* data, size_t size);
ToHex(const std::string & s)2000 inline std::string ToHex(const std::string& s) {
2001   return ToHex(s.c_str(), s.size());
2002 }
2003 std::string IntToHexString(uint32_t number);
2004 std::string Uint64ToHexString(uint64_t number);
2005 std::string Uint64ToHexStringNoPrefix(uint64_t number);
2006 std::string ReplaceAll(std::string str,
2007                        const std::string& to_replace,
2008                        const std::string& replacement);
2009 std::string TrimLeading(const std::string& str);
2010 
2011 // A BSD-style strlcpy without the return value.
2012 // Copies at most |dst_size|-1 characters. Unlike strncpy, it always \0
2013 // terminates |dst|, as long as |dst_size| is not 0.
2014 // Unlike strncpy and like strlcpy it does not zero-pad the rest of |dst|.
2015 // Returns nothing. The BSD strlcpy returns the size of |src|, which might
2016 // be > |dst_size|. Anecdotal experience suggests people assume the return value
2017 // is the number of bytes written in |dst|. That assumption can lead to
2018 // dangerous bugs.
2019 // In order to avoid being subtly uncompliant with strlcpy AND avoid misuse,
2020 // the choice here is to return nothing.
StringCopy(char * dst,const char * src,size_t dst_size)2021 inline void StringCopy(char* dst, const char* src, size_t dst_size) {
2022   for (size_t i = 0; i < dst_size; ++i) {
2023     if ((dst[i] = src[i]) == '\0') {
2024       return;  // We hit and copied the null terminator.
2025     }
2026   }
2027 
2028   // We were left off at dst_size. We over copied 1 byte. Null terminate.
2029   if (PERFETTO_LIKELY(dst_size > 0))
2030     dst[dst_size - 1] = 0;
2031 }
2032 
2033 // Like snprintf() but returns the number of chars *actually* written (without
2034 // counting the null terminator) NOT "the number of chars which would have been
2035 // written to the final string if enough  space had been available".
2036 // This should be used in almost all cases when the caller uses the return value
2037 // of snprintf(). If the return value is not used, there is no benefit in using
2038 // this wrapper, as this just calls snprintf() and mangles the return value.
2039 // It always null-terminates |dst| (even in case of errors), unless
2040 // |dst_size| == 0.
2041 // Examples:
2042 //   SprintfTrunc(x, 4, "123whatever"): returns 3 and writes "123\0".
2043 //   SprintfTrunc(x, 4, "123"): returns 3 and writes "123\0".
2044 //   SprintfTrunc(x, 3, "123"): returns 2 and writes "12\0".
2045 //   SprintfTrunc(x, 2, "123"): returns 1 and writes "1\0".
2046 //   SprintfTrunc(x, 1, "123"): returns 0 and writes "\0".
2047 //   SprintfTrunc(x, 0, "123"): returns 0 and writes nothing.
2048 // NOTE: This means that the caller has no way to tell when truncation happens
2049 //   vs the edge case of *just* fitting in the buffer.
2050 size_t SprintfTrunc(char* dst, size_t dst_size, const char* fmt, ...)
2051     PERFETTO_PRINTF_FORMAT(3, 4);
2052 
2053 // A helper class to facilitate construction and usage of write-once stack
2054 // strings.
2055 // Example usage:
2056 //   StackString<32> x("format %d %s", 42, string_arg);
2057 //   TakeString(x.c_str() | x.string_view() | x.ToStdString());
2058 // Rather than char x[32] + sprintf.
2059 // Advantages:
2060 // - Avoids useless zero-fills caused by people doing `char buf[32] {}` (mainly
2061 //   by fearing unknown snprintf failure modes).
2062 // - Makes the code more robust in case of snprintf truncations (len() and
2063 //  string_view() will return the truncated length, unlike snprintf).
2064 template <size_t N>
2065 class StackString {
2066  public:
2067   explicit PERFETTO_PRINTF_FORMAT(/* 1=this */ 2, 3)
StackString(const char * fmt,...)2068       StackString(const char* fmt, ...) {
2069     buf_[0] = '\0';
2070     va_list args;
2071     va_start(args, fmt);
2072     int res = vsnprintf(buf_, sizeof(buf_), fmt, args);
2073     va_end(args);
2074     buf_[sizeof(buf_) - 1] = '\0';
2075     len_ = res < 0 ? 0 : std::min(static_cast<size_t>(res), sizeof(buf_) - 1);
2076   }
2077 
string_view() const2078   StringView string_view() const { return StringView(buf_, len_); }
ToStdString() const2079   std::string ToStdString() const { return std::string(buf_, len_); }
c_str() const2080   const char* c_str() const { return buf_; }
len() const2081   size_t len() const { return len_; }
2082 
2083  private:
2084   char buf_[N];
2085   size_t len_ = 0;  // Does not include the \0.
2086 };
2087 
2088 }  // namespace base
2089 }  // namespace perfetto
2090 
2091 #endif  // INCLUDE_PERFETTO_EXT_BASE_STRING_UTILS_H_
2092 /*
2093  * Copyright (C) 2021 The Android Open Source Project
2094  *
2095  * Licensed under the Apache License, Version 2.0 (the "License");
2096  * you may not use this file except in compliance with the License.
2097  * You may obtain a copy of the License at
2098  *
2099  *      http://www.apache.org/licenses/LICENSE-2.0
2100  *
2101  * Unless required by applicable law or agreed to in writing, software
2102  * distributed under the License is distributed on an "AS IS" BASIS,
2103  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2104  * See the License for the specific language governing permissions and
2105  * limitations under the License.
2106  */
2107 
2108 // gen_amalgamated expanded: #include "perfetto/ext/base/crash_keys.h"
2109 
2110 #include <string.h>
2111 
2112 #include <atomic>
2113 #include <cinttypes>
2114 
2115 // gen_amalgamated expanded: #include "perfetto/ext/base/string_utils.h"
2116 
2117 namespace perfetto {
2118 namespace base {
2119 
2120 namespace {
2121 
2122 constexpr size_t kMaxKeys = 32;
2123 
2124 std::atomic<CrashKey*> g_keys[kMaxKeys]{};
2125 std::atomic<uint32_t> g_num_keys{};
2126 }  // namespace
2127 
Register()2128 void CrashKey::Register() {
2129   // If doesn't matter if we fail below. If there are no slots left, don't
2130   // keep trying re-registering on every Set(), the outcome won't change.
2131 
2132   // If two threads raced on the Register(), avoid registering the key twice.
2133   if (registered_.exchange(true))
2134     return;
2135 
2136   uint32_t slot = g_num_keys.fetch_add(1);
2137   if (slot >= kMaxKeys) {
2138     PERFETTO_LOG("Too many crash keys registered");
2139     return;
2140   }
2141   g_keys[slot].store(this);
2142 }
2143 
2144 // Returns the number of chars written, without counting the \0.
ToString(char * dst,size_t len)2145 size_t CrashKey::ToString(char* dst, size_t len) {
2146   if (len > 0)
2147     *dst = '\0';
2148   switch (type_.load(std::memory_order_relaxed)) {
2149     case Type::kUnset:
2150       break;
2151     case Type::kInt:
2152       return SprintfTrunc(dst, len, "%s: %" PRId64 "\n", name_,
2153                           int_value_.load(std::memory_order_relaxed));
2154     case Type::kStr:
2155       char buf[sizeof(str_value_)];
2156       for (size_t i = 0; i < sizeof(str_value_); i++)
2157         buf[i] = str_value_[i].load(std::memory_order_relaxed);
2158 
2159       // Don't assume |str_value_| is properly null-terminated.
2160       return SprintfTrunc(dst, len, "%s: %.*s\n", name_, int(sizeof(buf)), buf);
2161   }
2162   return 0;
2163 }
2164 
UnregisterAllCrashKeysForTesting()2165 void UnregisterAllCrashKeysForTesting() {
2166   g_num_keys.store(0);
2167   for (auto& key : g_keys)
2168     key.store(nullptr);
2169 }
2170 
SerializeCrashKeys(char * dst,size_t len)2171 size_t SerializeCrashKeys(char* dst, size_t len) {
2172   size_t written = 0;
2173   uint32_t num_keys = g_num_keys.load();
2174   if (len > 0)
2175     *dst = '\0';
2176   for (uint32_t i = 0; i < num_keys && written < len; i++) {
2177     CrashKey* key = g_keys[i].load();
2178     if (!key)
2179       continue;  // Can happen if we hit this between the add and the store.
2180     written += key->ToString(dst + written, len - written);
2181   }
2182   PERFETTO_DCHECK(written <= len);
2183   PERFETTO_DCHECK(len == 0 || dst[written] == '\0');
2184   return written;
2185 }
2186 
2187 }  // namespace base
2188 }  // namespace perfetto
2189 // gen_amalgamated begin source: src/base/ctrl_c_handler.cc
2190 // gen_amalgamated begin header: include/perfetto/ext/base/ctrl_c_handler.h
2191 /*
2192  * Copyright (C) 2021 The Android Open Source Project
2193  *
2194  * Licensed under the Apache License, Version 2.0 (the "License");
2195  * you may not use this file except in compliance with the License.
2196  * You may obtain a copy of the License at
2197  *
2198  *      http://www.apache.org/licenses/LICENSE-2.0
2199  *
2200  * Unless required by applicable law or agreed to in writing, software
2201  * distributed under the License is distributed on an "AS IS" BASIS,
2202  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2203  * See the License for the specific language governing permissions and
2204  * limitations under the License.
2205  */
2206 
2207 #ifndef INCLUDE_PERFETTO_EXT_BASE_CTRL_C_HANDLER_H_
2208 #define INCLUDE_PERFETTO_EXT_BASE_CTRL_C_HANDLER_H_
2209 
2210 namespace perfetto {
2211 namespace base {
2212 
2213 // On Linux/Android/Mac: installs SIGINT + SIGTERM signal handlers.
2214 // On Windows: installs a SetConsoleCtrlHandler() handler.
2215 // The passed handler must be async safe.
2216 using CtrlCHandlerFunction = void (*)();
2217 void InstallCtrCHandler(CtrlCHandlerFunction);
2218 
2219 }  // namespace base
2220 }  // namespace perfetto
2221 
2222 #endif  // INCLUDE_PERFETTO_EXT_BASE_CTRL_C_HANDLER_H_
2223 /*
2224  * Copyright (C) 2021 The Android Open Source Project
2225  *
2226  * Licensed under the Apache License, Version 2.0 (the "License");
2227  * you may not use this file except in compliance with the License.
2228  * You may obtain a copy of the License at
2229  *
2230  *      http://www.apache.org/licenses/LICENSE-2.0
2231  *
2232  * Unless required by applicable law or agreed to in writing, software
2233  * distributed under the License is distributed on an "AS IS" BASIS,
2234  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2235  * See the License for the specific language governing permissions and
2236  * limitations under the License.
2237  */
2238 
2239 // gen_amalgamated expanded: #include "perfetto/ext/base/ctrl_c_handler.h"
2240 
2241 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
2242 // gen_amalgamated expanded: #include "perfetto/base/compiler.h"
2243 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
2244 
2245 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
2246 #include <Windows.h>
2247 #include <io.h>
2248 #else
2249 #include <signal.h>
2250 #include <unistd.h>
2251 #endif
2252 
2253 namespace perfetto {
2254 namespace base {
2255 
2256 namespace {
2257 CtrlCHandlerFunction g_handler = nullptr;
2258 }
2259 
InstallCtrCHandler(CtrlCHandlerFunction handler)2260 void InstallCtrCHandler(CtrlCHandlerFunction handler) {
2261   PERFETTO_CHECK(g_handler == nullptr);
2262   g_handler = handler;
2263 
2264 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
2265   auto trampoline = [](DWORD type) -> int {
2266     if (type == CTRL_C_EVENT) {
2267       g_handler();
2268       return true;
2269     }
2270     return false;
2271   };
2272   ::SetConsoleCtrlHandler(trampoline, true);
2273 #elif PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
2274     PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \
2275     PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
2276   // Setup signal handler.
2277   struct sigaction sa {};
2278 
2279 // Glibc headers for sa_sigaction trigger this.
2280 #pragma GCC diagnostic push
2281 #if defined(__clang__)
2282 #pragma GCC diagnostic ignored "-Wdisabled-macro-expansion"
2283 #endif
2284   sa.sa_handler = [](int) { g_handler(); };
2285   sa.sa_flags = static_cast<decltype(sa.sa_flags)>(SA_RESETHAND | SA_RESTART);
2286 #pragma GCC diagnostic pop
2287   sigaction(SIGINT, &sa, nullptr);
2288   sigaction(SIGTERM, &sa, nullptr);
2289 #else
2290   // Do nothing on NaCL and Fuchsia.
2291   ignore_result(handler);
2292 #endif
2293 }
2294 
2295 }  // namespace base
2296 }  // namespace perfetto
2297 // gen_amalgamated begin source: src/base/event_fd.cc
2298 // gen_amalgamated begin header: include/perfetto/ext/base/event_fd.h
2299 // gen_amalgamated begin header: include/perfetto/base/platform_handle.h
2300 /*
2301  * Copyright (C) 2020 The Android Open Source Project
2302  *
2303  * Licensed under the Apache License, Version 2.0 (the "License");
2304  * you may not use this file except in compliance with the License.
2305  * You may obtain a copy of the License at
2306  *
2307  *      http://www.apache.org/licenses/LICENSE-2.0
2308  *
2309  * Unless required by applicable law or agreed to in writing, software
2310  * distributed under the License is distributed on an "AS IS" BASIS,
2311  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2312  * See the License for the specific language governing permissions and
2313  * limitations under the License.
2314  */
2315 
2316 #ifndef INCLUDE_PERFETTO_BASE_PLATFORM_HANDLE_H_
2317 #define INCLUDE_PERFETTO_BASE_PLATFORM_HANDLE_H_
2318 
2319 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
2320 
2321 namespace perfetto {
2322 namespace base {
2323 
2324 // PlatformHandle should be used only for types that are HANDLE(s) in Windows.
2325 // It should NOT be used to blanket-replace "int fd" in the codebase.
2326 // Windows has two types of "handles", which, in UNIX-land, both map to int:
2327 // 1. File handles returned by the posix-compatibility API like _open().
2328 //    These are just int(s) and should stay such, because all the posix-like API
2329 //    in Windows.h take an int, not a HANDLE.
2330 // 2. Handles returned by old-school WINAPI like CreateFile, CreateEvent etc.
2331 //    These are proper HANDLE(s). PlatformHandle should be used here.
2332 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
2333 // Windows.h typedefs HANDLE to void*. We use void* here to avoid leaking
2334 // Windows.h through our headers.
2335 using PlatformHandle = void*;
2336 
2337 // On Windows both nullptr and 0xffff... (INVALID_HANDLE_VALUE) are invalid.
2338 struct PlatformHandleChecker {
IsValidperfetto::base::PlatformHandleChecker2339   static inline bool IsValid(PlatformHandle h) {
2340     return h && h != reinterpret_cast<PlatformHandle>(-1);
2341   }
2342 };
2343 #else
2344 using PlatformHandle = int;
2345 struct PlatformHandleChecker {
2346   static inline bool IsValid(PlatformHandle h) { return h >= 0; }
2347 };
2348 #endif
2349 
2350 // The definition of this lives in base/file_utils.cc (to avoid creating an
2351 // extra build edge for a one liner). This is really an alias for close() (UNIX)
2352 // CloseHandle() (Windows). THe indirection layer is just to avoid leaking
2353 // system headers like Windows.h through perfetto headers.
2354 // Thre return value is always UNIX-style: 0 on success, -1 on failure.
2355 int ClosePlatformHandle(PlatformHandle);
2356 
2357 }  // namespace base
2358 }  // namespace perfetto
2359 
2360 #endif  // INCLUDE_PERFETTO_BASE_PLATFORM_HANDLE_H_
2361 // gen_amalgamated begin header: include/perfetto/ext/base/scoped_file.h
2362 /*
2363  * Copyright (C) 2017 The Android Open Source Project
2364  *
2365  * Licensed under the Apache License, Version 2.0 (the "License");
2366  * you may not use this file except in compliance with the License.
2367  * You may obtain a copy of the License at
2368  *
2369  *      http://www.apache.org/licenses/LICENSE-2.0
2370  *
2371  * Unless required by applicable law or agreed to in writing, software
2372  * distributed under the License is distributed on an "AS IS" BASIS,
2373  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2374  * See the License for the specific language governing permissions and
2375  * limitations under the License.
2376  */
2377 
2378 #ifndef INCLUDE_PERFETTO_EXT_BASE_SCOPED_FILE_H_
2379 #define INCLUDE_PERFETTO_EXT_BASE_SCOPED_FILE_H_
2380 
2381 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
2382 
2383 #include <stdio.h>
2384 
2385 #if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
2386 #include <dirent.h>  // For DIR* / opendir().
2387 #endif
2388 
2389 #include <string>
2390 
2391 // gen_amalgamated expanded: #include "perfetto/base/export.h"
2392 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
2393 // gen_amalgamated expanded: #include "perfetto/base/platform_handle.h"
2394 
2395 namespace perfetto {
2396 namespace base {
2397 
2398 namespace internal {
2399 // Used for the most common cases of ScopedResource where there is only one
2400 // invalid value.
2401 template <typename T, T InvalidValue>
2402 struct DefaultValidityChecker {
IsValidperfetto::base::internal::DefaultValidityChecker2403   static bool IsValid(T t) { return t != InvalidValue; }
2404 };
2405 }  // namespace internal
2406 
2407 // RAII classes for auto-releasing fds and dirs.
2408 // if T is a pointer type, InvalidValue must be nullptr. Doing otherwise
2409 // causes weird unexpected behaviors (See https://godbolt.org/z/5nGMW4).
2410 template <typename T,
2411           int (*CloseFunction)(T),
2412           T InvalidValue,
2413           bool CheckClose = true,
2414           class Checker = internal::DefaultValidityChecker<T, InvalidValue>>
2415 class PERFETTO_EXPORT ScopedResource {
2416  public:
2417   using ValidityChecker = Checker;
2418   static constexpr T kInvalid = InvalidValue;
2419 
ScopedResource(T t=InvalidValue)2420   explicit ScopedResource(T t = InvalidValue) : t_(t) {}
ScopedResource(ScopedResource && other)2421   ScopedResource(ScopedResource&& other) noexcept {
2422     t_ = other.t_;
2423     other.t_ = InvalidValue;
2424   }
operator =(ScopedResource && other)2425   ScopedResource& operator=(ScopedResource&& other) {
2426     reset(other.t_);
2427     other.t_ = InvalidValue;
2428     return *this;
2429   }
get() const2430   T get() const { return t_; }
operator *() const2431   T operator*() const { return t_; }
operator bool() const2432   explicit operator bool() const { return Checker::IsValid(t_); }
reset(T r=InvalidValue)2433   void reset(T r = InvalidValue) {
2434     if (Checker::IsValid(t_)) {
2435       int res = CloseFunction(t_);
2436       if (CheckClose)
2437         PERFETTO_CHECK(res == 0);
2438     }
2439     t_ = r;
2440   }
release()2441   T release() {
2442     T t = t_;
2443     t_ = InvalidValue;
2444     return t;
2445   }
~ScopedResource()2446   ~ScopedResource() { reset(InvalidValue); }
2447 
2448  private:
2449   ScopedResource(const ScopedResource&) = delete;
2450   ScopedResource& operator=(const ScopedResource&) = delete;
2451   T t_;
2452 };
2453 
2454 // Declared in file_utils.h. Forward declared to avoid #include cycles.
2455 int PERFETTO_EXPORT CloseFile(int fd);
2456 
2457 // Use this for file resources obtained via open() and similar APIs.
2458 using ScopedFile = ScopedResource<int, CloseFile, -1>;
2459 using ScopedFstream = ScopedResource<FILE*, fclose, nullptr>;
2460 
2461 // Use this for resources that are HANDLE on Windows. See comments in
2462 // platform_handle.h
2463 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
2464 using ScopedPlatformHandle = ScopedResource<PlatformHandle,
2465                                             ClosePlatformHandle,
2466                                             /*InvalidValue=*/nullptr,
2467                                             /*CheckClose=*/true,
2468                                             PlatformHandleChecker>;
2469 #else
2470 // On non-windows systems we alias ScopedPlatformHandle to ScopedFile because
2471 // they are really the same. This is to allow assignments between the two in
2472 // Linux-specific code paths that predate ScopedPlatformHandle.
2473 static_assert(std::is_same<int, PlatformHandle>::value, "");
2474 using ScopedPlatformHandle = ScopedFile;
2475 
2476 // DIR* does not exist on Windows.
2477 using ScopedDir = ScopedResource<DIR*, closedir, nullptr>;
2478 #endif
2479 
2480 }  // namespace base
2481 }  // namespace perfetto
2482 
2483 #endif  // INCLUDE_PERFETTO_EXT_BASE_SCOPED_FILE_H_
2484 /*
2485  * Copyright (C) 2018 The Android Open Source Project
2486  *
2487  * Licensed under the Apache License, Version 2.0 (the "License");
2488  * you may not use this file except in compliance with the License.
2489  * You may obtain a copy of the License at
2490  *
2491  *      http://www.apache.org/licenses/LICENSE-2.0
2492  *
2493  * Unless required by applicable law or agreed to in writing, software
2494  * distributed under the License is distributed on an "AS IS" BASIS,
2495  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2496  * See the License for the specific language governing permissions and
2497  * limitations under the License.
2498  */
2499 
2500 #ifndef INCLUDE_PERFETTO_EXT_BASE_EVENT_FD_H_
2501 #define INCLUDE_PERFETTO_EXT_BASE_EVENT_FD_H_
2502 
2503 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
2504 // gen_amalgamated expanded: #include "perfetto/base/platform_handle.h"
2505 // gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"
2506 
2507 namespace perfetto {
2508 namespace base {
2509 
2510 // A waitable event that can be used with poll/select.
2511 // This is really a wrapper around eventfd_create with a pipe-based fallback
2512 // for other platforms where eventfd is not supported.
2513 class EventFd {
2514  public:
2515   EventFd();
2516   ~EventFd();
2517   EventFd(EventFd&&) noexcept = default;
2518   EventFd& operator=(EventFd&&) = default;
2519 
2520   // The non-blocking file descriptor that can be polled to wait for the event.
fd() const2521   PlatformHandle fd() const { return event_handle_.get(); }
2522 
2523   // Can be called from any thread.
2524   void Notify();
2525 
2526   // Can be called from any thread. If more Notify() are queued a Clear() call
2527   // can clear all of them (up to 16 per call).
2528   void Clear();
2529 
2530  private:
2531   // The eventfd, when eventfd is supported, otherwise this is the read end of
2532   // the pipe for fallback mode.
2533   ScopedPlatformHandle event_handle_;
2534 
2535 #if !PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) &&   \
2536     !PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) && \
2537     !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
2538   // On Mac and other non-Linux UNIX platforms a pipe-based fallback is used.
2539   // The write end of the wakeup pipe.
2540   ScopedFile write_fd_;
2541 #endif
2542 };
2543 
2544 }  // namespace base
2545 }  // namespace perfetto
2546 
2547 #endif  // INCLUDE_PERFETTO_EXT_BASE_EVENT_FD_H_
2548 // gen_amalgamated begin header: include/perfetto/ext/base/pipe.h
2549 /*
2550  * Copyright (C) 2018 The Android Open Source Project
2551  *
2552  * Licensed under the Apache License, Version 2.0 (the "License");
2553  * you may not use this file except in compliance with the License.
2554  * You may obtain a copy of the License at
2555  *
2556  *      http://www.apache.org/licenses/LICENSE-2.0
2557  *
2558  * Unless required by applicable law or agreed to in writing, software
2559  * distributed under the License is distributed on an "AS IS" BASIS,
2560  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2561  * See the License for the specific language governing permissions and
2562  * limitations under the License.
2563  */
2564 
2565 #ifndef INCLUDE_PERFETTO_EXT_BASE_PIPE_H_
2566 #define INCLUDE_PERFETTO_EXT_BASE_PIPE_H_
2567 
2568 // gen_amalgamated expanded: #include "perfetto/base/platform_handle.h"
2569 // gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"
2570 
2571 namespace perfetto {
2572 namespace base {
2573 
2574 class Pipe {
2575  public:
2576   enum Flags {
2577     kBothBlock = 0,
2578 #if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
2579     kBothNonBlock,
2580     kRdNonBlock,
2581     kWrNonBlock,
2582 #endif
2583   };
2584 
2585   static Pipe Create(Flags = kBothBlock);
2586 
2587   Pipe();
2588   Pipe(Pipe&&) noexcept;
2589   Pipe& operator=(Pipe&&);
2590 
2591   ScopedPlatformHandle rd;
2592   ScopedPlatformHandle wr;
2593 };
2594 
2595 }  // namespace base
2596 }  // namespace perfetto
2597 
2598 #endif  // INCLUDE_PERFETTO_EXT_BASE_PIPE_H_
2599 /*
2600  * Copyright (C) 2018 The Android Open Source Project
2601  *
2602  * Licensed under the Apache License, Version 2.0 (the "License");
2603  * you may not use this file except in compliance with the License.
2604  * You may obtain a copy of the License at
2605  *
2606  *      http://www.apache.org/licenses/LICENSE-2.0
2607  *
2608  * Unless required by applicable law or agreed to in writing, software
2609  * distributed under the License is distributed on an "AS IS" BASIS,
2610  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2611  * See the License for the specific language governing permissions and
2612  * limitations under the License.
2613  */
2614 
2615 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
2616 
2617 #include <errno.h>
2618 #include <stdint.h>
2619 
2620 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
2621 #include <Windows.h>
2622 #include <synchapi.h>
2623 #elif PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
2624     PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
2625 #include <sys/eventfd.h>
2626 #include <unistd.h>
2627 #else  // Mac, Fuchsia and other non-Linux UNIXes
2628 #include <unistd.h>
2629 #endif
2630 
2631 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
2632 // gen_amalgamated expanded: #include "perfetto/ext/base/event_fd.h"
2633 // gen_amalgamated expanded: #include "perfetto/ext/base/pipe.h"
2634 // gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
2635 
2636 namespace perfetto {
2637 namespace base {
2638 
2639 EventFd::~EventFd() = default;
2640 
2641 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
EventFd()2642 EventFd::EventFd() {
2643   event_handle_.reset(
2644       CreateEventA(/*lpEventAttributes=*/nullptr, /*bManualReset=*/true,
2645                    /*bInitialState=*/false, /*bInitialState=*/nullptr));
2646 }
2647 
Notify()2648 void EventFd::Notify() {
2649   if (!SetEvent(event_handle_.get()))  // 0: fail, !0: success, unlike UNIX.
2650     PERFETTO_DFATAL("EventFd::Notify()");
2651 }
2652 
Clear()2653 void EventFd::Clear() {
2654   if (!ResetEvent(event_handle_.get()))  // 0: fail, !0: success, unlike UNIX.
2655     PERFETTO_DFATAL("EventFd::Clear()");
2656 }
2657 
2658 #elif PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
2659     PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
2660 
EventFd()2661 EventFd::EventFd() {
2662   event_handle_.reset(eventfd(/*initval=*/0, EFD_CLOEXEC | EFD_NONBLOCK));
2663   PERFETTO_CHECK(event_handle_);
2664 }
2665 
Notify()2666 void EventFd::Notify() {
2667   const uint64_t value = 1;
2668   ssize_t ret = write(event_handle_.get(), &value, sizeof(value));
2669   if (ret <= 0 && errno != EAGAIN)
2670     PERFETTO_DFATAL("EventFd::Notify()");
2671 }
2672 
Clear()2673 void EventFd::Clear() {
2674   uint64_t value;
2675   ssize_t ret = read(event_handle_.get(), &value, sizeof(value));
2676   if (ret <= 0 && errno != EAGAIN)
2677     PERFETTO_DFATAL("EventFd::Clear()");
2678 }
2679 
2680 #else
2681 
EventFd()2682 EventFd::EventFd() {
2683   // Make the pipe non-blocking so that we never block the waking thread (either
2684   // the main thread or another one) when scheduling a wake-up.
2685   Pipe pipe = Pipe::Create(Pipe::kBothNonBlock);
2686   event_handle_ = ScopedPlatformHandle(std::move(pipe.rd).release());
2687   write_fd_ = std::move(pipe.wr);
2688 }
2689 
Notify()2690 void EventFd::Notify() {
2691   const uint64_t value = 1;
2692   ssize_t ret = write(write_fd_.get(), &value, sizeof(uint8_t));
2693   if (ret <= 0 && errno != EAGAIN)
2694     PERFETTO_DFATAL("EventFd::Notify()");
2695 }
2696 
Clear()2697 void EventFd::Clear() {
2698   // Drain the byte(s) written to the wake-up pipe. We can potentially read
2699   // more than one byte if several wake-ups have been scheduled.
2700   char buffer[16];
2701   ssize_t ret = read(event_handle_.get(), &buffer[0], sizeof(buffer));
2702   if (ret <= 0 && errno != EAGAIN)
2703     PERFETTO_DFATAL("EventFd::Clear()");
2704 }
2705 #endif
2706 
2707 }  // namespace base
2708 }  // namespace perfetto
2709 // gen_amalgamated begin source: src/base/file_utils.cc
2710 // gen_amalgamated begin header: include/perfetto/ext/base/file_utils.h
2711 // gen_amalgamated begin header: include/perfetto/base/status.h
2712 /*
2713  * Copyright (C) 2019 The Android Open Source Project
2714  *
2715  * Licensed under the Apache License, Version 2.0 (the "License");
2716  * you may not use this file except in compliance with the License.
2717  * You may obtain a copy of the License at
2718  *
2719  *      http://www.apache.org/licenses/LICENSE-2.0
2720  *
2721  * Unless required by applicable law or agreed to in writing, software
2722  * distributed under the License is distributed on an "AS IS" BASIS,
2723  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2724  * See the License for the specific language governing permissions and
2725  * limitations under the License.
2726  */
2727 
2728 #ifndef INCLUDE_PERFETTO_BASE_STATUS_H_
2729 #define INCLUDE_PERFETTO_BASE_STATUS_H_
2730 
2731 #include <string>
2732 
2733 // gen_amalgamated expanded: #include "perfetto/base/compiler.h"
2734 // gen_amalgamated expanded: #include "perfetto/base/export.h"
2735 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
2736 
2737 namespace perfetto {
2738 namespace base {
2739 
2740 // Represents either the success or the failure message of a function.
2741 // This can used as the return type of functions which would usually return an
2742 // bool for success or int for errno but also wants to add some string context
2743 // (ususally for logging).
2744 class PERFETTO_EXPORT Status {
2745  public:
Status()2746   Status() : ok_(true) {}
Status(std::string msg)2747   explicit Status(std::string msg) : ok_(false), message_(std::move(msg)) {
2748     PERFETTO_CHECK(!message_.empty());
2749   }
2750 
2751   // Copy operations.
2752   Status(const Status&) = default;
2753   Status& operator=(const Status&) = default;
2754 
2755   // Move operations. The moved-from state is valid but unspecified.
2756   Status(Status&&) noexcept = default;
2757   Status& operator=(Status&&) = default;
2758 
ok() const2759   bool ok() const { return ok_; }
2760 
2761   // When ok() is false this returns the error message. Returns the empty string
2762   // otherwise.
message() const2763   const std::string& message() const { return message_; }
c_message() const2764   const char* c_message() const { return message_.c_str(); }
2765 
2766  private:
2767   bool ok_ = false;
2768   std::string message_;
2769 };
2770 
2771 // Returns a status object which represents the Ok status.
OkStatus()2772 inline Status OkStatus() {
2773   return Status();
2774 }
2775 
2776 PERFETTO_PRINTF_FORMAT(1, 2) Status ErrStatus(const char* format, ...);
2777 
2778 }  // namespace base
2779 }  // namespace perfetto
2780 
2781 #endif  // INCLUDE_PERFETTO_BASE_STATUS_H_
2782 /*
2783  * Copyright (C) 2018 The Android Open Source Project
2784  *
2785  * Licensed under the Apache License, Version 2.0 (the "License");
2786  * you may not use this file except in compliance with the License.
2787  * You may obtain a copy of the License at
2788  *
2789  *      http://www.apache.org/licenses/LICENSE-2.0
2790  *
2791  * Unless required by applicable law or agreed to in writing, software
2792  * distributed under the License is distributed on an "AS IS" BASIS,
2793  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2794  * See the License for the specific language governing permissions and
2795  * limitations under the License.
2796  */
2797 
2798 #ifndef INCLUDE_PERFETTO_EXT_BASE_FILE_UTILS_H_
2799 #define INCLUDE_PERFETTO_EXT_BASE_FILE_UTILS_H_
2800 
2801 #include <fcntl.h>  // For mode_t & O_RDONLY/RDWR. Exists also on Windows.
2802 #include <stddef.h>
2803 
2804 #include <string>
2805 #include <vector>
2806 
2807 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
2808 // gen_amalgamated expanded: #include "perfetto/base/export.h"
2809 // gen_amalgamated expanded: #include "perfetto/base/status.h"
2810 // gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"
2811 // gen_amalgamated expanded: #include "perfetto/ext/base/optional.h"
2812 // gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
2813 
2814 namespace perfetto {
2815 namespace base {
2816 
2817 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
2818 using FileOpenMode = int;
2819 #else
2820 using FileOpenMode = mode_t;
2821 #endif
2822 
2823 constexpr FileOpenMode kFileModeInvalid = static_cast<FileOpenMode>(-1);
2824 
2825 bool ReadPlatformHandle(PlatformHandle, std::string* out);
2826 bool ReadFileDescriptor(int fd, std::string* out);
2827 bool ReadFileStream(FILE* f, std::string* out);
2828 bool ReadFile(const std::string& path, std::string* out);
2829 
2830 // A wrapper around read(2). It deals with Linux vs Windows includes. It also
2831 // deals with handling EINTR. Has the same semantics of UNIX's read(2).
2832 ssize_t Read(int fd, void* dst, size_t dst_size);
2833 
2834 // Call write until all data is written or an error is detected.
2835 //
2836 // man 2 write:
2837 //   If a write() is interrupted by a signal handler before any bytes are
2838 //   written, then the call fails with the error EINTR; if it is
2839 //   interrupted after at least one byte has been written, the call
2840 //   succeeds, and returns the number of bytes written.
2841 ssize_t WriteAll(int fd, const void* buf, size_t count);
2842 
2843 ssize_t WriteAllHandle(PlatformHandle, const void* buf, size_t count);
2844 
2845 ScopedFile OpenFile(const std::string& path,
2846                     int flags,
2847                     FileOpenMode = kFileModeInvalid);
2848 
2849 // This is an alias for close(). It's to avoid leaking Windows.h in headers.
2850 // Exported because ScopedFile is used in the /include/ext API by Chromium
2851 // component builds.
2852 int PERFETTO_EXPORT CloseFile(int fd);
2853 
2854 bool FlushFile(int fd);
2855 
2856 // Returns true if mkdir succeeds, false if it fails (see errno in that case).
2857 bool Mkdir(const std::string& path);
2858 
2859 // Calls rmdir() on UNIX, _rmdir() on Windows.
2860 bool Rmdir(const std::string& path);
2861 
2862 // Wrapper around access(path, F_OK).
2863 bool FileExists(const std::string& path);
2864 
2865 // Gets the extension for a filename. If the file has two extensions, returns
2866 // only the last one (foo.pb.gz => .gz). Returns empty string if there is no
2867 // extension.
2868 std::string GetFileExtension(const std::string& filename);
2869 
2870 // Puts the path to all files under |dir_path| in |output|, recursively walking
2871 // subdirectories. File paths are relative to |dir_path|. Only files are
2872 // included, not directories. Path separator is always '/', even on windows (not
2873 // '\').
2874 base::Status ListFilesRecursive(const std::string& dir_path,
2875                                 std::vector<std::string>& output);
2876 
2877 // Returns the size of the file at `path` or nullopt in case of error.
2878 Optional<size_t> GetFileSize(const std::string& path);
2879 
2880 }  // namespace base
2881 }  // namespace perfetto
2882 
2883 #endif  // INCLUDE_PERFETTO_EXT_BASE_FILE_UTILS_H_
2884 /*
2885  * Copyright (C) 2018 The Android Open Source Project
2886  *
2887  * Licensed under the Apache License, Version 2.0 (the "License");
2888  * you may not use this file except in compliance with the License.
2889  * You may obtain a copy of the License at
2890  *
2891  *      http://www.apache.org/licenses/LICENSE-2.0
2892  *
2893  * Unless required by applicable law or agreed to in writing, software
2894  * distributed under the License is distributed on an "AS IS" BASIS,
2895  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2896  * See the License for the specific language governing permissions and
2897  * limitations under the License.
2898  */
2899 
2900 // gen_amalgamated expanded: #include "perfetto/ext/base/file_utils.h"
2901 
2902 #include <sys/stat.h>
2903 #include <sys/types.h>
2904 
2905 #include <algorithm>
2906 #include <deque>
2907 #include <string>
2908 #include <vector>
2909 
2910 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
2911 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
2912 // gen_amalgamated expanded: #include "perfetto/base/platform_handle.h"
2913 // gen_amalgamated expanded: #include "perfetto/base/status.h"
2914 // gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"
2915 // gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
2916 
2917 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
2918 #include <Windows.h>
2919 #include <direct.h>
2920 #include <io.h>
2921 #else
2922 #include <dirent.h>
2923 #include <unistd.h>
2924 #endif
2925 
2926 namespace perfetto {
2927 namespace base {
2928 namespace {
2929 constexpr size_t kBufSize = 2048;
2930 }  // namespace
2931 
Read(int fd,void * dst,size_t dst_size)2932 ssize_t Read(int fd, void* dst, size_t dst_size) {
2933 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
2934   return _read(fd, dst, static_cast<unsigned>(dst_size));
2935 #else
2936   return PERFETTO_EINTR(read(fd, dst, dst_size));
2937 #endif
2938 }
2939 
ReadFileDescriptor(int fd,std::string * out)2940 bool ReadFileDescriptor(int fd, std::string* out) {
2941   // Do not override existing data in string.
2942   size_t i = out->size();
2943 
2944   struct stat buf {};
2945   if (fstat(fd, &buf) != -1) {
2946     if (buf.st_size > 0)
2947       out->resize(i + static_cast<size_t>(buf.st_size));
2948   }
2949 
2950   ssize_t bytes_read;
2951   for (;;) {
2952     if (out->size() < i + kBufSize)
2953       out->resize(out->size() + kBufSize);
2954 
2955     bytes_read = Read(fd, &((*out)[i]), kBufSize);
2956     if (bytes_read > 0) {
2957       i += static_cast<size_t>(bytes_read);
2958     } else {
2959       out->resize(i);
2960       return bytes_read == 0;
2961     }
2962   }
2963 }
2964 
ReadPlatformHandle(PlatformHandle h,std::string * out)2965 bool ReadPlatformHandle(PlatformHandle h, std::string* out) {
2966 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
2967   // Do not override existing data in string.
2968   size_t i = out->size();
2969 
2970   for (;;) {
2971     if (out->size() < i + kBufSize)
2972       out->resize(out->size() + kBufSize);
2973     DWORD bytes_read = 0;
2974     auto res = ::ReadFile(h, &((*out)[i]), kBufSize, &bytes_read, nullptr);
2975     if (res && bytes_read > 0) {
2976       i += static_cast<size_t>(bytes_read);
2977     } else {
2978       out->resize(i);
2979       const bool is_eof = res && bytes_read == 0;
2980       auto err = res ? 0 : GetLastError();
2981       // The "Broken pipe" error on Windows is slighly different than Unix:
2982       // On Unix: a "broken pipe" error can happen only on the writer side. On
2983       // the reader there is no broken pipe, just a EOF.
2984       // On windows: the reader also sees a broken pipe error.
2985       // Here we normalize on the Unix behavior, treating broken pipe as EOF.
2986       return is_eof || err == ERROR_BROKEN_PIPE;
2987     }
2988   }
2989 #else
2990   return ReadFileDescriptor(h, out);
2991 #endif
2992 }
2993 
ReadFileStream(FILE * f,std::string * out)2994 bool ReadFileStream(FILE* f, std::string* out) {
2995   return ReadFileDescriptor(fileno(f), out);
2996 }
2997 
ReadFile(const std::string & path,std::string * out)2998 bool ReadFile(const std::string& path, std::string* out) {
2999   base::ScopedFile fd = base::OpenFile(path, O_RDONLY);
3000   if (!fd)
3001     return false;
3002 
3003   return ReadFileDescriptor(*fd, out);
3004 }
3005 
WriteAll(int fd,const void * buf,size_t count)3006 ssize_t WriteAll(int fd, const void* buf, size_t count) {
3007   size_t written = 0;
3008   while (written < count) {
3009     // write() on windows takes an unsigned int size.
3010     uint32_t bytes_left = static_cast<uint32_t>(
3011         std::min(count - written, static_cast<size_t>(UINT32_MAX)));
3012     ssize_t wr = PERFETTO_EINTR(
3013         write(fd, static_cast<const char*>(buf) + written, bytes_left));
3014     if (wr == 0)
3015       break;
3016     if (wr < 0)
3017       return wr;
3018     written += static_cast<size_t>(wr);
3019   }
3020   return static_cast<ssize_t>(written);
3021 }
3022 
WriteAllHandle(PlatformHandle h,const void * buf,size_t count)3023 ssize_t WriteAllHandle(PlatformHandle h, const void* buf, size_t count) {
3024 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
3025   DWORD wsize = 0;
3026   if (::WriteFile(h, buf, static_cast<DWORD>(count), &wsize, nullptr)) {
3027     return wsize;
3028   } else {
3029     return -1;
3030   }
3031 #else
3032   return WriteAll(h, buf, count);
3033 #endif
3034 }
3035 
FlushFile(int fd)3036 bool FlushFile(int fd) {
3037   PERFETTO_DCHECK(fd != 0);
3038 #if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
3039     PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
3040   return !PERFETTO_EINTR(fdatasync(fd));
3041 #elif PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
3042   return !PERFETTO_EINTR(_commit(fd));
3043 #else
3044   return !PERFETTO_EINTR(fsync(fd));
3045 #endif
3046 }
3047 
Mkdir(const std::string & path)3048 bool Mkdir(const std::string& path) {
3049 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
3050   return _mkdir(path.c_str()) == 0;
3051 #else
3052   return mkdir(path.c_str(), 0755) == 0;
3053 #endif
3054 }
3055 
Rmdir(const std::string & path)3056 bool Rmdir(const std::string& path) {
3057 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
3058   return _rmdir(path.c_str()) == 0;
3059 #else
3060   return rmdir(path.c_str()) == 0;
3061 #endif
3062 }
3063 
CloseFile(int fd)3064 int CloseFile(int fd) {
3065   return close(fd);
3066 }
3067 
OpenFile(const std::string & path,int flags,FileOpenMode mode)3068 ScopedFile OpenFile(const std::string& path, int flags, FileOpenMode mode) {
3069   PERFETTO_DCHECK((flags & O_CREAT) == 0 || mode != kFileModeInvalid);
3070 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
3071   // Always use O_BINARY on Windows, to avoid silly EOL translations.
3072   ScopedFile fd(_open(path.c_str(), flags | O_BINARY, mode));
3073 #else
3074   // Always open a ScopedFile with O_CLOEXEC so we can safely fork and exec.
3075   ScopedFile fd(open(path.c_str(), flags | O_CLOEXEC, mode));
3076 #endif
3077   return fd;
3078 }
3079 
FileExists(const std::string & path)3080 bool FileExists(const std::string& path) {
3081 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
3082   return _access(path.c_str(), 0) == 0;
3083 #else
3084   return access(path.c_str(), F_OK) == 0;
3085 #endif
3086 }
3087 
3088 // Declared in base/platform_handle.h.
ClosePlatformHandle(PlatformHandle handle)3089 int ClosePlatformHandle(PlatformHandle handle) {
3090 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
3091   // Make the return value UNIX-style.
3092   return CloseHandle(handle) ? 0 : -1;
3093 #else
3094   return close(handle);
3095 #endif
3096 }
3097 
ListFilesRecursive(const std::string & dir_path,std::vector<std::string> & output)3098 base::Status ListFilesRecursive(const std::string& dir_path,
3099                                 std::vector<std::string>& output) {
3100   std::string root_dir_path = dir_path;
3101   if (root_dir_path.back() == '\\') {
3102     root_dir_path.back() = '/';
3103   } else if (root_dir_path.back() != '/') {
3104     root_dir_path.push_back('/');
3105   }
3106 
3107   // dir_queue contains full paths to the directories. The paths include the
3108   // root_dir_path at the beginning and the trailing slash at the end.
3109   std::deque<std::string> dir_queue;
3110   dir_queue.push_back(root_dir_path);
3111 
3112   while (!dir_queue.empty()) {
3113     const std::string cur_dir = std::move(dir_queue.front());
3114     dir_queue.pop_front();
3115 #if PERFETTO_BUILDFLAG(PERFETTO_OS_NACL)
3116     return base::ErrStatus("ListFilesRecursive not supported yet");
3117 #elif PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
3118     std::string glob_path = cur_dir + "*";
3119     // + 1 because we also have to count the NULL terminator.
3120     if (glob_path.length() + 1 > MAX_PATH)
3121       return base::ErrStatus("Directory path %s is too long", dir_path.c_str());
3122     WIN32_FIND_DATAA ffd;
3123 
3124     base::ScopedResource<HANDLE, FindClose, nullptr, false,
3125                          base::PlatformHandleChecker>
3126         hFind(FindFirstFileA(glob_path.c_str(), &ffd));
3127     if (!hFind) {
3128       // For empty directories, there should be at least one entry '.'.
3129       // If FindFirstFileA returns INVALID_HANDLE_VALUE, this means directory
3130       // couldn't be accessed.
3131       return base::ErrStatus("Failed to open directory %s", cur_dir.c_str());
3132     }
3133     do {
3134       if (strcmp(ffd.cFileName, ".") == 0 || strcmp(ffd.cFileName, "..") == 0)
3135         continue;
3136       if (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
3137         std::string subdir_path = cur_dir + ffd.cFileName + '/';
3138         dir_queue.push_back(subdir_path);
3139       } else {
3140         const std::string full_path = cur_dir + ffd.cFileName;
3141         PERFETTO_CHECK(full_path.length() > root_dir_path.length());
3142         output.push_back(full_path.substr(root_dir_path.length()));
3143       }
3144     } while (FindNextFileA(*hFind, &ffd));
3145 #else
3146     ScopedDir dir = ScopedDir(opendir(cur_dir.c_str()));
3147     if (!dir) {
3148       return base::ErrStatus("Failed to open directory %s", cur_dir.c_str());
3149     }
3150     for (auto* dirent = readdir(dir.get()); dirent != nullptr;
3151          dirent = readdir(dir.get())) {
3152       if (strcmp(dirent->d_name, ".") == 0 ||
3153           strcmp(dirent->d_name, "..") == 0) {
3154         continue;
3155       }
3156       if (dirent->d_type == DT_DIR) {
3157         dir_queue.push_back(cur_dir + dirent->d_name + '/');
3158       } else if (dirent->d_type == DT_REG) {
3159         const std::string full_path = cur_dir + dirent->d_name;
3160         PERFETTO_CHECK(full_path.length() > root_dir_path.length());
3161         output.push_back(full_path.substr(root_dir_path.length()));
3162       }
3163     }
3164 #endif
3165   }
3166   return base::OkStatus();
3167 }
3168 
GetFileExtension(const std::string & filename)3169 std::string GetFileExtension(const std::string& filename) {
3170   auto ext_idx = filename.rfind('.');
3171   if (ext_idx == std::string::npos)
3172     return std::string();
3173   return filename.substr(ext_idx);
3174 }
3175 
GetFileSize(const std::string & file_path)3176 base::Optional<size_t> GetFileSize(const std::string& file_path) {
3177 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
3178   HANDLE file =
3179       CreateFileA(file_path.c_str(), GENERIC_READ, FILE_SHARE_READ, nullptr,
3180                   OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);
3181   if (file == INVALID_HANDLE_VALUE) {
3182     return nullopt;
3183   }
3184   LARGE_INTEGER file_size;
3185   file_size.QuadPart = 0;
3186   BOOL ok = GetFileSizeEx(file, &file_size);
3187   CloseHandle(file);
3188   if (!ok) {
3189     return nullopt;
3190   }
3191   return static_cast<size_t>(file_size.QuadPart);
3192 #else
3193   base::ScopedFile fd(base::OpenFile(file_path, O_RDONLY | O_CLOEXEC));
3194   if (!fd) {
3195     return nullopt;
3196   }
3197   struct stat buf{};
3198   if (fstat(*fd, &buf) == -1) {
3199     return nullopt;
3200   }
3201   return static_cast<size_t>(buf.st_size);
3202 #endif
3203 }
3204 
3205 }  // namespace base
3206 }  // namespace perfetto
3207 // gen_amalgamated begin source: src/base/getopt_compat.cc
3208 // gen_amalgamated begin header: include/perfetto/ext/base/getopt_compat.h
3209 /*
3210  * Copyright (C) 2021 The Android Open Source Project
3211  *
3212  * Licensed under the Apache License, Version 2.0 (the "License");
3213  * you may not use this file except in compliance with the License.
3214  * You may obtain a copy of the License at
3215  *
3216  *      http://www.apache.org/licenses/LICENSE-2.0
3217  *
3218  * Unless required by applicable law or agreed to in writing, software
3219  * distributed under the License is distributed on an "AS IS" BASIS,
3220  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
3221  * See the License for the specific language governing permissions and
3222  * limitations under the License.
3223  */
3224 
3225 #ifndef INCLUDE_PERFETTO_EXT_BASE_GETOPT_COMPAT_H_
3226 #define INCLUDE_PERFETTO_EXT_BASE_GETOPT_COMPAT_H_
3227 
3228 #include <cstddef>  // For std::nullptr_t
3229 
3230 // No translation units other than base/getopt.h and getopt_compat_unittest.cc
3231 // should directly include this file. Use base/getopt.h instead.
3232 
3233 namespace perfetto {
3234 namespace base {
3235 namespace getopt_compat {
3236 
3237 // A tiny getopt() replacement for Windows, which doesn't have <getopt.h>.
3238 // This implementation is based on the subset of features that we use in the
3239 // Perfetto codebase. It doesn't even try to deal with the full surface of GNU's
3240 // getopt().
3241 // Limitations:
3242 // - getopt_long_only() is not supported.
3243 // - optional_argument is not supported. That is extremely subtle and caused us
3244 //   problems in the past with GNU's getopt.
3245 // - It does not reorder non-option arguments. It behaves like MacOS getopt, or
3246 //   GNU's when POSIXLY_CORRECT=1.
3247 // - Doesn't expose optopt or opterr.
3248 // - option.flag and longindex are not supported and must be nullptr.
3249 
3250 enum {
3251   no_argument = 0,
3252   required_argument = 1,
3253 };
3254 
3255 struct option {
3256   const char* name;
3257   int has_arg;
3258   std::nullptr_t flag;  // Only nullptr is supported.
3259   int val;
3260 };
3261 
3262 extern char* optarg;
3263 extern int optind;
3264 extern int optopt;
3265 extern int opterr;
3266 
3267 int getopt_long(int argc,
3268                 char** argv,
3269                 const char* shortopts,
3270                 const option* longopts,
3271                 std::nullptr_t /*longindex is not supported*/);
3272 
3273 int getopt(int argc, char** argv, const char* shortopts);
3274 
3275 }  // namespace getopt_compat
3276 }  // namespace base
3277 }  // namespace perfetto
3278 
3279 #endif  // INCLUDE_PERFETTO_EXT_BASE_GETOPT_COMPAT_H_
3280 /*
3281  * Copyright (C) 2021 The Android Open Source Project
3282  *
3283  * Licensed under the Apache License, Version 2.0 (the "License");
3284  * you may not use this file except in compliance with the License.
3285  * You may obtain a copy of the License at
3286  *
3287  *      http://www.apache.org/licenses/LICENSE-2.0
3288  *
3289  * Unless required by applicable law or agreed to in writing, software
3290  * distributed under the License is distributed on an "AS IS" BASIS,
3291  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
3292  * See the License for the specific language governing permissions and
3293  * limitations under the License.
3294  */
3295 
3296 // gen_amalgamated expanded: #include "perfetto/ext/base/getopt_compat.h"
3297 
3298 #include <stdio.h>
3299 #include <stdlib.h>
3300 #include <string.h>
3301 
3302 #include <vector>
3303 
3304 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
3305 
3306 namespace perfetto {
3307 namespace base {
3308 namespace getopt_compat {
3309 
3310 char* optarg = nullptr;
3311 int optind = 0;
3312 int optopt = 0;
3313 int opterr = 1;
3314 
3315 namespace {
3316 
3317 char* nextchar = nullptr;
3318 
LookupLongOpt(const std::vector<option> & opts,const char * name,size_t len)3319 const option* LookupLongOpt(const std::vector<option>& opts,
3320                             const char* name,
3321                             size_t len) {
3322   for (const option& opt : opts) {
3323     if (strncmp(opt.name, name, len) == 0 && strlen(opt.name) == len)
3324       return &opt;
3325   }
3326   return nullptr;
3327 }
3328 
LookupShortOpt(const std::vector<option> & opts,char c)3329 const option* LookupShortOpt(const std::vector<option>& opts, char c) {
3330   for (const option& opt : opts) {
3331     if (!*opt.name && opt.val == c)
3332       return &opt;
3333   }
3334   return nullptr;
3335 }
3336 
ParseOpts(const char * shortopts,const option * longopts,std::vector<option> * res)3337 bool ParseOpts(const char* shortopts,
3338                const option* longopts,
3339                std::vector<option>* res) {
3340   // Parse long options first.
3341   for (const option* lopt = longopts; lopt && lopt->name; lopt++) {
3342     PERFETTO_CHECK(lopt->flag == nullptr);
3343     PERFETTO_CHECK(lopt->has_arg == no_argument ||
3344                    lopt->has_arg == required_argument);
3345     res->emplace_back(*lopt);
3346   }
3347 
3348   // Merge short options.
3349   for (const char* sopt = shortopts; sopt && *sopt;) {
3350     const size_t idx = static_cast<size_t>(sopt - shortopts);
3351     char c = *sopt++;
3352     bool valid = (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') ||
3353                  (c >= '0' && c <= '9');
3354     if (!valid) {
3355       fprintf(stderr,
3356               "Error parsing shortopts. Unexpected char '%c' at offset %zu\n",
3357               c, idx);
3358       return false;
3359     }
3360     res->emplace_back();
3361     option& opt = res->back();
3362     opt.name = "";
3363     opt.val = c;
3364     opt.has_arg = no_argument;
3365     if (*sopt == ':') {
3366       opt.has_arg = required_argument;
3367       ++sopt;
3368     }
3369   }
3370   return true;
3371 }
3372 
3373 }  // namespace
3374 
getopt_long(int argc,char ** argv,const char * shortopts,const option * longopts,std::nullptr_t)3375 int getopt_long(int argc,
3376                 char** argv,
3377                 const char* shortopts,
3378                 const option* longopts,
3379                 std::nullptr_t /*longind*/) {
3380   std::vector<option> opts;
3381   optarg = nullptr;
3382 
3383   if (optind == 0)
3384     optind = 1;
3385 
3386   if (optind >= argc)
3387     return -1;
3388 
3389   if (!ParseOpts(shortopts, longopts, &opts))
3390     return '?';
3391 
3392   char* arg = argv[optind];
3393   optopt = 0;
3394 
3395   if (!nextchar) {
3396     // If |nextchar| is null we are NOT in the middle of a short option and we
3397     // should parse the next argv.
3398     if (strncmp(arg, "--", 2) == 0 && strlen(arg) > 2) {
3399       // A --long option.
3400       arg += 2;
3401       char* sep = strchr(arg, '=');
3402       optind++;
3403 
3404       size_t len = sep ? static_cast<size_t>(sep - arg) : strlen(arg);
3405       const option* opt = LookupLongOpt(opts, arg, len);
3406 
3407       if (!opt) {
3408         if (opterr)
3409           fprintf(stderr, "unrecognized option '--%s'\n", arg);
3410         return '?';
3411       }
3412 
3413       optopt = opt->val;
3414       if (opt->has_arg == no_argument) {
3415         if (sep) {
3416           fprintf(stderr, "option '--%s' doesn't allow an argument\n", arg);
3417           return '?';
3418         } else {
3419           return opt->val;
3420         }
3421       } else if (opt->has_arg == required_argument) {
3422         if (sep) {
3423           optarg = sep + 1;
3424           return opt->val;
3425         } else if (optind >= argc) {
3426           if (opterr)
3427             fprintf(stderr, "option '--%s' requires an argument\n", arg);
3428           return '?';
3429         } else {
3430           optarg = argv[optind++];
3431           return opt->val;
3432         }
3433       }
3434       // has_arg must be either |no_argument| or |required_argument|. We
3435       // shoulnd't get here unless the check in ParseOpts() has a bug.
3436       PERFETTO_CHECK(false);
3437     }  // if (arg ~= "--*").
3438 
3439     if (strlen(arg) > 1 && arg[0] == '-' && arg[1] != '-') {
3440       // A sequence of short options. Parsing logic continues below.
3441       nextchar = &arg[1];
3442     }
3443   }  // if(!nextchar)
3444 
3445   if (nextchar) {
3446     // At this point either:
3447     // 1. This is the first char of a sequence of short options, and we fell
3448     //    through here from the lines above.
3449     // 2. This is the N (>1) char of a sequence of short options, and we got
3450     //    here from a new getopt() call to getopt().
3451     const char cur_char = *nextchar;
3452     PERFETTO_CHECK(cur_char != '\0');
3453 
3454     // Advance the option char in any case, before we start reasoning on them.
3455     // if we got to the end of the "-abc" sequence, increment optind so the next
3456     // getopt() call resumes from the next argv argument.
3457     if (*(++nextchar) == '\0') {
3458       nextchar = nullptr;
3459       ++optind;
3460     }
3461 
3462     const option* opt = LookupShortOpt(opts, cur_char);
3463     optopt = cur_char;
3464     if (!opt) {
3465       if (opterr)
3466         fprintf(stderr, "invalid option -- '%c'\n", cur_char);
3467       return '?';
3468     }
3469     if (opt->has_arg == no_argument) {
3470       return cur_char;
3471     } else if (opt->has_arg == required_argument) {
3472       // This is a subtle getopt behavior. Say you call `tar -fx`, there are
3473       // two cases:
3474       // 1. If 'f' is no_argument then 'x' (and anything else after) is
3475       //    interpreted as an independent argument (like `tar -f -x`).
3476       // 2. If 'f' is required_argument, than everything else after the 'f'
3477       //    is interpreted as the option argument (like `tar -f x`)
3478       if (!nextchar) {
3479         // Case 1.
3480         if (optind >= argc) {
3481           if (opterr)
3482             fprintf(stderr, "option requires an argument -- '%c'\n", cur_char);
3483           return '?';
3484         } else {
3485           optarg = argv[optind++];
3486           return cur_char;
3487         }
3488       } else {
3489         // Case 2.
3490         optarg = nextchar;
3491         nextchar = nullptr;
3492         optind++;
3493         return cur_char;
3494       }
3495     }
3496     PERFETTO_CHECK(false);
3497   }  // if (nextchar)
3498 
3499   // If we get here, we found the first non-option argument. Stop here.
3500 
3501   if (strcmp(arg, "--") == 0)
3502     optind++;
3503 
3504   return -1;
3505 }
3506 
getopt(int argc,char ** argv,const char * shortopts)3507 int getopt(int argc, char** argv, const char* shortopts) {
3508   return getopt_long(argc, argv, shortopts, nullptr, nullptr);
3509 }
3510 
3511 }  // namespace getopt_compat
3512 }  // namespace base
3513 }  // namespace perfetto
3514 // gen_amalgamated begin source: src/base/logging.cc
3515 // gen_amalgamated begin header: src/base/log_ring_buffer.h
3516 // gen_amalgamated begin header: include/perfetto/ext/base/thread_annotations.h
3517 /*
3518  * Copyright (C) 2019 The Android Open Source Project
3519  *
3520  * Licensed under the Apache License, Version 2.0 (the "License");
3521  * you may not use this file except in compliance with the License.
3522  * You may obtain a copy of the License at
3523  *
3524  *      http://www.apache.org/licenses/LICENSE-2.0
3525  *
3526  * Unless required by applicable law or agreed to in writing, software
3527  * distributed under the License is distributed on an "AS IS" BASIS,
3528  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
3529  * See the License for the specific language governing permissions and
3530  * limitations under the License.
3531  */
3532 
3533 #ifndef INCLUDE_PERFETTO_EXT_BASE_THREAD_ANNOTATIONS_H_
3534 #define INCLUDE_PERFETTO_EXT_BASE_THREAD_ANNOTATIONS_H_
3535 
3536 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
3537 
3538 // Windows TSAN doesn't currently support these annotations.
3539 #if defined(THREAD_SANITIZER) && !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
3540 extern "C" {
3541 void AnnotateBenignRaceSized(const char* file,
3542                              int line,
3543                              unsigned long address,
3544                              unsigned long size,
3545                              const char* description);
3546 }
3547 
3548 #define PERFETTO_ANNOTATE_BENIGN_RACE_SIZED(pointer, size, description)   \
3549   AnnotateBenignRaceSized(__FILE__, __LINE__,                             \
3550                           reinterpret_cast<unsigned long>(pointer), size, \
3551                           description);
3552 #else  // defined(ADDRESS_SANITIZER)
3553 #define PERFETTO_ANNOTATE_BENIGN_RACE_SIZED(pointer, size, description)
3554 #endif  // defined(ADDRESS_SANITIZER)
3555 
3556 #endif  // INCLUDE_PERFETTO_EXT_BASE_THREAD_ANNOTATIONS_H_
3557 /*
3558  * Copyright (C) 2021 The Android Open Source Project
3559  *
3560  * Licensed under the Apache License, Version 2.0 (the "License");
3561  * you may not use this file except in compliance with the License.
3562  * You may obtain a copy of the License at
3563  *
3564  *      http://www.apache.org/licenses/LICENSE-2.0
3565  *
3566  * Unless required by applicable law or agreed to in writing, software
3567  * distributed under the License is distributed on an "AS IS" BASIS,
3568  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
3569  * See the License for the specific language governing permissions and
3570  * limitations under the License.
3571  */
3572 
3573 #ifndef SRC_BASE_LOG_RING_BUFFER_H_
3574 #define SRC_BASE_LOG_RING_BUFFER_H_
3575 
3576 #include <stddef.h>
3577 #include <stdio.h>
3578 
3579 #include <array>
3580 #include <atomic>
3581 
3582 // gen_amalgamated expanded: #include "perfetto/ext/base/string_view.h"
3583 // gen_amalgamated expanded: #include "perfetto/ext/base/thread_annotations.h"
3584 
3585 namespace perfetto {
3586 namespace base {
3587 
3588 // Defined out of line because a static constexpr requires static storage if
3589 // ODR-used, not worth adding a .cc file just for tests.
3590 constexpr size_t kLogRingBufEntries = 8;
3591 constexpr size_t kLogRingBufMsgLen = 256;
3592 
3593 // A static non-allocating ring-buffer to hold the most recent log events.
3594 // This class is really an implementation detail of logging.cc. The only reason
3595 // why is fully defined in a dedicated header is for allowing unittesting,
3596 // without leaking extra headers into logging.h (which is a high-fanout header).
3597 // This is used to report the last logs in a crash report when a CHECK/FATAL
3598 // is encountered.
3599 // This class has just an Append() method to insert events into the buffer and
3600 // a Read() to read the events in FIFO order. Read() is non-destructive.
3601 //
3602 // Thread safety considerations:
3603 // - The Append() method can be called concurrently by several threads, unless
3604 //   there are > kLogRingBufEntries concurrent threads. Even if that happens,
3605 //   case some events will contain a mix of strings but the behavior of
3606 //   futher Append() and Read() is still defined.
3607 // - The Read() method is not thread safe but it's fine in practice. Even if
3608 //   it's called concurrently with other Append(), it only causes some partial
3609 //   events to be emitted in output.
3610 // In both cases, we never rely purely on \0, all operations are size-bound.
3611 //
3612 // See logging_unittest.cc for tests.
3613 class LogRingBuffer {
3614  public:
3615   LogRingBuffer() = default;
3616   LogRingBuffer(const LogRingBuffer&) = delete;
3617   LogRingBuffer& operator=(const LogRingBuffer&) = delete;
3618   LogRingBuffer(LogRingBuffer&&) = delete;
3619   LogRingBuffer& operator=(LogRingBuffer&&) = delete;
3620 
3621   // This takes three arguments because it fits its only caller (logging.cc).
3622   // The args are just concatenated together (plus one space before the msg).
Append(StringView tstamp,StringView source,StringView log_msg)3623   void Append(StringView tstamp, StringView source, StringView log_msg) {
3624     // Reserve atomically a slot in the ring buffer, so any concurrent Append()
3625     // won't overlap (unless too many concurrent Append() happen together).
3626     // There is no strict synchronization here, |event_slot_| is atomic only for
3627     // the sake of avoiding colliding on the same slot but does NOT guarantee
3628     // full consistency and integrity of the log messages written in each slot.
3629     // A release-store (or acq+rel) won't be enough for full consistency. Two
3630     // threads that race on Append() and take the N+1 and N+2 slots could finish
3631     // the write in reverse order. So Read() would need to synchronize with
3632     // something else (either a per-slot atomic flag or with a second atomic
3633     // counter which is incremented after the snprintf). Both options increase
3634     // the cost of Append() with no huge benefits (90% of the perfetto services
3635     // where we use it is single thread, and the log ring buffer is disabled
3636     // on non-standalone builds like the SDK).
3637     uint32_t slot = event_slot_.fetch_add(1, std::memory_order_relaxed);
3638     slot = slot % kLogRingBufEntries;
3639 
3640     char* const msg = events_[slot];
3641     PERFETTO_ANNOTATE_BENIGN_RACE_SIZED(msg, kLogRingBufMsgLen,
3642                                         "see comments in log_ring_buffer.h")
3643     snprintf(msg, kLogRingBufMsgLen, "%.*s%.*s %.*s",
3644              static_cast<int>(tstamp.size()), tstamp.data(),
3645              static_cast<int>(source.size()), source.data(),
3646              static_cast<int>(log_msg.size()), log_msg.data());
3647   }
3648 
3649   // Reads back the buffer in FIFO order, up to |len - 1| characters at most
3650   // (the -1 is because a NUL terminator is always appended, unless |len| == 0).
3651   // The string written in |dst| is guaranteed to be NUL-terminated, even if
3652   // |len| < buffer contents length.
3653   // Returns the number of bytes written in output, excluding the \0 terminator.
Read(char * dst,size_t len)3654   size_t Read(char* dst, size_t len) {
3655     if (len == 0)
3656       return 0;
3657     // This is a relaxed-load because we don't need to fully synchronize on the
3658     // writing path for the reasons described in the fetch_add() above.
3659     const uint32_t event_slot = event_slot_.load(std::memory_order_relaxed);
3660     size_t dst_written = 0;
3661     for (uint32_t pos = 0; pos < kLogRingBufEntries; ++pos) {
3662       const uint32_t slot = (event_slot + pos) % kLogRingBufEntries;
3663       const char* src = events_[slot];
3664       if (*src == '\0')
3665         continue;  // Empty slot. Skip.
3666       char* const wptr = dst + dst_written;
3667       // |src| might not be null terminated. This can happen if some
3668       // thread-race happened. Limit the copy length.
3669       const size_t limit = std::min(len - dst_written, kLogRingBufMsgLen);
3670       for (size_t i = 0; i < limit; ++i) {
3671         const char c = src[i];
3672         ++dst_written;
3673         if (c == '\0' || i == limit - 1) {
3674           wptr[i] = '\n';
3675           break;
3676         }
3677         // Skip non-printable ASCII characters to avoid confusing crash reports.
3678         // Note that this deliberately mangles \n. Log messages should not have
3679         // a \n in the middle and are NOT \n terminated. The trailing \n between
3680         // each line is appended by the if () branch above.
3681         const bool is_printable = c >= ' ' && c <= '~';
3682         wptr[i] = is_printable ? c : '?';
3683       }
3684     }
3685     // Ensure that the output string is null-terminated.
3686     PERFETTO_DCHECK(dst_written <= len);
3687     if (dst_written == len) {
3688       // In case of truncation we replace the last char with \0. But the return
3689       // value is the number of chars without \0, hence the --.
3690       dst[--dst_written] = '\0';
3691     } else {
3692       dst[dst_written] = '\0';
3693     }
3694     return dst_written;
3695   }
3696 
3697  private:
3698   using EventBuf = char[kLogRingBufMsgLen];
3699   EventBuf events_[kLogRingBufEntries]{};
3700 
3701   static_assert((kLogRingBufEntries & (kLogRingBufEntries - 1)) == 0,
3702                 "kLogRingBufEntries must be a power of two");
3703 
3704   // A monotonically increasing counter incremented on each event written.
3705   // It determines which of the kLogRingBufEntries indexes in |events_| should
3706   // be used next.
3707   // It grows >> kLogRingBufEntries, it's supposed to be always used
3708   // mod(kLogRingBufEntries). A static_assert in the .cc file ensures that
3709   // kLogRingBufEntries is a power of two so wraps are aligned.
3710   std::atomic<uint32_t> event_slot_{};
3711 };
3712 
3713 }  // namespace base
3714 }  // namespace perfetto
3715 
3716 #endif  // SRC_BASE_LOG_RING_BUFFER_H_
3717 /*
3718  * Copyright (C) 2019 The Android Open Source Project
3719  *
3720  * Licensed under the Apache License, Version 2.0 (the "License");
3721  * you may not use this file except in compliance with the License.
3722  * You may obtain a copy of the License at
3723  *
3724  *      http://www.apache.org/licenses/LICENSE-2.0
3725  *
3726  * Unless required by applicable law or agreed to in writing, software
3727  * distributed under the License is distributed on an "AS IS" BASIS,
3728  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
3729  * See the License for the specific language governing permissions and
3730  * limitations under the License.
3731  */
3732 
3733 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
3734 
3735 #include <stdarg.h>
3736 #include <stdio.h>
3737 
3738 #if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
3739 #include <unistd.h>  // For isatty()
3740 #endif
3741 
3742 #include <atomic>
3743 #include <memory>
3744 
3745 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
3746 // gen_amalgamated expanded: #include "perfetto/base/time.h"
3747 // gen_amalgamated expanded: #include "perfetto/ext/base/crash_keys.h"
3748 // gen_amalgamated expanded: #include "perfetto/ext/base/string_utils.h"
3749 // gen_amalgamated expanded: #include "perfetto/ext/base/string_view.h"
3750 // gen_amalgamated expanded: #include "src/base/log_ring_buffer.h"
3751 
3752 #if PERFETTO_ENABLE_LOG_RING_BUFFER() && PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
3753 #include <android/set_abort_message.h>
3754 #endif
3755 
3756 namespace perfetto {
3757 namespace base {
3758 
3759 namespace {
3760 const char kReset[] = "\x1b[0m";
3761 const char kDefault[] = "\x1b[39m";
3762 const char kDim[] = "\x1b[2m";
3763 const char kRed[] = "\x1b[31m";
3764 const char kBoldGreen[] = "\x1b[1m\x1b[32m";
3765 const char kLightGray[] = "\x1b[90m";
3766 
3767 std::atomic<LogMessageCallback> g_log_callback{};
3768 
3769 #if PERFETTO_BUILDFLAG(PERFETTO_STDERR_CRASH_DUMP)
3770 // __attribute__((constructor)) causes a static initializer that automagically
3771 // early runs this function before the main().
InitDebugCrashReporter()3772 void PERFETTO_EXPORT __attribute__((constructor)) InitDebugCrashReporter() {
3773   // This function is defined in debug_crash_stack_trace.cc.
3774   // The dynamic initializer is in logging.cc because logging.cc is included
3775   // in virtually any target that depends on base. Having it in
3776   // debug_crash_stack_trace.cc would require figuring out -Wl,whole-archive
3777   // which is not worth it.
3778   EnableStacktraceOnCrashForDebug();
3779 }
3780 #endif
3781 
3782 #if PERFETTO_ENABLE_LOG_RING_BUFFER()
3783 LogRingBuffer g_log_ring_buffer{};
3784 
3785 // This is global to avoid allocating memory or growing too much the stack
3786 // in MaybeSerializeLastLogsForCrashReporting(), which is called from
3787 // arbitrary code paths hitting PERFETTO_CHECK()/FATAL().
3788 char g_crash_buf[kLogRingBufEntries * kLogRingBufMsgLen];
3789 #endif
3790 
3791 }  // namespace
3792 
SetLogMessageCallback(LogMessageCallback callback)3793 void SetLogMessageCallback(LogMessageCallback callback) {
3794   g_log_callback.store(callback, std::memory_order_relaxed);
3795 }
3796 
LogMessage(LogLev level,const char * fname,int line,const char * fmt,...)3797 void LogMessage(LogLev level,
3798                 const char* fname,
3799                 int line,
3800                 const char* fmt,
3801                 ...) {
3802   char stack_buf[512];
3803   std::unique_ptr<char[]> large_buf;
3804   char* log_msg = &stack_buf[0];
3805   size_t log_msg_len = 0;
3806 
3807   // By default use a stack allocated buffer because most log messages are quite
3808   // short. In rare cases they can be larger (e.g. --help). In those cases we
3809   // pay the cost of allocating the buffer on the heap.
3810   for (size_t max_len = sizeof(stack_buf);;) {
3811     va_list args;
3812     va_start(args, fmt);
3813     int res = vsnprintf(log_msg, max_len, fmt, args);
3814     va_end(args);
3815 
3816     // If for any reason the print fails, overwrite the message but still print
3817     // it. The code below will attach the filename and line, which is still
3818     // useful.
3819     if (res < 0) {
3820       snprintf(log_msg, max_len, "%s", "[printf format error]");
3821       break;
3822     }
3823 
3824     // if res == max_len, vsnprintf saturated the input buffer. Retry with a
3825     // larger buffer in that case (within reasonable limits).
3826     if (res < static_cast<int>(max_len) || max_len >= 128 * 1024) {
3827       // In case of truncation vsnprintf returns the len that "would have been
3828       // written if the string was longer", not the actual chars written.
3829       log_msg_len = std::min(static_cast<size_t>(res), max_len - 1);
3830       break;
3831     }
3832     max_len *= 4;
3833     large_buf.reset(new char[max_len]);
3834     log_msg = &large_buf[0];
3835   }
3836 
3837   LogMessageCallback cb = g_log_callback.load(std::memory_order_relaxed);
3838   if (cb) {
3839     cb({level, line, fname, log_msg});
3840     return;
3841   }
3842 
3843   const char* color = kDefault;
3844   switch (level) {
3845     case kLogDebug:
3846       color = kDim;
3847       break;
3848     case kLogInfo:
3849       color = kDefault;
3850       break;
3851     case kLogImportant:
3852       color = kBoldGreen;
3853       break;
3854     case kLogError:
3855       color = kRed;
3856       break;
3857   }
3858 
3859 #if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) &&  \
3860     !PERFETTO_BUILDFLAG(PERFETTO_OS_WASM) && \
3861     !PERFETTO_BUILDFLAG(PERFETTO_CHROMIUM_BUILD)
3862   static const bool use_colors = isatty(STDERR_FILENO);
3863 #else
3864   static const bool use_colors = false;
3865 #endif
3866 
3867   // Formats file.cc:line as a space-padded fixed width string. If the file name
3868   // |fname| is too long, truncate it on the left-hand side.
3869   StackString<10> line_str("%d", line);
3870 
3871   // 24 will be the width of the file.cc:line column in the log event.
3872   static constexpr size_t kMaxNameAndLine = 24;
3873   size_t fname_len = strlen(fname);
3874   size_t fname_max = kMaxNameAndLine - line_str.len() - 2;  // 2 = ':' + '\0'.
3875   size_t fname_offset = fname_len <= fname_max ? 0 : fname_len - fname_max;
3876   StackString<kMaxNameAndLine> file_and_line(
3877       "%*s:%s", static_cast<int>(fname_max), &fname[fname_offset],
3878       line_str.c_str());
3879 
3880 #if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
3881   // Logcat has already timestamping, don't re-emit it.
3882   __android_log_print(ANDROID_LOG_DEBUG + level, "perfetto", "%s %s",
3883                       file_and_line.c_str(), log_msg);
3884 #endif
3885 
3886   // When printing on stderr, print also the timestamp. We don't really care
3887   // about the actual time. We just need some reference clock that can be used
3888   // to correlated events across differrent processses (e.g. traced and
3889   // traced_probes). The wall time % 1000 is good enough.
3890   uint32_t t_ms = static_cast<uint32_t>(GetWallTimeMs().count());
3891   uint32_t t_sec = t_ms / 1000;
3892   t_ms -= t_sec * 1000;
3893   t_sec = t_sec % 1000;
3894   StackString<32> timestamp("[%03u.%03u] ", t_sec, t_ms);
3895 
3896   if (use_colors) {
3897     fprintf(stderr, "%s%s%s%s %s%s%s\n", kLightGray, timestamp.c_str(),
3898             file_and_line.c_str(), kReset, color, log_msg, kReset);
3899   } else {
3900     fprintf(stderr, "%s%s %s\n", timestamp.c_str(), file_and_line.c_str(),
3901             log_msg);
3902   }
3903 
3904 #if PERFETTO_ENABLE_LOG_RING_BUFFER()
3905   // Append the message to the ring buffer for crash reporting postmortems.
3906   StringView timestamp_sv = timestamp.string_view();
3907   StringView file_and_line_sv = file_and_line.string_view();
3908   StringView log_msg_sv(log_msg, static_cast<size_t>(log_msg_len));
3909   g_log_ring_buffer.Append(timestamp_sv, file_and_line_sv, log_msg_sv);
3910 #else
3911   ignore_result(log_msg_len);
3912 #endif
3913 }
3914 
3915 #if PERFETTO_ENABLE_LOG_RING_BUFFER()
MaybeSerializeLastLogsForCrashReporting()3916 void MaybeSerializeLastLogsForCrashReporting() {
3917   // Keep this function minimal. This is called from the watchdog thread, often
3918   // when the system is thrashing.
3919 
3920   // This is racy because two threads could hit a CHECK/FATAL at the same time.
3921   // But if that happens we have bigger problems, not worth designing around it.
3922   // The behaviour is still defined in the race case (the string attached to
3923   // the crash report will contain a mixture of log strings).
3924   size_t wr = 0;
3925   wr += SerializeCrashKeys(&g_crash_buf[wr], sizeof(g_crash_buf) - wr);
3926   wr += g_log_ring_buffer.Read(&g_crash_buf[wr], sizeof(g_crash_buf) - wr);
3927 
3928   // Read() null-terminates the string properly. This is just to avoid UB when
3929   // two threads race on each other (T1 writes a shorter string, T2
3930   // overwrites the \0 writing a longer string. T1 continues here before T2
3931   // finishes writing the longer string with the \0 -> boom.
3932   g_crash_buf[sizeof(g_crash_buf) - 1] = '\0';
3933 
3934 #if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
3935   // android_set_abort_message() will cause debuggerd to report the message
3936   // in the tombstone and in the crash log in logcat.
3937   // NOTE: android_set_abort_message() can be called only once. This should
3938   // be called only when we are sure we are about to crash.
3939   android_set_abort_message(g_crash_buf);
3940 #else
3941   // Print out the message on stderr on Linux/Mac/Win.
3942   fputs("\n-----BEGIN PERFETTO PRE-CRASH LOG-----\n", stderr);
3943   fputs(g_crash_buf, stderr);
3944   fputs("\n-----END PERFETTO PRE-CRASH LOG-----\n", stderr);
3945 #endif
3946 }
3947 #endif  // PERFETTO_ENABLE_LOG_RING_BUFFER
3948 
3949 }  // namespace base
3950 }  // namespace perfetto
3951 // gen_amalgamated begin source: src/base/metatrace.cc
3952 // gen_amalgamated begin header: include/perfetto/ext/base/metatrace.h
3953 // gen_amalgamated begin header: include/perfetto/ext/base/metatrace_events.h
3954 /*
3955  * Copyright (C) 2019 The Android Open Source Project
3956  *
3957  * Licensed under the Apache License, Version 2.0 (the "License");
3958  * you may not use this file except in compliance with the License.
3959  * You may obtain a copy of the License at
3960  *
3961  *      http://www.apache.org/licenses/LICENSE-2.0
3962  *
3963  * Unless required by applicable law or agreed to in writing, software
3964  * distributed under the License is distributed on an "AS IS" BASIS,
3965  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
3966  * See the License for the specific language governing permissions and
3967  * limitations under the License.
3968  */
3969 
3970 #ifndef INCLUDE_PERFETTO_EXT_BASE_METATRACE_EVENTS_H_
3971 #define INCLUDE_PERFETTO_EXT_BASE_METATRACE_EVENTS_H_
3972 
3973 #include <stdint.h>
3974 
3975 namespace perfetto {
3976 namespace metatrace {
3977 
3978 enum Tags : uint32_t {
3979   TAG_NONE = 0,
3980   TAG_ANY = uint32_t(-1),
3981   TAG_FTRACE = 1 << 0,
3982   TAG_PROC_POLLERS = 1 << 1,
3983   TAG_TRACE_WRITER = 1 << 2,
3984   TAG_TRACE_SERVICE = 1 << 3,
3985   TAG_PRODUCER = 1 << 4,
3986 };
3987 
3988 // The macros below generate matching enums and arrays of string literals.
3989 // This is to avoid maintaining string maps manually.
3990 
3991 // clang-format off
3992 
3993 // DO NOT remove or reshuffle items in this list, only append. The ID of these
3994 // events are an ABI, the trace processor relies on these to open old traces.
3995 #define PERFETTO_METATRACE_EVENTS(F) \
3996   F(EVENT_ZERO_UNUSED), \
3997   F(FTRACE_CPU_READER_READ), /*unused*/ \
3998   F(FTRACE_DRAIN_CPUS), /*unused*/ \
3999   F(FTRACE_UNBLOCK_READERS), /*unused*/ \
4000   F(FTRACE_CPU_READ_NONBLOCK), /*unused*/ \
4001   F(FTRACE_CPU_READ_BLOCK), /*unused*/ \
4002   F(FTRACE_CPU_SPLICE_NONBLOCK), /*unused*/ \
4003   F(FTRACE_CPU_SPLICE_BLOCK), /*unused*/ \
4004   F(FTRACE_CPU_WAIT_CMD), /*unused*/ \
4005   F(FTRACE_CPU_RUN_CYCLE), /*unused*/ \
4006   F(FTRACE_CPU_FLUSH), \
4007   F(FTRACE_CPU_DRAIN), /*unused*/ \
4008   F(READ_SYS_STATS), \
4009   F(PS_WRITE_ALL_PROCESSES), \
4010   F(PS_ON_PIDS), \
4011   F(PS_ON_RENAME_PIDS), \
4012   F(PS_WRITE_ALL_PROCESS_STATS), \
4013   F(TRACE_WRITER_COMMIT_STARTUP_WRITER_BATCH), \
4014   F(FTRACE_READ_TICK), \
4015   F(FTRACE_CPU_READ_CYCLE), \
4016   F(FTRACE_CPU_READ_BATCH), \
4017   F(KALLSYMS_PARSE), \
4018   F(PROFILER_READ_TICK), \
4019   F(PROFILER_READ_CPU), \
4020   F(PROFILER_UNWIND_TICK), \
4021   F(PROFILER_UNWIND_SAMPLE), \
4022   F(PROFILER_UNWIND_INITIAL_ATTEMPT), \
4023   F(PROFILER_UNWIND_ATTEMPT), \
4024   F(PROFILER_MAPS_PARSE), \
4025   F(PROFILER_MAPS_REPARSE), \
4026   F(PROFILER_UNWIND_CACHE_CLEAR)
4027 
4028 // Append only, see above.
4029 //
4030 // Values that aren't used as counters:
4031 // * FTRACE_SERVICE_COMMIT_DATA is a bit-packed representation of an event, see
4032 //   tracing_service_impl.cc for the format.
4033 // * PROFILER_UNWIND_CURRENT_PID represents the PID that is being unwound.
4034 //
4035 #define PERFETTO_METATRACE_COUNTERS(F) \
4036   F(COUNTER_ZERO_UNUSED),\
4037   F(FTRACE_PAGES_DRAINED), \
4038   F(PS_PIDS_SCANNED), \
4039   F(TRACE_SERVICE_COMMIT_DATA), \
4040   F(PROFILER_UNWIND_QUEUE_SZ), \
4041   F(PROFILER_UNWIND_CURRENT_PID)
4042 
4043 // clang-format on
4044 
4045 #define PERFETTO_METATRACE_IDENTITY(name) name
4046 #define PERFETTO_METATRACE_TOSTRING(name) #name
4047 
4048 enum Events : uint16_t {
4049   PERFETTO_METATRACE_EVENTS(PERFETTO_METATRACE_IDENTITY),
4050   EVENTS_MAX
4051 };
4052 constexpr char const* kEventNames[] = {
4053     PERFETTO_METATRACE_EVENTS(PERFETTO_METATRACE_TOSTRING)};
4054 
4055 enum Counters : uint16_t {
4056   PERFETTO_METATRACE_COUNTERS(PERFETTO_METATRACE_IDENTITY),
4057   COUNTERS_MAX
4058 };
4059 constexpr char const* kCounterNames[] = {
4060     PERFETTO_METATRACE_COUNTERS(PERFETTO_METATRACE_TOSTRING)};
4061 
SuppressUnusedVarsInAmalgamatedBuild()4062 inline void SuppressUnusedVarsInAmalgamatedBuild() {
4063   (void)kCounterNames;
4064   (void)kEventNames;
4065 }
4066 
4067 }  // namespace metatrace
4068 }  // namespace perfetto
4069 
4070 #endif  // INCLUDE_PERFETTO_EXT_BASE_METATRACE_EVENTS_H_
4071 /*
4072  * Copyright (C) 2019 The Android Open Source Project
4073  *
4074  * Licensed under the Apache License, Version 2.0 (the "License");
4075  * you may not use this file except in compliance with the License.
4076  * You may obtain a copy of the License at
4077  *
4078  *      http://www.apache.org/licenses/LICENSE-2.0
4079  *
4080  * Unless required by applicable law or agreed to in writing, software
4081  * distributed under the License is distributed on an "AS IS" BASIS,
4082  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
4083  * See the License for the specific language governing permissions and
4084  * limitations under the License.
4085  */
4086 
4087 #ifndef INCLUDE_PERFETTO_EXT_BASE_METATRACE_H_
4088 #define INCLUDE_PERFETTO_EXT_BASE_METATRACE_H_
4089 
4090 #include <array>
4091 #include <atomic>
4092 #include <functional>
4093 #include <string>
4094 
4095 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
4096 // gen_amalgamated expanded: #include "perfetto/base/thread_utils.h"
4097 // gen_amalgamated expanded: #include "perfetto/base/time.h"
4098 // gen_amalgamated expanded: #include "perfetto/ext/base/metatrace_events.h"
4099 // gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
4100 
4101 // A facility to trace execution of the perfetto codebase itself.
4102 // The meta-tracing framework is organized into three layers:
4103 //
4104 // 1. A static ring-buffer in base/ (this file) that supports concurrent writes
4105 //    and a single reader.
4106 //    The responsibility of this layer is to store events and counters as
4107 //    efficiently as possible without re-entering any tracing code.
4108 //    This is really a static-storage-based ring-buffer based on a POD array.
4109 //    This layer does NOT deal with serializing the meta-trace buffer.
4110 //    It posts a task when it's half full and expects something outside of
4111 //    base/ to drain the ring-buffer and serialize it, eventually writing it
4112 //    into the trace itself, before it gets 100% full.
4113 //
4114 // 2. A class in tracing/core which takes care of serializing the meta-trace
4115 //    buffer into the trace using a TraceWriter. See metatrace_writer.h .
4116 //
4117 // 3. A data source in traced_probes that, when be enabled via the trace config,
4118 //    injects metatrace events into the trace. See metatrace_data_source.h .
4119 //
4120 // The available events and tags are defined in metatrace_events.h .
4121 
4122 namespace perfetto {
4123 
4124 namespace base {
4125 class TaskRunner;
4126 }  // namespace base
4127 
4128 namespace metatrace {
4129 
4130 // Meta-tracing is organized in "tags" that can be selectively enabled. This is
4131 // to enable meta-tracing only of one sub-system. This word has one "enabled"
4132 // bit for each tag. 0 -> meta-tracing off.
4133 extern std::atomic<uint32_t> g_enabled_tags;
4134 
4135 // Time of the Enable() call. Used as a reference for keeping delta timestmaps
4136 // in Record.
4137 extern std::atomic<uint64_t> g_enabled_timestamp;
4138 
4139 // Enables meta-tracing for one or more tags. Once enabled it will discard any
4140 // further Enable() calls and return false until disabled,
4141 // |read_task| is a closure that will be called enqueued |task_runner| when the
4142 // meta-tracing ring buffer is half full. The task is expected to read the ring
4143 // buffer using RingBuffer::GetReadIterator() and serialize the contents onto a
4144 // file or into the trace itself.
4145 // Must be called on the |task_runner| passed.
4146 // |task_runner| must have static lifetime.
4147 bool Enable(std::function<void()> read_task, base::TaskRunner*, uint32_t tags);
4148 
4149 // Disables meta-tracing.
4150 // Must be called on the same |task_runner| as Enable().
4151 void Disable();
4152 
TraceTimeNowNs()4153 inline uint64_t TraceTimeNowNs() {
4154   return static_cast<uint64_t>(base::GetBootTimeNs().count());
4155 }
4156 
4157 // Returns a relaxed view of whether metatracing is enabled for the given tag.
4158 // Useful for skipping unnecessary argument computation if metatracing is off.
IsEnabled(uint32_t tag)4159 inline bool IsEnabled(uint32_t tag) {
4160   auto enabled_tags = g_enabled_tags.load(std::memory_order_relaxed);
4161   return PERFETTO_UNLIKELY((enabled_tags & tag) != 0);
4162 }
4163 
4164 // Holds the data for a metatrace event or counter.
4165 struct Record {
4166   static constexpr uint16_t kTypeMask = 0x8000;
4167   static constexpr uint16_t kTypeCounter = 0x8000;
4168   static constexpr uint16_t kTypeEvent = 0;
4169 
timestamp_nsperfetto::metatrace::Record4170   uint64_t timestamp_ns() const {
4171     auto base_ns = g_enabled_timestamp.load(std::memory_order_relaxed);
4172     PERFETTO_DCHECK(base_ns);
4173     return base_ns + ((static_cast<uint64_t>(timestamp_ns_high) << 32) |
4174                       timestamp_ns_low);
4175   }
4176 
set_timestampperfetto::metatrace::Record4177   void set_timestamp(uint64_t ts) {
4178     auto t_start = g_enabled_timestamp.load(std::memory_order_relaxed);
4179     uint64_t diff = ts - t_start;
4180     PERFETTO_DCHECK(diff < (1ull << 48));
4181     timestamp_ns_low = static_cast<uint32_t>(diff);
4182     timestamp_ns_high = static_cast<uint16_t>(diff >> 32);
4183   }
4184 
4185   // We can't just memset() this class because on MSVC std::atomic<> is not
4186   // trivially constructible anymore. Also std::atomic<> has a deleted copy
4187   // constructor so we cant just do "*this = Record()" either.
4188   // See http://bit.ly/339Jlzd .
clearperfetto::metatrace::Record4189   void clear() {
4190     this->~Record();
4191     new (this) Record();
4192   }
4193 
4194   // This field holds the type (counter vs event) in the MSB and event ID (as
4195   // defined in metatrace_events.h) in the lowest 15 bits. It is also used also
4196   // as a linearization point: this is always written after all the other
4197   // fields with a release-store. This is so the reader can determine whether it
4198   // can safely process the other event fields after a load-acquire.
4199   std::atomic<uint16_t> type_and_id{};
4200 
4201   // Timestamp is stored as a 48-bits value diffed against g_enabled_timestamp.
4202   // This gives us 78 hours from Enabled().
4203   uint16_t timestamp_ns_high = 0;
4204   uint32_t timestamp_ns_low = 0;
4205 
4206   uint32_t thread_id = 0;
4207 
4208   union {
4209     // Only one of the two elements can be zero initialized, clang complains
4210     // about "initializing multiple members of union" otherwise.
4211     uint32_t duration_ns = 0;  // If type == event.
4212     int32_t counter_value;     // If type == counter.
4213   };
4214 };
4215 
4216 // Hold the meta-tracing data into a statically allocated array.
4217 // This class uses static storage (as opposite to being a singleton) to:
4218 // - Have the guarantee of always valid storage, so that meta-tracing can be
4219 //   safely used in any part of the codebase, including base/ itself.
4220 // - Avoid barriers that thread-safe static locals would require.
4221 class RingBuffer {
4222  public:
4223   static constexpr size_t kCapacity = 4096;  // 4096 * 16 bytes = 64K.
4224 
4225   // This iterator is not idempotent and will bump the read index in the buffer
4226   // at the end of the reads. There can be only one reader at any time.
4227   // Usage: for (auto it = RingBuffer::GetReadIterator(); it; ++it) { it->... }
4228   class ReadIterator {
4229    public:
ReadIterator(ReadIterator && other)4230     ReadIterator(ReadIterator&& other) {
4231       PERFETTO_DCHECK(other.valid_);
4232       cur_ = other.cur_;
4233       end_ = other.end_;
4234       valid_ = other.valid_;
4235       other.valid_ = false;
4236     }
4237 
~ReadIterator()4238     ~ReadIterator() {
4239       if (!valid_)
4240         return;
4241       PERFETTO_DCHECK(cur_ >= RingBuffer::rd_index_);
4242       PERFETTO_DCHECK(cur_ <= RingBuffer::wr_index_);
4243       RingBuffer::rd_index_.store(cur_, std::memory_order_release);
4244     }
4245 
operator bool() const4246     explicit operator bool() const { return cur_ < end_; }
operator ->() const4247     const Record* operator->() const { return RingBuffer::At(cur_); }
operator *() const4248     const Record& operator*() const { return *operator->(); }
4249 
4250     // This is for ++it. it++ is deliberately not supported.
operator ++()4251     ReadIterator& operator++() {
4252       PERFETTO_DCHECK(cur_ < end_);
4253       // Once a record has been read, mark it as free clearing its type_and_id,
4254       // so if we encounter it in another read iteration while being written
4255       // we know it's not fully written yet.
4256       // The memory_order_relaxed below is enough because:
4257       // - The reader is single-threaded and doesn't re-read the same records.
4258       // - Before starting a read batch, the reader has an acquire barrier on
4259       //   |rd_index_|.
4260       // - After terminating a read batch, the ~ReadIterator dtor updates the
4261       //   |rd_index_| with a release-store.
4262       // - Reader and writer are typically kCapacity/2 apart. So unless an
4263       //   overrun happens a writer won't reuse a newly released record any time
4264       //   soon. If an overrun happens, everything is busted regardless.
4265       At(cur_)->type_and_id.store(0, std::memory_order_relaxed);
4266       ++cur_;
4267       return *this;
4268     }
4269 
4270    private:
4271     friend class RingBuffer;
ReadIterator(uint64_t begin,uint64_t end)4272     ReadIterator(uint64_t begin, uint64_t end)
4273         : cur_(begin), end_(end), valid_(true) {}
4274     ReadIterator& operator=(const ReadIterator&) = delete;
4275     ReadIterator(const ReadIterator&) = delete;
4276 
4277     uint64_t cur_;
4278     uint64_t end_;
4279     bool valid_;
4280   };
4281 
At(uint64_t index)4282   static Record* At(uint64_t index) {
4283     // Doesn't really have to be pow2, but if not the compiler will emit
4284     // arithmetic operations to compute the modulo instead of a bitwise AND.
4285     static_assert(!(kCapacity & (kCapacity - 1)), "kCapacity must be pow2");
4286     PERFETTO_DCHECK(index >= rd_index_);
4287     PERFETTO_DCHECK(index <= wr_index_);
4288     return &records_[index % kCapacity];
4289   }
4290 
4291   // Must be called on the same task runner passed to Enable()
GetReadIterator()4292   static ReadIterator GetReadIterator() {
4293     PERFETTO_DCHECK(RingBuffer::IsOnValidTaskRunner());
4294     return ReadIterator(rd_index_.load(std::memory_order_acquire),
4295                         wr_index_.load(std::memory_order_acquire));
4296   }
4297 
4298   static Record* AppendNewRecord();
4299   static void Reset();
4300 
has_overruns()4301   static bool has_overruns() {
4302     return has_overruns_.load(std::memory_order_acquire);
4303   }
4304 
4305   // Can temporarily return a value >= kCapacity but is eventually consistent.
4306   // This would happen in case of overruns until threads hit the --wr_index_
4307   // in AppendNewRecord().
GetSizeForTesting()4308   static uint64_t GetSizeForTesting() {
4309     auto wr_index = wr_index_.load(std::memory_order_relaxed);
4310     auto rd_index = rd_index_.load(std::memory_order_relaxed);
4311     PERFETTO_DCHECK(wr_index >= rd_index);
4312     return wr_index - rd_index;
4313   }
4314 
4315  private:
4316   friend class ReadIterator;
4317 
4318   // Returns true if the caller is on the task runner passed to Enable().
4319   // Used only for DCHECKs.
4320   static bool IsOnValidTaskRunner();
4321 
4322   static std::array<Record, kCapacity> records_;
4323   static std::atomic<bool> read_task_queued_;
4324   static std::atomic<uint64_t> wr_index_;
4325   static std::atomic<uint64_t> rd_index_;
4326   static std::atomic<bool> has_overruns_;
4327   static Record bankruptcy_record_;  // Used in case of overruns.
4328 };
4329 
TraceCounter(uint32_t tag,uint16_t id,int32_t value)4330 inline void TraceCounter(uint32_t tag, uint16_t id, int32_t value) {
4331   // memory_order_relaxed is okay because the storage has static lifetime.
4332   // It is safe to accidentally log an event soon after disabling.
4333   auto enabled_tags = g_enabled_tags.load(std::memory_order_relaxed);
4334   if (PERFETTO_LIKELY((enabled_tags & tag) == 0))
4335     return;
4336   Record* record = RingBuffer::AppendNewRecord();
4337   record->thread_id = static_cast<uint32_t>(base::GetThreadId());
4338   record->set_timestamp(TraceTimeNowNs());
4339   record->counter_value = value;
4340   record->type_and_id.store(Record::kTypeCounter | id,
4341                             std::memory_order_release);
4342 }
4343 
4344 class ScopedEvent {
4345  public:
ScopedEvent(uint32_t tag,uint16_t event_id)4346   ScopedEvent(uint32_t tag, uint16_t event_id) {
4347     auto enabled_tags = g_enabled_tags.load(std::memory_order_relaxed);
4348     if (PERFETTO_LIKELY((enabled_tags & tag) == 0))
4349       return;
4350     event_id_ = event_id;
4351     record_ = RingBuffer::AppendNewRecord();
4352     record_->thread_id = static_cast<uint32_t>(base::GetThreadId());
4353     record_->set_timestamp(TraceTimeNowNs());
4354   }
4355 
~ScopedEvent()4356   ~ScopedEvent() {
4357     if (PERFETTO_LIKELY(!record_))
4358       return;
4359     auto now = TraceTimeNowNs();
4360     record_->duration_ns = static_cast<uint32_t>(now - record_->timestamp_ns());
4361     record_->type_and_id.store(Record::kTypeEvent | event_id_,
4362                                std::memory_order_release);
4363   }
4364 
4365  private:
4366   Record* record_ = nullptr;
4367   uint16_t event_id_ = 0;
4368   ScopedEvent(const ScopedEvent&) = delete;
4369   ScopedEvent& operator=(const ScopedEvent&) = delete;
4370 };
4371 
4372 // Boilerplate to derive a unique variable name for the event.
4373 #define PERFETTO_METATRACE_UID2(a, b) a##b
4374 #define PERFETTO_METATRACE_UID(x) PERFETTO_METATRACE_UID2(metatrace_, x)
4375 
4376 #define PERFETTO_METATRACE_SCOPED(TAG, ID)                                \
4377   ::perfetto::metatrace::ScopedEvent PERFETTO_METATRACE_UID(__COUNTER__)( \
4378       ::perfetto::metatrace::TAG, ::perfetto::metatrace::ID)
4379 
4380 #define PERFETTO_METATRACE_COUNTER(TAG, ID, VALUE)                \
4381   ::perfetto::metatrace::TraceCounter(::perfetto::metatrace::TAG, \
4382                                       ::perfetto::metatrace::ID,  \
4383                                       static_cast<int32_t>(VALUE))
4384 
4385 }  // namespace metatrace
4386 }  // namespace perfetto
4387 
4388 #endif  // INCLUDE_PERFETTO_EXT_BASE_METATRACE_H_
4389 // gen_amalgamated begin header: include/perfetto/base/task_runner.h
4390 /*
4391  * Copyright (C) 2017 The Android Open Source Project
4392  *
4393  * Licensed under the Apache License, Version 2.0 (the "License");
4394  * you may not use this file except in compliance with the License.
4395  * You may obtain a copy of the License at
4396  *
4397  *      http://www.apache.org/licenses/LICENSE-2.0
4398  *
4399  * Unless required by applicable law or agreed to in writing, software
4400  * distributed under the License is distributed on an "AS IS" BASIS,
4401  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
4402  * See the License for the specific language governing permissions and
4403  * limitations under the License.
4404  */
4405 
4406 #ifndef INCLUDE_PERFETTO_BASE_TASK_RUNNER_H_
4407 #define INCLUDE_PERFETTO_BASE_TASK_RUNNER_H_
4408 
4409 #include <stdint.h>
4410 
4411 #include <functional>
4412 
4413 // gen_amalgamated expanded: #include "perfetto/base/export.h"
4414 // gen_amalgamated expanded: #include "perfetto/base/platform_handle.h"
4415 
4416 namespace perfetto {
4417 namespace base {
4418 
4419 // A generic interface to allow the library clients to interleave the execution
4420 // of the tracing internals in their runtime environment.
4421 // The expectation is that all tasks, which are queued either via PostTask() or
4422 // AddFileDescriptorWatch(), are executed on the same sequence (either on the
4423 // same thread, or on a thread pool that gives sequencing guarantees).
4424 //
4425 // Tasks are never executed synchronously inside PostTask and there is a full
4426 // memory barrier between tasks.
4427 //
4428 // All methods of this interface can be called from any thread.
4429 class PERFETTO_EXPORT TaskRunner {
4430  public:
4431   virtual ~TaskRunner();
4432 
4433   // Schedule a task for immediate execution. Immediate tasks are always
4434   // executed in the order they are posted. Can be called from any thread.
4435   virtual void PostTask(std::function<void()>) = 0;
4436 
4437   // Schedule a task for execution after |delay_ms|. Note that there is no
4438   // strict ordering guarantee between immediate and delayed tasks. Can be
4439   // called from any thread.
4440   virtual void PostDelayedTask(std::function<void()>, uint32_t delay_ms) = 0;
4441 
4442   // Schedule a task to run when the handle becomes readable. The same handle
4443   // can only be monitored by one function. Note that this function only needs
4444   // to be implemented on platforms where the built-in ipc framework is used.
4445   // Can be called from any thread.
4446   // TODO(skyostil): Refactor this out of the shared interface.
4447   virtual void AddFileDescriptorWatch(PlatformHandle,
4448                                       std::function<void()>) = 0;
4449 
4450   // Remove a previously scheduled watch for the handle. If this is run on the
4451   // target thread of this TaskRunner, guarantees that the task registered to
4452   // this handle will not be executed after this function call.
4453   // Can be called from any thread.
4454   virtual void RemoveFileDescriptorWatch(PlatformHandle) = 0;
4455 
4456   // Checks if the current thread is the same thread where the TaskRunner's task
4457   // run. This allows single threaded task runners (like the ones used in
4458   // perfetto) to inform the caller that anything posted will run on the same
4459   // thread/sequence. This can allow some callers to skip PostTask and instead
4460   // directly execute the code. Can be called from any thread.
4461   virtual bool RunsTasksOnCurrentThread() const = 0;
4462 };
4463 
4464 }  // namespace base
4465 }  // namespace perfetto
4466 
4467 #endif  // INCLUDE_PERFETTO_BASE_TASK_RUNNER_H_
4468 /*
4469  * Copyright (C) 2018 The Android Open Source Project
4470  *
4471  * Licensed under the Apache License, Version 2.0 (the "License");
4472  * you may not use this file except in compliance with the License.
4473  * You may obtain a copy of the License at
4474  *
4475  *      http://www.apache.org/licenses/LICENSE-2.0
4476  *
4477  * Unless required by applicable law or agreed to in writing, software
4478  * distributed under the License is distributed on an "AS IS" BASIS,
4479  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
4480  * See the License for the specific language governing permissions and
4481  * limitations under the License.
4482  */
4483 
4484 // gen_amalgamated expanded: #include "perfetto/ext/base/metatrace.h"
4485 
4486 // gen_amalgamated expanded: #include "perfetto/base/compiler.h"
4487 // gen_amalgamated expanded: #include "perfetto/base/task_runner.h"
4488 // gen_amalgamated expanded: #include "perfetto/base/time.h"
4489 // gen_amalgamated expanded: #include "perfetto/ext/base/file_utils.h"
4490 // gen_amalgamated expanded: #include "perfetto/ext/base/thread_annotations.h"
4491 
4492 namespace perfetto {
4493 namespace metatrace {
4494 
4495 std::atomic<uint32_t> g_enabled_tags{0};
4496 std::atomic<uint64_t> g_enabled_timestamp{0};
4497 
4498 // static members
4499 constexpr size_t RingBuffer::kCapacity;
4500 std::array<Record, RingBuffer::kCapacity> RingBuffer::records_;
4501 std::atomic<bool> RingBuffer::read_task_queued_;
4502 std::atomic<uint64_t> RingBuffer::wr_index_;
4503 std::atomic<uint64_t> RingBuffer::rd_index_;
4504 std::atomic<bool> RingBuffer::has_overruns_;
4505 Record RingBuffer::bankruptcy_record_;
4506 
4507 constexpr uint16_t Record::kTypeMask;
4508 constexpr uint16_t Record::kTypeCounter;
4509 constexpr uint16_t Record::kTypeEvent;
4510 
4511 namespace {
4512 
4513 // std::function<> is not trivially de/constructible. This struct wraps it in a
4514 // heap-allocated struct to avoid static initializers.
4515 struct Delegate {
GetInstanceperfetto::metatrace::__anon3c415f210f11::Delegate4516   static Delegate* GetInstance() {
4517     static Delegate* instance = new Delegate();
4518     return instance;
4519   }
4520 
4521   base::TaskRunner* task_runner = nullptr;
4522   std::function<void()> read_task;
4523 };
4524 
4525 }  // namespace
4526 
Enable(std::function<void ()> read_task,base::TaskRunner * task_runner,uint32_t tags)4527 bool Enable(std::function<void()> read_task,
4528             base::TaskRunner* task_runner,
4529             uint32_t tags) {
4530   PERFETTO_DCHECK(read_task);
4531   PERFETTO_DCHECK(task_runner->RunsTasksOnCurrentThread());
4532   if (g_enabled_tags.load(std::memory_order_acquire))
4533     return false;
4534 
4535   Delegate* dg = Delegate::GetInstance();
4536   dg->task_runner = task_runner;
4537   dg->read_task = std::move(read_task);
4538   RingBuffer::Reset();
4539   g_enabled_timestamp.store(TraceTimeNowNs(), std::memory_order_relaxed);
4540   g_enabled_tags.store(tags, std::memory_order_release);
4541   return true;
4542 }
4543 
Disable()4544 void Disable() {
4545   g_enabled_tags.store(0, std::memory_order_release);
4546   Delegate* dg = Delegate::GetInstance();
4547   PERFETTO_DCHECK(!dg->task_runner ||
4548                   dg->task_runner->RunsTasksOnCurrentThread());
4549   dg->task_runner = nullptr;
4550   dg->read_task = nullptr;
4551 }
4552 
4553 // static
Reset()4554 void RingBuffer::Reset() {
4555   bankruptcy_record_.clear();
4556   for (Record& record : records_)
4557     record.clear();
4558   wr_index_ = 0;
4559   rd_index_ = 0;
4560   has_overruns_ = false;
4561   read_task_queued_ = false;
4562 }
4563 
4564 // static
AppendNewRecord()4565 Record* RingBuffer::AppendNewRecord() {
4566   auto wr_index = wr_index_.fetch_add(1, std::memory_order_acq_rel);
4567 
4568   // rd_index can only monotonically increase, we don't care if we read an
4569   // older value, we'll just hit the slow-path a bit earlier if it happens.
4570   auto rd_index = rd_index_.load(std::memory_order_relaxed);
4571 
4572   PERFETTO_DCHECK(wr_index >= rd_index);
4573   auto size = wr_index - rd_index;
4574   if (PERFETTO_LIKELY(size < kCapacity / 2))
4575     return At(wr_index);
4576 
4577   // Slow-path: Enqueue the read task and handle overruns.
4578   bool expected = false;
4579   if (RingBuffer::read_task_queued_.compare_exchange_strong(expected, true)) {
4580     Delegate* dg = Delegate::GetInstance();
4581     if (dg->task_runner) {
4582       dg->task_runner->PostTask([] {
4583         // Meta-tracing might have been disabled in the meantime.
4584         auto read_task = Delegate::GetInstance()->read_task;
4585         if (read_task)
4586           read_task();
4587         RingBuffer::read_task_queued_ = false;
4588       });
4589     }
4590   }
4591 
4592   if (PERFETTO_LIKELY(size < kCapacity))
4593     return At(wr_index);
4594 
4595   has_overruns_.store(true, std::memory_order_release);
4596   wr_index_.fetch_sub(1, std::memory_order_acq_rel);
4597 
4598   // In the case of overflows, threads will race writing on the same memory
4599   // location and TSan will rightly complain. This is fine though because nobody
4600   // will read the bankruptcy record and it's designed to contain garbage.
4601   PERFETTO_ANNOTATE_BENIGN_RACE_SIZED(&bankruptcy_record_, sizeof(Record),
4602                                       "nothing reads bankruptcy_record_")
4603   return &bankruptcy_record_;
4604 }
4605 
4606 // static
IsOnValidTaskRunner()4607 bool RingBuffer::IsOnValidTaskRunner() {
4608   auto* task_runner = Delegate::GetInstance()->task_runner;
4609   return task_runner && task_runner->RunsTasksOnCurrentThread();
4610 }
4611 
4612 }  // namespace metatrace
4613 }  // namespace perfetto
4614 // gen_amalgamated begin source: src/base/paged_memory.cc
4615 // gen_amalgamated begin header: include/perfetto/ext/base/paged_memory.h
4616 // gen_amalgamated begin header: include/perfetto/ext/base/container_annotations.h
4617 /*
4618  * Copyright (C) 2018 The Android Open Source Project
4619  *
4620  * Licensed under the Apache License, Version 2.0 (the "License");
4621  * you may not use this file except in compliance with the License.
4622  * You may obtain a copy of the License at
4623  *
4624  *      http://www.apache.org/licenses/LICENSE-2.0
4625  *
4626  * Unless required by applicable law or agreed to in writing, software
4627  * distributed under the License is distributed on an "AS IS" BASIS,
4628  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
4629  * See the License for the specific language governing permissions and
4630  * limitations under the License.
4631  */
4632 
4633 #ifndef INCLUDE_PERFETTO_EXT_BASE_CONTAINER_ANNOTATIONS_H_
4634 #define INCLUDE_PERFETTO_EXT_BASE_CONTAINER_ANNOTATIONS_H_
4635 
4636 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
4637 
4638 // Windows ASAN doesn't currently support these annotations.
4639 #if defined(ADDRESS_SANITIZER) && !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) && \
4640     !defined(ADDRESS_SANITIZER_WITHOUT_INSTRUMENTATION)
4641 
4642 #define ANNOTATE_NEW_BUFFER(buffer, capacity, new_size)                      \
4643   if (buffer) {                                                              \
4644     __sanitizer_annotate_contiguous_container(buffer, (buffer) + (capacity), \
4645                                               (buffer) + (capacity),         \
4646                                               (buffer) + (new_size));        \
4647   }
4648 #define ANNOTATE_DELETE_BUFFER(buffer, capacity, old_size)                   \
4649   if (buffer) {                                                              \
4650     __sanitizer_annotate_contiguous_container(buffer, (buffer) + (capacity), \
4651                                               (buffer) + (old_size),         \
4652                                               (buffer) + (capacity));        \
4653   }
4654 #define ANNOTATE_CHANGE_SIZE(buffer, capacity, old_size, new_size)           \
4655   if (buffer) {                                                              \
4656     __sanitizer_annotate_contiguous_container(buffer, (buffer) + (capacity), \
4657                                               (buffer) + (old_size),         \
4658                                               (buffer) + (new_size));        \
4659   }
4660 #define ANNOTATE_CHANGE_CAPACITY(buffer, old_capacity, buffer_size, \
4661                                  new_capacity)                      \
4662   ANNOTATE_DELETE_BUFFER(buffer, old_capacity, buffer_size);        \
4663   ANNOTATE_NEW_BUFFER(buffer, new_capacity, buffer_size);
4664 // Annotations require buffers to begin on an 8-byte boundary.
4665 #else  // defined(ADDRESS_SANITIZER)
4666 #define ANNOTATE_NEW_BUFFER(buffer, capacity, new_size)
4667 #define ANNOTATE_DELETE_BUFFER(buffer, capacity, old_size)
4668 #define ANNOTATE_CHANGE_SIZE(buffer, capacity, old_size, new_size)
4669 #define ANNOTATE_CHANGE_CAPACITY(buffer, old_capacity, buffer_size, \
4670                                  new_capacity)
4671 #endif  // defined(ADDRESS_SANITIZER)
4672 
4673 #endif  // INCLUDE_PERFETTO_EXT_BASE_CONTAINER_ANNOTATIONS_H_
4674 /*
4675  * Copyright (C) 2017 The Android Open Source Project
4676  *
4677  * Licensed under the Apache License, Version 2.0 (the "License");
4678  * you may not use this file except in compliance with the License.
4679  * You may obtain a copy of the License at
4680  *
4681  *      http://www.apache.org/licenses/LICENSE-2.0
4682  *
4683  * Unless required by applicable law or agreed to in writing, software
4684  * distributed under the License is distributed on an "AS IS" BASIS,
4685  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
4686  * See the License for the specific language governing permissions and
4687  * limitations under the License.
4688  */
4689 
4690 #ifndef INCLUDE_PERFETTO_EXT_BASE_PAGED_MEMORY_H_
4691 #define INCLUDE_PERFETTO_EXT_BASE_PAGED_MEMORY_H_
4692 
4693 #include <memory>
4694 
4695 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
4696 // gen_amalgamated expanded: #include "perfetto/ext/base/container_annotations.h"
4697 
4698 // We need to track the committed size on windows and when ASAN is enabled.
4699 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) || defined(ADDRESS_SANITIZER)
4700 #define TRACK_COMMITTED_SIZE() 1
4701 #else
4702 #define TRACK_COMMITTED_SIZE() 0
4703 #endif
4704 
4705 namespace perfetto {
4706 namespace base {
4707 
4708 class PagedMemory {
4709  public:
4710   // Initializes an invalid PagedMemory pointing to nullptr.
4711   PagedMemory();
4712 
4713   ~PagedMemory();
4714 
4715   PagedMemory(PagedMemory&& other) noexcept;
4716   PagedMemory& operator=(PagedMemory&& other);
4717 
4718   enum AllocationFlags {
4719     // By default, Allocate() crashes if the underlying mmap fails (e.g., if out
4720     // of virtual address space). When this flag is provided, an invalid
4721     // PagedMemory pointing to nullptr is returned in this case instead.
4722     kMayFail = 1 << 0,
4723 
4724     // By default, Allocate() commits the allocated memory immediately. When
4725     // this flag is provided, the memory virtual address space may only be
4726     // reserved and the user should call EnsureCommitted() before writing to
4727     // memory addresses.
4728     kDontCommit = 1 << 1,
4729   };
4730 
4731   // Allocates |size| bytes using mmap(MAP_ANONYMOUS). The returned memory is
4732   // guaranteed to be page-aligned and guaranteed to be zeroed.
4733   // For |flags|, see the AllocationFlags enum above.
4734   static PagedMemory Allocate(size_t size, int flags = 0);
4735 
4736   // Hint to the OS that the memory range is not needed and can be discarded.
4737   // The memory remains accessible and its contents may be retained, or they
4738   // may be zeroed. This function may be a NOP on some platforms. Returns true
4739   // if implemented.
4740   bool AdviseDontNeed(void* p, size_t size);
4741 
4742   // Ensures that at least the first |committed_size| bytes of the allocated
4743   // memory region are committed. The implementation may commit memory in larger
4744   // chunks above |committed_size|. Crashes if the memory couldn't be committed.
4745 #if TRACK_COMMITTED_SIZE()
4746   void EnsureCommitted(size_t committed_size);
4747 #else   // TRACK_COMMITTED_SIZE()
EnsureCommitted(size_t)4748   void EnsureCommitted(size_t /*committed_size*/) {}
4749 #endif  // TRACK_COMMITTED_SIZE()
4750 
Get() const4751   inline void* Get() const noexcept { return p_; }
IsValid() const4752   inline bool IsValid() const noexcept { return !!p_; }
size() const4753   inline size_t size() const noexcept { return size_; }
4754 
4755  private:
4756   PagedMemory(char* p, size_t size);
4757 
4758   PagedMemory(const PagedMemory&) = delete;
4759   // Defaulted for implementation of move constructor + assignment.
4760   PagedMemory& operator=(const PagedMemory&) = default;
4761 
4762   char* p_ = nullptr;
4763 
4764   // The size originally passed to Allocate(). The actual virtual memory
4765   // reservation will be larger due to: (i) guard pages; (ii) rounding up to
4766   // the system page size.
4767   size_t size_ = 0;
4768 
4769 #if TRACK_COMMITTED_SIZE()
4770   size_t committed_size_ = 0u;
4771 #endif  // TRACK_COMMITTED_SIZE()
4772 };
4773 
4774 }  // namespace base
4775 }  // namespace perfetto
4776 
4777 #endif  // INCLUDE_PERFETTO_EXT_BASE_PAGED_MEMORY_H_
4778 /*
4779  * Copyright (C) 2017 The Android Open Source Project
4780  *
4781  * Licensed under the Apache License, Version 2.0 (the "License");
4782  * you may not use this file except in compliance with the License.
4783  * You may obtain a copy of the License at
4784  *
4785  *      http://www.apache.org/licenses/LICENSE-2.0
4786  *
4787  * Unless required by applicable law or agreed to in writing, software
4788  * distributed under the License is distributed on an "AS IS" BASIS,
4789  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
4790  * See the License for the specific language governing permissions and
4791  * limitations under the License.
4792  */
4793 
4794 // gen_amalgamated expanded: #include "perfetto/ext/base/paged_memory.h"
4795 
4796 #include <algorithm>
4797 #include <cmath>
4798 
4799 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
4800 #include <Windows.h>
4801 #else  // PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
4802 #include <sys/mman.h>
4803 #endif  // PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
4804 
4805 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
4806 // gen_amalgamated expanded: #include "perfetto/ext/base/container_annotations.h"
4807 // gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
4808 
4809 namespace perfetto {
4810 namespace base {
4811 
4812 namespace {
4813 
4814 #if TRACK_COMMITTED_SIZE()
4815 constexpr size_t kCommitChunkSize = 4 * 1024 * 1024;  // 4MB
4816 #endif
4817 
RoundUpToSysPageSize(size_t req_size)4818 size_t RoundUpToSysPageSize(size_t req_size) {
4819   const size_t page_size = GetSysPageSize();
4820   return (req_size + page_size - 1) & ~(page_size - 1);
4821 }
4822 
GuardSize()4823 size_t GuardSize() {
4824   return GetSysPageSize();
4825 }
4826 
4827 }  // namespace
4828 
4829 // static
Allocate(size_t req_size,int flags)4830 PagedMemory PagedMemory::Allocate(size_t req_size, int flags) {
4831   size_t rounded_up_size = RoundUpToSysPageSize(req_size);
4832   PERFETTO_CHECK(rounded_up_size >= req_size);
4833   size_t outer_size = rounded_up_size + GuardSize() * 2;
4834 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
4835   void* ptr = VirtualAlloc(nullptr, outer_size, MEM_RESERVE, PAGE_NOACCESS);
4836   if (!ptr && (flags & kMayFail))
4837     return PagedMemory();
4838   PERFETTO_CHECK(ptr);
4839   char* usable_region = reinterpret_cast<char*>(ptr) + GuardSize();
4840 #else   // PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
4841   void* ptr = mmap(nullptr, outer_size, PROT_READ | PROT_WRITE,
4842                    MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
4843   if (ptr == MAP_FAILED && (flags & kMayFail))
4844     return PagedMemory();
4845   PERFETTO_CHECK(ptr && ptr != MAP_FAILED);
4846   char* usable_region = reinterpret_cast<char*>(ptr) + GuardSize();
4847   int res = mprotect(ptr, GuardSize(), PROT_NONE);
4848   res |= mprotect(usable_region + rounded_up_size, GuardSize(), PROT_NONE);
4849   PERFETTO_CHECK(res == 0);
4850 #endif  // PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
4851 
4852   auto memory = PagedMemory(usable_region, req_size);
4853 #if TRACK_COMMITTED_SIZE()
4854   size_t initial_commit = req_size;
4855   if (flags & kDontCommit)
4856     initial_commit = std::min(initial_commit, kCommitChunkSize);
4857   memory.EnsureCommitted(initial_commit);
4858 #endif  // TRACK_COMMITTED_SIZE()
4859   return memory;
4860 }
4861 
PagedMemory()4862 PagedMemory::PagedMemory() {}
4863 
4864 // clang-format off
PagedMemory(char * p,size_t size)4865 PagedMemory::PagedMemory(char* p, size_t size) : p_(p), size_(size) {
4866   ANNOTATE_NEW_BUFFER(p_, size_, committed_size_)
4867 }
4868 
PagedMemory(PagedMemory && other)4869 PagedMemory::PagedMemory(PagedMemory&& other) noexcept {
4870   *this = other;
4871   other.p_ = nullptr;
4872 }
4873 // clang-format on
4874 
operator =(PagedMemory && other)4875 PagedMemory& PagedMemory::operator=(PagedMemory&& other) {
4876   this->~PagedMemory();
4877   new (this) PagedMemory(std::move(other));
4878   return *this;
4879 }
4880 
~PagedMemory()4881 PagedMemory::~PagedMemory() {
4882   if (!p_)
4883     return;
4884   PERFETTO_CHECK(size_);
4885   char* start = p_ - GuardSize();
4886 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
4887   BOOL res = VirtualFree(start, 0, MEM_RELEASE);
4888   PERFETTO_CHECK(res != 0);
4889 #else   // PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
4890   const size_t outer_size = RoundUpToSysPageSize(size_) + GuardSize() * 2;
4891   int res = munmap(start, outer_size);
4892   PERFETTO_CHECK(res == 0);
4893 #endif  // PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
4894   ANNOTATE_DELETE_BUFFER(p_, size_, committed_size_)
4895 }
4896 
AdviseDontNeed(void * p,size_t size)4897 bool PagedMemory::AdviseDontNeed(void* p, size_t size) {
4898   PERFETTO_DCHECK(p_);
4899   PERFETTO_DCHECK(p >= p_);
4900   PERFETTO_DCHECK(static_cast<char*>(p) + size <= p_ + size_);
4901 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) || PERFETTO_BUILDFLAG(PERFETTO_OS_NACL)
4902   // Discarding pages on Windows has more CPU cost than is justified for the
4903   // possible memory savings.
4904   return false;
4905 #else   // PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) ||
4906         // PERFETTO_BUILDFLAG(PERFETTO_OS_NACL)
4907   // http://man7.org/linux/man-pages/man2/madvise.2.html
4908   int res = madvise(p, size, MADV_DONTNEED);
4909   PERFETTO_DCHECK(res == 0);
4910   return true;
4911 #endif  // PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) ||
4912         // PERFETTO_BUILDFLAG(PERFETTO_OS_NACL)
4913 }
4914 
4915 #if TRACK_COMMITTED_SIZE()
EnsureCommitted(size_t committed_size)4916 void PagedMemory::EnsureCommitted(size_t committed_size) {
4917   PERFETTO_DCHECK(committed_size > 0u);
4918   PERFETTO_DCHECK(committed_size <= size_);
4919 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
4920   if (committed_size_ >= committed_size)
4921     return;
4922   // Rounding up.
4923   size_t delta = committed_size - committed_size_;
4924   size_t num_additional_chunks =
4925       (delta + kCommitChunkSize - 1) / kCommitChunkSize;
4926   PERFETTO_DCHECK(num_additional_chunks * kCommitChunkSize >= delta);
4927   // Don't commit more than the total size.
4928   size_t commit_size = std::min(num_additional_chunks * kCommitChunkSize,
4929                                 size_ - committed_size_);
4930   void* res = VirtualAlloc(p_ + committed_size_, commit_size, MEM_COMMIT,
4931                            PAGE_READWRITE);
4932   PERFETTO_CHECK(res);
4933   ANNOTATE_CHANGE_SIZE(p_, size_, committed_size_,
4934                        committed_size_ + commit_size)
4935   committed_size_ += commit_size;
4936 #else   // PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
4937   // mmap commits automatically as needed, so we only track here for ASAN.
4938   committed_size = std::max(committed_size_, committed_size);
4939   ANNOTATE_CHANGE_SIZE(p_, size_, committed_size_, committed_size)
4940   committed_size_ = committed_size;
4941 #endif  // PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
4942 }
4943 #endif  // TRACK_COMMITTED_SIZE()
4944 
4945 }  // namespace base
4946 }  // namespace perfetto
4947 // gen_amalgamated begin source: src/base/periodic_task.cc
4948 // gen_amalgamated begin header: include/perfetto/ext/base/periodic_task.h
4949 // gen_amalgamated begin header: include/perfetto/ext/base/thread_checker.h
4950 /*
4951  * Copyright (C) 2017 The Android Open Source Project
4952  *
4953  * Licensed under the Apache License, Version 2.0 (the "License");
4954  * you may not use this file except in compliance with the License.
4955  * You may obtain a copy of the License at
4956  *
4957  *      http://www.apache.org/licenses/LICENSE-2.0
4958  *
4959  * Unless required by applicable law or agreed to in writing, software
4960  * distributed under the License is distributed on an "AS IS" BASIS,
4961  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
4962  * See the License for the specific language governing permissions and
4963  * limitations under the License.
4964  */
4965 
4966 #ifndef INCLUDE_PERFETTO_EXT_BASE_THREAD_CHECKER_H_
4967 #define INCLUDE_PERFETTO_EXT_BASE_THREAD_CHECKER_H_
4968 
4969 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
4970 
4971 #if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
4972 #include <pthread.h>
4973 #endif
4974 #include <atomic>
4975 
4976 // gen_amalgamated expanded: #include "perfetto/base/export.h"
4977 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
4978 // gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
4979 
4980 namespace perfetto {
4981 namespace base {
4982 
4983 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
4984 using ThreadID = unsigned long;
4985 #else
4986 using ThreadID = pthread_t;
4987 #endif
4988 
4989 class PERFETTO_EXPORT ThreadChecker {
4990  public:
4991   ThreadChecker();
4992   ~ThreadChecker();
4993   ThreadChecker(const ThreadChecker&);
4994   ThreadChecker& operator=(const ThreadChecker&);
4995   bool CalledOnValidThread() const PERFETTO_WARN_UNUSED_RESULT;
4996   void DetachFromThread();
4997 
4998  private:
4999   mutable std::atomic<ThreadID> thread_id_;
5000 };
5001 
5002 #if PERFETTO_DCHECK_IS_ON() && !PERFETTO_BUILDFLAG(PERFETTO_CHROMIUM_BUILD)
5003 // TODO(primiano) Use Chromium's thread checker in Chromium.
5004 #define PERFETTO_THREAD_CHECKER(name) base::ThreadChecker name;
5005 #define PERFETTO_DCHECK_THREAD(name) \
5006   PERFETTO_DCHECK((name).CalledOnValidThread())
5007 #define PERFETTO_DETACH_FROM_THREAD(name) (name).DetachFromThread()
5008 #else
5009 #define PERFETTO_THREAD_CHECKER(name)
5010 #define PERFETTO_DCHECK_THREAD(name)
5011 #define PERFETTO_DETACH_FROM_THREAD(name)
5012 #endif  // PERFETTO_DCHECK_IS_ON()
5013 
5014 }  // namespace base
5015 }  // namespace perfetto
5016 
5017 #endif  // INCLUDE_PERFETTO_EXT_BASE_THREAD_CHECKER_H_
5018 // gen_amalgamated begin header: include/perfetto/ext/base/weak_ptr.h
5019 /*
5020  * Copyright (C) 2017 The Android Open Source Project
5021  *
5022  * Licensed under the Apache License, Version 2.0 (the "License");
5023  * you may not use this file except in compliance with the License.
5024  * You may obtain a copy of the License at
5025  *
5026  *      http://www.apache.org/licenses/LICENSE-2.0
5027  *
5028  * Unless required by applicable law or agreed to in writing, software
5029  * distributed under the License is distributed on an "AS IS" BASIS,
5030  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
5031  * See the License for the specific language governing permissions and
5032  * limitations under the License.
5033  */
5034 
5035 #ifndef INCLUDE_PERFETTO_EXT_BASE_WEAK_PTR_H_
5036 #define INCLUDE_PERFETTO_EXT_BASE_WEAK_PTR_H_
5037 
5038 // gen_amalgamated expanded: #include "perfetto/ext/base/thread_checker.h"
5039 
5040 #include <memory>
5041 
5042 namespace perfetto {
5043 namespace base {
5044 
5045 // A simple WeakPtr for single-threaded cases.
5046 // Generally keep the WeakPtrFactory as last fields in classes: it makes the
5047 // WeakPtr(s) invalidate as first thing in the class dtor.
5048 // Usage:
5049 // class MyClass {
5050 //  MyClass() : weak_factory_(this) {}
5051 //  WeakPtr<MyClass> GetWeakPtr() { return weak_factory_.GetWeakPtr(); }
5052 //
5053 // private:
5054 //  WeakPtrFactory<MyClass> weak_factory_;
5055 // }
5056 //
5057 // int main() {
5058 //  std::unique_ptr<MyClass> foo(new MyClass);
5059 //  auto wptr = foo.GetWeakPtr();
5060 //  ASSERT_TRUE(wptr);
5061 //  ASSERT_EQ(foo.get(), wptr->get());
5062 //  foo.reset();
5063 //  ASSERT_FALSE(wptr);
5064 //  ASSERT_EQ(nullptr, wptr->get());
5065 // }
5066 
5067 template <typename T>
5068 class WeakPtrFactory;  // Forward declaration, defined below.
5069 
5070 template <typename T>
5071 class WeakPtr {
5072  public:
WeakPtr()5073   WeakPtr() {}
5074   WeakPtr(const WeakPtr&) = default;
5075   WeakPtr& operator=(const WeakPtr&) = default;
5076   WeakPtr(WeakPtr&&) = default;
5077   WeakPtr& operator=(WeakPtr&&) = default;
5078 
get() const5079   T* get() const {
5080     PERFETTO_DCHECK_THREAD(thread_checker);
5081     return handle_ ? *handle_.get() : nullptr;
5082   }
operator ->() const5083   T* operator->() const { return get(); }
operator *() const5084   T& operator*() const { return *get(); }
5085 
operator bool() const5086   explicit operator bool() const { return !!get(); }
5087 
5088  private:
5089   friend class WeakPtrFactory<T>;
WeakPtr(const std::shared_ptr<T * > & handle)5090   explicit WeakPtr(const std::shared_ptr<T*>& handle) : handle_(handle) {}
5091 
5092   std::shared_ptr<T*> handle_;
5093   PERFETTO_THREAD_CHECKER(thread_checker)
5094 };
5095 
5096 template <typename T>
5097 class WeakPtrFactory {
5098  public:
WeakPtrFactory(T * owner)5099   explicit WeakPtrFactory(T* owner)
5100       : weak_ptr_(std::shared_ptr<T*>(new T* {owner})) {
5101     PERFETTO_DCHECK_THREAD(thread_checker);
5102   }
5103 
~WeakPtrFactory()5104   ~WeakPtrFactory() {
5105     PERFETTO_DCHECK_THREAD(thread_checker);
5106     *(weak_ptr_.handle_.get()) = nullptr;
5107   }
5108 
5109   // Can be safely called on any thread, since it simply copies |weak_ptr_|.
5110   // Note that any accesses to the returned pointer need to be made on the
5111   // thread that created/reset the factory.
GetWeakPtr() const5112   WeakPtr<T> GetWeakPtr() const { return weak_ptr_; }
5113 
5114   // Reset the factory to a new owner & thread. May only be called before any
5115   // weak pointers were passed out. Future weak pointers will be valid on the
5116   // calling thread.
Reset(T * owner)5117   void Reset(T* owner) {
5118     // Reset thread checker to current thread.
5119     PERFETTO_DETACH_FROM_THREAD(thread_checker);
5120     PERFETTO_DCHECK_THREAD(thread_checker);
5121 
5122     // We should not have passed out any weak pointers yet at this point.
5123     PERFETTO_DCHECK(weak_ptr_.handle_.use_count() == 1);
5124 
5125     weak_ptr_ = WeakPtr<T>(std::shared_ptr<T*>(new T* {owner}));
5126   }
5127 
5128  private:
5129   WeakPtrFactory(const WeakPtrFactory&) = delete;
5130   WeakPtrFactory& operator=(const WeakPtrFactory&) = delete;
5131 
5132   WeakPtr<T> weak_ptr_;
5133   PERFETTO_THREAD_CHECKER(thread_checker)
5134 };
5135 
5136 }  // namespace base
5137 }  // namespace perfetto
5138 
5139 #endif  // INCLUDE_PERFETTO_EXT_BASE_WEAK_PTR_H_
5140 /*
5141  * Copyright (C) 2021 The Android Open Source Project
5142  *
5143  * Licensed under the Apache License, Version 2.0 (the "License");
5144  * you may not use this file except in compliance with the License.
5145  * You may obtain a copy of the License at
5146  *
5147  *      http://www.apache.org/licenses/LICENSE-2.0
5148  *
5149  * Unless required by applicable law or agreed to in writing, software
5150  * distributed under the License is distributed on an "AS IS" BASIS,
5151  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
5152  * See the License for the specific language governing permissions and
5153  * limitations under the License.
5154  */
5155 
5156 #ifndef INCLUDE_PERFETTO_EXT_BASE_PERIODIC_TASK_H_
5157 #define INCLUDE_PERFETTO_EXT_BASE_PERIODIC_TASK_H_
5158 
5159 #include <functional>
5160 
5161 // gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"
5162 // gen_amalgamated expanded: #include "perfetto/ext/base/thread_checker.h"
5163 // gen_amalgamated expanded: #include "perfetto/ext/base/weak_ptr.h"
5164 
5165 namespace perfetto {
5166 namespace base {
5167 
5168 class TaskRunner;
5169 
5170 // A periodic task utility class. It wraps the logic necessary to do periodic
5171 // tasks using a TaskRunner, taking care of subtleties like ensuring that
5172 // outstanding tasks are cancelled after reset/dtor.
5173 // Tasks are aligned on wall time, this is to ensure that when using multiple
5174 // periodic tasks, they happen at the same time, minimizing wakeups.
5175 // On Linux/Android it also supports suspend-aware mode (via timerfd). On other
5176 // operating systems it falls back to PostDelayedTask, which is not
5177 // suspend-aware.
5178 // TODO(primiano): this should probably become a periodic timer scheduler, so we
5179 // can use one FD for everything rather than one FD per task. For now we take
5180 // the hit of a FD-per-task to keep this low-risk.
5181 class PeriodicTask {
5182  public:
5183   explicit PeriodicTask(base::TaskRunner*);
5184   ~PeriodicTask();  // Calls Reset().
5185 
5186   struct Args {
5187     uint32_t period_ms = 0;
5188     std::function<void()> task = nullptr;
5189     bool start_first_task_immediately = false;
5190     bool use_suspend_aware_timer = false;
5191   };
5192 
5193   void Start(Args);
5194 
5195   // Safe to be called multiple times, even without calling Start():
5196   void Reset();
5197 
5198   // No copy or move. WeakPtr-wrapped pointers to |this| are posted on the
5199   // task runner, this class is not easily movable.
5200   PeriodicTask(const PeriodicTask&) = delete;
5201   PeriodicTask& operator=(const PeriodicTask&) = delete;
5202   PeriodicTask(PeriodicTask&&) = delete;
5203   PeriodicTask& operator=(PeriodicTask&&) = delete;
5204 
timer_fd_for_testing()5205   base::PlatformHandle timer_fd_for_testing() { return *timer_fd_; }
5206 
5207  private:
5208   static void RunTaskAndPostNext(base::WeakPtr<PeriodicTask>,
5209                                  uint32_t generation);
5210   void PostNextTask();
5211   void ResetTimerFd();
5212 
5213   base::TaskRunner* const task_runner_;
5214   Args args_;
5215   uint32_t generation_ = 0;
5216   base::ScopedPlatformHandle timer_fd_;
5217 
5218   PERFETTO_THREAD_CHECKER(thread_checker_)
5219   base::WeakPtrFactory<PeriodicTask> weak_ptr_factory_;  // Keep last.
5220 };
5221 
5222 }  // namespace base
5223 }  // namespace perfetto
5224 
5225 #endif  // INCLUDE_PERFETTO_EXT_BASE_PERIODIC_TASK_H_
5226 /*
5227  * Copyright (C) 2021 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/periodic_task.h"
5243 
5244 #include <limits>
5245 
5246 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
5247 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
5248 // gen_amalgamated expanded: #include "perfetto/base/task_runner.h"
5249 // gen_amalgamated expanded: #include "perfetto/base/time.h"
5250 // gen_amalgamated expanded: #include "perfetto/ext/base/file_utils.h"
5251 
5252 #if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
5253     (PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) && __ANDROID_API__ >= 19)
5254 #include <sys/timerfd.h>
5255 #endif
5256 
5257 namespace perfetto {
5258 namespace base {
5259 
5260 namespace {
CreateTimerFd(uint32_t period_ms)5261 base::ScopedPlatformHandle CreateTimerFd(uint32_t period_ms) {
5262 #if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
5263     (PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) && __ANDROID_API__ >= 19)
5264   base::ScopedPlatformHandle tfd(
5265       timerfd_create(CLOCK_BOOTTIME, TFD_CLOEXEC | TFD_NONBLOCK));
5266   // The initial phase, aligned on wall clock.
5267   uint32_t phase_ms =
5268       period_ms -
5269       static_cast<uint32_t>(base::GetBootTimeNs().count() % period_ms);
5270   struct itimerspec its {};
5271   // The "1 +" is to make sure that we never pass a zero it_value in the
5272   // unlikely case of phase_ms being 0. That would cause the timer to be
5273   // considered disarmed by timerfd_settime.
5274   its.it_value.tv_sec = static_cast<time_t>(phase_ms / 1000u);
5275   its.it_value.tv_nsec = 1 + static_cast<long>((phase_ms % 1000u) * 1000000u);
5276   its.it_interval.tv_sec = static_cast<time_t>(period_ms / 1000u);
5277   its.it_interval.tv_nsec = static_cast<long>((period_ms % 1000u) * 1000000u);
5278   if (timerfd_settime(*tfd, 0, &its, nullptr) < 0)
5279     return base::ScopedPlatformHandle();
5280   return tfd;
5281 #else
5282   base::ignore_result(period_ms);
5283   return base::ScopedPlatformHandle();
5284 #endif
5285 }
5286 }  // namespace
5287 
PeriodicTask(base::TaskRunner * task_runner)5288 PeriodicTask::PeriodicTask(base::TaskRunner* task_runner)
5289     : task_runner_(task_runner), weak_ptr_factory_(this) {}
5290 
~PeriodicTask()5291 PeriodicTask::~PeriodicTask() {
5292   Reset();
5293 }
5294 
Start(Args args)5295 void PeriodicTask::Start(Args args) {
5296   PERFETTO_DCHECK_THREAD(thread_checker_);
5297   Reset();
5298   if (args.period_ms == 0 || !args.task) {
5299     PERFETTO_DCHECK(args.period_ms > 0);
5300     PERFETTO_DCHECK(args.task);
5301     return;
5302   }
5303   args_ = std::move(args);
5304   if (args_.use_suspend_aware_timer) {
5305     timer_fd_ = CreateTimerFd(args_.period_ms);
5306     if (timer_fd_) {
5307       auto weak_this = weak_ptr_factory_.GetWeakPtr();
5308       task_runner_->AddFileDescriptorWatch(
5309           *timer_fd_,
5310           std::bind(PeriodicTask::RunTaskAndPostNext, weak_this, generation_));
5311     } else {
5312       PERFETTO_DPLOG("timerfd not supported, falling back on PostDelayedTask");
5313     }
5314   }  // if (use_suspend_aware_timer).
5315 
5316   if (!timer_fd_)
5317     PostNextTask();
5318 
5319   if (args_.start_first_task_immediately)
5320     args_.task();
5321 }
5322 
PostNextTask()5323 void PeriodicTask::PostNextTask() {
5324   PERFETTO_DCHECK_THREAD(thread_checker_);
5325   PERFETTO_DCHECK(args_.period_ms > 0);
5326   PERFETTO_DCHECK(!timer_fd_);
5327   uint32_t delay_ms =
5328       args_.period_ms -
5329       static_cast<uint32_t>(base::GetWallTimeMs().count() % args_.period_ms);
5330   auto weak_this = weak_ptr_factory_.GetWeakPtr();
5331   task_runner_->PostDelayedTask(
5332       std::bind(PeriodicTask::RunTaskAndPostNext, weak_this, generation_),
5333       delay_ms);
5334 }
5335 
5336 // static
5337 // This function can be called in two ways (both from the TaskRunner):
5338 // 1. When using a timerfd, this task is registered as a FD watch.
5339 // 2. When using PostDelayedTask, this is the task posted on the TaskRunner.
RunTaskAndPostNext(base::WeakPtr<PeriodicTask> thiz,uint32_t generation)5340 void PeriodicTask::RunTaskAndPostNext(base::WeakPtr<PeriodicTask> thiz,
5341                                       uint32_t generation) {
5342   if (!thiz || !thiz->args_.task || generation != thiz->generation_)
5343     return;  // Destroyed or Reset() in the meanwhile.
5344   PERFETTO_DCHECK_THREAD(thiz->thread_checker_);
5345   if (thiz->timer_fd_) {
5346 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
5347     PERFETTO_FATAL("timerfd for periodic tasks unsupported on Windows");
5348 #else
5349     // If we are using a timerfd there is no need to repeatedly call
5350     // PostDelayedTask(). The kernel will wakeup the timer fd periodically. We
5351     // just need to read() it.
5352     uint64_t ignored = 0;
5353     errno = 0;
5354     auto rsize = base::Read(*thiz->timer_fd_, &ignored, sizeof(&ignored));
5355     if (rsize != sizeof(uint64_t)) {
5356       if (errno == EAGAIN)
5357         return;  // A spurious wakeup. Rare, but can happen, just ignore.
5358       PERFETTO_PLOG("read(timerfd) failed, falling back on PostDelayedTask");
5359       thiz->ResetTimerFd();
5360     }
5361 #endif
5362   }
5363   // The repetition of the if() is to deal with the ResetTimerFd() case above.
5364   if (!thiz->timer_fd_) {
5365     thiz->PostNextTask();
5366   }
5367   // Create a copy of the task in the unlikely event that the task ends up
5368   // up destroying the PeriodicTask object or calling Reset() on it. That would
5369   // cause a reset of the args_.task itself, which would invalidate the task
5370   // bind state while we are invoking it.
5371   auto task = thiz->args_.task;
5372   task();
5373 }
5374 
Reset()5375 void PeriodicTask::Reset() {
5376   PERFETTO_DCHECK_THREAD(thread_checker_);
5377   ++generation_;
5378   args_ = Args();
5379   PERFETTO_DCHECK(!args_.task);
5380   ResetTimerFd();
5381 }
5382 
ResetTimerFd()5383 void PeriodicTask::ResetTimerFd() {
5384   if (!timer_fd_)
5385     return;
5386   task_runner_->RemoveFileDescriptorWatch(*timer_fd_);
5387   timer_fd_.reset();
5388 }
5389 
5390 }  // namespace base
5391 }  // namespace perfetto
5392 // gen_amalgamated begin source: src/base/pipe.cc
5393 /*
5394  * Copyright (C) 2018 The Android Open Source Project
5395  *
5396  * Licensed under the Apache License, Version 2.0 (the "License");
5397  * you may not use this file except in compliance with the License.
5398  * You may obtain a copy of the License at
5399  *
5400  *      http://www.apache.org/licenses/LICENSE-2.0
5401  *
5402  * Unless required by applicable law or agreed to in writing, software
5403  * distributed under the License is distributed on an "AS IS" BASIS,
5404  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
5405  * See the License for the specific language governing permissions and
5406  * limitations under the License.
5407  */
5408 
5409 // gen_amalgamated expanded: #include "perfetto/ext/base/pipe.h"
5410 
5411 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
5412 
5413 #include <fcntl.h>  // For O_BINARY (Windows) and F_SETxx (UNIX)
5414 
5415 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
5416 #include <Windows.h>
5417 #include <namedpipeapi.h>
5418 #else
5419 #include <sys/types.h>
5420 #include <unistd.h>
5421 #endif
5422 
5423 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
5424 
5425 namespace perfetto {
5426 namespace base {
5427 
5428 Pipe::Pipe() = default;
5429 Pipe::Pipe(Pipe&&) noexcept = default;
5430 Pipe& Pipe::operator=(Pipe&&) = default;
5431 
Create(Flags flags)5432 Pipe Pipe::Create(Flags flags) {
5433   PlatformHandle fds[2];
5434 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
5435   PERFETTO_CHECK(::CreatePipe(&fds[0], &fds[1], /*lpPipeAttributes=*/nullptr,
5436                               0 /*default size*/));
5437 #else
5438   PERFETTO_CHECK(pipe(fds) == 0);
5439   PERFETTO_CHECK(fcntl(fds[0], F_SETFD, FD_CLOEXEC) == 0);
5440   PERFETTO_CHECK(fcntl(fds[1], F_SETFD, FD_CLOEXEC) == 0);
5441 #endif
5442   Pipe p;
5443   p.rd.reset(fds[0]);
5444   p.wr.reset(fds[1]);
5445 
5446 #if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
5447   if (flags == kBothNonBlock || flags == kRdNonBlock) {
5448     int cur_flags = fcntl(*p.rd, F_GETFL, 0);
5449     PERFETTO_CHECK(cur_flags >= 0);
5450     PERFETTO_CHECK(fcntl(*p.rd, F_SETFL, cur_flags | O_NONBLOCK) == 0);
5451   }
5452 
5453   if (flags == kBothNonBlock || flags == kWrNonBlock) {
5454     int cur_flags = fcntl(*p.wr, F_GETFL, 0);
5455     PERFETTO_CHECK(cur_flags >= 0);
5456     PERFETTO_CHECK(fcntl(*p.wr, F_SETFL, cur_flags | O_NONBLOCK) == 0);
5457   }
5458 #else
5459   PERFETTO_CHECK(flags == kBothBlock);
5460 #endif
5461   return p;
5462 }
5463 
5464 }  // namespace base
5465 }  // namespace perfetto
5466 // gen_amalgamated begin source: src/base/status.cc
5467 /*
5468  * Copyright (C) 2020 The Android Open Source Project
5469  *
5470  * Licensed under the Apache License, Version 2.0 (the "License");
5471  * you may not use this file except in compliance with the License.
5472  * You may obtain a copy of the License at
5473  *
5474  *      http://www.apache.org/licenses/LICENSE-2.0
5475  *
5476  * Unless required by applicable law or agreed to in writing, software
5477  * distributed under the License is distributed on an "AS IS" BASIS,
5478  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
5479  * See the License for the specific language governing permissions and
5480  * limitations under the License.
5481  */
5482 
5483 // gen_amalgamated expanded: #include "perfetto/base/status.h"
5484 
5485 #include <stdarg.h>
5486 
5487 namespace perfetto {
5488 namespace base {
5489 
ErrStatus(const char * format,...)5490 Status ErrStatus(const char* format, ...) {
5491   char buffer[1024];
5492   va_list ap;
5493   va_start(ap, format);
5494   vsnprintf(buffer, sizeof(buffer), format, ap);
5495   va_end(ap);
5496   Status status(buffer);
5497   return status;
5498 }
5499 
5500 }  // namespace base
5501 }  // namespace perfetto
5502 // gen_amalgamated begin source: src/base/string_splitter.cc
5503 // gen_amalgamated begin header: include/perfetto/ext/base/string_splitter.h
5504 /*
5505  * Copyright (C) 2018 The Android Open Source Project
5506  *
5507  * Licensed under the Apache License, Version 2.0 (the "License");
5508  * you may not use this file except in compliance with the License.
5509  * You may obtain a copy of the License at
5510  *
5511  *      http://www.apache.org/licenses/LICENSE-2.0
5512  *
5513  * Unless required by applicable law or agreed to in writing, software
5514  * distributed under the License is distributed on an "AS IS" BASIS,
5515  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
5516  * See the License for the specific language governing permissions and
5517  * limitations under the License.
5518  */
5519 
5520 #ifndef INCLUDE_PERFETTO_EXT_BASE_STRING_SPLITTER_H_
5521 #define INCLUDE_PERFETTO_EXT_BASE_STRING_SPLITTER_H_
5522 
5523 #include <string>
5524 
5525 namespace perfetto {
5526 namespace base {
5527 
5528 // C++ version of strtok(). Splits a string without making copies or any heap
5529 // allocations. Destructs the original string passed in input.
5530 // Supports the special case of using \0 as a delimiter.
5531 // The token returned in output are valid as long as the input string is valid.
5532 class StringSplitter {
5533  public:
5534   // Can take ownership of the string if passed via std::move(), e.g.:
5535   // StringSplitter(std::move(str), '\n');
5536   StringSplitter(std::string, char delimiter);
5537 
5538   // Splits a C-string. The input string will be forcefully null-terminated (so
5539   // str[size - 1] should be == '\0' or the last char will be truncated).
5540   StringSplitter(char* str, size_t size, char delimiter);
5541 
5542   // Splits the current token from an outer StringSplitter instance. This is to
5543   // chain splitters as follows:
5544   // for (base::StringSplitter lines(x, '\n'); ss.Next();)
5545   //   for (base::StringSplitter words(&lines, ' '); words.Next();)
5546   StringSplitter(StringSplitter*, char delimiter);
5547 
5548   // Returns true if a token is found (in which case it will be stored in
5549   // cur_token()), false if no more tokens are found.
5550   bool Next();
5551 
5552   // Returns the current token iff last call to Next() returned true. In this
5553   // case it guarantees that the returned string is always null terminated.
5554   // In all other cases (before the 1st call to Next() and after Next() returns
5555   // false) returns nullptr.
cur_token()5556   char* cur_token() { return cur_; }
5557 
5558   // Returns the length of the current token (excluding the null terminator).
cur_token_size() const5559   size_t cur_token_size() const { return cur_size_; }
5560 
5561  private:
5562   StringSplitter(const StringSplitter&) = delete;
5563   StringSplitter& operator=(const StringSplitter&) = delete;
5564   void Initialize(char* str, size_t size);
5565 
5566   std::string str_;
5567   char* cur_;
5568   size_t cur_size_;
5569   char* next_;
5570   char* end_;  // STL-style, points one past the last char.
5571   const char delimiter_;
5572 };
5573 
5574 }  // namespace base
5575 }  // namespace perfetto
5576 
5577 #endif  // INCLUDE_PERFETTO_EXT_BASE_STRING_SPLITTER_H_
5578 /*
5579  * Copyright (C) 2018 The Android Open Source Project
5580  *
5581  * Licensed under the Apache License, Version 2.0 (the "License");
5582  * you may not use this file except in compliance with the License.
5583  * You may obtain a copy of the License at
5584  *
5585  *      http://www.apache.org/licenses/LICENSE-2.0
5586  *
5587  * Unless required by applicable law or agreed to in writing, software
5588  * distributed under the License is distributed on an "AS IS" BASIS,
5589  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
5590  * See the License for the specific language governing permissions and
5591  * limitations under the License.
5592  */
5593 
5594 // gen_amalgamated expanded: #include "perfetto/ext/base/string_splitter.h"
5595 
5596 #include <utility>
5597 
5598 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
5599 
5600 namespace perfetto {
5601 namespace base {
5602 
StringSplitter(std::string str,char delimiter)5603 StringSplitter::StringSplitter(std::string str, char delimiter)
5604     : str_(std::move(str)), delimiter_(delimiter) {
5605   // It's legal to access str[str.size()] in C++11 (it always returns \0),
5606   // hence the +1 (which becomes just size() after the -1 in Initialize()).
5607   Initialize(&str_[0], str_.size() + 1);
5608 }
5609 
StringSplitter(char * str,size_t size,char delimiter)5610 StringSplitter::StringSplitter(char* str, size_t size, char delimiter)
5611     : delimiter_(delimiter) {
5612   Initialize(str, size);
5613 }
5614 
StringSplitter(StringSplitter * outer,char delimiter)5615 StringSplitter::StringSplitter(StringSplitter* outer, char delimiter)
5616     : delimiter_(delimiter) {
5617   Initialize(outer->cur_token(), outer->cur_token_size() + 1);
5618 }
5619 
Initialize(char * str,size_t size)5620 void StringSplitter::Initialize(char* str, size_t size) {
5621   PERFETTO_DCHECK(!size || str);
5622   next_ = str;
5623   end_ = str + size;
5624   cur_ = nullptr;
5625   cur_size_ = 0;
5626   if (size)
5627     next_[size - 1] = '\0';
5628 }
5629 
Next()5630 bool StringSplitter::Next() {
5631   for (; next_ < end_; next_++) {
5632     if (*next_ == delimiter_)
5633       continue;
5634     cur_ = next_;
5635     for (;; next_++) {
5636       if (*next_ == delimiter_) {
5637         cur_size_ = static_cast<size_t>(next_ - cur_);
5638         *(next_++) = '\0';
5639         break;
5640       }
5641       if (*next_ == '\0') {
5642         cur_size_ = static_cast<size_t>(next_ - cur_);
5643         next_ = end_;
5644         break;
5645       }
5646     }
5647     if (*cur_)
5648       return true;
5649     break;
5650   }
5651   cur_ = nullptr;
5652   cur_size_ = 0;
5653   return false;
5654 }
5655 
5656 }  // namespace base
5657 }  // namespace perfetto
5658 // gen_amalgamated begin source: src/base/string_utils.cc
5659 /*
5660  * Copyright (C) 2018 The Android Open Source Project
5661  *
5662  * Licensed under the Apache License, Version 2.0 (the "License");
5663  * you may not use this file except in compliance with the License.
5664  * You may obtain a copy of the License at
5665  *
5666  *      http://www.apache.org/licenses/LICENSE-2.0
5667  *
5668  * Unless required by applicable law or agreed to in writing, software
5669  * distributed under the License is distributed on an "AS IS" BASIS,
5670  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
5671  * See the License for the specific language governing permissions and
5672  * limitations under the License.
5673  */
5674 
5675 // gen_amalgamated expanded: #include "perfetto/ext/base/string_utils.h"
5676 
5677 #include <locale.h>
5678 #include <stdarg.h>
5679 #include <string.h>
5680 
5681 #include <algorithm>
5682 
5683 #if PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
5684 #include <xlocale.h>
5685 #endif
5686 
5687 #include <cinttypes>
5688 
5689 // gen_amalgamated expanded: #include "perfetto/base/compiler.h"
5690 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
5691 
5692 namespace perfetto {
5693 namespace base {
5694 
5695 // Locale-independant as possible version of strtod.
StrToD(const char * nptr,char ** endptr)5696 double StrToD(const char* nptr, char** endptr) {
5697 #if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \
5698     PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) ||   \
5699     PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
5700   static auto c_locale = newlocale(LC_ALL, "C", nullptr);
5701   return strtod_l(nptr, endptr, c_locale);
5702 #else
5703   return strtod(nptr, endptr);
5704 #endif
5705 }
5706 
StartsWith(const std::string & str,const std::string & prefix)5707 bool StartsWith(const std::string& str, const std::string& prefix) {
5708   return str.compare(0, prefix.length(), prefix) == 0;
5709 }
5710 
StartsWithAny(const std::string & str,const std::vector<std::string> & prefixes)5711 bool StartsWithAny(const std::string& str,
5712                    const std::vector<std::string>& prefixes) {
5713   return std::any_of(
5714       prefixes.begin(), prefixes.end(),
5715       [&str](const std::string& prefix) { return StartsWith(str, prefix); });
5716 }
5717 
EndsWith(const std::string & str,const std::string & suffix)5718 bool EndsWith(const std::string& str, const std::string& suffix) {
5719   if (suffix.size() > str.size())
5720     return false;
5721   return str.compare(str.size() - suffix.size(), suffix.size(), suffix) == 0;
5722 }
5723 
Contains(const std::string & haystack,const std::string & needle)5724 bool Contains(const std::string& haystack, const std::string& needle) {
5725   return haystack.find(needle) != std::string::npos;
5726 }
5727 
Contains(const std::string & haystack,const char needle)5728 bool Contains(const std::string& haystack, const char needle) {
5729   return haystack.find(needle) != std::string::npos;
5730 }
5731 
Find(const StringView & needle,const StringView & haystack)5732 size_t Find(const StringView& needle, const StringView& haystack) {
5733   if (needle.empty())
5734     return 0;
5735   if (needle.size() > haystack.size())
5736     return std::string::npos;
5737   for (size_t i = 0; i < haystack.size() - (needle.size() - 1); ++i) {
5738     if (strncmp(haystack.data() + i, needle.data(), needle.size()) == 0)
5739       return i;
5740   }
5741   return std::string::npos;
5742 }
5743 
CaseInsensitiveEqual(const std::string & first,const std::string & second)5744 bool CaseInsensitiveEqual(const std::string& first, const std::string& second) {
5745   return first.size() == second.size() &&
5746          std::equal(
5747              first.begin(), first.end(), second.begin(),
5748              [](char a, char b) { return Lowercase(a) == Lowercase(b); });
5749 }
5750 
Join(const std::vector<std::string> & parts,const std::string & delim)5751 std::string Join(const std::vector<std::string>& parts,
5752                  const std::string& delim) {
5753   std::string acc;
5754   for (size_t i = 0; i < parts.size(); ++i) {
5755     acc += parts[i];
5756     if (i + 1 != parts.size()) {
5757       acc += delim;
5758     }
5759   }
5760   return acc;
5761 }
5762 
SplitString(const std::string & text,const std::string & delimiter)5763 std::vector<std::string> SplitString(const std::string& text,
5764                                      const std::string& delimiter) {
5765   PERFETTO_CHECK(!delimiter.empty());
5766 
5767   std::vector<std::string> output;
5768   size_t start = 0;
5769   size_t next;
5770   for (;;) {
5771     next = std::min(text.find(delimiter, start), text.size());
5772     if (next > start)
5773       output.emplace_back(&text[start], next - start);
5774     start = next + delimiter.size();
5775     if (start >= text.size())
5776       break;
5777   }
5778   return output;
5779 }
5780 
StripPrefix(const std::string & str,const std::string & prefix)5781 std::string StripPrefix(const std::string& str, const std::string& prefix) {
5782   return StartsWith(str, prefix) ? str.substr(prefix.size()) : str;
5783 }
5784 
StripSuffix(const std::string & str,const std::string & suffix)5785 std::string StripSuffix(const std::string& str, const std::string& suffix) {
5786   return EndsWith(str, suffix) ? str.substr(0, str.size() - suffix.size())
5787                                : str;
5788 }
5789 
ToUpper(const std::string & str)5790 std::string ToUpper(const std::string& str) {
5791   // Don't use toupper(), it depends on the locale.
5792   std::string res(str);
5793   auto end = res.end();
5794   for (auto c = res.begin(); c != end; ++c)
5795     *c = Uppercase(*c);
5796   return res;
5797 }
5798 
ToLower(const std::string & str)5799 std::string ToLower(const std::string& str) {
5800   // Don't use tolower(), it depends on the locale.
5801   std::string res(str);
5802   auto end = res.end();
5803   for (auto c = res.begin(); c != end; ++c)
5804     *c = Lowercase(*c);
5805   return res;
5806 }
5807 
ToHex(const char * data,size_t size)5808 std::string ToHex(const char* data, size_t size) {
5809   std::string hex(2 * size + 1, 'x');
5810   for (size_t i = 0; i < size; ++i) {
5811     // snprintf prints 3 characters, the two hex digits and a null byte. As we
5812     // write left to right, we keep overwriting the nullbytes, except for the
5813     // last call to snprintf.
5814     snprintf(&(hex[2 * i]), 3, "%02hhx", data[i]);
5815   }
5816   // Remove the trailing nullbyte produced by the last snprintf.
5817   hex.resize(2 * size);
5818   return hex;
5819 }
5820 
IntToHexString(uint32_t number)5821 std::string IntToHexString(uint32_t number) {
5822   size_t max_size = 11;  // Max uint32 is 0xFFFFFFFF + 1 for null byte.
5823   std::string buf;
5824   buf.resize(max_size);
5825   size_t final_len = SprintfTrunc(&buf[0], max_size, "0x%02x", number);
5826   buf.resize(static_cast<size_t>(final_len));  // Cuts off the final null byte.
5827   return buf;
5828 }
5829 
Uint64ToHexString(uint64_t number)5830 std::string Uint64ToHexString(uint64_t number) {
5831   return "0x" + Uint64ToHexStringNoPrefix(number);
5832 }
5833 
Uint64ToHexStringNoPrefix(uint64_t number)5834 std::string Uint64ToHexStringNoPrefix(uint64_t number) {
5835   size_t max_size = 17;  // Max uint64 is FFFFFFFFFFFFFFFF + 1 for null byte.
5836   std::string buf;
5837   buf.resize(max_size);
5838   size_t final_len = SprintfTrunc(&buf[0], max_size, "%" PRIx64 "", number);
5839   buf.resize(static_cast<size_t>(final_len));  // Cuts off the final null byte.
5840   return buf;
5841 }
5842 
StripChars(const std::string & str,const std::string & chars,char replacement)5843 std::string StripChars(const std::string& str,
5844                        const std::string& chars,
5845                        char replacement) {
5846   std::string res(str);
5847   const char* start = res.c_str();
5848   const char* remove = chars.c_str();
5849   for (const char* c = strpbrk(start, remove); c; c = strpbrk(c + 1, remove))
5850     res[static_cast<uintptr_t>(c - start)] = replacement;
5851   return res;
5852 }
5853 
ReplaceAll(std::string str,const std::string & to_replace,const std::string & replacement)5854 std::string ReplaceAll(std::string str,
5855                        const std::string& to_replace,
5856                        const std::string& replacement) {
5857   PERFETTO_CHECK(!to_replace.empty());
5858   size_t pos = 0;
5859   while ((pos = str.find(to_replace, pos)) != std::string::npos) {
5860     str.replace(pos, to_replace.length(), replacement);
5861     pos += replacement.length();
5862   }
5863   return str;
5864 }
5865 
TrimLeading(const std::string & str)5866 std::string TrimLeading(const std::string& str) {
5867   size_t idx = str.find_first_not_of(' ');
5868   return idx == std::string::npos ? str : str.substr(idx);
5869 }
5870 
SprintfTrunc(char * dst,size_t dst_size,const char * fmt,...)5871 size_t SprintfTrunc(char* dst, size_t dst_size, const char* fmt, ...) {
5872   if (PERFETTO_UNLIKELY(dst_size) == 0)
5873     return 0;
5874 
5875   va_list args;
5876   va_start(args, fmt);
5877   int src_size = vsnprintf(dst, dst_size, fmt, args);
5878   va_end(args);
5879 
5880   if (PERFETTO_UNLIKELY(src_size) <= 0) {
5881     dst[0] = '\0';
5882     return 0;
5883   }
5884 
5885   size_t res;
5886   if (PERFETTO_LIKELY(src_size < static_cast<int>(dst_size))) {
5887     // Most common case.
5888     res = static_cast<size_t>(src_size);
5889   } else {
5890     // Truncation case.
5891     res = dst_size - 1;
5892   }
5893 
5894   PERFETTO_DCHECK(res < dst_size);
5895   PERFETTO_DCHECK(dst[res] == '\0');
5896   return res;
5897 }
5898 
5899 }  // namespace base
5900 }  // namespace perfetto
5901 // gen_amalgamated begin source: src/base/string_view.cc
5902 /*
5903  * Copyright (C) 2019 The Android Open Source Project
5904  *
5905  * Licensed under the Apache License, Version 2.0 (the "License");
5906  * you may not use this file except in compliance with the License.
5907  * You may obtain a copy of the License at
5908  *
5909  *      http://www.apache.org/licenses/LICENSE-2.0
5910  *
5911  * Unless required by applicable law or agreed to in writing, software
5912  * distributed under the License is distributed on an "AS IS" BASIS,
5913  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
5914  * See the License for the specific language governing permissions and
5915  * limitations under the License.
5916  */
5917 
5918 // gen_amalgamated expanded: #include "perfetto/ext/base/string_view.h"
5919 
5920 namespace perfetto {
5921 namespace base {
5922 
5923 // static
5924 constexpr size_t StringView::npos;
5925 
5926 }  // namespace base
5927 }  // namespace perfetto
5928 // gen_amalgamated begin source: src/base/temp_file.cc
5929 // gen_amalgamated begin header: include/perfetto/ext/base/temp_file.h
5930 /*
5931  * Copyright (C) 2018 The Android Open Source Project
5932  *
5933  * Licensed under the Apache License, Version 2.0 (the "License");
5934  * you may not use this file except in compliance with the License.
5935  * You may obtain a copy of the License at
5936  *
5937  *      http://www.apache.org/licenses/LICENSE-2.0
5938  *
5939  * Unless required by applicable law or agreed to in writing, software
5940  * distributed under the License is distributed on an "AS IS" BASIS,
5941  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
5942  * See the License for the specific language governing permissions and
5943  * limitations under the License.
5944  */
5945 
5946 #ifndef INCLUDE_PERFETTO_EXT_BASE_TEMP_FILE_H_
5947 #define INCLUDE_PERFETTO_EXT_BASE_TEMP_FILE_H_
5948 
5949 #include <string>
5950 
5951 // gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"
5952 
5953 namespace perfetto {
5954 namespace base {
5955 
5956 std::string GetSysTempDir();
5957 
5958 class TempFile {
5959  public:
5960   static TempFile CreateUnlinked();
5961   static TempFile Create();
5962 
5963   TempFile(TempFile&&) noexcept;
5964   TempFile& operator=(TempFile&&);
5965   ~TempFile();
5966 
path() const5967   const std::string& path() const { return path_; }
fd() const5968   int fd() const { return *fd_; }
operator *() const5969   int operator*() const { return *fd_; }
5970 
5971   // Unlinks the file from the filesystem but keeps the fd() open.
5972   // It is safe to call this multiple times.
5973   void Unlink();
5974 
5975   // Releases the underlying file descriptor. Will unlink the file from the
5976   // filesystem if it was created via CreateUnlinked().
5977   ScopedFile ReleaseFD();
5978 
5979  private:
5980   TempFile();
5981   TempFile(const TempFile&) = delete;
5982   TempFile& operator=(const TempFile&) = delete;
5983 
5984   ScopedFile fd_;
5985   std::string path_;
5986 };
5987 
5988 class TempDir {
5989  public:
5990   static TempDir Create();
5991 
5992   TempDir(TempDir&&) noexcept;
5993   TempDir& operator=(TempDir&&);
5994   ~TempDir();
5995 
path() const5996   const std::string& path() const { return path_; }
5997 
5998  private:
5999   TempDir();
6000   TempDir(const TempDir&) = delete;
6001   TempDir& operator=(const TempDir&) = delete;
6002 
6003   std::string path_;
6004 };
6005 
6006 }  // namespace base
6007 }  // namespace perfetto
6008 
6009 #endif  // INCLUDE_PERFETTO_EXT_BASE_TEMP_FILE_H_
6010 /*
6011  * Copyright (C) 2018 The Android Open Source Project
6012  *
6013  * Licensed under the Apache License, Version 2.0 (the "License");
6014  * you may not use this file except in compliance with the License.
6015  * You may obtain a copy of the License at
6016  *
6017  *      http://www.apache.org/licenses/LICENSE-2.0
6018  *
6019  * Unless required by applicable law or agreed to in writing, software
6020  * distributed under the License is distributed on an "AS IS" BASIS,
6021  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
6022  * See the License for the specific language governing permissions and
6023  * limitations under the License.
6024  */
6025 
6026 // gen_amalgamated expanded: #include "perfetto/ext/base/temp_file.h"
6027 
6028 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
6029 
6030 #include <stdio.h>
6031 #include <stdlib.h>
6032 #include <string.h>
6033 
6034 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
6035 #include <Windows.h>
6036 #include <direct.h>
6037 #include <fileapi.h>
6038 #include <io.h>
6039 #else
6040 #include <unistd.h>
6041 #endif
6042 
6043 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
6044 // gen_amalgamated expanded: #include "perfetto/ext/base/file_utils.h"
6045 // gen_amalgamated expanded: #include "perfetto/ext/base/string_utils.h"
6046 
6047 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
6048 namespace {
GetTempName()6049 std::string GetTempName() {
6050   char name[] = "perfetto-XXXXXX";
6051   PERFETTO_CHECK(_mktemp_s(name, sizeof(name)) == 0);
6052   return name;
6053 }
6054 }  // namespace
6055 #endif
6056 
6057 namespace perfetto {
6058 namespace base {
6059 
GetSysTempDir()6060 std::string GetSysTempDir() {
6061   const char* tmpdir = nullptr;
6062 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
6063   if ((tmpdir = getenv("TMP")))
6064     return tmpdir;
6065   if ((tmpdir = getenv("TEMP")))
6066     return tmpdir;
6067   return "C:\\TEMP";
6068 #else
6069   if ((tmpdir = getenv("TMPDIR")))
6070     return base::StripSuffix(tmpdir, "/");
6071 #if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
6072   return "/data/local/tmp";
6073 #else
6074   return "/tmp";
6075 #endif  // !OS_ANDROID
6076 #endif  // !OS_WIN
6077 }
6078 
6079 // static
Create()6080 TempFile TempFile::Create() {
6081   TempFile temp_file;
6082 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
6083   temp_file.path_ = GetSysTempDir() + "\\" + GetTempName();
6084   // Several tests want to read-back the temp file while still open. On Windows,
6085   // that requires FILE_SHARE_READ. FILE_SHARE_READ is NOT settable when using
6086   // the POSIX-compat equivalent function _open(). Hence the CreateFileA +
6087   // _open_osfhandle dance here.
6088   HANDLE h =
6089       ::CreateFileA(temp_file.path_.c_str(), GENERIC_READ | GENERIC_WRITE,
6090                     FILE_SHARE_DELETE | FILE_SHARE_READ, nullptr, CREATE_ALWAYS,
6091                     FILE_ATTRIBUTE_TEMPORARY, nullptr);
6092   PERFETTO_CHECK(PlatformHandleChecker::IsValid(h));
6093   // According to MSDN, when using _open_osfhandle the caller must not call
6094   // CloseHandle(). Ownership is moved to the file descriptor, which then needs
6095   // to be closed with just with _close().
6096   temp_file.fd_.reset(_open_osfhandle(reinterpret_cast<intptr_t>(h), 0));
6097 #else
6098   temp_file.path_ = GetSysTempDir() + "/perfetto-XXXXXXXX";
6099   temp_file.fd_.reset(mkstemp(&temp_file.path_[0]));
6100 #endif
6101   if (PERFETTO_UNLIKELY(!temp_file.fd_)) {
6102     PERFETTO_FATAL("Could not create temp file %s", temp_file.path_.c_str());
6103   }
6104   return temp_file;
6105 }
6106 
6107 // static
CreateUnlinked()6108 TempFile TempFile::CreateUnlinked() {
6109   TempFile temp_file = TempFile::Create();
6110   temp_file.Unlink();
6111   return temp_file;
6112 }
6113 
6114 TempFile::TempFile() = default;
6115 
~TempFile()6116 TempFile::~TempFile() {
6117   Unlink();
6118 }
6119 
ReleaseFD()6120 ScopedFile TempFile::ReleaseFD() {
6121   Unlink();
6122   return std::move(fd_);
6123 }
6124 
Unlink()6125 void TempFile::Unlink() {
6126   if (path_.empty())
6127     return;
6128 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
6129   // If the FD is still open DeleteFile will mark the file as pending deletion
6130   // and delete it only when the process exists.
6131   PERFETTO_CHECK(DeleteFileA(path_.c_str()));
6132 #else
6133   PERFETTO_CHECK(unlink(path_.c_str()) == 0);
6134 #endif
6135   path_.clear();
6136 }
6137 
6138 TempFile::TempFile(TempFile&&) noexcept = default;
6139 TempFile& TempFile::operator=(TempFile&&) = default;
6140 
6141 // static
Create()6142 TempDir TempDir::Create() {
6143   TempDir temp_dir;
6144 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
6145   temp_dir.path_ = GetSysTempDir() + "\\" + GetTempName();
6146   PERFETTO_CHECK(_mkdir(temp_dir.path_.c_str()) == 0);
6147 #else
6148   temp_dir.path_ = GetSysTempDir() + "/perfetto-XXXXXXXX";
6149   PERFETTO_CHECK(mkdtemp(&temp_dir.path_[0]));
6150 #endif
6151   return temp_dir;
6152 }
6153 
6154 TempDir::TempDir() = default;
6155 TempDir::TempDir(TempDir&&) noexcept = default;
6156 TempDir& TempDir::operator=(TempDir&&) = default;
6157 
~TempDir()6158 TempDir::~TempDir() {
6159   if (path_.empty())
6160     return;  // For objects that get std::move()d.
6161   PERFETTO_CHECK(Rmdir(path_));
6162 }
6163 
6164 }  // namespace base
6165 }  // namespace perfetto
6166 // gen_amalgamated begin source: src/base/thread_checker.cc
6167 /*
6168  * Copyright (C) 2017 The Android Open Source Project
6169  *
6170  * Licensed under the Apache License, Version 2.0 (the "License");
6171  * you may not use this file except in compliance with the License.
6172  * You may obtain a copy of the License at
6173  *
6174  *      http://www.apache.org/licenses/LICENSE-2.0
6175  *
6176  * Unless required by applicable law or agreed to in writing, software
6177  * distributed under the License is distributed on an "AS IS" BASIS,
6178  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
6179  * See the License for the specific language governing permissions and
6180  * limitations under the License.
6181  */
6182 
6183 // gen_amalgamated expanded: #include "perfetto/ext/base/thread_checker.h"
6184 
6185 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
6186 #include <Windows.h>
6187 #endif
6188 
6189 namespace perfetto {
6190 namespace base {
6191 
6192 namespace {
6193 constexpr ThreadID kDetached{};
6194 
CurrentThreadId()6195 ThreadID CurrentThreadId() {
6196 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
6197   return ::GetCurrentThreadId();
6198 #else
6199   return pthread_self();
6200 #endif
6201 }
6202 }  // namespace
6203 
ThreadChecker()6204 ThreadChecker::ThreadChecker() {
6205   thread_id_.store(CurrentThreadId());
6206 }
6207 
6208 ThreadChecker::~ThreadChecker() = default;
6209 
ThreadChecker(const ThreadChecker & other)6210 ThreadChecker::ThreadChecker(const ThreadChecker& other) {
6211   thread_id_ = other.thread_id_.load();
6212 }
6213 
operator =(const ThreadChecker & other)6214 ThreadChecker& ThreadChecker::operator=(const ThreadChecker& other) {
6215   thread_id_ = other.thread_id_.load();
6216   return *this;
6217 }
6218 
CalledOnValidThread() const6219 bool ThreadChecker::CalledOnValidThread() const {
6220   auto self = CurrentThreadId();
6221 
6222   // Will re-attach if previously detached using DetachFromThread().
6223   auto prev_value = kDetached;
6224   if (thread_id_.compare_exchange_strong(prev_value, self))
6225     return true;
6226   return prev_value == self;
6227 }
6228 
DetachFromThread()6229 void ThreadChecker::DetachFromThread() {
6230   thread_id_.store(kDetached);
6231 }
6232 
6233 }  // namespace base
6234 }  // namespace perfetto
6235 // gen_amalgamated begin source: src/base/time.cc
6236 /*
6237  * Copyright (C) 2018 The Android Open Source Project
6238  *
6239  * Licensed under the Apache License, Version 2.0 (the "License");
6240  * you may not use this file except in compliance with the License.
6241  * You may obtain a copy of the License at
6242  *
6243  *      http://www.apache.org/licenses/LICENSE-2.0
6244  *
6245  * Unless required by applicable law or agreed to in writing, software
6246  * distributed under the License is distributed on an "AS IS" BASIS,
6247  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
6248  * See the License for the specific language governing permissions and
6249  * limitations under the License.
6250  */
6251 
6252 // gen_amalgamated expanded: #include "perfetto/base/time.h"
6253 
6254 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
6255 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
6256 
6257 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
6258 #include <Windows.h>
6259 #else
6260 #include <unistd.h>
6261 #endif
6262 
6263 namespace perfetto {
6264 namespace base {
6265 
6266 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
6267 
GetWallTimeNs()6268 TimeNanos GetWallTimeNs() {
6269   LARGE_INTEGER freq;
6270   ::QueryPerformanceFrequency(&freq);
6271   LARGE_INTEGER counter;
6272   ::QueryPerformanceCounter(&counter);
6273   double elapsed_nanoseconds = (1e9 * static_cast<double>(counter.QuadPart)) /
6274                                static_cast<double>(freq.QuadPart);
6275   return TimeNanos(static_cast<uint64_t>(elapsed_nanoseconds));
6276 }
6277 
GetThreadCPUTimeNs()6278 TimeNanos GetThreadCPUTimeNs() {
6279   FILETIME dummy, kernel_ftime, user_ftime;
6280   ::GetThreadTimes(GetCurrentThread(), &dummy, &dummy, &kernel_ftime,
6281                    &user_ftime);
6282   uint64_t kernel_time = kernel_ftime.dwHighDateTime * 0x100000000 +
6283                          kernel_ftime.dwLowDateTime;
6284   uint64_t user_time = user_ftime.dwHighDateTime * 0x100000000 +
6285                        user_ftime.dwLowDateTime;
6286 
6287   return TimeNanos((kernel_time + user_time) * 100);
6288 }
6289 
SleepMicroseconds(unsigned interval_us)6290 void SleepMicroseconds(unsigned interval_us) {
6291   // The Windows Sleep function takes a millisecond count. Round up so that
6292   // short sleeps don't turn into a busy wait. Note that the sleep granularity
6293   // on Windows can dynamically vary from 1 ms to ~16 ms, so don't count on this
6294   // being a short sleep.
6295   ::Sleep(static_cast<DWORD>((interval_us + 999) / 1000));
6296 }
6297 
6298 #else  // PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
6299 
6300 void SleepMicroseconds(unsigned interval_us) {
6301   ::usleep(static_cast<useconds_t>(interval_us));
6302 }
6303 
6304 #endif  // PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
6305 
GetTimeFmt(const std::string & fmt)6306 std::string GetTimeFmt(const std::string& fmt) {
6307   time_t raw_time;
6308   time(&raw_time);
6309   struct tm* local_tm;
6310   local_tm = localtime(&raw_time);
6311   char buf[128];
6312   PERFETTO_CHECK(strftime(buf, 80, fmt.c_str(), local_tm) > 0);
6313   return buf;
6314 }
6315 
6316 }  // namespace base
6317 }  // namespace perfetto
6318 // gen_amalgamated begin source: src/base/utils.cc
6319 /*
6320  * Copyright (C) 2020 The Android Open Source Project
6321  *
6322  * Licensed under the Apache License, Version 2.0 (the "License");
6323  * you may not use this file except in compliance with the License.
6324  * You may obtain a copy of the License at
6325  *
6326  *      http://www.apache.org/licenses/LICENSE-2.0
6327  *
6328  * Unless required by applicable law or agreed to in writing, software
6329  * distributed under the License is distributed on an "AS IS" BASIS,
6330  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
6331  * See the License for the specific language governing permissions and
6332  * limitations under the License.
6333  */
6334 
6335 // gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
6336 
6337 #include <string>
6338 
6339 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
6340 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
6341 // gen_amalgamated expanded: #include "perfetto/ext/base/file_utils.h"
6342 
6343 #if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) ||   \
6344     PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \
6345     PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE) ||   \
6346     PERFETTO_BUILDFLAG(PERFETTO_OS_FUCHSIA)
6347 #include <limits.h>
6348 #include <stdlib.h>  // For _exit()
6349 #include <unistd.h>  // For getpagesize() and geteuid() & fork()
6350 #endif
6351 
6352 #if PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
6353 #include <mach-o/dyld.h>
6354 #include <mach/vm_page_size.h>
6355 #endif
6356 
6357 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
6358 #include <Windows.h>
6359 #include <io.h>
6360 #include <malloc.h>  // For _aligned_malloc().
6361 #endif
6362 
6363 #if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
6364 #include <dlfcn.h>
6365 #include <malloc.h>
6366 
6367 #ifdef M_PURGE
6368 #define PERFETTO_M_PURGE M_PURGE
6369 #else
6370 // Only available in in-tree builds and on newer SDKs.
6371 #define PERFETTO_M_PURGE -101
6372 #endif  // M_PURGE
6373 
6374 namespace {
6375 extern "C" {
6376 using MalloptType = void (*)(int, int);
6377 }
6378 }  // namespace
6379 #endif  // OS_ANDROID
6380 
6381 namespace {
6382 
6383 #if PERFETTO_BUILDFLAG(PERFETTO_X64_CPU_OPT)
6384 
6385 // Preserve the %rbx register via %rdi to work around a clang bug
6386 // https://bugs.llvm.org/show_bug.cgi?id=17907 (%rbx in an output constraint
6387 // is not considered a clobbered register).
6388 #define PERFETTO_GETCPUID(a, b, c, d, a_inp, c_inp) \
6389   asm("mov %%rbx, %%rdi\n"                          \
6390       "cpuid\n"                                     \
6391       "xchg %%rdi, %%rbx\n"                         \
6392       : "=a"(a), "=D"(b), "=c"(c), "=d"(d)          \
6393       : "a"(a_inp), "2"(c_inp))
6394 
GetXCR0EAX()6395 uint32_t GetXCR0EAX() {
6396   uint32_t eax = 0, edx = 0;
6397   asm("xgetbv" : "=a"(eax), "=d"(edx) : "c"(0));
6398   return eax;
6399 }
6400 
6401 // If we are building with -msse4 check that the CPU actually supports it.
6402 // This file must be kept in sync with gn/standalone/BUILD.gn.
CheckCpuOptimizations()6403 void PERFETTO_EXPORT __attribute__((constructor)) CheckCpuOptimizations() {
6404   uint32_t eax = 0, ebx = 0, ecx = 0, edx = 0;
6405   PERFETTO_GETCPUID(eax, ebx, ecx, edx, 1, 0);
6406 
6407   static constexpr uint64_t xcr0_xmm_mask = 0x2;
6408   static constexpr uint64_t xcr0_ymm_mask = 0x4;
6409   static constexpr uint64_t xcr0_avx_mask = xcr0_xmm_mask | xcr0_ymm_mask;
6410 
6411   const bool have_popcnt = ecx & (1u << 23);
6412   const bool have_sse4_2 = ecx & (1u << 20);
6413   const bool have_avx =
6414       // Does the OS save/restore XMM and YMM state?
6415       ((GetXCR0EAX() & xcr0_avx_mask) == xcr0_avx_mask) &&
6416       (ecx & (1u << 27)) &&  // OS support XGETBV.
6417       (ecx & (1u << 28));    // AVX supported in hardware
6418 
6419   if (!have_sse4_2 || !have_popcnt || !have_avx) {
6420     fprintf(
6421         stderr,
6422         "This executable requires a cpu that supports SSE4.2 and AVX2.\n"
6423         "Rebuild with enable_perfetto_x64_cpu_opt=false (ebx=%x, ecx=%x).\n",
6424         ebx, ecx);
6425     _exit(126);
6426   }
6427 }
6428 #endif
6429 
6430 }  // namespace
6431 
6432 namespace perfetto {
6433 namespace base {
6434 
MaybeReleaseAllocatorMemToOS()6435 void MaybeReleaseAllocatorMemToOS() {
6436 #if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
6437   // mallopt() on Android requires SDK level 26. Many targets and embedders
6438   // still depend on a lower SDK level. Given mallopt() is a quite simple API,
6439   // use reflection to do this rather than bumping the SDK level for all
6440   // embedders. This keeps the behavior of standalone builds aligned with
6441   // in-tree builds.
6442   static MalloptType mallopt_fn =
6443       reinterpret_cast<MalloptType>(dlsym(RTLD_DEFAULT, "mallopt"));
6444   if (!mallopt_fn)
6445     return;
6446   mallopt_fn(PERFETTO_M_PURGE, 0);
6447 #endif
6448 }
6449 
GetSysPageSize()6450 uint32_t GetSysPageSize() {
6451   ignore_result(kPageSize);  // Just to keep the amalgamated build happy.
6452 #if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
6453     PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
6454   static std::atomic<uint32_t> page_size{0};
6455   // This function might be called in hot paths. Avoid calling getpagesize() all
6456   // the times, in many implementations getpagesize() calls sysconf() which is
6457   // not cheap.
6458   uint32_t cached_value = page_size.load(std::memory_order_relaxed);
6459   if (PERFETTO_UNLIKELY(cached_value == 0)) {
6460     cached_value = static_cast<uint32_t>(getpagesize());
6461     page_size.store(cached_value, std::memory_order_relaxed);
6462   }
6463   return cached_value;
6464 #elif PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
6465   return static_cast<uint32_t>(vm_page_size);
6466 #else
6467   return 4096;
6468 #endif
6469 }
6470 
GetCurrentUserId()6471 uid_t GetCurrentUserId() {
6472 #if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) ||   \
6473     PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \
6474     PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
6475   return geteuid();
6476 #else
6477   // TODO(primiano): On Windows we could hash the current user SID and derive a
6478   // numeric user id [1]. It is not clear whether we need that. Right now that
6479   // would not bring any benefit. Returning 0 unil we can prove we need it.
6480   // [1]:https://android-review.googlesource.com/c/platform/external/perfetto/+/1513879/25/src/base/utils.cc
6481   return 0;
6482 #endif
6483 }
6484 
SetEnv(const std::string & key,const std::string & value)6485 void SetEnv(const std::string& key, const std::string& value) {
6486 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
6487   PERFETTO_CHECK(::_putenv_s(key.c_str(), value.c_str()) == 0);
6488 #else
6489   PERFETTO_CHECK(::setenv(key.c_str(), value.c_str(), /*overwrite=*/true) == 0);
6490 #endif
6491 }
6492 
Daemonize(std::function<int ()> parent_cb)6493 void Daemonize(std::function<int()> parent_cb) {
6494 #if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) ||   \
6495     PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \
6496     PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
6497   pid_t pid;
6498   switch (pid = fork()) {
6499     case -1:
6500       PERFETTO_FATAL("fork");
6501     case 0: {
6502       PERFETTO_CHECK(setsid() != -1);
6503       base::ignore_result(chdir("/"));
6504       base::ScopedFile null = base::OpenFile("/dev/null", O_RDONLY);
6505       PERFETTO_CHECK(null);
6506       PERFETTO_CHECK(dup2(*null, STDIN_FILENO) != -1);
6507       PERFETTO_CHECK(dup2(*null, STDOUT_FILENO) != -1);
6508       PERFETTO_CHECK(dup2(*null, STDERR_FILENO) != -1);
6509       // Do not accidentally close stdin/stdout/stderr.
6510       if (*null <= 2)
6511         null.release();
6512       break;
6513     }
6514     default:
6515       printf("%d\n", pid);
6516       int err = parent_cb();
6517       exit(err);
6518   }
6519 #else
6520   // Avoid -Wunreachable warnings.
6521   if (reinterpret_cast<intptr_t>(&Daemonize) != 16)
6522     PERFETTO_FATAL("--background is only supported on Linux/Android/Mac");
6523   ignore_result(parent_cb);
6524 #endif  // OS_WIN
6525 }
6526 
GetCurExecutablePath()6527 std::string GetCurExecutablePath() {
6528   std::string self_path;
6529 #if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) ||   \
6530     PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \
6531     PERFETTO_BUILDFLAG(PERFETTO_OS_FUCHSIA)
6532   char buf[PATH_MAX];
6533   ssize_t size = readlink("/proc/self/exe", buf, sizeof(buf));
6534   PERFETTO_CHECK(size != -1);
6535   // readlink does not null terminate.
6536   self_path = std::string(buf, static_cast<size_t>(size));
6537 #elif PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
6538   uint32_t size = 0;
6539   PERFETTO_CHECK(_NSGetExecutablePath(nullptr, &size));
6540   self_path.resize(size);
6541   PERFETTO_CHECK(_NSGetExecutablePath(&self_path[0], &size) == 0);
6542 #elif PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
6543   char buf[MAX_PATH];
6544   auto len = ::GetModuleFileNameA(nullptr /*current*/, buf, sizeof(buf));
6545   self_path = std::string(buf, len);
6546 #else
6547   PERFETTO_FATAL(
6548       "GetCurExecutableDir() not implemented on the current platform");
6549 #endif
6550   return self_path;
6551 }
6552 
GetCurExecutableDir()6553 std::string GetCurExecutableDir() {
6554   auto path = GetCurExecutablePath();
6555 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
6556   // Paths in Windows can have both kinds of slashes (mingw vs msvc).
6557   path = path.substr(0, path.find_last_of('\\'));
6558 #endif
6559   path = path.substr(0, path.find_last_of('/'));
6560   return path;
6561 }
6562 
AlignedAlloc(size_t alignment,size_t size)6563 void* AlignedAlloc(size_t alignment, size_t size) {
6564   void* res = nullptr;
6565   alignment = AlignUp<sizeof(void*)>(alignment);  // At least pointer size.
6566 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
6567   // Window's _aligned_malloc() has a nearly identically signature to Unix's
6568   // aligned_alloc() but its arguments are obviously swapped.
6569   res = _aligned_malloc(size, alignment);
6570 #else
6571   // aligned_alloc() has been introduced in Android only in API 28.
6572   // Also NaCl and Fuchsia seems to have only posix_memalign().
6573   ignore_result(posix_memalign(&res, alignment, size));
6574 #endif
6575   PERFETTO_CHECK(res);
6576   return res;
6577 }
6578 
AlignedFree(void * ptr)6579 void AlignedFree(void* ptr) {
6580 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
6581   _aligned_free(ptr);  // MSDN says it is fine to pass nullptr.
6582 #else
6583   free(ptr);
6584 #endif
6585 }
6586 
HexDump(const void * data_void,size_t len,size_t bytes_per_line)6587 std::string HexDump(const void* data_void, size_t len, size_t bytes_per_line) {
6588   const char* data = reinterpret_cast<const char*>(data_void);
6589   std::string res;
6590   static const size_t kPadding = bytes_per_line * 3 + 12;
6591   std::unique_ptr<char[]> line(new char[bytes_per_line * 4 + 128]);
6592   for (size_t i = 0; i < len; i += bytes_per_line) {
6593     char* wptr = line.get();
6594     wptr += sprintf(wptr, "%08zX: ", i);
6595     for (size_t j = i; j < i + bytes_per_line && j < len; j++)
6596       wptr += sprintf(wptr, "%02X ", static_cast<unsigned>(data[j]) & 0xFF);
6597     for (size_t j = static_cast<size_t>(wptr - line.get()); j < kPadding; ++j)
6598       *(wptr++) = ' ';
6599     for (size_t j = i; j < i + bytes_per_line && j < len; j++) {
6600       char c = data[j];
6601       *(wptr++) = (c >= 32 && c < 127) ? c : '.';
6602     }
6603     *(wptr++) = '\n';
6604     *(wptr++) = '\0';
6605     res.append(line.get());
6606   }
6607   return res;
6608 }
6609 
6610 }  // namespace base
6611 }  // namespace perfetto
6612 // gen_amalgamated begin source: src/base/uuid.cc
6613 // gen_amalgamated begin header: include/perfetto/ext/base/uuid.h
6614 /*
6615  * Copyright (C) 2019 The Android Open Source Project
6616  *
6617  * Licensed under the Apache License, Version 2.0 (the "License");
6618  * you may not use this file except in compliance with the License.
6619  * You may obtain a copy of the License at
6620  *
6621  *      http://www.apache.org/licenses/LICENSE-2.0
6622  *
6623  * Unless required by applicable law or agreed to in writing, software
6624  * distributed under the License is distributed on an "AS IS" BASIS,
6625  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
6626  * See the License for the specific language governing permissions and
6627  * limitations under the License.
6628  */
6629 
6630 #ifndef INCLUDE_PERFETTO_EXT_BASE_UUID_H_
6631 #define INCLUDE_PERFETTO_EXT_BASE_UUID_H_
6632 
6633 #include <array>
6634 #include <string>
6635 
6636 // gen_amalgamated expanded: #include "perfetto/ext/base/optional.h"
6637 
6638 namespace perfetto {
6639 namespace base {
6640 
6641 class Uuid {
6642  public:
6643   explicit Uuid(const std::string& s);
6644   explicit Uuid(int64_t lsb, int64_t msb);
6645   Uuid();
6646 
data()6647   std::array<uint8_t, 16>* data() { return &data_; }
data() const6648   const std::array<uint8_t, 16>* data() const { return &data_; }
6649 
operator ==(const Uuid & other) const6650   bool operator==(const Uuid& other) const { return data_ == other.data_; }
6651 
operator !=(const Uuid & other) const6652   bool operator!=(const Uuid& other) const { return !(*this == other); }
6653 
msb() const6654   int64_t msb() const {
6655     int64_t result;
6656     memcpy(&result, data_.data() + 8, 8);
6657     return result;
6658   }
6659 
lsb() const6660   int64_t lsb() const {
6661     int64_t result;
6662     memcpy(&result, data_.data(), 8);
6663     return result;
6664   }
6665 
set_lsb_msb(int64_t lsb,int64_t msb)6666   void set_lsb_msb(int64_t lsb, int64_t msb) {
6667     set_lsb(lsb);
6668     set_msb(msb);
6669   }
set_msb(int64_t msb)6670   void set_msb(int64_t msb) { memcpy(data_.data() + 8, &msb, 8); }
set_lsb(int64_t lsb)6671   void set_lsb(int64_t lsb) { memcpy(data_.data(), &lsb, 8); }
6672 
6673   std::string ToString() const;
6674   std::string ToPrettyString() const;
6675 
6676  private:
6677   std::array<uint8_t, 16> data_{};
6678 };
6679 
6680 Uuid Uuidv4();
6681 
6682 }  // namespace base
6683 }  // namespace perfetto
6684 
6685 #endif  // INCLUDE_PERFETTO_EXT_BASE_UUID_H_
6686 /*
6687  * Copyright (C) 2019 The Android Open Source Project
6688  *
6689  * Licensed under the Apache License, Version 2.0 (the "License");
6690  * you may not use this file except in compliance with the License.
6691  * You may obtain a copy of the License at
6692  *
6693  *      http://www.apache.org/licenses/LICENSE-2.0
6694  *
6695  * Unless required by applicable law or agreed to in writing, software
6696  * distributed under the License is distributed on an "AS IS" BASIS,
6697  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
6698  * See the License for the specific language governing permissions and
6699  * limitations under the License.
6700  */
6701 
6702 // gen_amalgamated expanded: #include "perfetto/ext/base/uuid.h"
6703 
6704 #include <random>
6705 
6706 // gen_amalgamated expanded: #include "perfetto/base/time.h"
6707 
6708 namespace perfetto {
6709 namespace base {
6710 namespace {
6711 
6712 constexpr char kHexmap[] = {'0', '1', '2', '3', '4', '5', '6', '7',
6713                             '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
6714 }  // namespace
6715 
6716 // See https://www.ietf.org/rfc/rfc4122.txt
Uuidv4()6717 Uuid Uuidv4() {
6718   static std::minstd_rand rng(static_cast<uint32_t>(GetBootTimeNs().count()));
6719   Uuid uuid;
6720   auto& data = *uuid.data();
6721 
6722   for (size_t i = 0; i < 16; ++i)
6723     data[i] = static_cast<uint8_t>(rng());
6724 
6725   // version:
6726   data[6] = (data[6] & 0x0f) | 0x40;
6727   // clock_seq_hi_and_reserved:
6728   data[8] = (data[8] & 0x3f) | 0x80;
6729 
6730   return uuid;
6731 }
6732 
Uuid()6733 Uuid::Uuid() {}
6734 
Uuid(const std::string & s)6735 Uuid::Uuid(const std::string& s) {
6736   PERFETTO_CHECK(s.size() == data_.size());
6737   memcpy(data_.data(), s.data(), s.size());
6738 }
6739 
Uuid(int64_t lsb,int64_t msb)6740 Uuid::Uuid(int64_t lsb, int64_t msb) {
6741   set_lsb_msb(lsb, msb);
6742 }
6743 
ToString() const6744 std::string Uuid::ToString() const {
6745   return std::string(reinterpret_cast<const char*>(data_.data()), data_.size());
6746 }
6747 
ToPrettyString() const6748 std::string Uuid::ToPrettyString() const {
6749   std::string s(data_.size() * 2 + 4, '-');
6750   // Format is 123e4567-e89b-12d3-a456-426655443322.
6751   size_t j = 0;
6752   for (size_t i = 0; i < data_.size(); ++i) {
6753     if (i == 4 || i == 6 || i == 8 || i == 10)
6754       j++;
6755     s[2 * i + j] = kHexmap[(data_[data_.size() - i - 1] & 0xf0) >> 4];
6756     s[2 * i + 1 + j] = kHexmap[(data_[data_.size() - i - 1] & 0x0f)];
6757   }
6758   return s;
6759 }
6760 
6761 }  // namespace base
6762 }  // namespace perfetto
6763 // gen_amalgamated begin source: src/base/version.cc
6764 // gen_amalgamated begin header: include/perfetto/ext/base/version.h
6765 /*
6766  * Copyright (C) 2020 The Android Open Source Project
6767  *
6768  * Licensed under the Apache License, Version 2.0 (the "License");
6769  * you may not use this file except in compliance with the License.
6770  * You may obtain a copy of the License at
6771  *
6772  *      http://www.apache.org/licenses/LICENSE-2.0
6773  *
6774  * Unless required by applicable law or agreed to in writing, software
6775  * distributed under the License is distributed on an "AS IS" BASIS,
6776  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
6777  * See the License for the specific language governing permissions and
6778  * limitations under the License.
6779  */
6780 
6781 #ifndef INCLUDE_PERFETTO_EXT_BASE_VERSION_H_
6782 #define INCLUDE_PERFETTO_EXT_BASE_VERSION_H_
6783 
6784 namespace perfetto {
6785 namespace base {
6786 
6787 // The returned pointer is a static string is safe to pass around.
6788 const char* GetVersionString();
6789 
6790 }  // namespace base
6791 }  // namespace perfetto
6792 
6793 #endif  // INCLUDE_PERFETTO_EXT_BASE_VERSION_H_
6794 // gen_amalgamated begin header: gen/perfetto_version.gen.h
6795 // Generated by write_version_header.py
6796 
6797 #ifndef GEN_PERFETTO_VERSION_GEN_H_
6798 #define GEN_PERFETTO_VERSION_GEN_H_
6799 
6800 #define PERFETTO_VERSION_STRING() "v22.1-fa9722821"
6801 #define PERFETTO_VERSION_SCM_REVISION() "fa97228215c6c58574fbd64ac92487c31c9a4d73"
6802 
6803 #endif  // GEN_PERFETTO_VERSION_GEN_H_
6804 /*
6805  * Copyright (C) 2020 The Android Open Source Project
6806  *
6807  * Licensed under the Apache License, Version 2.0 (the "License");
6808  * you may not use this file except in compliance with the License.
6809  * You may obtain a copy of the License at
6810  *
6811  *      http://www.apache.org/licenses/LICENSE-2.0
6812  *
6813  * Unless required by applicable law or agreed to in writing, software
6814  * distributed under the License is distributed on an "AS IS" BASIS,
6815  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
6816  * See the License for the specific language governing permissions and
6817  * limitations under the License.
6818  */
6819 
6820 // gen_amalgamated expanded: #include "perfetto/ext/base/version.h"
6821 
6822 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
6823 
6824 #include <stdio.h>
6825 
6826 #if PERFETTO_BUILDFLAG(PERFETTO_VERSION_GEN)
6827 // gen_amalgamated expanded: #include "perfetto_version.gen.h"
6828 #else
6829 #define PERFETTO_VERSION_STRING() "v0.0"
6830 #define PERFETTO_VERSION_SCM_REVISION() "unknown"
6831 #endif
6832 
6833 namespace perfetto {
6834 namespace base {
6835 
GetVersionString()6836 const char* GetVersionString() {
6837   static const char* version_str = [] {
6838     static constexpr size_t kMaxLen = 256;
6839     char* version = new char[kMaxLen + 1];
6840     snprintf(version, kMaxLen, "Perfetto %s (%s)", PERFETTO_VERSION_STRING(),
6841              PERFETTO_VERSION_SCM_REVISION());
6842     return version;
6843   }();
6844   return version_str;
6845 }
6846 
6847 }  // namespace base
6848 }  // namespace perfetto
6849 // gen_amalgamated begin source: src/base/virtual_destructors.cc
6850 /*
6851  * Copyright (C) 2017 The Android Open Source Project
6852  *
6853  * Licensed under the Apache License, Version 2.0 (the "License");
6854  * you may not use this file except in compliance with the License.
6855  * You may obtain a copy of the License at
6856  *
6857  *      http://www.apache.org/licenses/LICENSE-2.0
6858  *
6859  * Unless required by applicable law or agreed to in writing, software
6860  * distributed under the License is distributed on an "AS IS" BASIS,
6861  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
6862  * See the License for the specific language governing permissions and
6863  * limitations under the License.
6864  */
6865 
6866 // gen_amalgamated expanded: #include "perfetto/base/task_runner.h"
6867 
6868 // This translation unit contains the definitions for the destructor of pure
6869 // virtual interfaces for the current build target. The alternative would be
6870 // introducing a one-liner .cc file for each pure virtual interface, which is
6871 // overkill. This is for compliance with -Wweak-vtables.
6872 
6873 namespace perfetto {
6874 namespace base {
6875 
6876 TaskRunner::~TaskRunner() = default;
6877 
6878 }  // namespace base
6879 }  // namespace perfetto
6880 // gen_amalgamated begin source: src/base/waitable_event.cc
6881 // gen_amalgamated begin header: include/perfetto/ext/base/waitable_event.h
6882 /*
6883  * Copyright (C) 2019 The Android Open Source Project
6884  *
6885  * Licensed under the Apache License, Version 2.0 (the "License");
6886  * you may not use this file except in compliance with the License.
6887  * You may obtain a copy of the License at
6888  *
6889  *      http://www.apache.org/licenses/LICENSE-2.0
6890  *
6891  * Unless required by applicable law or agreed to in writing, software
6892  * distributed under the License is distributed on an "AS IS" BASIS,
6893  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
6894  * See the License for the specific language governing permissions and
6895  * limitations under the License.
6896  */
6897 
6898 #ifndef INCLUDE_PERFETTO_EXT_BASE_WAITABLE_EVENT_H_
6899 #define INCLUDE_PERFETTO_EXT_BASE_WAITABLE_EVENT_H_
6900 
6901 #include <condition_variable>
6902 #include <mutex>
6903 
6904 namespace perfetto {
6905 namespace base {
6906 
6907 // A waitable event for cross-thread synchronization.
6908 // All methods on this class can be called from any thread.
6909 class WaitableEvent {
6910  public:
6911   WaitableEvent();
6912   ~WaitableEvent();
6913   WaitableEvent(const WaitableEvent&) = delete;
6914   WaitableEvent operator=(const WaitableEvent&) = delete;
6915 
6916   // Synchronously block until the event is notified.
6917   void Wait();
6918 
6919   // Signal the event, waking up blocked waiters.
6920   void Notify();
6921 
6922  private:
6923   std::mutex mutex_;
6924   std::condition_variable event_;
6925   bool notified_ = false;
6926 };
6927 
6928 }  // namespace base
6929 }  // namespace perfetto
6930 
6931 #endif  // INCLUDE_PERFETTO_EXT_BASE_WAITABLE_EVENT_H_
6932 /*
6933  * Copyright (C) 2019 The Android Open Source Project
6934  *
6935  * Licensed under the Apache License, Version 2.0 (the "License");
6936  * you may not use this file except in compliance with the License.
6937  * You may obtain a copy of the License at
6938  *
6939  *      http://www.apache.org/licenses/LICENSE-2.0
6940  *
6941  * Unless required by applicable law or agreed to in writing, software
6942  * distributed under the License is distributed on an "AS IS" BASIS,
6943  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
6944  * See the License for the specific language governing permissions and
6945  * limitations under the License.
6946  */
6947 
6948 // gen_amalgamated expanded: #include "perfetto/ext/base/waitable_event.h"
6949 
6950 namespace perfetto {
6951 namespace base {
6952 
6953 WaitableEvent::WaitableEvent() = default;
6954 WaitableEvent::~WaitableEvent() = default;
6955 
Wait()6956 void WaitableEvent::Wait() {
6957   std::unique_lock<std::mutex> lock(mutex_);
6958   return event_.wait(lock, [this] { return notified_; });
6959 }
6960 
Notify()6961 void WaitableEvent::Notify() {
6962   std::unique_lock<std::mutex> lock(mutex_);
6963   notified_ = true;
6964   event_.notify_all();
6965 }
6966 
6967 }  // namespace base
6968 }  // namespace perfetto
6969 // gen_amalgamated begin source: src/base/watchdog_posix.cc
6970 // gen_amalgamated begin header: include/perfetto/ext/base/watchdog.h
6971 // gen_amalgamated begin header: include/perfetto/ext/base/watchdog_noop.h
6972 /*
6973  * Copyright (C) 2018 The Android Open Source Project
6974  *
6975  * Licensed under the Apache License, Version 2.0 (the "License");
6976  * you may not use this file except in compliance with the License.
6977  * You may obtain a copy of the License at
6978  *
6979  *      http://www.apache.org/licenses/LICENSE-2.0
6980  *
6981  * Unless required by applicable law or agreed to in writing, software
6982  * distributed under the License is distributed on an "AS IS" BASIS,
6983  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
6984  * See the License for the specific language governing permissions and
6985  * limitations under the License.
6986  */
6987 
6988 #ifndef INCLUDE_PERFETTO_EXT_BASE_WATCHDOG_NOOP_H_
6989 #define INCLUDE_PERFETTO_EXT_BASE_WATCHDOG_NOOP_H_
6990 
6991 #include <stdint.h>
6992 
6993 namespace perfetto {
6994 namespace base {
6995 
6996 enum class WatchdogCrashReason;  // Defined in watchdog.h.
6997 
6998 class Watchdog {
6999  public:
7000   class Timer {
7001    public:
7002     // Define an empty dtor to avoid "unused variable" errors on the call site.
Timer()7003     Timer() {}
Timer(const Timer &)7004     Timer(const Timer&) {}
~Timer()7005     ~Timer() {}
7006   };
GetInstance()7007   static Watchdog* GetInstance() {
7008     static Watchdog* watchdog = new Watchdog();
7009     return watchdog;
7010   }
CreateFatalTimer(uint32_t,WatchdogCrashReason)7011   Timer CreateFatalTimer(uint32_t /*ms*/, WatchdogCrashReason) {
7012     return Timer();
7013   }
Start()7014   void Start() {}
SetMemoryLimit(uint64_t,uint32_t)7015   void SetMemoryLimit(uint64_t /*bytes*/, uint32_t /*window_ms*/) {}
SetCpuLimit(uint32_t,uint32_t)7016   void SetCpuLimit(uint32_t /*percentage*/, uint32_t /*window_ms*/) {}
7017 };
7018 
7019 }  // namespace base
7020 }  // namespace perfetto
7021 
7022 #endif  // INCLUDE_PERFETTO_EXT_BASE_WATCHDOG_NOOP_H_
7023 /*
7024  * Copyright (C) 2018 The Android Open Source Project
7025  *
7026  * Licensed under the Apache License, Version 2.0 (the "License");
7027  * you may not use this file except in compliance with the License.
7028  * You may obtain a copy of the License at
7029  *
7030  *      http://www.apache.org/licenses/LICENSE-2.0
7031  *
7032  * Unless required by applicable law or agreed to in writing, software
7033  * distributed under the License is distributed on an "AS IS" BASIS,
7034  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
7035  * See the License for the specific language governing permissions and
7036  * limitations under the License.
7037  */
7038 
7039 #ifndef INCLUDE_PERFETTO_EXT_BASE_WATCHDOG_H_
7040 #define INCLUDE_PERFETTO_EXT_BASE_WATCHDOG_H_
7041 
7042 #include <functional>
7043 
7044 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
7045 
7046 // The POSIX watchdog is only supported on Linux and Android in non-embedder
7047 // builds.
7048 #if PERFETTO_BUILDFLAG(PERFETTO_WATCHDOG)
7049 // gen_amalgamated expanded: #include "perfetto/ext/base/watchdog_posix.h"
7050 #else
7051 // gen_amalgamated expanded: #include "perfetto/ext/base/watchdog_noop.h"
7052 #endif
7053 
7054 namespace perfetto {
7055 namespace base {
7056 
7057 // Used only to add more details to crash reporting.
7058 enum class WatchdogCrashReason {
7059   kUnspecified = 0,
7060   kCpuGuardrail = 1,
7061   kMemGuardrail = 2,
7062   kTaskRunnerHung = 3,
7063   kTraceDidntStop = 4,
7064 };
7065 
7066 // Make the limits more relaxed on desktop, where multi-GB traces are likely.
7067 // Multi-GB traces can take bursts of cpu time to write into disk at the end of
7068 // the trace.
7069 #if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
7070 constexpr uint32_t kWatchdogDefaultCpuLimit = 75;
7071 constexpr uint32_t kWatchdogDefaultCpuWindow = 5 * 60 * 1000;  // 5 minutes.
7072 #else
7073 constexpr uint32_t kWatchdogDefaultCpuLimit = 90;
7074 constexpr uint32_t kWatchdogDefaultCpuWindow = 10 * 60 * 1000;  // 10 minutes.
7075 #endif
7076 
7077 // The default memory margin we give to our processes. This is used as as a
7078 // constant to put on top of the trace buffers.
7079 constexpr uint64_t kWatchdogDefaultMemorySlack = 32 * 1024 * 1024;  // 32 MiB.
7080 constexpr uint32_t kWatchdogDefaultMemoryWindow = 30 * 1000;  // 30 seconds.
7081 
RunTaskWithWatchdogGuard(const std::function<void ()> & task)7082 inline void RunTaskWithWatchdogGuard(const std::function<void()>& task) {
7083   // Maximum time a single task can take in a TaskRunner before the
7084   // program suicides.
7085   constexpr int64_t kWatchdogMillis = 30000;  // 30s
7086 
7087   Watchdog::Timer handle = base::Watchdog::GetInstance()->CreateFatalTimer(
7088       kWatchdogMillis, WatchdogCrashReason::kTaskRunnerHung);
7089   task();
7090 
7091   // Suppress unused variable warnings in the client library amalgamated build.
7092   (void)kWatchdogDefaultCpuLimit;
7093   (void)kWatchdogDefaultCpuWindow;
7094   (void)kWatchdogDefaultMemorySlack;
7095   (void)kWatchdogDefaultMemoryWindow;
7096 }
7097 
7098 }  // namespace base
7099 }  // namespace perfetto
7100 
7101 #endif  // INCLUDE_PERFETTO_EXT_BASE_WATCHDOG_H_
7102 /*
7103  * Copyright (C) 2018 The Android Open Source Project
7104  *
7105  * Licensed under the Apache License, Version 2.0 (the "License");
7106  * you may not use this file except in compliance with the License.
7107  * You may obtain a copy of the License at
7108  *
7109  *      http://www.apache.org/licenses/LICENSE-2.0
7110  *
7111  * Unless required by applicable law or agreed to in writing, software
7112  * distributed under the License is distributed on an "AS IS" BASIS,
7113  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
7114  * See the License for the specific language governing permissions and
7115  * limitations under the License.
7116  */
7117 
7118 // gen_amalgamated expanded: #include "perfetto/ext/base/watchdog.h"
7119 
7120 #if PERFETTO_BUILDFLAG(PERFETTO_WATCHDOG)
7121 
7122 #include <fcntl.h>
7123 #include <poll.h>
7124 #include <signal.h>
7125 #include <stdint.h>
7126 #include <stdlib.h>
7127 #include <sys/syscall.h>
7128 #include <sys/timerfd.h>
7129 #include <unistd.h>
7130 
7131 #include <algorithm>
7132 #include <cinttypes>
7133 #include <fstream>
7134 #include <thread>
7135 
7136 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
7137 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
7138 // gen_amalgamated expanded: #include "perfetto/base/thread_utils.h"
7139 // gen_amalgamated expanded: #include "perfetto/base/time.h"
7140 // gen_amalgamated expanded: #include "perfetto/ext/base/crash_keys.h"
7141 // gen_amalgamated expanded: #include "perfetto/ext/base/file_utils.h"
7142 // gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"
7143 // gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
7144 
7145 namespace perfetto {
7146 namespace base {
7147 
7148 namespace {
7149 
7150 constexpr uint32_t kDefaultPollingInterval = 30 * 1000;
7151 
7152 base::CrashKey g_crash_key_reason("wdog_reason");
7153 
7154 // TODO(primiano): for debugging b/191600928. Remove in Jan 2022.
7155 base::CrashKey g_crash_key_mono("wdog_mono");
7156 base::CrashKey g_crash_key_boot("wdog_boot");
7157 
IsMultipleOf(uint32_t number,uint32_t divisor)7158 bool IsMultipleOf(uint32_t number, uint32_t divisor) {
7159   return number >= divisor && number % divisor == 0;
7160 }
7161 
MeanForArray(const uint64_t array[],size_t size)7162 double MeanForArray(const uint64_t array[], size_t size) {
7163   uint64_t total = 0;
7164   for (size_t i = 0; i < size; i++) {
7165     total += array[i];
7166   }
7167   return static_cast<double>(total / size);
7168 }
7169 
7170 }  //  namespace
7171 
ReadProcStat(int fd,ProcStat * out)7172 bool ReadProcStat(int fd, ProcStat* out) {
7173   char c[512];
7174   size_t c_pos = 0;
7175   while (c_pos < sizeof(c) - 1) {
7176     ssize_t rd = PERFETTO_EINTR(read(fd, c + c_pos, sizeof(c) - c_pos));
7177     if (rd < 0) {
7178       PERFETTO_ELOG("Failed to read stat file to enforce resource limits.");
7179       return false;
7180     }
7181     if (rd == 0)
7182       break;
7183     c_pos += static_cast<size_t>(rd);
7184   }
7185   PERFETTO_CHECK(c_pos < sizeof(c));
7186   c[c_pos] = '\0';
7187 
7188   if (sscanf(c,
7189              "%*d %*s %*c %*d %*d %*d %*d %*d %*u %*u %*u %*u %*u %lu "
7190              "%lu %*d %*d %*d %*d %*d %*d %*u %*u %ld",
7191              &out->utime, &out->stime, &out->rss_pages) != 3) {
7192     PERFETTO_ELOG("Invalid stat format: %s", c);
7193     return false;
7194   }
7195   return true;
7196 }
7197 
Watchdog(uint32_t polling_interval_ms)7198 Watchdog::Watchdog(uint32_t polling_interval_ms)
7199     : polling_interval_ms_(polling_interval_ms) {}
7200 
~Watchdog()7201 Watchdog::~Watchdog() {
7202   if (!thread_.joinable()) {
7203     PERFETTO_DCHECK(!enabled_);
7204     return;
7205   }
7206   PERFETTO_DCHECK(enabled_);
7207   enabled_ = false;
7208 
7209   // Rearm the timer to 1ns from now. This will cause the watchdog thread to
7210   // wakeup from the poll() and see |enabled_| == false.
7211   // This code path is used only in tests. In production code the watchdog is
7212   // a singleton and is never destroyed.
7213   struct itimerspec ts {};
7214   ts.it_value.tv_sec = 0;
7215   ts.it_value.tv_nsec = 1;
7216   timerfd_settime(*timer_fd_, /*flags=*/0, &ts, nullptr);
7217 
7218   thread_.join();
7219 }
7220 
GetInstance()7221 Watchdog* Watchdog::GetInstance() {
7222   static Watchdog* watchdog = new Watchdog(kDefaultPollingInterval);
7223   return watchdog;
7224 }
7225 
7226 // Can be called from any thread.
CreateFatalTimer(uint32_t ms,WatchdogCrashReason crash_reason)7227 Watchdog::Timer Watchdog::CreateFatalTimer(uint32_t ms,
7228                                            WatchdogCrashReason crash_reason) {
7229   if (!enabled_.load(std::memory_order_relaxed))
7230     return Watchdog::Timer(this, 0, crash_reason);
7231 
7232   return Watchdog::Timer(this, ms, crash_reason);
7233 }
7234 
7235 // Can be called from any thread.
AddFatalTimer(TimerData timer)7236 void Watchdog::AddFatalTimer(TimerData timer) {
7237   std::lock_guard<std::mutex> guard(mutex_);
7238   timers_.emplace_back(std::move(timer));
7239   RearmTimerFd_Locked();
7240 }
7241 
7242 // Can be called from any thread.
RemoveFatalTimer(TimerData timer)7243 void Watchdog::RemoveFatalTimer(TimerData timer) {
7244   std::lock_guard<std::mutex> guard(mutex_);
7245   for (auto it = timers_.begin(); it != timers_.end(); it++) {
7246     if (*it == timer) {
7247       timers_.erase(it);
7248       break;  // Remove only one. Doesn't matter which one.
7249     }
7250   }
7251   RearmTimerFd_Locked();
7252 }
7253 
RearmTimerFd_Locked()7254 void Watchdog::RearmTimerFd_Locked() {
7255   if (!enabled_)
7256     return;
7257   auto it = std::min_element(timers_.begin(), timers_.end());
7258 
7259   // We use one timerfd to handle all the oustanding |timers_|. Keep it armed
7260   // to the task expiring soonest.
7261   struct itimerspec ts {};
7262   if (it != timers_.end()) {
7263     ts.it_value = ToPosixTimespec(it->deadline);
7264   }
7265   // If |timers_| is empty (it == end()) |ts.it_value| will remain
7266   // zero-initialized and that will disarm the timer in the call below.
7267   int res = timerfd_settime(*timer_fd_, TFD_TIMER_ABSTIME, &ts, nullptr);
7268   PERFETTO_DCHECK(res == 0);
7269 }
7270 
Start()7271 void Watchdog::Start() {
7272   std::lock_guard<std::mutex> guard(mutex_);
7273   if (thread_.joinable()) {
7274     PERFETTO_DCHECK(enabled_);
7275   } else {
7276     PERFETTO_DCHECK(!enabled_);
7277 
7278 #if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
7279     PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
7280     // Kick the thread to start running but only on Android or Linux.
7281     timer_fd_.reset(
7282         timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC | TFD_NONBLOCK));
7283     if (!timer_fd_) {
7284       PERFETTO_PLOG(
7285           "timerfd_create failed, the Perfetto watchdog is not available");
7286       return;
7287     }
7288     enabled_ = true;
7289     RearmTimerFd_Locked();  // Deal with timers created before Start().
7290     thread_ = std::thread(&Watchdog::ThreadMain, this);
7291 #endif
7292   }
7293 }
7294 
SetMemoryLimit(uint64_t bytes,uint32_t window_ms)7295 void Watchdog::SetMemoryLimit(uint64_t bytes, uint32_t window_ms) {
7296   // Update the fields under the lock.
7297   std::lock_guard<std::mutex> guard(mutex_);
7298 
7299   PERFETTO_CHECK(IsMultipleOf(window_ms, polling_interval_ms_) || bytes == 0);
7300 
7301   size_t size = bytes == 0 ? 0 : window_ms / polling_interval_ms_ + 1;
7302   memory_window_bytes_.Reset(size);
7303   memory_limit_bytes_ = bytes;
7304 }
7305 
SetCpuLimit(uint32_t percentage,uint32_t window_ms)7306 void Watchdog::SetCpuLimit(uint32_t percentage, uint32_t window_ms) {
7307   std::lock_guard<std::mutex> guard(mutex_);
7308 
7309   PERFETTO_CHECK(percentage <= 100);
7310   PERFETTO_CHECK(IsMultipleOf(window_ms, polling_interval_ms_) ||
7311                  percentage == 0);
7312 
7313   size_t size = percentage == 0 ? 0 : window_ms / polling_interval_ms_ + 1;
7314   cpu_window_time_ticks_.Reset(size);
7315   cpu_limit_percentage_ = percentage;
7316 }
7317 
ThreadMain()7318 void Watchdog::ThreadMain() {
7319   // Register crash keys explicitly to avoid running out of slots at crash time.
7320   g_crash_key_reason.Register();
7321   g_crash_key_boot.Register();
7322   g_crash_key_mono.Register();
7323 
7324   base::ScopedFile stat_fd(base::OpenFile("/proc/self/stat", O_RDONLY));
7325   if (!stat_fd) {
7326     PERFETTO_ELOG("Failed to open stat file to enforce resource limits.");
7327     return;
7328   }
7329 
7330   PERFETTO_DCHECK(timer_fd_);
7331 
7332   constexpr uint8_t kFdCount = 1;
7333   struct pollfd fds[kFdCount]{};
7334   fds[0].fd = *timer_fd_;
7335   fds[0].events = POLLIN;
7336 
7337   for (;;) {
7338     // We use the poll() timeout to drive the periodic ticks for the cpu/memory
7339     // checks. The only other case when the poll() unblocks is when we crash
7340     // (or have to quit via enabled_ == false, but that happens only in tests).
7341     auto ret = poll(fds, kFdCount, static_cast<int>(polling_interval_ms_));
7342     if (!enabled_)
7343       return;
7344     if (ret < 0) {
7345       if (errno == ENOMEM || errno == EINTR) {
7346         // Should happen extremely rarely.
7347         std::this_thread::sleep_for(std::chrono::milliseconds(100));
7348         continue;
7349       }
7350       PERFETTO_FATAL("watchdog poll() failed");
7351     }
7352 
7353     // If we get here either:
7354     // 1. poll() timed out, in which case we should process cpu/mem guardrails.
7355     // 2. A timer expired, in which case we shall crash.
7356 
7357     uint64_t expired = 0;  // Must be exactly 8 bytes.
7358     auto res = PERFETTO_EINTR(read(*timer_fd_, &expired, sizeof(expired)));
7359     PERFETTO_DCHECK((res < 0 && (errno == EAGAIN)) ||
7360                     (res == sizeof(expired) && expired > 0));
7361     const auto now = GetWallTimeMs();
7362 
7363     // Check if any of the timers expired.
7364     int tid_to_kill = 0;
7365     WatchdogCrashReason crash_reason{};
7366     std::unique_lock<std::mutex> guard(mutex_);
7367     for (const auto& timer : timers_) {
7368       if (now >= timer.deadline) {
7369         tid_to_kill = timer.thread_id;
7370         crash_reason = timer.crash_reason;
7371         break;
7372       }
7373     }
7374     guard.unlock();
7375 
7376     if (tid_to_kill)
7377       SerializeLogsAndKillThread(tid_to_kill, crash_reason);
7378 
7379     // Check CPU and memory guardrails (if enabled).
7380     lseek(stat_fd.get(), 0, SEEK_SET);
7381     ProcStat stat;
7382     if (!ReadProcStat(stat_fd.get(), &stat))
7383       continue;
7384     uint64_t cpu_time = stat.utime + stat.stime;
7385     uint64_t rss_bytes =
7386         static_cast<uint64_t>(stat.rss_pages) * base::GetSysPageSize();
7387 
7388     bool threshold_exceeded = false;
7389     guard.lock();
7390     if (CheckMemory_Locked(rss_bytes)) {
7391       threshold_exceeded = true;
7392       crash_reason = WatchdogCrashReason::kMemGuardrail;
7393     } else if (CheckCpu_Locked(cpu_time)) {
7394       threshold_exceeded = true;
7395       crash_reason = WatchdogCrashReason::kCpuGuardrail;
7396     }
7397     guard.unlock();
7398 
7399     if (threshold_exceeded)
7400       SerializeLogsAndKillThread(getpid(), crash_reason);
7401   }
7402 }
7403 
SerializeLogsAndKillThread(int tid,WatchdogCrashReason crash_reason)7404 void Watchdog::SerializeLogsAndKillThread(int tid,
7405                                           WatchdogCrashReason crash_reason) {
7406   g_crash_key_reason.Set(static_cast<int>(crash_reason));
7407   g_crash_key_boot.Set(base::GetBootTimeS().count());
7408   g_crash_key_mono.Set(base::GetWallTimeS().count());
7409 
7410   // We are about to die. Serialize the logs into the crash buffer so the
7411   // debuggerd crash handler picks them up and attaches to the bugreport.
7412   // In the case of a PERFETTO_CHECK/PERFETTO_FATAL this is done in logging.h.
7413   // But in the watchdog case, we don't hit that codepath and must do ourselves.
7414   MaybeSerializeLastLogsForCrashReporting();
7415 
7416   // Send a SIGABRT to the thread that armed the timer. This is to see the
7417   // callstack of the thread that is stuck in a long task rather than the
7418   // watchdog thread.
7419   if (syscall(__NR_tgkill, getpid(), tid, SIGABRT) < 0) {
7420     // At this point the process must die. If for any reason the tgkill doesn't
7421     // work (e.g. the thread has disappeared), force a crash from here.
7422     abort();
7423   }
7424 
7425   if (disable_kill_failsafe_for_testing_)
7426     return;
7427 
7428   // The tgkill() above will take some milliseconds to cause a crash, as it
7429   // involves the kernel to queue the SIGABRT on the target thread (often the
7430   // main thread, which is != watchdog thread) and do a scheduling round.
7431   // If something goes wrong though (the target thread has signals masked or
7432   // is stuck in an uninterruptible+wakekill syscall) force quit from this
7433   // thread.
7434   std::this_thread::sleep_for(std::chrono::seconds(10));
7435   abort();
7436 }
7437 
CheckMemory_Locked(uint64_t rss_bytes)7438 bool Watchdog::CheckMemory_Locked(uint64_t rss_bytes) {
7439   if (memory_limit_bytes_ == 0)
7440     return false;
7441 
7442   // Add the current stat value to the ring buffer and check that the mean
7443   // remains under our threshold.
7444   if (memory_window_bytes_.Push(rss_bytes)) {
7445     if (memory_window_bytes_.Mean() >
7446         static_cast<double>(memory_limit_bytes_)) {
7447       PERFETTO_ELOG(
7448           "Memory watchdog trigger. Memory window of %f bytes is above the "
7449           "%" PRIu64 " bytes limit.",
7450           memory_window_bytes_.Mean(), memory_limit_bytes_);
7451       return true;
7452     }
7453   }
7454   return false;
7455 }
7456 
CheckCpu_Locked(uint64_t cpu_time)7457 bool Watchdog::CheckCpu_Locked(uint64_t cpu_time) {
7458   if (cpu_limit_percentage_ == 0)
7459     return false;
7460 
7461   // Add the cpu time to the ring buffer.
7462   if (cpu_window_time_ticks_.Push(cpu_time)) {
7463     // Compute the percentage over the whole window and check that it remains
7464     // under the threshold.
7465     uint64_t difference_ticks = cpu_window_time_ticks_.NewestWhenFull() -
7466                                 cpu_window_time_ticks_.OldestWhenFull();
7467     double window_interval_ticks =
7468         (static_cast<double>(WindowTimeForRingBuffer(cpu_window_time_ticks_)) /
7469          1000.0) *
7470         static_cast<double>(sysconf(_SC_CLK_TCK));
7471     double percentage = static_cast<double>(difference_ticks) /
7472                         static_cast<double>(window_interval_ticks) * 100;
7473     if (percentage > cpu_limit_percentage_) {
7474       PERFETTO_ELOG("CPU watchdog trigger. %f%% CPU use is above the %" PRIu32
7475                     "%% CPU limit.",
7476                     percentage, cpu_limit_percentage_);
7477       return true;
7478     }
7479   }
7480   return false;
7481 }
7482 
WindowTimeForRingBuffer(const WindowedInterval & window)7483 uint32_t Watchdog::WindowTimeForRingBuffer(const WindowedInterval& window) {
7484   return static_cast<uint32_t>(window.size() - 1) * polling_interval_ms_;
7485 }
7486 
Push(uint64_t sample)7487 bool Watchdog::WindowedInterval::Push(uint64_t sample) {
7488   // Add the sample to the current position in the ring buffer.
7489   buffer_[position_] = sample;
7490 
7491   // Update the position with next one circularily.
7492   position_ = (position_ + 1) % size_;
7493 
7494   // Set the filled flag the first time we wrap.
7495   filled_ = filled_ || position_ == 0;
7496   return filled_;
7497 }
7498 
Mean() const7499 double Watchdog::WindowedInterval::Mean() const {
7500   return MeanForArray(buffer_.get(), size_);
7501 }
7502 
Clear()7503 void Watchdog::WindowedInterval::Clear() {
7504   position_ = 0;
7505   buffer_.reset(new uint64_t[size_]());
7506 }
7507 
Reset(size_t new_size)7508 void Watchdog::WindowedInterval::Reset(size_t new_size) {
7509   position_ = 0;
7510   size_ = new_size;
7511   buffer_.reset(new_size == 0 ? nullptr : new uint64_t[new_size]());
7512 }
7513 
Timer(Watchdog * watchdog,uint32_t ms,WatchdogCrashReason crash_reason)7514 Watchdog::Timer::Timer(Watchdog* watchdog,
7515                        uint32_t ms,
7516                        WatchdogCrashReason crash_reason)
7517     : watchdog_(watchdog) {
7518   if (!ms)
7519     return;  // No-op timer created when the watchdog is disabled.
7520   timer_data_.deadline = GetWallTimeMs() + std::chrono::milliseconds(ms);
7521   timer_data_.thread_id = GetThreadId();
7522   timer_data_.crash_reason = crash_reason;
7523   PERFETTO_DCHECK(watchdog_);
7524   watchdog_->AddFatalTimer(timer_data_);
7525 }
7526 
~Timer()7527 Watchdog::Timer::~Timer() {
7528   if (timer_data_.deadline.count())
7529     watchdog_->RemoveFatalTimer(timer_data_);
7530 }
7531 
Timer(Timer && other)7532 Watchdog::Timer::Timer(Timer&& other) noexcept {
7533   watchdog_ = std::move(other.watchdog_);
7534   other.watchdog_ = nullptr;
7535   timer_data_ = std::move(other.timer_data_);
7536   other.timer_data_ = TimerData();
7537 }
7538 
7539 }  // namespace base
7540 }  // namespace perfetto
7541 
7542 #endif  // PERFETTO_BUILDFLAG(PERFETTO_WATCHDOG)
7543 // gen_amalgamated begin source: src/base/thread_task_runner.cc
7544 // gen_amalgamated begin header: include/perfetto/ext/base/thread_task_runner.h
7545 // gen_amalgamated begin header: include/perfetto/ext/base/unix_task_runner.h
7546 /*
7547  * Copyright (C) 2017 The Android Open Source Project
7548  *
7549  * Licensed under the Apache License, Version 2.0 (the "License");
7550  * you may not use this file except in compliance with the License.
7551  * You may obtain a copy of the License at
7552  *
7553  *      http://www.apache.org/licenses/LICENSE-2.0
7554  *
7555  * Unless required by applicable law or agreed to in writing, software
7556  * distributed under the License is distributed on an "AS IS" BASIS,
7557  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
7558  * See the License for the specific language governing permissions and
7559  * limitations under the License.
7560  */
7561 
7562 #ifndef INCLUDE_PERFETTO_EXT_BASE_UNIX_TASK_RUNNER_H_
7563 #define INCLUDE_PERFETTO_EXT_BASE_UNIX_TASK_RUNNER_H_
7564 
7565 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
7566 // gen_amalgamated expanded: #include "perfetto/base/task_runner.h"
7567 // gen_amalgamated expanded: #include "perfetto/base/thread_utils.h"
7568 // gen_amalgamated expanded: #include "perfetto/base/time.h"
7569 // gen_amalgamated expanded: #include "perfetto/ext/base/event_fd.h"
7570 // gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"
7571 // gen_amalgamated expanded: #include "perfetto/ext/base/thread_checker.h"
7572 
7573 #include <chrono>
7574 #include <deque>
7575 #include <map>
7576 #include <mutex>
7577 #include <vector>
7578 
7579 #if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
7580 #include <poll.h>
7581 #endif
7582 
7583 namespace perfetto {
7584 namespace base {
7585 
7586 // Runs a task runner on the current thread.
7587 //
7588 // Implementation note: we currently assume (and enforce in debug builds) that
7589 // Run() is called from the thread that constructed the UnixTaskRunner. This is
7590 // not strictly necessary, and we could instead track the thread that invokes
7591 // Run(). However, a related property that *might* be important to enforce is
7592 // that the destructor runs on the task-running thread. Otherwise, if there are
7593 // still-pending tasks at the time of destruction, we would destroy those
7594 // outside of the task thread (which might be unexpected to the caller). On the
7595 // other hand, the std::function task interface discourages use of any
7596 // resource-owning tasks (as the callable needs to be copyable), so this might
7597 // not be important in practice.
7598 //
7599 // TODO(rsavitski): consider adding a thread-check in the destructor, after
7600 // auditing existing usages.
7601 // TODO(primiano): rename this to TaskRunnerImpl. The "Unix" part is misleading
7602 // now as it supports also Windows.
7603 class UnixTaskRunner : public TaskRunner {
7604  public:
7605   UnixTaskRunner();
7606   ~UnixTaskRunner() override;
7607 
7608   // Start executing tasks. Doesn't return until Quit() is called. Run() may be
7609   // called multiple times on the same task runner.
7610   void Run();
7611   void Quit();
7612 
7613   // Checks whether there are any pending immediate tasks to run. Note that
7614   // delayed tasks don't count even if they are due to run.
7615   bool IsIdleForTesting();
7616 
7617   // TaskRunner implementation:
7618   void PostTask(std::function<void()>) override;
7619   void PostDelayedTask(std::function<void()>, uint32_t delay_ms) override;
7620   void AddFileDescriptorWatch(PlatformHandle, std::function<void()>) override;
7621   void RemoveFileDescriptorWatch(PlatformHandle) override;
7622   bool RunsTasksOnCurrentThread() const override;
7623 
7624   // Returns true if the task runner is quitting, or has quit and hasn't been
7625   // restarted since. Exposed primarily for ThreadTaskRunner, not necessary for
7626   // normal use of this class.
7627   bool QuitCalled();
7628 
7629  private:
7630   void WakeUp();
7631   void UpdateWatchTasksLocked();
7632   int GetDelayMsToNextTaskLocked() const;
7633   void RunImmediateAndDelayedTask();
7634   void PostFileDescriptorWatches(uint64_t windows_wait_result);
7635   void RunFileDescriptorWatch(PlatformHandle);
7636 
7637   ThreadChecker thread_checker_;
7638   PlatformThreadId created_thread_id_ = GetThreadId();
7639 
7640   EventFd event_;
7641 
7642 // The array of fds/handles passed to poll(2) / WaitForMultipleObjects().
7643 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
7644   std::vector<PlatformHandle> poll_fds_;
7645 #else
7646   std::vector<struct pollfd> poll_fds_;
7647 #endif
7648 
7649   // --- Begin lock-protected members ---
7650 
7651   std::mutex lock_;
7652 
7653   std::deque<std::function<void()>> immediate_tasks_;
7654   std::multimap<TimeMillis, std::function<void()>> delayed_tasks_;
7655   bool quit_ = false;
7656 
7657   struct WatchTask {
7658     std::function<void()> callback;
7659 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
7660     // On UNIX systems we make the FD number negative in |poll_fds_| to avoid
7661     // polling it again until the queued task runs. On Windows we can't do that.
7662     // Instead we keep track of its state here.
7663     bool pending = false;
7664 #else
7665     size_t poll_fd_index;  // Index into |poll_fds_|.
7666 #endif
7667   };
7668 
7669   std::map<PlatformHandle, WatchTask> watch_tasks_;
7670   bool watch_tasks_changed_ = false;
7671 
7672   // --- End lock-protected members ---
7673 };
7674 
7675 }  // namespace base
7676 }  // namespace perfetto
7677 
7678 #endif  // INCLUDE_PERFETTO_EXT_BASE_UNIX_TASK_RUNNER_H_
7679 /*
7680  * Copyright (C) 2019 The Android Open Source Project
7681  *
7682  * Licensed under the Apache License, Version 2.0 (the "License");
7683  * you may not use this file except in compliance with the License.
7684  * You may obtain a copy of the License at
7685  *
7686  *      http://www.apache.org/licenses/LICENSE-2.0
7687  *
7688  * Unless required by applicable law or agreed to in writing, software
7689  * distributed under the License is distributed on an "AS IS" BASIS,
7690  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
7691  * See the License for the specific language governing permissions and
7692  * limitations under the License.
7693  */
7694 
7695 #ifndef INCLUDE_PERFETTO_EXT_BASE_THREAD_TASK_RUNNER_H_
7696 #define INCLUDE_PERFETTO_EXT_BASE_THREAD_TASK_RUNNER_H_
7697 
7698 #include <functional>
7699 #include <thread>
7700 
7701 // gen_amalgamated expanded: #include "perfetto/ext/base/unix_task_runner.h"
7702 
7703 namespace perfetto {
7704 namespace base {
7705 
7706 // A UnixTaskRunner backed by a dedicated task thread. Shuts down the runner and
7707 // joins the thread upon destruction. Can be moved to transfer ownership.
7708 //
7709 // Guarantees that:
7710 // * the UnixTaskRunner will be constructed and destructed on the task thread.
7711 // * the task thread will live for the lifetime of the UnixTaskRunner.
7712 //
7713 class PERFETTO_EXPORT ThreadTaskRunner : public TaskRunner {
7714  public:
CreateAndStart(const std::string & name="")7715   static ThreadTaskRunner CreateAndStart(const std::string& name = "") {
7716     return ThreadTaskRunner(name);
7717   }
7718 
7719   ThreadTaskRunner(const ThreadTaskRunner&) = delete;
7720   ThreadTaskRunner& operator=(const ThreadTaskRunner&) = delete;
7721 
7722   ThreadTaskRunner(ThreadTaskRunner&&) noexcept;
7723   ThreadTaskRunner& operator=(ThreadTaskRunner&&);
7724   ~ThreadTaskRunner() override;
7725 
7726   // Executes the given function on the task runner thread and blocks the caller
7727   // thread until the function has run.
7728   void PostTaskAndWaitForTesting(std::function<void()>);
7729 
7730   // Can be called from another thread to get the CPU time of the thread the
7731   // task-runner is executing on.
7732   uint64_t GetThreadCPUTimeNsForTesting();
7733 
7734   // Returns a pointer to the UnixTaskRunner, which is valid for the lifetime of
7735   // this ThreadTaskRunner object (unless this object is moved-from, in which
7736   // case the pointer remains valid for the lifetime of the new owning
7737   // ThreadTaskRunner).
7738   //
7739   // Warning: do not call Quit() on the returned runner pointer, the termination
7740   // should be handled exclusively by this class' destructor.
get() const7741   UnixTaskRunner* get() const { return task_runner_; }
7742 
7743   // TaskRunner implementation.
7744   // These methods just proxy to the underlying task_runner_.
7745   void PostTask(std::function<void()>) override;
7746   void PostDelayedTask(std::function<void()>, uint32_t delay_ms) override;
7747   void AddFileDescriptorWatch(PlatformHandle, std::function<void()>) override;
7748   void RemoveFileDescriptorWatch(PlatformHandle) override;
7749   bool RunsTasksOnCurrentThread() const override;
7750 
7751  private:
7752   explicit ThreadTaskRunner(const std::string& name);
7753   void RunTaskThread(std::function<void(UnixTaskRunner*)> initializer);
7754 
7755   std::thread thread_;
7756   std::string name_;
7757   UnixTaskRunner* task_runner_ = nullptr;
7758 };
7759 
7760 }  // namespace base
7761 }  // namespace perfetto
7762 
7763 #endif  // INCLUDE_PERFETTO_EXT_BASE_THREAD_TASK_RUNNER_H_
7764 // gen_amalgamated begin header: include/perfetto/ext/base/thread_utils.h
7765 /*
7766  * Copyright (C) 2020 The Android Open Source Project
7767  *
7768  * Licensed under the Apache License, Version 2.0 (the "License");
7769  * you may not use this file except in compliance with the License.
7770  * You may obtain a copy of the License at
7771  *
7772  *      http://www.apache.org/licenses/LICENSE-2.0
7773  *
7774  * Unless required by applicable law or agreed to in writing, software
7775  * distributed under the License is distributed on an "AS IS" BASIS,
7776  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
7777  * See the License for the specific language governing permissions and
7778  * limitations under the License.
7779  */
7780 
7781 #ifndef INCLUDE_PERFETTO_EXT_BASE_THREAD_UTILS_H_
7782 #define INCLUDE_PERFETTO_EXT_BASE_THREAD_UTILS_H_
7783 
7784 #include <string>
7785 
7786 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
7787 // gen_amalgamated expanded: #include "perfetto/ext/base/string_utils.h"
7788 
7789 #if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) ||   \
7790     PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \
7791     PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
7792 #include <pthread.h>
7793 #include <string.h>
7794 #include <algorithm>
7795 #endif
7796 
7797 #if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
7798 #include <sys/prctl.h>
7799 #endif
7800 
7801 // Internal implementation utils that aren't as widely useful/supported as
7802 // base/thread_utils.h.
7803 
7804 namespace perfetto {
7805 namespace base {
7806 
7807 #if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) ||   \
7808     PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \
7809     PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
7810 // Sets the "comm" of the calling thread to the first 15 chars of the given
7811 // string.
MaybeSetThreadName(const std::string & name)7812 inline bool MaybeSetThreadName(const std::string& name) {
7813   char buf[16] = {};
7814   StringCopy(buf, name.c_str(), sizeof(buf));
7815 
7816 #if PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
7817   return pthread_setname_np(buf) == 0;
7818 #else
7819   return pthread_setname_np(pthread_self(), buf) == 0;
7820 #endif
7821 }
7822 
GetThreadName(std::string & out_result)7823 inline bool GetThreadName(std::string& out_result) {
7824   char buf[16] = {};
7825 #if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
7826   if (prctl(PR_GET_NAME, buf) != 0)
7827     return false;
7828 #else
7829   if (pthread_getname_np(pthread_self(), buf, sizeof(buf)) != 0)
7830     return false;
7831 #endif
7832   out_result = std::string(buf);
7833   return true;
7834 }
7835 
7836 #else
7837 inline bool MaybeSetThreadName(const std::string&) {
7838   return false;
7839 }
7840 inline bool GetThreadName(std::string&) {
7841   return false;
7842 }
7843 #endif
7844 
7845 }  // namespace base
7846 }  // namespace perfetto
7847 
7848 #endif  // INCLUDE_PERFETTO_EXT_BASE_THREAD_UTILS_H_
7849 /*
7850  * Copyright (C) 2019 The Android Open Source Project
7851  *
7852  * Licensed under the Apache License, Version 2.0 (the "License");
7853  * you may not use this file except in compliance with the License.
7854  * You may obtain a copy of the License at
7855  *
7856  *      http://www.apache.org/licenses/LICENSE-2.0
7857  *
7858  * Unless required by applicable law or agreed to in writing, software
7859  * distributed under the License is distributed on an "AS IS" BASIS,
7860  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
7861  * See the License for the specific language governing permissions and
7862  * limitations under the License.
7863  */
7864 
7865 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
7866 
7867 // gen_amalgamated expanded: #include "perfetto/ext/base/thread_task_runner.h"
7868 
7869 #include <condition_variable>
7870 #include <functional>
7871 #include <mutex>
7872 #include <thread>
7873 
7874 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
7875 // gen_amalgamated expanded: #include "perfetto/ext/base/thread_utils.h"
7876 // gen_amalgamated expanded: #include "perfetto/ext/base/unix_task_runner.h"
7877 
7878 #if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
7879     PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
7880 #include <sys/prctl.h>
7881 #endif
7882 
7883 namespace perfetto {
7884 namespace base {
7885 
ThreadTaskRunner(ThreadTaskRunner && other)7886 ThreadTaskRunner::ThreadTaskRunner(ThreadTaskRunner&& other) noexcept
7887     : thread_(std::move(other.thread_)), task_runner_(other.task_runner_) {
7888   other.task_runner_ = nullptr;
7889 }
7890 
operator =(ThreadTaskRunner && other)7891 ThreadTaskRunner& ThreadTaskRunner::operator=(ThreadTaskRunner&& other) {
7892   this->~ThreadTaskRunner();
7893   new (this) ThreadTaskRunner(std::move(other));
7894   return *this;
7895 }
7896 
~ThreadTaskRunner()7897 ThreadTaskRunner::~ThreadTaskRunner() {
7898   if (task_runner_) {
7899     PERFETTO_CHECK(!task_runner_->QuitCalled());
7900     task_runner_->Quit();
7901 
7902     PERFETTO_DCHECK(thread_.joinable());
7903   }
7904   if (thread_.joinable())
7905     thread_.join();
7906 }
7907 
ThreadTaskRunner(const std::string & name)7908 ThreadTaskRunner::ThreadTaskRunner(const std::string& name) : name_(name) {
7909   std::mutex init_lock;
7910   std::condition_variable init_cv;
7911 
7912   std::function<void(UnixTaskRunner*)> initializer =
7913       [this, &init_lock, &init_cv](UnixTaskRunner* task_runner) {
7914         std::lock_guard<std::mutex> lock(init_lock);
7915         task_runner_ = task_runner;
7916         // Notify while still holding the lock, as init_cv ceases to exist as
7917         // soon as the main thread observes a non-null task_runner_, and it can
7918         // wake up spuriously (i.e. before the notify if we had unlocked before
7919         // notifying).
7920         init_cv.notify_one();
7921       };
7922 
7923   thread_ = std::thread(&ThreadTaskRunner::RunTaskThread, this,
7924                         std::move(initializer));
7925 
7926   std::unique_lock<std::mutex> lock(init_lock);
7927   init_cv.wait(lock, [this] { return !!task_runner_; });
7928 }
7929 
RunTaskThread(std::function<void (UnixTaskRunner *)> initializer)7930 void ThreadTaskRunner::RunTaskThread(
7931     std::function<void(UnixTaskRunner*)> initializer) {
7932   if (!name_.empty()) {
7933     base::MaybeSetThreadName(name_);
7934   }
7935 
7936   UnixTaskRunner task_runner;
7937   task_runner.PostTask(std::bind(std::move(initializer), &task_runner));
7938   task_runner.Run();
7939 }
7940 
PostTaskAndWaitForTesting(std::function<void ()> fn)7941 void ThreadTaskRunner::PostTaskAndWaitForTesting(std::function<void()> fn) {
7942   std::mutex mutex;
7943   std::condition_variable cv;
7944 
7945   std::unique_lock<std::mutex> lock(mutex);
7946   bool done = false;
7947   task_runner_->PostTask([&mutex, &cv, &done, &fn] {
7948     fn();
7949 
7950     std::lock_guard<std::mutex> inner_lock(mutex);
7951     done = true;
7952     cv.notify_one();
7953   });
7954   cv.wait(lock, [&done] { return done; });
7955 }
7956 
GetThreadCPUTimeNsForTesting()7957 uint64_t ThreadTaskRunner::GetThreadCPUTimeNsForTesting() {
7958   uint64_t thread_time_ns = 0;
7959   PostTaskAndWaitForTesting([&thread_time_ns] {
7960     thread_time_ns = static_cast<uint64_t>(base::GetThreadCPUTimeNs().count());
7961   });
7962   return thread_time_ns;
7963 }
7964 
PostTask(std::function<void ()> task)7965 void ThreadTaskRunner::PostTask(std::function<void()> task) {
7966   task_runner_->PostTask(std::move(task));
7967 }
7968 
PostDelayedTask(std::function<void ()> task,uint32_t delay_ms)7969 void ThreadTaskRunner::PostDelayedTask(std::function<void()> task,
7970                                        uint32_t delay_ms) {
7971   task_runner_->PostDelayedTask(std::move(task), delay_ms);
7972 }
7973 
AddFileDescriptorWatch(PlatformHandle handle,std::function<void ()> watch_task)7974 void ThreadTaskRunner::AddFileDescriptorWatch(
7975     PlatformHandle handle,
7976     std::function<void()> watch_task) {
7977   task_runner_->AddFileDescriptorWatch(handle, std::move(watch_task));
7978 }
7979 
RemoveFileDescriptorWatch(PlatformHandle handle)7980 void ThreadTaskRunner::RemoveFileDescriptorWatch(PlatformHandle handle) {
7981   task_runner_->RemoveFileDescriptorWatch(handle);
7982 }
7983 
RunsTasksOnCurrentThread() const7984 bool ThreadTaskRunner::RunsTasksOnCurrentThread() const {
7985   return task_runner_->RunsTasksOnCurrentThread();
7986 }
7987 
7988 }  // namespace base
7989 }  // namespace perfetto
7990 // gen_amalgamated begin source: src/base/unix_task_runner.cc
7991 /*
7992  * Copyright (C) 2017 The Android Open Source Project
7993  *
7994  * Licensed under the Apache License, Version 2.0 (the "License");
7995  * you may not use this file except in compliance with the License.
7996  * You may obtain a copy of the License at
7997  *
7998  *      http://www.apache.org/licenses/LICENSE-2.0
7999  *
8000  * Unless required by applicable law or agreed to in writing, software
8001  * distributed under the License is distributed on an "AS IS" BASIS,
8002  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
8003  * See the License for the specific language governing permissions and
8004  * limitations under the License.
8005  */
8006 
8007 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
8008 
8009 // gen_amalgamated expanded: #include "perfetto/ext/base/unix_task_runner.h"
8010 
8011 #include <errno.h>
8012 #include <stdlib.h>
8013 
8014 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
8015 #include <Windows.h>
8016 #include <synchapi.h>
8017 #else
8018 #include <unistd.h>
8019 #endif
8020 
8021 #include <algorithm>
8022 #include <limits>
8023 
8024 // gen_amalgamated expanded: #include "perfetto/ext/base/watchdog.h"
8025 
8026 namespace perfetto {
8027 namespace base {
8028 
UnixTaskRunner()8029 UnixTaskRunner::UnixTaskRunner() {
8030   AddFileDescriptorWatch(event_.fd(), [] {
8031     // Not reached -- see PostFileDescriptorWatches().
8032     PERFETTO_DFATAL("Should be unreachable.");
8033   });
8034 }
8035 
8036 UnixTaskRunner::~UnixTaskRunner() = default;
8037 
WakeUp()8038 void UnixTaskRunner::WakeUp() {
8039   event_.Notify();
8040 }
8041 
Run()8042 void UnixTaskRunner::Run() {
8043   PERFETTO_DCHECK_THREAD(thread_checker_);
8044   created_thread_id_ = GetThreadId();
8045   quit_ = false;
8046   for (;;) {
8047     int poll_timeout_ms;
8048     {
8049       std::lock_guard<std::mutex> lock(lock_);
8050       if (quit_)
8051         return;
8052       poll_timeout_ms = GetDelayMsToNextTaskLocked();
8053       UpdateWatchTasksLocked();
8054     }
8055 
8056 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
8057     DWORD timeout =
8058         poll_timeout_ms >= 0 ? static_cast<DWORD>(poll_timeout_ms) : INFINITE;
8059     DWORD ret =
8060         WaitForMultipleObjects(static_cast<DWORD>(poll_fds_.size()),
8061                                &poll_fds_[0], /*bWaitAll=*/false, timeout);
8062     // Unlike poll(2), WaitForMultipleObjects() returns only *one* handle in the
8063     // set, even when >1 is signalled. In order to avoid starvation,
8064     // PostFileDescriptorWatches() will WaitForSingleObject() each other handle
8065     // to ensure fairness. |ret| here is passed just to avoid an extra
8066     // WaitForSingleObject() for the one handle that WaitForMultipleObject()
8067     // returned.
8068     PostFileDescriptorWatches(ret);
8069 #else
8070     int ret = PERFETTO_EINTR(poll(
8071         &poll_fds_[0], static_cast<nfds_t>(poll_fds_.size()), poll_timeout_ms));
8072     PERFETTO_CHECK(ret >= 0);
8073     PostFileDescriptorWatches(0 /*ignored*/);
8074 #endif
8075 
8076     // To avoid starvation we always interleave all types of tasks -- immediate,
8077     // delayed and file descriptor watches.
8078     RunImmediateAndDelayedTask();
8079   }
8080 }
8081 
Quit()8082 void UnixTaskRunner::Quit() {
8083   std::lock_guard<std::mutex> lock(lock_);
8084   quit_ = true;
8085   WakeUp();
8086 }
8087 
QuitCalled()8088 bool UnixTaskRunner::QuitCalled() {
8089   std::lock_guard<std::mutex> lock(lock_);
8090   return quit_;
8091 }
8092 
IsIdleForTesting()8093 bool UnixTaskRunner::IsIdleForTesting() {
8094   std::lock_guard<std::mutex> lock(lock_);
8095   return immediate_tasks_.empty();
8096 }
8097 
UpdateWatchTasksLocked()8098 void UnixTaskRunner::UpdateWatchTasksLocked() {
8099   PERFETTO_DCHECK_THREAD(thread_checker_);
8100 #if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
8101   if (!watch_tasks_changed_)
8102     return;
8103   watch_tasks_changed_ = false;
8104 #endif
8105   poll_fds_.clear();
8106   for (auto& it : watch_tasks_) {
8107     PlatformHandle handle = it.first;
8108     WatchTask& watch_task = it.second;
8109 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
8110     if (!watch_task.pending)
8111       poll_fds_.push_back(handle);
8112 #else
8113     watch_task.poll_fd_index = poll_fds_.size();
8114     poll_fds_.push_back({handle, POLLIN | POLLHUP, 0});
8115 #endif
8116   }
8117 }
8118 
RunImmediateAndDelayedTask()8119 void UnixTaskRunner::RunImmediateAndDelayedTask() {
8120   // If locking overhead becomes an issue, add a separate work queue.
8121   std::function<void()> immediate_task;
8122   std::function<void()> delayed_task;
8123   TimeMillis now = GetWallTimeMs();
8124   {
8125     std::lock_guard<std::mutex> lock(lock_);
8126     if (!immediate_tasks_.empty()) {
8127       immediate_task = std::move(immediate_tasks_.front());
8128       immediate_tasks_.pop_front();
8129     }
8130     if (!delayed_tasks_.empty()) {
8131       auto it = delayed_tasks_.begin();
8132       if (now >= it->first) {
8133         delayed_task = std::move(it->second);
8134         delayed_tasks_.erase(it);
8135       }
8136     }
8137   }
8138 
8139   errno = 0;
8140   if (immediate_task)
8141     RunTaskWithWatchdogGuard(immediate_task);
8142   errno = 0;
8143   if (delayed_task)
8144     RunTaskWithWatchdogGuard(delayed_task);
8145 }
8146 
PostFileDescriptorWatches(uint64_t windows_wait_result)8147 void UnixTaskRunner::PostFileDescriptorWatches(uint64_t windows_wait_result) {
8148   PERFETTO_DCHECK_THREAD(thread_checker_);
8149   for (size_t i = 0; i < poll_fds_.size(); i++) {
8150 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
8151     const PlatformHandle handle = poll_fds_[i];
8152     // |windows_wait_result| is the result of WaitForMultipleObjects() call. If
8153     // one of the objects was signalled, it will have a value between
8154     // [0, poll_fds_.size()].
8155     if (i != windows_wait_result &&
8156         WaitForSingleObject(handle, 0) != WAIT_OBJECT_0) {
8157       continue;
8158     }
8159 #else
8160     base::ignore_result(windows_wait_result);
8161     const PlatformHandle handle = poll_fds_[i].fd;
8162     if (!(poll_fds_[i].revents & (POLLIN | POLLHUP)))
8163       continue;
8164     poll_fds_[i].revents = 0;
8165 #endif
8166 
8167     // The wake-up event is handled inline to avoid an infinite recursion of
8168     // posted tasks.
8169     if (handle == event_.fd()) {
8170       event_.Clear();
8171       continue;
8172     }
8173 
8174     // Binding to |this| is safe since we are the only object executing the
8175     // task.
8176     PostTask(std::bind(&UnixTaskRunner::RunFileDescriptorWatch, this, handle));
8177 
8178     // Flag the task as pending.
8179 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
8180     // On Windows this is done by marking the WatchTask entry as pending. This
8181     // is more expensive than Linux as requires rebuilding the |poll_fds_|
8182     // vector on each call. There doesn't seem to be a good alternative though.
8183     auto it = watch_tasks_.find(handle);
8184     PERFETTO_CHECK(it != watch_tasks_.end());
8185     PERFETTO_DCHECK(!it->second.pending);
8186     it->second.pending = true;
8187 #else
8188     // On UNIX systems instead, we just make the fd negative while its task is
8189     // pending. This makes poll(2) ignore the fd.
8190     PERFETTO_DCHECK(poll_fds_[i].fd >= 0);
8191     poll_fds_[i].fd = -poll_fds_[i].fd;
8192 #endif
8193   }
8194 }
8195 
RunFileDescriptorWatch(PlatformHandle fd)8196 void UnixTaskRunner::RunFileDescriptorWatch(PlatformHandle fd) {
8197   std::function<void()> task;
8198   {
8199     std::lock_guard<std::mutex> lock(lock_);
8200     auto it = watch_tasks_.find(fd);
8201     if (it == watch_tasks_.end())
8202       return;
8203     WatchTask& watch_task = it->second;
8204 
8205     // Make poll(2) pay attention to the fd again. Since another thread may have
8206     // updated this watch we need to refresh the set first.
8207     UpdateWatchTasksLocked();
8208 
8209 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
8210     // On Windows we manually track the presence of outstanding tasks for the
8211     // watch. The UpdateWatchTasksLocked() in the Run() loop will re-add the
8212     // task to the |poll_fds_| vector.
8213     PERFETTO_DCHECK(watch_task.pending);
8214     watch_task.pending = false;
8215 #else
8216     size_t fd_index = watch_task.poll_fd_index;
8217     PERFETTO_DCHECK(fd_index < poll_fds_.size());
8218     PERFETTO_DCHECK(::abs(poll_fds_[fd_index].fd) == fd);
8219     poll_fds_[fd_index].fd = fd;
8220 #endif
8221     task = watch_task.callback;
8222   }
8223   errno = 0;
8224   RunTaskWithWatchdogGuard(task);
8225 }
8226 
GetDelayMsToNextTaskLocked() const8227 int UnixTaskRunner::GetDelayMsToNextTaskLocked() const {
8228   PERFETTO_DCHECK_THREAD(thread_checker_);
8229   if (!immediate_tasks_.empty())
8230     return 0;
8231   if (!delayed_tasks_.empty()) {
8232     TimeMillis diff = delayed_tasks_.begin()->first - GetWallTimeMs();
8233     return std::max(0, static_cast<int>(diff.count()));
8234   }
8235   return -1;
8236 }
8237 
PostTask(std::function<void ()> task)8238 void UnixTaskRunner::PostTask(std::function<void()> task) {
8239   bool was_empty;
8240   {
8241     std::lock_guard<std::mutex> lock(lock_);
8242     was_empty = immediate_tasks_.empty();
8243     immediate_tasks_.push_back(std::move(task));
8244   }
8245   if (was_empty)
8246     WakeUp();
8247 }
8248 
PostDelayedTask(std::function<void ()> task,uint32_t delay_ms)8249 void UnixTaskRunner::PostDelayedTask(std::function<void()> task,
8250                                      uint32_t delay_ms) {
8251   TimeMillis runtime = GetWallTimeMs() + TimeMillis(delay_ms);
8252   {
8253     std::lock_guard<std::mutex> lock(lock_);
8254     delayed_tasks_.insert(std::make_pair(runtime, std::move(task)));
8255   }
8256   WakeUp();
8257 }
8258 
AddFileDescriptorWatch(PlatformHandle fd,std::function<void ()> task)8259 void UnixTaskRunner::AddFileDescriptorWatch(PlatformHandle fd,
8260                                             std::function<void()> task) {
8261   PERFETTO_DCHECK(PlatformHandleChecker::IsValid(fd));
8262   {
8263     std::lock_guard<std::mutex> lock(lock_);
8264     PERFETTO_DCHECK(!watch_tasks_.count(fd));
8265     WatchTask& watch_task = watch_tasks_[fd];
8266     watch_task.callback = std::move(task);
8267 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
8268     watch_task.pending = false;
8269 #else
8270     watch_task.poll_fd_index = SIZE_MAX;
8271 #endif
8272     watch_tasks_changed_ = true;
8273   }
8274   WakeUp();
8275 }
8276 
RemoveFileDescriptorWatch(PlatformHandle fd)8277 void UnixTaskRunner::RemoveFileDescriptorWatch(PlatformHandle fd) {
8278   PERFETTO_DCHECK(PlatformHandleChecker::IsValid(fd));
8279   {
8280     std::lock_guard<std::mutex> lock(lock_);
8281     PERFETTO_DCHECK(watch_tasks_.count(fd));
8282     watch_tasks_.erase(fd);
8283     watch_tasks_changed_ = true;
8284   }
8285   // No need to schedule a wake-up for this.
8286 }
8287 
RunsTasksOnCurrentThread() const8288 bool UnixTaskRunner::RunsTasksOnCurrentThread() const {
8289   return GetThreadId() == created_thread_id_;
8290 }
8291 
8292 }  // namespace base
8293 }  // namespace perfetto
8294 // gen_amalgamated begin source: src/base/subprocess.cc
8295 // gen_amalgamated begin header: include/perfetto/ext/base/subprocess.h
8296 /*
8297  * Copyright (C) 2020 The Android Open Source Project
8298  *
8299  * Licensed under the Apache License, Version 2.0 (the "License");
8300  * you may not use this file except in compliance with the License.
8301  * You may obtain a copy of the License at
8302  *
8303  *      http://www.apache.org/licenses/LICENSE-2.0
8304  *
8305  * Unless required by applicable law or agreed to in writing, software
8306  * distributed under the License is distributed on an "AS IS" BASIS,
8307  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
8308  * See the License for the specific language governing permissions and
8309  * limitations under the License.
8310  */
8311 
8312 #ifndef INCLUDE_PERFETTO_EXT_BASE_SUBPROCESS_H_
8313 #define INCLUDE_PERFETTO_EXT_BASE_SUBPROCESS_H_
8314 
8315 #include <condition_variable>
8316 #include <functional>
8317 #include <initializer_list>
8318 #include <mutex>
8319 #include <string>
8320 #include <thread>
8321 #include <vector>
8322 
8323 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
8324 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
8325 // gen_amalgamated expanded: #include "perfetto/base/platform_handle.h"
8326 // gen_amalgamated expanded: #include "perfetto/base/proc_utils.h"
8327 // gen_amalgamated expanded: #include "perfetto/ext/base/event_fd.h"
8328 // gen_amalgamated expanded: #include "perfetto/ext/base/optional.h"
8329 // gen_amalgamated expanded: #include "perfetto/ext/base/pipe.h"
8330 // gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"
8331 
8332 namespace perfetto {
8333 namespace base {
8334 
8335 // Handles creation and lifecycle management of subprocesses, taking care of
8336 // all subtleties involved in handling processes on UNIX.
8337 // This class allows to deal with macro two use-cases:
8338 // 1) fork() + exec() equivalent: for spawning a brand new process image.
8339 //    This happens when |args.exec_cmd| is not empty.
8340 //    This is safe to use even in a multi-threaded environment.
8341 // 2) fork(): for spawning a process and running a function.
8342 //    This happens when |args.posix_entrypoint_for_testing| is not empty.
8343 //    This is intended only for tests as it is extremely subtle.
8344 //    This mode must be used with extreme care. Before the entrypoint is
8345 //    invoked all file descriptors other than stdin/out/err and the ones
8346 //    specified in |args.preserve_fds| will be closed, to avoid each process
8347 //    retaining a dupe of other subprocesses pipes. This however means that
8348 //    any non trivial calls (including logging) must be avoided as they might
8349 //    refer to FDs that are now closed. The entrypoint should really be used
8350 //    just to signal a pipe or similar for synchronizing sequencing in tests.
8351 
8352 //
8353 // This class allows to control stdin/out/err pipe redirection and takes care
8354 // of keeping all the pipes pumped (stdin) / drained (stdout/err), in a similar
8355 // fashion of python's subprocess.Communicate()
8356 // stdin: is always piped and closed once the |args.input| buffer is written.
8357 // stdout/err can be either:
8358 //   - dup()ed onto the parent process stdout/err.
8359 //   - redirected onto /dev/null.
8360 //   - piped onto a buffer (see output() method). There is only one output
8361 //     buffer in total. If both stdout and stderr are set to kBuffer mode, they
8362 //     will be merged onto the same. There doesn't seem any use case where they
8363 //     are needed distinctly.
8364 //
8365 // Some caveats worth mentioning:
8366 // - It always waitpid()s, to avoid leaving zombies around. If the process is
8367 //   not terminated by the time the destructor is reached, the dtor will
8368 //   send a SIGKILL and wait for the termination.
8369 // - After fork()-ing it will close all file descriptors, preserving only
8370 //   stdin/out/err and the fds listed in |args.preserve_fds|.
8371 // - On Linux/Android, the child process will be SIGKILL-ed if the calling
8372 //   thread exists, even if the Subprocess is std::move()-d onto another thread.
8373 //   This happens by virtue PR_SET_PDEATHSIG, which is used to avoid that
8374 //   child processes are leaked in the case of a crash of the parent (frequent
8375 //   in tests). However, the child process might still be leaked if execing
8376 //   a setuid/setgid binary (see man 2 prctl).
8377 //
8378 // Usage:
8379 // base::Subprocess p({"/bin/cat", "-"});
8380 // (or equivalently:
8381 //     base::Subprocess p;
8382 //     p.args.exec_cmd.push_back("/bin/cat");
8383 //     p.args.exec_cmd.push_back("-");
8384 //  )
8385 // p.args.stdout_mode = base::Subprocess::kBuffer;
8386 // p.args.stderr_mode = base::Subprocess::kInherit;
8387 // p.args.input = "stdin contents";
8388 // p.Call();
8389 // (or equivalently:
8390 //     p.Start();
8391 //     p.Wait();
8392 // )
8393 // EXPECT_EQ(p.status(), base::Subprocess::kTerminated);
8394 // EXPECT_EQ(p.returncode(), 0);
8395 class Subprocess {
8396  public:
8397   enum Status {
8398     kNotStarted = 0,  // Before calling Start() or Call().
8399     kRunning,         // After calling Start(), before Wait().
8400     kTerminated,      // The subprocess terminated, either successfully or not.
8401                       // This includes crashes or other signals on UNIX.
8402   };
8403 
8404   enum OutputMode {
8405     kInherit = 0,  // Inherit's the caller process stdout/stderr.
8406     kDevNull,      // dup() onto /dev/null
8407     kBuffer,       // dup() onto a pipe and move it into the output() buffer.
8408     kFd,           // dup() onto the passed args.fd.
8409   };
8410 
8411   // Input arguments for configuring the subprocess behavior.
8412   struct Args {
Argsperfetto::base::Subprocess::Args8413     Args(std::initializer_list<std::string> _cmd = {}) : exec_cmd(_cmd) {}
8414     Args(Args&&) noexcept;
8415     Args& operator=(Args&&);
8416     // If non-empty this will cause an exec() when Start()/Call() are called.
8417     std::vector<std::string> exec_cmd;
8418 
8419 #if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
8420     // If non-empty, it changes the argv[0] argument passed to exec. If
8421     // unset, argv[0] == exec_cmd[0]. This is to handle cases like:
8422     // exec_cmd = {"/proc/self/exec"}, argv0: "my_custom_test_override".
8423     std::string posix_argv0_override_for_testing;
8424 
8425     // If non-empty this will be invoked on the fork()-ed child process, after
8426     // stdin/out/err has been redirected and all other file descriptor are
8427     // closed. It is valid to specify both |exec_cmd| AND
8428     // |posix_entrypoint_for_testing|. In this case the latter will be invoked
8429     // just before the exec() call, but after having closed all fds % stdin/o/e.
8430     // This is for synchronization barriers in tests.
8431     std::function<void()> posix_entrypoint_for_testing;
8432 
8433     // When set, will will move the process to the given process group. If set
8434     // and zero, it will create a new process group. Effectively this calls
8435     // setpgid(0 /*self_pid*/, posix_proc_group_id).
8436     // This can be used to avoid that subprocesses receive CTRL-C from the
8437     // terminal, while still living in the same session.
8438     base::Optional<pid_t> posix_proc_group_id{};
8439 #endif
8440 
8441     // If non-empty, replaces the environment passed to exec().
8442     std::vector<std::string> env;
8443 
8444     // The file descriptors in this list will not be closed.
8445     std::vector<int> preserve_fds;
8446 
8447     // The data to push in the child process stdin.
8448     std::string input;
8449 
8450     OutputMode stdout_mode = kInherit;
8451     OutputMode stderr_mode = kInherit;
8452 
8453     base::ScopedPlatformHandle out_fd;
8454 
8455     // Returns " ".join(exec_cmd), quoting arguments.
8456     std::string GetCmdString() const;
8457   };
8458 
8459   struct ResourceUsage {
8460     uint32_t cpu_utime_ms = 0;
8461     uint32_t cpu_stime_ms = 0;
8462     uint32_t max_rss_kb = 0;
8463     uint32_t min_page_faults = 0;
8464     uint32_t maj_page_faults = 0;
8465     uint32_t vol_ctx_switch = 0;
8466     uint32_t invol_ctx_switch = 0;
8467 
cpu_time_msperfetto::base::Subprocess::ResourceUsage8468     uint32_t cpu_time_ms() const { return cpu_utime_ms + cpu_stime_ms; }
8469   };
8470 
8471   explicit Subprocess(std::initializer_list<std::string> exec_cmd = {});
8472   Subprocess(Subprocess&&) noexcept;
8473   Subprocess& operator=(Subprocess&&);
8474   ~Subprocess();  // It will KillAndWaitForTermination() if still alive.
8475 
8476   // Starts the subprocess but doesn't wait for its termination. The caller
8477   // is expected to either call Wait() or Poll() after this call.
8478   void Start();
8479 
8480   // Wait for process termination. Can be called more than once.
8481   // Args:
8482   //   |timeout_ms| = 0: wait indefinitely.
8483   //   |timeout_ms| > 0: wait for at most |timeout_ms|.
8484   // Returns:
8485   //  True: The process terminated. See status() and returncode().
8486   //  False: Timeout reached, the process is still running. In this case the
8487   //         process will be left in the kRunning state.
8488   bool Wait(int timeout_ms = 0);
8489 
8490   // Equivalent of Start() + Wait();
8491   // Returns true if the process exited cleanly with return code 0. False in
8492   // any othe case.
8493   bool Call(int timeout_ms = 0);
8494 
8495   Status Poll();
8496 
8497   // Sends a signal (SIGKILL if not specified) and wait for process termination.
8498   void KillAndWaitForTermination(int sig_num = 0);
8499 
pid() const8500   PlatformProcessId pid() const { return s_->pid; }
8501 
8502   // The accessors below are updated only after a call to Poll(), Wait() or
8503   // KillAndWaitForTermination().
8504   // In most cases you want to call Poll() rather than these accessors.
8505 
status() const8506   Status status() const { return s_->status; }
returncode() const8507   int returncode() const { return s_->returncode; }
timed_out() const8508   bool timed_out() const { return s_->timed_out; }
8509 
8510   // This contains both stdout and stderr (if the corresponding _mode ==
8511   // kBuffer). It's non-const so the caller can std::move() it.
output()8512   std::string& output() { return s_->output; }
output() const8513   const std::string& output() const { return s_->output; }
8514 
posix_rusage() const8515   const ResourceUsage& posix_rusage() const { return *s_->rusage; }
8516 
8517   Args args;
8518 
8519  private:
8520   // The signal/exit code used when killing the process in case of a timeout.
8521   static const int kTimeoutSignal;
8522 
8523   Subprocess(const Subprocess&) = delete;
8524   Subprocess& operator=(const Subprocess&) = delete;
8525 
8526   // This is to deal robustly with the move operators, without having to
8527   // manually maintain member-wise move instructions.
8528   struct MovableState {
8529     base::Pipe stdin_pipe;
8530     base::Pipe stdouterr_pipe;
8531     PlatformProcessId pid;
8532     Status status = kNotStarted;
8533     int returncode = -1;
8534     std::string output;  // Stdin+stderr. Only when kBuffer.
8535     std::unique_ptr<ResourceUsage> rusage{new ResourceUsage()};
8536     bool timed_out = false;
8537 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
8538     std::thread stdouterr_thread;
8539     std::thread stdin_thread;
8540     ScopedPlatformHandle win_proc_handle;
8541     ScopedPlatformHandle win_thread_handle;
8542 
8543     base::EventFd stdouterr_done_event;
8544     std::mutex mutex;  // Protects locked_outerr_buf and the two pipes.
8545     std::string locked_outerr_buf;
8546 #else
8547     base::Pipe exit_status_pipe;
8548     size_t input_written = 0;
8549     std::thread waitpid_thread;
8550 #endif
8551   };
8552 
8553 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
8554   static void StdinThread(MovableState*, std::string input);
8555   static void StdoutErrThread(MovableState*);
8556 #else
8557   void TryPushStdin();
8558   void TryReadStdoutAndErr();
8559   void TryReadExitStatus();
8560   void KillAtMostOnce();
8561   bool PollInternal(int poll_timeout_ms);
8562 #endif
8563 
8564   std::unique_ptr<MovableState> s_;
8565 };
8566 
8567 }  // namespace base
8568 }  // namespace perfetto
8569 
8570 #endif  // INCLUDE_PERFETTO_EXT_BASE_SUBPROCESS_H_
8571 /*
8572  * Copyright (C) 2020 The Android Open Source Project
8573  *
8574  * Licensed under the Apache License, Version 2.0 (the "License");
8575  * you may not use this file except in compliance with the License.
8576  * You may obtain a copy of the License at
8577  *
8578  *      http://www.apache.org/licenses/LICENSE-2.0
8579  *
8580  * Unless required by applicable law or agreed to in writing, software
8581  * distributed under the License is distributed on an "AS IS" BASIS,
8582  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
8583  * See the License for the specific language governing permissions and
8584  * limitations under the License.
8585  */
8586 
8587 // gen_amalgamated expanded: #include "perfetto/ext/base/subprocess.h"
8588 
8589 #include <tuple>
8590 
8591 // This file contains only the common bits (ctors / dtors / move operators).
8592 // The rest lives in subprocess_posix.cc and subprocess_windows.cc.
8593 
8594 namespace perfetto {
8595 namespace base {
8596 
8597 Subprocess::Args::Args(Args&&) noexcept = default;
8598 Subprocess::Args& Subprocess::Args::operator=(Args&&) = default;
8599 
Subprocess(std::initializer_list<std::string> a)8600 Subprocess::Subprocess(std::initializer_list<std::string> a)
8601     : args(a), s_(new MovableState()) {}
8602 
Subprocess(Subprocess && other)8603 Subprocess::Subprocess(Subprocess&& other) noexcept {
8604   static_assert(sizeof(Subprocess) ==
8605                     sizeof(std::tuple<std::unique_ptr<MovableState>, Args>),
8606                 "base::Subprocess' move ctor needs updating");
8607   s_ = std::move(other.s_);
8608   args = std::move(other.args);
8609 
8610   // Reset the state of the moved-from object.
8611   other.s_.reset(new MovableState());
8612   other.~Subprocess();
8613   new (&other) Subprocess();
8614 }
8615 
operator =(Subprocess && other)8616 Subprocess& Subprocess::operator=(Subprocess&& other) {
8617   this->~Subprocess();
8618   new (this) Subprocess(std::move(other));
8619   return *this;
8620 }
8621 
~Subprocess()8622 Subprocess::~Subprocess() {
8623   if (s_->status == kRunning)
8624     KillAndWaitForTermination();
8625 }
8626 
Call(int timeout_ms)8627 bool Subprocess::Call(int timeout_ms) {
8628   PERFETTO_CHECK(s_->status == kNotStarted);
8629   Start();
8630 
8631   if (!Wait(timeout_ms)) {
8632     s_->timed_out = true;
8633     KillAndWaitForTermination(kTimeoutSignal);
8634   }
8635   PERFETTO_DCHECK(s_->status != kRunning);
8636   return s_->status == kTerminated && s_->returncode == 0;
8637 }
8638 
GetCmdString() const8639 std::string Subprocess::Args::GetCmdString() const {
8640   std::string str;
8641   for (size_t i = 0; i < exec_cmd.size(); i++) {
8642     str += i > 0 ? " \"" : "";
8643     str += exec_cmd[i];
8644     str += i > 0 ? "\"" : "";
8645   }
8646   return str;
8647 }
8648 
8649 }  // namespace base
8650 }  // namespace perfetto
8651 // gen_amalgamated begin source: src/base/subprocess_posix.cc
8652 /*
8653  * Copyright (C) 2020 The Android Open Source Project
8654  *
8655  * Licensed under the Apache License, Version 2.0 (the "License");
8656  * you may not use this file except in compliance with the License.
8657  * You may obtain a copy of the License at
8658  *
8659  *      http://www.apache.org/licenses/LICENSE-2.0
8660  *
8661  * Unless required by applicable law or agreed to in writing, software
8662  * distributed under the License is distributed on an "AS IS" BASIS,
8663  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
8664  * See the License for the specific language governing permissions and
8665  * limitations under the License.
8666  */
8667 
8668 // gen_amalgamated expanded: #include "perfetto/ext/base/subprocess.h"
8669 
8670 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
8671 
8672 #if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) ||   \
8673     PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \
8674     PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
8675 
8676 #include <fcntl.h>
8677 #include <poll.h>
8678 #include <signal.h>
8679 #include <stdio.h>
8680 #include <sys/resource.h>
8681 #include <sys/types.h>
8682 #include <sys/wait.h>
8683 #include <unistd.h>
8684 
8685 #include <algorithm>
8686 #include <thread>
8687 #include <tuple>
8688 
8689 #if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
8690     PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
8691 #include <sys/prctl.h>
8692 #endif
8693 
8694 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
8695 // gen_amalgamated expanded: #include "perfetto/base/time.h"
8696 // gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
8697 
8698 // In MacOS this is not defined in any header.
8699 extern "C" char** environ;
8700 
8701 namespace perfetto {
8702 namespace base {
8703 
8704 namespace {
8705 
8706 struct ChildProcessArgs {
8707   Subprocess::Args* create_args;
8708   const char* exec_cmd = nullptr;
8709   std::vector<char*> argv;
8710   std::vector<char*> env;
8711   int stdin_pipe_rd = -1;
8712   int stdouterr_pipe_wr = -1;
8713 };
8714 
8715 // Don't add any dynamic allocation in this function. This will be invoked
8716 // under a fork(), potentially in a state where the allocator lock is held.
ChildProcess(ChildProcessArgs * args)8717 void __attribute__((noreturn)) ChildProcess(ChildProcessArgs* args) {
8718 #if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
8719     PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
8720   // In no case we want a child process to outlive its parent process. This is
8721   // relevant for tests, so that a test failure/crash doesn't leave child
8722   // processes around that get reparented to init.
8723   prctl(PR_SET_PDEATHSIG, SIGKILL);
8724 #endif
8725 
8726   auto die = [args](const char* err) __attribute__((noreturn)) {
8727     base::ignore_result(write(args->stdouterr_pipe_wr, err, strlen(err)));
8728     base::ignore_result(write(args->stdouterr_pipe_wr, "\n", 1));
8729     // From https://www.gnu.org/software/libc/manual/html_node/Exit-Status.html
8730     // "In particular, the value 128 is used to indicate failure to execute
8731     // another program in a subprocess. This convention is not universally
8732     // obeyed, but it is a good idea to follow it in your programs."
8733     _exit(128);
8734   };
8735 
8736   if (args->create_args->posix_proc_group_id.has_value()) {
8737     if (setpgid(0 /*self*/, args->create_args->posix_proc_group_id.value())) {
8738       die("setpgid() failed");
8739     }
8740   }
8741 
8742   auto set_fd_close_on_exec = [&die](int fd, bool close_on_exec) {
8743     int flags = fcntl(fd, F_GETFD, 0);
8744     if (flags < 0)
8745       die("fcntl(F_GETFD) failed");
8746     flags = close_on_exec ? (flags | FD_CLOEXEC) : (flags & ~FD_CLOEXEC);
8747     if (fcntl(fd, F_SETFD, flags) < 0)
8748       die("fcntl(F_SETFD) failed");
8749   };
8750 
8751   if (getppid() == 1)
8752     die("terminating because parent process died");
8753 
8754   if (dup2(args->stdin_pipe_rd, STDIN_FILENO) == -1)
8755     die("Failed to dup2(STDIN)");
8756   close(args->stdin_pipe_rd);
8757 
8758   switch (args->create_args->stdout_mode) {
8759     case Subprocess::kInherit:
8760       break;
8761     case Subprocess::kDevNull: {
8762       if (dup2(open("/dev/null", O_RDWR), STDOUT_FILENO) == -1)
8763         die("Failed to dup2(STDOUT)");
8764       break;
8765     }
8766     case Subprocess::kBuffer:
8767       if (dup2(args->stdouterr_pipe_wr, STDOUT_FILENO) == -1)
8768         die("Failed to dup2(STDOUT)");
8769       break;
8770     case Subprocess::kFd:
8771       if (dup2(*args->create_args->out_fd, STDOUT_FILENO) == -1)
8772         die("Failed to dup2(STDOUT)");
8773       break;
8774   }
8775 
8776   switch (args->create_args->stderr_mode) {
8777     case Subprocess::kInherit:
8778       break;
8779     case Subprocess::kDevNull: {
8780       if (dup2(open("/dev/null", O_RDWR), STDERR_FILENO) == -1)
8781         die("Failed to dup2(STDERR)");
8782       break;
8783     }
8784     case Subprocess::kBuffer:
8785       if (dup2(args->stdouterr_pipe_wr, STDERR_FILENO) == -1)
8786         die("Failed to dup2(STDERR)");
8787       break;
8788     case Subprocess::kFd:
8789       if (dup2(*args->create_args->out_fd, STDERR_FILENO) == -1)
8790         die("Failed to dup2(STDERR)");
8791       break;
8792   }
8793 
8794   // Close all FDs % stdin/out/err and the ones that the client explicitly
8795   // asked to retain. The reason for this is twofold:
8796   // 1. For exec-only (i.e. entrypoint == empty) cases: it avoids leaking FDs
8797   //    that didn't get marked as O_CLOEXEC by accident.
8798   // 2. In fork() mode (entrypoint not empty) avoids retaining a dup of eventfds
8799   //    that would prevent the parent process to receive EOFs (tests usually use
8800   //    pipes as a synchronization mechanism between subprocesses).
8801   const auto& preserve_fds = args->create_args->preserve_fds;
8802   for (int i = 0; i < 512; i++) {
8803     if (i != STDIN_FILENO && i != STDERR_FILENO && i != STDOUT_FILENO &&
8804         i != args->stdouterr_pipe_wr &&
8805         !std::count(preserve_fds.begin(), preserve_fds.end(), i)) {
8806       close(i);
8807     }
8808   }
8809 
8810   // Clears O_CLOEXEC from stdin/out/err and the |preserve_fds| list. These are
8811   // the only FDs that we want to be preserved after the exec().
8812   set_fd_close_on_exec(STDIN_FILENO, false);
8813   set_fd_close_on_exec(STDOUT_FILENO, false);
8814   set_fd_close_on_exec(STDERR_FILENO, false);
8815 
8816   for (auto fd : preserve_fds)
8817     set_fd_close_on_exec(fd, false);
8818 
8819   // If the caller specified a std::function entrypoint, run that first.
8820   if (args->create_args->posix_entrypoint_for_testing)
8821     args->create_args->posix_entrypoint_for_testing();
8822 
8823   // If the caller specified only an entrypoint, without any args, exit now.
8824   // Otherwise proceed with the exec() below.
8825   if (!args->exec_cmd)
8826     _exit(0);
8827 
8828   // If |args[0]| is a path use execv() (which takes a path), othewise use
8829   // exevp(), which uses the shell and follows PATH.
8830   if (strchr(args->exec_cmd, '/')) {
8831     char** env = args->env.empty() ? environ : args->env.data();
8832     execve(args->exec_cmd, args->argv.data(), env);
8833   } else {
8834     // There is no execvpe() on Mac.
8835     if (!args->env.empty())
8836       die("A full path is required for |exec_cmd| when setting |env|");
8837     execvp(args->exec_cmd, args->argv.data());
8838   }
8839 
8840   // Reached only if execv fails.
8841   die("execve() failed");
8842 }
8843 
8844 }  // namespace
8845 
8846 // static
8847 const int Subprocess::kTimeoutSignal = SIGKILL;
8848 
Start()8849 void Subprocess::Start() {
8850   ChildProcessArgs proc_args;
8851   proc_args.create_args = &args;
8852 
8853   // Setup argv.
8854   if (!args.exec_cmd.empty()) {
8855     proc_args.exec_cmd = args.exec_cmd[0].c_str();
8856     for (const std::string& arg : args.exec_cmd)
8857       proc_args.argv.push_back(const_cast<char*>(arg.c_str()));
8858     proc_args.argv.push_back(nullptr);
8859 
8860     if (!args.posix_argv0_override_for_testing.empty()) {
8861       proc_args.argv[0] =
8862           const_cast<char*>(args.posix_argv0_override_for_testing.c_str());
8863     }
8864   }
8865 
8866   // Setup env.
8867   if (!args.env.empty()) {
8868     for (const std::string& str : args.env)
8869       proc_args.env.push_back(const_cast<char*>(str.c_str()));
8870     proc_args.env.push_back(nullptr);
8871   }
8872 
8873   // Setup the pipes for stdin/err redirection.
8874   s_->stdin_pipe = base::Pipe::Create(base::Pipe::kWrNonBlock);
8875   proc_args.stdin_pipe_rd = *s_->stdin_pipe.rd;
8876   s_->stdouterr_pipe = base::Pipe::Create(base::Pipe::kRdNonBlock);
8877   proc_args.stdouterr_pipe_wr = *s_->stdouterr_pipe.wr;
8878 
8879   // Spawn the child process that will exec().
8880   s_->pid = fork();
8881   PERFETTO_CHECK(s_->pid >= 0);
8882   if (s_->pid == 0) {
8883     // Close the parent-ends of the pipes.
8884     s_->stdin_pipe.wr.reset();
8885     s_->stdouterr_pipe.rd.reset();
8886     ChildProcess(&proc_args);
8887     // ChildProcess() doesn't return, not even in case of failures.
8888     PERFETTO_FATAL("not reached");
8889   }
8890 
8891   s_->status = kRunning;
8892 
8893   // Close the child-end of the pipes.
8894   // Deliberately NOT closing the s_->stdin_pipe.rd. This is to avoid crashing
8895   // with a SIGPIPE if the process exits without consuming its stdin, while
8896   // the parent tries to write() on the other end of the stdin pipe.
8897   s_->stdouterr_pipe.wr.reset();
8898   proc_args.create_args->out_fd.reset();
8899 
8900   // Spawn a thread that is blocked on waitpid() and writes the termination
8901   // status onto a pipe. The problem here is that waipid() doesn't have a
8902   // timeout option and can't be passed to poll(). The alternative would be
8903   // using a SIGCHLD handler, but anecdotally signal handlers introduce more
8904   // problems than what they solve.
8905   s_->exit_status_pipe = base::Pipe::Create(base::Pipe::kRdNonBlock);
8906 
8907   // Both ends of the pipe are closed after the thread.join().
8908   int pid = s_->pid;
8909   int exit_status_pipe_wr = s_->exit_status_pipe.wr.release();
8910   auto* rusage = s_->rusage.get();
8911   s_->waitpid_thread = std::thread([pid, exit_status_pipe_wr, rusage] {
8912     int pid_stat = -1;
8913     struct rusage usg {};
8914     int wait_res = PERFETTO_EINTR(wait4(pid, &pid_stat, 0, &usg));
8915     PERFETTO_CHECK(wait_res == pid);
8916 
8917     auto tv_to_ms = [](const struct timeval& tv) {
8918       return static_cast<uint32_t>(tv.tv_sec * 1000 + tv.tv_usec / 1000);
8919     };
8920     rusage->cpu_utime_ms = tv_to_ms(usg.ru_utime);
8921     rusage->cpu_stime_ms = tv_to_ms(usg.ru_stime);
8922     rusage->max_rss_kb = static_cast<uint32_t>(usg.ru_maxrss) / 1000;
8923     rusage->min_page_faults = static_cast<uint32_t>(usg.ru_minflt);
8924     rusage->maj_page_faults = static_cast<uint32_t>(usg.ru_majflt);
8925     rusage->vol_ctx_switch = static_cast<uint32_t>(usg.ru_nvcsw);
8926     rusage->invol_ctx_switch = static_cast<uint32_t>(usg.ru_nivcsw);
8927 
8928     base::ignore_result(PERFETTO_EINTR(
8929         write(exit_status_pipe_wr, &pid_stat, sizeof(pid_stat))));
8930     PERFETTO_CHECK(close(exit_status_pipe_wr) == 0 || errno == EINTR);
8931   });
8932 }
8933 
Poll()8934 Subprocess::Status Subprocess::Poll() {
8935   if (s_->status != kRunning)
8936     return s_->status;  // Nothing to poll.
8937   while (PollInternal(0 /* don't block*/)) {
8938   }
8939   return s_->status;
8940 }
8941 
8942 // |timeout_ms| semantic:
8943 //   -1: Block indefinitely.
8944 //    0: Don't block, return immediately.
8945 //   >0: Block for at most X ms.
8946 // Returns:
8947 //  True: Read at least one fd (so there might be more queued).
8948 //  False: if all fds reached quiescent (no data to read/write).
PollInternal(int poll_timeout_ms)8949 bool Subprocess::PollInternal(int poll_timeout_ms) {
8950   struct pollfd fds[3]{};
8951   size_t num_fds = 0;
8952   if (s_->exit_status_pipe.rd) {
8953     fds[num_fds].fd = *s_->exit_status_pipe.rd;
8954     fds[num_fds].events = POLLIN;
8955     num_fds++;
8956   }
8957   if (s_->stdouterr_pipe.rd) {
8958     fds[num_fds].fd = *s_->stdouterr_pipe.rd;
8959     fds[num_fds].events = POLLIN;
8960     num_fds++;
8961   }
8962   if (s_->stdin_pipe.wr) {
8963     fds[num_fds].fd = *s_->stdin_pipe.wr;
8964     fds[num_fds].events = POLLOUT;
8965     num_fds++;
8966   }
8967 
8968   if (num_fds == 0)
8969     return false;
8970 
8971   auto nfds = static_cast<nfds_t>(num_fds);
8972   int poll_res = PERFETTO_EINTR(poll(fds, nfds, poll_timeout_ms));
8973   PERFETTO_CHECK(poll_res >= 0);
8974 
8975   TryReadStdoutAndErr();
8976   TryPushStdin();
8977   TryReadExitStatus();
8978 
8979   return poll_res > 0;
8980 }
8981 
Wait(int timeout_ms)8982 bool Subprocess::Wait(int timeout_ms) {
8983   PERFETTO_CHECK(s_->status != kNotStarted);
8984 
8985   // Break out of the loop only after both conditions are satisfied:
8986   // - All stdout/stderr data has been read (if kBuffer).
8987   // - The process exited.
8988   // Note that the two events can happen arbitrary order. After the process
8989   // exits, there might be still data in the pipe buffer, which we want to
8990   // read fully.
8991   //
8992   // Instead, don't wait on the stdin to be fully written. The child process
8993   // might exit prematurely (or crash). If that happens, we can end up in a
8994   // state where the write(stdin_pipe_.wr) will never unblock.
8995 
8996   const int64_t t_start = base::GetWallTimeMs().count();
8997   while (s_->exit_status_pipe.rd || s_->stdouterr_pipe.rd) {
8998     int poll_timeout_ms = -1;  // Block until a FD is ready.
8999     if (timeout_ms > 0) {
9000       const int64_t now = GetWallTimeMs().count();
9001       poll_timeout_ms = timeout_ms - static_cast<int>(now - t_start);
9002       if (poll_timeout_ms <= 0)
9003         return false;
9004     }
9005     PollInternal(poll_timeout_ms);
9006   }  // while(...)
9007   return true;
9008 }
9009 
TryReadExitStatus()9010 void Subprocess::TryReadExitStatus() {
9011   if (!s_->exit_status_pipe.rd)
9012     return;
9013 
9014   int pid_stat = -1;
9015   int64_t rsize = PERFETTO_EINTR(
9016       read(*s_->exit_status_pipe.rd, &pid_stat, sizeof(pid_stat)));
9017   if (rsize < 0 && errno == EAGAIN)
9018     return;
9019 
9020   if (rsize > 0) {
9021     PERFETTO_CHECK(rsize == sizeof(pid_stat));
9022   } else if (rsize < 0) {
9023     PERFETTO_PLOG("Subprocess read(s_->exit_status_pipe) failed");
9024   }
9025   s_->waitpid_thread.join();
9026   s_->exit_status_pipe.rd.reset();
9027 
9028   s_->status = kTerminated;
9029   if (WIFEXITED(pid_stat)) {
9030     s_->returncode = WEXITSTATUS(pid_stat);
9031   } else if (WIFSIGNALED(pid_stat)) {
9032     s_->returncode = 128 + WTERMSIG(pid_stat);  // Follow bash convention.
9033   } else {
9034     PERFETTO_FATAL("waitpid() returned an unexpected value (0x%x)", pid_stat);
9035   }
9036 }
9037 
9038 // If the stidn pipe is still open, push input data and close it at the end.
TryPushStdin()9039 void Subprocess::TryPushStdin() {
9040   if (!s_->stdin_pipe.wr)
9041     return;
9042 
9043   PERFETTO_DCHECK(args.input.empty() || s_->input_written < args.input.size());
9044   if (!args.input.empty()) {
9045     int64_t wsize =
9046         PERFETTO_EINTR(write(*s_->stdin_pipe.wr, &args.input[s_->input_written],
9047                              args.input.size() - s_->input_written));
9048     if (wsize < 0 && errno == EAGAIN)
9049       return;
9050 
9051     if (wsize >= 0) {
9052       // Whether write() can return 0 is one of the greatest mysteries of UNIX.
9053       // Just ignore it.
9054       s_->input_written += static_cast<size_t>(wsize);
9055     } else {
9056       PERFETTO_PLOG("Subprocess write(stdin) failed");
9057       s_->stdin_pipe.wr.reset();
9058     }
9059   }
9060   PERFETTO_DCHECK(s_->input_written <= args.input.size());
9061   if (s_->input_written == args.input.size())
9062     s_->stdin_pipe.wr.reset();  // Close stdin.
9063 }
9064 
TryReadStdoutAndErr()9065 void Subprocess::TryReadStdoutAndErr() {
9066   if (!s_->stdouterr_pipe.rd)
9067     return;
9068   char buf[4096];
9069   int64_t rsize =
9070       PERFETTO_EINTR(read(*s_->stdouterr_pipe.rd, buf, sizeof(buf)));
9071   if (rsize < 0 && errno == EAGAIN)
9072     return;
9073 
9074   if (rsize > 0) {
9075     s_->output.append(buf, static_cast<size_t>(rsize));
9076   } else if (rsize == 0 /* EOF */) {
9077     s_->stdouterr_pipe.rd.reset();
9078   } else {
9079     PERFETTO_PLOG("Subprocess read(stdout/err) failed");
9080     s_->stdouterr_pipe.rd.reset();
9081   }
9082 }
9083 
KillAndWaitForTermination(int sig_num)9084 void Subprocess::KillAndWaitForTermination(int sig_num) {
9085   kill(s_->pid, sig_num ? sig_num : SIGKILL);
9086   Wait();
9087   // TryReadExitStatus must have joined the thread.
9088   PERFETTO_DCHECK(!s_->waitpid_thread.joinable());
9089 }
9090 
9091 }  // namespace base
9092 }  // namespace perfetto
9093 
9094 #endif  // PERFETTO_OS_LINUX || PERFETTO_OS_ANDROID || PERFETTO_OS_APPLE
9095 // gen_amalgamated begin source: src/base/subprocess_windows.cc
9096 /*
9097  * Copyright (C) 2020 The Android Open Source Project
9098  *
9099  * Licensed under the Apache License, Version 2.0 (the "License");
9100  * you may not use this file except in compliance with the License.
9101  * You may obtain a copy of the License at
9102  *
9103  *      http://www.apache.org/licenses/LICENSE-2.0
9104  *
9105  * Unless required by applicable law or agreed to in writing, software
9106  * distributed under the License is distributed on an "AS IS" BASIS,
9107  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
9108  * See the License for the specific language governing permissions and
9109  * limitations under the License.
9110  */
9111 
9112 // gen_amalgamated expanded: #include "perfetto/ext/base/subprocess.h"
9113 
9114 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
9115 
9116 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
9117 
9118 #include <stdio.h>
9119 
9120 #include <algorithm>
9121 #include <mutex>
9122 #include <tuple>
9123 
9124 #include <Windows.h>
9125 
9126 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
9127 // gen_amalgamated expanded: #include "perfetto/base/time.h"
9128 // gen_amalgamated expanded: #include "perfetto/ext/base/pipe.h"
9129 // gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
9130 
9131 namespace perfetto {
9132 namespace base {
9133 
9134 // static
9135 const int Subprocess::kTimeoutSignal = static_cast<int>(STATUS_TIMEOUT);
9136 
Start()9137 void Subprocess::Start() {
9138   if (args.exec_cmd.empty()) {
9139     PERFETTO_ELOG("Subprocess.exec_cmd cannot be empty on Windows");
9140     return;
9141   }
9142 
9143   // Quote arguments but only when ambiguous. When quoting, CreateProcess()
9144   // assumes that the command is an absolute path and does not search in the
9145   // %PATH%. If non quoted, instead, CreateProcess() tries both. This is to
9146   // allow Subprocess("cmd.exe", "/c", "shell command").
9147   std::string cmd;
9148   for (const auto& part : args.exec_cmd) {
9149     if (part.find(" ") != std::string::npos) {
9150       cmd += "\"" + part + "\" ";
9151     } else {
9152       cmd += part + " ";
9153     }
9154   }
9155   // Remove trailing space.
9156   if (!cmd.empty())
9157     cmd.resize(cmd.size() - 1);
9158 
9159   s_->stdin_pipe = Pipe::Create();
9160   // Allow the child process to inherit the other end of the pipe.
9161   PERFETTO_CHECK(
9162       ::SetHandleInformation(*s_->stdin_pipe.rd, HANDLE_FLAG_INHERIT, 1));
9163 
9164   if (args.stderr_mode == kBuffer || args.stdout_mode == kBuffer) {
9165     s_->stdouterr_pipe = Pipe::Create();
9166     PERFETTO_CHECK(
9167         ::SetHandleInformation(*s_->stdouterr_pipe.wr, HANDLE_FLAG_INHERIT, 1));
9168   }
9169 
9170   ScopedPlatformHandle nul_handle;
9171   if (args.stderr_mode == kDevNull || args.stdout_mode == kDevNull) {
9172     nul_handle.reset(::CreateFileA("NUL", GENERIC_WRITE, FILE_SHARE_WRITE,
9173                                    nullptr, OPEN_EXISTING,
9174                                    FILE_ATTRIBUTE_NORMAL, nullptr));
9175     PERFETTO_CHECK(::SetHandleInformation(*nul_handle, HANDLE_FLAG_INHERIT, 1));
9176   }
9177 
9178   PROCESS_INFORMATION proc_info{};
9179   STARTUPINFOA start_info{};
9180   start_info.cb = sizeof(STARTUPINFOA);
9181 
9182   if (args.stderr_mode == kInherit) {
9183     start_info.hStdError = ::GetStdHandle(STD_ERROR_HANDLE);
9184   } else if (args.stderr_mode == kBuffer) {
9185     start_info.hStdError = *s_->stdouterr_pipe.wr;
9186   } else if (args.stderr_mode == kDevNull) {
9187     start_info.hStdError = *nul_handle;
9188   } else if (args.stderr_mode == kFd) {
9189     PERFETTO_CHECK(
9190         ::SetHandleInformation(*args.out_fd, HANDLE_FLAG_INHERIT, 1));
9191     start_info.hStdError = *args.out_fd;
9192   } else {
9193     PERFETTO_CHECK(false);
9194   }
9195 
9196   if (args.stdout_mode == kInherit) {
9197     start_info.hStdOutput = ::GetStdHandle(STD_OUTPUT_HANDLE);
9198   } else if (args.stdout_mode == kBuffer) {
9199     start_info.hStdOutput = *s_->stdouterr_pipe.wr;
9200   } else if (args.stdout_mode == kDevNull) {
9201     start_info.hStdOutput = *nul_handle;
9202   } else if (args.stdout_mode == kFd) {
9203     PERFETTO_CHECK(
9204         ::SetHandleInformation(*args.out_fd, HANDLE_FLAG_INHERIT, 1));
9205     start_info.hStdOutput = *args.out_fd;
9206   } else {
9207     PERFETTO_CHECK(false);
9208   }
9209 
9210   start_info.hStdInput = *s_->stdin_pipe.rd;
9211   start_info.dwFlags |= STARTF_USESTDHANDLES;
9212 
9213   // Create the child process.
9214   bool success =
9215       ::CreateProcessA(nullptr,      // App name. Needs to be null to use PATH.
9216                        &cmd[0],      // Command line.
9217                        nullptr,      // Process security attributes.
9218                        nullptr,      // Primary thread security attributes.
9219                        true,         // Handles are inherited.
9220                        0,            // Flags.
9221                        nullptr,      // Use parent's environment.
9222                        nullptr,      // Use parent's current directory.
9223                        &start_info,  // STARTUPINFO pointer.
9224                        &proc_info);  // Receives PROCESS_INFORMATION.
9225 
9226   // Close on our side the pipe ends that we passed to the child process.
9227   s_->stdin_pipe.rd.reset();
9228   s_->stdouterr_pipe.wr.reset();
9229   args.out_fd.reset();
9230 
9231   if (!success) {
9232     s_->returncode = ERROR_FILE_NOT_FOUND;
9233     s_->status = kTerminated;
9234     s_->stdin_pipe.wr.reset();
9235     s_->stdouterr_pipe.rd.reset();
9236     PERFETTO_ELOG("CreateProcess failed: %lx, cmd: %s", GetLastError(),
9237                   &cmd[0]);
9238     return;
9239   }
9240 
9241   s_->pid = proc_info.dwProcessId;
9242   s_->win_proc_handle = ScopedPlatformHandle(proc_info.hProcess);
9243   s_->win_thread_handle = ScopedPlatformHandle(proc_info.hThread);
9244   s_->status = kRunning;
9245 
9246   MovableState* s = s_.get();
9247   s_->stdin_thread = std::thread(&Subprocess::StdinThread, s, args.input);
9248 
9249   if (args.stderr_mode == kBuffer || args.stdout_mode == kBuffer) {
9250     PERFETTO_DCHECK(s_->stdouterr_pipe.rd);
9251     s_->stdouterr_thread = std::thread(&Subprocess::StdoutErrThread, s);
9252   }
9253 }
9254 
9255 // static
StdinThread(MovableState * s,std::string input)9256 void Subprocess::StdinThread(MovableState* s, std::string input) {
9257   size_t input_written = 0;
9258   while (input_written < input.size()) {
9259     DWORD wsize = 0;
9260     if (::WriteFile(*s->stdin_pipe.wr, input.data() + input_written,
9261                     static_cast<DWORD>(input.size() - input_written), &wsize,
9262                     nullptr)) {
9263       input_written += wsize;
9264     } else {
9265       // ERROR_BROKEN_PIPE is WAI when the child just closes stdin and stops
9266       // accepting input.
9267       auto err = ::GetLastError();
9268       if (err != ERROR_BROKEN_PIPE)
9269         PERFETTO_PLOG("Subprocess WriteFile(stdin) failed %lx", err);
9270       break;
9271     }
9272   }  // while(...)
9273   std::unique_lock<std::mutex> lock(s->mutex);
9274   s->stdin_pipe.wr.reset();
9275 }
9276 
9277 // static
StdoutErrThread(MovableState * s)9278 void Subprocess::StdoutErrThread(MovableState* s) {
9279   char buf[4096];
9280   for (;;) {
9281     DWORD rsize = 0;
9282     bool res =
9283         ::ReadFile(*s->stdouterr_pipe.rd, buf, sizeof(buf), &rsize, nullptr);
9284     if (!res) {
9285       auto err = GetLastError();
9286       if (err != ERROR_BROKEN_PIPE)
9287         PERFETTO_PLOG("Subprocess ReadFile(stdouterr) failed %ld", err);
9288     }
9289 
9290     if (rsize > 0) {
9291       std::unique_lock<std::mutex> lock(s->mutex);
9292       s->locked_outerr_buf.append(buf, static_cast<size_t>(rsize));
9293     } else {  // EOF or some error.
9294       break;
9295     }
9296   }  // For(..)
9297 
9298   // Close the stdouterr_pipe. The main loop looks at the pipe closure to
9299   // determine whether the stdout/err thread has completed.
9300   {
9301     std::unique_lock<std::mutex> lock(s->mutex);
9302     s->stdouterr_pipe.rd.reset();
9303   }
9304   s->stdouterr_done_event.Notify();
9305 }
9306 
Poll()9307 Subprocess::Status Subprocess::Poll() {
9308   if (s_->status != kRunning)
9309     return s_->status;  // Nothing to poll.
9310   Wait(1 /*ms*/);
9311   return s_->status;
9312 }
9313 
Wait(int timeout_ms)9314 bool Subprocess::Wait(int timeout_ms) {
9315   PERFETTO_CHECK(s_->status != kNotStarted);
9316   const bool wait_forever = timeout_ms == 0;
9317   const int64_t wait_start_ms = base::GetWallTimeMs().count();
9318 
9319   // Break out of the loop only after both conditions are satisfied:
9320   // - All stdout/stderr data has been read (if kBuffer).
9321   // - The process exited.
9322   // Note that the two events can happen arbitrary order. After the process
9323   // exits, there might be still data in the pipe buffer, which we want to
9324   // read fully.
9325   // Note also that stdout/err might be "complete" before starting, if neither
9326   // is operating in kBuffer mode. In that case we just want to wait for the
9327   // process termination.
9328   //
9329   // Instead, don't wait on the stdin to be fully written. The child process
9330   // might exit prematurely (or crash). If that happens, we can end up in a
9331   // state where the write(stdin_pipe_.wr) will never unblock.
9332   bool stdouterr_complete = false;
9333   for (;;) {
9334     HANDLE wait_handles[2]{};
9335     DWORD num_handles = 0;
9336 
9337     // Check if the process exited.
9338     bool process_exited = !s_->win_proc_handle;
9339     if (!process_exited) {
9340       DWORD exit_code = STILL_ACTIVE;
9341       PERFETTO_CHECK(::GetExitCodeProcess(*s_->win_proc_handle, &exit_code));
9342       if (exit_code != STILL_ACTIVE) {
9343         s_->returncode = static_cast<int>(exit_code);
9344         s_->status = kTerminated;
9345         s_->win_proc_handle.reset();
9346         s_->win_thread_handle.reset();
9347         process_exited = true;
9348       }
9349     } else {
9350       PERFETTO_DCHECK(s_->status != kRunning);
9351     }
9352     if (!process_exited) {
9353       wait_handles[num_handles++] = *s_->win_proc_handle;
9354     }
9355 
9356     // Check if there is more output and if the stdout/err pipe has been closed.
9357     {
9358       std::unique_lock<std::mutex> lock(s_->mutex);
9359       // Move the output from the internal buffer shared with the
9360       // stdouterr_thread to the final buffer exposed to the client.
9361       if (!s_->locked_outerr_buf.empty()) {
9362         s_->output.append(std::move(s_->locked_outerr_buf));
9363         s_->locked_outerr_buf.clear();
9364       }
9365       stdouterr_complete = !s_->stdouterr_pipe.rd;
9366       if (!stdouterr_complete) {
9367         wait_handles[num_handles++] = s_->stdouterr_done_event.fd();
9368       }
9369     }  // lock(s_->mutex)
9370 
9371     if (num_handles == 0) {
9372       PERFETTO_DCHECK(process_exited && stdouterr_complete);
9373       break;
9374     }
9375 
9376     DWORD wait_ms;  // Note: DWORD is unsigned.
9377     if (wait_forever) {
9378       wait_ms = INFINITE;
9379     } else {
9380       const int64_t now = GetWallTimeMs().count();
9381       const int64_t wait_left_ms = timeout_ms - (now - wait_start_ms);
9382       if (wait_left_ms <= 0)
9383         return false;  // Timed out
9384       wait_ms = static_cast<DWORD>(wait_left_ms);
9385     }
9386 
9387     auto wait_res =
9388         ::WaitForMultipleObjects(num_handles, wait_handles, false, wait_ms);
9389     PERFETTO_CHECK(wait_res != WAIT_FAILED);
9390   }
9391 
9392   PERFETTO_DCHECK(!s_->win_proc_handle);
9393   PERFETTO_DCHECK(!s_->win_thread_handle);
9394 
9395   if (s_->stdin_thread.joinable())  // Might not exist if CreateProcess failed.
9396     s_->stdin_thread.join();
9397   if (s_->stdouterr_thread.joinable())
9398     s_->stdouterr_thread.join();
9399 
9400   // The stdin pipe is closed by the dedicated stdin thread. However if that is
9401   // not started (e.g. because of no redirection) force close it now. Needs to
9402   // happen after the join() to be thread safe.
9403   s_->stdin_pipe.wr.reset();
9404   s_->stdouterr_pipe.rd.reset();
9405 
9406   return true;
9407 }
9408 
KillAndWaitForTermination(int exit_code)9409 void Subprocess::KillAndWaitForTermination(int exit_code) {
9410   auto code = exit_code ? static_cast<DWORD>(exit_code) : STATUS_CONTROL_C_EXIT;
9411   ::TerminateProcess(*s_->win_proc_handle, code);
9412   Wait();
9413   // TryReadExitStatus must have joined the threads.
9414   PERFETTO_DCHECK(!s_->stdin_thread.joinable());
9415   PERFETTO_DCHECK(!s_->stdouterr_thread.joinable());
9416 }
9417 
9418 }  // namespace base
9419 }  // namespace perfetto
9420 
9421 #endif  // PERFETTO_OS_WIN
9422 // gen_amalgamated begin source: src/protozero/field.cc
9423 /*
9424  * Copyright (C) 2019 The Android Open Source Project
9425  *
9426  * Licensed under the Apache License, Version 2.0 (the "License");
9427  * you may not use this file except in compliance with the License.
9428  * You may obtain a copy of the License at
9429  *
9430  *      http://www.apache.org/licenses/LICENSE-2.0
9431  *
9432  * Unless required by applicable law or agreed to in writing, software
9433  * distributed under the License is distributed on an "AS IS" BASIS,
9434  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
9435  * See the License for the specific language governing permissions and
9436  * limitations under the License.
9437  */
9438 
9439 // gen_amalgamated expanded: #include "perfetto/protozero/field.h"
9440 
9441 // gen_amalgamated expanded: #include "perfetto/base/compiler.h"
9442 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
9443 
9444 #if !PERFETTO_IS_LITTLE_ENDIAN()
9445 // The memcpy() for fixed32/64 below needs to be adjusted if we want to
9446 // support big endian CPUs. There doesn't seem to be a compelling need today.
9447 #error Unimplemented for big endian archs.
9448 #endif
9449 
9450 namespace protozero {
9451 
9452 template <typename Container>
SerializeAndAppendToInternal(Container * dst) const9453 void Field::SerializeAndAppendToInternal(Container* dst) const {
9454   namespace pu = proto_utils;
9455   size_t initial_size = dst->size();
9456   dst->resize(initial_size + pu::kMaxSimpleFieldEncodedSize + size_);
9457   uint8_t* start = reinterpret_cast<uint8_t*>(&(*dst)[initial_size]);
9458   uint8_t* wptr = start;
9459   switch (type_) {
9460     case static_cast<int>(pu::ProtoWireType::kVarInt): {
9461       wptr = pu::WriteVarInt(pu::MakeTagVarInt(id_), wptr);
9462       wptr = pu::WriteVarInt(int_value_, wptr);
9463       break;
9464     }
9465     case static_cast<int>(pu::ProtoWireType::kFixed32): {
9466       wptr = pu::WriteVarInt(pu::MakeTagFixed<uint32_t>(id_), wptr);
9467       uint32_t value32 = static_cast<uint32_t>(int_value_);
9468       memcpy(wptr, &value32, sizeof(value32));
9469       wptr += sizeof(uint32_t);
9470       break;
9471     }
9472     case static_cast<int>(pu::ProtoWireType::kFixed64): {
9473       wptr = pu::WriteVarInt(pu::MakeTagFixed<uint64_t>(id_), wptr);
9474       memcpy(wptr, &int_value_, sizeof(int_value_));
9475       wptr += sizeof(uint64_t);
9476       break;
9477     }
9478     case static_cast<int>(pu::ProtoWireType::kLengthDelimited): {
9479       ConstBytes payload = as_bytes();
9480       wptr = pu::WriteVarInt(pu::MakeTagLengthDelimited(id_), wptr);
9481       wptr = pu::WriteVarInt(payload.size, wptr);
9482       memcpy(wptr, payload.data, payload.size);
9483       wptr += payload.size;
9484       break;
9485     }
9486     default:
9487       PERFETTO_FATAL("Unknown field type %u", type_);
9488   }
9489   size_t written_size = static_cast<size_t>(wptr - start);
9490   PERFETTO_DCHECK(written_size > 0 && written_size < pu::kMaxMessageLength);
9491   PERFETTO_DCHECK(initial_size + written_size <= dst->size());
9492   dst->resize(initial_size + written_size);
9493 }
9494 
SerializeAndAppendTo(std::string * dst) const9495 void Field::SerializeAndAppendTo(std::string* dst) const {
9496   SerializeAndAppendToInternal(dst);
9497 }
9498 
SerializeAndAppendTo(std::vector<uint8_t> * dst) const9499 void Field::SerializeAndAppendTo(std::vector<uint8_t>* dst) const {
9500   SerializeAndAppendToInternal(dst);
9501 }
9502 
9503 }  // namespace protozero
9504 // gen_amalgamated begin source: src/protozero/message.cc
9505 /*
9506  * Copyright (C) 2017 The Android Open Source Project
9507  *
9508  * Licensed under the Apache License, Version 2.0 (the "License");
9509  * you may not use this file except in compliance with the License.
9510  * You may obtain a copy of the License at
9511  *
9512  *      http://www.apache.org/licenses/LICENSE-2.0
9513  *
9514  * Unless required by applicable law or agreed to in writing, software
9515  * distributed under the License is distributed on an "AS IS" BASIS,
9516  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
9517  * See the License for the specific language governing permissions and
9518  * limitations under the License.
9519  */
9520 
9521 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
9522 
9523 #include <atomic>
9524 #include <type_traits>
9525 
9526 // gen_amalgamated expanded: #include "perfetto/base/compiler.h"
9527 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
9528 // gen_amalgamated expanded: #include "perfetto/protozero/message_arena.h"
9529 // gen_amalgamated expanded: #include "perfetto/protozero/message_handle.h"
9530 
9531 #if !PERFETTO_IS_LITTLE_ENDIAN()
9532 // The memcpy() for float and double below needs to be adjusted if we want to
9533 // support big endian CPUs. There doesn't seem to be a compelling need today.
9534 #error Unimplemented for big endian archs.
9535 #endif
9536 
9537 namespace protozero {
9538 
9539 namespace {
9540 
9541 #if PERFETTO_DCHECK_IS_ON()
9542 std::atomic<uint32_t> g_generation;
9543 #endif
9544 
9545 }  // namespace
9546 
9547 // Do NOT put any code in the constructor or use default initialization.
9548 // Use the Reset() method below instead.
9549 
9550 // This method is called to initialize both root and nested messages.
Reset(ScatteredStreamWriter * stream_writer,MessageArena * arena)9551 void Message::Reset(ScatteredStreamWriter* stream_writer, MessageArena* arena) {
9552 // Older versions of libstdcxx don't have is_trivially_constructible.
9553 #if !defined(__GLIBCXX__) || __GLIBCXX__ >= 20170516
9554   static_assert(std::is_trivially_constructible<Message>::value,
9555                 "Message must be trivially constructible");
9556 #endif
9557 
9558   static_assert(std::is_trivially_destructible<Message>::value,
9559                 "Message must be trivially destructible");
9560   stream_writer_ = stream_writer;
9561   arena_ = arena;
9562   size_ = 0;
9563   size_field_ = nullptr;
9564   size_already_written_ = 0;
9565   nested_message_ = nullptr;
9566   finalized_ = false;
9567 #if PERFETTO_DCHECK_IS_ON()
9568   handle_ = nullptr;
9569   generation_ = g_generation.fetch_add(1, std::memory_order_relaxed);
9570 #endif
9571 }
9572 
AppendString(uint32_t field_id,const char * str)9573 void Message::AppendString(uint32_t field_id, const char* str) {
9574   AppendBytes(field_id, str, strlen(str));
9575 }
9576 
AppendBytes(uint32_t field_id,const void * src,size_t size)9577 void Message::AppendBytes(uint32_t field_id, const void* src, size_t size) {
9578   if (nested_message_)
9579     EndNestedMessage();
9580 
9581   PERFETTO_DCHECK(size < proto_utils::kMaxMessageLength);
9582   // Write the proto preamble (field id, type and length of the field).
9583   uint8_t buffer[proto_utils::kMaxSimpleFieldEncodedSize];
9584   uint8_t* pos = buffer;
9585   pos = proto_utils::WriteVarInt(proto_utils::MakeTagLengthDelimited(field_id),
9586                                  pos);
9587   pos = proto_utils::WriteVarInt(static_cast<uint32_t>(size), pos);
9588   WriteToStream(buffer, pos);
9589 
9590   const uint8_t* src_u8 = reinterpret_cast<const uint8_t*>(src);
9591   WriteToStream(src_u8, src_u8 + size);
9592 }
9593 
AppendScatteredBytes(uint32_t field_id,ContiguousMemoryRange * ranges,size_t num_ranges)9594 size_t Message::AppendScatteredBytes(uint32_t field_id,
9595                                      ContiguousMemoryRange* ranges,
9596                                      size_t num_ranges) {
9597   size_t size = 0;
9598   for (size_t i = 0; i < num_ranges; ++i) {
9599     size += ranges[i].size();
9600   }
9601 
9602   PERFETTO_DCHECK(size < proto_utils::kMaxMessageLength);
9603 
9604   uint8_t buffer[proto_utils::kMaxSimpleFieldEncodedSize];
9605   uint8_t* pos = buffer;
9606   pos = proto_utils::WriteVarInt(proto_utils::MakeTagLengthDelimited(field_id),
9607                                  pos);
9608   pos = proto_utils::WriteVarInt(static_cast<uint32_t>(size), pos);
9609   WriteToStream(buffer, pos);
9610 
9611   for (size_t i = 0; i < num_ranges; ++i) {
9612     auto& range = ranges[i];
9613     WriteToStream(range.begin, range.end);
9614   }
9615 
9616   return size;
9617 }
9618 
Finalize()9619 uint32_t Message::Finalize() {
9620   if (finalized_)
9621     return size_;
9622 
9623   if (nested_message_)
9624     EndNestedMessage();
9625 
9626   // Write the length of the nested message a posteriori, using a leading-zero
9627   // redundant varint encoding.
9628   if (size_field_) {
9629     PERFETTO_DCHECK(!finalized_);
9630     PERFETTO_DCHECK(size_ < proto_utils::kMaxMessageLength);
9631     PERFETTO_DCHECK(size_ >= size_already_written_);
9632     proto_utils::WriteRedundantVarInt(size_ - size_already_written_,
9633                                       size_field_);
9634     size_field_ = nullptr;
9635   }
9636 
9637   finalized_ = true;
9638 #if PERFETTO_DCHECK_IS_ON()
9639   if (handle_)
9640     handle_->reset_message();
9641 #endif
9642 
9643   return size_;
9644 }
9645 
BeginNestedMessageInternal(uint32_t field_id)9646 Message* Message::BeginNestedMessageInternal(uint32_t field_id) {
9647   if (nested_message_)
9648     EndNestedMessage();
9649 
9650   // Write the proto preamble for the nested message.
9651   uint8_t data[proto_utils::kMaxTagEncodedSize];
9652   uint8_t* data_end = proto_utils::WriteVarInt(
9653       proto_utils::MakeTagLengthDelimited(field_id), data);
9654   WriteToStream(data, data_end);
9655 
9656   Message* message = arena_->NewMessage();
9657   message->Reset(stream_writer_, arena_);
9658 
9659   // The length of the nested message cannot be known upfront. So right now
9660   // just reserve the bytes to encode the size after the nested message is done.
9661   message->set_size_field(
9662       stream_writer_->ReserveBytes(proto_utils::kMessageLengthFieldSize));
9663   size_ += proto_utils::kMessageLengthFieldSize;
9664 
9665   nested_message_ = message;
9666   return message;
9667 }
9668 
EndNestedMessage()9669 void Message::EndNestedMessage() {
9670   size_ += nested_message_->Finalize();
9671   arena_->DeleteLastMessage(nested_message_);
9672   nested_message_ = nullptr;
9673 }
9674 
9675 }  // namespace protozero
9676 // gen_amalgamated begin source: src/protozero/message_arena.cc
9677 /*
9678  * Copyright (C) 2020 The Android Open Source Project
9679  *
9680  * Licensed under the Apache License, Version 2.0 (the "License");
9681  * you may not use this file except in compliance with the License.
9682  * You may obtain a copy of the License at
9683  *
9684  *      http://www.apache.org/licenses/LICENSE-2.0
9685  *
9686  * Unless required by applicable law or agreed to in writing, software
9687  * distributed under the License is distributed on an "AS IS" BASIS,
9688  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
9689  * See the License for the specific language governing permissions and
9690  * limitations under the License.
9691  */
9692 
9693 // gen_amalgamated expanded: #include "perfetto/protozero/message_arena.h"
9694 
9695 #include <atomic>
9696 #include <type_traits>
9697 
9698 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
9699 // gen_amalgamated expanded: #include "perfetto/protozero/message_handle.h"
9700 
9701 namespace protozero {
9702 
MessageArena()9703 MessageArena::MessageArena() {
9704   // The code below assumes that there is always at least one block.
9705   blocks_.emplace_front();
9706   static_assert(std::alignment_of<decltype(blocks_.back().storage[0])>::value >=
9707                     alignof(Message),
9708                 "MessageArea's storage is not properly aligned");
9709 }
9710 
9711 MessageArena::~MessageArena() = default;
9712 
NewMessage()9713 Message* MessageArena::NewMessage() {
9714   PERFETTO_DCHECK(!blocks_.empty());  // Should never become empty.
9715 
9716   Block* block = &blocks_.back();
9717   if (PERFETTO_UNLIKELY(block->entries >= Block::kCapacity)) {
9718     blocks_.emplace_back();
9719     block = &blocks_.back();
9720   }
9721   const auto idx = block->entries++;
9722   void* storage = &block->storage[idx];
9723   PERFETTO_ASAN_UNPOISON(storage, sizeof(Message));
9724   return new (storage) Message();
9725 }
9726 
DeleteLastMessageInternal()9727 void MessageArena::DeleteLastMessageInternal() {
9728   PERFETTO_DCHECK(!blocks_.empty());  // Should never be empty, see below.
9729   Block* block = &blocks_.back();
9730   PERFETTO_DCHECK(block->entries > 0);
9731 
9732   // This is the reason why there is no ~Message() call here.
9733   // MessageArea::Reset() (see header) also relies on dtor being trivial.
9734   static_assert(std::is_trivially_destructible<Message>::value,
9735                 "Message must be trivially destructible");
9736 
9737   --block->entries;
9738   PERFETTO_ASAN_POISON(&block->storage[block->entries], sizeof(Message));
9739 
9740   // Don't remove the first block to avoid malloc/free calls when the root
9741   // message is reset. Hitting the allocator all the times is a waste of time.
9742   if (block->entries == 0 && blocks_.size() > 1) {
9743     blocks_.pop_back();
9744   }
9745 }
9746 
9747 }  // namespace protozero
9748 // gen_amalgamated begin source: src/protozero/message_handle.cc
9749 /*
9750  * Copyright (C) 2017 The Android Open Source Project
9751  *
9752  * Licensed under the Apache License, Version 2.0 (the "License");
9753  * you may not use this file except in compliance with the License.
9754  * You may obtain a copy of the License at
9755  *
9756  *      http://www.apache.org/licenses/LICENSE-2.0
9757  *
9758  * Unless required by applicable law or agreed to in writing, software
9759  * distributed under the License is distributed on an "AS IS" BASIS,
9760  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
9761  * See the License for the specific language governing permissions and
9762  * limitations under the License.
9763  */
9764 
9765 // gen_amalgamated expanded: #include "perfetto/protozero/message_handle.h"
9766 
9767 #include <utility>
9768 
9769 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
9770 
9771 namespace protozero {
9772 
MessageHandleBase(Message * message)9773 MessageHandleBase::MessageHandleBase(Message* message) : message_(message) {
9774 #if PERFETTO_DCHECK_IS_ON()
9775   generation_ = message_ ? message->generation_ : 0;
9776   if (message_)
9777     message_->set_handle(this);
9778 #endif
9779 }
9780 
~MessageHandleBase()9781 MessageHandleBase::~MessageHandleBase() {
9782   if (message_) {
9783 #if PERFETTO_DCHECK_IS_ON()
9784     PERFETTO_DCHECK(generation_ == message_->generation_);
9785 #endif
9786     FinalizeMessage();
9787   }
9788 }
9789 
MessageHandleBase(MessageHandleBase && other)9790 MessageHandleBase::MessageHandleBase(MessageHandleBase&& other) noexcept {
9791   Move(std::move(other));
9792 }
9793 
operator =(MessageHandleBase && other)9794 MessageHandleBase& MessageHandleBase::operator=(MessageHandleBase&& other) {
9795   // If the current handle was pointing to a message and is being reset to a new
9796   // one, finalize the old message. However, if the other message is the same as
9797   // the one we point to, don't finalize.
9798   if (message_ && message_ != other.message_)
9799     FinalizeMessage();
9800   Move(std::move(other));
9801   return *this;
9802 }
9803 
Move(MessageHandleBase && other)9804 void MessageHandleBase::Move(MessageHandleBase&& other) {
9805   message_ = other.message_;
9806   other.message_ = nullptr;
9807 #if PERFETTO_DCHECK_IS_ON()
9808   if (message_) {
9809     generation_ = message_->generation_;
9810     message_->set_handle(this);
9811   }
9812 #endif
9813 }
9814 
9815 }  // namespace protozero
9816 // gen_amalgamated begin source: src/protozero/packed_repeated_fields.cc
9817 /*
9818  * Copyright (C) 2017 The Android Open Source Project
9819  *
9820  * Licensed under the Apache License, Version 2.0 (the "License");
9821  * you may not use this file except in compliance with the License.
9822  * You may obtain a copy of the License at
9823  *
9824  *      http://www.apache.org/licenses/LICENSE-2.0
9825  *
9826  * Unless required by applicable law or agreed to in writing, software
9827  * distributed under the License is distributed on an "AS IS" BASIS,
9828  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
9829  * See the License for the specific language governing permissions and
9830  * limitations under the License.
9831  */
9832 
9833 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
9834 
9835 // gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
9836 
9837 namespace protozero {
9838 
9839 // static
9840 constexpr size_t PackedBufferBase::kOnStackStorageSize;
9841 
GrowSlowpath()9842 void PackedBufferBase::GrowSlowpath() {
9843   size_t write_off = static_cast<size_t>(write_ptr_ - storage_begin_);
9844   size_t old_size = static_cast<size_t>(storage_end_ - storage_begin_);
9845   size_t new_size = old_size < 65536 ? (old_size * 2) : (old_size * 3 / 2);
9846   new_size = perfetto::base::AlignUp<4096>(new_size);
9847   std::unique_ptr<uint8_t[]> new_buf(new uint8_t[new_size]);
9848   memcpy(new_buf.get(), storage_begin_, old_size);
9849   heap_buf_ = std::move(new_buf);
9850   storage_begin_ = heap_buf_.get();
9851   storage_end_ = storage_begin_ + new_size;
9852   write_ptr_ = storage_begin_ + write_off;
9853 }
9854 
Reset()9855 void PackedBufferBase::Reset() {
9856   heap_buf_.reset();
9857   storage_begin_ = reinterpret_cast<uint8_t*>(&stack_buf_[0]);
9858   storage_end_ = reinterpret_cast<uint8_t*>(&stack_buf_[kOnStackStorageSize]);
9859   write_ptr_ = storage_begin_;
9860 }
9861 
9862 }  // namespace protozero
9863 // gen_amalgamated begin source: src/protozero/proto_decoder.cc
9864 /*
9865  * Copyright (C) 2018 The Android Open Source Project
9866  *
9867  * Licensed under the Apache License, Version 2.0 (the "License");
9868  * you may not use this file except in compliance with the License.
9869  * You may obtain a copy of the License at
9870  *
9871  *      http://www.apache.org/licenses/LICENSE-2.0
9872  *
9873  * Unless required by applicable law or agreed to in writing, software
9874  * distributed under the License is distributed on an "AS IS" BASIS,
9875  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
9876  * See the License for the specific language governing permissions and
9877  * limitations under the License.
9878  */
9879 
9880 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
9881 
9882 #include <string.h>
9883 
9884 #include <cinttypes>
9885 #include <limits>
9886 #include <memory>
9887 
9888 // gen_amalgamated expanded: #include "perfetto/base/compiler.h"
9889 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
9890 // gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
9891 // gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
9892 
9893 namespace protozero {
9894 
9895 using namespace proto_utils;
9896 
9897 #if !PERFETTO_IS_LITTLE_ENDIAN()
9898 #error Unimplemented for big endian archs.
9899 #endif
9900 
9901 namespace {
9902 
9903 struct ParseFieldResult {
9904   enum ParseResult { kAbort, kSkip, kOk };
9905   ParseResult parse_res;
9906   const uint8_t* next;
9907   Field field;
9908 };
9909 
9910 // Parses one field and returns the field itself and a pointer to the next
9911 // field to parse. If parsing fails, the returned |next| == |buffer|.
9912 PERFETTO_ALWAYS_INLINE ParseFieldResult
ParseOneField(const uint8_t * const buffer,const uint8_t * const end)9913 ParseOneField(const uint8_t* const buffer, const uint8_t* const end) {
9914   ParseFieldResult res{ParseFieldResult::kAbort, buffer, Field{}};
9915 
9916   // The first byte of a proto field is structured as follows:
9917   // The least 3 significant bits determine the field type.
9918   // The most 5 significant bits determine the field id. If MSB == 1, the
9919   // field id continues on the next bytes following the VarInt encoding.
9920   const uint8_t kFieldTypeNumBits = 3;
9921   const uint64_t kFieldTypeMask = (1 << kFieldTypeNumBits) - 1;  // 0000 0111;
9922   const uint8_t* pos = buffer;
9923 
9924   // If we've already hit the end, just return an invalid field.
9925   if (PERFETTO_UNLIKELY(pos >= end))
9926     return res;
9927 
9928   uint64_t preamble = 0;
9929   if (PERFETTO_LIKELY(*pos < 0x80)) {  // Fastpath for fields with ID < 16.
9930     preamble = *(pos++);
9931   } else {
9932     const uint8_t* next = ParseVarInt(pos, end, &preamble);
9933     if (PERFETTO_UNLIKELY(pos == next))
9934       return res;
9935     pos = next;
9936   }
9937 
9938   uint32_t field_id = static_cast<uint32_t>(preamble >> kFieldTypeNumBits);
9939   if (field_id == 0 || pos >= end)
9940     return res;
9941 
9942   auto field_type = static_cast<uint8_t>(preamble & kFieldTypeMask);
9943   const uint8_t* new_pos = pos;
9944   uint64_t int_value = 0;
9945   uint64_t size = 0;
9946 
9947   switch (field_type) {
9948     case static_cast<uint8_t>(ProtoWireType::kVarInt): {
9949       new_pos = ParseVarInt(pos, end, &int_value);
9950 
9951       // new_pos not being greater than pos means ParseVarInt could not fully
9952       // parse the number. This is because we are out of space in the buffer.
9953       // Set the id to zero and return but don't update the offset so a future
9954       // read can read this field.
9955       if (PERFETTO_UNLIKELY(new_pos == pos))
9956         return res;
9957 
9958       break;
9959     }
9960 
9961     case static_cast<uint8_t>(ProtoWireType::kLengthDelimited): {
9962       uint64_t payload_length;
9963       new_pos = ParseVarInt(pos, end, &payload_length);
9964       if (PERFETTO_UNLIKELY(new_pos == pos))
9965         return res;
9966 
9967       // ParseVarInt guarantees that |new_pos| <= |end| when it succeeds;
9968       if (payload_length > static_cast<uint64_t>(end - new_pos))
9969         return res;
9970 
9971       const uintptr_t payload_start = reinterpret_cast<uintptr_t>(new_pos);
9972       int_value = payload_start;
9973       size = payload_length;
9974       new_pos += payload_length;
9975       break;
9976     }
9977 
9978     case static_cast<uint8_t>(ProtoWireType::kFixed64): {
9979       new_pos = pos + sizeof(uint64_t);
9980       if (PERFETTO_UNLIKELY(new_pos > end))
9981         return res;
9982       memcpy(&int_value, pos, sizeof(uint64_t));
9983       break;
9984     }
9985 
9986     case static_cast<uint8_t>(ProtoWireType::kFixed32): {
9987       new_pos = pos + sizeof(uint32_t);
9988       if (PERFETTO_UNLIKELY(new_pos > end))
9989         return res;
9990       memcpy(&int_value, pos, sizeof(uint32_t));
9991       break;
9992     }
9993 
9994     default:
9995       PERFETTO_DLOG("Invalid proto field type: %u", field_type);
9996       return res;
9997   }
9998 
9999   res.next = new_pos;
10000 
10001   if (PERFETTO_UNLIKELY(field_id > std::numeric_limits<uint16_t>::max())) {
10002     PERFETTO_DLOG("Skipping field %" PRIu32 " because its id > 0xFFFF",
10003                   field_id);
10004     res.parse_res = ParseFieldResult::kSkip;
10005     return res;
10006   }
10007 
10008   if (PERFETTO_UNLIKELY(size > proto_utils::kMaxMessageLength)) {
10009     PERFETTO_DLOG("Skipping field %" PRIu32 " because it's too big (%" PRIu64
10010                   " KB)",
10011                   field_id, size / 1024);
10012     res.parse_res = ParseFieldResult::kSkip;
10013     return res;
10014   }
10015 
10016   res.parse_res = ParseFieldResult::kOk;
10017   res.field.initialize(static_cast<uint16_t>(field_id), field_type, int_value,
10018                        static_cast<uint32_t>(size));
10019   return res;
10020 }
10021 
10022 }  // namespace
10023 
FindField(uint32_t field_id)10024 Field ProtoDecoder::FindField(uint32_t field_id) {
10025   Field res{};
10026   auto old_position = read_ptr_;
10027   read_ptr_ = begin_;
10028   for (auto f = ReadField(); f.valid(); f = ReadField()) {
10029     if (f.id() == field_id) {
10030       res = f;
10031       break;
10032     }
10033   }
10034   read_ptr_ = old_position;
10035   return res;
10036 }
10037 
10038 PERFETTO_ALWAYS_INLINE
ReadField()10039 Field ProtoDecoder::ReadField() {
10040   ParseFieldResult res;
10041   do {
10042     res = ParseOneField(read_ptr_, end_);
10043     read_ptr_ = res.next;
10044   } while (PERFETTO_UNLIKELY(res.parse_res == ParseFieldResult::kSkip));
10045   return res.field;
10046 }
10047 
ParseAllFields()10048 void TypedProtoDecoderBase::ParseAllFields() {
10049   const uint8_t* cur = begin_;
10050   ParseFieldResult res;
10051   for (;;) {
10052     res = ParseOneField(cur, end_);
10053     PERFETTO_DCHECK(res.parse_res != ParseFieldResult::kOk || res.next != cur);
10054     cur = res.next;
10055     if (PERFETTO_UNLIKELY(res.parse_res == ParseFieldResult::kSkip))
10056       continue;
10057     if (PERFETTO_UNLIKELY(res.parse_res == ParseFieldResult::kAbort))
10058       break;
10059 
10060     PERFETTO_DCHECK(res.parse_res == ParseFieldResult::kOk);
10061     PERFETTO_DCHECK(res.field.valid());
10062     auto field_id = res.field.id();
10063     if (PERFETTO_UNLIKELY(field_id >= num_fields_))
10064       continue;
10065 
10066     // There are two reasons why we might want to expand the heap capacity:
10067     // 1. We are writing a non-repeated field, which has an id >
10068     //    INITIAL_STACK_CAPACITY. In this case ExpandHeapStorage() ensures to
10069     //    allocate at least (num_fields_ + 1) slots.
10070     // 2. We are writing a repeated field but ran out of capacity.
10071     if (PERFETTO_UNLIKELY(field_id >= size_ || size_ >= capacity_))
10072       ExpandHeapStorage();
10073 
10074     PERFETTO_DCHECK(field_id < size_);
10075     Field* fld = &fields_[field_id];
10076     if (PERFETTO_LIKELY(!fld->valid())) {
10077       // This is the first time we see this field.
10078       *fld = std::move(res.field);
10079     } else {
10080       // Repeated field case.
10081       // In this case we need to:
10082       // 1. Append the last value of the field to end of the repeated field
10083       //    storage.
10084       // 2. Replace the default instance at offset |field_id| with the current
10085       //    value. This is because in case of repeated field a call to Get(X) is
10086       //    supposed to return the last value of X, not the first one.
10087       // This is so that the RepeatedFieldIterator will iterate in the right
10088       // order, see comments on RepeatedFieldIterator.
10089       PERFETTO_DCHECK(size_ < capacity_);
10090       fields_[size_++] = *fld;
10091       *fld = std::move(res.field);
10092     }
10093   }
10094   read_ptr_ = res.next;
10095 }
10096 
ExpandHeapStorage()10097 void TypedProtoDecoderBase::ExpandHeapStorage() {
10098   // When we expand the heap we must ensure that we have at very last capacity
10099   // to deal with all known fields plus at least one repeated field. We go +2048
10100   // here based on observations on a large 4GB android trace. This is to avoid
10101   // trivial re-allocations when dealing with repeated fields of a message that
10102   // has > INITIAL_STACK_CAPACITY fields.
10103   const uint32_t min_capacity = num_fields_ + 2048;  // Any num >= +1 will do.
10104   const uint32_t new_capacity = std::max(capacity_ * 2, min_capacity);
10105   PERFETTO_CHECK(new_capacity > size_ && new_capacity > num_fields_);
10106   std::unique_ptr<Field[]> new_storage(new Field[new_capacity]);
10107 
10108   static_assert(std::is_trivially_constructible<Field>::value,
10109                 "Field must be trivially constructible");
10110   static_assert(std::is_trivially_copyable<Field>::value,
10111                 "Field must be trivially copyable");
10112 
10113   // Zero-initialize the slots for known field IDs slots, as they can be
10114   // randomly accessed. Instead, there is no need to initialize the repeated
10115   // slots, because they are written linearly with no gaps and are always
10116   // initialized before incrementing |size_|.
10117   const uint32_t new_size = std::max(size_, num_fields_);
10118   memset(&new_storage[size_], 0, sizeof(Field) * (new_size - size_));
10119 
10120   memcpy(&new_storage[0], fields_, sizeof(Field) * size_);
10121 
10122   heap_storage_ = std::move(new_storage);
10123   fields_ = &heap_storage_[0];
10124   capacity_ = new_capacity;
10125   size_ = new_size;
10126 }
10127 
10128 }  // namespace protozero
10129 // gen_amalgamated begin source: src/protozero/scattered_heap_buffer.cc
10130 /*
10131  * Copyright (C) 2017 The Android Open Source Project
10132  *
10133  * Licensed under the Apache License, Version 2.0 (the "License");
10134  * you may not use this file except in compliance with the License.
10135  * You may obtain a copy of the License at
10136  *
10137  *      http://www.apache.org/licenses/LICENSE-2.0
10138  *
10139  * Unless required by applicable law or agreed to in writing, software
10140  * distributed under the License is distributed on an "AS IS" BASIS,
10141  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10142  * See the License for the specific language governing permissions and
10143  * limitations under the License.
10144  */
10145 
10146 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
10147 
10148 #include <algorithm>
10149 
10150 namespace protozero {
10151 
Slice()10152 ScatteredHeapBuffer::Slice::Slice()
10153     : buffer_(nullptr), size_(0u), unused_bytes_(0u) {}
10154 
Slice(size_t size)10155 ScatteredHeapBuffer::Slice::Slice(size_t size)
10156     : buffer_(std::unique_ptr<uint8_t[]>(new uint8_t[size])),
10157       size_(size),
10158       unused_bytes_(size) {
10159   PERFETTO_DCHECK(size);
10160   Clear();
10161 }
10162 
10163 ScatteredHeapBuffer::Slice::Slice(Slice&& slice) noexcept = default;
10164 
10165 ScatteredHeapBuffer::Slice::~Slice() = default;
10166 
10167 ScatteredHeapBuffer::Slice& ScatteredHeapBuffer::Slice::operator=(Slice&&) =
10168     default;
10169 
Clear()10170 void ScatteredHeapBuffer::Slice::Clear() {
10171   unused_bytes_ = size_;
10172 #if PERFETTO_DCHECK_IS_ON()
10173   memset(start(), 0xff, size_);
10174 #endif  // PERFETTO_DCHECK_IS_ON()
10175 }
10176 
ScatteredHeapBuffer(size_t initial_slice_size_bytes,size_t maximum_slice_size_bytes)10177 ScatteredHeapBuffer::ScatteredHeapBuffer(size_t initial_slice_size_bytes,
10178                                          size_t maximum_slice_size_bytes)
10179     : next_slice_size_(initial_slice_size_bytes),
10180       maximum_slice_size_(maximum_slice_size_bytes) {
10181   PERFETTO_DCHECK(next_slice_size_ && maximum_slice_size_);
10182   PERFETTO_DCHECK(maximum_slice_size_ >= initial_slice_size_bytes);
10183 }
10184 
10185 ScatteredHeapBuffer::~ScatteredHeapBuffer() = default;
10186 
GetNewBuffer()10187 protozero::ContiguousMemoryRange ScatteredHeapBuffer::GetNewBuffer() {
10188   PERFETTO_CHECK(writer_);
10189   AdjustUsedSizeOfCurrentSlice();
10190 
10191   if (cached_slice_.start()) {
10192     slices_.push_back(std::move(cached_slice_));
10193     PERFETTO_DCHECK(!cached_slice_.start());
10194   } else {
10195     slices_.emplace_back(next_slice_size_);
10196   }
10197   next_slice_size_ = std::min(maximum_slice_size_, next_slice_size_ * 2);
10198   return slices_.back().GetTotalRange();
10199 }
10200 
10201 const std::vector<ScatteredHeapBuffer::Slice>&
GetSlices()10202 ScatteredHeapBuffer::GetSlices() {
10203   AdjustUsedSizeOfCurrentSlice();
10204   return slices_;
10205 }
10206 
StitchSlices()10207 std::vector<uint8_t> ScatteredHeapBuffer::StitchSlices() {
10208   size_t stitched_size = 0u;
10209   const auto& slices = GetSlices();
10210   for (const auto& slice : slices)
10211     stitched_size += slice.size() - slice.unused_bytes();
10212 
10213   std::vector<uint8_t> buffer;
10214   buffer.reserve(stitched_size);
10215   for (const auto& slice : slices) {
10216     auto used_range = slice.GetUsedRange();
10217     buffer.insert(buffer.end(), used_range.begin, used_range.end);
10218   }
10219   return buffer;
10220 }
10221 
GetRanges()10222 std::vector<protozero::ContiguousMemoryRange> ScatteredHeapBuffer::GetRanges() {
10223   std::vector<protozero::ContiguousMemoryRange> ranges;
10224   for (const auto& slice : GetSlices())
10225     ranges.push_back(slice.GetUsedRange());
10226   return ranges;
10227 }
10228 
AdjustUsedSizeOfCurrentSlice()10229 void ScatteredHeapBuffer::AdjustUsedSizeOfCurrentSlice() {
10230   if (!slices_.empty())
10231     slices_.back().set_unused_bytes(writer_->bytes_available());
10232 }
10233 
GetTotalSize()10234 size_t ScatteredHeapBuffer::GetTotalSize() {
10235   size_t total_size = 0;
10236   for (auto& slice : slices_) {
10237     total_size += slice.size();
10238   }
10239   return total_size;
10240 }
10241 
Reset()10242 void ScatteredHeapBuffer::Reset() {
10243   if (slices_.empty())
10244     return;
10245   cached_slice_ = std::move(slices_.front());
10246   cached_slice_.Clear();
10247   slices_.clear();
10248 }
10249 
10250 }  // namespace protozero
10251 // gen_amalgamated begin source: src/protozero/scattered_stream_null_delegate.cc
10252 // gen_amalgamated begin header: include/perfetto/protozero/scattered_stream_null_delegate.h
10253 /*
10254  * Copyright (C) 2018 The Android Open Source Project
10255  *
10256  * Licensed under the Apache License, Version 2.0 (the "License");
10257  * you may not use this file except in compliance with the License.
10258  * You may obtain a copy of the License at
10259  *
10260  *      http://www.apache.org/licenses/LICENSE-2.0
10261  *
10262  * Unless required by applicable law or agreed to in writing, software
10263  * distributed under the License is distributed on an "AS IS" BASIS,
10264  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10265  * See the License for the specific language governing permissions and
10266  * limitations under the License.
10267  */
10268 
10269 #ifndef INCLUDE_PERFETTO_PROTOZERO_SCATTERED_STREAM_NULL_DELEGATE_H_
10270 #define INCLUDE_PERFETTO_PROTOZERO_SCATTERED_STREAM_NULL_DELEGATE_H_
10271 
10272 #include <memory>
10273 #include <vector>
10274 
10275 // gen_amalgamated expanded: #include "perfetto/base/export.h"
10276 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
10277 // gen_amalgamated expanded: #include "perfetto/protozero/contiguous_memory_range.h"
10278 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_stream_writer.h"
10279 
10280 namespace protozero {
10281 
10282 class PERFETTO_EXPORT ScatteredStreamWriterNullDelegate
10283     : public ScatteredStreamWriter::Delegate {
10284  public:
10285   explicit ScatteredStreamWriterNullDelegate(size_t chunk_size);
10286   ~ScatteredStreamWriterNullDelegate() override;
10287 
10288   // protozero::ScatteredStreamWriter::Delegate implementation.
10289   ContiguousMemoryRange GetNewBuffer() override;
10290 
10291  private:
10292   const size_t chunk_size_;
10293   std::unique_ptr<uint8_t[]> chunk_;
10294 };
10295 
10296 }  // namespace protozero
10297 
10298 #endif  // INCLUDE_PERFETTO_PROTOZERO_SCATTERED_STREAM_NULL_DELEGATE_H_
10299 /*
10300  * Copyright (C) 2018 The Android Open Source Project
10301  *
10302  * Licensed under the Apache License, Version 2.0 (the "License");
10303  * you may not use this file except in compliance with the License.
10304  * You may obtain a copy of the License at
10305  *
10306  *      http://www.apache.org/licenses/LICENSE-2.0
10307  *
10308  * Unless required by applicable law or agreed to in writing, software
10309  * distributed under the License is distributed on an "AS IS" BASIS,
10310  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10311  * See the License for the specific language governing permissions and
10312  * limitations under the License.
10313  */
10314 
10315 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_stream_null_delegate.h"
10316 
10317 namespace protozero {
10318 
10319 // An implementation of ScatteredStreamWriter::Delegate which always returns
10320 // the same piece of memory.
10321 // This is used when we need to no-op the writers (e.g. during teardown or in
10322 // case of resource exhaustion), avoiding that the clients have to deal with
10323 // nullptr checks.
ScatteredStreamWriterNullDelegate(size_t chunk_size)10324 ScatteredStreamWriterNullDelegate::ScatteredStreamWriterNullDelegate(
10325     size_t chunk_size)
10326     : chunk_size_(chunk_size),
10327       chunk_(std::unique_ptr<uint8_t[]>(new uint8_t[chunk_size_])) {}
10328 
~ScatteredStreamWriterNullDelegate()10329 ScatteredStreamWriterNullDelegate::~ScatteredStreamWriterNullDelegate() {}
10330 
GetNewBuffer()10331 ContiguousMemoryRange ScatteredStreamWriterNullDelegate::GetNewBuffer() {
10332   return {chunk_.get(), chunk_.get() + chunk_size_};
10333 }
10334 
10335 }  // namespace protozero
10336 // gen_amalgamated begin source: src/protozero/scattered_stream_writer.cc
10337 /*
10338  * Copyright (C) 2017 The Android Open Source Project
10339  *
10340  * Licensed under the Apache License, Version 2.0 (the "License");
10341  * you may not use this file except in compliance with the License.
10342  * You may obtain a copy of the License at
10343  *
10344  *      http://www.apache.org/licenses/LICENSE-2.0
10345  *
10346  * Unless required by applicable law or agreed to in writing, software
10347  * distributed under the License is distributed on an "AS IS" BASIS,
10348  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10349  * See the License for the specific language governing permissions and
10350  * limitations under the License.
10351  */
10352 
10353 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_stream_writer.h"
10354 
10355 #include <algorithm>
10356 
10357 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
10358 
10359 namespace protozero {
10360 
~Delegate()10361 ScatteredStreamWriter::Delegate::~Delegate() {}
10362 
ScatteredStreamWriter(Delegate * delegate)10363 ScatteredStreamWriter::ScatteredStreamWriter(Delegate* delegate)
10364     : delegate_(delegate),
10365       cur_range_({nullptr, nullptr}),
10366       write_ptr_(nullptr) {}
10367 
~ScatteredStreamWriter()10368 ScatteredStreamWriter::~ScatteredStreamWriter() {}
10369 
Reset(ContiguousMemoryRange range)10370 void ScatteredStreamWriter::Reset(ContiguousMemoryRange range) {
10371   written_previously_ += static_cast<uint64_t>(write_ptr_ - cur_range_.begin);
10372   cur_range_ = range;
10373   write_ptr_ = range.begin;
10374   PERFETTO_DCHECK(!write_ptr_ || write_ptr_ < cur_range_.end);
10375 }
10376 
Extend()10377 void ScatteredStreamWriter::Extend() {
10378   Reset(delegate_->GetNewBuffer());
10379 }
10380 
WriteBytesSlowPath(const uint8_t * src,size_t size)10381 void ScatteredStreamWriter::WriteBytesSlowPath(const uint8_t* src,
10382                                                size_t size) {
10383   size_t bytes_left = size;
10384   while (bytes_left > 0) {
10385     if (write_ptr_ >= cur_range_.end)
10386       Extend();
10387     const size_t burst_size = std::min(bytes_available(), bytes_left);
10388     WriteBytesUnsafe(src, burst_size);
10389     bytes_left -= burst_size;
10390     src += burst_size;
10391   }
10392 }
10393 
10394 // TODO(primiano): perf optimization: I suspect that at the end this will always
10395 // be called with |size| == 4, in which case we might just hardcode it.
ReserveBytes(size_t size)10396 uint8_t* ScatteredStreamWriter::ReserveBytes(size_t size) {
10397   if (write_ptr_ + size > cur_range_.end) {
10398     // Assume the reservations are always < Delegate::GetNewBuffer().size(),
10399     // so that one single call to Extend() will definitely give enough headroom.
10400     Extend();
10401     PERFETTO_DCHECK(write_ptr_ + size <= cur_range_.end);
10402   }
10403   uint8_t* begin = write_ptr_;
10404   write_ptr_ += size;
10405 #if PERFETTO_DCHECK_IS_ON()
10406   // In the past, the service had a matching DCHECK in
10407   // TraceBuffer::TryPatchChunkContents, which was assuming that service and all
10408   // producers are built with matching DCHECK levels. This turned out to be a
10409   // source of problems and was removed in b/197340286. This memset is useless
10410   // these days and is here only to maintain ABI compatibility between producers
10411   // that use a v20+ SDK and older versions of the service that were built in
10412   // debug mode. At some point around 2023 it should be safe to remove it.
10413   // (running a debug version of traced in production seems a bad idea
10414   // regardless).
10415   memset(begin, 0, size);
10416 #endif
10417   return begin;
10418 }
10419 
10420 }  // namespace protozero
10421 // gen_amalgamated begin source: src/protozero/static_buffer.cc
10422 // gen_amalgamated begin header: include/perfetto/protozero/static_buffer.h
10423 /*
10424  * Copyright (C) 2019 The Android Open Source Project
10425  *
10426  * Licensed under the Apache License, Version 2.0 (the "License");
10427  * you may not use this file except in compliance with the License.
10428  * You may obtain a copy of the License at
10429  *
10430  *      http://www.apache.org/licenses/LICENSE-2.0
10431  *
10432  * Unless required by applicable law or agreed to in writing, software
10433  * distributed under the License is distributed on an "AS IS" BASIS,
10434  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10435  * See the License for the specific language governing permissions and
10436  * limitations under the License.
10437  */
10438 
10439 #ifndef INCLUDE_PERFETTO_PROTOZERO_STATIC_BUFFER_H_
10440 #define INCLUDE_PERFETTO_PROTOZERO_STATIC_BUFFER_H_
10441 
10442 #include <memory>
10443 #include <string>
10444 #include <vector>
10445 
10446 // gen_amalgamated expanded: #include "perfetto/base/export.h"
10447 // gen_amalgamated expanded: #include "perfetto/protozero/root_message.h"
10448 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_stream_writer.h"
10449 
10450 namespace protozero {
10451 
10452 class Message;
10453 
10454 // A simple implementation of ScatteredStreamWriter::Delegate backed by a
10455 // fixed-size buffer. It doesn't support expansion. The caller needs to ensure
10456 // to never write more than the size of the buffer. Will CHECK() otherwise.
10457 class PERFETTO_EXPORT StaticBufferDelegate
10458     : public ScatteredStreamWriter::Delegate {
10459  public:
StaticBufferDelegate(uint8_t * buf,size_t len)10460   StaticBufferDelegate(uint8_t* buf, size_t len) : range_{buf, buf + len} {}
10461   ~StaticBufferDelegate() override;
10462 
10463   // ScatteredStreamWriter::Delegate implementation.
10464   ContiguousMemoryRange GetNewBuffer() override;
10465 
10466   ContiguousMemoryRange const range_;
10467   bool get_new_buffer_called_once_ = false;
10468 };
10469 
10470 // Helper function to create protozero messages backed by a fixed-size buffer
10471 // in one line. You can write:
10472 //   protozero::Static<protozero::MyMessage> msg(buf.data(), buf.size());
10473 //   msg->set_stuff(...);
10474 //   size_t bytes_encoded = msg.Finalize();
10475 template <typename T /* protozero::Message */>
10476 class StaticBuffered {
10477  public:
StaticBuffered(void * buf,size_t len)10478   StaticBuffered(void* buf, size_t len)
10479       : delegate_(reinterpret_cast<uint8_t*>(buf), len), writer_(&delegate_) {
10480     msg_.Reset(&writer_);
10481   }
10482 
10483   // This can't be neither copied nor moved because Message hands out pointers
10484   // to itself when creating submessages.
10485   StaticBuffered(const StaticBuffered&) = delete;
10486   StaticBuffered& operator=(const StaticBuffered&) = delete;
10487   StaticBuffered(StaticBuffered&&) = delete;
10488   StaticBuffered& operator=(StaticBuffered&&) = delete;
10489 
get()10490   T* get() { return &msg_; }
operator ->()10491   T* operator->() { return &msg_; }
10492 
10493   // The lack of a size() method is deliberate. It's to prevent that one
10494   // accidentally calls size() before Finalize().
10495 
10496   // Returns the number of encoded bytes (<= the size passed in the ctor).
Finalize()10497   size_t Finalize() {
10498     msg_.Finalize();
10499     return static_cast<size_t>(writer_.write_ptr() - delegate_.range_.begin);
10500   }
10501 
10502  private:
10503   StaticBufferDelegate delegate_;
10504   ScatteredStreamWriter writer_;
10505   RootMessage<T> msg_;
10506 };
10507 
10508 // Helper function to create stack-based protozero messages in one line.
10509 // You can write:
10510 //   protozero::StackBuffered<protozero::MyMessage, 16> msg;
10511 //   msg->set_stuff(...);
10512 //   size_t bytes_encoded = msg.Finalize();
10513 template <typename T /* protozero::Message */, size_t N>
10514 class StackBuffered : public StaticBuffered<T> {
10515  public:
StackBuffered()10516   StackBuffered() : StaticBuffered<T>(&buf_[0], N) {}
10517 
10518  private:
10519   uint8_t buf_[N];  // Deliberately not initialized.
10520 };
10521 
10522 }  // namespace protozero
10523 
10524 #endif  // INCLUDE_PERFETTO_PROTOZERO_STATIC_BUFFER_H_
10525 /*
10526  * Copyright (C) 2019 The Android Open Source Project
10527  *
10528  * Licensed under the Apache License, Version 2.0 (the "License");
10529  * you may not use this file except in compliance with the License.
10530  * You may obtain a copy of the License at
10531  *
10532  *      http://www.apache.org/licenses/LICENSE-2.0
10533  *
10534  * Unless required by applicable law or agreed to in writing, software
10535  * distributed under the License is distributed on an "AS IS" BASIS,
10536  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10537  * See the License for the specific language governing permissions and
10538  * limitations under the License.
10539  */
10540 
10541 // gen_amalgamated expanded: #include "perfetto/protozero/static_buffer.h"
10542 
10543 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
10544 
10545 namespace protozero {
10546 
10547 StaticBufferDelegate::~StaticBufferDelegate() = default;
10548 
GetNewBuffer()10549 ContiguousMemoryRange StaticBufferDelegate::GetNewBuffer() {
10550   if (get_new_buffer_called_once_) {
10551     // This is the 2nd time GetNewBuffer is called. The estimate is wrong. We
10552     // shouldn't try to grow the buffer after the initial call.
10553     PERFETTO_FATAL("Static buffer too small");
10554   }
10555   get_new_buffer_called_once_ = true;
10556   return range_;
10557 }
10558 
10559 }  // namespace protozero
10560 // gen_amalgamated begin source: src/protozero/virtual_destructors.cc
10561 /*
10562  * Copyright (C) 2019 The Android Open Source Project
10563  *
10564  * Licensed under the Apache License, Version 2.0 (the "License");
10565  * you may not use this file except in compliance with the License.
10566  * You may obtain a copy of the License at
10567  *
10568  *      http://www.apache.org/licenses/LICENSE-2.0
10569  *
10570  * Unless required by applicable law or agreed to in writing, software
10571  * distributed under the License is distributed on an "AS IS" BASIS,
10572  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10573  * See the License for the specific language governing permissions and
10574  * limitations under the License.
10575  */
10576 
10577 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
10578 
10579 namespace protozero {
10580 
10581 CppMessageObj::~CppMessageObj() = default;
10582 
10583 }  // namespace protozero
10584 // gen_amalgamated begin source: gen/protos/perfetto/common/android_energy_consumer_descriptor.gen.cc
10585 // gen_amalgamated begin header: gen/protos/perfetto/common/android_energy_consumer_descriptor.gen.h
10586 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
10587 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_ANDROID_ENERGY_CONSUMER_DESCRIPTOR_PROTO_CPP_H_
10588 #define PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_ANDROID_ENERGY_CONSUMER_DESCRIPTOR_PROTO_CPP_H_
10589 
10590 #include <stdint.h>
10591 #include <bitset>
10592 #include <vector>
10593 #include <string>
10594 #include <type_traits>
10595 
10596 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
10597 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
10598 // gen_amalgamated expanded: #include "perfetto/base/export.h"
10599 
10600 namespace perfetto {
10601 namespace protos {
10602 namespace gen {
10603 class AndroidEnergyConsumerDescriptor;
10604 class AndroidEnergyConsumer;
10605 }  // namespace perfetto
10606 }  // namespace protos
10607 }  // namespace gen
10608 
10609 namespace protozero {
10610 class Message;
10611 }  // namespace protozero
10612 
10613 namespace perfetto {
10614 namespace protos {
10615 namespace gen {
10616 
10617 class PERFETTO_EXPORT AndroidEnergyConsumerDescriptor : public ::protozero::CppMessageObj {
10618  public:
10619   enum FieldNumbers {
10620     kEnergyConsumersFieldNumber = 1,
10621   };
10622 
10623   AndroidEnergyConsumerDescriptor();
10624   ~AndroidEnergyConsumerDescriptor() override;
10625   AndroidEnergyConsumerDescriptor(AndroidEnergyConsumerDescriptor&&) noexcept;
10626   AndroidEnergyConsumerDescriptor& operator=(AndroidEnergyConsumerDescriptor&&);
10627   AndroidEnergyConsumerDescriptor(const AndroidEnergyConsumerDescriptor&);
10628   AndroidEnergyConsumerDescriptor& operator=(const AndroidEnergyConsumerDescriptor&);
10629   bool operator==(const AndroidEnergyConsumerDescriptor&) const;
operator !=(const AndroidEnergyConsumerDescriptor & other) const10630   bool operator!=(const AndroidEnergyConsumerDescriptor& other) const { return !(*this == other); }
10631 
10632   bool ParseFromArray(const void*, size_t) override;
10633   std::string SerializeAsString() const override;
10634   std::vector<uint8_t> SerializeAsArray() const override;
10635   void Serialize(::protozero::Message*) const;
10636 
energy_consumers() const10637   const std::vector<AndroidEnergyConsumer>& energy_consumers() const { return energy_consumers_; }
mutable_energy_consumers()10638   std::vector<AndroidEnergyConsumer>* mutable_energy_consumers() { return &energy_consumers_; }
10639   int energy_consumers_size() const;
10640   void clear_energy_consumers();
10641   AndroidEnergyConsumer* add_energy_consumers();
10642 
10643  private:
10644   std::vector<AndroidEnergyConsumer> energy_consumers_;
10645 
10646   // Allows to preserve unknown protobuf fields for compatibility
10647   // with future versions of .proto files.
10648   std::string unknown_fields_;
10649 
10650   std::bitset<2> _has_field_{};
10651 };
10652 
10653 
10654 class PERFETTO_EXPORT AndroidEnergyConsumer : public ::protozero::CppMessageObj {
10655  public:
10656   enum FieldNumbers {
10657     kEnergyConsumerIdFieldNumber = 1,
10658     kOrdinalFieldNumber = 2,
10659     kTypeFieldNumber = 3,
10660     kNameFieldNumber = 4,
10661   };
10662 
10663   AndroidEnergyConsumer();
10664   ~AndroidEnergyConsumer() override;
10665   AndroidEnergyConsumer(AndroidEnergyConsumer&&) noexcept;
10666   AndroidEnergyConsumer& operator=(AndroidEnergyConsumer&&);
10667   AndroidEnergyConsumer(const AndroidEnergyConsumer&);
10668   AndroidEnergyConsumer& operator=(const AndroidEnergyConsumer&);
10669   bool operator==(const AndroidEnergyConsumer&) const;
operator !=(const AndroidEnergyConsumer & other) const10670   bool operator!=(const AndroidEnergyConsumer& other) const { return !(*this == other); }
10671 
10672   bool ParseFromArray(const void*, size_t) override;
10673   std::string SerializeAsString() const override;
10674   std::vector<uint8_t> SerializeAsArray() const override;
10675   void Serialize(::protozero::Message*) const;
10676 
has_energy_consumer_id() const10677   bool has_energy_consumer_id() const { return _has_field_[1]; }
energy_consumer_id() const10678   int32_t energy_consumer_id() const { return energy_consumer_id_; }
set_energy_consumer_id(int32_t value)10679   void set_energy_consumer_id(int32_t value) { energy_consumer_id_ = value; _has_field_.set(1); }
10680 
has_ordinal() const10681   bool has_ordinal() const { return _has_field_[2]; }
ordinal() const10682   int32_t ordinal() const { return ordinal_; }
set_ordinal(int32_t value)10683   void set_ordinal(int32_t value) { ordinal_ = value; _has_field_.set(2); }
10684 
has_type() const10685   bool has_type() const { return _has_field_[3]; }
type() const10686   const std::string& type() const { return type_; }
set_type(const std::string & value)10687   void set_type(const std::string& value) { type_ = value; _has_field_.set(3); }
10688 
has_name() const10689   bool has_name() const { return _has_field_[4]; }
name() const10690   const std::string& name() const { return name_; }
set_name(const std::string & value)10691   void set_name(const std::string& value) { name_ = value; _has_field_.set(4); }
10692 
10693  private:
10694   int32_t energy_consumer_id_{};
10695   int32_t ordinal_{};
10696   std::string type_{};
10697   std::string name_{};
10698 
10699   // Allows to preserve unknown protobuf fields for compatibility
10700   // with future versions of .proto files.
10701   std::string unknown_fields_;
10702 
10703   std::bitset<5> _has_field_{};
10704 };
10705 
10706 }  // namespace perfetto
10707 }  // namespace protos
10708 }  // namespace gen
10709 
10710 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_ANDROID_ENERGY_CONSUMER_DESCRIPTOR_PROTO_CPP_H_
10711 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
10712 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
10713 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
10714 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
10715 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
10716 #if defined(__GNUC__) || defined(__clang__)
10717 #pragma GCC diagnostic push
10718 #pragma GCC diagnostic ignored "-Wfloat-equal"
10719 #endif
10720 // gen_amalgamated expanded: #include "protos/perfetto/common/android_energy_consumer_descriptor.gen.h"
10721 
10722 namespace perfetto {
10723 namespace protos {
10724 namespace gen {
10725 
10726 AndroidEnergyConsumerDescriptor::AndroidEnergyConsumerDescriptor() = default;
10727 AndroidEnergyConsumerDescriptor::~AndroidEnergyConsumerDescriptor() = default;
10728 AndroidEnergyConsumerDescriptor::AndroidEnergyConsumerDescriptor(const AndroidEnergyConsumerDescriptor&) = default;
10729 AndroidEnergyConsumerDescriptor& AndroidEnergyConsumerDescriptor::operator=(const AndroidEnergyConsumerDescriptor&) = default;
10730 AndroidEnergyConsumerDescriptor::AndroidEnergyConsumerDescriptor(AndroidEnergyConsumerDescriptor&&) noexcept = default;
10731 AndroidEnergyConsumerDescriptor& AndroidEnergyConsumerDescriptor::operator=(AndroidEnergyConsumerDescriptor&&) = default;
10732 
operator ==(const AndroidEnergyConsumerDescriptor & other) const10733 bool AndroidEnergyConsumerDescriptor::operator==(const AndroidEnergyConsumerDescriptor& other) const {
10734   return unknown_fields_ == other.unknown_fields_
10735    && energy_consumers_ == other.energy_consumers_;
10736 }
10737 
energy_consumers_size() const10738 int AndroidEnergyConsumerDescriptor::energy_consumers_size() const { return static_cast<int>(energy_consumers_.size()); }
clear_energy_consumers()10739 void AndroidEnergyConsumerDescriptor::clear_energy_consumers() { energy_consumers_.clear(); }
add_energy_consumers()10740 AndroidEnergyConsumer* AndroidEnergyConsumerDescriptor::add_energy_consumers() { energy_consumers_.emplace_back(); return &energy_consumers_.back(); }
ParseFromArray(const void * raw,size_t size)10741 bool AndroidEnergyConsumerDescriptor::ParseFromArray(const void* raw, size_t size) {
10742   energy_consumers_.clear();
10743   unknown_fields_.clear();
10744   bool packed_error = false;
10745 
10746   ::protozero::ProtoDecoder dec(raw, size);
10747   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
10748     if (field.id() < _has_field_.size()) {
10749       _has_field_.set(field.id());
10750     }
10751     switch (field.id()) {
10752       case 1 /* energy_consumers */:
10753         energy_consumers_.emplace_back();
10754         energy_consumers_.back().ParseFromArray(field.data(), field.size());
10755         break;
10756       default:
10757         field.SerializeAndAppendTo(&unknown_fields_);
10758         break;
10759     }
10760   }
10761   return !packed_error && !dec.bytes_left();
10762 }
10763 
SerializeAsString() const10764 std::string AndroidEnergyConsumerDescriptor::SerializeAsString() const {
10765   ::protozero::HeapBuffered<::protozero::Message> msg;
10766   Serialize(msg.get());
10767   return msg.SerializeAsString();
10768 }
10769 
SerializeAsArray() const10770 std::vector<uint8_t> AndroidEnergyConsumerDescriptor::SerializeAsArray() const {
10771   ::protozero::HeapBuffered<::protozero::Message> msg;
10772   Serialize(msg.get());
10773   return msg.SerializeAsArray();
10774 }
10775 
Serialize(::protozero::Message * msg) const10776 void AndroidEnergyConsumerDescriptor::Serialize(::protozero::Message* msg) const {
10777   // Field 1: energy_consumers
10778   for (auto& it : energy_consumers_) {
10779     it.Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
10780   }
10781 
10782   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
10783 }
10784 
10785 
10786 AndroidEnergyConsumer::AndroidEnergyConsumer() = default;
10787 AndroidEnergyConsumer::~AndroidEnergyConsumer() = default;
10788 AndroidEnergyConsumer::AndroidEnergyConsumer(const AndroidEnergyConsumer&) = default;
10789 AndroidEnergyConsumer& AndroidEnergyConsumer::operator=(const AndroidEnergyConsumer&) = default;
10790 AndroidEnergyConsumer::AndroidEnergyConsumer(AndroidEnergyConsumer&&) noexcept = default;
10791 AndroidEnergyConsumer& AndroidEnergyConsumer::operator=(AndroidEnergyConsumer&&) = default;
10792 
operator ==(const AndroidEnergyConsumer & other) const10793 bool AndroidEnergyConsumer::operator==(const AndroidEnergyConsumer& other) const {
10794   return unknown_fields_ == other.unknown_fields_
10795    && energy_consumer_id_ == other.energy_consumer_id_
10796    && ordinal_ == other.ordinal_
10797    && type_ == other.type_
10798    && name_ == other.name_;
10799 }
10800 
ParseFromArray(const void * raw,size_t size)10801 bool AndroidEnergyConsumer::ParseFromArray(const void* raw, size_t size) {
10802   unknown_fields_.clear();
10803   bool packed_error = false;
10804 
10805   ::protozero::ProtoDecoder dec(raw, size);
10806   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
10807     if (field.id() < _has_field_.size()) {
10808       _has_field_.set(field.id());
10809     }
10810     switch (field.id()) {
10811       case 1 /* energy_consumer_id */:
10812         field.get(&energy_consumer_id_);
10813         break;
10814       case 2 /* ordinal */:
10815         field.get(&ordinal_);
10816         break;
10817       case 3 /* type */:
10818         field.get(&type_);
10819         break;
10820       case 4 /* name */:
10821         field.get(&name_);
10822         break;
10823       default:
10824         field.SerializeAndAppendTo(&unknown_fields_);
10825         break;
10826     }
10827   }
10828   return !packed_error && !dec.bytes_left();
10829 }
10830 
SerializeAsString() const10831 std::string AndroidEnergyConsumer::SerializeAsString() const {
10832   ::protozero::HeapBuffered<::protozero::Message> msg;
10833   Serialize(msg.get());
10834   return msg.SerializeAsString();
10835 }
10836 
SerializeAsArray() const10837 std::vector<uint8_t> AndroidEnergyConsumer::SerializeAsArray() const {
10838   ::protozero::HeapBuffered<::protozero::Message> msg;
10839   Serialize(msg.get());
10840   return msg.SerializeAsArray();
10841 }
10842 
Serialize(::protozero::Message * msg) const10843 void AndroidEnergyConsumer::Serialize(::protozero::Message* msg) const {
10844   // Field 1: energy_consumer_id
10845   if (_has_field_[1]) {
10846     msg->AppendVarInt(1, energy_consumer_id_);
10847   }
10848 
10849   // Field 2: ordinal
10850   if (_has_field_[2]) {
10851     msg->AppendVarInt(2, ordinal_);
10852   }
10853 
10854   // Field 3: type
10855   if (_has_field_[3]) {
10856     msg->AppendString(3, type_);
10857   }
10858 
10859   // Field 4: name
10860   if (_has_field_[4]) {
10861     msg->AppendString(4, name_);
10862   }
10863 
10864   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
10865 }
10866 
10867 }  // namespace perfetto
10868 }  // namespace protos
10869 }  // namespace gen
10870 #if defined(__GNUC__) || defined(__clang__)
10871 #pragma GCC diagnostic pop
10872 #endif
10873 // gen_amalgamated begin source: gen/protos/perfetto/common/android_log_constants.gen.cc
10874 // gen_amalgamated begin header: gen/protos/perfetto/common/android_log_constants.gen.h
10875 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
10876 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_ANDROID_LOG_CONSTANTS_PROTO_CPP_H_
10877 #define PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_ANDROID_LOG_CONSTANTS_PROTO_CPP_H_
10878 
10879 #include <stdint.h>
10880 #include <bitset>
10881 #include <vector>
10882 #include <string>
10883 #include <type_traits>
10884 
10885 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
10886 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
10887 // gen_amalgamated expanded: #include "perfetto/base/export.h"
10888 
10889 namespace perfetto {
10890 namespace protos {
10891 namespace gen {
10892 enum AndroidLogId : int;
10893 enum AndroidLogPriority : int;
10894 }  // namespace perfetto
10895 }  // namespace protos
10896 }  // namespace gen
10897 
10898 namespace protozero {
10899 class Message;
10900 }  // namespace protozero
10901 
10902 namespace perfetto {
10903 namespace protos {
10904 namespace gen {
10905 enum AndroidLogId : int {
10906   LID_DEFAULT = 0,
10907   LID_RADIO = 1,
10908   LID_EVENTS = 2,
10909   LID_SYSTEM = 3,
10910   LID_CRASH = 4,
10911   LID_STATS = 5,
10912   LID_SECURITY = 6,
10913   LID_KERNEL = 7,
10914 };
10915 enum AndroidLogPriority : int {
10916   PRIO_UNSPECIFIED = 0,
10917   PRIO_UNUSED = 1,
10918   PRIO_VERBOSE = 2,
10919   PRIO_DEBUG = 3,
10920   PRIO_INFO = 4,
10921   PRIO_WARN = 5,
10922   PRIO_ERROR = 6,
10923   PRIO_FATAL = 7,
10924 };
10925 }  // namespace perfetto
10926 }  // namespace protos
10927 }  // namespace gen
10928 
10929 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_ANDROID_LOG_CONSTANTS_PROTO_CPP_H_
10930 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
10931 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
10932 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
10933 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
10934 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
10935 #if defined(__GNUC__) || defined(__clang__)
10936 #pragma GCC diagnostic push
10937 #pragma GCC diagnostic ignored "-Wfloat-equal"
10938 #endif
10939 // gen_amalgamated expanded: #include "protos/perfetto/common/android_log_constants.gen.h"
10940 
10941 namespace perfetto {
10942 namespace protos {
10943 namespace gen {
10944 }  // namespace perfetto
10945 }  // namespace protos
10946 }  // namespace gen
10947 #if defined(__GNUC__) || defined(__clang__)
10948 #pragma GCC diagnostic pop
10949 #endif
10950 // gen_amalgamated begin source: gen/protos/perfetto/common/builtin_clock.gen.cc
10951 // gen_amalgamated begin header: gen/protos/perfetto/common/builtin_clock.gen.h
10952 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
10953 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_BUILTIN_CLOCK_PROTO_CPP_H_
10954 #define PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_BUILTIN_CLOCK_PROTO_CPP_H_
10955 
10956 #include <stdint.h>
10957 #include <bitset>
10958 #include <vector>
10959 #include <string>
10960 #include <type_traits>
10961 
10962 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
10963 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
10964 // gen_amalgamated expanded: #include "perfetto/base/export.h"
10965 
10966 namespace perfetto {
10967 namespace protos {
10968 namespace gen {
10969 enum BuiltinClock : int;
10970 }  // namespace perfetto
10971 }  // namespace protos
10972 }  // namespace gen
10973 
10974 namespace protozero {
10975 class Message;
10976 }  // namespace protozero
10977 
10978 namespace perfetto {
10979 namespace protos {
10980 namespace gen {
10981 enum BuiltinClock : int {
10982   BUILTIN_CLOCK_UNKNOWN = 0,
10983   BUILTIN_CLOCK_REALTIME = 1,
10984   BUILTIN_CLOCK_REALTIME_COARSE = 2,
10985   BUILTIN_CLOCK_MONOTONIC = 3,
10986   BUILTIN_CLOCK_MONOTONIC_COARSE = 4,
10987   BUILTIN_CLOCK_MONOTONIC_RAW = 5,
10988   BUILTIN_CLOCK_BOOTTIME = 6,
10989   BUILTIN_CLOCK_MAX_ID = 63,
10990 };
10991 }  // namespace perfetto
10992 }  // namespace protos
10993 }  // namespace gen
10994 
10995 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_BUILTIN_CLOCK_PROTO_CPP_H_
10996 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
10997 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
10998 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
10999 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
11000 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
11001 #if defined(__GNUC__) || defined(__clang__)
11002 #pragma GCC diagnostic push
11003 #pragma GCC diagnostic ignored "-Wfloat-equal"
11004 #endif
11005 // gen_amalgamated expanded: #include "protos/perfetto/common/builtin_clock.gen.h"
11006 
11007 namespace perfetto {
11008 namespace protos {
11009 namespace gen {
11010 }  // namespace perfetto
11011 }  // namespace protos
11012 }  // namespace gen
11013 #if defined(__GNUC__) || defined(__clang__)
11014 #pragma GCC diagnostic pop
11015 #endif
11016 // gen_amalgamated begin source: gen/protos/perfetto/common/commit_data_request.gen.cc
11017 // gen_amalgamated begin header: gen/protos/perfetto/common/commit_data_request.gen.h
11018 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
11019 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_COMMIT_DATA_REQUEST_PROTO_CPP_H_
11020 #define PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_COMMIT_DATA_REQUEST_PROTO_CPP_H_
11021 
11022 #include <stdint.h>
11023 #include <bitset>
11024 #include <vector>
11025 #include <string>
11026 #include <type_traits>
11027 
11028 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
11029 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
11030 // gen_amalgamated expanded: #include "perfetto/base/export.h"
11031 
11032 namespace perfetto {
11033 namespace protos {
11034 namespace gen {
11035 class CommitDataRequest;
11036 class CommitDataRequest_ChunkToPatch;
11037 class CommitDataRequest_ChunkToPatch_Patch;
11038 class CommitDataRequest_ChunksToMove;
11039 }  // namespace perfetto
11040 }  // namespace protos
11041 }  // namespace gen
11042 
11043 namespace protozero {
11044 class Message;
11045 }  // namespace protozero
11046 
11047 namespace perfetto {
11048 namespace protos {
11049 namespace gen {
11050 
11051 class PERFETTO_EXPORT CommitDataRequest : public ::protozero::CppMessageObj {
11052  public:
11053   using ChunksToMove = CommitDataRequest_ChunksToMove;
11054   using ChunkToPatch = CommitDataRequest_ChunkToPatch;
11055   enum FieldNumbers {
11056     kChunksToMoveFieldNumber = 1,
11057     kChunksToPatchFieldNumber = 2,
11058     kFlushRequestIdFieldNumber = 3,
11059   };
11060 
11061   CommitDataRequest();
11062   ~CommitDataRequest() override;
11063   CommitDataRequest(CommitDataRequest&&) noexcept;
11064   CommitDataRequest& operator=(CommitDataRequest&&);
11065   CommitDataRequest(const CommitDataRequest&);
11066   CommitDataRequest& operator=(const CommitDataRequest&);
11067   bool operator==(const CommitDataRequest&) const;
operator !=(const CommitDataRequest & other) const11068   bool operator!=(const CommitDataRequest& other) const { return !(*this == other); }
11069 
11070   bool ParseFromArray(const void*, size_t) override;
11071   std::string SerializeAsString() const override;
11072   std::vector<uint8_t> SerializeAsArray() const override;
11073   void Serialize(::protozero::Message*) const;
11074 
chunks_to_move() const11075   const std::vector<CommitDataRequest_ChunksToMove>& chunks_to_move() const { return chunks_to_move_; }
mutable_chunks_to_move()11076   std::vector<CommitDataRequest_ChunksToMove>* mutable_chunks_to_move() { return &chunks_to_move_; }
11077   int chunks_to_move_size() const;
11078   void clear_chunks_to_move();
11079   CommitDataRequest_ChunksToMove* add_chunks_to_move();
11080 
chunks_to_patch() const11081   const std::vector<CommitDataRequest_ChunkToPatch>& chunks_to_patch() const { return chunks_to_patch_; }
mutable_chunks_to_patch()11082   std::vector<CommitDataRequest_ChunkToPatch>* mutable_chunks_to_patch() { return &chunks_to_patch_; }
11083   int chunks_to_patch_size() const;
11084   void clear_chunks_to_patch();
11085   CommitDataRequest_ChunkToPatch* add_chunks_to_patch();
11086 
has_flush_request_id() const11087   bool has_flush_request_id() const { return _has_field_[3]; }
flush_request_id() const11088   uint64_t flush_request_id() const { return flush_request_id_; }
set_flush_request_id(uint64_t value)11089   void set_flush_request_id(uint64_t value) { flush_request_id_ = value; _has_field_.set(3); }
11090 
11091  private:
11092   std::vector<CommitDataRequest_ChunksToMove> chunks_to_move_;
11093   std::vector<CommitDataRequest_ChunkToPatch> chunks_to_patch_;
11094   uint64_t flush_request_id_{};
11095 
11096   // Allows to preserve unknown protobuf fields for compatibility
11097   // with future versions of .proto files.
11098   std::string unknown_fields_;
11099 
11100   std::bitset<4> _has_field_{};
11101 };
11102 
11103 
11104 class PERFETTO_EXPORT CommitDataRequest_ChunkToPatch : public ::protozero::CppMessageObj {
11105  public:
11106   using Patch = CommitDataRequest_ChunkToPatch_Patch;
11107   enum FieldNumbers {
11108     kTargetBufferFieldNumber = 1,
11109     kWriterIdFieldNumber = 2,
11110     kChunkIdFieldNumber = 3,
11111     kPatchesFieldNumber = 4,
11112     kHasMorePatchesFieldNumber = 5,
11113   };
11114 
11115   CommitDataRequest_ChunkToPatch();
11116   ~CommitDataRequest_ChunkToPatch() override;
11117   CommitDataRequest_ChunkToPatch(CommitDataRequest_ChunkToPatch&&) noexcept;
11118   CommitDataRequest_ChunkToPatch& operator=(CommitDataRequest_ChunkToPatch&&);
11119   CommitDataRequest_ChunkToPatch(const CommitDataRequest_ChunkToPatch&);
11120   CommitDataRequest_ChunkToPatch& operator=(const CommitDataRequest_ChunkToPatch&);
11121   bool operator==(const CommitDataRequest_ChunkToPatch&) const;
operator !=(const CommitDataRequest_ChunkToPatch & other) const11122   bool operator!=(const CommitDataRequest_ChunkToPatch& other) const { return !(*this == other); }
11123 
11124   bool ParseFromArray(const void*, size_t) override;
11125   std::string SerializeAsString() const override;
11126   std::vector<uint8_t> SerializeAsArray() const override;
11127   void Serialize(::protozero::Message*) const;
11128 
has_target_buffer() const11129   bool has_target_buffer() const { return _has_field_[1]; }
target_buffer() const11130   uint32_t target_buffer() const { return target_buffer_; }
set_target_buffer(uint32_t value)11131   void set_target_buffer(uint32_t value) { target_buffer_ = value; _has_field_.set(1); }
11132 
has_writer_id() const11133   bool has_writer_id() const { return _has_field_[2]; }
writer_id() const11134   uint32_t writer_id() const { return writer_id_; }
set_writer_id(uint32_t value)11135   void set_writer_id(uint32_t value) { writer_id_ = value; _has_field_.set(2); }
11136 
has_chunk_id() const11137   bool has_chunk_id() const { return _has_field_[3]; }
chunk_id() const11138   uint32_t chunk_id() const { return chunk_id_; }
set_chunk_id(uint32_t value)11139   void set_chunk_id(uint32_t value) { chunk_id_ = value; _has_field_.set(3); }
11140 
patches() const11141   const std::vector<CommitDataRequest_ChunkToPatch_Patch>& patches() const { return patches_; }
mutable_patches()11142   std::vector<CommitDataRequest_ChunkToPatch_Patch>* mutable_patches() { return &patches_; }
11143   int patches_size() const;
11144   void clear_patches();
11145   CommitDataRequest_ChunkToPatch_Patch* add_patches();
11146 
has_has_more_patches() const11147   bool has_has_more_patches() const { return _has_field_[5]; }
has_more_patches() const11148   bool has_more_patches() const { return has_more_patches_; }
set_has_more_patches(bool value)11149   void set_has_more_patches(bool value) { has_more_patches_ = value; _has_field_.set(5); }
11150 
11151  private:
11152   uint32_t target_buffer_{};
11153   uint32_t writer_id_{};
11154   uint32_t chunk_id_{};
11155   std::vector<CommitDataRequest_ChunkToPatch_Patch> patches_;
11156   bool has_more_patches_{};
11157 
11158   // Allows to preserve unknown protobuf fields for compatibility
11159   // with future versions of .proto files.
11160   std::string unknown_fields_;
11161 
11162   std::bitset<6> _has_field_{};
11163 };
11164 
11165 
11166 class PERFETTO_EXPORT CommitDataRequest_ChunkToPatch_Patch : public ::protozero::CppMessageObj {
11167  public:
11168   enum FieldNumbers {
11169     kOffsetFieldNumber = 1,
11170     kDataFieldNumber = 2,
11171   };
11172 
11173   CommitDataRequest_ChunkToPatch_Patch();
11174   ~CommitDataRequest_ChunkToPatch_Patch() override;
11175   CommitDataRequest_ChunkToPatch_Patch(CommitDataRequest_ChunkToPatch_Patch&&) noexcept;
11176   CommitDataRequest_ChunkToPatch_Patch& operator=(CommitDataRequest_ChunkToPatch_Patch&&);
11177   CommitDataRequest_ChunkToPatch_Patch(const CommitDataRequest_ChunkToPatch_Patch&);
11178   CommitDataRequest_ChunkToPatch_Patch& operator=(const CommitDataRequest_ChunkToPatch_Patch&);
11179   bool operator==(const CommitDataRequest_ChunkToPatch_Patch&) const;
operator !=(const CommitDataRequest_ChunkToPatch_Patch & other) const11180   bool operator!=(const CommitDataRequest_ChunkToPatch_Patch& other) const { return !(*this == other); }
11181 
11182   bool ParseFromArray(const void*, size_t) override;
11183   std::string SerializeAsString() const override;
11184   std::vector<uint8_t> SerializeAsArray() const override;
11185   void Serialize(::protozero::Message*) const;
11186 
has_offset() const11187   bool has_offset() const { return _has_field_[1]; }
offset() const11188   uint32_t offset() const { return offset_; }
set_offset(uint32_t value)11189   void set_offset(uint32_t value) { offset_ = value; _has_field_.set(1); }
11190 
has_data() const11191   bool has_data() const { return _has_field_[2]; }
data() const11192   const std::string& data() const { return data_; }
set_data(const std::string & value)11193   void set_data(const std::string& value) { data_ = value; _has_field_.set(2); }
set_data(const void * p,size_t s)11194   void set_data(const void* p, size_t s) { data_.assign(reinterpret_cast<const char*>(p), s); _has_field_.set(2); }
11195 
11196  private:
11197   uint32_t offset_{};
11198   std::string data_{};
11199 
11200   // Allows to preserve unknown protobuf fields for compatibility
11201   // with future versions of .proto files.
11202   std::string unknown_fields_;
11203 
11204   std::bitset<3> _has_field_{};
11205 };
11206 
11207 
11208 class PERFETTO_EXPORT CommitDataRequest_ChunksToMove : public ::protozero::CppMessageObj {
11209  public:
11210   enum FieldNumbers {
11211     kPageFieldNumber = 1,
11212     kChunkFieldNumber = 2,
11213     kTargetBufferFieldNumber = 3,
11214   };
11215 
11216   CommitDataRequest_ChunksToMove();
11217   ~CommitDataRequest_ChunksToMove() override;
11218   CommitDataRequest_ChunksToMove(CommitDataRequest_ChunksToMove&&) noexcept;
11219   CommitDataRequest_ChunksToMove& operator=(CommitDataRequest_ChunksToMove&&);
11220   CommitDataRequest_ChunksToMove(const CommitDataRequest_ChunksToMove&);
11221   CommitDataRequest_ChunksToMove& operator=(const CommitDataRequest_ChunksToMove&);
11222   bool operator==(const CommitDataRequest_ChunksToMove&) const;
operator !=(const CommitDataRequest_ChunksToMove & other) const11223   bool operator!=(const CommitDataRequest_ChunksToMove& other) const { return !(*this == other); }
11224 
11225   bool ParseFromArray(const void*, size_t) override;
11226   std::string SerializeAsString() const override;
11227   std::vector<uint8_t> SerializeAsArray() const override;
11228   void Serialize(::protozero::Message*) const;
11229 
has_page() const11230   bool has_page() const { return _has_field_[1]; }
page() const11231   uint32_t page() const { return page_; }
set_page(uint32_t value)11232   void set_page(uint32_t value) { page_ = value; _has_field_.set(1); }
11233 
has_chunk() const11234   bool has_chunk() const { return _has_field_[2]; }
chunk() const11235   uint32_t chunk() const { return chunk_; }
set_chunk(uint32_t value)11236   void set_chunk(uint32_t value) { chunk_ = value; _has_field_.set(2); }
11237 
has_target_buffer() const11238   bool has_target_buffer() const { return _has_field_[3]; }
target_buffer() const11239   uint32_t target_buffer() const { return target_buffer_; }
set_target_buffer(uint32_t value)11240   void set_target_buffer(uint32_t value) { target_buffer_ = value; _has_field_.set(3); }
11241 
11242  private:
11243   uint32_t page_{};
11244   uint32_t chunk_{};
11245   uint32_t target_buffer_{};
11246 
11247   // Allows to preserve unknown protobuf fields for compatibility
11248   // with future versions of .proto files.
11249   std::string unknown_fields_;
11250 
11251   std::bitset<4> _has_field_{};
11252 };
11253 
11254 }  // namespace perfetto
11255 }  // namespace protos
11256 }  // namespace gen
11257 
11258 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_COMMIT_DATA_REQUEST_PROTO_CPP_H_
11259 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
11260 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
11261 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
11262 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
11263 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
11264 #if defined(__GNUC__) || defined(__clang__)
11265 #pragma GCC diagnostic push
11266 #pragma GCC diagnostic ignored "-Wfloat-equal"
11267 #endif
11268 // gen_amalgamated expanded: #include "protos/perfetto/common/commit_data_request.gen.h"
11269 
11270 namespace perfetto {
11271 namespace protos {
11272 namespace gen {
11273 
11274 CommitDataRequest::CommitDataRequest() = default;
11275 CommitDataRequest::~CommitDataRequest() = default;
11276 CommitDataRequest::CommitDataRequest(const CommitDataRequest&) = default;
11277 CommitDataRequest& CommitDataRequest::operator=(const CommitDataRequest&) = default;
11278 CommitDataRequest::CommitDataRequest(CommitDataRequest&&) noexcept = default;
11279 CommitDataRequest& CommitDataRequest::operator=(CommitDataRequest&&) = default;
11280 
operator ==(const CommitDataRequest & other) const11281 bool CommitDataRequest::operator==(const CommitDataRequest& other) const {
11282   return unknown_fields_ == other.unknown_fields_
11283    && chunks_to_move_ == other.chunks_to_move_
11284    && chunks_to_patch_ == other.chunks_to_patch_
11285    && flush_request_id_ == other.flush_request_id_;
11286 }
11287 
chunks_to_move_size() const11288 int CommitDataRequest::chunks_to_move_size() const { return static_cast<int>(chunks_to_move_.size()); }
clear_chunks_to_move()11289 void CommitDataRequest::clear_chunks_to_move() { chunks_to_move_.clear(); }
add_chunks_to_move()11290 CommitDataRequest_ChunksToMove* CommitDataRequest::add_chunks_to_move() { chunks_to_move_.emplace_back(); return &chunks_to_move_.back(); }
chunks_to_patch_size() const11291 int CommitDataRequest::chunks_to_patch_size() const { return static_cast<int>(chunks_to_patch_.size()); }
clear_chunks_to_patch()11292 void CommitDataRequest::clear_chunks_to_patch() { chunks_to_patch_.clear(); }
add_chunks_to_patch()11293 CommitDataRequest_ChunkToPatch* CommitDataRequest::add_chunks_to_patch() { chunks_to_patch_.emplace_back(); return &chunks_to_patch_.back(); }
ParseFromArray(const void * raw,size_t size)11294 bool CommitDataRequest::ParseFromArray(const void* raw, size_t size) {
11295   chunks_to_move_.clear();
11296   chunks_to_patch_.clear();
11297   unknown_fields_.clear();
11298   bool packed_error = false;
11299 
11300   ::protozero::ProtoDecoder dec(raw, size);
11301   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
11302     if (field.id() < _has_field_.size()) {
11303       _has_field_.set(field.id());
11304     }
11305     switch (field.id()) {
11306       case 1 /* chunks_to_move */:
11307         chunks_to_move_.emplace_back();
11308         chunks_to_move_.back().ParseFromArray(field.data(), field.size());
11309         break;
11310       case 2 /* chunks_to_patch */:
11311         chunks_to_patch_.emplace_back();
11312         chunks_to_patch_.back().ParseFromArray(field.data(), field.size());
11313         break;
11314       case 3 /* flush_request_id */:
11315         field.get(&flush_request_id_);
11316         break;
11317       default:
11318         field.SerializeAndAppendTo(&unknown_fields_);
11319         break;
11320     }
11321   }
11322   return !packed_error && !dec.bytes_left();
11323 }
11324 
SerializeAsString() const11325 std::string CommitDataRequest::SerializeAsString() const {
11326   ::protozero::HeapBuffered<::protozero::Message> msg;
11327   Serialize(msg.get());
11328   return msg.SerializeAsString();
11329 }
11330 
SerializeAsArray() const11331 std::vector<uint8_t> CommitDataRequest::SerializeAsArray() const {
11332   ::protozero::HeapBuffered<::protozero::Message> msg;
11333   Serialize(msg.get());
11334   return msg.SerializeAsArray();
11335 }
11336 
Serialize(::protozero::Message * msg) const11337 void CommitDataRequest::Serialize(::protozero::Message* msg) const {
11338   // Field 1: chunks_to_move
11339   for (auto& it : chunks_to_move_) {
11340     it.Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
11341   }
11342 
11343   // Field 2: chunks_to_patch
11344   for (auto& it : chunks_to_patch_) {
11345     it.Serialize(msg->BeginNestedMessage<::protozero::Message>(2));
11346   }
11347 
11348   // Field 3: flush_request_id
11349   if (_has_field_[3]) {
11350     msg->AppendVarInt(3, flush_request_id_);
11351   }
11352 
11353   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
11354 }
11355 
11356 
11357 CommitDataRequest_ChunkToPatch::CommitDataRequest_ChunkToPatch() = default;
11358 CommitDataRequest_ChunkToPatch::~CommitDataRequest_ChunkToPatch() = default;
11359 CommitDataRequest_ChunkToPatch::CommitDataRequest_ChunkToPatch(const CommitDataRequest_ChunkToPatch&) = default;
11360 CommitDataRequest_ChunkToPatch& CommitDataRequest_ChunkToPatch::operator=(const CommitDataRequest_ChunkToPatch&) = default;
11361 CommitDataRequest_ChunkToPatch::CommitDataRequest_ChunkToPatch(CommitDataRequest_ChunkToPatch&&) noexcept = default;
11362 CommitDataRequest_ChunkToPatch& CommitDataRequest_ChunkToPatch::operator=(CommitDataRequest_ChunkToPatch&&) = default;
11363 
operator ==(const CommitDataRequest_ChunkToPatch & other) const11364 bool CommitDataRequest_ChunkToPatch::operator==(const CommitDataRequest_ChunkToPatch& other) const {
11365   return unknown_fields_ == other.unknown_fields_
11366    && target_buffer_ == other.target_buffer_
11367    && writer_id_ == other.writer_id_
11368    && chunk_id_ == other.chunk_id_
11369    && patches_ == other.patches_
11370    && has_more_patches_ == other.has_more_patches_;
11371 }
11372 
patches_size() const11373 int CommitDataRequest_ChunkToPatch::patches_size() const { return static_cast<int>(patches_.size()); }
clear_patches()11374 void CommitDataRequest_ChunkToPatch::clear_patches() { patches_.clear(); }
add_patches()11375 CommitDataRequest_ChunkToPatch_Patch* CommitDataRequest_ChunkToPatch::add_patches() { patches_.emplace_back(); return &patches_.back(); }
ParseFromArray(const void * raw,size_t size)11376 bool CommitDataRequest_ChunkToPatch::ParseFromArray(const void* raw, size_t size) {
11377   patches_.clear();
11378   unknown_fields_.clear();
11379   bool packed_error = false;
11380 
11381   ::protozero::ProtoDecoder dec(raw, size);
11382   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
11383     if (field.id() < _has_field_.size()) {
11384       _has_field_.set(field.id());
11385     }
11386     switch (field.id()) {
11387       case 1 /* target_buffer */:
11388         field.get(&target_buffer_);
11389         break;
11390       case 2 /* writer_id */:
11391         field.get(&writer_id_);
11392         break;
11393       case 3 /* chunk_id */:
11394         field.get(&chunk_id_);
11395         break;
11396       case 4 /* patches */:
11397         patches_.emplace_back();
11398         patches_.back().ParseFromArray(field.data(), field.size());
11399         break;
11400       case 5 /* has_more_patches */:
11401         field.get(&has_more_patches_);
11402         break;
11403       default:
11404         field.SerializeAndAppendTo(&unknown_fields_);
11405         break;
11406     }
11407   }
11408   return !packed_error && !dec.bytes_left();
11409 }
11410 
SerializeAsString() const11411 std::string CommitDataRequest_ChunkToPatch::SerializeAsString() const {
11412   ::protozero::HeapBuffered<::protozero::Message> msg;
11413   Serialize(msg.get());
11414   return msg.SerializeAsString();
11415 }
11416 
SerializeAsArray() const11417 std::vector<uint8_t> CommitDataRequest_ChunkToPatch::SerializeAsArray() const {
11418   ::protozero::HeapBuffered<::protozero::Message> msg;
11419   Serialize(msg.get());
11420   return msg.SerializeAsArray();
11421 }
11422 
Serialize(::protozero::Message * msg) const11423 void CommitDataRequest_ChunkToPatch::Serialize(::protozero::Message* msg) const {
11424   // Field 1: target_buffer
11425   if (_has_field_[1]) {
11426     msg->AppendVarInt(1, target_buffer_);
11427   }
11428 
11429   // Field 2: writer_id
11430   if (_has_field_[2]) {
11431     msg->AppendVarInt(2, writer_id_);
11432   }
11433 
11434   // Field 3: chunk_id
11435   if (_has_field_[3]) {
11436     msg->AppendVarInt(3, chunk_id_);
11437   }
11438 
11439   // Field 4: patches
11440   for (auto& it : patches_) {
11441     it.Serialize(msg->BeginNestedMessage<::protozero::Message>(4));
11442   }
11443 
11444   // Field 5: has_more_patches
11445   if (_has_field_[5]) {
11446     msg->AppendTinyVarInt(5, has_more_patches_);
11447   }
11448 
11449   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
11450 }
11451 
11452 
11453 CommitDataRequest_ChunkToPatch_Patch::CommitDataRequest_ChunkToPatch_Patch() = default;
11454 CommitDataRequest_ChunkToPatch_Patch::~CommitDataRequest_ChunkToPatch_Patch() = default;
11455 CommitDataRequest_ChunkToPatch_Patch::CommitDataRequest_ChunkToPatch_Patch(const CommitDataRequest_ChunkToPatch_Patch&) = default;
11456 CommitDataRequest_ChunkToPatch_Patch& CommitDataRequest_ChunkToPatch_Patch::operator=(const CommitDataRequest_ChunkToPatch_Patch&) = default;
11457 CommitDataRequest_ChunkToPatch_Patch::CommitDataRequest_ChunkToPatch_Patch(CommitDataRequest_ChunkToPatch_Patch&&) noexcept = default;
11458 CommitDataRequest_ChunkToPatch_Patch& CommitDataRequest_ChunkToPatch_Patch::operator=(CommitDataRequest_ChunkToPatch_Patch&&) = default;
11459 
operator ==(const CommitDataRequest_ChunkToPatch_Patch & other) const11460 bool CommitDataRequest_ChunkToPatch_Patch::operator==(const CommitDataRequest_ChunkToPatch_Patch& other) const {
11461   return unknown_fields_ == other.unknown_fields_
11462    && offset_ == other.offset_
11463    && data_ == other.data_;
11464 }
11465 
ParseFromArray(const void * raw,size_t size)11466 bool CommitDataRequest_ChunkToPatch_Patch::ParseFromArray(const void* raw, size_t size) {
11467   unknown_fields_.clear();
11468   bool packed_error = false;
11469 
11470   ::protozero::ProtoDecoder dec(raw, size);
11471   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
11472     if (field.id() < _has_field_.size()) {
11473       _has_field_.set(field.id());
11474     }
11475     switch (field.id()) {
11476       case 1 /* offset */:
11477         field.get(&offset_);
11478         break;
11479       case 2 /* data */:
11480         field.get(&data_);
11481         break;
11482       default:
11483         field.SerializeAndAppendTo(&unknown_fields_);
11484         break;
11485     }
11486   }
11487   return !packed_error && !dec.bytes_left();
11488 }
11489 
SerializeAsString() const11490 std::string CommitDataRequest_ChunkToPatch_Patch::SerializeAsString() const {
11491   ::protozero::HeapBuffered<::protozero::Message> msg;
11492   Serialize(msg.get());
11493   return msg.SerializeAsString();
11494 }
11495 
SerializeAsArray() const11496 std::vector<uint8_t> CommitDataRequest_ChunkToPatch_Patch::SerializeAsArray() const {
11497   ::protozero::HeapBuffered<::protozero::Message> msg;
11498   Serialize(msg.get());
11499   return msg.SerializeAsArray();
11500 }
11501 
Serialize(::protozero::Message * msg) const11502 void CommitDataRequest_ChunkToPatch_Patch::Serialize(::protozero::Message* msg) const {
11503   // Field 1: offset
11504   if (_has_field_[1]) {
11505     msg->AppendVarInt(1, offset_);
11506   }
11507 
11508   // Field 2: data
11509   if (_has_field_[2]) {
11510     msg->AppendString(2, data_);
11511   }
11512 
11513   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
11514 }
11515 
11516 
11517 CommitDataRequest_ChunksToMove::CommitDataRequest_ChunksToMove() = default;
11518 CommitDataRequest_ChunksToMove::~CommitDataRequest_ChunksToMove() = default;
11519 CommitDataRequest_ChunksToMove::CommitDataRequest_ChunksToMove(const CommitDataRequest_ChunksToMove&) = default;
11520 CommitDataRequest_ChunksToMove& CommitDataRequest_ChunksToMove::operator=(const CommitDataRequest_ChunksToMove&) = default;
11521 CommitDataRequest_ChunksToMove::CommitDataRequest_ChunksToMove(CommitDataRequest_ChunksToMove&&) noexcept = default;
11522 CommitDataRequest_ChunksToMove& CommitDataRequest_ChunksToMove::operator=(CommitDataRequest_ChunksToMove&&) = default;
11523 
operator ==(const CommitDataRequest_ChunksToMove & other) const11524 bool CommitDataRequest_ChunksToMove::operator==(const CommitDataRequest_ChunksToMove& other) const {
11525   return unknown_fields_ == other.unknown_fields_
11526    && page_ == other.page_
11527    && chunk_ == other.chunk_
11528    && target_buffer_ == other.target_buffer_;
11529 }
11530 
ParseFromArray(const void * raw,size_t size)11531 bool CommitDataRequest_ChunksToMove::ParseFromArray(const void* raw, size_t size) {
11532   unknown_fields_.clear();
11533   bool packed_error = false;
11534 
11535   ::protozero::ProtoDecoder dec(raw, size);
11536   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
11537     if (field.id() < _has_field_.size()) {
11538       _has_field_.set(field.id());
11539     }
11540     switch (field.id()) {
11541       case 1 /* page */:
11542         field.get(&page_);
11543         break;
11544       case 2 /* chunk */:
11545         field.get(&chunk_);
11546         break;
11547       case 3 /* target_buffer */:
11548         field.get(&target_buffer_);
11549         break;
11550       default:
11551         field.SerializeAndAppendTo(&unknown_fields_);
11552         break;
11553     }
11554   }
11555   return !packed_error && !dec.bytes_left();
11556 }
11557 
SerializeAsString() const11558 std::string CommitDataRequest_ChunksToMove::SerializeAsString() const {
11559   ::protozero::HeapBuffered<::protozero::Message> msg;
11560   Serialize(msg.get());
11561   return msg.SerializeAsString();
11562 }
11563 
SerializeAsArray() const11564 std::vector<uint8_t> CommitDataRequest_ChunksToMove::SerializeAsArray() const {
11565   ::protozero::HeapBuffered<::protozero::Message> msg;
11566   Serialize(msg.get());
11567   return msg.SerializeAsArray();
11568 }
11569 
Serialize(::protozero::Message * msg) const11570 void CommitDataRequest_ChunksToMove::Serialize(::protozero::Message* msg) const {
11571   // Field 1: page
11572   if (_has_field_[1]) {
11573     msg->AppendVarInt(1, page_);
11574   }
11575 
11576   // Field 2: chunk
11577   if (_has_field_[2]) {
11578     msg->AppendVarInt(2, chunk_);
11579   }
11580 
11581   // Field 3: target_buffer
11582   if (_has_field_[3]) {
11583     msg->AppendVarInt(3, target_buffer_);
11584   }
11585 
11586   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
11587 }
11588 
11589 }  // namespace perfetto
11590 }  // namespace protos
11591 }  // namespace gen
11592 #if defined(__GNUC__) || defined(__clang__)
11593 #pragma GCC diagnostic pop
11594 #endif
11595 // gen_amalgamated begin source: gen/protos/perfetto/common/data_source_descriptor.gen.cc
11596 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
11597 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
11598 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
11599 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
11600 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
11601 #if defined(__GNUC__) || defined(__clang__)
11602 #pragma GCC diagnostic push
11603 #pragma GCC diagnostic ignored "-Wfloat-equal"
11604 #endif
11605 // gen_amalgamated expanded: #include "protos/perfetto/common/data_source_descriptor.gen.h"
11606 
11607 namespace perfetto {
11608 namespace protos {
11609 namespace gen {
11610 
11611 DataSourceDescriptor::DataSourceDescriptor() = default;
11612 DataSourceDescriptor::~DataSourceDescriptor() = default;
11613 DataSourceDescriptor::DataSourceDescriptor(const DataSourceDescriptor&) = default;
11614 DataSourceDescriptor& DataSourceDescriptor::operator=(const DataSourceDescriptor&) = default;
11615 DataSourceDescriptor::DataSourceDescriptor(DataSourceDescriptor&&) noexcept = default;
11616 DataSourceDescriptor& DataSourceDescriptor::operator=(DataSourceDescriptor&&) = default;
11617 
operator ==(const DataSourceDescriptor & other) const11618 bool DataSourceDescriptor::operator==(const DataSourceDescriptor& other) const {
11619   return unknown_fields_ == other.unknown_fields_
11620    && name_ == other.name_
11621    && id_ == other.id_
11622    && will_notify_on_stop_ == other.will_notify_on_stop_
11623    && will_notify_on_start_ == other.will_notify_on_start_
11624    && handles_incremental_state_clear_ == other.handles_incremental_state_clear_
11625    && gpu_counter_descriptor_ == other.gpu_counter_descriptor_
11626    && track_event_descriptor_ == other.track_event_descriptor_;
11627 }
11628 
ParseFromArray(const void * raw,size_t size)11629 bool DataSourceDescriptor::ParseFromArray(const void* raw, size_t size) {
11630   unknown_fields_.clear();
11631   bool packed_error = false;
11632 
11633   ::protozero::ProtoDecoder dec(raw, size);
11634   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
11635     if (field.id() < _has_field_.size()) {
11636       _has_field_.set(field.id());
11637     }
11638     switch (field.id()) {
11639       case 1 /* name */:
11640         field.get(&name_);
11641         break;
11642       case 7 /* id */:
11643         field.get(&id_);
11644         break;
11645       case 2 /* will_notify_on_stop */:
11646         field.get(&will_notify_on_stop_);
11647         break;
11648       case 3 /* will_notify_on_start */:
11649         field.get(&will_notify_on_start_);
11650         break;
11651       case 4 /* handles_incremental_state_clear */:
11652         field.get(&handles_incremental_state_clear_);
11653         break;
11654       case 5 /* gpu_counter_descriptor */:
11655         gpu_counter_descriptor_ = field.as_std_string();
11656         break;
11657       case 6 /* track_event_descriptor */:
11658         track_event_descriptor_ = field.as_std_string();
11659         break;
11660       default:
11661         field.SerializeAndAppendTo(&unknown_fields_);
11662         break;
11663     }
11664   }
11665   return !packed_error && !dec.bytes_left();
11666 }
11667 
SerializeAsString() const11668 std::string DataSourceDescriptor::SerializeAsString() const {
11669   ::protozero::HeapBuffered<::protozero::Message> msg;
11670   Serialize(msg.get());
11671   return msg.SerializeAsString();
11672 }
11673 
SerializeAsArray() const11674 std::vector<uint8_t> DataSourceDescriptor::SerializeAsArray() const {
11675   ::protozero::HeapBuffered<::protozero::Message> msg;
11676   Serialize(msg.get());
11677   return msg.SerializeAsArray();
11678 }
11679 
Serialize(::protozero::Message * msg) const11680 void DataSourceDescriptor::Serialize(::protozero::Message* msg) const {
11681   // Field 1: name
11682   if (_has_field_[1]) {
11683     msg->AppendString(1, name_);
11684   }
11685 
11686   // Field 7: id
11687   if (_has_field_[7]) {
11688     msg->AppendVarInt(7, id_);
11689   }
11690 
11691   // Field 2: will_notify_on_stop
11692   if (_has_field_[2]) {
11693     msg->AppendTinyVarInt(2, will_notify_on_stop_);
11694   }
11695 
11696   // Field 3: will_notify_on_start
11697   if (_has_field_[3]) {
11698     msg->AppendTinyVarInt(3, will_notify_on_start_);
11699   }
11700 
11701   // Field 4: handles_incremental_state_clear
11702   if (_has_field_[4]) {
11703     msg->AppendTinyVarInt(4, handles_incremental_state_clear_);
11704   }
11705 
11706   // Field 5: gpu_counter_descriptor
11707   if (_has_field_[5]) {
11708     msg->AppendString(5, gpu_counter_descriptor_);
11709   }
11710 
11711   // Field 6: track_event_descriptor
11712   if (_has_field_[6]) {
11713     msg->AppendString(6, track_event_descriptor_);
11714   }
11715 
11716   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
11717 }
11718 
11719 }  // namespace perfetto
11720 }  // namespace protos
11721 }  // namespace gen
11722 #if defined(__GNUC__) || defined(__clang__)
11723 #pragma GCC diagnostic pop
11724 #endif
11725 // gen_amalgamated begin source: gen/protos/perfetto/common/descriptor.gen.cc
11726 // gen_amalgamated begin header: gen/protos/perfetto/common/descriptor.gen.h
11727 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
11728 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_DESCRIPTOR_PROTO_CPP_H_
11729 #define PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_DESCRIPTOR_PROTO_CPP_H_
11730 
11731 #include <stdint.h>
11732 #include <bitset>
11733 #include <vector>
11734 #include <string>
11735 #include <type_traits>
11736 
11737 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
11738 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
11739 // gen_amalgamated expanded: #include "perfetto/base/export.h"
11740 
11741 namespace perfetto {
11742 namespace protos {
11743 namespace gen {
11744 class OneofOptions;
11745 class EnumValueDescriptorProto;
11746 class EnumDescriptorProto;
11747 class OneofDescriptorProto;
11748 class FieldDescriptorProto;
11749 class DescriptorProto;
11750 class DescriptorProto_ReservedRange;
11751 class FileDescriptorProto;
11752 class FileDescriptorSet;
11753 enum FieldDescriptorProto_Type : int;
11754 enum FieldDescriptorProto_Label : int;
11755 }  // namespace perfetto
11756 }  // namespace protos
11757 }  // namespace gen
11758 
11759 namespace protozero {
11760 class Message;
11761 }  // namespace protozero
11762 
11763 namespace perfetto {
11764 namespace protos {
11765 namespace gen {
11766 enum FieldDescriptorProto_Type : int {
11767   FieldDescriptorProto_Type_TYPE_DOUBLE = 1,
11768   FieldDescriptorProto_Type_TYPE_FLOAT = 2,
11769   FieldDescriptorProto_Type_TYPE_INT64 = 3,
11770   FieldDescriptorProto_Type_TYPE_UINT64 = 4,
11771   FieldDescriptorProto_Type_TYPE_INT32 = 5,
11772   FieldDescriptorProto_Type_TYPE_FIXED64 = 6,
11773   FieldDescriptorProto_Type_TYPE_FIXED32 = 7,
11774   FieldDescriptorProto_Type_TYPE_BOOL = 8,
11775   FieldDescriptorProto_Type_TYPE_STRING = 9,
11776   FieldDescriptorProto_Type_TYPE_GROUP = 10,
11777   FieldDescriptorProto_Type_TYPE_MESSAGE = 11,
11778   FieldDescriptorProto_Type_TYPE_BYTES = 12,
11779   FieldDescriptorProto_Type_TYPE_UINT32 = 13,
11780   FieldDescriptorProto_Type_TYPE_ENUM = 14,
11781   FieldDescriptorProto_Type_TYPE_SFIXED32 = 15,
11782   FieldDescriptorProto_Type_TYPE_SFIXED64 = 16,
11783   FieldDescriptorProto_Type_TYPE_SINT32 = 17,
11784   FieldDescriptorProto_Type_TYPE_SINT64 = 18,
11785 };
11786 enum FieldDescriptorProto_Label : int {
11787   FieldDescriptorProto_Label_LABEL_OPTIONAL = 1,
11788   FieldDescriptorProto_Label_LABEL_REQUIRED = 2,
11789   FieldDescriptorProto_Label_LABEL_REPEATED = 3,
11790 };
11791 
11792 class PERFETTO_EXPORT OneofOptions : public ::protozero::CppMessageObj {
11793  public:
11794   enum FieldNumbers {
11795   };
11796 
11797   OneofOptions();
11798   ~OneofOptions() override;
11799   OneofOptions(OneofOptions&&) noexcept;
11800   OneofOptions& operator=(OneofOptions&&);
11801   OneofOptions(const OneofOptions&);
11802   OneofOptions& operator=(const OneofOptions&);
11803   bool operator==(const OneofOptions&) const;
operator !=(const OneofOptions & other) const11804   bool operator!=(const OneofOptions& other) const { return !(*this == other); }
11805 
11806   bool ParseFromArray(const void*, size_t) override;
11807   std::string SerializeAsString() const override;
11808   std::vector<uint8_t> SerializeAsArray() const override;
11809   void Serialize(::protozero::Message*) const;
11810 
11811  private:
11812 
11813   // Allows to preserve unknown protobuf fields for compatibility
11814   // with future versions of .proto files.
11815   std::string unknown_fields_;
11816 
11817   std::bitset<2> _has_field_{};
11818 };
11819 
11820 
11821 class PERFETTO_EXPORT EnumValueDescriptorProto : public ::protozero::CppMessageObj {
11822  public:
11823   enum FieldNumbers {
11824     kNameFieldNumber = 1,
11825     kNumberFieldNumber = 2,
11826   };
11827 
11828   EnumValueDescriptorProto();
11829   ~EnumValueDescriptorProto() override;
11830   EnumValueDescriptorProto(EnumValueDescriptorProto&&) noexcept;
11831   EnumValueDescriptorProto& operator=(EnumValueDescriptorProto&&);
11832   EnumValueDescriptorProto(const EnumValueDescriptorProto&);
11833   EnumValueDescriptorProto& operator=(const EnumValueDescriptorProto&);
11834   bool operator==(const EnumValueDescriptorProto&) const;
operator !=(const EnumValueDescriptorProto & other) const11835   bool operator!=(const EnumValueDescriptorProto& other) const { return !(*this == other); }
11836 
11837   bool ParseFromArray(const void*, size_t) override;
11838   std::string SerializeAsString() const override;
11839   std::vector<uint8_t> SerializeAsArray() const override;
11840   void Serialize(::protozero::Message*) const;
11841 
has_name() const11842   bool has_name() const { return _has_field_[1]; }
name() const11843   const std::string& name() const { return name_; }
set_name(const std::string & value)11844   void set_name(const std::string& value) { name_ = value; _has_field_.set(1); }
11845 
has_number() const11846   bool has_number() const { return _has_field_[2]; }
number() const11847   int32_t number() const { return number_; }
set_number(int32_t value)11848   void set_number(int32_t value) { number_ = value; _has_field_.set(2); }
11849 
11850  private:
11851   std::string name_{};
11852   int32_t number_{};
11853 
11854   // Allows to preserve unknown protobuf fields for compatibility
11855   // with future versions of .proto files.
11856   std::string unknown_fields_;
11857 
11858   std::bitset<3> _has_field_{};
11859 };
11860 
11861 
11862 class PERFETTO_EXPORT EnumDescriptorProto : public ::protozero::CppMessageObj {
11863  public:
11864   enum FieldNumbers {
11865     kNameFieldNumber = 1,
11866     kValueFieldNumber = 2,
11867     kReservedNameFieldNumber = 5,
11868   };
11869 
11870   EnumDescriptorProto();
11871   ~EnumDescriptorProto() override;
11872   EnumDescriptorProto(EnumDescriptorProto&&) noexcept;
11873   EnumDescriptorProto& operator=(EnumDescriptorProto&&);
11874   EnumDescriptorProto(const EnumDescriptorProto&);
11875   EnumDescriptorProto& operator=(const EnumDescriptorProto&);
11876   bool operator==(const EnumDescriptorProto&) const;
operator !=(const EnumDescriptorProto & other) const11877   bool operator!=(const EnumDescriptorProto& other) const { return !(*this == other); }
11878 
11879   bool ParseFromArray(const void*, size_t) override;
11880   std::string SerializeAsString() const override;
11881   std::vector<uint8_t> SerializeAsArray() const override;
11882   void Serialize(::protozero::Message*) const;
11883 
has_name() const11884   bool has_name() const { return _has_field_[1]; }
name() const11885   const std::string& name() const { return name_; }
set_name(const std::string & value)11886   void set_name(const std::string& value) { name_ = value; _has_field_.set(1); }
11887 
value() const11888   const std::vector<EnumValueDescriptorProto>& value() const { return value_; }
mutable_value()11889   std::vector<EnumValueDescriptorProto>* mutable_value() { return &value_; }
11890   int value_size() const;
11891   void clear_value();
11892   EnumValueDescriptorProto* add_value();
11893 
reserved_name() const11894   const std::vector<std::string>& reserved_name() const { return reserved_name_; }
mutable_reserved_name()11895   std::vector<std::string>* mutable_reserved_name() { return &reserved_name_; }
reserved_name_size() const11896   int reserved_name_size() const { return static_cast<int>(reserved_name_.size()); }
clear_reserved_name()11897   void clear_reserved_name() { reserved_name_.clear(); }
add_reserved_name(std::string value)11898   void add_reserved_name(std::string value) { reserved_name_.emplace_back(value); }
add_reserved_name()11899   std::string* add_reserved_name() { reserved_name_.emplace_back(); return &reserved_name_.back(); }
11900 
11901  private:
11902   std::string name_{};
11903   std::vector<EnumValueDescriptorProto> value_;
11904   std::vector<std::string> reserved_name_;
11905 
11906   // Allows to preserve unknown protobuf fields for compatibility
11907   // with future versions of .proto files.
11908   std::string unknown_fields_;
11909 
11910   std::bitset<6> _has_field_{};
11911 };
11912 
11913 
11914 class PERFETTO_EXPORT OneofDescriptorProto : public ::protozero::CppMessageObj {
11915  public:
11916   enum FieldNumbers {
11917     kNameFieldNumber = 1,
11918     kOptionsFieldNumber = 2,
11919   };
11920 
11921   OneofDescriptorProto();
11922   ~OneofDescriptorProto() override;
11923   OneofDescriptorProto(OneofDescriptorProto&&) noexcept;
11924   OneofDescriptorProto& operator=(OneofDescriptorProto&&);
11925   OneofDescriptorProto(const OneofDescriptorProto&);
11926   OneofDescriptorProto& operator=(const OneofDescriptorProto&);
11927   bool operator==(const OneofDescriptorProto&) const;
operator !=(const OneofDescriptorProto & other) const11928   bool operator!=(const OneofDescriptorProto& other) const { return !(*this == other); }
11929 
11930   bool ParseFromArray(const void*, size_t) override;
11931   std::string SerializeAsString() const override;
11932   std::vector<uint8_t> SerializeAsArray() const override;
11933   void Serialize(::protozero::Message*) const;
11934 
has_name() const11935   bool has_name() const { return _has_field_[1]; }
name() const11936   const std::string& name() const { return name_; }
set_name(const std::string & value)11937   void set_name(const std::string& value) { name_ = value; _has_field_.set(1); }
11938 
has_options() const11939   bool has_options() const { return _has_field_[2]; }
options() const11940   const OneofOptions& options() const { return *options_; }
mutable_options()11941   OneofOptions* mutable_options() { _has_field_.set(2); return options_.get(); }
11942 
11943  private:
11944   std::string name_{};
11945   ::protozero::CopyablePtr<OneofOptions> options_;
11946 
11947   // Allows to preserve unknown protobuf fields for compatibility
11948   // with future versions of .proto files.
11949   std::string unknown_fields_;
11950 
11951   std::bitset<3> _has_field_{};
11952 };
11953 
11954 
11955 class PERFETTO_EXPORT FieldDescriptorProto : public ::protozero::CppMessageObj {
11956  public:
11957   using Type = FieldDescriptorProto_Type;
11958   static constexpr auto TYPE_DOUBLE = FieldDescriptorProto_Type_TYPE_DOUBLE;
11959   static constexpr auto TYPE_FLOAT = FieldDescriptorProto_Type_TYPE_FLOAT;
11960   static constexpr auto TYPE_INT64 = FieldDescriptorProto_Type_TYPE_INT64;
11961   static constexpr auto TYPE_UINT64 = FieldDescriptorProto_Type_TYPE_UINT64;
11962   static constexpr auto TYPE_INT32 = FieldDescriptorProto_Type_TYPE_INT32;
11963   static constexpr auto TYPE_FIXED64 = FieldDescriptorProto_Type_TYPE_FIXED64;
11964   static constexpr auto TYPE_FIXED32 = FieldDescriptorProto_Type_TYPE_FIXED32;
11965   static constexpr auto TYPE_BOOL = FieldDescriptorProto_Type_TYPE_BOOL;
11966   static constexpr auto TYPE_STRING = FieldDescriptorProto_Type_TYPE_STRING;
11967   static constexpr auto TYPE_GROUP = FieldDescriptorProto_Type_TYPE_GROUP;
11968   static constexpr auto TYPE_MESSAGE = FieldDescriptorProto_Type_TYPE_MESSAGE;
11969   static constexpr auto TYPE_BYTES = FieldDescriptorProto_Type_TYPE_BYTES;
11970   static constexpr auto TYPE_UINT32 = FieldDescriptorProto_Type_TYPE_UINT32;
11971   static constexpr auto TYPE_ENUM = FieldDescriptorProto_Type_TYPE_ENUM;
11972   static constexpr auto TYPE_SFIXED32 = FieldDescriptorProto_Type_TYPE_SFIXED32;
11973   static constexpr auto TYPE_SFIXED64 = FieldDescriptorProto_Type_TYPE_SFIXED64;
11974   static constexpr auto TYPE_SINT32 = FieldDescriptorProto_Type_TYPE_SINT32;
11975   static constexpr auto TYPE_SINT64 = FieldDescriptorProto_Type_TYPE_SINT64;
11976   static constexpr auto Type_MIN = FieldDescriptorProto_Type_TYPE_DOUBLE;
11977   static constexpr auto Type_MAX = FieldDescriptorProto_Type_TYPE_SINT64;
11978   using Label = FieldDescriptorProto_Label;
11979   static constexpr auto LABEL_OPTIONAL = FieldDescriptorProto_Label_LABEL_OPTIONAL;
11980   static constexpr auto LABEL_REQUIRED = FieldDescriptorProto_Label_LABEL_REQUIRED;
11981   static constexpr auto LABEL_REPEATED = FieldDescriptorProto_Label_LABEL_REPEATED;
11982   static constexpr auto Label_MIN = FieldDescriptorProto_Label_LABEL_OPTIONAL;
11983   static constexpr auto Label_MAX = FieldDescriptorProto_Label_LABEL_REPEATED;
11984   enum FieldNumbers {
11985     kNameFieldNumber = 1,
11986     kNumberFieldNumber = 3,
11987     kLabelFieldNumber = 4,
11988     kTypeFieldNumber = 5,
11989     kTypeNameFieldNumber = 6,
11990     kExtendeeFieldNumber = 2,
11991     kDefaultValueFieldNumber = 7,
11992     kOneofIndexFieldNumber = 9,
11993   };
11994 
11995   FieldDescriptorProto();
11996   ~FieldDescriptorProto() override;
11997   FieldDescriptorProto(FieldDescriptorProto&&) noexcept;
11998   FieldDescriptorProto& operator=(FieldDescriptorProto&&);
11999   FieldDescriptorProto(const FieldDescriptorProto&);
12000   FieldDescriptorProto& operator=(const FieldDescriptorProto&);
12001   bool operator==(const FieldDescriptorProto&) const;
operator !=(const FieldDescriptorProto & other) const12002   bool operator!=(const FieldDescriptorProto& other) const { return !(*this == other); }
12003 
12004   bool ParseFromArray(const void*, size_t) override;
12005   std::string SerializeAsString() const override;
12006   std::vector<uint8_t> SerializeAsArray() const override;
12007   void Serialize(::protozero::Message*) const;
12008 
has_name() const12009   bool has_name() const { return _has_field_[1]; }
name() const12010   const std::string& name() const { return name_; }
set_name(const std::string & value)12011   void set_name(const std::string& value) { name_ = value; _has_field_.set(1); }
12012 
has_number() const12013   bool has_number() const { return _has_field_[3]; }
number() const12014   int32_t number() const { return number_; }
set_number(int32_t value)12015   void set_number(int32_t value) { number_ = value; _has_field_.set(3); }
12016 
has_label() const12017   bool has_label() const { return _has_field_[4]; }
label() const12018   FieldDescriptorProto_Label label() const { return label_; }
set_label(FieldDescriptorProto_Label value)12019   void set_label(FieldDescriptorProto_Label value) { label_ = value; _has_field_.set(4); }
12020 
has_type() const12021   bool has_type() const { return _has_field_[5]; }
type() const12022   FieldDescriptorProto_Type type() const { return type_; }
set_type(FieldDescriptorProto_Type value)12023   void set_type(FieldDescriptorProto_Type value) { type_ = value; _has_field_.set(5); }
12024 
has_type_name() const12025   bool has_type_name() const { return _has_field_[6]; }
type_name() const12026   const std::string& type_name() const { return type_name_; }
set_type_name(const std::string & value)12027   void set_type_name(const std::string& value) { type_name_ = value; _has_field_.set(6); }
12028 
has_extendee() const12029   bool has_extendee() const { return _has_field_[2]; }
extendee() const12030   const std::string& extendee() const { return extendee_; }
set_extendee(const std::string & value)12031   void set_extendee(const std::string& value) { extendee_ = value; _has_field_.set(2); }
12032 
has_default_value() const12033   bool has_default_value() const { return _has_field_[7]; }
default_value() const12034   const std::string& default_value() const { return default_value_; }
set_default_value(const std::string & value)12035   void set_default_value(const std::string& value) { default_value_ = value; _has_field_.set(7); }
12036 
has_oneof_index() const12037   bool has_oneof_index() const { return _has_field_[9]; }
oneof_index() const12038   int32_t oneof_index() const { return oneof_index_; }
set_oneof_index(int32_t value)12039   void set_oneof_index(int32_t value) { oneof_index_ = value; _has_field_.set(9); }
12040 
12041  private:
12042   std::string name_{};
12043   int32_t number_{};
12044   FieldDescriptorProto_Label label_{};
12045   FieldDescriptorProto_Type type_{};
12046   std::string type_name_{};
12047   std::string extendee_{};
12048   std::string default_value_{};
12049   int32_t oneof_index_{};
12050 
12051   // Allows to preserve unknown protobuf fields for compatibility
12052   // with future versions of .proto files.
12053   std::string unknown_fields_;
12054 
12055   std::bitset<10> _has_field_{};
12056 };
12057 
12058 
12059 class PERFETTO_EXPORT DescriptorProto : public ::protozero::CppMessageObj {
12060  public:
12061   using ReservedRange = DescriptorProto_ReservedRange;
12062   enum FieldNumbers {
12063     kNameFieldNumber = 1,
12064     kFieldFieldNumber = 2,
12065     kExtensionFieldNumber = 6,
12066     kNestedTypeFieldNumber = 3,
12067     kEnumTypeFieldNumber = 4,
12068     kOneofDeclFieldNumber = 8,
12069     kReservedRangeFieldNumber = 9,
12070     kReservedNameFieldNumber = 10,
12071   };
12072 
12073   DescriptorProto();
12074   ~DescriptorProto() override;
12075   DescriptorProto(DescriptorProto&&) noexcept;
12076   DescriptorProto& operator=(DescriptorProto&&);
12077   DescriptorProto(const DescriptorProto&);
12078   DescriptorProto& operator=(const DescriptorProto&);
12079   bool operator==(const DescriptorProto&) const;
operator !=(const DescriptorProto & other) const12080   bool operator!=(const DescriptorProto& other) const { return !(*this == other); }
12081 
12082   bool ParseFromArray(const void*, size_t) override;
12083   std::string SerializeAsString() const override;
12084   std::vector<uint8_t> SerializeAsArray() const override;
12085   void Serialize(::protozero::Message*) const;
12086 
has_name() const12087   bool has_name() const { return _has_field_[1]; }
name() const12088   const std::string& name() const { return name_; }
set_name(const std::string & value)12089   void set_name(const std::string& value) { name_ = value; _has_field_.set(1); }
12090 
field() const12091   const std::vector<FieldDescriptorProto>& field() const { return field_; }
mutable_field()12092   std::vector<FieldDescriptorProto>* mutable_field() { return &field_; }
12093   int field_size() const;
12094   void clear_field();
12095   FieldDescriptorProto* add_field();
12096 
extension() const12097   const std::vector<FieldDescriptorProto>& extension() const { return extension_; }
mutable_extension()12098   std::vector<FieldDescriptorProto>* mutable_extension() { return &extension_; }
12099   int extension_size() const;
12100   void clear_extension();
12101   FieldDescriptorProto* add_extension();
12102 
nested_type() const12103   const std::vector<DescriptorProto>& nested_type() const { return nested_type_; }
mutable_nested_type()12104   std::vector<DescriptorProto>* mutable_nested_type() { return &nested_type_; }
12105   int nested_type_size() const;
12106   void clear_nested_type();
12107   DescriptorProto* add_nested_type();
12108 
enum_type() const12109   const std::vector<EnumDescriptorProto>& enum_type() const { return enum_type_; }
mutable_enum_type()12110   std::vector<EnumDescriptorProto>* mutable_enum_type() { return &enum_type_; }
12111   int enum_type_size() const;
12112   void clear_enum_type();
12113   EnumDescriptorProto* add_enum_type();
12114 
oneof_decl() const12115   const std::vector<OneofDescriptorProto>& oneof_decl() const { return oneof_decl_; }
mutable_oneof_decl()12116   std::vector<OneofDescriptorProto>* mutable_oneof_decl() { return &oneof_decl_; }
12117   int oneof_decl_size() const;
12118   void clear_oneof_decl();
12119   OneofDescriptorProto* add_oneof_decl();
12120 
reserved_range() const12121   const std::vector<DescriptorProto_ReservedRange>& reserved_range() const { return reserved_range_; }
mutable_reserved_range()12122   std::vector<DescriptorProto_ReservedRange>* mutable_reserved_range() { return &reserved_range_; }
12123   int reserved_range_size() const;
12124   void clear_reserved_range();
12125   DescriptorProto_ReservedRange* add_reserved_range();
12126 
reserved_name() const12127   const std::vector<std::string>& reserved_name() const { return reserved_name_; }
mutable_reserved_name()12128   std::vector<std::string>* mutable_reserved_name() { return &reserved_name_; }
reserved_name_size() const12129   int reserved_name_size() const { return static_cast<int>(reserved_name_.size()); }
clear_reserved_name()12130   void clear_reserved_name() { reserved_name_.clear(); }
add_reserved_name(std::string value)12131   void add_reserved_name(std::string value) { reserved_name_.emplace_back(value); }
add_reserved_name()12132   std::string* add_reserved_name() { reserved_name_.emplace_back(); return &reserved_name_.back(); }
12133 
12134  private:
12135   std::string name_{};
12136   std::vector<FieldDescriptorProto> field_;
12137   std::vector<FieldDescriptorProto> extension_;
12138   std::vector<DescriptorProto> nested_type_;
12139   std::vector<EnumDescriptorProto> enum_type_;
12140   std::vector<OneofDescriptorProto> oneof_decl_;
12141   std::vector<DescriptorProto_ReservedRange> reserved_range_;
12142   std::vector<std::string> reserved_name_;
12143 
12144   // Allows to preserve unknown protobuf fields for compatibility
12145   // with future versions of .proto files.
12146   std::string unknown_fields_;
12147 
12148   std::bitset<11> _has_field_{};
12149 };
12150 
12151 
12152 class PERFETTO_EXPORT DescriptorProto_ReservedRange : public ::protozero::CppMessageObj {
12153  public:
12154   enum FieldNumbers {
12155     kStartFieldNumber = 1,
12156     kEndFieldNumber = 2,
12157   };
12158 
12159   DescriptorProto_ReservedRange();
12160   ~DescriptorProto_ReservedRange() override;
12161   DescriptorProto_ReservedRange(DescriptorProto_ReservedRange&&) noexcept;
12162   DescriptorProto_ReservedRange& operator=(DescriptorProto_ReservedRange&&);
12163   DescriptorProto_ReservedRange(const DescriptorProto_ReservedRange&);
12164   DescriptorProto_ReservedRange& operator=(const DescriptorProto_ReservedRange&);
12165   bool operator==(const DescriptorProto_ReservedRange&) const;
operator !=(const DescriptorProto_ReservedRange & other) const12166   bool operator!=(const DescriptorProto_ReservedRange& other) const { return !(*this == other); }
12167 
12168   bool ParseFromArray(const void*, size_t) override;
12169   std::string SerializeAsString() const override;
12170   std::vector<uint8_t> SerializeAsArray() const override;
12171   void Serialize(::protozero::Message*) const;
12172 
has_start() const12173   bool has_start() const { return _has_field_[1]; }
start() const12174   int32_t start() const { return start_; }
set_start(int32_t value)12175   void set_start(int32_t value) { start_ = value; _has_field_.set(1); }
12176 
has_end() const12177   bool has_end() const { return _has_field_[2]; }
end() const12178   int32_t end() const { return end_; }
set_end(int32_t value)12179   void set_end(int32_t value) { end_ = value; _has_field_.set(2); }
12180 
12181  private:
12182   int32_t start_{};
12183   int32_t end_{};
12184 
12185   // Allows to preserve unknown protobuf fields for compatibility
12186   // with future versions of .proto files.
12187   std::string unknown_fields_;
12188 
12189   std::bitset<3> _has_field_{};
12190 };
12191 
12192 
12193 class PERFETTO_EXPORT FileDescriptorProto : public ::protozero::CppMessageObj {
12194  public:
12195   enum FieldNumbers {
12196     kNameFieldNumber = 1,
12197     kPackageFieldNumber = 2,
12198     kDependencyFieldNumber = 3,
12199     kPublicDependencyFieldNumber = 10,
12200     kWeakDependencyFieldNumber = 11,
12201     kMessageTypeFieldNumber = 4,
12202     kEnumTypeFieldNumber = 5,
12203     kExtensionFieldNumber = 7,
12204   };
12205 
12206   FileDescriptorProto();
12207   ~FileDescriptorProto() override;
12208   FileDescriptorProto(FileDescriptorProto&&) noexcept;
12209   FileDescriptorProto& operator=(FileDescriptorProto&&);
12210   FileDescriptorProto(const FileDescriptorProto&);
12211   FileDescriptorProto& operator=(const FileDescriptorProto&);
12212   bool operator==(const FileDescriptorProto&) const;
operator !=(const FileDescriptorProto & other) const12213   bool operator!=(const FileDescriptorProto& other) const { return !(*this == other); }
12214 
12215   bool ParseFromArray(const void*, size_t) override;
12216   std::string SerializeAsString() const override;
12217   std::vector<uint8_t> SerializeAsArray() const override;
12218   void Serialize(::protozero::Message*) const;
12219 
has_name() const12220   bool has_name() const { return _has_field_[1]; }
name() const12221   const std::string& name() const { return name_; }
set_name(const std::string & value)12222   void set_name(const std::string& value) { name_ = value; _has_field_.set(1); }
12223 
has_package() const12224   bool has_package() const { return _has_field_[2]; }
package() const12225   const std::string& package() const { return package_; }
set_package(const std::string & value)12226   void set_package(const std::string& value) { package_ = value; _has_field_.set(2); }
12227 
dependency() const12228   const std::vector<std::string>& dependency() const { return dependency_; }
mutable_dependency()12229   std::vector<std::string>* mutable_dependency() { return &dependency_; }
dependency_size() const12230   int dependency_size() const { return static_cast<int>(dependency_.size()); }
clear_dependency()12231   void clear_dependency() { dependency_.clear(); }
add_dependency(std::string value)12232   void add_dependency(std::string value) { dependency_.emplace_back(value); }
add_dependency()12233   std::string* add_dependency() { dependency_.emplace_back(); return &dependency_.back(); }
12234 
public_dependency() const12235   const std::vector<int32_t>& public_dependency() const { return public_dependency_; }
mutable_public_dependency()12236   std::vector<int32_t>* mutable_public_dependency() { return &public_dependency_; }
public_dependency_size() const12237   int public_dependency_size() const { return static_cast<int>(public_dependency_.size()); }
clear_public_dependency()12238   void clear_public_dependency() { public_dependency_.clear(); }
add_public_dependency(int32_t value)12239   void add_public_dependency(int32_t value) { public_dependency_.emplace_back(value); }
add_public_dependency()12240   int32_t* add_public_dependency() { public_dependency_.emplace_back(); return &public_dependency_.back(); }
12241 
weak_dependency() const12242   const std::vector<int32_t>& weak_dependency() const { return weak_dependency_; }
mutable_weak_dependency()12243   std::vector<int32_t>* mutable_weak_dependency() { return &weak_dependency_; }
weak_dependency_size() const12244   int weak_dependency_size() const { return static_cast<int>(weak_dependency_.size()); }
clear_weak_dependency()12245   void clear_weak_dependency() { weak_dependency_.clear(); }
add_weak_dependency(int32_t value)12246   void add_weak_dependency(int32_t value) { weak_dependency_.emplace_back(value); }
add_weak_dependency()12247   int32_t* add_weak_dependency() { weak_dependency_.emplace_back(); return &weak_dependency_.back(); }
12248 
message_type() const12249   const std::vector<DescriptorProto>& message_type() const { return message_type_; }
mutable_message_type()12250   std::vector<DescriptorProto>* mutable_message_type() { return &message_type_; }
12251   int message_type_size() const;
12252   void clear_message_type();
12253   DescriptorProto* add_message_type();
12254 
enum_type() const12255   const std::vector<EnumDescriptorProto>& enum_type() const { return enum_type_; }
mutable_enum_type()12256   std::vector<EnumDescriptorProto>* mutable_enum_type() { return &enum_type_; }
12257   int enum_type_size() const;
12258   void clear_enum_type();
12259   EnumDescriptorProto* add_enum_type();
12260 
extension() const12261   const std::vector<FieldDescriptorProto>& extension() const { return extension_; }
mutable_extension()12262   std::vector<FieldDescriptorProto>* mutable_extension() { return &extension_; }
12263   int extension_size() const;
12264   void clear_extension();
12265   FieldDescriptorProto* add_extension();
12266 
12267  private:
12268   std::string name_{};
12269   std::string package_{};
12270   std::vector<std::string> dependency_;
12271   std::vector<int32_t> public_dependency_;
12272   std::vector<int32_t> weak_dependency_;
12273   std::vector<DescriptorProto> message_type_;
12274   std::vector<EnumDescriptorProto> enum_type_;
12275   std::vector<FieldDescriptorProto> extension_;
12276 
12277   // Allows to preserve unknown protobuf fields for compatibility
12278   // with future versions of .proto files.
12279   std::string unknown_fields_;
12280 
12281   std::bitset<12> _has_field_{};
12282 };
12283 
12284 
12285 class PERFETTO_EXPORT FileDescriptorSet : public ::protozero::CppMessageObj {
12286  public:
12287   enum FieldNumbers {
12288     kFileFieldNumber = 1,
12289   };
12290 
12291   FileDescriptorSet();
12292   ~FileDescriptorSet() override;
12293   FileDescriptorSet(FileDescriptorSet&&) noexcept;
12294   FileDescriptorSet& operator=(FileDescriptorSet&&);
12295   FileDescriptorSet(const FileDescriptorSet&);
12296   FileDescriptorSet& operator=(const FileDescriptorSet&);
12297   bool operator==(const FileDescriptorSet&) const;
operator !=(const FileDescriptorSet & other) const12298   bool operator!=(const FileDescriptorSet& other) const { return !(*this == other); }
12299 
12300   bool ParseFromArray(const void*, size_t) override;
12301   std::string SerializeAsString() const override;
12302   std::vector<uint8_t> SerializeAsArray() const override;
12303   void Serialize(::protozero::Message*) const;
12304 
file() const12305   const std::vector<FileDescriptorProto>& file() const { return file_; }
mutable_file()12306   std::vector<FileDescriptorProto>* mutable_file() { return &file_; }
12307   int file_size() const;
12308   void clear_file();
12309   FileDescriptorProto* add_file();
12310 
12311  private:
12312   std::vector<FileDescriptorProto> file_;
12313 
12314   // Allows to preserve unknown protobuf fields for compatibility
12315   // with future versions of .proto files.
12316   std::string unknown_fields_;
12317 
12318   std::bitset<2> _has_field_{};
12319 };
12320 
12321 }  // namespace perfetto
12322 }  // namespace protos
12323 }  // namespace gen
12324 
12325 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_DESCRIPTOR_PROTO_CPP_H_
12326 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
12327 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
12328 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
12329 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
12330 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
12331 #if defined(__GNUC__) || defined(__clang__)
12332 #pragma GCC diagnostic push
12333 #pragma GCC diagnostic ignored "-Wfloat-equal"
12334 #endif
12335 // gen_amalgamated expanded: #include "protos/perfetto/common/descriptor.gen.h"
12336 
12337 namespace perfetto {
12338 namespace protos {
12339 namespace gen {
12340 
12341 OneofOptions::OneofOptions() = default;
12342 OneofOptions::~OneofOptions() = default;
12343 OneofOptions::OneofOptions(const OneofOptions&) = default;
12344 OneofOptions& OneofOptions::operator=(const OneofOptions&) = default;
12345 OneofOptions::OneofOptions(OneofOptions&&) noexcept = default;
12346 OneofOptions& OneofOptions::operator=(OneofOptions&&) = default;
12347 
operator ==(const OneofOptions & other) const12348 bool OneofOptions::operator==(const OneofOptions& other) const {
12349   return unknown_fields_ == other.unknown_fields_;
12350 }
12351 
ParseFromArray(const void * raw,size_t size)12352 bool OneofOptions::ParseFromArray(const void* raw, size_t size) {
12353   unknown_fields_.clear();
12354   bool packed_error = false;
12355 
12356   ::protozero::ProtoDecoder dec(raw, size);
12357   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
12358     if (field.id() < _has_field_.size()) {
12359       _has_field_.set(field.id());
12360     }
12361     switch (field.id()) {
12362       default:
12363         field.SerializeAndAppendTo(&unknown_fields_);
12364         break;
12365     }
12366   }
12367   return !packed_error && !dec.bytes_left();
12368 }
12369 
SerializeAsString() const12370 std::string OneofOptions::SerializeAsString() const {
12371   ::protozero::HeapBuffered<::protozero::Message> msg;
12372   Serialize(msg.get());
12373   return msg.SerializeAsString();
12374 }
12375 
SerializeAsArray() const12376 std::vector<uint8_t> OneofOptions::SerializeAsArray() const {
12377   ::protozero::HeapBuffered<::protozero::Message> msg;
12378   Serialize(msg.get());
12379   return msg.SerializeAsArray();
12380 }
12381 
Serialize(::protozero::Message * msg) const12382 void OneofOptions::Serialize(::protozero::Message* msg) const {
12383   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
12384 }
12385 
12386 
12387 EnumValueDescriptorProto::EnumValueDescriptorProto() = default;
12388 EnumValueDescriptorProto::~EnumValueDescriptorProto() = default;
12389 EnumValueDescriptorProto::EnumValueDescriptorProto(const EnumValueDescriptorProto&) = default;
12390 EnumValueDescriptorProto& EnumValueDescriptorProto::operator=(const EnumValueDescriptorProto&) = default;
12391 EnumValueDescriptorProto::EnumValueDescriptorProto(EnumValueDescriptorProto&&) noexcept = default;
12392 EnumValueDescriptorProto& EnumValueDescriptorProto::operator=(EnumValueDescriptorProto&&) = default;
12393 
operator ==(const EnumValueDescriptorProto & other) const12394 bool EnumValueDescriptorProto::operator==(const EnumValueDescriptorProto& other) const {
12395   return unknown_fields_ == other.unknown_fields_
12396    && name_ == other.name_
12397    && number_ == other.number_;
12398 }
12399 
ParseFromArray(const void * raw,size_t size)12400 bool EnumValueDescriptorProto::ParseFromArray(const void* raw, size_t size) {
12401   unknown_fields_.clear();
12402   bool packed_error = false;
12403 
12404   ::protozero::ProtoDecoder dec(raw, size);
12405   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
12406     if (field.id() < _has_field_.size()) {
12407       _has_field_.set(field.id());
12408     }
12409     switch (field.id()) {
12410       case 1 /* name */:
12411         field.get(&name_);
12412         break;
12413       case 2 /* number */:
12414         field.get(&number_);
12415         break;
12416       default:
12417         field.SerializeAndAppendTo(&unknown_fields_);
12418         break;
12419     }
12420   }
12421   return !packed_error && !dec.bytes_left();
12422 }
12423 
SerializeAsString() const12424 std::string EnumValueDescriptorProto::SerializeAsString() const {
12425   ::protozero::HeapBuffered<::protozero::Message> msg;
12426   Serialize(msg.get());
12427   return msg.SerializeAsString();
12428 }
12429 
SerializeAsArray() const12430 std::vector<uint8_t> EnumValueDescriptorProto::SerializeAsArray() const {
12431   ::protozero::HeapBuffered<::protozero::Message> msg;
12432   Serialize(msg.get());
12433   return msg.SerializeAsArray();
12434 }
12435 
Serialize(::protozero::Message * msg) const12436 void EnumValueDescriptorProto::Serialize(::protozero::Message* msg) const {
12437   // Field 1: name
12438   if (_has_field_[1]) {
12439     msg->AppendString(1, name_);
12440   }
12441 
12442   // Field 2: number
12443   if (_has_field_[2]) {
12444     msg->AppendVarInt(2, number_);
12445   }
12446 
12447   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
12448 }
12449 
12450 
12451 EnumDescriptorProto::EnumDescriptorProto() = default;
12452 EnumDescriptorProto::~EnumDescriptorProto() = default;
12453 EnumDescriptorProto::EnumDescriptorProto(const EnumDescriptorProto&) = default;
12454 EnumDescriptorProto& EnumDescriptorProto::operator=(const EnumDescriptorProto&) = default;
12455 EnumDescriptorProto::EnumDescriptorProto(EnumDescriptorProto&&) noexcept = default;
12456 EnumDescriptorProto& EnumDescriptorProto::operator=(EnumDescriptorProto&&) = default;
12457 
operator ==(const EnumDescriptorProto & other) const12458 bool EnumDescriptorProto::operator==(const EnumDescriptorProto& other) const {
12459   return unknown_fields_ == other.unknown_fields_
12460    && name_ == other.name_
12461    && value_ == other.value_
12462    && reserved_name_ == other.reserved_name_;
12463 }
12464 
value_size() const12465 int EnumDescriptorProto::value_size() const { return static_cast<int>(value_.size()); }
clear_value()12466 void EnumDescriptorProto::clear_value() { value_.clear(); }
add_value()12467 EnumValueDescriptorProto* EnumDescriptorProto::add_value() { value_.emplace_back(); return &value_.back(); }
ParseFromArray(const void * raw,size_t size)12468 bool EnumDescriptorProto::ParseFromArray(const void* raw, size_t size) {
12469   value_.clear();
12470   reserved_name_.clear();
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       case 2 /* value */:
12484         value_.emplace_back();
12485         value_.back().ParseFromArray(field.data(), field.size());
12486         break;
12487       case 5 /* reserved_name */:
12488         reserved_name_.emplace_back();
12489         field.get(&reserved_name_.back());
12490         break;
12491       default:
12492         field.SerializeAndAppendTo(&unknown_fields_);
12493         break;
12494     }
12495   }
12496   return !packed_error && !dec.bytes_left();
12497 }
12498 
SerializeAsString() const12499 std::string EnumDescriptorProto::SerializeAsString() const {
12500   ::protozero::HeapBuffered<::protozero::Message> msg;
12501   Serialize(msg.get());
12502   return msg.SerializeAsString();
12503 }
12504 
SerializeAsArray() const12505 std::vector<uint8_t> EnumDescriptorProto::SerializeAsArray() const {
12506   ::protozero::HeapBuffered<::protozero::Message> msg;
12507   Serialize(msg.get());
12508   return msg.SerializeAsArray();
12509 }
12510 
Serialize(::protozero::Message * msg) const12511 void EnumDescriptorProto::Serialize(::protozero::Message* msg) const {
12512   // Field 1: name
12513   if (_has_field_[1]) {
12514     msg->AppendString(1, name_);
12515   }
12516 
12517   // Field 2: value
12518   for (auto& it : value_) {
12519     it.Serialize(msg->BeginNestedMessage<::protozero::Message>(2));
12520   }
12521 
12522   // Field 5: reserved_name
12523   for (auto& it : reserved_name_) {
12524     msg->AppendString(5, it);
12525   }
12526 
12527   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
12528 }
12529 
12530 
12531 OneofDescriptorProto::OneofDescriptorProto() = default;
12532 OneofDescriptorProto::~OneofDescriptorProto() = default;
12533 OneofDescriptorProto::OneofDescriptorProto(const OneofDescriptorProto&) = default;
12534 OneofDescriptorProto& OneofDescriptorProto::operator=(const OneofDescriptorProto&) = default;
12535 OneofDescriptorProto::OneofDescriptorProto(OneofDescriptorProto&&) noexcept = default;
12536 OneofDescriptorProto& OneofDescriptorProto::operator=(OneofDescriptorProto&&) = default;
12537 
operator ==(const OneofDescriptorProto & other) const12538 bool OneofDescriptorProto::operator==(const OneofDescriptorProto& other) const {
12539   return unknown_fields_ == other.unknown_fields_
12540    && name_ == other.name_
12541    && options_ == other.options_;
12542 }
12543 
ParseFromArray(const void * raw,size_t size)12544 bool OneofDescriptorProto::ParseFromArray(const void* raw, size_t size) {
12545   unknown_fields_.clear();
12546   bool packed_error = false;
12547 
12548   ::protozero::ProtoDecoder dec(raw, size);
12549   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
12550     if (field.id() < _has_field_.size()) {
12551       _has_field_.set(field.id());
12552     }
12553     switch (field.id()) {
12554       case 1 /* name */:
12555         field.get(&name_);
12556         break;
12557       case 2 /* options */:
12558         (*options_).ParseFromArray(field.data(), field.size());
12559         break;
12560       default:
12561         field.SerializeAndAppendTo(&unknown_fields_);
12562         break;
12563     }
12564   }
12565   return !packed_error && !dec.bytes_left();
12566 }
12567 
SerializeAsString() const12568 std::string OneofDescriptorProto::SerializeAsString() const {
12569   ::protozero::HeapBuffered<::protozero::Message> msg;
12570   Serialize(msg.get());
12571   return msg.SerializeAsString();
12572 }
12573 
SerializeAsArray() const12574 std::vector<uint8_t> OneofDescriptorProto::SerializeAsArray() const {
12575   ::protozero::HeapBuffered<::protozero::Message> msg;
12576   Serialize(msg.get());
12577   return msg.SerializeAsArray();
12578 }
12579 
Serialize(::protozero::Message * msg) const12580 void OneofDescriptorProto::Serialize(::protozero::Message* msg) const {
12581   // Field 1: name
12582   if (_has_field_[1]) {
12583     msg->AppendString(1, name_);
12584   }
12585 
12586   // Field 2: options
12587   if (_has_field_[2]) {
12588     (*options_).Serialize(msg->BeginNestedMessage<::protozero::Message>(2));
12589   }
12590 
12591   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
12592 }
12593 
12594 
12595 FieldDescriptorProto::FieldDescriptorProto() = default;
12596 FieldDescriptorProto::~FieldDescriptorProto() = default;
12597 FieldDescriptorProto::FieldDescriptorProto(const FieldDescriptorProto&) = default;
12598 FieldDescriptorProto& FieldDescriptorProto::operator=(const FieldDescriptorProto&) = default;
12599 FieldDescriptorProto::FieldDescriptorProto(FieldDescriptorProto&&) noexcept = default;
12600 FieldDescriptorProto& FieldDescriptorProto::operator=(FieldDescriptorProto&&) = default;
12601 
operator ==(const FieldDescriptorProto & other) const12602 bool FieldDescriptorProto::operator==(const FieldDescriptorProto& other) const {
12603   return unknown_fields_ == other.unknown_fields_
12604    && name_ == other.name_
12605    && number_ == other.number_
12606    && label_ == other.label_
12607    && type_ == other.type_
12608    && type_name_ == other.type_name_
12609    && extendee_ == other.extendee_
12610    && default_value_ == other.default_value_
12611    && oneof_index_ == other.oneof_index_;
12612 }
12613 
ParseFromArray(const void * raw,size_t size)12614 bool FieldDescriptorProto::ParseFromArray(const void* raw, size_t size) {
12615   unknown_fields_.clear();
12616   bool packed_error = false;
12617 
12618   ::protozero::ProtoDecoder dec(raw, size);
12619   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
12620     if (field.id() < _has_field_.size()) {
12621       _has_field_.set(field.id());
12622     }
12623     switch (field.id()) {
12624       case 1 /* name */:
12625         field.get(&name_);
12626         break;
12627       case 3 /* number */:
12628         field.get(&number_);
12629         break;
12630       case 4 /* label */:
12631         field.get(&label_);
12632         break;
12633       case 5 /* type */:
12634         field.get(&type_);
12635         break;
12636       case 6 /* type_name */:
12637         field.get(&type_name_);
12638         break;
12639       case 2 /* extendee */:
12640         field.get(&extendee_);
12641         break;
12642       case 7 /* default_value */:
12643         field.get(&default_value_);
12644         break;
12645       case 9 /* oneof_index */:
12646         field.get(&oneof_index_);
12647         break;
12648       default:
12649         field.SerializeAndAppendTo(&unknown_fields_);
12650         break;
12651     }
12652   }
12653   return !packed_error && !dec.bytes_left();
12654 }
12655 
SerializeAsString() const12656 std::string FieldDescriptorProto::SerializeAsString() const {
12657   ::protozero::HeapBuffered<::protozero::Message> msg;
12658   Serialize(msg.get());
12659   return msg.SerializeAsString();
12660 }
12661 
SerializeAsArray() const12662 std::vector<uint8_t> FieldDescriptorProto::SerializeAsArray() const {
12663   ::protozero::HeapBuffered<::protozero::Message> msg;
12664   Serialize(msg.get());
12665   return msg.SerializeAsArray();
12666 }
12667 
Serialize(::protozero::Message * msg) const12668 void FieldDescriptorProto::Serialize(::protozero::Message* msg) const {
12669   // Field 1: name
12670   if (_has_field_[1]) {
12671     msg->AppendString(1, name_);
12672   }
12673 
12674   // Field 3: number
12675   if (_has_field_[3]) {
12676     msg->AppendVarInt(3, number_);
12677   }
12678 
12679   // Field 4: label
12680   if (_has_field_[4]) {
12681     msg->AppendVarInt(4, label_);
12682   }
12683 
12684   // Field 5: type
12685   if (_has_field_[5]) {
12686     msg->AppendVarInt(5, type_);
12687   }
12688 
12689   // Field 6: type_name
12690   if (_has_field_[6]) {
12691     msg->AppendString(6, type_name_);
12692   }
12693 
12694   // Field 2: extendee
12695   if (_has_field_[2]) {
12696     msg->AppendString(2, extendee_);
12697   }
12698 
12699   // Field 7: default_value
12700   if (_has_field_[7]) {
12701     msg->AppendString(7, default_value_);
12702   }
12703 
12704   // Field 9: oneof_index
12705   if (_has_field_[9]) {
12706     msg->AppendVarInt(9, oneof_index_);
12707   }
12708 
12709   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
12710 }
12711 
12712 
12713 DescriptorProto::DescriptorProto() = default;
12714 DescriptorProto::~DescriptorProto() = default;
12715 DescriptorProto::DescriptorProto(const DescriptorProto&) = default;
12716 DescriptorProto& DescriptorProto::operator=(const DescriptorProto&) = default;
12717 DescriptorProto::DescriptorProto(DescriptorProto&&) noexcept = default;
12718 DescriptorProto& DescriptorProto::operator=(DescriptorProto&&) = default;
12719 
operator ==(const DescriptorProto & other) const12720 bool DescriptorProto::operator==(const DescriptorProto& other) const {
12721   return unknown_fields_ == other.unknown_fields_
12722    && name_ == other.name_
12723    && field_ == other.field_
12724    && extension_ == other.extension_
12725    && nested_type_ == other.nested_type_
12726    && enum_type_ == other.enum_type_
12727    && oneof_decl_ == other.oneof_decl_
12728    && reserved_range_ == other.reserved_range_
12729    && reserved_name_ == other.reserved_name_;
12730 }
12731 
field_size() const12732 int DescriptorProto::field_size() const { return static_cast<int>(field_.size()); }
clear_field()12733 void DescriptorProto::clear_field() { field_.clear(); }
add_field()12734 FieldDescriptorProto* DescriptorProto::add_field() { field_.emplace_back(); return &field_.back(); }
extension_size() const12735 int DescriptorProto::extension_size() const { return static_cast<int>(extension_.size()); }
clear_extension()12736 void DescriptorProto::clear_extension() { extension_.clear(); }
add_extension()12737 FieldDescriptorProto* DescriptorProto::add_extension() { extension_.emplace_back(); return &extension_.back(); }
nested_type_size() const12738 int DescriptorProto::nested_type_size() const { return static_cast<int>(nested_type_.size()); }
clear_nested_type()12739 void DescriptorProto::clear_nested_type() { nested_type_.clear(); }
add_nested_type()12740 DescriptorProto* DescriptorProto::add_nested_type() { nested_type_.emplace_back(); return &nested_type_.back(); }
enum_type_size() const12741 int DescriptorProto::enum_type_size() const { return static_cast<int>(enum_type_.size()); }
clear_enum_type()12742 void DescriptorProto::clear_enum_type() { enum_type_.clear(); }
add_enum_type()12743 EnumDescriptorProto* DescriptorProto::add_enum_type() { enum_type_.emplace_back(); return &enum_type_.back(); }
oneof_decl_size() const12744 int DescriptorProto::oneof_decl_size() const { return static_cast<int>(oneof_decl_.size()); }
clear_oneof_decl()12745 void DescriptorProto::clear_oneof_decl() { oneof_decl_.clear(); }
add_oneof_decl()12746 OneofDescriptorProto* DescriptorProto::add_oneof_decl() { oneof_decl_.emplace_back(); return &oneof_decl_.back(); }
reserved_range_size() const12747 int DescriptorProto::reserved_range_size() const { return static_cast<int>(reserved_range_.size()); }
clear_reserved_range()12748 void DescriptorProto::clear_reserved_range() { reserved_range_.clear(); }
add_reserved_range()12749 DescriptorProto_ReservedRange* DescriptorProto::add_reserved_range() { reserved_range_.emplace_back(); return &reserved_range_.back(); }
ParseFromArray(const void * raw,size_t size)12750 bool DescriptorProto::ParseFromArray(const void* raw, size_t size) {
12751   field_.clear();
12752   extension_.clear();
12753   nested_type_.clear();
12754   enum_type_.clear();
12755   oneof_decl_.clear();
12756   reserved_range_.clear();
12757   reserved_name_.clear();
12758   unknown_fields_.clear();
12759   bool packed_error = false;
12760 
12761   ::protozero::ProtoDecoder dec(raw, size);
12762   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
12763     if (field.id() < _has_field_.size()) {
12764       _has_field_.set(field.id());
12765     }
12766     switch (field.id()) {
12767       case 1 /* name */:
12768         field.get(&name_);
12769         break;
12770       case 2 /* field */:
12771         field_.emplace_back();
12772         field_.back().ParseFromArray(field.data(), field.size());
12773         break;
12774       case 6 /* extension */:
12775         extension_.emplace_back();
12776         extension_.back().ParseFromArray(field.data(), field.size());
12777         break;
12778       case 3 /* nested_type */:
12779         nested_type_.emplace_back();
12780         nested_type_.back().ParseFromArray(field.data(), field.size());
12781         break;
12782       case 4 /* enum_type */:
12783         enum_type_.emplace_back();
12784         enum_type_.back().ParseFromArray(field.data(), field.size());
12785         break;
12786       case 8 /* oneof_decl */:
12787         oneof_decl_.emplace_back();
12788         oneof_decl_.back().ParseFromArray(field.data(), field.size());
12789         break;
12790       case 9 /* reserved_range */:
12791         reserved_range_.emplace_back();
12792         reserved_range_.back().ParseFromArray(field.data(), field.size());
12793         break;
12794       case 10 /* reserved_name */:
12795         reserved_name_.emplace_back();
12796         field.get(&reserved_name_.back());
12797         break;
12798       default:
12799         field.SerializeAndAppendTo(&unknown_fields_);
12800         break;
12801     }
12802   }
12803   return !packed_error && !dec.bytes_left();
12804 }
12805 
SerializeAsString() const12806 std::string DescriptorProto::SerializeAsString() const {
12807   ::protozero::HeapBuffered<::protozero::Message> msg;
12808   Serialize(msg.get());
12809   return msg.SerializeAsString();
12810 }
12811 
SerializeAsArray() const12812 std::vector<uint8_t> DescriptorProto::SerializeAsArray() const {
12813   ::protozero::HeapBuffered<::protozero::Message> msg;
12814   Serialize(msg.get());
12815   return msg.SerializeAsArray();
12816 }
12817 
Serialize(::protozero::Message * msg) const12818 void DescriptorProto::Serialize(::protozero::Message* msg) const {
12819   // Field 1: name
12820   if (_has_field_[1]) {
12821     msg->AppendString(1, name_);
12822   }
12823 
12824   // Field 2: field
12825   for (auto& it : field_) {
12826     it.Serialize(msg->BeginNestedMessage<::protozero::Message>(2));
12827   }
12828 
12829   // Field 6: extension
12830   for (auto& it : extension_) {
12831     it.Serialize(msg->BeginNestedMessage<::protozero::Message>(6));
12832   }
12833 
12834   // Field 3: nested_type
12835   for (auto& it : nested_type_) {
12836     it.Serialize(msg->BeginNestedMessage<::protozero::Message>(3));
12837   }
12838 
12839   // Field 4: enum_type
12840   for (auto& it : enum_type_) {
12841     it.Serialize(msg->BeginNestedMessage<::protozero::Message>(4));
12842   }
12843 
12844   // Field 8: oneof_decl
12845   for (auto& it : oneof_decl_) {
12846     it.Serialize(msg->BeginNestedMessage<::protozero::Message>(8));
12847   }
12848 
12849   // Field 9: reserved_range
12850   for (auto& it : reserved_range_) {
12851     it.Serialize(msg->BeginNestedMessage<::protozero::Message>(9));
12852   }
12853 
12854   // Field 10: reserved_name
12855   for (auto& it : reserved_name_) {
12856     msg->AppendString(10, it);
12857   }
12858 
12859   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
12860 }
12861 
12862 
12863 DescriptorProto_ReservedRange::DescriptorProto_ReservedRange() = default;
12864 DescriptorProto_ReservedRange::~DescriptorProto_ReservedRange() = default;
12865 DescriptorProto_ReservedRange::DescriptorProto_ReservedRange(const DescriptorProto_ReservedRange&) = default;
12866 DescriptorProto_ReservedRange& DescriptorProto_ReservedRange::operator=(const DescriptorProto_ReservedRange&) = default;
12867 DescriptorProto_ReservedRange::DescriptorProto_ReservedRange(DescriptorProto_ReservedRange&&) noexcept = default;
12868 DescriptorProto_ReservedRange& DescriptorProto_ReservedRange::operator=(DescriptorProto_ReservedRange&&) = default;
12869 
operator ==(const DescriptorProto_ReservedRange & other) const12870 bool DescriptorProto_ReservedRange::operator==(const DescriptorProto_ReservedRange& other) const {
12871   return unknown_fields_ == other.unknown_fields_
12872    && start_ == other.start_
12873    && end_ == other.end_;
12874 }
12875 
ParseFromArray(const void * raw,size_t size)12876 bool DescriptorProto_ReservedRange::ParseFromArray(const void* raw, size_t size) {
12877   unknown_fields_.clear();
12878   bool packed_error = false;
12879 
12880   ::protozero::ProtoDecoder dec(raw, size);
12881   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
12882     if (field.id() < _has_field_.size()) {
12883       _has_field_.set(field.id());
12884     }
12885     switch (field.id()) {
12886       case 1 /* start */:
12887         field.get(&start_);
12888         break;
12889       case 2 /* end */:
12890         field.get(&end_);
12891         break;
12892       default:
12893         field.SerializeAndAppendTo(&unknown_fields_);
12894         break;
12895     }
12896   }
12897   return !packed_error && !dec.bytes_left();
12898 }
12899 
SerializeAsString() const12900 std::string DescriptorProto_ReservedRange::SerializeAsString() const {
12901   ::protozero::HeapBuffered<::protozero::Message> msg;
12902   Serialize(msg.get());
12903   return msg.SerializeAsString();
12904 }
12905 
SerializeAsArray() const12906 std::vector<uint8_t> DescriptorProto_ReservedRange::SerializeAsArray() const {
12907   ::protozero::HeapBuffered<::protozero::Message> msg;
12908   Serialize(msg.get());
12909   return msg.SerializeAsArray();
12910 }
12911 
Serialize(::protozero::Message * msg) const12912 void DescriptorProto_ReservedRange::Serialize(::protozero::Message* msg) const {
12913   // Field 1: start
12914   if (_has_field_[1]) {
12915     msg->AppendVarInt(1, start_);
12916   }
12917 
12918   // Field 2: end
12919   if (_has_field_[2]) {
12920     msg->AppendVarInt(2, end_);
12921   }
12922 
12923   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
12924 }
12925 
12926 
12927 FileDescriptorProto::FileDescriptorProto() = default;
12928 FileDescriptorProto::~FileDescriptorProto() = default;
12929 FileDescriptorProto::FileDescriptorProto(const FileDescriptorProto&) = default;
12930 FileDescriptorProto& FileDescriptorProto::operator=(const FileDescriptorProto&) = default;
12931 FileDescriptorProto::FileDescriptorProto(FileDescriptorProto&&) noexcept = default;
12932 FileDescriptorProto& FileDescriptorProto::operator=(FileDescriptorProto&&) = default;
12933 
operator ==(const FileDescriptorProto & other) const12934 bool FileDescriptorProto::operator==(const FileDescriptorProto& other) const {
12935   return unknown_fields_ == other.unknown_fields_
12936    && name_ == other.name_
12937    && package_ == other.package_
12938    && dependency_ == other.dependency_
12939    && public_dependency_ == other.public_dependency_
12940    && weak_dependency_ == other.weak_dependency_
12941    && message_type_ == other.message_type_
12942    && enum_type_ == other.enum_type_
12943    && extension_ == other.extension_;
12944 }
12945 
message_type_size() const12946 int FileDescriptorProto::message_type_size() const { return static_cast<int>(message_type_.size()); }
clear_message_type()12947 void FileDescriptorProto::clear_message_type() { message_type_.clear(); }
add_message_type()12948 DescriptorProto* FileDescriptorProto::add_message_type() { message_type_.emplace_back(); return &message_type_.back(); }
enum_type_size() const12949 int FileDescriptorProto::enum_type_size() const { return static_cast<int>(enum_type_.size()); }
clear_enum_type()12950 void FileDescriptorProto::clear_enum_type() { enum_type_.clear(); }
add_enum_type()12951 EnumDescriptorProto* FileDescriptorProto::add_enum_type() { enum_type_.emplace_back(); return &enum_type_.back(); }
extension_size() const12952 int FileDescriptorProto::extension_size() const { return static_cast<int>(extension_.size()); }
clear_extension()12953 void FileDescriptorProto::clear_extension() { extension_.clear(); }
add_extension()12954 FieldDescriptorProto* FileDescriptorProto::add_extension() { extension_.emplace_back(); return &extension_.back(); }
ParseFromArray(const void * raw,size_t size)12955 bool FileDescriptorProto::ParseFromArray(const void* raw, size_t size) {
12956   dependency_.clear();
12957   public_dependency_.clear();
12958   weak_dependency_.clear();
12959   message_type_.clear();
12960   enum_type_.clear();
12961   extension_.clear();
12962   unknown_fields_.clear();
12963   bool packed_error = false;
12964 
12965   ::protozero::ProtoDecoder dec(raw, size);
12966   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
12967     if (field.id() < _has_field_.size()) {
12968       _has_field_.set(field.id());
12969     }
12970     switch (field.id()) {
12971       case 1 /* name */:
12972         field.get(&name_);
12973         break;
12974       case 2 /* package */:
12975         field.get(&package_);
12976         break;
12977       case 3 /* dependency */:
12978         dependency_.emplace_back();
12979         field.get(&dependency_.back());
12980         break;
12981       case 10 /* public_dependency */:
12982         public_dependency_.emplace_back();
12983         field.get(&public_dependency_.back());
12984         break;
12985       case 11 /* weak_dependency */:
12986         weak_dependency_.emplace_back();
12987         field.get(&weak_dependency_.back());
12988         break;
12989       case 4 /* message_type */:
12990         message_type_.emplace_back();
12991         message_type_.back().ParseFromArray(field.data(), field.size());
12992         break;
12993       case 5 /* enum_type */:
12994         enum_type_.emplace_back();
12995         enum_type_.back().ParseFromArray(field.data(), field.size());
12996         break;
12997       case 7 /* extension */:
12998         extension_.emplace_back();
12999         extension_.back().ParseFromArray(field.data(), field.size());
13000         break;
13001       default:
13002         field.SerializeAndAppendTo(&unknown_fields_);
13003         break;
13004     }
13005   }
13006   return !packed_error && !dec.bytes_left();
13007 }
13008 
SerializeAsString() const13009 std::string FileDescriptorProto::SerializeAsString() const {
13010   ::protozero::HeapBuffered<::protozero::Message> msg;
13011   Serialize(msg.get());
13012   return msg.SerializeAsString();
13013 }
13014 
SerializeAsArray() const13015 std::vector<uint8_t> FileDescriptorProto::SerializeAsArray() const {
13016   ::protozero::HeapBuffered<::protozero::Message> msg;
13017   Serialize(msg.get());
13018   return msg.SerializeAsArray();
13019 }
13020 
Serialize(::protozero::Message * msg) const13021 void FileDescriptorProto::Serialize(::protozero::Message* msg) const {
13022   // Field 1: name
13023   if (_has_field_[1]) {
13024     msg->AppendString(1, name_);
13025   }
13026 
13027   // Field 2: package
13028   if (_has_field_[2]) {
13029     msg->AppendString(2, package_);
13030   }
13031 
13032   // Field 3: dependency
13033   for (auto& it : dependency_) {
13034     msg->AppendString(3, it);
13035   }
13036 
13037   // Field 10: public_dependency
13038   for (auto& it : public_dependency_) {
13039     msg->AppendVarInt(10, it);
13040   }
13041 
13042   // Field 11: weak_dependency
13043   for (auto& it : weak_dependency_) {
13044     msg->AppendVarInt(11, it);
13045   }
13046 
13047   // Field 4: message_type
13048   for (auto& it : message_type_) {
13049     it.Serialize(msg->BeginNestedMessage<::protozero::Message>(4));
13050   }
13051 
13052   // Field 5: enum_type
13053   for (auto& it : enum_type_) {
13054     it.Serialize(msg->BeginNestedMessage<::protozero::Message>(5));
13055   }
13056 
13057   // Field 7: extension
13058   for (auto& it : extension_) {
13059     it.Serialize(msg->BeginNestedMessage<::protozero::Message>(7));
13060   }
13061 
13062   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
13063 }
13064 
13065 
13066 FileDescriptorSet::FileDescriptorSet() = default;
13067 FileDescriptorSet::~FileDescriptorSet() = default;
13068 FileDescriptorSet::FileDescriptorSet(const FileDescriptorSet&) = default;
13069 FileDescriptorSet& FileDescriptorSet::operator=(const FileDescriptorSet&) = default;
13070 FileDescriptorSet::FileDescriptorSet(FileDescriptorSet&&) noexcept = default;
13071 FileDescriptorSet& FileDescriptorSet::operator=(FileDescriptorSet&&) = default;
13072 
operator ==(const FileDescriptorSet & other) const13073 bool FileDescriptorSet::operator==(const FileDescriptorSet& other) const {
13074   return unknown_fields_ == other.unknown_fields_
13075    && file_ == other.file_;
13076 }
13077 
file_size() const13078 int FileDescriptorSet::file_size() const { return static_cast<int>(file_.size()); }
clear_file()13079 void FileDescriptorSet::clear_file() { file_.clear(); }
add_file()13080 FileDescriptorProto* FileDescriptorSet::add_file() { file_.emplace_back(); return &file_.back(); }
ParseFromArray(const void * raw,size_t size)13081 bool FileDescriptorSet::ParseFromArray(const void* raw, size_t size) {
13082   file_.clear();
13083   unknown_fields_.clear();
13084   bool packed_error = false;
13085 
13086   ::protozero::ProtoDecoder dec(raw, size);
13087   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
13088     if (field.id() < _has_field_.size()) {
13089       _has_field_.set(field.id());
13090     }
13091     switch (field.id()) {
13092       case 1 /* file */:
13093         file_.emplace_back();
13094         file_.back().ParseFromArray(field.data(), field.size());
13095         break;
13096       default:
13097         field.SerializeAndAppendTo(&unknown_fields_);
13098         break;
13099     }
13100   }
13101   return !packed_error && !dec.bytes_left();
13102 }
13103 
SerializeAsString() const13104 std::string FileDescriptorSet::SerializeAsString() const {
13105   ::protozero::HeapBuffered<::protozero::Message> msg;
13106   Serialize(msg.get());
13107   return msg.SerializeAsString();
13108 }
13109 
SerializeAsArray() const13110 std::vector<uint8_t> FileDescriptorSet::SerializeAsArray() const {
13111   ::protozero::HeapBuffered<::protozero::Message> msg;
13112   Serialize(msg.get());
13113   return msg.SerializeAsArray();
13114 }
13115 
Serialize(::protozero::Message * msg) const13116 void FileDescriptorSet::Serialize(::protozero::Message* msg) const {
13117   // Field 1: file
13118   for (auto& it : file_) {
13119     it.Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
13120   }
13121 
13122   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
13123 }
13124 
13125 }  // namespace perfetto
13126 }  // namespace protos
13127 }  // namespace gen
13128 #if defined(__GNUC__) || defined(__clang__)
13129 #pragma GCC diagnostic pop
13130 #endif
13131 // gen_amalgamated begin source: gen/protos/perfetto/common/gpu_counter_descriptor.gen.cc
13132 // gen_amalgamated begin header: gen/protos/perfetto/common/gpu_counter_descriptor.gen.h
13133 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
13134 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_GPU_COUNTER_DESCRIPTOR_PROTO_CPP_H_
13135 #define PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_GPU_COUNTER_DESCRIPTOR_PROTO_CPP_H_
13136 
13137 #include <stdint.h>
13138 #include <bitset>
13139 #include <vector>
13140 #include <string>
13141 #include <type_traits>
13142 
13143 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
13144 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
13145 // gen_amalgamated expanded: #include "perfetto/base/export.h"
13146 
13147 namespace perfetto {
13148 namespace protos {
13149 namespace gen {
13150 class GpuCounterDescriptor;
13151 class GpuCounterDescriptor_GpuCounterBlock;
13152 class GpuCounterDescriptor_GpuCounterSpec;
13153 enum GpuCounterDescriptor_GpuCounterGroup : int;
13154 enum GpuCounterDescriptor_MeasureUnit : int;
13155 }  // namespace perfetto
13156 }  // namespace protos
13157 }  // namespace gen
13158 
13159 namespace protozero {
13160 class Message;
13161 }  // namespace protozero
13162 
13163 namespace perfetto {
13164 namespace protos {
13165 namespace gen {
13166 enum GpuCounterDescriptor_GpuCounterGroup : int {
13167   GpuCounterDescriptor_GpuCounterGroup_UNCLASSIFIED = 0,
13168   GpuCounterDescriptor_GpuCounterGroup_SYSTEM = 1,
13169   GpuCounterDescriptor_GpuCounterGroup_VERTICES = 2,
13170   GpuCounterDescriptor_GpuCounterGroup_FRAGMENTS = 3,
13171   GpuCounterDescriptor_GpuCounterGroup_PRIMITIVES = 4,
13172   GpuCounterDescriptor_GpuCounterGroup_MEMORY = 5,
13173   GpuCounterDescriptor_GpuCounterGroup_COMPUTE = 6,
13174 };
13175 enum GpuCounterDescriptor_MeasureUnit : int {
13176   GpuCounterDescriptor_MeasureUnit_NONE = 0,
13177   GpuCounterDescriptor_MeasureUnit_BIT = 1,
13178   GpuCounterDescriptor_MeasureUnit_KILOBIT = 2,
13179   GpuCounterDescriptor_MeasureUnit_MEGABIT = 3,
13180   GpuCounterDescriptor_MeasureUnit_GIGABIT = 4,
13181   GpuCounterDescriptor_MeasureUnit_TERABIT = 5,
13182   GpuCounterDescriptor_MeasureUnit_PETABIT = 6,
13183   GpuCounterDescriptor_MeasureUnit_BYTE = 7,
13184   GpuCounterDescriptor_MeasureUnit_KILOBYTE = 8,
13185   GpuCounterDescriptor_MeasureUnit_MEGABYTE = 9,
13186   GpuCounterDescriptor_MeasureUnit_GIGABYTE = 10,
13187   GpuCounterDescriptor_MeasureUnit_TERABYTE = 11,
13188   GpuCounterDescriptor_MeasureUnit_PETABYTE = 12,
13189   GpuCounterDescriptor_MeasureUnit_HERTZ = 13,
13190   GpuCounterDescriptor_MeasureUnit_KILOHERTZ = 14,
13191   GpuCounterDescriptor_MeasureUnit_MEGAHERTZ = 15,
13192   GpuCounterDescriptor_MeasureUnit_GIGAHERTZ = 16,
13193   GpuCounterDescriptor_MeasureUnit_TERAHERTZ = 17,
13194   GpuCounterDescriptor_MeasureUnit_PETAHERTZ = 18,
13195   GpuCounterDescriptor_MeasureUnit_NANOSECOND = 19,
13196   GpuCounterDescriptor_MeasureUnit_MICROSECOND = 20,
13197   GpuCounterDescriptor_MeasureUnit_MILLISECOND = 21,
13198   GpuCounterDescriptor_MeasureUnit_SECOND = 22,
13199   GpuCounterDescriptor_MeasureUnit_MINUTE = 23,
13200   GpuCounterDescriptor_MeasureUnit_HOUR = 24,
13201   GpuCounterDescriptor_MeasureUnit_VERTEX = 25,
13202   GpuCounterDescriptor_MeasureUnit_PIXEL = 26,
13203   GpuCounterDescriptor_MeasureUnit_TRIANGLE = 27,
13204   GpuCounterDescriptor_MeasureUnit_PRIMITIVE = 38,
13205   GpuCounterDescriptor_MeasureUnit_FRAGMENT = 39,
13206   GpuCounterDescriptor_MeasureUnit_MILLIWATT = 28,
13207   GpuCounterDescriptor_MeasureUnit_WATT = 29,
13208   GpuCounterDescriptor_MeasureUnit_KILOWATT = 30,
13209   GpuCounterDescriptor_MeasureUnit_JOULE = 31,
13210   GpuCounterDescriptor_MeasureUnit_VOLT = 32,
13211   GpuCounterDescriptor_MeasureUnit_AMPERE = 33,
13212   GpuCounterDescriptor_MeasureUnit_CELSIUS = 34,
13213   GpuCounterDescriptor_MeasureUnit_FAHRENHEIT = 35,
13214   GpuCounterDescriptor_MeasureUnit_KELVIN = 36,
13215   GpuCounterDescriptor_MeasureUnit_PERCENT = 37,
13216   GpuCounterDescriptor_MeasureUnit_INSTRUCTION = 40,
13217 };
13218 
13219 class PERFETTO_EXPORT GpuCounterDescriptor : public ::protozero::CppMessageObj {
13220  public:
13221   using GpuCounterSpec = GpuCounterDescriptor_GpuCounterSpec;
13222   using GpuCounterBlock = GpuCounterDescriptor_GpuCounterBlock;
13223   using GpuCounterGroup = GpuCounterDescriptor_GpuCounterGroup;
13224   static constexpr auto UNCLASSIFIED = GpuCounterDescriptor_GpuCounterGroup_UNCLASSIFIED;
13225   static constexpr auto SYSTEM = GpuCounterDescriptor_GpuCounterGroup_SYSTEM;
13226   static constexpr auto VERTICES = GpuCounterDescriptor_GpuCounterGroup_VERTICES;
13227   static constexpr auto FRAGMENTS = GpuCounterDescriptor_GpuCounterGroup_FRAGMENTS;
13228   static constexpr auto PRIMITIVES = GpuCounterDescriptor_GpuCounterGroup_PRIMITIVES;
13229   static constexpr auto MEMORY = GpuCounterDescriptor_GpuCounterGroup_MEMORY;
13230   static constexpr auto COMPUTE = GpuCounterDescriptor_GpuCounterGroup_COMPUTE;
13231   static constexpr auto GpuCounterGroup_MIN = GpuCounterDescriptor_GpuCounterGroup_UNCLASSIFIED;
13232   static constexpr auto GpuCounterGroup_MAX = GpuCounterDescriptor_GpuCounterGroup_COMPUTE;
13233   using MeasureUnit = GpuCounterDescriptor_MeasureUnit;
13234   static constexpr auto NONE = GpuCounterDescriptor_MeasureUnit_NONE;
13235   static constexpr auto BIT = GpuCounterDescriptor_MeasureUnit_BIT;
13236   static constexpr auto KILOBIT = GpuCounterDescriptor_MeasureUnit_KILOBIT;
13237   static constexpr auto MEGABIT = GpuCounterDescriptor_MeasureUnit_MEGABIT;
13238   static constexpr auto GIGABIT = GpuCounterDescriptor_MeasureUnit_GIGABIT;
13239   static constexpr auto TERABIT = GpuCounterDescriptor_MeasureUnit_TERABIT;
13240   static constexpr auto PETABIT = GpuCounterDescriptor_MeasureUnit_PETABIT;
13241   static constexpr auto BYTE = GpuCounterDescriptor_MeasureUnit_BYTE;
13242   static constexpr auto KILOBYTE = GpuCounterDescriptor_MeasureUnit_KILOBYTE;
13243   static constexpr auto MEGABYTE = GpuCounterDescriptor_MeasureUnit_MEGABYTE;
13244   static constexpr auto GIGABYTE = GpuCounterDescriptor_MeasureUnit_GIGABYTE;
13245   static constexpr auto TERABYTE = GpuCounterDescriptor_MeasureUnit_TERABYTE;
13246   static constexpr auto PETABYTE = GpuCounterDescriptor_MeasureUnit_PETABYTE;
13247   static constexpr auto HERTZ = GpuCounterDescriptor_MeasureUnit_HERTZ;
13248   static constexpr auto KILOHERTZ = GpuCounterDescriptor_MeasureUnit_KILOHERTZ;
13249   static constexpr auto MEGAHERTZ = GpuCounterDescriptor_MeasureUnit_MEGAHERTZ;
13250   static constexpr auto GIGAHERTZ = GpuCounterDescriptor_MeasureUnit_GIGAHERTZ;
13251   static constexpr auto TERAHERTZ = GpuCounterDescriptor_MeasureUnit_TERAHERTZ;
13252   static constexpr auto PETAHERTZ = GpuCounterDescriptor_MeasureUnit_PETAHERTZ;
13253   static constexpr auto NANOSECOND = GpuCounterDescriptor_MeasureUnit_NANOSECOND;
13254   static constexpr auto MICROSECOND = GpuCounterDescriptor_MeasureUnit_MICROSECOND;
13255   static constexpr auto MILLISECOND = GpuCounterDescriptor_MeasureUnit_MILLISECOND;
13256   static constexpr auto SECOND = GpuCounterDescriptor_MeasureUnit_SECOND;
13257   static constexpr auto MINUTE = GpuCounterDescriptor_MeasureUnit_MINUTE;
13258   static constexpr auto HOUR = GpuCounterDescriptor_MeasureUnit_HOUR;
13259   static constexpr auto VERTEX = GpuCounterDescriptor_MeasureUnit_VERTEX;
13260   static constexpr auto PIXEL = GpuCounterDescriptor_MeasureUnit_PIXEL;
13261   static constexpr auto TRIANGLE = GpuCounterDescriptor_MeasureUnit_TRIANGLE;
13262   static constexpr auto PRIMITIVE = GpuCounterDescriptor_MeasureUnit_PRIMITIVE;
13263   static constexpr auto FRAGMENT = GpuCounterDescriptor_MeasureUnit_FRAGMENT;
13264   static constexpr auto MILLIWATT = GpuCounterDescriptor_MeasureUnit_MILLIWATT;
13265   static constexpr auto WATT = GpuCounterDescriptor_MeasureUnit_WATT;
13266   static constexpr auto KILOWATT = GpuCounterDescriptor_MeasureUnit_KILOWATT;
13267   static constexpr auto JOULE = GpuCounterDescriptor_MeasureUnit_JOULE;
13268   static constexpr auto VOLT = GpuCounterDescriptor_MeasureUnit_VOLT;
13269   static constexpr auto AMPERE = GpuCounterDescriptor_MeasureUnit_AMPERE;
13270   static constexpr auto CELSIUS = GpuCounterDescriptor_MeasureUnit_CELSIUS;
13271   static constexpr auto FAHRENHEIT = GpuCounterDescriptor_MeasureUnit_FAHRENHEIT;
13272   static constexpr auto KELVIN = GpuCounterDescriptor_MeasureUnit_KELVIN;
13273   static constexpr auto PERCENT = GpuCounterDescriptor_MeasureUnit_PERCENT;
13274   static constexpr auto INSTRUCTION = GpuCounterDescriptor_MeasureUnit_INSTRUCTION;
13275   static constexpr auto MeasureUnit_MIN = GpuCounterDescriptor_MeasureUnit_NONE;
13276   static constexpr auto MeasureUnit_MAX = GpuCounterDescriptor_MeasureUnit_INSTRUCTION;
13277   enum FieldNumbers {
13278     kSpecsFieldNumber = 1,
13279     kBlocksFieldNumber = 2,
13280     kMinSamplingPeriodNsFieldNumber = 3,
13281     kMaxSamplingPeriodNsFieldNumber = 4,
13282     kSupportsInstrumentedSamplingFieldNumber = 5,
13283   };
13284 
13285   GpuCounterDescriptor();
13286   ~GpuCounterDescriptor() override;
13287   GpuCounterDescriptor(GpuCounterDescriptor&&) noexcept;
13288   GpuCounterDescriptor& operator=(GpuCounterDescriptor&&);
13289   GpuCounterDescriptor(const GpuCounterDescriptor&);
13290   GpuCounterDescriptor& operator=(const GpuCounterDescriptor&);
13291   bool operator==(const GpuCounterDescriptor&) const;
operator !=(const GpuCounterDescriptor & other) const13292   bool operator!=(const GpuCounterDescriptor& other) const { return !(*this == other); }
13293 
13294   bool ParseFromArray(const void*, size_t) override;
13295   std::string SerializeAsString() const override;
13296   std::vector<uint8_t> SerializeAsArray() const override;
13297   void Serialize(::protozero::Message*) const;
13298 
specs() const13299   const std::vector<GpuCounterDescriptor_GpuCounterSpec>& specs() const { return specs_; }
mutable_specs()13300   std::vector<GpuCounterDescriptor_GpuCounterSpec>* mutable_specs() { return &specs_; }
13301   int specs_size() const;
13302   void clear_specs();
13303   GpuCounterDescriptor_GpuCounterSpec* add_specs();
13304 
blocks() const13305   const std::vector<GpuCounterDescriptor_GpuCounterBlock>& blocks() const { return blocks_; }
mutable_blocks()13306   std::vector<GpuCounterDescriptor_GpuCounterBlock>* mutable_blocks() { return &blocks_; }
13307   int blocks_size() const;
13308   void clear_blocks();
13309   GpuCounterDescriptor_GpuCounterBlock* add_blocks();
13310 
has_min_sampling_period_ns() const13311   bool has_min_sampling_period_ns() const { return _has_field_[3]; }
min_sampling_period_ns() const13312   uint64_t min_sampling_period_ns() const { return min_sampling_period_ns_; }
set_min_sampling_period_ns(uint64_t value)13313   void set_min_sampling_period_ns(uint64_t value) { min_sampling_period_ns_ = value; _has_field_.set(3); }
13314 
has_max_sampling_period_ns() const13315   bool has_max_sampling_period_ns() const { return _has_field_[4]; }
max_sampling_period_ns() const13316   uint64_t max_sampling_period_ns() const { return max_sampling_period_ns_; }
set_max_sampling_period_ns(uint64_t value)13317   void set_max_sampling_period_ns(uint64_t value) { max_sampling_period_ns_ = value; _has_field_.set(4); }
13318 
has_supports_instrumented_sampling() const13319   bool has_supports_instrumented_sampling() const { return _has_field_[5]; }
supports_instrumented_sampling() const13320   bool supports_instrumented_sampling() const { return supports_instrumented_sampling_; }
set_supports_instrumented_sampling(bool value)13321   void set_supports_instrumented_sampling(bool value) { supports_instrumented_sampling_ = value; _has_field_.set(5); }
13322 
13323  private:
13324   std::vector<GpuCounterDescriptor_GpuCounterSpec> specs_;
13325   std::vector<GpuCounterDescriptor_GpuCounterBlock> blocks_;
13326   uint64_t min_sampling_period_ns_{};
13327   uint64_t max_sampling_period_ns_{};
13328   bool supports_instrumented_sampling_{};
13329 
13330   // Allows to preserve unknown protobuf fields for compatibility
13331   // with future versions of .proto files.
13332   std::string unknown_fields_;
13333 
13334   std::bitset<6> _has_field_{};
13335 };
13336 
13337 
13338 class PERFETTO_EXPORT GpuCounterDescriptor_GpuCounterBlock : public ::protozero::CppMessageObj {
13339  public:
13340   enum FieldNumbers {
13341     kBlockIdFieldNumber = 1,
13342     kBlockCapacityFieldNumber = 2,
13343     kNameFieldNumber = 3,
13344     kDescriptionFieldNumber = 4,
13345     kCounterIdsFieldNumber = 5,
13346   };
13347 
13348   GpuCounterDescriptor_GpuCounterBlock();
13349   ~GpuCounterDescriptor_GpuCounterBlock() override;
13350   GpuCounterDescriptor_GpuCounterBlock(GpuCounterDescriptor_GpuCounterBlock&&) noexcept;
13351   GpuCounterDescriptor_GpuCounterBlock& operator=(GpuCounterDescriptor_GpuCounterBlock&&);
13352   GpuCounterDescriptor_GpuCounterBlock(const GpuCounterDescriptor_GpuCounterBlock&);
13353   GpuCounterDescriptor_GpuCounterBlock& operator=(const GpuCounterDescriptor_GpuCounterBlock&);
13354   bool operator==(const GpuCounterDescriptor_GpuCounterBlock&) const;
operator !=(const GpuCounterDescriptor_GpuCounterBlock & other) const13355   bool operator!=(const GpuCounterDescriptor_GpuCounterBlock& other) const { return !(*this == other); }
13356 
13357   bool ParseFromArray(const void*, size_t) override;
13358   std::string SerializeAsString() const override;
13359   std::vector<uint8_t> SerializeAsArray() const override;
13360   void Serialize(::protozero::Message*) const;
13361 
has_block_id() const13362   bool has_block_id() const { return _has_field_[1]; }
block_id() const13363   uint32_t block_id() const { return block_id_; }
set_block_id(uint32_t value)13364   void set_block_id(uint32_t value) { block_id_ = value; _has_field_.set(1); }
13365 
has_block_capacity() const13366   bool has_block_capacity() const { return _has_field_[2]; }
block_capacity() const13367   uint32_t block_capacity() const { return block_capacity_; }
set_block_capacity(uint32_t value)13368   void set_block_capacity(uint32_t value) { block_capacity_ = value; _has_field_.set(2); }
13369 
has_name() const13370   bool has_name() const { return _has_field_[3]; }
name() const13371   const std::string& name() const { return name_; }
set_name(const std::string & value)13372   void set_name(const std::string& value) { name_ = value; _has_field_.set(3); }
13373 
has_description() const13374   bool has_description() const { return _has_field_[4]; }
description() const13375   const std::string& description() const { return description_; }
set_description(const std::string & value)13376   void set_description(const std::string& value) { description_ = value; _has_field_.set(4); }
13377 
counter_ids() const13378   const std::vector<uint32_t>& counter_ids() const { return counter_ids_; }
mutable_counter_ids()13379   std::vector<uint32_t>* mutable_counter_ids() { return &counter_ids_; }
counter_ids_size() const13380   int counter_ids_size() const { return static_cast<int>(counter_ids_.size()); }
clear_counter_ids()13381   void clear_counter_ids() { counter_ids_.clear(); }
add_counter_ids(uint32_t value)13382   void add_counter_ids(uint32_t value) { counter_ids_.emplace_back(value); }
add_counter_ids()13383   uint32_t* add_counter_ids() { counter_ids_.emplace_back(); return &counter_ids_.back(); }
13384 
13385  private:
13386   uint32_t block_id_{};
13387   uint32_t block_capacity_{};
13388   std::string name_{};
13389   std::string description_{};
13390   std::vector<uint32_t> counter_ids_;
13391 
13392   // Allows to preserve unknown protobuf fields for compatibility
13393   // with future versions of .proto files.
13394   std::string unknown_fields_;
13395 
13396   std::bitset<6> _has_field_{};
13397 };
13398 
13399 
13400 class PERFETTO_EXPORT GpuCounterDescriptor_GpuCounterSpec : public ::protozero::CppMessageObj {
13401  public:
13402   enum FieldNumbers {
13403     kCounterIdFieldNumber = 1,
13404     kNameFieldNumber = 2,
13405     kDescriptionFieldNumber = 3,
13406     kIntPeakValueFieldNumber = 5,
13407     kDoublePeakValueFieldNumber = 6,
13408     kNumeratorUnitsFieldNumber = 7,
13409     kDenominatorUnitsFieldNumber = 8,
13410     kSelectByDefaultFieldNumber = 9,
13411     kGroupsFieldNumber = 10,
13412   };
13413 
13414   GpuCounterDescriptor_GpuCounterSpec();
13415   ~GpuCounterDescriptor_GpuCounterSpec() override;
13416   GpuCounterDescriptor_GpuCounterSpec(GpuCounterDescriptor_GpuCounterSpec&&) noexcept;
13417   GpuCounterDescriptor_GpuCounterSpec& operator=(GpuCounterDescriptor_GpuCounterSpec&&);
13418   GpuCounterDescriptor_GpuCounterSpec(const GpuCounterDescriptor_GpuCounterSpec&);
13419   GpuCounterDescriptor_GpuCounterSpec& operator=(const GpuCounterDescriptor_GpuCounterSpec&);
13420   bool operator==(const GpuCounterDescriptor_GpuCounterSpec&) const;
operator !=(const GpuCounterDescriptor_GpuCounterSpec & other) const13421   bool operator!=(const GpuCounterDescriptor_GpuCounterSpec& other) const { return !(*this == other); }
13422 
13423   bool ParseFromArray(const void*, size_t) override;
13424   std::string SerializeAsString() const override;
13425   std::vector<uint8_t> SerializeAsArray() const override;
13426   void Serialize(::protozero::Message*) const;
13427 
has_counter_id() const13428   bool has_counter_id() const { return _has_field_[1]; }
counter_id() const13429   uint32_t counter_id() const { return counter_id_; }
set_counter_id(uint32_t value)13430   void set_counter_id(uint32_t value) { counter_id_ = value; _has_field_.set(1); }
13431 
has_name() const13432   bool has_name() const { return _has_field_[2]; }
name() const13433   const std::string& name() const { return name_; }
set_name(const std::string & value)13434   void set_name(const std::string& value) { name_ = value; _has_field_.set(2); }
13435 
has_description() const13436   bool has_description() const { return _has_field_[3]; }
description() const13437   const std::string& description() const { return description_; }
set_description(const std::string & value)13438   void set_description(const std::string& value) { description_ = value; _has_field_.set(3); }
13439 
has_int_peak_value() const13440   bool has_int_peak_value() const { return _has_field_[5]; }
int_peak_value() const13441   int64_t int_peak_value() const { return int_peak_value_; }
set_int_peak_value(int64_t value)13442   void set_int_peak_value(int64_t value) { int_peak_value_ = value; _has_field_.set(5); }
13443 
has_double_peak_value() const13444   bool has_double_peak_value() const { return _has_field_[6]; }
double_peak_value() const13445   double double_peak_value() const { return double_peak_value_; }
set_double_peak_value(double value)13446   void set_double_peak_value(double value) { double_peak_value_ = value; _has_field_.set(6); }
13447 
numerator_units() const13448   const std::vector<GpuCounterDescriptor_MeasureUnit>& numerator_units() const { return numerator_units_; }
mutable_numerator_units()13449   std::vector<GpuCounterDescriptor_MeasureUnit>* mutable_numerator_units() { return &numerator_units_; }
numerator_units_size() const13450   int numerator_units_size() const { return static_cast<int>(numerator_units_.size()); }
clear_numerator_units()13451   void clear_numerator_units() { numerator_units_.clear(); }
add_numerator_units(GpuCounterDescriptor_MeasureUnit value)13452   void add_numerator_units(GpuCounterDescriptor_MeasureUnit value) { numerator_units_.emplace_back(value); }
add_numerator_units()13453   GpuCounterDescriptor_MeasureUnit* add_numerator_units() { numerator_units_.emplace_back(); return &numerator_units_.back(); }
13454 
denominator_units() const13455   const std::vector<GpuCounterDescriptor_MeasureUnit>& denominator_units() const { return denominator_units_; }
mutable_denominator_units()13456   std::vector<GpuCounterDescriptor_MeasureUnit>* mutable_denominator_units() { return &denominator_units_; }
denominator_units_size() const13457   int denominator_units_size() const { return static_cast<int>(denominator_units_.size()); }
clear_denominator_units()13458   void clear_denominator_units() { denominator_units_.clear(); }
add_denominator_units(GpuCounterDescriptor_MeasureUnit value)13459   void add_denominator_units(GpuCounterDescriptor_MeasureUnit value) { denominator_units_.emplace_back(value); }
add_denominator_units()13460   GpuCounterDescriptor_MeasureUnit* add_denominator_units() { denominator_units_.emplace_back(); return &denominator_units_.back(); }
13461 
has_select_by_default() const13462   bool has_select_by_default() const { return _has_field_[9]; }
select_by_default() const13463   bool select_by_default() const { return select_by_default_; }
set_select_by_default(bool value)13464   void set_select_by_default(bool value) { select_by_default_ = value; _has_field_.set(9); }
13465 
groups() const13466   const std::vector<GpuCounterDescriptor_GpuCounterGroup>& groups() const { return groups_; }
mutable_groups()13467   std::vector<GpuCounterDescriptor_GpuCounterGroup>* mutable_groups() { return &groups_; }
groups_size() const13468   int groups_size() const { return static_cast<int>(groups_.size()); }
clear_groups()13469   void clear_groups() { groups_.clear(); }
add_groups(GpuCounterDescriptor_GpuCounterGroup value)13470   void add_groups(GpuCounterDescriptor_GpuCounterGroup value) { groups_.emplace_back(value); }
add_groups()13471   GpuCounterDescriptor_GpuCounterGroup* add_groups() { groups_.emplace_back(); return &groups_.back(); }
13472 
13473  private:
13474   uint32_t counter_id_{};
13475   std::string name_{};
13476   std::string description_{};
13477   int64_t int_peak_value_{};
13478   double double_peak_value_{};
13479   std::vector<GpuCounterDescriptor_MeasureUnit> numerator_units_;
13480   std::vector<GpuCounterDescriptor_MeasureUnit> denominator_units_;
13481   bool select_by_default_{};
13482   std::vector<GpuCounterDescriptor_GpuCounterGroup> groups_;
13483 
13484   // Allows to preserve unknown protobuf fields for compatibility
13485   // with future versions of .proto files.
13486   std::string unknown_fields_;
13487 
13488   std::bitset<11> _has_field_{};
13489 };
13490 
13491 }  // namespace perfetto
13492 }  // namespace protos
13493 }  // namespace gen
13494 
13495 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_GPU_COUNTER_DESCRIPTOR_PROTO_CPP_H_
13496 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
13497 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
13498 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
13499 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
13500 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
13501 #if defined(__GNUC__) || defined(__clang__)
13502 #pragma GCC diagnostic push
13503 #pragma GCC diagnostic ignored "-Wfloat-equal"
13504 #endif
13505 // gen_amalgamated expanded: #include "protos/perfetto/common/gpu_counter_descriptor.gen.h"
13506 
13507 namespace perfetto {
13508 namespace protos {
13509 namespace gen {
13510 
13511 GpuCounterDescriptor::GpuCounterDescriptor() = default;
13512 GpuCounterDescriptor::~GpuCounterDescriptor() = default;
13513 GpuCounterDescriptor::GpuCounterDescriptor(const GpuCounterDescriptor&) = default;
13514 GpuCounterDescriptor& GpuCounterDescriptor::operator=(const GpuCounterDescriptor&) = default;
13515 GpuCounterDescriptor::GpuCounterDescriptor(GpuCounterDescriptor&&) noexcept = default;
13516 GpuCounterDescriptor& GpuCounterDescriptor::operator=(GpuCounterDescriptor&&) = default;
13517 
operator ==(const GpuCounterDescriptor & other) const13518 bool GpuCounterDescriptor::operator==(const GpuCounterDescriptor& other) const {
13519   return unknown_fields_ == other.unknown_fields_
13520    && specs_ == other.specs_
13521    && blocks_ == other.blocks_
13522    && min_sampling_period_ns_ == other.min_sampling_period_ns_
13523    && max_sampling_period_ns_ == other.max_sampling_period_ns_
13524    && supports_instrumented_sampling_ == other.supports_instrumented_sampling_;
13525 }
13526 
specs_size() const13527 int GpuCounterDescriptor::specs_size() const { return static_cast<int>(specs_.size()); }
clear_specs()13528 void GpuCounterDescriptor::clear_specs() { specs_.clear(); }
add_specs()13529 GpuCounterDescriptor_GpuCounterSpec* GpuCounterDescriptor::add_specs() { specs_.emplace_back(); return &specs_.back(); }
blocks_size() const13530 int GpuCounterDescriptor::blocks_size() const { return static_cast<int>(blocks_.size()); }
clear_blocks()13531 void GpuCounterDescriptor::clear_blocks() { blocks_.clear(); }
add_blocks()13532 GpuCounterDescriptor_GpuCounterBlock* GpuCounterDescriptor::add_blocks() { blocks_.emplace_back(); return &blocks_.back(); }
ParseFromArray(const void * raw,size_t size)13533 bool GpuCounterDescriptor::ParseFromArray(const void* raw, size_t size) {
13534   specs_.clear();
13535   blocks_.clear();
13536   unknown_fields_.clear();
13537   bool packed_error = false;
13538 
13539   ::protozero::ProtoDecoder dec(raw, size);
13540   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
13541     if (field.id() < _has_field_.size()) {
13542       _has_field_.set(field.id());
13543     }
13544     switch (field.id()) {
13545       case 1 /* specs */:
13546         specs_.emplace_back();
13547         specs_.back().ParseFromArray(field.data(), field.size());
13548         break;
13549       case 2 /* blocks */:
13550         blocks_.emplace_back();
13551         blocks_.back().ParseFromArray(field.data(), field.size());
13552         break;
13553       case 3 /* min_sampling_period_ns */:
13554         field.get(&min_sampling_period_ns_);
13555         break;
13556       case 4 /* max_sampling_period_ns */:
13557         field.get(&max_sampling_period_ns_);
13558         break;
13559       case 5 /* supports_instrumented_sampling */:
13560         field.get(&supports_instrumented_sampling_);
13561         break;
13562       default:
13563         field.SerializeAndAppendTo(&unknown_fields_);
13564         break;
13565     }
13566   }
13567   return !packed_error && !dec.bytes_left();
13568 }
13569 
SerializeAsString() const13570 std::string GpuCounterDescriptor::SerializeAsString() const {
13571   ::protozero::HeapBuffered<::protozero::Message> msg;
13572   Serialize(msg.get());
13573   return msg.SerializeAsString();
13574 }
13575 
SerializeAsArray() const13576 std::vector<uint8_t> GpuCounterDescriptor::SerializeAsArray() const {
13577   ::protozero::HeapBuffered<::protozero::Message> msg;
13578   Serialize(msg.get());
13579   return msg.SerializeAsArray();
13580 }
13581 
Serialize(::protozero::Message * msg) const13582 void GpuCounterDescriptor::Serialize(::protozero::Message* msg) const {
13583   // Field 1: specs
13584   for (auto& it : specs_) {
13585     it.Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
13586   }
13587 
13588   // Field 2: blocks
13589   for (auto& it : blocks_) {
13590     it.Serialize(msg->BeginNestedMessage<::protozero::Message>(2));
13591   }
13592 
13593   // Field 3: min_sampling_period_ns
13594   if (_has_field_[3]) {
13595     msg->AppendVarInt(3, min_sampling_period_ns_);
13596   }
13597 
13598   // Field 4: max_sampling_period_ns
13599   if (_has_field_[4]) {
13600     msg->AppendVarInt(4, max_sampling_period_ns_);
13601   }
13602 
13603   // Field 5: supports_instrumented_sampling
13604   if (_has_field_[5]) {
13605     msg->AppendTinyVarInt(5, supports_instrumented_sampling_);
13606   }
13607 
13608   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
13609 }
13610 
13611 
13612 GpuCounterDescriptor_GpuCounterBlock::GpuCounterDescriptor_GpuCounterBlock() = default;
13613 GpuCounterDescriptor_GpuCounterBlock::~GpuCounterDescriptor_GpuCounterBlock() = default;
13614 GpuCounterDescriptor_GpuCounterBlock::GpuCounterDescriptor_GpuCounterBlock(const GpuCounterDescriptor_GpuCounterBlock&) = default;
13615 GpuCounterDescriptor_GpuCounterBlock& GpuCounterDescriptor_GpuCounterBlock::operator=(const GpuCounterDescriptor_GpuCounterBlock&) = default;
13616 GpuCounterDescriptor_GpuCounterBlock::GpuCounterDescriptor_GpuCounterBlock(GpuCounterDescriptor_GpuCounterBlock&&) noexcept = default;
13617 GpuCounterDescriptor_GpuCounterBlock& GpuCounterDescriptor_GpuCounterBlock::operator=(GpuCounterDescriptor_GpuCounterBlock&&) = default;
13618 
operator ==(const GpuCounterDescriptor_GpuCounterBlock & other) const13619 bool GpuCounterDescriptor_GpuCounterBlock::operator==(const GpuCounterDescriptor_GpuCounterBlock& other) const {
13620   return unknown_fields_ == other.unknown_fields_
13621    && block_id_ == other.block_id_
13622    && block_capacity_ == other.block_capacity_
13623    && name_ == other.name_
13624    && description_ == other.description_
13625    && counter_ids_ == other.counter_ids_;
13626 }
13627 
ParseFromArray(const void * raw,size_t size)13628 bool GpuCounterDescriptor_GpuCounterBlock::ParseFromArray(const void* raw, size_t size) {
13629   counter_ids_.clear();
13630   unknown_fields_.clear();
13631   bool packed_error = false;
13632 
13633   ::protozero::ProtoDecoder dec(raw, size);
13634   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
13635     if (field.id() < _has_field_.size()) {
13636       _has_field_.set(field.id());
13637     }
13638     switch (field.id()) {
13639       case 1 /* block_id */:
13640         field.get(&block_id_);
13641         break;
13642       case 2 /* block_capacity */:
13643         field.get(&block_capacity_);
13644         break;
13645       case 3 /* name */:
13646         field.get(&name_);
13647         break;
13648       case 4 /* description */:
13649         field.get(&description_);
13650         break;
13651       case 5 /* counter_ids */:
13652         counter_ids_.emplace_back();
13653         field.get(&counter_ids_.back());
13654         break;
13655       default:
13656         field.SerializeAndAppendTo(&unknown_fields_);
13657         break;
13658     }
13659   }
13660   return !packed_error && !dec.bytes_left();
13661 }
13662 
SerializeAsString() const13663 std::string GpuCounterDescriptor_GpuCounterBlock::SerializeAsString() const {
13664   ::protozero::HeapBuffered<::protozero::Message> msg;
13665   Serialize(msg.get());
13666   return msg.SerializeAsString();
13667 }
13668 
SerializeAsArray() const13669 std::vector<uint8_t> GpuCounterDescriptor_GpuCounterBlock::SerializeAsArray() const {
13670   ::protozero::HeapBuffered<::protozero::Message> msg;
13671   Serialize(msg.get());
13672   return msg.SerializeAsArray();
13673 }
13674 
Serialize(::protozero::Message * msg) const13675 void GpuCounterDescriptor_GpuCounterBlock::Serialize(::protozero::Message* msg) const {
13676   // Field 1: block_id
13677   if (_has_field_[1]) {
13678     msg->AppendVarInt(1, block_id_);
13679   }
13680 
13681   // Field 2: block_capacity
13682   if (_has_field_[2]) {
13683     msg->AppendVarInt(2, block_capacity_);
13684   }
13685 
13686   // Field 3: name
13687   if (_has_field_[3]) {
13688     msg->AppendString(3, name_);
13689   }
13690 
13691   // Field 4: description
13692   if (_has_field_[4]) {
13693     msg->AppendString(4, description_);
13694   }
13695 
13696   // Field 5: counter_ids
13697   for (auto& it : counter_ids_) {
13698     msg->AppendVarInt(5, it);
13699   }
13700 
13701   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
13702 }
13703 
13704 
13705 GpuCounterDescriptor_GpuCounterSpec::GpuCounterDescriptor_GpuCounterSpec() = default;
13706 GpuCounterDescriptor_GpuCounterSpec::~GpuCounterDescriptor_GpuCounterSpec() = default;
13707 GpuCounterDescriptor_GpuCounterSpec::GpuCounterDescriptor_GpuCounterSpec(const GpuCounterDescriptor_GpuCounterSpec&) = default;
13708 GpuCounterDescriptor_GpuCounterSpec& GpuCounterDescriptor_GpuCounterSpec::operator=(const GpuCounterDescriptor_GpuCounterSpec&) = default;
13709 GpuCounterDescriptor_GpuCounterSpec::GpuCounterDescriptor_GpuCounterSpec(GpuCounterDescriptor_GpuCounterSpec&&) noexcept = default;
13710 GpuCounterDescriptor_GpuCounterSpec& GpuCounterDescriptor_GpuCounterSpec::operator=(GpuCounterDescriptor_GpuCounterSpec&&) = default;
13711 
operator ==(const GpuCounterDescriptor_GpuCounterSpec & other) const13712 bool GpuCounterDescriptor_GpuCounterSpec::operator==(const GpuCounterDescriptor_GpuCounterSpec& other) const {
13713   return unknown_fields_ == other.unknown_fields_
13714    && counter_id_ == other.counter_id_
13715    && name_ == other.name_
13716    && description_ == other.description_
13717    && int_peak_value_ == other.int_peak_value_
13718    && double_peak_value_ == other.double_peak_value_
13719    && numerator_units_ == other.numerator_units_
13720    && denominator_units_ == other.denominator_units_
13721    && select_by_default_ == other.select_by_default_
13722    && groups_ == other.groups_;
13723 }
13724 
ParseFromArray(const void * raw,size_t size)13725 bool GpuCounterDescriptor_GpuCounterSpec::ParseFromArray(const void* raw, size_t size) {
13726   numerator_units_.clear();
13727   denominator_units_.clear();
13728   groups_.clear();
13729   unknown_fields_.clear();
13730   bool packed_error = false;
13731 
13732   ::protozero::ProtoDecoder dec(raw, size);
13733   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
13734     if (field.id() < _has_field_.size()) {
13735       _has_field_.set(field.id());
13736     }
13737     switch (field.id()) {
13738       case 1 /* counter_id */:
13739         field.get(&counter_id_);
13740         break;
13741       case 2 /* name */:
13742         field.get(&name_);
13743         break;
13744       case 3 /* description */:
13745         field.get(&description_);
13746         break;
13747       case 5 /* int_peak_value */:
13748         field.get(&int_peak_value_);
13749         break;
13750       case 6 /* double_peak_value */:
13751         field.get(&double_peak_value_);
13752         break;
13753       case 7 /* numerator_units */:
13754         numerator_units_.emplace_back();
13755         field.get(&numerator_units_.back());
13756         break;
13757       case 8 /* denominator_units */:
13758         denominator_units_.emplace_back();
13759         field.get(&denominator_units_.back());
13760         break;
13761       case 9 /* select_by_default */:
13762         field.get(&select_by_default_);
13763         break;
13764       case 10 /* groups */:
13765         groups_.emplace_back();
13766         field.get(&groups_.back());
13767         break;
13768       default:
13769         field.SerializeAndAppendTo(&unknown_fields_);
13770         break;
13771     }
13772   }
13773   return !packed_error && !dec.bytes_left();
13774 }
13775 
SerializeAsString() const13776 std::string GpuCounterDescriptor_GpuCounterSpec::SerializeAsString() const {
13777   ::protozero::HeapBuffered<::protozero::Message> msg;
13778   Serialize(msg.get());
13779   return msg.SerializeAsString();
13780 }
13781 
SerializeAsArray() const13782 std::vector<uint8_t> GpuCounterDescriptor_GpuCounterSpec::SerializeAsArray() const {
13783   ::protozero::HeapBuffered<::protozero::Message> msg;
13784   Serialize(msg.get());
13785   return msg.SerializeAsArray();
13786 }
13787 
Serialize(::protozero::Message * msg) const13788 void GpuCounterDescriptor_GpuCounterSpec::Serialize(::protozero::Message* msg) const {
13789   // Field 1: counter_id
13790   if (_has_field_[1]) {
13791     msg->AppendVarInt(1, counter_id_);
13792   }
13793 
13794   // Field 2: name
13795   if (_has_field_[2]) {
13796     msg->AppendString(2, name_);
13797   }
13798 
13799   // Field 3: description
13800   if (_has_field_[3]) {
13801     msg->AppendString(3, description_);
13802   }
13803 
13804   // Field 5: int_peak_value
13805   if (_has_field_[5]) {
13806     msg->AppendVarInt(5, int_peak_value_);
13807   }
13808 
13809   // Field 6: double_peak_value
13810   if (_has_field_[6]) {
13811     msg->AppendFixed(6, double_peak_value_);
13812   }
13813 
13814   // Field 7: numerator_units
13815   for (auto& it : numerator_units_) {
13816     msg->AppendVarInt(7, it);
13817   }
13818 
13819   // Field 8: denominator_units
13820   for (auto& it : denominator_units_) {
13821     msg->AppendVarInt(8, it);
13822   }
13823 
13824   // Field 9: select_by_default
13825   if (_has_field_[9]) {
13826     msg->AppendTinyVarInt(9, select_by_default_);
13827   }
13828 
13829   // Field 10: groups
13830   for (auto& it : groups_) {
13831     msg->AppendVarInt(10, it);
13832   }
13833 
13834   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
13835 }
13836 
13837 }  // namespace perfetto
13838 }  // namespace protos
13839 }  // namespace gen
13840 #if defined(__GNUC__) || defined(__clang__)
13841 #pragma GCC diagnostic pop
13842 #endif
13843 // gen_amalgamated begin source: gen/protos/perfetto/common/interceptor_descriptor.gen.cc
13844 // gen_amalgamated begin header: gen/protos/perfetto/common/interceptor_descriptor.gen.h
13845 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
13846 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_INTERCEPTOR_DESCRIPTOR_PROTO_CPP_H_
13847 #define PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_INTERCEPTOR_DESCRIPTOR_PROTO_CPP_H_
13848 
13849 #include <stdint.h>
13850 #include <bitset>
13851 #include <vector>
13852 #include <string>
13853 #include <type_traits>
13854 
13855 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
13856 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
13857 // gen_amalgamated expanded: #include "perfetto/base/export.h"
13858 
13859 namespace perfetto {
13860 namespace protos {
13861 namespace gen {
13862 class InterceptorDescriptor;
13863 }  // namespace perfetto
13864 }  // namespace protos
13865 }  // namespace gen
13866 
13867 namespace protozero {
13868 class Message;
13869 }  // namespace protozero
13870 
13871 namespace perfetto {
13872 namespace protos {
13873 namespace gen {
13874 
13875 class PERFETTO_EXPORT InterceptorDescriptor : public ::protozero::CppMessageObj {
13876  public:
13877   enum FieldNumbers {
13878     kNameFieldNumber = 1,
13879   };
13880 
13881   InterceptorDescriptor();
13882   ~InterceptorDescriptor() override;
13883   InterceptorDescriptor(InterceptorDescriptor&&) noexcept;
13884   InterceptorDescriptor& operator=(InterceptorDescriptor&&);
13885   InterceptorDescriptor(const InterceptorDescriptor&);
13886   InterceptorDescriptor& operator=(const InterceptorDescriptor&);
13887   bool operator==(const InterceptorDescriptor&) const;
operator !=(const InterceptorDescriptor & other) const13888   bool operator!=(const InterceptorDescriptor& other) const { return !(*this == other); }
13889 
13890   bool ParseFromArray(const void*, size_t) override;
13891   std::string SerializeAsString() const override;
13892   std::vector<uint8_t> SerializeAsArray() const override;
13893   void Serialize(::protozero::Message*) const;
13894 
has_name() const13895   bool has_name() const { return _has_field_[1]; }
name() const13896   const std::string& name() const { return name_; }
set_name(const std::string & value)13897   void set_name(const std::string& value) { name_ = value; _has_field_.set(1); }
13898 
13899  private:
13900   std::string name_{};
13901 
13902   // Allows to preserve unknown protobuf fields for compatibility
13903   // with future versions of .proto files.
13904   std::string unknown_fields_;
13905 
13906   std::bitset<2> _has_field_{};
13907 };
13908 
13909 }  // namespace perfetto
13910 }  // namespace protos
13911 }  // namespace gen
13912 
13913 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_INTERCEPTOR_DESCRIPTOR_PROTO_CPP_H_
13914 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
13915 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
13916 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
13917 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
13918 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
13919 #if defined(__GNUC__) || defined(__clang__)
13920 #pragma GCC diagnostic push
13921 #pragma GCC diagnostic ignored "-Wfloat-equal"
13922 #endif
13923 // gen_amalgamated expanded: #include "protos/perfetto/common/interceptor_descriptor.gen.h"
13924 
13925 namespace perfetto {
13926 namespace protos {
13927 namespace gen {
13928 
13929 InterceptorDescriptor::InterceptorDescriptor() = default;
13930 InterceptorDescriptor::~InterceptorDescriptor() = default;
13931 InterceptorDescriptor::InterceptorDescriptor(const InterceptorDescriptor&) = default;
13932 InterceptorDescriptor& InterceptorDescriptor::operator=(const InterceptorDescriptor&) = default;
13933 InterceptorDescriptor::InterceptorDescriptor(InterceptorDescriptor&&) noexcept = default;
13934 InterceptorDescriptor& InterceptorDescriptor::operator=(InterceptorDescriptor&&) = default;
13935 
operator ==(const InterceptorDescriptor & other) const13936 bool InterceptorDescriptor::operator==(const InterceptorDescriptor& other) const {
13937   return unknown_fields_ == other.unknown_fields_
13938    && name_ == other.name_;
13939 }
13940 
ParseFromArray(const void * raw,size_t size)13941 bool InterceptorDescriptor::ParseFromArray(const void* raw, size_t size) {
13942   unknown_fields_.clear();
13943   bool packed_error = false;
13944 
13945   ::protozero::ProtoDecoder dec(raw, size);
13946   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
13947     if (field.id() < _has_field_.size()) {
13948       _has_field_.set(field.id());
13949     }
13950     switch (field.id()) {
13951       case 1 /* name */:
13952         field.get(&name_);
13953         break;
13954       default:
13955         field.SerializeAndAppendTo(&unknown_fields_);
13956         break;
13957     }
13958   }
13959   return !packed_error && !dec.bytes_left();
13960 }
13961 
SerializeAsString() const13962 std::string InterceptorDescriptor::SerializeAsString() const {
13963   ::protozero::HeapBuffered<::protozero::Message> msg;
13964   Serialize(msg.get());
13965   return msg.SerializeAsString();
13966 }
13967 
SerializeAsArray() const13968 std::vector<uint8_t> InterceptorDescriptor::SerializeAsArray() const {
13969   ::protozero::HeapBuffered<::protozero::Message> msg;
13970   Serialize(msg.get());
13971   return msg.SerializeAsArray();
13972 }
13973 
Serialize(::protozero::Message * msg) const13974 void InterceptorDescriptor::Serialize(::protozero::Message* msg) const {
13975   // Field 1: name
13976   if (_has_field_[1]) {
13977     msg->AppendString(1, name_);
13978   }
13979 
13980   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
13981 }
13982 
13983 }  // namespace perfetto
13984 }  // namespace protos
13985 }  // namespace gen
13986 #if defined(__GNUC__) || defined(__clang__)
13987 #pragma GCC diagnostic pop
13988 #endif
13989 // gen_amalgamated begin source: gen/protos/perfetto/common/observable_events.gen.cc
13990 // gen_amalgamated begin header: gen/protos/perfetto/common/observable_events.gen.h
13991 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
13992 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_OBSERVABLE_EVENTS_PROTO_CPP_H_
13993 #define PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_OBSERVABLE_EVENTS_PROTO_CPP_H_
13994 
13995 #include <stdint.h>
13996 #include <bitset>
13997 #include <vector>
13998 #include <string>
13999 #include <type_traits>
14000 
14001 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
14002 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
14003 // gen_amalgamated expanded: #include "perfetto/base/export.h"
14004 
14005 namespace perfetto {
14006 namespace protos {
14007 namespace gen {
14008 class ObservableEvents;
14009 class ObservableEvents_DataSourceInstanceStateChange;
14010 enum ObservableEvents_Type : int;
14011 enum ObservableEvents_DataSourceInstanceState : int;
14012 }  // namespace perfetto
14013 }  // namespace protos
14014 }  // namespace gen
14015 
14016 namespace protozero {
14017 class Message;
14018 }  // namespace protozero
14019 
14020 namespace perfetto {
14021 namespace protos {
14022 namespace gen {
14023 enum ObservableEvents_Type : int {
14024   ObservableEvents_Type_TYPE_UNSPECIFIED = 0,
14025   ObservableEvents_Type_TYPE_DATA_SOURCES_INSTANCES = 1,
14026   ObservableEvents_Type_TYPE_ALL_DATA_SOURCES_STARTED = 2,
14027 };
14028 enum ObservableEvents_DataSourceInstanceState : int {
14029   ObservableEvents_DataSourceInstanceState_DATA_SOURCE_INSTANCE_STATE_STOPPED = 1,
14030   ObservableEvents_DataSourceInstanceState_DATA_SOURCE_INSTANCE_STATE_STARTED = 2,
14031 };
14032 
14033 class PERFETTO_EXPORT ObservableEvents : public ::protozero::CppMessageObj {
14034  public:
14035   using DataSourceInstanceStateChange = ObservableEvents_DataSourceInstanceStateChange;
14036   using Type = ObservableEvents_Type;
14037   static constexpr auto TYPE_UNSPECIFIED = ObservableEvents_Type_TYPE_UNSPECIFIED;
14038   static constexpr auto TYPE_DATA_SOURCES_INSTANCES = ObservableEvents_Type_TYPE_DATA_SOURCES_INSTANCES;
14039   static constexpr auto TYPE_ALL_DATA_SOURCES_STARTED = ObservableEvents_Type_TYPE_ALL_DATA_SOURCES_STARTED;
14040   static constexpr auto Type_MIN = ObservableEvents_Type_TYPE_UNSPECIFIED;
14041   static constexpr auto Type_MAX = ObservableEvents_Type_TYPE_ALL_DATA_SOURCES_STARTED;
14042   using DataSourceInstanceState = ObservableEvents_DataSourceInstanceState;
14043   static constexpr auto DATA_SOURCE_INSTANCE_STATE_STOPPED = ObservableEvents_DataSourceInstanceState_DATA_SOURCE_INSTANCE_STATE_STOPPED;
14044   static constexpr auto DATA_SOURCE_INSTANCE_STATE_STARTED = ObservableEvents_DataSourceInstanceState_DATA_SOURCE_INSTANCE_STATE_STARTED;
14045   static constexpr auto DataSourceInstanceState_MIN = ObservableEvents_DataSourceInstanceState_DATA_SOURCE_INSTANCE_STATE_STOPPED;
14046   static constexpr auto DataSourceInstanceState_MAX = ObservableEvents_DataSourceInstanceState_DATA_SOURCE_INSTANCE_STATE_STARTED;
14047   enum FieldNumbers {
14048     kInstanceStateChangesFieldNumber = 1,
14049     kAllDataSourcesStartedFieldNumber = 2,
14050   };
14051 
14052   ObservableEvents();
14053   ~ObservableEvents() override;
14054   ObservableEvents(ObservableEvents&&) noexcept;
14055   ObservableEvents& operator=(ObservableEvents&&);
14056   ObservableEvents(const ObservableEvents&);
14057   ObservableEvents& operator=(const ObservableEvents&);
14058   bool operator==(const ObservableEvents&) const;
operator !=(const ObservableEvents & other) const14059   bool operator!=(const ObservableEvents& other) const { return !(*this == other); }
14060 
14061   bool ParseFromArray(const void*, size_t) override;
14062   std::string SerializeAsString() const override;
14063   std::vector<uint8_t> SerializeAsArray() const override;
14064   void Serialize(::protozero::Message*) const;
14065 
instance_state_changes() const14066   const std::vector<ObservableEvents_DataSourceInstanceStateChange>& instance_state_changes() const { return instance_state_changes_; }
mutable_instance_state_changes()14067   std::vector<ObservableEvents_DataSourceInstanceStateChange>* mutable_instance_state_changes() { return &instance_state_changes_; }
14068   int instance_state_changes_size() const;
14069   void clear_instance_state_changes();
14070   ObservableEvents_DataSourceInstanceStateChange* add_instance_state_changes();
14071 
has_all_data_sources_started() const14072   bool has_all_data_sources_started() const { return _has_field_[2]; }
all_data_sources_started() const14073   bool all_data_sources_started() const { return all_data_sources_started_; }
set_all_data_sources_started(bool value)14074   void set_all_data_sources_started(bool value) { all_data_sources_started_ = value; _has_field_.set(2); }
14075 
14076  private:
14077   std::vector<ObservableEvents_DataSourceInstanceStateChange> instance_state_changes_;
14078   bool all_data_sources_started_{};
14079 
14080   // Allows to preserve unknown protobuf fields for compatibility
14081   // with future versions of .proto files.
14082   std::string unknown_fields_;
14083 
14084   std::bitset<3> _has_field_{};
14085 };
14086 
14087 
14088 class PERFETTO_EXPORT ObservableEvents_DataSourceInstanceStateChange : public ::protozero::CppMessageObj {
14089  public:
14090   enum FieldNumbers {
14091     kProducerNameFieldNumber = 1,
14092     kDataSourceNameFieldNumber = 2,
14093     kStateFieldNumber = 3,
14094   };
14095 
14096   ObservableEvents_DataSourceInstanceStateChange();
14097   ~ObservableEvents_DataSourceInstanceStateChange() override;
14098   ObservableEvents_DataSourceInstanceStateChange(ObservableEvents_DataSourceInstanceStateChange&&) noexcept;
14099   ObservableEvents_DataSourceInstanceStateChange& operator=(ObservableEvents_DataSourceInstanceStateChange&&);
14100   ObservableEvents_DataSourceInstanceStateChange(const ObservableEvents_DataSourceInstanceStateChange&);
14101   ObservableEvents_DataSourceInstanceStateChange& operator=(const ObservableEvents_DataSourceInstanceStateChange&);
14102   bool operator==(const ObservableEvents_DataSourceInstanceStateChange&) const;
operator !=(const ObservableEvents_DataSourceInstanceStateChange & other) const14103   bool operator!=(const ObservableEvents_DataSourceInstanceStateChange& other) const { return !(*this == other); }
14104 
14105   bool ParseFromArray(const void*, size_t) override;
14106   std::string SerializeAsString() const override;
14107   std::vector<uint8_t> SerializeAsArray() const override;
14108   void Serialize(::protozero::Message*) const;
14109 
has_producer_name() const14110   bool has_producer_name() const { return _has_field_[1]; }
producer_name() const14111   const std::string& producer_name() const { return producer_name_; }
set_producer_name(const std::string & value)14112   void set_producer_name(const std::string& value) { producer_name_ = value; _has_field_.set(1); }
14113 
has_data_source_name() const14114   bool has_data_source_name() const { return _has_field_[2]; }
data_source_name() const14115   const std::string& data_source_name() const { return data_source_name_; }
set_data_source_name(const std::string & value)14116   void set_data_source_name(const std::string& value) { data_source_name_ = value; _has_field_.set(2); }
14117 
has_state() const14118   bool has_state() const { return _has_field_[3]; }
state() const14119   ObservableEvents_DataSourceInstanceState state() const { return state_; }
set_state(ObservableEvents_DataSourceInstanceState value)14120   void set_state(ObservableEvents_DataSourceInstanceState value) { state_ = value; _has_field_.set(3); }
14121 
14122  private:
14123   std::string producer_name_{};
14124   std::string data_source_name_{};
14125   ObservableEvents_DataSourceInstanceState state_{};
14126 
14127   // Allows to preserve unknown protobuf fields for compatibility
14128   // with future versions of .proto files.
14129   std::string unknown_fields_;
14130 
14131   std::bitset<4> _has_field_{};
14132 };
14133 
14134 }  // namespace perfetto
14135 }  // namespace protos
14136 }  // namespace gen
14137 
14138 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_OBSERVABLE_EVENTS_PROTO_CPP_H_
14139 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
14140 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
14141 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
14142 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
14143 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
14144 #if defined(__GNUC__) || defined(__clang__)
14145 #pragma GCC diagnostic push
14146 #pragma GCC diagnostic ignored "-Wfloat-equal"
14147 #endif
14148 // gen_amalgamated expanded: #include "protos/perfetto/common/observable_events.gen.h"
14149 
14150 namespace perfetto {
14151 namespace protos {
14152 namespace gen {
14153 
14154 ObservableEvents::ObservableEvents() = default;
14155 ObservableEvents::~ObservableEvents() = default;
14156 ObservableEvents::ObservableEvents(const ObservableEvents&) = default;
14157 ObservableEvents& ObservableEvents::operator=(const ObservableEvents&) = default;
14158 ObservableEvents::ObservableEvents(ObservableEvents&&) noexcept = default;
14159 ObservableEvents& ObservableEvents::operator=(ObservableEvents&&) = default;
14160 
operator ==(const ObservableEvents & other) const14161 bool ObservableEvents::operator==(const ObservableEvents& other) const {
14162   return unknown_fields_ == other.unknown_fields_
14163    && instance_state_changes_ == other.instance_state_changes_
14164    && all_data_sources_started_ == other.all_data_sources_started_;
14165 }
14166 
instance_state_changes_size() const14167 int ObservableEvents::instance_state_changes_size() const { return static_cast<int>(instance_state_changes_.size()); }
clear_instance_state_changes()14168 void ObservableEvents::clear_instance_state_changes() { instance_state_changes_.clear(); }
add_instance_state_changes()14169 ObservableEvents_DataSourceInstanceStateChange* ObservableEvents::add_instance_state_changes() { instance_state_changes_.emplace_back(); return &instance_state_changes_.back(); }
ParseFromArray(const void * raw,size_t size)14170 bool ObservableEvents::ParseFromArray(const void* raw, size_t size) {
14171   instance_state_changes_.clear();
14172   unknown_fields_.clear();
14173   bool packed_error = false;
14174 
14175   ::protozero::ProtoDecoder dec(raw, size);
14176   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
14177     if (field.id() < _has_field_.size()) {
14178       _has_field_.set(field.id());
14179     }
14180     switch (field.id()) {
14181       case 1 /* instance_state_changes */:
14182         instance_state_changes_.emplace_back();
14183         instance_state_changes_.back().ParseFromArray(field.data(), field.size());
14184         break;
14185       case 2 /* all_data_sources_started */:
14186         field.get(&all_data_sources_started_);
14187         break;
14188       default:
14189         field.SerializeAndAppendTo(&unknown_fields_);
14190         break;
14191     }
14192   }
14193   return !packed_error && !dec.bytes_left();
14194 }
14195 
SerializeAsString() const14196 std::string ObservableEvents::SerializeAsString() const {
14197   ::protozero::HeapBuffered<::protozero::Message> msg;
14198   Serialize(msg.get());
14199   return msg.SerializeAsString();
14200 }
14201 
SerializeAsArray() const14202 std::vector<uint8_t> ObservableEvents::SerializeAsArray() const {
14203   ::protozero::HeapBuffered<::protozero::Message> msg;
14204   Serialize(msg.get());
14205   return msg.SerializeAsArray();
14206 }
14207 
Serialize(::protozero::Message * msg) const14208 void ObservableEvents::Serialize(::protozero::Message* msg) const {
14209   // Field 1: instance_state_changes
14210   for (auto& it : instance_state_changes_) {
14211     it.Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
14212   }
14213 
14214   // Field 2: all_data_sources_started
14215   if (_has_field_[2]) {
14216     msg->AppendTinyVarInt(2, all_data_sources_started_);
14217   }
14218 
14219   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
14220 }
14221 
14222 
14223 ObservableEvents_DataSourceInstanceStateChange::ObservableEvents_DataSourceInstanceStateChange() = default;
14224 ObservableEvents_DataSourceInstanceStateChange::~ObservableEvents_DataSourceInstanceStateChange() = default;
14225 ObservableEvents_DataSourceInstanceStateChange::ObservableEvents_DataSourceInstanceStateChange(const ObservableEvents_DataSourceInstanceStateChange&) = default;
14226 ObservableEvents_DataSourceInstanceStateChange& ObservableEvents_DataSourceInstanceStateChange::operator=(const ObservableEvents_DataSourceInstanceStateChange&) = default;
14227 ObservableEvents_DataSourceInstanceStateChange::ObservableEvents_DataSourceInstanceStateChange(ObservableEvents_DataSourceInstanceStateChange&&) noexcept = default;
14228 ObservableEvents_DataSourceInstanceStateChange& ObservableEvents_DataSourceInstanceStateChange::operator=(ObservableEvents_DataSourceInstanceStateChange&&) = default;
14229 
operator ==(const ObservableEvents_DataSourceInstanceStateChange & other) const14230 bool ObservableEvents_DataSourceInstanceStateChange::operator==(const ObservableEvents_DataSourceInstanceStateChange& other) const {
14231   return unknown_fields_ == other.unknown_fields_
14232    && producer_name_ == other.producer_name_
14233    && data_source_name_ == other.data_source_name_
14234    && state_ == other.state_;
14235 }
14236 
ParseFromArray(const void * raw,size_t size)14237 bool ObservableEvents_DataSourceInstanceStateChange::ParseFromArray(const void* raw, size_t size) {
14238   unknown_fields_.clear();
14239   bool packed_error = false;
14240 
14241   ::protozero::ProtoDecoder dec(raw, size);
14242   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
14243     if (field.id() < _has_field_.size()) {
14244       _has_field_.set(field.id());
14245     }
14246     switch (field.id()) {
14247       case 1 /* producer_name */:
14248         field.get(&producer_name_);
14249         break;
14250       case 2 /* data_source_name */:
14251         field.get(&data_source_name_);
14252         break;
14253       case 3 /* state */:
14254         field.get(&state_);
14255         break;
14256       default:
14257         field.SerializeAndAppendTo(&unknown_fields_);
14258         break;
14259     }
14260   }
14261   return !packed_error && !dec.bytes_left();
14262 }
14263 
SerializeAsString() const14264 std::string ObservableEvents_DataSourceInstanceStateChange::SerializeAsString() const {
14265   ::protozero::HeapBuffered<::protozero::Message> msg;
14266   Serialize(msg.get());
14267   return msg.SerializeAsString();
14268 }
14269 
SerializeAsArray() const14270 std::vector<uint8_t> ObservableEvents_DataSourceInstanceStateChange::SerializeAsArray() const {
14271   ::protozero::HeapBuffered<::protozero::Message> msg;
14272   Serialize(msg.get());
14273   return msg.SerializeAsArray();
14274 }
14275 
Serialize(::protozero::Message * msg) const14276 void ObservableEvents_DataSourceInstanceStateChange::Serialize(::protozero::Message* msg) const {
14277   // Field 1: producer_name
14278   if (_has_field_[1]) {
14279     msg->AppendString(1, producer_name_);
14280   }
14281 
14282   // Field 2: data_source_name
14283   if (_has_field_[2]) {
14284     msg->AppendString(2, data_source_name_);
14285   }
14286 
14287   // Field 3: state
14288   if (_has_field_[3]) {
14289     msg->AppendVarInt(3, state_);
14290   }
14291 
14292   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
14293 }
14294 
14295 }  // namespace perfetto
14296 }  // namespace protos
14297 }  // namespace gen
14298 #if defined(__GNUC__) || defined(__clang__)
14299 #pragma GCC diagnostic pop
14300 #endif
14301 // gen_amalgamated begin source: gen/protos/perfetto/common/perf_events.gen.cc
14302 // gen_amalgamated begin header: gen/protos/perfetto/common/perf_events.gen.h
14303 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
14304 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_PERF_EVENTS_PROTO_CPP_H_
14305 #define PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_PERF_EVENTS_PROTO_CPP_H_
14306 
14307 #include <stdint.h>
14308 #include <bitset>
14309 #include <vector>
14310 #include <string>
14311 #include <type_traits>
14312 
14313 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
14314 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
14315 // gen_amalgamated expanded: #include "perfetto/base/export.h"
14316 
14317 namespace perfetto {
14318 namespace protos {
14319 namespace gen {
14320 class PerfEvents;
14321 class PerfEvents_RawEvent;
14322 class PerfEvents_Tracepoint;
14323 class PerfEvents_Timebase;
14324 enum PerfEvents_Counter : int;
14325 enum PerfEvents_PerfClock : int;
14326 }  // namespace perfetto
14327 }  // namespace protos
14328 }  // namespace gen
14329 
14330 namespace protozero {
14331 class Message;
14332 }  // namespace protozero
14333 
14334 namespace perfetto {
14335 namespace protos {
14336 namespace gen {
14337 enum PerfEvents_Counter : int {
14338   PerfEvents_Counter_UNKNOWN_COUNTER = 0,
14339   PerfEvents_Counter_SW_CPU_CLOCK = 1,
14340   PerfEvents_Counter_SW_PAGE_FAULTS = 2,
14341   PerfEvents_Counter_HW_CPU_CYCLES = 10,
14342   PerfEvents_Counter_HW_INSTRUCTIONS = 11,
14343 };
14344 enum PerfEvents_PerfClock : int {
14345   PerfEvents_PerfClock_UNKNOWN_PERF_CLOCK = 0,
14346   PerfEvents_PerfClock_PERF_CLOCK_REALTIME = 1,
14347   PerfEvents_PerfClock_PERF_CLOCK_MONOTONIC = 2,
14348   PerfEvents_PerfClock_PERF_CLOCK_MONOTONIC_RAW = 3,
14349   PerfEvents_PerfClock_PERF_CLOCK_BOOTTIME = 4,
14350 };
14351 
14352 class PERFETTO_EXPORT PerfEvents : public ::protozero::CppMessageObj {
14353  public:
14354   using Timebase = PerfEvents_Timebase;
14355   using Tracepoint = PerfEvents_Tracepoint;
14356   using RawEvent = PerfEvents_RawEvent;
14357   using Counter = PerfEvents_Counter;
14358   static constexpr auto UNKNOWN_COUNTER = PerfEvents_Counter_UNKNOWN_COUNTER;
14359   static constexpr auto SW_CPU_CLOCK = PerfEvents_Counter_SW_CPU_CLOCK;
14360   static constexpr auto SW_PAGE_FAULTS = PerfEvents_Counter_SW_PAGE_FAULTS;
14361   static constexpr auto HW_CPU_CYCLES = PerfEvents_Counter_HW_CPU_CYCLES;
14362   static constexpr auto HW_INSTRUCTIONS = PerfEvents_Counter_HW_INSTRUCTIONS;
14363   static constexpr auto Counter_MIN = PerfEvents_Counter_UNKNOWN_COUNTER;
14364   static constexpr auto Counter_MAX = PerfEvents_Counter_HW_INSTRUCTIONS;
14365   using PerfClock = PerfEvents_PerfClock;
14366   static constexpr auto UNKNOWN_PERF_CLOCK = PerfEvents_PerfClock_UNKNOWN_PERF_CLOCK;
14367   static constexpr auto PERF_CLOCK_REALTIME = PerfEvents_PerfClock_PERF_CLOCK_REALTIME;
14368   static constexpr auto PERF_CLOCK_MONOTONIC = PerfEvents_PerfClock_PERF_CLOCK_MONOTONIC;
14369   static constexpr auto PERF_CLOCK_MONOTONIC_RAW = PerfEvents_PerfClock_PERF_CLOCK_MONOTONIC_RAW;
14370   static constexpr auto PERF_CLOCK_BOOTTIME = PerfEvents_PerfClock_PERF_CLOCK_BOOTTIME;
14371   static constexpr auto PerfClock_MIN = PerfEvents_PerfClock_UNKNOWN_PERF_CLOCK;
14372   static constexpr auto PerfClock_MAX = PerfEvents_PerfClock_PERF_CLOCK_BOOTTIME;
14373   enum FieldNumbers {
14374   };
14375 
14376   PerfEvents();
14377   ~PerfEvents() override;
14378   PerfEvents(PerfEvents&&) noexcept;
14379   PerfEvents& operator=(PerfEvents&&);
14380   PerfEvents(const PerfEvents&);
14381   PerfEvents& operator=(const PerfEvents&);
14382   bool operator==(const PerfEvents&) const;
operator !=(const PerfEvents & other) const14383   bool operator!=(const PerfEvents& other) const { return !(*this == other); }
14384 
14385   bool ParseFromArray(const void*, size_t) override;
14386   std::string SerializeAsString() const override;
14387   std::vector<uint8_t> SerializeAsArray() const override;
14388   void Serialize(::protozero::Message*) const;
14389 
14390  private:
14391 
14392   // Allows to preserve unknown protobuf fields for compatibility
14393   // with future versions of .proto files.
14394   std::string unknown_fields_;
14395 
14396   std::bitset<2> _has_field_{};
14397 };
14398 
14399 
14400 class PERFETTO_EXPORT PerfEvents_RawEvent : public ::protozero::CppMessageObj {
14401  public:
14402   enum FieldNumbers {
14403     kTypeFieldNumber = 1,
14404     kConfigFieldNumber = 2,
14405     kConfig1FieldNumber = 3,
14406     kConfig2FieldNumber = 4,
14407   };
14408 
14409   PerfEvents_RawEvent();
14410   ~PerfEvents_RawEvent() override;
14411   PerfEvents_RawEvent(PerfEvents_RawEvent&&) noexcept;
14412   PerfEvents_RawEvent& operator=(PerfEvents_RawEvent&&);
14413   PerfEvents_RawEvent(const PerfEvents_RawEvent&);
14414   PerfEvents_RawEvent& operator=(const PerfEvents_RawEvent&);
14415   bool operator==(const PerfEvents_RawEvent&) const;
operator !=(const PerfEvents_RawEvent & other) const14416   bool operator!=(const PerfEvents_RawEvent& other) const { return !(*this == other); }
14417 
14418   bool ParseFromArray(const void*, size_t) override;
14419   std::string SerializeAsString() const override;
14420   std::vector<uint8_t> SerializeAsArray() const override;
14421   void Serialize(::protozero::Message*) const;
14422 
has_type() const14423   bool has_type() const { return _has_field_[1]; }
type() const14424   uint32_t type() const { return type_; }
set_type(uint32_t value)14425   void set_type(uint32_t value) { type_ = value; _has_field_.set(1); }
14426 
has_config() const14427   bool has_config() const { return _has_field_[2]; }
config() const14428   uint64_t config() const { return config_; }
set_config(uint64_t value)14429   void set_config(uint64_t value) { config_ = value; _has_field_.set(2); }
14430 
has_config1() const14431   bool has_config1() const { return _has_field_[3]; }
config1() const14432   uint64_t config1() const { return config1_; }
set_config1(uint64_t value)14433   void set_config1(uint64_t value) { config1_ = value; _has_field_.set(3); }
14434 
has_config2() const14435   bool has_config2() const { return _has_field_[4]; }
config2() const14436   uint64_t config2() const { return config2_; }
set_config2(uint64_t value)14437   void set_config2(uint64_t value) { config2_ = value; _has_field_.set(4); }
14438 
14439  private:
14440   uint32_t type_{};
14441   uint64_t config_{};
14442   uint64_t config1_{};
14443   uint64_t config2_{};
14444 
14445   // Allows to preserve unknown protobuf fields for compatibility
14446   // with future versions of .proto files.
14447   std::string unknown_fields_;
14448 
14449   std::bitset<5> _has_field_{};
14450 };
14451 
14452 
14453 class PERFETTO_EXPORT PerfEvents_Tracepoint : public ::protozero::CppMessageObj {
14454  public:
14455   enum FieldNumbers {
14456     kNameFieldNumber = 1,
14457     kFilterFieldNumber = 2,
14458   };
14459 
14460   PerfEvents_Tracepoint();
14461   ~PerfEvents_Tracepoint() override;
14462   PerfEvents_Tracepoint(PerfEvents_Tracepoint&&) noexcept;
14463   PerfEvents_Tracepoint& operator=(PerfEvents_Tracepoint&&);
14464   PerfEvents_Tracepoint(const PerfEvents_Tracepoint&);
14465   PerfEvents_Tracepoint& operator=(const PerfEvents_Tracepoint&);
14466   bool operator==(const PerfEvents_Tracepoint&) const;
operator !=(const PerfEvents_Tracepoint & other) const14467   bool operator!=(const PerfEvents_Tracepoint& other) const { return !(*this == other); }
14468 
14469   bool ParseFromArray(const void*, size_t) override;
14470   std::string SerializeAsString() const override;
14471   std::vector<uint8_t> SerializeAsArray() const override;
14472   void Serialize(::protozero::Message*) const;
14473 
has_name() const14474   bool has_name() const { return _has_field_[1]; }
name() const14475   const std::string& name() const { return name_; }
set_name(const std::string & value)14476   void set_name(const std::string& value) { name_ = value; _has_field_.set(1); }
14477 
has_filter() const14478   bool has_filter() const { return _has_field_[2]; }
filter() const14479   const std::string& filter() const { return filter_; }
set_filter(const std::string & value)14480   void set_filter(const std::string& value) { filter_ = value; _has_field_.set(2); }
14481 
14482  private:
14483   std::string name_{};
14484   std::string filter_{};
14485 
14486   // Allows to preserve unknown protobuf fields for compatibility
14487   // with future versions of .proto files.
14488   std::string unknown_fields_;
14489 
14490   std::bitset<3> _has_field_{};
14491 };
14492 
14493 
14494 class PERFETTO_EXPORT PerfEvents_Timebase : public ::protozero::CppMessageObj {
14495  public:
14496   enum FieldNumbers {
14497     kFrequencyFieldNumber = 2,
14498     kPeriodFieldNumber = 1,
14499     kCounterFieldNumber = 4,
14500     kTracepointFieldNumber = 3,
14501     kRawEventFieldNumber = 5,
14502     kTimestampClockFieldNumber = 11,
14503     kNameFieldNumber = 10,
14504   };
14505 
14506   PerfEvents_Timebase();
14507   ~PerfEvents_Timebase() override;
14508   PerfEvents_Timebase(PerfEvents_Timebase&&) noexcept;
14509   PerfEvents_Timebase& operator=(PerfEvents_Timebase&&);
14510   PerfEvents_Timebase(const PerfEvents_Timebase&);
14511   PerfEvents_Timebase& operator=(const PerfEvents_Timebase&);
14512   bool operator==(const PerfEvents_Timebase&) const;
operator !=(const PerfEvents_Timebase & other) const14513   bool operator!=(const PerfEvents_Timebase& other) const { return !(*this == other); }
14514 
14515   bool ParseFromArray(const void*, size_t) override;
14516   std::string SerializeAsString() const override;
14517   std::vector<uint8_t> SerializeAsArray() const override;
14518   void Serialize(::protozero::Message*) const;
14519 
has_frequency() const14520   bool has_frequency() const { return _has_field_[2]; }
frequency() const14521   uint64_t frequency() const { return frequency_; }
set_frequency(uint64_t value)14522   void set_frequency(uint64_t value) { frequency_ = value; _has_field_.set(2); }
14523 
has_period() const14524   bool has_period() const { return _has_field_[1]; }
period() const14525   uint64_t period() const { return period_; }
set_period(uint64_t value)14526   void set_period(uint64_t value) { period_ = value; _has_field_.set(1); }
14527 
has_counter() const14528   bool has_counter() const { return _has_field_[4]; }
counter() const14529   PerfEvents_Counter counter() const { return counter_; }
set_counter(PerfEvents_Counter value)14530   void set_counter(PerfEvents_Counter value) { counter_ = value; _has_field_.set(4); }
14531 
has_tracepoint() const14532   bool has_tracepoint() const { return _has_field_[3]; }
tracepoint() const14533   const PerfEvents_Tracepoint& tracepoint() const { return *tracepoint_; }
mutable_tracepoint()14534   PerfEvents_Tracepoint* mutable_tracepoint() { _has_field_.set(3); return tracepoint_.get(); }
14535 
has_raw_event() const14536   bool has_raw_event() const { return _has_field_[5]; }
raw_event() const14537   const PerfEvents_RawEvent& raw_event() const { return *raw_event_; }
mutable_raw_event()14538   PerfEvents_RawEvent* mutable_raw_event() { _has_field_.set(5); return raw_event_.get(); }
14539 
has_timestamp_clock() const14540   bool has_timestamp_clock() const { return _has_field_[11]; }
timestamp_clock() const14541   PerfEvents_PerfClock timestamp_clock() const { return timestamp_clock_; }
set_timestamp_clock(PerfEvents_PerfClock value)14542   void set_timestamp_clock(PerfEvents_PerfClock value) { timestamp_clock_ = value; _has_field_.set(11); }
14543 
has_name() const14544   bool has_name() const { return _has_field_[10]; }
name() const14545   const std::string& name() const { return name_; }
set_name(const std::string & value)14546   void set_name(const std::string& value) { name_ = value; _has_field_.set(10); }
14547 
14548  private:
14549   uint64_t frequency_{};
14550   uint64_t period_{};
14551   PerfEvents_Counter counter_{};
14552   ::protozero::CopyablePtr<PerfEvents_Tracepoint> tracepoint_;
14553   ::protozero::CopyablePtr<PerfEvents_RawEvent> raw_event_;
14554   PerfEvents_PerfClock timestamp_clock_{};
14555   std::string name_{};
14556 
14557   // Allows to preserve unknown protobuf fields for compatibility
14558   // with future versions of .proto files.
14559   std::string unknown_fields_;
14560 
14561   std::bitset<12> _has_field_{};
14562 };
14563 
14564 }  // namespace perfetto
14565 }  // namespace protos
14566 }  // namespace gen
14567 
14568 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_PERF_EVENTS_PROTO_CPP_H_
14569 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
14570 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
14571 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
14572 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
14573 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
14574 #if defined(__GNUC__) || defined(__clang__)
14575 #pragma GCC diagnostic push
14576 #pragma GCC diagnostic ignored "-Wfloat-equal"
14577 #endif
14578 // gen_amalgamated expanded: #include "protos/perfetto/common/perf_events.gen.h"
14579 
14580 namespace perfetto {
14581 namespace protos {
14582 namespace gen {
14583 
14584 PerfEvents::PerfEvents() = default;
14585 PerfEvents::~PerfEvents() = default;
14586 PerfEvents::PerfEvents(const PerfEvents&) = default;
14587 PerfEvents& PerfEvents::operator=(const PerfEvents&) = default;
14588 PerfEvents::PerfEvents(PerfEvents&&) noexcept = default;
14589 PerfEvents& PerfEvents::operator=(PerfEvents&&) = default;
14590 
operator ==(const PerfEvents & other) const14591 bool PerfEvents::operator==(const PerfEvents& other) const {
14592   return unknown_fields_ == other.unknown_fields_;
14593 }
14594 
ParseFromArray(const void * raw,size_t size)14595 bool PerfEvents::ParseFromArray(const void* raw, size_t size) {
14596   unknown_fields_.clear();
14597   bool packed_error = false;
14598 
14599   ::protozero::ProtoDecoder dec(raw, size);
14600   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
14601     if (field.id() < _has_field_.size()) {
14602       _has_field_.set(field.id());
14603     }
14604     switch (field.id()) {
14605       default:
14606         field.SerializeAndAppendTo(&unknown_fields_);
14607         break;
14608     }
14609   }
14610   return !packed_error && !dec.bytes_left();
14611 }
14612 
SerializeAsString() const14613 std::string PerfEvents::SerializeAsString() const {
14614   ::protozero::HeapBuffered<::protozero::Message> msg;
14615   Serialize(msg.get());
14616   return msg.SerializeAsString();
14617 }
14618 
SerializeAsArray() const14619 std::vector<uint8_t> PerfEvents::SerializeAsArray() const {
14620   ::protozero::HeapBuffered<::protozero::Message> msg;
14621   Serialize(msg.get());
14622   return msg.SerializeAsArray();
14623 }
14624 
Serialize(::protozero::Message * msg) const14625 void PerfEvents::Serialize(::protozero::Message* msg) const {
14626   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
14627 }
14628 
14629 
14630 PerfEvents_RawEvent::PerfEvents_RawEvent() = default;
14631 PerfEvents_RawEvent::~PerfEvents_RawEvent() = default;
14632 PerfEvents_RawEvent::PerfEvents_RawEvent(const PerfEvents_RawEvent&) = default;
14633 PerfEvents_RawEvent& PerfEvents_RawEvent::operator=(const PerfEvents_RawEvent&) = default;
14634 PerfEvents_RawEvent::PerfEvents_RawEvent(PerfEvents_RawEvent&&) noexcept = default;
14635 PerfEvents_RawEvent& PerfEvents_RawEvent::operator=(PerfEvents_RawEvent&&) = default;
14636 
operator ==(const PerfEvents_RawEvent & other) const14637 bool PerfEvents_RawEvent::operator==(const PerfEvents_RawEvent& other) const {
14638   return unknown_fields_ == other.unknown_fields_
14639    && type_ == other.type_
14640    && config_ == other.config_
14641    && config1_ == other.config1_
14642    && config2_ == other.config2_;
14643 }
14644 
ParseFromArray(const void * raw,size_t size)14645 bool PerfEvents_RawEvent::ParseFromArray(const void* raw, size_t size) {
14646   unknown_fields_.clear();
14647   bool packed_error = false;
14648 
14649   ::protozero::ProtoDecoder dec(raw, size);
14650   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
14651     if (field.id() < _has_field_.size()) {
14652       _has_field_.set(field.id());
14653     }
14654     switch (field.id()) {
14655       case 1 /* type */:
14656         field.get(&type_);
14657         break;
14658       case 2 /* config */:
14659         field.get(&config_);
14660         break;
14661       case 3 /* config1 */:
14662         field.get(&config1_);
14663         break;
14664       case 4 /* config2 */:
14665         field.get(&config2_);
14666         break;
14667       default:
14668         field.SerializeAndAppendTo(&unknown_fields_);
14669         break;
14670     }
14671   }
14672   return !packed_error && !dec.bytes_left();
14673 }
14674 
SerializeAsString() const14675 std::string PerfEvents_RawEvent::SerializeAsString() const {
14676   ::protozero::HeapBuffered<::protozero::Message> msg;
14677   Serialize(msg.get());
14678   return msg.SerializeAsString();
14679 }
14680 
SerializeAsArray() const14681 std::vector<uint8_t> PerfEvents_RawEvent::SerializeAsArray() const {
14682   ::protozero::HeapBuffered<::protozero::Message> msg;
14683   Serialize(msg.get());
14684   return msg.SerializeAsArray();
14685 }
14686 
Serialize(::protozero::Message * msg) const14687 void PerfEvents_RawEvent::Serialize(::protozero::Message* msg) const {
14688   // Field 1: type
14689   if (_has_field_[1]) {
14690     msg->AppendVarInt(1, type_);
14691   }
14692 
14693   // Field 2: config
14694   if (_has_field_[2]) {
14695     msg->AppendVarInt(2, config_);
14696   }
14697 
14698   // Field 3: config1
14699   if (_has_field_[3]) {
14700     msg->AppendVarInt(3, config1_);
14701   }
14702 
14703   // Field 4: config2
14704   if (_has_field_[4]) {
14705     msg->AppendVarInt(4, config2_);
14706   }
14707 
14708   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
14709 }
14710 
14711 
14712 PerfEvents_Tracepoint::PerfEvents_Tracepoint() = default;
14713 PerfEvents_Tracepoint::~PerfEvents_Tracepoint() = default;
14714 PerfEvents_Tracepoint::PerfEvents_Tracepoint(const PerfEvents_Tracepoint&) = default;
14715 PerfEvents_Tracepoint& PerfEvents_Tracepoint::operator=(const PerfEvents_Tracepoint&) = default;
14716 PerfEvents_Tracepoint::PerfEvents_Tracepoint(PerfEvents_Tracepoint&&) noexcept = default;
14717 PerfEvents_Tracepoint& PerfEvents_Tracepoint::operator=(PerfEvents_Tracepoint&&) = default;
14718 
operator ==(const PerfEvents_Tracepoint & other) const14719 bool PerfEvents_Tracepoint::operator==(const PerfEvents_Tracepoint& other) const {
14720   return unknown_fields_ == other.unknown_fields_
14721    && name_ == other.name_
14722    && filter_ == other.filter_;
14723 }
14724 
ParseFromArray(const void * raw,size_t size)14725 bool PerfEvents_Tracepoint::ParseFromArray(const void* raw, size_t size) {
14726   unknown_fields_.clear();
14727   bool packed_error = false;
14728 
14729   ::protozero::ProtoDecoder dec(raw, size);
14730   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
14731     if (field.id() < _has_field_.size()) {
14732       _has_field_.set(field.id());
14733     }
14734     switch (field.id()) {
14735       case 1 /* name */:
14736         field.get(&name_);
14737         break;
14738       case 2 /* filter */:
14739         field.get(&filter_);
14740         break;
14741       default:
14742         field.SerializeAndAppendTo(&unknown_fields_);
14743         break;
14744     }
14745   }
14746   return !packed_error && !dec.bytes_left();
14747 }
14748 
SerializeAsString() const14749 std::string PerfEvents_Tracepoint::SerializeAsString() const {
14750   ::protozero::HeapBuffered<::protozero::Message> msg;
14751   Serialize(msg.get());
14752   return msg.SerializeAsString();
14753 }
14754 
SerializeAsArray() const14755 std::vector<uint8_t> PerfEvents_Tracepoint::SerializeAsArray() const {
14756   ::protozero::HeapBuffered<::protozero::Message> msg;
14757   Serialize(msg.get());
14758   return msg.SerializeAsArray();
14759 }
14760 
Serialize(::protozero::Message * msg) const14761 void PerfEvents_Tracepoint::Serialize(::protozero::Message* msg) const {
14762   // Field 1: name
14763   if (_has_field_[1]) {
14764     msg->AppendString(1, name_);
14765   }
14766 
14767   // Field 2: filter
14768   if (_has_field_[2]) {
14769     msg->AppendString(2, filter_);
14770   }
14771 
14772   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
14773 }
14774 
14775 
14776 PerfEvents_Timebase::PerfEvents_Timebase() = default;
14777 PerfEvents_Timebase::~PerfEvents_Timebase() = default;
14778 PerfEvents_Timebase::PerfEvents_Timebase(const PerfEvents_Timebase&) = default;
14779 PerfEvents_Timebase& PerfEvents_Timebase::operator=(const PerfEvents_Timebase&) = default;
14780 PerfEvents_Timebase::PerfEvents_Timebase(PerfEvents_Timebase&&) noexcept = default;
14781 PerfEvents_Timebase& PerfEvents_Timebase::operator=(PerfEvents_Timebase&&) = default;
14782 
operator ==(const PerfEvents_Timebase & other) const14783 bool PerfEvents_Timebase::operator==(const PerfEvents_Timebase& other) const {
14784   return unknown_fields_ == other.unknown_fields_
14785    && frequency_ == other.frequency_
14786    && period_ == other.period_
14787    && counter_ == other.counter_
14788    && tracepoint_ == other.tracepoint_
14789    && raw_event_ == other.raw_event_
14790    && timestamp_clock_ == other.timestamp_clock_
14791    && name_ == other.name_;
14792 }
14793 
ParseFromArray(const void * raw,size_t size)14794 bool PerfEvents_Timebase::ParseFromArray(const void* raw, size_t size) {
14795   unknown_fields_.clear();
14796   bool packed_error = false;
14797 
14798   ::protozero::ProtoDecoder dec(raw, size);
14799   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
14800     if (field.id() < _has_field_.size()) {
14801       _has_field_.set(field.id());
14802     }
14803     switch (field.id()) {
14804       case 2 /* frequency */:
14805         field.get(&frequency_);
14806         break;
14807       case 1 /* period */:
14808         field.get(&period_);
14809         break;
14810       case 4 /* counter */:
14811         field.get(&counter_);
14812         break;
14813       case 3 /* tracepoint */:
14814         (*tracepoint_).ParseFromArray(field.data(), field.size());
14815         break;
14816       case 5 /* raw_event */:
14817         (*raw_event_).ParseFromArray(field.data(), field.size());
14818         break;
14819       case 11 /* timestamp_clock */:
14820         field.get(&timestamp_clock_);
14821         break;
14822       case 10 /* name */:
14823         field.get(&name_);
14824         break;
14825       default:
14826         field.SerializeAndAppendTo(&unknown_fields_);
14827         break;
14828     }
14829   }
14830   return !packed_error && !dec.bytes_left();
14831 }
14832 
SerializeAsString() const14833 std::string PerfEvents_Timebase::SerializeAsString() const {
14834   ::protozero::HeapBuffered<::protozero::Message> msg;
14835   Serialize(msg.get());
14836   return msg.SerializeAsString();
14837 }
14838 
SerializeAsArray() const14839 std::vector<uint8_t> PerfEvents_Timebase::SerializeAsArray() const {
14840   ::protozero::HeapBuffered<::protozero::Message> msg;
14841   Serialize(msg.get());
14842   return msg.SerializeAsArray();
14843 }
14844 
Serialize(::protozero::Message * msg) const14845 void PerfEvents_Timebase::Serialize(::protozero::Message* msg) const {
14846   // Field 2: frequency
14847   if (_has_field_[2]) {
14848     msg->AppendVarInt(2, frequency_);
14849   }
14850 
14851   // Field 1: period
14852   if (_has_field_[1]) {
14853     msg->AppendVarInt(1, period_);
14854   }
14855 
14856   // Field 4: counter
14857   if (_has_field_[4]) {
14858     msg->AppendVarInt(4, counter_);
14859   }
14860 
14861   // Field 3: tracepoint
14862   if (_has_field_[3]) {
14863     (*tracepoint_).Serialize(msg->BeginNestedMessage<::protozero::Message>(3));
14864   }
14865 
14866   // Field 5: raw_event
14867   if (_has_field_[5]) {
14868     (*raw_event_).Serialize(msg->BeginNestedMessage<::protozero::Message>(5));
14869   }
14870 
14871   // Field 11: timestamp_clock
14872   if (_has_field_[11]) {
14873     msg->AppendVarInt(11, timestamp_clock_);
14874   }
14875 
14876   // Field 10: name
14877   if (_has_field_[10]) {
14878     msg->AppendString(10, name_);
14879   }
14880 
14881   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
14882 }
14883 
14884 }  // namespace perfetto
14885 }  // namespace protos
14886 }  // namespace gen
14887 #if defined(__GNUC__) || defined(__clang__)
14888 #pragma GCC diagnostic pop
14889 #endif
14890 // gen_amalgamated begin source: gen/protos/perfetto/common/sys_stats_counters.gen.cc
14891 // gen_amalgamated begin header: gen/protos/perfetto/common/sys_stats_counters.gen.h
14892 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
14893 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_SYS_STATS_COUNTERS_PROTO_CPP_H_
14894 #define PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_SYS_STATS_COUNTERS_PROTO_CPP_H_
14895 
14896 #include <stdint.h>
14897 #include <bitset>
14898 #include <vector>
14899 #include <string>
14900 #include <type_traits>
14901 
14902 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
14903 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
14904 // gen_amalgamated expanded: #include "perfetto/base/export.h"
14905 
14906 namespace perfetto {
14907 namespace protos {
14908 namespace gen {
14909 enum MeminfoCounters : int;
14910 enum VmstatCounters : int;
14911 }  // namespace perfetto
14912 }  // namespace protos
14913 }  // namespace gen
14914 
14915 namespace protozero {
14916 class Message;
14917 }  // namespace protozero
14918 
14919 namespace perfetto {
14920 namespace protos {
14921 namespace gen {
14922 enum MeminfoCounters : int {
14923   MEMINFO_UNSPECIFIED = 0,
14924   MEMINFO_MEM_TOTAL = 1,
14925   MEMINFO_MEM_FREE = 2,
14926   MEMINFO_MEM_AVAILABLE = 3,
14927   MEMINFO_BUFFERS = 4,
14928   MEMINFO_CACHED = 5,
14929   MEMINFO_SWAP_CACHED = 6,
14930   MEMINFO_ACTIVE = 7,
14931   MEMINFO_INACTIVE = 8,
14932   MEMINFO_ACTIVE_ANON = 9,
14933   MEMINFO_INACTIVE_ANON = 10,
14934   MEMINFO_ACTIVE_FILE = 11,
14935   MEMINFO_INACTIVE_FILE = 12,
14936   MEMINFO_UNEVICTABLE = 13,
14937   MEMINFO_MLOCKED = 14,
14938   MEMINFO_SWAP_TOTAL = 15,
14939   MEMINFO_SWAP_FREE = 16,
14940   MEMINFO_DIRTY = 17,
14941   MEMINFO_WRITEBACK = 18,
14942   MEMINFO_ANON_PAGES = 19,
14943   MEMINFO_MAPPED = 20,
14944   MEMINFO_SHMEM = 21,
14945   MEMINFO_SLAB = 22,
14946   MEMINFO_SLAB_RECLAIMABLE = 23,
14947   MEMINFO_SLAB_UNRECLAIMABLE = 24,
14948   MEMINFO_KERNEL_STACK = 25,
14949   MEMINFO_PAGE_TABLES = 26,
14950   MEMINFO_COMMIT_LIMIT = 27,
14951   MEMINFO_COMMITED_AS = 28,
14952   MEMINFO_VMALLOC_TOTAL = 29,
14953   MEMINFO_VMALLOC_USED = 30,
14954   MEMINFO_VMALLOC_CHUNK = 31,
14955   MEMINFO_CMA_TOTAL = 32,
14956   MEMINFO_CMA_FREE = 33,
14957 };
14958 enum VmstatCounters : int {
14959   VMSTAT_UNSPECIFIED = 0,
14960   VMSTAT_NR_FREE_PAGES = 1,
14961   VMSTAT_NR_ALLOC_BATCH = 2,
14962   VMSTAT_NR_INACTIVE_ANON = 3,
14963   VMSTAT_NR_ACTIVE_ANON = 4,
14964   VMSTAT_NR_INACTIVE_FILE = 5,
14965   VMSTAT_NR_ACTIVE_FILE = 6,
14966   VMSTAT_NR_UNEVICTABLE = 7,
14967   VMSTAT_NR_MLOCK = 8,
14968   VMSTAT_NR_ANON_PAGES = 9,
14969   VMSTAT_NR_MAPPED = 10,
14970   VMSTAT_NR_FILE_PAGES = 11,
14971   VMSTAT_NR_DIRTY = 12,
14972   VMSTAT_NR_WRITEBACK = 13,
14973   VMSTAT_NR_SLAB_RECLAIMABLE = 14,
14974   VMSTAT_NR_SLAB_UNRECLAIMABLE = 15,
14975   VMSTAT_NR_PAGE_TABLE_PAGES = 16,
14976   VMSTAT_NR_KERNEL_STACK = 17,
14977   VMSTAT_NR_OVERHEAD = 18,
14978   VMSTAT_NR_UNSTABLE = 19,
14979   VMSTAT_NR_BOUNCE = 20,
14980   VMSTAT_NR_VMSCAN_WRITE = 21,
14981   VMSTAT_NR_VMSCAN_IMMEDIATE_RECLAIM = 22,
14982   VMSTAT_NR_WRITEBACK_TEMP = 23,
14983   VMSTAT_NR_ISOLATED_ANON = 24,
14984   VMSTAT_NR_ISOLATED_FILE = 25,
14985   VMSTAT_NR_SHMEM = 26,
14986   VMSTAT_NR_DIRTIED = 27,
14987   VMSTAT_NR_WRITTEN = 28,
14988   VMSTAT_NR_PAGES_SCANNED = 29,
14989   VMSTAT_WORKINGSET_REFAULT = 30,
14990   VMSTAT_WORKINGSET_ACTIVATE = 31,
14991   VMSTAT_WORKINGSET_NODERECLAIM = 32,
14992   VMSTAT_NR_ANON_TRANSPARENT_HUGEPAGES = 33,
14993   VMSTAT_NR_FREE_CMA = 34,
14994   VMSTAT_NR_SWAPCACHE = 35,
14995   VMSTAT_NR_DIRTY_THRESHOLD = 36,
14996   VMSTAT_NR_DIRTY_BACKGROUND_THRESHOLD = 37,
14997   VMSTAT_PGPGIN = 38,
14998   VMSTAT_PGPGOUT = 39,
14999   VMSTAT_PGPGOUTCLEAN = 40,
15000   VMSTAT_PSWPIN = 41,
15001   VMSTAT_PSWPOUT = 42,
15002   VMSTAT_PGALLOC_DMA = 43,
15003   VMSTAT_PGALLOC_NORMAL = 44,
15004   VMSTAT_PGALLOC_MOVABLE = 45,
15005   VMSTAT_PGFREE = 46,
15006   VMSTAT_PGACTIVATE = 47,
15007   VMSTAT_PGDEACTIVATE = 48,
15008   VMSTAT_PGFAULT = 49,
15009   VMSTAT_PGMAJFAULT = 50,
15010   VMSTAT_PGREFILL_DMA = 51,
15011   VMSTAT_PGREFILL_NORMAL = 52,
15012   VMSTAT_PGREFILL_MOVABLE = 53,
15013   VMSTAT_PGSTEAL_KSWAPD_DMA = 54,
15014   VMSTAT_PGSTEAL_KSWAPD_NORMAL = 55,
15015   VMSTAT_PGSTEAL_KSWAPD_MOVABLE = 56,
15016   VMSTAT_PGSTEAL_DIRECT_DMA = 57,
15017   VMSTAT_PGSTEAL_DIRECT_NORMAL = 58,
15018   VMSTAT_PGSTEAL_DIRECT_MOVABLE = 59,
15019   VMSTAT_PGSCAN_KSWAPD_DMA = 60,
15020   VMSTAT_PGSCAN_KSWAPD_NORMAL = 61,
15021   VMSTAT_PGSCAN_KSWAPD_MOVABLE = 62,
15022   VMSTAT_PGSCAN_DIRECT_DMA = 63,
15023   VMSTAT_PGSCAN_DIRECT_NORMAL = 64,
15024   VMSTAT_PGSCAN_DIRECT_MOVABLE = 65,
15025   VMSTAT_PGSCAN_DIRECT_THROTTLE = 66,
15026   VMSTAT_PGINODESTEAL = 67,
15027   VMSTAT_SLABS_SCANNED = 68,
15028   VMSTAT_KSWAPD_INODESTEAL = 69,
15029   VMSTAT_KSWAPD_LOW_WMARK_HIT_QUICKLY = 70,
15030   VMSTAT_KSWAPD_HIGH_WMARK_HIT_QUICKLY = 71,
15031   VMSTAT_PAGEOUTRUN = 72,
15032   VMSTAT_ALLOCSTALL = 73,
15033   VMSTAT_PGROTATED = 74,
15034   VMSTAT_DROP_PAGECACHE = 75,
15035   VMSTAT_DROP_SLAB = 76,
15036   VMSTAT_PGMIGRATE_SUCCESS = 77,
15037   VMSTAT_PGMIGRATE_FAIL = 78,
15038   VMSTAT_COMPACT_MIGRATE_SCANNED = 79,
15039   VMSTAT_COMPACT_FREE_SCANNED = 80,
15040   VMSTAT_COMPACT_ISOLATED = 81,
15041   VMSTAT_COMPACT_STALL = 82,
15042   VMSTAT_COMPACT_FAIL = 83,
15043   VMSTAT_COMPACT_SUCCESS = 84,
15044   VMSTAT_COMPACT_DAEMON_WAKE = 85,
15045   VMSTAT_UNEVICTABLE_PGS_CULLED = 86,
15046   VMSTAT_UNEVICTABLE_PGS_SCANNED = 87,
15047   VMSTAT_UNEVICTABLE_PGS_RESCUED = 88,
15048   VMSTAT_UNEVICTABLE_PGS_MLOCKED = 89,
15049   VMSTAT_UNEVICTABLE_PGS_MUNLOCKED = 90,
15050   VMSTAT_UNEVICTABLE_PGS_CLEARED = 91,
15051   VMSTAT_UNEVICTABLE_PGS_STRANDED = 92,
15052   VMSTAT_NR_ZSPAGES = 93,
15053   VMSTAT_NR_ION_HEAP = 94,
15054   VMSTAT_NR_GPU_HEAP = 95,
15055   VMSTAT_ALLOCSTALL_DMA = 96,
15056   VMSTAT_ALLOCSTALL_MOVABLE = 97,
15057   VMSTAT_ALLOCSTALL_NORMAL = 98,
15058   VMSTAT_COMPACT_DAEMON_FREE_SCANNED = 99,
15059   VMSTAT_COMPACT_DAEMON_MIGRATE_SCANNED = 100,
15060   VMSTAT_NR_FASTRPC = 101,
15061   VMSTAT_NR_INDIRECTLY_RECLAIMABLE = 102,
15062   VMSTAT_NR_ION_HEAP_POOL = 103,
15063   VMSTAT_NR_KERNEL_MISC_RECLAIMABLE = 104,
15064   VMSTAT_NR_SHADOW_CALL_STACK_BYTES = 105,
15065   VMSTAT_NR_SHMEM_HUGEPAGES = 106,
15066   VMSTAT_NR_SHMEM_PMDMAPPED = 107,
15067   VMSTAT_NR_UNRECLAIMABLE_PAGES = 108,
15068   VMSTAT_NR_ZONE_ACTIVE_ANON = 109,
15069   VMSTAT_NR_ZONE_ACTIVE_FILE = 110,
15070   VMSTAT_NR_ZONE_INACTIVE_ANON = 111,
15071   VMSTAT_NR_ZONE_INACTIVE_FILE = 112,
15072   VMSTAT_NR_ZONE_UNEVICTABLE = 113,
15073   VMSTAT_NR_ZONE_WRITE_PENDING = 114,
15074   VMSTAT_OOM_KILL = 115,
15075   VMSTAT_PGLAZYFREE = 116,
15076   VMSTAT_PGLAZYFREED = 117,
15077   VMSTAT_PGREFILL = 118,
15078   VMSTAT_PGSCAN_DIRECT = 119,
15079   VMSTAT_PGSCAN_KSWAPD = 120,
15080   VMSTAT_PGSKIP_DMA = 121,
15081   VMSTAT_PGSKIP_MOVABLE = 122,
15082   VMSTAT_PGSKIP_NORMAL = 123,
15083   VMSTAT_PGSTEAL_DIRECT = 124,
15084   VMSTAT_PGSTEAL_KSWAPD = 125,
15085   VMSTAT_SWAP_RA = 126,
15086   VMSTAT_SWAP_RA_HIT = 127,
15087   VMSTAT_WORKINGSET_RESTORE = 128,
15088 };
15089 }  // namespace perfetto
15090 }  // namespace protos
15091 }  // namespace gen
15092 
15093 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_SYS_STATS_COUNTERS_PROTO_CPP_H_
15094 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
15095 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
15096 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
15097 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
15098 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
15099 #if defined(__GNUC__) || defined(__clang__)
15100 #pragma GCC diagnostic push
15101 #pragma GCC diagnostic ignored "-Wfloat-equal"
15102 #endif
15103 // gen_amalgamated expanded: #include "protos/perfetto/common/sys_stats_counters.gen.h"
15104 
15105 namespace perfetto {
15106 namespace protos {
15107 namespace gen {
15108 }  // namespace perfetto
15109 }  // namespace protos
15110 }  // namespace gen
15111 #if defined(__GNUC__) || defined(__clang__)
15112 #pragma GCC diagnostic pop
15113 #endif
15114 // gen_amalgamated begin source: gen/protos/perfetto/common/trace_stats.gen.cc
15115 // gen_amalgamated begin header: gen/protos/perfetto/common/trace_stats.gen.h
15116 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
15117 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_TRACE_STATS_PROTO_CPP_H_
15118 #define PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_TRACE_STATS_PROTO_CPP_H_
15119 
15120 #include <stdint.h>
15121 #include <bitset>
15122 #include <vector>
15123 #include <string>
15124 #include <type_traits>
15125 
15126 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
15127 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
15128 // gen_amalgamated expanded: #include "perfetto/base/export.h"
15129 
15130 namespace perfetto {
15131 namespace protos {
15132 namespace gen {
15133 class TraceStats;
15134 class TraceStats_FilterStats;
15135 class TraceStats_BufferStats;
15136 }  // namespace perfetto
15137 }  // namespace protos
15138 }  // namespace gen
15139 
15140 namespace protozero {
15141 class Message;
15142 }  // namespace protozero
15143 
15144 namespace perfetto {
15145 namespace protos {
15146 namespace gen {
15147 
15148 class PERFETTO_EXPORT TraceStats : public ::protozero::CppMessageObj {
15149  public:
15150   using BufferStats = TraceStats_BufferStats;
15151   using FilterStats = TraceStats_FilterStats;
15152   enum FieldNumbers {
15153     kBufferStatsFieldNumber = 1,
15154     kProducersConnectedFieldNumber = 2,
15155     kProducersSeenFieldNumber = 3,
15156     kDataSourcesRegisteredFieldNumber = 4,
15157     kDataSourcesSeenFieldNumber = 5,
15158     kTracingSessionsFieldNumber = 6,
15159     kTotalBuffersFieldNumber = 7,
15160     kChunksDiscardedFieldNumber = 8,
15161     kPatchesDiscardedFieldNumber = 9,
15162     kInvalidPacketsFieldNumber = 10,
15163     kFilterStatsFieldNumber = 11,
15164   };
15165 
15166   TraceStats();
15167   ~TraceStats() override;
15168   TraceStats(TraceStats&&) noexcept;
15169   TraceStats& operator=(TraceStats&&);
15170   TraceStats(const TraceStats&);
15171   TraceStats& operator=(const TraceStats&);
15172   bool operator==(const TraceStats&) const;
operator !=(const TraceStats & other) const15173   bool operator!=(const TraceStats& other) const { return !(*this == other); }
15174 
15175   bool ParseFromArray(const void*, size_t) override;
15176   std::string SerializeAsString() const override;
15177   std::vector<uint8_t> SerializeAsArray() const override;
15178   void Serialize(::protozero::Message*) const;
15179 
buffer_stats() const15180   const std::vector<TraceStats_BufferStats>& buffer_stats() const { return buffer_stats_; }
mutable_buffer_stats()15181   std::vector<TraceStats_BufferStats>* mutable_buffer_stats() { return &buffer_stats_; }
15182   int buffer_stats_size() const;
15183   void clear_buffer_stats();
15184   TraceStats_BufferStats* add_buffer_stats();
15185 
has_producers_connected() const15186   bool has_producers_connected() const { return _has_field_[2]; }
producers_connected() const15187   uint32_t producers_connected() const { return producers_connected_; }
set_producers_connected(uint32_t value)15188   void set_producers_connected(uint32_t value) { producers_connected_ = value; _has_field_.set(2); }
15189 
has_producers_seen() const15190   bool has_producers_seen() const { return _has_field_[3]; }
producers_seen() const15191   uint64_t producers_seen() const { return producers_seen_; }
set_producers_seen(uint64_t value)15192   void set_producers_seen(uint64_t value) { producers_seen_ = value; _has_field_.set(3); }
15193 
has_data_sources_registered() const15194   bool has_data_sources_registered() const { return _has_field_[4]; }
data_sources_registered() const15195   uint32_t data_sources_registered() const { return data_sources_registered_; }
set_data_sources_registered(uint32_t value)15196   void set_data_sources_registered(uint32_t value) { data_sources_registered_ = value; _has_field_.set(4); }
15197 
has_data_sources_seen() const15198   bool has_data_sources_seen() const { return _has_field_[5]; }
data_sources_seen() const15199   uint64_t data_sources_seen() const { return data_sources_seen_; }
set_data_sources_seen(uint64_t value)15200   void set_data_sources_seen(uint64_t value) { data_sources_seen_ = value; _has_field_.set(5); }
15201 
has_tracing_sessions() const15202   bool has_tracing_sessions() const { return _has_field_[6]; }
tracing_sessions() const15203   uint32_t tracing_sessions() const { return tracing_sessions_; }
set_tracing_sessions(uint32_t value)15204   void set_tracing_sessions(uint32_t value) { tracing_sessions_ = value; _has_field_.set(6); }
15205 
has_total_buffers() const15206   bool has_total_buffers() const { return _has_field_[7]; }
total_buffers() const15207   uint32_t total_buffers() const { return total_buffers_; }
set_total_buffers(uint32_t value)15208   void set_total_buffers(uint32_t value) { total_buffers_ = value; _has_field_.set(7); }
15209 
has_chunks_discarded() const15210   bool has_chunks_discarded() const { return _has_field_[8]; }
chunks_discarded() const15211   uint64_t chunks_discarded() const { return chunks_discarded_; }
set_chunks_discarded(uint64_t value)15212   void set_chunks_discarded(uint64_t value) { chunks_discarded_ = value; _has_field_.set(8); }
15213 
has_patches_discarded() const15214   bool has_patches_discarded() const { return _has_field_[9]; }
patches_discarded() const15215   uint64_t patches_discarded() const { return patches_discarded_; }
set_patches_discarded(uint64_t value)15216   void set_patches_discarded(uint64_t value) { patches_discarded_ = value; _has_field_.set(9); }
15217 
has_invalid_packets() const15218   bool has_invalid_packets() const { return _has_field_[10]; }
invalid_packets() const15219   uint64_t invalid_packets() const { return invalid_packets_; }
set_invalid_packets(uint64_t value)15220   void set_invalid_packets(uint64_t value) { invalid_packets_ = value; _has_field_.set(10); }
15221 
has_filter_stats() const15222   bool has_filter_stats() const { return _has_field_[11]; }
filter_stats() const15223   const TraceStats_FilterStats& filter_stats() const { return *filter_stats_; }
mutable_filter_stats()15224   TraceStats_FilterStats* mutable_filter_stats() { _has_field_.set(11); return filter_stats_.get(); }
15225 
15226  private:
15227   std::vector<TraceStats_BufferStats> buffer_stats_;
15228   uint32_t producers_connected_{};
15229   uint64_t producers_seen_{};
15230   uint32_t data_sources_registered_{};
15231   uint64_t data_sources_seen_{};
15232   uint32_t tracing_sessions_{};
15233   uint32_t total_buffers_{};
15234   uint64_t chunks_discarded_{};
15235   uint64_t patches_discarded_{};
15236   uint64_t invalid_packets_{};
15237   ::protozero::CopyablePtr<TraceStats_FilterStats> filter_stats_;
15238 
15239   // Allows to preserve unknown protobuf fields for compatibility
15240   // with future versions of .proto files.
15241   std::string unknown_fields_;
15242 
15243   std::bitset<12> _has_field_{};
15244 };
15245 
15246 
15247 class PERFETTO_EXPORT TraceStats_FilterStats : public ::protozero::CppMessageObj {
15248  public:
15249   enum FieldNumbers {
15250     kInputPacketsFieldNumber = 1,
15251     kInputBytesFieldNumber = 2,
15252     kOutputBytesFieldNumber = 3,
15253     kErrorsFieldNumber = 4,
15254   };
15255 
15256   TraceStats_FilterStats();
15257   ~TraceStats_FilterStats() override;
15258   TraceStats_FilterStats(TraceStats_FilterStats&&) noexcept;
15259   TraceStats_FilterStats& operator=(TraceStats_FilterStats&&);
15260   TraceStats_FilterStats(const TraceStats_FilterStats&);
15261   TraceStats_FilterStats& operator=(const TraceStats_FilterStats&);
15262   bool operator==(const TraceStats_FilterStats&) const;
operator !=(const TraceStats_FilterStats & other) const15263   bool operator!=(const TraceStats_FilterStats& other) const { return !(*this == other); }
15264 
15265   bool ParseFromArray(const void*, size_t) override;
15266   std::string SerializeAsString() const override;
15267   std::vector<uint8_t> SerializeAsArray() const override;
15268   void Serialize(::protozero::Message*) const;
15269 
has_input_packets() const15270   bool has_input_packets() const { return _has_field_[1]; }
input_packets() const15271   uint64_t input_packets() const { return input_packets_; }
set_input_packets(uint64_t value)15272   void set_input_packets(uint64_t value) { input_packets_ = value; _has_field_.set(1); }
15273 
has_input_bytes() const15274   bool has_input_bytes() const { return _has_field_[2]; }
input_bytes() const15275   uint64_t input_bytes() const { return input_bytes_; }
set_input_bytes(uint64_t value)15276   void set_input_bytes(uint64_t value) { input_bytes_ = value; _has_field_.set(2); }
15277 
has_output_bytes() const15278   bool has_output_bytes() const { return _has_field_[3]; }
output_bytes() const15279   uint64_t output_bytes() const { return output_bytes_; }
set_output_bytes(uint64_t value)15280   void set_output_bytes(uint64_t value) { output_bytes_ = value; _has_field_.set(3); }
15281 
has_errors() const15282   bool has_errors() const { return _has_field_[4]; }
errors() const15283   uint64_t errors() const { return errors_; }
set_errors(uint64_t value)15284   void set_errors(uint64_t value) { errors_ = value; _has_field_.set(4); }
15285 
15286  private:
15287   uint64_t input_packets_{};
15288   uint64_t input_bytes_{};
15289   uint64_t output_bytes_{};
15290   uint64_t errors_{};
15291 
15292   // Allows to preserve unknown protobuf fields for compatibility
15293   // with future versions of .proto files.
15294   std::string unknown_fields_;
15295 
15296   std::bitset<5> _has_field_{};
15297 };
15298 
15299 
15300 class PERFETTO_EXPORT TraceStats_BufferStats : public ::protozero::CppMessageObj {
15301  public:
15302   enum FieldNumbers {
15303     kBufferSizeFieldNumber = 12,
15304     kBytesWrittenFieldNumber = 1,
15305     kBytesOverwrittenFieldNumber = 13,
15306     kBytesReadFieldNumber = 14,
15307     kPaddingBytesWrittenFieldNumber = 15,
15308     kPaddingBytesClearedFieldNumber = 16,
15309     kChunksWrittenFieldNumber = 2,
15310     kChunksRewrittenFieldNumber = 10,
15311     kChunksOverwrittenFieldNumber = 3,
15312     kChunksDiscardedFieldNumber = 18,
15313     kChunksReadFieldNumber = 17,
15314     kChunksCommittedOutOfOrderFieldNumber = 11,
15315     kWriteWrapCountFieldNumber = 4,
15316     kPatchesSucceededFieldNumber = 5,
15317     kPatchesFailedFieldNumber = 6,
15318     kReadaheadsSucceededFieldNumber = 7,
15319     kReadaheadsFailedFieldNumber = 8,
15320     kAbiViolationsFieldNumber = 9,
15321     kTraceWriterPacketLossFieldNumber = 19,
15322   };
15323 
15324   TraceStats_BufferStats();
15325   ~TraceStats_BufferStats() override;
15326   TraceStats_BufferStats(TraceStats_BufferStats&&) noexcept;
15327   TraceStats_BufferStats& operator=(TraceStats_BufferStats&&);
15328   TraceStats_BufferStats(const TraceStats_BufferStats&);
15329   TraceStats_BufferStats& operator=(const TraceStats_BufferStats&);
15330   bool operator==(const TraceStats_BufferStats&) const;
operator !=(const TraceStats_BufferStats & other) const15331   bool operator!=(const TraceStats_BufferStats& other) const { return !(*this == other); }
15332 
15333   bool ParseFromArray(const void*, size_t) override;
15334   std::string SerializeAsString() const override;
15335   std::vector<uint8_t> SerializeAsArray() const override;
15336   void Serialize(::protozero::Message*) const;
15337 
has_buffer_size() const15338   bool has_buffer_size() const { return _has_field_[12]; }
buffer_size() const15339   uint64_t buffer_size() const { return buffer_size_; }
set_buffer_size(uint64_t value)15340   void set_buffer_size(uint64_t value) { buffer_size_ = value; _has_field_.set(12); }
15341 
has_bytes_written() const15342   bool has_bytes_written() const { return _has_field_[1]; }
bytes_written() const15343   uint64_t bytes_written() const { return bytes_written_; }
set_bytes_written(uint64_t value)15344   void set_bytes_written(uint64_t value) { bytes_written_ = value; _has_field_.set(1); }
15345 
has_bytes_overwritten() const15346   bool has_bytes_overwritten() const { return _has_field_[13]; }
bytes_overwritten() const15347   uint64_t bytes_overwritten() const { return bytes_overwritten_; }
set_bytes_overwritten(uint64_t value)15348   void set_bytes_overwritten(uint64_t value) { bytes_overwritten_ = value; _has_field_.set(13); }
15349 
has_bytes_read() const15350   bool has_bytes_read() const { return _has_field_[14]; }
bytes_read() const15351   uint64_t bytes_read() const { return bytes_read_; }
set_bytes_read(uint64_t value)15352   void set_bytes_read(uint64_t value) { bytes_read_ = value; _has_field_.set(14); }
15353 
has_padding_bytes_written() const15354   bool has_padding_bytes_written() const { return _has_field_[15]; }
padding_bytes_written() const15355   uint64_t padding_bytes_written() const { return padding_bytes_written_; }
set_padding_bytes_written(uint64_t value)15356   void set_padding_bytes_written(uint64_t value) { padding_bytes_written_ = value; _has_field_.set(15); }
15357 
has_padding_bytes_cleared() const15358   bool has_padding_bytes_cleared() const { return _has_field_[16]; }
padding_bytes_cleared() const15359   uint64_t padding_bytes_cleared() const { return padding_bytes_cleared_; }
set_padding_bytes_cleared(uint64_t value)15360   void set_padding_bytes_cleared(uint64_t value) { padding_bytes_cleared_ = value; _has_field_.set(16); }
15361 
has_chunks_written() const15362   bool has_chunks_written() const { return _has_field_[2]; }
chunks_written() const15363   uint64_t chunks_written() const { return chunks_written_; }
set_chunks_written(uint64_t value)15364   void set_chunks_written(uint64_t value) { chunks_written_ = value; _has_field_.set(2); }
15365 
has_chunks_rewritten() const15366   bool has_chunks_rewritten() const { return _has_field_[10]; }
chunks_rewritten() const15367   uint64_t chunks_rewritten() const { return chunks_rewritten_; }
set_chunks_rewritten(uint64_t value)15368   void set_chunks_rewritten(uint64_t value) { chunks_rewritten_ = value; _has_field_.set(10); }
15369 
has_chunks_overwritten() const15370   bool has_chunks_overwritten() const { return _has_field_[3]; }
chunks_overwritten() const15371   uint64_t chunks_overwritten() const { return chunks_overwritten_; }
set_chunks_overwritten(uint64_t value)15372   void set_chunks_overwritten(uint64_t value) { chunks_overwritten_ = value; _has_field_.set(3); }
15373 
has_chunks_discarded() const15374   bool has_chunks_discarded() const { return _has_field_[18]; }
chunks_discarded() const15375   uint64_t chunks_discarded() const { return chunks_discarded_; }
set_chunks_discarded(uint64_t value)15376   void set_chunks_discarded(uint64_t value) { chunks_discarded_ = value; _has_field_.set(18); }
15377 
has_chunks_read() const15378   bool has_chunks_read() const { return _has_field_[17]; }
chunks_read() const15379   uint64_t chunks_read() const { return chunks_read_; }
set_chunks_read(uint64_t value)15380   void set_chunks_read(uint64_t value) { chunks_read_ = value; _has_field_.set(17); }
15381 
has_chunks_committed_out_of_order() const15382   bool has_chunks_committed_out_of_order() const { return _has_field_[11]; }
chunks_committed_out_of_order() const15383   uint64_t chunks_committed_out_of_order() const { return chunks_committed_out_of_order_; }
set_chunks_committed_out_of_order(uint64_t value)15384   void set_chunks_committed_out_of_order(uint64_t value) { chunks_committed_out_of_order_ = value; _has_field_.set(11); }
15385 
has_write_wrap_count() const15386   bool has_write_wrap_count() const { return _has_field_[4]; }
write_wrap_count() const15387   uint64_t write_wrap_count() const { return write_wrap_count_; }
set_write_wrap_count(uint64_t value)15388   void set_write_wrap_count(uint64_t value) { write_wrap_count_ = value; _has_field_.set(4); }
15389 
has_patches_succeeded() const15390   bool has_patches_succeeded() const { return _has_field_[5]; }
patches_succeeded() const15391   uint64_t patches_succeeded() const { return patches_succeeded_; }
set_patches_succeeded(uint64_t value)15392   void set_patches_succeeded(uint64_t value) { patches_succeeded_ = value; _has_field_.set(5); }
15393 
has_patches_failed() const15394   bool has_patches_failed() const { return _has_field_[6]; }
patches_failed() const15395   uint64_t patches_failed() const { return patches_failed_; }
set_patches_failed(uint64_t value)15396   void set_patches_failed(uint64_t value) { patches_failed_ = value; _has_field_.set(6); }
15397 
has_readaheads_succeeded() const15398   bool has_readaheads_succeeded() const { return _has_field_[7]; }
readaheads_succeeded() const15399   uint64_t readaheads_succeeded() const { return readaheads_succeeded_; }
set_readaheads_succeeded(uint64_t value)15400   void set_readaheads_succeeded(uint64_t value) { readaheads_succeeded_ = value; _has_field_.set(7); }
15401 
has_readaheads_failed() const15402   bool has_readaheads_failed() const { return _has_field_[8]; }
readaheads_failed() const15403   uint64_t readaheads_failed() const { return readaheads_failed_; }
set_readaheads_failed(uint64_t value)15404   void set_readaheads_failed(uint64_t value) { readaheads_failed_ = value; _has_field_.set(8); }
15405 
has_abi_violations() const15406   bool has_abi_violations() const { return _has_field_[9]; }
abi_violations() const15407   uint64_t abi_violations() const { return abi_violations_; }
set_abi_violations(uint64_t value)15408   void set_abi_violations(uint64_t value) { abi_violations_ = value; _has_field_.set(9); }
15409 
has_trace_writer_packet_loss() const15410   bool has_trace_writer_packet_loss() const { return _has_field_[19]; }
trace_writer_packet_loss() const15411   uint64_t trace_writer_packet_loss() const { return trace_writer_packet_loss_; }
set_trace_writer_packet_loss(uint64_t value)15412   void set_trace_writer_packet_loss(uint64_t value) { trace_writer_packet_loss_ = value; _has_field_.set(19); }
15413 
15414  private:
15415   uint64_t buffer_size_{};
15416   uint64_t bytes_written_{};
15417   uint64_t bytes_overwritten_{};
15418   uint64_t bytes_read_{};
15419   uint64_t padding_bytes_written_{};
15420   uint64_t padding_bytes_cleared_{};
15421   uint64_t chunks_written_{};
15422   uint64_t chunks_rewritten_{};
15423   uint64_t chunks_overwritten_{};
15424   uint64_t chunks_discarded_{};
15425   uint64_t chunks_read_{};
15426   uint64_t chunks_committed_out_of_order_{};
15427   uint64_t write_wrap_count_{};
15428   uint64_t patches_succeeded_{};
15429   uint64_t patches_failed_{};
15430   uint64_t readaheads_succeeded_{};
15431   uint64_t readaheads_failed_{};
15432   uint64_t abi_violations_{};
15433   uint64_t trace_writer_packet_loss_{};
15434 
15435   // Allows to preserve unknown protobuf fields for compatibility
15436   // with future versions of .proto files.
15437   std::string unknown_fields_;
15438 
15439   std::bitset<20> _has_field_{};
15440 };
15441 
15442 }  // namespace perfetto
15443 }  // namespace protos
15444 }  // namespace gen
15445 
15446 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_TRACE_STATS_PROTO_CPP_H_
15447 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
15448 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
15449 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
15450 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
15451 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
15452 #if defined(__GNUC__) || defined(__clang__)
15453 #pragma GCC diagnostic push
15454 #pragma GCC diagnostic ignored "-Wfloat-equal"
15455 #endif
15456 // gen_amalgamated expanded: #include "protos/perfetto/common/trace_stats.gen.h"
15457 
15458 namespace perfetto {
15459 namespace protos {
15460 namespace gen {
15461 
15462 TraceStats::TraceStats() = default;
15463 TraceStats::~TraceStats() = default;
15464 TraceStats::TraceStats(const TraceStats&) = default;
15465 TraceStats& TraceStats::operator=(const TraceStats&) = default;
15466 TraceStats::TraceStats(TraceStats&&) noexcept = default;
15467 TraceStats& TraceStats::operator=(TraceStats&&) = default;
15468 
operator ==(const TraceStats & other) const15469 bool TraceStats::operator==(const TraceStats& other) const {
15470   return unknown_fields_ == other.unknown_fields_
15471    && buffer_stats_ == other.buffer_stats_
15472    && producers_connected_ == other.producers_connected_
15473    && producers_seen_ == other.producers_seen_
15474    && data_sources_registered_ == other.data_sources_registered_
15475    && data_sources_seen_ == other.data_sources_seen_
15476    && tracing_sessions_ == other.tracing_sessions_
15477    && total_buffers_ == other.total_buffers_
15478    && chunks_discarded_ == other.chunks_discarded_
15479    && patches_discarded_ == other.patches_discarded_
15480    && invalid_packets_ == other.invalid_packets_
15481    && filter_stats_ == other.filter_stats_;
15482 }
15483 
buffer_stats_size() const15484 int TraceStats::buffer_stats_size() const { return static_cast<int>(buffer_stats_.size()); }
clear_buffer_stats()15485 void TraceStats::clear_buffer_stats() { buffer_stats_.clear(); }
add_buffer_stats()15486 TraceStats_BufferStats* TraceStats::add_buffer_stats() { buffer_stats_.emplace_back(); return &buffer_stats_.back(); }
ParseFromArray(const void * raw,size_t size)15487 bool TraceStats::ParseFromArray(const void* raw, size_t size) {
15488   buffer_stats_.clear();
15489   unknown_fields_.clear();
15490   bool packed_error = false;
15491 
15492   ::protozero::ProtoDecoder dec(raw, size);
15493   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
15494     if (field.id() < _has_field_.size()) {
15495       _has_field_.set(field.id());
15496     }
15497     switch (field.id()) {
15498       case 1 /* buffer_stats */:
15499         buffer_stats_.emplace_back();
15500         buffer_stats_.back().ParseFromArray(field.data(), field.size());
15501         break;
15502       case 2 /* producers_connected */:
15503         field.get(&producers_connected_);
15504         break;
15505       case 3 /* producers_seen */:
15506         field.get(&producers_seen_);
15507         break;
15508       case 4 /* data_sources_registered */:
15509         field.get(&data_sources_registered_);
15510         break;
15511       case 5 /* data_sources_seen */:
15512         field.get(&data_sources_seen_);
15513         break;
15514       case 6 /* tracing_sessions */:
15515         field.get(&tracing_sessions_);
15516         break;
15517       case 7 /* total_buffers */:
15518         field.get(&total_buffers_);
15519         break;
15520       case 8 /* chunks_discarded */:
15521         field.get(&chunks_discarded_);
15522         break;
15523       case 9 /* patches_discarded */:
15524         field.get(&patches_discarded_);
15525         break;
15526       case 10 /* invalid_packets */:
15527         field.get(&invalid_packets_);
15528         break;
15529       case 11 /* filter_stats */:
15530         (*filter_stats_).ParseFromArray(field.data(), field.size());
15531         break;
15532       default:
15533         field.SerializeAndAppendTo(&unknown_fields_);
15534         break;
15535     }
15536   }
15537   return !packed_error && !dec.bytes_left();
15538 }
15539 
SerializeAsString() const15540 std::string TraceStats::SerializeAsString() const {
15541   ::protozero::HeapBuffered<::protozero::Message> msg;
15542   Serialize(msg.get());
15543   return msg.SerializeAsString();
15544 }
15545 
SerializeAsArray() const15546 std::vector<uint8_t> TraceStats::SerializeAsArray() const {
15547   ::protozero::HeapBuffered<::protozero::Message> msg;
15548   Serialize(msg.get());
15549   return msg.SerializeAsArray();
15550 }
15551 
Serialize(::protozero::Message * msg) const15552 void TraceStats::Serialize(::protozero::Message* msg) const {
15553   // Field 1: buffer_stats
15554   for (auto& it : buffer_stats_) {
15555     it.Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
15556   }
15557 
15558   // Field 2: producers_connected
15559   if (_has_field_[2]) {
15560     msg->AppendVarInt(2, producers_connected_);
15561   }
15562 
15563   // Field 3: producers_seen
15564   if (_has_field_[3]) {
15565     msg->AppendVarInt(3, producers_seen_);
15566   }
15567 
15568   // Field 4: data_sources_registered
15569   if (_has_field_[4]) {
15570     msg->AppendVarInt(4, data_sources_registered_);
15571   }
15572 
15573   // Field 5: data_sources_seen
15574   if (_has_field_[5]) {
15575     msg->AppendVarInt(5, data_sources_seen_);
15576   }
15577 
15578   // Field 6: tracing_sessions
15579   if (_has_field_[6]) {
15580     msg->AppendVarInt(6, tracing_sessions_);
15581   }
15582 
15583   // Field 7: total_buffers
15584   if (_has_field_[7]) {
15585     msg->AppendVarInt(7, total_buffers_);
15586   }
15587 
15588   // Field 8: chunks_discarded
15589   if (_has_field_[8]) {
15590     msg->AppendVarInt(8, chunks_discarded_);
15591   }
15592 
15593   // Field 9: patches_discarded
15594   if (_has_field_[9]) {
15595     msg->AppendVarInt(9, patches_discarded_);
15596   }
15597 
15598   // Field 10: invalid_packets
15599   if (_has_field_[10]) {
15600     msg->AppendVarInt(10, invalid_packets_);
15601   }
15602 
15603   // Field 11: filter_stats
15604   if (_has_field_[11]) {
15605     (*filter_stats_).Serialize(msg->BeginNestedMessage<::protozero::Message>(11));
15606   }
15607 
15608   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
15609 }
15610 
15611 
15612 TraceStats_FilterStats::TraceStats_FilterStats() = default;
15613 TraceStats_FilterStats::~TraceStats_FilterStats() = default;
15614 TraceStats_FilterStats::TraceStats_FilterStats(const TraceStats_FilterStats&) = default;
15615 TraceStats_FilterStats& TraceStats_FilterStats::operator=(const TraceStats_FilterStats&) = default;
15616 TraceStats_FilterStats::TraceStats_FilterStats(TraceStats_FilterStats&&) noexcept = default;
15617 TraceStats_FilterStats& TraceStats_FilterStats::operator=(TraceStats_FilterStats&&) = default;
15618 
operator ==(const TraceStats_FilterStats & other) const15619 bool TraceStats_FilterStats::operator==(const TraceStats_FilterStats& other) const {
15620   return unknown_fields_ == other.unknown_fields_
15621    && input_packets_ == other.input_packets_
15622    && input_bytes_ == other.input_bytes_
15623    && output_bytes_ == other.output_bytes_
15624    && errors_ == other.errors_;
15625 }
15626 
ParseFromArray(const void * raw,size_t size)15627 bool TraceStats_FilterStats::ParseFromArray(const void* raw, size_t size) {
15628   unknown_fields_.clear();
15629   bool packed_error = false;
15630 
15631   ::protozero::ProtoDecoder dec(raw, size);
15632   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
15633     if (field.id() < _has_field_.size()) {
15634       _has_field_.set(field.id());
15635     }
15636     switch (field.id()) {
15637       case 1 /* input_packets */:
15638         field.get(&input_packets_);
15639         break;
15640       case 2 /* input_bytes */:
15641         field.get(&input_bytes_);
15642         break;
15643       case 3 /* output_bytes */:
15644         field.get(&output_bytes_);
15645         break;
15646       case 4 /* errors */:
15647         field.get(&errors_);
15648         break;
15649       default:
15650         field.SerializeAndAppendTo(&unknown_fields_);
15651         break;
15652     }
15653   }
15654   return !packed_error && !dec.bytes_left();
15655 }
15656 
SerializeAsString() const15657 std::string TraceStats_FilterStats::SerializeAsString() const {
15658   ::protozero::HeapBuffered<::protozero::Message> msg;
15659   Serialize(msg.get());
15660   return msg.SerializeAsString();
15661 }
15662 
SerializeAsArray() const15663 std::vector<uint8_t> TraceStats_FilterStats::SerializeAsArray() const {
15664   ::protozero::HeapBuffered<::protozero::Message> msg;
15665   Serialize(msg.get());
15666   return msg.SerializeAsArray();
15667 }
15668 
Serialize(::protozero::Message * msg) const15669 void TraceStats_FilterStats::Serialize(::protozero::Message* msg) const {
15670   // Field 1: input_packets
15671   if (_has_field_[1]) {
15672     msg->AppendVarInt(1, input_packets_);
15673   }
15674 
15675   // Field 2: input_bytes
15676   if (_has_field_[2]) {
15677     msg->AppendVarInt(2, input_bytes_);
15678   }
15679 
15680   // Field 3: output_bytes
15681   if (_has_field_[3]) {
15682     msg->AppendVarInt(3, output_bytes_);
15683   }
15684 
15685   // Field 4: errors
15686   if (_has_field_[4]) {
15687     msg->AppendVarInt(4, errors_);
15688   }
15689 
15690   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
15691 }
15692 
15693 
15694 TraceStats_BufferStats::TraceStats_BufferStats() = default;
15695 TraceStats_BufferStats::~TraceStats_BufferStats() = default;
15696 TraceStats_BufferStats::TraceStats_BufferStats(const TraceStats_BufferStats&) = default;
15697 TraceStats_BufferStats& TraceStats_BufferStats::operator=(const TraceStats_BufferStats&) = default;
15698 TraceStats_BufferStats::TraceStats_BufferStats(TraceStats_BufferStats&&) noexcept = default;
15699 TraceStats_BufferStats& TraceStats_BufferStats::operator=(TraceStats_BufferStats&&) = default;
15700 
operator ==(const TraceStats_BufferStats & other) const15701 bool TraceStats_BufferStats::operator==(const TraceStats_BufferStats& other) const {
15702   return unknown_fields_ == other.unknown_fields_
15703    && buffer_size_ == other.buffer_size_
15704    && bytes_written_ == other.bytes_written_
15705    && bytes_overwritten_ == other.bytes_overwritten_
15706    && bytes_read_ == other.bytes_read_
15707    && padding_bytes_written_ == other.padding_bytes_written_
15708    && padding_bytes_cleared_ == other.padding_bytes_cleared_
15709    && chunks_written_ == other.chunks_written_
15710    && chunks_rewritten_ == other.chunks_rewritten_
15711    && chunks_overwritten_ == other.chunks_overwritten_
15712    && chunks_discarded_ == other.chunks_discarded_
15713    && chunks_read_ == other.chunks_read_
15714    && chunks_committed_out_of_order_ == other.chunks_committed_out_of_order_
15715    && write_wrap_count_ == other.write_wrap_count_
15716    && patches_succeeded_ == other.patches_succeeded_
15717    && patches_failed_ == other.patches_failed_
15718    && readaheads_succeeded_ == other.readaheads_succeeded_
15719    && readaheads_failed_ == other.readaheads_failed_
15720    && abi_violations_ == other.abi_violations_
15721    && trace_writer_packet_loss_ == other.trace_writer_packet_loss_;
15722 }
15723 
ParseFromArray(const void * raw,size_t size)15724 bool TraceStats_BufferStats::ParseFromArray(const void* raw, size_t size) {
15725   unknown_fields_.clear();
15726   bool packed_error = false;
15727 
15728   ::protozero::ProtoDecoder dec(raw, size);
15729   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
15730     if (field.id() < _has_field_.size()) {
15731       _has_field_.set(field.id());
15732     }
15733     switch (field.id()) {
15734       case 12 /* buffer_size */:
15735         field.get(&buffer_size_);
15736         break;
15737       case 1 /* bytes_written */:
15738         field.get(&bytes_written_);
15739         break;
15740       case 13 /* bytes_overwritten */:
15741         field.get(&bytes_overwritten_);
15742         break;
15743       case 14 /* bytes_read */:
15744         field.get(&bytes_read_);
15745         break;
15746       case 15 /* padding_bytes_written */:
15747         field.get(&padding_bytes_written_);
15748         break;
15749       case 16 /* padding_bytes_cleared */:
15750         field.get(&padding_bytes_cleared_);
15751         break;
15752       case 2 /* chunks_written */:
15753         field.get(&chunks_written_);
15754         break;
15755       case 10 /* chunks_rewritten */:
15756         field.get(&chunks_rewritten_);
15757         break;
15758       case 3 /* chunks_overwritten */:
15759         field.get(&chunks_overwritten_);
15760         break;
15761       case 18 /* chunks_discarded */:
15762         field.get(&chunks_discarded_);
15763         break;
15764       case 17 /* chunks_read */:
15765         field.get(&chunks_read_);
15766         break;
15767       case 11 /* chunks_committed_out_of_order */:
15768         field.get(&chunks_committed_out_of_order_);
15769         break;
15770       case 4 /* write_wrap_count */:
15771         field.get(&write_wrap_count_);
15772         break;
15773       case 5 /* patches_succeeded */:
15774         field.get(&patches_succeeded_);
15775         break;
15776       case 6 /* patches_failed */:
15777         field.get(&patches_failed_);
15778         break;
15779       case 7 /* readaheads_succeeded */:
15780         field.get(&readaheads_succeeded_);
15781         break;
15782       case 8 /* readaheads_failed */:
15783         field.get(&readaheads_failed_);
15784         break;
15785       case 9 /* abi_violations */:
15786         field.get(&abi_violations_);
15787         break;
15788       case 19 /* trace_writer_packet_loss */:
15789         field.get(&trace_writer_packet_loss_);
15790         break;
15791       default:
15792         field.SerializeAndAppendTo(&unknown_fields_);
15793         break;
15794     }
15795   }
15796   return !packed_error && !dec.bytes_left();
15797 }
15798 
SerializeAsString() const15799 std::string TraceStats_BufferStats::SerializeAsString() const {
15800   ::protozero::HeapBuffered<::protozero::Message> msg;
15801   Serialize(msg.get());
15802   return msg.SerializeAsString();
15803 }
15804 
SerializeAsArray() const15805 std::vector<uint8_t> TraceStats_BufferStats::SerializeAsArray() const {
15806   ::protozero::HeapBuffered<::protozero::Message> msg;
15807   Serialize(msg.get());
15808   return msg.SerializeAsArray();
15809 }
15810 
Serialize(::protozero::Message * msg) const15811 void TraceStats_BufferStats::Serialize(::protozero::Message* msg) const {
15812   // Field 12: buffer_size
15813   if (_has_field_[12]) {
15814     msg->AppendVarInt(12, buffer_size_);
15815   }
15816 
15817   // Field 1: bytes_written
15818   if (_has_field_[1]) {
15819     msg->AppendVarInt(1, bytes_written_);
15820   }
15821 
15822   // Field 13: bytes_overwritten
15823   if (_has_field_[13]) {
15824     msg->AppendVarInt(13, bytes_overwritten_);
15825   }
15826 
15827   // Field 14: bytes_read
15828   if (_has_field_[14]) {
15829     msg->AppendVarInt(14, bytes_read_);
15830   }
15831 
15832   // Field 15: padding_bytes_written
15833   if (_has_field_[15]) {
15834     msg->AppendVarInt(15, padding_bytes_written_);
15835   }
15836 
15837   // Field 16: padding_bytes_cleared
15838   if (_has_field_[16]) {
15839     msg->AppendVarInt(16, padding_bytes_cleared_);
15840   }
15841 
15842   // Field 2: chunks_written
15843   if (_has_field_[2]) {
15844     msg->AppendVarInt(2, chunks_written_);
15845   }
15846 
15847   // Field 10: chunks_rewritten
15848   if (_has_field_[10]) {
15849     msg->AppendVarInt(10, chunks_rewritten_);
15850   }
15851 
15852   // Field 3: chunks_overwritten
15853   if (_has_field_[3]) {
15854     msg->AppendVarInt(3, chunks_overwritten_);
15855   }
15856 
15857   // Field 18: chunks_discarded
15858   if (_has_field_[18]) {
15859     msg->AppendVarInt(18, chunks_discarded_);
15860   }
15861 
15862   // Field 17: chunks_read
15863   if (_has_field_[17]) {
15864     msg->AppendVarInt(17, chunks_read_);
15865   }
15866 
15867   // Field 11: chunks_committed_out_of_order
15868   if (_has_field_[11]) {
15869     msg->AppendVarInt(11, chunks_committed_out_of_order_);
15870   }
15871 
15872   // Field 4: write_wrap_count
15873   if (_has_field_[4]) {
15874     msg->AppendVarInt(4, write_wrap_count_);
15875   }
15876 
15877   // Field 5: patches_succeeded
15878   if (_has_field_[5]) {
15879     msg->AppendVarInt(5, patches_succeeded_);
15880   }
15881 
15882   // Field 6: patches_failed
15883   if (_has_field_[6]) {
15884     msg->AppendVarInt(6, patches_failed_);
15885   }
15886 
15887   // Field 7: readaheads_succeeded
15888   if (_has_field_[7]) {
15889     msg->AppendVarInt(7, readaheads_succeeded_);
15890   }
15891 
15892   // Field 8: readaheads_failed
15893   if (_has_field_[8]) {
15894     msg->AppendVarInt(8, readaheads_failed_);
15895   }
15896 
15897   // Field 9: abi_violations
15898   if (_has_field_[9]) {
15899     msg->AppendVarInt(9, abi_violations_);
15900   }
15901 
15902   // Field 19: trace_writer_packet_loss
15903   if (_has_field_[19]) {
15904     msg->AppendVarInt(19, trace_writer_packet_loss_);
15905   }
15906 
15907   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
15908 }
15909 
15910 }  // namespace perfetto
15911 }  // namespace protos
15912 }  // namespace gen
15913 #if defined(__GNUC__) || defined(__clang__)
15914 #pragma GCC diagnostic pop
15915 #endif
15916 // gen_amalgamated begin source: gen/protos/perfetto/common/tracing_service_capabilities.gen.cc
15917 // gen_amalgamated begin header: gen/protos/perfetto/common/tracing_service_capabilities.gen.h
15918 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
15919 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_TRACING_SERVICE_CAPABILITIES_PROTO_CPP_H_
15920 #define PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_TRACING_SERVICE_CAPABILITIES_PROTO_CPP_H_
15921 
15922 #include <stdint.h>
15923 #include <bitset>
15924 #include <vector>
15925 #include <string>
15926 #include <type_traits>
15927 
15928 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
15929 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
15930 // gen_amalgamated expanded: #include "perfetto/base/export.h"
15931 
15932 namespace perfetto {
15933 namespace protos {
15934 namespace gen {
15935 class TracingServiceCapabilities;
15936 enum ObservableEvents_Type : int;
15937 }  // namespace perfetto
15938 }  // namespace protos
15939 }  // namespace gen
15940 
15941 namespace protozero {
15942 class Message;
15943 }  // namespace protozero
15944 
15945 namespace perfetto {
15946 namespace protos {
15947 namespace gen {
15948 
15949 class PERFETTO_EXPORT TracingServiceCapabilities : public ::protozero::CppMessageObj {
15950  public:
15951   enum FieldNumbers {
15952     kHasQueryCapabilitiesFieldNumber = 1,
15953     kObservableEventsFieldNumber = 2,
15954     kHasTraceConfigOutputPathFieldNumber = 3,
15955   };
15956 
15957   TracingServiceCapabilities();
15958   ~TracingServiceCapabilities() override;
15959   TracingServiceCapabilities(TracingServiceCapabilities&&) noexcept;
15960   TracingServiceCapabilities& operator=(TracingServiceCapabilities&&);
15961   TracingServiceCapabilities(const TracingServiceCapabilities&);
15962   TracingServiceCapabilities& operator=(const TracingServiceCapabilities&);
15963   bool operator==(const TracingServiceCapabilities&) const;
operator !=(const TracingServiceCapabilities & other) const15964   bool operator!=(const TracingServiceCapabilities& other) const { return !(*this == other); }
15965 
15966   bool ParseFromArray(const void*, size_t) override;
15967   std::string SerializeAsString() const override;
15968   std::vector<uint8_t> SerializeAsArray() const override;
15969   void Serialize(::protozero::Message*) const;
15970 
has_has_query_capabilities() const15971   bool has_has_query_capabilities() const { return _has_field_[1]; }
has_query_capabilities() const15972   bool has_query_capabilities() const { return has_query_capabilities_; }
set_has_query_capabilities(bool value)15973   void set_has_query_capabilities(bool value) { has_query_capabilities_ = value; _has_field_.set(1); }
15974 
observable_events() const15975   const std::vector<ObservableEvents_Type>& observable_events() const { return observable_events_; }
mutable_observable_events()15976   std::vector<ObservableEvents_Type>* mutable_observable_events() { return &observable_events_; }
observable_events_size() const15977   int observable_events_size() const { return static_cast<int>(observable_events_.size()); }
clear_observable_events()15978   void clear_observable_events() { observable_events_.clear(); }
add_observable_events(ObservableEvents_Type value)15979   void add_observable_events(ObservableEvents_Type value) { observable_events_.emplace_back(value); }
add_observable_events()15980   ObservableEvents_Type* add_observable_events() { observable_events_.emplace_back(); return &observable_events_.back(); }
15981 
has_has_trace_config_output_path() const15982   bool has_has_trace_config_output_path() const { return _has_field_[3]; }
has_trace_config_output_path() const15983   bool has_trace_config_output_path() const { return has_trace_config_output_path_; }
set_has_trace_config_output_path(bool value)15984   void set_has_trace_config_output_path(bool value) { has_trace_config_output_path_ = value; _has_field_.set(3); }
15985 
15986  private:
15987   bool has_query_capabilities_{};
15988   std::vector<ObservableEvents_Type> observable_events_;
15989   bool has_trace_config_output_path_{};
15990 
15991   // Allows to preserve unknown protobuf fields for compatibility
15992   // with future versions of .proto files.
15993   std::string unknown_fields_;
15994 
15995   std::bitset<4> _has_field_{};
15996 };
15997 
15998 }  // namespace perfetto
15999 }  // namespace protos
16000 }  // namespace gen
16001 
16002 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_TRACING_SERVICE_CAPABILITIES_PROTO_CPP_H_
16003 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
16004 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
16005 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
16006 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
16007 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
16008 #if defined(__GNUC__) || defined(__clang__)
16009 #pragma GCC diagnostic push
16010 #pragma GCC diagnostic ignored "-Wfloat-equal"
16011 #endif
16012 // gen_amalgamated expanded: #include "protos/perfetto/common/tracing_service_capabilities.gen.h"
16013 // gen_amalgamated expanded: #include "protos/perfetto/common/observable_events.gen.h"
16014 
16015 namespace perfetto {
16016 namespace protos {
16017 namespace gen {
16018 
16019 TracingServiceCapabilities::TracingServiceCapabilities() = default;
16020 TracingServiceCapabilities::~TracingServiceCapabilities() = default;
16021 TracingServiceCapabilities::TracingServiceCapabilities(const TracingServiceCapabilities&) = default;
16022 TracingServiceCapabilities& TracingServiceCapabilities::operator=(const TracingServiceCapabilities&) = default;
16023 TracingServiceCapabilities::TracingServiceCapabilities(TracingServiceCapabilities&&) noexcept = default;
16024 TracingServiceCapabilities& TracingServiceCapabilities::operator=(TracingServiceCapabilities&&) = default;
16025 
operator ==(const TracingServiceCapabilities & other) const16026 bool TracingServiceCapabilities::operator==(const TracingServiceCapabilities& other) const {
16027   return unknown_fields_ == other.unknown_fields_
16028    && has_query_capabilities_ == other.has_query_capabilities_
16029    && observable_events_ == other.observable_events_
16030    && has_trace_config_output_path_ == other.has_trace_config_output_path_;
16031 }
16032 
ParseFromArray(const void * raw,size_t size)16033 bool TracingServiceCapabilities::ParseFromArray(const void* raw, size_t size) {
16034   observable_events_.clear();
16035   unknown_fields_.clear();
16036   bool packed_error = false;
16037 
16038   ::protozero::ProtoDecoder dec(raw, size);
16039   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
16040     if (field.id() < _has_field_.size()) {
16041       _has_field_.set(field.id());
16042     }
16043     switch (field.id()) {
16044       case 1 /* has_query_capabilities */:
16045         field.get(&has_query_capabilities_);
16046         break;
16047       case 2 /* observable_events */:
16048         observable_events_.emplace_back();
16049         field.get(&observable_events_.back());
16050         break;
16051       case 3 /* has_trace_config_output_path */:
16052         field.get(&has_trace_config_output_path_);
16053         break;
16054       default:
16055         field.SerializeAndAppendTo(&unknown_fields_);
16056         break;
16057     }
16058   }
16059   return !packed_error && !dec.bytes_left();
16060 }
16061 
SerializeAsString() const16062 std::string TracingServiceCapabilities::SerializeAsString() const {
16063   ::protozero::HeapBuffered<::protozero::Message> msg;
16064   Serialize(msg.get());
16065   return msg.SerializeAsString();
16066 }
16067 
SerializeAsArray() const16068 std::vector<uint8_t> TracingServiceCapabilities::SerializeAsArray() const {
16069   ::protozero::HeapBuffered<::protozero::Message> msg;
16070   Serialize(msg.get());
16071   return msg.SerializeAsArray();
16072 }
16073 
Serialize(::protozero::Message * msg) const16074 void TracingServiceCapabilities::Serialize(::protozero::Message* msg) const {
16075   // Field 1: has_query_capabilities
16076   if (_has_field_[1]) {
16077     msg->AppendTinyVarInt(1, has_query_capabilities_);
16078   }
16079 
16080   // Field 2: observable_events
16081   for (auto& it : observable_events_) {
16082     msg->AppendVarInt(2, it);
16083   }
16084 
16085   // Field 3: has_trace_config_output_path
16086   if (_has_field_[3]) {
16087     msg->AppendTinyVarInt(3, has_trace_config_output_path_);
16088   }
16089 
16090   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
16091 }
16092 
16093 }  // namespace perfetto
16094 }  // namespace protos
16095 }  // namespace gen
16096 #if defined(__GNUC__) || defined(__clang__)
16097 #pragma GCC diagnostic pop
16098 #endif
16099 // gen_amalgamated begin source: gen/protos/perfetto/common/tracing_service_state.gen.cc
16100 // gen_amalgamated begin header: gen/protos/perfetto/common/tracing_service_state.gen.h
16101 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
16102 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_TRACING_SERVICE_STATE_PROTO_CPP_H_
16103 #define PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_TRACING_SERVICE_STATE_PROTO_CPP_H_
16104 
16105 #include <stdint.h>
16106 #include <bitset>
16107 #include <vector>
16108 #include <string>
16109 #include <type_traits>
16110 
16111 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
16112 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
16113 // gen_amalgamated expanded: #include "perfetto/base/export.h"
16114 
16115 namespace perfetto {
16116 namespace protos {
16117 namespace gen {
16118 class TracingServiceState;
16119 class TracingServiceState_DataSource;
16120 class DataSourceDescriptor;
16121 class TracingServiceState_Producer;
16122 }  // namespace perfetto
16123 }  // namespace protos
16124 }  // namespace gen
16125 
16126 namespace protozero {
16127 class Message;
16128 }  // namespace protozero
16129 
16130 namespace perfetto {
16131 namespace protos {
16132 namespace gen {
16133 
16134 class PERFETTO_EXPORT TracingServiceState : public ::protozero::CppMessageObj {
16135  public:
16136   using Producer = TracingServiceState_Producer;
16137   using DataSource = TracingServiceState_DataSource;
16138   enum FieldNumbers {
16139     kProducersFieldNumber = 1,
16140     kDataSourcesFieldNumber = 2,
16141     kNumSessionsFieldNumber = 3,
16142     kNumSessionsStartedFieldNumber = 4,
16143     kTracingServiceVersionFieldNumber = 5,
16144   };
16145 
16146   TracingServiceState();
16147   ~TracingServiceState() override;
16148   TracingServiceState(TracingServiceState&&) noexcept;
16149   TracingServiceState& operator=(TracingServiceState&&);
16150   TracingServiceState(const TracingServiceState&);
16151   TracingServiceState& operator=(const TracingServiceState&);
16152   bool operator==(const TracingServiceState&) const;
operator !=(const TracingServiceState & other) const16153   bool operator!=(const TracingServiceState& other) const { return !(*this == other); }
16154 
16155   bool ParseFromArray(const void*, size_t) override;
16156   std::string SerializeAsString() const override;
16157   std::vector<uint8_t> SerializeAsArray() const override;
16158   void Serialize(::protozero::Message*) const;
16159 
producers() const16160   const std::vector<TracingServiceState_Producer>& producers() const { return producers_; }
mutable_producers()16161   std::vector<TracingServiceState_Producer>* mutable_producers() { return &producers_; }
16162   int producers_size() const;
16163   void clear_producers();
16164   TracingServiceState_Producer* add_producers();
16165 
data_sources() const16166   const std::vector<TracingServiceState_DataSource>& data_sources() const { return data_sources_; }
mutable_data_sources()16167   std::vector<TracingServiceState_DataSource>* mutable_data_sources() { return &data_sources_; }
16168   int data_sources_size() const;
16169   void clear_data_sources();
16170   TracingServiceState_DataSource* add_data_sources();
16171 
has_num_sessions() const16172   bool has_num_sessions() const { return _has_field_[3]; }
num_sessions() const16173   int32_t num_sessions() const { return num_sessions_; }
set_num_sessions(int32_t value)16174   void set_num_sessions(int32_t value) { num_sessions_ = value; _has_field_.set(3); }
16175 
has_num_sessions_started() const16176   bool has_num_sessions_started() const { return _has_field_[4]; }
num_sessions_started() const16177   int32_t num_sessions_started() const { return num_sessions_started_; }
set_num_sessions_started(int32_t value)16178   void set_num_sessions_started(int32_t value) { num_sessions_started_ = value; _has_field_.set(4); }
16179 
has_tracing_service_version() const16180   bool has_tracing_service_version() const { return _has_field_[5]; }
tracing_service_version() const16181   const std::string& tracing_service_version() const { return tracing_service_version_; }
set_tracing_service_version(const std::string & value)16182   void set_tracing_service_version(const std::string& value) { tracing_service_version_ = value; _has_field_.set(5); }
16183 
16184  private:
16185   std::vector<TracingServiceState_Producer> producers_;
16186   std::vector<TracingServiceState_DataSource> data_sources_;
16187   int32_t num_sessions_{};
16188   int32_t num_sessions_started_{};
16189   std::string tracing_service_version_{};
16190 
16191   // Allows to preserve unknown protobuf fields for compatibility
16192   // with future versions of .proto files.
16193   std::string unknown_fields_;
16194 
16195   std::bitset<6> _has_field_{};
16196 };
16197 
16198 
16199 class PERFETTO_EXPORT TracingServiceState_DataSource : public ::protozero::CppMessageObj {
16200  public:
16201   enum FieldNumbers {
16202     kDsDescriptorFieldNumber = 1,
16203     kProducerIdFieldNumber = 2,
16204   };
16205 
16206   TracingServiceState_DataSource();
16207   ~TracingServiceState_DataSource() override;
16208   TracingServiceState_DataSource(TracingServiceState_DataSource&&) noexcept;
16209   TracingServiceState_DataSource& operator=(TracingServiceState_DataSource&&);
16210   TracingServiceState_DataSource(const TracingServiceState_DataSource&);
16211   TracingServiceState_DataSource& operator=(const TracingServiceState_DataSource&);
16212   bool operator==(const TracingServiceState_DataSource&) const;
operator !=(const TracingServiceState_DataSource & other) const16213   bool operator!=(const TracingServiceState_DataSource& other) const { return !(*this == other); }
16214 
16215   bool ParseFromArray(const void*, size_t) override;
16216   std::string SerializeAsString() const override;
16217   std::vector<uint8_t> SerializeAsArray() const override;
16218   void Serialize(::protozero::Message*) const;
16219 
has_ds_descriptor() const16220   bool has_ds_descriptor() const { return _has_field_[1]; }
ds_descriptor() const16221   const DataSourceDescriptor& ds_descriptor() const { return *ds_descriptor_; }
mutable_ds_descriptor()16222   DataSourceDescriptor* mutable_ds_descriptor() { _has_field_.set(1); return ds_descriptor_.get(); }
16223 
has_producer_id() const16224   bool has_producer_id() const { return _has_field_[2]; }
producer_id() const16225   int32_t producer_id() const { return producer_id_; }
set_producer_id(int32_t value)16226   void set_producer_id(int32_t value) { producer_id_ = value; _has_field_.set(2); }
16227 
16228  private:
16229   ::protozero::CopyablePtr<DataSourceDescriptor> ds_descriptor_;
16230   int32_t producer_id_{};
16231 
16232   // Allows to preserve unknown protobuf fields for compatibility
16233   // with future versions of .proto files.
16234   std::string unknown_fields_;
16235 
16236   std::bitset<3> _has_field_{};
16237 };
16238 
16239 
16240 class PERFETTO_EXPORT TracingServiceState_Producer : public ::protozero::CppMessageObj {
16241  public:
16242   enum FieldNumbers {
16243     kIdFieldNumber = 1,
16244     kNameFieldNumber = 2,
16245     kUidFieldNumber = 3,
16246     kSdkVersionFieldNumber = 4,
16247   };
16248 
16249   TracingServiceState_Producer();
16250   ~TracingServiceState_Producer() override;
16251   TracingServiceState_Producer(TracingServiceState_Producer&&) noexcept;
16252   TracingServiceState_Producer& operator=(TracingServiceState_Producer&&);
16253   TracingServiceState_Producer(const TracingServiceState_Producer&);
16254   TracingServiceState_Producer& operator=(const TracingServiceState_Producer&);
16255   bool operator==(const TracingServiceState_Producer&) const;
operator !=(const TracingServiceState_Producer & other) const16256   bool operator!=(const TracingServiceState_Producer& other) const { return !(*this == other); }
16257 
16258   bool ParseFromArray(const void*, size_t) override;
16259   std::string SerializeAsString() const override;
16260   std::vector<uint8_t> SerializeAsArray() const override;
16261   void Serialize(::protozero::Message*) const;
16262 
has_id() const16263   bool has_id() const { return _has_field_[1]; }
id() const16264   int32_t id() const { return id_; }
set_id(int32_t value)16265   void set_id(int32_t value) { id_ = value; _has_field_.set(1); }
16266 
has_name() const16267   bool has_name() const { return _has_field_[2]; }
name() const16268   const std::string& name() const { return name_; }
set_name(const std::string & value)16269   void set_name(const std::string& value) { name_ = value; _has_field_.set(2); }
16270 
has_uid() const16271   bool has_uid() const { return _has_field_[3]; }
uid() const16272   int32_t uid() const { return uid_; }
set_uid(int32_t value)16273   void set_uid(int32_t value) { uid_ = value; _has_field_.set(3); }
16274 
has_sdk_version() const16275   bool has_sdk_version() const { return _has_field_[4]; }
sdk_version() const16276   const std::string& sdk_version() const { return sdk_version_; }
set_sdk_version(const std::string & value)16277   void set_sdk_version(const std::string& value) { sdk_version_ = value; _has_field_.set(4); }
16278 
16279  private:
16280   int32_t id_{};
16281   std::string name_{};
16282   int32_t uid_{};
16283   std::string sdk_version_{};
16284 
16285   // Allows to preserve unknown protobuf fields for compatibility
16286   // with future versions of .proto files.
16287   std::string unknown_fields_;
16288 
16289   std::bitset<5> _has_field_{};
16290 };
16291 
16292 }  // namespace perfetto
16293 }  // namespace protos
16294 }  // namespace gen
16295 
16296 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_TRACING_SERVICE_STATE_PROTO_CPP_H_
16297 // gen_amalgamated begin header: gen/protos/perfetto/common/track_event_descriptor.gen.h
16298 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
16299 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_TRACK_EVENT_DESCRIPTOR_PROTO_CPP_H_
16300 #define PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_TRACK_EVENT_DESCRIPTOR_PROTO_CPP_H_
16301 
16302 #include <stdint.h>
16303 #include <bitset>
16304 #include <vector>
16305 #include <string>
16306 #include <type_traits>
16307 
16308 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
16309 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
16310 // gen_amalgamated expanded: #include "perfetto/base/export.h"
16311 
16312 namespace perfetto {
16313 namespace protos {
16314 namespace gen {
16315 class TrackEventDescriptor;
16316 class TrackEventCategory;
16317 }  // namespace perfetto
16318 }  // namespace protos
16319 }  // namespace gen
16320 
16321 namespace protozero {
16322 class Message;
16323 }  // namespace protozero
16324 
16325 namespace perfetto {
16326 namespace protos {
16327 namespace gen {
16328 
16329 class PERFETTO_EXPORT TrackEventDescriptor : public ::protozero::CppMessageObj {
16330  public:
16331   enum FieldNumbers {
16332     kAvailableCategoriesFieldNumber = 1,
16333   };
16334 
16335   TrackEventDescriptor();
16336   ~TrackEventDescriptor() override;
16337   TrackEventDescriptor(TrackEventDescriptor&&) noexcept;
16338   TrackEventDescriptor& operator=(TrackEventDescriptor&&);
16339   TrackEventDescriptor(const TrackEventDescriptor&);
16340   TrackEventDescriptor& operator=(const TrackEventDescriptor&);
16341   bool operator==(const TrackEventDescriptor&) const;
operator !=(const TrackEventDescriptor & other) const16342   bool operator!=(const TrackEventDescriptor& other) const { return !(*this == other); }
16343 
16344   bool ParseFromArray(const void*, size_t) override;
16345   std::string SerializeAsString() const override;
16346   std::vector<uint8_t> SerializeAsArray() const override;
16347   void Serialize(::protozero::Message*) const;
16348 
available_categories() const16349   const std::vector<TrackEventCategory>& available_categories() const { return available_categories_; }
mutable_available_categories()16350   std::vector<TrackEventCategory>* mutable_available_categories() { return &available_categories_; }
16351   int available_categories_size() const;
16352   void clear_available_categories();
16353   TrackEventCategory* add_available_categories();
16354 
16355  private:
16356   std::vector<TrackEventCategory> available_categories_;
16357 
16358   // Allows to preserve unknown protobuf fields for compatibility
16359   // with future versions of .proto files.
16360   std::string unknown_fields_;
16361 
16362   std::bitset<2> _has_field_{};
16363 };
16364 
16365 
16366 class PERFETTO_EXPORT TrackEventCategory : public ::protozero::CppMessageObj {
16367  public:
16368   enum FieldNumbers {
16369     kNameFieldNumber = 1,
16370     kDescriptionFieldNumber = 2,
16371     kTagsFieldNumber = 3,
16372   };
16373 
16374   TrackEventCategory();
16375   ~TrackEventCategory() override;
16376   TrackEventCategory(TrackEventCategory&&) noexcept;
16377   TrackEventCategory& operator=(TrackEventCategory&&);
16378   TrackEventCategory(const TrackEventCategory&);
16379   TrackEventCategory& operator=(const TrackEventCategory&);
16380   bool operator==(const TrackEventCategory&) const;
operator !=(const TrackEventCategory & other) const16381   bool operator!=(const TrackEventCategory& other) const { return !(*this == other); }
16382 
16383   bool ParseFromArray(const void*, size_t) override;
16384   std::string SerializeAsString() const override;
16385   std::vector<uint8_t> SerializeAsArray() const override;
16386   void Serialize(::protozero::Message*) const;
16387 
has_name() const16388   bool has_name() const { return _has_field_[1]; }
name() const16389   const std::string& name() const { return name_; }
set_name(const std::string & value)16390   void set_name(const std::string& value) { name_ = value; _has_field_.set(1); }
16391 
has_description() const16392   bool has_description() const { return _has_field_[2]; }
description() const16393   const std::string& description() const { return description_; }
set_description(const std::string & value)16394   void set_description(const std::string& value) { description_ = value; _has_field_.set(2); }
16395 
tags() const16396   const std::vector<std::string>& tags() const { return tags_; }
mutable_tags()16397   std::vector<std::string>* mutable_tags() { return &tags_; }
tags_size() const16398   int tags_size() const { return static_cast<int>(tags_.size()); }
clear_tags()16399   void clear_tags() { tags_.clear(); }
add_tags(std::string value)16400   void add_tags(std::string value) { tags_.emplace_back(value); }
add_tags()16401   std::string* add_tags() { tags_.emplace_back(); return &tags_.back(); }
16402 
16403  private:
16404   std::string name_{};
16405   std::string description_{};
16406   std::vector<std::string> tags_;
16407 
16408   // Allows to preserve unknown protobuf fields for compatibility
16409   // with future versions of .proto files.
16410   std::string unknown_fields_;
16411 
16412   std::bitset<4> _has_field_{};
16413 };
16414 
16415 }  // namespace perfetto
16416 }  // namespace protos
16417 }  // namespace gen
16418 
16419 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_TRACK_EVENT_DESCRIPTOR_PROTO_CPP_H_
16420 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
16421 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
16422 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
16423 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
16424 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
16425 #if defined(__GNUC__) || defined(__clang__)
16426 #pragma GCC diagnostic push
16427 #pragma GCC diagnostic ignored "-Wfloat-equal"
16428 #endif
16429 // gen_amalgamated expanded: #include "protos/perfetto/common/tracing_service_state.gen.h"
16430 // gen_amalgamated expanded: #include "protos/perfetto/common/data_source_descriptor.gen.h"
16431 // gen_amalgamated expanded: #include "protos/perfetto/common/track_event_descriptor.gen.h"
16432 // gen_amalgamated expanded: #include "protos/perfetto/common/gpu_counter_descriptor.gen.h"
16433 
16434 namespace perfetto {
16435 namespace protos {
16436 namespace gen {
16437 
16438 TracingServiceState::TracingServiceState() = default;
16439 TracingServiceState::~TracingServiceState() = default;
16440 TracingServiceState::TracingServiceState(const TracingServiceState&) = default;
16441 TracingServiceState& TracingServiceState::operator=(const TracingServiceState&) = default;
16442 TracingServiceState::TracingServiceState(TracingServiceState&&) noexcept = default;
16443 TracingServiceState& TracingServiceState::operator=(TracingServiceState&&) = default;
16444 
operator ==(const TracingServiceState & other) const16445 bool TracingServiceState::operator==(const TracingServiceState& other) const {
16446   return unknown_fields_ == other.unknown_fields_
16447    && producers_ == other.producers_
16448    && data_sources_ == other.data_sources_
16449    && num_sessions_ == other.num_sessions_
16450    && num_sessions_started_ == other.num_sessions_started_
16451    && tracing_service_version_ == other.tracing_service_version_;
16452 }
16453 
producers_size() const16454 int TracingServiceState::producers_size() const { return static_cast<int>(producers_.size()); }
clear_producers()16455 void TracingServiceState::clear_producers() { producers_.clear(); }
add_producers()16456 TracingServiceState_Producer* TracingServiceState::add_producers() { producers_.emplace_back(); return &producers_.back(); }
data_sources_size() const16457 int TracingServiceState::data_sources_size() const { return static_cast<int>(data_sources_.size()); }
clear_data_sources()16458 void TracingServiceState::clear_data_sources() { data_sources_.clear(); }
add_data_sources()16459 TracingServiceState_DataSource* TracingServiceState::add_data_sources() { data_sources_.emplace_back(); return &data_sources_.back(); }
ParseFromArray(const void * raw,size_t size)16460 bool TracingServiceState::ParseFromArray(const void* raw, size_t size) {
16461   producers_.clear();
16462   data_sources_.clear();
16463   unknown_fields_.clear();
16464   bool packed_error = false;
16465 
16466   ::protozero::ProtoDecoder dec(raw, size);
16467   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
16468     if (field.id() < _has_field_.size()) {
16469       _has_field_.set(field.id());
16470     }
16471     switch (field.id()) {
16472       case 1 /* producers */:
16473         producers_.emplace_back();
16474         producers_.back().ParseFromArray(field.data(), field.size());
16475         break;
16476       case 2 /* data_sources */:
16477         data_sources_.emplace_back();
16478         data_sources_.back().ParseFromArray(field.data(), field.size());
16479         break;
16480       case 3 /* num_sessions */:
16481         field.get(&num_sessions_);
16482         break;
16483       case 4 /* num_sessions_started */:
16484         field.get(&num_sessions_started_);
16485         break;
16486       case 5 /* tracing_service_version */:
16487         field.get(&tracing_service_version_);
16488         break;
16489       default:
16490         field.SerializeAndAppendTo(&unknown_fields_);
16491         break;
16492     }
16493   }
16494   return !packed_error && !dec.bytes_left();
16495 }
16496 
SerializeAsString() const16497 std::string TracingServiceState::SerializeAsString() const {
16498   ::protozero::HeapBuffered<::protozero::Message> msg;
16499   Serialize(msg.get());
16500   return msg.SerializeAsString();
16501 }
16502 
SerializeAsArray() const16503 std::vector<uint8_t> TracingServiceState::SerializeAsArray() const {
16504   ::protozero::HeapBuffered<::protozero::Message> msg;
16505   Serialize(msg.get());
16506   return msg.SerializeAsArray();
16507 }
16508 
Serialize(::protozero::Message * msg) const16509 void TracingServiceState::Serialize(::protozero::Message* msg) const {
16510   // Field 1: producers
16511   for (auto& it : producers_) {
16512     it.Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
16513   }
16514 
16515   // Field 2: data_sources
16516   for (auto& it : data_sources_) {
16517     it.Serialize(msg->BeginNestedMessage<::protozero::Message>(2));
16518   }
16519 
16520   // Field 3: num_sessions
16521   if (_has_field_[3]) {
16522     msg->AppendVarInt(3, num_sessions_);
16523   }
16524 
16525   // Field 4: num_sessions_started
16526   if (_has_field_[4]) {
16527     msg->AppendVarInt(4, num_sessions_started_);
16528   }
16529 
16530   // Field 5: tracing_service_version
16531   if (_has_field_[5]) {
16532     msg->AppendString(5, tracing_service_version_);
16533   }
16534 
16535   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
16536 }
16537 
16538 
16539 TracingServiceState_DataSource::TracingServiceState_DataSource() = default;
16540 TracingServiceState_DataSource::~TracingServiceState_DataSource() = default;
16541 TracingServiceState_DataSource::TracingServiceState_DataSource(const TracingServiceState_DataSource&) = default;
16542 TracingServiceState_DataSource& TracingServiceState_DataSource::operator=(const TracingServiceState_DataSource&) = default;
16543 TracingServiceState_DataSource::TracingServiceState_DataSource(TracingServiceState_DataSource&&) noexcept = default;
16544 TracingServiceState_DataSource& TracingServiceState_DataSource::operator=(TracingServiceState_DataSource&&) = default;
16545 
operator ==(const TracingServiceState_DataSource & other) const16546 bool TracingServiceState_DataSource::operator==(const TracingServiceState_DataSource& other) const {
16547   return unknown_fields_ == other.unknown_fields_
16548    && ds_descriptor_ == other.ds_descriptor_
16549    && producer_id_ == other.producer_id_;
16550 }
16551 
ParseFromArray(const void * raw,size_t size)16552 bool TracingServiceState_DataSource::ParseFromArray(const void* raw, size_t size) {
16553   unknown_fields_.clear();
16554   bool packed_error = false;
16555 
16556   ::protozero::ProtoDecoder dec(raw, size);
16557   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
16558     if (field.id() < _has_field_.size()) {
16559       _has_field_.set(field.id());
16560     }
16561     switch (field.id()) {
16562       case 1 /* ds_descriptor */:
16563         (*ds_descriptor_).ParseFromArray(field.data(), field.size());
16564         break;
16565       case 2 /* producer_id */:
16566         field.get(&producer_id_);
16567         break;
16568       default:
16569         field.SerializeAndAppendTo(&unknown_fields_);
16570         break;
16571     }
16572   }
16573   return !packed_error && !dec.bytes_left();
16574 }
16575 
SerializeAsString() const16576 std::string TracingServiceState_DataSource::SerializeAsString() const {
16577   ::protozero::HeapBuffered<::protozero::Message> msg;
16578   Serialize(msg.get());
16579   return msg.SerializeAsString();
16580 }
16581 
SerializeAsArray() const16582 std::vector<uint8_t> TracingServiceState_DataSource::SerializeAsArray() const {
16583   ::protozero::HeapBuffered<::protozero::Message> msg;
16584   Serialize(msg.get());
16585   return msg.SerializeAsArray();
16586 }
16587 
Serialize(::protozero::Message * msg) const16588 void TracingServiceState_DataSource::Serialize(::protozero::Message* msg) const {
16589   // Field 1: ds_descriptor
16590   if (_has_field_[1]) {
16591     (*ds_descriptor_).Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
16592   }
16593 
16594   // Field 2: producer_id
16595   if (_has_field_[2]) {
16596     msg->AppendVarInt(2, producer_id_);
16597   }
16598 
16599   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
16600 }
16601 
16602 
16603 TracingServiceState_Producer::TracingServiceState_Producer() = default;
16604 TracingServiceState_Producer::~TracingServiceState_Producer() = default;
16605 TracingServiceState_Producer::TracingServiceState_Producer(const TracingServiceState_Producer&) = default;
16606 TracingServiceState_Producer& TracingServiceState_Producer::operator=(const TracingServiceState_Producer&) = default;
16607 TracingServiceState_Producer::TracingServiceState_Producer(TracingServiceState_Producer&&) noexcept = default;
16608 TracingServiceState_Producer& TracingServiceState_Producer::operator=(TracingServiceState_Producer&&) = default;
16609 
operator ==(const TracingServiceState_Producer & other) const16610 bool TracingServiceState_Producer::operator==(const TracingServiceState_Producer& other) const {
16611   return unknown_fields_ == other.unknown_fields_
16612    && id_ == other.id_
16613    && name_ == other.name_
16614    && uid_ == other.uid_
16615    && sdk_version_ == other.sdk_version_;
16616 }
16617 
ParseFromArray(const void * raw,size_t size)16618 bool TracingServiceState_Producer::ParseFromArray(const void* raw, size_t size) {
16619   unknown_fields_.clear();
16620   bool packed_error = false;
16621 
16622   ::protozero::ProtoDecoder dec(raw, size);
16623   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
16624     if (field.id() < _has_field_.size()) {
16625       _has_field_.set(field.id());
16626     }
16627     switch (field.id()) {
16628       case 1 /* id */:
16629         field.get(&id_);
16630         break;
16631       case 2 /* name */:
16632         field.get(&name_);
16633         break;
16634       case 3 /* uid */:
16635         field.get(&uid_);
16636         break;
16637       case 4 /* sdk_version */:
16638         field.get(&sdk_version_);
16639         break;
16640       default:
16641         field.SerializeAndAppendTo(&unknown_fields_);
16642         break;
16643     }
16644   }
16645   return !packed_error && !dec.bytes_left();
16646 }
16647 
SerializeAsString() const16648 std::string TracingServiceState_Producer::SerializeAsString() const {
16649   ::protozero::HeapBuffered<::protozero::Message> msg;
16650   Serialize(msg.get());
16651   return msg.SerializeAsString();
16652 }
16653 
SerializeAsArray() const16654 std::vector<uint8_t> TracingServiceState_Producer::SerializeAsArray() const {
16655   ::protozero::HeapBuffered<::protozero::Message> msg;
16656   Serialize(msg.get());
16657   return msg.SerializeAsArray();
16658 }
16659 
Serialize(::protozero::Message * msg) const16660 void TracingServiceState_Producer::Serialize(::protozero::Message* msg) const {
16661   // Field 1: id
16662   if (_has_field_[1]) {
16663     msg->AppendVarInt(1, id_);
16664   }
16665 
16666   // Field 2: name
16667   if (_has_field_[2]) {
16668     msg->AppendString(2, name_);
16669   }
16670 
16671   // Field 3: uid
16672   if (_has_field_[3]) {
16673     msg->AppendVarInt(3, uid_);
16674   }
16675 
16676   // Field 4: sdk_version
16677   if (_has_field_[4]) {
16678     msg->AppendString(4, sdk_version_);
16679   }
16680 
16681   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
16682 }
16683 
16684 }  // namespace perfetto
16685 }  // namespace protos
16686 }  // namespace gen
16687 #if defined(__GNUC__) || defined(__clang__)
16688 #pragma GCC diagnostic pop
16689 #endif
16690 // gen_amalgamated begin source: gen/protos/perfetto/common/track_event_descriptor.gen.cc
16691 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
16692 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
16693 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
16694 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
16695 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
16696 #if defined(__GNUC__) || defined(__clang__)
16697 #pragma GCC diagnostic push
16698 #pragma GCC diagnostic ignored "-Wfloat-equal"
16699 #endif
16700 // gen_amalgamated expanded: #include "protos/perfetto/common/track_event_descriptor.gen.h"
16701 
16702 namespace perfetto {
16703 namespace protos {
16704 namespace gen {
16705 
16706 TrackEventDescriptor::TrackEventDescriptor() = default;
16707 TrackEventDescriptor::~TrackEventDescriptor() = default;
16708 TrackEventDescriptor::TrackEventDescriptor(const TrackEventDescriptor&) = default;
16709 TrackEventDescriptor& TrackEventDescriptor::operator=(const TrackEventDescriptor&) = default;
16710 TrackEventDescriptor::TrackEventDescriptor(TrackEventDescriptor&&) noexcept = default;
16711 TrackEventDescriptor& TrackEventDescriptor::operator=(TrackEventDescriptor&&) = default;
16712 
operator ==(const TrackEventDescriptor & other) const16713 bool TrackEventDescriptor::operator==(const TrackEventDescriptor& other) const {
16714   return unknown_fields_ == other.unknown_fields_
16715    && available_categories_ == other.available_categories_;
16716 }
16717 
available_categories_size() const16718 int TrackEventDescriptor::available_categories_size() const { return static_cast<int>(available_categories_.size()); }
clear_available_categories()16719 void TrackEventDescriptor::clear_available_categories() { available_categories_.clear(); }
add_available_categories()16720 TrackEventCategory* TrackEventDescriptor::add_available_categories() { available_categories_.emplace_back(); return &available_categories_.back(); }
ParseFromArray(const void * raw,size_t size)16721 bool TrackEventDescriptor::ParseFromArray(const void* raw, size_t size) {
16722   available_categories_.clear();
16723   unknown_fields_.clear();
16724   bool packed_error = false;
16725 
16726   ::protozero::ProtoDecoder dec(raw, size);
16727   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
16728     if (field.id() < _has_field_.size()) {
16729       _has_field_.set(field.id());
16730     }
16731     switch (field.id()) {
16732       case 1 /* available_categories */:
16733         available_categories_.emplace_back();
16734         available_categories_.back().ParseFromArray(field.data(), field.size());
16735         break;
16736       default:
16737         field.SerializeAndAppendTo(&unknown_fields_);
16738         break;
16739     }
16740   }
16741   return !packed_error && !dec.bytes_left();
16742 }
16743 
SerializeAsString() const16744 std::string TrackEventDescriptor::SerializeAsString() const {
16745   ::protozero::HeapBuffered<::protozero::Message> msg;
16746   Serialize(msg.get());
16747   return msg.SerializeAsString();
16748 }
16749 
SerializeAsArray() const16750 std::vector<uint8_t> TrackEventDescriptor::SerializeAsArray() const {
16751   ::protozero::HeapBuffered<::protozero::Message> msg;
16752   Serialize(msg.get());
16753   return msg.SerializeAsArray();
16754 }
16755 
Serialize(::protozero::Message * msg) const16756 void TrackEventDescriptor::Serialize(::protozero::Message* msg) const {
16757   // Field 1: available_categories
16758   for (auto& it : available_categories_) {
16759     it.Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
16760   }
16761 
16762   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
16763 }
16764 
16765 
16766 TrackEventCategory::TrackEventCategory() = default;
16767 TrackEventCategory::~TrackEventCategory() = default;
16768 TrackEventCategory::TrackEventCategory(const TrackEventCategory&) = default;
16769 TrackEventCategory& TrackEventCategory::operator=(const TrackEventCategory&) = default;
16770 TrackEventCategory::TrackEventCategory(TrackEventCategory&&) noexcept = default;
16771 TrackEventCategory& TrackEventCategory::operator=(TrackEventCategory&&) = default;
16772 
operator ==(const TrackEventCategory & other) const16773 bool TrackEventCategory::operator==(const TrackEventCategory& other) const {
16774   return unknown_fields_ == other.unknown_fields_
16775    && name_ == other.name_
16776    && description_ == other.description_
16777    && tags_ == other.tags_;
16778 }
16779 
ParseFromArray(const void * raw,size_t size)16780 bool TrackEventCategory::ParseFromArray(const void* raw, size_t size) {
16781   tags_.clear();
16782   unknown_fields_.clear();
16783   bool packed_error = false;
16784 
16785   ::protozero::ProtoDecoder dec(raw, size);
16786   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
16787     if (field.id() < _has_field_.size()) {
16788       _has_field_.set(field.id());
16789     }
16790     switch (field.id()) {
16791       case 1 /* name */:
16792         field.get(&name_);
16793         break;
16794       case 2 /* description */:
16795         field.get(&description_);
16796         break;
16797       case 3 /* tags */:
16798         tags_.emplace_back();
16799         field.get(&tags_.back());
16800         break;
16801       default:
16802         field.SerializeAndAppendTo(&unknown_fields_);
16803         break;
16804     }
16805   }
16806   return !packed_error && !dec.bytes_left();
16807 }
16808 
SerializeAsString() const16809 std::string TrackEventCategory::SerializeAsString() const {
16810   ::protozero::HeapBuffered<::protozero::Message> msg;
16811   Serialize(msg.get());
16812   return msg.SerializeAsString();
16813 }
16814 
SerializeAsArray() const16815 std::vector<uint8_t> TrackEventCategory::SerializeAsArray() const {
16816   ::protozero::HeapBuffered<::protozero::Message> msg;
16817   Serialize(msg.get());
16818   return msg.SerializeAsArray();
16819 }
16820 
Serialize(::protozero::Message * msg) const16821 void TrackEventCategory::Serialize(::protozero::Message* msg) const {
16822   // Field 1: name
16823   if (_has_field_[1]) {
16824     msg->AppendString(1, name_);
16825   }
16826 
16827   // Field 2: description
16828   if (_has_field_[2]) {
16829     msg->AppendString(2, description_);
16830   }
16831 
16832   // Field 3: tags
16833   for (auto& it : tags_) {
16834     msg->AppendString(3, it);
16835   }
16836 
16837   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
16838 }
16839 
16840 }  // namespace perfetto
16841 }  // namespace protos
16842 }  // namespace gen
16843 #if defined(__GNUC__) || defined(__clang__)
16844 #pragma GCC diagnostic pop
16845 #endif
16846 // gen_amalgamated begin source: gen/protos/perfetto/config/android/android_log_config.gen.cc
16847 // gen_amalgamated begin header: gen/protos/perfetto/config/android/android_log_config.gen.h
16848 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
16849 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_ANDROID_ANDROID_LOG_CONFIG_PROTO_CPP_H_
16850 #define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_ANDROID_ANDROID_LOG_CONFIG_PROTO_CPP_H_
16851 
16852 #include <stdint.h>
16853 #include <bitset>
16854 #include <vector>
16855 #include <string>
16856 #include <type_traits>
16857 
16858 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
16859 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
16860 // gen_amalgamated expanded: #include "perfetto/base/export.h"
16861 
16862 namespace perfetto {
16863 namespace protos {
16864 namespace gen {
16865 class AndroidLogConfig;
16866 enum AndroidLogId : int;
16867 enum AndroidLogPriority : int;
16868 }  // namespace perfetto
16869 }  // namespace protos
16870 }  // namespace gen
16871 
16872 namespace protozero {
16873 class Message;
16874 }  // namespace protozero
16875 
16876 namespace perfetto {
16877 namespace protos {
16878 namespace gen {
16879 
16880 class PERFETTO_EXPORT AndroidLogConfig : public ::protozero::CppMessageObj {
16881  public:
16882   enum FieldNumbers {
16883     kLogIdsFieldNumber = 1,
16884     kMinPrioFieldNumber = 3,
16885     kFilterTagsFieldNumber = 4,
16886   };
16887 
16888   AndroidLogConfig();
16889   ~AndroidLogConfig() override;
16890   AndroidLogConfig(AndroidLogConfig&&) noexcept;
16891   AndroidLogConfig& operator=(AndroidLogConfig&&);
16892   AndroidLogConfig(const AndroidLogConfig&);
16893   AndroidLogConfig& operator=(const AndroidLogConfig&);
16894   bool operator==(const AndroidLogConfig&) const;
operator !=(const AndroidLogConfig & other) const16895   bool operator!=(const AndroidLogConfig& other) const { return !(*this == other); }
16896 
16897   bool ParseFromArray(const void*, size_t) override;
16898   std::string SerializeAsString() const override;
16899   std::vector<uint8_t> SerializeAsArray() const override;
16900   void Serialize(::protozero::Message*) const;
16901 
log_ids() const16902   const std::vector<AndroidLogId>& log_ids() const { return log_ids_; }
mutable_log_ids()16903   std::vector<AndroidLogId>* mutable_log_ids() { return &log_ids_; }
log_ids_size() const16904   int log_ids_size() const { return static_cast<int>(log_ids_.size()); }
clear_log_ids()16905   void clear_log_ids() { log_ids_.clear(); }
add_log_ids(AndroidLogId value)16906   void add_log_ids(AndroidLogId value) { log_ids_.emplace_back(value); }
add_log_ids()16907   AndroidLogId* add_log_ids() { log_ids_.emplace_back(); return &log_ids_.back(); }
16908 
has_min_prio() const16909   bool has_min_prio() const { return _has_field_[3]; }
min_prio() const16910   AndroidLogPriority min_prio() const { return min_prio_; }
set_min_prio(AndroidLogPriority value)16911   void set_min_prio(AndroidLogPriority value) { min_prio_ = value; _has_field_.set(3); }
16912 
filter_tags() const16913   const std::vector<std::string>& filter_tags() const { return filter_tags_; }
mutable_filter_tags()16914   std::vector<std::string>* mutable_filter_tags() { return &filter_tags_; }
filter_tags_size() const16915   int filter_tags_size() const { return static_cast<int>(filter_tags_.size()); }
clear_filter_tags()16916   void clear_filter_tags() { filter_tags_.clear(); }
add_filter_tags(std::string value)16917   void add_filter_tags(std::string value) { filter_tags_.emplace_back(value); }
add_filter_tags()16918   std::string* add_filter_tags() { filter_tags_.emplace_back(); return &filter_tags_.back(); }
16919 
16920  private:
16921   std::vector<AndroidLogId> log_ids_;
16922   AndroidLogPriority min_prio_{};
16923   std::vector<std::string> filter_tags_;
16924 
16925   // Allows to preserve unknown protobuf fields for compatibility
16926   // with future versions of .proto files.
16927   std::string unknown_fields_;
16928 
16929   std::bitset<5> _has_field_{};
16930 };
16931 
16932 }  // namespace perfetto
16933 }  // namespace protos
16934 }  // namespace gen
16935 
16936 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_ANDROID_ANDROID_LOG_CONFIG_PROTO_CPP_H_
16937 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
16938 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
16939 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
16940 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
16941 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
16942 #if defined(__GNUC__) || defined(__clang__)
16943 #pragma GCC diagnostic push
16944 #pragma GCC diagnostic ignored "-Wfloat-equal"
16945 #endif
16946 // gen_amalgamated expanded: #include "protos/perfetto/config/android/android_log_config.gen.h"
16947 // gen_amalgamated expanded: #include "protos/perfetto/common/android_log_constants.gen.h"
16948 
16949 namespace perfetto {
16950 namespace protos {
16951 namespace gen {
16952 
16953 AndroidLogConfig::AndroidLogConfig() = default;
16954 AndroidLogConfig::~AndroidLogConfig() = default;
16955 AndroidLogConfig::AndroidLogConfig(const AndroidLogConfig&) = default;
16956 AndroidLogConfig& AndroidLogConfig::operator=(const AndroidLogConfig&) = default;
16957 AndroidLogConfig::AndroidLogConfig(AndroidLogConfig&&) noexcept = default;
16958 AndroidLogConfig& AndroidLogConfig::operator=(AndroidLogConfig&&) = default;
16959 
operator ==(const AndroidLogConfig & other) const16960 bool AndroidLogConfig::operator==(const AndroidLogConfig& other) const {
16961   return unknown_fields_ == other.unknown_fields_
16962    && log_ids_ == other.log_ids_
16963    && min_prio_ == other.min_prio_
16964    && filter_tags_ == other.filter_tags_;
16965 }
16966 
ParseFromArray(const void * raw,size_t size)16967 bool AndroidLogConfig::ParseFromArray(const void* raw, size_t size) {
16968   log_ids_.clear();
16969   filter_tags_.clear();
16970   unknown_fields_.clear();
16971   bool packed_error = false;
16972 
16973   ::protozero::ProtoDecoder dec(raw, size);
16974   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
16975     if (field.id() < _has_field_.size()) {
16976       _has_field_.set(field.id());
16977     }
16978     switch (field.id()) {
16979       case 1 /* log_ids */:
16980         log_ids_.emplace_back();
16981         field.get(&log_ids_.back());
16982         break;
16983       case 3 /* min_prio */:
16984         field.get(&min_prio_);
16985         break;
16986       case 4 /* filter_tags */:
16987         filter_tags_.emplace_back();
16988         field.get(&filter_tags_.back());
16989         break;
16990       default:
16991         field.SerializeAndAppendTo(&unknown_fields_);
16992         break;
16993     }
16994   }
16995   return !packed_error && !dec.bytes_left();
16996 }
16997 
SerializeAsString() const16998 std::string AndroidLogConfig::SerializeAsString() const {
16999   ::protozero::HeapBuffered<::protozero::Message> msg;
17000   Serialize(msg.get());
17001   return msg.SerializeAsString();
17002 }
17003 
SerializeAsArray() const17004 std::vector<uint8_t> AndroidLogConfig::SerializeAsArray() const {
17005   ::protozero::HeapBuffered<::protozero::Message> msg;
17006   Serialize(msg.get());
17007   return msg.SerializeAsArray();
17008 }
17009 
Serialize(::protozero::Message * msg) const17010 void AndroidLogConfig::Serialize(::protozero::Message* msg) const {
17011   // Field 1: log_ids
17012   for (auto& it : log_ids_) {
17013     msg->AppendVarInt(1, it);
17014   }
17015 
17016   // Field 3: min_prio
17017   if (_has_field_[3]) {
17018     msg->AppendVarInt(3, min_prio_);
17019   }
17020 
17021   // Field 4: filter_tags
17022   for (auto& it : filter_tags_) {
17023     msg->AppendString(4, it);
17024   }
17025 
17026   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
17027 }
17028 
17029 }  // namespace perfetto
17030 }  // namespace protos
17031 }  // namespace gen
17032 #if defined(__GNUC__) || defined(__clang__)
17033 #pragma GCC diagnostic pop
17034 #endif
17035 // gen_amalgamated begin source: gen/protos/perfetto/config/android/android_polled_state_config.gen.cc
17036 // gen_amalgamated begin header: gen/protos/perfetto/config/android/android_polled_state_config.gen.h
17037 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
17038 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_ANDROID_ANDROID_POLLED_STATE_CONFIG_PROTO_CPP_H_
17039 #define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_ANDROID_ANDROID_POLLED_STATE_CONFIG_PROTO_CPP_H_
17040 
17041 #include <stdint.h>
17042 #include <bitset>
17043 #include <vector>
17044 #include <string>
17045 #include <type_traits>
17046 
17047 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
17048 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
17049 // gen_amalgamated expanded: #include "perfetto/base/export.h"
17050 
17051 namespace perfetto {
17052 namespace protos {
17053 namespace gen {
17054 class AndroidPolledStateConfig;
17055 }  // namespace perfetto
17056 }  // namespace protos
17057 }  // namespace gen
17058 
17059 namespace protozero {
17060 class Message;
17061 }  // namespace protozero
17062 
17063 namespace perfetto {
17064 namespace protos {
17065 namespace gen {
17066 
17067 class PERFETTO_EXPORT AndroidPolledStateConfig : public ::protozero::CppMessageObj {
17068  public:
17069   enum FieldNumbers {
17070     kPollMsFieldNumber = 1,
17071   };
17072 
17073   AndroidPolledStateConfig();
17074   ~AndroidPolledStateConfig() override;
17075   AndroidPolledStateConfig(AndroidPolledStateConfig&&) noexcept;
17076   AndroidPolledStateConfig& operator=(AndroidPolledStateConfig&&);
17077   AndroidPolledStateConfig(const AndroidPolledStateConfig&);
17078   AndroidPolledStateConfig& operator=(const AndroidPolledStateConfig&);
17079   bool operator==(const AndroidPolledStateConfig&) const;
operator !=(const AndroidPolledStateConfig & other) const17080   bool operator!=(const AndroidPolledStateConfig& other) const { return !(*this == other); }
17081 
17082   bool ParseFromArray(const void*, size_t) override;
17083   std::string SerializeAsString() const override;
17084   std::vector<uint8_t> SerializeAsArray() const override;
17085   void Serialize(::protozero::Message*) const;
17086 
has_poll_ms() const17087   bool has_poll_ms() const { return _has_field_[1]; }
poll_ms() const17088   uint32_t poll_ms() const { return poll_ms_; }
set_poll_ms(uint32_t value)17089   void set_poll_ms(uint32_t value) { poll_ms_ = value; _has_field_.set(1); }
17090 
17091  private:
17092   uint32_t poll_ms_{};
17093 
17094   // Allows to preserve unknown protobuf fields for compatibility
17095   // with future versions of .proto files.
17096   std::string unknown_fields_;
17097 
17098   std::bitset<2> _has_field_{};
17099 };
17100 
17101 }  // namespace perfetto
17102 }  // namespace protos
17103 }  // namespace gen
17104 
17105 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_ANDROID_ANDROID_POLLED_STATE_CONFIG_PROTO_CPP_H_
17106 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
17107 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
17108 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
17109 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
17110 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
17111 #if defined(__GNUC__) || defined(__clang__)
17112 #pragma GCC diagnostic push
17113 #pragma GCC diagnostic ignored "-Wfloat-equal"
17114 #endif
17115 // gen_amalgamated expanded: #include "protos/perfetto/config/android/android_polled_state_config.gen.h"
17116 
17117 namespace perfetto {
17118 namespace protos {
17119 namespace gen {
17120 
17121 AndroidPolledStateConfig::AndroidPolledStateConfig() = default;
17122 AndroidPolledStateConfig::~AndroidPolledStateConfig() = default;
17123 AndroidPolledStateConfig::AndroidPolledStateConfig(const AndroidPolledStateConfig&) = default;
17124 AndroidPolledStateConfig& AndroidPolledStateConfig::operator=(const AndroidPolledStateConfig&) = default;
17125 AndroidPolledStateConfig::AndroidPolledStateConfig(AndroidPolledStateConfig&&) noexcept = default;
17126 AndroidPolledStateConfig& AndroidPolledStateConfig::operator=(AndroidPolledStateConfig&&) = default;
17127 
operator ==(const AndroidPolledStateConfig & other) const17128 bool AndroidPolledStateConfig::operator==(const AndroidPolledStateConfig& other) const {
17129   return unknown_fields_ == other.unknown_fields_
17130    && poll_ms_ == other.poll_ms_;
17131 }
17132 
ParseFromArray(const void * raw,size_t size)17133 bool AndroidPolledStateConfig::ParseFromArray(const void* raw, size_t size) {
17134   unknown_fields_.clear();
17135   bool packed_error = false;
17136 
17137   ::protozero::ProtoDecoder dec(raw, size);
17138   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
17139     if (field.id() < _has_field_.size()) {
17140       _has_field_.set(field.id());
17141     }
17142     switch (field.id()) {
17143       case 1 /* poll_ms */:
17144         field.get(&poll_ms_);
17145         break;
17146       default:
17147         field.SerializeAndAppendTo(&unknown_fields_);
17148         break;
17149     }
17150   }
17151   return !packed_error && !dec.bytes_left();
17152 }
17153 
SerializeAsString() const17154 std::string AndroidPolledStateConfig::SerializeAsString() const {
17155   ::protozero::HeapBuffered<::protozero::Message> msg;
17156   Serialize(msg.get());
17157   return msg.SerializeAsString();
17158 }
17159 
SerializeAsArray() const17160 std::vector<uint8_t> AndroidPolledStateConfig::SerializeAsArray() const {
17161   ::protozero::HeapBuffered<::protozero::Message> msg;
17162   Serialize(msg.get());
17163   return msg.SerializeAsArray();
17164 }
17165 
Serialize(::protozero::Message * msg) const17166 void AndroidPolledStateConfig::Serialize(::protozero::Message* msg) const {
17167   // Field 1: poll_ms
17168   if (_has_field_[1]) {
17169     msg->AppendVarInt(1, poll_ms_);
17170   }
17171 
17172   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
17173 }
17174 
17175 }  // namespace perfetto
17176 }  // namespace protos
17177 }  // namespace gen
17178 #if defined(__GNUC__) || defined(__clang__)
17179 #pragma GCC diagnostic pop
17180 #endif
17181 // gen_amalgamated begin source: gen/protos/perfetto/config/android/packages_list_config.gen.cc
17182 // gen_amalgamated begin header: gen/protos/perfetto/config/android/packages_list_config.gen.h
17183 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
17184 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_ANDROID_PACKAGES_LIST_CONFIG_PROTO_CPP_H_
17185 #define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_ANDROID_PACKAGES_LIST_CONFIG_PROTO_CPP_H_
17186 
17187 #include <stdint.h>
17188 #include <bitset>
17189 #include <vector>
17190 #include <string>
17191 #include <type_traits>
17192 
17193 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
17194 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
17195 // gen_amalgamated expanded: #include "perfetto/base/export.h"
17196 
17197 namespace perfetto {
17198 namespace protos {
17199 namespace gen {
17200 class PackagesListConfig;
17201 }  // namespace perfetto
17202 }  // namespace protos
17203 }  // namespace gen
17204 
17205 namespace protozero {
17206 class Message;
17207 }  // namespace protozero
17208 
17209 namespace perfetto {
17210 namespace protos {
17211 namespace gen {
17212 
17213 class PERFETTO_EXPORT PackagesListConfig : public ::protozero::CppMessageObj {
17214  public:
17215   enum FieldNumbers {
17216     kPackageNameFilterFieldNumber = 1,
17217   };
17218 
17219   PackagesListConfig();
17220   ~PackagesListConfig() override;
17221   PackagesListConfig(PackagesListConfig&&) noexcept;
17222   PackagesListConfig& operator=(PackagesListConfig&&);
17223   PackagesListConfig(const PackagesListConfig&);
17224   PackagesListConfig& operator=(const PackagesListConfig&);
17225   bool operator==(const PackagesListConfig&) const;
operator !=(const PackagesListConfig & other) const17226   bool operator!=(const PackagesListConfig& other) const { return !(*this == other); }
17227 
17228   bool ParseFromArray(const void*, size_t) override;
17229   std::string SerializeAsString() const override;
17230   std::vector<uint8_t> SerializeAsArray() const override;
17231   void Serialize(::protozero::Message*) const;
17232 
package_name_filter() const17233   const std::vector<std::string>& package_name_filter() const { return package_name_filter_; }
mutable_package_name_filter()17234   std::vector<std::string>* mutable_package_name_filter() { return &package_name_filter_; }
package_name_filter_size() const17235   int package_name_filter_size() const { return static_cast<int>(package_name_filter_.size()); }
clear_package_name_filter()17236   void clear_package_name_filter() { package_name_filter_.clear(); }
add_package_name_filter(std::string value)17237   void add_package_name_filter(std::string value) { package_name_filter_.emplace_back(value); }
add_package_name_filter()17238   std::string* add_package_name_filter() { package_name_filter_.emplace_back(); return &package_name_filter_.back(); }
17239 
17240  private:
17241   std::vector<std::string> package_name_filter_;
17242 
17243   // Allows to preserve unknown protobuf fields for compatibility
17244   // with future versions of .proto files.
17245   std::string unknown_fields_;
17246 
17247   std::bitset<2> _has_field_{};
17248 };
17249 
17250 }  // namespace perfetto
17251 }  // namespace protos
17252 }  // namespace gen
17253 
17254 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_ANDROID_PACKAGES_LIST_CONFIG_PROTO_CPP_H_
17255 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
17256 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
17257 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
17258 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
17259 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
17260 #if defined(__GNUC__) || defined(__clang__)
17261 #pragma GCC diagnostic push
17262 #pragma GCC diagnostic ignored "-Wfloat-equal"
17263 #endif
17264 // gen_amalgamated expanded: #include "protos/perfetto/config/android/packages_list_config.gen.h"
17265 
17266 namespace perfetto {
17267 namespace protos {
17268 namespace gen {
17269 
17270 PackagesListConfig::PackagesListConfig() = default;
17271 PackagesListConfig::~PackagesListConfig() = default;
17272 PackagesListConfig::PackagesListConfig(const PackagesListConfig&) = default;
17273 PackagesListConfig& PackagesListConfig::operator=(const PackagesListConfig&) = default;
17274 PackagesListConfig::PackagesListConfig(PackagesListConfig&&) noexcept = default;
17275 PackagesListConfig& PackagesListConfig::operator=(PackagesListConfig&&) = default;
17276 
operator ==(const PackagesListConfig & other) const17277 bool PackagesListConfig::operator==(const PackagesListConfig& other) const {
17278   return unknown_fields_ == other.unknown_fields_
17279    && package_name_filter_ == other.package_name_filter_;
17280 }
17281 
ParseFromArray(const void * raw,size_t size)17282 bool PackagesListConfig::ParseFromArray(const void* raw, size_t size) {
17283   package_name_filter_.clear();
17284   unknown_fields_.clear();
17285   bool packed_error = false;
17286 
17287   ::protozero::ProtoDecoder dec(raw, size);
17288   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
17289     if (field.id() < _has_field_.size()) {
17290       _has_field_.set(field.id());
17291     }
17292     switch (field.id()) {
17293       case 1 /* package_name_filter */:
17294         package_name_filter_.emplace_back();
17295         field.get(&package_name_filter_.back());
17296         break;
17297       default:
17298         field.SerializeAndAppendTo(&unknown_fields_);
17299         break;
17300     }
17301   }
17302   return !packed_error && !dec.bytes_left();
17303 }
17304 
SerializeAsString() const17305 std::string PackagesListConfig::SerializeAsString() const {
17306   ::protozero::HeapBuffered<::protozero::Message> msg;
17307   Serialize(msg.get());
17308   return msg.SerializeAsString();
17309 }
17310 
SerializeAsArray() const17311 std::vector<uint8_t> PackagesListConfig::SerializeAsArray() const {
17312   ::protozero::HeapBuffered<::protozero::Message> msg;
17313   Serialize(msg.get());
17314   return msg.SerializeAsArray();
17315 }
17316 
Serialize(::protozero::Message * msg) const17317 void PackagesListConfig::Serialize(::protozero::Message* msg) const {
17318   // Field 1: package_name_filter
17319   for (auto& it : package_name_filter_) {
17320     msg->AppendString(1, it);
17321   }
17322 
17323   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
17324 }
17325 
17326 }  // namespace perfetto
17327 }  // namespace protos
17328 }  // namespace gen
17329 #if defined(__GNUC__) || defined(__clang__)
17330 #pragma GCC diagnostic pop
17331 #endif
17332 // gen_amalgamated begin source: gen/protos/perfetto/config/ftrace/ftrace_config.gen.cc
17333 // gen_amalgamated begin header: gen/protos/perfetto/config/ftrace/ftrace_config.gen.h
17334 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
17335 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_FTRACE_FTRACE_CONFIG_PROTO_CPP_H_
17336 #define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_FTRACE_FTRACE_CONFIG_PROTO_CPP_H_
17337 
17338 #include <stdint.h>
17339 #include <bitset>
17340 #include <vector>
17341 #include <string>
17342 #include <type_traits>
17343 
17344 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
17345 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
17346 // gen_amalgamated expanded: #include "perfetto/base/export.h"
17347 
17348 namespace perfetto {
17349 namespace protos {
17350 namespace gen {
17351 class FtraceConfig;
17352 class FtraceConfig_CompactSchedConfig;
17353 }  // namespace perfetto
17354 }  // namespace protos
17355 }  // namespace gen
17356 
17357 namespace protozero {
17358 class Message;
17359 }  // namespace protozero
17360 
17361 namespace perfetto {
17362 namespace protos {
17363 namespace gen {
17364 
17365 class PERFETTO_EXPORT FtraceConfig : public ::protozero::CppMessageObj {
17366  public:
17367   using CompactSchedConfig = FtraceConfig_CompactSchedConfig;
17368   enum FieldNumbers {
17369     kFtraceEventsFieldNumber = 1,
17370     kAtraceCategoriesFieldNumber = 2,
17371     kAtraceAppsFieldNumber = 3,
17372     kBufferSizeKbFieldNumber = 10,
17373     kDrainPeriodMsFieldNumber = 11,
17374     kCompactSchedFieldNumber = 12,
17375     kSymbolizeKsymsFieldNumber = 13,
17376     kInitializeKsymsSynchronouslyForTestingFieldNumber = 14,
17377     kThrottleRssStatFieldNumber = 15,
17378   };
17379 
17380   FtraceConfig();
17381   ~FtraceConfig() override;
17382   FtraceConfig(FtraceConfig&&) noexcept;
17383   FtraceConfig& operator=(FtraceConfig&&);
17384   FtraceConfig(const FtraceConfig&);
17385   FtraceConfig& operator=(const FtraceConfig&);
17386   bool operator==(const FtraceConfig&) const;
operator !=(const FtraceConfig & other) const17387   bool operator!=(const FtraceConfig& other) const { return !(*this == other); }
17388 
17389   bool ParseFromArray(const void*, size_t) override;
17390   std::string SerializeAsString() const override;
17391   std::vector<uint8_t> SerializeAsArray() const override;
17392   void Serialize(::protozero::Message*) const;
17393 
ftrace_events() const17394   const std::vector<std::string>& ftrace_events() const { return ftrace_events_; }
mutable_ftrace_events()17395   std::vector<std::string>* mutable_ftrace_events() { return &ftrace_events_; }
ftrace_events_size() const17396   int ftrace_events_size() const { return static_cast<int>(ftrace_events_.size()); }
clear_ftrace_events()17397   void clear_ftrace_events() { ftrace_events_.clear(); }
add_ftrace_events(std::string value)17398   void add_ftrace_events(std::string value) { ftrace_events_.emplace_back(value); }
add_ftrace_events()17399   std::string* add_ftrace_events() { ftrace_events_.emplace_back(); return &ftrace_events_.back(); }
17400 
atrace_categories() const17401   const std::vector<std::string>& atrace_categories() const { return atrace_categories_; }
mutable_atrace_categories()17402   std::vector<std::string>* mutable_atrace_categories() { return &atrace_categories_; }
atrace_categories_size() const17403   int atrace_categories_size() const { return static_cast<int>(atrace_categories_.size()); }
clear_atrace_categories()17404   void clear_atrace_categories() { atrace_categories_.clear(); }
add_atrace_categories(std::string value)17405   void add_atrace_categories(std::string value) { atrace_categories_.emplace_back(value); }
add_atrace_categories()17406   std::string* add_atrace_categories() { atrace_categories_.emplace_back(); return &atrace_categories_.back(); }
17407 
atrace_apps() const17408   const std::vector<std::string>& atrace_apps() const { return atrace_apps_; }
mutable_atrace_apps()17409   std::vector<std::string>* mutable_atrace_apps() { return &atrace_apps_; }
atrace_apps_size() const17410   int atrace_apps_size() const { return static_cast<int>(atrace_apps_.size()); }
clear_atrace_apps()17411   void clear_atrace_apps() { atrace_apps_.clear(); }
add_atrace_apps(std::string value)17412   void add_atrace_apps(std::string value) { atrace_apps_.emplace_back(value); }
add_atrace_apps()17413   std::string* add_atrace_apps() { atrace_apps_.emplace_back(); return &atrace_apps_.back(); }
17414 
has_buffer_size_kb() const17415   bool has_buffer_size_kb() const { return _has_field_[10]; }
buffer_size_kb() const17416   uint32_t buffer_size_kb() const { return buffer_size_kb_; }
set_buffer_size_kb(uint32_t value)17417   void set_buffer_size_kb(uint32_t value) { buffer_size_kb_ = value; _has_field_.set(10); }
17418 
has_drain_period_ms() const17419   bool has_drain_period_ms() const { return _has_field_[11]; }
drain_period_ms() const17420   uint32_t drain_period_ms() const { return drain_period_ms_; }
set_drain_period_ms(uint32_t value)17421   void set_drain_period_ms(uint32_t value) { drain_period_ms_ = value; _has_field_.set(11); }
17422 
has_compact_sched() const17423   bool has_compact_sched() const { return _has_field_[12]; }
compact_sched() const17424   const FtraceConfig_CompactSchedConfig& compact_sched() const { return *compact_sched_; }
mutable_compact_sched()17425   FtraceConfig_CompactSchedConfig* mutable_compact_sched() { _has_field_.set(12); return compact_sched_.get(); }
17426 
has_symbolize_ksyms() const17427   bool has_symbolize_ksyms() const { return _has_field_[13]; }
symbolize_ksyms() const17428   bool symbolize_ksyms() const { return symbolize_ksyms_; }
set_symbolize_ksyms(bool value)17429   void set_symbolize_ksyms(bool value) { symbolize_ksyms_ = value; _has_field_.set(13); }
17430 
has_initialize_ksyms_synchronously_for_testing() const17431   bool has_initialize_ksyms_synchronously_for_testing() const { return _has_field_[14]; }
initialize_ksyms_synchronously_for_testing() const17432   bool initialize_ksyms_synchronously_for_testing() const { return initialize_ksyms_synchronously_for_testing_; }
set_initialize_ksyms_synchronously_for_testing(bool value)17433   void set_initialize_ksyms_synchronously_for_testing(bool value) { initialize_ksyms_synchronously_for_testing_ = value; _has_field_.set(14); }
17434 
has_throttle_rss_stat() const17435   bool has_throttle_rss_stat() const { return _has_field_[15]; }
throttle_rss_stat() const17436   bool throttle_rss_stat() const { return throttle_rss_stat_; }
set_throttle_rss_stat(bool value)17437   void set_throttle_rss_stat(bool value) { throttle_rss_stat_ = value; _has_field_.set(15); }
17438 
17439  private:
17440   std::vector<std::string> ftrace_events_;
17441   std::vector<std::string> atrace_categories_;
17442   std::vector<std::string> atrace_apps_;
17443   uint32_t buffer_size_kb_{};
17444   uint32_t drain_period_ms_{};
17445   ::protozero::CopyablePtr<FtraceConfig_CompactSchedConfig> compact_sched_;
17446   bool symbolize_ksyms_{};
17447   bool initialize_ksyms_synchronously_for_testing_{};
17448   bool throttle_rss_stat_{};
17449 
17450   // Allows to preserve unknown protobuf fields for compatibility
17451   // with future versions of .proto files.
17452   std::string unknown_fields_;
17453 
17454   std::bitset<16> _has_field_{};
17455 };
17456 
17457 
17458 class PERFETTO_EXPORT FtraceConfig_CompactSchedConfig : public ::protozero::CppMessageObj {
17459  public:
17460   enum FieldNumbers {
17461     kEnabledFieldNumber = 1,
17462   };
17463 
17464   FtraceConfig_CompactSchedConfig();
17465   ~FtraceConfig_CompactSchedConfig() override;
17466   FtraceConfig_CompactSchedConfig(FtraceConfig_CompactSchedConfig&&) noexcept;
17467   FtraceConfig_CompactSchedConfig& operator=(FtraceConfig_CompactSchedConfig&&);
17468   FtraceConfig_CompactSchedConfig(const FtraceConfig_CompactSchedConfig&);
17469   FtraceConfig_CompactSchedConfig& operator=(const FtraceConfig_CompactSchedConfig&);
17470   bool operator==(const FtraceConfig_CompactSchedConfig&) const;
operator !=(const FtraceConfig_CompactSchedConfig & other) const17471   bool operator!=(const FtraceConfig_CompactSchedConfig& other) const { return !(*this == other); }
17472 
17473   bool ParseFromArray(const void*, size_t) override;
17474   std::string SerializeAsString() const override;
17475   std::vector<uint8_t> SerializeAsArray() const override;
17476   void Serialize(::protozero::Message*) const;
17477 
has_enabled() const17478   bool has_enabled() const { return _has_field_[1]; }
enabled() const17479   bool enabled() const { return enabled_; }
set_enabled(bool value)17480   void set_enabled(bool value) { enabled_ = value; _has_field_.set(1); }
17481 
17482  private:
17483   bool enabled_{};
17484 
17485   // Allows to preserve unknown protobuf fields for compatibility
17486   // with future versions of .proto files.
17487   std::string unknown_fields_;
17488 
17489   std::bitset<2> _has_field_{};
17490 };
17491 
17492 }  // namespace perfetto
17493 }  // namespace protos
17494 }  // namespace gen
17495 
17496 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_FTRACE_FTRACE_CONFIG_PROTO_CPP_H_
17497 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
17498 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
17499 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
17500 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
17501 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
17502 #if defined(__GNUC__) || defined(__clang__)
17503 #pragma GCC diagnostic push
17504 #pragma GCC diagnostic ignored "-Wfloat-equal"
17505 #endif
17506 // gen_amalgamated expanded: #include "protos/perfetto/config/ftrace/ftrace_config.gen.h"
17507 
17508 namespace perfetto {
17509 namespace protos {
17510 namespace gen {
17511 
17512 FtraceConfig::FtraceConfig() = default;
17513 FtraceConfig::~FtraceConfig() = default;
17514 FtraceConfig::FtraceConfig(const FtraceConfig&) = default;
17515 FtraceConfig& FtraceConfig::operator=(const FtraceConfig&) = default;
17516 FtraceConfig::FtraceConfig(FtraceConfig&&) noexcept = default;
17517 FtraceConfig& FtraceConfig::operator=(FtraceConfig&&) = default;
17518 
operator ==(const FtraceConfig & other) const17519 bool FtraceConfig::operator==(const FtraceConfig& other) const {
17520   return unknown_fields_ == other.unknown_fields_
17521    && ftrace_events_ == other.ftrace_events_
17522    && atrace_categories_ == other.atrace_categories_
17523    && atrace_apps_ == other.atrace_apps_
17524    && buffer_size_kb_ == other.buffer_size_kb_
17525    && drain_period_ms_ == other.drain_period_ms_
17526    && compact_sched_ == other.compact_sched_
17527    && symbolize_ksyms_ == other.symbolize_ksyms_
17528    && initialize_ksyms_synchronously_for_testing_ == other.initialize_ksyms_synchronously_for_testing_
17529    && throttle_rss_stat_ == other.throttle_rss_stat_;
17530 }
17531 
ParseFromArray(const void * raw,size_t size)17532 bool FtraceConfig::ParseFromArray(const void* raw, size_t size) {
17533   ftrace_events_.clear();
17534   atrace_categories_.clear();
17535   atrace_apps_.clear();
17536   unknown_fields_.clear();
17537   bool packed_error = false;
17538 
17539   ::protozero::ProtoDecoder dec(raw, size);
17540   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
17541     if (field.id() < _has_field_.size()) {
17542       _has_field_.set(field.id());
17543     }
17544     switch (field.id()) {
17545       case 1 /* ftrace_events */:
17546         ftrace_events_.emplace_back();
17547         field.get(&ftrace_events_.back());
17548         break;
17549       case 2 /* atrace_categories */:
17550         atrace_categories_.emplace_back();
17551         field.get(&atrace_categories_.back());
17552         break;
17553       case 3 /* atrace_apps */:
17554         atrace_apps_.emplace_back();
17555         field.get(&atrace_apps_.back());
17556         break;
17557       case 10 /* buffer_size_kb */:
17558         field.get(&buffer_size_kb_);
17559         break;
17560       case 11 /* drain_period_ms */:
17561         field.get(&drain_period_ms_);
17562         break;
17563       case 12 /* compact_sched */:
17564         (*compact_sched_).ParseFromArray(field.data(), field.size());
17565         break;
17566       case 13 /* symbolize_ksyms */:
17567         field.get(&symbolize_ksyms_);
17568         break;
17569       case 14 /* initialize_ksyms_synchronously_for_testing */:
17570         field.get(&initialize_ksyms_synchronously_for_testing_);
17571         break;
17572       case 15 /* throttle_rss_stat */:
17573         field.get(&throttle_rss_stat_);
17574         break;
17575       default:
17576         field.SerializeAndAppendTo(&unknown_fields_);
17577         break;
17578     }
17579   }
17580   return !packed_error && !dec.bytes_left();
17581 }
17582 
SerializeAsString() const17583 std::string FtraceConfig::SerializeAsString() const {
17584   ::protozero::HeapBuffered<::protozero::Message> msg;
17585   Serialize(msg.get());
17586   return msg.SerializeAsString();
17587 }
17588 
SerializeAsArray() const17589 std::vector<uint8_t> FtraceConfig::SerializeAsArray() const {
17590   ::protozero::HeapBuffered<::protozero::Message> msg;
17591   Serialize(msg.get());
17592   return msg.SerializeAsArray();
17593 }
17594 
Serialize(::protozero::Message * msg) const17595 void FtraceConfig::Serialize(::protozero::Message* msg) const {
17596   // Field 1: ftrace_events
17597   for (auto& it : ftrace_events_) {
17598     msg->AppendString(1, it);
17599   }
17600 
17601   // Field 2: atrace_categories
17602   for (auto& it : atrace_categories_) {
17603     msg->AppendString(2, it);
17604   }
17605 
17606   // Field 3: atrace_apps
17607   for (auto& it : atrace_apps_) {
17608     msg->AppendString(3, it);
17609   }
17610 
17611   // Field 10: buffer_size_kb
17612   if (_has_field_[10]) {
17613     msg->AppendVarInt(10, buffer_size_kb_);
17614   }
17615 
17616   // Field 11: drain_period_ms
17617   if (_has_field_[11]) {
17618     msg->AppendVarInt(11, drain_period_ms_);
17619   }
17620 
17621   // Field 12: compact_sched
17622   if (_has_field_[12]) {
17623     (*compact_sched_).Serialize(msg->BeginNestedMessage<::protozero::Message>(12));
17624   }
17625 
17626   // Field 13: symbolize_ksyms
17627   if (_has_field_[13]) {
17628     msg->AppendTinyVarInt(13, symbolize_ksyms_);
17629   }
17630 
17631   // Field 14: initialize_ksyms_synchronously_for_testing
17632   if (_has_field_[14]) {
17633     msg->AppendTinyVarInt(14, initialize_ksyms_synchronously_for_testing_);
17634   }
17635 
17636   // Field 15: throttle_rss_stat
17637   if (_has_field_[15]) {
17638     msg->AppendTinyVarInt(15, throttle_rss_stat_);
17639   }
17640 
17641   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
17642 }
17643 
17644 
17645 FtraceConfig_CompactSchedConfig::FtraceConfig_CompactSchedConfig() = default;
17646 FtraceConfig_CompactSchedConfig::~FtraceConfig_CompactSchedConfig() = default;
17647 FtraceConfig_CompactSchedConfig::FtraceConfig_CompactSchedConfig(const FtraceConfig_CompactSchedConfig&) = default;
17648 FtraceConfig_CompactSchedConfig& FtraceConfig_CompactSchedConfig::operator=(const FtraceConfig_CompactSchedConfig&) = default;
17649 FtraceConfig_CompactSchedConfig::FtraceConfig_CompactSchedConfig(FtraceConfig_CompactSchedConfig&&) noexcept = default;
17650 FtraceConfig_CompactSchedConfig& FtraceConfig_CompactSchedConfig::operator=(FtraceConfig_CompactSchedConfig&&) = default;
17651 
operator ==(const FtraceConfig_CompactSchedConfig & other) const17652 bool FtraceConfig_CompactSchedConfig::operator==(const FtraceConfig_CompactSchedConfig& other) const {
17653   return unknown_fields_ == other.unknown_fields_
17654    && enabled_ == other.enabled_;
17655 }
17656 
ParseFromArray(const void * raw,size_t size)17657 bool FtraceConfig_CompactSchedConfig::ParseFromArray(const void* raw, size_t size) {
17658   unknown_fields_.clear();
17659   bool packed_error = false;
17660 
17661   ::protozero::ProtoDecoder dec(raw, size);
17662   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
17663     if (field.id() < _has_field_.size()) {
17664       _has_field_.set(field.id());
17665     }
17666     switch (field.id()) {
17667       case 1 /* enabled */:
17668         field.get(&enabled_);
17669         break;
17670       default:
17671         field.SerializeAndAppendTo(&unknown_fields_);
17672         break;
17673     }
17674   }
17675   return !packed_error && !dec.bytes_left();
17676 }
17677 
SerializeAsString() const17678 std::string FtraceConfig_CompactSchedConfig::SerializeAsString() const {
17679   ::protozero::HeapBuffered<::protozero::Message> msg;
17680   Serialize(msg.get());
17681   return msg.SerializeAsString();
17682 }
17683 
SerializeAsArray() const17684 std::vector<uint8_t> FtraceConfig_CompactSchedConfig::SerializeAsArray() const {
17685   ::protozero::HeapBuffered<::protozero::Message> msg;
17686   Serialize(msg.get());
17687   return msg.SerializeAsArray();
17688 }
17689 
Serialize(::protozero::Message * msg) const17690 void FtraceConfig_CompactSchedConfig::Serialize(::protozero::Message* msg) const {
17691   // Field 1: enabled
17692   if (_has_field_[1]) {
17693     msg->AppendTinyVarInt(1, enabled_);
17694   }
17695 
17696   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
17697 }
17698 
17699 }  // namespace perfetto
17700 }  // namespace protos
17701 }  // namespace gen
17702 #if defined(__GNUC__) || defined(__clang__)
17703 #pragma GCC diagnostic pop
17704 #endif
17705 // gen_amalgamated begin source: gen/protos/perfetto/config/gpu/gpu_counter_config.gen.cc
17706 // gen_amalgamated begin header: gen/protos/perfetto/config/gpu/gpu_counter_config.gen.h
17707 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
17708 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_GPU_GPU_COUNTER_CONFIG_PROTO_CPP_H_
17709 #define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_GPU_GPU_COUNTER_CONFIG_PROTO_CPP_H_
17710 
17711 #include <stdint.h>
17712 #include <bitset>
17713 #include <vector>
17714 #include <string>
17715 #include <type_traits>
17716 
17717 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
17718 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
17719 // gen_amalgamated expanded: #include "perfetto/base/export.h"
17720 
17721 namespace perfetto {
17722 namespace protos {
17723 namespace gen {
17724 class GpuCounterConfig;
17725 }  // namespace perfetto
17726 }  // namespace protos
17727 }  // namespace gen
17728 
17729 namespace protozero {
17730 class Message;
17731 }  // namespace protozero
17732 
17733 namespace perfetto {
17734 namespace protos {
17735 namespace gen {
17736 
17737 class PERFETTO_EXPORT GpuCounterConfig : public ::protozero::CppMessageObj {
17738  public:
17739   enum FieldNumbers {
17740     kCounterPeriodNsFieldNumber = 1,
17741     kCounterIdsFieldNumber = 2,
17742     kInstrumentedSamplingFieldNumber = 3,
17743     kFixGpuClockFieldNumber = 4,
17744   };
17745 
17746   GpuCounterConfig();
17747   ~GpuCounterConfig() override;
17748   GpuCounterConfig(GpuCounterConfig&&) noexcept;
17749   GpuCounterConfig& operator=(GpuCounterConfig&&);
17750   GpuCounterConfig(const GpuCounterConfig&);
17751   GpuCounterConfig& operator=(const GpuCounterConfig&);
17752   bool operator==(const GpuCounterConfig&) const;
operator !=(const GpuCounterConfig & other) const17753   bool operator!=(const GpuCounterConfig& other) const { return !(*this == other); }
17754 
17755   bool ParseFromArray(const void*, size_t) override;
17756   std::string SerializeAsString() const override;
17757   std::vector<uint8_t> SerializeAsArray() const override;
17758   void Serialize(::protozero::Message*) const;
17759 
has_counter_period_ns() const17760   bool has_counter_period_ns() const { return _has_field_[1]; }
counter_period_ns() const17761   uint64_t counter_period_ns() const { return counter_period_ns_; }
set_counter_period_ns(uint64_t value)17762   void set_counter_period_ns(uint64_t value) { counter_period_ns_ = value; _has_field_.set(1); }
17763 
counter_ids() const17764   const std::vector<uint32_t>& counter_ids() const { return counter_ids_; }
mutable_counter_ids()17765   std::vector<uint32_t>* mutable_counter_ids() { return &counter_ids_; }
counter_ids_size() const17766   int counter_ids_size() const { return static_cast<int>(counter_ids_.size()); }
clear_counter_ids()17767   void clear_counter_ids() { counter_ids_.clear(); }
add_counter_ids(uint32_t value)17768   void add_counter_ids(uint32_t value) { counter_ids_.emplace_back(value); }
add_counter_ids()17769   uint32_t* add_counter_ids() { counter_ids_.emplace_back(); return &counter_ids_.back(); }
17770 
has_instrumented_sampling() const17771   bool has_instrumented_sampling() const { return _has_field_[3]; }
instrumented_sampling() const17772   bool instrumented_sampling() const { return instrumented_sampling_; }
set_instrumented_sampling(bool value)17773   void set_instrumented_sampling(bool value) { instrumented_sampling_ = value; _has_field_.set(3); }
17774 
has_fix_gpu_clock() const17775   bool has_fix_gpu_clock() const { return _has_field_[4]; }
fix_gpu_clock() const17776   bool fix_gpu_clock() const { return fix_gpu_clock_; }
set_fix_gpu_clock(bool value)17777   void set_fix_gpu_clock(bool value) { fix_gpu_clock_ = value; _has_field_.set(4); }
17778 
17779  private:
17780   uint64_t counter_period_ns_{};
17781   std::vector<uint32_t> counter_ids_;
17782   bool instrumented_sampling_{};
17783   bool fix_gpu_clock_{};
17784 
17785   // Allows to preserve unknown protobuf fields for compatibility
17786   // with future versions of .proto files.
17787   std::string unknown_fields_;
17788 
17789   std::bitset<5> _has_field_{};
17790 };
17791 
17792 }  // namespace perfetto
17793 }  // namespace protos
17794 }  // namespace gen
17795 
17796 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_GPU_GPU_COUNTER_CONFIG_PROTO_CPP_H_
17797 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
17798 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
17799 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
17800 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
17801 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
17802 #if defined(__GNUC__) || defined(__clang__)
17803 #pragma GCC diagnostic push
17804 #pragma GCC diagnostic ignored "-Wfloat-equal"
17805 #endif
17806 // gen_amalgamated expanded: #include "protos/perfetto/config/gpu/gpu_counter_config.gen.h"
17807 
17808 namespace perfetto {
17809 namespace protos {
17810 namespace gen {
17811 
17812 GpuCounterConfig::GpuCounterConfig() = default;
17813 GpuCounterConfig::~GpuCounterConfig() = default;
17814 GpuCounterConfig::GpuCounterConfig(const GpuCounterConfig&) = default;
17815 GpuCounterConfig& GpuCounterConfig::operator=(const GpuCounterConfig&) = default;
17816 GpuCounterConfig::GpuCounterConfig(GpuCounterConfig&&) noexcept = default;
17817 GpuCounterConfig& GpuCounterConfig::operator=(GpuCounterConfig&&) = default;
17818 
operator ==(const GpuCounterConfig & other) const17819 bool GpuCounterConfig::operator==(const GpuCounterConfig& other) const {
17820   return unknown_fields_ == other.unknown_fields_
17821    && counter_period_ns_ == other.counter_period_ns_
17822    && counter_ids_ == other.counter_ids_
17823    && instrumented_sampling_ == other.instrumented_sampling_
17824    && fix_gpu_clock_ == other.fix_gpu_clock_;
17825 }
17826 
ParseFromArray(const void * raw,size_t size)17827 bool GpuCounterConfig::ParseFromArray(const void* raw, size_t size) {
17828   counter_ids_.clear();
17829   unknown_fields_.clear();
17830   bool packed_error = false;
17831 
17832   ::protozero::ProtoDecoder dec(raw, size);
17833   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
17834     if (field.id() < _has_field_.size()) {
17835       _has_field_.set(field.id());
17836     }
17837     switch (field.id()) {
17838       case 1 /* counter_period_ns */:
17839         field.get(&counter_period_ns_);
17840         break;
17841       case 2 /* counter_ids */:
17842         counter_ids_.emplace_back();
17843         field.get(&counter_ids_.back());
17844         break;
17845       case 3 /* instrumented_sampling */:
17846         field.get(&instrumented_sampling_);
17847         break;
17848       case 4 /* fix_gpu_clock */:
17849         field.get(&fix_gpu_clock_);
17850         break;
17851       default:
17852         field.SerializeAndAppendTo(&unknown_fields_);
17853         break;
17854     }
17855   }
17856   return !packed_error && !dec.bytes_left();
17857 }
17858 
SerializeAsString() const17859 std::string GpuCounterConfig::SerializeAsString() const {
17860   ::protozero::HeapBuffered<::protozero::Message> msg;
17861   Serialize(msg.get());
17862   return msg.SerializeAsString();
17863 }
17864 
SerializeAsArray() const17865 std::vector<uint8_t> GpuCounterConfig::SerializeAsArray() const {
17866   ::protozero::HeapBuffered<::protozero::Message> msg;
17867   Serialize(msg.get());
17868   return msg.SerializeAsArray();
17869 }
17870 
Serialize(::protozero::Message * msg) const17871 void GpuCounterConfig::Serialize(::protozero::Message* msg) const {
17872   // Field 1: counter_period_ns
17873   if (_has_field_[1]) {
17874     msg->AppendVarInt(1, counter_period_ns_);
17875   }
17876 
17877   // Field 2: counter_ids
17878   for (auto& it : counter_ids_) {
17879     msg->AppendVarInt(2, it);
17880   }
17881 
17882   // Field 3: instrumented_sampling
17883   if (_has_field_[3]) {
17884     msg->AppendTinyVarInt(3, instrumented_sampling_);
17885   }
17886 
17887   // Field 4: fix_gpu_clock
17888   if (_has_field_[4]) {
17889     msg->AppendTinyVarInt(4, fix_gpu_clock_);
17890   }
17891 
17892   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
17893 }
17894 
17895 }  // namespace perfetto
17896 }  // namespace protos
17897 }  // namespace gen
17898 #if defined(__GNUC__) || defined(__clang__)
17899 #pragma GCC diagnostic pop
17900 #endif
17901 // gen_amalgamated begin source: gen/protos/perfetto/config/gpu/vulkan_memory_config.gen.cc
17902 // gen_amalgamated begin header: gen/protos/perfetto/config/gpu/vulkan_memory_config.gen.h
17903 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
17904 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_GPU_VULKAN_MEMORY_CONFIG_PROTO_CPP_H_
17905 #define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_GPU_VULKAN_MEMORY_CONFIG_PROTO_CPP_H_
17906 
17907 #include <stdint.h>
17908 #include <bitset>
17909 #include <vector>
17910 #include <string>
17911 #include <type_traits>
17912 
17913 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
17914 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
17915 // gen_amalgamated expanded: #include "perfetto/base/export.h"
17916 
17917 namespace perfetto {
17918 namespace protos {
17919 namespace gen {
17920 class VulkanMemoryConfig;
17921 }  // namespace perfetto
17922 }  // namespace protos
17923 }  // namespace gen
17924 
17925 namespace protozero {
17926 class Message;
17927 }  // namespace protozero
17928 
17929 namespace perfetto {
17930 namespace protos {
17931 namespace gen {
17932 
17933 class PERFETTO_EXPORT VulkanMemoryConfig : public ::protozero::CppMessageObj {
17934  public:
17935   enum FieldNumbers {
17936     kTrackDriverMemoryUsageFieldNumber = 1,
17937     kTrackDeviceMemoryUsageFieldNumber = 2,
17938   };
17939 
17940   VulkanMemoryConfig();
17941   ~VulkanMemoryConfig() override;
17942   VulkanMemoryConfig(VulkanMemoryConfig&&) noexcept;
17943   VulkanMemoryConfig& operator=(VulkanMemoryConfig&&);
17944   VulkanMemoryConfig(const VulkanMemoryConfig&);
17945   VulkanMemoryConfig& operator=(const VulkanMemoryConfig&);
17946   bool operator==(const VulkanMemoryConfig&) const;
operator !=(const VulkanMemoryConfig & other) const17947   bool operator!=(const VulkanMemoryConfig& other) const { return !(*this == other); }
17948 
17949   bool ParseFromArray(const void*, size_t) override;
17950   std::string SerializeAsString() const override;
17951   std::vector<uint8_t> SerializeAsArray() const override;
17952   void Serialize(::protozero::Message*) const;
17953 
has_track_driver_memory_usage() const17954   bool has_track_driver_memory_usage() const { return _has_field_[1]; }
track_driver_memory_usage() const17955   bool track_driver_memory_usage() const { return track_driver_memory_usage_; }
set_track_driver_memory_usage(bool value)17956   void set_track_driver_memory_usage(bool value) { track_driver_memory_usage_ = value; _has_field_.set(1); }
17957 
has_track_device_memory_usage() const17958   bool has_track_device_memory_usage() const { return _has_field_[2]; }
track_device_memory_usage() const17959   bool track_device_memory_usage() const { return track_device_memory_usage_; }
set_track_device_memory_usage(bool value)17960   void set_track_device_memory_usage(bool value) { track_device_memory_usage_ = value; _has_field_.set(2); }
17961 
17962  private:
17963   bool track_driver_memory_usage_{};
17964   bool track_device_memory_usage_{};
17965 
17966   // Allows to preserve unknown protobuf fields for compatibility
17967   // with future versions of .proto files.
17968   std::string unknown_fields_;
17969 
17970   std::bitset<3> _has_field_{};
17971 };
17972 
17973 }  // namespace perfetto
17974 }  // namespace protos
17975 }  // namespace gen
17976 
17977 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_GPU_VULKAN_MEMORY_CONFIG_PROTO_CPP_H_
17978 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
17979 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
17980 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
17981 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
17982 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
17983 #if defined(__GNUC__) || defined(__clang__)
17984 #pragma GCC diagnostic push
17985 #pragma GCC diagnostic ignored "-Wfloat-equal"
17986 #endif
17987 // gen_amalgamated expanded: #include "protos/perfetto/config/gpu/vulkan_memory_config.gen.h"
17988 
17989 namespace perfetto {
17990 namespace protos {
17991 namespace gen {
17992 
17993 VulkanMemoryConfig::VulkanMemoryConfig() = default;
17994 VulkanMemoryConfig::~VulkanMemoryConfig() = default;
17995 VulkanMemoryConfig::VulkanMemoryConfig(const VulkanMemoryConfig&) = default;
17996 VulkanMemoryConfig& VulkanMemoryConfig::operator=(const VulkanMemoryConfig&) = default;
17997 VulkanMemoryConfig::VulkanMemoryConfig(VulkanMemoryConfig&&) noexcept = default;
17998 VulkanMemoryConfig& VulkanMemoryConfig::operator=(VulkanMemoryConfig&&) = default;
17999 
operator ==(const VulkanMemoryConfig & other) const18000 bool VulkanMemoryConfig::operator==(const VulkanMemoryConfig& other) const {
18001   return unknown_fields_ == other.unknown_fields_
18002    && track_driver_memory_usage_ == other.track_driver_memory_usage_
18003    && track_device_memory_usage_ == other.track_device_memory_usage_;
18004 }
18005 
ParseFromArray(const void * raw,size_t size)18006 bool VulkanMemoryConfig::ParseFromArray(const void* raw, size_t size) {
18007   unknown_fields_.clear();
18008   bool packed_error = false;
18009 
18010   ::protozero::ProtoDecoder dec(raw, size);
18011   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
18012     if (field.id() < _has_field_.size()) {
18013       _has_field_.set(field.id());
18014     }
18015     switch (field.id()) {
18016       case 1 /* track_driver_memory_usage */:
18017         field.get(&track_driver_memory_usage_);
18018         break;
18019       case 2 /* track_device_memory_usage */:
18020         field.get(&track_device_memory_usage_);
18021         break;
18022       default:
18023         field.SerializeAndAppendTo(&unknown_fields_);
18024         break;
18025     }
18026   }
18027   return !packed_error && !dec.bytes_left();
18028 }
18029 
SerializeAsString() const18030 std::string VulkanMemoryConfig::SerializeAsString() const {
18031   ::protozero::HeapBuffered<::protozero::Message> msg;
18032   Serialize(msg.get());
18033   return msg.SerializeAsString();
18034 }
18035 
SerializeAsArray() const18036 std::vector<uint8_t> VulkanMemoryConfig::SerializeAsArray() const {
18037   ::protozero::HeapBuffered<::protozero::Message> msg;
18038   Serialize(msg.get());
18039   return msg.SerializeAsArray();
18040 }
18041 
Serialize(::protozero::Message * msg) const18042 void VulkanMemoryConfig::Serialize(::protozero::Message* msg) const {
18043   // Field 1: track_driver_memory_usage
18044   if (_has_field_[1]) {
18045     msg->AppendTinyVarInt(1, track_driver_memory_usage_);
18046   }
18047 
18048   // Field 2: track_device_memory_usage
18049   if (_has_field_[2]) {
18050     msg->AppendTinyVarInt(2, track_device_memory_usage_);
18051   }
18052 
18053   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
18054 }
18055 
18056 }  // namespace perfetto
18057 }  // namespace protos
18058 }  // namespace gen
18059 #if defined(__GNUC__) || defined(__clang__)
18060 #pragma GCC diagnostic pop
18061 #endif
18062 // gen_amalgamated begin source: gen/protos/perfetto/config/inode_file/inode_file_config.gen.cc
18063 // gen_amalgamated begin header: gen/protos/perfetto/config/inode_file/inode_file_config.gen.h
18064 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
18065 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_INODE_FILE_INODE_FILE_CONFIG_PROTO_CPP_H_
18066 #define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_INODE_FILE_INODE_FILE_CONFIG_PROTO_CPP_H_
18067 
18068 #include <stdint.h>
18069 #include <bitset>
18070 #include <vector>
18071 #include <string>
18072 #include <type_traits>
18073 
18074 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
18075 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
18076 // gen_amalgamated expanded: #include "perfetto/base/export.h"
18077 
18078 namespace perfetto {
18079 namespace protos {
18080 namespace gen {
18081 class InodeFileConfig;
18082 class InodeFileConfig_MountPointMappingEntry;
18083 }  // namespace perfetto
18084 }  // namespace protos
18085 }  // namespace gen
18086 
18087 namespace protozero {
18088 class Message;
18089 }  // namespace protozero
18090 
18091 namespace perfetto {
18092 namespace protos {
18093 namespace gen {
18094 
18095 class PERFETTO_EXPORT InodeFileConfig : public ::protozero::CppMessageObj {
18096  public:
18097   using MountPointMappingEntry = InodeFileConfig_MountPointMappingEntry;
18098   enum FieldNumbers {
18099     kScanIntervalMsFieldNumber = 1,
18100     kScanDelayMsFieldNumber = 2,
18101     kScanBatchSizeFieldNumber = 3,
18102     kDoNotScanFieldNumber = 4,
18103     kScanMountPointsFieldNumber = 5,
18104     kMountPointMappingFieldNumber = 6,
18105   };
18106 
18107   InodeFileConfig();
18108   ~InodeFileConfig() override;
18109   InodeFileConfig(InodeFileConfig&&) noexcept;
18110   InodeFileConfig& operator=(InodeFileConfig&&);
18111   InodeFileConfig(const InodeFileConfig&);
18112   InodeFileConfig& operator=(const InodeFileConfig&);
18113   bool operator==(const InodeFileConfig&) const;
operator !=(const InodeFileConfig & other) const18114   bool operator!=(const InodeFileConfig& other) const { return !(*this == other); }
18115 
18116   bool ParseFromArray(const void*, size_t) override;
18117   std::string SerializeAsString() const override;
18118   std::vector<uint8_t> SerializeAsArray() const override;
18119   void Serialize(::protozero::Message*) const;
18120 
has_scan_interval_ms() const18121   bool has_scan_interval_ms() const { return _has_field_[1]; }
scan_interval_ms() const18122   uint32_t scan_interval_ms() const { return scan_interval_ms_; }
set_scan_interval_ms(uint32_t value)18123   void set_scan_interval_ms(uint32_t value) { scan_interval_ms_ = value; _has_field_.set(1); }
18124 
has_scan_delay_ms() const18125   bool has_scan_delay_ms() const { return _has_field_[2]; }
scan_delay_ms() const18126   uint32_t scan_delay_ms() const { return scan_delay_ms_; }
set_scan_delay_ms(uint32_t value)18127   void set_scan_delay_ms(uint32_t value) { scan_delay_ms_ = value; _has_field_.set(2); }
18128 
has_scan_batch_size() const18129   bool has_scan_batch_size() const { return _has_field_[3]; }
scan_batch_size() const18130   uint32_t scan_batch_size() const { return scan_batch_size_; }
set_scan_batch_size(uint32_t value)18131   void set_scan_batch_size(uint32_t value) { scan_batch_size_ = value; _has_field_.set(3); }
18132 
has_do_not_scan() const18133   bool has_do_not_scan() const { return _has_field_[4]; }
do_not_scan() const18134   bool do_not_scan() const { return do_not_scan_; }
set_do_not_scan(bool value)18135   void set_do_not_scan(bool value) { do_not_scan_ = value; _has_field_.set(4); }
18136 
scan_mount_points() const18137   const std::vector<std::string>& scan_mount_points() const { return scan_mount_points_; }
mutable_scan_mount_points()18138   std::vector<std::string>* mutable_scan_mount_points() { return &scan_mount_points_; }
scan_mount_points_size() const18139   int scan_mount_points_size() const { return static_cast<int>(scan_mount_points_.size()); }
clear_scan_mount_points()18140   void clear_scan_mount_points() { scan_mount_points_.clear(); }
add_scan_mount_points(std::string value)18141   void add_scan_mount_points(std::string value) { scan_mount_points_.emplace_back(value); }
add_scan_mount_points()18142   std::string* add_scan_mount_points() { scan_mount_points_.emplace_back(); return &scan_mount_points_.back(); }
18143 
mount_point_mapping() const18144   const std::vector<InodeFileConfig_MountPointMappingEntry>& mount_point_mapping() const { return mount_point_mapping_; }
mutable_mount_point_mapping()18145   std::vector<InodeFileConfig_MountPointMappingEntry>* mutable_mount_point_mapping() { return &mount_point_mapping_; }
18146   int mount_point_mapping_size() const;
18147   void clear_mount_point_mapping();
18148   InodeFileConfig_MountPointMappingEntry* add_mount_point_mapping();
18149 
18150  private:
18151   uint32_t scan_interval_ms_{};
18152   uint32_t scan_delay_ms_{};
18153   uint32_t scan_batch_size_{};
18154   bool do_not_scan_{};
18155   std::vector<std::string> scan_mount_points_;
18156   std::vector<InodeFileConfig_MountPointMappingEntry> mount_point_mapping_;
18157 
18158   // Allows to preserve unknown protobuf fields for compatibility
18159   // with future versions of .proto files.
18160   std::string unknown_fields_;
18161 
18162   std::bitset<7> _has_field_{};
18163 };
18164 
18165 
18166 class PERFETTO_EXPORT InodeFileConfig_MountPointMappingEntry : public ::protozero::CppMessageObj {
18167  public:
18168   enum FieldNumbers {
18169     kMountpointFieldNumber = 1,
18170     kScanRootsFieldNumber = 2,
18171   };
18172 
18173   InodeFileConfig_MountPointMappingEntry();
18174   ~InodeFileConfig_MountPointMappingEntry() override;
18175   InodeFileConfig_MountPointMappingEntry(InodeFileConfig_MountPointMappingEntry&&) noexcept;
18176   InodeFileConfig_MountPointMappingEntry& operator=(InodeFileConfig_MountPointMappingEntry&&);
18177   InodeFileConfig_MountPointMappingEntry(const InodeFileConfig_MountPointMappingEntry&);
18178   InodeFileConfig_MountPointMappingEntry& operator=(const InodeFileConfig_MountPointMappingEntry&);
18179   bool operator==(const InodeFileConfig_MountPointMappingEntry&) const;
operator !=(const InodeFileConfig_MountPointMappingEntry & other) const18180   bool operator!=(const InodeFileConfig_MountPointMappingEntry& other) const { return !(*this == other); }
18181 
18182   bool ParseFromArray(const void*, size_t) override;
18183   std::string SerializeAsString() const override;
18184   std::vector<uint8_t> SerializeAsArray() const override;
18185   void Serialize(::protozero::Message*) const;
18186 
has_mountpoint() const18187   bool has_mountpoint() const { return _has_field_[1]; }
mountpoint() const18188   const std::string& mountpoint() const { return mountpoint_; }
set_mountpoint(const std::string & value)18189   void set_mountpoint(const std::string& value) { mountpoint_ = value; _has_field_.set(1); }
18190 
scan_roots() const18191   const std::vector<std::string>& scan_roots() const { return scan_roots_; }
mutable_scan_roots()18192   std::vector<std::string>* mutable_scan_roots() { return &scan_roots_; }
scan_roots_size() const18193   int scan_roots_size() const { return static_cast<int>(scan_roots_.size()); }
clear_scan_roots()18194   void clear_scan_roots() { scan_roots_.clear(); }
add_scan_roots(std::string value)18195   void add_scan_roots(std::string value) { scan_roots_.emplace_back(value); }
add_scan_roots()18196   std::string* add_scan_roots() { scan_roots_.emplace_back(); return &scan_roots_.back(); }
18197 
18198  private:
18199   std::string mountpoint_{};
18200   std::vector<std::string> scan_roots_;
18201 
18202   // Allows to preserve unknown protobuf fields for compatibility
18203   // with future versions of .proto files.
18204   std::string unknown_fields_;
18205 
18206   std::bitset<3> _has_field_{};
18207 };
18208 
18209 }  // namespace perfetto
18210 }  // namespace protos
18211 }  // namespace gen
18212 
18213 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_INODE_FILE_INODE_FILE_CONFIG_PROTO_CPP_H_
18214 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
18215 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
18216 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
18217 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
18218 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
18219 #if defined(__GNUC__) || defined(__clang__)
18220 #pragma GCC diagnostic push
18221 #pragma GCC diagnostic ignored "-Wfloat-equal"
18222 #endif
18223 // gen_amalgamated expanded: #include "protos/perfetto/config/inode_file/inode_file_config.gen.h"
18224 
18225 namespace perfetto {
18226 namespace protos {
18227 namespace gen {
18228 
18229 InodeFileConfig::InodeFileConfig() = default;
18230 InodeFileConfig::~InodeFileConfig() = default;
18231 InodeFileConfig::InodeFileConfig(const InodeFileConfig&) = default;
18232 InodeFileConfig& InodeFileConfig::operator=(const InodeFileConfig&) = default;
18233 InodeFileConfig::InodeFileConfig(InodeFileConfig&&) noexcept = default;
18234 InodeFileConfig& InodeFileConfig::operator=(InodeFileConfig&&) = default;
18235 
operator ==(const InodeFileConfig & other) const18236 bool InodeFileConfig::operator==(const InodeFileConfig& other) const {
18237   return unknown_fields_ == other.unknown_fields_
18238    && scan_interval_ms_ == other.scan_interval_ms_
18239    && scan_delay_ms_ == other.scan_delay_ms_
18240    && scan_batch_size_ == other.scan_batch_size_
18241    && do_not_scan_ == other.do_not_scan_
18242    && scan_mount_points_ == other.scan_mount_points_
18243    && mount_point_mapping_ == other.mount_point_mapping_;
18244 }
18245 
mount_point_mapping_size() const18246 int InodeFileConfig::mount_point_mapping_size() const { return static_cast<int>(mount_point_mapping_.size()); }
clear_mount_point_mapping()18247 void InodeFileConfig::clear_mount_point_mapping() { mount_point_mapping_.clear(); }
add_mount_point_mapping()18248 InodeFileConfig_MountPointMappingEntry* InodeFileConfig::add_mount_point_mapping() { mount_point_mapping_.emplace_back(); return &mount_point_mapping_.back(); }
ParseFromArray(const void * raw,size_t size)18249 bool InodeFileConfig::ParseFromArray(const void* raw, size_t size) {
18250   scan_mount_points_.clear();
18251   mount_point_mapping_.clear();
18252   unknown_fields_.clear();
18253   bool packed_error = false;
18254 
18255   ::protozero::ProtoDecoder dec(raw, size);
18256   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
18257     if (field.id() < _has_field_.size()) {
18258       _has_field_.set(field.id());
18259     }
18260     switch (field.id()) {
18261       case 1 /* scan_interval_ms */:
18262         field.get(&scan_interval_ms_);
18263         break;
18264       case 2 /* scan_delay_ms */:
18265         field.get(&scan_delay_ms_);
18266         break;
18267       case 3 /* scan_batch_size */:
18268         field.get(&scan_batch_size_);
18269         break;
18270       case 4 /* do_not_scan */:
18271         field.get(&do_not_scan_);
18272         break;
18273       case 5 /* scan_mount_points */:
18274         scan_mount_points_.emplace_back();
18275         field.get(&scan_mount_points_.back());
18276         break;
18277       case 6 /* mount_point_mapping */:
18278         mount_point_mapping_.emplace_back();
18279         mount_point_mapping_.back().ParseFromArray(field.data(), field.size());
18280         break;
18281       default:
18282         field.SerializeAndAppendTo(&unknown_fields_);
18283         break;
18284     }
18285   }
18286   return !packed_error && !dec.bytes_left();
18287 }
18288 
SerializeAsString() const18289 std::string InodeFileConfig::SerializeAsString() const {
18290   ::protozero::HeapBuffered<::protozero::Message> msg;
18291   Serialize(msg.get());
18292   return msg.SerializeAsString();
18293 }
18294 
SerializeAsArray() const18295 std::vector<uint8_t> InodeFileConfig::SerializeAsArray() const {
18296   ::protozero::HeapBuffered<::protozero::Message> msg;
18297   Serialize(msg.get());
18298   return msg.SerializeAsArray();
18299 }
18300 
Serialize(::protozero::Message * msg) const18301 void InodeFileConfig::Serialize(::protozero::Message* msg) const {
18302   // Field 1: scan_interval_ms
18303   if (_has_field_[1]) {
18304     msg->AppendVarInt(1, scan_interval_ms_);
18305   }
18306 
18307   // Field 2: scan_delay_ms
18308   if (_has_field_[2]) {
18309     msg->AppendVarInt(2, scan_delay_ms_);
18310   }
18311 
18312   // Field 3: scan_batch_size
18313   if (_has_field_[3]) {
18314     msg->AppendVarInt(3, scan_batch_size_);
18315   }
18316 
18317   // Field 4: do_not_scan
18318   if (_has_field_[4]) {
18319     msg->AppendTinyVarInt(4, do_not_scan_);
18320   }
18321 
18322   // Field 5: scan_mount_points
18323   for (auto& it : scan_mount_points_) {
18324     msg->AppendString(5, it);
18325   }
18326 
18327   // Field 6: mount_point_mapping
18328   for (auto& it : mount_point_mapping_) {
18329     it.Serialize(msg->BeginNestedMessage<::protozero::Message>(6));
18330   }
18331 
18332   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
18333 }
18334 
18335 
18336 InodeFileConfig_MountPointMappingEntry::InodeFileConfig_MountPointMappingEntry() = default;
18337 InodeFileConfig_MountPointMappingEntry::~InodeFileConfig_MountPointMappingEntry() = default;
18338 InodeFileConfig_MountPointMappingEntry::InodeFileConfig_MountPointMappingEntry(const InodeFileConfig_MountPointMappingEntry&) = default;
18339 InodeFileConfig_MountPointMappingEntry& InodeFileConfig_MountPointMappingEntry::operator=(const InodeFileConfig_MountPointMappingEntry&) = default;
18340 InodeFileConfig_MountPointMappingEntry::InodeFileConfig_MountPointMappingEntry(InodeFileConfig_MountPointMappingEntry&&) noexcept = default;
18341 InodeFileConfig_MountPointMappingEntry& InodeFileConfig_MountPointMappingEntry::operator=(InodeFileConfig_MountPointMappingEntry&&) = default;
18342 
operator ==(const InodeFileConfig_MountPointMappingEntry & other) const18343 bool InodeFileConfig_MountPointMappingEntry::operator==(const InodeFileConfig_MountPointMappingEntry& other) const {
18344   return unknown_fields_ == other.unknown_fields_
18345    && mountpoint_ == other.mountpoint_
18346    && scan_roots_ == other.scan_roots_;
18347 }
18348 
ParseFromArray(const void * raw,size_t size)18349 bool InodeFileConfig_MountPointMappingEntry::ParseFromArray(const void* raw, size_t size) {
18350   scan_roots_.clear();
18351   unknown_fields_.clear();
18352   bool packed_error = false;
18353 
18354   ::protozero::ProtoDecoder dec(raw, size);
18355   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
18356     if (field.id() < _has_field_.size()) {
18357       _has_field_.set(field.id());
18358     }
18359     switch (field.id()) {
18360       case 1 /* mountpoint */:
18361         field.get(&mountpoint_);
18362         break;
18363       case 2 /* scan_roots */:
18364         scan_roots_.emplace_back();
18365         field.get(&scan_roots_.back());
18366         break;
18367       default:
18368         field.SerializeAndAppendTo(&unknown_fields_);
18369         break;
18370     }
18371   }
18372   return !packed_error && !dec.bytes_left();
18373 }
18374 
SerializeAsString() const18375 std::string InodeFileConfig_MountPointMappingEntry::SerializeAsString() const {
18376   ::protozero::HeapBuffered<::protozero::Message> msg;
18377   Serialize(msg.get());
18378   return msg.SerializeAsString();
18379 }
18380 
SerializeAsArray() const18381 std::vector<uint8_t> InodeFileConfig_MountPointMappingEntry::SerializeAsArray() const {
18382   ::protozero::HeapBuffered<::protozero::Message> msg;
18383   Serialize(msg.get());
18384   return msg.SerializeAsArray();
18385 }
18386 
Serialize(::protozero::Message * msg) const18387 void InodeFileConfig_MountPointMappingEntry::Serialize(::protozero::Message* msg) const {
18388   // Field 1: mountpoint
18389   if (_has_field_[1]) {
18390     msg->AppendString(1, mountpoint_);
18391   }
18392 
18393   // Field 2: scan_roots
18394   for (auto& it : scan_roots_) {
18395     msg->AppendString(2, it);
18396   }
18397 
18398   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
18399 }
18400 
18401 }  // namespace perfetto
18402 }  // namespace protos
18403 }  // namespace gen
18404 #if defined(__GNUC__) || defined(__clang__)
18405 #pragma GCC diagnostic pop
18406 #endif
18407 // gen_amalgamated begin source: gen/protos/perfetto/config/interceptors/console_config.gen.cc
18408 // gen_amalgamated begin header: gen/protos/perfetto/config/interceptors/console_config.gen.h
18409 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
18410 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_INTERCEPTORS_CONSOLE_CONFIG_PROTO_CPP_H_
18411 #define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_INTERCEPTORS_CONSOLE_CONFIG_PROTO_CPP_H_
18412 
18413 #include <stdint.h>
18414 #include <bitset>
18415 #include <vector>
18416 #include <string>
18417 #include <type_traits>
18418 
18419 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
18420 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
18421 // gen_amalgamated expanded: #include "perfetto/base/export.h"
18422 
18423 namespace perfetto {
18424 namespace protos {
18425 namespace gen {
18426 class ConsoleConfig;
18427 enum ConsoleConfig_Output : int;
18428 }  // namespace perfetto
18429 }  // namespace protos
18430 }  // namespace gen
18431 
18432 namespace protozero {
18433 class Message;
18434 }  // namespace protozero
18435 
18436 namespace perfetto {
18437 namespace protos {
18438 namespace gen {
18439 enum ConsoleConfig_Output : int {
18440   ConsoleConfig_Output_OUTPUT_UNSPECIFIED = 0,
18441   ConsoleConfig_Output_OUTPUT_STDOUT = 1,
18442   ConsoleConfig_Output_OUTPUT_STDERR = 2,
18443 };
18444 
18445 class PERFETTO_EXPORT ConsoleConfig : public ::protozero::CppMessageObj {
18446  public:
18447   using Output = ConsoleConfig_Output;
18448   static constexpr auto OUTPUT_UNSPECIFIED = ConsoleConfig_Output_OUTPUT_UNSPECIFIED;
18449   static constexpr auto OUTPUT_STDOUT = ConsoleConfig_Output_OUTPUT_STDOUT;
18450   static constexpr auto OUTPUT_STDERR = ConsoleConfig_Output_OUTPUT_STDERR;
18451   static constexpr auto Output_MIN = ConsoleConfig_Output_OUTPUT_UNSPECIFIED;
18452   static constexpr auto Output_MAX = ConsoleConfig_Output_OUTPUT_STDERR;
18453   enum FieldNumbers {
18454     kOutputFieldNumber = 1,
18455     kEnableColorsFieldNumber = 2,
18456   };
18457 
18458   ConsoleConfig();
18459   ~ConsoleConfig() override;
18460   ConsoleConfig(ConsoleConfig&&) noexcept;
18461   ConsoleConfig& operator=(ConsoleConfig&&);
18462   ConsoleConfig(const ConsoleConfig&);
18463   ConsoleConfig& operator=(const ConsoleConfig&);
18464   bool operator==(const ConsoleConfig&) const;
operator !=(const ConsoleConfig & other) const18465   bool operator!=(const ConsoleConfig& other) const { return !(*this == other); }
18466 
18467   bool ParseFromArray(const void*, size_t) override;
18468   std::string SerializeAsString() const override;
18469   std::vector<uint8_t> SerializeAsArray() const override;
18470   void Serialize(::protozero::Message*) const;
18471 
has_output() const18472   bool has_output() const { return _has_field_[1]; }
output() const18473   ConsoleConfig_Output output() const { return output_; }
set_output(ConsoleConfig_Output value)18474   void set_output(ConsoleConfig_Output value) { output_ = value; _has_field_.set(1); }
18475 
has_enable_colors() const18476   bool has_enable_colors() const { return _has_field_[2]; }
enable_colors() const18477   bool enable_colors() const { return enable_colors_; }
set_enable_colors(bool value)18478   void set_enable_colors(bool value) { enable_colors_ = value; _has_field_.set(2); }
18479 
18480  private:
18481   ConsoleConfig_Output output_{};
18482   bool enable_colors_{};
18483 
18484   // Allows to preserve unknown protobuf fields for compatibility
18485   // with future versions of .proto files.
18486   std::string unknown_fields_;
18487 
18488   std::bitset<3> _has_field_{};
18489 };
18490 
18491 }  // namespace perfetto
18492 }  // namespace protos
18493 }  // namespace gen
18494 
18495 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_INTERCEPTORS_CONSOLE_CONFIG_PROTO_CPP_H_
18496 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
18497 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
18498 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
18499 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
18500 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
18501 #if defined(__GNUC__) || defined(__clang__)
18502 #pragma GCC diagnostic push
18503 #pragma GCC diagnostic ignored "-Wfloat-equal"
18504 #endif
18505 // gen_amalgamated expanded: #include "protos/perfetto/config/interceptors/console_config.gen.h"
18506 
18507 namespace perfetto {
18508 namespace protos {
18509 namespace gen {
18510 
18511 ConsoleConfig::ConsoleConfig() = default;
18512 ConsoleConfig::~ConsoleConfig() = default;
18513 ConsoleConfig::ConsoleConfig(const ConsoleConfig&) = default;
18514 ConsoleConfig& ConsoleConfig::operator=(const ConsoleConfig&) = default;
18515 ConsoleConfig::ConsoleConfig(ConsoleConfig&&) noexcept = default;
18516 ConsoleConfig& ConsoleConfig::operator=(ConsoleConfig&&) = default;
18517 
operator ==(const ConsoleConfig & other) const18518 bool ConsoleConfig::operator==(const ConsoleConfig& other) const {
18519   return unknown_fields_ == other.unknown_fields_
18520    && output_ == other.output_
18521    && enable_colors_ == other.enable_colors_;
18522 }
18523 
ParseFromArray(const void * raw,size_t size)18524 bool ConsoleConfig::ParseFromArray(const void* raw, size_t size) {
18525   unknown_fields_.clear();
18526   bool packed_error = false;
18527 
18528   ::protozero::ProtoDecoder dec(raw, size);
18529   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
18530     if (field.id() < _has_field_.size()) {
18531       _has_field_.set(field.id());
18532     }
18533     switch (field.id()) {
18534       case 1 /* output */:
18535         field.get(&output_);
18536         break;
18537       case 2 /* enable_colors */:
18538         field.get(&enable_colors_);
18539         break;
18540       default:
18541         field.SerializeAndAppendTo(&unknown_fields_);
18542         break;
18543     }
18544   }
18545   return !packed_error && !dec.bytes_left();
18546 }
18547 
SerializeAsString() const18548 std::string ConsoleConfig::SerializeAsString() const {
18549   ::protozero::HeapBuffered<::protozero::Message> msg;
18550   Serialize(msg.get());
18551   return msg.SerializeAsString();
18552 }
18553 
SerializeAsArray() const18554 std::vector<uint8_t> ConsoleConfig::SerializeAsArray() const {
18555   ::protozero::HeapBuffered<::protozero::Message> msg;
18556   Serialize(msg.get());
18557   return msg.SerializeAsArray();
18558 }
18559 
Serialize(::protozero::Message * msg) const18560 void ConsoleConfig::Serialize(::protozero::Message* msg) const {
18561   // Field 1: output
18562   if (_has_field_[1]) {
18563     msg->AppendVarInt(1, output_);
18564   }
18565 
18566   // Field 2: enable_colors
18567   if (_has_field_[2]) {
18568     msg->AppendTinyVarInt(2, enable_colors_);
18569   }
18570 
18571   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
18572 }
18573 
18574 }  // namespace perfetto
18575 }  // namespace protos
18576 }  // namespace gen
18577 #if defined(__GNUC__) || defined(__clang__)
18578 #pragma GCC diagnostic pop
18579 #endif
18580 // gen_amalgamated begin source: gen/protos/perfetto/config/power/android_power_config.gen.cc
18581 // gen_amalgamated begin header: gen/protos/perfetto/config/power/android_power_config.gen.h
18582 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
18583 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_POWER_ANDROID_POWER_CONFIG_PROTO_CPP_H_
18584 #define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_POWER_ANDROID_POWER_CONFIG_PROTO_CPP_H_
18585 
18586 #include <stdint.h>
18587 #include <bitset>
18588 #include <vector>
18589 #include <string>
18590 #include <type_traits>
18591 
18592 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
18593 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
18594 // gen_amalgamated expanded: #include "perfetto/base/export.h"
18595 
18596 namespace perfetto {
18597 namespace protos {
18598 namespace gen {
18599 class AndroidPowerConfig;
18600 enum AndroidPowerConfig_BatteryCounters : int;
18601 }  // namespace perfetto
18602 }  // namespace protos
18603 }  // namespace gen
18604 
18605 namespace protozero {
18606 class Message;
18607 }  // namespace protozero
18608 
18609 namespace perfetto {
18610 namespace protos {
18611 namespace gen {
18612 enum AndroidPowerConfig_BatteryCounters : int {
18613   AndroidPowerConfig_BatteryCounters_BATTERY_COUNTER_UNSPECIFIED = 0,
18614   AndroidPowerConfig_BatteryCounters_BATTERY_COUNTER_CHARGE = 1,
18615   AndroidPowerConfig_BatteryCounters_BATTERY_COUNTER_CAPACITY_PERCENT = 2,
18616   AndroidPowerConfig_BatteryCounters_BATTERY_COUNTER_CURRENT = 3,
18617   AndroidPowerConfig_BatteryCounters_BATTERY_COUNTER_CURRENT_AVG = 4,
18618 };
18619 
18620 class PERFETTO_EXPORT AndroidPowerConfig : public ::protozero::CppMessageObj {
18621  public:
18622   using BatteryCounters = AndroidPowerConfig_BatteryCounters;
18623   static constexpr auto BATTERY_COUNTER_UNSPECIFIED = AndroidPowerConfig_BatteryCounters_BATTERY_COUNTER_UNSPECIFIED;
18624   static constexpr auto BATTERY_COUNTER_CHARGE = AndroidPowerConfig_BatteryCounters_BATTERY_COUNTER_CHARGE;
18625   static constexpr auto BATTERY_COUNTER_CAPACITY_PERCENT = AndroidPowerConfig_BatteryCounters_BATTERY_COUNTER_CAPACITY_PERCENT;
18626   static constexpr auto BATTERY_COUNTER_CURRENT = AndroidPowerConfig_BatteryCounters_BATTERY_COUNTER_CURRENT;
18627   static constexpr auto BATTERY_COUNTER_CURRENT_AVG = AndroidPowerConfig_BatteryCounters_BATTERY_COUNTER_CURRENT_AVG;
18628   static constexpr auto BatteryCounters_MIN = AndroidPowerConfig_BatteryCounters_BATTERY_COUNTER_UNSPECIFIED;
18629   static constexpr auto BatteryCounters_MAX = AndroidPowerConfig_BatteryCounters_BATTERY_COUNTER_CURRENT_AVG;
18630   enum FieldNumbers {
18631     kBatteryPollMsFieldNumber = 1,
18632     kBatteryCountersFieldNumber = 2,
18633     kCollectPowerRailsFieldNumber = 3,
18634     kCollectEnergyEstimationBreakdownFieldNumber = 4,
18635   };
18636 
18637   AndroidPowerConfig();
18638   ~AndroidPowerConfig() override;
18639   AndroidPowerConfig(AndroidPowerConfig&&) noexcept;
18640   AndroidPowerConfig& operator=(AndroidPowerConfig&&);
18641   AndroidPowerConfig(const AndroidPowerConfig&);
18642   AndroidPowerConfig& operator=(const AndroidPowerConfig&);
18643   bool operator==(const AndroidPowerConfig&) const;
operator !=(const AndroidPowerConfig & other) const18644   bool operator!=(const AndroidPowerConfig& other) const { return !(*this == other); }
18645 
18646   bool ParseFromArray(const void*, size_t) override;
18647   std::string SerializeAsString() const override;
18648   std::vector<uint8_t> SerializeAsArray() const override;
18649   void Serialize(::protozero::Message*) const;
18650 
has_battery_poll_ms() const18651   bool has_battery_poll_ms() const { return _has_field_[1]; }
battery_poll_ms() const18652   uint32_t battery_poll_ms() const { return battery_poll_ms_; }
set_battery_poll_ms(uint32_t value)18653   void set_battery_poll_ms(uint32_t value) { battery_poll_ms_ = value; _has_field_.set(1); }
18654 
battery_counters() const18655   const std::vector<AndroidPowerConfig_BatteryCounters>& battery_counters() const { return battery_counters_; }
mutable_battery_counters()18656   std::vector<AndroidPowerConfig_BatteryCounters>* mutable_battery_counters() { return &battery_counters_; }
battery_counters_size() const18657   int battery_counters_size() const { return static_cast<int>(battery_counters_.size()); }
clear_battery_counters()18658   void clear_battery_counters() { battery_counters_.clear(); }
add_battery_counters(AndroidPowerConfig_BatteryCounters value)18659   void add_battery_counters(AndroidPowerConfig_BatteryCounters value) { battery_counters_.emplace_back(value); }
add_battery_counters()18660   AndroidPowerConfig_BatteryCounters* add_battery_counters() { battery_counters_.emplace_back(); return &battery_counters_.back(); }
18661 
has_collect_power_rails() const18662   bool has_collect_power_rails() const { return _has_field_[3]; }
collect_power_rails() const18663   bool collect_power_rails() const { return collect_power_rails_; }
set_collect_power_rails(bool value)18664   void set_collect_power_rails(bool value) { collect_power_rails_ = value; _has_field_.set(3); }
18665 
has_collect_energy_estimation_breakdown() const18666   bool has_collect_energy_estimation_breakdown() const { return _has_field_[4]; }
collect_energy_estimation_breakdown() const18667   bool collect_energy_estimation_breakdown() const { return collect_energy_estimation_breakdown_; }
set_collect_energy_estimation_breakdown(bool value)18668   void set_collect_energy_estimation_breakdown(bool value) { collect_energy_estimation_breakdown_ = value; _has_field_.set(4); }
18669 
18670  private:
18671   uint32_t battery_poll_ms_{};
18672   std::vector<AndroidPowerConfig_BatteryCounters> battery_counters_;
18673   bool collect_power_rails_{};
18674   bool collect_energy_estimation_breakdown_{};
18675 
18676   // Allows to preserve unknown protobuf fields for compatibility
18677   // with future versions of .proto files.
18678   std::string unknown_fields_;
18679 
18680   std::bitset<5> _has_field_{};
18681 };
18682 
18683 }  // namespace perfetto
18684 }  // namespace protos
18685 }  // namespace gen
18686 
18687 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_POWER_ANDROID_POWER_CONFIG_PROTO_CPP_H_
18688 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
18689 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
18690 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
18691 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
18692 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
18693 #if defined(__GNUC__) || defined(__clang__)
18694 #pragma GCC diagnostic push
18695 #pragma GCC diagnostic ignored "-Wfloat-equal"
18696 #endif
18697 // gen_amalgamated expanded: #include "protos/perfetto/config/power/android_power_config.gen.h"
18698 
18699 namespace perfetto {
18700 namespace protos {
18701 namespace gen {
18702 
18703 AndroidPowerConfig::AndroidPowerConfig() = default;
18704 AndroidPowerConfig::~AndroidPowerConfig() = default;
18705 AndroidPowerConfig::AndroidPowerConfig(const AndroidPowerConfig&) = default;
18706 AndroidPowerConfig& AndroidPowerConfig::operator=(const AndroidPowerConfig&) = default;
18707 AndroidPowerConfig::AndroidPowerConfig(AndroidPowerConfig&&) noexcept = default;
18708 AndroidPowerConfig& AndroidPowerConfig::operator=(AndroidPowerConfig&&) = default;
18709 
operator ==(const AndroidPowerConfig & other) const18710 bool AndroidPowerConfig::operator==(const AndroidPowerConfig& other) const {
18711   return unknown_fields_ == other.unknown_fields_
18712    && battery_poll_ms_ == other.battery_poll_ms_
18713    && battery_counters_ == other.battery_counters_
18714    && collect_power_rails_ == other.collect_power_rails_
18715    && collect_energy_estimation_breakdown_ == other.collect_energy_estimation_breakdown_;
18716 }
18717 
ParseFromArray(const void * raw,size_t size)18718 bool AndroidPowerConfig::ParseFromArray(const void* raw, size_t size) {
18719   battery_counters_.clear();
18720   unknown_fields_.clear();
18721   bool packed_error = false;
18722 
18723   ::protozero::ProtoDecoder dec(raw, size);
18724   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
18725     if (field.id() < _has_field_.size()) {
18726       _has_field_.set(field.id());
18727     }
18728     switch (field.id()) {
18729       case 1 /* battery_poll_ms */:
18730         field.get(&battery_poll_ms_);
18731         break;
18732       case 2 /* battery_counters */:
18733         battery_counters_.emplace_back();
18734         field.get(&battery_counters_.back());
18735         break;
18736       case 3 /* collect_power_rails */:
18737         field.get(&collect_power_rails_);
18738         break;
18739       case 4 /* collect_energy_estimation_breakdown */:
18740         field.get(&collect_energy_estimation_breakdown_);
18741         break;
18742       default:
18743         field.SerializeAndAppendTo(&unknown_fields_);
18744         break;
18745     }
18746   }
18747   return !packed_error && !dec.bytes_left();
18748 }
18749 
SerializeAsString() const18750 std::string AndroidPowerConfig::SerializeAsString() const {
18751   ::protozero::HeapBuffered<::protozero::Message> msg;
18752   Serialize(msg.get());
18753   return msg.SerializeAsString();
18754 }
18755 
SerializeAsArray() const18756 std::vector<uint8_t> AndroidPowerConfig::SerializeAsArray() const {
18757   ::protozero::HeapBuffered<::protozero::Message> msg;
18758   Serialize(msg.get());
18759   return msg.SerializeAsArray();
18760 }
18761 
Serialize(::protozero::Message * msg) const18762 void AndroidPowerConfig::Serialize(::protozero::Message* msg) const {
18763   // Field 1: battery_poll_ms
18764   if (_has_field_[1]) {
18765     msg->AppendVarInt(1, battery_poll_ms_);
18766   }
18767 
18768   // Field 2: battery_counters
18769   for (auto& it : battery_counters_) {
18770     msg->AppendVarInt(2, it);
18771   }
18772 
18773   // Field 3: collect_power_rails
18774   if (_has_field_[3]) {
18775     msg->AppendTinyVarInt(3, collect_power_rails_);
18776   }
18777 
18778   // Field 4: collect_energy_estimation_breakdown
18779   if (_has_field_[4]) {
18780     msg->AppendTinyVarInt(4, collect_energy_estimation_breakdown_);
18781   }
18782 
18783   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
18784 }
18785 
18786 }  // namespace perfetto
18787 }  // namespace protos
18788 }  // namespace gen
18789 #if defined(__GNUC__) || defined(__clang__)
18790 #pragma GCC diagnostic pop
18791 #endif
18792 // gen_amalgamated begin source: gen/protos/perfetto/config/process_stats/process_stats_config.gen.cc
18793 // gen_amalgamated begin header: gen/protos/perfetto/config/process_stats/process_stats_config.gen.h
18794 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
18795 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_PROCESS_STATS_PROCESS_STATS_CONFIG_PROTO_CPP_H_
18796 #define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_PROCESS_STATS_PROCESS_STATS_CONFIG_PROTO_CPP_H_
18797 
18798 #include <stdint.h>
18799 #include <bitset>
18800 #include <vector>
18801 #include <string>
18802 #include <type_traits>
18803 
18804 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
18805 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
18806 // gen_amalgamated expanded: #include "perfetto/base/export.h"
18807 
18808 namespace perfetto {
18809 namespace protos {
18810 namespace gen {
18811 class ProcessStatsConfig;
18812 enum ProcessStatsConfig_Quirks : int;
18813 }  // namespace perfetto
18814 }  // namespace protos
18815 }  // namespace gen
18816 
18817 namespace protozero {
18818 class Message;
18819 }  // namespace protozero
18820 
18821 namespace perfetto {
18822 namespace protos {
18823 namespace gen {
18824 enum ProcessStatsConfig_Quirks : int {
18825   ProcessStatsConfig_Quirks_QUIRKS_UNSPECIFIED = 0,
18826   ProcessStatsConfig_Quirks_DISABLE_INITIAL_DUMP = 1,
18827   ProcessStatsConfig_Quirks_DISABLE_ON_DEMAND = 2,
18828 };
18829 
18830 class PERFETTO_EXPORT ProcessStatsConfig : public ::protozero::CppMessageObj {
18831  public:
18832   using Quirks = ProcessStatsConfig_Quirks;
18833   static constexpr auto QUIRKS_UNSPECIFIED = ProcessStatsConfig_Quirks_QUIRKS_UNSPECIFIED;
18834   static constexpr auto DISABLE_INITIAL_DUMP = ProcessStatsConfig_Quirks_DISABLE_INITIAL_DUMP;
18835   static constexpr auto DISABLE_ON_DEMAND = ProcessStatsConfig_Quirks_DISABLE_ON_DEMAND;
18836   static constexpr auto Quirks_MIN = ProcessStatsConfig_Quirks_QUIRKS_UNSPECIFIED;
18837   static constexpr auto Quirks_MAX = ProcessStatsConfig_Quirks_DISABLE_ON_DEMAND;
18838   enum FieldNumbers {
18839     kQuirksFieldNumber = 1,
18840     kScanAllProcessesOnStartFieldNumber = 2,
18841     kRecordThreadNamesFieldNumber = 3,
18842     kProcStatsPollMsFieldNumber = 4,
18843     kProcStatsCacheTtlMsFieldNumber = 6,
18844     kRecordThreadTimeInStateFieldNumber = 7,
18845     kThreadTimeInStateCacheSizeFieldNumber = 8,
18846   };
18847 
18848   ProcessStatsConfig();
18849   ~ProcessStatsConfig() override;
18850   ProcessStatsConfig(ProcessStatsConfig&&) noexcept;
18851   ProcessStatsConfig& operator=(ProcessStatsConfig&&);
18852   ProcessStatsConfig(const ProcessStatsConfig&);
18853   ProcessStatsConfig& operator=(const ProcessStatsConfig&);
18854   bool operator==(const ProcessStatsConfig&) const;
operator !=(const ProcessStatsConfig & other) const18855   bool operator!=(const ProcessStatsConfig& other) const { return !(*this == other); }
18856 
18857   bool ParseFromArray(const void*, size_t) override;
18858   std::string SerializeAsString() const override;
18859   std::vector<uint8_t> SerializeAsArray() const override;
18860   void Serialize(::protozero::Message*) const;
18861 
quirks() const18862   const std::vector<ProcessStatsConfig_Quirks>& quirks() const { return quirks_; }
mutable_quirks()18863   std::vector<ProcessStatsConfig_Quirks>* mutable_quirks() { return &quirks_; }
quirks_size() const18864   int quirks_size() const { return static_cast<int>(quirks_.size()); }
clear_quirks()18865   void clear_quirks() { quirks_.clear(); }
add_quirks(ProcessStatsConfig_Quirks value)18866   void add_quirks(ProcessStatsConfig_Quirks value) { quirks_.emplace_back(value); }
add_quirks()18867   ProcessStatsConfig_Quirks* add_quirks() { quirks_.emplace_back(); return &quirks_.back(); }
18868 
has_scan_all_processes_on_start() const18869   bool has_scan_all_processes_on_start() const { return _has_field_[2]; }
scan_all_processes_on_start() const18870   bool scan_all_processes_on_start() const { return scan_all_processes_on_start_; }
set_scan_all_processes_on_start(bool value)18871   void set_scan_all_processes_on_start(bool value) { scan_all_processes_on_start_ = value; _has_field_.set(2); }
18872 
has_record_thread_names() const18873   bool has_record_thread_names() const { return _has_field_[3]; }
record_thread_names() const18874   bool record_thread_names() const { return record_thread_names_; }
set_record_thread_names(bool value)18875   void set_record_thread_names(bool value) { record_thread_names_ = value; _has_field_.set(3); }
18876 
has_proc_stats_poll_ms() const18877   bool has_proc_stats_poll_ms() const { return _has_field_[4]; }
proc_stats_poll_ms() const18878   uint32_t proc_stats_poll_ms() const { return proc_stats_poll_ms_; }
set_proc_stats_poll_ms(uint32_t value)18879   void set_proc_stats_poll_ms(uint32_t value) { proc_stats_poll_ms_ = value; _has_field_.set(4); }
18880 
has_proc_stats_cache_ttl_ms() const18881   bool has_proc_stats_cache_ttl_ms() const { return _has_field_[6]; }
proc_stats_cache_ttl_ms() const18882   uint32_t proc_stats_cache_ttl_ms() const { return proc_stats_cache_ttl_ms_; }
set_proc_stats_cache_ttl_ms(uint32_t value)18883   void set_proc_stats_cache_ttl_ms(uint32_t value) { proc_stats_cache_ttl_ms_ = value; _has_field_.set(6); }
18884 
has_record_thread_time_in_state() const18885   bool has_record_thread_time_in_state() const { return _has_field_[7]; }
record_thread_time_in_state() const18886   bool record_thread_time_in_state() const { return record_thread_time_in_state_; }
set_record_thread_time_in_state(bool value)18887   void set_record_thread_time_in_state(bool value) { record_thread_time_in_state_ = value; _has_field_.set(7); }
18888 
has_thread_time_in_state_cache_size() const18889   bool has_thread_time_in_state_cache_size() const { return _has_field_[8]; }
thread_time_in_state_cache_size() const18890   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)18891   void set_thread_time_in_state_cache_size(uint32_t value) { thread_time_in_state_cache_size_ = value; _has_field_.set(8); }
18892 
18893  private:
18894   std::vector<ProcessStatsConfig_Quirks> quirks_;
18895   bool scan_all_processes_on_start_{};
18896   bool record_thread_names_{};
18897   uint32_t proc_stats_poll_ms_{};
18898   uint32_t proc_stats_cache_ttl_ms_{};
18899   bool record_thread_time_in_state_{};
18900   uint32_t thread_time_in_state_cache_size_{};
18901 
18902   // Allows to preserve unknown protobuf fields for compatibility
18903   // with future versions of .proto files.
18904   std::string unknown_fields_;
18905 
18906   std::bitset<9> _has_field_{};
18907 };
18908 
18909 }  // namespace perfetto
18910 }  // namespace protos
18911 }  // namespace gen
18912 
18913 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_PROCESS_STATS_PROCESS_STATS_CONFIG_PROTO_CPP_H_
18914 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
18915 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
18916 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
18917 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
18918 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
18919 #if defined(__GNUC__) || defined(__clang__)
18920 #pragma GCC diagnostic push
18921 #pragma GCC diagnostic ignored "-Wfloat-equal"
18922 #endif
18923 // gen_amalgamated expanded: #include "protos/perfetto/config/process_stats/process_stats_config.gen.h"
18924 
18925 namespace perfetto {
18926 namespace protos {
18927 namespace gen {
18928 
18929 ProcessStatsConfig::ProcessStatsConfig() = default;
18930 ProcessStatsConfig::~ProcessStatsConfig() = default;
18931 ProcessStatsConfig::ProcessStatsConfig(const ProcessStatsConfig&) = default;
18932 ProcessStatsConfig& ProcessStatsConfig::operator=(const ProcessStatsConfig&) = default;
18933 ProcessStatsConfig::ProcessStatsConfig(ProcessStatsConfig&&) noexcept = default;
18934 ProcessStatsConfig& ProcessStatsConfig::operator=(ProcessStatsConfig&&) = default;
18935 
operator ==(const ProcessStatsConfig & other) const18936 bool ProcessStatsConfig::operator==(const ProcessStatsConfig& other) const {
18937   return unknown_fields_ == other.unknown_fields_
18938    && quirks_ == other.quirks_
18939    && scan_all_processes_on_start_ == other.scan_all_processes_on_start_
18940    && record_thread_names_ == other.record_thread_names_
18941    && proc_stats_poll_ms_ == other.proc_stats_poll_ms_
18942    && proc_stats_cache_ttl_ms_ == other.proc_stats_cache_ttl_ms_
18943    && record_thread_time_in_state_ == other.record_thread_time_in_state_
18944    && thread_time_in_state_cache_size_ == other.thread_time_in_state_cache_size_;
18945 }
18946 
ParseFromArray(const void * raw,size_t size)18947 bool ProcessStatsConfig::ParseFromArray(const void* raw, size_t size) {
18948   quirks_.clear();
18949   unknown_fields_.clear();
18950   bool packed_error = false;
18951 
18952   ::protozero::ProtoDecoder dec(raw, size);
18953   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
18954     if (field.id() < _has_field_.size()) {
18955       _has_field_.set(field.id());
18956     }
18957     switch (field.id()) {
18958       case 1 /* quirks */:
18959         quirks_.emplace_back();
18960         field.get(&quirks_.back());
18961         break;
18962       case 2 /* scan_all_processes_on_start */:
18963         field.get(&scan_all_processes_on_start_);
18964         break;
18965       case 3 /* record_thread_names */:
18966         field.get(&record_thread_names_);
18967         break;
18968       case 4 /* proc_stats_poll_ms */:
18969         field.get(&proc_stats_poll_ms_);
18970         break;
18971       case 6 /* proc_stats_cache_ttl_ms */:
18972         field.get(&proc_stats_cache_ttl_ms_);
18973         break;
18974       case 7 /* record_thread_time_in_state */:
18975         field.get(&record_thread_time_in_state_);
18976         break;
18977       case 8 /* thread_time_in_state_cache_size */:
18978         field.get(&thread_time_in_state_cache_size_);
18979         break;
18980       default:
18981         field.SerializeAndAppendTo(&unknown_fields_);
18982         break;
18983     }
18984   }
18985   return !packed_error && !dec.bytes_left();
18986 }
18987 
SerializeAsString() const18988 std::string ProcessStatsConfig::SerializeAsString() const {
18989   ::protozero::HeapBuffered<::protozero::Message> msg;
18990   Serialize(msg.get());
18991   return msg.SerializeAsString();
18992 }
18993 
SerializeAsArray() const18994 std::vector<uint8_t> ProcessStatsConfig::SerializeAsArray() const {
18995   ::protozero::HeapBuffered<::protozero::Message> msg;
18996   Serialize(msg.get());
18997   return msg.SerializeAsArray();
18998 }
18999 
Serialize(::protozero::Message * msg) const19000 void ProcessStatsConfig::Serialize(::protozero::Message* msg) const {
19001   // Field 1: quirks
19002   for (auto& it : quirks_) {
19003     msg->AppendVarInt(1, it);
19004   }
19005 
19006   // Field 2: scan_all_processes_on_start
19007   if (_has_field_[2]) {
19008     msg->AppendTinyVarInt(2, scan_all_processes_on_start_);
19009   }
19010 
19011   // Field 3: record_thread_names
19012   if (_has_field_[3]) {
19013     msg->AppendTinyVarInt(3, record_thread_names_);
19014   }
19015 
19016   // Field 4: proc_stats_poll_ms
19017   if (_has_field_[4]) {
19018     msg->AppendVarInt(4, proc_stats_poll_ms_);
19019   }
19020 
19021   // Field 6: proc_stats_cache_ttl_ms
19022   if (_has_field_[6]) {
19023     msg->AppendVarInt(6, proc_stats_cache_ttl_ms_);
19024   }
19025 
19026   // Field 7: record_thread_time_in_state
19027   if (_has_field_[7]) {
19028     msg->AppendTinyVarInt(7, record_thread_time_in_state_);
19029   }
19030 
19031   // Field 8: thread_time_in_state_cache_size
19032   if (_has_field_[8]) {
19033     msg->AppendVarInt(8, thread_time_in_state_cache_size_);
19034   }
19035 
19036   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
19037 }
19038 
19039 }  // namespace perfetto
19040 }  // namespace protos
19041 }  // namespace gen
19042 #if defined(__GNUC__) || defined(__clang__)
19043 #pragma GCC diagnostic pop
19044 #endif
19045 // gen_amalgamated begin source: gen/protos/perfetto/config/profiling/heapprofd_config.gen.cc
19046 // gen_amalgamated begin header: gen/protos/perfetto/config/profiling/heapprofd_config.gen.h
19047 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
19048 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_PROFILING_HEAPPROFD_CONFIG_PROTO_CPP_H_
19049 #define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_PROFILING_HEAPPROFD_CONFIG_PROTO_CPP_H_
19050 
19051 #include <stdint.h>
19052 #include <bitset>
19053 #include <vector>
19054 #include <string>
19055 #include <type_traits>
19056 
19057 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
19058 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
19059 // gen_amalgamated expanded: #include "perfetto/base/export.h"
19060 
19061 namespace perfetto {
19062 namespace protos {
19063 namespace gen {
19064 class HeapprofdConfig;
19065 class HeapprofdConfig_ContinuousDumpConfig;
19066 }  // namespace perfetto
19067 }  // namespace protos
19068 }  // namespace gen
19069 
19070 namespace protozero {
19071 class Message;
19072 }  // namespace protozero
19073 
19074 namespace perfetto {
19075 namespace protos {
19076 namespace gen {
19077 
19078 class PERFETTO_EXPORT HeapprofdConfig : public ::protozero::CppMessageObj {
19079  public:
19080   using ContinuousDumpConfig = HeapprofdConfig_ContinuousDumpConfig;
19081   enum FieldNumbers {
19082     kSamplingIntervalBytesFieldNumber = 1,
19083     kAdaptiveSamplingShmemThresholdFieldNumber = 24,
19084     kAdaptiveSamplingMaxSamplingIntervalBytesFieldNumber = 25,
19085     kProcessCmdlineFieldNumber = 2,
19086     kPidFieldNumber = 4,
19087     kTargetInstalledByFieldNumber = 26,
19088     kHeapsFieldNumber = 20,
19089     kExcludeHeapsFieldNumber = 27,
19090     kStreamAllocationsFieldNumber = 23,
19091     kHeapSamplingIntervalsFieldNumber = 22,
19092     kAllHeapsFieldNumber = 21,
19093     kAllFieldNumber = 5,
19094     kMinAnonymousMemoryKbFieldNumber = 15,
19095     kMaxHeapprofdMemoryKbFieldNumber = 16,
19096     kMaxHeapprofdCpuSecsFieldNumber = 17,
19097     kSkipSymbolPrefixFieldNumber = 7,
19098     kContinuousDumpConfigFieldNumber = 6,
19099     kShmemSizeBytesFieldNumber = 8,
19100     kBlockClientFieldNumber = 9,
19101     kBlockClientTimeoutUsFieldNumber = 14,
19102     kNoStartupFieldNumber = 10,
19103     kNoRunningFieldNumber = 11,
19104     kDumpAtMaxFieldNumber = 13,
19105     kDisableForkTeardownFieldNumber = 18,
19106     kDisableVforkDetectionFieldNumber = 19,
19107   };
19108 
19109   HeapprofdConfig();
19110   ~HeapprofdConfig() override;
19111   HeapprofdConfig(HeapprofdConfig&&) noexcept;
19112   HeapprofdConfig& operator=(HeapprofdConfig&&);
19113   HeapprofdConfig(const HeapprofdConfig&);
19114   HeapprofdConfig& operator=(const HeapprofdConfig&);
19115   bool operator==(const HeapprofdConfig&) const;
operator !=(const HeapprofdConfig & other) const19116   bool operator!=(const HeapprofdConfig& other) const { return !(*this == other); }
19117 
19118   bool ParseFromArray(const void*, size_t) override;
19119   std::string SerializeAsString() const override;
19120   std::vector<uint8_t> SerializeAsArray() const override;
19121   void Serialize(::protozero::Message*) const;
19122 
has_sampling_interval_bytes() const19123   bool has_sampling_interval_bytes() const { return _has_field_[1]; }
sampling_interval_bytes() const19124   uint64_t sampling_interval_bytes() const { return sampling_interval_bytes_; }
set_sampling_interval_bytes(uint64_t value)19125   void set_sampling_interval_bytes(uint64_t value) { sampling_interval_bytes_ = value; _has_field_.set(1); }
19126 
has_adaptive_sampling_shmem_threshold() const19127   bool has_adaptive_sampling_shmem_threshold() const { return _has_field_[24]; }
adaptive_sampling_shmem_threshold() const19128   uint64_t adaptive_sampling_shmem_threshold() const { return adaptive_sampling_shmem_threshold_; }
set_adaptive_sampling_shmem_threshold(uint64_t value)19129   void set_adaptive_sampling_shmem_threshold(uint64_t value) { adaptive_sampling_shmem_threshold_ = value; _has_field_.set(24); }
19130 
has_adaptive_sampling_max_sampling_interval_bytes() const19131   bool has_adaptive_sampling_max_sampling_interval_bytes() const { return _has_field_[25]; }
adaptive_sampling_max_sampling_interval_bytes() const19132   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)19133   void set_adaptive_sampling_max_sampling_interval_bytes(uint64_t value) { adaptive_sampling_max_sampling_interval_bytes_ = value; _has_field_.set(25); }
19134 
process_cmdline() const19135   const std::vector<std::string>& process_cmdline() const { return process_cmdline_; }
mutable_process_cmdline()19136   std::vector<std::string>* mutable_process_cmdline() { return &process_cmdline_; }
process_cmdline_size() const19137   int process_cmdline_size() const { return static_cast<int>(process_cmdline_.size()); }
clear_process_cmdline()19138   void clear_process_cmdline() { process_cmdline_.clear(); }
add_process_cmdline(std::string value)19139   void add_process_cmdline(std::string value) { process_cmdline_.emplace_back(value); }
add_process_cmdline()19140   std::string* add_process_cmdline() { process_cmdline_.emplace_back(); return &process_cmdline_.back(); }
19141 
pid() const19142   const std::vector<uint64_t>& pid() const { return pid_; }
mutable_pid()19143   std::vector<uint64_t>* mutable_pid() { return &pid_; }
pid_size() const19144   int pid_size() const { return static_cast<int>(pid_.size()); }
clear_pid()19145   void clear_pid() { pid_.clear(); }
add_pid(uint64_t value)19146   void add_pid(uint64_t value) { pid_.emplace_back(value); }
add_pid()19147   uint64_t* add_pid() { pid_.emplace_back(); return &pid_.back(); }
19148 
target_installed_by() const19149   const std::vector<std::string>& target_installed_by() const { return target_installed_by_; }
mutable_target_installed_by()19150   std::vector<std::string>* mutable_target_installed_by() { return &target_installed_by_; }
target_installed_by_size() const19151   int target_installed_by_size() const { return static_cast<int>(target_installed_by_.size()); }
clear_target_installed_by()19152   void clear_target_installed_by() { target_installed_by_.clear(); }
add_target_installed_by(std::string value)19153   void add_target_installed_by(std::string value) { target_installed_by_.emplace_back(value); }
add_target_installed_by()19154   std::string* add_target_installed_by() { target_installed_by_.emplace_back(); return &target_installed_by_.back(); }
19155 
heaps() const19156   const std::vector<std::string>& heaps() const { return heaps_; }
mutable_heaps()19157   std::vector<std::string>* mutable_heaps() { return &heaps_; }
heaps_size() const19158   int heaps_size() const { return static_cast<int>(heaps_.size()); }
clear_heaps()19159   void clear_heaps() { heaps_.clear(); }
add_heaps(std::string value)19160   void add_heaps(std::string value) { heaps_.emplace_back(value); }
add_heaps()19161   std::string* add_heaps() { heaps_.emplace_back(); return &heaps_.back(); }
19162 
exclude_heaps() const19163   const std::vector<std::string>& exclude_heaps() const { return exclude_heaps_; }
mutable_exclude_heaps()19164   std::vector<std::string>* mutable_exclude_heaps() { return &exclude_heaps_; }
exclude_heaps_size() const19165   int exclude_heaps_size() const { return static_cast<int>(exclude_heaps_.size()); }
clear_exclude_heaps()19166   void clear_exclude_heaps() { exclude_heaps_.clear(); }
add_exclude_heaps(std::string value)19167   void add_exclude_heaps(std::string value) { exclude_heaps_.emplace_back(value); }
add_exclude_heaps()19168   std::string* add_exclude_heaps() { exclude_heaps_.emplace_back(); return &exclude_heaps_.back(); }
19169 
has_stream_allocations() const19170   bool has_stream_allocations() const { return _has_field_[23]; }
stream_allocations() const19171   bool stream_allocations() const { return stream_allocations_; }
set_stream_allocations(bool value)19172   void set_stream_allocations(bool value) { stream_allocations_ = value; _has_field_.set(23); }
19173 
heap_sampling_intervals() const19174   const std::vector<uint64_t>& heap_sampling_intervals() const { return heap_sampling_intervals_; }
mutable_heap_sampling_intervals()19175   std::vector<uint64_t>* mutable_heap_sampling_intervals() { return &heap_sampling_intervals_; }
heap_sampling_intervals_size() const19176   int heap_sampling_intervals_size() const { return static_cast<int>(heap_sampling_intervals_.size()); }
clear_heap_sampling_intervals()19177   void clear_heap_sampling_intervals() { heap_sampling_intervals_.clear(); }
add_heap_sampling_intervals(uint64_t value)19178   void add_heap_sampling_intervals(uint64_t value) { heap_sampling_intervals_.emplace_back(value); }
add_heap_sampling_intervals()19179   uint64_t* add_heap_sampling_intervals() { heap_sampling_intervals_.emplace_back(); return &heap_sampling_intervals_.back(); }
19180 
has_all_heaps() const19181   bool has_all_heaps() const { return _has_field_[21]; }
all_heaps() const19182   bool all_heaps() const { return all_heaps_; }
set_all_heaps(bool value)19183   void set_all_heaps(bool value) { all_heaps_ = value; _has_field_.set(21); }
19184 
has_all() const19185   bool has_all() const { return _has_field_[5]; }
all() const19186   bool all() const { return all_; }
set_all(bool value)19187   void set_all(bool value) { all_ = value; _has_field_.set(5); }
19188 
has_min_anonymous_memory_kb() const19189   bool has_min_anonymous_memory_kb() const { return _has_field_[15]; }
min_anonymous_memory_kb() const19190   uint32_t min_anonymous_memory_kb() const { return min_anonymous_memory_kb_; }
set_min_anonymous_memory_kb(uint32_t value)19191   void set_min_anonymous_memory_kb(uint32_t value) { min_anonymous_memory_kb_ = value; _has_field_.set(15); }
19192 
has_max_heapprofd_memory_kb() const19193   bool has_max_heapprofd_memory_kb() const { return _has_field_[16]; }
max_heapprofd_memory_kb() const19194   uint32_t max_heapprofd_memory_kb() const { return max_heapprofd_memory_kb_; }
set_max_heapprofd_memory_kb(uint32_t value)19195   void set_max_heapprofd_memory_kb(uint32_t value) { max_heapprofd_memory_kb_ = value; _has_field_.set(16); }
19196 
has_max_heapprofd_cpu_secs() const19197   bool has_max_heapprofd_cpu_secs() const { return _has_field_[17]; }
max_heapprofd_cpu_secs() const19198   uint64_t max_heapprofd_cpu_secs() const { return max_heapprofd_cpu_secs_; }
set_max_heapprofd_cpu_secs(uint64_t value)19199   void set_max_heapprofd_cpu_secs(uint64_t value) { max_heapprofd_cpu_secs_ = value; _has_field_.set(17); }
19200 
skip_symbol_prefix() const19201   const std::vector<std::string>& skip_symbol_prefix() const { return skip_symbol_prefix_; }
mutable_skip_symbol_prefix()19202   std::vector<std::string>* mutable_skip_symbol_prefix() { return &skip_symbol_prefix_; }
skip_symbol_prefix_size() const19203   int skip_symbol_prefix_size() const { return static_cast<int>(skip_symbol_prefix_.size()); }
clear_skip_symbol_prefix()19204   void clear_skip_symbol_prefix() { skip_symbol_prefix_.clear(); }
add_skip_symbol_prefix(std::string value)19205   void add_skip_symbol_prefix(std::string value) { skip_symbol_prefix_.emplace_back(value); }
add_skip_symbol_prefix()19206   std::string* add_skip_symbol_prefix() { skip_symbol_prefix_.emplace_back(); return &skip_symbol_prefix_.back(); }
19207 
has_continuous_dump_config() const19208   bool has_continuous_dump_config() const { return _has_field_[6]; }
continuous_dump_config() const19209   const HeapprofdConfig_ContinuousDumpConfig& continuous_dump_config() const { return *continuous_dump_config_; }
mutable_continuous_dump_config()19210   HeapprofdConfig_ContinuousDumpConfig* mutable_continuous_dump_config() { _has_field_.set(6); return continuous_dump_config_.get(); }
19211 
has_shmem_size_bytes() const19212   bool has_shmem_size_bytes() const { return _has_field_[8]; }
shmem_size_bytes() const19213   uint64_t shmem_size_bytes() const { return shmem_size_bytes_; }
set_shmem_size_bytes(uint64_t value)19214   void set_shmem_size_bytes(uint64_t value) { shmem_size_bytes_ = value; _has_field_.set(8); }
19215 
has_block_client() const19216   bool has_block_client() const { return _has_field_[9]; }
block_client() const19217   bool block_client() const { return block_client_; }
set_block_client(bool value)19218   void set_block_client(bool value) { block_client_ = value; _has_field_.set(9); }
19219 
has_block_client_timeout_us() const19220   bool has_block_client_timeout_us() const { return _has_field_[14]; }
block_client_timeout_us() const19221   uint32_t block_client_timeout_us() const { return block_client_timeout_us_; }
set_block_client_timeout_us(uint32_t value)19222   void set_block_client_timeout_us(uint32_t value) { block_client_timeout_us_ = value; _has_field_.set(14); }
19223 
has_no_startup() const19224   bool has_no_startup() const { return _has_field_[10]; }
no_startup() const19225   bool no_startup() const { return no_startup_; }
set_no_startup(bool value)19226   void set_no_startup(bool value) { no_startup_ = value; _has_field_.set(10); }
19227 
has_no_running() const19228   bool has_no_running() const { return _has_field_[11]; }
no_running() const19229   bool no_running() const { return no_running_; }
set_no_running(bool value)19230   void set_no_running(bool value) { no_running_ = value; _has_field_.set(11); }
19231 
has_dump_at_max() const19232   bool has_dump_at_max() const { return _has_field_[13]; }
dump_at_max() const19233   bool dump_at_max() const { return dump_at_max_; }
set_dump_at_max(bool value)19234   void set_dump_at_max(bool value) { dump_at_max_ = value; _has_field_.set(13); }
19235 
has_disable_fork_teardown() const19236   bool has_disable_fork_teardown() const { return _has_field_[18]; }
disable_fork_teardown() const19237   bool disable_fork_teardown() const { return disable_fork_teardown_; }
set_disable_fork_teardown(bool value)19238   void set_disable_fork_teardown(bool value) { disable_fork_teardown_ = value; _has_field_.set(18); }
19239 
has_disable_vfork_detection() const19240   bool has_disable_vfork_detection() const { return _has_field_[19]; }
disable_vfork_detection() const19241   bool disable_vfork_detection() const { return disable_vfork_detection_; }
set_disable_vfork_detection(bool value)19242   void set_disable_vfork_detection(bool value) { disable_vfork_detection_ = value; _has_field_.set(19); }
19243 
19244  private:
19245   uint64_t sampling_interval_bytes_{};
19246   uint64_t adaptive_sampling_shmem_threshold_{};
19247   uint64_t adaptive_sampling_max_sampling_interval_bytes_{};
19248   std::vector<std::string> process_cmdline_;
19249   std::vector<uint64_t> pid_;
19250   std::vector<std::string> target_installed_by_;
19251   std::vector<std::string> heaps_;
19252   std::vector<std::string> exclude_heaps_;
19253   bool stream_allocations_{};
19254   std::vector<uint64_t> heap_sampling_intervals_;
19255   bool all_heaps_{};
19256   bool all_{};
19257   uint32_t min_anonymous_memory_kb_{};
19258   uint32_t max_heapprofd_memory_kb_{};
19259   uint64_t max_heapprofd_cpu_secs_{};
19260   std::vector<std::string> skip_symbol_prefix_;
19261   ::protozero::CopyablePtr<HeapprofdConfig_ContinuousDumpConfig> continuous_dump_config_;
19262   uint64_t shmem_size_bytes_{};
19263   bool block_client_{};
19264   uint32_t block_client_timeout_us_{};
19265   bool no_startup_{};
19266   bool no_running_{};
19267   bool dump_at_max_{};
19268   bool disable_fork_teardown_{};
19269   bool disable_vfork_detection_{};
19270 
19271   // Allows to preserve unknown protobuf fields for compatibility
19272   // with future versions of .proto files.
19273   std::string unknown_fields_;
19274 
19275   std::bitset<28> _has_field_{};
19276 };
19277 
19278 
19279 class PERFETTO_EXPORT HeapprofdConfig_ContinuousDumpConfig : public ::protozero::CppMessageObj {
19280  public:
19281   enum FieldNumbers {
19282     kDumpPhaseMsFieldNumber = 5,
19283     kDumpIntervalMsFieldNumber = 6,
19284   };
19285 
19286   HeapprofdConfig_ContinuousDumpConfig();
19287   ~HeapprofdConfig_ContinuousDumpConfig() override;
19288   HeapprofdConfig_ContinuousDumpConfig(HeapprofdConfig_ContinuousDumpConfig&&) noexcept;
19289   HeapprofdConfig_ContinuousDumpConfig& operator=(HeapprofdConfig_ContinuousDumpConfig&&);
19290   HeapprofdConfig_ContinuousDumpConfig(const HeapprofdConfig_ContinuousDumpConfig&);
19291   HeapprofdConfig_ContinuousDumpConfig& operator=(const HeapprofdConfig_ContinuousDumpConfig&);
19292   bool operator==(const HeapprofdConfig_ContinuousDumpConfig&) const;
operator !=(const HeapprofdConfig_ContinuousDumpConfig & other) const19293   bool operator!=(const HeapprofdConfig_ContinuousDumpConfig& other) const { return !(*this == other); }
19294 
19295   bool ParseFromArray(const void*, size_t) override;
19296   std::string SerializeAsString() const override;
19297   std::vector<uint8_t> SerializeAsArray() const override;
19298   void Serialize(::protozero::Message*) const;
19299 
has_dump_phase_ms() const19300   bool has_dump_phase_ms() const { return _has_field_[5]; }
dump_phase_ms() const19301   uint32_t dump_phase_ms() const { return dump_phase_ms_; }
set_dump_phase_ms(uint32_t value)19302   void set_dump_phase_ms(uint32_t value) { dump_phase_ms_ = value; _has_field_.set(5); }
19303 
has_dump_interval_ms() const19304   bool has_dump_interval_ms() const { return _has_field_[6]; }
dump_interval_ms() const19305   uint32_t dump_interval_ms() const { return dump_interval_ms_; }
set_dump_interval_ms(uint32_t value)19306   void set_dump_interval_ms(uint32_t value) { dump_interval_ms_ = value; _has_field_.set(6); }
19307 
19308  private:
19309   uint32_t dump_phase_ms_{};
19310   uint32_t dump_interval_ms_{};
19311 
19312   // Allows to preserve unknown protobuf fields for compatibility
19313   // with future versions of .proto files.
19314   std::string unknown_fields_;
19315 
19316   std::bitset<7> _has_field_{};
19317 };
19318 
19319 }  // namespace perfetto
19320 }  // namespace protos
19321 }  // namespace gen
19322 
19323 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_PROFILING_HEAPPROFD_CONFIG_PROTO_CPP_H_
19324 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
19325 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
19326 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
19327 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
19328 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
19329 #if defined(__GNUC__) || defined(__clang__)
19330 #pragma GCC diagnostic push
19331 #pragma GCC diagnostic ignored "-Wfloat-equal"
19332 #endif
19333 // gen_amalgamated expanded: #include "protos/perfetto/config/profiling/heapprofd_config.gen.h"
19334 
19335 namespace perfetto {
19336 namespace protos {
19337 namespace gen {
19338 
19339 HeapprofdConfig::HeapprofdConfig() = default;
19340 HeapprofdConfig::~HeapprofdConfig() = default;
19341 HeapprofdConfig::HeapprofdConfig(const HeapprofdConfig&) = default;
19342 HeapprofdConfig& HeapprofdConfig::operator=(const HeapprofdConfig&) = default;
19343 HeapprofdConfig::HeapprofdConfig(HeapprofdConfig&&) noexcept = default;
19344 HeapprofdConfig& HeapprofdConfig::operator=(HeapprofdConfig&&) = default;
19345 
operator ==(const HeapprofdConfig & other) const19346 bool HeapprofdConfig::operator==(const HeapprofdConfig& other) const {
19347   return unknown_fields_ == other.unknown_fields_
19348    && sampling_interval_bytes_ == other.sampling_interval_bytes_
19349    && adaptive_sampling_shmem_threshold_ == other.adaptive_sampling_shmem_threshold_
19350    && adaptive_sampling_max_sampling_interval_bytes_ == other.adaptive_sampling_max_sampling_interval_bytes_
19351    && process_cmdline_ == other.process_cmdline_
19352    && pid_ == other.pid_
19353    && target_installed_by_ == other.target_installed_by_
19354    && heaps_ == other.heaps_
19355    && exclude_heaps_ == other.exclude_heaps_
19356    && stream_allocations_ == other.stream_allocations_
19357    && heap_sampling_intervals_ == other.heap_sampling_intervals_
19358    && all_heaps_ == other.all_heaps_
19359    && all_ == other.all_
19360    && min_anonymous_memory_kb_ == other.min_anonymous_memory_kb_
19361    && max_heapprofd_memory_kb_ == other.max_heapprofd_memory_kb_
19362    && max_heapprofd_cpu_secs_ == other.max_heapprofd_cpu_secs_
19363    && skip_symbol_prefix_ == other.skip_symbol_prefix_
19364    && continuous_dump_config_ == other.continuous_dump_config_
19365    && shmem_size_bytes_ == other.shmem_size_bytes_
19366    && block_client_ == other.block_client_
19367    && block_client_timeout_us_ == other.block_client_timeout_us_
19368    && no_startup_ == other.no_startup_
19369    && no_running_ == other.no_running_
19370    && dump_at_max_ == other.dump_at_max_
19371    && disable_fork_teardown_ == other.disable_fork_teardown_
19372    && disable_vfork_detection_ == other.disable_vfork_detection_;
19373 }
19374 
ParseFromArray(const void * raw,size_t size)19375 bool HeapprofdConfig::ParseFromArray(const void* raw, size_t size) {
19376   process_cmdline_.clear();
19377   pid_.clear();
19378   target_installed_by_.clear();
19379   heaps_.clear();
19380   exclude_heaps_.clear();
19381   heap_sampling_intervals_.clear();
19382   skip_symbol_prefix_.clear();
19383   unknown_fields_.clear();
19384   bool packed_error = false;
19385 
19386   ::protozero::ProtoDecoder dec(raw, size);
19387   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
19388     if (field.id() < _has_field_.size()) {
19389       _has_field_.set(field.id());
19390     }
19391     switch (field.id()) {
19392       case 1 /* sampling_interval_bytes */:
19393         field.get(&sampling_interval_bytes_);
19394         break;
19395       case 24 /* adaptive_sampling_shmem_threshold */:
19396         field.get(&adaptive_sampling_shmem_threshold_);
19397         break;
19398       case 25 /* adaptive_sampling_max_sampling_interval_bytes */:
19399         field.get(&adaptive_sampling_max_sampling_interval_bytes_);
19400         break;
19401       case 2 /* process_cmdline */:
19402         process_cmdline_.emplace_back();
19403         field.get(&process_cmdline_.back());
19404         break;
19405       case 4 /* pid */:
19406         pid_.emplace_back();
19407         field.get(&pid_.back());
19408         break;
19409       case 26 /* target_installed_by */:
19410         target_installed_by_.emplace_back();
19411         field.get(&target_installed_by_.back());
19412         break;
19413       case 20 /* heaps */:
19414         heaps_.emplace_back();
19415         field.get(&heaps_.back());
19416         break;
19417       case 27 /* exclude_heaps */:
19418         exclude_heaps_.emplace_back();
19419         field.get(&exclude_heaps_.back());
19420         break;
19421       case 23 /* stream_allocations */:
19422         field.get(&stream_allocations_);
19423         break;
19424       case 22 /* heap_sampling_intervals */:
19425         heap_sampling_intervals_.emplace_back();
19426         field.get(&heap_sampling_intervals_.back());
19427         break;
19428       case 21 /* all_heaps */:
19429         field.get(&all_heaps_);
19430         break;
19431       case 5 /* all */:
19432         field.get(&all_);
19433         break;
19434       case 15 /* min_anonymous_memory_kb */:
19435         field.get(&min_anonymous_memory_kb_);
19436         break;
19437       case 16 /* max_heapprofd_memory_kb */:
19438         field.get(&max_heapprofd_memory_kb_);
19439         break;
19440       case 17 /* max_heapprofd_cpu_secs */:
19441         field.get(&max_heapprofd_cpu_secs_);
19442         break;
19443       case 7 /* skip_symbol_prefix */:
19444         skip_symbol_prefix_.emplace_back();
19445         field.get(&skip_symbol_prefix_.back());
19446         break;
19447       case 6 /* continuous_dump_config */:
19448         (*continuous_dump_config_).ParseFromArray(field.data(), field.size());
19449         break;
19450       case 8 /* shmem_size_bytes */:
19451         field.get(&shmem_size_bytes_);
19452         break;
19453       case 9 /* block_client */:
19454         field.get(&block_client_);
19455         break;
19456       case 14 /* block_client_timeout_us */:
19457         field.get(&block_client_timeout_us_);
19458         break;
19459       case 10 /* no_startup */:
19460         field.get(&no_startup_);
19461         break;
19462       case 11 /* no_running */:
19463         field.get(&no_running_);
19464         break;
19465       case 13 /* dump_at_max */:
19466         field.get(&dump_at_max_);
19467         break;
19468       case 18 /* disable_fork_teardown */:
19469         field.get(&disable_fork_teardown_);
19470         break;
19471       case 19 /* disable_vfork_detection */:
19472         field.get(&disable_vfork_detection_);
19473         break;
19474       default:
19475         field.SerializeAndAppendTo(&unknown_fields_);
19476         break;
19477     }
19478   }
19479   return !packed_error && !dec.bytes_left();
19480 }
19481 
SerializeAsString() const19482 std::string HeapprofdConfig::SerializeAsString() const {
19483   ::protozero::HeapBuffered<::protozero::Message> msg;
19484   Serialize(msg.get());
19485   return msg.SerializeAsString();
19486 }
19487 
SerializeAsArray() const19488 std::vector<uint8_t> HeapprofdConfig::SerializeAsArray() const {
19489   ::protozero::HeapBuffered<::protozero::Message> msg;
19490   Serialize(msg.get());
19491   return msg.SerializeAsArray();
19492 }
19493 
Serialize(::protozero::Message * msg) const19494 void HeapprofdConfig::Serialize(::protozero::Message* msg) const {
19495   // Field 1: sampling_interval_bytes
19496   if (_has_field_[1]) {
19497     msg->AppendVarInt(1, sampling_interval_bytes_);
19498   }
19499 
19500   // Field 24: adaptive_sampling_shmem_threshold
19501   if (_has_field_[24]) {
19502     msg->AppendVarInt(24, adaptive_sampling_shmem_threshold_);
19503   }
19504 
19505   // Field 25: adaptive_sampling_max_sampling_interval_bytes
19506   if (_has_field_[25]) {
19507     msg->AppendVarInt(25, adaptive_sampling_max_sampling_interval_bytes_);
19508   }
19509 
19510   // Field 2: process_cmdline
19511   for (auto& it : process_cmdline_) {
19512     msg->AppendString(2, it);
19513   }
19514 
19515   // Field 4: pid
19516   for (auto& it : pid_) {
19517     msg->AppendVarInt(4, it);
19518   }
19519 
19520   // Field 26: target_installed_by
19521   for (auto& it : target_installed_by_) {
19522     msg->AppendString(26, it);
19523   }
19524 
19525   // Field 20: heaps
19526   for (auto& it : heaps_) {
19527     msg->AppendString(20, it);
19528   }
19529 
19530   // Field 27: exclude_heaps
19531   for (auto& it : exclude_heaps_) {
19532     msg->AppendString(27, it);
19533   }
19534 
19535   // Field 23: stream_allocations
19536   if (_has_field_[23]) {
19537     msg->AppendTinyVarInt(23, stream_allocations_);
19538   }
19539 
19540   // Field 22: heap_sampling_intervals
19541   for (auto& it : heap_sampling_intervals_) {
19542     msg->AppendVarInt(22, it);
19543   }
19544 
19545   // Field 21: all_heaps
19546   if (_has_field_[21]) {
19547     msg->AppendTinyVarInt(21, all_heaps_);
19548   }
19549 
19550   // Field 5: all
19551   if (_has_field_[5]) {
19552     msg->AppendTinyVarInt(5, all_);
19553   }
19554 
19555   // Field 15: min_anonymous_memory_kb
19556   if (_has_field_[15]) {
19557     msg->AppendVarInt(15, min_anonymous_memory_kb_);
19558   }
19559 
19560   // Field 16: max_heapprofd_memory_kb
19561   if (_has_field_[16]) {
19562     msg->AppendVarInt(16, max_heapprofd_memory_kb_);
19563   }
19564 
19565   // Field 17: max_heapprofd_cpu_secs
19566   if (_has_field_[17]) {
19567     msg->AppendVarInt(17, max_heapprofd_cpu_secs_);
19568   }
19569 
19570   // Field 7: skip_symbol_prefix
19571   for (auto& it : skip_symbol_prefix_) {
19572     msg->AppendString(7, it);
19573   }
19574 
19575   // Field 6: continuous_dump_config
19576   if (_has_field_[6]) {
19577     (*continuous_dump_config_).Serialize(msg->BeginNestedMessage<::protozero::Message>(6));
19578   }
19579 
19580   // Field 8: shmem_size_bytes
19581   if (_has_field_[8]) {
19582     msg->AppendVarInt(8, shmem_size_bytes_);
19583   }
19584 
19585   // Field 9: block_client
19586   if (_has_field_[9]) {
19587     msg->AppendTinyVarInt(9, block_client_);
19588   }
19589 
19590   // Field 14: block_client_timeout_us
19591   if (_has_field_[14]) {
19592     msg->AppendVarInt(14, block_client_timeout_us_);
19593   }
19594 
19595   // Field 10: no_startup
19596   if (_has_field_[10]) {
19597     msg->AppendTinyVarInt(10, no_startup_);
19598   }
19599 
19600   // Field 11: no_running
19601   if (_has_field_[11]) {
19602     msg->AppendTinyVarInt(11, no_running_);
19603   }
19604 
19605   // Field 13: dump_at_max
19606   if (_has_field_[13]) {
19607     msg->AppendTinyVarInt(13, dump_at_max_);
19608   }
19609 
19610   // Field 18: disable_fork_teardown
19611   if (_has_field_[18]) {
19612     msg->AppendTinyVarInt(18, disable_fork_teardown_);
19613   }
19614 
19615   // Field 19: disable_vfork_detection
19616   if (_has_field_[19]) {
19617     msg->AppendTinyVarInt(19, disable_vfork_detection_);
19618   }
19619 
19620   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
19621 }
19622 
19623 
19624 HeapprofdConfig_ContinuousDumpConfig::HeapprofdConfig_ContinuousDumpConfig() = default;
19625 HeapprofdConfig_ContinuousDumpConfig::~HeapprofdConfig_ContinuousDumpConfig() = default;
19626 HeapprofdConfig_ContinuousDumpConfig::HeapprofdConfig_ContinuousDumpConfig(const HeapprofdConfig_ContinuousDumpConfig&) = default;
19627 HeapprofdConfig_ContinuousDumpConfig& HeapprofdConfig_ContinuousDumpConfig::operator=(const HeapprofdConfig_ContinuousDumpConfig&) = default;
19628 HeapprofdConfig_ContinuousDumpConfig::HeapprofdConfig_ContinuousDumpConfig(HeapprofdConfig_ContinuousDumpConfig&&) noexcept = default;
19629 HeapprofdConfig_ContinuousDumpConfig& HeapprofdConfig_ContinuousDumpConfig::operator=(HeapprofdConfig_ContinuousDumpConfig&&) = default;
19630 
operator ==(const HeapprofdConfig_ContinuousDumpConfig & other) const19631 bool HeapprofdConfig_ContinuousDumpConfig::operator==(const HeapprofdConfig_ContinuousDumpConfig& other) const {
19632   return unknown_fields_ == other.unknown_fields_
19633    && dump_phase_ms_ == other.dump_phase_ms_
19634    && dump_interval_ms_ == other.dump_interval_ms_;
19635 }
19636 
ParseFromArray(const void * raw,size_t size)19637 bool HeapprofdConfig_ContinuousDumpConfig::ParseFromArray(const void* raw, size_t size) {
19638   unknown_fields_.clear();
19639   bool packed_error = false;
19640 
19641   ::protozero::ProtoDecoder dec(raw, size);
19642   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
19643     if (field.id() < _has_field_.size()) {
19644       _has_field_.set(field.id());
19645     }
19646     switch (field.id()) {
19647       case 5 /* dump_phase_ms */:
19648         field.get(&dump_phase_ms_);
19649         break;
19650       case 6 /* dump_interval_ms */:
19651         field.get(&dump_interval_ms_);
19652         break;
19653       default:
19654         field.SerializeAndAppendTo(&unknown_fields_);
19655         break;
19656     }
19657   }
19658   return !packed_error && !dec.bytes_left();
19659 }
19660 
SerializeAsString() const19661 std::string HeapprofdConfig_ContinuousDumpConfig::SerializeAsString() const {
19662   ::protozero::HeapBuffered<::protozero::Message> msg;
19663   Serialize(msg.get());
19664   return msg.SerializeAsString();
19665 }
19666 
SerializeAsArray() const19667 std::vector<uint8_t> HeapprofdConfig_ContinuousDumpConfig::SerializeAsArray() const {
19668   ::protozero::HeapBuffered<::protozero::Message> msg;
19669   Serialize(msg.get());
19670   return msg.SerializeAsArray();
19671 }
19672 
Serialize(::protozero::Message * msg) const19673 void HeapprofdConfig_ContinuousDumpConfig::Serialize(::protozero::Message* msg) const {
19674   // Field 5: dump_phase_ms
19675   if (_has_field_[5]) {
19676     msg->AppendVarInt(5, dump_phase_ms_);
19677   }
19678 
19679   // Field 6: dump_interval_ms
19680   if (_has_field_[6]) {
19681     msg->AppendVarInt(6, dump_interval_ms_);
19682   }
19683 
19684   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
19685 }
19686 
19687 }  // namespace perfetto
19688 }  // namespace protos
19689 }  // namespace gen
19690 #if defined(__GNUC__) || defined(__clang__)
19691 #pragma GCC diagnostic pop
19692 #endif
19693 // gen_amalgamated begin source: gen/protos/perfetto/config/profiling/java_hprof_config.gen.cc
19694 // gen_amalgamated begin header: gen/protos/perfetto/config/profiling/java_hprof_config.gen.h
19695 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
19696 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_PROFILING_JAVA_HPROF_CONFIG_PROTO_CPP_H_
19697 #define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_PROFILING_JAVA_HPROF_CONFIG_PROTO_CPP_H_
19698 
19699 #include <stdint.h>
19700 #include <bitset>
19701 #include <vector>
19702 #include <string>
19703 #include <type_traits>
19704 
19705 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
19706 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
19707 // gen_amalgamated expanded: #include "perfetto/base/export.h"
19708 
19709 namespace perfetto {
19710 namespace protos {
19711 namespace gen {
19712 class JavaHprofConfig;
19713 class JavaHprofConfig_ContinuousDumpConfig;
19714 }  // namespace perfetto
19715 }  // namespace protos
19716 }  // namespace gen
19717 
19718 namespace protozero {
19719 class Message;
19720 }  // namespace protozero
19721 
19722 namespace perfetto {
19723 namespace protos {
19724 namespace gen {
19725 
19726 class PERFETTO_EXPORT JavaHprofConfig : public ::protozero::CppMessageObj {
19727  public:
19728   using ContinuousDumpConfig = JavaHprofConfig_ContinuousDumpConfig;
19729   enum FieldNumbers {
19730     kProcessCmdlineFieldNumber = 1,
19731     kPidFieldNumber = 2,
19732     kTargetInstalledByFieldNumber = 7,
19733     kContinuousDumpConfigFieldNumber = 3,
19734     kMinAnonymousMemoryKbFieldNumber = 4,
19735     kDumpSmapsFieldNumber = 5,
19736     kIgnoredTypesFieldNumber = 6,
19737   };
19738 
19739   JavaHprofConfig();
19740   ~JavaHprofConfig() override;
19741   JavaHprofConfig(JavaHprofConfig&&) noexcept;
19742   JavaHprofConfig& operator=(JavaHprofConfig&&);
19743   JavaHprofConfig(const JavaHprofConfig&);
19744   JavaHprofConfig& operator=(const JavaHprofConfig&);
19745   bool operator==(const JavaHprofConfig&) const;
operator !=(const JavaHprofConfig & other) const19746   bool operator!=(const JavaHprofConfig& other) const { return !(*this == other); }
19747 
19748   bool ParseFromArray(const void*, size_t) override;
19749   std::string SerializeAsString() const override;
19750   std::vector<uint8_t> SerializeAsArray() const override;
19751   void Serialize(::protozero::Message*) const;
19752 
process_cmdline() const19753   const std::vector<std::string>& process_cmdline() const { return process_cmdline_; }
mutable_process_cmdline()19754   std::vector<std::string>* mutable_process_cmdline() { return &process_cmdline_; }
process_cmdline_size() const19755   int process_cmdline_size() const { return static_cast<int>(process_cmdline_.size()); }
clear_process_cmdline()19756   void clear_process_cmdline() { process_cmdline_.clear(); }
add_process_cmdline(std::string value)19757   void add_process_cmdline(std::string value) { process_cmdline_.emplace_back(value); }
add_process_cmdline()19758   std::string* add_process_cmdline() { process_cmdline_.emplace_back(); return &process_cmdline_.back(); }
19759 
pid() const19760   const std::vector<uint64_t>& pid() const { return pid_; }
mutable_pid()19761   std::vector<uint64_t>* mutable_pid() { return &pid_; }
pid_size() const19762   int pid_size() const { return static_cast<int>(pid_.size()); }
clear_pid()19763   void clear_pid() { pid_.clear(); }
add_pid(uint64_t value)19764   void add_pid(uint64_t value) { pid_.emplace_back(value); }
add_pid()19765   uint64_t* add_pid() { pid_.emplace_back(); return &pid_.back(); }
19766 
target_installed_by() const19767   const std::vector<std::string>& target_installed_by() const { return target_installed_by_; }
mutable_target_installed_by()19768   std::vector<std::string>* mutable_target_installed_by() { return &target_installed_by_; }
target_installed_by_size() const19769   int target_installed_by_size() const { return static_cast<int>(target_installed_by_.size()); }
clear_target_installed_by()19770   void clear_target_installed_by() { target_installed_by_.clear(); }
add_target_installed_by(std::string value)19771   void add_target_installed_by(std::string value) { target_installed_by_.emplace_back(value); }
add_target_installed_by()19772   std::string* add_target_installed_by() { target_installed_by_.emplace_back(); return &target_installed_by_.back(); }
19773 
has_continuous_dump_config() const19774   bool has_continuous_dump_config() const { return _has_field_[3]; }
continuous_dump_config() const19775   const JavaHprofConfig_ContinuousDumpConfig& continuous_dump_config() const { return *continuous_dump_config_; }
mutable_continuous_dump_config()19776   JavaHprofConfig_ContinuousDumpConfig* mutable_continuous_dump_config() { _has_field_.set(3); return continuous_dump_config_.get(); }
19777 
has_min_anonymous_memory_kb() const19778   bool has_min_anonymous_memory_kb() const { return _has_field_[4]; }
min_anonymous_memory_kb() const19779   uint32_t min_anonymous_memory_kb() const { return min_anonymous_memory_kb_; }
set_min_anonymous_memory_kb(uint32_t value)19780   void set_min_anonymous_memory_kb(uint32_t value) { min_anonymous_memory_kb_ = value; _has_field_.set(4); }
19781 
has_dump_smaps() const19782   bool has_dump_smaps() const { return _has_field_[5]; }
dump_smaps() const19783   bool dump_smaps() const { return dump_smaps_; }
set_dump_smaps(bool value)19784   void set_dump_smaps(bool value) { dump_smaps_ = value; _has_field_.set(5); }
19785 
ignored_types() const19786   const std::vector<std::string>& ignored_types() const { return ignored_types_; }
mutable_ignored_types()19787   std::vector<std::string>* mutable_ignored_types() { return &ignored_types_; }
ignored_types_size() const19788   int ignored_types_size() const { return static_cast<int>(ignored_types_.size()); }
clear_ignored_types()19789   void clear_ignored_types() { ignored_types_.clear(); }
add_ignored_types(std::string value)19790   void add_ignored_types(std::string value) { ignored_types_.emplace_back(value); }
add_ignored_types()19791   std::string* add_ignored_types() { ignored_types_.emplace_back(); return &ignored_types_.back(); }
19792 
19793  private:
19794   std::vector<std::string> process_cmdline_;
19795   std::vector<uint64_t> pid_;
19796   std::vector<std::string> target_installed_by_;
19797   ::protozero::CopyablePtr<JavaHprofConfig_ContinuousDumpConfig> continuous_dump_config_;
19798   uint32_t min_anonymous_memory_kb_{};
19799   bool dump_smaps_{};
19800   std::vector<std::string> ignored_types_;
19801 
19802   // Allows to preserve unknown protobuf fields for compatibility
19803   // with future versions of .proto files.
19804   std::string unknown_fields_;
19805 
19806   std::bitset<8> _has_field_{};
19807 };
19808 
19809 
19810 class PERFETTO_EXPORT JavaHprofConfig_ContinuousDumpConfig : public ::protozero::CppMessageObj {
19811  public:
19812   enum FieldNumbers {
19813     kDumpPhaseMsFieldNumber = 1,
19814     kDumpIntervalMsFieldNumber = 2,
19815     kScanPidsOnlyOnStartFieldNumber = 3,
19816   };
19817 
19818   JavaHprofConfig_ContinuousDumpConfig();
19819   ~JavaHprofConfig_ContinuousDumpConfig() override;
19820   JavaHprofConfig_ContinuousDumpConfig(JavaHprofConfig_ContinuousDumpConfig&&) noexcept;
19821   JavaHprofConfig_ContinuousDumpConfig& operator=(JavaHprofConfig_ContinuousDumpConfig&&);
19822   JavaHprofConfig_ContinuousDumpConfig(const JavaHprofConfig_ContinuousDumpConfig&);
19823   JavaHprofConfig_ContinuousDumpConfig& operator=(const JavaHprofConfig_ContinuousDumpConfig&);
19824   bool operator==(const JavaHprofConfig_ContinuousDumpConfig&) const;
operator !=(const JavaHprofConfig_ContinuousDumpConfig & other) const19825   bool operator!=(const JavaHprofConfig_ContinuousDumpConfig& other) const { return !(*this == other); }
19826 
19827   bool ParseFromArray(const void*, size_t) override;
19828   std::string SerializeAsString() const override;
19829   std::vector<uint8_t> SerializeAsArray() const override;
19830   void Serialize(::protozero::Message*) const;
19831 
has_dump_phase_ms() const19832   bool has_dump_phase_ms() const { return _has_field_[1]; }
dump_phase_ms() const19833   uint32_t dump_phase_ms() const { return dump_phase_ms_; }
set_dump_phase_ms(uint32_t value)19834   void set_dump_phase_ms(uint32_t value) { dump_phase_ms_ = value; _has_field_.set(1); }
19835 
has_dump_interval_ms() const19836   bool has_dump_interval_ms() const { return _has_field_[2]; }
dump_interval_ms() const19837   uint32_t dump_interval_ms() const { return dump_interval_ms_; }
set_dump_interval_ms(uint32_t value)19838   void set_dump_interval_ms(uint32_t value) { dump_interval_ms_ = value; _has_field_.set(2); }
19839 
has_scan_pids_only_on_start() const19840   bool has_scan_pids_only_on_start() const { return _has_field_[3]; }
scan_pids_only_on_start() const19841   bool scan_pids_only_on_start() const { return scan_pids_only_on_start_; }
set_scan_pids_only_on_start(bool value)19842   void set_scan_pids_only_on_start(bool value) { scan_pids_only_on_start_ = value; _has_field_.set(3); }
19843 
19844  private:
19845   uint32_t dump_phase_ms_{};
19846   uint32_t dump_interval_ms_{};
19847   bool scan_pids_only_on_start_{};
19848 
19849   // Allows to preserve unknown protobuf fields for compatibility
19850   // with future versions of .proto files.
19851   std::string unknown_fields_;
19852 
19853   std::bitset<4> _has_field_{};
19854 };
19855 
19856 }  // namespace perfetto
19857 }  // namespace protos
19858 }  // namespace gen
19859 
19860 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_PROFILING_JAVA_HPROF_CONFIG_PROTO_CPP_H_
19861 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
19862 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
19863 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
19864 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
19865 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
19866 #if defined(__GNUC__) || defined(__clang__)
19867 #pragma GCC diagnostic push
19868 #pragma GCC diagnostic ignored "-Wfloat-equal"
19869 #endif
19870 // gen_amalgamated expanded: #include "protos/perfetto/config/profiling/java_hprof_config.gen.h"
19871 
19872 namespace perfetto {
19873 namespace protos {
19874 namespace gen {
19875 
19876 JavaHprofConfig::JavaHprofConfig() = default;
19877 JavaHprofConfig::~JavaHprofConfig() = default;
19878 JavaHprofConfig::JavaHprofConfig(const JavaHprofConfig&) = default;
19879 JavaHprofConfig& JavaHprofConfig::operator=(const JavaHprofConfig&) = default;
19880 JavaHprofConfig::JavaHprofConfig(JavaHprofConfig&&) noexcept = default;
19881 JavaHprofConfig& JavaHprofConfig::operator=(JavaHprofConfig&&) = default;
19882 
operator ==(const JavaHprofConfig & other) const19883 bool JavaHprofConfig::operator==(const JavaHprofConfig& other) const {
19884   return unknown_fields_ == other.unknown_fields_
19885    && process_cmdline_ == other.process_cmdline_
19886    && pid_ == other.pid_
19887    && target_installed_by_ == other.target_installed_by_
19888    && continuous_dump_config_ == other.continuous_dump_config_
19889    && min_anonymous_memory_kb_ == other.min_anonymous_memory_kb_
19890    && dump_smaps_ == other.dump_smaps_
19891    && ignored_types_ == other.ignored_types_;
19892 }
19893 
ParseFromArray(const void * raw,size_t size)19894 bool JavaHprofConfig::ParseFromArray(const void* raw, size_t size) {
19895   process_cmdline_.clear();
19896   pid_.clear();
19897   target_installed_by_.clear();
19898   ignored_types_.clear();
19899   unknown_fields_.clear();
19900   bool packed_error = false;
19901 
19902   ::protozero::ProtoDecoder dec(raw, size);
19903   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
19904     if (field.id() < _has_field_.size()) {
19905       _has_field_.set(field.id());
19906     }
19907     switch (field.id()) {
19908       case 1 /* process_cmdline */:
19909         process_cmdline_.emplace_back();
19910         field.get(&process_cmdline_.back());
19911         break;
19912       case 2 /* pid */:
19913         pid_.emplace_back();
19914         field.get(&pid_.back());
19915         break;
19916       case 7 /* target_installed_by */:
19917         target_installed_by_.emplace_back();
19918         field.get(&target_installed_by_.back());
19919         break;
19920       case 3 /* continuous_dump_config */:
19921         (*continuous_dump_config_).ParseFromArray(field.data(), field.size());
19922         break;
19923       case 4 /* min_anonymous_memory_kb */:
19924         field.get(&min_anonymous_memory_kb_);
19925         break;
19926       case 5 /* dump_smaps */:
19927         field.get(&dump_smaps_);
19928         break;
19929       case 6 /* ignored_types */:
19930         ignored_types_.emplace_back();
19931         field.get(&ignored_types_.back());
19932         break;
19933       default:
19934         field.SerializeAndAppendTo(&unknown_fields_);
19935         break;
19936     }
19937   }
19938   return !packed_error && !dec.bytes_left();
19939 }
19940 
SerializeAsString() const19941 std::string JavaHprofConfig::SerializeAsString() const {
19942   ::protozero::HeapBuffered<::protozero::Message> msg;
19943   Serialize(msg.get());
19944   return msg.SerializeAsString();
19945 }
19946 
SerializeAsArray() const19947 std::vector<uint8_t> JavaHprofConfig::SerializeAsArray() const {
19948   ::protozero::HeapBuffered<::protozero::Message> msg;
19949   Serialize(msg.get());
19950   return msg.SerializeAsArray();
19951 }
19952 
Serialize(::protozero::Message * msg) const19953 void JavaHprofConfig::Serialize(::protozero::Message* msg) const {
19954   // Field 1: process_cmdline
19955   for (auto& it : process_cmdline_) {
19956     msg->AppendString(1, it);
19957   }
19958 
19959   // Field 2: pid
19960   for (auto& it : pid_) {
19961     msg->AppendVarInt(2, it);
19962   }
19963 
19964   // Field 7: target_installed_by
19965   for (auto& it : target_installed_by_) {
19966     msg->AppendString(7, it);
19967   }
19968 
19969   // Field 3: continuous_dump_config
19970   if (_has_field_[3]) {
19971     (*continuous_dump_config_).Serialize(msg->BeginNestedMessage<::protozero::Message>(3));
19972   }
19973 
19974   // Field 4: min_anonymous_memory_kb
19975   if (_has_field_[4]) {
19976     msg->AppendVarInt(4, min_anonymous_memory_kb_);
19977   }
19978 
19979   // Field 5: dump_smaps
19980   if (_has_field_[5]) {
19981     msg->AppendTinyVarInt(5, dump_smaps_);
19982   }
19983 
19984   // Field 6: ignored_types
19985   for (auto& it : ignored_types_) {
19986     msg->AppendString(6, it);
19987   }
19988 
19989   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
19990 }
19991 
19992 
19993 JavaHprofConfig_ContinuousDumpConfig::JavaHprofConfig_ContinuousDumpConfig() = default;
19994 JavaHprofConfig_ContinuousDumpConfig::~JavaHprofConfig_ContinuousDumpConfig() = default;
19995 JavaHprofConfig_ContinuousDumpConfig::JavaHprofConfig_ContinuousDumpConfig(const JavaHprofConfig_ContinuousDumpConfig&) = default;
19996 JavaHprofConfig_ContinuousDumpConfig& JavaHprofConfig_ContinuousDumpConfig::operator=(const JavaHprofConfig_ContinuousDumpConfig&) = default;
19997 JavaHprofConfig_ContinuousDumpConfig::JavaHprofConfig_ContinuousDumpConfig(JavaHprofConfig_ContinuousDumpConfig&&) noexcept = default;
19998 JavaHprofConfig_ContinuousDumpConfig& JavaHprofConfig_ContinuousDumpConfig::operator=(JavaHprofConfig_ContinuousDumpConfig&&) = default;
19999 
operator ==(const JavaHprofConfig_ContinuousDumpConfig & other) const20000 bool JavaHprofConfig_ContinuousDumpConfig::operator==(const JavaHprofConfig_ContinuousDumpConfig& other) const {
20001   return unknown_fields_ == other.unknown_fields_
20002    && dump_phase_ms_ == other.dump_phase_ms_
20003    && dump_interval_ms_ == other.dump_interval_ms_
20004    && scan_pids_only_on_start_ == other.scan_pids_only_on_start_;
20005 }
20006 
ParseFromArray(const void * raw,size_t size)20007 bool JavaHprofConfig_ContinuousDumpConfig::ParseFromArray(const void* raw, size_t size) {
20008   unknown_fields_.clear();
20009   bool packed_error = false;
20010 
20011   ::protozero::ProtoDecoder dec(raw, size);
20012   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
20013     if (field.id() < _has_field_.size()) {
20014       _has_field_.set(field.id());
20015     }
20016     switch (field.id()) {
20017       case 1 /* dump_phase_ms */:
20018         field.get(&dump_phase_ms_);
20019         break;
20020       case 2 /* dump_interval_ms */:
20021         field.get(&dump_interval_ms_);
20022         break;
20023       case 3 /* scan_pids_only_on_start */:
20024         field.get(&scan_pids_only_on_start_);
20025         break;
20026       default:
20027         field.SerializeAndAppendTo(&unknown_fields_);
20028         break;
20029     }
20030   }
20031   return !packed_error && !dec.bytes_left();
20032 }
20033 
SerializeAsString() const20034 std::string JavaHprofConfig_ContinuousDumpConfig::SerializeAsString() const {
20035   ::protozero::HeapBuffered<::protozero::Message> msg;
20036   Serialize(msg.get());
20037   return msg.SerializeAsString();
20038 }
20039 
SerializeAsArray() const20040 std::vector<uint8_t> JavaHprofConfig_ContinuousDumpConfig::SerializeAsArray() const {
20041   ::protozero::HeapBuffered<::protozero::Message> msg;
20042   Serialize(msg.get());
20043   return msg.SerializeAsArray();
20044 }
20045 
Serialize(::protozero::Message * msg) const20046 void JavaHprofConfig_ContinuousDumpConfig::Serialize(::protozero::Message* msg) const {
20047   // Field 1: dump_phase_ms
20048   if (_has_field_[1]) {
20049     msg->AppendVarInt(1, dump_phase_ms_);
20050   }
20051 
20052   // Field 2: dump_interval_ms
20053   if (_has_field_[2]) {
20054     msg->AppendVarInt(2, dump_interval_ms_);
20055   }
20056 
20057   // Field 3: scan_pids_only_on_start
20058   if (_has_field_[3]) {
20059     msg->AppendTinyVarInt(3, scan_pids_only_on_start_);
20060   }
20061 
20062   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
20063 }
20064 
20065 }  // namespace perfetto
20066 }  // namespace protos
20067 }  // namespace gen
20068 #if defined(__GNUC__) || defined(__clang__)
20069 #pragma GCC diagnostic pop
20070 #endif
20071 // gen_amalgamated begin source: gen/protos/perfetto/config/profiling/perf_event_config.gen.cc
20072 // gen_amalgamated begin header: gen/protos/perfetto/config/profiling/perf_event_config.gen.h
20073 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
20074 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_PROFILING_PERF_EVENT_CONFIG_PROTO_CPP_H_
20075 #define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_PROFILING_PERF_EVENT_CONFIG_PROTO_CPP_H_
20076 
20077 #include <stdint.h>
20078 #include <bitset>
20079 #include <vector>
20080 #include <string>
20081 #include <type_traits>
20082 
20083 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
20084 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
20085 // gen_amalgamated expanded: #include "perfetto/base/export.h"
20086 
20087 namespace perfetto {
20088 namespace protos {
20089 namespace gen {
20090 class PerfEventConfig;
20091 class PerfEventConfig_CallstackSampling;
20092 class PerfEventConfig_Scope;
20093 class PerfEvents_Timebase;
20094 class PerfEvents_RawEvent;
20095 class PerfEvents_Tracepoint;
20096 enum PerfEvents_Counter : int;
20097 enum PerfEvents_PerfClock : int;
20098 }  // namespace perfetto
20099 }  // namespace protos
20100 }  // namespace gen
20101 
20102 namespace protozero {
20103 class Message;
20104 }  // namespace protozero
20105 
20106 namespace perfetto {
20107 namespace protos {
20108 namespace gen {
20109 
20110 class PERFETTO_EXPORT PerfEventConfig : public ::protozero::CppMessageObj {
20111  public:
20112   using CallstackSampling = PerfEventConfig_CallstackSampling;
20113   using Scope = PerfEventConfig_Scope;
20114   enum FieldNumbers {
20115     kTimebaseFieldNumber = 15,
20116     kCallstackSamplingFieldNumber = 16,
20117     kRingBufferReadPeriodMsFieldNumber = 8,
20118     kRingBufferPagesFieldNumber = 3,
20119     kMaxEnqueuedFootprintKbFieldNumber = 17,
20120     kMaxDaemonMemoryKbFieldNumber = 13,
20121     kRemoteDescriptorTimeoutMsFieldNumber = 9,
20122     kUnwindStateClearPeriodMsFieldNumber = 10,
20123     kTargetInstalledByFieldNumber = 18,
20124     kAllCpusFieldNumber = 1,
20125     kSamplingFrequencyFieldNumber = 2,
20126     kKernelFramesFieldNumber = 12,
20127     kTargetPidFieldNumber = 4,
20128     kTargetCmdlineFieldNumber = 5,
20129     kExcludePidFieldNumber = 6,
20130     kExcludeCmdlineFieldNumber = 7,
20131     kAdditionalCmdlineCountFieldNumber = 11,
20132   };
20133 
20134   PerfEventConfig();
20135   ~PerfEventConfig() override;
20136   PerfEventConfig(PerfEventConfig&&) noexcept;
20137   PerfEventConfig& operator=(PerfEventConfig&&);
20138   PerfEventConfig(const PerfEventConfig&);
20139   PerfEventConfig& operator=(const PerfEventConfig&);
20140   bool operator==(const PerfEventConfig&) const;
operator !=(const PerfEventConfig & other) const20141   bool operator!=(const PerfEventConfig& other) const { return !(*this == other); }
20142 
20143   bool ParseFromArray(const void*, size_t) override;
20144   std::string SerializeAsString() const override;
20145   std::vector<uint8_t> SerializeAsArray() const override;
20146   void Serialize(::protozero::Message*) const;
20147 
has_timebase() const20148   bool has_timebase() const { return _has_field_[15]; }
timebase() const20149   const PerfEvents_Timebase& timebase() const { return *timebase_; }
mutable_timebase()20150   PerfEvents_Timebase* mutable_timebase() { _has_field_.set(15); return timebase_.get(); }
20151 
has_callstack_sampling() const20152   bool has_callstack_sampling() const { return _has_field_[16]; }
callstack_sampling() const20153   const PerfEventConfig_CallstackSampling& callstack_sampling() const { return *callstack_sampling_; }
mutable_callstack_sampling()20154   PerfEventConfig_CallstackSampling* mutable_callstack_sampling() { _has_field_.set(16); return callstack_sampling_.get(); }
20155 
has_ring_buffer_read_period_ms() const20156   bool has_ring_buffer_read_period_ms() const { return _has_field_[8]; }
ring_buffer_read_period_ms() const20157   uint32_t ring_buffer_read_period_ms() const { return ring_buffer_read_period_ms_; }
set_ring_buffer_read_period_ms(uint32_t value)20158   void set_ring_buffer_read_period_ms(uint32_t value) { ring_buffer_read_period_ms_ = value; _has_field_.set(8); }
20159 
has_ring_buffer_pages() const20160   bool has_ring_buffer_pages() const { return _has_field_[3]; }
ring_buffer_pages() const20161   uint32_t ring_buffer_pages() const { return ring_buffer_pages_; }
set_ring_buffer_pages(uint32_t value)20162   void set_ring_buffer_pages(uint32_t value) { ring_buffer_pages_ = value; _has_field_.set(3); }
20163 
has_max_enqueued_footprint_kb() const20164   bool has_max_enqueued_footprint_kb() const { return _has_field_[17]; }
max_enqueued_footprint_kb() const20165   uint64_t max_enqueued_footprint_kb() const { return max_enqueued_footprint_kb_; }
set_max_enqueued_footprint_kb(uint64_t value)20166   void set_max_enqueued_footprint_kb(uint64_t value) { max_enqueued_footprint_kb_ = value; _has_field_.set(17); }
20167 
has_max_daemon_memory_kb() const20168   bool has_max_daemon_memory_kb() const { return _has_field_[13]; }
max_daemon_memory_kb() const20169   uint32_t max_daemon_memory_kb() const { return max_daemon_memory_kb_; }
set_max_daemon_memory_kb(uint32_t value)20170   void set_max_daemon_memory_kb(uint32_t value) { max_daemon_memory_kb_ = value; _has_field_.set(13); }
20171 
has_remote_descriptor_timeout_ms() const20172   bool has_remote_descriptor_timeout_ms() const { return _has_field_[9]; }
remote_descriptor_timeout_ms() const20173   uint32_t remote_descriptor_timeout_ms() const { return remote_descriptor_timeout_ms_; }
set_remote_descriptor_timeout_ms(uint32_t value)20174   void set_remote_descriptor_timeout_ms(uint32_t value) { remote_descriptor_timeout_ms_ = value; _has_field_.set(9); }
20175 
has_unwind_state_clear_period_ms() const20176   bool has_unwind_state_clear_period_ms() const { return _has_field_[10]; }
unwind_state_clear_period_ms() const20177   uint32_t unwind_state_clear_period_ms() const { return unwind_state_clear_period_ms_; }
set_unwind_state_clear_period_ms(uint32_t value)20178   void set_unwind_state_clear_period_ms(uint32_t value) { unwind_state_clear_period_ms_ = value; _has_field_.set(10); }
20179 
target_installed_by() const20180   const std::vector<std::string>& target_installed_by() const { return target_installed_by_; }
mutable_target_installed_by()20181   std::vector<std::string>* mutable_target_installed_by() { return &target_installed_by_; }
target_installed_by_size() const20182   int target_installed_by_size() const { return static_cast<int>(target_installed_by_.size()); }
clear_target_installed_by()20183   void clear_target_installed_by() { target_installed_by_.clear(); }
add_target_installed_by(std::string value)20184   void add_target_installed_by(std::string value) { target_installed_by_.emplace_back(value); }
add_target_installed_by()20185   std::string* add_target_installed_by() { target_installed_by_.emplace_back(); return &target_installed_by_.back(); }
20186 
has_all_cpus() const20187   bool has_all_cpus() const { return _has_field_[1]; }
all_cpus() const20188   bool all_cpus() const { return all_cpus_; }
set_all_cpus(bool value)20189   void set_all_cpus(bool value) { all_cpus_ = value; _has_field_.set(1); }
20190 
has_sampling_frequency() const20191   bool has_sampling_frequency() const { return _has_field_[2]; }
sampling_frequency() const20192   uint32_t sampling_frequency() const { return sampling_frequency_; }
set_sampling_frequency(uint32_t value)20193   void set_sampling_frequency(uint32_t value) { sampling_frequency_ = value; _has_field_.set(2); }
20194 
has_kernel_frames() const20195   bool has_kernel_frames() const { return _has_field_[12]; }
kernel_frames() const20196   bool kernel_frames() const { return kernel_frames_; }
set_kernel_frames(bool value)20197   void set_kernel_frames(bool value) { kernel_frames_ = value; _has_field_.set(12); }
20198 
target_pid() const20199   const std::vector<int32_t>& target_pid() const { return target_pid_; }
mutable_target_pid()20200   std::vector<int32_t>* mutable_target_pid() { return &target_pid_; }
target_pid_size() const20201   int target_pid_size() const { return static_cast<int>(target_pid_.size()); }
clear_target_pid()20202   void clear_target_pid() { target_pid_.clear(); }
add_target_pid(int32_t value)20203   void add_target_pid(int32_t value) { target_pid_.emplace_back(value); }
add_target_pid()20204   int32_t* add_target_pid() { target_pid_.emplace_back(); return &target_pid_.back(); }
20205 
target_cmdline() const20206   const std::vector<std::string>& target_cmdline() const { return target_cmdline_; }
mutable_target_cmdline()20207   std::vector<std::string>* mutable_target_cmdline() { return &target_cmdline_; }
target_cmdline_size() const20208   int target_cmdline_size() const { return static_cast<int>(target_cmdline_.size()); }
clear_target_cmdline()20209   void clear_target_cmdline() { target_cmdline_.clear(); }
add_target_cmdline(std::string value)20210   void add_target_cmdline(std::string value) { target_cmdline_.emplace_back(value); }
add_target_cmdline()20211   std::string* add_target_cmdline() { target_cmdline_.emplace_back(); return &target_cmdline_.back(); }
20212 
exclude_pid() const20213   const std::vector<int32_t>& exclude_pid() const { return exclude_pid_; }
mutable_exclude_pid()20214   std::vector<int32_t>* mutable_exclude_pid() { return &exclude_pid_; }
exclude_pid_size() const20215   int exclude_pid_size() const { return static_cast<int>(exclude_pid_.size()); }
clear_exclude_pid()20216   void clear_exclude_pid() { exclude_pid_.clear(); }
add_exclude_pid(int32_t value)20217   void add_exclude_pid(int32_t value) { exclude_pid_.emplace_back(value); }
add_exclude_pid()20218   int32_t* add_exclude_pid() { exclude_pid_.emplace_back(); return &exclude_pid_.back(); }
20219 
exclude_cmdline() const20220   const std::vector<std::string>& exclude_cmdline() const { return exclude_cmdline_; }
mutable_exclude_cmdline()20221   std::vector<std::string>* mutable_exclude_cmdline() { return &exclude_cmdline_; }
exclude_cmdline_size() const20222   int exclude_cmdline_size() const { return static_cast<int>(exclude_cmdline_.size()); }
clear_exclude_cmdline()20223   void clear_exclude_cmdline() { exclude_cmdline_.clear(); }
add_exclude_cmdline(std::string value)20224   void add_exclude_cmdline(std::string value) { exclude_cmdline_.emplace_back(value); }
add_exclude_cmdline()20225   std::string* add_exclude_cmdline() { exclude_cmdline_.emplace_back(); return &exclude_cmdline_.back(); }
20226 
has_additional_cmdline_count() const20227   bool has_additional_cmdline_count() const { return _has_field_[11]; }
additional_cmdline_count() const20228   uint32_t additional_cmdline_count() const { return additional_cmdline_count_; }
set_additional_cmdline_count(uint32_t value)20229   void set_additional_cmdline_count(uint32_t value) { additional_cmdline_count_ = value; _has_field_.set(11); }
20230 
20231  private:
20232   ::protozero::CopyablePtr<PerfEvents_Timebase> timebase_;
20233   ::protozero::CopyablePtr<PerfEventConfig_CallstackSampling> callstack_sampling_;
20234   uint32_t ring_buffer_read_period_ms_{};
20235   uint32_t ring_buffer_pages_{};
20236   uint64_t max_enqueued_footprint_kb_{};
20237   uint32_t max_daemon_memory_kb_{};
20238   uint32_t remote_descriptor_timeout_ms_{};
20239   uint32_t unwind_state_clear_period_ms_{};
20240   std::vector<std::string> target_installed_by_;
20241   bool all_cpus_{};
20242   uint32_t sampling_frequency_{};
20243   bool kernel_frames_{};
20244   std::vector<int32_t> target_pid_;
20245   std::vector<std::string> target_cmdline_;
20246   std::vector<int32_t> exclude_pid_;
20247   std::vector<std::string> exclude_cmdline_;
20248   uint32_t additional_cmdline_count_{};
20249 
20250   // Allows to preserve unknown protobuf fields for compatibility
20251   // with future versions of .proto files.
20252   std::string unknown_fields_;
20253 
20254   std::bitset<19> _has_field_{};
20255 };
20256 
20257 
20258 class PERFETTO_EXPORT PerfEventConfig_CallstackSampling : public ::protozero::CppMessageObj {
20259  public:
20260   enum FieldNumbers {
20261     kScopeFieldNumber = 1,
20262     kKernelFramesFieldNumber = 2,
20263   };
20264 
20265   PerfEventConfig_CallstackSampling();
20266   ~PerfEventConfig_CallstackSampling() override;
20267   PerfEventConfig_CallstackSampling(PerfEventConfig_CallstackSampling&&) noexcept;
20268   PerfEventConfig_CallstackSampling& operator=(PerfEventConfig_CallstackSampling&&);
20269   PerfEventConfig_CallstackSampling(const PerfEventConfig_CallstackSampling&);
20270   PerfEventConfig_CallstackSampling& operator=(const PerfEventConfig_CallstackSampling&);
20271   bool operator==(const PerfEventConfig_CallstackSampling&) const;
operator !=(const PerfEventConfig_CallstackSampling & other) const20272   bool operator!=(const PerfEventConfig_CallstackSampling& other) const { return !(*this == other); }
20273 
20274   bool ParseFromArray(const void*, size_t) override;
20275   std::string SerializeAsString() const override;
20276   std::vector<uint8_t> SerializeAsArray() const override;
20277   void Serialize(::protozero::Message*) const;
20278 
has_scope() const20279   bool has_scope() const { return _has_field_[1]; }
scope() const20280   const PerfEventConfig_Scope& scope() const { return *scope_; }
mutable_scope()20281   PerfEventConfig_Scope* mutable_scope() { _has_field_.set(1); return scope_.get(); }
20282 
has_kernel_frames() const20283   bool has_kernel_frames() const { return _has_field_[2]; }
kernel_frames() const20284   bool kernel_frames() const { return kernel_frames_; }
set_kernel_frames(bool value)20285   void set_kernel_frames(bool value) { kernel_frames_ = value; _has_field_.set(2); }
20286 
20287  private:
20288   ::protozero::CopyablePtr<PerfEventConfig_Scope> scope_;
20289   bool kernel_frames_{};
20290 
20291   // Allows to preserve unknown protobuf fields for compatibility
20292   // with future versions of .proto files.
20293   std::string unknown_fields_;
20294 
20295   std::bitset<3> _has_field_{};
20296 };
20297 
20298 
20299 class PERFETTO_EXPORT PerfEventConfig_Scope : public ::protozero::CppMessageObj {
20300  public:
20301   enum FieldNumbers {
20302     kTargetPidFieldNumber = 1,
20303     kTargetCmdlineFieldNumber = 2,
20304     kExcludePidFieldNumber = 3,
20305     kExcludeCmdlineFieldNumber = 4,
20306     kAdditionalCmdlineCountFieldNumber = 5,
20307   };
20308 
20309   PerfEventConfig_Scope();
20310   ~PerfEventConfig_Scope() override;
20311   PerfEventConfig_Scope(PerfEventConfig_Scope&&) noexcept;
20312   PerfEventConfig_Scope& operator=(PerfEventConfig_Scope&&);
20313   PerfEventConfig_Scope(const PerfEventConfig_Scope&);
20314   PerfEventConfig_Scope& operator=(const PerfEventConfig_Scope&);
20315   bool operator==(const PerfEventConfig_Scope&) const;
operator !=(const PerfEventConfig_Scope & other) const20316   bool operator!=(const PerfEventConfig_Scope& other) const { return !(*this == other); }
20317 
20318   bool ParseFromArray(const void*, size_t) override;
20319   std::string SerializeAsString() const override;
20320   std::vector<uint8_t> SerializeAsArray() const override;
20321   void Serialize(::protozero::Message*) const;
20322 
target_pid() const20323   const std::vector<int32_t>& target_pid() const { return target_pid_; }
mutable_target_pid()20324   std::vector<int32_t>* mutable_target_pid() { return &target_pid_; }
target_pid_size() const20325   int target_pid_size() const { return static_cast<int>(target_pid_.size()); }
clear_target_pid()20326   void clear_target_pid() { target_pid_.clear(); }
add_target_pid(int32_t value)20327   void add_target_pid(int32_t value) { target_pid_.emplace_back(value); }
add_target_pid()20328   int32_t* add_target_pid() { target_pid_.emplace_back(); return &target_pid_.back(); }
20329 
target_cmdline() const20330   const std::vector<std::string>& target_cmdline() const { return target_cmdline_; }
mutable_target_cmdline()20331   std::vector<std::string>* mutable_target_cmdline() { return &target_cmdline_; }
target_cmdline_size() const20332   int target_cmdline_size() const { return static_cast<int>(target_cmdline_.size()); }
clear_target_cmdline()20333   void clear_target_cmdline() { target_cmdline_.clear(); }
add_target_cmdline(std::string value)20334   void add_target_cmdline(std::string value) { target_cmdline_.emplace_back(value); }
add_target_cmdline()20335   std::string* add_target_cmdline() { target_cmdline_.emplace_back(); return &target_cmdline_.back(); }
20336 
exclude_pid() const20337   const std::vector<int32_t>& exclude_pid() const { return exclude_pid_; }
mutable_exclude_pid()20338   std::vector<int32_t>* mutable_exclude_pid() { return &exclude_pid_; }
exclude_pid_size() const20339   int exclude_pid_size() const { return static_cast<int>(exclude_pid_.size()); }
clear_exclude_pid()20340   void clear_exclude_pid() { exclude_pid_.clear(); }
add_exclude_pid(int32_t value)20341   void add_exclude_pid(int32_t value) { exclude_pid_.emplace_back(value); }
add_exclude_pid()20342   int32_t* add_exclude_pid() { exclude_pid_.emplace_back(); return &exclude_pid_.back(); }
20343 
exclude_cmdline() const20344   const std::vector<std::string>& exclude_cmdline() const { return exclude_cmdline_; }
mutable_exclude_cmdline()20345   std::vector<std::string>* mutable_exclude_cmdline() { return &exclude_cmdline_; }
exclude_cmdline_size() const20346   int exclude_cmdline_size() const { return static_cast<int>(exclude_cmdline_.size()); }
clear_exclude_cmdline()20347   void clear_exclude_cmdline() { exclude_cmdline_.clear(); }
add_exclude_cmdline(std::string value)20348   void add_exclude_cmdline(std::string value) { exclude_cmdline_.emplace_back(value); }
add_exclude_cmdline()20349   std::string* add_exclude_cmdline() { exclude_cmdline_.emplace_back(); return &exclude_cmdline_.back(); }
20350 
has_additional_cmdline_count() const20351   bool has_additional_cmdline_count() const { return _has_field_[5]; }
additional_cmdline_count() const20352   uint32_t additional_cmdline_count() const { return additional_cmdline_count_; }
set_additional_cmdline_count(uint32_t value)20353   void set_additional_cmdline_count(uint32_t value) { additional_cmdline_count_ = value; _has_field_.set(5); }
20354 
20355  private:
20356   std::vector<int32_t> target_pid_;
20357   std::vector<std::string> target_cmdline_;
20358   std::vector<int32_t> exclude_pid_;
20359   std::vector<std::string> exclude_cmdline_;
20360   uint32_t additional_cmdline_count_{};
20361 
20362   // Allows to preserve unknown protobuf fields for compatibility
20363   // with future versions of .proto files.
20364   std::string unknown_fields_;
20365 
20366   std::bitset<6> _has_field_{};
20367 };
20368 
20369 }  // namespace perfetto
20370 }  // namespace protos
20371 }  // namespace gen
20372 
20373 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_PROFILING_PERF_EVENT_CONFIG_PROTO_CPP_H_
20374 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
20375 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
20376 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
20377 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
20378 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
20379 #if defined(__GNUC__) || defined(__clang__)
20380 #pragma GCC diagnostic push
20381 #pragma GCC diagnostic ignored "-Wfloat-equal"
20382 #endif
20383 // gen_amalgamated expanded: #include "protos/perfetto/config/profiling/perf_event_config.gen.h"
20384 // gen_amalgamated expanded: #include "protos/perfetto/common/perf_events.gen.h"
20385 
20386 namespace perfetto {
20387 namespace protos {
20388 namespace gen {
20389 
20390 PerfEventConfig::PerfEventConfig() = default;
20391 PerfEventConfig::~PerfEventConfig() = default;
20392 PerfEventConfig::PerfEventConfig(const PerfEventConfig&) = default;
20393 PerfEventConfig& PerfEventConfig::operator=(const PerfEventConfig&) = default;
20394 PerfEventConfig::PerfEventConfig(PerfEventConfig&&) noexcept = default;
20395 PerfEventConfig& PerfEventConfig::operator=(PerfEventConfig&&) = default;
20396 
operator ==(const PerfEventConfig & other) const20397 bool PerfEventConfig::operator==(const PerfEventConfig& other) const {
20398   return unknown_fields_ == other.unknown_fields_
20399    && timebase_ == other.timebase_
20400    && callstack_sampling_ == other.callstack_sampling_
20401    && ring_buffer_read_period_ms_ == other.ring_buffer_read_period_ms_
20402    && ring_buffer_pages_ == other.ring_buffer_pages_
20403    && max_enqueued_footprint_kb_ == other.max_enqueued_footprint_kb_
20404    && max_daemon_memory_kb_ == other.max_daemon_memory_kb_
20405    && remote_descriptor_timeout_ms_ == other.remote_descriptor_timeout_ms_
20406    && unwind_state_clear_period_ms_ == other.unwind_state_clear_period_ms_
20407    && target_installed_by_ == other.target_installed_by_
20408    && all_cpus_ == other.all_cpus_
20409    && sampling_frequency_ == other.sampling_frequency_
20410    && kernel_frames_ == other.kernel_frames_
20411    && target_pid_ == other.target_pid_
20412    && target_cmdline_ == other.target_cmdline_
20413    && exclude_pid_ == other.exclude_pid_
20414    && exclude_cmdline_ == other.exclude_cmdline_
20415    && additional_cmdline_count_ == other.additional_cmdline_count_;
20416 }
20417 
ParseFromArray(const void * raw,size_t size)20418 bool PerfEventConfig::ParseFromArray(const void* raw, size_t size) {
20419   target_installed_by_.clear();
20420   target_pid_.clear();
20421   target_cmdline_.clear();
20422   exclude_pid_.clear();
20423   exclude_cmdline_.clear();
20424   unknown_fields_.clear();
20425   bool packed_error = false;
20426 
20427   ::protozero::ProtoDecoder dec(raw, size);
20428   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
20429     if (field.id() < _has_field_.size()) {
20430       _has_field_.set(field.id());
20431     }
20432     switch (field.id()) {
20433       case 15 /* timebase */:
20434         (*timebase_).ParseFromArray(field.data(), field.size());
20435         break;
20436       case 16 /* callstack_sampling */:
20437         (*callstack_sampling_).ParseFromArray(field.data(), field.size());
20438         break;
20439       case 8 /* ring_buffer_read_period_ms */:
20440         field.get(&ring_buffer_read_period_ms_);
20441         break;
20442       case 3 /* ring_buffer_pages */:
20443         field.get(&ring_buffer_pages_);
20444         break;
20445       case 17 /* max_enqueued_footprint_kb */:
20446         field.get(&max_enqueued_footprint_kb_);
20447         break;
20448       case 13 /* max_daemon_memory_kb */:
20449         field.get(&max_daemon_memory_kb_);
20450         break;
20451       case 9 /* remote_descriptor_timeout_ms */:
20452         field.get(&remote_descriptor_timeout_ms_);
20453         break;
20454       case 10 /* unwind_state_clear_period_ms */:
20455         field.get(&unwind_state_clear_period_ms_);
20456         break;
20457       case 18 /* target_installed_by */:
20458         target_installed_by_.emplace_back();
20459         field.get(&target_installed_by_.back());
20460         break;
20461       case 1 /* all_cpus */:
20462         field.get(&all_cpus_);
20463         break;
20464       case 2 /* sampling_frequency */:
20465         field.get(&sampling_frequency_);
20466         break;
20467       case 12 /* kernel_frames */:
20468         field.get(&kernel_frames_);
20469         break;
20470       case 4 /* target_pid */:
20471         target_pid_.emplace_back();
20472         field.get(&target_pid_.back());
20473         break;
20474       case 5 /* target_cmdline */:
20475         target_cmdline_.emplace_back();
20476         field.get(&target_cmdline_.back());
20477         break;
20478       case 6 /* exclude_pid */:
20479         exclude_pid_.emplace_back();
20480         field.get(&exclude_pid_.back());
20481         break;
20482       case 7 /* exclude_cmdline */:
20483         exclude_cmdline_.emplace_back();
20484         field.get(&exclude_cmdline_.back());
20485         break;
20486       case 11 /* additional_cmdline_count */:
20487         field.get(&additional_cmdline_count_);
20488         break;
20489       default:
20490         field.SerializeAndAppendTo(&unknown_fields_);
20491         break;
20492     }
20493   }
20494   return !packed_error && !dec.bytes_left();
20495 }
20496 
SerializeAsString() const20497 std::string PerfEventConfig::SerializeAsString() const {
20498   ::protozero::HeapBuffered<::protozero::Message> msg;
20499   Serialize(msg.get());
20500   return msg.SerializeAsString();
20501 }
20502 
SerializeAsArray() const20503 std::vector<uint8_t> PerfEventConfig::SerializeAsArray() const {
20504   ::protozero::HeapBuffered<::protozero::Message> msg;
20505   Serialize(msg.get());
20506   return msg.SerializeAsArray();
20507 }
20508 
Serialize(::protozero::Message * msg) const20509 void PerfEventConfig::Serialize(::protozero::Message* msg) const {
20510   // Field 15: timebase
20511   if (_has_field_[15]) {
20512     (*timebase_).Serialize(msg->BeginNestedMessage<::protozero::Message>(15));
20513   }
20514 
20515   // Field 16: callstack_sampling
20516   if (_has_field_[16]) {
20517     (*callstack_sampling_).Serialize(msg->BeginNestedMessage<::protozero::Message>(16));
20518   }
20519 
20520   // Field 8: ring_buffer_read_period_ms
20521   if (_has_field_[8]) {
20522     msg->AppendVarInt(8, ring_buffer_read_period_ms_);
20523   }
20524 
20525   // Field 3: ring_buffer_pages
20526   if (_has_field_[3]) {
20527     msg->AppendVarInt(3, ring_buffer_pages_);
20528   }
20529 
20530   // Field 17: max_enqueued_footprint_kb
20531   if (_has_field_[17]) {
20532     msg->AppendVarInt(17, max_enqueued_footprint_kb_);
20533   }
20534 
20535   // Field 13: max_daemon_memory_kb
20536   if (_has_field_[13]) {
20537     msg->AppendVarInt(13, max_daemon_memory_kb_);
20538   }
20539 
20540   // Field 9: remote_descriptor_timeout_ms
20541   if (_has_field_[9]) {
20542     msg->AppendVarInt(9, remote_descriptor_timeout_ms_);
20543   }
20544 
20545   // Field 10: unwind_state_clear_period_ms
20546   if (_has_field_[10]) {
20547     msg->AppendVarInt(10, unwind_state_clear_period_ms_);
20548   }
20549 
20550   // Field 18: target_installed_by
20551   for (auto& it : target_installed_by_) {
20552     msg->AppendString(18, it);
20553   }
20554 
20555   // Field 1: all_cpus
20556   if (_has_field_[1]) {
20557     msg->AppendTinyVarInt(1, all_cpus_);
20558   }
20559 
20560   // Field 2: sampling_frequency
20561   if (_has_field_[2]) {
20562     msg->AppendVarInt(2, sampling_frequency_);
20563   }
20564 
20565   // Field 12: kernel_frames
20566   if (_has_field_[12]) {
20567     msg->AppendTinyVarInt(12, kernel_frames_);
20568   }
20569 
20570   // Field 4: target_pid
20571   for (auto& it : target_pid_) {
20572     msg->AppendVarInt(4, it);
20573   }
20574 
20575   // Field 5: target_cmdline
20576   for (auto& it : target_cmdline_) {
20577     msg->AppendString(5, it);
20578   }
20579 
20580   // Field 6: exclude_pid
20581   for (auto& it : exclude_pid_) {
20582     msg->AppendVarInt(6, it);
20583   }
20584 
20585   // Field 7: exclude_cmdline
20586   for (auto& it : exclude_cmdline_) {
20587     msg->AppendString(7, it);
20588   }
20589 
20590   // Field 11: additional_cmdline_count
20591   if (_has_field_[11]) {
20592     msg->AppendVarInt(11, additional_cmdline_count_);
20593   }
20594 
20595   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
20596 }
20597 
20598 
20599 PerfEventConfig_CallstackSampling::PerfEventConfig_CallstackSampling() = default;
20600 PerfEventConfig_CallstackSampling::~PerfEventConfig_CallstackSampling() = default;
20601 PerfEventConfig_CallstackSampling::PerfEventConfig_CallstackSampling(const PerfEventConfig_CallstackSampling&) = default;
20602 PerfEventConfig_CallstackSampling& PerfEventConfig_CallstackSampling::operator=(const PerfEventConfig_CallstackSampling&) = default;
20603 PerfEventConfig_CallstackSampling::PerfEventConfig_CallstackSampling(PerfEventConfig_CallstackSampling&&) noexcept = default;
20604 PerfEventConfig_CallstackSampling& PerfEventConfig_CallstackSampling::operator=(PerfEventConfig_CallstackSampling&&) = default;
20605 
operator ==(const PerfEventConfig_CallstackSampling & other) const20606 bool PerfEventConfig_CallstackSampling::operator==(const PerfEventConfig_CallstackSampling& other) const {
20607   return unknown_fields_ == other.unknown_fields_
20608    && scope_ == other.scope_
20609    && kernel_frames_ == other.kernel_frames_;
20610 }
20611 
ParseFromArray(const void * raw,size_t size)20612 bool PerfEventConfig_CallstackSampling::ParseFromArray(const void* raw, size_t size) {
20613   unknown_fields_.clear();
20614   bool packed_error = false;
20615 
20616   ::protozero::ProtoDecoder dec(raw, size);
20617   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
20618     if (field.id() < _has_field_.size()) {
20619       _has_field_.set(field.id());
20620     }
20621     switch (field.id()) {
20622       case 1 /* scope */:
20623         (*scope_).ParseFromArray(field.data(), field.size());
20624         break;
20625       case 2 /* kernel_frames */:
20626         field.get(&kernel_frames_);
20627         break;
20628       default:
20629         field.SerializeAndAppendTo(&unknown_fields_);
20630         break;
20631     }
20632   }
20633   return !packed_error && !dec.bytes_left();
20634 }
20635 
SerializeAsString() const20636 std::string PerfEventConfig_CallstackSampling::SerializeAsString() const {
20637   ::protozero::HeapBuffered<::protozero::Message> msg;
20638   Serialize(msg.get());
20639   return msg.SerializeAsString();
20640 }
20641 
SerializeAsArray() const20642 std::vector<uint8_t> PerfEventConfig_CallstackSampling::SerializeAsArray() const {
20643   ::protozero::HeapBuffered<::protozero::Message> msg;
20644   Serialize(msg.get());
20645   return msg.SerializeAsArray();
20646 }
20647 
Serialize(::protozero::Message * msg) const20648 void PerfEventConfig_CallstackSampling::Serialize(::protozero::Message* msg) const {
20649   // Field 1: scope
20650   if (_has_field_[1]) {
20651     (*scope_).Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
20652   }
20653 
20654   // Field 2: kernel_frames
20655   if (_has_field_[2]) {
20656     msg->AppendTinyVarInt(2, kernel_frames_);
20657   }
20658 
20659   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
20660 }
20661 
20662 
20663 PerfEventConfig_Scope::PerfEventConfig_Scope() = default;
20664 PerfEventConfig_Scope::~PerfEventConfig_Scope() = default;
20665 PerfEventConfig_Scope::PerfEventConfig_Scope(const PerfEventConfig_Scope&) = default;
20666 PerfEventConfig_Scope& PerfEventConfig_Scope::operator=(const PerfEventConfig_Scope&) = default;
20667 PerfEventConfig_Scope::PerfEventConfig_Scope(PerfEventConfig_Scope&&) noexcept = default;
20668 PerfEventConfig_Scope& PerfEventConfig_Scope::operator=(PerfEventConfig_Scope&&) = default;
20669 
operator ==(const PerfEventConfig_Scope & other) const20670 bool PerfEventConfig_Scope::operator==(const PerfEventConfig_Scope& other) const {
20671   return unknown_fields_ == other.unknown_fields_
20672    && target_pid_ == other.target_pid_
20673    && target_cmdline_ == other.target_cmdline_
20674    && exclude_pid_ == other.exclude_pid_
20675    && exclude_cmdline_ == other.exclude_cmdline_
20676    && additional_cmdline_count_ == other.additional_cmdline_count_;
20677 }
20678 
ParseFromArray(const void * raw,size_t size)20679 bool PerfEventConfig_Scope::ParseFromArray(const void* raw, size_t size) {
20680   target_pid_.clear();
20681   target_cmdline_.clear();
20682   exclude_pid_.clear();
20683   exclude_cmdline_.clear();
20684   unknown_fields_.clear();
20685   bool packed_error = false;
20686 
20687   ::protozero::ProtoDecoder dec(raw, size);
20688   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
20689     if (field.id() < _has_field_.size()) {
20690       _has_field_.set(field.id());
20691     }
20692     switch (field.id()) {
20693       case 1 /* target_pid */:
20694         target_pid_.emplace_back();
20695         field.get(&target_pid_.back());
20696         break;
20697       case 2 /* target_cmdline */:
20698         target_cmdline_.emplace_back();
20699         field.get(&target_cmdline_.back());
20700         break;
20701       case 3 /* exclude_pid */:
20702         exclude_pid_.emplace_back();
20703         field.get(&exclude_pid_.back());
20704         break;
20705       case 4 /* exclude_cmdline */:
20706         exclude_cmdline_.emplace_back();
20707         field.get(&exclude_cmdline_.back());
20708         break;
20709       case 5 /* additional_cmdline_count */:
20710         field.get(&additional_cmdline_count_);
20711         break;
20712       default:
20713         field.SerializeAndAppendTo(&unknown_fields_);
20714         break;
20715     }
20716   }
20717   return !packed_error && !dec.bytes_left();
20718 }
20719 
SerializeAsString() const20720 std::string PerfEventConfig_Scope::SerializeAsString() const {
20721   ::protozero::HeapBuffered<::protozero::Message> msg;
20722   Serialize(msg.get());
20723   return msg.SerializeAsString();
20724 }
20725 
SerializeAsArray() const20726 std::vector<uint8_t> PerfEventConfig_Scope::SerializeAsArray() const {
20727   ::protozero::HeapBuffered<::protozero::Message> msg;
20728   Serialize(msg.get());
20729   return msg.SerializeAsArray();
20730 }
20731 
Serialize(::protozero::Message * msg) const20732 void PerfEventConfig_Scope::Serialize(::protozero::Message* msg) const {
20733   // Field 1: target_pid
20734   for (auto& it : target_pid_) {
20735     msg->AppendVarInt(1, it);
20736   }
20737 
20738   // Field 2: target_cmdline
20739   for (auto& it : target_cmdline_) {
20740     msg->AppendString(2, it);
20741   }
20742 
20743   // Field 3: exclude_pid
20744   for (auto& it : exclude_pid_) {
20745     msg->AppendVarInt(3, it);
20746   }
20747 
20748   // Field 4: exclude_cmdline
20749   for (auto& it : exclude_cmdline_) {
20750     msg->AppendString(4, it);
20751   }
20752 
20753   // Field 5: additional_cmdline_count
20754   if (_has_field_[5]) {
20755     msg->AppendVarInt(5, additional_cmdline_count_);
20756   }
20757 
20758   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
20759 }
20760 
20761 }  // namespace perfetto
20762 }  // namespace protos
20763 }  // namespace gen
20764 #if defined(__GNUC__) || defined(__clang__)
20765 #pragma GCC diagnostic pop
20766 #endif
20767 // gen_amalgamated begin source: gen/protos/perfetto/config/sys_stats/sys_stats_config.gen.cc
20768 // gen_amalgamated begin header: gen/protos/perfetto/config/sys_stats/sys_stats_config.gen.h
20769 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
20770 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_SYS_STATS_SYS_STATS_CONFIG_PROTO_CPP_H_
20771 #define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_SYS_STATS_SYS_STATS_CONFIG_PROTO_CPP_H_
20772 
20773 #include <stdint.h>
20774 #include <bitset>
20775 #include <vector>
20776 #include <string>
20777 #include <type_traits>
20778 
20779 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
20780 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
20781 // gen_amalgamated expanded: #include "perfetto/base/export.h"
20782 
20783 namespace perfetto {
20784 namespace protos {
20785 namespace gen {
20786 class SysStatsConfig;
20787 enum SysStatsConfig_StatCounters : int;
20788 enum MeminfoCounters : int;
20789 enum VmstatCounters : int;
20790 }  // namespace perfetto
20791 }  // namespace protos
20792 }  // namespace gen
20793 
20794 namespace protozero {
20795 class Message;
20796 }  // namespace protozero
20797 
20798 namespace perfetto {
20799 namespace protos {
20800 namespace gen {
20801 enum SysStatsConfig_StatCounters : int {
20802   SysStatsConfig_StatCounters_STAT_UNSPECIFIED = 0,
20803   SysStatsConfig_StatCounters_STAT_CPU_TIMES = 1,
20804   SysStatsConfig_StatCounters_STAT_IRQ_COUNTS = 2,
20805   SysStatsConfig_StatCounters_STAT_SOFTIRQ_COUNTS = 3,
20806   SysStatsConfig_StatCounters_STAT_FORK_COUNT = 4,
20807 };
20808 
20809 class PERFETTO_EXPORT SysStatsConfig : public ::protozero::CppMessageObj {
20810  public:
20811   using StatCounters = SysStatsConfig_StatCounters;
20812   static constexpr auto STAT_UNSPECIFIED = SysStatsConfig_StatCounters_STAT_UNSPECIFIED;
20813   static constexpr auto STAT_CPU_TIMES = SysStatsConfig_StatCounters_STAT_CPU_TIMES;
20814   static constexpr auto STAT_IRQ_COUNTS = SysStatsConfig_StatCounters_STAT_IRQ_COUNTS;
20815   static constexpr auto STAT_SOFTIRQ_COUNTS = SysStatsConfig_StatCounters_STAT_SOFTIRQ_COUNTS;
20816   static constexpr auto STAT_FORK_COUNT = SysStatsConfig_StatCounters_STAT_FORK_COUNT;
20817   static constexpr auto StatCounters_MIN = SysStatsConfig_StatCounters_STAT_UNSPECIFIED;
20818   static constexpr auto StatCounters_MAX = SysStatsConfig_StatCounters_STAT_FORK_COUNT;
20819   enum FieldNumbers {
20820     kMeminfoPeriodMsFieldNumber = 1,
20821     kMeminfoCountersFieldNumber = 2,
20822     kVmstatPeriodMsFieldNumber = 3,
20823     kVmstatCountersFieldNumber = 4,
20824     kStatPeriodMsFieldNumber = 5,
20825     kStatCountersFieldNumber = 6,
20826     kDevfreqPeriodMsFieldNumber = 7,
20827   };
20828 
20829   SysStatsConfig();
20830   ~SysStatsConfig() override;
20831   SysStatsConfig(SysStatsConfig&&) noexcept;
20832   SysStatsConfig& operator=(SysStatsConfig&&);
20833   SysStatsConfig(const SysStatsConfig&);
20834   SysStatsConfig& operator=(const SysStatsConfig&);
20835   bool operator==(const SysStatsConfig&) const;
operator !=(const SysStatsConfig & other) const20836   bool operator!=(const SysStatsConfig& other) const { return !(*this == other); }
20837 
20838   bool ParseFromArray(const void*, size_t) override;
20839   std::string SerializeAsString() const override;
20840   std::vector<uint8_t> SerializeAsArray() const override;
20841   void Serialize(::protozero::Message*) const;
20842 
has_meminfo_period_ms() const20843   bool has_meminfo_period_ms() const { return _has_field_[1]; }
meminfo_period_ms() const20844   uint32_t meminfo_period_ms() const { return meminfo_period_ms_; }
set_meminfo_period_ms(uint32_t value)20845   void set_meminfo_period_ms(uint32_t value) { meminfo_period_ms_ = value; _has_field_.set(1); }
20846 
meminfo_counters() const20847   const std::vector<MeminfoCounters>& meminfo_counters() const { return meminfo_counters_; }
mutable_meminfo_counters()20848   std::vector<MeminfoCounters>* mutable_meminfo_counters() { return &meminfo_counters_; }
meminfo_counters_size() const20849   int meminfo_counters_size() const { return static_cast<int>(meminfo_counters_.size()); }
clear_meminfo_counters()20850   void clear_meminfo_counters() { meminfo_counters_.clear(); }
add_meminfo_counters(MeminfoCounters value)20851   void add_meminfo_counters(MeminfoCounters value) { meminfo_counters_.emplace_back(value); }
add_meminfo_counters()20852   MeminfoCounters* add_meminfo_counters() { meminfo_counters_.emplace_back(); return &meminfo_counters_.back(); }
20853 
has_vmstat_period_ms() const20854   bool has_vmstat_period_ms() const { return _has_field_[3]; }
vmstat_period_ms() const20855   uint32_t vmstat_period_ms() const { return vmstat_period_ms_; }
set_vmstat_period_ms(uint32_t value)20856   void set_vmstat_period_ms(uint32_t value) { vmstat_period_ms_ = value; _has_field_.set(3); }
20857 
vmstat_counters() const20858   const std::vector<VmstatCounters>& vmstat_counters() const { return vmstat_counters_; }
mutable_vmstat_counters()20859   std::vector<VmstatCounters>* mutable_vmstat_counters() { return &vmstat_counters_; }
vmstat_counters_size() const20860   int vmstat_counters_size() const { return static_cast<int>(vmstat_counters_.size()); }
clear_vmstat_counters()20861   void clear_vmstat_counters() { vmstat_counters_.clear(); }
add_vmstat_counters(VmstatCounters value)20862   void add_vmstat_counters(VmstatCounters value) { vmstat_counters_.emplace_back(value); }
add_vmstat_counters()20863   VmstatCounters* add_vmstat_counters() { vmstat_counters_.emplace_back(); return &vmstat_counters_.back(); }
20864 
has_stat_period_ms() const20865   bool has_stat_period_ms() const { return _has_field_[5]; }
stat_period_ms() const20866   uint32_t stat_period_ms() const { return stat_period_ms_; }
set_stat_period_ms(uint32_t value)20867   void set_stat_period_ms(uint32_t value) { stat_period_ms_ = value; _has_field_.set(5); }
20868 
stat_counters() const20869   const std::vector<SysStatsConfig_StatCounters>& stat_counters() const { return stat_counters_; }
mutable_stat_counters()20870   std::vector<SysStatsConfig_StatCounters>* mutable_stat_counters() { return &stat_counters_; }
stat_counters_size() const20871   int stat_counters_size() const { return static_cast<int>(stat_counters_.size()); }
clear_stat_counters()20872   void clear_stat_counters() { stat_counters_.clear(); }
add_stat_counters(SysStatsConfig_StatCounters value)20873   void add_stat_counters(SysStatsConfig_StatCounters value) { stat_counters_.emplace_back(value); }
add_stat_counters()20874   SysStatsConfig_StatCounters* add_stat_counters() { stat_counters_.emplace_back(); return &stat_counters_.back(); }
20875 
has_devfreq_period_ms() const20876   bool has_devfreq_period_ms() const { return _has_field_[7]; }
devfreq_period_ms() const20877   uint32_t devfreq_period_ms() const { return devfreq_period_ms_; }
set_devfreq_period_ms(uint32_t value)20878   void set_devfreq_period_ms(uint32_t value) { devfreq_period_ms_ = value; _has_field_.set(7); }
20879 
20880  private:
20881   uint32_t meminfo_period_ms_{};
20882   std::vector<MeminfoCounters> meminfo_counters_;
20883   uint32_t vmstat_period_ms_{};
20884   std::vector<VmstatCounters> vmstat_counters_;
20885   uint32_t stat_period_ms_{};
20886   std::vector<SysStatsConfig_StatCounters> stat_counters_;
20887   uint32_t devfreq_period_ms_{};
20888 
20889   // Allows to preserve unknown protobuf fields for compatibility
20890   // with future versions of .proto files.
20891   std::string unknown_fields_;
20892 
20893   std::bitset<8> _has_field_{};
20894 };
20895 
20896 }  // namespace perfetto
20897 }  // namespace protos
20898 }  // namespace gen
20899 
20900 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_SYS_STATS_SYS_STATS_CONFIG_PROTO_CPP_H_
20901 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
20902 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
20903 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
20904 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
20905 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
20906 #if defined(__GNUC__) || defined(__clang__)
20907 #pragma GCC diagnostic push
20908 #pragma GCC diagnostic ignored "-Wfloat-equal"
20909 #endif
20910 // gen_amalgamated expanded: #include "protos/perfetto/config/sys_stats/sys_stats_config.gen.h"
20911 // gen_amalgamated expanded: #include "protos/perfetto/common/sys_stats_counters.gen.h"
20912 
20913 namespace perfetto {
20914 namespace protos {
20915 namespace gen {
20916 
20917 SysStatsConfig::SysStatsConfig() = default;
20918 SysStatsConfig::~SysStatsConfig() = default;
20919 SysStatsConfig::SysStatsConfig(const SysStatsConfig&) = default;
20920 SysStatsConfig& SysStatsConfig::operator=(const SysStatsConfig&) = default;
20921 SysStatsConfig::SysStatsConfig(SysStatsConfig&&) noexcept = default;
20922 SysStatsConfig& SysStatsConfig::operator=(SysStatsConfig&&) = default;
20923 
operator ==(const SysStatsConfig & other) const20924 bool SysStatsConfig::operator==(const SysStatsConfig& other) const {
20925   return unknown_fields_ == other.unknown_fields_
20926    && meminfo_period_ms_ == other.meminfo_period_ms_
20927    && meminfo_counters_ == other.meminfo_counters_
20928    && vmstat_period_ms_ == other.vmstat_period_ms_
20929    && vmstat_counters_ == other.vmstat_counters_
20930    && stat_period_ms_ == other.stat_period_ms_
20931    && stat_counters_ == other.stat_counters_
20932    && devfreq_period_ms_ == other.devfreq_period_ms_;
20933 }
20934 
ParseFromArray(const void * raw,size_t size)20935 bool SysStatsConfig::ParseFromArray(const void* raw, size_t size) {
20936   meminfo_counters_.clear();
20937   vmstat_counters_.clear();
20938   stat_counters_.clear();
20939   unknown_fields_.clear();
20940   bool packed_error = false;
20941 
20942   ::protozero::ProtoDecoder dec(raw, size);
20943   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
20944     if (field.id() < _has_field_.size()) {
20945       _has_field_.set(field.id());
20946     }
20947     switch (field.id()) {
20948       case 1 /* meminfo_period_ms */:
20949         field.get(&meminfo_period_ms_);
20950         break;
20951       case 2 /* meminfo_counters */:
20952         meminfo_counters_.emplace_back();
20953         field.get(&meminfo_counters_.back());
20954         break;
20955       case 3 /* vmstat_period_ms */:
20956         field.get(&vmstat_period_ms_);
20957         break;
20958       case 4 /* vmstat_counters */:
20959         vmstat_counters_.emplace_back();
20960         field.get(&vmstat_counters_.back());
20961         break;
20962       case 5 /* stat_period_ms */:
20963         field.get(&stat_period_ms_);
20964         break;
20965       case 6 /* stat_counters */:
20966         stat_counters_.emplace_back();
20967         field.get(&stat_counters_.back());
20968         break;
20969       case 7 /* devfreq_period_ms */:
20970         field.get(&devfreq_period_ms_);
20971         break;
20972       default:
20973         field.SerializeAndAppendTo(&unknown_fields_);
20974         break;
20975     }
20976   }
20977   return !packed_error && !dec.bytes_left();
20978 }
20979 
SerializeAsString() const20980 std::string SysStatsConfig::SerializeAsString() const {
20981   ::protozero::HeapBuffered<::protozero::Message> msg;
20982   Serialize(msg.get());
20983   return msg.SerializeAsString();
20984 }
20985 
SerializeAsArray() const20986 std::vector<uint8_t> SysStatsConfig::SerializeAsArray() const {
20987   ::protozero::HeapBuffered<::protozero::Message> msg;
20988   Serialize(msg.get());
20989   return msg.SerializeAsArray();
20990 }
20991 
Serialize(::protozero::Message * msg) const20992 void SysStatsConfig::Serialize(::protozero::Message* msg) const {
20993   // Field 1: meminfo_period_ms
20994   if (_has_field_[1]) {
20995     msg->AppendVarInt(1, meminfo_period_ms_);
20996   }
20997 
20998   // Field 2: meminfo_counters
20999   for (auto& it : meminfo_counters_) {
21000     msg->AppendVarInt(2, it);
21001   }
21002 
21003   // Field 3: vmstat_period_ms
21004   if (_has_field_[3]) {
21005     msg->AppendVarInt(3, vmstat_period_ms_);
21006   }
21007 
21008   // Field 4: vmstat_counters
21009   for (auto& it : vmstat_counters_) {
21010     msg->AppendVarInt(4, it);
21011   }
21012 
21013   // Field 5: stat_period_ms
21014   if (_has_field_[5]) {
21015     msg->AppendVarInt(5, stat_period_ms_);
21016   }
21017 
21018   // Field 6: stat_counters
21019   for (auto& it : stat_counters_) {
21020     msg->AppendVarInt(6, it);
21021   }
21022 
21023   // Field 7: devfreq_period_ms
21024   if (_has_field_[7]) {
21025     msg->AppendVarInt(7, devfreq_period_ms_);
21026   }
21027 
21028   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
21029 }
21030 
21031 }  // namespace perfetto
21032 }  // namespace protos
21033 }  // namespace gen
21034 #if defined(__GNUC__) || defined(__clang__)
21035 #pragma GCC diagnostic pop
21036 #endif
21037 // gen_amalgamated begin source: gen/protos/perfetto/config/track_event/track_event_config.gen.cc
21038 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
21039 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
21040 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
21041 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
21042 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
21043 #if defined(__GNUC__) || defined(__clang__)
21044 #pragma GCC diagnostic push
21045 #pragma GCC diagnostic ignored "-Wfloat-equal"
21046 #endif
21047 // gen_amalgamated expanded: #include "protos/perfetto/config/track_event/track_event_config.gen.h"
21048 
21049 namespace perfetto {
21050 namespace protos {
21051 namespace gen {
21052 
21053 TrackEventConfig::TrackEventConfig() = default;
21054 TrackEventConfig::~TrackEventConfig() = default;
21055 TrackEventConfig::TrackEventConfig(const TrackEventConfig&) = default;
21056 TrackEventConfig& TrackEventConfig::operator=(const TrackEventConfig&) = default;
21057 TrackEventConfig::TrackEventConfig(TrackEventConfig&&) noexcept = default;
21058 TrackEventConfig& TrackEventConfig::operator=(TrackEventConfig&&) = default;
21059 
operator ==(const TrackEventConfig & other) const21060 bool TrackEventConfig::operator==(const TrackEventConfig& other) const {
21061   return unknown_fields_ == other.unknown_fields_
21062    && disabled_categories_ == other.disabled_categories_
21063    && enabled_categories_ == other.enabled_categories_
21064    && disabled_tags_ == other.disabled_tags_
21065    && enabled_tags_ == other.enabled_tags_;
21066 }
21067 
ParseFromArray(const void * raw,size_t size)21068 bool TrackEventConfig::ParseFromArray(const void* raw, size_t size) {
21069   disabled_categories_.clear();
21070   enabled_categories_.clear();
21071   disabled_tags_.clear();
21072   enabled_tags_.clear();
21073   unknown_fields_.clear();
21074   bool packed_error = false;
21075 
21076   ::protozero::ProtoDecoder dec(raw, size);
21077   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
21078     if (field.id() < _has_field_.size()) {
21079       _has_field_.set(field.id());
21080     }
21081     switch (field.id()) {
21082       case 1 /* disabled_categories */:
21083         disabled_categories_.emplace_back();
21084         field.get(&disabled_categories_.back());
21085         break;
21086       case 2 /* enabled_categories */:
21087         enabled_categories_.emplace_back();
21088         field.get(&enabled_categories_.back());
21089         break;
21090       case 3 /* disabled_tags */:
21091         disabled_tags_.emplace_back();
21092         field.get(&disabled_tags_.back());
21093         break;
21094       case 4 /* enabled_tags */:
21095         enabled_tags_.emplace_back();
21096         field.get(&enabled_tags_.back());
21097         break;
21098       default:
21099         field.SerializeAndAppendTo(&unknown_fields_);
21100         break;
21101     }
21102   }
21103   return !packed_error && !dec.bytes_left();
21104 }
21105 
SerializeAsString() const21106 std::string TrackEventConfig::SerializeAsString() const {
21107   ::protozero::HeapBuffered<::protozero::Message> msg;
21108   Serialize(msg.get());
21109   return msg.SerializeAsString();
21110 }
21111 
SerializeAsArray() const21112 std::vector<uint8_t> TrackEventConfig::SerializeAsArray() const {
21113   ::protozero::HeapBuffered<::protozero::Message> msg;
21114   Serialize(msg.get());
21115   return msg.SerializeAsArray();
21116 }
21117 
Serialize(::protozero::Message * msg) const21118 void TrackEventConfig::Serialize(::protozero::Message* msg) const {
21119   // Field 1: disabled_categories
21120   for (auto& it : disabled_categories_) {
21121     msg->AppendString(1, it);
21122   }
21123 
21124   // Field 2: enabled_categories
21125   for (auto& it : enabled_categories_) {
21126     msg->AppendString(2, it);
21127   }
21128 
21129   // Field 3: disabled_tags
21130   for (auto& it : disabled_tags_) {
21131     msg->AppendString(3, it);
21132   }
21133 
21134   // Field 4: enabled_tags
21135   for (auto& it : enabled_tags_) {
21136     msg->AppendString(4, it);
21137   }
21138 
21139   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
21140 }
21141 
21142 }  // namespace perfetto
21143 }  // namespace protos
21144 }  // namespace gen
21145 #if defined(__GNUC__) || defined(__clang__)
21146 #pragma GCC diagnostic pop
21147 #endif
21148 // gen_amalgamated begin source: gen/protos/perfetto/config/chrome/chrome_config.gen.cc
21149 // gen_amalgamated begin header: gen/protos/perfetto/config/chrome/chrome_config.gen.h
21150 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
21151 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_CHROME_CHROME_CONFIG_PROTO_CPP_H_
21152 #define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_CHROME_CHROME_CONFIG_PROTO_CPP_H_
21153 
21154 #include <stdint.h>
21155 #include <bitset>
21156 #include <vector>
21157 #include <string>
21158 #include <type_traits>
21159 
21160 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
21161 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
21162 // gen_amalgamated expanded: #include "perfetto/base/export.h"
21163 
21164 namespace perfetto {
21165 namespace protos {
21166 namespace gen {
21167 class ChromeConfig;
21168 enum ChromeConfig_ClientPriority : int;
21169 }  // namespace perfetto
21170 }  // namespace protos
21171 }  // namespace gen
21172 
21173 namespace protozero {
21174 class Message;
21175 }  // namespace protozero
21176 
21177 namespace perfetto {
21178 namespace protos {
21179 namespace gen {
21180 enum ChromeConfig_ClientPriority : int {
21181   ChromeConfig_ClientPriority_UNKNOWN = 0,
21182   ChromeConfig_ClientPriority_BACKGROUND = 1,
21183   ChromeConfig_ClientPriority_USER_INITIATED = 2,
21184 };
21185 
21186 class PERFETTO_EXPORT ChromeConfig : public ::protozero::CppMessageObj {
21187  public:
21188   using ClientPriority = ChromeConfig_ClientPriority;
21189   static constexpr auto UNKNOWN = ChromeConfig_ClientPriority_UNKNOWN;
21190   static constexpr auto BACKGROUND = ChromeConfig_ClientPriority_BACKGROUND;
21191   static constexpr auto USER_INITIATED = ChromeConfig_ClientPriority_USER_INITIATED;
21192   static constexpr auto ClientPriority_MIN = ChromeConfig_ClientPriority_UNKNOWN;
21193   static constexpr auto ClientPriority_MAX = ChromeConfig_ClientPriority_USER_INITIATED;
21194   enum FieldNumbers {
21195     kTraceConfigFieldNumber = 1,
21196     kPrivacyFilteringEnabledFieldNumber = 2,
21197     kConvertToLegacyJsonFieldNumber = 3,
21198     kClientPriorityFieldNumber = 4,
21199     kJsonAgentLabelFilterFieldNumber = 5,
21200   };
21201 
21202   ChromeConfig();
21203   ~ChromeConfig() override;
21204   ChromeConfig(ChromeConfig&&) noexcept;
21205   ChromeConfig& operator=(ChromeConfig&&);
21206   ChromeConfig(const ChromeConfig&);
21207   ChromeConfig& operator=(const ChromeConfig&);
21208   bool operator==(const ChromeConfig&) const;
operator !=(const ChromeConfig & other) const21209   bool operator!=(const ChromeConfig& other) const { return !(*this == other); }
21210 
21211   bool ParseFromArray(const void*, size_t) override;
21212   std::string SerializeAsString() const override;
21213   std::vector<uint8_t> SerializeAsArray() const override;
21214   void Serialize(::protozero::Message*) const;
21215 
has_trace_config() const21216   bool has_trace_config() const { return _has_field_[1]; }
trace_config() const21217   const std::string& trace_config() const { return trace_config_; }
set_trace_config(const std::string & value)21218   void set_trace_config(const std::string& value) { trace_config_ = value; _has_field_.set(1); }
21219 
has_privacy_filtering_enabled() const21220   bool has_privacy_filtering_enabled() const { return _has_field_[2]; }
privacy_filtering_enabled() const21221   bool privacy_filtering_enabled() const { return privacy_filtering_enabled_; }
set_privacy_filtering_enabled(bool value)21222   void set_privacy_filtering_enabled(bool value) { privacy_filtering_enabled_ = value; _has_field_.set(2); }
21223 
has_convert_to_legacy_json() const21224   bool has_convert_to_legacy_json() const { return _has_field_[3]; }
convert_to_legacy_json() const21225   bool convert_to_legacy_json() const { return convert_to_legacy_json_; }
set_convert_to_legacy_json(bool value)21226   void set_convert_to_legacy_json(bool value) { convert_to_legacy_json_ = value; _has_field_.set(3); }
21227 
has_client_priority() const21228   bool has_client_priority() const { return _has_field_[4]; }
client_priority() const21229   ChromeConfig_ClientPriority client_priority() const { return client_priority_; }
set_client_priority(ChromeConfig_ClientPriority value)21230   void set_client_priority(ChromeConfig_ClientPriority value) { client_priority_ = value; _has_field_.set(4); }
21231 
has_json_agent_label_filter() const21232   bool has_json_agent_label_filter() const { return _has_field_[5]; }
json_agent_label_filter() const21233   const std::string& json_agent_label_filter() const { return json_agent_label_filter_; }
set_json_agent_label_filter(const std::string & value)21234   void set_json_agent_label_filter(const std::string& value) { json_agent_label_filter_ = value; _has_field_.set(5); }
21235 
21236  private:
21237   std::string trace_config_{};
21238   bool privacy_filtering_enabled_{};
21239   bool convert_to_legacy_json_{};
21240   ChromeConfig_ClientPriority client_priority_{};
21241   std::string json_agent_label_filter_{};
21242 
21243   // Allows to preserve unknown protobuf fields for compatibility
21244   // with future versions of .proto files.
21245   std::string unknown_fields_;
21246 
21247   std::bitset<6> _has_field_{};
21248 };
21249 
21250 }  // namespace perfetto
21251 }  // namespace protos
21252 }  // namespace gen
21253 
21254 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_CHROME_CHROME_CONFIG_PROTO_CPP_H_
21255 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
21256 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
21257 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
21258 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
21259 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
21260 #if defined(__GNUC__) || defined(__clang__)
21261 #pragma GCC diagnostic push
21262 #pragma GCC diagnostic ignored "-Wfloat-equal"
21263 #endif
21264 // gen_amalgamated expanded: #include "protos/perfetto/config/chrome/chrome_config.gen.h"
21265 
21266 namespace perfetto {
21267 namespace protos {
21268 namespace gen {
21269 
21270 ChromeConfig::ChromeConfig() = default;
21271 ChromeConfig::~ChromeConfig() = default;
21272 ChromeConfig::ChromeConfig(const ChromeConfig&) = default;
21273 ChromeConfig& ChromeConfig::operator=(const ChromeConfig&) = default;
21274 ChromeConfig::ChromeConfig(ChromeConfig&&) noexcept = default;
21275 ChromeConfig& ChromeConfig::operator=(ChromeConfig&&) = default;
21276 
operator ==(const ChromeConfig & other) const21277 bool ChromeConfig::operator==(const ChromeConfig& other) const {
21278   return unknown_fields_ == other.unknown_fields_
21279    && trace_config_ == other.trace_config_
21280    && privacy_filtering_enabled_ == other.privacy_filtering_enabled_
21281    && convert_to_legacy_json_ == other.convert_to_legacy_json_
21282    && client_priority_ == other.client_priority_
21283    && json_agent_label_filter_ == other.json_agent_label_filter_;
21284 }
21285 
ParseFromArray(const void * raw,size_t size)21286 bool ChromeConfig::ParseFromArray(const void* raw, size_t size) {
21287   unknown_fields_.clear();
21288   bool packed_error = false;
21289 
21290   ::protozero::ProtoDecoder dec(raw, size);
21291   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
21292     if (field.id() < _has_field_.size()) {
21293       _has_field_.set(field.id());
21294     }
21295     switch (field.id()) {
21296       case 1 /* trace_config */:
21297         field.get(&trace_config_);
21298         break;
21299       case 2 /* privacy_filtering_enabled */:
21300         field.get(&privacy_filtering_enabled_);
21301         break;
21302       case 3 /* convert_to_legacy_json */:
21303         field.get(&convert_to_legacy_json_);
21304         break;
21305       case 4 /* client_priority */:
21306         field.get(&client_priority_);
21307         break;
21308       case 5 /* json_agent_label_filter */:
21309         field.get(&json_agent_label_filter_);
21310         break;
21311       default:
21312         field.SerializeAndAppendTo(&unknown_fields_);
21313         break;
21314     }
21315   }
21316   return !packed_error && !dec.bytes_left();
21317 }
21318 
SerializeAsString() const21319 std::string ChromeConfig::SerializeAsString() const {
21320   ::protozero::HeapBuffered<::protozero::Message> msg;
21321   Serialize(msg.get());
21322   return msg.SerializeAsString();
21323 }
21324 
SerializeAsArray() const21325 std::vector<uint8_t> ChromeConfig::SerializeAsArray() const {
21326   ::protozero::HeapBuffered<::protozero::Message> msg;
21327   Serialize(msg.get());
21328   return msg.SerializeAsArray();
21329 }
21330 
Serialize(::protozero::Message * msg) const21331 void ChromeConfig::Serialize(::protozero::Message* msg) const {
21332   // Field 1: trace_config
21333   if (_has_field_[1]) {
21334     msg->AppendString(1, trace_config_);
21335   }
21336 
21337   // Field 2: privacy_filtering_enabled
21338   if (_has_field_[2]) {
21339     msg->AppendTinyVarInt(2, privacy_filtering_enabled_);
21340   }
21341 
21342   // Field 3: convert_to_legacy_json
21343   if (_has_field_[3]) {
21344     msg->AppendTinyVarInt(3, convert_to_legacy_json_);
21345   }
21346 
21347   // Field 4: client_priority
21348   if (_has_field_[4]) {
21349     msg->AppendVarInt(4, client_priority_);
21350   }
21351 
21352   // Field 5: json_agent_label_filter
21353   if (_has_field_[5]) {
21354     msg->AppendString(5, json_agent_label_filter_);
21355   }
21356 
21357   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
21358 }
21359 
21360 }  // namespace perfetto
21361 }  // namespace protos
21362 }  // namespace gen
21363 #if defined(__GNUC__) || defined(__clang__)
21364 #pragma GCC diagnostic pop
21365 #endif
21366 // gen_amalgamated begin source: gen/protos/perfetto/config/data_source_config.gen.cc
21367 // gen_amalgamated begin header: gen/protos/perfetto/config/test_config.gen.h
21368 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
21369 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_TEST_CONFIG_PROTO_CPP_H_
21370 #define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_TEST_CONFIG_PROTO_CPP_H_
21371 
21372 #include <stdint.h>
21373 #include <bitset>
21374 #include <vector>
21375 #include <string>
21376 #include <type_traits>
21377 
21378 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
21379 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
21380 // gen_amalgamated expanded: #include "perfetto/base/export.h"
21381 
21382 namespace perfetto {
21383 namespace protos {
21384 namespace gen {
21385 class TestConfig;
21386 class TestConfig_DummyFields;
21387 }  // namespace perfetto
21388 }  // namespace protos
21389 }  // namespace gen
21390 
21391 namespace protozero {
21392 class Message;
21393 }  // namespace protozero
21394 
21395 namespace perfetto {
21396 namespace protos {
21397 namespace gen {
21398 
21399 class PERFETTO_EXPORT TestConfig : public ::protozero::CppMessageObj {
21400  public:
21401   using DummyFields = TestConfig_DummyFields;
21402   enum FieldNumbers {
21403     kMessageCountFieldNumber = 1,
21404     kMaxMessagesPerSecondFieldNumber = 2,
21405     kSeedFieldNumber = 3,
21406     kMessageSizeFieldNumber = 4,
21407     kSendBatchOnRegisterFieldNumber = 5,
21408     kDummyFieldsFieldNumber = 6,
21409   };
21410 
21411   TestConfig();
21412   ~TestConfig() override;
21413   TestConfig(TestConfig&&) noexcept;
21414   TestConfig& operator=(TestConfig&&);
21415   TestConfig(const TestConfig&);
21416   TestConfig& operator=(const TestConfig&);
21417   bool operator==(const TestConfig&) const;
operator !=(const TestConfig & other) const21418   bool operator!=(const TestConfig& other) const { return !(*this == other); }
21419 
21420   bool ParseFromArray(const void*, size_t) override;
21421   std::string SerializeAsString() const override;
21422   std::vector<uint8_t> SerializeAsArray() const override;
21423   void Serialize(::protozero::Message*) const;
21424 
has_message_count() const21425   bool has_message_count() const { return _has_field_[1]; }
message_count() const21426   uint32_t message_count() const { return message_count_; }
set_message_count(uint32_t value)21427   void set_message_count(uint32_t value) { message_count_ = value; _has_field_.set(1); }
21428 
has_max_messages_per_second() const21429   bool has_max_messages_per_second() const { return _has_field_[2]; }
max_messages_per_second() const21430   uint32_t max_messages_per_second() const { return max_messages_per_second_; }
set_max_messages_per_second(uint32_t value)21431   void set_max_messages_per_second(uint32_t value) { max_messages_per_second_ = value; _has_field_.set(2); }
21432 
has_seed() const21433   bool has_seed() const { return _has_field_[3]; }
seed() const21434   uint32_t seed() const { return seed_; }
set_seed(uint32_t value)21435   void set_seed(uint32_t value) { seed_ = value; _has_field_.set(3); }
21436 
has_message_size() const21437   bool has_message_size() const { return _has_field_[4]; }
message_size() const21438   uint32_t message_size() const { return message_size_; }
set_message_size(uint32_t value)21439   void set_message_size(uint32_t value) { message_size_ = value; _has_field_.set(4); }
21440 
has_send_batch_on_register() const21441   bool has_send_batch_on_register() const { return _has_field_[5]; }
send_batch_on_register() const21442   bool send_batch_on_register() const { return send_batch_on_register_; }
set_send_batch_on_register(bool value)21443   void set_send_batch_on_register(bool value) { send_batch_on_register_ = value; _has_field_.set(5); }
21444 
has_dummy_fields() const21445   bool has_dummy_fields() const { return _has_field_[6]; }
dummy_fields() const21446   const TestConfig_DummyFields& dummy_fields() const { return *dummy_fields_; }
mutable_dummy_fields()21447   TestConfig_DummyFields* mutable_dummy_fields() { _has_field_.set(6); return dummy_fields_.get(); }
21448 
21449  private:
21450   uint32_t message_count_{};
21451   uint32_t max_messages_per_second_{};
21452   uint32_t seed_{};
21453   uint32_t message_size_{};
21454   bool send_batch_on_register_{};
21455   ::protozero::CopyablePtr<TestConfig_DummyFields> dummy_fields_;
21456 
21457   // Allows to preserve unknown protobuf fields for compatibility
21458   // with future versions of .proto files.
21459   std::string unknown_fields_;
21460 
21461   std::bitset<7> _has_field_{};
21462 };
21463 
21464 
21465 class PERFETTO_EXPORT TestConfig_DummyFields : public ::protozero::CppMessageObj {
21466  public:
21467   enum FieldNumbers {
21468     kFieldUint32FieldNumber = 1,
21469     kFieldInt32FieldNumber = 2,
21470     kFieldUint64FieldNumber = 3,
21471     kFieldInt64FieldNumber = 4,
21472     kFieldFixed64FieldNumber = 5,
21473     kFieldSfixed64FieldNumber = 6,
21474     kFieldFixed32FieldNumber = 7,
21475     kFieldSfixed32FieldNumber = 8,
21476     kFieldDoubleFieldNumber = 9,
21477     kFieldFloatFieldNumber = 10,
21478     kFieldSint64FieldNumber = 11,
21479     kFieldSint32FieldNumber = 12,
21480     kFieldStringFieldNumber = 13,
21481     kFieldBytesFieldNumber = 14,
21482   };
21483 
21484   TestConfig_DummyFields();
21485   ~TestConfig_DummyFields() override;
21486   TestConfig_DummyFields(TestConfig_DummyFields&&) noexcept;
21487   TestConfig_DummyFields& operator=(TestConfig_DummyFields&&);
21488   TestConfig_DummyFields(const TestConfig_DummyFields&);
21489   TestConfig_DummyFields& operator=(const TestConfig_DummyFields&);
21490   bool operator==(const TestConfig_DummyFields&) const;
operator !=(const TestConfig_DummyFields & other) const21491   bool operator!=(const TestConfig_DummyFields& other) const { return !(*this == other); }
21492 
21493   bool ParseFromArray(const void*, size_t) override;
21494   std::string SerializeAsString() const override;
21495   std::vector<uint8_t> SerializeAsArray() const override;
21496   void Serialize(::protozero::Message*) const;
21497 
has_field_uint32() const21498   bool has_field_uint32() const { return _has_field_[1]; }
field_uint32() const21499   uint32_t field_uint32() const { return field_uint32_; }
set_field_uint32(uint32_t value)21500   void set_field_uint32(uint32_t value) { field_uint32_ = value; _has_field_.set(1); }
21501 
has_field_int32() const21502   bool has_field_int32() const { return _has_field_[2]; }
field_int32() const21503   int32_t field_int32() const { return field_int32_; }
set_field_int32(int32_t value)21504   void set_field_int32(int32_t value) { field_int32_ = value; _has_field_.set(2); }
21505 
has_field_uint64() const21506   bool has_field_uint64() const { return _has_field_[3]; }
field_uint64() const21507   uint64_t field_uint64() const { return field_uint64_; }
set_field_uint64(uint64_t value)21508   void set_field_uint64(uint64_t value) { field_uint64_ = value; _has_field_.set(3); }
21509 
has_field_int64() const21510   bool has_field_int64() const { return _has_field_[4]; }
field_int64() const21511   int64_t field_int64() const { return field_int64_; }
set_field_int64(int64_t value)21512   void set_field_int64(int64_t value) { field_int64_ = value; _has_field_.set(4); }
21513 
has_field_fixed64() const21514   bool has_field_fixed64() const { return _has_field_[5]; }
field_fixed64() const21515   uint64_t field_fixed64() const { return field_fixed64_; }
set_field_fixed64(uint64_t value)21516   void set_field_fixed64(uint64_t value) { field_fixed64_ = value; _has_field_.set(5); }
21517 
has_field_sfixed64() const21518   bool has_field_sfixed64() const { return _has_field_[6]; }
field_sfixed64() const21519   int64_t field_sfixed64() const { return field_sfixed64_; }
set_field_sfixed64(int64_t value)21520   void set_field_sfixed64(int64_t value) { field_sfixed64_ = value; _has_field_.set(6); }
21521 
has_field_fixed32() const21522   bool has_field_fixed32() const { return _has_field_[7]; }
field_fixed32() const21523   uint32_t field_fixed32() const { return field_fixed32_; }
set_field_fixed32(uint32_t value)21524   void set_field_fixed32(uint32_t value) { field_fixed32_ = value; _has_field_.set(7); }
21525 
has_field_sfixed32() const21526   bool has_field_sfixed32() const { return _has_field_[8]; }
field_sfixed32() const21527   int32_t field_sfixed32() const { return field_sfixed32_; }
set_field_sfixed32(int32_t value)21528   void set_field_sfixed32(int32_t value) { field_sfixed32_ = value; _has_field_.set(8); }
21529 
has_field_double() const21530   bool has_field_double() const { return _has_field_[9]; }
field_double() const21531   double field_double() const { return field_double_; }
set_field_double(double value)21532   void set_field_double(double value) { field_double_ = value; _has_field_.set(9); }
21533 
has_field_float() const21534   bool has_field_float() const { return _has_field_[10]; }
field_float() const21535   float field_float() const { return field_float_; }
set_field_float(float value)21536   void set_field_float(float value) { field_float_ = value; _has_field_.set(10); }
21537 
has_field_sint64() const21538   bool has_field_sint64() const { return _has_field_[11]; }
field_sint64() const21539   int64_t field_sint64() const { return field_sint64_; }
set_field_sint64(int64_t value)21540   void set_field_sint64(int64_t value) { field_sint64_ = value; _has_field_.set(11); }
21541 
has_field_sint32() const21542   bool has_field_sint32() const { return _has_field_[12]; }
field_sint32() const21543   int32_t field_sint32() const { return field_sint32_; }
set_field_sint32(int32_t value)21544   void set_field_sint32(int32_t value) { field_sint32_ = value; _has_field_.set(12); }
21545 
has_field_string() const21546   bool has_field_string() const { return _has_field_[13]; }
field_string() const21547   const std::string& field_string() const { return field_string_; }
set_field_string(const std::string & value)21548   void set_field_string(const std::string& value) { field_string_ = value; _has_field_.set(13); }
21549 
has_field_bytes() const21550   bool has_field_bytes() const { return _has_field_[14]; }
field_bytes() const21551   const std::string& field_bytes() const { return field_bytes_; }
set_field_bytes(const std::string & value)21552   void set_field_bytes(const std::string& value) { field_bytes_ = value; _has_field_.set(14); }
set_field_bytes(const void * p,size_t s)21553   void set_field_bytes(const void* p, size_t s) { field_bytes_.assign(reinterpret_cast<const char*>(p), s); _has_field_.set(14); }
21554 
21555  private:
21556   uint32_t field_uint32_{};
21557   int32_t field_int32_{};
21558   uint64_t field_uint64_{};
21559   int64_t field_int64_{};
21560   uint64_t field_fixed64_{};
21561   int64_t field_sfixed64_{};
21562   uint32_t field_fixed32_{};
21563   int32_t field_sfixed32_{};
21564   double field_double_{};
21565   float field_float_{};
21566   int64_t field_sint64_{};
21567   int32_t field_sint32_{};
21568   std::string field_string_{};
21569   std::string field_bytes_{};
21570 
21571   // Allows to preserve unknown protobuf fields for compatibility
21572   // with future versions of .proto files.
21573   std::string unknown_fields_;
21574 
21575   std::bitset<15> _has_field_{};
21576 };
21577 
21578 }  // namespace perfetto
21579 }  // namespace protos
21580 }  // namespace gen
21581 
21582 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_TEST_CONFIG_PROTO_CPP_H_
21583 // gen_amalgamated begin header: gen/protos/perfetto/config/interceptor_config.gen.h
21584 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
21585 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_INTERCEPTOR_CONFIG_PROTO_CPP_H_
21586 #define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_INTERCEPTOR_CONFIG_PROTO_CPP_H_
21587 
21588 #include <stdint.h>
21589 #include <bitset>
21590 #include <vector>
21591 #include <string>
21592 #include <type_traits>
21593 
21594 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
21595 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
21596 // gen_amalgamated expanded: #include "perfetto/base/export.h"
21597 
21598 namespace perfetto {
21599 namespace protos {
21600 namespace gen {
21601 class InterceptorConfig;
21602 }  // namespace perfetto
21603 }  // namespace protos
21604 }  // namespace gen
21605 
21606 namespace protozero {
21607 class Message;
21608 }  // namespace protozero
21609 
21610 namespace perfetto {
21611 namespace protos {
21612 namespace gen {
21613 
21614 class PERFETTO_EXPORT InterceptorConfig : public ::protozero::CppMessageObj {
21615  public:
21616   enum FieldNumbers {
21617     kNameFieldNumber = 1,
21618     kConsoleConfigFieldNumber = 100,
21619   };
21620 
21621   InterceptorConfig();
21622   ~InterceptorConfig() override;
21623   InterceptorConfig(InterceptorConfig&&) noexcept;
21624   InterceptorConfig& operator=(InterceptorConfig&&);
21625   InterceptorConfig(const InterceptorConfig&);
21626   InterceptorConfig& operator=(const InterceptorConfig&);
21627   bool operator==(const InterceptorConfig&) const;
operator !=(const InterceptorConfig & other) const21628   bool operator!=(const InterceptorConfig& other) const { return !(*this == other); }
21629 
21630   bool ParseFromArray(const void*, size_t) override;
21631   std::string SerializeAsString() const override;
21632   std::vector<uint8_t> SerializeAsArray() const override;
21633   void Serialize(::protozero::Message*) const;
21634 
has_name() const21635   bool has_name() const { return _has_field_[1]; }
name() const21636   const std::string& name() const { return name_; }
set_name(const std::string & value)21637   void set_name(const std::string& value) { name_ = value; _has_field_.set(1); }
21638 
console_config_raw() const21639   const std::string& console_config_raw() const { return console_config_; }
set_console_config_raw(const std::string & raw)21640   void set_console_config_raw(const std::string& raw) { console_config_ = raw; _has_field_.set(100); }
21641 
21642  private:
21643   std::string name_{};
21644   std::string console_config_;  // [lazy=true]
21645 
21646   // Allows to preserve unknown protobuf fields for compatibility
21647   // with future versions of .proto files.
21648   std::string unknown_fields_;
21649 
21650   std::bitset<101> _has_field_{};
21651 };
21652 
21653 }  // namespace perfetto
21654 }  // namespace protos
21655 }  // namespace gen
21656 
21657 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_INTERCEPTOR_CONFIG_PROTO_CPP_H_
21658 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
21659 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
21660 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
21661 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
21662 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
21663 #if defined(__GNUC__) || defined(__clang__)
21664 #pragma GCC diagnostic push
21665 #pragma GCC diagnostic ignored "-Wfloat-equal"
21666 #endif
21667 // gen_amalgamated expanded: #include "protos/perfetto/config/data_source_config.gen.h"
21668 // gen_amalgamated expanded: #include "protos/perfetto/config/test_config.gen.h"
21669 // gen_amalgamated expanded: #include "protos/perfetto/config/interceptor_config.gen.h"
21670 // gen_amalgamated expanded: #include "protos/perfetto/config/interceptors/console_config.gen.h"
21671 // gen_amalgamated expanded: #include "protos/perfetto/config/chrome/chrome_config.gen.h"
21672 
21673 namespace perfetto {
21674 namespace protos {
21675 namespace gen {
21676 
21677 DataSourceConfig::DataSourceConfig() = default;
21678 DataSourceConfig::~DataSourceConfig() = default;
21679 DataSourceConfig::DataSourceConfig(const DataSourceConfig&) = default;
21680 DataSourceConfig& DataSourceConfig::operator=(const DataSourceConfig&) = default;
21681 DataSourceConfig::DataSourceConfig(DataSourceConfig&&) noexcept = default;
21682 DataSourceConfig& DataSourceConfig::operator=(DataSourceConfig&&) = default;
21683 
operator ==(const DataSourceConfig & other) const21684 bool DataSourceConfig::operator==(const DataSourceConfig& other) const {
21685   return unknown_fields_ == other.unknown_fields_
21686    && name_ == other.name_
21687    && target_buffer_ == other.target_buffer_
21688    && trace_duration_ms_ == other.trace_duration_ms_
21689    && stop_timeout_ms_ == other.stop_timeout_ms_
21690    && enable_extra_guardrails_ == other.enable_extra_guardrails_
21691    && session_initiator_ == other.session_initiator_
21692    && tracing_session_id_ == other.tracing_session_id_
21693    && ftrace_config_ == other.ftrace_config_
21694    && inode_file_config_ == other.inode_file_config_
21695    && process_stats_config_ == other.process_stats_config_
21696    && sys_stats_config_ == other.sys_stats_config_
21697    && heapprofd_config_ == other.heapprofd_config_
21698    && java_hprof_config_ == other.java_hprof_config_
21699    && android_power_config_ == other.android_power_config_
21700    && android_log_config_ == other.android_log_config_
21701    && gpu_counter_config_ == other.gpu_counter_config_
21702    && packages_list_config_ == other.packages_list_config_
21703    && perf_event_config_ == other.perf_event_config_
21704    && vulkan_memory_config_ == other.vulkan_memory_config_
21705    && track_event_config_ == other.track_event_config_
21706    && android_polled_state_config_ == other.android_polled_state_config_
21707    && chrome_config_ == other.chrome_config_
21708    && interceptor_config_ == other.interceptor_config_
21709    && legacy_config_ == other.legacy_config_
21710    && for_testing_ == other.for_testing_;
21711 }
21712 
ParseFromArray(const void * raw,size_t size)21713 bool DataSourceConfig::ParseFromArray(const void* raw, size_t size) {
21714   unknown_fields_.clear();
21715   bool packed_error = false;
21716 
21717   ::protozero::ProtoDecoder dec(raw, size);
21718   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
21719     if (field.id() < _has_field_.size()) {
21720       _has_field_.set(field.id());
21721     }
21722     switch (field.id()) {
21723       case 1 /* name */:
21724         field.get(&name_);
21725         break;
21726       case 2 /* target_buffer */:
21727         field.get(&target_buffer_);
21728         break;
21729       case 3 /* trace_duration_ms */:
21730         field.get(&trace_duration_ms_);
21731         break;
21732       case 7 /* stop_timeout_ms */:
21733         field.get(&stop_timeout_ms_);
21734         break;
21735       case 6 /* enable_extra_guardrails */:
21736         field.get(&enable_extra_guardrails_);
21737         break;
21738       case 8 /* session_initiator */:
21739         field.get(&session_initiator_);
21740         break;
21741       case 4 /* tracing_session_id */:
21742         field.get(&tracing_session_id_);
21743         break;
21744       case 100 /* ftrace_config */:
21745         ftrace_config_ = field.as_std_string();
21746         break;
21747       case 102 /* inode_file_config */:
21748         inode_file_config_ = field.as_std_string();
21749         break;
21750       case 103 /* process_stats_config */:
21751         process_stats_config_ = field.as_std_string();
21752         break;
21753       case 104 /* sys_stats_config */:
21754         sys_stats_config_ = field.as_std_string();
21755         break;
21756       case 105 /* heapprofd_config */:
21757         heapprofd_config_ = field.as_std_string();
21758         break;
21759       case 110 /* java_hprof_config */:
21760         java_hprof_config_ = field.as_std_string();
21761         break;
21762       case 106 /* android_power_config */:
21763         android_power_config_ = field.as_std_string();
21764         break;
21765       case 107 /* android_log_config */:
21766         android_log_config_ = field.as_std_string();
21767         break;
21768       case 108 /* gpu_counter_config */:
21769         gpu_counter_config_ = field.as_std_string();
21770         break;
21771       case 109 /* packages_list_config */:
21772         packages_list_config_ = field.as_std_string();
21773         break;
21774       case 111 /* perf_event_config */:
21775         perf_event_config_ = field.as_std_string();
21776         break;
21777       case 112 /* vulkan_memory_config */:
21778         vulkan_memory_config_ = field.as_std_string();
21779         break;
21780       case 113 /* track_event_config */:
21781         track_event_config_ = field.as_std_string();
21782         break;
21783       case 114 /* android_polled_state_config */:
21784         android_polled_state_config_ = field.as_std_string();
21785         break;
21786       case 101 /* chrome_config */:
21787         (*chrome_config_).ParseFromArray(field.data(), field.size());
21788         break;
21789       case 115 /* interceptor_config */:
21790         (*interceptor_config_).ParseFromArray(field.data(), field.size());
21791         break;
21792       case 1000 /* legacy_config */:
21793         field.get(&legacy_config_);
21794         break;
21795       case 1001 /* for_testing */:
21796         (*for_testing_).ParseFromArray(field.data(), field.size());
21797         break;
21798       default:
21799         field.SerializeAndAppendTo(&unknown_fields_);
21800         break;
21801     }
21802   }
21803   return !packed_error && !dec.bytes_left();
21804 }
21805 
SerializeAsString() const21806 std::string DataSourceConfig::SerializeAsString() const {
21807   ::protozero::HeapBuffered<::protozero::Message> msg;
21808   Serialize(msg.get());
21809   return msg.SerializeAsString();
21810 }
21811 
SerializeAsArray() const21812 std::vector<uint8_t> DataSourceConfig::SerializeAsArray() const {
21813   ::protozero::HeapBuffered<::protozero::Message> msg;
21814   Serialize(msg.get());
21815   return msg.SerializeAsArray();
21816 }
21817 
Serialize(::protozero::Message * msg) const21818 void DataSourceConfig::Serialize(::protozero::Message* msg) const {
21819   // Field 1: name
21820   if (_has_field_[1]) {
21821     msg->AppendString(1, name_);
21822   }
21823 
21824   // Field 2: target_buffer
21825   if (_has_field_[2]) {
21826     msg->AppendVarInt(2, target_buffer_);
21827   }
21828 
21829   // Field 3: trace_duration_ms
21830   if (_has_field_[3]) {
21831     msg->AppendVarInt(3, trace_duration_ms_);
21832   }
21833 
21834   // Field 7: stop_timeout_ms
21835   if (_has_field_[7]) {
21836     msg->AppendVarInt(7, stop_timeout_ms_);
21837   }
21838 
21839   // Field 6: enable_extra_guardrails
21840   if (_has_field_[6]) {
21841     msg->AppendTinyVarInt(6, enable_extra_guardrails_);
21842   }
21843 
21844   // Field 8: session_initiator
21845   if (_has_field_[8]) {
21846     msg->AppendVarInt(8, session_initiator_);
21847   }
21848 
21849   // Field 4: tracing_session_id
21850   if (_has_field_[4]) {
21851     msg->AppendVarInt(4, tracing_session_id_);
21852   }
21853 
21854   // Field 100: ftrace_config
21855   if (_has_field_[100]) {
21856     msg->AppendString(100, ftrace_config_);
21857   }
21858 
21859   // Field 102: inode_file_config
21860   if (_has_field_[102]) {
21861     msg->AppendString(102, inode_file_config_);
21862   }
21863 
21864   // Field 103: process_stats_config
21865   if (_has_field_[103]) {
21866     msg->AppendString(103, process_stats_config_);
21867   }
21868 
21869   // Field 104: sys_stats_config
21870   if (_has_field_[104]) {
21871     msg->AppendString(104, sys_stats_config_);
21872   }
21873 
21874   // Field 105: heapprofd_config
21875   if (_has_field_[105]) {
21876     msg->AppendString(105, heapprofd_config_);
21877   }
21878 
21879   // Field 110: java_hprof_config
21880   if (_has_field_[110]) {
21881     msg->AppendString(110, java_hprof_config_);
21882   }
21883 
21884   // Field 106: android_power_config
21885   if (_has_field_[106]) {
21886     msg->AppendString(106, android_power_config_);
21887   }
21888 
21889   // Field 107: android_log_config
21890   if (_has_field_[107]) {
21891     msg->AppendString(107, android_log_config_);
21892   }
21893 
21894   // Field 108: gpu_counter_config
21895   if (_has_field_[108]) {
21896     msg->AppendString(108, gpu_counter_config_);
21897   }
21898 
21899   // Field 109: packages_list_config
21900   if (_has_field_[109]) {
21901     msg->AppendString(109, packages_list_config_);
21902   }
21903 
21904   // Field 111: perf_event_config
21905   if (_has_field_[111]) {
21906     msg->AppendString(111, perf_event_config_);
21907   }
21908 
21909   // Field 112: vulkan_memory_config
21910   if (_has_field_[112]) {
21911     msg->AppendString(112, vulkan_memory_config_);
21912   }
21913 
21914   // Field 113: track_event_config
21915   if (_has_field_[113]) {
21916     msg->AppendString(113, track_event_config_);
21917   }
21918 
21919   // Field 114: android_polled_state_config
21920   if (_has_field_[114]) {
21921     msg->AppendString(114, android_polled_state_config_);
21922   }
21923 
21924   // Field 101: chrome_config
21925   if (_has_field_[101]) {
21926     (*chrome_config_).Serialize(msg->BeginNestedMessage<::protozero::Message>(101));
21927   }
21928 
21929   // Field 115: interceptor_config
21930   if (_has_field_[115]) {
21931     (*interceptor_config_).Serialize(msg->BeginNestedMessage<::protozero::Message>(115));
21932   }
21933 
21934   // Field 1000: legacy_config
21935   if (_has_field_[1000]) {
21936     msg->AppendString(1000, legacy_config_);
21937   }
21938 
21939   // Field 1001: for_testing
21940   if (_has_field_[1001]) {
21941     (*for_testing_).Serialize(msg->BeginNestedMessage<::protozero::Message>(1001));
21942   }
21943 
21944   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
21945 }
21946 
21947 }  // namespace perfetto
21948 }  // namespace protos
21949 }  // namespace gen
21950 #if defined(__GNUC__) || defined(__clang__)
21951 #pragma GCC diagnostic pop
21952 #endif
21953 // gen_amalgamated begin source: gen/protos/perfetto/config/interceptor_config.gen.cc
21954 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
21955 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
21956 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
21957 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
21958 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
21959 #if defined(__GNUC__) || defined(__clang__)
21960 #pragma GCC diagnostic push
21961 #pragma GCC diagnostic ignored "-Wfloat-equal"
21962 #endif
21963 // gen_amalgamated expanded: #include "protos/perfetto/config/interceptor_config.gen.h"
21964 
21965 namespace perfetto {
21966 namespace protos {
21967 namespace gen {
21968 
21969 InterceptorConfig::InterceptorConfig() = default;
21970 InterceptorConfig::~InterceptorConfig() = default;
21971 InterceptorConfig::InterceptorConfig(const InterceptorConfig&) = default;
21972 InterceptorConfig& InterceptorConfig::operator=(const InterceptorConfig&) = default;
21973 InterceptorConfig::InterceptorConfig(InterceptorConfig&&) noexcept = default;
21974 InterceptorConfig& InterceptorConfig::operator=(InterceptorConfig&&) = default;
21975 
operator ==(const InterceptorConfig & other) const21976 bool InterceptorConfig::operator==(const InterceptorConfig& other) const {
21977   return unknown_fields_ == other.unknown_fields_
21978    && name_ == other.name_
21979    && console_config_ == other.console_config_;
21980 }
21981 
ParseFromArray(const void * raw,size_t size)21982 bool InterceptorConfig::ParseFromArray(const void* raw, size_t size) {
21983   unknown_fields_.clear();
21984   bool packed_error = false;
21985 
21986   ::protozero::ProtoDecoder dec(raw, size);
21987   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
21988     if (field.id() < _has_field_.size()) {
21989       _has_field_.set(field.id());
21990     }
21991     switch (field.id()) {
21992       case 1 /* name */:
21993         field.get(&name_);
21994         break;
21995       case 100 /* console_config */:
21996         console_config_ = field.as_std_string();
21997         break;
21998       default:
21999         field.SerializeAndAppendTo(&unknown_fields_);
22000         break;
22001     }
22002   }
22003   return !packed_error && !dec.bytes_left();
22004 }
22005 
SerializeAsString() const22006 std::string InterceptorConfig::SerializeAsString() const {
22007   ::protozero::HeapBuffered<::protozero::Message> msg;
22008   Serialize(msg.get());
22009   return msg.SerializeAsString();
22010 }
22011 
SerializeAsArray() const22012 std::vector<uint8_t> InterceptorConfig::SerializeAsArray() const {
22013   ::protozero::HeapBuffered<::protozero::Message> msg;
22014   Serialize(msg.get());
22015   return msg.SerializeAsArray();
22016 }
22017 
Serialize(::protozero::Message * msg) const22018 void InterceptorConfig::Serialize(::protozero::Message* msg) const {
22019   // Field 1: name
22020   if (_has_field_[1]) {
22021     msg->AppendString(1, name_);
22022   }
22023 
22024   // Field 100: console_config
22025   if (_has_field_[100]) {
22026     msg->AppendString(100, console_config_);
22027   }
22028 
22029   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
22030 }
22031 
22032 }  // namespace perfetto
22033 }  // namespace protos
22034 }  // namespace gen
22035 #if defined(__GNUC__) || defined(__clang__)
22036 #pragma GCC diagnostic pop
22037 #endif
22038 // gen_amalgamated begin source: gen/protos/perfetto/config/stress_test_config.gen.cc
22039 // gen_amalgamated begin header: gen/protos/perfetto/config/stress_test_config.gen.h
22040 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
22041 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_STRESS_TEST_CONFIG_PROTO_CPP_H_
22042 #define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_STRESS_TEST_CONFIG_PROTO_CPP_H_
22043 
22044 #include <stdint.h>
22045 #include <bitset>
22046 #include <vector>
22047 #include <string>
22048 #include <type_traits>
22049 
22050 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
22051 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
22052 // gen_amalgamated expanded: #include "perfetto/base/export.h"
22053 
22054 namespace perfetto {
22055 namespace protos {
22056 namespace gen {
22057 class StressTestConfig;
22058 class StressTestConfig_WriterTiming;
22059 class TraceConfig;
22060 class TraceConfig_TraceFilter;
22061 class TraceConfig_IncidentReportConfig;
22062 class TraceConfig_IncrementalStateConfig;
22063 class TraceConfig_TriggerConfig;
22064 class TraceConfig_TriggerConfig_Trigger;
22065 class TraceConfig_GuardrailOverrides;
22066 class TraceConfig_StatsdMetadata;
22067 class TraceConfig_ProducerConfig;
22068 class TraceConfig_BuiltinDataSource;
22069 class TraceConfig_DataSource;
22070 class DataSourceConfig;
22071 class TestConfig;
22072 class TestConfig_DummyFields;
22073 class InterceptorConfig;
22074 class ChromeConfig;
22075 class TraceConfig_BufferConfig;
22076 enum TraceConfig_LockdownModeOperation : int;
22077 enum TraceConfig_CompressionType : int;
22078 enum TraceConfig_StatsdLogging : int;
22079 enum TraceConfig_TriggerConfig_TriggerMode : int;
22080 enum BuiltinClock : int;
22081 enum DataSourceConfig_SessionInitiator : int;
22082 enum ChromeConfig_ClientPriority : int;
22083 enum TraceConfig_BufferConfig_FillPolicy : int;
22084 }  // namespace perfetto
22085 }  // namespace protos
22086 }  // namespace gen
22087 
22088 namespace protozero {
22089 class Message;
22090 }  // namespace protozero
22091 
22092 namespace perfetto {
22093 namespace protos {
22094 namespace gen {
22095 
22096 class PERFETTO_EXPORT StressTestConfig : public ::protozero::CppMessageObj {
22097  public:
22098   using WriterTiming = StressTestConfig_WriterTiming;
22099   enum FieldNumbers {
22100     kTraceConfigFieldNumber = 1,
22101     kShmemSizeKbFieldNumber = 2,
22102     kShmemPageSizeKbFieldNumber = 3,
22103     kNumProcessesFieldNumber = 4,
22104     kNumThreadsFieldNumber = 5,
22105     kMaxEventsFieldNumber = 6,
22106     kNestingFieldNumber = 7,
22107     kSteadyStateTimingsFieldNumber = 8,
22108     kBurstPeriodMsFieldNumber = 9,
22109     kBurstDurationMsFieldNumber = 10,
22110     kBurstTimingsFieldNumber = 11,
22111   };
22112 
22113   StressTestConfig();
22114   ~StressTestConfig() override;
22115   StressTestConfig(StressTestConfig&&) noexcept;
22116   StressTestConfig& operator=(StressTestConfig&&);
22117   StressTestConfig(const StressTestConfig&);
22118   StressTestConfig& operator=(const StressTestConfig&);
22119   bool operator==(const StressTestConfig&) const;
operator !=(const StressTestConfig & other) const22120   bool operator!=(const StressTestConfig& other) const { return !(*this == other); }
22121 
22122   bool ParseFromArray(const void*, size_t) override;
22123   std::string SerializeAsString() const override;
22124   std::vector<uint8_t> SerializeAsArray() const override;
22125   void Serialize(::protozero::Message*) const;
22126 
has_trace_config() const22127   bool has_trace_config() const { return _has_field_[1]; }
trace_config() const22128   const TraceConfig& trace_config() const { return *trace_config_; }
mutable_trace_config()22129   TraceConfig* mutable_trace_config() { _has_field_.set(1); return trace_config_.get(); }
22130 
has_shmem_size_kb() const22131   bool has_shmem_size_kb() const { return _has_field_[2]; }
shmem_size_kb() const22132   uint32_t shmem_size_kb() const { return shmem_size_kb_; }
set_shmem_size_kb(uint32_t value)22133   void set_shmem_size_kb(uint32_t value) { shmem_size_kb_ = value; _has_field_.set(2); }
22134 
has_shmem_page_size_kb() const22135   bool has_shmem_page_size_kb() const { return _has_field_[3]; }
shmem_page_size_kb() const22136   uint32_t shmem_page_size_kb() const { return shmem_page_size_kb_; }
set_shmem_page_size_kb(uint32_t value)22137   void set_shmem_page_size_kb(uint32_t value) { shmem_page_size_kb_ = value; _has_field_.set(3); }
22138 
has_num_processes() const22139   bool has_num_processes() const { return _has_field_[4]; }
num_processes() const22140   uint32_t num_processes() const { return num_processes_; }
set_num_processes(uint32_t value)22141   void set_num_processes(uint32_t value) { num_processes_ = value; _has_field_.set(4); }
22142 
has_num_threads() const22143   bool has_num_threads() const { return _has_field_[5]; }
num_threads() const22144   uint32_t num_threads() const { return num_threads_; }
set_num_threads(uint32_t value)22145   void set_num_threads(uint32_t value) { num_threads_ = value; _has_field_.set(5); }
22146 
has_max_events() const22147   bool has_max_events() const { return _has_field_[6]; }
max_events() const22148   uint32_t max_events() const { return max_events_; }
set_max_events(uint32_t value)22149   void set_max_events(uint32_t value) { max_events_ = value; _has_field_.set(6); }
22150 
has_nesting() const22151   bool has_nesting() const { return _has_field_[7]; }
nesting() const22152   uint32_t nesting() const { return nesting_; }
set_nesting(uint32_t value)22153   void set_nesting(uint32_t value) { nesting_ = value; _has_field_.set(7); }
22154 
has_steady_state_timings() const22155   bool has_steady_state_timings() const { return _has_field_[8]; }
steady_state_timings() const22156   const StressTestConfig_WriterTiming& steady_state_timings() const { return *steady_state_timings_; }
mutable_steady_state_timings()22157   StressTestConfig_WriterTiming* mutable_steady_state_timings() { _has_field_.set(8); return steady_state_timings_.get(); }
22158 
has_burst_period_ms() const22159   bool has_burst_period_ms() const { return _has_field_[9]; }
burst_period_ms() const22160   uint32_t burst_period_ms() const { return burst_period_ms_; }
set_burst_period_ms(uint32_t value)22161   void set_burst_period_ms(uint32_t value) { burst_period_ms_ = value; _has_field_.set(9); }
22162 
has_burst_duration_ms() const22163   bool has_burst_duration_ms() const { return _has_field_[10]; }
burst_duration_ms() const22164   uint32_t burst_duration_ms() const { return burst_duration_ms_; }
set_burst_duration_ms(uint32_t value)22165   void set_burst_duration_ms(uint32_t value) { burst_duration_ms_ = value; _has_field_.set(10); }
22166 
has_burst_timings() const22167   bool has_burst_timings() const { return _has_field_[11]; }
burst_timings() const22168   const StressTestConfig_WriterTiming& burst_timings() const { return *burst_timings_; }
mutable_burst_timings()22169   StressTestConfig_WriterTiming* mutable_burst_timings() { _has_field_.set(11); return burst_timings_.get(); }
22170 
22171  private:
22172   ::protozero::CopyablePtr<TraceConfig> trace_config_;
22173   uint32_t shmem_size_kb_{};
22174   uint32_t shmem_page_size_kb_{};
22175   uint32_t num_processes_{};
22176   uint32_t num_threads_{};
22177   uint32_t max_events_{};
22178   uint32_t nesting_{};
22179   ::protozero::CopyablePtr<StressTestConfig_WriterTiming> steady_state_timings_;
22180   uint32_t burst_period_ms_{};
22181   uint32_t burst_duration_ms_{};
22182   ::protozero::CopyablePtr<StressTestConfig_WriterTiming> burst_timings_;
22183 
22184   // Allows to preserve unknown protobuf fields for compatibility
22185   // with future versions of .proto files.
22186   std::string unknown_fields_;
22187 
22188   std::bitset<12> _has_field_{};
22189 };
22190 
22191 
22192 class PERFETTO_EXPORT StressTestConfig_WriterTiming : public ::protozero::CppMessageObj {
22193  public:
22194   enum FieldNumbers {
22195     kPayloadMeanFieldNumber = 1,
22196     kPayloadStddevFieldNumber = 2,
22197     kRateMeanFieldNumber = 3,
22198     kRateStddevFieldNumber = 4,
22199     kPayloadWriteTimeMsFieldNumber = 5,
22200   };
22201 
22202   StressTestConfig_WriterTiming();
22203   ~StressTestConfig_WriterTiming() override;
22204   StressTestConfig_WriterTiming(StressTestConfig_WriterTiming&&) noexcept;
22205   StressTestConfig_WriterTiming& operator=(StressTestConfig_WriterTiming&&);
22206   StressTestConfig_WriterTiming(const StressTestConfig_WriterTiming&);
22207   StressTestConfig_WriterTiming& operator=(const StressTestConfig_WriterTiming&);
22208   bool operator==(const StressTestConfig_WriterTiming&) const;
operator !=(const StressTestConfig_WriterTiming & other) const22209   bool operator!=(const StressTestConfig_WriterTiming& other) const { return !(*this == other); }
22210 
22211   bool ParseFromArray(const void*, size_t) override;
22212   std::string SerializeAsString() const override;
22213   std::vector<uint8_t> SerializeAsArray() const override;
22214   void Serialize(::protozero::Message*) const;
22215 
has_payload_mean() const22216   bool has_payload_mean() const { return _has_field_[1]; }
payload_mean() const22217   double payload_mean() const { return payload_mean_; }
set_payload_mean(double value)22218   void set_payload_mean(double value) { payload_mean_ = value; _has_field_.set(1); }
22219 
has_payload_stddev() const22220   bool has_payload_stddev() const { return _has_field_[2]; }
payload_stddev() const22221   double payload_stddev() const { return payload_stddev_; }
set_payload_stddev(double value)22222   void set_payload_stddev(double value) { payload_stddev_ = value; _has_field_.set(2); }
22223 
has_rate_mean() const22224   bool has_rate_mean() const { return _has_field_[3]; }
rate_mean() const22225   double rate_mean() const { return rate_mean_; }
set_rate_mean(double value)22226   void set_rate_mean(double value) { rate_mean_ = value; _has_field_.set(3); }
22227 
has_rate_stddev() const22228   bool has_rate_stddev() const { return _has_field_[4]; }
rate_stddev() const22229   double rate_stddev() const { return rate_stddev_; }
set_rate_stddev(double value)22230   void set_rate_stddev(double value) { rate_stddev_ = value; _has_field_.set(4); }
22231 
has_payload_write_time_ms() const22232   bool has_payload_write_time_ms() const { return _has_field_[5]; }
payload_write_time_ms() const22233   uint32_t payload_write_time_ms() const { return payload_write_time_ms_; }
set_payload_write_time_ms(uint32_t value)22234   void set_payload_write_time_ms(uint32_t value) { payload_write_time_ms_ = value; _has_field_.set(5); }
22235 
22236  private:
22237   double payload_mean_{};
22238   double payload_stddev_{};
22239   double rate_mean_{};
22240   double rate_stddev_{};
22241   uint32_t payload_write_time_ms_{};
22242 
22243   // Allows to preserve unknown protobuf fields for compatibility
22244   // with future versions of .proto files.
22245   std::string unknown_fields_;
22246 
22247   std::bitset<6> _has_field_{};
22248 };
22249 
22250 }  // namespace perfetto
22251 }  // namespace protos
22252 }  // namespace gen
22253 
22254 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_STRESS_TEST_CONFIG_PROTO_CPP_H_
22255 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
22256 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
22257 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
22258 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
22259 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
22260 #if defined(__GNUC__) || defined(__clang__)
22261 #pragma GCC diagnostic push
22262 #pragma GCC diagnostic ignored "-Wfloat-equal"
22263 #endif
22264 // gen_amalgamated expanded: #include "protos/perfetto/config/stress_test_config.gen.h"
22265 // gen_amalgamated expanded: #include "protos/perfetto/config/trace_config.gen.h"
22266 // gen_amalgamated expanded: #include "protos/perfetto/config/data_source_config.gen.h"
22267 // gen_amalgamated expanded: #include "protos/perfetto/config/track_event/track_event_config.gen.h"
22268 // gen_amalgamated expanded: #include "protos/perfetto/config/test_config.gen.h"
22269 // gen_amalgamated expanded: #include "protos/perfetto/config/sys_stats/sys_stats_config.gen.h"
22270 // gen_amalgamated expanded: #include "protos/perfetto/common/sys_stats_counters.gen.h"
22271 // gen_amalgamated expanded: #include "protos/perfetto/config/profiling/perf_event_config.gen.h"
22272 // gen_amalgamated expanded: #include "protos/perfetto/common/perf_events.gen.h"
22273 // gen_amalgamated expanded: #include "protos/perfetto/config/profiling/java_hprof_config.gen.h"
22274 // gen_amalgamated expanded: #include "protos/perfetto/config/profiling/heapprofd_config.gen.h"
22275 // gen_amalgamated expanded: #include "protos/perfetto/config/process_stats/process_stats_config.gen.h"
22276 // gen_amalgamated expanded: #include "protos/perfetto/config/power/android_power_config.gen.h"
22277 // gen_amalgamated expanded: #include "protos/perfetto/config/interceptor_config.gen.h"
22278 // gen_amalgamated expanded: #include "protos/perfetto/config/interceptors/console_config.gen.h"
22279 // gen_amalgamated expanded: #include "protos/perfetto/config/inode_file/inode_file_config.gen.h"
22280 // gen_amalgamated expanded: #include "protos/perfetto/config/gpu/vulkan_memory_config.gen.h"
22281 // gen_amalgamated expanded: #include "protos/perfetto/config/gpu/gpu_counter_config.gen.h"
22282 // gen_amalgamated expanded: #include "protos/perfetto/config/ftrace/ftrace_config.gen.h"
22283 // gen_amalgamated expanded: #include "protos/perfetto/config/chrome/chrome_config.gen.h"
22284 // gen_amalgamated expanded: #include "protos/perfetto/config/android/packages_list_config.gen.h"
22285 // gen_amalgamated expanded: #include "protos/perfetto/config/android/android_polled_state_config.gen.h"
22286 // gen_amalgamated expanded: #include "protos/perfetto/config/android/android_log_config.gen.h"
22287 // gen_amalgamated expanded: #include "protos/perfetto/common/android_log_constants.gen.h"
22288 // gen_amalgamated expanded: #include "protos/perfetto/common/builtin_clock.gen.h"
22289 
22290 namespace perfetto {
22291 namespace protos {
22292 namespace gen {
22293 
22294 StressTestConfig::StressTestConfig() = default;
22295 StressTestConfig::~StressTestConfig() = default;
22296 StressTestConfig::StressTestConfig(const StressTestConfig&) = default;
22297 StressTestConfig& StressTestConfig::operator=(const StressTestConfig&) = default;
22298 StressTestConfig::StressTestConfig(StressTestConfig&&) noexcept = default;
22299 StressTestConfig& StressTestConfig::operator=(StressTestConfig&&) = default;
22300 
operator ==(const StressTestConfig & other) const22301 bool StressTestConfig::operator==(const StressTestConfig& other) const {
22302   return unknown_fields_ == other.unknown_fields_
22303    && trace_config_ == other.trace_config_
22304    && shmem_size_kb_ == other.shmem_size_kb_
22305    && shmem_page_size_kb_ == other.shmem_page_size_kb_
22306    && num_processes_ == other.num_processes_
22307    && num_threads_ == other.num_threads_
22308    && max_events_ == other.max_events_
22309    && nesting_ == other.nesting_
22310    && steady_state_timings_ == other.steady_state_timings_
22311    && burst_period_ms_ == other.burst_period_ms_
22312    && burst_duration_ms_ == other.burst_duration_ms_
22313    && burst_timings_ == other.burst_timings_;
22314 }
22315 
ParseFromArray(const void * raw,size_t size)22316 bool StressTestConfig::ParseFromArray(const void* raw, size_t size) {
22317   unknown_fields_.clear();
22318   bool packed_error = false;
22319 
22320   ::protozero::ProtoDecoder dec(raw, size);
22321   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
22322     if (field.id() < _has_field_.size()) {
22323       _has_field_.set(field.id());
22324     }
22325     switch (field.id()) {
22326       case 1 /* trace_config */:
22327         (*trace_config_).ParseFromArray(field.data(), field.size());
22328         break;
22329       case 2 /* shmem_size_kb */:
22330         field.get(&shmem_size_kb_);
22331         break;
22332       case 3 /* shmem_page_size_kb */:
22333         field.get(&shmem_page_size_kb_);
22334         break;
22335       case 4 /* num_processes */:
22336         field.get(&num_processes_);
22337         break;
22338       case 5 /* num_threads */:
22339         field.get(&num_threads_);
22340         break;
22341       case 6 /* max_events */:
22342         field.get(&max_events_);
22343         break;
22344       case 7 /* nesting */:
22345         field.get(&nesting_);
22346         break;
22347       case 8 /* steady_state_timings */:
22348         (*steady_state_timings_).ParseFromArray(field.data(), field.size());
22349         break;
22350       case 9 /* burst_period_ms */:
22351         field.get(&burst_period_ms_);
22352         break;
22353       case 10 /* burst_duration_ms */:
22354         field.get(&burst_duration_ms_);
22355         break;
22356       case 11 /* burst_timings */:
22357         (*burst_timings_).ParseFromArray(field.data(), field.size());
22358         break;
22359       default:
22360         field.SerializeAndAppendTo(&unknown_fields_);
22361         break;
22362     }
22363   }
22364   return !packed_error && !dec.bytes_left();
22365 }
22366 
SerializeAsString() const22367 std::string StressTestConfig::SerializeAsString() const {
22368   ::protozero::HeapBuffered<::protozero::Message> msg;
22369   Serialize(msg.get());
22370   return msg.SerializeAsString();
22371 }
22372 
SerializeAsArray() const22373 std::vector<uint8_t> StressTestConfig::SerializeAsArray() const {
22374   ::protozero::HeapBuffered<::protozero::Message> msg;
22375   Serialize(msg.get());
22376   return msg.SerializeAsArray();
22377 }
22378 
Serialize(::protozero::Message * msg) const22379 void StressTestConfig::Serialize(::protozero::Message* msg) const {
22380   // Field 1: trace_config
22381   if (_has_field_[1]) {
22382     (*trace_config_).Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
22383   }
22384 
22385   // Field 2: shmem_size_kb
22386   if (_has_field_[2]) {
22387     msg->AppendVarInt(2, shmem_size_kb_);
22388   }
22389 
22390   // Field 3: shmem_page_size_kb
22391   if (_has_field_[3]) {
22392     msg->AppendVarInt(3, shmem_page_size_kb_);
22393   }
22394 
22395   // Field 4: num_processes
22396   if (_has_field_[4]) {
22397     msg->AppendVarInt(4, num_processes_);
22398   }
22399 
22400   // Field 5: num_threads
22401   if (_has_field_[5]) {
22402     msg->AppendVarInt(5, num_threads_);
22403   }
22404 
22405   // Field 6: max_events
22406   if (_has_field_[6]) {
22407     msg->AppendVarInt(6, max_events_);
22408   }
22409 
22410   // Field 7: nesting
22411   if (_has_field_[7]) {
22412     msg->AppendVarInt(7, nesting_);
22413   }
22414 
22415   // Field 8: steady_state_timings
22416   if (_has_field_[8]) {
22417     (*steady_state_timings_).Serialize(msg->BeginNestedMessage<::protozero::Message>(8));
22418   }
22419 
22420   // Field 9: burst_period_ms
22421   if (_has_field_[9]) {
22422     msg->AppendVarInt(9, burst_period_ms_);
22423   }
22424 
22425   // Field 10: burst_duration_ms
22426   if (_has_field_[10]) {
22427     msg->AppendVarInt(10, burst_duration_ms_);
22428   }
22429 
22430   // Field 11: burst_timings
22431   if (_has_field_[11]) {
22432     (*burst_timings_).Serialize(msg->BeginNestedMessage<::protozero::Message>(11));
22433   }
22434 
22435   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
22436 }
22437 
22438 
22439 StressTestConfig_WriterTiming::StressTestConfig_WriterTiming() = default;
22440 StressTestConfig_WriterTiming::~StressTestConfig_WriterTiming() = default;
22441 StressTestConfig_WriterTiming::StressTestConfig_WriterTiming(const StressTestConfig_WriterTiming&) = default;
22442 StressTestConfig_WriterTiming& StressTestConfig_WriterTiming::operator=(const StressTestConfig_WriterTiming&) = default;
22443 StressTestConfig_WriterTiming::StressTestConfig_WriterTiming(StressTestConfig_WriterTiming&&) noexcept = default;
22444 StressTestConfig_WriterTiming& StressTestConfig_WriterTiming::operator=(StressTestConfig_WriterTiming&&) = default;
22445 
operator ==(const StressTestConfig_WriterTiming & other) const22446 bool StressTestConfig_WriterTiming::operator==(const StressTestConfig_WriterTiming& other) const {
22447   return unknown_fields_ == other.unknown_fields_
22448    && payload_mean_ == other.payload_mean_
22449    && payload_stddev_ == other.payload_stddev_
22450    && rate_mean_ == other.rate_mean_
22451    && rate_stddev_ == other.rate_stddev_
22452    && payload_write_time_ms_ == other.payload_write_time_ms_;
22453 }
22454 
ParseFromArray(const void * raw,size_t size)22455 bool StressTestConfig_WriterTiming::ParseFromArray(const void* raw, size_t size) {
22456   unknown_fields_.clear();
22457   bool packed_error = false;
22458 
22459   ::protozero::ProtoDecoder dec(raw, size);
22460   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
22461     if (field.id() < _has_field_.size()) {
22462       _has_field_.set(field.id());
22463     }
22464     switch (field.id()) {
22465       case 1 /* payload_mean */:
22466         field.get(&payload_mean_);
22467         break;
22468       case 2 /* payload_stddev */:
22469         field.get(&payload_stddev_);
22470         break;
22471       case 3 /* rate_mean */:
22472         field.get(&rate_mean_);
22473         break;
22474       case 4 /* rate_stddev */:
22475         field.get(&rate_stddev_);
22476         break;
22477       case 5 /* payload_write_time_ms */:
22478         field.get(&payload_write_time_ms_);
22479         break;
22480       default:
22481         field.SerializeAndAppendTo(&unknown_fields_);
22482         break;
22483     }
22484   }
22485   return !packed_error && !dec.bytes_left();
22486 }
22487 
SerializeAsString() const22488 std::string StressTestConfig_WriterTiming::SerializeAsString() const {
22489   ::protozero::HeapBuffered<::protozero::Message> msg;
22490   Serialize(msg.get());
22491   return msg.SerializeAsString();
22492 }
22493 
SerializeAsArray() const22494 std::vector<uint8_t> StressTestConfig_WriterTiming::SerializeAsArray() const {
22495   ::protozero::HeapBuffered<::protozero::Message> msg;
22496   Serialize(msg.get());
22497   return msg.SerializeAsArray();
22498 }
22499 
Serialize(::protozero::Message * msg) const22500 void StressTestConfig_WriterTiming::Serialize(::protozero::Message* msg) const {
22501   // Field 1: payload_mean
22502   if (_has_field_[1]) {
22503     msg->AppendFixed(1, payload_mean_);
22504   }
22505 
22506   // Field 2: payload_stddev
22507   if (_has_field_[2]) {
22508     msg->AppendFixed(2, payload_stddev_);
22509   }
22510 
22511   // Field 3: rate_mean
22512   if (_has_field_[3]) {
22513     msg->AppendFixed(3, rate_mean_);
22514   }
22515 
22516   // Field 4: rate_stddev
22517   if (_has_field_[4]) {
22518     msg->AppendFixed(4, rate_stddev_);
22519   }
22520 
22521   // Field 5: payload_write_time_ms
22522   if (_has_field_[5]) {
22523     msg->AppendVarInt(5, payload_write_time_ms_);
22524   }
22525 
22526   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
22527 }
22528 
22529 }  // namespace perfetto
22530 }  // namespace protos
22531 }  // namespace gen
22532 #if defined(__GNUC__) || defined(__clang__)
22533 #pragma GCC diagnostic pop
22534 #endif
22535 // gen_amalgamated begin source: gen/protos/perfetto/config/test_config.gen.cc
22536 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
22537 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
22538 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
22539 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
22540 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
22541 #if defined(__GNUC__) || defined(__clang__)
22542 #pragma GCC diagnostic push
22543 #pragma GCC diagnostic ignored "-Wfloat-equal"
22544 #endif
22545 // gen_amalgamated expanded: #include "protos/perfetto/config/test_config.gen.h"
22546 
22547 namespace perfetto {
22548 namespace protos {
22549 namespace gen {
22550 
22551 TestConfig::TestConfig() = default;
22552 TestConfig::~TestConfig() = default;
22553 TestConfig::TestConfig(const TestConfig&) = default;
22554 TestConfig& TestConfig::operator=(const TestConfig&) = default;
22555 TestConfig::TestConfig(TestConfig&&) noexcept = default;
22556 TestConfig& TestConfig::operator=(TestConfig&&) = default;
22557 
operator ==(const TestConfig & other) const22558 bool TestConfig::operator==(const TestConfig& other) const {
22559   return unknown_fields_ == other.unknown_fields_
22560    && message_count_ == other.message_count_
22561    && max_messages_per_second_ == other.max_messages_per_second_
22562    && seed_ == other.seed_
22563    && message_size_ == other.message_size_
22564    && send_batch_on_register_ == other.send_batch_on_register_
22565    && dummy_fields_ == other.dummy_fields_;
22566 }
22567 
ParseFromArray(const void * raw,size_t size)22568 bool TestConfig::ParseFromArray(const void* raw, size_t size) {
22569   unknown_fields_.clear();
22570   bool packed_error = false;
22571 
22572   ::protozero::ProtoDecoder dec(raw, size);
22573   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
22574     if (field.id() < _has_field_.size()) {
22575       _has_field_.set(field.id());
22576     }
22577     switch (field.id()) {
22578       case 1 /* message_count */:
22579         field.get(&message_count_);
22580         break;
22581       case 2 /* max_messages_per_second */:
22582         field.get(&max_messages_per_second_);
22583         break;
22584       case 3 /* seed */:
22585         field.get(&seed_);
22586         break;
22587       case 4 /* message_size */:
22588         field.get(&message_size_);
22589         break;
22590       case 5 /* send_batch_on_register */:
22591         field.get(&send_batch_on_register_);
22592         break;
22593       case 6 /* dummy_fields */:
22594         (*dummy_fields_).ParseFromArray(field.data(), field.size());
22595         break;
22596       default:
22597         field.SerializeAndAppendTo(&unknown_fields_);
22598         break;
22599     }
22600   }
22601   return !packed_error && !dec.bytes_left();
22602 }
22603 
SerializeAsString() const22604 std::string TestConfig::SerializeAsString() const {
22605   ::protozero::HeapBuffered<::protozero::Message> msg;
22606   Serialize(msg.get());
22607   return msg.SerializeAsString();
22608 }
22609 
SerializeAsArray() const22610 std::vector<uint8_t> TestConfig::SerializeAsArray() const {
22611   ::protozero::HeapBuffered<::protozero::Message> msg;
22612   Serialize(msg.get());
22613   return msg.SerializeAsArray();
22614 }
22615 
Serialize(::protozero::Message * msg) const22616 void TestConfig::Serialize(::protozero::Message* msg) const {
22617   // Field 1: message_count
22618   if (_has_field_[1]) {
22619     msg->AppendVarInt(1, message_count_);
22620   }
22621 
22622   // Field 2: max_messages_per_second
22623   if (_has_field_[2]) {
22624     msg->AppendVarInt(2, max_messages_per_second_);
22625   }
22626 
22627   // Field 3: seed
22628   if (_has_field_[3]) {
22629     msg->AppendVarInt(3, seed_);
22630   }
22631 
22632   // Field 4: message_size
22633   if (_has_field_[4]) {
22634     msg->AppendVarInt(4, message_size_);
22635   }
22636 
22637   // Field 5: send_batch_on_register
22638   if (_has_field_[5]) {
22639     msg->AppendTinyVarInt(5, send_batch_on_register_);
22640   }
22641 
22642   // Field 6: dummy_fields
22643   if (_has_field_[6]) {
22644     (*dummy_fields_).Serialize(msg->BeginNestedMessage<::protozero::Message>(6));
22645   }
22646 
22647   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
22648 }
22649 
22650 
22651 TestConfig_DummyFields::TestConfig_DummyFields() = default;
22652 TestConfig_DummyFields::~TestConfig_DummyFields() = default;
22653 TestConfig_DummyFields::TestConfig_DummyFields(const TestConfig_DummyFields&) = default;
22654 TestConfig_DummyFields& TestConfig_DummyFields::operator=(const TestConfig_DummyFields&) = default;
22655 TestConfig_DummyFields::TestConfig_DummyFields(TestConfig_DummyFields&&) noexcept = default;
22656 TestConfig_DummyFields& TestConfig_DummyFields::operator=(TestConfig_DummyFields&&) = default;
22657 
operator ==(const TestConfig_DummyFields & other) const22658 bool TestConfig_DummyFields::operator==(const TestConfig_DummyFields& other) const {
22659   return unknown_fields_ == other.unknown_fields_
22660    && field_uint32_ == other.field_uint32_
22661    && field_int32_ == other.field_int32_
22662    && field_uint64_ == other.field_uint64_
22663    && field_int64_ == other.field_int64_
22664    && field_fixed64_ == other.field_fixed64_
22665    && field_sfixed64_ == other.field_sfixed64_
22666    && field_fixed32_ == other.field_fixed32_
22667    && field_sfixed32_ == other.field_sfixed32_
22668    && field_double_ == other.field_double_
22669    && field_float_ == other.field_float_
22670    && field_sint64_ == other.field_sint64_
22671    && field_sint32_ == other.field_sint32_
22672    && field_string_ == other.field_string_
22673    && field_bytes_ == other.field_bytes_;
22674 }
22675 
ParseFromArray(const void * raw,size_t size)22676 bool TestConfig_DummyFields::ParseFromArray(const void* raw, size_t size) {
22677   unknown_fields_.clear();
22678   bool packed_error = false;
22679 
22680   ::protozero::ProtoDecoder dec(raw, size);
22681   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
22682     if (field.id() < _has_field_.size()) {
22683       _has_field_.set(field.id());
22684     }
22685     switch (field.id()) {
22686       case 1 /* field_uint32 */:
22687         field.get(&field_uint32_);
22688         break;
22689       case 2 /* field_int32 */:
22690         field.get(&field_int32_);
22691         break;
22692       case 3 /* field_uint64 */:
22693         field.get(&field_uint64_);
22694         break;
22695       case 4 /* field_int64 */:
22696         field.get(&field_int64_);
22697         break;
22698       case 5 /* field_fixed64 */:
22699         field.get(&field_fixed64_);
22700         break;
22701       case 6 /* field_sfixed64 */:
22702         field.get(&field_sfixed64_);
22703         break;
22704       case 7 /* field_fixed32 */:
22705         field.get(&field_fixed32_);
22706         break;
22707       case 8 /* field_sfixed32 */:
22708         field.get(&field_sfixed32_);
22709         break;
22710       case 9 /* field_double */:
22711         field.get(&field_double_);
22712         break;
22713       case 10 /* field_float */:
22714         field.get(&field_float_);
22715         break;
22716       case 11 /* field_sint64 */:
22717         field.get_signed(&field_sint64_);
22718         break;
22719       case 12 /* field_sint32 */:
22720         field.get_signed(&field_sint32_);
22721         break;
22722       case 13 /* field_string */:
22723         field.get(&field_string_);
22724         break;
22725       case 14 /* field_bytes */:
22726         field.get(&field_bytes_);
22727         break;
22728       default:
22729         field.SerializeAndAppendTo(&unknown_fields_);
22730         break;
22731     }
22732   }
22733   return !packed_error && !dec.bytes_left();
22734 }
22735 
SerializeAsString() const22736 std::string TestConfig_DummyFields::SerializeAsString() const {
22737   ::protozero::HeapBuffered<::protozero::Message> msg;
22738   Serialize(msg.get());
22739   return msg.SerializeAsString();
22740 }
22741 
SerializeAsArray() const22742 std::vector<uint8_t> TestConfig_DummyFields::SerializeAsArray() const {
22743   ::protozero::HeapBuffered<::protozero::Message> msg;
22744   Serialize(msg.get());
22745   return msg.SerializeAsArray();
22746 }
22747 
Serialize(::protozero::Message * msg) const22748 void TestConfig_DummyFields::Serialize(::protozero::Message* msg) const {
22749   // Field 1: field_uint32
22750   if (_has_field_[1]) {
22751     msg->AppendVarInt(1, field_uint32_);
22752   }
22753 
22754   // Field 2: field_int32
22755   if (_has_field_[2]) {
22756     msg->AppendVarInt(2, field_int32_);
22757   }
22758 
22759   // Field 3: field_uint64
22760   if (_has_field_[3]) {
22761     msg->AppendVarInt(3, field_uint64_);
22762   }
22763 
22764   // Field 4: field_int64
22765   if (_has_field_[4]) {
22766     msg->AppendVarInt(4, field_int64_);
22767   }
22768 
22769   // Field 5: field_fixed64
22770   if (_has_field_[5]) {
22771     msg->AppendFixed(5, field_fixed64_);
22772   }
22773 
22774   // Field 6: field_sfixed64
22775   if (_has_field_[6]) {
22776     msg->AppendFixed(6, field_sfixed64_);
22777   }
22778 
22779   // Field 7: field_fixed32
22780   if (_has_field_[7]) {
22781     msg->AppendFixed(7, field_fixed32_);
22782   }
22783 
22784   // Field 8: field_sfixed32
22785   if (_has_field_[8]) {
22786     msg->AppendFixed(8, field_sfixed32_);
22787   }
22788 
22789   // Field 9: field_double
22790   if (_has_field_[9]) {
22791     msg->AppendFixed(9, field_double_);
22792   }
22793 
22794   // Field 10: field_float
22795   if (_has_field_[10]) {
22796     msg->AppendFixed(10, field_float_);
22797   }
22798 
22799   // Field 11: field_sint64
22800   if (_has_field_[11]) {
22801     msg->AppendSignedVarInt(11, field_sint64_);
22802   }
22803 
22804   // Field 12: field_sint32
22805   if (_has_field_[12]) {
22806     msg->AppendSignedVarInt(12, field_sint32_);
22807   }
22808 
22809   // Field 13: field_string
22810   if (_has_field_[13]) {
22811     msg->AppendString(13, field_string_);
22812   }
22813 
22814   // Field 14: field_bytes
22815   if (_has_field_[14]) {
22816     msg->AppendString(14, field_bytes_);
22817   }
22818 
22819   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
22820 }
22821 
22822 }  // namespace perfetto
22823 }  // namespace protos
22824 }  // namespace gen
22825 #if defined(__GNUC__) || defined(__clang__)
22826 #pragma GCC diagnostic pop
22827 #endif
22828 // gen_amalgamated begin source: gen/protos/perfetto/config/trace_config.gen.cc
22829 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
22830 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
22831 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
22832 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
22833 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
22834 #if defined(__GNUC__) || defined(__clang__)
22835 #pragma GCC diagnostic push
22836 #pragma GCC diagnostic ignored "-Wfloat-equal"
22837 #endif
22838 // gen_amalgamated expanded: #include "protos/perfetto/config/trace_config.gen.h"
22839 // gen_amalgamated expanded: #include "protos/perfetto/config/data_source_config.gen.h"
22840 // gen_amalgamated expanded: #include "protos/perfetto/config/track_event/track_event_config.gen.h"
22841 // gen_amalgamated expanded: #include "protos/perfetto/config/test_config.gen.h"
22842 // gen_amalgamated expanded: #include "protos/perfetto/config/sys_stats/sys_stats_config.gen.h"
22843 // gen_amalgamated expanded: #include "protos/perfetto/common/sys_stats_counters.gen.h"
22844 // gen_amalgamated expanded: #include "protos/perfetto/config/profiling/perf_event_config.gen.h"
22845 // gen_amalgamated expanded: #include "protos/perfetto/common/perf_events.gen.h"
22846 // gen_amalgamated expanded: #include "protos/perfetto/config/profiling/java_hprof_config.gen.h"
22847 // gen_amalgamated expanded: #include "protos/perfetto/config/profiling/heapprofd_config.gen.h"
22848 // gen_amalgamated expanded: #include "protos/perfetto/config/process_stats/process_stats_config.gen.h"
22849 // gen_amalgamated expanded: #include "protos/perfetto/config/power/android_power_config.gen.h"
22850 // gen_amalgamated expanded: #include "protos/perfetto/config/interceptor_config.gen.h"
22851 // gen_amalgamated expanded: #include "protos/perfetto/config/interceptors/console_config.gen.h"
22852 // gen_amalgamated expanded: #include "protos/perfetto/config/inode_file/inode_file_config.gen.h"
22853 // gen_amalgamated expanded: #include "protos/perfetto/config/gpu/vulkan_memory_config.gen.h"
22854 // gen_amalgamated expanded: #include "protos/perfetto/config/gpu/gpu_counter_config.gen.h"
22855 // gen_amalgamated expanded: #include "protos/perfetto/config/ftrace/ftrace_config.gen.h"
22856 // gen_amalgamated expanded: #include "protos/perfetto/config/chrome/chrome_config.gen.h"
22857 // gen_amalgamated expanded: #include "protos/perfetto/config/android/packages_list_config.gen.h"
22858 // gen_amalgamated expanded: #include "protos/perfetto/config/android/android_polled_state_config.gen.h"
22859 // gen_amalgamated expanded: #include "protos/perfetto/config/android/android_log_config.gen.h"
22860 // gen_amalgamated expanded: #include "protos/perfetto/common/android_log_constants.gen.h"
22861 // gen_amalgamated expanded: #include "protos/perfetto/common/builtin_clock.gen.h"
22862 
22863 namespace perfetto {
22864 namespace protos {
22865 namespace gen {
22866 
22867 TraceConfig::TraceConfig() = default;
22868 TraceConfig::~TraceConfig() = default;
22869 TraceConfig::TraceConfig(const TraceConfig&) = default;
22870 TraceConfig& TraceConfig::operator=(const TraceConfig&) = default;
22871 TraceConfig::TraceConfig(TraceConfig&&) noexcept = default;
22872 TraceConfig& TraceConfig::operator=(TraceConfig&&) = default;
22873 
operator ==(const TraceConfig & other) const22874 bool TraceConfig::operator==(const TraceConfig& other) const {
22875   return unknown_fields_ == other.unknown_fields_
22876    && buffers_ == other.buffers_
22877    && data_sources_ == other.data_sources_
22878    && builtin_data_sources_ == other.builtin_data_sources_
22879    && duration_ms_ == other.duration_ms_
22880    && enable_extra_guardrails_ == other.enable_extra_guardrails_
22881    && lockdown_mode_ == other.lockdown_mode_
22882    && producers_ == other.producers_
22883    && statsd_metadata_ == other.statsd_metadata_
22884    && write_into_file_ == other.write_into_file_
22885    && output_path_ == other.output_path_
22886    && file_write_period_ms_ == other.file_write_period_ms_
22887    && max_file_size_bytes_ == other.max_file_size_bytes_
22888    && guardrail_overrides_ == other.guardrail_overrides_
22889    && deferred_start_ == other.deferred_start_
22890    && flush_period_ms_ == other.flush_period_ms_
22891    && flush_timeout_ms_ == other.flush_timeout_ms_
22892    && data_source_stop_timeout_ms_ == other.data_source_stop_timeout_ms_
22893    && notify_traceur_ == other.notify_traceur_
22894    && bugreport_score_ == other.bugreport_score_
22895    && trigger_config_ == other.trigger_config_
22896    && activate_triggers_ == other.activate_triggers_
22897    && incremental_state_config_ == other.incremental_state_config_
22898    && allow_user_build_tracing_ == other.allow_user_build_tracing_
22899    && unique_session_name_ == other.unique_session_name_
22900    && compression_type_ == other.compression_type_
22901    && incident_report_config_ == other.incident_report_config_
22902    && statsd_logging_ == other.statsd_logging_
22903    && trace_uuid_msb_ == other.trace_uuid_msb_
22904    && trace_uuid_lsb_ == other.trace_uuid_lsb_
22905    && trace_filter_ == other.trace_filter_;
22906 }
22907 
buffers_size() const22908 int TraceConfig::buffers_size() const { return static_cast<int>(buffers_.size()); }
clear_buffers()22909 void TraceConfig::clear_buffers() { buffers_.clear(); }
add_buffers()22910 TraceConfig_BufferConfig* TraceConfig::add_buffers() { buffers_.emplace_back(); return &buffers_.back(); }
data_sources_size() const22911 int TraceConfig::data_sources_size() const { return static_cast<int>(data_sources_.size()); }
clear_data_sources()22912 void TraceConfig::clear_data_sources() { data_sources_.clear(); }
add_data_sources()22913 TraceConfig_DataSource* TraceConfig::add_data_sources() { data_sources_.emplace_back(); return &data_sources_.back(); }
producers_size() const22914 int TraceConfig::producers_size() const { return static_cast<int>(producers_.size()); }
clear_producers()22915 void TraceConfig::clear_producers() { producers_.clear(); }
add_producers()22916 TraceConfig_ProducerConfig* TraceConfig::add_producers() { producers_.emplace_back(); return &producers_.back(); }
ParseFromArray(const void * raw,size_t size)22917 bool TraceConfig::ParseFromArray(const void* raw, size_t size) {
22918   buffers_.clear();
22919   data_sources_.clear();
22920   producers_.clear();
22921   activate_triggers_.clear();
22922   unknown_fields_.clear();
22923   bool packed_error = false;
22924 
22925   ::protozero::ProtoDecoder dec(raw, size);
22926   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
22927     if (field.id() < _has_field_.size()) {
22928       _has_field_.set(field.id());
22929     }
22930     switch (field.id()) {
22931       case 1 /* buffers */:
22932         buffers_.emplace_back();
22933         buffers_.back().ParseFromArray(field.data(), field.size());
22934         break;
22935       case 2 /* data_sources */:
22936         data_sources_.emplace_back();
22937         data_sources_.back().ParseFromArray(field.data(), field.size());
22938         break;
22939       case 20 /* builtin_data_sources */:
22940         (*builtin_data_sources_).ParseFromArray(field.data(), field.size());
22941         break;
22942       case 3 /* duration_ms */:
22943         field.get(&duration_ms_);
22944         break;
22945       case 4 /* enable_extra_guardrails */:
22946         field.get(&enable_extra_guardrails_);
22947         break;
22948       case 5 /* lockdown_mode */:
22949         field.get(&lockdown_mode_);
22950         break;
22951       case 6 /* producers */:
22952         producers_.emplace_back();
22953         producers_.back().ParseFromArray(field.data(), field.size());
22954         break;
22955       case 7 /* statsd_metadata */:
22956         (*statsd_metadata_).ParseFromArray(field.data(), field.size());
22957         break;
22958       case 8 /* write_into_file */:
22959         field.get(&write_into_file_);
22960         break;
22961       case 29 /* output_path */:
22962         field.get(&output_path_);
22963         break;
22964       case 9 /* file_write_period_ms */:
22965         field.get(&file_write_period_ms_);
22966         break;
22967       case 10 /* max_file_size_bytes */:
22968         field.get(&max_file_size_bytes_);
22969         break;
22970       case 11 /* guardrail_overrides */:
22971         (*guardrail_overrides_).ParseFromArray(field.data(), field.size());
22972         break;
22973       case 12 /* deferred_start */:
22974         field.get(&deferred_start_);
22975         break;
22976       case 13 /* flush_period_ms */:
22977         field.get(&flush_period_ms_);
22978         break;
22979       case 14 /* flush_timeout_ms */:
22980         field.get(&flush_timeout_ms_);
22981         break;
22982       case 23 /* data_source_stop_timeout_ms */:
22983         field.get(&data_source_stop_timeout_ms_);
22984         break;
22985       case 16 /* notify_traceur */:
22986         field.get(&notify_traceur_);
22987         break;
22988       case 30 /* bugreport_score */:
22989         field.get(&bugreport_score_);
22990         break;
22991       case 17 /* trigger_config */:
22992         (*trigger_config_).ParseFromArray(field.data(), field.size());
22993         break;
22994       case 18 /* activate_triggers */:
22995         activate_triggers_.emplace_back();
22996         field.get(&activate_triggers_.back());
22997         break;
22998       case 21 /* incremental_state_config */:
22999         (*incremental_state_config_).ParseFromArray(field.data(), field.size());
23000         break;
23001       case 19 /* allow_user_build_tracing */:
23002         field.get(&allow_user_build_tracing_);
23003         break;
23004       case 22 /* unique_session_name */:
23005         field.get(&unique_session_name_);
23006         break;
23007       case 24 /* compression_type */:
23008         field.get(&compression_type_);
23009         break;
23010       case 25 /* incident_report_config */:
23011         (*incident_report_config_).ParseFromArray(field.data(), field.size());
23012         break;
23013       case 31 /* statsd_logging */:
23014         field.get(&statsd_logging_);
23015         break;
23016       case 27 /* trace_uuid_msb */:
23017         field.get(&trace_uuid_msb_);
23018         break;
23019       case 28 /* trace_uuid_lsb */:
23020         field.get(&trace_uuid_lsb_);
23021         break;
23022       case 33 /* trace_filter */:
23023         (*trace_filter_).ParseFromArray(field.data(), field.size());
23024         break;
23025       default:
23026         field.SerializeAndAppendTo(&unknown_fields_);
23027         break;
23028     }
23029   }
23030   return !packed_error && !dec.bytes_left();
23031 }
23032 
SerializeAsString() const23033 std::string TraceConfig::SerializeAsString() const {
23034   ::protozero::HeapBuffered<::protozero::Message> msg;
23035   Serialize(msg.get());
23036   return msg.SerializeAsString();
23037 }
23038 
SerializeAsArray() const23039 std::vector<uint8_t> TraceConfig::SerializeAsArray() const {
23040   ::protozero::HeapBuffered<::protozero::Message> msg;
23041   Serialize(msg.get());
23042   return msg.SerializeAsArray();
23043 }
23044 
Serialize(::protozero::Message * msg) const23045 void TraceConfig::Serialize(::protozero::Message* msg) const {
23046   // Field 1: buffers
23047   for (auto& it : buffers_) {
23048     it.Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
23049   }
23050 
23051   // Field 2: data_sources
23052   for (auto& it : data_sources_) {
23053     it.Serialize(msg->BeginNestedMessage<::protozero::Message>(2));
23054   }
23055 
23056   // Field 20: builtin_data_sources
23057   if (_has_field_[20]) {
23058     (*builtin_data_sources_).Serialize(msg->BeginNestedMessage<::protozero::Message>(20));
23059   }
23060 
23061   // Field 3: duration_ms
23062   if (_has_field_[3]) {
23063     msg->AppendVarInt(3, duration_ms_);
23064   }
23065 
23066   // Field 4: enable_extra_guardrails
23067   if (_has_field_[4]) {
23068     msg->AppendTinyVarInt(4, enable_extra_guardrails_);
23069   }
23070 
23071   // Field 5: lockdown_mode
23072   if (_has_field_[5]) {
23073     msg->AppendVarInt(5, lockdown_mode_);
23074   }
23075 
23076   // Field 6: producers
23077   for (auto& it : producers_) {
23078     it.Serialize(msg->BeginNestedMessage<::protozero::Message>(6));
23079   }
23080 
23081   // Field 7: statsd_metadata
23082   if (_has_field_[7]) {
23083     (*statsd_metadata_).Serialize(msg->BeginNestedMessage<::protozero::Message>(7));
23084   }
23085 
23086   // Field 8: write_into_file
23087   if (_has_field_[8]) {
23088     msg->AppendTinyVarInt(8, write_into_file_);
23089   }
23090 
23091   // Field 29: output_path
23092   if (_has_field_[29]) {
23093     msg->AppendString(29, output_path_);
23094   }
23095 
23096   // Field 9: file_write_period_ms
23097   if (_has_field_[9]) {
23098     msg->AppendVarInt(9, file_write_period_ms_);
23099   }
23100 
23101   // Field 10: max_file_size_bytes
23102   if (_has_field_[10]) {
23103     msg->AppendVarInt(10, max_file_size_bytes_);
23104   }
23105 
23106   // Field 11: guardrail_overrides
23107   if (_has_field_[11]) {
23108     (*guardrail_overrides_).Serialize(msg->BeginNestedMessage<::protozero::Message>(11));
23109   }
23110 
23111   // Field 12: deferred_start
23112   if (_has_field_[12]) {
23113     msg->AppendTinyVarInt(12, deferred_start_);
23114   }
23115 
23116   // Field 13: flush_period_ms
23117   if (_has_field_[13]) {
23118     msg->AppendVarInt(13, flush_period_ms_);
23119   }
23120 
23121   // Field 14: flush_timeout_ms
23122   if (_has_field_[14]) {
23123     msg->AppendVarInt(14, flush_timeout_ms_);
23124   }
23125 
23126   // Field 23: data_source_stop_timeout_ms
23127   if (_has_field_[23]) {
23128     msg->AppendVarInt(23, data_source_stop_timeout_ms_);
23129   }
23130 
23131   // Field 16: notify_traceur
23132   if (_has_field_[16]) {
23133     msg->AppendTinyVarInt(16, notify_traceur_);
23134   }
23135 
23136   // Field 30: bugreport_score
23137   if (_has_field_[30]) {
23138     msg->AppendVarInt(30, bugreport_score_);
23139   }
23140 
23141   // Field 17: trigger_config
23142   if (_has_field_[17]) {
23143     (*trigger_config_).Serialize(msg->BeginNestedMessage<::protozero::Message>(17));
23144   }
23145 
23146   // Field 18: activate_triggers
23147   for (auto& it : activate_triggers_) {
23148     msg->AppendString(18, it);
23149   }
23150 
23151   // Field 21: incremental_state_config
23152   if (_has_field_[21]) {
23153     (*incremental_state_config_).Serialize(msg->BeginNestedMessage<::protozero::Message>(21));
23154   }
23155 
23156   // Field 19: allow_user_build_tracing
23157   if (_has_field_[19]) {
23158     msg->AppendTinyVarInt(19, allow_user_build_tracing_);
23159   }
23160 
23161   // Field 22: unique_session_name
23162   if (_has_field_[22]) {
23163     msg->AppendString(22, unique_session_name_);
23164   }
23165 
23166   // Field 24: compression_type
23167   if (_has_field_[24]) {
23168     msg->AppendVarInt(24, compression_type_);
23169   }
23170 
23171   // Field 25: incident_report_config
23172   if (_has_field_[25]) {
23173     (*incident_report_config_).Serialize(msg->BeginNestedMessage<::protozero::Message>(25));
23174   }
23175 
23176   // Field 31: statsd_logging
23177   if (_has_field_[31]) {
23178     msg->AppendVarInt(31, statsd_logging_);
23179   }
23180 
23181   // Field 27: trace_uuid_msb
23182   if (_has_field_[27]) {
23183     msg->AppendVarInt(27, trace_uuid_msb_);
23184   }
23185 
23186   // Field 28: trace_uuid_lsb
23187   if (_has_field_[28]) {
23188     msg->AppendVarInt(28, trace_uuid_lsb_);
23189   }
23190 
23191   // Field 33: trace_filter
23192   if (_has_field_[33]) {
23193     (*trace_filter_).Serialize(msg->BeginNestedMessage<::protozero::Message>(33));
23194   }
23195 
23196   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
23197 }
23198 
23199 
23200 TraceConfig_TraceFilter::TraceConfig_TraceFilter() = default;
23201 TraceConfig_TraceFilter::~TraceConfig_TraceFilter() = default;
23202 TraceConfig_TraceFilter::TraceConfig_TraceFilter(const TraceConfig_TraceFilter&) = default;
23203 TraceConfig_TraceFilter& TraceConfig_TraceFilter::operator=(const TraceConfig_TraceFilter&) = default;
23204 TraceConfig_TraceFilter::TraceConfig_TraceFilter(TraceConfig_TraceFilter&&) noexcept = default;
23205 TraceConfig_TraceFilter& TraceConfig_TraceFilter::operator=(TraceConfig_TraceFilter&&) = default;
23206 
operator ==(const TraceConfig_TraceFilter & other) const23207 bool TraceConfig_TraceFilter::operator==(const TraceConfig_TraceFilter& other) const {
23208   return unknown_fields_ == other.unknown_fields_
23209    && bytecode_ == other.bytecode_;
23210 }
23211 
ParseFromArray(const void * raw,size_t size)23212 bool TraceConfig_TraceFilter::ParseFromArray(const void* raw, size_t size) {
23213   unknown_fields_.clear();
23214   bool packed_error = false;
23215 
23216   ::protozero::ProtoDecoder dec(raw, size);
23217   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
23218     if (field.id() < _has_field_.size()) {
23219       _has_field_.set(field.id());
23220     }
23221     switch (field.id()) {
23222       case 1 /* bytecode */:
23223         field.get(&bytecode_);
23224         break;
23225       default:
23226         field.SerializeAndAppendTo(&unknown_fields_);
23227         break;
23228     }
23229   }
23230   return !packed_error && !dec.bytes_left();
23231 }
23232 
SerializeAsString() const23233 std::string TraceConfig_TraceFilter::SerializeAsString() const {
23234   ::protozero::HeapBuffered<::protozero::Message> msg;
23235   Serialize(msg.get());
23236   return msg.SerializeAsString();
23237 }
23238 
SerializeAsArray() const23239 std::vector<uint8_t> TraceConfig_TraceFilter::SerializeAsArray() const {
23240   ::protozero::HeapBuffered<::protozero::Message> msg;
23241   Serialize(msg.get());
23242   return msg.SerializeAsArray();
23243 }
23244 
Serialize(::protozero::Message * msg) const23245 void TraceConfig_TraceFilter::Serialize(::protozero::Message* msg) const {
23246   // Field 1: bytecode
23247   if (_has_field_[1]) {
23248     msg->AppendString(1, bytecode_);
23249   }
23250 
23251   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
23252 }
23253 
23254 
23255 TraceConfig_IncidentReportConfig::TraceConfig_IncidentReportConfig() = default;
23256 TraceConfig_IncidentReportConfig::~TraceConfig_IncidentReportConfig() = default;
23257 TraceConfig_IncidentReportConfig::TraceConfig_IncidentReportConfig(const TraceConfig_IncidentReportConfig&) = default;
23258 TraceConfig_IncidentReportConfig& TraceConfig_IncidentReportConfig::operator=(const TraceConfig_IncidentReportConfig&) = default;
23259 TraceConfig_IncidentReportConfig::TraceConfig_IncidentReportConfig(TraceConfig_IncidentReportConfig&&) noexcept = default;
23260 TraceConfig_IncidentReportConfig& TraceConfig_IncidentReportConfig::operator=(TraceConfig_IncidentReportConfig&&) = default;
23261 
operator ==(const TraceConfig_IncidentReportConfig & other) const23262 bool TraceConfig_IncidentReportConfig::operator==(const TraceConfig_IncidentReportConfig& other) const {
23263   return unknown_fields_ == other.unknown_fields_
23264    && destination_package_ == other.destination_package_
23265    && destination_class_ == other.destination_class_
23266    && privacy_level_ == other.privacy_level_
23267    && skip_incidentd_ == other.skip_incidentd_
23268    && skip_dropbox_ == other.skip_dropbox_;
23269 }
23270 
ParseFromArray(const void * raw,size_t size)23271 bool TraceConfig_IncidentReportConfig::ParseFromArray(const void* raw, size_t size) {
23272   unknown_fields_.clear();
23273   bool packed_error = false;
23274 
23275   ::protozero::ProtoDecoder dec(raw, size);
23276   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
23277     if (field.id() < _has_field_.size()) {
23278       _has_field_.set(field.id());
23279     }
23280     switch (field.id()) {
23281       case 1 /* destination_package */:
23282         field.get(&destination_package_);
23283         break;
23284       case 2 /* destination_class */:
23285         field.get(&destination_class_);
23286         break;
23287       case 3 /* privacy_level */:
23288         field.get(&privacy_level_);
23289         break;
23290       case 5 /* skip_incidentd */:
23291         field.get(&skip_incidentd_);
23292         break;
23293       case 4 /* skip_dropbox */:
23294         field.get(&skip_dropbox_);
23295         break;
23296       default:
23297         field.SerializeAndAppendTo(&unknown_fields_);
23298         break;
23299     }
23300   }
23301   return !packed_error && !dec.bytes_left();
23302 }
23303 
SerializeAsString() const23304 std::string TraceConfig_IncidentReportConfig::SerializeAsString() const {
23305   ::protozero::HeapBuffered<::protozero::Message> msg;
23306   Serialize(msg.get());
23307   return msg.SerializeAsString();
23308 }
23309 
SerializeAsArray() const23310 std::vector<uint8_t> TraceConfig_IncidentReportConfig::SerializeAsArray() const {
23311   ::protozero::HeapBuffered<::protozero::Message> msg;
23312   Serialize(msg.get());
23313   return msg.SerializeAsArray();
23314 }
23315 
Serialize(::protozero::Message * msg) const23316 void TraceConfig_IncidentReportConfig::Serialize(::protozero::Message* msg) const {
23317   // Field 1: destination_package
23318   if (_has_field_[1]) {
23319     msg->AppendString(1, destination_package_);
23320   }
23321 
23322   // Field 2: destination_class
23323   if (_has_field_[2]) {
23324     msg->AppendString(2, destination_class_);
23325   }
23326 
23327   // Field 3: privacy_level
23328   if (_has_field_[3]) {
23329     msg->AppendVarInt(3, privacy_level_);
23330   }
23331 
23332   // Field 5: skip_incidentd
23333   if (_has_field_[5]) {
23334     msg->AppendTinyVarInt(5, skip_incidentd_);
23335   }
23336 
23337   // Field 4: skip_dropbox
23338   if (_has_field_[4]) {
23339     msg->AppendTinyVarInt(4, skip_dropbox_);
23340   }
23341 
23342   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
23343 }
23344 
23345 
23346 TraceConfig_IncrementalStateConfig::TraceConfig_IncrementalStateConfig() = default;
23347 TraceConfig_IncrementalStateConfig::~TraceConfig_IncrementalStateConfig() = default;
23348 TraceConfig_IncrementalStateConfig::TraceConfig_IncrementalStateConfig(const TraceConfig_IncrementalStateConfig&) = default;
23349 TraceConfig_IncrementalStateConfig& TraceConfig_IncrementalStateConfig::operator=(const TraceConfig_IncrementalStateConfig&) = default;
23350 TraceConfig_IncrementalStateConfig::TraceConfig_IncrementalStateConfig(TraceConfig_IncrementalStateConfig&&) noexcept = default;
23351 TraceConfig_IncrementalStateConfig& TraceConfig_IncrementalStateConfig::operator=(TraceConfig_IncrementalStateConfig&&) = default;
23352 
operator ==(const TraceConfig_IncrementalStateConfig & other) const23353 bool TraceConfig_IncrementalStateConfig::operator==(const TraceConfig_IncrementalStateConfig& other) const {
23354   return unknown_fields_ == other.unknown_fields_
23355    && clear_period_ms_ == other.clear_period_ms_;
23356 }
23357 
ParseFromArray(const void * raw,size_t size)23358 bool TraceConfig_IncrementalStateConfig::ParseFromArray(const void* raw, size_t size) {
23359   unknown_fields_.clear();
23360   bool packed_error = false;
23361 
23362   ::protozero::ProtoDecoder dec(raw, size);
23363   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
23364     if (field.id() < _has_field_.size()) {
23365       _has_field_.set(field.id());
23366     }
23367     switch (field.id()) {
23368       case 1 /* clear_period_ms */:
23369         field.get(&clear_period_ms_);
23370         break;
23371       default:
23372         field.SerializeAndAppendTo(&unknown_fields_);
23373         break;
23374     }
23375   }
23376   return !packed_error && !dec.bytes_left();
23377 }
23378 
SerializeAsString() const23379 std::string TraceConfig_IncrementalStateConfig::SerializeAsString() const {
23380   ::protozero::HeapBuffered<::protozero::Message> msg;
23381   Serialize(msg.get());
23382   return msg.SerializeAsString();
23383 }
23384 
SerializeAsArray() const23385 std::vector<uint8_t> TraceConfig_IncrementalStateConfig::SerializeAsArray() const {
23386   ::protozero::HeapBuffered<::protozero::Message> msg;
23387   Serialize(msg.get());
23388   return msg.SerializeAsArray();
23389 }
23390 
Serialize(::protozero::Message * msg) const23391 void TraceConfig_IncrementalStateConfig::Serialize(::protozero::Message* msg) const {
23392   // Field 1: clear_period_ms
23393   if (_has_field_[1]) {
23394     msg->AppendVarInt(1, clear_period_ms_);
23395   }
23396 
23397   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
23398 }
23399 
23400 
23401 TraceConfig_TriggerConfig::TraceConfig_TriggerConfig() = default;
23402 TraceConfig_TriggerConfig::~TraceConfig_TriggerConfig() = default;
23403 TraceConfig_TriggerConfig::TraceConfig_TriggerConfig(const TraceConfig_TriggerConfig&) = default;
23404 TraceConfig_TriggerConfig& TraceConfig_TriggerConfig::operator=(const TraceConfig_TriggerConfig&) = default;
23405 TraceConfig_TriggerConfig::TraceConfig_TriggerConfig(TraceConfig_TriggerConfig&&) noexcept = default;
23406 TraceConfig_TriggerConfig& TraceConfig_TriggerConfig::operator=(TraceConfig_TriggerConfig&&) = default;
23407 
operator ==(const TraceConfig_TriggerConfig & other) const23408 bool TraceConfig_TriggerConfig::operator==(const TraceConfig_TriggerConfig& other) const {
23409   return unknown_fields_ == other.unknown_fields_
23410    && trigger_mode_ == other.trigger_mode_
23411    && triggers_ == other.triggers_
23412    && trigger_timeout_ms_ == other.trigger_timeout_ms_;
23413 }
23414 
triggers_size() const23415 int TraceConfig_TriggerConfig::triggers_size() const { return static_cast<int>(triggers_.size()); }
clear_triggers()23416 void TraceConfig_TriggerConfig::clear_triggers() { triggers_.clear(); }
add_triggers()23417 TraceConfig_TriggerConfig_Trigger* TraceConfig_TriggerConfig::add_triggers() { triggers_.emplace_back(); return &triggers_.back(); }
ParseFromArray(const void * raw,size_t size)23418 bool TraceConfig_TriggerConfig::ParseFromArray(const void* raw, size_t size) {
23419   triggers_.clear();
23420   unknown_fields_.clear();
23421   bool packed_error = false;
23422 
23423   ::protozero::ProtoDecoder dec(raw, size);
23424   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
23425     if (field.id() < _has_field_.size()) {
23426       _has_field_.set(field.id());
23427     }
23428     switch (field.id()) {
23429       case 1 /* trigger_mode */:
23430         field.get(&trigger_mode_);
23431         break;
23432       case 2 /* triggers */:
23433         triggers_.emplace_back();
23434         triggers_.back().ParseFromArray(field.data(), field.size());
23435         break;
23436       case 3 /* trigger_timeout_ms */:
23437         field.get(&trigger_timeout_ms_);
23438         break;
23439       default:
23440         field.SerializeAndAppendTo(&unknown_fields_);
23441         break;
23442     }
23443   }
23444   return !packed_error && !dec.bytes_left();
23445 }
23446 
SerializeAsString() const23447 std::string TraceConfig_TriggerConfig::SerializeAsString() const {
23448   ::protozero::HeapBuffered<::protozero::Message> msg;
23449   Serialize(msg.get());
23450   return msg.SerializeAsString();
23451 }
23452 
SerializeAsArray() const23453 std::vector<uint8_t> TraceConfig_TriggerConfig::SerializeAsArray() const {
23454   ::protozero::HeapBuffered<::protozero::Message> msg;
23455   Serialize(msg.get());
23456   return msg.SerializeAsArray();
23457 }
23458 
Serialize(::protozero::Message * msg) const23459 void TraceConfig_TriggerConfig::Serialize(::protozero::Message* msg) const {
23460   // Field 1: trigger_mode
23461   if (_has_field_[1]) {
23462     msg->AppendVarInt(1, trigger_mode_);
23463   }
23464 
23465   // Field 2: triggers
23466   for (auto& it : triggers_) {
23467     it.Serialize(msg->BeginNestedMessage<::protozero::Message>(2));
23468   }
23469 
23470   // Field 3: trigger_timeout_ms
23471   if (_has_field_[3]) {
23472     msg->AppendVarInt(3, trigger_timeout_ms_);
23473   }
23474 
23475   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
23476 }
23477 
23478 
23479 TraceConfig_TriggerConfig_Trigger::TraceConfig_TriggerConfig_Trigger() = default;
23480 TraceConfig_TriggerConfig_Trigger::~TraceConfig_TriggerConfig_Trigger() = default;
23481 TraceConfig_TriggerConfig_Trigger::TraceConfig_TriggerConfig_Trigger(const TraceConfig_TriggerConfig_Trigger&) = default;
23482 TraceConfig_TriggerConfig_Trigger& TraceConfig_TriggerConfig_Trigger::operator=(const TraceConfig_TriggerConfig_Trigger&) = default;
23483 TraceConfig_TriggerConfig_Trigger::TraceConfig_TriggerConfig_Trigger(TraceConfig_TriggerConfig_Trigger&&) noexcept = default;
23484 TraceConfig_TriggerConfig_Trigger& TraceConfig_TriggerConfig_Trigger::operator=(TraceConfig_TriggerConfig_Trigger&&) = default;
23485 
operator ==(const TraceConfig_TriggerConfig_Trigger & other) const23486 bool TraceConfig_TriggerConfig_Trigger::operator==(const TraceConfig_TriggerConfig_Trigger& other) const {
23487   return unknown_fields_ == other.unknown_fields_
23488    && name_ == other.name_
23489    && producer_name_regex_ == other.producer_name_regex_
23490    && stop_delay_ms_ == other.stop_delay_ms_
23491    && max_per_24_h_ == other.max_per_24_h_
23492    && skip_probability_ == other.skip_probability_;
23493 }
23494 
ParseFromArray(const void * raw,size_t size)23495 bool TraceConfig_TriggerConfig_Trigger::ParseFromArray(const void* raw, size_t size) {
23496   unknown_fields_.clear();
23497   bool packed_error = false;
23498 
23499   ::protozero::ProtoDecoder dec(raw, size);
23500   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
23501     if (field.id() < _has_field_.size()) {
23502       _has_field_.set(field.id());
23503     }
23504     switch (field.id()) {
23505       case 1 /* name */:
23506         field.get(&name_);
23507         break;
23508       case 2 /* producer_name_regex */:
23509         field.get(&producer_name_regex_);
23510         break;
23511       case 3 /* stop_delay_ms */:
23512         field.get(&stop_delay_ms_);
23513         break;
23514       case 4 /* max_per_24_h */:
23515         field.get(&max_per_24_h_);
23516         break;
23517       case 5 /* skip_probability */:
23518         field.get(&skip_probability_);
23519         break;
23520       default:
23521         field.SerializeAndAppendTo(&unknown_fields_);
23522         break;
23523     }
23524   }
23525   return !packed_error && !dec.bytes_left();
23526 }
23527 
SerializeAsString() const23528 std::string TraceConfig_TriggerConfig_Trigger::SerializeAsString() const {
23529   ::protozero::HeapBuffered<::protozero::Message> msg;
23530   Serialize(msg.get());
23531   return msg.SerializeAsString();
23532 }
23533 
SerializeAsArray() const23534 std::vector<uint8_t> TraceConfig_TriggerConfig_Trigger::SerializeAsArray() const {
23535   ::protozero::HeapBuffered<::protozero::Message> msg;
23536   Serialize(msg.get());
23537   return msg.SerializeAsArray();
23538 }
23539 
Serialize(::protozero::Message * msg) const23540 void TraceConfig_TriggerConfig_Trigger::Serialize(::protozero::Message* msg) const {
23541   // Field 1: name
23542   if (_has_field_[1]) {
23543     msg->AppendString(1, name_);
23544   }
23545 
23546   // Field 2: producer_name_regex
23547   if (_has_field_[2]) {
23548     msg->AppendString(2, producer_name_regex_);
23549   }
23550 
23551   // Field 3: stop_delay_ms
23552   if (_has_field_[3]) {
23553     msg->AppendVarInt(3, stop_delay_ms_);
23554   }
23555 
23556   // Field 4: max_per_24_h
23557   if (_has_field_[4]) {
23558     msg->AppendVarInt(4, max_per_24_h_);
23559   }
23560 
23561   // Field 5: skip_probability
23562   if (_has_field_[5]) {
23563     msg->AppendFixed(5, skip_probability_);
23564   }
23565 
23566   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
23567 }
23568 
23569 
23570 TraceConfig_GuardrailOverrides::TraceConfig_GuardrailOverrides() = default;
23571 TraceConfig_GuardrailOverrides::~TraceConfig_GuardrailOverrides() = default;
23572 TraceConfig_GuardrailOverrides::TraceConfig_GuardrailOverrides(const TraceConfig_GuardrailOverrides&) = default;
23573 TraceConfig_GuardrailOverrides& TraceConfig_GuardrailOverrides::operator=(const TraceConfig_GuardrailOverrides&) = default;
23574 TraceConfig_GuardrailOverrides::TraceConfig_GuardrailOverrides(TraceConfig_GuardrailOverrides&&) noexcept = default;
23575 TraceConfig_GuardrailOverrides& TraceConfig_GuardrailOverrides::operator=(TraceConfig_GuardrailOverrides&&) = default;
23576 
operator ==(const TraceConfig_GuardrailOverrides & other) const23577 bool TraceConfig_GuardrailOverrides::operator==(const TraceConfig_GuardrailOverrides& other) const {
23578   return unknown_fields_ == other.unknown_fields_
23579    && max_upload_per_day_bytes_ == other.max_upload_per_day_bytes_;
23580 }
23581 
ParseFromArray(const void * raw,size_t size)23582 bool TraceConfig_GuardrailOverrides::ParseFromArray(const void* raw, size_t size) {
23583   unknown_fields_.clear();
23584   bool packed_error = false;
23585 
23586   ::protozero::ProtoDecoder dec(raw, size);
23587   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
23588     if (field.id() < _has_field_.size()) {
23589       _has_field_.set(field.id());
23590     }
23591     switch (field.id()) {
23592       case 1 /* max_upload_per_day_bytes */:
23593         field.get(&max_upload_per_day_bytes_);
23594         break;
23595       default:
23596         field.SerializeAndAppendTo(&unknown_fields_);
23597         break;
23598     }
23599   }
23600   return !packed_error && !dec.bytes_left();
23601 }
23602 
SerializeAsString() const23603 std::string TraceConfig_GuardrailOverrides::SerializeAsString() const {
23604   ::protozero::HeapBuffered<::protozero::Message> msg;
23605   Serialize(msg.get());
23606   return msg.SerializeAsString();
23607 }
23608 
SerializeAsArray() const23609 std::vector<uint8_t> TraceConfig_GuardrailOverrides::SerializeAsArray() const {
23610   ::protozero::HeapBuffered<::protozero::Message> msg;
23611   Serialize(msg.get());
23612   return msg.SerializeAsArray();
23613 }
23614 
Serialize(::protozero::Message * msg) const23615 void TraceConfig_GuardrailOverrides::Serialize(::protozero::Message* msg) const {
23616   // Field 1: max_upload_per_day_bytes
23617   if (_has_field_[1]) {
23618     msg->AppendVarInt(1, max_upload_per_day_bytes_);
23619   }
23620 
23621   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
23622 }
23623 
23624 
23625 TraceConfig_StatsdMetadata::TraceConfig_StatsdMetadata() = default;
23626 TraceConfig_StatsdMetadata::~TraceConfig_StatsdMetadata() = default;
23627 TraceConfig_StatsdMetadata::TraceConfig_StatsdMetadata(const TraceConfig_StatsdMetadata&) = default;
23628 TraceConfig_StatsdMetadata& TraceConfig_StatsdMetadata::operator=(const TraceConfig_StatsdMetadata&) = default;
23629 TraceConfig_StatsdMetadata::TraceConfig_StatsdMetadata(TraceConfig_StatsdMetadata&&) noexcept = default;
23630 TraceConfig_StatsdMetadata& TraceConfig_StatsdMetadata::operator=(TraceConfig_StatsdMetadata&&) = default;
23631 
operator ==(const TraceConfig_StatsdMetadata & other) const23632 bool TraceConfig_StatsdMetadata::operator==(const TraceConfig_StatsdMetadata& other) const {
23633   return unknown_fields_ == other.unknown_fields_
23634    && triggering_alert_id_ == other.triggering_alert_id_
23635    && triggering_config_uid_ == other.triggering_config_uid_
23636    && triggering_config_id_ == other.triggering_config_id_
23637    && triggering_subscription_id_ == other.triggering_subscription_id_;
23638 }
23639 
ParseFromArray(const void * raw,size_t size)23640 bool TraceConfig_StatsdMetadata::ParseFromArray(const void* raw, size_t size) {
23641   unknown_fields_.clear();
23642   bool packed_error = false;
23643 
23644   ::protozero::ProtoDecoder dec(raw, size);
23645   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
23646     if (field.id() < _has_field_.size()) {
23647       _has_field_.set(field.id());
23648     }
23649     switch (field.id()) {
23650       case 1 /* triggering_alert_id */:
23651         field.get(&triggering_alert_id_);
23652         break;
23653       case 2 /* triggering_config_uid */:
23654         field.get(&triggering_config_uid_);
23655         break;
23656       case 3 /* triggering_config_id */:
23657         field.get(&triggering_config_id_);
23658         break;
23659       case 4 /* triggering_subscription_id */:
23660         field.get(&triggering_subscription_id_);
23661         break;
23662       default:
23663         field.SerializeAndAppendTo(&unknown_fields_);
23664         break;
23665     }
23666   }
23667   return !packed_error && !dec.bytes_left();
23668 }
23669 
SerializeAsString() const23670 std::string TraceConfig_StatsdMetadata::SerializeAsString() const {
23671   ::protozero::HeapBuffered<::protozero::Message> msg;
23672   Serialize(msg.get());
23673   return msg.SerializeAsString();
23674 }
23675 
SerializeAsArray() const23676 std::vector<uint8_t> TraceConfig_StatsdMetadata::SerializeAsArray() const {
23677   ::protozero::HeapBuffered<::protozero::Message> msg;
23678   Serialize(msg.get());
23679   return msg.SerializeAsArray();
23680 }
23681 
Serialize(::protozero::Message * msg) const23682 void TraceConfig_StatsdMetadata::Serialize(::protozero::Message* msg) const {
23683   // Field 1: triggering_alert_id
23684   if (_has_field_[1]) {
23685     msg->AppendVarInt(1, triggering_alert_id_);
23686   }
23687 
23688   // Field 2: triggering_config_uid
23689   if (_has_field_[2]) {
23690     msg->AppendVarInt(2, triggering_config_uid_);
23691   }
23692 
23693   // Field 3: triggering_config_id
23694   if (_has_field_[3]) {
23695     msg->AppendVarInt(3, triggering_config_id_);
23696   }
23697 
23698   // Field 4: triggering_subscription_id
23699   if (_has_field_[4]) {
23700     msg->AppendVarInt(4, triggering_subscription_id_);
23701   }
23702 
23703   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
23704 }
23705 
23706 
23707 TraceConfig_ProducerConfig::TraceConfig_ProducerConfig() = default;
23708 TraceConfig_ProducerConfig::~TraceConfig_ProducerConfig() = default;
23709 TraceConfig_ProducerConfig::TraceConfig_ProducerConfig(const TraceConfig_ProducerConfig&) = default;
23710 TraceConfig_ProducerConfig& TraceConfig_ProducerConfig::operator=(const TraceConfig_ProducerConfig&) = default;
23711 TraceConfig_ProducerConfig::TraceConfig_ProducerConfig(TraceConfig_ProducerConfig&&) noexcept = default;
23712 TraceConfig_ProducerConfig& TraceConfig_ProducerConfig::operator=(TraceConfig_ProducerConfig&&) = default;
23713 
operator ==(const TraceConfig_ProducerConfig & other) const23714 bool TraceConfig_ProducerConfig::operator==(const TraceConfig_ProducerConfig& other) const {
23715   return unknown_fields_ == other.unknown_fields_
23716    && producer_name_ == other.producer_name_
23717    && shm_size_kb_ == other.shm_size_kb_
23718    && page_size_kb_ == other.page_size_kb_;
23719 }
23720 
ParseFromArray(const void * raw,size_t size)23721 bool TraceConfig_ProducerConfig::ParseFromArray(const void* raw, size_t size) {
23722   unknown_fields_.clear();
23723   bool packed_error = false;
23724 
23725   ::protozero::ProtoDecoder dec(raw, size);
23726   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
23727     if (field.id() < _has_field_.size()) {
23728       _has_field_.set(field.id());
23729     }
23730     switch (field.id()) {
23731       case 1 /* producer_name */:
23732         field.get(&producer_name_);
23733         break;
23734       case 2 /* shm_size_kb */:
23735         field.get(&shm_size_kb_);
23736         break;
23737       case 3 /* page_size_kb */:
23738         field.get(&page_size_kb_);
23739         break;
23740       default:
23741         field.SerializeAndAppendTo(&unknown_fields_);
23742         break;
23743     }
23744   }
23745   return !packed_error && !dec.bytes_left();
23746 }
23747 
SerializeAsString() const23748 std::string TraceConfig_ProducerConfig::SerializeAsString() const {
23749   ::protozero::HeapBuffered<::protozero::Message> msg;
23750   Serialize(msg.get());
23751   return msg.SerializeAsString();
23752 }
23753 
SerializeAsArray() const23754 std::vector<uint8_t> TraceConfig_ProducerConfig::SerializeAsArray() const {
23755   ::protozero::HeapBuffered<::protozero::Message> msg;
23756   Serialize(msg.get());
23757   return msg.SerializeAsArray();
23758 }
23759 
Serialize(::protozero::Message * msg) const23760 void TraceConfig_ProducerConfig::Serialize(::protozero::Message* msg) const {
23761   // Field 1: producer_name
23762   if (_has_field_[1]) {
23763     msg->AppendString(1, producer_name_);
23764   }
23765 
23766   // Field 2: shm_size_kb
23767   if (_has_field_[2]) {
23768     msg->AppendVarInt(2, shm_size_kb_);
23769   }
23770 
23771   // Field 3: page_size_kb
23772   if (_has_field_[3]) {
23773     msg->AppendVarInt(3, page_size_kb_);
23774   }
23775 
23776   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
23777 }
23778 
23779 
23780 TraceConfig_BuiltinDataSource::TraceConfig_BuiltinDataSource() = default;
23781 TraceConfig_BuiltinDataSource::~TraceConfig_BuiltinDataSource() = default;
23782 TraceConfig_BuiltinDataSource::TraceConfig_BuiltinDataSource(const TraceConfig_BuiltinDataSource&) = default;
23783 TraceConfig_BuiltinDataSource& TraceConfig_BuiltinDataSource::operator=(const TraceConfig_BuiltinDataSource&) = default;
23784 TraceConfig_BuiltinDataSource::TraceConfig_BuiltinDataSource(TraceConfig_BuiltinDataSource&&) noexcept = default;
23785 TraceConfig_BuiltinDataSource& TraceConfig_BuiltinDataSource::operator=(TraceConfig_BuiltinDataSource&&) = default;
23786 
operator ==(const TraceConfig_BuiltinDataSource & other) const23787 bool TraceConfig_BuiltinDataSource::operator==(const TraceConfig_BuiltinDataSource& other) const {
23788   return unknown_fields_ == other.unknown_fields_
23789    && disable_clock_snapshotting_ == other.disable_clock_snapshotting_
23790    && disable_trace_config_ == other.disable_trace_config_
23791    && disable_system_info_ == other.disable_system_info_
23792    && disable_service_events_ == other.disable_service_events_
23793    && primary_trace_clock_ == other.primary_trace_clock_
23794    && snapshot_interval_ms_ == other.snapshot_interval_ms_
23795    && prefer_suspend_clock_for_snapshot_ == other.prefer_suspend_clock_for_snapshot_;
23796 }
23797 
ParseFromArray(const void * raw,size_t size)23798 bool TraceConfig_BuiltinDataSource::ParseFromArray(const void* raw, size_t size) {
23799   unknown_fields_.clear();
23800   bool packed_error = false;
23801 
23802   ::protozero::ProtoDecoder dec(raw, size);
23803   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
23804     if (field.id() < _has_field_.size()) {
23805       _has_field_.set(field.id());
23806     }
23807     switch (field.id()) {
23808       case 1 /* disable_clock_snapshotting */:
23809         field.get(&disable_clock_snapshotting_);
23810         break;
23811       case 2 /* disable_trace_config */:
23812         field.get(&disable_trace_config_);
23813         break;
23814       case 3 /* disable_system_info */:
23815         field.get(&disable_system_info_);
23816         break;
23817       case 4 /* disable_service_events */:
23818         field.get(&disable_service_events_);
23819         break;
23820       case 5 /* primary_trace_clock */:
23821         field.get(&primary_trace_clock_);
23822         break;
23823       case 6 /* snapshot_interval_ms */:
23824         field.get(&snapshot_interval_ms_);
23825         break;
23826       case 7 /* prefer_suspend_clock_for_snapshot */:
23827         field.get(&prefer_suspend_clock_for_snapshot_);
23828         break;
23829       default:
23830         field.SerializeAndAppendTo(&unknown_fields_);
23831         break;
23832     }
23833   }
23834   return !packed_error && !dec.bytes_left();
23835 }
23836 
SerializeAsString() const23837 std::string TraceConfig_BuiltinDataSource::SerializeAsString() const {
23838   ::protozero::HeapBuffered<::protozero::Message> msg;
23839   Serialize(msg.get());
23840   return msg.SerializeAsString();
23841 }
23842 
SerializeAsArray() const23843 std::vector<uint8_t> TraceConfig_BuiltinDataSource::SerializeAsArray() const {
23844   ::protozero::HeapBuffered<::protozero::Message> msg;
23845   Serialize(msg.get());
23846   return msg.SerializeAsArray();
23847 }
23848 
Serialize(::protozero::Message * msg) const23849 void TraceConfig_BuiltinDataSource::Serialize(::protozero::Message* msg) const {
23850   // Field 1: disable_clock_snapshotting
23851   if (_has_field_[1]) {
23852     msg->AppendTinyVarInt(1, disable_clock_snapshotting_);
23853   }
23854 
23855   // Field 2: disable_trace_config
23856   if (_has_field_[2]) {
23857     msg->AppendTinyVarInt(2, disable_trace_config_);
23858   }
23859 
23860   // Field 3: disable_system_info
23861   if (_has_field_[3]) {
23862     msg->AppendTinyVarInt(3, disable_system_info_);
23863   }
23864 
23865   // Field 4: disable_service_events
23866   if (_has_field_[4]) {
23867     msg->AppendTinyVarInt(4, disable_service_events_);
23868   }
23869 
23870   // Field 5: primary_trace_clock
23871   if (_has_field_[5]) {
23872     msg->AppendVarInt(5, primary_trace_clock_);
23873   }
23874 
23875   // Field 6: snapshot_interval_ms
23876   if (_has_field_[6]) {
23877     msg->AppendVarInt(6, snapshot_interval_ms_);
23878   }
23879 
23880   // Field 7: prefer_suspend_clock_for_snapshot
23881   if (_has_field_[7]) {
23882     msg->AppendTinyVarInt(7, prefer_suspend_clock_for_snapshot_);
23883   }
23884 
23885   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
23886 }
23887 
23888 
23889 TraceConfig_DataSource::TraceConfig_DataSource() = default;
23890 TraceConfig_DataSource::~TraceConfig_DataSource() = default;
23891 TraceConfig_DataSource::TraceConfig_DataSource(const TraceConfig_DataSource&) = default;
23892 TraceConfig_DataSource& TraceConfig_DataSource::operator=(const TraceConfig_DataSource&) = default;
23893 TraceConfig_DataSource::TraceConfig_DataSource(TraceConfig_DataSource&&) noexcept = default;
23894 TraceConfig_DataSource& TraceConfig_DataSource::operator=(TraceConfig_DataSource&&) = default;
23895 
operator ==(const TraceConfig_DataSource & other) const23896 bool TraceConfig_DataSource::operator==(const TraceConfig_DataSource& other) const {
23897   return unknown_fields_ == other.unknown_fields_
23898    && config_ == other.config_
23899    && producer_name_filter_ == other.producer_name_filter_
23900    && producer_name_regex_filter_ == other.producer_name_regex_filter_;
23901 }
23902 
ParseFromArray(const void * raw,size_t size)23903 bool TraceConfig_DataSource::ParseFromArray(const void* raw, size_t size) {
23904   producer_name_filter_.clear();
23905   producer_name_regex_filter_.clear();
23906   unknown_fields_.clear();
23907   bool packed_error = false;
23908 
23909   ::protozero::ProtoDecoder dec(raw, size);
23910   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
23911     if (field.id() < _has_field_.size()) {
23912       _has_field_.set(field.id());
23913     }
23914     switch (field.id()) {
23915       case 1 /* config */:
23916         (*config_).ParseFromArray(field.data(), field.size());
23917         break;
23918       case 2 /* producer_name_filter */:
23919         producer_name_filter_.emplace_back();
23920         field.get(&producer_name_filter_.back());
23921         break;
23922       case 3 /* producer_name_regex_filter */:
23923         producer_name_regex_filter_.emplace_back();
23924         field.get(&producer_name_regex_filter_.back());
23925         break;
23926       default:
23927         field.SerializeAndAppendTo(&unknown_fields_);
23928         break;
23929     }
23930   }
23931   return !packed_error && !dec.bytes_left();
23932 }
23933 
SerializeAsString() const23934 std::string TraceConfig_DataSource::SerializeAsString() const {
23935   ::protozero::HeapBuffered<::protozero::Message> msg;
23936   Serialize(msg.get());
23937   return msg.SerializeAsString();
23938 }
23939 
SerializeAsArray() const23940 std::vector<uint8_t> TraceConfig_DataSource::SerializeAsArray() const {
23941   ::protozero::HeapBuffered<::protozero::Message> msg;
23942   Serialize(msg.get());
23943   return msg.SerializeAsArray();
23944 }
23945 
Serialize(::protozero::Message * msg) const23946 void TraceConfig_DataSource::Serialize(::protozero::Message* msg) const {
23947   // Field 1: config
23948   if (_has_field_[1]) {
23949     (*config_).Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
23950   }
23951 
23952   // Field 2: producer_name_filter
23953   for (auto& it : producer_name_filter_) {
23954     msg->AppendString(2, it);
23955   }
23956 
23957   // Field 3: producer_name_regex_filter
23958   for (auto& it : producer_name_regex_filter_) {
23959     msg->AppendString(3, it);
23960   }
23961 
23962   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
23963 }
23964 
23965 
23966 TraceConfig_BufferConfig::TraceConfig_BufferConfig() = default;
23967 TraceConfig_BufferConfig::~TraceConfig_BufferConfig() = default;
23968 TraceConfig_BufferConfig::TraceConfig_BufferConfig(const TraceConfig_BufferConfig&) = default;
23969 TraceConfig_BufferConfig& TraceConfig_BufferConfig::operator=(const TraceConfig_BufferConfig&) = default;
23970 TraceConfig_BufferConfig::TraceConfig_BufferConfig(TraceConfig_BufferConfig&&) noexcept = default;
23971 TraceConfig_BufferConfig& TraceConfig_BufferConfig::operator=(TraceConfig_BufferConfig&&) = default;
23972 
operator ==(const TraceConfig_BufferConfig & other) const23973 bool TraceConfig_BufferConfig::operator==(const TraceConfig_BufferConfig& other) const {
23974   return unknown_fields_ == other.unknown_fields_
23975    && size_kb_ == other.size_kb_
23976    && fill_policy_ == other.fill_policy_;
23977 }
23978 
ParseFromArray(const void * raw,size_t size)23979 bool TraceConfig_BufferConfig::ParseFromArray(const void* raw, size_t size) {
23980   unknown_fields_.clear();
23981   bool packed_error = false;
23982 
23983   ::protozero::ProtoDecoder dec(raw, size);
23984   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
23985     if (field.id() < _has_field_.size()) {
23986       _has_field_.set(field.id());
23987     }
23988     switch (field.id()) {
23989       case 1 /* size_kb */:
23990         field.get(&size_kb_);
23991         break;
23992       case 4 /* fill_policy */:
23993         field.get(&fill_policy_);
23994         break;
23995       default:
23996         field.SerializeAndAppendTo(&unknown_fields_);
23997         break;
23998     }
23999   }
24000   return !packed_error && !dec.bytes_left();
24001 }
24002 
SerializeAsString() const24003 std::string TraceConfig_BufferConfig::SerializeAsString() const {
24004   ::protozero::HeapBuffered<::protozero::Message> msg;
24005   Serialize(msg.get());
24006   return msg.SerializeAsString();
24007 }
24008 
SerializeAsArray() const24009 std::vector<uint8_t> TraceConfig_BufferConfig::SerializeAsArray() const {
24010   ::protozero::HeapBuffered<::protozero::Message> msg;
24011   Serialize(msg.get());
24012   return msg.SerializeAsArray();
24013 }
24014 
Serialize(::protozero::Message * msg) const24015 void TraceConfig_BufferConfig::Serialize(::protozero::Message* msg) const {
24016   // Field 1: size_kb
24017   if (_has_field_[1]) {
24018     msg->AppendVarInt(1, size_kb_);
24019   }
24020 
24021   // Field 4: fill_policy
24022   if (_has_field_[4]) {
24023     msg->AppendVarInt(4, fill_policy_);
24024   }
24025 
24026   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
24027 }
24028 
24029 }  // namespace perfetto
24030 }  // namespace protos
24031 }  // namespace gen
24032 #if defined(__GNUC__) || defined(__clang__)
24033 #pragma GCC diagnostic pop
24034 #endif
24035 // gen_amalgamated begin source: gen/protos/perfetto/common/android_energy_consumer_descriptor.pbzero.cc
24036 // Intentionally empty (crbug.com/998165)
24037 // gen_amalgamated begin source: gen/protos/perfetto/common/android_log_constants.pbzero.cc
24038 // Intentionally empty (crbug.com/998165)
24039 // gen_amalgamated begin source: gen/protos/perfetto/common/builtin_clock.pbzero.cc
24040 // Intentionally empty (crbug.com/998165)
24041 // gen_amalgamated begin source: gen/protos/perfetto/common/commit_data_request.pbzero.cc
24042 // Intentionally empty (crbug.com/998165)
24043 // gen_amalgamated begin source: gen/protos/perfetto/common/data_source_descriptor.pbzero.cc
24044 // Intentionally empty (crbug.com/998165)
24045 // gen_amalgamated begin source: gen/protos/perfetto/common/descriptor.pbzero.cc
24046 // Intentionally empty (crbug.com/998165)
24047 // gen_amalgamated begin source: gen/protos/perfetto/common/gpu_counter_descriptor.pbzero.cc
24048 // Intentionally empty (crbug.com/998165)
24049 // gen_amalgamated begin source: gen/protos/perfetto/common/interceptor_descriptor.pbzero.cc
24050 // Intentionally empty (crbug.com/998165)
24051 // gen_amalgamated begin source: gen/protos/perfetto/common/observable_events.pbzero.cc
24052 // Intentionally empty (crbug.com/998165)
24053 // gen_amalgamated begin source: gen/protos/perfetto/common/perf_events.pbzero.cc
24054 // Intentionally empty (crbug.com/998165)
24055 // gen_amalgamated begin source: gen/protos/perfetto/common/sys_stats_counters.pbzero.cc
24056 // Intentionally empty (crbug.com/998165)
24057 // gen_amalgamated begin source: gen/protos/perfetto/common/trace_stats.pbzero.cc
24058 // Intentionally empty (crbug.com/998165)
24059 // gen_amalgamated begin source: gen/protos/perfetto/common/tracing_service_capabilities.pbzero.cc
24060 // Intentionally empty (crbug.com/998165)
24061 // gen_amalgamated begin source: gen/protos/perfetto/common/tracing_service_state.pbzero.cc
24062 // Intentionally empty (crbug.com/998165)
24063 // gen_amalgamated begin source: gen/protos/perfetto/common/track_event_descriptor.pbzero.cc
24064 // Intentionally empty (crbug.com/998165)
24065 // gen_amalgamated begin source: gen/protos/perfetto/trace/gpu/gpu_counter_event.pbzero.cc
24066 // Intentionally empty (crbug.com/998165)
24067 // gen_amalgamated begin source: gen/protos/perfetto/trace/gpu/gpu_log.pbzero.cc
24068 // Intentionally empty (crbug.com/998165)
24069 // gen_amalgamated begin source: gen/protos/perfetto/trace/gpu/gpu_render_stage_event.pbzero.cc
24070 // Intentionally empty (crbug.com/998165)
24071 // gen_amalgamated begin source: gen/protos/perfetto/trace/gpu/vulkan_api_event.pbzero.cc
24072 // Intentionally empty (crbug.com/998165)
24073 // gen_amalgamated begin source: gen/protos/perfetto/trace/gpu/vulkan_memory_event.pbzero.cc
24074 // Intentionally empty (crbug.com/998165)
24075 // gen_amalgamated begin source: gen/protos/perfetto/trace/profiling/deobfuscation.pbzero.cc
24076 // Intentionally empty (crbug.com/998165)
24077 // gen_amalgamated begin source: gen/protos/perfetto/trace/profiling/heap_graph.pbzero.cc
24078 // Intentionally empty (crbug.com/998165)
24079 // gen_amalgamated begin source: gen/protos/perfetto/trace/profiling/profile_common.pbzero.cc
24080 // Intentionally empty (crbug.com/998165)
24081 // gen_amalgamated begin source: gen/protos/perfetto/trace/profiling/profile_packet.pbzero.cc
24082 // Intentionally empty (crbug.com/998165)
24083 // gen_amalgamated begin source: gen/protos/perfetto/trace/profiling/smaps.pbzero.cc
24084 // Intentionally empty (crbug.com/998165)
24085 // gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_application_state_info.pbzero.cc
24086 // Intentionally empty (crbug.com/998165)
24087 // gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_compositor_scheduler_state.pbzero.cc
24088 // Intentionally empty (crbug.com/998165)
24089 // gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_content_settings_event_info.pbzero.cc
24090 // Intentionally empty (crbug.com/998165)
24091 // gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_frame_reporter.pbzero.cc
24092 // Intentionally empty (crbug.com/998165)
24093 // gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_histogram_sample.pbzero.cc
24094 // Intentionally empty (crbug.com/998165)
24095 // gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_keyed_service.pbzero.cc
24096 // Intentionally empty (crbug.com/998165)
24097 // gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_latency_info.pbzero.cc
24098 // Intentionally empty (crbug.com/998165)
24099 // gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_legacy_ipc.pbzero.cc
24100 // Intentionally empty (crbug.com/998165)
24101 // gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_message_pump.pbzero.cc
24102 // Intentionally empty (crbug.com/998165)
24103 // gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_mojo_event_info.pbzero.cc
24104 // Intentionally empty (crbug.com/998165)
24105 // gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_process_descriptor.pbzero.cc
24106 // Intentionally empty (crbug.com/998165)
24107 // gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_renderer_scheduler_state.pbzero.cc
24108 // Intentionally empty (crbug.com/998165)
24109 // gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_thread_descriptor.pbzero.cc
24110 // Intentionally empty (crbug.com/998165)
24111 // gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_user_event.pbzero.cc
24112 // Intentionally empty (crbug.com/998165)
24113 // gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_window_handle_event_info.pbzero.cc
24114 // Intentionally empty (crbug.com/998165)
24115 // gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/counter_descriptor.pbzero.cc
24116 // Intentionally empty (crbug.com/998165)
24117 // gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/debug_annotation.pbzero.cc
24118 // Intentionally empty (crbug.com/998165)
24119 // gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/log_message.pbzero.cc
24120 // Intentionally empty (crbug.com/998165)
24121 // gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/process_descriptor.pbzero.cc
24122 // Intentionally empty (crbug.com/998165)
24123 // gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/source_location.pbzero.cc
24124 // Intentionally empty (crbug.com/998165)
24125 // gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/task_execution.pbzero.cc
24126 // Intentionally empty (crbug.com/998165)
24127 // gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/thread_descriptor.pbzero.cc
24128 // Intentionally empty (crbug.com/998165)
24129 // gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/track_descriptor.pbzero.cc
24130 // Intentionally empty (crbug.com/998165)
24131 // gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/track_event.pbzero.cc
24132 // Intentionally empty (crbug.com/998165)
24133 // gen_amalgamated begin source: gen/protos/perfetto/trace/interned_data/interned_data.pbzero.cc
24134 // Intentionally empty (crbug.com/998165)
24135 // gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_application_state_info.gen.cc
24136 // gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/chrome_application_state_info.gen.h
24137 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
24138 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_APPLICATION_STATE_INFO_PROTO_CPP_H_
24139 #define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_APPLICATION_STATE_INFO_PROTO_CPP_H_
24140 
24141 #include <stdint.h>
24142 #include <bitset>
24143 #include <vector>
24144 #include <string>
24145 #include <type_traits>
24146 
24147 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
24148 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
24149 // gen_amalgamated expanded: #include "perfetto/base/export.h"
24150 
24151 namespace perfetto {
24152 namespace protos {
24153 namespace gen {
24154 class ChromeApplicationStateInfo;
24155 enum ChromeApplicationStateInfo_ChromeApplicationState : int;
24156 }  // namespace perfetto
24157 }  // namespace protos
24158 }  // namespace gen
24159 
24160 namespace protozero {
24161 class Message;
24162 }  // namespace protozero
24163 
24164 namespace perfetto {
24165 namespace protos {
24166 namespace gen {
24167 enum ChromeApplicationStateInfo_ChromeApplicationState : int {
24168   ChromeApplicationStateInfo_ChromeApplicationState_APPLICATION_STATE_UNKNOWN = 0,
24169   ChromeApplicationStateInfo_ChromeApplicationState_APPLICATION_STATE_HAS_RUNNING_ACTIVITIES = 1,
24170   ChromeApplicationStateInfo_ChromeApplicationState_APPLICATION_STATE_HAS_PAUSED_ACTIVITIES = 2,
24171   ChromeApplicationStateInfo_ChromeApplicationState_APPLICATION_STATE_HAS_STOPPED_ACTIVITIES = 3,
24172   ChromeApplicationStateInfo_ChromeApplicationState_APPLICATION_STATE_HAS_DESTROYED_ACTIVITIES = 4,
24173 };
24174 
24175 class PERFETTO_EXPORT ChromeApplicationStateInfo : public ::protozero::CppMessageObj {
24176  public:
24177   using ChromeApplicationState = ChromeApplicationStateInfo_ChromeApplicationState;
24178   static constexpr auto APPLICATION_STATE_UNKNOWN = ChromeApplicationStateInfo_ChromeApplicationState_APPLICATION_STATE_UNKNOWN;
24179   static constexpr auto APPLICATION_STATE_HAS_RUNNING_ACTIVITIES = ChromeApplicationStateInfo_ChromeApplicationState_APPLICATION_STATE_HAS_RUNNING_ACTIVITIES;
24180   static constexpr auto APPLICATION_STATE_HAS_PAUSED_ACTIVITIES = ChromeApplicationStateInfo_ChromeApplicationState_APPLICATION_STATE_HAS_PAUSED_ACTIVITIES;
24181   static constexpr auto APPLICATION_STATE_HAS_STOPPED_ACTIVITIES = ChromeApplicationStateInfo_ChromeApplicationState_APPLICATION_STATE_HAS_STOPPED_ACTIVITIES;
24182   static constexpr auto APPLICATION_STATE_HAS_DESTROYED_ACTIVITIES = ChromeApplicationStateInfo_ChromeApplicationState_APPLICATION_STATE_HAS_DESTROYED_ACTIVITIES;
24183   static constexpr auto ChromeApplicationState_MIN = ChromeApplicationStateInfo_ChromeApplicationState_APPLICATION_STATE_UNKNOWN;
24184   static constexpr auto ChromeApplicationState_MAX = ChromeApplicationStateInfo_ChromeApplicationState_APPLICATION_STATE_HAS_DESTROYED_ACTIVITIES;
24185   enum FieldNumbers {
24186     kApplicationStateFieldNumber = 1,
24187   };
24188 
24189   ChromeApplicationStateInfo();
24190   ~ChromeApplicationStateInfo() override;
24191   ChromeApplicationStateInfo(ChromeApplicationStateInfo&&) noexcept;
24192   ChromeApplicationStateInfo& operator=(ChromeApplicationStateInfo&&);
24193   ChromeApplicationStateInfo(const ChromeApplicationStateInfo&);
24194   ChromeApplicationStateInfo& operator=(const ChromeApplicationStateInfo&);
24195   bool operator==(const ChromeApplicationStateInfo&) const;
operator !=(const ChromeApplicationStateInfo & other) const24196   bool operator!=(const ChromeApplicationStateInfo& other) const { return !(*this == other); }
24197 
24198   bool ParseFromArray(const void*, size_t) override;
24199   std::string SerializeAsString() const override;
24200   std::vector<uint8_t> SerializeAsArray() const override;
24201   void Serialize(::protozero::Message*) const;
24202 
has_application_state() const24203   bool has_application_state() const { return _has_field_[1]; }
application_state() const24204   ChromeApplicationStateInfo_ChromeApplicationState application_state() const { return application_state_; }
set_application_state(ChromeApplicationStateInfo_ChromeApplicationState value)24205   void set_application_state(ChromeApplicationStateInfo_ChromeApplicationState value) { application_state_ = value; _has_field_.set(1); }
24206 
24207  private:
24208   ChromeApplicationStateInfo_ChromeApplicationState application_state_{};
24209 
24210   // Allows to preserve unknown protobuf fields for compatibility
24211   // with future versions of .proto files.
24212   std::string unknown_fields_;
24213 
24214   std::bitset<2> _has_field_{};
24215 };
24216 
24217 }  // namespace perfetto
24218 }  // namespace protos
24219 }  // namespace gen
24220 
24221 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_APPLICATION_STATE_INFO_PROTO_CPP_H_
24222 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
24223 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
24224 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
24225 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
24226 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
24227 #if defined(__GNUC__) || defined(__clang__)
24228 #pragma GCC diagnostic push
24229 #pragma GCC diagnostic ignored "-Wfloat-equal"
24230 #endif
24231 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_application_state_info.gen.h"
24232 
24233 namespace perfetto {
24234 namespace protos {
24235 namespace gen {
24236 
24237 ChromeApplicationStateInfo::ChromeApplicationStateInfo() = default;
24238 ChromeApplicationStateInfo::~ChromeApplicationStateInfo() = default;
24239 ChromeApplicationStateInfo::ChromeApplicationStateInfo(const ChromeApplicationStateInfo&) = default;
24240 ChromeApplicationStateInfo& ChromeApplicationStateInfo::operator=(const ChromeApplicationStateInfo&) = default;
24241 ChromeApplicationStateInfo::ChromeApplicationStateInfo(ChromeApplicationStateInfo&&) noexcept = default;
24242 ChromeApplicationStateInfo& ChromeApplicationStateInfo::operator=(ChromeApplicationStateInfo&&) = default;
24243 
operator ==(const ChromeApplicationStateInfo & other) const24244 bool ChromeApplicationStateInfo::operator==(const ChromeApplicationStateInfo& other) const {
24245   return unknown_fields_ == other.unknown_fields_
24246    && application_state_ == other.application_state_;
24247 }
24248 
ParseFromArray(const void * raw,size_t size)24249 bool ChromeApplicationStateInfo::ParseFromArray(const void* raw, size_t size) {
24250   unknown_fields_.clear();
24251   bool packed_error = false;
24252 
24253   ::protozero::ProtoDecoder dec(raw, size);
24254   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
24255     if (field.id() < _has_field_.size()) {
24256       _has_field_.set(field.id());
24257     }
24258     switch (field.id()) {
24259       case 1 /* application_state */:
24260         field.get(&application_state_);
24261         break;
24262       default:
24263         field.SerializeAndAppendTo(&unknown_fields_);
24264         break;
24265     }
24266   }
24267   return !packed_error && !dec.bytes_left();
24268 }
24269 
SerializeAsString() const24270 std::string ChromeApplicationStateInfo::SerializeAsString() const {
24271   ::protozero::HeapBuffered<::protozero::Message> msg;
24272   Serialize(msg.get());
24273   return msg.SerializeAsString();
24274 }
24275 
SerializeAsArray() const24276 std::vector<uint8_t> ChromeApplicationStateInfo::SerializeAsArray() const {
24277   ::protozero::HeapBuffered<::protozero::Message> msg;
24278   Serialize(msg.get());
24279   return msg.SerializeAsArray();
24280 }
24281 
Serialize(::protozero::Message * msg) const24282 void ChromeApplicationStateInfo::Serialize(::protozero::Message* msg) const {
24283   // Field 1: application_state
24284   if (_has_field_[1]) {
24285     msg->AppendVarInt(1, application_state_);
24286   }
24287 
24288   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
24289 }
24290 
24291 }  // namespace perfetto
24292 }  // namespace protos
24293 }  // namespace gen
24294 #if defined(__GNUC__) || defined(__clang__)
24295 #pragma GCC diagnostic pop
24296 #endif
24297 // gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_compositor_scheduler_state.gen.cc
24298 // gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/chrome_compositor_scheduler_state.gen.h
24299 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
24300 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_COMPOSITOR_SCHEDULER_STATE_PROTO_CPP_H_
24301 #define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_COMPOSITOR_SCHEDULER_STATE_PROTO_CPP_H_
24302 
24303 #include <stdint.h>
24304 #include <bitset>
24305 #include <vector>
24306 #include <string>
24307 #include <type_traits>
24308 
24309 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
24310 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
24311 // gen_amalgamated expanded: #include "perfetto/base/export.h"
24312 
24313 namespace perfetto {
24314 namespace protos {
24315 namespace gen {
24316 class CompositorTimingHistory;
24317 class BeginFrameSourceState;
24318 class BeginFrameArgs;
24319 class SourceLocation;
24320 class BeginFrameObserverState;
24321 class BeginImplFrameArgs;
24322 class BeginImplFrameArgs_TimestampsInUs;
24323 class ChromeCompositorStateMachine;
24324 class ChromeCompositorStateMachine_MinorState;
24325 class ChromeCompositorStateMachine_MajorState;
24326 class ChromeCompositorSchedulerState;
24327 enum ChromeCompositorSchedulerAction : int;
24328 enum BeginFrameArgs_BeginFrameArgsType : int;
24329 enum BeginImplFrameArgs_State : int;
24330 enum ChromeCompositorStateMachine_MinorState_TreePriority : int;
24331 enum ChromeCompositorStateMachine_MinorState_ScrollHandlerState : int;
24332 enum ChromeCompositorStateMachine_MajorState_BeginImplFrameState : int;
24333 enum ChromeCompositorStateMachine_MajorState_BeginMainFrameState : int;
24334 enum ChromeCompositorStateMachine_MajorState_LayerTreeFrameSinkState : int;
24335 enum ChromeCompositorStateMachine_MajorState_ForcedRedrawOnTimeoutState : int;
24336 enum ChromeCompositorSchedulerState_BeginImplFrameDeadlineMode : int;
24337 }  // namespace perfetto
24338 }  // namespace protos
24339 }  // namespace gen
24340 
24341 namespace protozero {
24342 class Message;
24343 }  // namespace protozero
24344 
24345 namespace perfetto {
24346 namespace protos {
24347 namespace gen {
24348 enum ChromeCompositorSchedulerAction : int {
24349   CC_SCHEDULER_ACTION_UNSPECIFIED = 0,
24350   CC_SCHEDULER_ACTION_NONE = 1,
24351   CC_SCHEDULER_ACTION_SEND_BEGIN_MAIN_FRAME = 2,
24352   CC_SCHEDULER_ACTION_COMMIT = 3,
24353   CC_SCHEDULER_ACTION_ACTIVATE_SYNC_TREE = 4,
24354   CC_SCHEDULER_ACTION_DRAW_IF_POSSIBLE = 5,
24355   CC_SCHEDULER_ACTION_DRAW_FORCED = 6,
24356   CC_SCHEDULER_ACTION_DRAW_ABORT = 7,
24357   CC_SCHEDULER_ACTION_BEGIN_LAYER_TREE_FRAME_SINK_CREATION = 8,
24358   CC_SCHEDULER_ACTION_PREPARE_TILES = 9,
24359   CC_SCHEDULER_ACTION_INVALIDATE_LAYER_TREE_FRAME_SINK = 10,
24360   CC_SCHEDULER_ACTION_PERFORM_IMPL_SIDE_INVALIDATION = 11,
24361   CC_SCHEDULER_ACTION_NOTIFY_BEGIN_MAIN_FRAME_NOT_EXPECTED_UNTIL = 12,
24362   CC_SCHEDULER_ACTION_NOTIFY_BEGIN_MAIN_FRAME_NOT_EXPECTED_SOON = 13,
24363 };
24364 enum BeginFrameArgs_BeginFrameArgsType : int {
24365   BeginFrameArgs_BeginFrameArgsType_BEGIN_FRAME_ARGS_TYPE_UNSPECIFIED = 0,
24366   BeginFrameArgs_BeginFrameArgsType_BEGIN_FRAME_ARGS_TYPE_INVALID = 1,
24367   BeginFrameArgs_BeginFrameArgsType_BEGIN_FRAME_ARGS_TYPE_NORMAL = 2,
24368   BeginFrameArgs_BeginFrameArgsType_BEGIN_FRAME_ARGS_TYPE_MISSED = 3,
24369 };
24370 enum BeginImplFrameArgs_State : int {
24371   BeginImplFrameArgs_State_BEGIN_FRAME_FINISHED = 0,
24372   BeginImplFrameArgs_State_BEGIN_FRAME_USING = 1,
24373 };
24374 enum ChromeCompositorStateMachine_MinorState_TreePriority : int {
24375   ChromeCompositorStateMachine_MinorState_TreePriority_TREE_PRIORITY_UNSPECIFIED = 0,
24376   ChromeCompositorStateMachine_MinorState_TreePriority_TREE_PRIORITY_SAME_PRIORITY_FOR_BOTH_TREES = 1,
24377   ChromeCompositorStateMachine_MinorState_TreePriority_TREE_PRIORITY_SMOOTHNESS_TAKES_PRIORITY = 2,
24378   ChromeCompositorStateMachine_MinorState_TreePriority_TREE_PRIORITY_NEW_CONTENT_TAKES_PRIORITY = 3,
24379 };
24380 enum ChromeCompositorStateMachine_MinorState_ScrollHandlerState : int {
24381   ChromeCompositorStateMachine_MinorState_ScrollHandlerState_SCROLL_HANDLER_UNSPECIFIED = 0,
24382   ChromeCompositorStateMachine_MinorState_ScrollHandlerState_SCROLL_AFFECTS_SCROLL_HANDLER = 1,
24383   ChromeCompositorStateMachine_MinorState_ScrollHandlerState_SCROLL_DOES_NOT_AFFECT_SCROLL_HANDLER = 2,
24384 };
24385 enum ChromeCompositorStateMachine_MajorState_BeginImplFrameState : int {
24386   ChromeCompositorStateMachine_MajorState_BeginImplFrameState_BEGIN_IMPL_FRAME_UNSPECIFIED = 0,
24387   ChromeCompositorStateMachine_MajorState_BeginImplFrameState_BEGIN_IMPL_FRAME_IDLE = 1,
24388   ChromeCompositorStateMachine_MajorState_BeginImplFrameState_BEGIN_IMPL_FRAME_INSIDE_BEGIN_FRAME = 2,
24389   ChromeCompositorStateMachine_MajorState_BeginImplFrameState_BEGIN_IMPL_FRAME_INSIDE_DEADLINE = 3,
24390 };
24391 enum ChromeCompositorStateMachine_MajorState_BeginMainFrameState : int {
24392   ChromeCompositorStateMachine_MajorState_BeginMainFrameState_BEGIN_MAIN_FRAME_UNSPECIFIED = 0,
24393   ChromeCompositorStateMachine_MajorState_BeginMainFrameState_BEGIN_MAIN_FRAME_IDLE = 1,
24394   ChromeCompositorStateMachine_MajorState_BeginMainFrameState_BEGIN_MAIN_FRAME_SENT = 2,
24395   ChromeCompositorStateMachine_MajorState_BeginMainFrameState_BEGIN_MAIN_FRAME_READY_TO_COMMIT = 3,
24396 };
24397 enum ChromeCompositorStateMachine_MajorState_LayerTreeFrameSinkState : int {
24398   ChromeCompositorStateMachine_MajorState_LayerTreeFrameSinkState_LAYER_TREE_FRAME_UNSPECIFIED = 0,
24399   ChromeCompositorStateMachine_MajorState_LayerTreeFrameSinkState_LAYER_TREE_FRAME_NONE = 1,
24400   ChromeCompositorStateMachine_MajorState_LayerTreeFrameSinkState_LAYER_TREE_FRAME_ACTIVE = 2,
24401   ChromeCompositorStateMachine_MajorState_LayerTreeFrameSinkState_LAYER_TREE_FRAME_CREATING = 3,
24402   ChromeCompositorStateMachine_MajorState_LayerTreeFrameSinkState_LAYER_TREE_FRAME_WAITING_FOR_FIRST_COMMIT = 4,
24403   ChromeCompositorStateMachine_MajorState_LayerTreeFrameSinkState_LAYER_TREE_FRAME_WAITING_FOR_FIRST_ACTIVATION = 5,
24404 };
24405 enum ChromeCompositorStateMachine_MajorState_ForcedRedrawOnTimeoutState : int {
24406   ChromeCompositorStateMachine_MajorState_ForcedRedrawOnTimeoutState_FORCED_REDRAW_UNSPECIFIED = 0,
24407   ChromeCompositorStateMachine_MajorState_ForcedRedrawOnTimeoutState_FORCED_REDRAW_IDLE = 1,
24408   ChromeCompositorStateMachine_MajorState_ForcedRedrawOnTimeoutState_FORCED_REDRAW_WAITING_FOR_COMMIT = 2,
24409   ChromeCompositorStateMachine_MajorState_ForcedRedrawOnTimeoutState_FORCED_REDRAW_WAITING_FOR_ACTIVATION = 3,
24410   ChromeCompositorStateMachine_MajorState_ForcedRedrawOnTimeoutState_FORCED_REDRAW_WAITING_FOR_DRAW = 4,
24411 };
24412 enum ChromeCompositorSchedulerState_BeginImplFrameDeadlineMode : int {
24413   ChromeCompositorSchedulerState_BeginImplFrameDeadlineMode_DEADLINE_MODE_UNSPECIFIED = 0,
24414   ChromeCompositorSchedulerState_BeginImplFrameDeadlineMode_DEADLINE_MODE_NONE = 1,
24415   ChromeCompositorSchedulerState_BeginImplFrameDeadlineMode_DEADLINE_MODE_IMMEDIATE = 2,
24416   ChromeCompositorSchedulerState_BeginImplFrameDeadlineMode_DEADLINE_MODE_REGULAR = 3,
24417   ChromeCompositorSchedulerState_BeginImplFrameDeadlineMode_DEADLINE_MODE_LATE = 4,
24418   ChromeCompositorSchedulerState_BeginImplFrameDeadlineMode_DEADLINE_MODE_BLOCKED = 5,
24419 };
24420 
24421 class PERFETTO_EXPORT CompositorTimingHistory : public ::protozero::CppMessageObj {
24422  public:
24423   enum FieldNumbers {
24424     kBeginMainFrameQueueCriticalEstimateDeltaUsFieldNumber = 1,
24425     kBeginMainFrameQueueNotCriticalEstimateDeltaUsFieldNumber = 2,
24426     kBeginMainFrameStartToReadyToCommitEstimateDeltaUsFieldNumber = 3,
24427     kCommitToReadyToActivateEstimateDeltaUsFieldNumber = 4,
24428     kPrepareTilesEstimateDeltaUsFieldNumber = 5,
24429     kActivateEstimateDeltaUsFieldNumber = 6,
24430     kDrawEstimateDeltaUsFieldNumber = 7,
24431   };
24432 
24433   CompositorTimingHistory();
24434   ~CompositorTimingHistory() override;
24435   CompositorTimingHistory(CompositorTimingHistory&&) noexcept;
24436   CompositorTimingHistory& operator=(CompositorTimingHistory&&);
24437   CompositorTimingHistory(const CompositorTimingHistory&);
24438   CompositorTimingHistory& operator=(const CompositorTimingHistory&);
24439   bool operator==(const CompositorTimingHistory&) const;
operator !=(const CompositorTimingHistory & other) const24440   bool operator!=(const CompositorTimingHistory& other) const { return !(*this == other); }
24441 
24442   bool ParseFromArray(const void*, size_t) override;
24443   std::string SerializeAsString() const override;
24444   std::vector<uint8_t> SerializeAsArray() const override;
24445   void Serialize(::protozero::Message*) const;
24446 
has_begin_main_frame_queue_critical_estimate_delta_us() const24447   bool has_begin_main_frame_queue_critical_estimate_delta_us() const { return _has_field_[1]; }
begin_main_frame_queue_critical_estimate_delta_us() const24448   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)24449   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); }
24450 
has_begin_main_frame_queue_not_critical_estimate_delta_us() const24451   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() const24452   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)24453   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); }
24454 
has_begin_main_frame_start_to_ready_to_commit_estimate_delta_us() const24455   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() const24456   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)24457   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); }
24458 
has_commit_to_ready_to_activate_estimate_delta_us() const24459   bool has_commit_to_ready_to_activate_estimate_delta_us() const { return _has_field_[4]; }
commit_to_ready_to_activate_estimate_delta_us() const24460   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)24461   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); }
24462 
has_prepare_tiles_estimate_delta_us() const24463   bool has_prepare_tiles_estimate_delta_us() const { return _has_field_[5]; }
prepare_tiles_estimate_delta_us() const24464   int64_t prepare_tiles_estimate_delta_us() const { return prepare_tiles_estimate_delta_us_; }
set_prepare_tiles_estimate_delta_us(int64_t value)24465   void set_prepare_tiles_estimate_delta_us(int64_t value) { prepare_tiles_estimate_delta_us_ = value; _has_field_.set(5); }
24466 
has_activate_estimate_delta_us() const24467   bool has_activate_estimate_delta_us() const { return _has_field_[6]; }
activate_estimate_delta_us() const24468   int64_t activate_estimate_delta_us() const { return activate_estimate_delta_us_; }
set_activate_estimate_delta_us(int64_t value)24469   void set_activate_estimate_delta_us(int64_t value) { activate_estimate_delta_us_ = value; _has_field_.set(6); }
24470 
has_draw_estimate_delta_us() const24471   bool has_draw_estimate_delta_us() const { return _has_field_[7]; }
draw_estimate_delta_us() const24472   int64_t draw_estimate_delta_us() const { return draw_estimate_delta_us_; }
set_draw_estimate_delta_us(int64_t value)24473   void set_draw_estimate_delta_us(int64_t value) { draw_estimate_delta_us_ = value; _has_field_.set(7); }
24474 
24475  private:
24476   int64_t begin_main_frame_queue_critical_estimate_delta_us_{};
24477   int64_t begin_main_frame_queue_not_critical_estimate_delta_us_{};
24478   int64_t begin_main_frame_start_to_ready_to_commit_estimate_delta_us_{};
24479   int64_t commit_to_ready_to_activate_estimate_delta_us_{};
24480   int64_t prepare_tiles_estimate_delta_us_{};
24481   int64_t activate_estimate_delta_us_{};
24482   int64_t draw_estimate_delta_us_{};
24483 
24484   // Allows to preserve unknown protobuf fields for compatibility
24485   // with future versions of .proto files.
24486   std::string unknown_fields_;
24487 
24488   std::bitset<8> _has_field_{};
24489 };
24490 
24491 
24492 class PERFETTO_EXPORT BeginFrameSourceState : public ::protozero::CppMessageObj {
24493  public:
24494   enum FieldNumbers {
24495     kSourceIdFieldNumber = 1,
24496     kPausedFieldNumber = 2,
24497     kNumObserversFieldNumber = 3,
24498     kLastBeginFrameArgsFieldNumber = 4,
24499   };
24500 
24501   BeginFrameSourceState();
24502   ~BeginFrameSourceState() override;
24503   BeginFrameSourceState(BeginFrameSourceState&&) noexcept;
24504   BeginFrameSourceState& operator=(BeginFrameSourceState&&);
24505   BeginFrameSourceState(const BeginFrameSourceState&);
24506   BeginFrameSourceState& operator=(const BeginFrameSourceState&);
24507   bool operator==(const BeginFrameSourceState&) const;
operator !=(const BeginFrameSourceState & other) const24508   bool operator!=(const BeginFrameSourceState& other) const { return !(*this == other); }
24509 
24510   bool ParseFromArray(const void*, size_t) override;
24511   std::string SerializeAsString() const override;
24512   std::vector<uint8_t> SerializeAsArray() const override;
24513   void Serialize(::protozero::Message*) const;
24514 
has_source_id() const24515   bool has_source_id() const { return _has_field_[1]; }
source_id() const24516   uint32_t source_id() const { return source_id_; }
set_source_id(uint32_t value)24517   void set_source_id(uint32_t value) { source_id_ = value; _has_field_.set(1); }
24518 
has_paused() const24519   bool has_paused() const { return _has_field_[2]; }
paused() const24520   bool paused() const { return paused_; }
set_paused(bool value)24521   void set_paused(bool value) { paused_ = value; _has_field_.set(2); }
24522 
has_num_observers() const24523   bool has_num_observers() const { return _has_field_[3]; }
num_observers() const24524   uint32_t num_observers() const { return num_observers_; }
set_num_observers(uint32_t value)24525   void set_num_observers(uint32_t value) { num_observers_ = value; _has_field_.set(3); }
24526 
has_last_begin_frame_args() const24527   bool has_last_begin_frame_args() const { return _has_field_[4]; }
last_begin_frame_args() const24528   const BeginFrameArgs& last_begin_frame_args() const { return *last_begin_frame_args_; }
mutable_last_begin_frame_args()24529   BeginFrameArgs* mutable_last_begin_frame_args() { _has_field_.set(4); return last_begin_frame_args_.get(); }
24530 
24531  private:
24532   uint32_t source_id_{};
24533   bool paused_{};
24534   uint32_t num_observers_{};
24535   ::protozero::CopyablePtr<BeginFrameArgs> last_begin_frame_args_;
24536 
24537   // Allows to preserve unknown protobuf fields for compatibility
24538   // with future versions of .proto files.
24539   std::string unknown_fields_;
24540 
24541   std::bitset<5> _has_field_{};
24542 };
24543 
24544 
24545 class PERFETTO_EXPORT BeginFrameArgs : public ::protozero::CppMessageObj {
24546  public:
24547   using BeginFrameArgsType = BeginFrameArgs_BeginFrameArgsType;
24548   static constexpr auto BEGIN_FRAME_ARGS_TYPE_UNSPECIFIED = BeginFrameArgs_BeginFrameArgsType_BEGIN_FRAME_ARGS_TYPE_UNSPECIFIED;
24549   static constexpr auto BEGIN_FRAME_ARGS_TYPE_INVALID = BeginFrameArgs_BeginFrameArgsType_BEGIN_FRAME_ARGS_TYPE_INVALID;
24550   static constexpr auto BEGIN_FRAME_ARGS_TYPE_NORMAL = BeginFrameArgs_BeginFrameArgsType_BEGIN_FRAME_ARGS_TYPE_NORMAL;
24551   static constexpr auto BEGIN_FRAME_ARGS_TYPE_MISSED = BeginFrameArgs_BeginFrameArgsType_BEGIN_FRAME_ARGS_TYPE_MISSED;
24552   static constexpr auto BeginFrameArgsType_MIN = BeginFrameArgs_BeginFrameArgsType_BEGIN_FRAME_ARGS_TYPE_UNSPECIFIED;
24553   static constexpr auto BeginFrameArgsType_MAX = BeginFrameArgs_BeginFrameArgsType_BEGIN_FRAME_ARGS_TYPE_MISSED;
24554   enum FieldNumbers {
24555     kTypeFieldNumber = 1,
24556     kSourceIdFieldNumber = 2,
24557     kSequenceNumberFieldNumber = 3,
24558     kFrameTimeUsFieldNumber = 4,
24559     kDeadlineUsFieldNumber = 5,
24560     kIntervalDeltaUsFieldNumber = 6,
24561     kOnCriticalPathFieldNumber = 7,
24562     kAnimateOnlyFieldNumber = 8,
24563     kSourceLocationIidFieldNumber = 9,
24564     kSourceLocationFieldNumber = 10,
24565     kFramesThrottledSinceLastFieldNumber = 12,
24566   };
24567 
24568   BeginFrameArgs();
24569   ~BeginFrameArgs() override;
24570   BeginFrameArgs(BeginFrameArgs&&) noexcept;
24571   BeginFrameArgs& operator=(BeginFrameArgs&&);
24572   BeginFrameArgs(const BeginFrameArgs&);
24573   BeginFrameArgs& operator=(const BeginFrameArgs&);
24574   bool operator==(const BeginFrameArgs&) const;
operator !=(const BeginFrameArgs & other) const24575   bool operator!=(const BeginFrameArgs& other) const { return !(*this == other); }
24576 
24577   bool ParseFromArray(const void*, size_t) override;
24578   std::string SerializeAsString() const override;
24579   std::vector<uint8_t> SerializeAsArray() const override;
24580   void Serialize(::protozero::Message*) const;
24581 
has_type() const24582   bool has_type() const { return _has_field_[1]; }
type() const24583   BeginFrameArgs_BeginFrameArgsType type() const { return type_; }
set_type(BeginFrameArgs_BeginFrameArgsType value)24584   void set_type(BeginFrameArgs_BeginFrameArgsType value) { type_ = value; _has_field_.set(1); }
24585 
has_source_id() const24586   bool has_source_id() const { return _has_field_[2]; }
source_id() const24587   uint64_t source_id() const { return source_id_; }
set_source_id(uint64_t value)24588   void set_source_id(uint64_t value) { source_id_ = value; _has_field_.set(2); }
24589 
has_sequence_number() const24590   bool has_sequence_number() const { return _has_field_[3]; }
sequence_number() const24591   uint64_t sequence_number() const { return sequence_number_; }
set_sequence_number(uint64_t value)24592   void set_sequence_number(uint64_t value) { sequence_number_ = value; _has_field_.set(3); }
24593 
has_frame_time_us() const24594   bool has_frame_time_us() const { return _has_field_[4]; }
frame_time_us() const24595   int64_t frame_time_us() const { return frame_time_us_; }
set_frame_time_us(int64_t value)24596   void set_frame_time_us(int64_t value) { frame_time_us_ = value; _has_field_.set(4); }
24597 
has_deadline_us() const24598   bool has_deadline_us() const { return _has_field_[5]; }
deadline_us() const24599   int64_t deadline_us() const { return deadline_us_; }
set_deadline_us(int64_t value)24600   void set_deadline_us(int64_t value) { deadline_us_ = value; _has_field_.set(5); }
24601 
has_interval_delta_us() const24602   bool has_interval_delta_us() const { return _has_field_[6]; }
interval_delta_us() const24603   int64_t interval_delta_us() const { return interval_delta_us_; }
set_interval_delta_us(int64_t value)24604   void set_interval_delta_us(int64_t value) { interval_delta_us_ = value; _has_field_.set(6); }
24605 
has_on_critical_path() const24606   bool has_on_critical_path() const { return _has_field_[7]; }
on_critical_path() const24607   bool on_critical_path() const { return on_critical_path_; }
set_on_critical_path(bool value)24608   void set_on_critical_path(bool value) { on_critical_path_ = value; _has_field_.set(7); }
24609 
has_animate_only() const24610   bool has_animate_only() const { return _has_field_[8]; }
animate_only() const24611   bool animate_only() const { return animate_only_; }
set_animate_only(bool value)24612   void set_animate_only(bool value) { animate_only_ = value; _has_field_.set(8); }
24613 
has_source_location_iid() const24614   bool has_source_location_iid() const { return _has_field_[9]; }
source_location_iid() const24615   uint64_t source_location_iid() const { return source_location_iid_; }
set_source_location_iid(uint64_t value)24616   void set_source_location_iid(uint64_t value) { source_location_iid_ = value; _has_field_.set(9); }
24617 
has_source_location() const24618   bool has_source_location() const { return _has_field_[10]; }
source_location() const24619   const SourceLocation& source_location() const { return *source_location_; }
mutable_source_location()24620   SourceLocation* mutable_source_location() { _has_field_.set(10); return source_location_.get(); }
24621 
has_frames_throttled_since_last() const24622   bool has_frames_throttled_since_last() const { return _has_field_[12]; }
frames_throttled_since_last() const24623   int64_t frames_throttled_since_last() const { return frames_throttled_since_last_; }
set_frames_throttled_since_last(int64_t value)24624   void set_frames_throttled_since_last(int64_t value) { frames_throttled_since_last_ = value; _has_field_.set(12); }
24625 
24626  private:
24627   BeginFrameArgs_BeginFrameArgsType type_{};
24628   uint64_t source_id_{};
24629   uint64_t sequence_number_{};
24630   int64_t frame_time_us_{};
24631   int64_t deadline_us_{};
24632   int64_t interval_delta_us_{};
24633   bool on_critical_path_{};
24634   bool animate_only_{};
24635   uint64_t source_location_iid_{};
24636   ::protozero::CopyablePtr<SourceLocation> source_location_;
24637   int64_t frames_throttled_since_last_{};
24638 
24639   // Allows to preserve unknown protobuf fields for compatibility
24640   // with future versions of .proto files.
24641   std::string unknown_fields_;
24642 
24643   std::bitset<13> _has_field_{};
24644 };
24645 
24646 
24647 class PERFETTO_EXPORT BeginFrameObserverState : public ::protozero::CppMessageObj {
24648  public:
24649   enum FieldNumbers {
24650     kDroppedBeginFrameArgsFieldNumber = 1,
24651     kLastBeginFrameArgsFieldNumber = 2,
24652   };
24653 
24654   BeginFrameObserverState();
24655   ~BeginFrameObserverState() override;
24656   BeginFrameObserverState(BeginFrameObserverState&&) noexcept;
24657   BeginFrameObserverState& operator=(BeginFrameObserverState&&);
24658   BeginFrameObserverState(const BeginFrameObserverState&);
24659   BeginFrameObserverState& operator=(const BeginFrameObserverState&);
24660   bool operator==(const BeginFrameObserverState&) const;
operator !=(const BeginFrameObserverState & other) const24661   bool operator!=(const BeginFrameObserverState& other) const { return !(*this == other); }
24662 
24663   bool ParseFromArray(const void*, size_t) override;
24664   std::string SerializeAsString() const override;
24665   std::vector<uint8_t> SerializeAsArray() const override;
24666   void Serialize(::protozero::Message*) const;
24667 
has_dropped_begin_frame_args() const24668   bool has_dropped_begin_frame_args() const { return _has_field_[1]; }
dropped_begin_frame_args() const24669   int64_t dropped_begin_frame_args() const { return dropped_begin_frame_args_; }
set_dropped_begin_frame_args(int64_t value)24670   void set_dropped_begin_frame_args(int64_t value) { dropped_begin_frame_args_ = value; _has_field_.set(1); }
24671 
has_last_begin_frame_args() const24672   bool has_last_begin_frame_args() const { return _has_field_[2]; }
last_begin_frame_args() const24673   const BeginFrameArgs& last_begin_frame_args() const { return *last_begin_frame_args_; }
mutable_last_begin_frame_args()24674   BeginFrameArgs* mutable_last_begin_frame_args() { _has_field_.set(2); return last_begin_frame_args_.get(); }
24675 
24676  private:
24677   int64_t dropped_begin_frame_args_{};
24678   ::protozero::CopyablePtr<BeginFrameArgs> last_begin_frame_args_;
24679 
24680   // Allows to preserve unknown protobuf fields for compatibility
24681   // with future versions of .proto files.
24682   std::string unknown_fields_;
24683 
24684   std::bitset<3> _has_field_{};
24685 };
24686 
24687 
24688 class PERFETTO_EXPORT BeginImplFrameArgs : public ::protozero::CppMessageObj {
24689  public:
24690   using TimestampsInUs = BeginImplFrameArgs_TimestampsInUs;
24691   using State = BeginImplFrameArgs_State;
24692   static constexpr auto BEGIN_FRAME_FINISHED = BeginImplFrameArgs_State_BEGIN_FRAME_FINISHED;
24693   static constexpr auto BEGIN_FRAME_USING = BeginImplFrameArgs_State_BEGIN_FRAME_USING;
24694   static constexpr auto State_MIN = BeginImplFrameArgs_State_BEGIN_FRAME_FINISHED;
24695   static constexpr auto State_MAX = BeginImplFrameArgs_State_BEGIN_FRAME_USING;
24696   enum FieldNumbers {
24697     kUpdatedAtUsFieldNumber = 1,
24698     kFinishedAtUsFieldNumber = 2,
24699     kStateFieldNumber = 3,
24700     kCurrentArgsFieldNumber = 4,
24701     kLastArgsFieldNumber = 5,
24702     kTimestampsInUsFieldNumber = 6,
24703   };
24704 
24705   BeginImplFrameArgs();
24706   ~BeginImplFrameArgs() override;
24707   BeginImplFrameArgs(BeginImplFrameArgs&&) noexcept;
24708   BeginImplFrameArgs& operator=(BeginImplFrameArgs&&);
24709   BeginImplFrameArgs(const BeginImplFrameArgs&);
24710   BeginImplFrameArgs& operator=(const BeginImplFrameArgs&);
24711   bool operator==(const BeginImplFrameArgs&) const;
operator !=(const BeginImplFrameArgs & other) const24712   bool operator!=(const BeginImplFrameArgs& other) const { return !(*this == other); }
24713 
24714   bool ParseFromArray(const void*, size_t) override;
24715   std::string SerializeAsString() const override;
24716   std::vector<uint8_t> SerializeAsArray() const override;
24717   void Serialize(::protozero::Message*) const;
24718 
has_updated_at_us() const24719   bool has_updated_at_us() const { return _has_field_[1]; }
updated_at_us() const24720   int64_t updated_at_us() const { return updated_at_us_; }
set_updated_at_us(int64_t value)24721   void set_updated_at_us(int64_t value) { updated_at_us_ = value; _has_field_.set(1); }
24722 
has_finished_at_us() const24723   bool has_finished_at_us() const { return _has_field_[2]; }
finished_at_us() const24724   int64_t finished_at_us() const { return finished_at_us_; }
set_finished_at_us(int64_t value)24725   void set_finished_at_us(int64_t value) { finished_at_us_ = value; _has_field_.set(2); }
24726 
has_state() const24727   bool has_state() const { return _has_field_[3]; }
state() const24728   BeginImplFrameArgs_State state() const { return state_; }
set_state(BeginImplFrameArgs_State value)24729   void set_state(BeginImplFrameArgs_State value) { state_ = value; _has_field_.set(3); }
24730 
has_current_args() const24731   bool has_current_args() const { return _has_field_[4]; }
current_args() const24732   const BeginFrameArgs& current_args() const { return *current_args_; }
mutable_current_args()24733   BeginFrameArgs* mutable_current_args() { _has_field_.set(4); return current_args_.get(); }
24734 
has_last_args() const24735   bool has_last_args() const { return _has_field_[5]; }
last_args() const24736   const BeginFrameArgs& last_args() const { return *last_args_; }
mutable_last_args()24737   BeginFrameArgs* mutable_last_args() { _has_field_.set(5); return last_args_.get(); }
24738 
has_timestamps_in_us() const24739   bool has_timestamps_in_us() const { return _has_field_[6]; }
timestamps_in_us() const24740   const BeginImplFrameArgs_TimestampsInUs& timestamps_in_us() const { return *timestamps_in_us_; }
mutable_timestamps_in_us()24741   BeginImplFrameArgs_TimestampsInUs* mutable_timestamps_in_us() { _has_field_.set(6); return timestamps_in_us_.get(); }
24742 
24743  private:
24744   int64_t updated_at_us_{};
24745   int64_t finished_at_us_{};
24746   BeginImplFrameArgs_State state_{};
24747   ::protozero::CopyablePtr<BeginFrameArgs> current_args_;
24748   ::protozero::CopyablePtr<BeginFrameArgs> last_args_;
24749   ::protozero::CopyablePtr<BeginImplFrameArgs_TimestampsInUs> timestamps_in_us_;
24750 
24751   // Allows to preserve unknown protobuf fields for compatibility
24752   // with future versions of .proto files.
24753   std::string unknown_fields_;
24754 
24755   std::bitset<7> _has_field_{};
24756 };
24757 
24758 
24759 class PERFETTO_EXPORT BeginImplFrameArgs_TimestampsInUs : public ::protozero::CppMessageObj {
24760  public:
24761   enum FieldNumbers {
24762     kIntervalDeltaFieldNumber = 1,
24763     kNowToDeadlineDeltaFieldNumber = 2,
24764     kFrameTimeToNowDeltaFieldNumber = 3,
24765     kFrameTimeToDeadlineDeltaFieldNumber = 4,
24766     kNowFieldNumber = 5,
24767     kFrameTimeFieldNumber = 6,
24768     kDeadlineFieldNumber = 7,
24769   };
24770 
24771   BeginImplFrameArgs_TimestampsInUs();
24772   ~BeginImplFrameArgs_TimestampsInUs() override;
24773   BeginImplFrameArgs_TimestampsInUs(BeginImplFrameArgs_TimestampsInUs&&) noexcept;
24774   BeginImplFrameArgs_TimestampsInUs& operator=(BeginImplFrameArgs_TimestampsInUs&&);
24775   BeginImplFrameArgs_TimestampsInUs(const BeginImplFrameArgs_TimestampsInUs&);
24776   BeginImplFrameArgs_TimestampsInUs& operator=(const BeginImplFrameArgs_TimestampsInUs&);
24777   bool operator==(const BeginImplFrameArgs_TimestampsInUs&) const;
operator !=(const BeginImplFrameArgs_TimestampsInUs & other) const24778   bool operator!=(const BeginImplFrameArgs_TimestampsInUs& other) const { return !(*this == other); }
24779 
24780   bool ParseFromArray(const void*, size_t) override;
24781   std::string SerializeAsString() const override;
24782   std::vector<uint8_t> SerializeAsArray() const override;
24783   void Serialize(::protozero::Message*) const;
24784 
has_interval_delta() const24785   bool has_interval_delta() const { return _has_field_[1]; }
interval_delta() const24786   int64_t interval_delta() const { return interval_delta_; }
set_interval_delta(int64_t value)24787   void set_interval_delta(int64_t value) { interval_delta_ = value; _has_field_.set(1); }
24788 
has_now_to_deadline_delta() const24789   bool has_now_to_deadline_delta() const { return _has_field_[2]; }
now_to_deadline_delta() const24790   int64_t now_to_deadline_delta() const { return now_to_deadline_delta_; }
set_now_to_deadline_delta(int64_t value)24791   void set_now_to_deadline_delta(int64_t value) { now_to_deadline_delta_ = value; _has_field_.set(2); }
24792 
has_frame_time_to_now_delta() const24793   bool has_frame_time_to_now_delta() const { return _has_field_[3]; }
frame_time_to_now_delta() const24794   int64_t frame_time_to_now_delta() const { return frame_time_to_now_delta_; }
set_frame_time_to_now_delta(int64_t value)24795   void set_frame_time_to_now_delta(int64_t value) { frame_time_to_now_delta_ = value; _has_field_.set(3); }
24796 
has_frame_time_to_deadline_delta() const24797   bool has_frame_time_to_deadline_delta() const { return _has_field_[4]; }
frame_time_to_deadline_delta() const24798   int64_t frame_time_to_deadline_delta() const { return frame_time_to_deadline_delta_; }
set_frame_time_to_deadline_delta(int64_t value)24799   void set_frame_time_to_deadline_delta(int64_t value) { frame_time_to_deadline_delta_ = value; _has_field_.set(4); }
24800 
has_now() const24801   bool has_now() const { return _has_field_[5]; }
now() const24802   int64_t now() const { return now_; }
set_now(int64_t value)24803   void set_now(int64_t value) { now_ = value; _has_field_.set(5); }
24804 
has_frame_time() const24805   bool has_frame_time() const { return _has_field_[6]; }
frame_time() const24806   int64_t frame_time() const { return frame_time_; }
set_frame_time(int64_t value)24807   void set_frame_time(int64_t value) { frame_time_ = value; _has_field_.set(6); }
24808 
has_deadline() const24809   bool has_deadline() const { return _has_field_[7]; }
deadline() const24810   int64_t deadline() const { return deadline_; }
set_deadline(int64_t value)24811   void set_deadline(int64_t value) { deadline_ = value; _has_field_.set(7); }
24812 
24813  private:
24814   int64_t interval_delta_{};
24815   int64_t now_to_deadline_delta_{};
24816   int64_t frame_time_to_now_delta_{};
24817   int64_t frame_time_to_deadline_delta_{};
24818   int64_t now_{};
24819   int64_t frame_time_{};
24820   int64_t deadline_{};
24821 
24822   // Allows to preserve unknown protobuf fields for compatibility
24823   // with future versions of .proto files.
24824   std::string unknown_fields_;
24825 
24826   std::bitset<8> _has_field_{};
24827 };
24828 
24829 
24830 class PERFETTO_EXPORT ChromeCompositorStateMachine : public ::protozero::CppMessageObj {
24831  public:
24832   using MajorState = ChromeCompositorStateMachine_MajorState;
24833   using MinorState = ChromeCompositorStateMachine_MinorState;
24834   enum FieldNumbers {
24835     kMajorStateFieldNumber = 1,
24836     kMinorStateFieldNumber = 2,
24837   };
24838 
24839   ChromeCompositorStateMachine();
24840   ~ChromeCompositorStateMachine() override;
24841   ChromeCompositorStateMachine(ChromeCompositorStateMachine&&) noexcept;
24842   ChromeCompositorStateMachine& operator=(ChromeCompositorStateMachine&&);
24843   ChromeCompositorStateMachine(const ChromeCompositorStateMachine&);
24844   ChromeCompositorStateMachine& operator=(const ChromeCompositorStateMachine&);
24845   bool operator==(const ChromeCompositorStateMachine&) const;
operator !=(const ChromeCompositorStateMachine & other) const24846   bool operator!=(const ChromeCompositorStateMachine& other) const { return !(*this == other); }
24847 
24848   bool ParseFromArray(const void*, size_t) override;
24849   std::string SerializeAsString() const override;
24850   std::vector<uint8_t> SerializeAsArray() const override;
24851   void Serialize(::protozero::Message*) const;
24852 
has_major_state() const24853   bool has_major_state() const { return _has_field_[1]; }
major_state() const24854   const ChromeCompositorStateMachine_MajorState& major_state() const { return *major_state_; }
mutable_major_state()24855   ChromeCompositorStateMachine_MajorState* mutable_major_state() { _has_field_.set(1); return major_state_.get(); }
24856 
has_minor_state() const24857   bool has_minor_state() const { return _has_field_[2]; }
minor_state() const24858   const ChromeCompositorStateMachine_MinorState& minor_state() const { return *minor_state_; }
mutable_minor_state()24859   ChromeCompositorStateMachine_MinorState* mutable_minor_state() { _has_field_.set(2); return minor_state_.get(); }
24860 
24861  private:
24862   ::protozero::CopyablePtr<ChromeCompositorStateMachine_MajorState> major_state_;
24863   ::protozero::CopyablePtr<ChromeCompositorStateMachine_MinorState> minor_state_;
24864 
24865   // Allows to preserve unknown protobuf fields for compatibility
24866   // with future versions of .proto files.
24867   std::string unknown_fields_;
24868 
24869   std::bitset<3> _has_field_{};
24870 };
24871 
24872 
24873 class PERFETTO_EXPORT ChromeCompositorStateMachine_MinorState : public ::protozero::CppMessageObj {
24874  public:
24875   using TreePriority = ChromeCompositorStateMachine_MinorState_TreePriority;
24876   static constexpr auto TREE_PRIORITY_UNSPECIFIED = ChromeCompositorStateMachine_MinorState_TreePriority_TREE_PRIORITY_UNSPECIFIED;
24877   static constexpr auto TREE_PRIORITY_SAME_PRIORITY_FOR_BOTH_TREES = ChromeCompositorStateMachine_MinorState_TreePriority_TREE_PRIORITY_SAME_PRIORITY_FOR_BOTH_TREES;
24878   static constexpr auto TREE_PRIORITY_SMOOTHNESS_TAKES_PRIORITY = ChromeCompositorStateMachine_MinorState_TreePriority_TREE_PRIORITY_SMOOTHNESS_TAKES_PRIORITY;
24879   static constexpr auto TREE_PRIORITY_NEW_CONTENT_TAKES_PRIORITY = ChromeCompositorStateMachine_MinorState_TreePriority_TREE_PRIORITY_NEW_CONTENT_TAKES_PRIORITY;
24880   static constexpr auto TreePriority_MIN = ChromeCompositorStateMachine_MinorState_TreePriority_TREE_PRIORITY_UNSPECIFIED;
24881   static constexpr auto TreePriority_MAX = ChromeCompositorStateMachine_MinorState_TreePriority_TREE_PRIORITY_NEW_CONTENT_TAKES_PRIORITY;
24882   using ScrollHandlerState = ChromeCompositorStateMachine_MinorState_ScrollHandlerState;
24883   static constexpr auto SCROLL_HANDLER_UNSPECIFIED = ChromeCompositorStateMachine_MinorState_ScrollHandlerState_SCROLL_HANDLER_UNSPECIFIED;
24884   static constexpr auto SCROLL_AFFECTS_SCROLL_HANDLER = ChromeCompositorStateMachine_MinorState_ScrollHandlerState_SCROLL_AFFECTS_SCROLL_HANDLER;
24885   static constexpr auto SCROLL_DOES_NOT_AFFECT_SCROLL_HANDLER = ChromeCompositorStateMachine_MinorState_ScrollHandlerState_SCROLL_DOES_NOT_AFFECT_SCROLL_HANDLER;
24886   static constexpr auto ScrollHandlerState_MIN = ChromeCompositorStateMachine_MinorState_ScrollHandlerState_SCROLL_HANDLER_UNSPECIFIED;
24887   static constexpr auto ScrollHandlerState_MAX = ChromeCompositorStateMachine_MinorState_ScrollHandlerState_SCROLL_DOES_NOT_AFFECT_SCROLL_HANDLER;
24888   enum FieldNumbers {
24889     kCommitCountFieldNumber = 1,
24890     kCurrentFrameNumberFieldNumber = 2,
24891     kLastFrameNumberSubmitPerformedFieldNumber = 3,
24892     kLastFrameNumberDrawPerformedFieldNumber = 4,
24893     kLastFrameNumberBeginMainFrameSentFieldNumber = 5,
24894     kDidDrawFieldNumber = 6,
24895     kDidSendBeginMainFrameForCurrentFrameFieldNumber = 7,
24896     kDidNotifyBeginMainFrameNotExpectedUntilFieldNumber = 8,
24897     kDidNotifyBeginMainFrameNotExpectedSoonFieldNumber = 9,
24898     kWantsBeginMainFrameNotExpectedFieldNumber = 10,
24899     kDidCommitDuringFrameFieldNumber = 11,
24900     kDidInvalidateLayerTreeFrameSinkFieldNumber = 12,
24901     kDidPerformImplSideInvalidaionFieldNumber = 13,
24902     kDidPrepareTilesFieldNumber = 14,
24903     kConsecutiveCheckerboardAnimationsFieldNumber = 15,
24904     kPendingSubmitFramesFieldNumber = 16,
24905     kSubmitFramesWithCurrentLayerTreeFrameSinkFieldNumber = 17,
24906     kNeedsRedrawFieldNumber = 18,
24907     kNeedsPrepareTilesFieldNumber = 19,
24908     kNeedsBeginMainFrameFieldNumber = 20,
24909     kNeedsOneBeginImplFrameFieldNumber = 21,
24910     kVisibleFieldNumber = 22,
24911     kBeginFrameSourcePausedFieldNumber = 23,
24912     kCanDrawFieldNumber = 24,
24913     kResourcelessDrawFieldNumber = 25,
24914     kHasPendingTreeFieldNumber = 26,
24915     kPendingTreeIsReadyForActivationFieldNumber = 27,
24916     kActiveTreeNeedsFirstDrawFieldNumber = 28,
24917     kActiveTreeIsReadyToDrawFieldNumber = 29,
24918     kDidCreateAndInitializeFirstLayerTreeFrameSinkFieldNumber = 30,
24919     kTreePriorityFieldNumber = 31,
24920     kScrollHandlerStateFieldNumber = 32,
24921     kCriticalBeginMainFrameToActivateIsFastFieldNumber = 33,
24922     kMainThreadMissedLastDeadlineFieldNumber = 34,
24923     kVideoNeedsBeginFramesFieldNumber = 36,
24924     kDeferBeginMainFrameFieldNumber = 37,
24925     kLastCommitHadNoUpdatesFieldNumber = 38,
24926     kDidDrawInLastFrameFieldNumber = 39,
24927     kDidSubmitInLastFrameFieldNumber = 40,
24928     kNeedsImplSideInvalidationFieldNumber = 41,
24929     kCurrentPendingTreeIsImplSideFieldNumber = 42,
24930     kPreviousPendingTreeWasImplSideFieldNumber = 43,
24931     kProcessingAnimationWorkletsForActiveTreeFieldNumber = 44,
24932     kProcessingAnimationWorkletsForPendingTreeFieldNumber = 45,
24933     kProcessingPaintWorkletsForPendingTreeFieldNumber = 46,
24934   };
24935 
24936   ChromeCompositorStateMachine_MinorState();
24937   ~ChromeCompositorStateMachine_MinorState() override;
24938   ChromeCompositorStateMachine_MinorState(ChromeCompositorStateMachine_MinorState&&) noexcept;
24939   ChromeCompositorStateMachine_MinorState& operator=(ChromeCompositorStateMachine_MinorState&&);
24940   ChromeCompositorStateMachine_MinorState(const ChromeCompositorStateMachine_MinorState&);
24941   ChromeCompositorStateMachine_MinorState& operator=(const ChromeCompositorStateMachine_MinorState&);
24942   bool operator==(const ChromeCompositorStateMachine_MinorState&) const;
operator !=(const ChromeCompositorStateMachine_MinorState & other) const24943   bool operator!=(const ChromeCompositorStateMachine_MinorState& other) const { return !(*this == other); }
24944 
24945   bool ParseFromArray(const void*, size_t) override;
24946   std::string SerializeAsString() const override;
24947   std::vector<uint8_t> SerializeAsArray() const override;
24948   void Serialize(::protozero::Message*) const;
24949 
has_commit_count() const24950   bool has_commit_count() const { return _has_field_[1]; }
commit_count() const24951   int32_t commit_count() const { return commit_count_; }
set_commit_count(int32_t value)24952   void set_commit_count(int32_t value) { commit_count_ = value; _has_field_.set(1); }
24953 
has_current_frame_number() const24954   bool has_current_frame_number() const { return _has_field_[2]; }
current_frame_number() const24955   int32_t current_frame_number() const { return current_frame_number_; }
set_current_frame_number(int32_t value)24956   void set_current_frame_number(int32_t value) { current_frame_number_ = value; _has_field_.set(2); }
24957 
has_last_frame_number_submit_performed() const24958   bool has_last_frame_number_submit_performed() const { return _has_field_[3]; }
last_frame_number_submit_performed() const24959   int32_t last_frame_number_submit_performed() const { return last_frame_number_submit_performed_; }
set_last_frame_number_submit_performed(int32_t value)24960   void set_last_frame_number_submit_performed(int32_t value) { last_frame_number_submit_performed_ = value; _has_field_.set(3); }
24961 
has_last_frame_number_draw_performed() const24962   bool has_last_frame_number_draw_performed() const { return _has_field_[4]; }
last_frame_number_draw_performed() const24963   int32_t last_frame_number_draw_performed() const { return last_frame_number_draw_performed_; }
set_last_frame_number_draw_performed(int32_t value)24964   void set_last_frame_number_draw_performed(int32_t value) { last_frame_number_draw_performed_ = value; _has_field_.set(4); }
24965 
has_last_frame_number_begin_main_frame_sent() const24966   bool has_last_frame_number_begin_main_frame_sent() const { return _has_field_[5]; }
last_frame_number_begin_main_frame_sent() const24967   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)24968   void set_last_frame_number_begin_main_frame_sent(int32_t value) { last_frame_number_begin_main_frame_sent_ = value; _has_field_.set(5); }
24969 
has_did_draw() const24970   bool has_did_draw() const { return _has_field_[6]; }
did_draw() const24971   bool did_draw() const { return did_draw_; }
set_did_draw(bool value)24972   void set_did_draw(bool value) { did_draw_ = value; _has_field_.set(6); }
24973 
has_did_send_begin_main_frame_for_current_frame() const24974   bool has_did_send_begin_main_frame_for_current_frame() const { return _has_field_[7]; }
did_send_begin_main_frame_for_current_frame() const24975   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)24976   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); }
24977 
has_did_notify_begin_main_frame_not_expected_until() const24978   bool has_did_notify_begin_main_frame_not_expected_until() const { return _has_field_[8]; }
did_notify_begin_main_frame_not_expected_until() const24979   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)24980   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); }
24981 
has_did_notify_begin_main_frame_not_expected_soon() const24982   bool has_did_notify_begin_main_frame_not_expected_soon() const { return _has_field_[9]; }
did_notify_begin_main_frame_not_expected_soon() const24983   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)24984   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); }
24985 
has_wants_begin_main_frame_not_expected() const24986   bool has_wants_begin_main_frame_not_expected() const { return _has_field_[10]; }
wants_begin_main_frame_not_expected() const24987   bool wants_begin_main_frame_not_expected() const { return wants_begin_main_frame_not_expected_; }
set_wants_begin_main_frame_not_expected(bool value)24988   void set_wants_begin_main_frame_not_expected(bool value) { wants_begin_main_frame_not_expected_ = value; _has_field_.set(10); }
24989 
has_did_commit_during_frame() const24990   bool has_did_commit_during_frame() const { return _has_field_[11]; }
did_commit_during_frame() const24991   bool did_commit_during_frame() const { return did_commit_during_frame_; }
set_did_commit_during_frame(bool value)24992   void set_did_commit_during_frame(bool value) { did_commit_during_frame_ = value; _has_field_.set(11); }
24993 
has_did_invalidate_layer_tree_frame_sink() const24994   bool has_did_invalidate_layer_tree_frame_sink() const { return _has_field_[12]; }
did_invalidate_layer_tree_frame_sink() const24995   bool did_invalidate_layer_tree_frame_sink() const { return did_invalidate_layer_tree_frame_sink_; }
set_did_invalidate_layer_tree_frame_sink(bool value)24996   void set_did_invalidate_layer_tree_frame_sink(bool value) { did_invalidate_layer_tree_frame_sink_ = value; _has_field_.set(12); }
24997 
has_did_perform_impl_side_invalidaion() const24998   bool has_did_perform_impl_side_invalidaion() const { return _has_field_[13]; }
did_perform_impl_side_invalidaion() const24999   bool did_perform_impl_side_invalidaion() const { return did_perform_impl_side_invalidaion_; }
set_did_perform_impl_side_invalidaion(bool value)25000   void set_did_perform_impl_side_invalidaion(bool value) { did_perform_impl_side_invalidaion_ = value; _has_field_.set(13); }
25001 
has_did_prepare_tiles() const25002   bool has_did_prepare_tiles() const { return _has_field_[14]; }
did_prepare_tiles() const25003   bool did_prepare_tiles() const { return did_prepare_tiles_; }
set_did_prepare_tiles(bool value)25004   void set_did_prepare_tiles(bool value) { did_prepare_tiles_ = value; _has_field_.set(14); }
25005 
has_consecutive_checkerboard_animations() const25006   bool has_consecutive_checkerboard_animations() const { return _has_field_[15]; }
consecutive_checkerboard_animations() const25007   int32_t consecutive_checkerboard_animations() const { return consecutive_checkerboard_animations_; }
set_consecutive_checkerboard_animations(int32_t value)25008   void set_consecutive_checkerboard_animations(int32_t value) { consecutive_checkerboard_animations_ = value; _has_field_.set(15); }
25009 
has_pending_submit_frames() const25010   bool has_pending_submit_frames() const { return _has_field_[16]; }
pending_submit_frames() const25011   int32_t pending_submit_frames() const { return pending_submit_frames_; }
set_pending_submit_frames(int32_t value)25012   void set_pending_submit_frames(int32_t value) { pending_submit_frames_ = value; _has_field_.set(16); }
25013 
has_submit_frames_with_current_layer_tree_frame_sink() const25014   bool has_submit_frames_with_current_layer_tree_frame_sink() const { return _has_field_[17]; }
submit_frames_with_current_layer_tree_frame_sink() const25015   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)25016   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); }
25017 
has_needs_redraw() const25018   bool has_needs_redraw() const { return _has_field_[18]; }
needs_redraw() const25019   bool needs_redraw() const { return needs_redraw_; }
set_needs_redraw(bool value)25020   void set_needs_redraw(bool value) { needs_redraw_ = value; _has_field_.set(18); }
25021 
has_needs_prepare_tiles() const25022   bool has_needs_prepare_tiles() const { return _has_field_[19]; }
needs_prepare_tiles() const25023   bool needs_prepare_tiles() const { return needs_prepare_tiles_; }
set_needs_prepare_tiles(bool value)25024   void set_needs_prepare_tiles(bool value) { needs_prepare_tiles_ = value; _has_field_.set(19); }
25025 
has_needs_begin_main_frame() const25026   bool has_needs_begin_main_frame() const { return _has_field_[20]; }
needs_begin_main_frame() const25027   bool needs_begin_main_frame() const { return needs_begin_main_frame_; }
set_needs_begin_main_frame(bool value)25028   void set_needs_begin_main_frame(bool value) { needs_begin_main_frame_ = value; _has_field_.set(20); }
25029 
has_needs_one_begin_impl_frame() const25030   bool has_needs_one_begin_impl_frame() const { return _has_field_[21]; }
needs_one_begin_impl_frame() const25031   bool needs_one_begin_impl_frame() const { return needs_one_begin_impl_frame_; }
set_needs_one_begin_impl_frame(bool value)25032   void set_needs_one_begin_impl_frame(bool value) { needs_one_begin_impl_frame_ = value; _has_field_.set(21); }
25033 
has_visible() const25034   bool has_visible() const { return _has_field_[22]; }
visible() const25035   bool visible() const { return visible_; }
set_visible(bool value)25036   void set_visible(bool value) { visible_ = value; _has_field_.set(22); }
25037 
has_begin_frame_source_paused() const25038   bool has_begin_frame_source_paused() const { return _has_field_[23]; }
begin_frame_source_paused() const25039   bool begin_frame_source_paused() const { return begin_frame_source_paused_; }
set_begin_frame_source_paused(bool value)25040   void set_begin_frame_source_paused(bool value) { begin_frame_source_paused_ = value; _has_field_.set(23); }
25041 
has_can_draw() const25042   bool has_can_draw() const { return _has_field_[24]; }
can_draw() const25043   bool can_draw() const { return can_draw_; }
set_can_draw(bool value)25044   void set_can_draw(bool value) { can_draw_ = value; _has_field_.set(24); }
25045 
has_resourceless_draw() const25046   bool has_resourceless_draw() const { return _has_field_[25]; }
resourceless_draw() const25047   bool resourceless_draw() const { return resourceless_draw_; }
set_resourceless_draw(bool value)25048   void set_resourceless_draw(bool value) { resourceless_draw_ = value; _has_field_.set(25); }
25049 
has_has_pending_tree() const25050   bool has_has_pending_tree() const { return _has_field_[26]; }
has_pending_tree() const25051   bool has_pending_tree() const { return has_pending_tree_; }
set_has_pending_tree(bool value)25052   void set_has_pending_tree(bool value) { has_pending_tree_ = value; _has_field_.set(26); }
25053 
has_pending_tree_is_ready_for_activation() const25054   bool has_pending_tree_is_ready_for_activation() const { return _has_field_[27]; }
pending_tree_is_ready_for_activation() const25055   bool pending_tree_is_ready_for_activation() const { return pending_tree_is_ready_for_activation_; }
set_pending_tree_is_ready_for_activation(bool value)25056   void set_pending_tree_is_ready_for_activation(bool value) { pending_tree_is_ready_for_activation_ = value; _has_field_.set(27); }
25057 
has_active_tree_needs_first_draw() const25058   bool has_active_tree_needs_first_draw() const { return _has_field_[28]; }
active_tree_needs_first_draw() const25059   bool active_tree_needs_first_draw() const { return active_tree_needs_first_draw_; }
set_active_tree_needs_first_draw(bool value)25060   void set_active_tree_needs_first_draw(bool value) { active_tree_needs_first_draw_ = value; _has_field_.set(28); }
25061 
has_active_tree_is_ready_to_draw() const25062   bool has_active_tree_is_ready_to_draw() const { return _has_field_[29]; }
active_tree_is_ready_to_draw() const25063   bool active_tree_is_ready_to_draw() const { return active_tree_is_ready_to_draw_; }
set_active_tree_is_ready_to_draw(bool value)25064   void set_active_tree_is_ready_to_draw(bool value) { active_tree_is_ready_to_draw_ = value; _has_field_.set(29); }
25065 
has_did_create_and_initialize_first_layer_tree_frame_sink() const25066   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() const25067   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)25068   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); }
25069 
has_tree_priority() const25070   bool has_tree_priority() const { return _has_field_[31]; }
tree_priority() const25071   ChromeCompositorStateMachine_MinorState_TreePriority tree_priority() const { return tree_priority_; }
set_tree_priority(ChromeCompositorStateMachine_MinorState_TreePriority value)25072   void set_tree_priority(ChromeCompositorStateMachine_MinorState_TreePriority value) { tree_priority_ = value; _has_field_.set(31); }
25073 
has_scroll_handler_state() const25074   bool has_scroll_handler_state() const { return _has_field_[32]; }
scroll_handler_state() const25075   ChromeCompositorStateMachine_MinorState_ScrollHandlerState scroll_handler_state() const { return scroll_handler_state_; }
set_scroll_handler_state(ChromeCompositorStateMachine_MinorState_ScrollHandlerState value)25076   void set_scroll_handler_state(ChromeCompositorStateMachine_MinorState_ScrollHandlerState value) { scroll_handler_state_ = value; _has_field_.set(32); }
25077 
has_critical_begin_main_frame_to_activate_is_fast() const25078   bool has_critical_begin_main_frame_to_activate_is_fast() const { return _has_field_[33]; }
critical_begin_main_frame_to_activate_is_fast() const25079   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)25080   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); }
25081 
has_main_thread_missed_last_deadline() const25082   bool has_main_thread_missed_last_deadline() const { return _has_field_[34]; }
main_thread_missed_last_deadline() const25083   bool main_thread_missed_last_deadline() const { return main_thread_missed_last_deadline_; }
set_main_thread_missed_last_deadline(bool value)25084   void set_main_thread_missed_last_deadline(bool value) { main_thread_missed_last_deadline_ = value; _has_field_.set(34); }
25085 
has_video_needs_begin_frames() const25086   bool has_video_needs_begin_frames() const { return _has_field_[36]; }
video_needs_begin_frames() const25087   bool video_needs_begin_frames() const { return video_needs_begin_frames_; }
set_video_needs_begin_frames(bool value)25088   void set_video_needs_begin_frames(bool value) { video_needs_begin_frames_ = value; _has_field_.set(36); }
25089 
has_defer_begin_main_frame() const25090   bool has_defer_begin_main_frame() const { return _has_field_[37]; }
defer_begin_main_frame() const25091   bool defer_begin_main_frame() const { return defer_begin_main_frame_; }
set_defer_begin_main_frame(bool value)25092   void set_defer_begin_main_frame(bool value) { defer_begin_main_frame_ = value; _has_field_.set(37); }
25093 
has_last_commit_had_no_updates() const25094   bool has_last_commit_had_no_updates() const { return _has_field_[38]; }
last_commit_had_no_updates() const25095   bool last_commit_had_no_updates() const { return last_commit_had_no_updates_; }
set_last_commit_had_no_updates(bool value)25096   void set_last_commit_had_no_updates(bool value) { last_commit_had_no_updates_ = value; _has_field_.set(38); }
25097 
has_did_draw_in_last_frame() const25098   bool has_did_draw_in_last_frame() const { return _has_field_[39]; }
did_draw_in_last_frame() const25099   bool did_draw_in_last_frame() const { return did_draw_in_last_frame_; }
set_did_draw_in_last_frame(bool value)25100   void set_did_draw_in_last_frame(bool value) { did_draw_in_last_frame_ = value; _has_field_.set(39); }
25101 
has_did_submit_in_last_frame() const25102   bool has_did_submit_in_last_frame() const { return _has_field_[40]; }
did_submit_in_last_frame() const25103   bool did_submit_in_last_frame() const { return did_submit_in_last_frame_; }
set_did_submit_in_last_frame(bool value)25104   void set_did_submit_in_last_frame(bool value) { did_submit_in_last_frame_ = value; _has_field_.set(40); }
25105 
has_needs_impl_side_invalidation() const25106   bool has_needs_impl_side_invalidation() const { return _has_field_[41]; }
needs_impl_side_invalidation() const25107   bool needs_impl_side_invalidation() const { return needs_impl_side_invalidation_; }
set_needs_impl_side_invalidation(bool value)25108   void set_needs_impl_side_invalidation(bool value) { needs_impl_side_invalidation_ = value; _has_field_.set(41); }
25109 
has_current_pending_tree_is_impl_side() const25110   bool has_current_pending_tree_is_impl_side() const { return _has_field_[42]; }
current_pending_tree_is_impl_side() const25111   bool current_pending_tree_is_impl_side() const { return current_pending_tree_is_impl_side_; }
set_current_pending_tree_is_impl_side(bool value)25112   void set_current_pending_tree_is_impl_side(bool value) { current_pending_tree_is_impl_side_ = value; _has_field_.set(42); }
25113 
has_previous_pending_tree_was_impl_side() const25114   bool has_previous_pending_tree_was_impl_side() const { return _has_field_[43]; }
previous_pending_tree_was_impl_side() const25115   bool previous_pending_tree_was_impl_side() const { return previous_pending_tree_was_impl_side_; }
set_previous_pending_tree_was_impl_side(bool value)25116   void set_previous_pending_tree_was_impl_side(bool value) { previous_pending_tree_was_impl_side_ = value; _has_field_.set(43); }
25117 
has_processing_animation_worklets_for_active_tree() const25118   bool has_processing_animation_worklets_for_active_tree() const { return _has_field_[44]; }
processing_animation_worklets_for_active_tree() const25119   bool processing_animation_worklets_for_active_tree() const { return processing_animation_worklets_for_active_tree_; }
set_processing_animation_worklets_for_active_tree(bool value)25120   void set_processing_animation_worklets_for_active_tree(bool value) { processing_animation_worklets_for_active_tree_ = value; _has_field_.set(44); }
25121 
has_processing_animation_worklets_for_pending_tree() const25122   bool has_processing_animation_worklets_for_pending_tree() const { return _has_field_[45]; }
processing_animation_worklets_for_pending_tree() const25123   bool processing_animation_worklets_for_pending_tree() const { return processing_animation_worklets_for_pending_tree_; }
set_processing_animation_worklets_for_pending_tree(bool value)25124   void set_processing_animation_worklets_for_pending_tree(bool value) { processing_animation_worklets_for_pending_tree_ = value; _has_field_.set(45); }
25125 
has_processing_paint_worklets_for_pending_tree() const25126   bool has_processing_paint_worklets_for_pending_tree() const { return _has_field_[46]; }
processing_paint_worklets_for_pending_tree() const25127   bool processing_paint_worklets_for_pending_tree() const { return processing_paint_worklets_for_pending_tree_; }
set_processing_paint_worklets_for_pending_tree(bool value)25128   void set_processing_paint_worklets_for_pending_tree(bool value) { processing_paint_worklets_for_pending_tree_ = value; _has_field_.set(46); }
25129 
25130  private:
25131   int32_t commit_count_{};
25132   int32_t current_frame_number_{};
25133   int32_t last_frame_number_submit_performed_{};
25134   int32_t last_frame_number_draw_performed_{};
25135   int32_t last_frame_number_begin_main_frame_sent_{};
25136   bool did_draw_{};
25137   bool did_send_begin_main_frame_for_current_frame_{};
25138   bool did_notify_begin_main_frame_not_expected_until_{};
25139   bool did_notify_begin_main_frame_not_expected_soon_{};
25140   bool wants_begin_main_frame_not_expected_{};
25141   bool did_commit_during_frame_{};
25142   bool did_invalidate_layer_tree_frame_sink_{};
25143   bool did_perform_impl_side_invalidaion_{};
25144   bool did_prepare_tiles_{};
25145   int32_t consecutive_checkerboard_animations_{};
25146   int32_t pending_submit_frames_{};
25147   int32_t submit_frames_with_current_layer_tree_frame_sink_{};
25148   bool needs_redraw_{};
25149   bool needs_prepare_tiles_{};
25150   bool needs_begin_main_frame_{};
25151   bool needs_one_begin_impl_frame_{};
25152   bool visible_{};
25153   bool begin_frame_source_paused_{};
25154   bool can_draw_{};
25155   bool resourceless_draw_{};
25156   bool has_pending_tree_{};
25157   bool pending_tree_is_ready_for_activation_{};
25158   bool active_tree_needs_first_draw_{};
25159   bool active_tree_is_ready_to_draw_{};
25160   bool did_create_and_initialize_first_layer_tree_frame_sink_{};
25161   ChromeCompositorStateMachine_MinorState_TreePriority tree_priority_{};
25162   ChromeCompositorStateMachine_MinorState_ScrollHandlerState scroll_handler_state_{};
25163   bool critical_begin_main_frame_to_activate_is_fast_{};
25164   bool main_thread_missed_last_deadline_{};
25165   bool video_needs_begin_frames_{};
25166   bool defer_begin_main_frame_{};
25167   bool last_commit_had_no_updates_{};
25168   bool did_draw_in_last_frame_{};
25169   bool did_submit_in_last_frame_{};
25170   bool needs_impl_side_invalidation_{};
25171   bool current_pending_tree_is_impl_side_{};
25172   bool previous_pending_tree_was_impl_side_{};
25173   bool processing_animation_worklets_for_active_tree_{};
25174   bool processing_animation_worklets_for_pending_tree_{};
25175   bool processing_paint_worklets_for_pending_tree_{};
25176 
25177   // Allows to preserve unknown protobuf fields for compatibility
25178   // with future versions of .proto files.
25179   std::string unknown_fields_;
25180 
25181   std::bitset<47> _has_field_{};
25182 };
25183 
25184 
25185 class PERFETTO_EXPORT ChromeCompositorStateMachine_MajorState : public ::protozero::CppMessageObj {
25186  public:
25187   using BeginImplFrameState = ChromeCompositorStateMachine_MajorState_BeginImplFrameState;
25188   static constexpr auto BEGIN_IMPL_FRAME_UNSPECIFIED = ChromeCompositorStateMachine_MajorState_BeginImplFrameState_BEGIN_IMPL_FRAME_UNSPECIFIED;
25189   static constexpr auto BEGIN_IMPL_FRAME_IDLE = ChromeCompositorStateMachine_MajorState_BeginImplFrameState_BEGIN_IMPL_FRAME_IDLE;
25190   static constexpr auto BEGIN_IMPL_FRAME_INSIDE_BEGIN_FRAME = ChromeCompositorStateMachine_MajorState_BeginImplFrameState_BEGIN_IMPL_FRAME_INSIDE_BEGIN_FRAME;
25191   static constexpr auto BEGIN_IMPL_FRAME_INSIDE_DEADLINE = ChromeCompositorStateMachine_MajorState_BeginImplFrameState_BEGIN_IMPL_FRAME_INSIDE_DEADLINE;
25192   static constexpr auto BeginImplFrameState_MIN = ChromeCompositorStateMachine_MajorState_BeginImplFrameState_BEGIN_IMPL_FRAME_UNSPECIFIED;
25193   static constexpr auto BeginImplFrameState_MAX = ChromeCompositorStateMachine_MajorState_BeginImplFrameState_BEGIN_IMPL_FRAME_INSIDE_DEADLINE;
25194   using BeginMainFrameState = ChromeCompositorStateMachine_MajorState_BeginMainFrameState;
25195   static constexpr auto BEGIN_MAIN_FRAME_UNSPECIFIED = ChromeCompositorStateMachine_MajorState_BeginMainFrameState_BEGIN_MAIN_FRAME_UNSPECIFIED;
25196   static constexpr auto BEGIN_MAIN_FRAME_IDLE = ChromeCompositorStateMachine_MajorState_BeginMainFrameState_BEGIN_MAIN_FRAME_IDLE;
25197   static constexpr auto BEGIN_MAIN_FRAME_SENT = ChromeCompositorStateMachine_MajorState_BeginMainFrameState_BEGIN_MAIN_FRAME_SENT;
25198   static constexpr auto BEGIN_MAIN_FRAME_READY_TO_COMMIT = ChromeCompositorStateMachine_MajorState_BeginMainFrameState_BEGIN_MAIN_FRAME_READY_TO_COMMIT;
25199   static constexpr auto BeginMainFrameState_MIN = ChromeCompositorStateMachine_MajorState_BeginMainFrameState_BEGIN_MAIN_FRAME_UNSPECIFIED;
25200   static constexpr auto BeginMainFrameState_MAX = ChromeCompositorStateMachine_MajorState_BeginMainFrameState_BEGIN_MAIN_FRAME_READY_TO_COMMIT;
25201   using LayerTreeFrameSinkState = ChromeCompositorStateMachine_MajorState_LayerTreeFrameSinkState;
25202   static constexpr auto LAYER_TREE_FRAME_UNSPECIFIED = ChromeCompositorStateMachine_MajorState_LayerTreeFrameSinkState_LAYER_TREE_FRAME_UNSPECIFIED;
25203   static constexpr auto LAYER_TREE_FRAME_NONE = ChromeCompositorStateMachine_MajorState_LayerTreeFrameSinkState_LAYER_TREE_FRAME_NONE;
25204   static constexpr auto LAYER_TREE_FRAME_ACTIVE = ChromeCompositorStateMachine_MajorState_LayerTreeFrameSinkState_LAYER_TREE_FRAME_ACTIVE;
25205   static constexpr auto LAYER_TREE_FRAME_CREATING = ChromeCompositorStateMachine_MajorState_LayerTreeFrameSinkState_LAYER_TREE_FRAME_CREATING;
25206   static constexpr auto LAYER_TREE_FRAME_WAITING_FOR_FIRST_COMMIT = ChromeCompositorStateMachine_MajorState_LayerTreeFrameSinkState_LAYER_TREE_FRAME_WAITING_FOR_FIRST_COMMIT;
25207   static constexpr auto LAYER_TREE_FRAME_WAITING_FOR_FIRST_ACTIVATION = ChromeCompositorStateMachine_MajorState_LayerTreeFrameSinkState_LAYER_TREE_FRAME_WAITING_FOR_FIRST_ACTIVATION;
25208   static constexpr auto LayerTreeFrameSinkState_MIN = ChromeCompositorStateMachine_MajorState_LayerTreeFrameSinkState_LAYER_TREE_FRAME_UNSPECIFIED;
25209   static constexpr auto LayerTreeFrameSinkState_MAX = ChromeCompositorStateMachine_MajorState_LayerTreeFrameSinkState_LAYER_TREE_FRAME_WAITING_FOR_FIRST_ACTIVATION;
25210   using ForcedRedrawOnTimeoutState = ChromeCompositorStateMachine_MajorState_ForcedRedrawOnTimeoutState;
25211   static constexpr auto FORCED_REDRAW_UNSPECIFIED = ChromeCompositorStateMachine_MajorState_ForcedRedrawOnTimeoutState_FORCED_REDRAW_UNSPECIFIED;
25212   static constexpr auto FORCED_REDRAW_IDLE = ChromeCompositorStateMachine_MajorState_ForcedRedrawOnTimeoutState_FORCED_REDRAW_IDLE;
25213   static constexpr auto FORCED_REDRAW_WAITING_FOR_COMMIT = ChromeCompositorStateMachine_MajorState_ForcedRedrawOnTimeoutState_FORCED_REDRAW_WAITING_FOR_COMMIT;
25214   static constexpr auto FORCED_REDRAW_WAITING_FOR_ACTIVATION = ChromeCompositorStateMachine_MajorState_ForcedRedrawOnTimeoutState_FORCED_REDRAW_WAITING_FOR_ACTIVATION;
25215   static constexpr auto FORCED_REDRAW_WAITING_FOR_DRAW = ChromeCompositorStateMachine_MajorState_ForcedRedrawOnTimeoutState_FORCED_REDRAW_WAITING_FOR_DRAW;
25216   static constexpr auto ForcedRedrawOnTimeoutState_MIN = ChromeCompositorStateMachine_MajorState_ForcedRedrawOnTimeoutState_FORCED_REDRAW_UNSPECIFIED;
25217   static constexpr auto ForcedRedrawOnTimeoutState_MAX = ChromeCompositorStateMachine_MajorState_ForcedRedrawOnTimeoutState_FORCED_REDRAW_WAITING_FOR_DRAW;
25218   enum FieldNumbers {
25219     kNextActionFieldNumber = 1,
25220     kBeginImplFrameStateFieldNumber = 2,
25221     kBeginMainFrameStateFieldNumber = 3,
25222     kLayerTreeFrameSinkStateFieldNumber = 4,
25223     kForcedRedrawStateFieldNumber = 5,
25224   };
25225 
25226   ChromeCompositorStateMachine_MajorState();
25227   ~ChromeCompositorStateMachine_MajorState() override;
25228   ChromeCompositorStateMachine_MajorState(ChromeCompositorStateMachine_MajorState&&) noexcept;
25229   ChromeCompositorStateMachine_MajorState& operator=(ChromeCompositorStateMachine_MajorState&&);
25230   ChromeCompositorStateMachine_MajorState(const ChromeCompositorStateMachine_MajorState&);
25231   ChromeCompositorStateMachine_MajorState& operator=(const ChromeCompositorStateMachine_MajorState&);
25232   bool operator==(const ChromeCompositorStateMachine_MajorState&) const;
operator !=(const ChromeCompositorStateMachine_MajorState & other) const25233   bool operator!=(const ChromeCompositorStateMachine_MajorState& other) const { return !(*this == other); }
25234 
25235   bool ParseFromArray(const void*, size_t) override;
25236   std::string SerializeAsString() const override;
25237   std::vector<uint8_t> SerializeAsArray() const override;
25238   void Serialize(::protozero::Message*) const;
25239 
has_next_action() const25240   bool has_next_action() const { return _has_field_[1]; }
next_action() const25241   ChromeCompositorSchedulerAction next_action() const { return next_action_; }
set_next_action(ChromeCompositorSchedulerAction value)25242   void set_next_action(ChromeCompositorSchedulerAction value) { next_action_ = value; _has_field_.set(1); }
25243 
has_begin_impl_frame_state() const25244   bool has_begin_impl_frame_state() const { return _has_field_[2]; }
begin_impl_frame_state() const25245   ChromeCompositorStateMachine_MajorState_BeginImplFrameState begin_impl_frame_state() const { return begin_impl_frame_state_; }
set_begin_impl_frame_state(ChromeCompositorStateMachine_MajorState_BeginImplFrameState value)25246   void set_begin_impl_frame_state(ChromeCompositorStateMachine_MajorState_BeginImplFrameState value) { begin_impl_frame_state_ = value; _has_field_.set(2); }
25247 
has_begin_main_frame_state() const25248   bool has_begin_main_frame_state() const { return _has_field_[3]; }
begin_main_frame_state() const25249   ChromeCompositorStateMachine_MajorState_BeginMainFrameState begin_main_frame_state() const { return begin_main_frame_state_; }
set_begin_main_frame_state(ChromeCompositorStateMachine_MajorState_BeginMainFrameState value)25250   void set_begin_main_frame_state(ChromeCompositorStateMachine_MajorState_BeginMainFrameState value) { begin_main_frame_state_ = value; _has_field_.set(3); }
25251 
has_layer_tree_frame_sink_state() const25252   bool has_layer_tree_frame_sink_state() const { return _has_field_[4]; }
layer_tree_frame_sink_state() const25253   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)25254   void set_layer_tree_frame_sink_state(ChromeCompositorStateMachine_MajorState_LayerTreeFrameSinkState value) { layer_tree_frame_sink_state_ = value; _has_field_.set(4); }
25255 
has_forced_redraw_state() const25256   bool has_forced_redraw_state() const { return _has_field_[5]; }
forced_redraw_state() const25257   ChromeCompositorStateMachine_MajorState_ForcedRedrawOnTimeoutState forced_redraw_state() const { return forced_redraw_state_; }
set_forced_redraw_state(ChromeCompositorStateMachine_MajorState_ForcedRedrawOnTimeoutState value)25258   void set_forced_redraw_state(ChromeCompositorStateMachine_MajorState_ForcedRedrawOnTimeoutState value) { forced_redraw_state_ = value; _has_field_.set(5); }
25259 
25260  private:
25261   ChromeCompositorSchedulerAction next_action_{};
25262   ChromeCompositorStateMachine_MajorState_BeginImplFrameState begin_impl_frame_state_{};
25263   ChromeCompositorStateMachine_MajorState_BeginMainFrameState begin_main_frame_state_{};
25264   ChromeCompositorStateMachine_MajorState_LayerTreeFrameSinkState layer_tree_frame_sink_state_{};
25265   ChromeCompositorStateMachine_MajorState_ForcedRedrawOnTimeoutState forced_redraw_state_{};
25266 
25267   // Allows to preserve unknown protobuf fields for compatibility
25268   // with future versions of .proto files.
25269   std::string unknown_fields_;
25270 
25271   std::bitset<6> _has_field_{};
25272 };
25273 
25274 
25275 class PERFETTO_EXPORT ChromeCompositorSchedulerState : public ::protozero::CppMessageObj {
25276  public:
25277   using BeginImplFrameDeadlineMode = ChromeCompositorSchedulerState_BeginImplFrameDeadlineMode;
25278   static constexpr auto DEADLINE_MODE_UNSPECIFIED = ChromeCompositorSchedulerState_BeginImplFrameDeadlineMode_DEADLINE_MODE_UNSPECIFIED;
25279   static constexpr auto DEADLINE_MODE_NONE = ChromeCompositorSchedulerState_BeginImplFrameDeadlineMode_DEADLINE_MODE_NONE;
25280   static constexpr auto DEADLINE_MODE_IMMEDIATE = ChromeCompositorSchedulerState_BeginImplFrameDeadlineMode_DEADLINE_MODE_IMMEDIATE;
25281   static constexpr auto DEADLINE_MODE_REGULAR = ChromeCompositorSchedulerState_BeginImplFrameDeadlineMode_DEADLINE_MODE_REGULAR;
25282   static constexpr auto DEADLINE_MODE_LATE = ChromeCompositorSchedulerState_BeginImplFrameDeadlineMode_DEADLINE_MODE_LATE;
25283   static constexpr auto DEADLINE_MODE_BLOCKED = ChromeCompositorSchedulerState_BeginImplFrameDeadlineMode_DEADLINE_MODE_BLOCKED;
25284   static constexpr auto BeginImplFrameDeadlineMode_MIN = ChromeCompositorSchedulerState_BeginImplFrameDeadlineMode_DEADLINE_MODE_UNSPECIFIED;
25285   static constexpr auto BeginImplFrameDeadlineMode_MAX = ChromeCompositorSchedulerState_BeginImplFrameDeadlineMode_DEADLINE_MODE_BLOCKED;
25286   enum FieldNumbers {
25287     kStateMachineFieldNumber = 1,
25288     kObservingBeginFrameSourceFieldNumber = 2,
25289     kBeginImplFrameDeadlineTaskFieldNumber = 3,
25290     kPendingBeginFrameTaskFieldNumber = 4,
25291     kSkippedLastFrameMissedExceededDeadlineFieldNumber = 5,
25292     kInsideActionFieldNumber = 7,
25293     kDeadlineModeFieldNumber = 8,
25294     kDeadlineUsFieldNumber = 9,
25295     kDeadlineScheduledAtUsFieldNumber = 10,
25296     kNowUsFieldNumber = 11,
25297     kNowToDeadlineDeltaUsFieldNumber = 12,
25298     kNowToDeadlineScheduledAtDeltaUsFieldNumber = 13,
25299     kBeginImplFrameArgsFieldNumber = 14,
25300     kBeginFrameObserverStateFieldNumber = 15,
25301     kBeginFrameSourceStateFieldNumber = 16,
25302     kCompositorTimingHistoryFieldNumber = 17,
25303   };
25304 
25305   ChromeCompositorSchedulerState();
25306   ~ChromeCompositorSchedulerState() override;
25307   ChromeCompositorSchedulerState(ChromeCompositorSchedulerState&&) noexcept;
25308   ChromeCompositorSchedulerState& operator=(ChromeCompositorSchedulerState&&);
25309   ChromeCompositorSchedulerState(const ChromeCompositorSchedulerState&);
25310   ChromeCompositorSchedulerState& operator=(const ChromeCompositorSchedulerState&);
25311   bool operator==(const ChromeCompositorSchedulerState&) const;
operator !=(const ChromeCompositorSchedulerState & other) const25312   bool operator!=(const ChromeCompositorSchedulerState& other) const { return !(*this == other); }
25313 
25314   bool ParseFromArray(const void*, size_t) override;
25315   std::string SerializeAsString() const override;
25316   std::vector<uint8_t> SerializeAsArray() const override;
25317   void Serialize(::protozero::Message*) const;
25318 
has_state_machine() const25319   bool has_state_machine() const { return _has_field_[1]; }
state_machine() const25320   const ChromeCompositorStateMachine& state_machine() const { return *state_machine_; }
mutable_state_machine()25321   ChromeCompositorStateMachine* mutable_state_machine() { _has_field_.set(1); return state_machine_.get(); }
25322 
has_observing_begin_frame_source() const25323   bool has_observing_begin_frame_source() const { return _has_field_[2]; }
observing_begin_frame_source() const25324   bool observing_begin_frame_source() const { return observing_begin_frame_source_; }
set_observing_begin_frame_source(bool value)25325   void set_observing_begin_frame_source(bool value) { observing_begin_frame_source_ = value; _has_field_.set(2); }
25326 
has_begin_impl_frame_deadline_task() const25327   bool has_begin_impl_frame_deadline_task() const { return _has_field_[3]; }
begin_impl_frame_deadline_task() const25328   bool begin_impl_frame_deadline_task() const { return begin_impl_frame_deadline_task_; }
set_begin_impl_frame_deadline_task(bool value)25329   void set_begin_impl_frame_deadline_task(bool value) { begin_impl_frame_deadline_task_ = value; _has_field_.set(3); }
25330 
has_pending_begin_frame_task() const25331   bool has_pending_begin_frame_task() const { return _has_field_[4]; }
pending_begin_frame_task() const25332   bool pending_begin_frame_task() const { return pending_begin_frame_task_; }
set_pending_begin_frame_task(bool value)25333   void set_pending_begin_frame_task(bool value) { pending_begin_frame_task_ = value; _has_field_.set(4); }
25334 
has_skipped_last_frame_missed_exceeded_deadline() const25335   bool has_skipped_last_frame_missed_exceeded_deadline() const { return _has_field_[5]; }
skipped_last_frame_missed_exceeded_deadline() const25336   bool skipped_last_frame_missed_exceeded_deadline() const { return skipped_last_frame_missed_exceeded_deadline_; }
set_skipped_last_frame_missed_exceeded_deadline(bool value)25337   void set_skipped_last_frame_missed_exceeded_deadline(bool value) { skipped_last_frame_missed_exceeded_deadline_ = value; _has_field_.set(5); }
25338 
has_inside_action() const25339   bool has_inside_action() const { return _has_field_[7]; }
inside_action() const25340   ChromeCompositorSchedulerAction inside_action() const { return inside_action_; }
set_inside_action(ChromeCompositorSchedulerAction value)25341   void set_inside_action(ChromeCompositorSchedulerAction value) { inside_action_ = value; _has_field_.set(7); }
25342 
has_deadline_mode() const25343   bool has_deadline_mode() const { return _has_field_[8]; }
deadline_mode() const25344   ChromeCompositorSchedulerState_BeginImplFrameDeadlineMode deadline_mode() const { return deadline_mode_; }
set_deadline_mode(ChromeCompositorSchedulerState_BeginImplFrameDeadlineMode value)25345   void set_deadline_mode(ChromeCompositorSchedulerState_BeginImplFrameDeadlineMode value) { deadline_mode_ = value; _has_field_.set(8); }
25346 
has_deadline_us() const25347   bool has_deadline_us() const { return _has_field_[9]; }
deadline_us() const25348   int64_t deadline_us() const { return deadline_us_; }
set_deadline_us(int64_t value)25349   void set_deadline_us(int64_t value) { deadline_us_ = value; _has_field_.set(9); }
25350 
has_deadline_scheduled_at_us() const25351   bool has_deadline_scheduled_at_us() const { return _has_field_[10]; }
deadline_scheduled_at_us() const25352   int64_t deadline_scheduled_at_us() const { return deadline_scheduled_at_us_; }
set_deadline_scheduled_at_us(int64_t value)25353   void set_deadline_scheduled_at_us(int64_t value) { deadline_scheduled_at_us_ = value; _has_field_.set(10); }
25354 
has_now_us() const25355   bool has_now_us() const { return _has_field_[11]; }
now_us() const25356   int64_t now_us() const { return now_us_; }
set_now_us(int64_t value)25357   void set_now_us(int64_t value) { now_us_ = value; _has_field_.set(11); }
25358 
has_now_to_deadline_delta_us() const25359   bool has_now_to_deadline_delta_us() const { return _has_field_[12]; }
now_to_deadline_delta_us() const25360   int64_t now_to_deadline_delta_us() const { return now_to_deadline_delta_us_; }
set_now_to_deadline_delta_us(int64_t value)25361   void set_now_to_deadline_delta_us(int64_t value) { now_to_deadline_delta_us_ = value; _has_field_.set(12); }
25362 
has_now_to_deadline_scheduled_at_delta_us() const25363   bool has_now_to_deadline_scheduled_at_delta_us() const { return _has_field_[13]; }
now_to_deadline_scheduled_at_delta_us() const25364   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)25365   void set_now_to_deadline_scheduled_at_delta_us(int64_t value) { now_to_deadline_scheduled_at_delta_us_ = value; _has_field_.set(13); }
25366 
has_begin_impl_frame_args() const25367   bool has_begin_impl_frame_args() const { return _has_field_[14]; }
begin_impl_frame_args() const25368   const BeginImplFrameArgs& begin_impl_frame_args() const { return *begin_impl_frame_args_; }
mutable_begin_impl_frame_args()25369   BeginImplFrameArgs* mutable_begin_impl_frame_args() { _has_field_.set(14); return begin_impl_frame_args_.get(); }
25370 
has_begin_frame_observer_state() const25371   bool has_begin_frame_observer_state() const { return _has_field_[15]; }
begin_frame_observer_state() const25372   const BeginFrameObserverState& begin_frame_observer_state() const { return *begin_frame_observer_state_; }
mutable_begin_frame_observer_state()25373   BeginFrameObserverState* mutable_begin_frame_observer_state() { _has_field_.set(15); return begin_frame_observer_state_.get(); }
25374 
has_begin_frame_source_state() const25375   bool has_begin_frame_source_state() const { return _has_field_[16]; }
begin_frame_source_state() const25376   const BeginFrameSourceState& begin_frame_source_state() const { return *begin_frame_source_state_; }
mutable_begin_frame_source_state()25377   BeginFrameSourceState* mutable_begin_frame_source_state() { _has_field_.set(16); return begin_frame_source_state_.get(); }
25378 
has_compositor_timing_history() const25379   bool has_compositor_timing_history() const { return _has_field_[17]; }
compositor_timing_history() const25380   const CompositorTimingHistory& compositor_timing_history() const { return *compositor_timing_history_; }
mutable_compositor_timing_history()25381   CompositorTimingHistory* mutable_compositor_timing_history() { _has_field_.set(17); return compositor_timing_history_.get(); }
25382 
25383  private:
25384   ::protozero::CopyablePtr<ChromeCompositorStateMachine> state_machine_;
25385   bool observing_begin_frame_source_{};
25386   bool begin_impl_frame_deadline_task_{};
25387   bool pending_begin_frame_task_{};
25388   bool skipped_last_frame_missed_exceeded_deadline_{};
25389   ChromeCompositorSchedulerAction inside_action_{};
25390   ChromeCompositorSchedulerState_BeginImplFrameDeadlineMode deadline_mode_{};
25391   int64_t deadline_us_{};
25392   int64_t deadline_scheduled_at_us_{};
25393   int64_t now_us_{};
25394   int64_t now_to_deadline_delta_us_{};
25395   int64_t now_to_deadline_scheduled_at_delta_us_{};
25396   ::protozero::CopyablePtr<BeginImplFrameArgs> begin_impl_frame_args_;
25397   ::protozero::CopyablePtr<BeginFrameObserverState> begin_frame_observer_state_;
25398   ::protozero::CopyablePtr<BeginFrameSourceState> begin_frame_source_state_;
25399   ::protozero::CopyablePtr<CompositorTimingHistory> compositor_timing_history_;
25400 
25401   // Allows to preserve unknown protobuf fields for compatibility
25402   // with future versions of .proto files.
25403   std::string unknown_fields_;
25404 
25405   std::bitset<18> _has_field_{};
25406 };
25407 
25408 }  // namespace perfetto
25409 }  // namespace protos
25410 }  // namespace gen
25411 
25412 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_COMPOSITOR_SCHEDULER_STATE_PROTO_CPP_H_
25413 // gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/source_location.gen.h
25414 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
25415 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_SOURCE_LOCATION_PROTO_CPP_H_
25416 #define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_SOURCE_LOCATION_PROTO_CPP_H_
25417 
25418 #include <stdint.h>
25419 #include <bitset>
25420 #include <vector>
25421 #include <string>
25422 #include <type_traits>
25423 
25424 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
25425 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
25426 // gen_amalgamated expanded: #include "perfetto/base/export.h"
25427 
25428 namespace perfetto {
25429 namespace protos {
25430 namespace gen {
25431 class SourceLocation;
25432 }  // namespace perfetto
25433 }  // namespace protos
25434 }  // namespace gen
25435 
25436 namespace protozero {
25437 class Message;
25438 }  // namespace protozero
25439 
25440 namespace perfetto {
25441 namespace protos {
25442 namespace gen {
25443 
25444 class PERFETTO_EXPORT SourceLocation : public ::protozero::CppMessageObj {
25445  public:
25446   enum FieldNumbers {
25447     kIidFieldNumber = 1,
25448     kFileNameFieldNumber = 2,
25449     kFunctionNameFieldNumber = 3,
25450     kLineNumberFieldNumber = 4,
25451   };
25452 
25453   SourceLocation();
25454   ~SourceLocation() override;
25455   SourceLocation(SourceLocation&&) noexcept;
25456   SourceLocation& operator=(SourceLocation&&);
25457   SourceLocation(const SourceLocation&);
25458   SourceLocation& operator=(const SourceLocation&);
25459   bool operator==(const SourceLocation&) const;
operator !=(const SourceLocation & other) const25460   bool operator!=(const SourceLocation& other) const { return !(*this == other); }
25461 
25462   bool ParseFromArray(const void*, size_t) override;
25463   std::string SerializeAsString() const override;
25464   std::vector<uint8_t> SerializeAsArray() const override;
25465   void Serialize(::protozero::Message*) const;
25466 
has_iid() const25467   bool has_iid() const { return _has_field_[1]; }
iid() const25468   uint64_t iid() const { return iid_; }
set_iid(uint64_t value)25469   void set_iid(uint64_t value) { iid_ = value; _has_field_.set(1); }
25470 
has_file_name() const25471   bool has_file_name() const { return _has_field_[2]; }
file_name() const25472   const std::string& file_name() const { return file_name_; }
set_file_name(const std::string & value)25473   void set_file_name(const std::string& value) { file_name_ = value; _has_field_.set(2); }
25474 
has_function_name() const25475   bool has_function_name() const { return _has_field_[3]; }
function_name() const25476   const std::string& function_name() const { return function_name_; }
set_function_name(const std::string & value)25477   void set_function_name(const std::string& value) { function_name_ = value; _has_field_.set(3); }
25478 
has_line_number() const25479   bool has_line_number() const { return _has_field_[4]; }
line_number() const25480   uint32_t line_number() const { return line_number_; }
set_line_number(uint32_t value)25481   void set_line_number(uint32_t value) { line_number_ = value; _has_field_.set(4); }
25482 
25483  private:
25484   uint64_t iid_{};
25485   std::string file_name_{};
25486   std::string function_name_{};
25487   uint32_t line_number_{};
25488 
25489   // Allows to preserve unknown protobuf fields for compatibility
25490   // with future versions of .proto files.
25491   std::string unknown_fields_;
25492 
25493   std::bitset<5> _has_field_{};
25494 };
25495 
25496 }  // namespace perfetto
25497 }  // namespace protos
25498 }  // namespace gen
25499 
25500 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_SOURCE_LOCATION_PROTO_CPP_H_
25501 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
25502 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
25503 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
25504 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
25505 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
25506 #if defined(__GNUC__) || defined(__clang__)
25507 #pragma GCC diagnostic push
25508 #pragma GCC diagnostic ignored "-Wfloat-equal"
25509 #endif
25510 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_compositor_scheduler_state.gen.h"
25511 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/source_location.gen.h"
25512 
25513 namespace perfetto {
25514 namespace protos {
25515 namespace gen {
25516 
25517 CompositorTimingHistory::CompositorTimingHistory() = default;
25518 CompositorTimingHistory::~CompositorTimingHistory() = default;
25519 CompositorTimingHistory::CompositorTimingHistory(const CompositorTimingHistory&) = default;
25520 CompositorTimingHistory& CompositorTimingHistory::operator=(const CompositorTimingHistory&) = default;
25521 CompositorTimingHistory::CompositorTimingHistory(CompositorTimingHistory&&) noexcept = default;
25522 CompositorTimingHistory& CompositorTimingHistory::operator=(CompositorTimingHistory&&) = default;
25523 
operator ==(const CompositorTimingHistory & other) const25524 bool CompositorTimingHistory::operator==(const CompositorTimingHistory& other) const {
25525   return unknown_fields_ == other.unknown_fields_
25526    && begin_main_frame_queue_critical_estimate_delta_us_ == other.begin_main_frame_queue_critical_estimate_delta_us_
25527    && begin_main_frame_queue_not_critical_estimate_delta_us_ == other.begin_main_frame_queue_not_critical_estimate_delta_us_
25528    && begin_main_frame_start_to_ready_to_commit_estimate_delta_us_ == other.begin_main_frame_start_to_ready_to_commit_estimate_delta_us_
25529    && commit_to_ready_to_activate_estimate_delta_us_ == other.commit_to_ready_to_activate_estimate_delta_us_
25530    && prepare_tiles_estimate_delta_us_ == other.prepare_tiles_estimate_delta_us_
25531    && activate_estimate_delta_us_ == other.activate_estimate_delta_us_
25532    && draw_estimate_delta_us_ == other.draw_estimate_delta_us_;
25533 }
25534 
ParseFromArray(const void * raw,size_t size)25535 bool CompositorTimingHistory::ParseFromArray(const void* raw, size_t size) {
25536   unknown_fields_.clear();
25537   bool packed_error = false;
25538 
25539   ::protozero::ProtoDecoder dec(raw, size);
25540   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
25541     if (field.id() < _has_field_.size()) {
25542       _has_field_.set(field.id());
25543     }
25544     switch (field.id()) {
25545       case 1 /* begin_main_frame_queue_critical_estimate_delta_us */:
25546         field.get(&begin_main_frame_queue_critical_estimate_delta_us_);
25547         break;
25548       case 2 /* begin_main_frame_queue_not_critical_estimate_delta_us */:
25549         field.get(&begin_main_frame_queue_not_critical_estimate_delta_us_);
25550         break;
25551       case 3 /* begin_main_frame_start_to_ready_to_commit_estimate_delta_us */:
25552         field.get(&begin_main_frame_start_to_ready_to_commit_estimate_delta_us_);
25553         break;
25554       case 4 /* commit_to_ready_to_activate_estimate_delta_us */:
25555         field.get(&commit_to_ready_to_activate_estimate_delta_us_);
25556         break;
25557       case 5 /* prepare_tiles_estimate_delta_us */:
25558         field.get(&prepare_tiles_estimate_delta_us_);
25559         break;
25560       case 6 /* activate_estimate_delta_us */:
25561         field.get(&activate_estimate_delta_us_);
25562         break;
25563       case 7 /* draw_estimate_delta_us */:
25564         field.get(&draw_estimate_delta_us_);
25565         break;
25566       default:
25567         field.SerializeAndAppendTo(&unknown_fields_);
25568         break;
25569     }
25570   }
25571   return !packed_error && !dec.bytes_left();
25572 }
25573 
SerializeAsString() const25574 std::string CompositorTimingHistory::SerializeAsString() const {
25575   ::protozero::HeapBuffered<::protozero::Message> msg;
25576   Serialize(msg.get());
25577   return msg.SerializeAsString();
25578 }
25579 
SerializeAsArray() const25580 std::vector<uint8_t> CompositorTimingHistory::SerializeAsArray() const {
25581   ::protozero::HeapBuffered<::protozero::Message> msg;
25582   Serialize(msg.get());
25583   return msg.SerializeAsArray();
25584 }
25585 
Serialize(::protozero::Message * msg) const25586 void CompositorTimingHistory::Serialize(::protozero::Message* msg) const {
25587   // Field 1: begin_main_frame_queue_critical_estimate_delta_us
25588   if (_has_field_[1]) {
25589     msg->AppendVarInt(1, begin_main_frame_queue_critical_estimate_delta_us_);
25590   }
25591 
25592   // Field 2: begin_main_frame_queue_not_critical_estimate_delta_us
25593   if (_has_field_[2]) {
25594     msg->AppendVarInt(2, begin_main_frame_queue_not_critical_estimate_delta_us_);
25595   }
25596 
25597   // Field 3: begin_main_frame_start_to_ready_to_commit_estimate_delta_us
25598   if (_has_field_[3]) {
25599     msg->AppendVarInt(3, begin_main_frame_start_to_ready_to_commit_estimate_delta_us_);
25600   }
25601 
25602   // Field 4: commit_to_ready_to_activate_estimate_delta_us
25603   if (_has_field_[4]) {
25604     msg->AppendVarInt(4, commit_to_ready_to_activate_estimate_delta_us_);
25605   }
25606 
25607   // Field 5: prepare_tiles_estimate_delta_us
25608   if (_has_field_[5]) {
25609     msg->AppendVarInt(5, prepare_tiles_estimate_delta_us_);
25610   }
25611 
25612   // Field 6: activate_estimate_delta_us
25613   if (_has_field_[6]) {
25614     msg->AppendVarInt(6, activate_estimate_delta_us_);
25615   }
25616 
25617   // Field 7: draw_estimate_delta_us
25618   if (_has_field_[7]) {
25619     msg->AppendVarInt(7, draw_estimate_delta_us_);
25620   }
25621 
25622   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
25623 }
25624 
25625 
25626 BeginFrameSourceState::BeginFrameSourceState() = default;
25627 BeginFrameSourceState::~BeginFrameSourceState() = default;
25628 BeginFrameSourceState::BeginFrameSourceState(const BeginFrameSourceState&) = default;
25629 BeginFrameSourceState& BeginFrameSourceState::operator=(const BeginFrameSourceState&) = default;
25630 BeginFrameSourceState::BeginFrameSourceState(BeginFrameSourceState&&) noexcept = default;
25631 BeginFrameSourceState& BeginFrameSourceState::operator=(BeginFrameSourceState&&) = default;
25632 
operator ==(const BeginFrameSourceState & other) const25633 bool BeginFrameSourceState::operator==(const BeginFrameSourceState& other) const {
25634   return unknown_fields_ == other.unknown_fields_
25635    && source_id_ == other.source_id_
25636    && paused_ == other.paused_
25637    && num_observers_ == other.num_observers_
25638    && last_begin_frame_args_ == other.last_begin_frame_args_;
25639 }
25640 
ParseFromArray(const void * raw,size_t size)25641 bool BeginFrameSourceState::ParseFromArray(const void* raw, size_t size) {
25642   unknown_fields_.clear();
25643   bool packed_error = false;
25644 
25645   ::protozero::ProtoDecoder dec(raw, size);
25646   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
25647     if (field.id() < _has_field_.size()) {
25648       _has_field_.set(field.id());
25649     }
25650     switch (field.id()) {
25651       case 1 /* source_id */:
25652         field.get(&source_id_);
25653         break;
25654       case 2 /* paused */:
25655         field.get(&paused_);
25656         break;
25657       case 3 /* num_observers */:
25658         field.get(&num_observers_);
25659         break;
25660       case 4 /* last_begin_frame_args */:
25661         (*last_begin_frame_args_).ParseFromArray(field.data(), field.size());
25662         break;
25663       default:
25664         field.SerializeAndAppendTo(&unknown_fields_);
25665         break;
25666     }
25667   }
25668   return !packed_error && !dec.bytes_left();
25669 }
25670 
SerializeAsString() const25671 std::string BeginFrameSourceState::SerializeAsString() const {
25672   ::protozero::HeapBuffered<::protozero::Message> msg;
25673   Serialize(msg.get());
25674   return msg.SerializeAsString();
25675 }
25676 
SerializeAsArray() const25677 std::vector<uint8_t> BeginFrameSourceState::SerializeAsArray() const {
25678   ::protozero::HeapBuffered<::protozero::Message> msg;
25679   Serialize(msg.get());
25680   return msg.SerializeAsArray();
25681 }
25682 
Serialize(::protozero::Message * msg) const25683 void BeginFrameSourceState::Serialize(::protozero::Message* msg) const {
25684   // Field 1: source_id
25685   if (_has_field_[1]) {
25686     msg->AppendVarInt(1, source_id_);
25687   }
25688 
25689   // Field 2: paused
25690   if (_has_field_[2]) {
25691     msg->AppendTinyVarInt(2, paused_);
25692   }
25693 
25694   // Field 3: num_observers
25695   if (_has_field_[3]) {
25696     msg->AppendVarInt(3, num_observers_);
25697   }
25698 
25699   // Field 4: last_begin_frame_args
25700   if (_has_field_[4]) {
25701     (*last_begin_frame_args_).Serialize(msg->BeginNestedMessage<::protozero::Message>(4));
25702   }
25703 
25704   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
25705 }
25706 
25707 
25708 BeginFrameArgs::BeginFrameArgs() = default;
25709 BeginFrameArgs::~BeginFrameArgs() = default;
25710 BeginFrameArgs::BeginFrameArgs(const BeginFrameArgs&) = default;
25711 BeginFrameArgs& BeginFrameArgs::operator=(const BeginFrameArgs&) = default;
25712 BeginFrameArgs::BeginFrameArgs(BeginFrameArgs&&) noexcept = default;
25713 BeginFrameArgs& BeginFrameArgs::operator=(BeginFrameArgs&&) = default;
25714 
operator ==(const BeginFrameArgs & other) const25715 bool BeginFrameArgs::operator==(const BeginFrameArgs& other) const {
25716   return unknown_fields_ == other.unknown_fields_
25717    && type_ == other.type_
25718    && source_id_ == other.source_id_
25719    && sequence_number_ == other.sequence_number_
25720    && frame_time_us_ == other.frame_time_us_
25721    && deadline_us_ == other.deadline_us_
25722    && interval_delta_us_ == other.interval_delta_us_
25723    && on_critical_path_ == other.on_critical_path_
25724    && animate_only_ == other.animate_only_
25725    && source_location_iid_ == other.source_location_iid_
25726    && source_location_ == other.source_location_
25727    && frames_throttled_since_last_ == other.frames_throttled_since_last_;
25728 }
25729 
ParseFromArray(const void * raw,size_t size)25730 bool BeginFrameArgs::ParseFromArray(const void* raw, size_t size) {
25731   unknown_fields_.clear();
25732   bool packed_error = false;
25733 
25734   ::protozero::ProtoDecoder dec(raw, size);
25735   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
25736     if (field.id() < _has_field_.size()) {
25737       _has_field_.set(field.id());
25738     }
25739     switch (field.id()) {
25740       case 1 /* type */:
25741         field.get(&type_);
25742         break;
25743       case 2 /* source_id */:
25744         field.get(&source_id_);
25745         break;
25746       case 3 /* sequence_number */:
25747         field.get(&sequence_number_);
25748         break;
25749       case 4 /* frame_time_us */:
25750         field.get(&frame_time_us_);
25751         break;
25752       case 5 /* deadline_us */:
25753         field.get(&deadline_us_);
25754         break;
25755       case 6 /* interval_delta_us */:
25756         field.get(&interval_delta_us_);
25757         break;
25758       case 7 /* on_critical_path */:
25759         field.get(&on_critical_path_);
25760         break;
25761       case 8 /* animate_only */:
25762         field.get(&animate_only_);
25763         break;
25764       case 9 /* source_location_iid */:
25765         field.get(&source_location_iid_);
25766         break;
25767       case 10 /* source_location */:
25768         (*source_location_).ParseFromArray(field.data(), field.size());
25769         break;
25770       case 12 /* frames_throttled_since_last */:
25771         field.get(&frames_throttled_since_last_);
25772         break;
25773       default:
25774         field.SerializeAndAppendTo(&unknown_fields_);
25775         break;
25776     }
25777   }
25778   return !packed_error && !dec.bytes_left();
25779 }
25780 
SerializeAsString() const25781 std::string BeginFrameArgs::SerializeAsString() const {
25782   ::protozero::HeapBuffered<::protozero::Message> msg;
25783   Serialize(msg.get());
25784   return msg.SerializeAsString();
25785 }
25786 
SerializeAsArray() const25787 std::vector<uint8_t> BeginFrameArgs::SerializeAsArray() const {
25788   ::protozero::HeapBuffered<::protozero::Message> msg;
25789   Serialize(msg.get());
25790   return msg.SerializeAsArray();
25791 }
25792 
Serialize(::protozero::Message * msg) const25793 void BeginFrameArgs::Serialize(::protozero::Message* msg) const {
25794   // Field 1: type
25795   if (_has_field_[1]) {
25796     msg->AppendVarInt(1, type_);
25797   }
25798 
25799   // Field 2: source_id
25800   if (_has_field_[2]) {
25801     msg->AppendVarInt(2, source_id_);
25802   }
25803 
25804   // Field 3: sequence_number
25805   if (_has_field_[3]) {
25806     msg->AppendVarInt(3, sequence_number_);
25807   }
25808 
25809   // Field 4: frame_time_us
25810   if (_has_field_[4]) {
25811     msg->AppendVarInt(4, frame_time_us_);
25812   }
25813 
25814   // Field 5: deadline_us
25815   if (_has_field_[5]) {
25816     msg->AppendVarInt(5, deadline_us_);
25817   }
25818 
25819   // Field 6: interval_delta_us
25820   if (_has_field_[6]) {
25821     msg->AppendVarInt(6, interval_delta_us_);
25822   }
25823 
25824   // Field 7: on_critical_path
25825   if (_has_field_[7]) {
25826     msg->AppendTinyVarInt(7, on_critical_path_);
25827   }
25828 
25829   // Field 8: animate_only
25830   if (_has_field_[8]) {
25831     msg->AppendTinyVarInt(8, animate_only_);
25832   }
25833 
25834   // Field 9: source_location_iid
25835   if (_has_field_[9]) {
25836     msg->AppendVarInt(9, source_location_iid_);
25837   }
25838 
25839   // Field 10: source_location
25840   if (_has_field_[10]) {
25841     (*source_location_).Serialize(msg->BeginNestedMessage<::protozero::Message>(10));
25842   }
25843 
25844   // Field 12: frames_throttled_since_last
25845   if (_has_field_[12]) {
25846     msg->AppendVarInt(12, frames_throttled_since_last_);
25847   }
25848 
25849   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
25850 }
25851 
25852 
25853 BeginFrameObserverState::BeginFrameObserverState() = default;
25854 BeginFrameObserverState::~BeginFrameObserverState() = default;
25855 BeginFrameObserverState::BeginFrameObserverState(const BeginFrameObserverState&) = default;
25856 BeginFrameObserverState& BeginFrameObserverState::operator=(const BeginFrameObserverState&) = default;
25857 BeginFrameObserverState::BeginFrameObserverState(BeginFrameObserverState&&) noexcept = default;
25858 BeginFrameObserverState& BeginFrameObserverState::operator=(BeginFrameObserverState&&) = default;
25859 
operator ==(const BeginFrameObserverState & other) const25860 bool BeginFrameObserverState::operator==(const BeginFrameObserverState& other) const {
25861   return unknown_fields_ == other.unknown_fields_
25862    && dropped_begin_frame_args_ == other.dropped_begin_frame_args_
25863    && last_begin_frame_args_ == other.last_begin_frame_args_;
25864 }
25865 
ParseFromArray(const void * raw,size_t size)25866 bool BeginFrameObserverState::ParseFromArray(const void* raw, size_t size) {
25867   unknown_fields_.clear();
25868   bool packed_error = false;
25869 
25870   ::protozero::ProtoDecoder dec(raw, size);
25871   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
25872     if (field.id() < _has_field_.size()) {
25873       _has_field_.set(field.id());
25874     }
25875     switch (field.id()) {
25876       case 1 /* dropped_begin_frame_args */:
25877         field.get(&dropped_begin_frame_args_);
25878         break;
25879       case 2 /* last_begin_frame_args */:
25880         (*last_begin_frame_args_).ParseFromArray(field.data(), field.size());
25881         break;
25882       default:
25883         field.SerializeAndAppendTo(&unknown_fields_);
25884         break;
25885     }
25886   }
25887   return !packed_error && !dec.bytes_left();
25888 }
25889 
SerializeAsString() const25890 std::string BeginFrameObserverState::SerializeAsString() const {
25891   ::protozero::HeapBuffered<::protozero::Message> msg;
25892   Serialize(msg.get());
25893   return msg.SerializeAsString();
25894 }
25895 
SerializeAsArray() const25896 std::vector<uint8_t> BeginFrameObserverState::SerializeAsArray() const {
25897   ::protozero::HeapBuffered<::protozero::Message> msg;
25898   Serialize(msg.get());
25899   return msg.SerializeAsArray();
25900 }
25901 
Serialize(::protozero::Message * msg) const25902 void BeginFrameObserverState::Serialize(::protozero::Message* msg) const {
25903   // Field 1: dropped_begin_frame_args
25904   if (_has_field_[1]) {
25905     msg->AppendVarInt(1, dropped_begin_frame_args_);
25906   }
25907 
25908   // Field 2: last_begin_frame_args
25909   if (_has_field_[2]) {
25910     (*last_begin_frame_args_).Serialize(msg->BeginNestedMessage<::protozero::Message>(2));
25911   }
25912 
25913   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
25914 }
25915 
25916 
25917 BeginImplFrameArgs::BeginImplFrameArgs() = default;
25918 BeginImplFrameArgs::~BeginImplFrameArgs() = default;
25919 BeginImplFrameArgs::BeginImplFrameArgs(const BeginImplFrameArgs&) = default;
25920 BeginImplFrameArgs& BeginImplFrameArgs::operator=(const BeginImplFrameArgs&) = default;
25921 BeginImplFrameArgs::BeginImplFrameArgs(BeginImplFrameArgs&&) noexcept = default;
25922 BeginImplFrameArgs& BeginImplFrameArgs::operator=(BeginImplFrameArgs&&) = default;
25923 
operator ==(const BeginImplFrameArgs & other) const25924 bool BeginImplFrameArgs::operator==(const BeginImplFrameArgs& other) const {
25925   return unknown_fields_ == other.unknown_fields_
25926    && updated_at_us_ == other.updated_at_us_
25927    && finished_at_us_ == other.finished_at_us_
25928    && state_ == other.state_
25929    && current_args_ == other.current_args_
25930    && last_args_ == other.last_args_
25931    && timestamps_in_us_ == other.timestamps_in_us_;
25932 }
25933 
ParseFromArray(const void * raw,size_t size)25934 bool BeginImplFrameArgs::ParseFromArray(const void* raw, size_t size) {
25935   unknown_fields_.clear();
25936   bool packed_error = false;
25937 
25938   ::protozero::ProtoDecoder dec(raw, size);
25939   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
25940     if (field.id() < _has_field_.size()) {
25941       _has_field_.set(field.id());
25942     }
25943     switch (field.id()) {
25944       case 1 /* updated_at_us */:
25945         field.get(&updated_at_us_);
25946         break;
25947       case 2 /* finished_at_us */:
25948         field.get(&finished_at_us_);
25949         break;
25950       case 3 /* state */:
25951         field.get(&state_);
25952         break;
25953       case 4 /* current_args */:
25954         (*current_args_).ParseFromArray(field.data(), field.size());
25955         break;
25956       case 5 /* last_args */:
25957         (*last_args_).ParseFromArray(field.data(), field.size());
25958         break;
25959       case 6 /* timestamps_in_us */:
25960         (*timestamps_in_us_).ParseFromArray(field.data(), field.size());
25961         break;
25962       default:
25963         field.SerializeAndAppendTo(&unknown_fields_);
25964         break;
25965     }
25966   }
25967   return !packed_error && !dec.bytes_left();
25968 }
25969 
SerializeAsString() const25970 std::string BeginImplFrameArgs::SerializeAsString() const {
25971   ::protozero::HeapBuffered<::protozero::Message> msg;
25972   Serialize(msg.get());
25973   return msg.SerializeAsString();
25974 }
25975 
SerializeAsArray() const25976 std::vector<uint8_t> BeginImplFrameArgs::SerializeAsArray() const {
25977   ::protozero::HeapBuffered<::protozero::Message> msg;
25978   Serialize(msg.get());
25979   return msg.SerializeAsArray();
25980 }
25981 
Serialize(::protozero::Message * msg) const25982 void BeginImplFrameArgs::Serialize(::protozero::Message* msg) const {
25983   // Field 1: updated_at_us
25984   if (_has_field_[1]) {
25985     msg->AppendVarInt(1, updated_at_us_);
25986   }
25987 
25988   // Field 2: finished_at_us
25989   if (_has_field_[2]) {
25990     msg->AppendVarInt(2, finished_at_us_);
25991   }
25992 
25993   // Field 3: state
25994   if (_has_field_[3]) {
25995     msg->AppendVarInt(3, state_);
25996   }
25997 
25998   // Field 4: current_args
25999   if (_has_field_[4]) {
26000     (*current_args_).Serialize(msg->BeginNestedMessage<::protozero::Message>(4));
26001   }
26002 
26003   // Field 5: last_args
26004   if (_has_field_[5]) {
26005     (*last_args_).Serialize(msg->BeginNestedMessage<::protozero::Message>(5));
26006   }
26007 
26008   // Field 6: timestamps_in_us
26009   if (_has_field_[6]) {
26010     (*timestamps_in_us_).Serialize(msg->BeginNestedMessage<::protozero::Message>(6));
26011   }
26012 
26013   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
26014 }
26015 
26016 
26017 BeginImplFrameArgs_TimestampsInUs::BeginImplFrameArgs_TimestampsInUs() = default;
26018 BeginImplFrameArgs_TimestampsInUs::~BeginImplFrameArgs_TimestampsInUs() = default;
26019 BeginImplFrameArgs_TimestampsInUs::BeginImplFrameArgs_TimestampsInUs(const BeginImplFrameArgs_TimestampsInUs&) = default;
26020 BeginImplFrameArgs_TimestampsInUs& BeginImplFrameArgs_TimestampsInUs::operator=(const BeginImplFrameArgs_TimestampsInUs&) = default;
26021 BeginImplFrameArgs_TimestampsInUs::BeginImplFrameArgs_TimestampsInUs(BeginImplFrameArgs_TimestampsInUs&&) noexcept = default;
26022 BeginImplFrameArgs_TimestampsInUs& BeginImplFrameArgs_TimestampsInUs::operator=(BeginImplFrameArgs_TimestampsInUs&&) = default;
26023 
operator ==(const BeginImplFrameArgs_TimestampsInUs & other) const26024 bool BeginImplFrameArgs_TimestampsInUs::operator==(const BeginImplFrameArgs_TimestampsInUs& other) const {
26025   return unknown_fields_ == other.unknown_fields_
26026    && interval_delta_ == other.interval_delta_
26027    && now_to_deadline_delta_ == other.now_to_deadline_delta_
26028    && frame_time_to_now_delta_ == other.frame_time_to_now_delta_
26029    && frame_time_to_deadline_delta_ == other.frame_time_to_deadline_delta_
26030    && now_ == other.now_
26031    && frame_time_ == other.frame_time_
26032    && deadline_ == other.deadline_;
26033 }
26034 
ParseFromArray(const void * raw,size_t size)26035 bool BeginImplFrameArgs_TimestampsInUs::ParseFromArray(const void* raw, size_t size) {
26036   unknown_fields_.clear();
26037   bool packed_error = false;
26038 
26039   ::protozero::ProtoDecoder dec(raw, size);
26040   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
26041     if (field.id() < _has_field_.size()) {
26042       _has_field_.set(field.id());
26043     }
26044     switch (field.id()) {
26045       case 1 /* interval_delta */:
26046         field.get(&interval_delta_);
26047         break;
26048       case 2 /* now_to_deadline_delta */:
26049         field.get(&now_to_deadline_delta_);
26050         break;
26051       case 3 /* frame_time_to_now_delta */:
26052         field.get(&frame_time_to_now_delta_);
26053         break;
26054       case 4 /* frame_time_to_deadline_delta */:
26055         field.get(&frame_time_to_deadline_delta_);
26056         break;
26057       case 5 /* now */:
26058         field.get(&now_);
26059         break;
26060       case 6 /* frame_time */:
26061         field.get(&frame_time_);
26062         break;
26063       case 7 /* deadline */:
26064         field.get(&deadline_);
26065         break;
26066       default:
26067         field.SerializeAndAppendTo(&unknown_fields_);
26068         break;
26069     }
26070   }
26071   return !packed_error && !dec.bytes_left();
26072 }
26073 
SerializeAsString() const26074 std::string BeginImplFrameArgs_TimestampsInUs::SerializeAsString() const {
26075   ::protozero::HeapBuffered<::protozero::Message> msg;
26076   Serialize(msg.get());
26077   return msg.SerializeAsString();
26078 }
26079 
SerializeAsArray() const26080 std::vector<uint8_t> BeginImplFrameArgs_TimestampsInUs::SerializeAsArray() const {
26081   ::protozero::HeapBuffered<::protozero::Message> msg;
26082   Serialize(msg.get());
26083   return msg.SerializeAsArray();
26084 }
26085 
Serialize(::protozero::Message * msg) const26086 void BeginImplFrameArgs_TimestampsInUs::Serialize(::protozero::Message* msg) const {
26087   // Field 1: interval_delta
26088   if (_has_field_[1]) {
26089     msg->AppendVarInt(1, interval_delta_);
26090   }
26091 
26092   // Field 2: now_to_deadline_delta
26093   if (_has_field_[2]) {
26094     msg->AppendVarInt(2, now_to_deadline_delta_);
26095   }
26096 
26097   // Field 3: frame_time_to_now_delta
26098   if (_has_field_[3]) {
26099     msg->AppendVarInt(3, frame_time_to_now_delta_);
26100   }
26101 
26102   // Field 4: frame_time_to_deadline_delta
26103   if (_has_field_[4]) {
26104     msg->AppendVarInt(4, frame_time_to_deadline_delta_);
26105   }
26106 
26107   // Field 5: now
26108   if (_has_field_[5]) {
26109     msg->AppendVarInt(5, now_);
26110   }
26111 
26112   // Field 6: frame_time
26113   if (_has_field_[6]) {
26114     msg->AppendVarInt(6, frame_time_);
26115   }
26116 
26117   // Field 7: deadline
26118   if (_has_field_[7]) {
26119     msg->AppendVarInt(7, deadline_);
26120   }
26121 
26122   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
26123 }
26124 
26125 
26126 ChromeCompositorStateMachine::ChromeCompositorStateMachine() = default;
26127 ChromeCompositorStateMachine::~ChromeCompositorStateMachine() = default;
26128 ChromeCompositorStateMachine::ChromeCompositorStateMachine(const ChromeCompositorStateMachine&) = default;
26129 ChromeCompositorStateMachine& ChromeCompositorStateMachine::operator=(const ChromeCompositorStateMachine&) = default;
26130 ChromeCompositorStateMachine::ChromeCompositorStateMachine(ChromeCompositorStateMachine&&) noexcept = default;
26131 ChromeCompositorStateMachine& ChromeCompositorStateMachine::operator=(ChromeCompositorStateMachine&&) = default;
26132 
operator ==(const ChromeCompositorStateMachine & other) const26133 bool ChromeCompositorStateMachine::operator==(const ChromeCompositorStateMachine& other) const {
26134   return unknown_fields_ == other.unknown_fields_
26135    && major_state_ == other.major_state_
26136    && minor_state_ == other.minor_state_;
26137 }
26138 
ParseFromArray(const void * raw,size_t size)26139 bool ChromeCompositorStateMachine::ParseFromArray(const void* raw, size_t size) {
26140   unknown_fields_.clear();
26141   bool packed_error = false;
26142 
26143   ::protozero::ProtoDecoder dec(raw, size);
26144   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
26145     if (field.id() < _has_field_.size()) {
26146       _has_field_.set(field.id());
26147     }
26148     switch (field.id()) {
26149       case 1 /* major_state */:
26150         (*major_state_).ParseFromArray(field.data(), field.size());
26151         break;
26152       case 2 /* minor_state */:
26153         (*minor_state_).ParseFromArray(field.data(), field.size());
26154         break;
26155       default:
26156         field.SerializeAndAppendTo(&unknown_fields_);
26157         break;
26158     }
26159   }
26160   return !packed_error && !dec.bytes_left();
26161 }
26162 
SerializeAsString() const26163 std::string ChromeCompositorStateMachine::SerializeAsString() const {
26164   ::protozero::HeapBuffered<::protozero::Message> msg;
26165   Serialize(msg.get());
26166   return msg.SerializeAsString();
26167 }
26168 
SerializeAsArray() const26169 std::vector<uint8_t> ChromeCompositorStateMachine::SerializeAsArray() const {
26170   ::protozero::HeapBuffered<::protozero::Message> msg;
26171   Serialize(msg.get());
26172   return msg.SerializeAsArray();
26173 }
26174 
Serialize(::protozero::Message * msg) const26175 void ChromeCompositorStateMachine::Serialize(::protozero::Message* msg) const {
26176   // Field 1: major_state
26177   if (_has_field_[1]) {
26178     (*major_state_).Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
26179   }
26180 
26181   // Field 2: minor_state
26182   if (_has_field_[2]) {
26183     (*minor_state_).Serialize(msg->BeginNestedMessage<::protozero::Message>(2));
26184   }
26185 
26186   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
26187 }
26188 
26189 
26190 ChromeCompositorStateMachine_MinorState::ChromeCompositorStateMachine_MinorState() = default;
26191 ChromeCompositorStateMachine_MinorState::~ChromeCompositorStateMachine_MinorState() = default;
26192 ChromeCompositorStateMachine_MinorState::ChromeCompositorStateMachine_MinorState(const ChromeCompositorStateMachine_MinorState&) = default;
26193 ChromeCompositorStateMachine_MinorState& ChromeCompositorStateMachine_MinorState::operator=(const ChromeCompositorStateMachine_MinorState&) = default;
26194 ChromeCompositorStateMachine_MinorState::ChromeCompositorStateMachine_MinorState(ChromeCompositorStateMachine_MinorState&&) noexcept = default;
26195 ChromeCompositorStateMachine_MinorState& ChromeCompositorStateMachine_MinorState::operator=(ChromeCompositorStateMachine_MinorState&&) = default;
26196 
operator ==(const ChromeCompositorStateMachine_MinorState & other) const26197 bool ChromeCompositorStateMachine_MinorState::operator==(const ChromeCompositorStateMachine_MinorState& other) const {
26198   return unknown_fields_ == other.unknown_fields_
26199    && commit_count_ == other.commit_count_
26200    && current_frame_number_ == other.current_frame_number_
26201    && last_frame_number_submit_performed_ == other.last_frame_number_submit_performed_
26202    && last_frame_number_draw_performed_ == other.last_frame_number_draw_performed_
26203    && last_frame_number_begin_main_frame_sent_ == other.last_frame_number_begin_main_frame_sent_
26204    && did_draw_ == other.did_draw_
26205    && did_send_begin_main_frame_for_current_frame_ == other.did_send_begin_main_frame_for_current_frame_
26206    && did_notify_begin_main_frame_not_expected_until_ == other.did_notify_begin_main_frame_not_expected_until_
26207    && did_notify_begin_main_frame_not_expected_soon_ == other.did_notify_begin_main_frame_not_expected_soon_
26208    && wants_begin_main_frame_not_expected_ == other.wants_begin_main_frame_not_expected_
26209    && did_commit_during_frame_ == other.did_commit_during_frame_
26210    && did_invalidate_layer_tree_frame_sink_ == other.did_invalidate_layer_tree_frame_sink_
26211    && did_perform_impl_side_invalidaion_ == other.did_perform_impl_side_invalidaion_
26212    && did_prepare_tiles_ == other.did_prepare_tiles_
26213    && consecutive_checkerboard_animations_ == other.consecutive_checkerboard_animations_
26214    && pending_submit_frames_ == other.pending_submit_frames_
26215    && submit_frames_with_current_layer_tree_frame_sink_ == other.submit_frames_with_current_layer_tree_frame_sink_
26216    && needs_redraw_ == other.needs_redraw_
26217    && needs_prepare_tiles_ == other.needs_prepare_tiles_
26218    && needs_begin_main_frame_ == other.needs_begin_main_frame_
26219    && needs_one_begin_impl_frame_ == other.needs_one_begin_impl_frame_
26220    && visible_ == other.visible_
26221    && begin_frame_source_paused_ == other.begin_frame_source_paused_
26222    && can_draw_ == other.can_draw_
26223    && resourceless_draw_ == other.resourceless_draw_
26224    && has_pending_tree_ == other.has_pending_tree_
26225    && pending_tree_is_ready_for_activation_ == other.pending_tree_is_ready_for_activation_
26226    && active_tree_needs_first_draw_ == other.active_tree_needs_first_draw_
26227    && active_tree_is_ready_to_draw_ == other.active_tree_is_ready_to_draw_
26228    && did_create_and_initialize_first_layer_tree_frame_sink_ == other.did_create_and_initialize_first_layer_tree_frame_sink_
26229    && tree_priority_ == other.tree_priority_
26230    && scroll_handler_state_ == other.scroll_handler_state_
26231    && critical_begin_main_frame_to_activate_is_fast_ == other.critical_begin_main_frame_to_activate_is_fast_
26232    && main_thread_missed_last_deadline_ == other.main_thread_missed_last_deadline_
26233    && video_needs_begin_frames_ == other.video_needs_begin_frames_
26234    && defer_begin_main_frame_ == other.defer_begin_main_frame_
26235    && last_commit_had_no_updates_ == other.last_commit_had_no_updates_
26236    && did_draw_in_last_frame_ == other.did_draw_in_last_frame_
26237    && did_submit_in_last_frame_ == other.did_submit_in_last_frame_
26238    && needs_impl_side_invalidation_ == other.needs_impl_side_invalidation_
26239    && current_pending_tree_is_impl_side_ == other.current_pending_tree_is_impl_side_
26240    && previous_pending_tree_was_impl_side_ == other.previous_pending_tree_was_impl_side_
26241    && processing_animation_worklets_for_active_tree_ == other.processing_animation_worklets_for_active_tree_
26242    && processing_animation_worklets_for_pending_tree_ == other.processing_animation_worklets_for_pending_tree_
26243    && processing_paint_worklets_for_pending_tree_ == other.processing_paint_worklets_for_pending_tree_;
26244 }
26245 
ParseFromArray(const void * raw,size_t size)26246 bool ChromeCompositorStateMachine_MinorState::ParseFromArray(const void* raw, size_t size) {
26247   unknown_fields_.clear();
26248   bool packed_error = false;
26249 
26250   ::protozero::ProtoDecoder dec(raw, size);
26251   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
26252     if (field.id() < _has_field_.size()) {
26253       _has_field_.set(field.id());
26254     }
26255     switch (field.id()) {
26256       case 1 /* commit_count */:
26257         field.get(&commit_count_);
26258         break;
26259       case 2 /* current_frame_number */:
26260         field.get(&current_frame_number_);
26261         break;
26262       case 3 /* last_frame_number_submit_performed */:
26263         field.get(&last_frame_number_submit_performed_);
26264         break;
26265       case 4 /* last_frame_number_draw_performed */:
26266         field.get(&last_frame_number_draw_performed_);
26267         break;
26268       case 5 /* last_frame_number_begin_main_frame_sent */:
26269         field.get(&last_frame_number_begin_main_frame_sent_);
26270         break;
26271       case 6 /* did_draw */:
26272         field.get(&did_draw_);
26273         break;
26274       case 7 /* did_send_begin_main_frame_for_current_frame */:
26275         field.get(&did_send_begin_main_frame_for_current_frame_);
26276         break;
26277       case 8 /* did_notify_begin_main_frame_not_expected_until */:
26278         field.get(&did_notify_begin_main_frame_not_expected_until_);
26279         break;
26280       case 9 /* did_notify_begin_main_frame_not_expected_soon */:
26281         field.get(&did_notify_begin_main_frame_not_expected_soon_);
26282         break;
26283       case 10 /* wants_begin_main_frame_not_expected */:
26284         field.get(&wants_begin_main_frame_not_expected_);
26285         break;
26286       case 11 /* did_commit_during_frame */:
26287         field.get(&did_commit_during_frame_);
26288         break;
26289       case 12 /* did_invalidate_layer_tree_frame_sink */:
26290         field.get(&did_invalidate_layer_tree_frame_sink_);
26291         break;
26292       case 13 /* did_perform_impl_side_invalidaion */:
26293         field.get(&did_perform_impl_side_invalidaion_);
26294         break;
26295       case 14 /* did_prepare_tiles */:
26296         field.get(&did_prepare_tiles_);
26297         break;
26298       case 15 /* consecutive_checkerboard_animations */:
26299         field.get(&consecutive_checkerboard_animations_);
26300         break;
26301       case 16 /* pending_submit_frames */:
26302         field.get(&pending_submit_frames_);
26303         break;
26304       case 17 /* submit_frames_with_current_layer_tree_frame_sink */:
26305         field.get(&submit_frames_with_current_layer_tree_frame_sink_);
26306         break;
26307       case 18 /* needs_redraw */:
26308         field.get(&needs_redraw_);
26309         break;
26310       case 19 /* needs_prepare_tiles */:
26311         field.get(&needs_prepare_tiles_);
26312         break;
26313       case 20 /* needs_begin_main_frame */:
26314         field.get(&needs_begin_main_frame_);
26315         break;
26316       case 21 /* needs_one_begin_impl_frame */:
26317         field.get(&needs_one_begin_impl_frame_);
26318         break;
26319       case 22 /* visible */:
26320         field.get(&visible_);
26321         break;
26322       case 23 /* begin_frame_source_paused */:
26323         field.get(&begin_frame_source_paused_);
26324         break;
26325       case 24 /* can_draw */:
26326         field.get(&can_draw_);
26327         break;
26328       case 25 /* resourceless_draw */:
26329         field.get(&resourceless_draw_);
26330         break;
26331       case 26 /* has_pending_tree */:
26332         field.get(&has_pending_tree_);
26333         break;
26334       case 27 /* pending_tree_is_ready_for_activation */:
26335         field.get(&pending_tree_is_ready_for_activation_);
26336         break;
26337       case 28 /* active_tree_needs_first_draw */:
26338         field.get(&active_tree_needs_first_draw_);
26339         break;
26340       case 29 /* active_tree_is_ready_to_draw */:
26341         field.get(&active_tree_is_ready_to_draw_);
26342         break;
26343       case 30 /* did_create_and_initialize_first_layer_tree_frame_sink */:
26344         field.get(&did_create_and_initialize_first_layer_tree_frame_sink_);
26345         break;
26346       case 31 /* tree_priority */:
26347         field.get(&tree_priority_);
26348         break;
26349       case 32 /* scroll_handler_state */:
26350         field.get(&scroll_handler_state_);
26351         break;
26352       case 33 /* critical_begin_main_frame_to_activate_is_fast */:
26353         field.get(&critical_begin_main_frame_to_activate_is_fast_);
26354         break;
26355       case 34 /* main_thread_missed_last_deadline */:
26356         field.get(&main_thread_missed_last_deadline_);
26357         break;
26358       case 36 /* video_needs_begin_frames */:
26359         field.get(&video_needs_begin_frames_);
26360         break;
26361       case 37 /* defer_begin_main_frame */:
26362         field.get(&defer_begin_main_frame_);
26363         break;
26364       case 38 /* last_commit_had_no_updates */:
26365         field.get(&last_commit_had_no_updates_);
26366         break;
26367       case 39 /* did_draw_in_last_frame */:
26368         field.get(&did_draw_in_last_frame_);
26369         break;
26370       case 40 /* did_submit_in_last_frame */:
26371         field.get(&did_submit_in_last_frame_);
26372         break;
26373       case 41 /* needs_impl_side_invalidation */:
26374         field.get(&needs_impl_side_invalidation_);
26375         break;
26376       case 42 /* current_pending_tree_is_impl_side */:
26377         field.get(&current_pending_tree_is_impl_side_);
26378         break;
26379       case 43 /* previous_pending_tree_was_impl_side */:
26380         field.get(&previous_pending_tree_was_impl_side_);
26381         break;
26382       case 44 /* processing_animation_worklets_for_active_tree */:
26383         field.get(&processing_animation_worklets_for_active_tree_);
26384         break;
26385       case 45 /* processing_animation_worklets_for_pending_tree */:
26386         field.get(&processing_animation_worklets_for_pending_tree_);
26387         break;
26388       case 46 /* processing_paint_worklets_for_pending_tree */:
26389         field.get(&processing_paint_worklets_for_pending_tree_);
26390         break;
26391       default:
26392         field.SerializeAndAppendTo(&unknown_fields_);
26393         break;
26394     }
26395   }
26396   return !packed_error && !dec.bytes_left();
26397 }
26398 
SerializeAsString() const26399 std::string ChromeCompositorStateMachine_MinorState::SerializeAsString() const {
26400   ::protozero::HeapBuffered<::protozero::Message> msg;
26401   Serialize(msg.get());
26402   return msg.SerializeAsString();
26403 }
26404 
SerializeAsArray() const26405 std::vector<uint8_t> ChromeCompositorStateMachine_MinorState::SerializeAsArray() const {
26406   ::protozero::HeapBuffered<::protozero::Message> msg;
26407   Serialize(msg.get());
26408   return msg.SerializeAsArray();
26409 }
26410 
Serialize(::protozero::Message * msg) const26411 void ChromeCompositorStateMachine_MinorState::Serialize(::protozero::Message* msg) const {
26412   // Field 1: commit_count
26413   if (_has_field_[1]) {
26414     msg->AppendVarInt(1, commit_count_);
26415   }
26416 
26417   // Field 2: current_frame_number
26418   if (_has_field_[2]) {
26419     msg->AppendVarInt(2, current_frame_number_);
26420   }
26421 
26422   // Field 3: last_frame_number_submit_performed
26423   if (_has_field_[3]) {
26424     msg->AppendVarInt(3, last_frame_number_submit_performed_);
26425   }
26426 
26427   // Field 4: last_frame_number_draw_performed
26428   if (_has_field_[4]) {
26429     msg->AppendVarInt(4, last_frame_number_draw_performed_);
26430   }
26431 
26432   // Field 5: last_frame_number_begin_main_frame_sent
26433   if (_has_field_[5]) {
26434     msg->AppendVarInt(5, last_frame_number_begin_main_frame_sent_);
26435   }
26436 
26437   // Field 6: did_draw
26438   if (_has_field_[6]) {
26439     msg->AppendTinyVarInt(6, did_draw_);
26440   }
26441 
26442   // Field 7: did_send_begin_main_frame_for_current_frame
26443   if (_has_field_[7]) {
26444     msg->AppendTinyVarInt(7, did_send_begin_main_frame_for_current_frame_);
26445   }
26446 
26447   // Field 8: did_notify_begin_main_frame_not_expected_until
26448   if (_has_field_[8]) {
26449     msg->AppendTinyVarInt(8, did_notify_begin_main_frame_not_expected_until_);
26450   }
26451 
26452   // Field 9: did_notify_begin_main_frame_not_expected_soon
26453   if (_has_field_[9]) {
26454     msg->AppendTinyVarInt(9, did_notify_begin_main_frame_not_expected_soon_);
26455   }
26456 
26457   // Field 10: wants_begin_main_frame_not_expected
26458   if (_has_field_[10]) {
26459     msg->AppendTinyVarInt(10, wants_begin_main_frame_not_expected_);
26460   }
26461 
26462   // Field 11: did_commit_during_frame
26463   if (_has_field_[11]) {
26464     msg->AppendTinyVarInt(11, did_commit_during_frame_);
26465   }
26466 
26467   // Field 12: did_invalidate_layer_tree_frame_sink
26468   if (_has_field_[12]) {
26469     msg->AppendTinyVarInt(12, did_invalidate_layer_tree_frame_sink_);
26470   }
26471 
26472   // Field 13: did_perform_impl_side_invalidaion
26473   if (_has_field_[13]) {
26474     msg->AppendTinyVarInt(13, did_perform_impl_side_invalidaion_);
26475   }
26476 
26477   // Field 14: did_prepare_tiles
26478   if (_has_field_[14]) {
26479     msg->AppendTinyVarInt(14, did_prepare_tiles_);
26480   }
26481 
26482   // Field 15: consecutive_checkerboard_animations
26483   if (_has_field_[15]) {
26484     msg->AppendVarInt(15, consecutive_checkerboard_animations_);
26485   }
26486 
26487   // Field 16: pending_submit_frames
26488   if (_has_field_[16]) {
26489     msg->AppendVarInt(16, pending_submit_frames_);
26490   }
26491 
26492   // Field 17: submit_frames_with_current_layer_tree_frame_sink
26493   if (_has_field_[17]) {
26494     msg->AppendVarInt(17, submit_frames_with_current_layer_tree_frame_sink_);
26495   }
26496 
26497   // Field 18: needs_redraw
26498   if (_has_field_[18]) {
26499     msg->AppendTinyVarInt(18, needs_redraw_);
26500   }
26501 
26502   // Field 19: needs_prepare_tiles
26503   if (_has_field_[19]) {
26504     msg->AppendTinyVarInt(19, needs_prepare_tiles_);
26505   }
26506 
26507   // Field 20: needs_begin_main_frame
26508   if (_has_field_[20]) {
26509     msg->AppendTinyVarInt(20, needs_begin_main_frame_);
26510   }
26511 
26512   // Field 21: needs_one_begin_impl_frame
26513   if (_has_field_[21]) {
26514     msg->AppendTinyVarInt(21, needs_one_begin_impl_frame_);
26515   }
26516 
26517   // Field 22: visible
26518   if (_has_field_[22]) {
26519     msg->AppendTinyVarInt(22, visible_);
26520   }
26521 
26522   // Field 23: begin_frame_source_paused
26523   if (_has_field_[23]) {
26524     msg->AppendTinyVarInt(23, begin_frame_source_paused_);
26525   }
26526 
26527   // Field 24: can_draw
26528   if (_has_field_[24]) {
26529     msg->AppendTinyVarInt(24, can_draw_);
26530   }
26531 
26532   // Field 25: resourceless_draw
26533   if (_has_field_[25]) {
26534     msg->AppendTinyVarInt(25, resourceless_draw_);
26535   }
26536 
26537   // Field 26: has_pending_tree
26538   if (_has_field_[26]) {
26539     msg->AppendTinyVarInt(26, has_pending_tree_);
26540   }
26541 
26542   // Field 27: pending_tree_is_ready_for_activation
26543   if (_has_field_[27]) {
26544     msg->AppendTinyVarInt(27, pending_tree_is_ready_for_activation_);
26545   }
26546 
26547   // Field 28: active_tree_needs_first_draw
26548   if (_has_field_[28]) {
26549     msg->AppendTinyVarInt(28, active_tree_needs_first_draw_);
26550   }
26551 
26552   // Field 29: active_tree_is_ready_to_draw
26553   if (_has_field_[29]) {
26554     msg->AppendTinyVarInt(29, active_tree_is_ready_to_draw_);
26555   }
26556 
26557   // Field 30: did_create_and_initialize_first_layer_tree_frame_sink
26558   if (_has_field_[30]) {
26559     msg->AppendTinyVarInt(30, did_create_and_initialize_first_layer_tree_frame_sink_);
26560   }
26561 
26562   // Field 31: tree_priority
26563   if (_has_field_[31]) {
26564     msg->AppendVarInt(31, tree_priority_);
26565   }
26566 
26567   // Field 32: scroll_handler_state
26568   if (_has_field_[32]) {
26569     msg->AppendVarInt(32, scroll_handler_state_);
26570   }
26571 
26572   // Field 33: critical_begin_main_frame_to_activate_is_fast
26573   if (_has_field_[33]) {
26574     msg->AppendTinyVarInt(33, critical_begin_main_frame_to_activate_is_fast_);
26575   }
26576 
26577   // Field 34: main_thread_missed_last_deadline
26578   if (_has_field_[34]) {
26579     msg->AppendTinyVarInt(34, main_thread_missed_last_deadline_);
26580   }
26581 
26582   // Field 36: video_needs_begin_frames
26583   if (_has_field_[36]) {
26584     msg->AppendTinyVarInt(36, video_needs_begin_frames_);
26585   }
26586 
26587   // Field 37: defer_begin_main_frame
26588   if (_has_field_[37]) {
26589     msg->AppendTinyVarInt(37, defer_begin_main_frame_);
26590   }
26591 
26592   // Field 38: last_commit_had_no_updates
26593   if (_has_field_[38]) {
26594     msg->AppendTinyVarInt(38, last_commit_had_no_updates_);
26595   }
26596 
26597   // Field 39: did_draw_in_last_frame
26598   if (_has_field_[39]) {
26599     msg->AppendTinyVarInt(39, did_draw_in_last_frame_);
26600   }
26601 
26602   // Field 40: did_submit_in_last_frame
26603   if (_has_field_[40]) {
26604     msg->AppendTinyVarInt(40, did_submit_in_last_frame_);
26605   }
26606 
26607   // Field 41: needs_impl_side_invalidation
26608   if (_has_field_[41]) {
26609     msg->AppendTinyVarInt(41, needs_impl_side_invalidation_);
26610   }
26611 
26612   // Field 42: current_pending_tree_is_impl_side
26613   if (_has_field_[42]) {
26614     msg->AppendTinyVarInt(42, current_pending_tree_is_impl_side_);
26615   }
26616 
26617   // Field 43: previous_pending_tree_was_impl_side
26618   if (_has_field_[43]) {
26619     msg->AppendTinyVarInt(43, previous_pending_tree_was_impl_side_);
26620   }
26621 
26622   // Field 44: processing_animation_worklets_for_active_tree
26623   if (_has_field_[44]) {
26624     msg->AppendTinyVarInt(44, processing_animation_worklets_for_active_tree_);
26625   }
26626 
26627   // Field 45: processing_animation_worklets_for_pending_tree
26628   if (_has_field_[45]) {
26629     msg->AppendTinyVarInt(45, processing_animation_worklets_for_pending_tree_);
26630   }
26631 
26632   // Field 46: processing_paint_worklets_for_pending_tree
26633   if (_has_field_[46]) {
26634     msg->AppendTinyVarInt(46, processing_paint_worklets_for_pending_tree_);
26635   }
26636 
26637   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
26638 }
26639 
26640 
26641 ChromeCompositorStateMachine_MajorState::ChromeCompositorStateMachine_MajorState() = default;
26642 ChromeCompositorStateMachine_MajorState::~ChromeCompositorStateMachine_MajorState() = default;
26643 ChromeCompositorStateMachine_MajorState::ChromeCompositorStateMachine_MajorState(const ChromeCompositorStateMachine_MajorState&) = default;
26644 ChromeCompositorStateMachine_MajorState& ChromeCompositorStateMachine_MajorState::operator=(const ChromeCompositorStateMachine_MajorState&) = default;
26645 ChromeCompositorStateMachine_MajorState::ChromeCompositorStateMachine_MajorState(ChromeCompositorStateMachine_MajorState&&) noexcept = default;
26646 ChromeCompositorStateMachine_MajorState& ChromeCompositorStateMachine_MajorState::operator=(ChromeCompositorStateMachine_MajorState&&) = default;
26647 
operator ==(const ChromeCompositorStateMachine_MajorState & other) const26648 bool ChromeCompositorStateMachine_MajorState::operator==(const ChromeCompositorStateMachine_MajorState& other) const {
26649   return unknown_fields_ == other.unknown_fields_
26650    && next_action_ == other.next_action_
26651    && begin_impl_frame_state_ == other.begin_impl_frame_state_
26652    && begin_main_frame_state_ == other.begin_main_frame_state_
26653    && layer_tree_frame_sink_state_ == other.layer_tree_frame_sink_state_
26654    && forced_redraw_state_ == other.forced_redraw_state_;
26655 }
26656 
ParseFromArray(const void * raw,size_t size)26657 bool ChromeCompositorStateMachine_MajorState::ParseFromArray(const void* raw, size_t size) {
26658   unknown_fields_.clear();
26659   bool packed_error = false;
26660 
26661   ::protozero::ProtoDecoder dec(raw, size);
26662   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
26663     if (field.id() < _has_field_.size()) {
26664       _has_field_.set(field.id());
26665     }
26666     switch (field.id()) {
26667       case 1 /* next_action */:
26668         field.get(&next_action_);
26669         break;
26670       case 2 /* begin_impl_frame_state */:
26671         field.get(&begin_impl_frame_state_);
26672         break;
26673       case 3 /* begin_main_frame_state */:
26674         field.get(&begin_main_frame_state_);
26675         break;
26676       case 4 /* layer_tree_frame_sink_state */:
26677         field.get(&layer_tree_frame_sink_state_);
26678         break;
26679       case 5 /* forced_redraw_state */:
26680         field.get(&forced_redraw_state_);
26681         break;
26682       default:
26683         field.SerializeAndAppendTo(&unknown_fields_);
26684         break;
26685     }
26686   }
26687   return !packed_error && !dec.bytes_left();
26688 }
26689 
SerializeAsString() const26690 std::string ChromeCompositorStateMachine_MajorState::SerializeAsString() const {
26691   ::protozero::HeapBuffered<::protozero::Message> msg;
26692   Serialize(msg.get());
26693   return msg.SerializeAsString();
26694 }
26695 
SerializeAsArray() const26696 std::vector<uint8_t> ChromeCompositorStateMachine_MajorState::SerializeAsArray() const {
26697   ::protozero::HeapBuffered<::protozero::Message> msg;
26698   Serialize(msg.get());
26699   return msg.SerializeAsArray();
26700 }
26701 
Serialize(::protozero::Message * msg) const26702 void ChromeCompositorStateMachine_MajorState::Serialize(::protozero::Message* msg) const {
26703   // Field 1: next_action
26704   if (_has_field_[1]) {
26705     msg->AppendVarInt(1, next_action_);
26706   }
26707 
26708   // Field 2: begin_impl_frame_state
26709   if (_has_field_[2]) {
26710     msg->AppendVarInt(2, begin_impl_frame_state_);
26711   }
26712 
26713   // Field 3: begin_main_frame_state
26714   if (_has_field_[3]) {
26715     msg->AppendVarInt(3, begin_main_frame_state_);
26716   }
26717 
26718   // Field 4: layer_tree_frame_sink_state
26719   if (_has_field_[4]) {
26720     msg->AppendVarInt(4, layer_tree_frame_sink_state_);
26721   }
26722 
26723   // Field 5: forced_redraw_state
26724   if (_has_field_[5]) {
26725     msg->AppendVarInt(5, forced_redraw_state_);
26726   }
26727 
26728   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
26729 }
26730 
26731 
26732 ChromeCompositorSchedulerState::ChromeCompositorSchedulerState() = default;
26733 ChromeCompositorSchedulerState::~ChromeCompositorSchedulerState() = default;
26734 ChromeCompositorSchedulerState::ChromeCompositorSchedulerState(const ChromeCompositorSchedulerState&) = default;
26735 ChromeCompositorSchedulerState& ChromeCompositorSchedulerState::operator=(const ChromeCompositorSchedulerState&) = default;
26736 ChromeCompositorSchedulerState::ChromeCompositorSchedulerState(ChromeCompositorSchedulerState&&) noexcept = default;
26737 ChromeCompositorSchedulerState& ChromeCompositorSchedulerState::operator=(ChromeCompositorSchedulerState&&) = default;
26738 
operator ==(const ChromeCompositorSchedulerState & other) const26739 bool ChromeCompositorSchedulerState::operator==(const ChromeCompositorSchedulerState& other) const {
26740   return unknown_fields_ == other.unknown_fields_
26741    && state_machine_ == other.state_machine_
26742    && observing_begin_frame_source_ == other.observing_begin_frame_source_
26743    && begin_impl_frame_deadline_task_ == other.begin_impl_frame_deadline_task_
26744    && pending_begin_frame_task_ == other.pending_begin_frame_task_
26745    && skipped_last_frame_missed_exceeded_deadline_ == other.skipped_last_frame_missed_exceeded_deadline_
26746    && inside_action_ == other.inside_action_
26747    && deadline_mode_ == other.deadline_mode_
26748    && deadline_us_ == other.deadline_us_
26749    && deadline_scheduled_at_us_ == other.deadline_scheduled_at_us_
26750    && now_us_ == other.now_us_
26751    && now_to_deadline_delta_us_ == other.now_to_deadline_delta_us_
26752    && now_to_deadline_scheduled_at_delta_us_ == other.now_to_deadline_scheduled_at_delta_us_
26753    && begin_impl_frame_args_ == other.begin_impl_frame_args_
26754    && begin_frame_observer_state_ == other.begin_frame_observer_state_
26755    && begin_frame_source_state_ == other.begin_frame_source_state_
26756    && compositor_timing_history_ == other.compositor_timing_history_;
26757 }
26758 
ParseFromArray(const void * raw,size_t size)26759 bool ChromeCompositorSchedulerState::ParseFromArray(const void* raw, size_t size) {
26760   unknown_fields_.clear();
26761   bool packed_error = false;
26762 
26763   ::protozero::ProtoDecoder dec(raw, size);
26764   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
26765     if (field.id() < _has_field_.size()) {
26766       _has_field_.set(field.id());
26767     }
26768     switch (field.id()) {
26769       case 1 /* state_machine */:
26770         (*state_machine_).ParseFromArray(field.data(), field.size());
26771         break;
26772       case 2 /* observing_begin_frame_source */:
26773         field.get(&observing_begin_frame_source_);
26774         break;
26775       case 3 /* begin_impl_frame_deadline_task */:
26776         field.get(&begin_impl_frame_deadline_task_);
26777         break;
26778       case 4 /* pending_begin_frame_task */:
26779         field.get(&pending_begin_frame_task_);
26780         break;
26781       case 5 /* skipped_last_frame_missed_exceeded_deadline */:
26782         field.get(&skipped_last_frame_missed_exceeded_deadline_);
26783         break;
26784       case 7 /* inside_action */:
26785         field.get(&inside_action_);
26786         break;
26787       case 8 /* deadline_mode */:
26788         field.get(&deadline_mode_);
26789         break;
26790       case 9 /* deadline_us */:
26791         field.get(&deadline_us_);
26792         break;
26793       case 10 /* deadline_scheduled_at_us */:
26794         field.get(&deadline_scheduled_at_us_);
26795         break;
26796       case 11 /* now_us */:
26797         field.get(&now_us_);
26798         break;
26799       case 12 /* now_to_deadline_delta_us */:
26800         field.get(&now_to_deadline_delta_us_);
26801         break;
26802       case 13 /* now_to_deadline_scheduled_at_delta_us */:
26803         field.get(&now_to_deadline_scheduled_at_delta_us_);
26804         break;
26805       case 14 /* begin_impl_frame_args */:
26806         (*begin_impl_frame_args_).ParseFromArray(field.data(), field.size());
26807         break;
26808       case 15 /* begin_frame_observer_state */:
26809         (*begin_frame_observer_state_).ParseFromArray(field.data(), field.size());
26810         break;
26811       case 16 /* begin_frame_source_state */:
26812         (*begin_frame_source_state_).ParseFromArray(field.data(), field.size());
26813         break;
26814       case 17 /* compositor_timing_history */:
26815         (*compositor_timing_history_).ParseFromArray(field.data(), field.size());
26816         break;
26817       default:
26818         field.SerializeAndAppendTo(&unknown_fields_);
26819         break;
26820     }
26821   }
26822   return !packed_error && !dec.bytes_left();
26823 }
26824 
SerializeAsString() const26825 std::string ChromeCompositorSchedulerState::SerializeAsString() const {
26826   ::protozero::HeapBuffered<::protozero::Message> msg;
26827   Serialize(msg.get());
26828   return msg.SerializeAsString();
26829 }
26830 
SerializeAsArray() const26831 std::vector<uint8_t> ChromeCompositorSchedulerState::SerializeAsArray() const {
26832   ::protozero::HeapBuffered<::protozero::Message> msg;
26833   Serialize(msg.get());
26834   return msg.SerializeAsArray();
26835 }
26836 
Serialize(::protozero::Message * msg) const26837 void ChromeCompositorSchedulerState::Serialize(::protozero::Message* msg) const {
26838   // Field 1: state_machine
26839   if (_has_field_[1]) {
26840     (*state_machine_).Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
26841   }
26842 
26843   // Field 2: observing_begin_frame_source
26844   if (_has_field_[2]) {
26845     msg->AppendTinyVarInt(2, observing_begin_frame_source_);
26846   }
26847 
26848   // Field 3: begin_impl_frame_deadline_task
26849   if (_has_field_[3]) {
26850     msg->AppendTinyVarInt(3, begin_impl_frame_deadline_task_);
26851   }
26852 
26853   // Field 4: pending_begin_frame_task
26854   if (_has_field_[4]) {
26855     msg->AppendTinyVarInt(4, pending_begin_frame_task_);
26856   }
26857 
26858   // Field 5: skipped_last_frame_missed_exceeded_deadline
26859   if (_has_field_[5]) {
26860     msg->AppendTinyVarInt(5, skipped_last_frame_missed_exceeded_deadline_);
26861   }
26862 
26863   // Field 7: inside_action
26864   if (_has_field_[7]) {
26865     msg->AppendVarInt(7, inside_action_);
26866   }
26867 
26868   // Field 8: deadline_mode
26869   if (_has_field_[8]) {
26870     msg->AppendVarInt(8, deadline_mode_);
26871   }
26872 
26873   // Field 9: deadline_us
26874   if (_has_field_[9]) {
26875     msg->AppendVarInt(9, deadline_us_);
26876   }
26877 
26878   // Field 10: deadline_scheduled_at_us
26879   if (_has_field_[10]) {
26880     msg->AppendVarInt(10, deadline_scheduled_at_us_);
26881   }
26882 
26883   // Field 11: now_us
26884   if (_has_field_[11]) {
26885     msg->AppendVarInt(11, now_us_);
26886   }
26887 
26888   // Field 12: now_to_deadline_delta_us
26889   if (_has_field_[12]) {
26890     msg->AppendVarInt(12, now_to_deadline_delta_us_);
26891   }
26892 
26893   // Field 13: now_to_deadline_scheduled_at_delta_us
26894   if (_has_field_[13]) {
26895     msg->AppendVarInt(13, now_to_deadline_scheduled_at_delta_us_);
26896   }
26897 
26898   // Field 14: begin_impl_frame_args
26899   if (_has_field_[14]) {
26900     (*begin_impl_frame_args_).Serialize(msg->BeginNestedMessage<::protozero::Message>(14));
26901   }
26902 
26903   // Field 15: begin_frame_observer_state
26904   if (_has_field_[15]) {
26905     (*begin_frame_observer_state_).Serialize(msg->BeginNestedMessage<::protozero::Message>(15));
26906   }
26907 
26908   // Field 16: begin_frame_source_state
26909   if (_has_field_[16]) {
26910     (*begin_frame_source_state_).Serialize(msg->BeginNestedMessage<::protozero::Message>(16));
26911   }
26912 
26913   // Field 17: compositor_timing_history
26914   if (_has_field_[17]) {
26915     (*compositor_timing_history_).Serialize(msg->BeginNestedMessage<::protozero::Message>(17));
26916   }
26917 
26918   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
26919 }
26920 
26921 }  // namespace perfetto
26922 }  // namespace protos
26923 }  // namespace gen
26924 #if defined(__GNUC__) || defined(__clang__)
26925 #pragma GCC diagnostic pop
26926 #endif
26927 // gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_content_settings_event_info.gen.cc
26928 // gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/chrome_content_settings_event_info.gen.h
26929 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
26930 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_CONTENT_SETTINGS_EVENT_INFO_PROTO_CPP_H_
26931 #define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_CONTENT_SETTINGS_EVENT_INFO_PROTO_CPP_H_
26932 
26933 #include <stdint.h>
26934 #include <bitset>
26935 #include <vector>
26936 #include <string>
26937 #include <type_traits>
26938 
26939 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
26940 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
26941 // gen_amalgamated expanded: #include "perfetto/base/export.h"
26942 
26943 namespace perfetto {
26944 namespace protos {
26945 namespace gen {
26946 class ChromeContentSettingsEventInfo;
26947 }  // namespace perfetto
26948 }  // namespace protos
26949 }  // namespace gen
26950 
26951 namespace protozero {
26952 class Message;
26953 }  // namespace protozero
26954 
26955 namespace perfetto {
26956 namespace protos {
26957 namespace gen {
26958 
26959 class PERFETTO_EXPORT ChromeContentSettingsEventInfo : public ::protozero::CppMessageObj {
26960  public:
26961   enum FieldNumbers {
26962     kNumberOfExceptionsFieldNumber = 1,
26963   };
26964 
26965   ChromeContentSettingsEventInfo();
26966   ~ChromeContentSettingsEventInfo() override;
26967   ChromeContentSettingsEventInfo(ChromeContentSettingsEventInfo&&) noexcept;
26968   ChromeContentSettingsEventInfo& operator=(ChromeContentSettingsEventInfo&&);
26969   ChromeContentSettingsEventInfo(const ChromeContentSettingsEventInfo&);
26970   ChromeContentSettingsEventInfo& operator=(const ChromeContentSettingsEventInfo&);
26971   bool operator==(const ChromeContentSettingsEventInfo&) const;
operator !=(const ChromeContentSettingsEventInfo & other) const26972   bool operator!=(const ChromeContentSettingsEventInfo& other) const { return !(*this == other); }
26973 
26974   bool ParseFromArray(const void*, size_t) override;
26975   std::string SerializeAsString() const override;
26976   std::vector<uint8_t> SerializeAsArray() const override;
26977   void Serialize(::protozero::Message*) const;
26978 
has_number_of_exceptions() const26979   bool has_number_of_exceptions() const { return _has_field_[1]; }
number_of_exceptions() const26980   uint32_t number_of_exceptions() const { return number_of_exceptions_; }
set_number_of_exceptions(uint32_t value)26981   void set_number_of_exceptions(uint32_t value) { number_of_exceptions_ = value; _has_field_.set(1); }
26982 
26983  private:
26984   uint32_t number_of_exceptions_{};
26985 
26986   // Allows to preserve unknown protobuf fields for compatibility
26987   // with future versions of .proto files.
26988   std::string unknown_fields_;
26989 
26990   std::bitset<2> _has_field_{};
26991 };
26992 
26993 }  // namespace perfetto
26994 }  // namespace protos
26995 }  // namespace gen
26996 
26997 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_CONTENT_SETTINGS_EVENT_INFO_PROTO_CPP_H_
26998 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
26999 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
27000 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
27001 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
27002 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
27003 #if defined(__GNUC__) || defined(__clang__)
27004 #pragma GCC diagnostic push
27005 #pragma GCC diagnostic ignored "-Wfloat-equal"
27006 #endif
27007 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_content_settings_event_info.gen.h"
27008 
27009 namespace perfetto {
27010 namespace protos {
27011 namespace gen {
27012 
27013 ChromeContentSettingsEventInfo::ChromeContentSettingsEventInfo() = default;
27014 ChromeContentSettingsEventInfo::~ChromeContentSettingsEventInfo() = default;
27015 ChromeContentSettingsEventInfo::ChromeContentSettingsEventInfo(const ChromeContentSettingsEventInfo&) = default;
27016 ChromeContentSettingsEventInfo& ChromeContentSettingsEventInfo::operator=(const ChromeContentSettingsEventInfo&) = default;
27017 ChromeContentSettingsEventInfo::ChromeContentSettingsEventInfo(ChromeContentSettingsEventInfo&&) noexcept = default;
27018 ChromeContentSettingsEventInfo& ChromeContentSettingsEventInfo::operator=(ChromeContentSettingsEventInfo&&) = default;
27019 
operator ==(const ChromeContentSettingsEventInfo & other) const27020 bool ChromeContentSettingsEventInfo::operator==(const ChromeContentSettingsEventInfo& other) const {
27021   return unknown_fields_ == other.unknown_fields_
27022    && number_of_exceptions_ == other.number_of_exceptions_;
27023 }
27024 
ParseFromArray(const void * raw,size_t size)27025 bool ChromeContentSettingsEventInfo::ParseFromArray(const void* raw, size_t size) {
27026   unknown_fields_.clear();
27027   bool packed_error = false;
27028 
27029   ::protozero::ProtoDecoder dec(raw, size);
27030   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
27031     if (field.id() < _has_field_.size()) {
27032       _has_field_.set(field.id());
27033     }
27034     switch (field.id()) {
27035       case 1 /* number_of_exceptions */:
27036         field.get(&number_of_exceptions_);
27037         break;
27038       default:
27039         field.SerializeAndAppendTo(&unknown_fields_);
27040         break;
27041     }
27042   }
27043   return !packed_error && !dec.bytes_left();
27044 }
27045 
SerializeAsString() const27046 std::string ChromeContentSettingsEventInfo::SerializeAsString() const {
27047   ::protozero::HeapBuffered<::protozero::Message> msg;
27048   Serialize(msg.get());
27049   return msg.SerializeAsString();
27050 }
27051 
SerializeAsArray() const27052 std::vector<uint8_t> ChromeContentSettingsEventInfo::SerializeAsArray() const {
27053   ::protozero::HeapBuffered<::protozero::Message> msg;
27054   Serialize(msg.get());
27055   return msg.SerializeAsArray();
27056 }
27057 
Serialize(::protozero::Message * msg) const27058 void ChromeContentSettingsEventInfo::Serialize(::protozero::Message* msg) const {
27059   // Field 1: number_of_exceptions
27060   if (_has_field_[1]) {
27061     msg->AppendVarInt(1, number_of_exceptions_);
27062   }
27063 
27064   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
27065 }
27066 
27067 }  // namespace perfetto
27068 }  // namespace protos
27069 }  // namespace gen
27070 #if defined(__GNUC__) || defined(__clang__)
27071 #pragma GCC diagnostic pop
27072 #endif
27073 // gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_frame_reporter.gen.cc
27074 // gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/chrome_frame_reporter.gen.h
27075 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
27076 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_FRAME_REPORTER_PROTO_CPP_H_
27077 #define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_FRAME_REPORTER_PROTO_CPP_H_
27078 
27079 #include <stdint.h>
27080 #include <bitset>
27081 #include <vector>
27082 #include <string>
27083 #include <type_traits>
27084 
27085 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
27086 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
27087 // gen_amalgamated expanded: #include "perfetto/base/export.h"
27088 
27089 namespace perfetto {
27090 namespace protos {
27091 namespace gen {
27092 class ChromeFrameReporter;
27093 enum ChromeFrameReporter_State : int;
27094 enum ChromeFrameReporter_FrameDropReason : int;
27095 enum ChromeFrameReporter_ScrollState : int;
27096 }  // namespace perfetto
27097 }  // namespace protos
27098 }  // namespace gen
27099 
27100 namespace protozero {
27101 class Message;
27102 }  // namespace protozero
27103 
27104 namespace perfetto {
27105 namespace protos {
27106 namespace gen {
27107 enum ChromeFrameReporter_State : int {
27108   ChromeFrameReporter_State_STATE_NO_UPDATE_DESIRED = 0,
27109   ChromeFrameReporter_State_STATE_PRESENTED_ALL = 1,
27110   ChromeFrameReporter_State_STATE_PRESENTED_PARTIAL = 2,
27111   ChromeFrameReporter_State_STATE_DROPPED = 3,
27112 };
27113 enum ChromeFrameReporter_FrameDropReason : int {
27114   ChromeFrameReporter_FrameDropReason_REASON_UNSPECIFIED = 0,
27115   ChromeFrameReporter_FrameDropReason_REASON_DISPLAY_COMPOSITOR = 1,
27116   ChromeFrameReporter_FrameDropReason_REASON_MAIN_THREAD = 2,
27117   ChromeFrameReporter_FrameDropReason_REASON_CLIENT_COMPOSITOR = 3,
27118 };
27119 enum ChromeFrameReporter_ScrollState : int {
27120   ChromeFrameReporter_ScrollState_SCROLL_NONE = 0,
27121   ChromeFrameReporter_ScrollState_SCROLL_MAIN_THREAD = 1,
27122   ChromeFrameReporter_ScrollState_SCROLL_COMPOSITOR_THREAD = 2,
27123   ChromeFrameReporter_ScrollState_SCROLL_UNKNOWN = 3,
27124 };
27125 
27126 class PERFETTO_EXPORT ChromeFrameReporter : public ::protozero::CppMessageObj {
27127  public:
27128   using State = ChromeFrameReporter_State;
27129   static constexpr auto STATE_NO_UPDATE_DESIRED = ChromeFrameReporter_State_STATE_NO_UPDATE_DESIRED;
27130   static constexpr auto STATE_PRESENTED_ALL = ChromeFrameReporter_State_STATE_PRESENTED_ALL;
27131   static constexpr auto STATE_PRESENTED_PARTIAL = ChromeFrameReporter_State_STATE_PRESENTED_PARTIAL;
27132   static constexpr auto STATE_DROPPED = ChromeFrameReporter_State_STATE_DROPPED;
27133   static constexpr auto State_MIN = ChromeFrameReporter_State_STATE_NO_UPDATE_DESIRED;
27134   static constexpr auto State_MAX = ChromeFrameReporter_State_STATE_DROPPED;
27135   using FrameDropReason = ChromeFrameReporter_FrameDropReason;
27136   static constexpr auto REASON_UNSPECIFIED = ChromeFrameReporter_FrameDropReason_REASON_UNSPECIFIED;
27137   static constexpr auto REASON_DISPLAY_COMPOSITOR = ChromeFrameReporter_FrameDropReason_REASON_DISPLAY_COMPOSITOR;
27138   static constexpr auto REASON_MAIN_THREAD = ChromeFrameReporter_FrameDropReason_REASON_MAIN_THREAD;
27139   static constexpr auto REASON_CLIENT_COMPOSITOR = ChromeFrameReporter_FrameDropReason_REASON_CLIENT_COMPOSITOR;
27140   static constexpr auto FrameDropReason_MIN = ChromeFrameReporter_FrameDropReason_REASON_UNSPECIFIED;
27141   static constexpr auto FrameDropReason_MAX = ChromeFrameReporter_FrameDropReason_REASON_CLIENT_COMPOSITOR;
27142   using ScrollState = ChromeFrameReporter_ScrollState;
27143   static constexpr auto SCROLL_NONE = ChromeFrameReporter_ScrollState_SCROLL_NONE;
27144   static constexpr auto SCROLL_MAIN_THREAD = ChromeFrameReporter_ScrollState_SCROLL_MAIN_THREAD;
27145   static constexpr auto SCROLL_COMPOSITOR_THREAD = ChromeFrameReporter_ScrollState_SCROLL_COMPOSITOR_THREAD;
27146   static constexpr auto SCROLL_UNKNOWN = ChromeFrameReporter_ScrollState_SCROLL_UNKNOWN;
27147   static constexpr auto ScrollState_MIN = ChromeFrameReporter_ScrollState_SCROLL_NONE;
27148   static constexpr auto ScrollState_MAX = ChromeFrameReporter_ScrollState_SCROLL_UNKNOWN;
27149   enum FieldNumbers {
27150     kStateFieldNumber = 1,
27151     kReasonFieldNumber = 2,
27152     kFrameSourceFieldNumber = 3,
27153     kFrameSequenceFieldNumber = 4,
27154     kAffectsSmoothnessFieldNumber = 5,
27155     kScrollStateFieldNumber = 6,
27156     kHasMainAnimationFieldNumber = 7,
27157     kHasCompositorAnimationFieldNumber = 8,
27158     kHasSmoothInputMainFieldNumber = 9,
27159     kHasMissingContentFieldNumber = 10,
27160     kLayerTreeHostIdFieldNumber = 11,
27161   };
27162 
27163   ChromeFrameReporter();
27164   ~ChromeFrameReporter() override;
27165   ChromeFrameReporter(ChromeFrameReporter&&) noexcept;
27166   ChromeFrameReporter& operator=(ChromeFrameReporter&&);
27167   ChromeFrameReporter(const ChromeFrameReporter&);
27168   ChromeFrameReporter& operator=(const ChromeFrameReporter&);
27169   bool operator==(const ChromeFrameReporter&) const;
operator !=(const ChromeFrameReporter & other) const27170   bool operator!=(const ChromeFrameReporter& other) const { return !(*this == other); }
27171 
27172   bool ParseFromArray(const void*, size_t) override;
27173   std::string SerializeAsString() const override;
27174   std::vector<uint8_t> SerializeAsArray() const override;
27175   void Serialize(::protozero::Message*) const;
27176 
has_state() const27177   bool has_state() const { return _has_field_[1]; }
state() const27178   ChromeFrameReporter_State state() const { return state_; }
set_state(ChromeFrameReporter_State value)27179   void set_state(ChromeFrameReporter_State value) { state_ = value; _has_field_.set(1); }
27180 
has_reason() const27181   bool has_reason() const { return _has_field_[2]; }
reason() const27182   ChromeFrameReporter_FrameDropReason reason() const { return reason_; }
set_reason(ChromeFrameReporter_FrameDropReason value)27183   void set_reason(ChromeFrameReporter_FrameDropReason value) { reason_ = value; _has_field_.set(2); }
27184 
has_frame_source() const27185   bool has_frame_source() const { return _has_field_[3]; }
frame_source() const27186   uint64_t frame_source() const { return frame_source_; }
set_frame_source(uint64_t value)27187   void set_frame_source(uint64_t value) { frame_source_ = value; _has_field_.set(3); }
27188 
has_frame_sequence() const27189   bool has_frame_sequence() const { return _has_field_[4]; }
frame_sequence() const27190   uint64_t frame_sequence() const { return frame_sequence_; }
set_frame_sequence(uint64_t value)27191   void set_frame_sequence(uint64_t value) { frame_sequence_ = value; _has_field_.set(4); }
27192 
has_affects_smoothness() const27193   bool has_affects_smoothness() const { return _has_field_[5]; }
affects_smoothness() const27194   bool affects_smoothness() const { return affects_smoothness_; }
set_affects_smoothness(bool value)27195   void set_affects_smoothness(bool value) { affects_smoothness_ = value; _has_field_.set(5); }
27196 
has_scroll_state() const27197   bool has_scroll_state() const { return _has_field_[6]; }
scroll_state() const27198   ChromeFrameReporter_ScrollState scroll_state() const { return scroll_state_; }
set_scroll_state(ChromeFrameReporter_ScrollState value)27199   void set_scroll_state(ChromeFrameReporter_ScrollState value) { scroll_state_ = value; _has_field_.set(6); }
27200 
has_has_main_animation() const27201   bool has_has_main_animation() const { return _has_field_[7]; }
has_main_animation() const27202   bool has_main_animation() const { return has_main_animation_; }
set_has_main_animation(bool value)27203   void set_has_main_animation(bool value) { has_main_animation_ = value; _has_field_.set(7); }
27204 
has_has_compositor_animation() const27205   bool has_has_compositor_animation() const { return _has_field_[8]; }
has_compositor_animation() const27206   bool has_compositor_animation() const { return has_compositor_animation_; }
set_has_compositor_animation(bool value)27207   void set_has_compositor_animation(bool value) { has_compositor_animation_ = value; _has_field_.set(8); }
27208 
has_has_smooth_input_main() const27209   bool has_has_smooth_input_main() const { return _has_field_[9]; }
has_smooth_input_main() const27210   bool has_smooth_input_main() const { return has_smooth_input_main_; }
set_has_smooth_input_main(bool value)27211   void set_has_smooth_input_main(bool value) { has_smooth_input_main_ = value; _has_field_.set(9); }
27212 
has_has_missing_content() const27213   bool has_has_missing_content() const { return _has_field_[10]; }
has_missing_content() const27214   bool has_missing_content() const { return has_missing_content_; }
set_has_missing_content(bool value)27215   void set_has_missing_content(bool value) { has_missing_content_ = value; _has_field_.set(10); }
27216 
has_layer_tree_host_id() const27217   bool has_layer_tree_host_id() const { return _has_field_[11]; }
layer_tree_host_id() const27218   uint64_t layer_tree_host_id() const { return layer_tree_host_id_; }
set_layer_tree_host_id(uint64_t value)27219   void set_layer_tree_host_id(uint64_t value) { layer_tree_host_id_ = value; _has_field_.set(11); }
27220 
27221  private:
27222   ChromeFrameReporter_State state_{};
27223   ChromeFrameReporter_FrameDropReason reason_{};
27224   uint64_t frame_source_{};
27225   uint64_t frame_sequence_{};
27226   bool affects_smoothness_{};
27227   ChromeFrameReporter_ScrollState scroll_state_{};
27228   bool has_main_animation_{};
27229   bool has_compositor_animation_{};
27230   bool has_smooth_input_main_{};
27231   bool has_missing_content_{};
27232   uint64_t layer_tree_host_id_{};
27233 
27234   // Allows to preserve unknown protobuf fields for compatibility
27235   // with future versions of .proto files.
27236   std::string unknown_fields_;
27237 
27238   std::bitset<12> _has_field_{};
27239 };
27240 
27241 }  // namespace perfetto
27242 }  // namespace protos
27243 }  // namespace gen
27244 
27245 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_FRAME_REPORTER_PROTO_CPP_H_
27246 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
27247 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
27248 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
27249 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
27250 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
27251 #if defined(__GNUC__) || defined(__clang__)
27252 #pragma GCC diagnostic push
27253 #pragma GCC diagnostic ignored "-Wfloat-equal"
27254 #endif
27255 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_frame_reporter.gen.h"
27256 
27257 namespace perfetto {
27258 namespace protos {
27259 namespace gen {
27260 
27261 ChromeFrameReporter::ChromeFrameReporter() = default;
27262 ChromeFrameReporter::~ChromeFrameReporter() = default;
27263 ChromeFrameReporter::ChromeFrameReporter(const ChromeFrameReporter&) = default;
27264 ChromeFrameReporter& ChromeFrameReporter::operator=(const ChromeFrameReporter&) = default;
27265 ChromeFrameReporter::ChromeFrameReporter(ChromeFrameReporter&&) noexcept = default;
27266 ChromeFrameReporter& ChromeFrameReporter::operator=(ChromeFrameReporter&&) = default;
27267 
operator ==(const ChromeFrameReporter & other) const27268 bool ChromeFrameReporter::operator==(const ChromeFrameReporter& other) const {
27269   return unknown_fields_ == other.unknown_fields_
27270    && state_ == other.state_
27271    && reason_ == other.reason_
27272    && frame_source_ == other.frame_source_
27273    && frame_sequence_ == other.frame_sequence_
27274    && affects_smoothness_ == other.affects_smoothness_
27275    && scroll_state_ == other.scroll_state_
27276    && has_main_animation_ == other.has_main_animation_
27277    && has_compositor_animation_ == other.has_compositor_animation_
27278    && has_smooth_input_main_ == other.has_smooth_input_main_
27279    && has_missing_content_ == other.has_missing_content_
27280    && layer_tree_host_id_ == other.layer_tree_host_id_;
27281 }
27282 
ParseFromArray(const void * raw,size_t size)27283 bool ChromeFrameReporter::ParseFromArray(const void* raw, size_t size) {
27284   unknown_fields_.clear();
27285   bool packed_error = false;
27286 
27287   ::protozero::ProtoDecoder dec(raw, size);
27288   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
27289     if (field.id() < _has_field_.size()) {
27290       _has_field_.set(field.id());
27291     }
27292     switch (field.id()) {
27293       case 1 /* state */:
27294         field.get(&state_);
27295         break;
27296       case 2 /* reason */:
27297         field.get(&reason_);
27298         break;
27299       case 3 /* frame_source */:
27300         field.get(&frame_source_);
27301         break;
27302       case 4 /* frame_sequence */:
27303         field.get(&frame_sequence_);
27304         break;
27305       case 5 /* affects_smoothness */:
27306         field.get(&affects_smoothness_);
27307         break;
27308       case 6 /* scroll_state */:
27309         field.get(&scroll_state_);
27310         break;
27311       case 7 /* has_main_animation */:
27312         field.get(&has_main_animation_);
27313         break;
27314       case 8 /* has_compositor_animation */:
27315         field.get(&has_compositor_animation_);
27316         break;
27317       case 9 /* has_smooth_input_main */:
27318         field.get(&has_smooth_input_main_);
27319         break;
27320       case 10 /* has_missing_content */:
27321         field.get(&has_missing_content_);
27322         break;
27323       case 11 /* layer_tree_host_id */:
27324         field.get(&layer_tree_host_id_);
27325         break;
27326       default:
27327         field.SerializeAndAppendTo(&unknown_fields_);
27328         break;
27329     }
27330   }
27331   return !packed_error && !dec.bytes_left();
27332 }
27333 
SerializeAsString() const27334 std::string ChromeFrameReporter::SerializeAsString() const {
27335   ::protozero::HeapBuffered<::protozero::Message> msg;
27336   Serialize(msg.get());
27337   return msg.SerializeAsString();
27338 }
27339 
SerializeAsArray() const27340 std::vector<uint8_t> ChromeFrameReporter::SerializeAsArray() const {
27341   ::protozero::HeapBuffered<::protozero::Message> msg;
27342   Serialize(msg.get());
27343   return msg.SerializeAsArray();
27344 }
27345 
Serialize(::protozero::Message * msg) const27346 void ChromeFrameReporter::Serialize(::protozero::Message* msg) const {
27347   // Field 1: state
27348   if (_has_field_[1]) {
27349     msg->AppendVarInt(1, state_);
27350   }
27351 
27352   // Field 2: reason
27353   if (_has_field_[2]) {
27354     msg->AppendVarInt(2, reason_);
27355   }
27356 
27357   // Field 3: frame_source
27358   if (_has_field_[3]) {
27359     msg->AppendVarInt(3, frame_source_);
27360   }
27361 
27362   // Field 4: frame_sequence
27363   if (_has_field_[4]) {
27364     msg->AppendVarInt(4, frame_sequence_);
27365   }
27366 
27367   // Field 5: affects_smoothness
27368   if (_has_field_[5]) {
27369     msg->AppendTinyVarInt(5, affects_smoothness_);
27370   }
27371 
27372   // Field 6: scroll_state
27373   if (_has_field_[6]) {
27374     msg->AppendVarInt(6, scroll_state_);
27375   }
27376 
27377   // Field 7: has_main_animation
27378   if (_has_field_[7]) {
27379     msg->AppendTinyVarInt(7, has_main_animation_);
27380   }
27381 
27382   // Field 8: has_compositor_animation
27383   if (_has_field_[8]) {
27384     msg->AppendTinyVarInt(8, has_compositor_animation_);
27385   }
27386 
27387   // Field 9: has_smooth_input_main
27388   if (_has_field_[9]) {
27389     msg->AppendTinyVarInt(9, has_smooth_input_main_);
27390   }
27391 
27392   // Field 10: has_missing_content
27393   if (_has_field_[10]) {
27394     msg->AppendTinyVarInt(10, has_missing_content_);
27395   }
27396 
27397   // Field 11: layer_tree_host_id
27398   if (_has_field_[11]) {
27399     msg->AppendVarInt(11, layer_tree_host_id_);
27400   }
27401 
27402   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
27403 }
27404 
27405 }  // namespace perfetto
27406 }  // namespace protos
27407 }  // namespace gen
27408 #if defined(__GNUC__) || defined(__clang__)
27409 #pragma GCC diagnostic pop
27410 #endif
27411 // gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_histogram_sample.gen.cc
27412 // gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/chrome_histogram_sample.gen.h
27413 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
27414 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_HISTOGRAM_SAMPLE_PROTO_CPP_H_
27415 #define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_HISTOGRAM_SAMPLE_PROTO_CPP_H_
27416 
27417 #include <stdint.h>
27418 #include <bitset>
27419 #include <vector>
27420 #include <string>
27421 #include <type_traits>
27422 
27423 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
27424 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
27425 // gen_amalgamated expanded: #include "perfetto/base/export.h"
27426 
27427 namespace perfetto {
27428 namespace protos {
27429 namespace gen {
27430 class ChromeHistogramSample;
27431 class HistogramName;
27432 }  // namespace perfetto
27433 }  // namespace protos
27434 }  // namespace gen
27435 
27436 namespace protozero {
27437 class Message;
27438 }  // namespace protozero
27439 
27440 namespace perfetto {
27441 namespace protos {
27442 namespace gen {
27443 
27444 class PERFETTO_EXPORT ChromeHistogramSample : public ::protozero::CppMessageObj {
27445  public:
27446   enum FieldNumbers {
27447     kNameHashFieldNumber = 1,
27448     kNameFieldNumber = 2,
27449     kSampleFieldNumber = 3,
27450     kNameIidFieldNumber = 4,
27451   };
27452 
27453   ChromeHistogramSample();
27454   ~ChromeHistogramSample() override;
27455   ChromeHistogramSample(ChromeHistogramSample&&) noexcept;
27456   ChromeHistogramSample& operator=(ChromeHistogramSample&&);
27457   ChromeHistogramSample(const ChromeHistogramSample&);
27458   ChromeHistogramSample& operator=(const ChromeHistogramSample&);
27459   bool operator==(const ChromeHistogramSample&) const;
operator !=(const ChromeHistogramSample & other) const27460   bool operator!=(const ChromeHistogramSample& other) const { return !(*this == other); }
27461 
27462   bool ParseFromArray(const void*, size_t) override;
27463   std::string SerializeAsString() const override;
27464   std::vector<uint8_t> SerializeAsArray() const override;
27465   void Serialize(::protozero::Message*) const;
27466 
has_name_hash() const27467   bool has_name_hash() const { return _has_field_[1]; }
name_hash() const27468   uint64_t name_hash() const { return name_hash_; }
set_name_hash(uint64_t value)27469   void set_name_hash(uint64_t value) { name_hash_ = value; _has_field_.set(1); }
27470 
has_name() const27471   bool has_name() const { return _has_field_[2]; }
name() const27472   const std::string& name() const { return name_; }
set_name(const std::string & value)27473   void set_name(const std::string& value) { name_ = value; _has_field_.set(2); }
27474 
has_sample() const27475   bool has_sample() const { return _has_field_[3]; }
sample() const27476   int64_t sample() const { return sample_; }
set_sample(int64_t value)27477   void set_sample(int64_t value) { sample_ = value; _has_field_.set(3); }
27478 
has_name_iid() const27479   bool has_name_iid() const { return _has_field_[4]; }
name_iid() const27480   uint64_t name_iid() const { return name_iid_; }
set_name_iid(uint64_t value)27481   void set_name_iid(uint64_t value) { name_iid_ = value; _has_field_.set(4); }
27482 
27483  private:
27484   uint64_t name_hash_{};
27485   std::string name_{};
27486   int64_t sample_{};
27487   uint64_t name_iid_{};
27488 
27489   // Allows to preserve unknown protobuf fields for compatibility
27490   // with future versions of .proto files.
27491   std::string unknown_fields_;
27492 
27493   std::bitset<5> _has_field_{};
27494 };
27495 
27496 
27497 class PERFETTO_EXPORT HistogramName : public ::protozero::CppMessageObj {
27498  public:
27499   enum FieldNumbers {
27500     kIidFieldNumber = 1,
27501     kNameFieldNumber = 2,
27502   };
27503 
27504   HistogramName();
27505   ~HistogramName() override;
27506   HistogramName(HistogramName&&) noexcept;
27507   HistogramName& operator=(HistogramName&&);
27508   HistogramName(const HistogramName&);
27509   HistogramName& operator=(const HistogramName&);
27510   bool operator==(const HistogramName&) const;
operator !=(const HistogramName & other) const27511   bool operator!=(const HistogramName& other) const { return !(*this == other); }
27512 
27513   bool ParseFromArray(const void*, size_t) override;
27514   std::string SerializeAsString() const override;
27515   std::vector<uint8_t> SerializeAsArray() const override;
27516   void Serialize(::protozero::Message*) const;
27517 
has_iid() const27518   bool has_iid() const { return _has_field_[1]; }
iid() const27519   uint64_t iid() const { return iid_; }
set_iid(uint64_t value)27520   void set_iid(uint64_t value) { iid_ = value; _has_field_.set(1); }
27521 
has_name() const27522   bool has_name() const { return _has_field_[2]; }
name() const27523   const std::string& name() const { return name_; }
set_name(const std::string & value)27524   void set_name(const std::string& value) { name_ = value; _has_field_.set(2); }
27525 
27526  private:
27527   uint64_t iid_{};
27528   std::string name_{};
27529 
27530   // Allows to preserve unknown protobuf fields for compatibility
27531   // with future versions of .proto files.
27532   std::string unknown_fields_;
27533 
27534   std::bitset<3> _has_field_{};
27535 };
27536 
27537 }  // namespace perfetto
27538 }  // namespace protos
27539 }  // namespace gen
27540 
27541 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_HISTOGRAM_SAMPLE_PROTO_CPP_H_
27542 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
27543 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
27544 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
27545 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
27546 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
27547 #if defined(__GNUC__) || defined(__clang__)
27548 #pragma GCC diagnostic push
27549 #pragma GCC diagnostic ignored "-Wfloat-equal"
27550 #endif
27551 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_histogram_sample.gen.h"
27552 
27553 namespace perfetto {
27554 namespace protos {
27555 namespace gen {
27556 
27557 ChromeHistogramSample::ChromeHistogramSample() = default;
27558 ChromeHistogramSample::~ChromeHistogramSample() = default;
27559 ChromeHistogramSample::ChromeHistogramSample(const ChromeHistogramSample&) = default;
27560 ChromeHistogramSample& ChromeHistogramSample::operator=(const ChromeHistogramSample&) = default;
27561 ChromeHistogramSample::ChromeHistogramSample(ChromeHistogramSample&&) noexcept = default;
27562 ChromeHistogramSample& ChromeHistogramSample::operator=(ChromeHistogramSample&&) = default;
27563 
operator ==(const ChromeHistogramSample & other) const27564 bool ChromeHistogramSample::operator==(const ChromeHistogramSample& other) const {
27565   return unknown_fields_ == other.unknown_fields_
27566    && name_hash_ == other.name_hash_
27567    && name_ == other.name_
27568    && sample_ == other.sample_
27569    && name_iid_ == other.name_iid_;
27570 }
27571 
ParseFromArray(const void * raw,size_t size)27572 bool ChromeHistogramSample::ParseFromArray(const void* raw, size_t size) {
27573   unknown_fields_.clear();
27574   bool packed_error = false;
27575 
27576   ::protozero::ProtoDecoder dec(raw, size);
27577   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
27578     if (field.id() < _has_field_.size()) {
27579       _has_field_.set(field.id());
27580     }
27581     switch (field.id()) {
27582       case 1 /* name_hash */:
27583         field.get(&name_hash_);
27584         break;
27585       case 2 /* name */:
27586         field.get(&name_);
27587         break;
27588       case 3 /* sample */:
27589         field.get(&sample_);
27590         break;
27591       case 4 /* name_iid */:
27592         field.get(&name_iid_);
27593         break;
27594       default:
27595         field.SerializeAndAppendTo(&unknown_fields_);
27596         break;
27597     }
27598   }
27599   return !packed_error && !dec.bytes_left();
27600 }
27601 
SerializeAsString() const27602 std::string ChromeHistogramSample::SerializeAsString() const {
27603   ::protozero::HeapBuffered<::protozero::Message> msg;
27604   Serialize(msg.get());
27605   return msg.SerializeAsString();
27606 }
27607 
SerializeAsArray() const27608 std::vector<uint8_t> ChromeHistogramSample::SerializeAsArray() const {
27609   ::protozero::HeapBuffered<::protozero::Message> msg;
27610   Serialize(msg.get());
27611   return msg.SerializeAsArray();
27612 }
27613 
Serialize(::protozero::Message * msg) const27614 void ChromeHistogramSample::Serialize(::protozero::Message* msg) const {
27615   // Field 1: name_hash
27616   if (_has_field_[1]) {
27617     msg->AppendVarInt(1, name_hash_);
27618   }
27619 
27620   // Field 2: name
27621   if (_has_field_[2]) {
27622     msg->AppendString(2, name_);
27623   }
27624 
27625   // Field 3: sample
27626   if (_has_field_[3]) {
27627     msg->AppendVarInt(3, sample_);
27628   }
27629 
27630   // Field 4: name_iid
27631   if (_has_field_[4]) {
27632     msg->AppendVarInt(4, name_iid_);
27633   }
27634 
27635   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
27636 }
27637 
27638 
27639 HistogramName::HistogramName() = default;
27640 HistogramName::~HistogramName() = default;
27641 HistogramName::HistogramName(const HistogramName&) = default;
27642 HistogramName& HistogramName::operator=(const HistogramName&) = default;
27643 HistogramName::HistogramName(HistogramName&&) noexcept = default;
27644 HistogramName& HistogramName::operator=(HistogramName&&) = default;
27645 
operator ==(const HistogramName & other) const27646 bool HistogramName::operator==(const HistogramName& other) const {
27647   return unknown_fields_ == other.unknown_fields_
27648    && iid_ == other.iid_
27649    && name_ == other.name_;
27650 }
27651 
ParseFromArray(const void * raw,size_t size)27652 bool HistogramName::ParseFromArray(const void* raw, size_t size) {
27653   unknown_fields_.clear();
27654   bool packed_error = false;
27655 
27656   ::protozero::ProtoDecoder dec(raw, size);
27657   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
27658     if (field.id() < _has_field_.size()) {
27659       _has_field_.set(field.id());
27660     }
27661     switch (field.id()) {
27662       case 1 /* iid */:
27663         field.get(&iid_);
27664         break;
27665       case 2 /* name */:
27666         field.get(&name_);
27667         break;
27668       default:
27669         field.SerializeAndAppendTo(&unknown_fields_);
27670         break;
27671     }
27672   }
27673   return !packed_error && !dec.bytes_left();
27674 }
27675 
SerializeAsString() const27676 std::string HistogramName::SerializeAsString() const {
27677   ::protozero::HeapBuffered<::protozero::Message> msg;
27678   Serialize(msg.get());
27679   return msg.SerializeAsString();
27680 }
27681 
SerializeAsArray() const27682 std::vector<uint8_t> HistogramName::SerializeAsArray() const {
27683   ::protozero::HeapBuffered<::protozero::Message> msg;
27684   Serialize(msg.get());
27685   return msg.SerializeAsArray();
27686 }
27687 
Serialize(::protozero::Message * msg) const27688 void HistogramName::Serialize(::protozero::Message* msg) const {
27689   // Field 1: iid
27690   if (_has_field_[1]) {
27691     msg->AppendVarInt(1, iid_);
27692   }
27693 
27694   // Field 2: name
27695   if (_has_field_[2]) {
27696     msg->AppendString(2, name_);
27697   }
27698 
27699   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
27700 }
27701 
27702 }  // namespace perfetto
27703 }  // namespace protos
27704 }  // namespace gen
27705 #if defined(__GNUC__) || defined(__clang__)
27706 #pragma GCC diagnostic pop
27707 #endif
27708 // gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_keyed_service.gen.cc
27709 // gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/chrome_keyed_service.gen.h
27710 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
27711 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_KEYED_SERVICE_PROTO_CPP_H_
27712 #define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_KEYED_SERVICE_PROTO_CPP_H_
27713 
27714 #include <stdint.h>
27715 #include <bitset>
27716 #include <vector>
27717 #include <string>
27718 #include <type_traits>
27719 
27720 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
27721 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
27722 // gen_amalgamated expanded: #include "perfetto/base/export.h"
27723 
27724 namespace perfetto {
27725 namespace protos {
27726 namespace gen {
27727 class ChromeKeyedService;
27728 }  // namespace perfetto
27729 }  // namespace protos
27730 }  // namespace gen
27731 
27732 namespace protozero {
27733 class Message;
27734 }  // namespace protozero
27735 
27736 namespace perfetto {
27737 namespace protos {
27738 namespace gen {
27739 
27740 class PERFETTO_EXPORT ChromeKeyedService : public ::protozero::CppMessageObj {
27741  public:
27742   enum FieldNumbers {
27743     kNameFieldNumber = 1,
27744   };
27745 
27746   ChromeKeyedService();
27747   ~ChromeKeyedService() override;
27748   ChromeKeyedService(ChromeKeyedService&&) noexcept;
27749   ChromeKeyedService& operator=(ChromeKeyedService&&);
27750   ChromeKeyedService(const ChromeKeyedService&);
27751   ChromeKeyedService& operator=(const ChromeKeyedService&);
27752   bool operator==(const ChromeKeyedService&) const;
operator !=(const ChromeKeyedService & other) const27753   bool operator!=(const ChromeKeyedService& other) const { return !(*this == other); }
27754 
27755   bool ParseFromArray(const void*, size_t) override;
27756   std::string SerializeAsString() const override;
27757   std::vector<uint8_t> SerializeAsArray() const override;
27758   void Serialize(::protozero::Message*) const;
27759 
has_name() const27760   bool has_name() const { return _has_field_[1]; }
name() const27761   const std::string& name() const { return name_; }
set_name(const std::string & value)27762   void set_name(const std::string& value) { name_ = value; _has_field_.set(1); }
27763 
27764  private:
27765   std::string name_{};
27766 
27767   // Allows to preserve unknown protobuf fields for compatibility
27768   // with future versions of .proto files.
27769   std::string unknown_fields_;
27770 
27771   std::bitset<2> _has_field_{};
27772 };
27773 
27774 }  // namespace perfetto
27775 }  // namespace protos
27776 }  // namespace gen
27777 
27778 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_KEYED_SERVICE_PROTO_CPP_H_
27779 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
27780 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
27781 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
27782 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
27783 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
27784 #if defined(__GNUC__) || defined(__clang__)
27785 #pragma GCC diagnostic push
27786 #pragma GCC diagnostic ignored "-Wfloat-equal"
27787 #endif
27788 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_keyed_service.gen.h"
27789 
27790 namespace perfetto {
27791 namespace protos {
27792 namespace gen {
27793 
27794 ChromeKeyedService::ChromeKeyedService() = default;
27795 ChromeKeyedService::~ChromeKeyedService() = default;
27796 ChromeKeyedService::ChromeKeyedService(const ChromeKeyedService&) = default;
27797 ChromeKeyedService& ChromeKeyedService::operator=(const ChromeKeyedService&) = default;
27798 ChromeKeyedService::ChromeKeyedService(ChromeKeyedService&&) noexcept = default;
27799 ChromeKeyedService& ChromeKeyedService::operator=(ChromeKeyedService&&) = default;
27800 
operator ==(const ChromeKeyedService & other) const27801 bool ChromeKeyedService::operator==(const ChromeKeyedService& other) const {
27802   return unknown_fields_ == other.unknown_fields_
27803    && name_ == other.name_;
27804 }
27805 
ParseFromArray(const void * raw,size_t size)27806 bool ChromeKeyedService::ParseFromArray(const void* raw, size_t size) {
27807   unknown_fields_.clear();
27808   bool packed_error = false;
27809 
27810   ::protozero::ProtoDecoder dec(raw, size);
27811   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
27812     if (field.id() < _has_field_.size()) {
27813       _has_field_.set(field.id());
27814     }
27815     switch (field.id()) {
27816       case 1 /* name */:
27817         field.get(&name_);
27818         break;
27819       default:
27820         field.SerializeAndAppendTo(&unknown_fields_);
27821         break;
27822     }
27823   }
27824   return !packed_error && !dec.bytes_left();
27825 }
27826 
SerializeAsString() const27827 std::string ChromeKeyedService::SerializeAsString() const {
27828   ::protozero::HeapBuffered<::protozero::Message> msg;
27829   Serialize(msg.get());
27830   return msg.SerializeAsString();
27831 }
27832 
SerializeAsArray() const27833 std::vector<uint8_t> ChromeKeyedService::SerializeAsArray() const {
27834   ::protozero::HeapBuffered<::protozero::Message> msg;
27835   Serialize(msg.get());
27836   return msg.SerializeAsArray();
27837 }
27838 
Serialize(::protozero::Message * msg) const27839 void ChromeKeyedService::Serialize(::protozero::Message* msg) const {
27840   // Field 1: name
27841   if (_has_field_[1]) {
27842     msg->AppendString(1, name_);
27843   }
27844 
27845   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
27846 }
27847 
27848 }  // namespace perfetto
27849 }  // namespace protos
27850 }  // namespace gen
27851 #if defined(__GNUC__) || defined(__clang__)
27852 #pragma GCC diagnostic pop
27853 #endif
27854 // gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_latency_info.gen.cc
27855 // gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/chrome_latency_info.gen.h
27856 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
27857 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_LATENCY_INFO_PROTO_CPP_H_
27858 #define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_LATENCY_INFO_PROTO_CPP_H_
27859 
27860 #include <stdint.h>
27861 #include <bitset>
27862 #include <vector>
27863 #include <string>
27864 #include <type_traits>
27865 
27866 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
27867 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
27868 // gen_amalgamated expanded: #include "perfetto/base/export.h"
27869 
27870 namespace perfetto {
27871 namespace protos {
27872 namespace gen {
27873 class ChromeLatencyInfo;
27874 class ChromeLatencyInfo_ComponentInfo;
27875 enum ChromeLatencyInfo_Step : int;
27876 enum ChromeLatencyInfo_LatencyComponentType : int;
27877 }  // namespace perfetto
27878 }  // namespace protos
27879 }  // namespace gen
27880 
27881 namespace protozero {
27882 class Message;
27883 }  // namespace protozero
27884 
27885 namespace perfetto {
27886 namespace protos {
27887 namespace gen {
27888 enum ChromeLatencyInfo_Step : int {
27889   ChromeLatencyInfo_Step_STEP_UNSPECIFIED = 0,
27890   ChromeLatencyInfo_Step_STEP_SEND_INPUT_EVENT_UI = 3,
27891   ChromeLatencyInfo_Step_STEP_HANDLE_INPUT_EVENT_IMPL = 5,
27892   ChromeLatencyInfo_Step_STEP_DID_HANDLE_INPUT_AND_OVERSCROLL = 8,
27893   ChromeLatencyInfo_Step_STEP_HANDLE_INPUT_EVENT_MAIN = 4,
27894   ChromeLatencyInfo_Step_STEP_MAIN_THREAD_SCROLL_UPDATE = 2,
27895   ChromeLatencyInfo_Step_STEP_HANDLE_INPUT_EVENT_MAIN_COMMIT = 1,
27896   ChromeLatencyInfo_Step_STEP_HANDLED_INPUT_EVENT_MAIN_OR_IMPL = 9,
27897   ChromeLatencyInfo_Step_STEP_HANDLED_INPUT_EVENT_IMPL = 10,
27898   ChromeLatencyInfo_Step_STEP_SWAP_BUFFERS = 6,
27899   ChromeLatencyInfo_Step_STEP_DRAW_AND_SWAP = 7,
27900   ChromeLatencyInfo_Step_STEP_FINISHED_SWAP_BUFFERS = 11,
27901 };
27902 enum ChromeLatencyInfo_LatencyComponentType : int {
27903   ChromeLatencyInfo_LatencyComponentType_COMPONENT_UNSPECIFIED = 0,
27904   ChromeLatencyInfo_LatencyComponentType_COMPONENT_INPUT_EVENT_LATENCY_BEGIN_RWH = 1,
27905   ChromeLatencyInfo_LatencyComponentType_COMPONENT_INPUT_EVENT_LATENCY_SCROLL_UPDATE_ORIGINAL = 2,
27906   ChromeLatencyInfo_LatencyComponentType_COMPONENT_INPUT_EVENT_LATENCY_FIRST_SCROLL_UPDATE_ORIGINAL = 3,
27907   ChromeLatencyInfo_LatencyComponentType_COMPONENT_INPUT_EVENT_LATENCY_ORIGINAL = 4,
27908   ChromeLatencyInfo_LatencyComponentType_COMPONENT_INPUT_EVENT_LATENCY_UI = 5,
27909   ChromeLatencyInfo_LatencyComponentType_COMPONENT_INPUT_EVENT_LATENCY_RENDERER_MAIN = 6,
27910   ChromeLatencyInfo_LatencyComponentType_COMPONENT_INPUT_EVENT_LATENCY_RENDERING_SCHEDULED_MAIN = 7,
27911   ChromeLatencyInfo_LatencyComponentType_COMPONENT_INPUT_EVENT_LATENCY_RENDERING_SCHEDULED_IMPL = 8,
27912   ChromeLatencyInfo_LatencyComponentType_COMPONENT_INPUT_EVENT_LATENCY_SCROLL_UPDATE_LAST_EVENT = 9,
27913   ChromeLatencyInfo_LatencyComponentType_COMPONENT_INPUT_EVENT_LATENCY_ACK_RWH = 10,
27914   ChromeLatencyInfo_LatencyComponentType_COMPONENT_INPUT_EVENT_LATENCY_RENDERER_SWAP = 11,
27915   ChromeLatencyInfo_LatencyComponentType_COMPONENT_DISPLAY_COMPOSITOR_RECEIVED_FRAME = 12,
27916   ChromeLatencyInfo_LatencyComponentType_COMPONENT_INPUT_EVENT_GPU_SWAP_BUFFER = 13,
27917   ChromeLatencyInfo_LatencyComponentType_COMPONENT_INPUT_EVENT_LATENCY_FRAME_SWAP = 14,
27918 };
27919 
27920 class PERFETTO_EXPORT ChromeLatencyInfo : public ::protozero::CppMessageObj {
27921  public:
27922   using ComponentInfo = ChromeLatencyInfo_ComponentInfo;
27923   using Step = ChromeLatencyInfo_Step;
27924   static constexpr auto STEP_UNSPECIFIED = ChromeLatencyInfo_Step_STEP_UNSPECIFIED;
27925   static constexpr auto STEP_SEND_INPUT_EVENT_UI = ChromeLatencyInfo_Step_STEP_SEND_INPUT_EVENT_UI;
27926   static constexpr auto STEP_HANDLE_INPUT_EVENT_IMPL = ChromeLatencyInfo_Step_STEP_HANDLE_INPUT_EVENT_IMPL;
27927   static constexpr auto STEP_DID_HANDLE_INPUT_AND_OVERSCROLL = ChromeLatencyInfo_Step_STEP_DID_HANDLE_INPUT_AND_OVERSCROLL;
27928   static constexpr auto STEP_HANDLE_INPUT_EVENT_MAIN = ChromeLatencyInfo_Step_STEP_HANDLE_INPUT_EVENT_MAIN;
27929   static constexpr auto STEP_MAIN_THREAD_SCROLL_UPDATE = ChromeLatencyInfo_Step_STEP_MAIN_THREAD_SCROLL_UPDATE;
27930   static constexpr auto STEP_HANDLE_INPUT_EVENT_MAIN_COMMIT = ChromeLatencyInfo_Step_STEP_HANDLE_INPUT_EVENT_MAIN_COMMIT;
27931   static constexpr auto STEP_HANDLED_INPUT_EVENT_MAIN_OR_IMPL = ChromeLatencyInfo_Step_STEP_HANDLED_INPUT_EVENT_MAIN_OR_IMPL;
27932   static constexpr auto STEP_HANDLED_INPUT_EVENT_IMPL = ChromeLatencyInfo_Step_STEP_HANDLED_INPUT_EVENT_IMPL;
27933   static constexpr auto STEP_SWAP_BUFFERS = ChromeLatencyInfo_Step_STEP_SWAP_BUFFERS;
27934   static constexpr auto STEP_DRAW_AND_SWAP = ChromeLatencyInfo_Step_STEP_DRAW_AND_SWAP;
27935   static constexpr auto STEP_FINISHED_SWAP_BUFFERS = ChromeLatencyInfo_Step_STEP_FINISHED_SWAP_BUFFERS;
27936   static constexpr auto Step_MIN = ChromeLatencyInfo_Step_STEP_UNSPECIFIED;
27937   static constexpr auto Step_MAX = ChromeLatencyInfo_Step_STEP_FINISHED_SWAP_BUFFERS;
27938   using LatencyComponentType = ChromeLatencyInfo_LatencyComponentType;
27939   static constexpr auto COMPONENT_UNSPECIFIED = ChromeLatencyInfo_LatencyComponentType_COMPONENT_UNSPECIFIED;
27940   static constexpr auto COMPONENT_INPUT_EVENT_LATENCY_BEGIN_RWH = ChromeLatencyInfo_LatencyComponentType_COMPONENT_INPUT_EVENT_LATENCY_BEGIN_RWH;
27941   static constexpr auto COMPONENT_INPUT_EVENT_LATENCY_SCROLL_UPDATE_ORIGINAL = ChromeLatencyInfo_LatencyComponentType_COMPONENT_INPUT_EVENT_LATENCY_SCROLL_UPDATE_ORIGINAL;
27942   static constexpr auto COMPONENT_INPUT_EVENT_LATENCY_FIRST_SCROLL_UPDATE_ORIGINAL = ChromeLatencyInfo_LatencyComponentType_COMPONENT_INPUT_EVENT_LATENCY_FIRST_SCROLL_UPDATE_ORIGINAL;
27943   static constexpr auto COMPONENT_INPUT_EVENT_LATENCY_ORIGINAL = ChromeLatencyInfo_LatencyComponentType_COMPONENT_INPUT_EVENT_LATENCY_ORIGINAL;
27944   static constexpr auto COMPONENT_INPUT_EVENT_LATENCY_UI = ChromeLatencyInfo_LatencyComponentType_COMPONENT_INPUT_EVENT_LATENCY_UI;
27945   static constexpr auto COMPONENT_INPUT_EVENT_LATENCY_RENDERER_MAIN = ChromeLatencyInfo_LatencyComponentType_COMPONENT_INPUT_EVENT_LATENCY_RENDERER_MAIN;
27946   static constexpr auto COMPONENT_INPUT_EVENT_LATENCY_RENDERING_SCHEDULED_MAIN = ChromeLatencyInfo_LatencyComponentType_COMPONENT_INPUT_EVENT_LATENCY_RENDERING_SCHEDULED_MAIN;
27947   static constexpr auto COMPONENT_INPUT_EVENT_LATENCY_RENDERING_SCHEDULED_IMPL = ChromeLatencyInfo_LatencyComponentType_COMPONENT_INPUT_EVENT_LATENCY_RENDERING_SCHEDULED_IMPL;
27948   static constexpr auto COMPONENT_INPUT_EVENT_LATENCY_SCROLL_UPDATE_LAST_EVENT = ChromeLatencyInfo_LatencyComponentType_COMPONENT_INPUT_EVENT_LATENCY_SCROLL_UPDATE_LAST_EVENT;
27949   static constexpr auto COMPONENT_INPUT_EVENT_LATENCY_ACK_RWH = ChromeLatencyInfo_LatencyComponentType_COMPONENT_INPUT_EVENT_LATENCY_ACK_RWH;
27950   static constexpr auto COMPONENT_INPUT_EVENT_LATENCY_RENDERER_SWAP = ChromeLatencyInfo_LatencyComponentType_COMPONENT_INPUT_EVENT_LATENCY_RENDERER_SWAP;
27951   static constexpr auto COMPONENT_DISPLAY_COMPOSITOR_RECEIVED_FRAME = ChromeLatencyInfo_LatencyComponentType_COMPONENT_DISPLAY_COMPOSITOR_RECEIVED_FRAME;
27952   static constexpr auto COMPONENT_INPUT_EVENT_GPU_SWAP_BUFFER = ChromeLatencyInfo_LatencyComponentType_COMPONENT_INPUT_EVENT_GPU_SWAP_BUFFER;
27953   static constexpr auto COMPONENT_INPUT_EVENT_LATENCY_FRAME_SWAP = ChromeLatencyInfo_LatencyComponentType_COMPONENT_INPUT_EVENT_LATENCY_FRAME_SWAP;
27954   static constexpr auto LatencyComponentType_MIN = ChromeLatencyInfo_LatencyComponentType_COMPONENT_UNSPECIFIED;
27955   static constexpr auto LatencyComponentType_MAX = ChromeLatencyInfo_LatencyComponentType_COMPONENT_INPUT_EVENT_LATENCY_FRAME_SWAP;
27956   enum FieldNumbers {
27957     kTraceIdFieldNumber = 1,
27958     kStepFieldNumber = 2,
27959     kFrameTreeNodeIdFieldNumber = 3,
27960     kComponentInfoFieldNumber = 4,
27961     kIsCoalescedFieldNumber = 5,
27962     kGestureScrollIdFieldNumber = 6,
27963     kTouchIdFieldNumber = 7,
27964   };
27965 
27966   ChromeLatencyInfo();
27967   ~ChromeLatencyInfo() override;
27968   ChromeLatencyInfo(ChromeLatencyInfo&&) noexcept;
27969   ChromeLatencyInfo& operator=(ChromeLatencyInfo&&);
27970   ChromeLatencyInfo(const ChromeLatencyInfo&);
27971   ChromeLatencyInfo& operator=(const ChromeLatencyInfo&);
27972   bool operator==(const ChromeLatencyInfo&) const;
operator !=(const ChromeLatencyInfo & other) const27973   bool operator!=(const ChromeLatencyInfo& other) const { return !(*this == other); }
27974 
27975   bool ParseFromArray(const void*, size_t) override;
27976   std::string SerializeAsString() const override;
27977   std::vector<uint8_t> SerializeAsArray() const override;
27978   void Serialize(::protozero::Message*) const;
27979 
has_trace_id() const27980   bool has_trace_id() const { return _has_field_[1]; }
trace_id() const27981   int64_t trace_id() const { return trace_id_; }
set_trace_id(int64_t value)27982   void set_trace_id(int64_t value) { trace_id_ = value; _has_field_.set(1); }
27983 
has_step() const27984   bool has_step() const { return _has_field_[2]; }
step() const27985   ChromeLatencyInfo_Step step() const { return step_; }
set_step(ChromeLatencyInfo_Step value)27986   void set_step(ChromeLatencyInfo_Step value) { step_ = value; _has_field_.set(2); }
27987 
has_frame_tree_node_id() const27988   bool has_frame_tree_node_id() const { return _has_field_[3]; }
frame_tree_node_id() const27989   int32_t frame_tree_node_id() const { return frame_tree_node_id_; }
set_frame_tree_node_id(int32_t value)27990   void set_frame_tree_node_id(int32_t value) { frame_tree_node_id_ = value; _has_field_.set(3); }
27991 
component_info() const27992   const std::vector<ChromeLatencyInfo_ComponentInfo>& component_info() const { return component_info_; }
mutable_component_info()27993   std::vector<ChromeLatencyInfo_ComponentInfo>* mutable_component_info() { return &component_info_; }
27994   int component_info_size() const;
27995   void clear_component_info();
27996   ChromeLatencyInfo_ComponentInfo* add_component_info();
27997 
has_is_coalesced() const27998   bool has_is_coalesced() const { return _has_field_[5]; }
is_coalesced() const27999   bool is_coalesced() const { return is_coalesced_; }
set_is_coalesced(bool value)28000   void set_is_coalesced(bool value) { is_coalesced_ = value; _has_field_.set(5); }
28001 
has_gesture_scroll_id() const28002   bool has_gesture_scroll_id() const { return _has_field_[6]; }
gesture_scroll_id() const28003   int64_t gesture_scroll_id() const { return gesture_scroll_id_; }
set_gesture_scroll_id(int64_t value)28004   void set_gesture_scroll_id(int64_t value) { gesture_scroll_id_ = value; _has_field_.set(6); }
28005 
has_touch_id() const28006   bool has_touch_id() const { return _has_field_[7]; }
touch_id() const28007   int64_t touch_id() const { return touch_id_; }
set_touch_id(int64_t value)28008   void set_touch_id(int64_t value) { touch_id_ = value; _has_field_.set(7); }
28009 
28010  private:
28011   int64_t trace_id_{};
28012   ChromeLatencyInfo_Step step_{};
28013   int32_t frame_tree_node_id_{};
28014   std::vector<ChromeLatencyInfo_ComponentInfo> component_info_;
28015   bool is_coalesced_{};
28016   int64_t gesture_scroll_id_{};
28017   int64_t touch_id_{};
28018 
28019   // Allows to preserve unknown protobuf fields for compatibility
28020   // with future versions of .proto files.
28021   std::string unknown_fields_;
28022 
28023   std::bitset<8> _has_field_{};
28024 };
28025 
28026 
28027 class PERFETTO_EXPORT ChromeLatencyInfo_ComponentInfo : public ::protozero::CppMessageObj {
28028  public:
28029   enum FieldNumbers {
28030     kComponentTypeFieldNumber = 1,
28031     kTimeUsFieldNumber = 2,
28032   };
28033 
28034   ChromeLatencyInfo_ComponentInfo();
28035   ~ChromeLatencyInfo_ComponentInfo() override;
28036   ChromeLatencyInfo_ComponentInfo(ChromeLatencyInfo_ComponentInfo&&) noexcept;
28037   ChromeLatencyInfo_ComponentInfo& operator=(ChromeLatencyInfo_ComponentInfo&&);
28038   ChromeLatencyInfo_ComponentInfo(const ChromeLatencyInfo_ComponentInfo&);
28039   ChromeLatencyInfo_ComponentInfo& operator=(const ChromeLatencyInfo_ComponentInfo&);
28040   bool operator==(const ChromeLatencyInfo_ComponentInfo&) const;
operator !=(const ChromeLatencyInfo_ComponentInfo & other) const28041   bool operator!=(const ChromeLatencyInfo_ComponentInfo& other) const { return !(*this == other); }
28042 
28043   bool ParseFromArray(const void*, size_t) override;
28044   std::string SerializeAsString() const override;
28045   std::vector<uint8_t> SerializeAsArray() const override;
28046   void Serialize(::protozero::Message*) const;
28047 
has_component_type() const28048   bool has_component_type() const { return _has_field_[1]; }
component_type() const28049   ChromeLatencyInfo_LatencyComponentType component_type() const { return component_type_; }
set_component_type(ChromeLatencyInfo_LatencyComponentType value)28050   void set_component_type(ChromeLatencyInfo_LatencyComponentType value) { component_type_ = value; _has_field_.set(1); }
28051 
has_time_us() const28052   bool has_time_us() const { return _has_field_[2]; }
time_us() const28053   uint64_t time_us() const { return time_us_; }
set_time_us(uint64_t value)28054   void set_time_us(uint64_t value) { time_us_ = value; _has_field_.set(2); }
28055 
28056  private:
28057   ChromeLatencyInfo_LatencyComponentType component_type_{};
28058   uint64_t time_us_{};
28059 
28060   // Allows to preserve unknown protobuf fields for compatibility
28061   // with future versions of .proto files.
28062   std::string unknown_fields_;
28063 
28064   std::bitset<3> _has_field_{};
28065 };
28066 
28067 }  // namespace perfetto
28068 }  // namespace protos
28069 }  // namespace gen
28070 
28071 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_LATENCY_INFO_PROTO_CPP_H_
28072 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
28073 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
28074 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
28075 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
28076 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
28077 #if defined(__GNUC__) || defined(__clang__)
28078 #pragma GCC diagnostic push
28079 #pragma GCC diagnostic ignored "-Wfloat-equal"
28080 #endif
28081 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_latency_info.gen.h"
28082 
28083 namespace perfetto {
28084 namespace protos {
28085 namespace gen {
28086 
28087 ChromeLatencyInfo::ChromeLatencyInfo() = default;
28088 ChromeLatencyInfo::~ChromeLatencyInfo() = default;
28089 ChromeLatencyInfo::ChromeLatencyInfo(const ChromeLatencyInfo&) = default;
28090 ChromeLatencyInfo& ChromeLatencyInfo::operator=(const ChromeLatencyInfo&) = default;
28091 ChromeLatencyInfo::ChromeLatencyInfo(ChromeLatencyInfo&&) noexcept = default;
28092 ChromeLatencyInfo& ChromeLatencyInfo::operator=(ChromeLatencyInfo&&) = default;
28093 
operator ==(const ChromeLatencyInfo & other) const28094 bool ChromeLatencyInfo::operator==(const ChromeLatencyInfo& other) const {
28095   return unknown_fields_ == other.unknown_fields_
28096    && trace_id_ == other.trace_id_
28097    && step_ == other.step_
28098    && frame_tree_node_id_ == other.frame_tree_node_id_
28099    && component_info_ == other.component_info_
28100    && is_coalesced_ == other.is_coalesced_
28101    && gesture_scroll_id_ == other.gesture_scroll_id_
28102    && touch_id_ == other.touch_id_;
28103 }
28104 
component_info_size() const28105 int ChromeLatencyInfo::component_info_size() const { return static_cast<int>(component_info_.size()); }
clear_component_info()28106 void ChromeLatencyInfo::clear_component_info() { component_info_.clear(); }
add_component_info()28107 ChromeLatencyInfo_ComponentInfo* ChromeLatencyInfo::add_component_info() { component_info_.emplace_back(); return &component_info_.back(); }
ParseFromArray(const void * raw,size_t size)28108 bool ChromeLatencyInfo::ParseFromArray(const void* raw, size_t size) {
28109   component_info_.clear();
28110   unknown_fields_.clear();
28111   bool packed_error = false;
28112 
28113   ::protozero::ProtoDecoder dec(raw, size);
28114   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
28115     if (field.id() < _has_field_.size()) {
28116       _has_field_.set(field.id());
28117     }
28118     switch (field.id()) {
28119       case 1 /* trace_id */:
28120         field.get(&trace_id_);
28121         break;
28122       case 2 /* step */:
28123         field.get(&step_);
28124         break;
28125       case 3 /* frame_tree_node_id */:
28126         field.get(&frame_tree_node_id_);
28127         break;
28128       case 4 /* component_info */:
28129         component_info_.emplace_back();
28130         component_info_.back().ParseFromArray(field.data(), field.size());
28131         break;
28132       case 5 /* is_coalesced */:
28133         field.get(&is_coalesced_);
28134         break;
28135       case 6 /* gesture_scroll_id */:
28136         field.get(&gesture_scroll_id_);
28137         break;
28138       case 7 /* touch_id */:
28139         field.get(&touch_id_);
28140         break;
28141       default:
28142         field.SerializeAndAppendTo(&unknown_fields_);
28143         break;
28144     }
28145   }
28146   return !packed_error && !dec.bytes_left();
28147 }
28148 
SerializeAsString() const28149 std::string ChromeLatencyInfo::SerializeAsString() const {
28150   ::protozero::HeapBuffered<::protozero::Message> msg;
28151   Serialize(msg.get());
28152   return msg.SerializeAsString();
28153 }
28154 
SerializeAsArray() const28155 std::vector<uint8_t> ChromeLatencyInfo::SerializeAsArray() const {
28156   ::protozero::HeapBuffered<::protozero::Message> msg;
28157   Serialize(msg.get());
28158   return msg.SerializeAsArray();
28159 }
28160 
Serialize(::protozero::Message * msg) const28161 void ChromeLatencyInfo::Serialize(::protozero::Message* msg) const {
28162   // Field 1: trace_id
28163   if (_has_field_[1]) {
28164     msg->AppendVarInt(1, trace_id_);
28165   }
28166 
28167   // Field 2: step
28168   if (_has_field_[2]) {
28169     msg->AppendVarInt(2, step_);
28170   }
28171 
28172   // Field 3: frame_tree_node_id
28173   if (_has_field_[3]) {
28174     msg->AppendVarInt(3, frame_tree_node_id_);
28175   }
28176 
28177   // Field 4: component_info
28178   for (auto& it : component_info_) {
28179     it.Serialize(msg->BeginNestedMessage<::protozero::Message>(4));
28180   }
28181 
28182   // Field 5: is_coalesced
28183   if (_has_field_[5]) {
28184     msg->AppendTinyVarInt(5, is_coalesced_);
28185   }
28186 
28187   // Field 6: gesture_scroll_id
28188   if (_has_field_[6]) {
28189     msg->AppendVarInt(6, gesture_scroll_id_);
28190   }
28191 
28192   // Field 7: touch_id
28193   if (_has_field_[7]) {
28194     msg->AppendVarInt(7, touch_id_);
28195   }
28196 
28197   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
28198 }
28199 
28200 
28201 ChromeLatencyInfo_ComponentInfo::ChromeLatencyInfo_ComponentInfo() = default;
28202 ChromeLatencyInfo_ComponentInfo::~ChromeLatencyInfo_ComponentInfo() = default;
28203 ChromeLatencyInfo_ComponentInfo::ChromeLatencyInfo_ComponentInfo(const ChromeLatencyInfo_ComponentInfo&) = default;
28204 ChromeLatencyInfo_ComponentInfo& ChromeLatencyInfo_ComponentInfo::operator=(const ChromeLatencyInfo_ComponentInfo&) = default;
28205 ChromeLatencyInfo_ComponentInfo::ChromeLatencyInfo_ComponentInfo(ChromeLatencyInfo_ComponentInfo&&) noexcept = default;
28206 ChromeLatencyInfo_ComponentInfo& ChromeLatencyInfo_ComponentInfo::operator=(ChromeLatencyInfo_ComponentInfo&&) = default;
28207 
operator ==(const ChromeLatencyInfo_ComponentInfo & other) const28208 bool ChromeLatencyInfo_ComponentInfo::operator==(const ChromeLatencyInfo_ComponentInfo& other) const {
28209   return unknown_fields_ == other.unknown_fields_
28210    && component_type_ == other.component_type_
28211    && time_us_ == other.time_us_;
28212 }
28213 
ParseFromArray(const void * raw,size_t size)28214 bool ChromeLatencyInfo_ComponentInfo::ParseFromArray(const void* raw, size_t size) {
28215   unknown_fields_.clear();
28216   bool packed_error = false;
28217 
28218   ::protozero::ProtoDecoder dec(raw, size);
28219   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
28220     if (field.id() < _has_field_.size()) {
28221       _has_field_.set(field.id());
28222     }
28223     switch (field.id()) {
28224       case 1 /* component_type */:
28225         field.get(&component_type_);
28226         break;
28227       case 2 /* time_us */:
28228         field.get(&time_us_);
28229         break;
28230       default:
28231         field.SerializeAndAppendTo(&unknown_fields_);
28232         break;
28233     }
28234   }
28235   return !packed_error && !dec.bytes_left();
28236 }
28237 
SerializeAsString() const28238 std::string ChromeLatencyInfo_ComponentInfo::SerializeAsString() const {
28239   ::protozero::HeapBuffered<::protozero::Message> msg;
28240   Serialize(msg.get());
28241   return msg.SerializeAsString();
28242 }
28243 
SerializeAsArray() const28244 std::vector<uint8_t> ChromeLatencyInfo_ComponentInfo::SerializeAsArray() const {
28245   ::protozero::HeapBuffered<::protozero::Message> msg;
28246   Serialize(msg.get());
28247   return msg.SerializeAsArray();
28248 }
28249 
Serialize(::protozero::Message * msg) const28250 void ChromeLatencyInfo_ComponentInfo::Serialize(::protozero::Message* msg) const {
28251   // Field 1: component_type
28252   if (_has_field_[1]) {
28253     msg->AppendVarInt(1, component_type_);
28254   }
28255 
28256   // Field 2: time_us
28257   if (_has_field_[2]) {
28258     msg->AppendVarInt(2, time_us_);
28259   }
28260 
28261   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
28262 }
28263 
28264 }  // namespace perfetto
28265 }  // namespace protos
28266 }  // namespace gen
28267 #if defined(__GNUC__) || defined(__clang__)
28268 #pragma GCC diagnostic pop
28269 #endif
28270 // gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_legacy_ipc.gen.cc
28271 // gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/chrome_legacy_ipc.gen.h
28272 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
28273 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_LEGACY_IPC_PROTO_CPP_H_
28274 #define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_LEGACY_IPC_PROTO_CPP_H_
28275 
28276 #include <stdint.h>
28277 #include <bitset>
28278 #include <vector>
28279 #include <string>
28280 #include <type_traits>
28281 
28282 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
28283 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
28284 // gen_amalgamated expanded: #include "perfetto/base/export.h"
28285 
28286 namespace perfetto {
28287 namespace protos {
28288 namespace gen {
28289 class ChromeLegacyIpc;
28290 enum ChromeLegacyIpc_MessageClass : int;
28291 }  // namespace perfetto
28292 }  // namespace protos
28293 }  // namespace gen
28294 
28295 namespace protozero {
28296 class Message;
28297 }  // namespace protozero
28298 
28299 namespace perfetto {
28300 namespace protos {
28301 namespace gen {
28302 enum ChromeLegacyIpc_MessageClass : int {
28303   ChromeLegacyIpc_MessageClass_CLASS_UNSPECIFIED = 0,
28304   ChromeLegacyIpc_MessageClass_CLASS_AUTOMATION = 1,
28305   ChromeLegacyIpc_MessageClass_CLASS_FRAME = 2,
28306   ChromeLegacyIpc_MessageClass_CLASS_PAGE = 3,
28307   ChromeLegacyIpc_MessageClass_CLASS_VIEW = 4,
28308   ChromeLegacyIpc_MessageClass_CLASS_WIDGET = 5,
28309   ChromeLegacyIpc_MessageClass_CLASS_INPUT = 6,
28310   ChromeLegacyIpc_MessageClass_CLASS_TEST = 7,
28311   ChromeLegacyIpc_MessageClass_CLASS_WORKER = 8,
28312   ChromeLegacyIpc_MessageClass_CLASS_NACL = 9,
28313   ChromeLegacyIpc_MessageClass_CLASS_GPU_CHANNEL = 10,
28314   ChromeLegacyIpc_MessageClass_CLASS_MEDIA = 11,
28315   ChromeLegacyIpc_MessageClass_CLASS_PPAPI = 12,
28316   ChromeLegacyIpc_MessageClass_CLASS_CHROME = 13,
28317   ChromeLegacyIpc_MessageClass_CLASS_DRAG = 14,
28318   ChromeLegacyIpc_MessageClass_CLASS_PRINT = 15,
28319   ChromeLegacyIpc_MessageClass_CLASS_EXTENSION = 16,
28320   ChromeLegacyIpc_MessageClass_CLASS_TEXT_INPUT_CLIENT = 17,
28321   ChromeLegacyIpc_MessageClass_CLASS_BLINK_TEST = 18,
28322   ChromeLegacyIpc_MessageClass_CLASS_ACCESSIBILITY = 19,
28323   ChromeLegacyIpc_MessageClass_CLASS_PRERENDER = 20,
28324   ChromeLegacyIpc_MessageClass_CLASS_CHROMOTING = 21,
28325   ChromeLegacyIpc_MessageClass_CLASS_BROWSER_PLUGIN = 22,
28326   ChromeLegacyIpc_MessageClass_CLASS_ANDROID_WEB_VIEW = 23,
28327   ChromeLegacyIpc_MessageClass_CLASS_NACL_HOST = 24,
28328   ChromeLegacyIpc_MessageClass_CLASS_ENCRYPTED_MEDIA = 25,
28329   ChromeLegacyIpc_MessageClass_CLASS_CAST = 26,
28330   ChromeLegacyIpc_MessageClass_CLASS_GIN_JAVA_BRIDGE = 27,
28331   ChromeLegacyIpc_MessageClass_CLASS_CHROME_UTILITY_PRINTING = 28,
28332   ChromeLegacyIpc_MessageClass_CLASS_OZONE_GPU = 29,
28333   ChromeLegacyIpc_MessageClass_CLASS_WEB_TEST = 30,
28334   ChromeLegacyIpc_MessageClass_CLASS_NETWORK_HINTS = 31,
28335   ChromeLegacyIpc_MessageClass_CLASS_EXTENSIONS_GUEST_VIEW = 32,
28336   ChromeLegacyIpc_MessageClass_CLASS_GUEST_VIEW = 33,
28337   ChromeLegacyIpc_MessageClass_CLASS_MEDIA_PLAYER_DELEGATE = 34,
28338   ChromeLegacyIpc_MessageClass_CLASS_EXTENSION_WORKER = 35,
28339   ChromeLegacyIpc_MessageClass_CLASS_SUBRESOURCE_FILTER = 36,
28340   ChromeLegacyIpc_MessageClass_CLASS_UNFREEZABLE_FRAME = 37,
28341 };
28342 
28343 class PERFETTO_EXPORT ChromeLegacyIpc : public ::protozero::CppMessageObj {
28344  public:
28345   using MessageClass = ChromeLegacyIpc_MessageClass;
28346   static constexpr auto CLASS_UNSPECIFIED = ChromeLegacyIpc_MessageClass_CLASS_UNSPECIFIED;
28347   static constexpr auto CLASS_AUTOMATION = ChromeLegacyIpc_MessageClass_CLASS_AUTOMATION;
28348   static constexpr auto CLASS_FRAME = ChromeLegacyIpc_MessageClass_CLASS_FRAME;
28349   static constexpr auto CLASS_PAGE = ChromeLegacyIpc_MessageClass_CLASS_PAGE;
28350   static constexpr auto CLASS_VIEW = ChromeLegacyIpc_MessageClass_CLASS_VIEW;
28351   static constexpr auto CLASS_WIDGET = ChromeLegacyIpc_MessageClass_CLASS_WIDGET;
28352   static constexpr auto CLASS_INPUT = ChromeLegacyIpc_MessageClass_CLASS_INPUT;
28353   static constexpr auto CLASS_TEST = ChromeLegacyIpc_MessageClass_CLASS_TEST;
28354   static constexpr auto CLASS_WORKER = ChromeLegacyIpc_MessageClass_CLASS_WORKER;
28355   static constexpr auto CLASS_NACL = ChromeLegacyIpc_MessageClass_CLASS_NACL;
28356   static constexpr auto CLASS_GPU_CHANNEL = ChromeLegacyIpc_MessageClass_CLASS_GPU_CHANNEL;
28357   static constexpr auto CLASS_MEDIA = ChromeLegacyIpc_MessageClass_CLASS_MEDIA;
28358   static constexpr auto CLASS_PPAPI = ChromeLegacyIpc_MessageClass_CLASS_PPAPI;
28359   static constexpr auto CLASS_CHROME = ChromeLegacyIpc_MessageClass_CLASS_CHROME;
28360   static constexpr auto CLASS_DRAG = ChromeLegacyIpc_MessageClass_CLASS_DRAG;
28361   static constexpr auto CLASS_PRINT = ChromeLegacyIpc_MessageClass_CLASS_PRINT;
28362   static constexpr auto CLASS_EXTENSION = ChromeLegacyIpc_MessageClass_CLASS_EXTENSION;
28363   static constexpr auto CLASS_TEXT_INPUT_CLIENT = ChromeLegacyIpc_MessageClass_CLASS_TEXT_INPUT_CLIENT;
28364   static constexpr auto CLASS_BLINK_TEST = ChromeLegacyIpc_MessageClass_CLASS_BLINK_TEST;
28365   static constexpr auto CLASS_ACCESSIBILITY = ChromeLegacyIpc_MessageClass_CLASS_ACCESSIBILITY;
28366   static constexpr auto CLASS_PRERENDER = ChromeLegacyIpc_MessageClass_CLASS_PRERENDER;
28367   static constexpr auto CLASS_CHROMOTING = ChromeLegacyIpc_MessageClass_CLASS_CHROMOTING;
28368   static constexpr auto CLASS_BROWSER_PLUGIN = ChromeLegacyIpc_MessageClass_CLASS_BROWSER_PLUGIN;
28369   static constexpr auto CLASS_ANDROID_WEB_VIEW = ChromeLegacyIpc_MessageClass_CLASS_ANDROID_WEB_VIEW;
28370   static constexpr auto CLASS_NACL_HOST = ChromeLegacyIpc_MessageClass_CLASS_NACL_HOST;
28371   static constexpr auto CLASS_ENCRYPTED_MEDIA = ChromeLegacyIpc_MessageClass_CLASS_ENCRYPTED_MEDIA;
28372   static constexpr auto CLASS_CAST = ChromeLegacyIpc_MessageClass_CLASS_CAST;
28373   static constexpr auto CLASS_GIN_JAVA_BRIDGE = ChromeLegacyIpc_MessageClass_CLASS_GIN_JAVA_BRIDGE;
28374   static constexpr auto CLASS_CHROME_UTILITY_PRINTING = ChromeLegacyIpc_MessageClass_CLASS_CHROME_UTILITY_PRINTING;
28375   static constexpr auto CLASS_OZONE_GPU = ChromeLegacyIpc_MessageClass_CLASS_OZONE_GPU;
28376   static constexpr auto CLASS_WEB_TEST = ChromeLegacyIpc_MessageClass_CLASS_WEB_TEST;
28377   static constexpr auto CLASS_NETWORK_HINTS = ChromeLegacyIpc_MessageClass_CLASS_NETWORK_HINTS;
28378   static constexpr auto CLASS_EXTENSIONS_GUEST_VIEW = ChromeLegacyIpc_MessageClass_CLASS_EXTENSIONS_GUEST_VIEW;
28379   static constexpr auto CLASS_GUEST_VIEW = ChromeLegacyIpc_MessageClass_CLASS_GUEST_VIEW;
28380   static constexpr auto CLASS_MEDIA_PLAYER_DELEGATE = ChromeLegacyIpc_MessageClass_CLASS_MEDIA_PLAYER_DELEGATE;
28381   static constexpr auto CLASS_EXTENSION_WORKER = ChromeLegacyIpc_MessageClass_CLASS_EXTENSION_WORKER;
28382   static constexpr auto CLASS_SUBRESOURCE_FILTER = ChromeLegacyIpc_MessageClass_CLASS_SUBRESOURCE_FILTER;
28383   static constexpr auto CLASS_UNFREEZABLE_FRAME = ChromeLegacyIpc_MessageClass_CLASS_UNFREEZABLE_FRAME;
28384   static constexpr auto MessageClass_MIN = ChromeLegacyIpc_MessageClass_CLASS_UNSPECIFIED;
28385   static constexpr auto MessageClass_MAX = ChromeLegacyIpc_MessageClass_CLASS_UNFREEZABLE_FRAME;
28386   enum FieldNumbers {
28387     kMessageClassFieldNumber = 1,
28388     kMessageLineFieldNumber = 2,
28389   };
28390 
28391   ChromeLegacyIpc();
28392   ~ChromeLegacyIpc() override;
28393   ChromeLegacyIpc(ChromeLegacyIpc&&) noexcept;
28394   ChromeLegacyIpc& operator=(ChromeLegacyIpc&&);
28395   ChromeLegacyIpc(const ChromeLegacyIpc&);
28396   ChromeLegacyIpc& operator=(const ChromeLegacyIpc&);
28397   bool operator==(const ChromeLegacyIpc&) const;
operator !=(const ChromeLegacyIpc & other) const28398   bool operator!=(const ChromeLegacyIpc& other) const { return !(*this == other); }
28399 
28400   bool ParseFromArray(const void*, size_t) override;
28401   std::string SerializeAsString() const override;
28402   std::vector<uint8_t> SerializeAsArray() const override;
28403   void Serialize(::protozero::Message*) const;
28404 
has_message_class() const28405   bool has_message_class() const { return _has_field_[1]; }
message_class() const28406   ChromeLegacyIpc_MessageClass message_class() const { return message_class_; }
set_message_class(ChromeLegacyIpc_MessageClass value)28407   void set_message_class(ChromeLegacyIpc_MessageClass value) { message_class_ = value; _has_field_.set(1); }
28408 
has_message_line() const28409   bool has_message_line() const { return _has_field_[2]; }
message_line() const28410   uint32_t message_line() const { return message_line_; }
set_message_line(uint32_t value)28411   void set_message_line(uint32_t value) { message_line_ = value; _has_field_.set(2); }
28412 
28413  private:
28414   ChromeLegacyIpc_MessageClass message_class_{};
28415   uint32_t message_line_{};
28416 
28417   // Allows to preserve unknown protobuf fields for compatibility
28418   // with future versions of .proto files.
28419   std::string unknown_fields_;
28420 
28421   std::bitset<3> _has_field_{};
28422 };
28423 
28424 }  // namespace perfetto
28425 }  // namespace protos
28426 }  // namespace gen
28427 
28428 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_LEGACY_IPC_PROTO_CPP_H_
28429 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
28430 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
28431 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
28432 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
28433 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
28434 #if defined(__GNUC__) || defined(__clang__)
28435 #pragma GCC diagnostic push
28436 #pragma GCC diagnostic ignored "-Wfloat-equal"
28437 #endif
28438 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_legacy_ipc.gen.h"
28439 
28440 namespace perfetto {
28441 namespace protos {
28442 namespace gen {
28443 
28444 ChromeLegacyIpc::ChromeLegacyIpc() = default;
28445 ChromeLegacyIpc::~ChromeLegacyIpc() = default;
28446 ChromeLegacyIpc::ChromeLegacyIpc(const ChromeLegacyIpc&) = default;
28447 ChromeLegacyIpc& ChromeLegacyIpc::operator=(const ChromeLegacyIpc&) = default;
28448 ChromeLegacyIpc::ChromeLegacyIpc(ChromeLegacyIpc&&) noexcept = default;
28449 ChromeLegacyIpc& ChromeLegacyIpc::operator=(ChromeLegacyIpc&&) = default;
28450 
operator ==(const ChromeLegacyIpc & other) const28451 bool ChromeLegacyIpc::operator==(const ChromeLegacyIpc& other) const {
28452   return unknown_fields_ == other.unknown_fields_
28453    && message_class_ == other.message_class_
28454    && message_line_ == other.message_line_;
28455 }
28456 
ParseFromArray(const void * raw,size_t size)28457 bool ChromeLegacyIpc::ParseFromArray(const void* raw, size_t size) {
28458   unknown_fields_.clear();
28459   bool packed_error = false;
28460 
28461   ::protozero::ProtoDecoder dec(raw, size);
28462   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
28463     if (field.id() < _has_field_.size()) {
28464       _has_field_.set(field.id());
28465     }
28466     switch (field.id()) {
28467       case 1 /* message_class */:
28468         field.get(&message_class_);
28469         break;
28470       case 2 /* message_line */:
28471         field.get(&message_line_);
28472         break;
28473       default:
28474         field.SerializeAndAppendTo(&unknown_fields_);
28475         break;
28476     }
28477   }
28478   return !packed_error && !dec.bytes_left();
28479 }
28480 
SerializeAsString() const28481 std::string ChromeLegacyIpc::SerializeAsString() const {
28482   ::protozero::HeapBuffered<::protozero::Message> msg;
28483   Serialize(msg.get());
28484   return msg.SerializeAsString();
28485 }
28486 
SerializeAsArray() const28487 std::vector<uint8_t> ChromeLegacyIpc::SerializeAsArray() const {
28488   ::protozero::HeapBuffered<::protozero::Message> msg;
28489   Serialize(msg.get());
28490   return msg.SerializeAsArray();
28491 }
28492 
Serialize(::protozero::Message * msg) const28493 void ChromeLegacyIpc::Serialize(::protozero::Message* msg) const {
28494   // Field 1: message_class
28495   if (_has_field_[1]) {
28496     msg->AppendVarInt(1, message_class_);
28497   }
28498 
28499   // Field 2: message_line
28500   if (_has_field_[2]) {
28501     msg->AppendVarInt(2, message_line_);
28502   }
28503 
28504   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
28505 }
28506 
28507 }  // namespace perfetto
28508 }  // namespace protos
28509 }  // namespace gen
28510 #if defined(__GNUC__) || defined(__clang__)
28511 #pragma GCC diagnostic pop
28512 #endif
28513 // gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_message_pump.gen.cc
28514 // gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/chrome_message_pump.gen.h
28515 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
28516 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_MESSAGE_PUMP_PROTO_CPP_H_
28517 #define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_MESSAGE_PUMP_PROTO_CPP_H_
28518 
28519 #include <stdint.h>
28520 #include <bitset>
28521 #include <vector>
28522 #include <string>
28523 #include <type_traits>
28524 
28525 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
28526 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
28527 // gen_amalgamated expanded: #include "perfetto/base/export.h"
28528 
28529 namespace perfetto {
28530 namespace protos {
28531 namespace gen {
28532 class ChromeMessagePump;
28533 }  // namespace perfetto
28534 }  // namespace protos
28535 }  // namespace gen
28536 
28537 namespace protozero {
28538 class Message;
28539 }  // namespace protozero
28540 
28541 namespace perfetto {
28542 namespace protos {
28543 namespace gen {
28544 
28545 class PERFETTO_EXPORT ChromeMessagePump : public ::protozero::CppMessageObj {
28546  public:
28547   enum FieldNumbers {
28548     kSentMessagesInQueueFieldNumber = 1,
28549     kIoHandlerLocationIidFieldNumber = 2,
28550   };
28551 
28552   ChromeMessagePump();
28553   ~ChromeMessagePump() override;
28554   ChromeMessagePump(ChromeMessagePump&&) noexcept;
28555   ChromeMessagePump& operator=(ChromeMessagePump&&);
28556   ChromeMessagePump(const ChromeMessagePump&);
28557   ChromeMessagePump& operator=(const ChromeMessagePump&);
28558   bool operator==(const ChromeMessagePump&) const;
operator !=(const ChromeMessagePump & other) const28559   bool operator!=(const ChromeMessagePump& other) const { return !(*this == other); }
28560 
28561   bool ParseFromArray(const void*, size_t) override;
28562   std::string SerializeAsString() const override;
28563   std::vector<uint8_t> SerializeAsArray() const override;
28564   void Serialize(::protozero::Message*) const;
28565 
has_sent_messages_in_queue() const28566   bool has_sent_messages_in_queue() const { return _has_field_[1]; }
sent_messages_in_queue() const28567   bool sent_messages_in_queue() const { return sent_messages_in_queue_; }
set_sent_messages_in_queue(bool value)28568   void set_sent_messages_in_queue(bool value) { sent_messages_in_queue_ = value; _has_field_.set(1); }
28569 
has_io_handler_location_iid() const28570   bool has_io_handler_location_iid() const { return _has_field_[2]; }
io_handler_location_iid() const28571   uint64_t io_handler_location_iid() const { return io_handler_location_iid_; }
set_io_handler_location_iid(uint64_t value)28572   void set_io_handler_location_iid(uint64_t value) { io_handler_location_iid_ = value; _has_field_.set(2); }
28573 
28574  private:
28575   bool sent_messages_in_queue_{};
28576   uint64_t io_handler_location_iid_{};
28577 
28578   // Allows to preserve unknown protobuf fields for compatibility
28579   // with future versions of .proto files.
28580   std::string unknown_fields_;
28581 
28582   std::bitset<3> _has_field_{};
28583 };
28584 
28585 }  // namespace perfetto
28586 }  // namespace protos
28587 }  // namespace gen
28588 
28589 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_MESSAGE_PUMP_PROTO_CPP_H_
28590 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
28591 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
28592 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
28593 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
28594 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
28595 #if defined(__GNUC__) || defined(__clang__)
28596 #pragma GCC diagnostic push
28597 #pragma GCC diagnostic ignored "-Wfloat-equal"
28598 #endif
28599 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_message_pump.gen.h"
28600 
28601 namespace perfetto {
28602 namespace protos {
28603 namespace gen {
28604 
28605 ChromeMessagePump::ChromeMessagePump() = default;
28606 ChromeMessagePump::~ChromeMessagePump() = default;
28607 ChromeMessagePump::ChromeMessagePump(const ChromeMessagePump&) = default;
28608 ChromeMessagePump& ChromeMessagePump::operator=(const ChromeMessagePump&) = default;
28609 ChromeMessagePump::ChromeMessagePump(ChromeMessagePump&&) noexcept = default;
28610 ChromeMessagePump& ChromeMessagePump::operator=(ChromeMessagePump&&) = default;
28611 
operator ==(const ChromeMessagePump & other) const28612 bool ChromeMessagePump::operator==(const ChromeMessagePump& other) const {
28613   return unknown_fields_ == other.unknown_fields_
28614    && sent_messages_in_queue_ == other.sent_messages_in_queue_
28615    && io_handler_location_iid_ == other.io_handler_location_iid_;
28616 }
28617 
ParseFromArray(const void * raw,size_t size)28618 bool ChromeMessagePump::ParseFromArray(const void* raw, size_t size) {
28619   unknown_fields_.clear();
28620   bool packed_error = false;
28621 
28622   ::protozero::ProtoDecoder dec(raw, size);
28623   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
28624     if (field.id() < _has_field_.size()) {
28625       _has_field_.set(field.id());
28626     }
28627     switch (field.id()) {
28628       case 1 /* sent_messages_in_queue */:
28629         field.get(&sent_messages_in_queue_);
28630         break;
28631       case 2 /* io_handler_location_iid */:
28632         field.get(&io_handler_location_iid_);
28633         break;
28634       default:
28635         field.SerializeAndAppendTo(&unknown_fields_);
28636         break;
28637     }
28638   }
28639   return !packed_error && !dec.bytes_left();
28640 }
28641 
SerializeAsString() const28642 std::string ChromeMessagePump::SerializeAsString() const {
28643   ::protozero::HeapBuffered<::protozero::Message> msg;
28644   Serialize(msg.get());
28645   return msg.SerializeAsString();
28646 }
28647 
SerializeAsArray() const28648 std::vector<uint8_t> ChromeMessagePump::SerializeAsArray() const {
28649   ::protozero::HeapBuffered<::protozero::Message> msg;
28650   Serialize(msg.get());
28651   return msg.SerializeAsArray();
28652 }
28653 
Serialize(::protozero::Message * msg) const28654 void ChromeMessagePump::Serialize(::protozero::Message* msg) const {
28655   // Field 1: sent_messages_in_queue
28656   if (_has_field_[1]) {
28657     msg->AppendTinyVarInt(1, sent_messages_in_queue_);
28658   }
28659 
28660   // Field 2: io_handler_location_iid
28661   if (_has_field_[2]) {
28662     msg->AppendVarInt(2, io_handler_location_iid_);
28663   }
28664 
28665   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
28666 }
28667 
28668 }  // namespace perfetto
28669 }  // namespace protos
28670 }  // namespace gen
28671 #if defined(__GNUC__) || defined(__clang__)
28672 #pragma GCC diagnostic pop
28673 #endif
28674 // gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_mojo_event_info.gen.cc
28675 // gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/chrome_mojo_event_info.gen.h
28676 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
28677 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_MOJO_EVENT_INFO_PROTO_CPP_H_
28678 #define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_MOJO_EVENT_INFO_PROTO_CPP_H_
28679 
28680 #include <stdint.h>
28681 #include <bitset>
28682 #include <vector>
28683 #include <string>
28684 #include <type_traits>
28685 
28686 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
28687 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
28688 // gen_amalgamated expanded: #include "perfetto/base/export.h"
28689 
28690 namespace perfetto {
28691 namespace protos {
28692 namespace gen {
28693 class ChromeMojoEventInfo;
28694 }  // namespace perfetto
28695 }  // namespace protos
28696 }  // namespace gen
28697 
28698 namespace protozero {
28699 class Message;
28700 }  // namespace protozero
28701 
28702 namespace perfetto {
28703 namespace protos {
28704 namespace gen {
28705 
28706 class PERFETTO_EXPORT ChromeMojoEventInfo : public ::protozero::CppMessageObj {
28707  public:
28708   enum FieldNumbers {
28709     kWatcherNotifyInterfaceTagFieldNumber = 1,
28710     kIpcHashFieldNumber = 2,
28711     kMojoInterfaceTagFieldNumber = 3,
28712   };
28713 
28714   ChromeMojoEventInfo();
28715   ~ChromeMojoEventInfo() override;
28716   ChromeMojoEventInfo(ChromeMojoEventInfo&&) noexcept;
28717   ChromeMojoEventInfo& operator=(ChromeMojoEventInfo&&);
28718   ChromeMojoEventInfo(const ChromeMojoEventInfo&);
28719   ChromeMojoEventInfo& operator=(const ChromeMojoEventInfo&);
28720   bool operator==(const ChromeMojoEventInfo&) const;
operator !=(const ChromeMojoEventInfo & other) const28721   bool operator!=(const ChromeMojoEventInfo& other) const { return !(*this == other); }
28722 
28723   bool ParseFromArray(const void*, size_t) override;
28724   std::string SerializeAsString() const override;
28725   std::vector<uint8_t> SerializeAsArray() const override;
28726   void Serialize(::protozero::Message*) const;
28727 
has_watcher_notify_interface_tag() const28728   bool has_watcher_notify_interface_tag() const { return _has_field_[1]; }
watcher_notify_interface_tag() const28729   const std::string& watcher_notify_interface_tag() const { return watcher_notify_interface_tag_; }
set_watcher_notify_interface_tag(const std::string & value)28730   void set_watcher_notify_interface_tag(const std::string& value) { watcher_notify_interface_tag_ = value; _has_field_.set(1); }
28731 
has_ipc_hash() const28732   bool has_ipc_hash() const { return _has_field_[2]; }
ipc_hash() const28733   uint32_t ipc_hash() const { return ipc_hash_; }
set_ipc_hash(uint32_t value)28734   void set_ipc_hash(uint32_t value) { ipc_hash_ = value; _has_field_.set(2); }
28735 
has_mojo_interface_tag() const28736   bool has_mojo_interface_tag() const { return _has_field_[3]; }
mojo_interface_tag() const28737   const std::string& mojo_interface_tag() const { return mojo_interface_tag_; }
set_mojo_interface_tag(const std::string & value)28738   void set_mojo_interface_tag(const std::string& value) { mojo_interface_tag_ = value; _has_field_.set(3); }
28739 
28740  private:
28741   std::string watcher_notify_interface_tag_{};
28742   uint32_t ipc_hash_{};
28743   std::string mojo_interface_tag_{};
28744 
28745   // Allows to preserve unknown protobuf fields for compatibility
28746   // with future versions of .proto files.
28747   std::string unknown_fields_;
28748 
28749   std::bitset<4> _has_field_{};
28750 };
28751 
28752 }  // namespace perfetto
28753 }  // namespace protos
28754 }  // namespace gen
28755 
28756 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_MOJO_EVENT_INFO_PROTO_CPP_H_
28757 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
28758 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
28759 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
28760 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
28761 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
28762 #if defined(__GNUC__) || defined(__clang__)
28763 #pragma GCC diagnostic push
28764 #pragma GCC diagnostic ignored "-Wfloat-equal"
28765 #endif
28766 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_mojo_event_info.gen.h"
28767 
28768 namespace perfetto {
28769 namespace protos {
28770 namespace gen {
28771 
28772 ChromeMojoEventInfo::ChromeMojoEventInfo() = default;
28773 ChromeMojoEventInfo::~ChromeMojoEventInfo() = default;
28774 ChromeMojoEventInfo::ChromeMojoEventInfo(const ChromeMojoEventInfo&) = default;
28775 ChromeMojoEventInfo& ChromeMojoEventInfo::operator=(const ChromeMojoEventInfo&) = default;
28776 ChromeMojoEventInfo::ChromeMojoEventInfo(ChromeMojoEventInfo&&) noexcept = default;
28777 ChromeMojoEventInfo& ChromeMojoEventInfo::operator=(ChromeMojoEventInfo&&) = default;
28778 
operator ==(const ChromeMojoEventInfo & other) const28779 bool ChromeMojoEventInfo::operator==(const ChromeMojoEventInfo& other) const {
28780   return unknown_fields_ == other.unknown_fields_
28781    && watcher_notify_interface_tag_ == other.watcher_notify_interface_tag_
28782    && ipc_hash_ == other.ipc_hash_
28783    && mojo_interface_tag_ == other.mojo_interface_tag_;
28784 }
28785 
ParseFromArray(const void * raw,size_t size)28786 bool ChromeMojoEventInfo::ParseFromArray(const void* raw, size_t size) {
28787   unknown_fields_.clear();
28788   bool packed_error = false;
28789 
28790   ::protozero::ProtoDecoder dec(raw, size);
28791   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
28792     if (field.id() < _has_field_.size()) {
28793       _has_field_.set(field.id());
28794     }
28795     switch (field.id()) {
28796       case 1 /* watcher_notify_interface_tag */:
28797         field.get(&watcher_notify_interface_tag_);
28798         break;
28799       case 2 /* ipc_hash */:
28800         field.get(&ipc_hash_);
28801         break;
28802       case 3 /* mojo_interface_tag */:
28803         field.get(&mojo_interface_tag_);
28804         break;
28805       default:
28806         field.SerializeAndAppendTo(&unknown_fields_);
28807         break;
28808     }
28809   }
28810   return !packed_error && !dec.bytes_left();
28811 }
28812 
SerializeAsString() const28813 std::string ChromeMojoEventInfo::SerializeAsString() const {
28814   ::protozero::HeapBuffered<::protozero::Message> msg;
28815   Serialize(msg.get());
28816   return msg.SerializeAsString();
28817 }
28818 
SerializeAsArray() const28819 std::vector<uint8_t> ChromeMojoEventInfo::SerializeAsArray() const {
28820   ::protozero::HeapBuffered<::protozero::Message> msg;
28821   Serialize(msg.get());
28822   return msg.SerializeAsArray();
28823 }
28824 
Serialize(::protozero::Message * msg) const28825 void ChromeMojoEventInfo::Serialize(::protozero::Message* msg) const {
28826   // Field 1: watcher_notify_interface_tag
28827   if (_has_field_[1]) {
28828     msg->AppendString(1, watcher_notify_interface_tag_);
28829   }
28830 
28831   // Field 2: ipc_hash
28832   if (_has_field_[2]) {
28833     msg->AppendVarInt(2, ipc_hash_);
28834   }
28835 
28836   // Field 3: mojo_interface_tag
28837   if (_has_field_[3]) {
28838     msg->AppendString(3, mojo_interface_tag_);
28839   }
28840 
28841   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
28842 }
28843 
28844 }  // namespace perfetto
28845 }  // namespace protos
28846 }  // namespace gen
28847 #if defined(__GNUC__) || defined(__clang__)
28848 #pragma GCC diagnostic pop
28849 #endif
28850 // gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_process_descriptor.gen.cc
28851 // gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/chrome_process_descriptor.gen.h
28852 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
28853 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_PROCESS_DESCRIPTOR_PROTO_CPP_H_
28854 #define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_PROCESS_DESCRIPTOR_PROTO_CPP_H_
28855 
28856 #include <stdint.h>
28857 #include <bitset>
28858 #include <vector>
28859 #include <string>
28860 #include <type_traits>
28861 
28862 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
28863 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
28864 // gen_amalgamated expanded: #include "perfetto/base/export.h"
28865 
28866 namespace perfetto {
28867 namespace protos {
28868 namespace gen {
28869 class ChromeProcessDescriptor;
28870 enum ChromeProcessDescriptor_ProcessType : int;
28871 }  // namespace perfetto
28872 }  // namespace protos
28873 }  // namespace gen
28874 
28875 namespace protozero {
28876 class Message;
28877 }  // namespace protozero
28878 
28879 namespace perfetto {
28880 namespace protos {
28881 namespace gen {
28882 enum ChromeProcessDescriptor_ProcessType : int {
28883   ChromeProcessDescriptor_ProcessType_PROCESS_UNSPECIFIED = 0,
28884   ChromeProcessDescriptor_ProcessType_PROCESS_BROWSER = 1,
28885   ChromeProcessDescriptor_ProcessType_PROCESS_RENDERER = 2,
28886   ChromeProcessDescriptor_ProcessType_PROCESS_UTILITY = 3,
28887   ChromeProcessDescriptor_ProcessType_PROCESS_ZYGOTE = 4,
28888   ChromeProcessDescriptor_ProcessType_PROCESS_SANDBOX_HELPER = 5,
28889   ChromeProcessDescriptor_ProcessType_PROCESS_GPU = 6,
28890   ChromeProcessDescriptor_ProcessType_PROCESS_PPAPI_PLUGIN = 7,
28891   ChromeProcessDescriptor_ProcessType_PROCESS_PPAPI_BROKER = 8,
28892   ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_NETWORK = 9,
28893   ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_TRACING = 10,
28894   ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_STORAGE = 11,
28895   ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_AUDIO = 12,
28896   ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_DATA_DECODER = 13,
28897   ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_UTIL_WIN = 14,
28898   ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_PROXY_RESOLVER = 15,
28899   ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_CDM = 16,
28900   ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_VIDEO_CAPTURE = 17,
28901   ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_UNZIPPER = 18,
28902   ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_MIRRORING = 19,
28903   ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_FILEPATCHER = 20,
28904   ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_TTS = 21,
28905   ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_PRINTING = 22,
28906   ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_QUARANTINE = 23,
28907   ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_CROS_LOCALSEARCH = 24,
28908   ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_CROS_ASSISTANT_AUDIO_DECODER = 25,
28909   ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_FILEUTIL = 26,
28910   ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_PRINTCOMPOSITOR = 27,
28911   ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_PAINTPREVIEW = 28,
28912   ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_SPEECHRECOGNITION = 29,
28913   ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_XRDEVICE = 30,
28914   ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_READICON = 31,
28915   ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_LANGUAGEDETECTION = 32,
28916   ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_SHARING = 33,
28917   ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_MEDIAPARSER = 34,
28918   ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_QRCODEGENERATOR = 35,
28919   ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_PROFILEIMPORT = 36,
28920   ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_IME = 37,
28921   ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_RECORDING = 38,
28922   ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_SHAPEDETECTION = 39,
28923   ChromeProcessDescriptor_ProcessType_PROCESS_RENDERER_EXTENSION = 40,
28924 };
28925 
28926 class PERFETTO_EXPORT ChromeProcessDescriptor : public ::protozero::CppMessageObj {
28927  public:
28928   using ProcessType = ChromeProcessDescriptor_ProcessType;
28929   static constexpr auto PROCESS_UNSPECIFIED = ChromeProcessDescriptor_ProcessType_PROCESS_UNSPECIFIED;
28930   static constexpr auto PROCESS_BROWSER = ChromeProcessDescriptor_ProcessType_PROCESS_BROWSER;
28931   static constexpr auto PROCESS_RENDERER = ChromeProcessDescriptor_ProcessType_PROCESS_RENDERER;
28932   static constexpr auto PROCESS_UTILITY = ChromeProcessDescriptor_ProcessType_PROCESS_UTILITY;
28933   static constexpr auto PROCESS_ZYGOTE = ChromeProcessDescriptor_ProcessType_PROCESS_ZYGOTE;
28934   static constexpr auto PROCESS_SANDBOX_HELPER = ChromeProcessDescriptor_ProcessType_PROCESS_SANDBOX_HELPER;
28935   static constexpr auto PROCESS_GPU = ChromeProcessDescriptor_ProcessType_PROCESS_GPU;
28936   static constexpr auto PROCESS_PPAPI_PLUGIN = ChromeProcessDescriptor_ProcessType_PROCESS_PPAPI_PLUGIN;
28937   static constexpr auto PROCESS_PPAPI_BROKER = ChromeProcessDescriptor_ProcessType_PROCESS_PPAPI_BROKER;
28938   static constexpr auto PROCESS_SERVICE_NETWORK = ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_NETWORK;
28939   static constexpr auto PROCESS_SERVICE_TRACING = ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_TRACING;
28940   static constexpr auto PROCESS_SERVICE_STORAGE = ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_STORAGE;
28941   static constexpr auto PROCESS_SERVICE_AUDIO = ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_AUDIO;
28942   static constexpr auto PROCESS_SERVICE_DATA_DECODER = ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_DATA_DECODER;
28943   static constexpr auto PROCESS_SERVICE_UTIL_WIN = ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_UTIL_WIN;
28944   static constexpr auto PROCESS_SERVICE_PROXY_RESOLVER = ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_PROXY_RESOLVER;
28945   static constexpr auto PROCESS_SERVICE_CDM = ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_CDM;
28946   static constexpr auto PROCESS_SERVICE_VIDEO_CAPTURE = ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_VIDEO_CAPTURE;
28947   static constexpr auto PROCESS_SERVICE_UNZIPPER = ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_UNZIPPER;
28948   static constexpr auto PROCESS_SERVICE_MIRRORING = ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_MIRRORING;
28949   static constexpr auto PROCESS_SERVICE_FILEPATCHER = ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_FILEPATCHER;
28950   static constexpr auto PROCESS_SERVICE_TTS = ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_TTS;
28951   static constexpr auto PROCESS_SERVICE_PRINTING = ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_PRINTING;
28952   static constexpr auto PROCESS_SERVICE_QUARANTINE = ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_QUARANTINE;
28953   static constexpr auto PROCESS_SERVICE_CROS_LOCALSEARCH = ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_CROS_LOCALSEARCH;
28954   static constexpr auto PROCESS_SERVICE_CROS_ASSISTANT_AUDIO_DECODER = ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_CROS_ASSISTANT_AUDIO_DECODER;
28955   static constexpr auto PROCESS_SERVICE_FILEUTIL = ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_FILEUTIL;
28956   static constexpr auto PROCESS_SERVICE_PRINTCOMPOSITOR = ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_PRINTCOMPOSITOR;
28957   static constexpr auto PROCESS_SERVICE_PAINTPREVIEW = ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_PAINTPREVIEW;
28958   static constexpr auto PROCESS_SERVICE_SPEECHRECOGNITION = ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_SPEECHRECOGNITION;
28959   static constexpr auto PROCESS_SERVICE_XRDEVICE = ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_XRDEVICE;
28960   static constexpr auto PROCESS_SERVICE_READICON = ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_READICON;
28961   static constexpr auto PROCESS_SERVICE_LANGUAGEDETECTION = ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_LANGUAGEDETECTION;
28962   static constexpr auto PROCESS_SERVICE_SHARING = ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_SHARING;
28963   static constexpr auto PROCESS_SERVICE_MEDIAPARSER = ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_MEDIAPARSER;
28964   static constexpr auto PROCESS_SERVICE_QRCODEGENERATOR = ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_QRCODEGENERATOR;
28965   static constexpr auto PROCESS_SERVICE_PROFILEIMPORT = ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_PROFILEIMPORT;
28966   static constexpr auto PROCESS_SERVICE_IME = ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_IME;
28967   static constexpr auto PROCESS_SERVICE_RECORDING = ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_RECORDING;
28968   static constexpr auto PROCESS_SERVICE_SHAPEDETECTION = ChromeProcessDescriptor_ProcessType_PROCESS_SERVICE_SHAPEDETECTION;
28969   static constexpr auto PROCESS_RENDERER_EXTENSION = ChromeProcessDescriptor_ProcessType_PROCESS_RENDERER_EXTENSION;
28970   static constexpr auto ProcessType_MIN = ChromeProcessDescriptor_ProcessType_PROCESS_UNSPECIFIED;
28971   static constexpr auto ProcessType_MAX = ChromeProcessDescriptor_ProcessType_PROCESS_RENDERER_EXTENSION;
28972   enum FieldNumbers {
28973     kProcessTypeFieldNumber = 1,
28974     kProcessPriorityFieldNumber = 2,
28975     kLegacySortIndexFieldNumber = 3,
28976     kHostAppPackageNameFieldNumber = 4,
28977     kCrashTraceIdFieldNumber = 5,
28978   };
28979 
28980   ChromeProcessDescriptor();
28981   ~ChromeProcessDescriptor() override;
28982   ChromeProcessDescriptor(ChromeProcessDescriptor&&) noexcept;
28983   ChromeProcessDescriptor& operator=(ChromeProcessDescriptor&&);
28984   ChromeProcessDescriptor(const ChromeProcessDescriptor&);
28985   ChromeProcessDescriptor& operator=(const ChromeProcessDescriptor&);
28986   bool operator==(const ChromeProcessDescriptor&) const;
operator !=(const ChromeProcessDescriptor & other) const28987   bool operator!=(const ChromeProcessDescriptor& other) const { return !(*this == other); }
28988 
28989   bool ParseFromArray(const void*, size_t) override;
28990   std::string SerializeAsString() const override;
28991   std::vector<uint8_t> SerializeAsArray() const override;
28992   void Serialize(::protozero::Message*) const;
28993 
has_process_type() const28994   bool has_process_type() const { return _has_field_[1]; }
process_type() const28995   ChromeProcessDescriptor_ProcessType process_type() const { return process_type_; }
set_process_type(ChromeProcessDescriptor_ProcessType value)28996   void set_process_type(ChromeProcessDescriptor_ProcessType value) { process_type_ = value; _has_field_.set(1); }
28997 
has_process_priority() const28998   bool has_process_priority() const { return _has_field_[2]; }
process_priority() const28999   int32_t process_priority() const { return process_priority_; }
set_process_priority(int32_t value)29000   void set_process_priority(int32_t value) { process_priority_ = value; _has_field_.set(2); }
29001 
has_legacy_sort_index() const29002   bool has_legacy_sort_index() const { return _has_field_[3]; }
legacy_sort_index() const29003   int32_t legacy_sort_index() const { return legacy_sort_index_; }
set_legacy_sort_index(int32_t value)29004   void set_legacy_sort_index(int32_t value) { legacy_sort_index_ = value; _has_field_.set(3); }
29005 
has_host_app_package_name() const29006   bool has_host_app_package_name() const { return _has_field_[4]; }
host_app_package_name() const29007   const std::string& host_app_package_name() const { return host_app_package_name_; }
set_host_app_package_name(const std::string & value)29008   void set_host_app_package_name(const std::string& value) { host_app_package_name_ = value; _has_field_.set(4); }
29009 
has_crash_trace_id() const29010   bool has_crash_trace_id() const { return _has_field_[5]; }
crash_trace_id() const29011   uint64_t crash_trace_id() const { return crash_trace_id_; }
set_crash_trace_id(uint64_t value)29012   void set_crash_trace_id(uint64_t value) { crash_trace_id_ = value; _has_field_.set(5); }
29013 
29014  private:
29015   ChromeProcessDescriptor_ProcessType process_type_{};
29016   int32_t process_priority_{};
29017   int32_t legacy_sort_index_{};
29018   std::string host_app_package_name_{};
29019   uint64_t crash_trace_id_{};
29020 
29021   // Allows to preserve unknown protobuf fields for compatibility
29022   // with future versions of .proto files.
29023   std::string unknown_fields_;
29024 
29025   std::bitset<6> _has_field_{};
29026 };
29027 
29028 }  // namespace perfetto
29029 }  // namespace protos
29030 }  // namespace gen
29031 
29032 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_PROCESS_DESCRIPTOR_PROTO_CPP_H_
29033 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
29034 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
29035 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
29036 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
29037 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
29038 #if defined(__GNUC__) || defined(__clang__)
29039 #pragma GCC diagnostic push
29040 #pragma GCC diagnostic ignored "-Wfloat-equal"
29041 #endif
29042 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_process_descriptor.gen.h"
29043 
29044 namespace perfetto {
29045 namespace protos {
29046 namespace gen {
29047 
29048 ChromeProcessDescriptor::ChromeProcessDescriptor() = default;
29049 ChromeProcessDescriptor::~ChromeProcessDescriptor() = default;
29050 ChromeProcessDescriptor::ChromeProcessDescriptor(const ChromeProcessDescriptor&) = default;
29051 ChromeProcessDescriptor& ChromeProcessDescriptor::operator=(const ChromeProcessDescriptor&) = default;
29052 ChromeProcessDescriptor::ChromeProcessDescriptor(ChromeProcessDescriptor&&) noexcept = default;
29053 ChromeProcessDescriptor& ChromeProcessDescriptor::operator=(ChromeProcessDescriptor&&) = default;
29054 
operator ==(const ChromeProcessDescriptor & other) const29055 bool ChromeProcessDescriptor::operator==(const ChromeProcessDescriptor& other) const {
29056   return unknown_fields_ == other.unknown_fields_
29057    && process_type_ == other.process_type_
29058    && process_priority_ == other.process_priority_
29059    && legacy_sort_index_ == other.legacy_sort_index_
29060    && host_app_package_name_ == other.host_app_package_name_
29061    && crash_trace_id_ == other.crash_trace_id_;
29062 }
29063 
ParseFromArray(const void * raw,size_t size)29064 bool ChromeProcessDescriptor::ParseFromArray(const void* raw, size_t size) {
29065   unknown_fields_.clear();
29066   bool packed_error = false;
29067 
29068   ::protozero::ProtoDecoder dec(raw, size);
29069   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
29070     if (field.id() < _has_field_.size()) {
29071       _has_field_.set(field.id());
29072     }
29073     switch (field.id()) {
29074       case 1 /* process_type */:
29075         field.get(&process_type_);
29076         break;
29077       case 2 /* process_priority */:
29078         field.get(&process_priority_);
29079         break;
29080       case 3 /* legacy_sort_index */:
29081         field.get(&legacy_sort_index_);
29082         break;
29083       case 4 /* host_app_package_name */:
29084         field.get(&host_app_package_name_);
29085         break;
29086       case 5 /* crash_trace_id */:
29087         field.get(&crash_trace_id_);
29088         break;
29089       default:
29090         field.SerializeAndAppendTo(&unknown_fields_);
29091         break;
29092     }
29093   }
29094   return !packed_error && !dec.bytes_left();
29095 }
29096 
SerializeAsString() const29097 std::string ChromeProcessDescriptor::SerializeAsString() const {
29098   ::protozero::HeapBuffered<::protozero::Message> msg;
29099   Serialize(msg.get());
29100   return msg.SerializeAsString();
29101 }
29102 
SerializeAsArray() const29103 std::vector<uint8_t> ChromeProcessDescriptor::SerializeAsArray() const {
29104   ::protozero::HeapBuffered<::protozero::Message> msg;
29105   Serialize(msg.get());
29106   return msg.SerializeAsArray();
29107 }
29108 
Serialize(::protozero::Message * msg) const29109 void ChromeProcessDescriptor::Serialize(::protozero::Message* msg) const {
29110   // Field 1: process_type
29111   if (_has_field_[1]) {
29112     msg->AppendVarInt(1, process_type_);
29113   }
29114 
29115   // Field 2: process_priority
29116   if (_has_field_[2]) {
29117     msg->AppendVarInt(2, process_priority_);
29118   }
29119 
29120   // Field 3: legacy_sort_index
29121   if (_has_field_[3]) {
29122     msg->AppendVarInt(3, legacy_sort_index_);
29123   }
29124 
29125   // Field 4: host_app_package_name
29126   if (_has_field_[4]) {
29127     msg->AppendString(4, host_app_package_name_);
29128   }
29129 
29130   // Field 5: crash_trace_id
29131   if (_has_field_[5]) {
29132     msg->AppendVarInt(5, crash_trace_id_);
29133   }
29134 
29135   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
29136 }
29137 
29138 }  // namespace perfetto
29139 }  // namespace protos
29140 }  // namespace gen
29141 #if defined(__GNUC__) || defined(__clang__)
29142 #pragma GCC diagnostic pop
29143 #endif
29144 // gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_renderer_scheduler_state.gen.cc
29145 // gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/chrome_renderer_scheduler_state.gen.h
29146 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
29147 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_RENDERER_SCHEDULER_STATE_PROTO_CPP_H_
29148 #define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_RENDERER_SCHEDULER_STATE_PROTO_CPP_H_
29149 
29150 #include <stdint.h>
29151 #include <bitset>
29152 #include <vector>
29153 #include <string>
29154 #include <type_traits>
29155 
29156 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
29157 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
29158 // gen_amalgamated expanded: #include "perfetto/base/export.h"
29159 
29160 namespace perfetto {
29161 namespace protos {
29162 namespace gen {
29163 class ChromeRendererSchedulerState;
29164 enum ChromeRAILMode : int;
29165 }  // namespace perfetto
29166 }  // namespace protos
29167 }  // namespace gen
29168 
29169 namespace protozero {
29170 class Message;
29171 }  // namespace protozero
29172 
29173 namespace perfetto {
29174 namespace protos {
29175 namespace gen {
29176 enum ChromeRAILMode : int {
29177   RAIL_MODE_NONE = 0,
29178   RAIL_MODE_RESPONSE = 1,
29179   RAIL_MODE_ANIMATION = 2,
29180   RAIL_MODE_IDLE = 3,
29181   RAIL_MODE_LOAD = 4,
29182 };
29183 
29184 class PERFETTO_EXPORT ChromeRendererSchedulerState : public ::protozero::CppMessageObj {
29185  public:
29186   enum FieldNumbers {
29187     kRailModeFieldNumber = 1,
29188     kIsBackgroundedFieldNumber = 2,
29189     kIsHiddenFieldNumber = 3,
29190   };
29191 
29192   ChromeRendererSchedulerState();
29193   ~ChromeRendererSchedulerState() override;
29194   ChromeRendererSchedulerState(ChromeRendererSchedulerState&&) noexcept;
29195   ChromeRendererSchedulerState& operator=(ChromeRendererSchedulerState&&);
29196   ChromeRendererSchedulerState(const ChromeRendererSchedulerState&);
29197   ChromeRendererSchedulerState& operator=(const ChromeRendererSchedulerState&);
29198   bool operator==(const ChromeRendererSchedulerState&) const;
operator !=(const ChromeRendererSchedulerState & other) const29199   bool operator!=(const ChromeRendererSchedulerState& other) const { return !(*this == other); }
29200 
29201   bool ParseFromArray(const void*, size_t) override;
29202   std::string SerializeAsString() const override;
29203   std::vector<uint8_t> SerializeAsArray() const override;
29204   void Serialize(::protozero::Message*) const;
29205 
has_rail_mode() const29206   bool has_rail_mode() const { return _has_field_[1]; }
rail_mode() const29207   ChromeRAILMode rail_mode() const { return rail_mode_; }
set_rail_mode(ChromeRAILMode value)29208   void set_rail_mode(ChromeRAILMode value) { rail_mode_ = value; _has_field_.set(1); }
29209 
has_is_backgrounded() const29210   bool has_is_backgrounded() const { return _has_field_[2]; }
is_backgrounded() const29211   bool is_backgrounded() const { return is_backgrounded_; }
set_is_backgrounded(bool value)29212   void set_is_backgrounded(bool value) { is_backgrounded_ = value; _has_field_.set(2); }
29213 
has_is_hidden() const29214   bool has_is_hidden() const { return _has_field_[3]; }
is_hidden() const29215   bool is_hidden() const { return is_hidden_; }
set_is_hidden(bool value)29216   void set_is_hidden(bool value) { is_hidden_ = value; _has_field_.set(3); }
29217 
29218  private:
29219   ChromeRAILMode rail_mode_{};
29220   bool is_backgrounded_{};
29221   bool is_hidden_{};
29222 
29223   // Allows to preserve unknown protobuf fields for compatibility
29224   // with future versions of .proto files.
29225   std::string unknown_fields_;
29226 
29227   std::bitset<4> _has_field_{};
29228 };
29229 
29230 }  // namespace perfetto
29231 }  // namespace protos
29232 }  // namespace gen
29233 
29234 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_RENDERER_SCHEDULER_STATE_PROTO_CPP_H_
29235 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
29236 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
29237 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
29238 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
29239 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
29240 #if defined(__GNUC__) || defined(__clang__)
29241 #pragma GCC diagnostic push
29242 #pragma GCC diagnostic ignored "-Wfloat-equal"
29243 #endif
29244 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_renderer_scheduler_state.gen.h"
29245 
29246 namespace perfetto {
29247 namespace protos {
29248 namespace gen {
29249 
29250 ChromeRendererSchedulerState::ChromeRendererSchedulerState() = default;
29251 ChromeRendererSchedulerState::~ChromeRendererSchedulerState() = default;
29252 ChromeRendererSchedulerState::ChromeRendererSchedulerState(const ChromeRendererSchedulerState&) = default;
29253 ChromeRendererSchedulerState& ChromeRendererSchedulerState::operator=(const ChromeRendererSchedulerState&) = default;
29254 ChromeRendererSchedulerState::ChromeRendererSchedulerState(ChromeRendererSchedulerState&&) noexcept = default;
29255 ChromeRendererSchedulerState& ChromeRendererSchedulerState::operator=(ChromeRendererSchedulerState&&) = default;
29256 
operator ==(const ChromeRendererSchedulerState & other) const29257 bool ChromeRendererSchedulerState::operator==(const ChromeRendererSchedulerState& other) const {
29258   return unknown_fields_ == other.unknown_fields_
29259    && rail_mode_ == other.rail_mode_
29260    && is_backgrounded_ == other.is_backgrounded_
29261    && is_hidden_ == other.is_hidden_;
29262 }
29263 
ParseFromArray(const void * raw,size_t size)29264 bool ChromeRendererSchedulerState::ParseFromArray(const void* raw, size_t size) {
29265   unknown_fields_.clear();
29266   bool packed_error = false;
29267 
29268   ::protozero::ProtoDecoder dec(raw, size);
29269   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
29270     if (field.id() < _has_field_.size()) {
29271       _has_field_.set(field.id());
29272     }
29273     switch (field.id()) {
29274       case 1 /* rail_mode */:
29275         field.get(&rail_mode_);
29276         break;
29277       case 2 /* is_backgrounded */:
29278         field.get(&is_backgrounded_);
29279         break;
29280       case 3 /* is_hidden */:
29281         field.get(&is_hidden_);
29282         break;
29283       default:
29284         field.SerializeAndAppendTo(&unknown_fields_);
29285         break;
29286     }
29287   }
29288   return !packed_error && !dec.bytes_left();
29289 }
29290 
SerializeAsString() const29291 std::string ChromeRendererSchedulerState::SerializeAsString() const {
29292   ::protozero::HeapBuffered<::protozero::Message> msg;
29293   Serialize(msg.get());
29294   return msg.SerializeAsString();
29295 }
29296 
SerializeAsArray() const29297 std::vector<uint8_t> ChromeRendererSchedulerState::SerializeAsArray() const {
29298   ::protozero::HeapBuffered<::protozero::Message> msg;
29299   Serialize(msg.get());
29300   return msg.SerializeAsArray();
29301 }
29302 
Serialize(::protozero::Message * msg) const29303 void ChromeRendererSchedulerState::Serialize(::protozero::Message* msg) const {
29304   // Field 1: rail_mode
29305   if (_has_field_[1]) {
29306     msg->AppendVarInt(1, rail_mode_);
29307   }
29308 
29309   // Field 2: is_backgrounded
29310   if (_has_field_[2]) {
29311     msg->AppendTinyVarInt(2, is_backgrounded_);
29312   }
29313 
29314   // Field 3: is_hidden
29315   if (_has_field_[3]) {
29316     msg->AppendTinyVarInt(3, is_hidden_);
29317   }
29318 
29319   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
29320 }
29321 
29322 }  // namespace perfetto
29323 }  // namespace protos
29324 }  // namespace gen
29325 #if defined(__GNUC__) || defined(__clang__)
29326 #pragma GCC diagnostic pop
29327 #endif
29328 // gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_thread_descriptor.gen.cc
29329 // gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/chrome_thread_descriptor.gen.h
29330 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
29331 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_THREAD_DESCRIPTOR_PROTO_CPP_H_
29332 #define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_THREAD_DESCRIPTOR_PROTO_CPP_H_
29333 
29334 #include <stdint.h>
29335 #include <bitset>
29336 #include <vector>
29337 #include <string>
29338 #include <type_traits>
29339 
29340 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
29341 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
29342 // gen_amalgamated expanded: #include "perfetto/base/export.h"
29343 
29344 namespace perfetto {
29345 namespace protos {
29346 namespace gen {
29347 class ChromeThreadDescriptor;
29348 enum ChromeThreadDescriptor_ThreadType : int;
29349 }  // namespace perfetto
29350 }  // namespace protos
29351 }  // namespace gen
29352 
29353 namespace protozero {
29354 class Message;
29355 }  // namespace protozero
29356 
29357 namespace perfetto {
29358 namespace protos {
29359 namespace gen {
29360 enum ChromeThreadDescriptor_ThreadType : int {
29361   ChromeThreadDescriptor_ThreadType_THREAD_UNSPECIFIED = 0,
29362   ChromeThreadDescriptor_ThreadType_THREAD_MAIN = 1,
29363   ChromeThreadDescriptor_ThreadType_THREAD_IO = 2,
29364   ChromeThreadDescriptor_ThreadType_THREAD_POOL_BG_WORKER = 3,
29365   ChromeThreadDescriptor_ThreadType_THREAD_POOL_FG_WORKER = 4,
29366   ChromeThreadDescriptor_ThreadType_THREAD_POOL_FG_BLOCKING = 5,
29367   ChromeThreadDescriptor_ThreadType_THREAD_POOL_BG_BLOCKING = 6,
29368   ChromeThreadDescriptor_ThreadType_THREAD_POOL_SERVICE = 7,
29369   ChromeThreadDescriptor_ThreadType_THREAD_COMPOSITOR = 8,
29370   ChromeThreadDescriptor_ThreadType_THREAD_VIZ_COMPOSITOR = 9,
29371   ChromeThreadDescriptor_ThreadType_THREAD_COMPOSITOR_WORKER = 10,
29372   ChromeThreadDescriptor_ThreadType_THREAD_SERVICE_WORKER = 11,
29373   ChromeThreadDescriptor_ThreadType_THREAD_NETWORK_SERVICE = 12,
29374   ChromeThreadDescriptor_ThreadType_THREAD_CHILD_IO = 13,
29375   ChromeThreadDescriptor_ThreadType_THREAD_BROWSER_IO = 14,
29376   ChromeThreadDescriptor_ThreadType_THREAD_BROWSER_MAIN = 15,
29377   ChromeThreadDescriptor_ThreadType_THREAD_RENDERER_MAIN = 16,
29378   ChromeThreadDescriptor_ThreadType_THREAD_UTILITY_MAIN = 17,
29379   ChromeThreadDescriptor_ThreadType_THREAD_GPU_MAIN = 18,
29380   ChromeThreadDescriptor_ThreadType_THREAD_CACHE_BLOCKFILE = 19,
29381   ChromeThreadDescriptor_ThreadType_THREAD_MEDIA = 20,
29382   ChromeThreadDescriptor_ThreadType_THREAD_AUDIO_OUTPUTDEVICE = 21,
29383   ChromeThreadDescriptor_ThreadType_THREAD_AUDIO_INPUTDEVICE = 22,
29384   ChromeThreadDescriptor_ThreadType_THREAD_GPU_MEMORY = 23,
29385   ChromeThreadDescriptor_ThreadType_THREAD_GPU_VSYNC = 24,
29386   ChromeThreadDescriptor_ThreadType_THREAD_DXA_VIDEODECODER = 25,
29387   ChromeThreadDescriptor_ThreadType_THREAD_BROWSER_WATCHDOG = 26,
29388   ChromeThreadDescriptor_ThreadType_THREAD_WEBRTC_NETWORK = 27,
29389   ChromeThreadDescriptor_ThreadType_THREAD_WINDOW_OWNER = 28,
29390   ChromeThreadDescriptor_ThreadType_THREAD_WEBRTC_SIGNALING = 29,
29391   ChromeThreadDescriptor_ThreadType_THREAD_WEBRTC_WORKER = 30,
29392   ChromeThreadDescriptor_ThreadType_THREAD_PPAPI_MAIN = 31,
29393   ChromeThreadDescriptor_ThreadType_THREAD_GPU_WATCHDOG = 32,
29394   ChromeThreadDescriptor_ThreadType_THREAD_SWAPPER = 33,
29395   ChromeThreadDescriptor_ThreadType_THREAD_GAMEPAD_POLLING = 34,
29396   ChromeThreadDescriptor_ThreadType_THREAD_WEBCRYPTO = 35,
29397   ChromeThreadDescriptor_ThreadType_THREAD_DATABASE = 36,
29398   ChromeThreadDescriptor_ThreadType_THREAD_PROXYRESOLVER = 37,
29399   ChromeThreadDescriptor_ThreadType_THREAD_DEVTOOLSADB = 38,
29400   ChromeThreadDescriptor_ThreadType_THREAD_NETWORKCONFIGWATCHER = 39,
29401   ChromeThreadDescriptor_ThreadType_THREAD_WASAPI_RENDER = 40,
29402   ChromeThreadDescriptor_ThreadType_THREAD_LOADER_LOCK_SAMPLER = 41,
29403   ChromeThreadDescriptor_ThreadType_THREAD_MEMORY_INFRA = 50,
29404   ChromeThreadDescriptor_ThreadType_THREAD_SAMPLING_PROFILER = 51,
29405 };
29406 
29407 class PERFETTO_EXPORT ChromeThreadDescriptor : public ::protozero::CppMessageObj {
29408  public:
29409   using ThreadType = ChromeThreadDescriptor_ThreadType;
29410   static constexpr auto THREAD_UNSPECIFIED = ChromeThreadDescriptor_ThreadType_THREAD_UNSPECIFIED;
29411   static constexpr auto THREAD_MAIN = ChromeThreadDescriptor_ThreadType_THREAD_MAIN;
29412   static constexpr auto THREAD_IO = ChromeThreadDescriptor_ThreadType_THREAD_IO;
29413   static constexpr auto THREAD_POOL_BG_WORKER = ChromeThreadDescriptor_ThreadType_THREAD_POOL_BG_WORKER;
29414   static constexpr auto THREAD_POOL_FG_WORKER = ChromeThreadDescriptor_ThreadType_THREAD_POOL_FG_WORKER;
29415   static constexpr auto THREAD_POOL_FG_BLOCKING = ChromeThreadDescriptor_ThreadType_THREAD_POOL_FG_BLOCKING;
29416   static constexpr auto THREAD_POOL_BG_BLOCKING = ChromeThreadDescriptor_ThreadType_THREAD_POOL_BG_BLOCKING;
29417   static constexpr auto THREAD_POOL_SERVICE = ChromeThreadDescriptor_ThreadType_THREAD_POOL_SERVICE;
29418   static constexpr auto THREAD_COMPOSITOR = ChromeThreadDescriptor_ThreadType_THREAD_COMPOSITOR;
29419   static constexpr auto THREAD_VIZ_COMPOSITOR = ChromeThreadDescriptor_ThreadType_THREAD_VIZ_COMPOSITOR;
29420   static constexpr auto THREAD_COMPOSITOR_WORKER = ChromeThreadDescriptor_ThreadType_THREAD_COMPOSITOR_WORKER;
29421   static constexpr auto THREAD_SERVICE_WORKER = ChromeThreadDescriptor_ThreadType_THREAD_SERVICE_WORKER;
29422   static constexpr auto THREAD_NETWORK_SERVICE = ChromeThreadDescriptor_ThreadType_THREAD_NETWORK_SERVICE;
29423   static constexpr auto THREAD_CHILD_IO = ChromeThreadDescriptor_ThreadType_THREAD_CHILD_IO;
29424   static constexpr auto THREAD_BROWSER_IO = ChromeThreadDescriptor_ThreadType_THREAD_BROWSER_IO;
29425   static constexpr auto THREAD_BROWSER_MAIN = ChromeThreadDescriptor_ThreadType_THREAD_BROWSER_MAIN;
29426   static constexpr auto THREAD_RENDERER_MAIN = ChromeThreadDescriptor_ThreadType_THREAD_RENDERER_MAIN;
29427   static constexpr auto THREAD_UTILITY_MAIN = ChromeThreadDescriptor_ThreadType_THREAD_UTILITY_MAIN;
29428   static constexpr auto THREAD_GPU_MAIN = ChromeThreadDescriptor_ThreadType_THREAD_GPU_MAIN;
29429   static constexpr auto THREAD_CACHE_BLOCKFILE = ChromeThreadDescriptor_ThreadType_THREAD_CACHE_BLOCKFILE;
29430   static constexpr auto THREAD_MEDIA = ChromeThreadDescriptor_ThreadType_THREAD_MEDIA;
29431   static constexpr auto THREAD_AUDIO_OUTPUTDEVICE = ChromeThreadDescriptor_ThreadType_THREAD_AUDIO_OUTPUTDEVICE;
29432   static constexpr auto THREAD_AUDIO_INPUTDEVICE = ChromeThreadDescriptor_ThreadType_THREAD_AUDIO_INPUTDEVICE;
29433   static constexpr auto THREAD_GPU_MEMORY = ChromeThreadDescriptor_ThreadType_THREAD_GPU_MEMORY;
29434   static constexpr auto THREAD_GPU_VSYNC = ChromeThreadDescriptor_ThreadType_THREAD_GPU_VSYNC;
29435   static constexpr auto THREAD_DXA_VIDEODECODER = ChromeThreadDescriptor_ThreadType_THREAD_DXA_VIDEODECODER;
29436   static constexpr auto THREAD_BROWSER_WATCHDOG = ChromeThreadDescriptor_ThreadType_THREAD_BROWSER_WATCHDOG;
29437   static constexpr auto THREAD_WEBRTC_NETWORK = ChromeThreadDescriptor_ThreadType_THREAD_WEBRTC_NETWORK;
29438   static constexpr auto THREAD_WINDOW_OWNER = ChromeThreadDescriptor_ThreadType_THREAD_WINDOW_OWNER;
29439   static constexpr auto THREAD_WEBRTC_SIGNALING = ChromeThreadDescriptor_ThreadType_THREAD_WEBRTC_SIGNALING;
29440   static constexpr auto THREAD_WEBRTC_WORKER = ChromeThreadDescriptor_ThreadType_THREAD_WEBRTC_WORKER;
29441   static constexpr auto THREAD_PPAPI_MAIN = ChromeThreadDescriptor_ThreadType_THREAD_PPAPI_MAIN;
29442   static constexpr auto THREAD_GPU_WATCHDOG = ChromeThreadDescriptor_ThreadType_THREAD_GPU_WATCHDOG;
29443   static constexpr auto THREAD_SWAPPER = ChromeThreadDescriptor_ThreadType_THREAD_SWAPPER;
29444   static constexpr auto THREAD_GAMEPAD_POLLING = ChromeThreadDescriptor_ThreadType_THREAD_GAMEPAD_POLLING;
29445   static constexpr auto THREAD_WEBCRYPTO = ChromeThreadDescriptor_ThreadType_THREAD_WEBCRYPTO;
29446   static constexpr auto THREAD_DATABASE = ChromeThreadDescriptor_ThreadType_THREAD_DATABASE;
29447   static constexpr auto THREAD_PROXYRESOLVER = ChromeThreadDescriptor_ThreadType_THREAD_PROXYRESOLVER;
29448   static constexpr auto THREAD_DEVTOOLSADB = ChromeThreadDescriptor_ThreadType_THREAD_DEVTOOLSADB;
29449   static constexpr auto THREAD_NETWORKCONFIGWATCHER = ChromeThreadDescriptor_ThreadType_THREAD_NETWORKCONFIGWATCHER;
29450   static constexpr auto THREAD_WASAPI_RENDER = ChromeThreadDescriptor_ThreadType_THREAD_WASAPI_RENDER;
29451   static constexpr auto THREAD_LOADER_LOCK_SAMPLER = ChromeThreadDescriptor_ThreadType_THREAD_LOADER_LOCK_SAMPLER;
29452   static constexpr auto THREAD_MEMORY_INFRA = ChromeThreadDescriptor_ThreadType_THREAD_MEMORY_INFRA;
29453   static constexpr auto THREAD_SAMPLING_PROFILER = ChromeThreadDescriptor_ThreadType_THREAD_SAMPLING_PROFILER;
29454   static constexpr auto ThreadType_MIN = ChromeThreadDescriptor_ThreadType_THREAD_UNSPECIFIED;
29455   static constexpr auto ThreadType_MAX = ChromeThreadDescriptor_ThreadType_THREAD_SAMPLING_PROFILER;
29456   enum FieldNumbers {
29457     kThreadTypeFieldNumber = 1,
29458     kLegacySortIndexFieldNumber = 2,
29459   };
29460 
29461   ChromeThreadDescriptor();
29462   ~ChromeThreadDescriptor() override;
29463   ChromeThreadDescriptor(ChromeThreadDescriptor&&) noexcept;
29464   ChromeThreadDescriptor& operator=(ChromeThreadDescriptor&&);
29465   ChromeThreadDescriptor(const ChromeThreadDescriptor&);
29466   ChromeThreadDescriptor& operator=(const ChromeThreadDescriptor&);
29467   bool operator==(const ChromeThreadDescriptor&) const;
operator !=(const ChromeThreadDescriptor & other) const29468   bool operator!=(const ChromeThreadDescriptor& other) const { return !(*this == other); }
29469 
29470   bool ParseFromArray(const void*, size_t) override;
29471   std::string SerializeAsString() const override;
29472   std::vector<uint8_t> SerializeAsArray() const override;
29473   void Serialize(::protozero::Message*) const;
29474 
has_thread_type() const29475   bool has_thread_type() const { return _has_field_[1]; }
thread_type() const29476   ChromeThreadDescriptor_ThreadType thread_type() const { return thread_type_; }
set_thread_type(ChromeThreadDescriptor_ThreadType value)29477   void set_thread_type(ChromeThreadDescriptor_ThreadType value) { thread_type_ = value; _has_field_.set(1); }
29478 
has_legacy_sort_index() const29479   bool has_legacy_sort_index() const { return _has_field_[2]; }
legacy_sort_index() const29480   int32_t legacy_sort_index() const { return legacy_sort_index_; }
set_legacy_sort_index(int32_t value)29481   void set_legacy_sort_index(int32_t value) { legacy_sort_index_ = value; _has_field_.set(2); }
29482 
29483  private:
29484   ChromeThreadDescriptor_ThreadType thread_type_{};
29485   int32_t legacy_sort_index_{};
29486 
29487   // Allows to preserve unknown protobuf fields for compatibility
29488   // with future versions of .proto files.
29489   std::string unknown_fields_;
29490 
29491   std::bitset<3> _has_field_{};
29492 };
29493 
29494 }  // namespace perfetto
29495 }  // namespace protos
29496 }  // namespace gen
29497 
29498 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_THREAD_DESCRIPTOR_PROTO_CPP_H_
29499 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
29500 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
29501 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
29502 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
29503 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
29504 #if defined(__GNUC__) || defined(__clang__)
29505 #pragma GCC diagnostic push
29506 #pragma GCC diagnostic ignored "-Wfloat-equal"
29507 #endif
29508 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_thread_descriptor.gen.h"
29509 
29510 namespace perfetto {
29511 namespace protos {
29512 namespace gen {
29513 
29514 ChromeThreadDescriptor::ChromeThreadDescriptor() = default;
29515 ChromeThreadDescriptor::~ChromeThreadDescriptor() = default;
29516 ChromeThreadDescriptor::ChromeThreadDescriptor(const ChromeThreadDescriptor&) = default;
29517 ChromeThreadDescriptor& ChromeThreadDescriptor::operator=(const ChromeThreadDescriptor&) = default;
29518 ChromeThreadDescriptor::ChromeThreadDescriptor(ChromeThreadDescriptor&&) noexcept = default;
29519 ChromeThreadDescriptor& ChromeThreadDescriptor::operator=(ChromeThreadDescriptor&&) = default;
29520 
operator ==(const ChromeThreadDescriptor & other) const29521 bool ChromeThreadDescriptor::operator==(const ChromeThreadDescriptor& other) const {
29522   return unknown_fields_ == other.unknown_fields_
29523    && thread_type_ == other.thread_type_
29524    && legacy_sort_index_ == other.legacy_sort_index_;
29525 }
29526 
ParseFromArray(const void * raw,size_t size)29527 bool ChromeThreadDescriptor::ParseFromArray(const void* raw, size_t size) {
29528   unknown_fields_.clear();
29529   bool packed_error = false;
29530 
29531   ::protozero::ProtoDecoder dec(raw, size);
29532   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
29533     if (field.id() < _has_field_.size()) {
29534       _has_field_.set(field.id());
29535     }
29536     switch (field.id()) {
29537       case 1 /* thread_type */:
29538         field.get(&thread_type_);
29539         break;
29540       case 2 /* legacy_sort_index */:
29541         field.get(&legacy_sort_index_);
29542         break;
29543       default:
29544         field.SerializeAndAppendTo(&unknown_fields_);
29545         break;
29546     }
29547   }
29548   return !packed_error && !dec.bytes_left();
29549 }
29550 
SerializeAsString() const29551 std::string ChromeThreadDescriptor::SerializeAsString() const {
29552   ::protozero::HeapBuffered<::protozero::Message> msg;
29553   Serialize(msg.get());
29554   return msg.SerializeAsString();
29555 }
29556 
SerializeAsArray() const29557 std::vector<uint8_t> ChromeThreadDescriptor::SerializeAsArray() const {
29558   ::protozero::HeapBuffered<::protozero::Message> msg;
29559   Serialize(msg.get());
29560   return msg.SerializeAsArray();
29561 }
29562 
Serialize(::protozero::Message * msg) const29563 void ChromeThreadDescriptor::Serialize(::protozero::Message* msg) const {
29564   // Field 1: thread_type
29565   if (_has_field_[1]) {
29566     msg->AppendVarInt(1, thread_type_);
29567   }
29568 
29569   // Field 2: legacy_sort_index
29570   if (_has_field_[2]) {
29571     msg->AppendVarInt(2, legacy_sort_index_);
29572   }
29573 
29574   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
29575 }
29576 
29577 }  // namespace perfetto
29578 }  // namespace protos
29579 }  // namespace gen
29580 #if defined(__GNUC__) || defined(__clang__)
29581 #pragma GCC diagnostic pop
29582 #endif
29583 // gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_user_event.gen.cc
29584 // gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/chrome_user_event.gen.h
29585 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
29586 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_USER_EVENT_PROTO_CPP_H_
29587 #define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_USER_EVENT_PROTO_CPP_H_
29588 
29589 #include <stdint.h>
29590 #include <bitset>
29591 #include <vector>
29592 #include <string>
29593 #include <type_traits>
29594 
29595 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
29596 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
29597 // gen_amalgamated expanded: #include "perfetto/base/export.h"
29598 
29599 namespace perfetto {
29600 namespace protos {
29601 namespace gen {
29602 class ChromeUserEvent;
29603 }  // namespace perfetto
29604 }  // namespace protos
29605 }  // namespace gen
29606 
29607 namespace protozero {
29608 class Message;
29609 }  // namespace protozero
29610 
29611 namespace perfetto {
29612 namespace protos {
29613 namespace gen {
29614 
29615 class PERFETTO_EXPORT ChromeUserEvent : public ::protozero::CppMessageObj {
29616  public:
29617   enum FieldNumbers {
29618     kActionFieldNumber = 1,
29619     kActionHashFieldNumber = 2,
29620   };
29621 
29622   ChromeUserEvent();
29623   ~ChromeUserEvent() override;
29624   ChromeUserEvent(ChromeUserEvent&&) noexcept;
29625   ChromeUserEvent& operator=(ChromeUserEvent&&);
29626   ChromeUserEvent(const ChromeUserEvent&);
29627   ChromeUserEvent& operator=(const ChromeUserEvent&);
29628   bool operator==(const ChromeUserEvent&) const;
operator !=(const ChromeUserEvent & other) const29629   bool operator!=(const ChromeUserEvent& other) const { return !(*this == other); }
29630 
29631   bool ParseFromArray(const void*, size_t) override;
29632   std::string SerializeAsString() const override;
29633   std::vector<uint8_t> SerializeAsArray() const override;
29634   void Serialize(::protozero::Message*) const;
29635 
has_action() const29636   bool has_action() const { return _has_field_[1]; }
action() const29637   const std::string& action() const { return action_; }
set_action(const std::string & value)29638   void set_action(const std::string& value) { action_ = value; _has_field_.set(1); }
29639 
has_action_hash() const29640   bool has_action_hash() const { return _has_field_[2]; }
action_hash() const29641   uint64_t action_hash() const { return action_hash_; }
set_action_hash(uint64_t value)29642   void set_action_hash(uint64_t value) { action_hash_ = value; _has_field_.set(2); }
29643 
29644  private:
29645   std::string action_{};
29646   uint64_t action_hash_{};
29647 
29648   // Allows to preserve unknown protobuf fields for compatibility
29649   // with future versions of .proto files.
29650   std::string unknown_fields_;
29651 
29652   std::bitset<3> _has_field_{};
29653 };
29654 
29655 }  // namespace perfetto
29656 }  // namespace protos
29657 }  // namespace gen
29658 
29659 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_USER_EVENT_PROTO_CPP_H_
29660 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
29661 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
29662 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
29663 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
29664 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
29665 #if defined(__GNUC__) || defined(__clang__)
29666 #pragma GCC diagnostic push
29667 #pragma GCC diagnostic ignored "-Wfloat-equal"
29668 #endif
29669 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_user_event.gen.h"
29670 
29671 namespace perfetto {
29672 namespace protos {
29673 namespace gen {
29674 
29675 ChromeUserEvent::ChromeUserEvent() = default;
29676 ChromeUserEvent::~ChromeUserEvent() = default;
29677 ChromeUserEvent::ChromeUserEvent(const ChromeUserEvent&) = default;
29678 ChromeUserEvent& ChromeUserEvent::operator=(const ChromeUserEvent&) = default;
29679 ChromeUserEvent::ChromeUserEvent(ChromeUserEvent&&) noexcept = default;
29680 ChromeUserEvent& ChromeUserEvent::operator=(ChromeUserEvent&&) = default;
29681 
operator ==(const ChromeUserEvent & other) const29682 bool ChromeUserEvent::operator==(const ChromeUserEvent& other) const {
29683   return unknown_fields_ == other.unknown_fields_
29684    && action_ == other.action_
29685    && action_hash_ == other.action_hash_;
29686 }
29687 
ParseFromArray(const void * raw,size_t size)29688 bool ChromeUserEvent::ParseFromArray(const void* raw, size_t size) {
29689   unknown_fields_.clear();
29690   bool packed_error = false;
29691 
29692   ::protozero::ProtoDecoder dec(raw, size);
29693   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
29694     if (field.id() < _has_field_.size()) {
29695       _has_field_.set(field.id());
29696     }
29697     switch (field.id()) {
29698       case 1 /* action */:
29699         field.get(&action_);
29700         break;
29701       case 2 /* action_hash */:
29702         field.get(&action_hash_);
29703         break;
29704       default:
29705         field.SerializeAndAppendTo(&unknown_fields_);
29706         break;
29707     }
29708   }
29709   return !packed_error && !dec.bytes_left();
29710 }
29711 
SerializeAsString() const29712 std::string ChromeUserEvent::SerializeAsString() const {
29713   ::protozero::HeapBuffered<::protozero::Message> msg;
29714   Serialize(msg.get());
29715   return msg.SerializeAsString();
29716 }
29717 
SerializeAsArray() const29718 std::vector<uint8_t> ChromeUserEvent::SerializeAsArray() const {
29719   ::protozero::HeapBuffered<::protozero::Message> msg;
29720   Serialize(msg.get());
29721   return msg.SerializeAsArray();
29722 }
29723 
Serialize(::protozero::Message * msg) const29724 void ChromeUserEvent::Serialize(::protozero::Message* msg) const {
29725   // Field 1: action
29726   if (_has_field_[1]) {
29727     msg->AppendString(1, action_);
29728   }
29729 
29730   // Field 2: action_hash
29731   if (_has_field_[2]) {
29732     msg->AppendVarInt(2, action_hash_);
29733   }
29734 
29735   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
29736 }
29737 
29738 }  // namespace perfetto
29739 }  // namespace protos
29740 }  // namespace gen
29741 #if defined(__GNUC__) || defined(__clang__)
29742 #pragma GCC diagnostic pop
29743 #endif
29744 // gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_window_handle_event_info.gen.cc
29745 // gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/chrome_window_handle_event_info.gen.h
29746 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
29747 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_WINDOW_HANDLE_EVENT_INFO_PROTO_CPP_H_
29748 #define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_WINDOW_HANDLE_EVENT_INFO_PROTO_CPP_H_
29749 
29750 #include <stdint.h>
29751 #include <bitset>
29752 #include <vector>
29753 #include <string>
29754 #include <type_traits>
29755 
29756 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
29757 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
29758 // gen_amalgamated expanded: #include "perfetto/base/export.h"
29759 
29760 namespace perfetto {
29761 namespace protos {
29762 namespace gen {
29763 class ChromeWindowHandleEventInfo;
29764 }  // namespace perfetto
29765 }  // namespace protos
29766 }  // namespace gen
29767 
29768 namespace protozero {
29769 class Message;
29770 }  // namespace protozero
29771 
29772 namespace perfetto {
29773 namespace protos {
29774 namespace gen {
29775 
29776 class PERFETTO_EXPORT ChromeWindowHandleEventInfo : public ::protozero::CppMessageObj {
29777  public:
29778   enum FieldNumbers {
29779     kDpiFieldNumber = 1,
29780     kMessageIdFieldNumber = 2,
29781     kHwndPtrFieldNumber = 3,
29782   };
29783 
29784   ChromeWindowHandleEventInfo();
29785   ~ChromeWindowHandleEventInfo() override;
29786   ChromeWindowHandleEventInfo(ChromeWindowHandleEventInfo&&) noexcept;
29787   ChromeWindowHandleEventInfo& operator=(ChromeWindowHandleEventInfo&&);
29788   ChromeWindowHandleEventInfo(const ChromeWindowHandleEventInfo&);
29789   ChromeWindowHandleEventInfo& operator=(const ChromeWindowHandleEventInfo&);
29790   bool operator==(const ChromeWindowHandleEventInfo&) const;
operator !=(const ChromeWindowHandleEventInfo & other) const29791   bool operator!=(const ChromeWindowHandleEventInfo& other) const { return !(*this == other); }
29792 
29793   bool ParseFromArray(const void*, size_t) override;
29794   std::string SerializeAsString() const override;
29795   std::vector<uint8_t> SerializeAsArray() const override;
29796   void Serialize(::protozero::Message*) const;
29797 
has_dpi() const29798   bool has_dpi() const { return _has_field_[1]; }
dpi() const29799   uint32_t dpi() const { return dpi_; }
set_dpi(uint32_t value)29800   void set_dpi(uint32_t value) { dpi_ = value; _has_field_.set(1); }
29801 
has_message_id() const29802   bool has_message_id() const { return _has_field_[2]; }
message_id() const29803   uint32_t message_id() const { return message_id_; }
set_message_id(uint32_t value)29804   void set_message_id(uint32_t value) { message_id_ = value; _has_field_.set(2); }
29805 
has_hwnd_ptr() const29806   bool has_hwnd_ptr() const { return _has_field_[3]; }
hwnd_ptr() const29807   uint64_t hwnd_ptr() const { return hwnd_ptr_; }
set_hwnd_ptr(uint64_t value)29808   void set_hwnd_ptr(uint64_t value) { hwnd_ptr_ = value; _has_field_.set(3); }
29809 
29810  private:
29811   uint32_t dpi_{};
29812   uint32_t message_id_{};
29813   uint64_t hwnd_ptr_{};
29814 
29815   // Allows to preserve unknown protobuf fields for compatibility
29816   // with future versions of .proto files.
29817   std::string unknown_fields_;
29818 
29819   std::bitset<4> _has_field_{};
29820 };
29821 
29822 }  // namespace perfetto
29823 }  // namespace protos
29824 }  // namespace gen
29825 
29826 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_CHROME_WINDOW_HANDLE_EVENT_INFO_PROTO_CPP_H_
29827 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
29828 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
29829 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
29830 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
29831 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
29832 #if defined(__GNUC__) || defined(__clang__)
29833 #pragma GCC diagnostic push
29834 #pragma GCC diagnostic ignored "-Wfloat-equal"
29835 #endif
29836 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_window_handle_event_info.gen.h"
29837 
29838 namespace perfetto {
29839 namespace protos {
29840 namespace gen {
29841 
29842 ChromeWindowHandleEventInfo::ChromeWindowHandleEventInfo() = default;
29843 ChromeWindowHandleEventInfo::~ChromeWindowHandleEventInfo() = default;
29844 ChromeWindowHandleEventInfo::ChromeWindowHandleEventInfo(const ChromeWindowHandleEventInfo&) = default;
29845 ChromeWindowHandleEventInfo& ChromeWindowHandleEventInfo::operator=(const ChromeWindowHandleEventInfo&) = default;
29846 ChromeWindowHandleEventInfo::ChromeWindowHandleEventInfo(ChromeWindowHandleEventInfo&&) noexcept = default;
29847 ChromeWindowHandleEventInfo& ChromeWindowHandleEventInfo::operator=(ChromeWindowHandleEventInfo&&) = default;
29848 
operator ==(const ChromeWindowHandleEventInfo & other) const29849 bool ChromeWindowHandleEventInfo::operator==(const ChromeWindowHandleEventInfo& other) const {
29850   return unknown_fields_ == other.unknown_fields_
29851    && dpi_ == other.dpi_
29852    && message_id_ == other.message_id_
29853    && hwnd_ptr_ == other.hwnd_ptr_;
29854 }
29855 
ParseFromArray(const void * raw,size_t size)29856 bool ChromeWindowHandleEventInfo::ParseFromArray(const void* raw, size_t size) {
29857   unknown_fields_.clear();
29858   bool packed_error = false;
29859 
29860   ::protozero::ProtoDecoder dec(raw, size);
29861   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
29862     if (field.id() < _has_field_.size()) {
29863       _has_field_.set(field.id());
29864     }
29865     switch (field.id()) {
29866       case 1 /* dpi */:
29867         field.get(&dpi_);
29868         break;
29869       case 2 /* message_id */:
29870         field.get(&message_id_);
29871         break;
29872       case 3 /* hwnd_ptr */:
29873         field.get(&hwnd_ptr_);
29874         break;
29875       default:
29876         field.SerializeAndAppendTo(&unknown_fields_);
29877         break;
29878     }
29879   }
29880   return !packed_error && !dec.bytes_left();
29881 }
29882 
SerializeAsString() const29883 std::string ChromeWindowHandleEventInfo::SerializeAsString() const {
29884   ::protozero::HeapBuffered<::protozero::Message> msg;
29885   Serialize(msg.get());
29886   return msg.SerializeAsString();
29887 }
29888 
SerializeAsArray() const29889 std::vector<uint8_t> ChromeWindowHandleEventInfo::SerializeAsArray() const {
29890   ::protozero::HeapBuffered<::protozero::Message> msg;
29891   Serialize(msg.get());
29892   return msg.SerializeAsArray();
29893 }
29894 
Serialize(::protozero::Message * msg) const29895 void ChromeWindowHandleEventInfo::Serialize(::protozero::Message* msg) const {
29896   // Field 1: dpi
29897   if (_has_field_[1]) {
29898     msg->AppendVarInt(1, dpi_);
29899   }
29900 
29901   // Field 2: message_id
29902   if (_has_field_[2]) {
29903     msg->AppendVarInt(2, message_id_);
29904   }
29905 
29906   // Field 3: hwnd_ptr
29907   if (_has_field_[3]) {
29908     msg->AppendFixed(3, hwnd_ptr_);
29909   }
29910 
29911   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
29912 }
29913 
29914 }  // namespace perfetto
29915 }  // namespace protos
29916 }  // namespace gen
29917 #if defined(__GNUC__) || defined(__clang__)
29918 #pragma GCC diagnostic pop
29919 #endif
29920 // gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/counter_descriptor.gen.cc
29921 // gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/counter_descriptor.gen.h
29922 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
29923 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_COUNTER_DESCRIPTOR_PROTO_CPP_H_
29924 #define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_COUNTER_DESCRIPTOR_PROTO_CPP_H_
29925 
29926 #include <stdint.h>
29927 #include <bitset>
29928 #include <vector>
29929 #include <string>
29930 #include <type_traits>
29931 
29932 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
29933 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
29934 // gen_amalgamated expanded: #include "perfetto/base/export.h"
29935 
29936 namespace perfetto {
29937 namespace protos {
29938 namespace gen {
29939 class CounterDescriptor;
29940 enum CounterDescriptor_BuiltinCounterType : int;
29941 enum CounterDescriptor_Unit : int;
29942 }  // namespace perfetto
29943 }  // namespace protos
29944 }  // namespace gen
29945 
29946 namespace protozero {
29947 class Message;
29948 }  // namespace protozero
29949 
29950 namespace perfetto {
29951 namespace protos {
29952 namespace gen {
29953 enum CounterDescriptor_BuiltinCounterType : int {
29954   CounterDescriptor_BuiltinCounterType_COUNTER_UNSPECIFIED = 0,
29955   CounterDescriptor_BuiltinCounterType_COUNTER_THREAD_TIME_NS = 1,
29956   CounterDescriptor_BuiltinCounterType_COUNTER_THREAD_INSTRUCTION_COUNT = 2,
29957 };
29958 enum CounterDescriptor_Unit : int {
29959   CounterDescriptor_Unit_UNIT_UNSPECIFIED = 0,
29960   CounterDescriptor_Unit_UNIT_TIME_NS = 1,
29961   CounterDescriptor_Unit_UNIT_COUNT = 2,
29962   CounterDescriptor_Unit_UNIT_SIZE_BYTES = 3,
29963 };
29964 
29965 class PERFETTO_EXPORT CounterDescriptor : public ::protozero::CppMessageObj {
29966  public:
29967   using BuiltinCounterType = CounterDescriptor_BuiltinCounterType;
29968   static constexpr auto COUNTER_UNSPECIFIED = CounterDescriptor_BuiltinCounterType_COUNTER_UNSPECIFIED;
29969   static constexpr auto COUNTER_THREAD_TIME_NS = CounterDescriptor_BuiltinCounterType_COUNTER_THREAD_TIME_NS;
29970   static constexpr auto COUNTER_THREAD_INSTRUCTION_COUNT = CounterDescriptor_BuiltinCounterType_COUNTER_THREAD_INSTRUCTION_COUNT;
29971   static constexpr auto BuiltinCounterType_MIN = CounterDescriptor_BuiltinCounterType_COUNTER_UNSPECIFIED;
29972   static constexpr auto BuiltinCounterType_MAX = CounterDescriptor_BuiltinCounterType_COUNTER_THREAD_INSTRUCTION_COUNT;
29973   using Unit = CounterDescriptor_Unit;
29974   static constexpr auto UNIT_UNSPECIFIED = CounterDescriptor_Unit_UNIT_UNSPECIFIED;
29975   static constexpr auto UNIT_TIME_NS = CounterDescriptor_Unit_UNIT_TIME_NS;
29976   static constexpr auto UNIT_COUNT = CounterDescriptor_Unit_UNIT_COUNT;
29977   static constexpr auto UNIT_SIZE_BYTES = CounterDescriptor_Unit_UNIT_SIZE_BYTES;
29978   static constexpr auto Unit_MIN = CounterDescriptor_Unit_UNIT_UNSPECIFIED;
29979   static constexpr auto Unit_MAX = CounterDescriptor_Unit_UNIT_SIZE_BYTES;
29980   enum FieldNumbers {
29981     kTypeFieldNumber = 1,
29982     kCategoriesFieldNumber = 2,
29983     kUnitFieldNumber = 3,
29984     kUnitNameFieldNumber = 6,
29985     kUnitMultiplierFieldNumber = 4,
29986     kIsIncrementalFieldNumber = 5,
29987   };
29988 
29989   CounterDescriptor();
29990   ~CounterDescriptor() override;
29991   CounterDescriptor(CounterDescriptor&&) noexcept;
29992   CounterDescriptor& operator=(CounterDescriptor&&);
29993   CounterDescriptor(const CounterDescriptor&);
29994   CounterDescriptor& operator=(const CounterDescriptor&);
29995   bool operator==(const CounterDescriptor&) const;
operator !=(const CounterDescriptor & other) const29996   bool operator!=(const CounterDescriptor& other) const { return !(*this == other); }
29997 
29998   bool ParseFromArray(const void*, size_t) override;
29999   std::string SerializeAsString() const override;
30000   std::vector<uint8_t> SerializeAsArray() const override;
30001   void Serialize(::protozero::Message*) const;
30002 
has_type() const30003   bool has_type() const { return _has_field_[1]; }
type() const30004   CounterDescriptor_BuiltinCounterType type() const { return type_; }
set_type(CounterDescriptor_BuiltinCounterType value)30005   void set_type(CounterDescriptor_BuiltinCounterType value) { type_ = value; _has_field_.set(1); }
30006 
categories() const30007   const std::vector<std::string>& categories() const { return categories_; }
mutable_categories()30008   std::vector<std::string>* mutable_categories() { return &categories_; }
categories_size() const30009   int categories_size() const { return static_cast<int>(categories_.size()); }
clear_categories()30010   void clear_categories() { categories_.clear(); }
add_categories(std::string value)30011   void add_categories(std::string value) { categories_.emplace_back(value); }
add_categories()30012   std::string* add_categories() { categories_.emplace_back(); return &categories_.back(); }
30013 
has_unit() const30014   bool has_unit() const { return _has_field_[3]; }
unit() const30015   CounterDescriptor_Unit unit() const { return unit_; }
set_unit(CounterDescriptor_Unit value)30016   void set_unit(CounterDescriptor_Unit value) { unit_ = value; _has_field_.set(3); }
30017 
has_unit_name() const30018   bool has_unit_name() const { return _has_field_[6]; }
unit_name() const30019   const std::string& unit_name() const { return unit_name_; }
set_unit_name(const std::string & value)30020   void set_unit_name(const std::string& value) { unit_name_ = value; _has_field_.set(6); }
30021 
has_unit_multiplier() const30022   bool has_unit_multiplier() const { return _has_field_[4]; }
unit_multiplier() const30023   int64_t unit_multiplier() const { return unit_multiplier_; }
set_unit_multiplier(int64_t value)30024   void set_unit_multiplier(int64_t value) { unit_multiplier_ = value; _has_field_.set(4); }
30025 
has_is_incremental() const30026   bool has_is_incremental() const { return _has_field_[5]; }
is_incremental() const30027   bool is_incremental() const { return is_incremental_; }
set_is_incremental(bool value)30028   void set_is_incremental(bool value) { is_incremental_ = value; _has_field_.set(5); }
30029 
30030  private:
30031   CounterDescriptor_BuiltinCounterType type_{};
30032   std::vector<std::string> categories_;
30033   CounterDescriptor_Unit unit_{};
30034   std::string unit_name_{};
30035   int64_t unit_multiplier_{};
30036   bool is_incremental_{};
30037 
30038   // Allows to preserve unknown protobuf fields for compatibility
30039   // with future versions of .proto files.
30040   std::string unknown_fields_;
30041 
30042   std::bitset<7> _has_field_{};
30043 };
30044 
30045 }  // namespace perfetto
30046 }  // namespace protos
30047 }  // namespace gen
30048 
30049 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_COUNTER_DESCRIPTOR_PROTO_CPP_H_
30050 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
30051 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
30052 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
30053 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
30054 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
30055 #if defined(__GNUC__) || defined(__clang__)
30056 #pragma GCC diagnostic push
30057 #pragma GCC diagnostic ignored "-Wfloat-equal"
30058 #endif
30059 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/counter_descriptor.gen.h"
30060 
30061 namespace perfetto {
30062 namespace protos {
30063 namespace gen {
30064 
30065 CounterDescriptor::CounterDescriptor() = default;
30066 CounterDescriptor::~CounterDescriptor() = default;
30067 CounterDescriptor::CounterDescriptor(const CounterDescriptor&) = default;
30068 CounterDescriptor& CounterDescriptor::operator=(const CounterDescriptor&) = default;
30069 CounterDescriptor::CounterDescriptor(CounterDescriptor&&) noexcept = default;
30070 CounterDescriptor& CounterDescriptor::operator=(CounterDescriptor&&) = default;
30071 
operator ==(const CounterDescriptor & other) const30072 bool CounterDescriptor::operator==(const CounterDescriptor& other) const {
30073   return unknown_fields_ == other.unknown_fields_
30074    && type_ == other.type_
30075    && categories_ == other.categories_
30076    && unit_ == other.unit_
30077    && unit_name_ == other.unit_name_
30078    && unit_multiplier_ == other.unit_multiplier_
30079    && is_incremental_ == other.is_incremental_;
30080 }
30081 
ParseFromArray(const void * raw,size_t size)30082 bool CounterDescriptor::ParseFromArray(const void* raw, size_t size) {
30083   categories_.clear();
30084   unknown_fields_.clear();
30085   bool packed_error = false;
30086 
30087   ::protozero::ProtoDecoder dec(raw, size);
30088   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
30089     if (field.id() < _has_field_.size()) {
30090       _has_field_.set(field.id());
30091     }
30092     switch (field.id()) {
30093       case 1 /* type */:
30094         field.get(&type_);
30095         break;
30096       case 2 /* categories */:
30097         categories_.emplace_back();
30098         field.get(&categories_.back());
30099         break;
30100       case 3 /* unit */:
30101         field.get(&unit_);
30102         break;
30103       case 6 /* unit_name */:
30104         field.get(&unit_name_);
30105         break;
30106       case 4 /* unit_multiplier */:
30107         field.get(&unit_multiplier_);
30108         break;
30109       case 5 /* is_incremental */:
30110         field.get(&is_incremental_);
30111         break;
30112       default:
30113         field.SerializeAndAppendTo(&unknown_fields_);
30114         break;
30115     }
30116   }
30117   return !packed_error && !dec.bytes_left();
30118 }
30119 
SerializeAsString() const30120 std::string CounterDescriptor::SerializeAsString() const {
30121   ::protozero::HeapBuffered<::protozero::Message> msg;
30122   Serialize(msg.get());
30123   return msg.SerializeAsString();
30124 }
30125 
SerializeAsArray() const30126 std::vector<uint8_t> CounterDescriptor::SerializeAsArray() const {
30127   ::protozero::HeapBuffered<::protozero::Message> msg;
30128   Serialize(msg.get());
30129   return msg.SerializeAsArray();
30130 }
30131 
Serialize(::protozero::Message * msg) const30132 void CounterDescriptor::Serialize(::protozero::Message* msg) const {
30133   // Field 1: type
30134   if (_has_field_[1]) {
30135     msg->AppendVarInt(1, type_);
30136   }
30137 
30138   // Field 2: categories
30139   for (auto& it : categories_) {
30140     msg->AppendString(2, it);
30141   }
30142 
30143   // Field 3: unit
30144   if (_has_field_[3]) {
30145     msg->AppendVarInt(3, unit_);
30146   }
30147 
30148   // Field 6: unit_name
30149   if (_has_field_[6]) {
30150     msg->AppendString(6, unit_name_);
30151   }
30152 
30153   // Field 4: unit_multiplier
30154   if (_has_field_[4]) {
30155     msg->AppendVarInt(4, unit_multiplier_);
30156   }
30157 
30158   // Field 5: is_incremental
30159   if (_has_field_[5]) {
30160     msg->AppendTinyVarInt(5, is_incremental_);
30161   }
30162 
30163   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
30164 }
30165 
30166 }  // namespace perfetto
30167 }  // namespace protos
30168 }  // namespace gen
30169 #if defined(__GNUC__) || defined(__clang__)
30170 #pragma GCC diagnostic pop
30171 #endif
30172 // gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/debug_annotation.gen.cc
30173 // gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/debug_annotation.gen.h
30174 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
30175 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_DEBUG_ANNOTATION_PROTO_CPP_H_
30176 #define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_DEBUG_ANNOTATION_PROTO_CPP_H_
30177 
30178 #include <stdint.h>
30179 #include <bitset>
30180 #include <vector>
30181 #include <string>
30182 #include <type_traits>
30183 
30184 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
30185 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
30186 // gen_amalgamated expanded: #include "perfetto/base/export.h"
30187 
30188 namespace perfetto {
30189 namespace protos {
30190 namespace gen {
30191 class DebugAnnotationName;
30192 class DebugAnnotation;
30193 class DebugAnnotation_NestedValue;
30194 enum DebugAnnotation_NestedValue_NestedType : int;
30195 }  // namespace perfetto
30196 }  // namespace protos
30197 }  // namespace gen
30198 
30199 namespace protozero {
30200 class Message;
30201 }  // namespace protozero
30202 
30203 namespace perfetto {
30204 namespace protos {
30205 namespace gen {
30206 enum DebugAnnotation_NestedValue_NestedType : int {
30207   DebugAnnotation_NestedValue_NestedType_UNSPECIFIED = 0,
30208   DebugAnnotation_NestedValue_NestedType_DICT = 1,
30209   DebugAnnotation_NestedValue_NestedType_ARRAY = 2,
30210 };
30211 
30212 class PERFETTO_EXPORT DebugAnnotationName : public ::protozero::CppMessageObj {
30213  public:
30214   enum FieldNumbers {
30215     kIidFieldNumber = 1,
30216     kNameFieldNumber = 2,
30217   };
30218 
30219   DebugAnnotationName();
30220   ~DebugAnnotationName() override;
30221   DebugAnnotationName(DebugAnnotationName&&) noexcept;
30222   DebugAnnotationName& operator=(DebugAnnotationName&&);
30223   DebugAnnotationName(const DebugAnnotationName&);
30224   DebugAnnotationName& operator=(const DebugAnnotationName&);
30225   bool operator==(const DebugAnnotationName&) const;
operator !=(const DebugAnnotationName & other) const30226   bool operator!=(const DebugAnnotationName& other) const { return !(*this == other); }
30227 
30228   bool ParseFromArray(const void*, size_t) override;
30229   std::string SerializeAsString() const override;
30230   std::vector<uint8_t> SerializeAsArray() const override;
30231   void Serialize(::protozero::Message*) const;
30232 
has_iid() const30233   bool has_iid() const { return _has_field_[1]; }
iid() const30234   uint64_t iid() const { return iid_; }
set_iid(uint64_t value)30235   void set_iid(uint64_t value) { iid_ = value; _has_field_.set(1); }
30236 
has_name() const30237   bool has_name() const { return _has_field_[2]; }
name() const30238   const std::string& name() const { return name_; }
set_name(const std::string & value)30239   void set_name(const std::string& value) { name_ = value; _has_field_.set(2); }
30240 
30241  private:
30242   uint64_t iid_{};
30243   std::string name_{};
30244 
30245   // Allows to preserve unknown protobuf fields for compatibility
30246   // with future versions of .proto files.
30247   std::string unknown_fields_;
30248 
30249   std::bitset<3> _has_field_{};
30250 };
30251 
30252 
30253 class PERFETTO_EXPORT DebugAnnotation : public ::protozero::CppMessageObj {
30254  public:
30255   using NestedValue = DebugAnnotation_NestedValue;
30256   enum FieldNumbers {
30257     kNameIidFieldNumber = 1,
30258     kNameFieldNumber = 10,
30259     kBoolValueFieldNumber = 2,
30260     kUintValueFieldNumber = 3,
30261     kIntValueFieldNumber = 4,
30262     kDoubleValueFieldNumber = 5,
30263     kStringValueFieldNumber = 6,
30264     kPointerValueFieldNumber = 7,
30265     kNestedValueFieldNumber = 8,
30266     kLegacyJsonValueFieldNumber = 9,
30267     kDictEntriesFieldNumber = 11,
30268     kArrayValuesFieldNumber = 12,
30269   };
30270 
30271   DebugAnnotation();
30272   ~DebugAnnotation() override;
30273   DebugAnnotation(DebugAnnotation&&) noexcept;
30274   DebugAnnotation& operator=(DebugAnnotation&&);
30275   DebugAnnotation(const DebugAnnotation&);
30276   DebugAnnotation& operator=(const DebugAnnotation&);
30277   bool operator==(const DebugAnnotation&) const;
operator !=(const DebugAnnotation & other) const30278   bool operator!=(const DebugAnnotation& other) const { return !(*this == other); }
30279 
30280   bool ParseFromArray(const void*, size_t) override;
30281   std::string SerializeAsString() const override;
30282   std::vector<uint8_t> SerializeAsArray() const override;
30283   void Serialize(::protozero::Message*) const;
30284 
has_name_iid() const30285   bool has_name_iid() const { return _has_field_[1]; }
name_iid() const30286   uint64_t name_iid() const { return name_iid_; }
set_name_iid(uint64_t value)30287   void set_name_iid(uint64_t value) { name_iid_ = value; _has_field_.set(1); }
30288 
has_name() const30289   bool has_name() const { return _has_field_[10]; }
name() const30290   const std::string& name() const { return name_; }
set_name(const std::string & value)30291   void set_name(const std::string& value) { name_ = value; _has_field_.set(10); }
30292 
has_bool_value() const30293   bool has_bool_value() const { return _has_field_[2]; }
bool_value() const30294   bool bool_value() const { return bool_value_; }
set_bool_value(bool value)30295   void set_bool_value(bool value) { bool_value_ = value; _has_field_.set(2); }
30296 
has_uint_value() const30297   bool has_uint_value() const { return _has_field_[3]; }
uint_value() const30298   uint64_t uint_value() const { return uint_value_; }
set_uint_value(uint64_t value)30299   void set_uint_value(uint64_t value) { uint_value_ = value; _has_field_.set(3); }
30300 
has_int_value() const30301   bool has_int_value() const { return _has_field_[4]; }
int_value() const30302   int64_t int_value() const { return int_value_; }
set_int_value(int64_t value)30303   void set_int_value(int64_t value) { int_value_ = value; _has_field_.set(4); }
30304 
has_double_value() const30305   bool has_double_value() const { return _has_field_[5]; }
double_value() const30306   double double_value() const { return double_value_; }
set_double_value(double value)30307   void set_double_value(double value) { double_value_ = value; _has_field_.set(5); }
30308 
has_string_value() const30309   bool has_string_value() const { return _has_field_[6]; }
string_value() const30310   const std::string& string_value() const { return string_value_; }
set_string_value(const std::string & value)30311   void set_string_value(const std::string& value) { string_value_ = value; _has_field_.set(6); }
30312 
has_pointer_value() const30313   bool has_pointer_value() const { return _has_field_[7]; }
pointer_value() const30314   uint64_t pointer_value() const { return pointer_value_; }
set_pointer_value(uint64_t value)30315   void set_pointer_value(uint64_t value) { pointer_value_ = value; _has_field_.set(7); }
30316 
has_nested_value() const30317   bool has_nested_value() const { return _has_field_[8]; }
nested_value() const30318   const DebugAnnotation_NestedValue& nested_value() const { return *nested_value_; }
mutable_nested_value()30319   DebugAnnotation_NestedValue* mutable_nested_value() { _has_field_.set(8); return nested_value_.get(); }
30320 
has_legacy_json_value() const30321   bool has_legacy_json_value() const { return _has_field_[9]; }
legacy_json_value() const30322   const std::string& legacy_json_value() const { return legacy_json_value_; }
set_legacy_json_value(const std::string & value)30323   void set_legacy_json_value(const std::string& value) { legacy_json_value_ = value; _has_field_.set(9); }
30324 
dict_entries() const30325   const std::vector<DebugAnnotation>& dict_entries() const { return dict_entries_; }
mutable_dict_entries()30326   std::vector<DebugAnnotation>* mutable_dict_entries() { return &dict_entries_; }
30327   int dict_entries_size() const;
30328   void clear_dict_entries();
30329   DebugAnnotation* add_dict_entries();
30330 
array_values() const30331   const std::vector<DebugAnnotation>& array_values() const { return array_values_; }
mutable_array_values()30332   std::vector<DebugAnnotation>* mutable_array_values() { return &array_values_; }
30333   int array_values_size() const;
30334   void clear_array_values();
30335   DebugAnnotation* add_array_values();
30336 
30337  private:
30338   uint64_t name_iid_{};
30339   std::string name_{};
30340   bool bool_value_{};
30341   uint64_t uint_value_{};
30342   int64_t int_value_{};
30343   double double_value_{};
30344   std::string string_value_{};
30345   uint64_t pointer_value_{};
30346   ::protozero::CopyablePtr<DebugAnnotation_NestedValue> nested_value_;
30347   std::string legacy_json_value_{};
30348   std::vector<DebugAnnotation> dict_entries_;
30349   std::vector<DebugAnnotation> array_values_;
30350 
30351   // Allows to preserve unknown protobuf fields for compatibility
30352   // with future versions of .proto files.
30353   std::string unknown_fields_;
30354 
30355   std::bitset<13> _has_field_{};
30356 };
30357 
30358 
30359 class PERFETTO_EXPORT DebugAnnotation_NestedValue : public ::protozero::CppMessageObj {
30360  public:
30361   using NestedType = DebugAnnotation_NestedValue_NestedType;
30362   static constexpr auto UNSPECIFIED = DebugAnnotation_NestedValue_NestedType_UNSPECIFIED;
30363   static constexpr auto DICT = DebugAnnotation_NestedValue_NestedType_DICT;
30364   static constexpr auto ARRAY = DebugAnnotation_NestedValue_NestedType_ARRAY;
30365   static constexpr auto NestedType_MIN = DebugAnnotation_NestedValue_NestedType_UNSPECIFIED;
30366   static constexpr auto NestedType_MAX = DebugAnnotation_NestedValue_NestedType_ARRAY;
30367   enum FieldNumbers {
30368     kNestedTypeFieldNumber = 1,
30369     kDictKeysFieldNumber = 2,
30370     kDictValuesFieldNumber = 3,
30371     kArrayValuesFieldNumber = 4,
30372     kIntValueFieldNumber = 5,
30373     kDoubleValueFieldNumber = 6,
30374     kBoolValueFieldNumber = 7,
30375     kStringValueFieldNumber = 8,
30376   };
30377 
30378   DebugAnnotation_NestedValue();
30379   ~DebugAnnotation_NestedValue() override;
30380   DebugAnnotation_NestedValue(DebugAnnotation_NestedValue&&) noexcept;
30381   DebugAnnotation_NestedValue& operator=(DebugAnnotation_NestedValue&&);
30382   DebugAnnotation_NestedValue(const DebugAnnotation_NestedValue&);
30383   DebugAnnotation_NestedValue& operator=(const DebugAnnotation_NestedValue&);
30384   bool operator==(const DebugAnnotation_NestedValue&) const;
operator !=(const DebugAnnotation_NestedValue & other) const30385   bool operator!=(const DebugAnnotation_NestedValue& other) const { return !(*this == other); }
30386 
30387   bool ParseFromArray(const void*, size_t) override;
30388   std::string SerializeAsString() const override;
30389   std::vector<uint8_t> SerializeAsArray() const override;
30390   void Serialize(::protozero::Message*) const;
30391 
has_nested_type() const30392   bool has_nested_type() const { return _has_field_[1]; }
nested_type() const30393   DebugAnnotation_NestedValue_NestedType nested_type() const { return nested_type_; }
set_nested_type(DebugAnnotation_NestedValue_NestedType value)30394   void set_nested_type(DebugAnnotation_NestedValue_NestedType value) { nested_type_ = value; _has_field_.set(1); }
30395 
dict_keys() const30396   const std::vector<std::string>& dict_keys() const { return dict_keys_; }
mutable_dict_keys()30397   std::vector<std::string>* mutable_dict_keys() { return &dict_keys_; }
dict_keys_size() const30398   int dict_keys_size() const { return static_cast<int>(dict_keys_.size()); }
clear_dict_keys()30399   void clear_dict_keys() { dict_keys_.clear(); }
add_dict_keys(std::string value)30400   void add_dict_keys(std::string value) { dict_keys_.emplace_back(value); }
add_dict_keys()30401   std::string* add_dict_keys() { dict_keys_.emplace_back(); return &dict_keys_.back(); }
30402 
dict_values() const30403   const std::vector<DebugAnnotation_NestedValue>& dict_values() const { return dict_values_; }
mutable_dict_values()30404   std::vector<DebugAnnotation_NestedValue>* mutable_dict_values() { return &dict_values_; }
30405   int dict_values_size() const;
30406   void clear_dict_values();
30407   DebugAnnotation_NestedValue* add_dict_values();
30408 
array_values() const30409   const std::vector<DebugAnnotation_NestedValue>& array_values() const { return array_values_; }
mutable_array_values()30410   std::vector<DebugAnnotation_NestedValue>* mutable_array_values() { return &array_values_; }
30411   int array_values_size() const;
30412   void clear_array_values();
30413   DebugAnnotation_NestedValue* add_array_values();
30414 
has_int_value() const30415   bool has_int_value() const { return _has_field_[5]; }
int_value() const30416   int64_t int_value() const { return int_value_; }
set_int_value(int64_t value)30417   void set_int_value(int64_t value) { int_value_ = value; _has_field_.set(5); }
30418 
has_double_value() const30419   bool has_double_value() const { return _has_field_[6]; }
double_value() const30420   double double_value() const { return double_value_; }
set_double_value(double value)30421   void set_double_value(double value) { double_value_ = value; _has_field_.set(6); }
30422 
has_bool_value() const30423   bool has_bool_value() const { return _has_field_[7]; }
bool_value() const30424   bool bool_value() const { return bool_value_; }
set_bool_value(bool value)30425   void set_bool_value(bool value) { bool_value_ = value; _has_field_.set(7); }
30426 
has_string_value() const30427   bool has_string_value() const { return _has_field_[8]; }
string_value() const30428   const std::string& string_value() const { return string_value_; }
set_string_value(const std::string & value)30429   void set_string_value(const std::string& value) { string_value_ = value; _has_field_.set(8); }
30430 
30431  private:
30432   DebugAnnotation_NestedValue_NestedType nested_type_{};
30433   std::vector<std::string> dict_keys_;
30434   std::vector<DebugAnnotation_NestedValue> dict_values_;
30435   std::vector<DebugAnnotation_NestedValue> array_values_;
30436   int64_t int_value_{};
30437   double double_value_{};
30438   bool bool_value_{};
30439   std::string string_value_{};
30440 
30441   // Allows to preserve unknown protobuf fields for compatibility
30442   // with future versions of .proto files.
30443   std::string unknown_fields_;
30444 
30445   std::bitset<9> _has_field_{};
30446 };
30447 
30448 }  // namespace perfetto
30449 }  // namespace protos
30450 }  // namespace gen
30451 
30452 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_DEBUG_ANNOTATION_PROTO_CPP_H_
30453 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
30454 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
30455 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
30456 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
30457 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
30458 #if defined(__GNUC__) || defined(__clang__)
30459 #pragma GCC diagnostic push
30460 #pragma GCC diagnostic ignored "-Wfloat-equal"
30461 #endif
30462 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/debug_annotation.gen.h"
30463 
30464 namespace perfetto {
30465 namespace protos {
30466 namespace gen {
30467 
30468 DebugAnnotationName::DebugAnnotationName() = default;
30469 DebugAnnotationName::~DebugAnnotationName() = default;
30470 DebugAnnotationName::DebugAnnotationName(const DebugAnnotationName&) = default;
30471 DebugAnnotationName& DebugAnnotationName::operator=(const DebugAnnotationName&) = default;
30472 DebugAnnotationName::DebugAnnotationName(DebugAnnotationName&&) noexcept = default;
30473 DebugAnnotationName& DebugAnnotationName::operator=(DebugAnnotationName&&) = default;
30474 
operator ==(const DebugAnnotationName & other) const30475 bool DebugAnnotationName::operator==(const DebugAnnotationName& other) const {
30476   return unknown_fields_ == other.unknown_fields_
30477    && iid_ == other.iid_
30478    && name_ == other.name_;
30479 }
30480 
ParseFromArray(const void * raw,size_t size)30481 bool DebugAnnotationName::ParseFromArray(const void* raw, size_t size) {
30482   unknown_fields_.clear();
30483   bool packed_error = false;
30484 
30485   ::protozero::ProtoDecoder dec(raw, size);
30486   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
30487     if (field.id() < _has_field_.size()) {
30488       _has_field_.set(field.id());
30489     }
30490     switch (field.id()) {
30491       case 1 /* iid */:
30492         field.get(&iid_);
30493         break;
30494       case 2 /* name */:
30495         field.get(&name_);
30496         break;
30497       default:
30498         field.SerializeAndAppendTo(&unknown_fields_);
30499         break;
30500     }
30501   }
30502   return !packed_error && !dec.bytes_left();
30503 }
30504 
SerializeAsString() const30505 std::string DebugAnnotationName::SerializeAsString() const {
30506   ::protozero::HeapBuffered<::protozero::Message> msg;
30507   Serialize(msg.get());
30508   return msg.SerializeAsString();
30509 }
30510 
SerializeAsArray() const30511 std::vector<uint8_t> DebugAnnotationName::SerializeAsArray() const {
30512   ::protozero::HeapBuffered<::protozero::Message> msg;
30513   Serialize(msg.get());
30514   return msg.SerializeAsArray();
30515 }
30516 
Serialize(::protozero::Message * msg) const30517 void DebugAnnotationName::Serialize(::protozero::Message* msg) const {
30518   // Field 1: iid
30519   if (_has_field_[1]) {
30520     msg->AppendVarInt(1, iid_);
30521   }
30522 
30523   // Field 2: name
30524   if (_has_field_[2]) {
30525     msg->AppendString(2, name_);
30526   }
30527 
30528   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
30529 }
30530 
30531 
30532 DebugAnnotation::DebugAnnotation() = default;
30533 DebugAnnotation::~DebugAnnotation() = default;
30534 DebugAnnotation::DebugAnnotation(const DebugAnnotation&) = default;
30535 DebugAnnotation& DebugAnnotation::operator=(const DebugAnnotation&) = default;
30536 DebugAnnotation::DebugAnnotation(DebugAnnotation&&) noexcept = default;
30537 DebugAnnotation& DebugAnnotation::operator=(DebugAnnotation&&) = default;
30538 
operator ==(const DebugAnnotation & other) const30539 bool DebugAnnotation::operator==(const DebugAnnotation& other) const {
30540   return unknown_fields_ == other.unknown_fields_
30541    && name_iid_ == other.name_iid_
30542    && name_ == other.name_
30543    && bool_value_ == other.bool_value_
30544    && uint_value_ == other.uint_value_
30545    && int_value_ == other.int_value_
30546    && double_value_ == other.double_value_
30547    && string_value_ == other.string_value_
30548    && pointer_value_ == other.pointer_value_
30549    && nested_value_ == other.nested_value_
30550    && legacy_json_value_ == other.legacy_json_value_
30551    && dict_entries_ == other.dict_entries_
30552    && array_values_ == other.array_values_;
30553 }
30554 
dict_entries_size() const30555 int DebugAnnotation::dict_entries_size() const { return static_cast<int>(dict_entries_.size()); }
clear_dict_entries()30556 void DebugAnnotation::clear_dict_entries() { dict_entries_.clear(); }
add_dict_entries()30557 DebugAnnotation* DebugAnnotation::add_dict_entries() { dict_entries_.emplace_back(); return &dict_entries_.back(); }
array_values_size() const30558 int DebugAnnotation::array_values_size() const { return static_cast<int>(array_values_.size()); }
clear_array_values()30559 void DebugAnnotation::clear_array_values() { array_values_.clear(); }
add_array_values()30560 DebugAnnotation* DebugAnnotation::add_array_values() { array_values_.emplace_back(); return &array_values_.back(); }
ParseFromArray(const void * raw,size_t size)30561 bool DebugAnnotation::ParseFromArray(const void* raw, size_t size) {
30562   dict_entries_.clear();
30563   array_values_.clear();
30564   unknown_fields_.clear();
30565   bool packed_error = false;
30566 
30567   ::protozero::ProtoDecoder dec(raw, size);
30568   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
30569     if (field.id() < _has_field_.size()) {
30570       _has_field_.set(field.id());
30571     }
30572     switch (field.id()) {
30573       case 1 /* name_iid */:
30574         field.get(&name_iid_);
30575         break;
30576       case 10 /* name */:
30577         field.get(&name_);
30578         break;
30579       case 2 /* bool_value */:
30580         field.get(&bool_value_);
30581         break;
30582       case 3 /* uint_value */:
30583         field.get(&uint_value_);
30584         break;
30585       case 4 /* int_value */:
30586         field.get(&int_value_);
30587         break;
30588       case 5 /* double_value */:
30589         field.get(&double_value_);
30590         break;
30591       case 6 /* string_value */:
30592         field.get(&string_value_);
30593         break;
30594       case 7 /* pointer_value */:
30595         field.get(&pointer_value_);
30596         break;
30597       case 8 /* nested_value */:
30598         (*nested_value_).ParseFromArray(field.data(), field.size());
30599         break;
30600       case 9 /* legacy_json_value */:
30601         field.get(&legacy_json_value_);
30602         break;
30603       case 11 /* dict_entries */:
30604         dict_entries_.emplace_back();
30605         dict_entries_.back().ParseFromArray(field.data(), field.size());
30606         break;
30607       case 12 /* array_values */:
30608         array_values_.emplace_back();
30609         array_values_.back().ParseFromArray(field.data(), field.size());
30610         break;
30611       default:
30612         field.SerializeAndAppendTo(&unknown_fields_);
30613         break;
30614     }
30615   }
30616   return !packed_error && !dec.bytes_left();
30617 }
30618 
SerializeAsString() const30619 std::string DebugAnnotation::SerializeAsString() const {
30620   ::protozero::HeapBuffered<::protozero::Message> msg;
30621   Serialize(msg.get());
30622   return msg.SerializeAsString();
30623 }
30624 
SerializeAsArray() const30625 std::vector<uint8_t> DebugAnnotation::SerializeAsArray() const {
30626   ::protozero::HeapBuffered<::protozero::Message> msg;
30627   Serialize(msg.get());
30628   return msg.SerializeAsArray();
30629 }
30630 
Serialize(::protozero::Message * msg) const30631 void DebugAnnotation::Serialize(::protozero::Message* msg) const {
30632   // Field 1: name_iid
30633   if (_has_field_[1]) {
30634     msg->AppendVarInt(1, name_iid_);
30635   }
30636 
30637   // Field 10: name
30638   if (_has_field_[10]) {
30639     msg->AppendString(10, name_);
30640   }
30641 
30642   // Field 2: bool_value
30643   if (_has_field_[2]) {
30644     msg->AppendTinyVarInt(2, bool_value_);
30645   }
30646 
30647   // Field 3: uint_value
30648   if (_has_field_[3]) {
30649     msg->AppendVarInt(3, uint_value_);
30650   }
30651 
30652   // Field 4: int_value
30653   if (_has_field_[4]) {
30654     msg->AppendVarInt(4, int_value_);
30655   }
30656 
30657   // Field 5: double_value
30658   if (_has_field_[5]) {
30659     msg->AppendFixed(5, double_value_);
30660   }
30661 
30662   // Field 6: string_value
30663   if (_has_field_[6]) {
30664     msg->AppendString(6, string_value_);
30665   }
30666 
30667   // Field 7: pointer_value
30668   if (_has_field_[7]) {
30669     msg->AppendVarInt(7, pointer_value_);
30670   }
30671 
30672   // Field 8: nested_value
30673   if (_has_field_[8]) {
30674     (*nested_value_).Serialize(msg->BeginNestedMessage<::protozero::Message>(8));
30675   }
30676 
30677   // Field 9: legacy_json_value
30678   if (_has_field_[9]) {
30679     msg->AppendString(9, legacy_json_value_);
30680   }
30681 
30682   // Field 11: dict_entries
30683   for (auto& it : dict_entries_) {
30684     it.Serialize(msg->BeginNestedMessage<::protozero::Message>(11));
30685   }
30686 
30687   // Field 12: array_values
30688   for (auto& it : array_values_) {
30689     it.Serialize(msg->BeginNestedMessage<::protozero::Message>(12));
30690   }
30691 
30692   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
30693 }
30694 
30695 
30696 DebugAnnotation_NestedValue::DebugAnnotation_NestedValue() = default;
30697 DebugAnnotation_NestedValue::~DebugAnnotation_NestedValue() = default;
30698 DebugAnnotation_NestedValue::DebugAnnotation_NestedValue(const DebugAnnotation_NestedValue&) = default;
30699 DebugAnnotation_NestedValue& DebugAnnotation_NestedValue::operator=(const DebugAnnotation_NestedValue&) = default;
30700 DebugAnnotation_NestedValue::DebugAnnotation_NestedValue(DebugAnnotation_NestedValue&&) noexcept = default;
30701 DebugAnnotation_NestedValue& DebugAnnotation_NestedValue::operator=(DebugAnnotation_NestedValue&&) = default;
30702 
operator ==(const DebugAnnotation_NestedValue & other) const30703 bool DebugAnnotation_NestedValue::operator==(const DebugAnnotation_NestedValue& other) const {
30704   return unknown_fields_ == other.unknown_fields_
30705    && nested_type_ == other.nested_type_
30706    && dict_keys_ == other.dict_keys_
30707    && dict_values_ == other.dict_values_
30708    && array_values_ == other.array_values_
30709    && int_value_ == other.int_value_
30710    && double_value_ == other.double_value_
30711    && bool_value_ == other.bool_value_
30712    && string_value_ == other.string_value_;
30713 }
30714 
dict_values_size() const30715 int DebugAnnotation_NestedValue::dict_values_size() const { return static_cast<int>(dict_values_.size()); }
clear_dict_values()30716 void DebugAnnotation_NestedValue::clear_dict_values() { dict_values_.clear(); }
add_dict_values()30717 DebugAnnotation_NestedValue* DebugAnnotation_NestedValue::add_dict_values() { dict_values_.emplace_back(); return &dict_values_.back(); }
array_values_size() const30718 int DebugAnnotation_NestedValue::array_values_size() const { return static_cast<int>(array_values_.size()); }
clear_array_values()30719 void DebugAnnotation_NestedValue::clear_array_values() { array_values_.clear(); }
add_array_values()30720 DebugAnnotation_NestedValue* DebugAnnotation_NestedValue::add_array_values() { array_values_.emplace_back(); return &array_values_.back(); }
ParseFromArray(const void * raw,size_t size)30721 bool DebugAnnotation_NestedValue::ParseFromArray(const void* raw, size_t size) {
30722   dict_keys_.clear();
30723   dict_values_.clear();
30724   array_values_.clear();
30725   unknown_fields_.clear();
30726   bool packed_error = false;
30727 
30728   ::protozero::ProtoDecoder dec(raw, size);
30729   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
30730     if (field.id() < _has_field_.size()) {
30731       _has_field_.set(field.id());
30732     }
30733     switch (field.id()) {
30734       case 1 /* nested_type */:
30735         field.get(&nested_type_);
30736         break;
30737       case 2 /* dict_keys */:
30738         dict_keys_.emplace_back();
30739         field.get(&dict_keys_.back());
30740         break;
30741       case 3 /* dict_values */:
30742         dict_values_.emplace_back();
30743         dict_values_.back().ParseFromArray(field.data(), field.size());
30744         break;
30745       case 4 /* array_values */:
30746         array_values_.emplace_back();
30747         array_values_.back().ParseFromArray(field.data(), field.size());
30748         break;
30749       case 5 /* int_value */:
30750         field.get(&int_value_);
30751         break;
30752       case 6 /* double_value */:
30753         field.get(&double_value_);
30754         break;
30755       case 7 /* bool_value */:
30756         field.get(&bool_value_);
30757         break;
30758       case 8 /* string_value */:
30759         field.get(&string_value_);
30760         break;
30761       default:
30762         field.SerializeAndAppendTo(&unknown_fields_);
30763         break;
30764     }
30765   }
30766   return !packed_error && !dec.bytes_left();
30767 }
30768 
SerializeAsString() const30769 std::string DebugAnnotation_NestedValue::SerializeAsString() const {
30770   ::protozero::HeapBuffered<::protozero::Message> msg;
30771   Serialize(msg.get());
30772   return msg.SerializeAsString();
30773 }
30774 
SerializeAsArray() const30775 std::vector<uint8_t> DebugAnnotation_NestedValue::SerializeAsArray() const {
30776   ::protozero::HeapBuffered<::protozero::Message> msg;
30777   Serialize(msg.get());
30778   return msg.SerializeAsArray();
30779 }
30780 
Serialize(::protozero::Message * msg) const30781 void DebugAnnotation_NestedValue::Serialize(::protozero::Message* msg) const {
30782   // Field 1: nested_type
30783   if (_has_field_[1]) {
30784     msg->AppendVarInt(1, nested_type_);
30785   }
30786 
30787   // Field 2: dict_keys
30788   for (auto& it : dict_keys_) {
30789     msg->AppendString(2, it);
30790   }
30791 
30792   // Field 3: dict_values
30793   for (auto& it : dict_values_) {
30794     it.Serialize(msg->BeginNestedMessage<::protozero::Message>(3));
30795   }
30796 
30797   // Field 4: array_values
30798   for (auto& it : array_values_) {
30799     it.Serialize(msg->BeginNestedMessage<::protozero::Message>(4));
30800   }
30801 
30802   // Field 5: int_value
30803   if (_has_field_[5]) {
30804     msg->AppendVarInt(5, int_value_);
30805   }
30806 
30807   // Field 6: double_value
30808   if (_has_field_[6]) {
30809     msg->AppendFixed(6, double_value_);
30810   }
30811 
30812   // Field 7: bool_value
30813   if (_has_field_[7]) {
30814     msg->AppendTinyVarInt(7, bool_value_);
30815   }
30816 
30817   // Field 8: string_value
30818   if (_has_field_[8]) {
30819     msg->AppendString(8, string_value_);
30820   }
30821 
30822   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
30823 }
30824 
30825 }  // namespace perfetto
30826 }  // namespace protos
30827 }  // namespace gen
30828 #if defined(__GNUC__) || defined(__clang__)
30829 #pragma GCC diagnostic pop
30830 #endif
30831 // gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/log_message.gen.cc
30832 // gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/log_message.gen.h
30833 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
30834 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_LOG_MESSAGE_PROTO_CPP_H_
30835 #define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_LOG_MESSAGE_PROTO_CPP_H_
30836 
30837 #include <stdint.h>
30838 #include <bitset>
30839 #include <vector>
30840 #include <string>
30841 #include <type_traits>
30842 
30843 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
30844 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
30845 // gen_amalgamated expanded: #include "perfetto/base/export.h"
30846 
30847 namespace perfetto {
30848 namespace protos {
30849 namespace gen {
30850 class LogMessageBody;
30851 class LogMessage;
30852 }  // namespace perfetto
30853 }  // namespace protos
30854 }  // namespace gen
30855 
30856 namespace protozero {
30857 class Message;
30858 }  // namespace protozero
30859 
30860 namespace perfetto {
30861 namespace protos {
30862 namespace gen {
30863 
30864 class PERFETTO_EXPORT LogMessageBody : public ::protozero::CppMessageObj {
30865  public:
30866   enum FieldNumbers {
30867     kIidFieldNumber = 1,
30868     kBodyFieldNumber = 2,
30869   };
30870 
30871   LogMessageBody();
30872   ~LogMessageBody() override;
30873   LogMessageBody(LogMessageBody&&) noexcept;
30874   LogMessageBody& operator=(LogMessageBody&&);
30875   LogMessageBody(const LogMessageBody&);
30876   LogMessageBody& operator=(const LogMessageBody&);
30877   bool operator==(const LogMessageBody&) const;
operator !=(const LogMessageBody & other) const30878   bool operator!=(const LogMessageBody& other) const { return !(*this == other); }
30879 
30880   bool ParseFromArray(const void*, size_t) override;
30881   std::string SerializeAsString() const override;
30882   std::vector<uint8_t> SerializeAsArray() const override;
30883   void Serialize(::protozero::Message*) const;
30884 
has_iid() const30885   bool has_iid() const { return _has_field_[1]; }
iid() const30886   uint64_t iid() const { return iid_; }
set_iid(uint64_t value)30887   void set_iid(uint64_t value) { iid_ = value; _has_field_.set(1); }
30888 
has_body() const30889   bool has_body() const { return _has_field_[2]; }
body() const30890   const std::string& body() const { return body_; }
set_body(const std::string & value)30891   void set_body(const std::string& value) { body_ = value; _has_field_.set(2); }
30892 
30893  private:
30894   uint64_t iid_{};
30895   std::string body_{};
30896 
30897   // Allows to preserve unknown protobuf fields for compatibility
30898   // with future versions of .proto files.
30899   std::string unknown_fields_;
30900 
30901   std::bitset<3> _has_field_{};
30902 };
30903 
30904 
30905 class PERFETTO_EXPORT LogMessage : public ::protozero::CppMessageObj {
30906  public:
30907   enum FieldNumbers {
30908     kSourceLocationIidFieldNumber = 1,
30909     kBodyIidFieldNumber = 2,
30910   };
30911 
30912   LogMessage();
30913   ~LogMessage() override;
30914   LogMessage(LogMessage&&) noexcept;
30915   LogMessage& operator=(LogMessage&&);
30916   LogMessage(const LogMessage&);
30917   LogMessage& operator=(const LogMessage&);
30918   bool operator==(const LogMessage&) const;
operator !=(const LogMessage & other) const30919   bool operator!=(const LogMessage& other) const { return !(*this == other); }
30920 
30921   bool ParseFromArray(const void*, size_t) override;
30922   std::string SerializeAsString() const override;
30923   std::vector<uint8_t> SerializeAsArray() const override;
30924   void Serialize(::protozero::Message*) const;
30925 
has_source_location_iid() const30926   bool has_source_location_iid() const { return _has_field_[1]; }
source_location_iid() const30927   uint64_t source_location_iid() const { return source_location_iid_; }
set_source_location_iid(uint64_t value)30928   void set_source_location_iid(uint64_t value) { source_location_iid_ = value; _has_field_.set(1); }
30929 
has_body_iid() const30930   bool has_body_iid() const { return _has_field_[2]; }
body_iid() const30931   uint64_t body_iid() const { return body_iid_; }
set_body_iid(uint64_t value)30932   void set_body_iid(uint64_t value) { body_iid_ = value; _has_field_.set(2); }
30933 
30934  private:
30935   uint64_t source_location_iid_{};
30936   uint64_t body_iid_{};
30937 
30938   // Allows to preserve unknown protobuf fields for compatibility
30939   // with future versions of .proto files.
30940   std::string unknown_fields_;
30941 
30942   std::bitset<3> _has_field_{};
30943 };
30944 
30945 }  // namespace perfetto
30946 }  // namespace protos
30947 }  // namespace gen
30948 
30949 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_LOG_MESSAGE_PROTO_CPP_H_
30950 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
30951 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
30952 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
30953 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
30954 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
30955 #if defined(__GNUC__) || defined(__clang__)
30956 #pragma GCC diagnostic push
30957 #pragma GCC diagnostic ignored "-Wfloat-equal"
30958 #endif
30959 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/log_message.gen.h"
30960 
30961 namespace perfetto {
30962 namespace protos {
30963 namespace gen {
30964 
30965 LogMessageBody::LogMessageBody() = default;
30966 LogMessageBody::~LogMessageBody() = default;
30967 LogMessageBody::LogMessageBody(const LogMessageBody&) = default;
30968 LogMessageBody& LogMessageBody::operator=(const LogMessageBody&) = default;
30969 LogMessageBody::LogMessageBody(LogMessageBody&&) noexcept = default;
30970 LogMessageBody& LogMessageBody::operator=(LogMessageBody&&) = default;
30971 
operator ==(const LogMessageBody & other) const30972 bool LogMessageBody::operator==(const LogMessageBody& other) const {
30973   return unknown_fields_ == other.unknown_fields_
30974    && iid_ == other.iid_
30975    && body_ == other.body_;
30976 }
30977 
ParseFromArray(const void * raw,size_t size)30978 bool LogMessageBody::ParseFromArray(const void* raw, size_t size) {
30979   unknown_fields_.clear();
30980   bool packed_error = false;
30981 
30982   ::protozero::ProtoDecoder dec(raw, size);
30983   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
30984     if (field.id() < _has_field_.size()) {
30985       _has_field_.set(field.id());
30986     }
30987     switch (field.id()) {
30988       case 1 /* iid */:
30989         field.get(&iid_);
30990         break;
30991       case 2 /* body */:
30992         field.get(&body_);
30993         break;
30994       default:
30995         field.SerializeAndAppendTo(&unknown_fields_);
30996         break;
30997     }
30998   }
30999   return !packed_error && !dec.bytes_left();
31000 }
31001 
SerializeAsString() const31002 std::string LogMessageBody::SerializeAsString() const {
31003   ::protozero::HeapBuffered<::protozero::Message> msg;
31004   Serialize(msg.get());
31005   return msg.SerializeAsString();
31006 }
31007 
SerializeAsArray() const31008 std::vector<uint8_t> LogMessageBody::SerializeAsArray() const {
31009   ::protozero::HeapBuffered<::protozero::Message> msg;
31010   Serialize(msg.get());
31011   return msg.SerializeAsArray();
31012 }
31013 
Serialize(::protozero::Message * msg) const31014 void LogMessageBody::Serialize(::protozero::Message* msg) const {
31015   // Field 1: iid
31016   if (_has_field_[1]) {
31017     msg->AppendVarInt(1, iid_);
31018   }
31019 
31020   // Field 2: body
31021   if (_has_field_[2]) {
31022     msg->AppendString(2, body_);
31023   }
31024 
31025   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
31026 }
31027 
31028 
31029 LogMessage::LogMessage() = default;
31030 LogMessage::~LogMessage() = default;
31031 LogMessage::LogMessage(const LogMessage&) = default;
31032 LogMessage& LogMessage::operator=(const LogMessage&) = default;
31033 LogMessage::LogMessage(LogMessage&&) noexcept = default;
31034 LogMessage& LogMessage::operator=(LogMessage&&) = default;
31035 
operator ==(const LogMessage & other) const31036 bool LogMessage::operator==(const LogMessage& other) const {
31037   return unknown_fields_ == other.unknown_fields_
31038    && source_location_iid_ == other.source_location_iid_
31039    && body_iid_ == other.body_iid_;
31040 }
31041 
ParseFromArray(const void * raw,size_t size)31042 bool LogMessage::ParseFromArray(const void* raw, size_t size) {
31043   unknown_fields_.clear();
31044   bool packed_error = false;
31045 
31046   ::protozero::ProtoDecoder dec(raw, size);
31047   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
31048     if (field.id() < _has_field_.size()) {
31049       _has_field_.set(field.id());
31050     }
31051     switch (field.id()) {
31052       case 1 /* source_location_iid */:
31053         field.get(&source_location_iid_);
31054         break;
31055       case 2 /* body_iid */:
31056         field.get(&body_iid_);
31057         break;
31058       default:
31059         field.SerializeAndAppendTo(&unknown_fields_);
31060         break;
31061     }
31062   }
31063   return !packed_error && !dec.bytes_left();
31064 }
31065 
SerializeAsString() const31066 std::string LogMessage::SerializeAsString() const {
31067   ::protozero::HeapBuffered<::protozero::Message> msg;
31068   Serialize(msg.get());
31069   return msg.SerializeAsString();
31070 }
31071 
SerializeAsArray() const31072 std::vector<uint8_t> LogMessage::SerializeAsArray() const {
31073   ::protozero::HeapBuffered<::protozero::Message> msg;
31074   Serialize(msg.get());
31075   return msg.SerializeAsArray();
31076 }
31077 
Serialize(::protozero::Message * msg) const31078 void LogMessage::Serialize(::protozero::Message* msg) const {
31079   // Field 1: source_location_iid
31080   if (_has_field_[1]) {
31081     msg->AppendVarInt(1, source_location_iid_);
31082   }
31083 
31084   // Field 2: body_iid
31085   if (_has_field_[2]) {
31086     msg->AppendVarInt(2, body_iid_);
31087   }
31088 
31089   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
31090 }
31091 
31092 }  // namespace perfetto
31093 }  // namespace protos
31094 }  // namespace gen
31095 #if defined(__GNUC__) || defined(__clang__)
31096 #pragma GCC diagnostic pop
31097 #endif
31098 // gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/process_descriptor.gen.cc
31099 // gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/process_descriptor.gen.h
31100 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
31101 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_PROCESS_DESCRIPTOR_PROTO_CPP_H_
31102 #define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_PROCESS_DESCRIPTOR_PROTO_CPP_H_
31103 
31104 #include <stdint.h>
31105 #include <bitset>
31106 #include <vector>
31107 #include <string>
31108 #include <type_traits>
31109 
31110 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
31111 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
31112 // gen_amalgamated expanded: #include "perfetto/base/export.h"
31113 
31114 namespace perfetto {
31115 namespace protos {
31116 namespace gen {
31117 class ProcessDescriptor;
31118 enum ProcessDescriptor_ChromeProcessType : int;
31119 }  // namespace perfetto
31120 }  // namespace protos
31121 }  // namespace gen
31122 
31123 namespace protozero {
31124 class Message;
31125 }  // namespace protozero
31126 
31127 namespace perfetto {
31128 namespace protos {
31129 namespace gen {
31130 enum ProcessDescriptor_ChromeProcessType : int {
31131   ProcessDescriptor_ChromeProcessType_PROCESS_UNSPECIFIED = 0,
31132   ProcessDescriptor_ChromeProcessType_PROCESS_BROWSER = 1,
31133   ProcessDescriptor_ChromeProcessType_PROCESS_RENDERER = 2,
31134   ProcessDescriptor_ChromeProcessType_PROCESS_UTILITY = 3,
31135   ProcessDescriptor_ChromeProcessType_PROCESS_ZYGOTE = 4,
31136   ProcessDescriptor_ChromeProcessType_PROCESS_SANDBOX_HELPER = 5,
31137   ProcessDescriptor_ChromeProcessType_PROCESS_GPU = 6,
31138   ProcessDescriptor_ChromeProcessType_PROCESS_PPAPI_PLUGIN = 7,
31139   ProcessDescriptor_ChromeProcessType_PROCESS_PPAPI_BROKER = 8,
31140 };
31141 
31142 class PERFETTO_EXPORT ProcessDescriptor : public ::protozero::CppMessageObj {
31143  public:
31144   using ChromeProcessType = ProcessDescriptor_ChromeProcessType;
31145   static constexpr auto PROCESS_UNSPECIFIED = ProcessDescriptor_ChromeProcessType_PROCESS_UNSPECIFIED;
31146   static constexpr auto PROCESS_BROWSER = ProcessDescriptor_ChromeProcessType_PROCESS_BROWSER;
31147   static constexpr auto PROCESS_RENDERER = ProcessDescriptor_ChromeProcessType_PROCESS_RENDERER;
31148   static constexpr auto PROCESS_UTILITY = ProcessDescriptor_ChromeProcessType_PROCESS_UTILITY;
31149   static constexpr auto PROCESS_ZYGOTE = ProcessDescriptor_ChromeProcessType_PROCESS_ZYGOTE;
31150   static constexpr auto PROCESS_SANDBOX_HELPER = ProcessDescriptor_ChromeProcessType_PROCESS_SANDBOX_HELPER;
31151   static constexpr auto PROCESS_GPU = ProcessDescriptor_ChromeProcessType_PROCESS_GPU;
31152   static constexpr auto PROCESS_PPAPI_PLUGIN = ProcessDescriptor_ChromeProcessType_PROCESS_PPAPI_PLUGIN;
31153   static constexpr auto PROCESS_PPAPI_BROKER = ProcessDescriptor_ChromeProcessType_PROCESS_PPAPI_BROKER;
31154   static constexpr auto ChromeProcessType_MIN = ProcessDescriptor_ChromeProcessType_PROCESS_UNSPECIFIED;
31155   static constexpr auto ChromeProcessType_MAX = ProcessDescriptor_ChromeProcessType_PROCESS_PPAPI_BROKER;
31156   enum FieldNumbers {
31157     kPidFieldNumber = 1,
31158     kCmdlineFieldNumber = 2,
31159     kProcessNameFieldNumber = 6,
31160     kProcessPriorityFieldNumber = 5,
31161     kStartTimestampNsFieldNumber = 7,
31162     kChromeProcessTypeFieldNumber = 4,
31163     kLegacySortIndexFieldNumber = 3,
31164     kProcessLabelsFieldNumber = 8,
31165   };
31166 
31167   ProcessDescriptor();
31168   ~ProcessDescriptor() override;
31169   ProcessDescriptor(ProcessDescriptor&&) noexcept;
31170   ProcessDescriptor& operator=(ProcessDescriptor&&);
31171   ProcessDescriptor(const ProcessDescriptor&);
31172   ProcessDescriptor& operator=(const ProcessDescriptor&);
31173   bool operator==(const ProcessDescriptor&) const;
operator !=(const ProcessDescriptor & other) const31174   bool operator!=(const ProcessDescriptor& other) const { return !(*this == other); }
31175 
31176   bool ParseFromArray(const void*, size_t) override;
31177   std::string SerializeAsString() const override;
31178   std::vector<uint8_t> SerializeAsArray() const override;
31179   void Serialize(::protozero::Message*) const;
31180 
has_pid() const31181   bool has_pid() const { return _has_field_[1]; }
pid() const31182   int32_t pid() const { return pid_; }
set_pid(int32_t value)31183   void set_pid(int32_t value) { pid_ = value; _has_field_.set(1); }
31184 
cmdline() const31185   const std::vector<std::string>& cmdline() const { return cmdline_; }
mutable_cmdline()31186   std::vector<std::string>* mutable_cmdline() { return &cmdline_; }
cmdline_size() const31187   int cmdline_size() const { return static_cast<int>(cmdline_.size()); }
clear_cmdline()31188   void clear_cmdline() { cmdline_.clear(); }
add_cmdline(std::string value)31189   void add_cmdline(std::string value) { cmdline_.emplace_back(value); }
add_cmdline()31190   std::string* add_cmdline() { cmdline_.emplace_back(); return &cmdline_.back(); }
31191 
has_process_name() const31192   bool has_process_name() const { return _has_field_[6]; }
process_name() const31193   const std::string& process_name() const { return process_name_; }
set_process_name(const std::string & value)31194   void set_process_name(const std::string& value) { process_name_ = value; _has_field_.set(6); }
31195 
has_process_priority() const31196   bool has_process_priority() const { return _has_field_[5]; }
process_priority() const31197   int32_t process_priority() const { return process_priority_; }
set_process_priority(int32_t value)31198   void set_process_priority(int32_t value) { process_priority_ = value; _has_field_.set(5); }
31199 
has_start_timestamp_ns() const31200   bool has_start_timestamp_ns() const { return _has_field_[7]; }
start_timestamp_ns() const31201   int64_t start_timestamp_ns() const { return start_timestamp_ns_; }
set_start_timestamp_ns(int64_t value)31202   void set_start_timestamp_ns(int64_t value) { start_timestamp_ns_ = value; _has_field_.set(7); }
31203 
has_chrome_process_type() const31204   bool has_chrome_process_type() const { return _has_field_[4]; }
chrome_process_type() const31205   ProcessDescriptor_ChromeProcessType chrome_process_type() const { return chrome_process_type_; }
set_chrome_process_type(ProcessDescriptor_ChromeProcessType value)31206   void set_chrome_process_type(ProcessDescriptor_ChromeProcessType value) { chrome_process_type_ = value; _has_field_.set(4); }
31207 
has_legacy_sort_index() const31208   bool has_legacy_sort_index() const { return _has_field_[3]; }
legacy_sort_index() const31209   int32_t legacy_sort_index() const { return legacy_sort_index_; }
set_legacy_sort_index(int32_t value)31210   void set_legacy_sort_index(int32_t value) { legacy_sort_index_ = value; _has_field_.set(3); }
31211 
process_labels() const31212   const std::vector<std::string>& process_labels() const { return process_labels_; }
mutable_process_labels()31213   std::vector<std::string>* mutable_process_labels() { return &process_labels_; }
process_labels_size() const31214   int process_labels_size() const { return static_cast<int>(process_labels_.size()); }
clear_process_labels()31215   void clear_process_labels() { process_labels_.clear(); }
add_process_labels(std::string value)31216   void add_process_labels(std::string value) { process_labels_.emplace_back(value); }
add_process_labels()31217   std::string* add_process_labels() { process_labels_.emplace_back(); return &process_labels_.back(); }
31218 
31219  private:
31220   int32_t pid_{};
31221   std::vector<std::string> cmdline_;
31222   std::string process_name_{};
31223   int32_t process_priority_{};
31224   int64_t start_timestamp_ns_{};
31225   ProcessDescriptor_ChromeProcessType chrome_process_type_{};
31226   int32_t legacy_sort_index_{};
31227   std::vector<std::string> process_labels_;
31228 
31229   // Allows to preserve unknown protobuf fields for compatibility
31230   // with future versions of .proto files.
31231   std::string unknown_fields_;
31232 
31233   std::bitset<9> _has_field_{};
31234 };
31235 
31236 }  // namespace perfetto
31237 }  // namespace protos
31238 }  // namespace gen
31239 
31240 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_PROCESS_DESCRIPTOR_PROTO_CPP_H_
31241 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
31242 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
31243 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
31244 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
31245 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
31246 #if defined(__GNUC__) || defined(__clang__)
31247 #pragma GCC diagnostic push
31248 #pragma GCC diagnostic ignored "-Wfloat-equal"
31249 #endif
31250 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/process_descriptor.gen.h"
31251 
31252 namespace perfetto {
31253 namespace protos {
31254 namespace gen {
31255 
31256 ProcessDescriptor::ProcessDescriptor() = default;
31257 ProcessDescriptor::~ProcessDescriptor() = default;
31258 ProcessDescriptor::ProcessDescriptor(const ProcessDescriptor&) = default;
31259 ProcessDescriptor& ProcessDescriptor::operator=(const ProcessDescriptor&) = default;
31260 ProcessDescriptor::ProcessDescriptor(ProcessDescriptor&&) noexcept = default;
31261 ProcessDescriptor& ProcessDescriptor::operator=(ProcessDescriptor&&) = default;
31262 
operator ==(const ProcessDescriptor & other) const31263 bool ProcessDescriptor::operator==(const ProcessDescriptor& other) const {
31264   return unknown_fields_ == other.unknown_fields_
31265    && pid_ == other.pid_
31266    && cmdline_ == other.cmdline_
31267    && process_name_ == other.process_name_
31268    && process_priority_ == other.process_priority_
31269    && start_timestamp_ns_ == other.start_timestamp_ns_
31270    && chrome_process_type_ == other.chrome_process_type_
31271    && legacy_sort_index_ == other.legacy_sort_index_
31272    && process_labels_ == other.process_labels_;
31273 }
31274 
ParseFromArray(const void * raw,size_t size)31275 bool ProcessDescriptor::ParseFromArray(const void* raw, size_t size) {
31276   cmdline_.clear();
31277   process_labels_.clear();
31278   unknown_fields_.clear();
31279   bool packed_error = false;
31280 
31281   ::protozero::ProtoDecoder dec(raw, size);
31282   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
31283     if (field.id() < _has_field_.size()) {
31284       _has_field_.set(field.id());
31285     }
31286     switch (field.id()) {
31287       case 1 /* pid */:
31288         field.get(&pid_);
31289         break;
31290       case 2 /* cmdline */:
31291         cmdline_.emplace_back();
31292         field.get(&cmdline_.back());
31293         break;
31294       case 6 /* process_name */:
31295         field.get(&process_name_);
31296         break;
31297       case 5 /* process_priority */:
31298         field.get(&process_priority_);
31299         break;
31300       case 7 /* start_timestamp_ns */:
31301         field.get(&start_timestamp_ns_);
31302         break;
31303       case 4 /* chrome_process_type */:
31304         field.get(&chrome_process_type_);
31305         break;
31306       case 3 /* legacy_sort_index */:
31307         field.get(&legacy_sort_index_);
31308         break;
31309       case 8 /* process_labels */:
31310         process_labels_.emplace_back();
31311         field.get(&process_labels_.back());
31312         break;
31313       default:
31314         field.SerializeAndAppendTo(&unknown_fields_);
31315         break;
31316     }
31317   }
31318   return !packed_error && !dec.bytes_left();
31319 }
31320 
SerializeAsString() const31321 std::string ProcessDescriptor::SerializeAsString() const {
31322   ::protozero::HeapBuffered<::protozero::Message> msg;
31323   Serialize(msg.get());
31324   return msg.SerializeAsString();
31325 }
31326 
SerializeAsArray() const31327 std::vector<uint8_t> ProcessDescriptor::SerializeAsArray() const {
31328   ::protozero::HeapBuffered<::protozero::Message> msg;
31329   Serialize(msg.get());
31330   return msg.SerializeAsArray();
31331 }
31332 
Serialize(::protozero::Message * msg) const31333 void ProcessDescriptor::Serialize(::protozero::Message* msg) const {
31334   // Field 1: pid
31335   if (_has_field_[1]) {
31336     msg->AppendVarInt(1, pid_);
31337   }
31338 
31339   // Field 2: cmdline
31340   for (auto& it : cmdline_) {
31341     msg->AppendString(2, it);
31342   }
31343 
31344   // Field 6: process_name
31345   if (_has_field_[6]) {
31346     msg->AppendString(6, process_name_);
31347   }
31348 
31349   // Field 5: process_priority
31350   if (_has_field_[5]) {
31351     msg->AppendVarInt(5, process_priority_);
31352   }
31353 
31354   // Field 7: start_timestamp_ns
31355   if (_has_field_[7]) {
31356     msg->AppendVarInt(7, start_timestamp_ns_);
31357   }
31358 
31359   // Field 4: chrome_process_type
31360   if (_has_field_[4]) {
31361     msg->AppendVarInt(4, chrome_process_type_);
31362   }
31363 
31364   // Field 3: legacy_sort_index
31365   if (_has_field_[3]) {
31366     msg->AppendVarInt(3, legacy_sort_index_);
31367   }
31368 
31369   // Field 8: process_labels
31370   for (auto& it : process_labels_) {
31371     msg->AppendString(8, it);
31372   }
31373 
31374   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
31375 }
31376 
31377 }  // namespace perfetto
31378 }  // namespace protos
31379 }  // namespace gen
31380 #if defined(__GNUC__) || defined(__clang__)
31381 #pragma GCC diagnostic pop
31382 #endif
31383 // gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/source_location.gen.cc
31384 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
31385 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
31386 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
31387 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
31388 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
31389 #if defined(__GNUC__) || defined(__clang__)
31390 #pragma GCC diagnostic push
31391 #pragma GCC diagnostic ignored "-Wfloat-equal"
31392 #endif
31393 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/source_location.gen.h"
31394 
31395 namespace perfetto {
31396 namespace protos {
31397 namespace gen {
31398 
31399 SourceLocation::SourceLocation() = default;
31400 SourceLocation::~SourceLocation() = default;
31401 SourceLocation::SourceLocation(const SourceLocation&) = default;
31402 SourceLocation& SourceLocation::operator=(const SourceLocation&) = default;
31403 SourceLocation::SourceLocation(SourceLocation&&) noexcept = default;
31404 SourceLocation& SourceLocation::operator=(SourceLocation&&) = default;
31405 
operator ==(const SourceLocation & other) const31406 bool SourceLocation::operator==(const SourceLocation& other) const {
31407   return unknown_fields_ == other.unknown_fields_
31408    && iid_ == other.iid_
31409    && file_name_ == other.file_name_
31410    && function_name_ == other.function_name_
31411    && line_number_ == other.line_number_;
31412 }
31413 
ParseFromArray(const void * raw,size_t size)31414 bool SourceLocation::ParseFromArray(const void* raw, size_t size) {
31415   unknown_fields_.clear();
31416   bool packed_error = false;
31417 
31418   ::protozero::ProtoDecoder dec(raw, size);
31419   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
31420     if (field.id() < _has_field_.size()) {
31421       _has_field_.set(field.id());
31422     }
31423     switch (field.id()) {
31424       case 1 /* iid */:
31425         field.get(&iid_);
31426         break;
31427       case 2 /* file_name */:
31428         field.get(&file_name_);
31429         break;
31430       case 3 /* function_name */:
31431         field.get(&function_name_);
31432         break;
31433       case 4 /* line_number */:
31434         field.get(&line_number_);
31435         break;
31436       default:
31437         field.SerializeAndAppendTo(&unknown_fields_);
31438         break;
31439     }
31440   }
31441   return !packed_error && !dec.bytes_left();
31442 }
31443 
SerializeAsString() const31444 std::string SourceLocation::SerializeAsString() const {
31445   ::protozero::HeapBuffered<::protozero::Message> msg;
31446   Serialize(msg.get());
31447   return msg.SerializeAsString();
31448 }
31449 
SerializeAsArray() const31450 std::vector<uint8_t> SourceLocation::SerializeAsArray() const {
31451   ::protozero::HeapBuffered<::protozero::Message> msg;
31452   Serialize(msg.get());
31453   return msg.SerializeAsArray();
31454 }
31455 
Serialize(::protozero::Message * msg) const31456 void SourceLocation::Serialize(::protozero::Message* msg) const {
31457   // Field 1: iid
31458   if (_has_field_[1]) {
31459     msg->AppendVarInt(1, iid_);
31460   }
31461 
31462   // Field 2: file_name
31463   if (_has_field_[2]) {
31464     msg->AppendString(2, file_name_);
31465   }
31466 
31467   // Field 3: function_name
31468   if (_has_field_[3]) {
31469     msg->AppendString(3, function_name_);
31470   }
31471 
31472   // Field 4: line_number
31473   if (_has_field_[4]) {
31474     msg->AppendVarInt(4, line_number_);
31475   }
31476 
31477   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
31478 }
31479 
31480 }  // namespace perfetto
31481 }  // namespace protos
31482 }  // namespace gen
31483 #if defined(__GNUC__) || defined(__clang__)
31484 #pragma GCC diagnostic pop
31485 #endif
31486 // gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/task_execution.gen.cc
31487 // gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/task_execution.gen.h
31488 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
31489 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_TASK_EXECUTION_PROTO_CPP_H_
31490 #define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_TASK_EXECUTION_PROTO_CPP_H_
31491 
31492 #include <stdint.h>
31493 #include <bitset>
31494 #include <vector>
31495 #include <string>
31496 #include <type_traits>
31497 
31498 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
31499 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
31500 // gen_amalgamated expanded: #include "perfetto/base/export.h"
31501 
31502 namespace perfetto {
31503 namespace protos {
31504 namespace gen {
31505 class TaskExecution;
31506 }  // namespace perfetto
31507 }  // namespace protos
31508 }  // namespace gen
31509 
31510 namespace protozero {
31511 class Message;
31512 }  // namespace protozero
31513 
31514 namespace perfetto {
31515 namespace protos {
31516 namespace gen {
31517 
31518 class PERFETTO_EXPORT TaskExecution : public ::protozero::CppMessageObj {
31519  public:
31520   enum FieldNumbers {
31521     kPostedFromIidFieldNumber = 1,
31522   };
31523 
31524   TaskExecution();
31525   ~TaskExecution() override;
31526   TaskExecution(TaskExecution&&) noexcept;
31527   TaskExecution& operator=(TaskExecution&&);
31528   TaskExecution(const TaskExecution&);
31529   TaskExecution& operator=(const TaskExecution&);
31530   bool operator==(const TaskExecution&) const;
operator !=(const TaskExecution & other) const31531   bool operator!=(const TaskExecution& other) const { return !(*this == other); }
31532 
31533   bool ParseFromArray(const void*, size_t) override;
31534   std::string SerializeAsString() const override;
31535   std::vector<uint8_t> SerializeAsArray() const override;
31536   void Serialize(::protozero::Message*) const;
31537 
has_posted_from_iid() const31538   bool has_posted_from_iid() const { return _has_field_[1]; }
posted_from_iid() const31539   uint64_t posted_from_iid() const { return posted_from_iid_; }
set_posted_from_iid(uint64_t value)31540   void set_posted_from_iid(uint64_t value) { posted_from_iid_ = value; _has_field_.set(1); }
31541 
31542  private:
31543   uint64_t posted_from_iid_{};
31544 
31545   // Allows to preserve unknown protobuf fields for compatibility
31546   // with future versions of .proto files.
31547   std::string unknown_fields_;
31548 
31549   std::bitset<2> _has_field_{};
31550 };
31551 
31552 }  // namespace perfetto
31553 }  // namespace protos
31554 }  // namespace gen
31555 
31556 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_TASK_EXECUTION_PROTO_CPP_H_
31557 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
31558 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
31559 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
31560 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
31561 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
31562 #if defined(__GNUC__) || defined(__clang__)
31563 #pragma GCC diagnostic push
31564 #pragma GCC diagnostic ignored "-Wfloat-equal"
31565 #endif
31566 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/task_execution.gen.h"
31567 
31568 namespace perfetto {
31569 namespace protos {
31570 namespace gen {
31571 
31572 TaskExecution::TaskExecution() = default;
31573 TaskExecution::~TaskExecution() = default;
31574 TaskExecution::TaskExecution(const TaskExecution&) = default;
31575 TaskExecution& TaskExecution::operator=(const TaskExecution&) = default;
31576 TaskExecution::TaskExecution(TaskExecution&&) noexcept = default;
31577 TaskExecution& TaskExecution::operator=(TaskExecution&&) = default;
31578 
operator ==(const TaskExecution & other) const31579 bool TaskExecution::operator==(const TaskExecution& other) const {
31580   return unknown_fields_ == other.unknown_fields_
31581    && posted_from_iid_ == other.posted_from_iid_;
31582 }
31583 
ParseFromArray(const void * raw,size_t size)31584 bool TaskExecution::ParseFromArray(const void* raw, size_t size) {
31585   unknown_fields_.clear();
31586   bool packed_error = false;
31587 
31588   ::protozero::ProtoDecoder dec(raw, size);
31589   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
31590     if (field.id() < _has_field_.size()) {
31591       _has_field_.set(field.id());
31592     }
31593     switch (field.id()) {
31594       case 1 /* posted_from_iid */:
31595         field.get(&posted_from_iid_);
31596         break;
31597       default:
31598         field.SerializeAndAppendTo(&unknown_fields_);
31599         break;
31600     }
31601   }
31602   return !packed_error && !dec.bytes_left();
31603 }
31604 
SerializeAsString() const31605 std::string TaskExecution::SerializeAsString() const {
31606   ::protozero::HeapBuffered<::protozero::Message> msg;
31607   Serialize(msg.get());
31608   return msg.SerializeAsString();
31609 }
31610 
SerializeAsArray() const31611 std::vector<uint8_t> TaskExecution::SerializeAsArray() const {
31612   ::protozero::HeapBuffered<::protozero::Message> msg;
31613   Serialize(msg.get());
31614   return msg.SerializeAsArray();
31615 }
31616 
Serialize(::protozero::Message * msg) const31617 void TaskExecution::Serialize(::protozero::Message* msg) const {
31618   // Field 1: posted_from_iid
31619   if (_has_field_[1]) {
31620     msg->AppendVarInt(1, posted_from_iid_);
31621   }
31622 
31623   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
31624 }
31625 
31626 }  // namespace perfetto
31627 }  // namespace protos
31628 }  // namespace gen
31629 #if defined(__GNUC__) || defined(__clang__)
31630 #pragma GCC diagnostic pop
31631 #endif
31632 // gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/thread_descriptor.gen.cc
31633 // gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/thread_descriptor.gen.h
31634 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
31635 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_THREAD_DESCRIPTOR_PROTO_CPP_H_
31636 #define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_THREAD_DESCRIPTOR_PROTO_CPP_H_
31637 
31638 #include <stdint.h>
31639 #include <bitset>
31640 #include <vector>
31641 #include <string>
31642 #include <type_traits>
31643 
31644 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
31645 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
31646 // gen_amalgamated expanded: #include "perfetto/base/export.h"
31647 
31648 namespace perfetto {
31649 namespace protos {
31650 namespace gen {
31651 class ThreadDescriptor;
31652 enum ThreadDescriptor_ChromeThreadType : int;
31653 }  // namespace perfetto
31654 }  // namespace protos
31655 }  // namespace gen
31656 
31657 namespace protozero {
31658 class Message;
31659 }  // namespace protozero
31660 
31661 namespace perfetto {
31662 namespace protos {
31663 namespace gen {
31664 enum ThreadDescriptor_ChromeThreadType : int {
31665   ThreadDescriptor_ChromeThreadType_CHROME_THREAD_UNSPECIFIED = 0,
31666   ThreadDescriptor_ChromeThreadType_CHROME_THREAD_MAIN = 1,
31667   ThreadDescriptor_ChromeThreadType_CHROME_THREAD_IO = 2,
31668   ThreadDescriptor_ChromeThreadType_CHROME_THREAD_POOL_BG_WORKER = 3,
31669   ThreadDescriptor_ChromeThreadType_CHROME_THREAD_POOL_FG_WORKER = 4,
31670   ThreadDescriptor_ChromeThreadType_CHROME_THREAD_POOL_FB_BLOCKING = 5,
31671   ThreadDescriptor_ChromeThreadType_CHROME_THREAD_POOL_BG_BLOCKING = 6,
31672   ThreadDescriptor_ChromeThreadType_CHROME_THREAD_POOL_SERVICE = 7,
31673   ThreadDescriptor_ChromeThreadType_CHROME_THREAD_COMPOSITOR = 8,
31674   ThreadDescriptor_ChromeThreadType_CHROME_THREAD_VIZ_COMPOSITOR = 9,
31675   ThreadDescriptor_ChromeThreadType_CHROME_THREAD_COMPOSITOR_WORKER = 10,
31676   ThreadDescriptor_ChromeThreadType_CHROME_THREAD_SERVICE_WORKER = 11,
31677   ThreadDescriptor_ChromeThreadType_CHROME_THREAD_MEMORY_INFRA = 50,
31678   ThreadDescriptor_ChromeThreadType_CHROME_THREAD_SAMPLING_PROFILER = 51,
31679 };
31680 
31681 class PERFETTO_EXPORT ThreadDescriptor : public ::protozero::CppMessageObj {
31682  public:
31683   using ChromeThreadType = ThreadDescriptor_ChromeThreadType;
31684   static constexpr auto CHROME_THREAD_UNSPECIFIED = ThreadDescriptor_ChromeThreadType_CHROME_THREAD_UNSPECIFIED;
31685   static constexpr auto CHROME_THREAD_MAIN = ThreadDescriptor_ChromeThreadType_CHROME_THREAD_MAIN;
31686   static constexpr auto CHROME_THREAD_IO = ThreadDescriptor_ChromeThreadType_CHROME_THREAD_IO;
31687   static constexpr auto CHROME_THREAD_POOL_BG_WORKER = ThreadDescriptor_ChromeThreadType_CHROME_THREAD_POOL_BG_WORKER;
31688   static constexpr auto CHROME_THREAD_POOL_FG_WORKER = ThreadDescriptor_ChromeThreadType_CHROME_THREAD_POOL_FG_WORKER;
31689   static constexpr auto CHROME_THREAD_POOL_FB_BLOCKING = ThreadDescriptor_ChromeThreadType_CHROME_THREAD_POOL_FB_BLOCKING;
31690   static constexpr auto CHROME_THREAD_POOL_BG_BLOCKING = ThreadDescriptor_ChromeThreadType_CHROME_THREAD_POOL_BG_BLOCKING;
31691   static constexpr auto CHROME_THREAD_POOL_SERVICE = ThreadDescriptor_ChromeThreadType_CHROME_THREAD_POOL_SERVICE;
31692   static constexpr auto CHROME_THREAD_COMPOSITOR = ThreadDescriptor_ChromeThreadType_CHROME_THREAD_COMPOSITOR;
31693   static constexpr auto CHROME_THREAD_VIZ_COMPOSITOR = ThreadDescriptor_ChromeThreadType_CHROME_THREAD_VIZ_COMPOSITOR;
31694   static constexpr auto CHROME_THREAD_COMPOSITOR_WORKER = ThreadDescriptor_ChromeThreadType_CHROME_THREAD_COMPOSITOR_WORKER;
31695   static constexpr auto CHROME_THREAD_SERVICE_WORKER = ThreadDescriptor_ChromeThreadType_CHROME_THREAD_SERVICE_WORKER;
31696   static constexpr auto CHROME_THREAD_MEMORY_INFRA = ThreadDescriptor_ChromeThreadType_CHROME_THREAD_MEMORY_INFRA;
31697   static constexpr auto CHROME_THREAD_SAMPLING_PROFILER = ThreadDescriptor_ChromeThreadType_CHROME_THREAD_SAMPLING_PROFILER;
31698   static constexpr auto ChromeThreadType_MIN = ThreadDescriptor_ChromeThreadType_CHROME_THREAD_UNSPECIFIED;
31699   static constexpr auto ChromeThreadType_MAX = ThreadDescriptor_ChromeThreadType_CHROME_THREAD_SAMPLING_PROFILER;
31700   enum FieldNumbers {
31701     kPidFieldNumber = 1,
31702     kTidFieldNumber = 2,
31703     kThreadNameFieldNumber = 5,
31704     kChromeThreadTypeFieldNumber = 4,
31705     kReferenceTimestampUsFieldNumber = 6,
31706     kReferenceThreadTimeUsFieldNumber = 7,
31707     kReferenceThreadInstructionCountFieldNumber = 8,
31708     kLegacySortIndexFieldNumber = 3,
31709   };
31710 
31711   ThreadDescriptor();
31712   ~ThreadDescriptor() override;
31713   ThreadDescriptor(ThreadDescriptor&&) noexcept;
31714   ThreadDescriptor& operator=(ThreadDescriptor&&);
31715   ThreadDescriptor(const ThreadDescriptor&);
31716   ThreadDescriptor& operator=(const ThreadDescriptor&);
31717   bool operator==(const ThreadDescriptor&) const;
operator !=(const ThreadDescriptor & other) const31718   bool operator!=(const ThreadDescriptor& other) const { return !(*this == other); }
31719 
31720   bool ParseFromArray(const void*, size_t) override;
31721   std::string SerializeAsString() const override;
31722   std::vector<uint8_t> SerializeAsArray() const override;
31723   void Serialize(::protozero::Message*) const;
31724 
has_pid() const31725   bool has_pid() const { return _has_field_[1]; }
pid() const31726   int32_t pid() const { return pid_; }
set_pid(int32_t value)31727   void set_pid(int32_t value) { pid_ = value; _has_field_.set(1); }
31728 
has_tid() const31729   bool has_tid() const { return _has_field_[2]; }
tid() const31730   int32_t tid() const { return tid_; }
set_tid(int32_t value)31731   void set_tid(int32_t value) { tid_ = value; _has_field_.set(2); }
31732 
has_thread_name() const31733   bool has_thread_name() const { return _has_field_[5]; }
thread_name() const31734   const std::string& thread_name() const { return thread_name_; }
set_thread_name(const std::string & value)31735   void set_thread_name(const std::string& value) { thread_name_ = value; _has_field_.set(5); }
31736 
has_chrome_thread_type() const31737   bool has_chrome_thread_type() const { return _has_field_[4]; }
chrome_thread_type() const31738   ThreadDescriptor_ChromeThreadType chrome_thread_type() const { return chrome_thread_type_; }
set_chrome_thread_type(ThreadDescriptor_ChromeThreadType value)31739   void set_chrome_thread_type(ThreadDescriptor_ChromeThreadType value) { chrome_thread_type_ = value; _has_field_.set(4); }
31740 
has_reference_timestamp_us() const31741   bool has_reference_timestamp_us() const { return _has_field_[6]; }
reference_timestamp_us() const31742   int64_t reference_timestamp_us() const { return reference_timestamp_us_; }
set_reference_timestamp_us(int64_t value)31743   void set_reference_timestamp_us(int64_t value) { reference_timestamp_us_ = value; _has_field_.set(6); }
31744 
has_reference_thread_time_us() const31745   bool has_reference_thread_time_us() const { return _has_field_[7]; }
reference_thread_time_us() const31746   int64_t reference_thread_time_us() const { return reference_thread_time_us_; }
set_reference_thread_time_us(int64_t value)31747   void set_reference_thread_time_us(int64_t value) { reference_thread_time_us_ = value; _has_field_.set(7); }
31748 
has_reference_thread_instruction_count() const31749   bool has_reference_thread_instruction_count() const { return _has_field_[8]; }
reference_thread_instruction_count() const31750   int64_t reference_thread_instruction_count() const { return reference_thread_instruction_count_; }
set_reference_thread_instruction_count(int64_t value)31751   void set_reference_thread_instruction_count(int64_t value) { reference_thread_instruction_count_ = value; _has_field_.set(8); }
31752 
has_legacy_sort_index() const31753   bool has_legacy_sort_index() const { return _has_field_[3]; }
legacy_sort_index() const31754   int32_t legacy_sort_index() const { return legacy_sort_index_; }
set_legacy_sort_index(int32_t value)31755   void set_legacy_sort_index(int32_t value) { legacy_sort_index_ = value; _has_field_.set(3); }
31756 
31757  private:
31758   int32_t pid_{};
31759   int32_t tid_{};
31760   std::string thread_name_{};
31761   ThreadDescriptor_ChromeThreadType chrome_thread_type_{};
31762   int64_t reference_timestamp_us_{};
31763   int64_t reference_thread_time_us_{};
31764   int64_t reference_thread_instruction_count_{};
31765   int32_t legacy_sort_index_{};
31766 
31767   // Allows to preserve unknown protobuf fields for compatibility
31768   // with future versions of .proto files.
31769   std::string unknown_fields_;
31770 
31771   std::bitset<9> _has_field_{};
31772 };
31773 
31774 }  // namespace perfetto
31775 }  // namespace protos
31776 }  // namespace gen
31777 
31778 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_THREAD_DESCRIPTOR_PROTO_CPP_H_
31779 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
31780 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
31781 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
31782 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
31783 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
31784 #if defined(__GNUC__) || defined(__clang__)
31785 #pragma GCC diagnostic push
31786 #pragma GCC diagnostic ignored "-Wfloat-equal"
31787 #endif
31788 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/thread_descriptor.gen.h"
31789 
31790 namespace perfetto {
31791 namespace protos {
31792 namespace gen {
31793 
31794 ThreadDescriptor::ThreadDescriptor() = default;
31795 ThreadDescriptor::~ThreadDescriptor() = default;
31796 ThreadDescriptor::ThreadDescriptor(const ThreadDescriptor&) = default;
31797 ThreadDescriptor& ThreadDescriptor::operator=(const ThreadDescriptor&) = default;
31798 ThreadDescriptor::ThreadDescriptor(ThreadDescriptor&&) noexcept = default;
31799 ThreadDescriptor& ThreadDescriptor::operator=(ThreadDescriptor&&) = default;
31800 
operator ==(const ThreadDescriptor & other) const31801 bool ThreadDescriptor::operator==(const ThreadDescriptor& other) const {
31802   return unknown_fields_ == other.unknown_fields_
31803    && pid_ == other.pid_
31804    && tid_ == other.tid_
31805    && thread_name_ == other.thread_name_
31806    && chrome_thread_type_ == other.chrome_thread_type_
31807    && reference_timestamp_us_ == other.reference_timestamp_us_
31808    && reference_thread_time_us_ == other.reference_thread_time_us_
31809    && reference_thread_instruction_count_ == other.reference_thread_instruction_count_
31810    && legacy_sort_index_ == other.legacy_sort_index_;
31811 }
31812 
ParseFromArray(const void * raw,size_t size)31813 bool ThreadDescriptor::ParseFromArray(const void* raw, size_t size) {
31814   unknown_fields_.clear();
31815   bool packed_error = false;
31816 
31817   ::protozero::ProtoDecoder dec(raw, size);
31818   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
31819     if (field.id() < _has_field_.size()) {
31820       _has_field_.set(field.id());
31821     }
31822     switch (field.id()) {
31823       case 1 /* pid */:
31824         field.get(&pid_);
31825         break;
31826       case 2 /* tid */:
31827         field.get(&tid_);
31828         break;
31829       case 5 /* thread_name */:
31830         field.get(&thread_name_);
31831         break;
31832       case 4 /* chrome_thread_type */:
31833         field.get(&chrome_thread_type_);
31834         break;
31835       case 6 /* reference_timestamp_us */:
31836         field.get(&reference_timestamp_us_);
31837         break;
31838       case 7 /* reference_thread_time_us */:
31839         field.get(&reference_thread_time_us_);
31840         break;
31841       case 8 /* reference_thread_instruction_count */:
31842         field.get(&reference_thread_instruction_count_);
31843         break;
31844       case 3 /* legacy_sort_index */:
31845         field.get(&legacy_sort_index_);
31846         break;
31847       default:
31848         field.SerializeAndAppendTo(&unknown_fields_);
31849         break;
31850     }
31851   }
31852   return !packed_error && !dec.bytes_left();
31853 }
31854 
SerializeAsString() const31855 std::string ThreadDescriptor::SerializeAsString() const {
31856   ::protozero::HeapBuffered<::protozero::Message> msg;
31857   Serialize(msg.get());
31858   return msg.SerializeAsString();
31859 }
31860 
SerializeAsArray() const31861 std::vector<uint8_t> ThreadDescriptor::SerializeAsArray() const {
31862   ::protozero::HeapBuffered<::protozero::Message> msg;
31863   Serialize(msg.get());
31864   return msg.SerializeAsArray();
31865 }
31866 
Serialize(::protozero::Message * msg) const31867 void ThreadDescriptor::Serialize(::protozero::Message* msg) const {
31868   // Field 1: pid
31869   if (_has_field_[1]) {
31870     msg->AppendVarInt(1, pid_);
31871   }
31872 
31873   // Field 2: tid
31874   if (_has_field_[2]) {
31875     msg->AppendVarInt(2, tid_);
31876   }
31877 
31878   // Field 5: thread_name
31879   if (_has_field_[5]) {
31880     msg->AppendString(5, thread_name_);
31881   }
31882 
31883   // Field 4: chrome_thread_type
31884   if (_has_field_[4]) {
31885     msg->AppendVarInt(4, chrome_thread_type_);
31886   }
31887 
31888   // Field 6: reference_timestamp_us
31889   if (_has_field_[6]) {
31890     msg->AppendVarInt(6, reference_timestamp_us_);
31891   }
31892 
31893   // Field 7: reference_thread_time_us
31894   if (_has_field_[7]) {
31895     msg->AppendVarInt(7, reference_thread_time_us_);
31896   }
31897 
31898   // Field 8: reference_thread_instruction_count
31899   if (_has_field_[8]) {
31900     msg->AppendVarInt(8, reference_thread_instruction_count_);
31901   }
31902 
31903   // Field 3: legacy_sort_index
31904   if (_has_field_[3]) {
31905     msg->AppendVarInt(3, legacy_sort_index_);
31906   }
31907 
31908   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
31909 }
31910 
31911 }  // namespace perfetto
31912 }  // namespace protos
31913 }  // namespace gen
31914 #if defined(__GNUC__) || defined(__clang__)
31915 #pragma GCC diagnostic pop
31916 #endif
31917 // gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/track_descriptor.gen.cc
31918 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
31919 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
31920 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
31921 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
31922 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
31923 #if defined(__GNUC__) || defined(__clang__)
31924 #pragma GCC diagnostic push
31925 #pragma GCC diagnostic ignored "-Wfloat-equal"
31926 #endif
31927 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/track_descriptor.gen.h"
31928 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/counter_descriptor.gen.h"
31929 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/thread_descriptor.gen.h"
31930 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/process_descriptor.gen.h"
31931 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_thread_descriptor.gen.h"
31932 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_process_descriptor.gen.h"
31933 
31934 namespace perfetto {
31935 namespace protos {
31936 namespace gen {
31937 
31938 TrackDescriptor::TrackDescriptor() = default;
31939 TrackDescriptor::~TrackDescriptor() = default;
31940 TrackDescriptor::TrackDescriptor(const TrackDescriptor&) = default;
31941 TrackDescriptor& TrackDescriptor::operator=(const TrackDescriptor&) = default;
31942 TrackDescriptor::TrackDescriptor(TrackDescriptor&&) noexcept = default;
31943 TrackDescriptor& TrackDescriptor::operator=(TrackDescriptor&&) = default;
31944 
operator ==(const TrackDescriptor & other) const31945 bool TrackDescriptor::operator==(const TrackDescriptor& other) const {
31946   return unknown_fields_ == other.unknown_fields_
31947    && uuid_ == other.uuid_
31948    && parent_uuid_ == other.parent_uuid_
31949    && name_ == other.name_
31950    && process_ == other.process_
31951    && chrome_process_ == other.chrome_process_
31952    && thread_ == other.thread_
31953    && chrome_thread_ == other.chrome_thread_
31954    && counter_ == other.counter_;
31955 }
31956 
ParseFromArray(const void * raw,size_t size)31957 bool TrackDescriptor::ParseFromArray(const void* raw, size_t size) {
31958   unknown_fields_.clear();
31959   bool packed_error = false;
31960 
31961   ::protozero::ProtoDecoder dec(raw, size);
31962   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
31963     if (field.id() < _has_field_.size()) {
31964       _has_field_.set(field.id());
31965     }
31966     switch (field.id()) {
31967       case 1 /* uuid */:
31968         field.get(&uuid_);
31969         break;
31970       case 5 /* parent_uuid */:
31971         field.get(&parent_uuid_);
31972         break;
31973       case 2 /* name */:
31974         field.get(&name_);
31975         break;
31976       case 3 /* process */:
31977         (*process_).ParseFromArray(field.data(), field.size());
31978         break;
31979       case 6 /* chrome_process */:
31980         (*chrome_process_).ParseFromArray(field.data(), field.size());
31981         break;
31982       case 4 /* thread */:
31983         (*thread_).ParseFromArray(field.data(), field.size());
31984         break;
31985       case 7 /* chrome_thread */:
31986         (*chrome_thread_).ParseFromArray(field.data(), field.size());
31987         break;
31988       case 8 /* counter */:
31989         (*counter_).ParseFromArray(field.data(), field.size());
31990         break;
31991       default:
31992         field.SerializeAndAppendTo(&unknown_fields_);
31993         break;
31994     }
31995   }
31996   return !packed_error && !dec.bytes_left();
31997 }
31998 
SerializeAsString() const31999 std::string TrackDescriptor::SerializeAsString() const {
32000   ::protozero::HeapBuffered<::protozero::Message> msg;
32001   Serialize(msg.get());
32002   return msg.SerializeAsString();
32003 }
32004 
SerializeAsArray() const32005 std::vector<uint8_t> TrackDescriptor::SerializeAsArray() const {
32006   ::protozero::HeapBuffered<::protozero::Message> msg;
32007   Serialize(msg.get());
32008   return msg.SerializeAsArray();
32009 }
32010 
Serialize(::protozero::Message * msg) const32011 void TrackDescriptor::Serialize(::protozero::Message* msg) const {
32012   // Field 1: uuid
32013   if (_has_field_[1]) {
32014     msg->AppendVarInt(1, uuid_);
32015   }
32016 
32017   // Field 5: parent_uuid
32018   if (_has_field_[5]) {
32019     msg->AppendVarInt(5, parent_uuid_);
32020   }
32021 
32022   // Field 2: name
32023   if (_has_field_[2]) {
32024     msg->AppendString(2, name_);
32025   }
32026 
32027   // Field 3: process
32028   if (_has_field_[3]) {
32029     (*process_).Serialize(msg->BeginNestedMessage<::protozero::Message>(3));
32030   }
32031 
32032   // Field 6: chrome_process
32033   if (_has_field_[6]) {
32034     (*chrome_process_).Serialize(msg->BeginNestedMessage<::protozero::Message>(6));
32035   }
32036 
32037   // Field 4: thread
32038   if (_has_field_[4]) {
32039     (*thread_).Serialize(msg->BeginNestedMessage<::protozero::Message>(4));
32040   }
32041 
32042   // Field 7: chrome_thread
32043   if (_has_field_[7]) {
32044     (*chrome_thread_).Serialize(msg->BeginNestedMessage<::protozero::Message>(7));
32045   }
32046 
32047   // Field 8: counter
32048   if (_has_field_[8]) {
32049     (*counter_).Serialize(msg->BeginNestedMessage<::protozero::Message>(8));
32050   }
32051 
32052   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
32053 }
32054 
32055 }  // namespace perfetto
32056 }  // namespace protos
32057 }  // namespace gen
32058 #if defined(__GNUC__) || defined(__clang__)
32059 #pragma GCC diagnostic pop
32060 #endif
32061 // gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/track_event.gen.cc
32062 // gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/track_event.gen.h
32063 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
32064 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_TRACK_EVENT_PROTO_CPP_H_
32065 #define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_TRACK_EVENT_PROTO_CPP_H_
32066 
32067 #include <stdint.h>
32068 #include <bitset>
32069 #include <vector>
32070 #include <string>
32071 #include <type_traits>
32072 
32073 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
32074 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
32075 // gen_amalgamated expanded: #include "perfetto/base/export.h"
32076 
32077 namespace perfetto {
32078 namespace protos {
32079 namespace gen {
32080 class EventName;
32081 class EventCategory;
32082 class TrackEventDefaults;
32083 class TrackEvent;
32084 class TrackEvent_LegacyEvent;
32085 class ChromeMojoEventInfo;
32086 class ChromeMessagePump;
32087 class SourceLocation;
32088 class ChromeContentSettingsEventInfo;
32089 class ChromeWindowHandleEventInfo;
32090 class ChromeRendererSchedulerState;
32091 class ChromeApplicationStateInfo;
32092 class ChromeFrameReporter;
32093 class ChromeLatencyInfo;
32094 class ChromeLatencyInfo_ComponentInfo;
32095 class ChromeHistogramSample;
32096 class ChromeLegacyIpc;
32097 class ChromeKeyedService;
32098 class ChromeUserEvent;
32099 class ChromeCompositorSchedulerState;
32100 class CompositorTimingHistory;
32101 class BeginFrameSourceState;
32102 class BeginFrameArgs;
32103 class BeginFrameObserverState;
32104 class BeginImplFrameArgs;
32105 class BeginImplFrameArgs_TimestampsInUs;
32106 class ChromeCompositorStateMachine;
32107 class ChromeCompositorStateMachine_MinorState;
32108 class ChromeCompositorStateMachine_MajorState;
32109 class LogMessage;
32110 class TaskExecution;
32111 class DebugAnnotation;
32112 class DebugAnnotation_NestedValue;
32113 enum TrackEvent_Type : int;
32114 enum TrackEvent_LegacyEvent_FlowDirection : int;
32115 enum TrackEvent_LegacyEvent_InstantEventScope : int;
32116 enum ChromeRAILMode : int;
32117 enum ChromeApplicationStateInfo_ChromeApplicationState : int;
32118 enum ChromeFrameReporter_State : int;
32119 enum ChromeFrameReporter_FrameDropReason : int;
32120 enum ChromeFrameReporter_ScrollState : int;
32121 enum ChromeLatencyInfo_Step : int;
32122 enum ChromeLatencyInfo_LatencyComponentType : int;
32123 enum ChromeLegacyIpc_MessageClass : int;
32124 enum ChromeCompositorSchedulerState_BeginImplFrameDeadlineMode : int;
32125 enum ChromeCompositorSchedulerAction : int;
32126 enum BeginFrameArgs_BeginFrameArgsType : int;
32127 enum BeginImplFrameArgs_State : int;
32128 enum ChromeCompositorStateMachine_MinorState_TreePriority : int;
32129 enum ChromeCompositorStateMachine_MinorState_ScrollHandlerState : int;
32130 enum ChromeCompositorStateMachine_MajorState_BeginImplFrameState : int;
32131 enum ChromeCompositorStateMachine_MajorState_BeginMainFrameState : int;
32132 enum ChromeCompositorStateMachine_MajorState_LayerTreeFrameSinkState : int;
32133 enum ChromeCompositorStateMachine_MajorState_ForcedRedrawOnTimeoutState : int;
32134 enum DebugAnnotation_NestedValue_NestedType : int;
32135 }  // namespace perfetto
32136 }  // namespace protos
32137 }  // namespace gen
32138 
32139 namespace protozero {
32140 class Message;
32141 }  // namespace protozero
32142 
32143 namespace perfetto {
32144 namespace protos {
32145 namespace gen {
32146 enum TrackEvent_Type : int {
32147   TrackEvent_Type_TYPE_UNSPECIFIED = 0,
32148   TrackEvent_Type_TYPE_SLICE_BEGIN = 1,
32149   TrackEvent_Type_TYPE_SLICE_END = 2,
32150   TrackEvent_Type_TYPE_INSTANT = 3,
32151   TrackEvent_Type_TYPE_COUNTER = 4,
32152 };
32153 enum TrackEvent_LegacyEvent_FlowDirection : int {
32154   TrackEvent_LegacyEvent_FlowDirection_FLOW_UNSPECIFIED = 0,
32155   TrackEvent_LegacyEvent_FlowDirection_FLOW_IN = 1,
32156   TrackEvent_LegacyEvent_FlowDirection_FLOW_OUT = 2,
32157   TrackEvent_LegacyEvent_FlowDirection_FLOW_INOUT = 3,
32158 };
32159 enum TrackEvent_LegacyEvent_InstantEventScope : int {
32160   TrackEvent_LegacyEvent_InstantEventScope_SCOPE_UNSPECIFIED = 0,
32161   TrackEvent_LegacyEvent_InstantEventScope_SCOPE_GLOBAL = 1,
32162   TrackEvent_LegacyEvent_InstantEventScope_SCOPE_PROCESS = 2,
32163   TrackEvent_LegacyEvent_InstantEventScope_SCOPE_THREAD = 3,
32164 };
32165 
32166 class PERFETTO_EXPORT EventName : public ::protozero::CppMessageObj {
32167  public:
32168   enum FieldNumbers {
32169     kIidFieldNumber = 1,
32170     kNameFieldNumber = 2,
32171   };
32172 
32173   EventName();
32174   ~EventName() override;
32175   EventName(EventName&&) noexcept;
32176   EventName& operator=(EventName&&);
32177   EventName(const EventName&);
32178   EventName& operator=(const EventName&);
32179   bool operator==(const EventName&) const;
operator !=(const EventName & other) const32180   bool operator!=(const EventName& other) const { return !(*this == other); }
32181 
32182   bool ParseFromArray(const void*, size_t) override;
32183   std::string SerializeAsString() const override;
32184   std::vector<uint8_t> SerializeAsArray() const override;
32185   void Serialize(::protozero::Message*) const;
32186 
has_iid() const32187   bool has_iid() const { return _has_field_[1]; }
iid() const32188   uint64_t iid() const { return iid_; }
set_iid(uint64_t value)32189   void set_iid(uint64_t value) { iid_ = value; _has_field_.set(1); }
32190 
has_name() const32191   bool has_name() const { return _has_field_[2]; }
name() const32192   const std::string& name() const { return name_; }
set_name(const std::string & value)32193   void set_name(const std::string& value) { name_ = value; _has_field_.set(2); }
32194 
32195  private:
32196   uint64_t iid_{};
32197   std::string name_{};
32198 
32199   // Allows to preserve unknown protobuf fields for compatibility
32200   // with future versions of .proto files.
32201   std::string unknown_fields_;
32202 
32203   std::bitset<3> _has_field_{};
32204 };
32205 
32206 
32207 class PERFETTO_EXPORT EventCategory : public ::protozero::CppMessageObj {
32208  public:
32209   enum FieldNumbers {
32210     kIidFieldNumber = 1,
32211     kNameFieldNumber = 2,
32212   };
32213 
32214   EventCategory();
32215   ~EventCategory() override;
32216   EventCategory(EventCategory&&) noexcept;
32217   EventCategory& operator=(EventCategory&&);
32218   EventCategory(const EventCategory&);
32219   EventCategory& operator=(const EventCategory&);
32220   bool operator==(const EventCategory&) const;
operator !=(const EventCategory & other) const32221   bool operator!=(const EventCategory& other) const { return !(*this == other); }
32222 
32223   bool ParseFromArray(const void*, size_t) override;
32224   std::string SerializeAsString() const override;
32225   std::vector<uint8_t> SerializeAsArray() const override;
32226   void Serialize(::protozero::Message*) const;
32227 
has_iid() const32228   bool has_iid() const { return _has_field_[1]; }
iid() const32229   uint64_t iid() const { return iid_; }
set_iid(uint64_t value)32230   void set_iid(uint64_t value) { iid_ = value; _has_field_.set(1); }
32231 
has_name() const32232   bool has_name() const { return _has_field_[2]; }
name() const32233   const std::string& name() const { return name_; }
set_name(const std::string & value)32234   void set_name(const std::string& value) { name_ = value; _has_field_.set(2); }
32235 
32236  private:
32237   uint64_t iid_{};
32238   std::string name_{};
32239 
32240   // Allows to preserve unknown protobuf fields for compatibility
32241   // with future versions of .proto files.
32242   std::string unknown_fields_;
32243 
32244   std::bitset<3> _has_field_{};
32245 };
32246 
32247 
32248 class PERFETTO_EXPORT TrackEventDefaults : public ::protozero::CppMessageObj {
32249  public:
32250   enum FieldNumbers {
32251     kTrackUuidFieldNumber = 11,
32252     kExtraCounterTrackUuidsFieldNumber = 31,
32253     kExtraDoubleCounterTrackUuidsFieldNumber = 45,
32254   };
32255 
32256   TrackEventDefaults();
32257   ~TrackEventDefaults() override;
32258   TrackEventDefaults(TrackEventDefaults&&) noexcept;
32259   TrackEventDefaults& operator=(TrackEventDefaults&&);
32260   TrackEventDefaults(const TrackEventDefaults&);
32261   TrackEventDefaults& operator=(const TrackEventDefaults&);
32262   bool operator==(const TrackEventDefaults&) const;
operator !=(const TrackEventDefaults & other) const32263   bool operator!=(const TrackEventDefaults& other) const { return !(*this == other); }
32264 
32265   bool ParseFromArray(const void*, size_t) override;
32266   std::string SerializeAsString() const override;
32267   std::vector<uint8_t> SerializeAsArray() const override;
32268   void Serialize(::protozero::Message*) const;
32269 
has_track_uuid() const32270   bool has_track_uuid() const { return _has_field_[11]; }
track_uuid() const32271   uint64_t track_uuid() const { return track_uuid_; }
set_track_uuid(uint64_t value)32272   void set_track_uuid(uint64_t value) { track_uuid_ = value; _has_field_.set(11); }
32273 
extra_counter_track_uuids() const32274   const std::vector<uint64_t>& extra_counter_track_uuids() const { return extra_counter_track_uuids_; }
mutable_extra_counter_track_uuids()32275   std::vector<uint64_t>* mutable_extra_counter_track_uuids() { return &extra_counter_track_uuids_; }
extra_counter_track_uuids_size() const32276   int extra_counter_track_uuids_size() const { return static_cast<int>(extra_counter_track_uuids_.size()); }
clear_extra_counter_track_uuids()32277   void clear_extra_counter_track_uuids() { extra_counter_track_uuids_.clear(); }
add_extra_counter_track_uuids(uint64_t value)32278   void add_extra_counter_track_uuids(uint64_t value) { extra_counter_track_uuids_.emplace_back(value); }
add_extra_counter_track_uuids()32279   uint64_t* add_extra_counter_track_uuids() { extra_counter_track_uuids_.emplace_back(); return &extra_counter_track_uuids_.back(); }
32280 
extra_double_counter_track_uuids() const32281   const std::vector<uint64_t>& extra_double_counter_track_uuids() const { return extra_double_counter_track_uuids_; }
mutable_extra_double_counter_track_uuids()32282   std::vector<uint64_t>* mutable_extra_double_counter_track_uuids() { return &extra_double_counter_track_uuids_; }
extra_double_counter_track_uuids_size() const32283   int extra_double_counter_track_uuids_size() const { return static_cast<int>(extra_double_counter_track_uuids_.size()); }
clear_extra_double_counter_track_uuids()32284   void clear_extra_double_counter_track_uuids() { extra_double_counter_track_uuids_.clear(); }
add_extra_double_counter_track_uuids(uint64_t value)32285   void add_extra_double_counter_track_uuids(uint64_t value) { extra_double_counter_track_uuids_.emplace_back(value); }
add_extra_double_counter_track_uuids()32286   uint64_t* add_extra_double_counter_track_uuids() { extra_double_counter_track_uuids_.emplace_back(); return &extra_double_counter_track_uuids_.back(); }
32287 
32288  private:
32289   uint64_t track_uuid_{};
32290   std::vector<uint64_t> extra_counter_track_uuids_;
32291   std::vector<uint64_t> extra_double_counter_track_uuids_;
32292 
32293   // Allows to preserve unknown protobuf fields for compatibility
32294   // with future versions of .proto files.
32295   std::string unknown_fields_;
32296 
32297   std::bitset<46> _has_field_{};
32298 };
32299 
32300 
32301 class PERFETTO_EXPORT TrackEvent : public ::protozero::CppMessageObj {
32302  public:
32303   using LegacyEvent = TrackEvent_LegacyEvent;
32304   using Type = TrackEvent_Type;
32305   static constexpr auto TYPE_UNSPECIFIED = TrackEvent_Type_TYPE_UNSPECIFIED;
32306   static constexpr auto TYPE_SLICE_BEGIN = TrackEvent_Type_TYPE_SLICE_BEGIN;
32307   static constexpr auto TYPE_SLICE_END = TrackEvent_Type_TYPE_SLICE_END;
32308   static constexpr auto TYPE_INSTANT = TrackEvent_Type_TYPE_INSTANT;
32309   static constexpr auto TYPE_COUNTER = TrackEvent_Type_TYPE_COUNTER;
32310   static constexpr auto Type_MIN = TrackEvent_Type_TYPE_UNSPECIFIED;
32311   static constexpr auto Type_MAX = TrackEvent_Type_TYPE_COUNTER;
32312   enum FieldNumbers {
32313     kCategoryIidsFieldNumber = 3,
32314     kCategoriesFieldNumber = 22,
32315     kNameIidFieldNumber = 10,
32316     kNameFieldNumber = 23,
32317     kTypeFieldNumber = 9,
32318     kTrackUuidFieldNumber = 11,
32319     kCounterValueFieldNumber = 30,
32320     kDoubleCounterValueFieldNumber = 44,
32321     kExtraCounterTrackUuidsFieldNumber = 31,
32322     kExtraCounterValuesFieldNumber = 12,
32323     kExtraDoubleCounterTrackUuidsFieldNumber = 45,
32324     kExtraDoubleCounterValuesFieldNumber = 46,
32325     kFlowIdsFieldNumber = 36,
32326     kTerminatingFlowIdsFieldNumber = 42,
32327     kDebugAnnotationsFieldNumber = 4,
32328     kTaskExecutionFieldNumber = 5,
32329     kLogMessageFieldNumber = 21,
32330     kCcSchedulerStateFieldNumber = 24,
32331     kChromeUserEventFieldNumber = 25,
32332     kChromeKeyedServiceFieldNumber = 26,
32333     kChromeLegacyIpcFieldNumber = 27,
32334     kChromeHistogramSampleFieldNumber = 28,
32335     kChromeLatencyInfoFieldNumber = 29,
32336     kChromeFrameReporterFieldNumber = 32,
32337     kChromeApplicationStateInfoFieldNumber = 39,
32338     kChromeRendererSchedulerStateFieldNumber = 40,
32339     kChromeWindowHandleEventInfoFieldNumber = 41,
32340     kChromeContentSettingsEventInfoFieldNumber = 43,
32341     kSourceLocationFieldNumber = 33,
32342     kSourceLocationIidFieldNumber = 34,
32343     kChromeMessagePumpFieldNumber = 35,
32344     kChromeMojoEventInfoFieldNumber = 38,
32345     kTimestampDeltaUsFieldNumber = 1,
32346     kTimestampAbsoluteUsFieldNumber = 16,
32347     kThreadTimeDeltaUsFieldNumber = 2,
32348     kThreadTimeAbsoluteUsFieldNumber = 17,
32349     kThreadInstructionCountDeltaFieldNumber = 8,
32350     kThreadInstructionCountAbsoluteFieldNumber = 20,
32351     kLegacyEventFieldNumber = 6,
32352   };
32353 
32354   TrackEvent();
32355   ~TrackEvent() override;
32356   TrackEvent(TrackEvent&&) noexcept;
32357   TrackEvent& operator=(TrackEvent&&);
32358   TrackEvent(const TrackEvent&);
32359   TrackEvent& operator=(const TrackEvent&);
32360   bool operator==(const TrackEvent&) const;
operator !=(const TrackEvent & other) const32361   bool operator!=(const TrackEvent& other) const { return !(*this == other); }
32362 
32363   bool ParseFromArray(const void*, size_t) override;
32364   std::string SerializeAsString() const override;
32365   std::vector<uint8_t> SerializeAsArray() const override;
32366   void Serialize(::protozero::Message*) const;
32367 
category_iids() const32368   const std::vector<uint64_t>& category_iids() const { return category_iids_; }
mutable_category_iids()32369   std::vector<uint64_t>* mutable_category_iids() { return &category_iids_; }
category_iids_size() const32370   int category_iids_size() const { return static_cast<int>(category_iids_.size()); }
clear_category_iids()32371   void clear_category_iids() { category_iids_.clear(); }
add_category_iids(uint64_t value)32372   void add_category_iids(uint64_t value) { category_iids_.emplace_back(value); }
add_category_iids()32373   uint64_t* add_category_iids() { category_iids_.emplace_back(); return &category_iids_.back(); }
32374 
categories() const32375   const std::vector<std::string>& categories() const { return categories_; }
mutable_categories()32376   std::vector<std::string>* mutable_categories() { return &categories_; }
categories_size() const32377   int categories_size() const { return static_cast<int>(categories_.size()); }
clear_categories()32378   void clear_categories() { categories_.clear(); }
add_categories(std::string value)32379   void add_categories(std::string value) { categories_.emplace_back(value); }
add_categories()32380   std::string* add_categories() { categories_.emplace_back(); return &categories_.back(); }
32381 
has_name_iid() const32382   bool has_name_iid() const { return _has_field_[10]; }
name_iid() const32383   uint64_t name_iid() const { return name_iid_; }
set_name_iid(uint64_t value)32384   void set_name_iid(uint64_t value) { name_iid_ = value; _has_field_.set(10); }
32385 
has_name() const32386   bool has_name() const { return _has_field_[23]; }
name() const32387   const std::string& name() const { return name_; }
set_name(const std::string & value)32388   void set_name(const std::string& value) { name_ = value; _has_field_.set(23); }
32389 
has_type() const32390   bool has_type() const { return _has_field_[9]; }
type() const32391   TrackEvent_Type type() const { return type_; }
set_type(TrackEvent_Type value)32392   void set_type(TrackEvent_Type value) { type_ = value; _has_field_.set(9); }
32393 
has_track_uuid() const32394   bool has_track_uuid() const { return _has_field_[11]; }
track_uuid() const32395   uint64_t track_uuid() const { return track_uuid_; }
set_track_uuid(uint64_t value)32396   void set_track_uuid(uint64_t value) { track_uuid_ = value; _has_field_.set(11); }
32397 
has_counter_value() const32398   bool has_counter_value() const { return _has_field_[30]; }
counter_value() const32399   int64_t counter_value() const { return counter_value_; }
set_counter_value(int64_t value)32400   void set_counter_value(int64_t value) { counter_value_ = value; _has_field_.set(30); }
32401 
has_double_counter_value() const32402   bool has_double_counter_value() const { return _has_field_[44]; }
double_counter_value() const32403   double double_counter_value() const { return double_counter_value_; }
set_double_counter_value(double value)32404   void set_double_counter_value(double value) { double_counter_value_ = value; _has_field_.set(44); }
32405 
extra_counter_track_uuids() const32406   const std::vector<uint64_t>& extra_counter_track_uuids() const { return extra_counter_track_uuids_; }
mutable_extra_counter_track_uuids()32407   std::vector<uint64_t>* mutable_extra_counter_track_uuids() { return &extra_counter_track_uuids_; }
extra_counter_track_uuids_size() const32408   int extra_counter_track_uuids_size() const { return static_cast<int>(extra_counter_track_uuids_.size()); }
clear_extra_counter_track_uuids()32409   void clear_extra_counter_track_uuids() { extra_counter_track_uuids_.clear(); }
add_extra_counter_track_uuids(uint64_t value)32410   void add_extra_counter_track_uuids(uint64_t value) { extra_counter_track_uuids_.emplace_back(value); }
add_extra_counter_track_uuids()32411   uint64_t* add_extra_counter_track_uuids() { extra_counter_track_uuids_.emplace_back(); return &extra_counter_track_uuids_.back(); }
32412 
extra_counter_values() const32413   const std::vector<int64_t>& extra_counter_values() const { return extra_counter_values_; }
mutable_extra_counter_values()32414   std::vector<int64_t>* mutable_extra_counter_values() { return &extra_counter_values_; }
extra_counter_values_size() const32415   int extra_counter_values_size() const { return static_cast<int>(extra_counter_values_.size()); }
clear_extra_counter_values()32416   void clear_extra_counter_values() { extra_counter_values_.clear(); }
add_extra_counter_values(int64_t value)32417   void add_extra_counter_values(int64_t value) { extra_counter_values_.emplace_back(value); }
add_extra_counter_values()32418   int64_t* add_extra_counter_values() { extra_counter_values_.emplace_back(); return &extra_counter_values_.back(); }
32419 
extra_double_counter_track_uuids() const32420   const std::vector<uint64_t>& extra_double_counter_track_uuids() const { return extra_double_counter_track_uuids_; }
mutable_extra_double_counter_track_uuids()32421   std::vector<uint64_t>* mutable_extra_double_counter_track_uuids() { return &extra_double_counter_track_uuids_; }
extra_double_counter_track_uuids_size() const32422   int extra_double_counter_track_uuids_size() const { return static_cast<int>(extra_double_counter_track_uuids_.size()); }
clear_extra_double_counter_track_uuids()32423   void clear_extra_double_counter_track_uuids() { extra_double_counter_track_uuids_.clear(); }
add_extra_double_counter_track_uuids(uint64_t value)32424   void add_extra_double_counter_track_uuids(uint64_t value) { extra_double_counter_track_uuids_.emplace_back(value); }
add_extra_double_counter_track_uuids()32425   uint64_t* add_extra_double_counter_track_uuids() { extra_double_counter_track_uuids_.emplace_back(); return &extra_double_counter_track_uuids_.back(); }
32426 
extra_double_counter_values() const32427   const std::vector<double>& extra_double_counter_values() const { return extra_double_counter_values_; }
mutable_extra_double_counter_values()32428   std::vector<double>* mutable_extra_double_counter_values() { return &extra_double_counter_values_; }
extra_double_counter_values_size() const32429   int extra_double_counter_values_size() const { return static_cast<int>(extra_double_counter_values_.size()); }
clear_extra_double_counter_values()32430   void clear_extra_double_counter_values() { extra_double_counter_values_.clear(); }
add_extra_double_counter_values(double value)32431   void add_extra_double_counter_values(double value) { extra_double_counter_values_.emplace_back(value); }
add_extra_double_counter_values()32432   double* add_extra_double_counter_values() { extra_double_counter_values_.emplace_back(); return &extra_double_counter_values_.back(); }
32433 
flow_ids() const32434   const std::vector<uint64_t>& flow_ids() const { return flow_ids_; }
mutable_flow_ids()32435   std::vector<uint64_t>* mutable_flow_ids() { return &flow_ids_; }
flow_ids_size() const32436   int flow_ids_size() const { return static_cast<int>(flow_ids_.size()); }
clear_flow_ids()32437   void clear_flow_ids() { flow_ids_.clear(); }
add_flow_ids(uint64_t value)32438   void add_flow_ids(uint64_t value) { flow_ids_.emplace_back(value); }
add_flow_ids()32439   uint64_t* add_flow_ids() { flow_ids_.emplace_back(); return &flow_ids_.back(); }
32440 
terminating_flow_ids() const32441   const std::vector<uint64_t>& terminating_flow_ids() const { return terminating_flow_ids_; }
mutable_terminating_flow_ids()32442   std::vector<uint64_t>* mutable_terminating_flow_ids() { return &terminating_flow_ids_; }
terminating_flow_ids_size() const32443   int terminating_flow_ids_size() const { return static_cast<int>(terminating_flow_ids_.size()); }
clear_terminating_flow_ids()32444   void clear_terminating_flow_ids() { terminating_flow_ids_.clear(); }
add_terminating_flow_ids(uint64_t value)32445   void add_terminating_flow_ids(uint64_t value) { terminating_flow_ids_.emplace_back(value); }
add_terminating_flow_ids()32446   uint64_t* add_terminating_flow_ids() { terminating_flow_ids_.emplace_back(); return &terminating_flow_ids_.back(); }
32447 
debug_annotations() const32448   const std::vector<DebugAnnotation>& debug_annotations() const { return debug_annotations_; }
mutable_debug_annotations()32449   std::vector<DebugAnnotation>* mutable_debug_annotations() { return &debug_annotations_; }
32450   int debug_annotations_size() const;
32451   void clear_debug_annotations();
32452   DebugAnnotation* add_debug_annotations();
32453 
has_task_execution() const32454   bool has_task_execution() const { return _has_field_[5]; }
task_execution() const32455   const TaskExecution& task_execution() const { return *task_execution_; }
mutable_task_execution()32456   TaskExecution* mutable_task_execution() { _has_field_.set(5); return task_execution_.get(); }
32457 
has_log_message() const32458   bool has_log_message() const { return _has_field_[21]; }
log_message() const32459   const LogMessage& log_message() const { return *log_message_; }
mutable_log_message()32460   LogMessage* mutable_log_message() { _has_field_.set(21); return log_message_.get(); }
32461 
has_cc_scheduler_state() const32462   bool has_cc_scheduler_state() const { return _has_field_[24]; }
cc_scheduler_state() const32463   const ChromeCompositorSchedulerState& cc_scheduler_state() const { return *cc_scheduler_state_; }
mutable_cc_scheduler_state()32464   ChromeCompositorSchedulerState* mutable_cc_scheduler_state() { _has_field_.set(24); return cc_scheduler_state_.get(); }
32465 
has_chrome_user_event() const32466   bool has_chrome_user_event() const { return _has_field_[25]; }
chrome_user_event() const32467   const ChromeUserEvent& chrome_user_event() const { return *chrome_user_event_; }
mutable_chrome_user_event()32468   ChromeUserEvent* mutable_chrome_user_event() { _has_field_.set(25); return chrome_user_event_.get(); }
32469 
has_chrome_keyed_service() const32470   bool has_chrome_keyed_service() const { return _has_field_[26]; }
chrome_keyed_service() const32471   const ChromeKeyedService& chrome_keyed_service() const { return *chrome_keyed_service_; }
mutable_chrome_keyed_service()32472   ChromeKeyedService* mutable_chrome_keyed_service() { _has_field_.set(26); return chrome_keyed_service_.get(); }
32473 
has_chrome_legacy_ipc() const32474   bool has_chrome_legacy_ipc() const { return _has_field_[27]; }
chrome_legacy_ipc() const32475   const ChromeLegacyIpc& chrome_legacy_ipc() const { return *chrome_legacy_ipc_; }
mutable_chrome_legacy_ipc()32476   ChromeLegacyIpc* mutable_chrome_legacy_ipc() { _has_field_.set(27); return chrome_legacy_ipc_.get(); }
32477 
has_chrome_histogram_sample() const32478   bool has_chrome_histogram_sample() const { return _has_field_[28]; }
chrome_histogram_sample() const32479   const ChromeHistogramSample& chrome_histogram_sample() const { return *chrome_histogram_sample_; }
mutable_chrome_histogram_sample()32480   ChromeHistogramSample* mutable_chrome_histogram_sample() { _has_field_.set(28); return chrome_histogram_sample_.get(); }
32481 
has_chrome_latency_info() const32482   bool has_chrome_latency_info() const { return _has_field_[29]; }
chrome_latency_info() const32483   const ChromeLatencyInfo& chrome_latency_info() const { return *chrome_latency_info_; }
mutable_chrome_latency_info()32484   ChromeLatencyInfo* mutable_chrome_latency_info() { _has_field_.set(29); return chrome_latency_info_.get(); }
32485 
has_chrome_frame_reporter() const32486   bool has_chrome_frame_reporter() const { return _has_field_[32]; }
chrome_frame_reporter() const32487   const ChromeFrameReporter& chrome_frame_reporter() const { return *chrome_frame_reporter_; }
mutable_chrome_frame_reporter()32488   ChromeFrameReporter* mutable_chrome_frame_reporter() { _has_field_.set(32); return chrome_frame_reporter_.get(); }
32489 
has_chrome_application_state_info() const32490   bool has_chrome_application_state_info() const { return _has_field_[39]; }
chrome_application_state_info() const32491   const ChromeApplicationStateInfo& chrome_application_state_info() const { return *chrome_application_state_info_; }
mutable_chrome_application_state_info()32492   ChromeApplicationStateInfo* mutable_chrome_application_state_info() { _has_field_.set(39); return chrome_application_state_info_.get(); }
32493 
has_chrome_renderer_scheduler_state() const32494   bool has_chrome_renderer_scheduler_state() const { return _has_field_[40]; }
chrome_renderer_scheduler_state() const32495   const ChromeRendererSchedulerState& chrome_renderer_scheduler_state() const { return *chrome_renderer_scheduler_state_; }
mutable_chrome_renderer_scheduler_state()32496   ChromeRendererSchedulerState* mutable_chrome_renderer_scheduler_state() { _has_field_.set(40); return chrome_renderer_scheduler_state_.get(); }
32497 
has_chrome_window_handle_event_info() const32498   bool has_chrome_window_handle_event_info() const { return _has_field_[41]; }
chrome_window_handle_event_info() const32499   const ChromeWindowHandleEventInfo& chrome_window_handle_event_info() const { return *chrome_window_handle_event_info_; }
mutable_chrome_window_handle_event_info()32500   ChromeWindowHandleEventInfo* mutable_chrome_window_handle_event_info() { _has_field_.set(41); return chrome_window_handle_event_info_.get(); }
32501 
has_chrome_content_settings_event_info() const32502   bool has_chrome_content_settings_event_info() const { return _has_field_[43]; }
chrome_content_settings_event_info() const32503   const ChromeContentSettingsEventInfo& chrome_content_settings_event_info() const { return *chrome_content_settings_event_info_; }
mutable_chrome_content_settings_event_info()32504   ChromeContentSettingsEventInfo* mutable_chrome_content_settings_event_info() { _has_field_.set(43); return chrome_content_settings_event_info_.get(); }
32505 
has_source_location() const32506   bool has_source_location() const { return _has_field_[33]; }
source_location() const32507   const SourceLocation& source_location() const { return *source_location_; }
mutable_source_location()32508   SourceLocation* mutable_source_location() { _has_field_.set(33); return source_location_.get(); }
32509 
has_source_location_iid() const32510   bool has_source_location_iid() const { return _has_field_[34]; }
source_location_iid() const32511   uint64_t source_location_iid() const { return source_location_iid_; }
set_source_location_iid(uint64_t value)32512   void set_source_location_iid(uint64_t value) { source_location_iid_ = value; _has_field_.set(34); }
32513 
has_chrome_message_pump() const32514   bool has_chrome_message_pump() const { return _has_field_[35]; }
chrome_message_pump() const32515   const ChromeMessagePump& chrome_message_pump() const { return *chrome_message_pump_; }
mutable_chrome_message_pump()32516   ChromeMessagePump* mutable_chrome_message_pump() { _has_field_.set(35); return chrome_message_pump_.get(); }
32517 
has_chrome_mojo_event_info() const32518   bool has_chrome_mojo_event_info() const { return _has_field_[38]; }
chrome_mojo_event_info() const32519   const ChromeMojoEventInfo& chrome_mojo_event_info() const { return *chrome_mojo_event_info_; }
mutable_chrome_mojo_event_info()32520   ChromeMojoEventInfo* mutable_chrome_mojo_event_info() { _has_field_.set(38); return chrome_mojo_event_info_.get(); }
32521 
has_timestamp_delta_us() const32522   bool has_timestamp_delta_us() const { return _has_field_[1]; }
timestamp_delta_us() const32523   int64_t timestamp_delta_us() const { return timestamp_delta_us_; }
set_timestamp_delta_us(int64_t value)32524   void set_timestamp_delta_us(int64_t value) { timestamp_delta_us_ = value; _has_field_.set(1); }
32525 
has_timestamp_absolute_us() const32526   bool has_timestamp_absolute_us() const { return _has_field_[16]; }
timestamp_absolute_us() const32527   int64_t timestamp_absolute_us() const { return timestamp_absolute_us_; }
set_timestamp_absolute_us(int64_t value)32528   void set_timestamp_absolute_us(int64_t value) { timestamp_absolute_us_ = value; _has_field_.set(16); }
32529 
has_thread_time_delta_us() const32530   bool has_thread_time_delta_us() const { return _has_field_[2]; }
thread_time_delta_us() const32531   int64_t thread_time_delta_us() const { return thread_time_delta_us_; }
set_thread_time_delta_us(int64_t value)32532   void set_thread_time_delta_us(int64_t value) { thread_time_delta_us_ = value; _has_field_.set(2); }
32533 
has_thread_time_absolute_us() const32534   bool has_thread_time_absolute_us() const { return _has_field_[17]; }
thread_time_absolute_us() const32535   int64_t thread_time_absolute_us() const { return thread_time_absolute_us_; }
set_thread_time_absolute_us(int64_t value)32536   void set_thread_time_absolute_us(int64_t value) { thread_time_absolute_us_ = value; _has_field_.set(17); }
32537 
has_thread_instruction_count_delta() const32538   bool has_thread_instruction_count_delta() const { return _has_field_[8]; }
thread_instruction_count_delta() const32539   int64_t thread_instruction_count_delta() const { return thread_instruction_count_delta_; }
set_thread_instruction_count_delta(int64_t value)32540   void set_thread_instruction_count_delta(int64_t value) { thread_instruction_count_delta_ = value; _has_field_.set(8); }
32541 
has_thread_instruction_count_absolute() const32542   bool has_thread_instruction_count_absolute() const { return _has_field_[20]; }
thread_instruction_count_absolute() const32543   int64_t thread_instruction_count_absolute() const { return thread_instruction_count_absolute_; }
set_thread_instruction_count_absolute(int64_t value)32544   void set_thread_instruction_count_absolute(int64_t value) { thread_instruction_count_absolute_ = value; _has_field_.set(20); }
32545 
has_legacy_event() const32546   bool has_legacy_event() const { return _has_field_[6]; }
legacy_event() const32547   const TrackEvent_LegacyEvent& legacy_event() const { return *legacy_event_; }
mutable_legacy_event()32548   TrackEvent_LegacyEvent* mutable_legacy_event() { _has_field_.set(6); return legacy_event_.get(); }
32549 
32550  private:
32551   std::vector<uint64_t> category_iids_;
32552   std::vector<std::string> categories_;
32553   uint64_t name_iid_{};
32554   std::string name_{};
32555   TrackEvent_Type type_{};
32556   uint64_t track_uuid_{};
32557   int64_t counter_value_{};
32558   double double_counter_value_{};
32559   std::vector<uint64_t> extra_counter_track_uuids_;
32560   std::vector<int64_t> extra_counter_values_;
32561   std::vector<uint64_t> extra_double_counter_track_uuids_;
32562   std::vector<double> extra_double_counter_values_;
32563   std::vector<uint64_t> flow_ids_;
32564   std::vector<uint64_t> terminating_flow_ids_;
32565   std::vector<DebugAnnotation> debug_annotations_;
32566   ::protozero::CopyablePtr<TaskExecution> task_execution_;
32567   ::protozero::CopyablePtr<LogMessage> log_message_;
32568   ::protozero::CopyablePtr<ChromeCompositorSchedulerState> cc_scheduler_state_;
32569   ::protozero::CopyablePtr<ChromeUserEvent> chrome_user_event_;
32570   ::protozero::CopyablePtr<ChromeKeyedService> chrome_keyed_service_;
32571   ::protozero::CopyablePtr<ChromeLegacyIpc> chrome_legacy_ipc_;
32572   ::protozero::CopyablePtr<ChromeHistogramSample> chrome_histogram_sample_;
32573   ::protozero::CopyablePtr<ChromeLatencyInfo> chrome_latency_info_;
32574   ::protozero::CopyablePtr<ChromeFrameReporter> chrome_frame_reporter_;
32575   ::protozero::CopyablePtr<ChromeApplicationStateInfo> chrome_application_state_info_;
32576   ::protozero::CopyablePtr<ChromeRendererSchedulerState> chrome_renderer_scheduler_state_;
32577   ::protozero::CopyablePtr<ChromeWindowHandleEventInfo> chrome_window_handle_event_info_;
32578   ::protozero::CopyablePtr<ChromeContentSettingsEventInfo> chrome_content_settings_event_info_;
32579   ::protozero::CopyablePtr<SourceLocation> source_location_;
32580   uint64_t source_location_iid_{};
32581   ::protozero::CopyablePtr<ChromeMessagePump> chrome_message_pump_;
32582   ::protozero::CopyablePtr<ChromeMojoEventInfo> chrome_mojo_event_info_;
32583   int64_t timestamp_delta_us_{};
32584   int64_t timestamp_absolute_us_{};
32585   int64_t thread_time_delta_us_{};
32586   int64_t thread_time_absolute_us_{};
32587   int64_t thread_instruction_count_delta_{};
32588   int64_t thread_instruction_count_absolute_{};
32589   ::protozero::CopyablePtr<TrackEvent_LegacyEvent> legacy_event_;
32590 
32591   // Allows to preserve unknown protobuf fields for compatibility
32592   // with future versions of .proto files.
32593   std::string unknown_fields_;
32594 
32595   std::bitset<47> _has_field_{};
32596 };
32597 
32598 
32599 class PERFETTO_EXPORT TrackEvent_LegacyEvent : public ::protozero::CppMessageObj {
32600  public:
32601   using FlowDirection = TrackEvent_LegacyEvent_FlowDirection;
32602   static constexpr auto FLOW_UNSPECIFIED = TrackEvent_LegacyEvent_FlowDirection_FLOW_UNSPECIFIED;
32603   static constexpr auto FLOW_IN = TrackEvent_LegacyEvent_FlowDirection_FLOW_IN;
32604   static constexpr auto FLOW_OUT = TrackEvent_LegacyEvent_FlowDirection_FLOW_OUT;
32605   static constexpr auto FLOW_INOUT = TrackEvent_LegacyEvent_FlowDirection_FLOW_INOUT;
32606   static constexpr auto FlowDirection_MIN = TrackEvent_LegacyEvent_FlowDirection_FLOW_UNSPECIFIED;
32607   static constexpr auto FlowDirection_MAX = TrackEvent_LegacyEvent_FlowDirection_FLOW_INOUT;
32608   using InstantEventScope = TrackEvent_LegacyEvent_InstantEventScope;
32609   static constexpr auto SCOPE_UNSPECIFIED = TrackEvent_LegacyEvent_InstantEventScope_SCOPE_UNSPECIFIED;
32610   static constexpr auto SCOPE_GLOBAL = TrackEvent_LegacyEvent_InstantEventScope_SCOPE_GLOBAL;
32611   static constexpr auto SCOPE_PROCESS = TrackEvent_LegacyEvent_InstantEventScope_SCOPE_PROCESS;
32612   static constexpr auto SCOPE_THREAD = TrackEvent_LegacyEvent_InstantEventScope_SCOPE_THREAD;
32613   static constexpr auto InstantEventScope_MIN = TrackEvent_LegacyEvent_InstantEventScope_SCOPE_UNSPECIFIED;
32614   static constexpr auto InstantEventScope_MAX = TrackEvent_LegacyEvent_InstantEventScope_SCOPE_THREAD;
32615   enum FieldNumbers {
32616     kNameIidFieldNumber = 1,
32617     kPhaseFieldNumber = 2,
32618     kDurationUsFieldNumber = 3,
32619     kThreadDurationUsFieldNumber = 4,
32620     kThreadInstructionDeltaFieldNumber = 15,
32621     kUnscopedIdFieldNumber = 6,
32622     kLocalIdFieldNumber = 10,
32623     kGlobalIdFieldNumber = 11,
32624     kIdScopeFieldNumber = 7,
32625     kUseAsyncTtsFieldNumber = 9,
32626     kBindIdFieldNumber = 8,
32627     kBindToEnclosingFieldNumber = 12,
32628     kFlowDirectionFieldNumber = 13,
32629     kInstantEventScopeFieldNumber = 14,
32630     kPidOverrideFieldNumber = 18,
32631     kTidOverrideFieldNumber = 19,
32632   };
32633 
32634   TrackEvent_LegacyEvent();
32635   ~TrackEvent_LegacyEvent() override;
32636   TrackEvent_LegacyEvent(TrackEvent_LegacyEvent&&) noexcept;
32637   TrackEvent_LegacyEvent& operator=(TrackEvent_LegacyEvent&&);
32638   TrackEvent_LegacyEvent(const TrackEvent_LegacyEvent&);
32639   TrackEvent_LegacyEvent& operator=(const TrackEvent_LegacyEvent&);
32640   bool operator==(const TrackEvent_LegacyEvent&) const;
operator !=(const TrackEvent_LegacyEvent & other) const32641   bool operator!=(const TrackEvent_LegacyEvent& other) const { return !(*this == other); }
32642 
32643   bool ParseFromArray(const void*, size_t) override;
32644   std::string SerializeAsString() const override;
32645   std::vector<uint8_t> SerializeAsArray() const override;
32646   void Serialize(::protozero::Message*) const;
32647 
has_name_iid() const32648   bool has_name_iid() const { return _has_field_[1]; }
name_iid() const32649   uint64_t name_iid() const { return name_iid_; }
set_name_iid(uint64_t value)32650   void set_name_iid(uint64_t value) { name_iid_ = value; _has_field_.set(1); }
32651 
has_phase() const32652   bool has_phase() const { return _has_field_[2]; }
phase() const32653   int32_t phase() const { return phase_; }
set_phase(int32_t value)32654   void set_phase(int32_t value) { phase_ = value; _has_field_.set(2); }
32655 
has_duration_us() const32656   bool has_duration_us() const { return _has_field_[3]; }
duration_us() const32657   int64_t duration_us() const { return duration_us_; }
set_duration_us(int64_t value)32658   void set_duration_us(int64_t value) { duration_us_ = value; _has_field_.set(3); }
32659 
has_thread_duration_us() const32660   bool has_thread_duration_us() const { return _has_field_[4]; }
thread_duration_us() const32661   int64_t thread_duration_us() const { return thread_duration_us_; }
set_thread_duration_us(int64_t value)32662   void set_thread_duration_us(int64_t value) { thread_duration_us_ = value; _has_field_.set(4); }
32663 
has_thread_instruction_delta() const32664   bool has_thread_instruction_delta() const { return _has_field_[15]; }
thread_instruction_delta() const32665   int64_t thread_instruction_delta() const { return thread_instruction_delta_; }
set_thread_instruction_delta(int64_t value)32666   void set_thread_instruction_delta(int64_t value) { thread_instruction_delta_ = value; _has_field_.set(15); }
32667 
has_unscoped_id() const32668   bool has_unscoped_id() const { return _has_field_[6]; }
unscoped_id() const32669   uint64_t unscoped_id() const { return unscoped_id_; }
set_unscoped_id(uint64_t value)32670   void set_unscoped_id(uint64_t value) { unscoped_id_ = value; _has_field_.set(6); }
32671 
has_local_id() const32672   bool has_local_id() const { return _has_field_[10]; }
local_id() const32673   uint64_t local_id() const { return local_id_; }
set_local_id(uint64_t value)32674   void set_local_id(uint64_t value) { local_id_ = value; _has_field_.set(10); }
32675 
has_global_id() const32676   bool has_global_id() const { return _has_field_[11]; }
global_id() const32677   uint64_t global_id() const { return global_id_; }
set_global_id(uint64_t value)32678   void set_global_id(uint64_t value) { global_id_ = value; _has_field_.set(11); }
32679 
has_id_scope() const32680   bool has_id_scope() const { return _has_field_[7]; }
id_scope() const32681   const std::string& id_scope() const { return id_scope_; }
set_id_scope(const std::string & value)32682   void set_id_scope(const std::string& value) { id_scope_ = value; _has_field_.set(7); }
32683 
has_use_async_tts() const32684   bool has_use_async_tts() const { return _has_field_[9]; }
use_async_tts() const32685   bool use_async_tts() const { return use_async_tts_; }
set_use_async_tts(bool value)32686   void set_use_async_tts(bool value) { use_async_tts_ = value; _has_field_.set(9); }
32687 
has_bind_id() const32688   bool has_bind_id() const { return _has_field_[8]; }
bind_id() const32689   uint64_t bind_id() const { return bind_id_; }
set_bind_id(uint64_t value)32690   void set_bind_id(uint64_t value) { bind_id_ = value; _has_field_.set(8); }
32691 
has_bind_to_enclosing() const32692   bool has_bind_to_enclosing() const { return _has_field_[12]; }
bind_to_enclosing() const32693   bool bind_to_enclosing() const { return bind_to_enclosing_; }
set_bind_to_enclosing(bool value)32694   void set_bind_to_enclosing(bool value) { bind_to_enclosing_ = value; _has_field_.set(12); }
32695 
has_flow_direction() const32696   bool has_flow_direction() const { return _has_field_[13]; }
flow_direction() const32697   TrackEvent_LegacyEvent_FlowDirection flow_direction() const { return flow_direction_; }
set_flow_direction(TrackEvent_LegacyEvent_FlowDirection value)32698   void set_flow_direction(TrackEvent_LegacyEvent_FlowDirection value) { flow_direction_ = value; _has_field_.set(13); }
32699 
has_instant_event_scope() const32700   bool has_instant_event_scope() const { return _has_field_[14]; }
instant_event_scope() const32701   TrackEvent_LegacyEvent_InstantEventScope instant_event_scope() const { return instant_event_scope_; }
set_instant_event_scope(TrackEvent_LegacyEvent_InstantEventScope value)32702   void set_instant_event_scope(TrackEvent_LegacyEvent_InstantEventScope value) { instant_event_scope_ = value; _has_field_.set(14); }
32703 
has_pid_override() const32704   bool has_pid_override() const { return _has_field_[18]; }
pid_override() const32705   int32_t pid_override() const { return pid_override_; }
set_pid_override(int32_t value)32706   void set_pid_override(int32_t value) { pid_override_ = value; _has_field_.set(18); }
32707 
has_tid_override() const32708   bool has_tid_override() const { return _has_field_[19]; }
tid_override() const32709   int32_t tid_override() const { return tid_override_; }
set_tid_override(int32_t value)32710   void set_tid_override(int32_t value) { tid_override_ = value; _has_field_.set(19); }
32711 
32712  private:
32713   uint64_t name_iid_{};
32714   int32_t phase_{};
32715   int64_t duration_us_{};
32716   int64_t thread_duration_us_{};
32717   int64_t thread_instruction_delta_{};
32718   uint64_t unscoped_id_{};
32719   uint64_t local_id_{};
32720   uint64_t global_id_{};
32721   std::string id_scope_{};
32722   bool use_async_tts_{};
32723   uint64_t bind_id_{};
32724   bool bind_to_enclosing_{};
32725   TrackEvent_LegacyEvent_FlowDirection flow_direction_{};
32726   TrackEvent_LegacyEvent_InstantEventScope instant_event_scope_{};
32727   int32_t pid_override_{};
32728   int32_t tid_override_{};
32729 
32730   // Allows to preserve unknown protobuf fields for compatibility
32731   // with future versions of .proto files.
32732   std::string unknown_fields_;
32733 
32734   std::bitset<20> _has_field_{};
32735 };
32736 
32737 }  // namespace perfetto
32738 }  // namespace protos
32739 }  // namespace gen
32740 
32741 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_TRACK_EVENT_PROTO_CPP_H_
32742 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
32743 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
32744 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
32745 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
32746 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
32747 #if defined(__GNUC__) || defined(__clang__)
32748 #pragma GCC diagnostic push
32749 #pragma GCC diagnostic ignored "-Wfloat-equal"
32750 #endif
32751 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/track_event.gen.h"
32752 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/source_location.gen.h"
32753 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_window_handle_event_info.gen.h"
32754 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_user_event.gen.h"
32755 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_renderer_scheduler_state.gen.h"
32756 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_mojo_event_info.gen.h"
32757 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_message_pump.gen.h"
32758 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_legacy_ipc.gen.h"
32759 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_latency_info.gen.h"
32760 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_keyed_service.gen.h"
32761 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_histogram_sample.gen.h"
32762 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_frame_reporter.gen.h"
32763 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_content_settings_event_info.gen.h"
32764 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_compositor_scheduler_state.gen.h"
32765 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_application_state_info.gen.h"
32766 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/task_execution.gen.h"
32767 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/log_message.gen.h"
32768 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/debug_annotation.gen.h"
32769 
32770 namespace perfetto {
32771 namespace protos {
32772 namespace gen {
32773 
32774 EventName::EventName() = default;
32775 EventName::~EventName() = default;
32776 EventName::EventName(const EventName&) = default;
32777 EventName& EventName::operator=(const EventName&) = default;
32778 EventName::EventName(EventName&&) noexcept = default;
32779 EventName& EventName::operator=(EventName&&) = default;
32780 
operator ==(const EventName & other) const32781 bool EventName::operator==(const EventName& other) const {
32782   return unknown_fields_ == other.unknown_fields_
32783    && iid_ == other.iid_
32784    && name_ == other.name_;
32785 }
32786 
ParseFromArray(const void * raw,size_t size)32787 bool EventName::ParseFromArray(const void* raw, size_t size) {
32788   unknown_fields_.clear();
32789   bool packed_error = false;
32790 
32791   ::protozero::ProtoDecoder dec(raw, size);
32792   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
32793     if (field.id() < _has_field_.size()) {
32794       _has_field_.set(field.id());
32795     }
32796     switch (field.id()) {
32797       case 1 /* iid */:
32798         field.get(&iid_);
32799         break;
32800       case 2 /* name */:
32801         field.get(&name_);
32802         break;
32803       default:
32804         field.SerializeAndAppendTo(&unknown_fields_);
32805         break;
32806     }
32807   }
32808   return !packed_error && !dec.bytes_left();
32809 }
32810 
SerializeAsString() const32811 std::string EventName::SerializeAsString() const {
32812   ::protozero::HeapBuffered<::protozero::Message> msg;
32813   Serialize(msg.get());
32814   return msg.SerializeAsString();
32815 }
32816 
SerializeAsArray() const32817 std::vector<uint8_t> EventName::SerializeAsArray() const {
32818   ::protozero::HeapBuffered<::protozero::Message> msg;
32819   Serialize(msg.get());
32820   return msg.SerializeAsArray();
32821 }
32822 
Serialize(::protozero::Message * msg) const32823 void EventName::Serialize(::protozero::Message* msg) const {
32824   // Field 1: iid
32825   if (_has_field_[1]) {
32826     msg->AppendVarInt(1, iid_);
32827   }
32828 
32829   // Field 2: name
32830   if (_has_field_[2]) {
32831     msg->AppendString(2, name_);
32832   }
32833 
32834   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
32835 }
32836 
32837 
32838 EventCategory::EventCategory() = default;
32839 EventCategory::~EventCategory() = default;
32840 EventCategory::EventCategory(const EventCategory&) = default;
32841 EventCategory& EventCategory::operator=(const EventCategory&) = default;
32842 EventCategory::EventCategory(EventCategory&&) noexcept = default;
32843 EventCategory& EventCategory::operator=(EventCategory&&) = default;
32844 
operator ==(const EventCategory & other) const32845 bool EventCategory::operator==(const EventCategory& other) const {
32846   return unknown_fields_ == other.unknown_fields_
32847    && iid_ == other.iid_
32848    && name_ == other.name_;
32849 }
32850 
ParseFromArray(const void * raw,size_t size)32851 bool EventCategory::ParseFromArray(const void* raw, size_t size) {
32852   unknown_fields_.clear();
32853   bool packed_error = false;
32854 
32855   ::protozero::ProtoDecoder dec(raw, size);
32856   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
32857     if (field.id() < _has_field_.size()) {
32858       _has_field_.set(field.id());
32859     }
32860     switch (field.id()) {
32861       case 1 /* iid */:
32862         field.get(&iid_);
32863         break;
32864       case 2 /* name */:
32865         field.get(&name_);
32866         break;
32867       default:
32868         field.SerializeAndAppendTo(&unknown_fields_);
32869         break;
32870     }
32871   }
32872   return !packed_error && !dec.bytes_left();
32873 }
32874 
SerializeAsString() const32875 std::string EventCategory::SerializeAsString() const {
32876   ::protozero::HeapBuffered<::protozero::Message> msg;
32877   Serialize(msg.get());
32878   return msg.SerializeAsString();
32879 }
32880 
SerializeAsArray() const32881 std::vector<uint8_t> EventCategory::SerializeAsArray() const {
32882   ::protozero::HeapBuffered<::protozero::Message> msg;
32883   Serialize(msg.get());
32884   return msg.SerializeAsArray();
32885 }
32886 
Serialize(::protozero::Message * msg) const32887 void EventCategory::Serialize(::protozero::Message* msg) const {
32888   // Field 1: iid
32889   if (_has_field_[1]) {
32890     msg->AppendVarInt(1, iid_);
32891   }
32892 
32893   // Field 2: name
32894   if (_has_field_[2]) {
32895     msg->AppendString(2, name_);
32896   }
32897 
32898   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
32899 }
32900 
32901 
32902 TrackEventDefaults::TrackEventDefaults() = default;
32903 TrackEventDefaults::~TrackEventDefaults() = default;
32904 TrackEventDefaults::TrackEventDefaults(const TrackEventDefaults&) = default;
32905 TrackEventDefaults& TrackEventDefaults::operator=(const TrackEventDefaults&) = default;
32906 TrackEventDefaults::TrackEventDefaults(TrackEventDefaults&&) noexcept = default;
32907 TrackEventDefaults& TrackEventDefaults::operator=(TrackEventDefaults&&) = default;
32908 
operator ==(const TrackEventDefaults & other) const32909 bool TrackEventDefaults::operator==(const TrackEventDefaults& other) const {
32910   return unknown_fields_ == other.unknown_fields_
32911    && track_uuid_ == other.track_uuid_
32912    && extra_counter_track_uuids_ == other.extra_counter_track_uuids_
32913    && extra_double_counter_track_uuids_ == other.extra_double_counter_track_uuids_;
32914 }
32915 
ParseFromArray(const void * raw,size_t size)32916 bool TrackEventDefaults::ParseFromArray(const void* raw, size_t size) {
32917   extra_counter_track_uuids_.clear();
32918   extra_double_counter_track_uuids_.clear();
32919   unknown_fields_.clear();
32920   bool packed_error = false;
32921 
32922   ::protozero::ProtoDecoder dec(raw, size);
32923   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
32924     if (field.id() < _has_field_.size()) {
32925       _has_field_.set(field.id());
32926     }
32927     switch (field.id()) {
32928       case 11 /* track_uuid */:
32929         field.get(&track_uuid_);
32930         break;
32931       case 31 /* extra_counter_track_uuids */:
32932         extra_counter_track_uuids_.emplace_back();
32933         field.get(&extra_counter_track_uuids_.back());
32934         break;
32935       case 45 /* extra_double_counter_track_uuids */:
32936         extra_double_counter_track_uuids_.emplace_back();
32937         field.get(&extra_double_counter_track_uuids_.back());
32938         break;
32939       default:
32940         field.SerializeAndAppendTo(&unknown_fields_);
32941         break;
32942     }
32943   }
32944   return !packed_error && !dec.bytes_left();
32945 }
32946 
SerializeAsString() const32947 std::string TrackEventDefaults::SerializeAsString() const {
32948   ::protozero::HeapBuffered<::protozero::Message> msg;
32949   Serialize(msg.get());
32950   return msg.SerializeAsString();
32951 }
32952 
SerializeAsArray() const32953 std::vector<uint8_t> TrackEventDefaults::SerializeAsArray() const {
32954   ::protozero::HeapBuffered<::protozero::Message> msg;
32955   Serialize(msg.get());
32956   return msg.SerializeAsArray();
32957 }
32958 
Serialize(::protozero::Message * msg) const32959 void TrackEventDefaults::Serialize(::protozero::Message* msg) const {
32960   // Field 11: track_uuid
32961   if (_has_field_[11]) {
32962     msg->AppendVarInt(11, track_uuid_);
32963   }
32964 
32965   // Field 31: extra_counter_track_uuids
32966   for (auto& it : extra_counter_track_uuids_) {
32967     msg->AppendVarInt(31, it);
32968   }
32969 
32970   // Field 45: extra_double_counter_track_uuids
32971   for (auto& it : extra_double_counter_track_uuids_) {
32972     msg->AppendVarInt(45, it);
32973   }
32974 
32975   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
32976 }
32977 
32978 
32979 TrackEvent::TrackEvent() = default;
32980 TrackEvent::~TrackEvent() = default;
32981 TrackEvent::TrackEvent(const TrackEvent&) = default;
32982 TrackEvent& TrackEvent::operator=(const TrackEvent&) = default;
32983 TrackEvent::TrackEvent(TrackEvent&&) noexcept = default;
32984 TrackEvent& TrackEvent::operator=(TrackEvent&&) = default;
32985 
operator ==(const TrackEvent & other) const32986 bool TrackEvent::operator==(const TrackEvent& other) const {
32987   return unknown_fields_ == other.unknown_fields_
32988    && category_iids_ == other.category_iids_
32989    && categories_ == other.categories_
32990    && name_iid_ == other.name_iid_
32991    && name_ == other.name_
32992    && type_ == other.type_
32993    && track_uuid_ == other.track_uuid_
32994    && counter_value_ == other.counter_value_
32995    && double_counter_value_ == other.double_counter_value_
32996    && extra_counter_track_uuids_ == other.extra_counter_track_uuids_
32997    && extra_counter_values_ == other.extra_counter_values_
32998    && extra_double_counter_track_uuids_ == other.extra_double_counter_track_uuids_
32999    && extra_double_counter_values_ == other.extra_double_counter_values_
33000    && flow_ids_ == other.flow_ids_
33001    && terminating_flow_ids_ == other.terminating_flow_ids_
33002    && debug_annotations_ == other.debug_annotations_
33003    && task_execution_ == other.task_execution_
33004    && log_message_ == other.log_message_
33005    && cc_scheduler_state_ == other.cc_scheduler_state_
33006    && chrome_user_event_ == other.chrome_user_event_
33007    && chrome_keyed_service_ == other.chrome_keyed_service_
33008    && chrome_legacy_ipc_ == other.chrome_legacy_ipc_
33009    && chrome_histogram_sample_ == other.chrome_histogram_sample_
33010    && chrome_latency_info_ == other.chrome_latency_info_
33011    && chrome_frame_reporter_ == other.chrome_frame_reporter_
33012    && chrome_application_state_info_ == other.chrome_application_state_info_
33013    && chrome_renderer_scheduler_state_ == other.chrome_renderer_scheduler_state_
33014    && chrome_window_handle_event_info_ == other.chrome_window_handle_event_info_
33015    && chrome_content_settings_event_info_ == other.chrome_content_settings_event_info_
33016    && source_location_ == other.source_location_
33017    && source_location_iid_ == other.source_location_iid_
33018    && chrome_message_pump_ == other.chrome_message_pump_
33019    && chrome_mojo_event_info_ == other.chrome_mojo_event_info_
33020    && timestamp_delta_us_ == other.timestamp_delta_us_
33021    && timestamp_absolute_us_ == other.timestamp_absolute_us_
33022    && thread_time_delta_us_ == other.thread_time_delta_us_
33023    && thread_time_absolute_us_ == other.thread_time_absolute_us_
33024    && thread_instruction_count_delta_ == other.thread_instruction_count_delta_
33025    && thread_instruction_count_absolute_ == other.thread_instruction_count_absolute_
33026    && legacy_event_ == other.legacy_event_;
33027 }
33028 
debug_annotations_size() const33029 int TrackEvent::debug_annotations_size() const { return static_cast<int>(debug_annotations_.size()); }
clear_debug_annotations()33030 void TrackEvent::clear_debug_annotations() { debug_annotations_.clear(); }
add_debug_annotations()33031 DebugAnnotation* TrackEvent::add_debug_annotations() { debug_annotations_.emplace_back(); return &debug_annotations_.back(); }
ParseFromArray(const void * raw,size_t size)33032 bool TrackEvent::ParseFromArray(const void* raw, size_t size) {
33033   category_iids_.clear();
33034   categories_.clear();
33035   extra_counter_track_uuids_.clear();
33036   extra_counter_values_.clear();
33037   extra_double_counter_track_uuids_.clear();
33038   extra_double_counter_values_.clear();
33039   flow_ids_.clear();
33040   terminating_flow_ids_.clear();
33041   debug_annotations_.clear();
33042   unknown_fields_.clear();
33043   bool packed_error = false;
33044 
33045   ::protozero::ProtoDecoder dec(raw, size);
33046   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
33047     if (field.id() < _has_field_.size()) {
33048       _has_field_.set(field.id());
33049     }
33050     switch (field.id()) {
33051       case 3 /* category_iids */:
33052         category_iids_.emplace_back();
33053         field.get(&category_iids_.back());
33054         break;
33055       case 22 /* categories */:
33056         categories_.emplace_back();
33057         field.get(&categories_.back());
33058         break;
33059       case 10 /* name_iid */:
33060         field.get(&name_iid_);
33061         break;
33062       case 23 /* name */:
33063         field.get(&name_);
33064         break;
33065       case 9 /* type */:
33066         field.get(&type_);
33067         break;
33068       case 11 /* track_uuid */:
33069         field.get(&track_uuid_);
33070         break;
33071       case 30 /* counter_value */:
33072         field.get(&counter_value_);
33073         break;
33074       case 44 /* double_counter_value */:
33075         field.get(&double_counter_value_);
33076         break;
33077       case 31 /* extra_counter_track_uuids */:
33078         extra_counter_track_uuids_.emplace_back();
33079         field.get(&extra_counter_track_uuids_.back());
33080         break;
33081       case 12 /* extra_counter_values */:
33082         extra_counter_values_.emplace_back();
33083         field.get(&extra_counter_values_.back());
33084         break;
33085       case 45 /* extra_double_counter_track_uuids */:
33086         extra_double_counter_track_uuids_.emplace_back();
33087         field.get(&extra_double_counter_track_uuids_.back());
33088         break;
33089       case 46 /* extra_double_counter_values */:
33090         extra_double_counter_values_.emplace_back();
33091         field.get(&extra_double_counter_values_.back());
33092         break;
33093       case 36 /* flow_ids */:
33094         flow_ids_.emplace_back();
33095         field.get(&flow_ids_.back());
33096         break;
33097       case 42 /* terminating_flow_ids */:
33098         terminating_flow_ids_.emplace_back();
33099         field.get(&terminating_flow_ids_.back());
33100         break;
33101       case 4 /* debug_annotations */:
33102         debug_annotations_.emplace_back();
33103         debug_annotations_.back().ParseFromArray(field.data(), field.size());
33104         break;
33105       case 5 /* task_execution */:
33106         (*task_execution_).ParseFromArray(field.data(), field.size());
33107         break;
33108       case 21 /* log_message */:
33109         (*log_message_).ParseFromArray(field.data(), field.size());
33110         break;
33111       case 24 /* cc_scheduler_state */:
33112         (*cc_scheduler_state_).ParseFromArray(field.data(), field.size());
33113         break;
33114       case 25 /* chrome_user_event */:
33115         (*chrome_user_event_).ParseFromArray(field.data(), field.size());
33116         break;
33117       case 26 /* chrome_keyed_service */:
33118         (*chrome_keyed_service_).ParseFromArray(field.data(), field.size());
33119         break;
33120       case 27 /* chrome_legacy_ipc */:
33121         (*chrome_legacy_ipc_).ParseFromArray(field.data(), field.size());
33122         break;
33123       case 28 /* chrome_histogram_sample */:
33124         (*chrome_histogram_sample_).ParseFromArray(field.data(), field.size());
33125         break;
33126       case 29 /* chrome_latency_info */:
33127         (*chrome_latency_info_).ParseFromArray(field.data(), field.size());
33128         break;
33129       case 32 /* chrome_frame_reporter */:
33130         (*chrome_frame_reporter_).ParseFromArray(field.data(), field.size());
33131         break;
33132       case 39 /* chrome_application_state_info */:
33133         (*chrome_application_state_info_).ParseFromArray(field.data(), field.size());
33134         break;
33135       case 40 /* chrome_renderer_scheduler_state */:
33136         (*chrome_renderer_scheduler_state_).ParseFromArray(field.data(), field.size());
33137         break;
33138       case 41 /* chrome_window_handle_event_info */:
33139         (*chrome_window_handle_event_info_).ParseFromArray(field.data(), field.size());
33140         break;
33141       case 43 /* chrome_content_settings_event_info */:
33142         (*chrome_content_settings_event_info_).ParseFromArray(field.data(), field.size());
33143         break;
33144       case 33 /* source_location */:
33145         (*source_location_).ParseFromArray(field.data(), field.size());
33146         break;
33147       case 34 /* source_location_iid */:
33148         field.get(&source_location_iid_);
33149         break;
33150       case 35 /* chrome_message_pump */:
33151         (*chrome_message_pump_).ParseFromArray(field.data(), field.size());
33152         break;
33153       case 38 /* chrome_mojo_event_info */:
33154         (*chrome_mojo_event_info_).ParseFromArray(field.data(), field.size());
33155         break;
33156       case 1 /* timestamp_delta_us */:
33157         field.get(&timestamp_delta_us_);
33158         break;
33159       case 16 /* timestamp_absolute_us */:
33160         field.get(&timestamp_absolute_us_);
33161         break;
33162       case 2 /* thread_time_delta_us */:
33163         field.get(&thread_time_delta_us_);
33164         break;
33165       case 17 /* thread_time_absolute_us */:
33166         field.get(&thread_time_absolute_us_);
33167         break;
33168       case 8 /* thread_instruction_count_delta */:
33169         field.get(&thread_instruction_count_delta_);
33170         break;
33171       case 20 /* thread_instruction_count_absolute */:
33172         field.get(&thread_instruction_count_absolute_);
33173         break;
33174       case 6 /* legacy_event */:
33175         (*legacy_event_).ParseFromArray(field.data(), field.size());
33176         break;
33177       default:
33178         field.SerializeAndAppendTo(&unknown_fields_);
33179         break;
33180     }
33181   }
33182   return !packed_error && !dec.bytes_left();
33183 }
33184 
SerializeAsString() const33185 std::string TrackEvent::SerializeAsString() const {
33186   ::protozero::HeapBuffered<::protozero::Message> msg;
33187   Serialize(msg.get());
33188   return msg.SerializeAsString();
33189 }
33190 
SerializeAsArray() const33191 std::vector<uint8_t> TrackEvent::SerializeAsArray() const {
33192   ::protozero::HeapBuffered<::protozero::Message> msg;
33193   Serialize(msg.get());
33194   return msg.SerializeAsArray();
33195 }
33196 
Serialize(::protozero::Message * msg) const33197 void TrackEvent::Serialize(::protozero::Message* msg) const {
33198   // Field 3: category_iids
33199   for (auto& it : category_iids_) {
33200     msg->AppendVarInt(3, it);
33201   }
33202 
33203   // Field 22: categories
33204   for (auto& it : categories_) {
33205     msg->AppendString(22, it);
33206   }
33207 
33208   // Field 10: name_iid
33209   if (_has_field_[10]) {
33210     msg->AppendVarInt(10, name_iid_);
33211   }
33212 
33213   // Field 23: name
33214   if (_has_field_[23]) {
33215     msg->AppendString(23, name_);
33216   }
33217 
33218   // Field 9: type
33219   if (_has_field_[9]) {
33220     msg->AppendVarInt(9, type_);
33221   }
33222 
33223   // Field 11: track_uuid
33224   if (_has_field_[11]) {
33225     msg->AppendVarInt(11, track_uuid_);
33226   }
33227 
33228   // Field 30: counter_value
33229   if (_has_field_[30]) {
33230     msg->AppendVarInt(30, counter_value_);
33231   }
33232 
33233   // Field 44: double_counter_value
33234   if (_has_field_[44]) {
33235     msg->AppendFixed(44, double_counter_value_);
33236   }
33237 
33238   // Field 31: extra_counter_track_uuids
33239   for (auto& it : extra_counter_track_uuids_) {
33240     msg->AppendVarInt(31, it);
33241   }
33242 
33243   // Field 12: extra_counter_values
33244   for (auto& it : extra_counter_values_) {
33245     msg->AppendVarInt(12, it);
33246   }
33247 
33248   // Field 45: extra_double_counter_track_uuids
33249   for (auto& it : extra_double_counter_track_uuids_) {
33250     msg->AppendVarInt(45, it);
33251   }
33252 
33253   // Field 46: extra_double_counter_values
33254   for (auto& it : extra_double_counter_values_) {
33255     msg->AppendFixed(46, it);
33256   }
33257 
33258   // Field 36: flow_ids
33259   for (auto& it : flow_ids_) {
33260     msg->AppendVarInt(36, it);
33261   }
33262 
33263   // Field 42: terminating_flow_ids
33264   for (auto& it : terminating_flow_ids_) {
33265     msg->AppendVarInt(42, it);
33266   }
33267 
33268   // Field 4: debug_annotations
33269   for (auto& it : debug_annotations_) {
33270     it.Serialize(msg->BeginNestedMessage<::protozero::Message>(4));
33271   }
33272 
33273   // Field 5: task_execution
33274   if (_has_field_[5]) {
33275     (*task_execution_).Serialize(msg->BeginNestedMessage<::protozero::Message>(5));
33276   }
33277 
33278   // Field 21: log_message
33279   if (_has_field_[21]) {
33280     (*log_message_).Serialize(msg->BeginNestedMessage<::protozero::Message>(21));
33281   }
33282 
33283   // Field 24: cc_scheduler_state
33284   if (_has_field_[24]) {
33285     (*cc_scheduler_state_).Serialize(msg->BeginNestedMessage<::protozero::Message>(24));
33286   }
33287 
33288   // Field 25: chrome_user_event
33289   if (_has_field_[25]) {
33290     (*chrome_user_event_).Serialize(msg->BeginNestedMessage<::protozero::Message>(25));
33291   }
33292 
33293   // Field 26: chrome_keyed_service
33294   if (_has_field_[26]) {
33295     (*chrome_keyed_service_).Serialize(msg->BeginNestedMessage<::protozero::Message>(26));
33296   }
33297 
33298   // Field 27: chrome_legacy_ipc
33299   if (_has_field_[27]) {
33300     (*chrome_legacy_ipc_).Serialize(msg->BeginNestedMessage<::protozero::Message>(27));
33301   }
33302 
33303   // Field 28: chrome_histogram_sample
33304   if (_has_field_[28]) {
33305     (*chrome_histogram_sample_).Serialize(msg->BeginNestedMessage<::protozero::Message>(28));
33306   }
33307 
33308   // Field 29: chrome_latency_info
33309   if (_has_field_[29]) {
33310     (*chrome_latency_info_).Serialize(msg->BeginNestedMessage<::protozero::Message>(29));
33311   }
33312 
33313   // Field 32: chrome_frame_reporter
33314   if (_has_field_[32]) {
33315     (*chrome_frame_reporter_).Serialize(msg->BeginNestedMessage<::protozero::Message>(32));
33316   }
33317 
33318   // Field 39: chrome_application_state_info
33319   if (_has_field_[39]) {
33320     (*chrome_application_state_info_).Serialize(msg->BeginNestedMessage<::protozero::Message>(39));
33321   }
33322 
33323   // Field 40: chrome_renderer_scheduler_state
33324   if (_has_field_[40]) {
33325     (*chrome_renderer_scheduler_state_).Serialize(msg->BeginNestedMessage<::protozero::Message>(40));
33326   }
33327 
33328   // Field 41: chrome_window_handle_event_info
33329   if (_has_field_[41]) {
33330     (*chrome_window_handle_event_info_).Serialize(msg->BeginNestedMessage<::protozero::Message>(41));
33331   }
33332 
33333   // Field 43: chrome_content_settings_event_info
33334   if (_has_field_[43]) {
33335     (*chrome_content_settings_event_info_).Serialize(msg->BeginNestedMessage<::protozero::Message>(43));
33336   }
33337 
33338   // Field 33: source_location
33339   if (_has_field_[33]) {
33340     (*source_location_).Serialize(msg->BeginNestedMessage<::protozero::Message>(33));
33341   }
33342 
33343   // Field 34: source_location_iid
33344   if (_has_field_[34]) {
33345     msg->AppendVarInt(34, source_location_iid_);
33346   }
33347 
33348   // Field 35: chrome_message_pump
33349   if (_has_field_[35]) {
33350     (*chrome_message_pump_).Serialize(msg->BeginNestedMessage<::protozero::Message>(35));
33351   }
33352 
33353   // Field 38: chrome_mojo_event_info
33354   if (_has_field_[38]) {
33355     (*chrome_mojo_event_info_).Serialize(msg->BeginNestedMessage<::protozero::Message>(38));
33356   }
33357 
33358   // Field 1: timestamp_delta_us
33359   if (_has_field_[1]) {
33360     msg->AppendVarInt(1, timestamp_delta_us_);
33361   }
33362 
33363   // Field 16: timestamp_absolute_us
33364   if (_has_field_[16]) {
33365     msg->AppendVarInt(16, timestamp_absolute_us_);
33366   }
33367 
33368   // Field 2: thread_time_delta_us
33369   if (_has_field_[2]) {
33370     msg->AppendVarInt(2, thread_time_delta_us_);
33371   }
33372 
33373   // Field 17: thread_time_absolute_us
33374   if (_has_field_[17]) {
33375     msg->AppendVarInt(17, thread_time_absolute_us_);
33376   }
33377 
33378   // Field 8: thread_instruction_count_delta
33379   if (_has_field_[8]) {
33380     msg->AppendVarInt(8, thread_instruction_count_delta_);
33381   }
33382 
33383   // Field 20: thread_instruction_count_absolute
33384   if (_has_field_[20]) {
33385     msg->AppendVarInt(20, thread_instruction_count_absolute_);
33386   }
33387 
33388   // Field 6: legacy_event
33389   if (_has_field_[6]) {
33390     (*legacy_event_).Serialize(msg->BeginNestedMessage<::protozero::Message>(6));
33391   }
33392 
33393   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
33394 }
33395 
33396 
33397 TrackEvent_LegacyEvent::TrackEvent_LegacyEvent() = default;
33398 TrackEvent_LegacyEvent::~TrackEvent_LegacyEvent() = default;
33399 TrackEvent_LegacyEvent::TrackEvent_LegacyEvent(const TrackEvent_LegacyEvent&) = default;
33400 TrackEvent_LegacyEvent& TrackEvent_LegacyEvent::operator=(const TrackEvent_LegacyEvent&) = default;
33401 TrackEvent_LegacyEvent::TrackEvent_LegacyEvent(TrackEvent_LegacyEvent&&) noexcept = default;
33402 TrackEvent_LegacyEvent& TrackEvent_LegacyEvent::operator=(TrackEvent_LegacyEvent&&) = default;
33403 
operator ==(const TrackEvent_LegacyEvent & other) const33404 bool TrackEvent_LegacyEvent::operator==(const TrackEvent_LegacyEvent& other) const {
33405   return unknown_fields_ == other.unknown_fields_
33406    && name_iid_ == other.name_iid_
33407    && phase_ == other.phase_
33408    && duration_us_ == other.duration_us_
33409    && thread_duration_us_ == other.thread_duration_us_
33410    && thread_instruction_delta_ == other.thread_instruction_delta_
33411    && unscoped_id_ == other.unscoped_id_
33412    && local_id_ == other.local_id_
33413    && global_id_ == other.global_id_
33414    && id_scope_ == other.id_scope_
33415    && use_async_tts_ == other.use_async_tts_
33416    && bind_id_ == other.bind_id_
33417    && bind_to_enclosing_ == other.bind_to_enclosing_
33418    && flow_direction_ == other.flow_direction_
33419    && instant_event_scope_ == other.instant_event_scope_
33420    && pid_override_ == other.pid_override_
33421    && tid_override_ == other.tid_override_;
33422 }
33423 
ParseFromArray(const void * raw,size_t size)33424 bool TrackEvent_LegacyEvent::ParseFromArray(const void* raw, size_t size) {
33425   unknown_fields_.clear();
33426   bool packed_error = false;
33427 
33428   ::protozero::ProtoDecoder dec(raw, size);
33429   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
33430     if (field.id() < _has_field_.size()) {
33431       _has_field_.set(field.id());
33432     }
33433     switch (field.id()) {
33434       case 1 /* name_iid */:
33435         field.get(&name_iid_);
33436         break;
33437       case 2 /* phase */:
33438         field.get(&phase_);
33439         break;
33440       case 3 /* duration_us */:
33441         field.get(&duration_us_);
33442         break;
33443       case 4 /* thread_duration_us */:
33444         field.get(&thread_duration_us_);
33445         break;
33446       case 15 /* thread_instruction_delta */:
33447         field.get(&thread_instruction_delta_);
33448         break;
33449       case 6 /* unscoped_id */:
33450         field.get(&unscoped_id_);
33451         break;
33452       case 10 /* local_id */:
33453         field.get(&local_id_);
33454         break;
33455       case 11 /* global_id */:
33456         field.get(&global_id_);
33457         break;
33458       case 7 /* id_scope */:
33459         field.get(&id_scope_);
33460         break;
33461       case 9 /* use_async_tts */:
33462         field.get(&use_async_tts_);
33463         break;
33464       case 8 /* bind_id */:
33465         field.get(&bind_id_);
33466         break;
33467       case 12 /* bind_to_enclosing */:
33468         field.get(&bind_to_enclosing_);
33469         break;
33470       case 13 /* flow_direction */:
33471         field.get(&flow_direction_);
33472         break;
33473       case 14 /* instant_event_scope */:
33474         field.get(&instant_event_scope_);
33475         break;
33476       case 18 /* pid_override */:
33477         field.get(&pid_override_);
33478         break;
33479       case 19 /* tid_override */:
33480         field.get(&tid_override_);
33481         break;
33482       default:
33483         field.SerializeAndAppendTo(&unknown_fields_);
33484         break;
33485     }
33486   }
33487   return !packed_error && !dec.bytes_left();
33488 }
33489 
SerializeAsString() const33490 std::string TrackEvent_LegacyEvent::SerializeAsString() const {
33491   ::protozero::HeapBuffered<::protozero::Message> msg;
33492   Serialize(msg.get());
33493   return msg.SerializeAsString();
33494 }
33495 
SerializeAsArray() const33496 std::vector<uint8_t> TrackEvent_LegacyEvent::SerializeAsArray() const {
33497   ::protozero::HeapBuffered<::protozero::Message> msg;
33498   Serialize(msg.get());
33499   return msg.SerializeAsArray();
33500 }
33501 
Serialize(::protozero::Message * msg) const33502 void TrackEvent_LegacyEvent::Serialize(::protozero::Message* msg) const {
33503   // Field 1: name_iid
33504   if (_has_field_[1]) {
33505     msg->AppendVarInt(1, name_iid_);
33506   }
33507 
33508   // Field 2: phase
33509   if (_has_field_[2]) {
33510     msg->AppendVarInt(2, phase_);
33511   }
33512 
33513   // Field 3: duration_us
33514   if (_has_field_[3]) {
33515     msg->AppendVarInt(3, duration_us_);
33516   }
33517 
33518   // Field 4: thread_duration_us
33519   if (_has_field_[4]) {
33520     msg->AppendVarInt(4, thread_duration_us_);
33521   }
33522 
33523   // Field 15: thread_instruction_delta
33524   if (_has_field_[15]) {
33525     msg->AppendVarInt(15, thread_instruction_delta_);
33526   }
33527 
33528   // Field 6: unscoped_id
33529   if (_has_field_[6]) {
33530     msg->AppendVarInt(6, unscoped_id_);
33531   }
33532 
33533   // Field 10: local_id
33534   if (_has_field_[10]) {
33535     msg->AppendVarInt(10, local_id_);
33536   }
33537 
33538   // Field 11: global_id
33539   if (_has_field_[11]) {
33540     msg->AppendVarInt(11, global_id_);
33541   }
33542 
33543   // Field 7: id_scope
33544   if (_has_field_[7]) {
33545     msg->AppendString(7, id_scope_);
33546   }
33547 
33548   // Field 9: use_async_tts
33549   if (_has_field_[9]) {
33550     msg->AppendTinyVarInt(9, use_async_tts_);
33551   }
33552 
33553   // Field 8: bind_id
33554   if (_has_field_[8]) {
33555     msg->AppendVarInt(8, bind_id_);
33556   }
33557 
33558   // Field 12: bind_to_enclosing
33559   if (_has_field_[12]) {
33560     msg->AppendTinyVarInt(12, bind_to_enclosing_);
33561   }
33562 
33563   // Field 13: flow_direction
33564   if (_has_field_[13]) {
33565     msg->AppendVarInt(13, flow_direction_);
33566   }
33567 
33568   // Field 14: instant_event_scope
33569   if (_has_field_[14]) {
33570     msg->AppendVarInt(14, instant_event_scope_);
33571   }
33572 
33573   // Field 18: pid_override
33574   if (_has_field_[18]) {
33575     msg->AppendVarInt(18, pid_override_);
33576   }
33577 
33578   // Field 19: tid_override
33579   if (_has_field_[19]) {
33580     msg->AppendVarInt(19, tid_override_);
33581   }
33582 
33583   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
33584 }
33585 
33586 }  // namespace perfetto
33587 }  // namespace protos
33588 }  // namespace gen
33589 #if defined(__GNUC__) || defined(__clang__)
33590 #pragma GCC diagnostic pop
33591 #endif
33592 // gen_amalgamated begin source: gen/protos/perfetto/config/android/android_log_config.pbzero.cc
33593 // Intentionally empty (crbug.com/998165)
33594 // gen_amalgamated begin source: gen/protos/perfetto/config/android/android_polled_state_config.pbzero.cc
33595 // Intentionally empty (crbug.com/998165)
33596 // gen_amalgamated begin source: gen/protos/perfetto/config/android/packages_list_config.pbzero.cc
33597 // Intentionally empty (crbug.com/998165)
33598 // gen_amalgamated begin source: gen/protos/perfetto/config/ftrace/ftrace_config.pbzero.cc
33599 // Intentionally empty (crbug.com/998165)
33600 // gen_amalgamated begin source: gen/protos/perfetto/config/gpu/gpu_counter_config.pbzero.cc
33601 // Intentionally empty (crbug.com/998165)
33602 // gen_amalgamated begin source: gen/protos/perfetto/config/gpu/vulkan_memory_config.pbzero.cc
33603 // Intentionally empty (crbug.com/998165)
33604 // gen_amalgamated begin source: gen/protos/perfetto/config/inode_file/inode_file_config.pbzero.cc
33605 // Intentionally empty (crbug.com/998165)
33606 // gen_amalgamated begin source: gen/protos/perfetto/config/interceptors/console_config.pbzero.cc
33607 // Intentionally empty (crbug.com/998165)
33608 // gen_amalgamated begin source: gen/protos/perfetto/config/power/android_power_config.pbzero.cc
33609 // Intentionally empty (crbug.com/998165)
33610 // gen_amalgamated begin source: gen/protos/perfetto/config/process_stats/process_stats_config.pbzero.cc
33611 // Intentionally empty (crbug.com/998165)
33612 // gen_amalgamated begin source: gen/protos/perfetto/config/profiling/heapprofd_config.pbzero.cc
33613 // Intentionally empty (crbug.com/998165)
33614 // gen_amalgamated begin source: gen/protos/perfetto/config/profiling/java_hprof_config.pbzero.cc
33615 // Intentionally empty (crbug.com/998165)
33616 // gen_amalgamated begin source: gen/protos/perfetto/config/profiling/perf_event_config.pbzero.cc
33617 // Intentionally empty (crbug.com/998165)
33618 // gen_amalgamated begin source: gen/protos/perfetto/config/sys_stats/sys_stats_config.pbzero.cc
33619 // Intentionally empty (crbug.com/998165)
33620 // gen_amalgamated begin source: gen/protos/perfetto/config/track_event/track_event_config.pbzero.cc
33621 // Intentionally empty (crbug.com/998165)
33622 // gen_amalgamated begin source: gen/protos/perfetto/config/chrome/chrome_config.pbzero.cc
33623 // Intentionally empty (crbug.com/998165)
33624 // gen_amalgamated begin source: gen/protos/perfetto/config/data_source_config.pbzero.cc
33625 // Intentionally empty (crbug.com/998165)
33626 // gen_amalgamated begin source: gen/protos/perfetto/config/interceptor_config.pbzero.cc
33627 // Intentionally empty (crbug.com/998165)
33628 // gen_amalgamated begin source: gen/protos/perfetto/config/stress_test_config.pbzero.cc
33629 // Intentionally empty (crbug.com/998165)
33630 // gen_amalgamated begin source: gen/protos/perfetto/config/test_config.pbzero.cc
33631 // Intentionally empty (crbug.com/998165)
33632 // gen_amalgamated begin source: gen/protos/perfetto/config/trace_config.pbzero.cc
33633 // Intentionally empty (crbug.com/998165)
33634 // gen_amalgamated begin source: gen/protos/perfetto/trace/clock_snapshot.pbzero.cc
33635 // Intentionally empty (crbug.com/998165)
33636 // gen_amalgamated begin source: gen/protos/perfetto/trace/trigger.pbzero.cc
33637 // Intentionally empty (crbug.com/998165)
33638 // gen_amalgamated begin source: gen/protos/perfetto/trace/system_info.pbzero.cc
33639 // Intentionally empty (crbug.com/998165)
33640 // gen_amalgamated begin source: gen/protos/perfetto/trace/android/android_log.pbzero.cc
33641 // Intentionally empty (crbug.com/998165)
33642 // gen_amalgamated begin source: gen/protos/perfetto/trace/android/frame_timeline_event.pbzero.cc
33643 // Intentionally empty (crbug.com/998165)
33644 // gen_amalgamated begin source: gen/protos/perfetto/trace/android/gpu_mem_event.pbzero.cc
33645 // Intentionally empty (crbug.com/998165)
33646 // gen_amalgamated begin source: gen/protos/perfetto/trace/android/graphics_frame_event.pbzero.cc
33647 // Intentionally empty (crbug.com/998165)
33648 // gen_amalgamated begin source: gen/protos/perfetto/trace/android/initial_display_state.pbzero.cc
33649 // Intentionally empty (crbug.com/998165)
33650 // gen_amalgamated begin source: gen/protos/perfetto/trace/android/packages_list.pbzero.cc
33651 // Intentionally empty (crbug.com/998165)
33652 // gen_amalgamated begin source: gen/protos/perfetto/trace/chrome/chrome_benchmark_metadata.pbzero.cc
33653 // Intentionally empty (crbug.com/998165)
33654 // gen_amalgamated begin source: gen/protos/perfetto/trace/chrome/chrome_metadata.pbzero.cc
33655 // Intentionally empty (crbug.com/998165)
33656 // gen_amalgamated begin source: gen/protos/perfetto/trace/chrome/chrome_trace_event.pbzero.cc
33657 // Intentionally empty (crbug.com/998165)
33658 // gen_amalgamated begin source: gen/protos/perfetto/trace/filesystem/inode_file_map.pbzero.cc
33659 // Intentionally empty (crbug.com/998165)
33660 // gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/ftrace_event.pbzero.cc
33661 // Intentionally empty (crbug.com/998165)
33662 // gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/ftrace_event_bundle.pbzero.cc
33663 // Intentionally empty (crbug.com/998165)
33664 // gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/ftrace_stats.pbzero.cc
33665 // Intentionally empty (crbug.com/998165)
33666 // gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/test_bundle_wrapper.pbzero.cc
33667 // Intentionally empty (crbug.com/998165)
33668 // gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/generic.pbzero.cc
33669 // Intentionally empty (crbug.com/998165)
33670 // gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/binder.pbzero.cc
33671 // Intentionally empty (crbug.com/998165)
33672 // gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/block.pbzero.cc
33673 // Intentionally empty (crbug.com/998165)
33674 // gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/cgroup.pbzero.cc
33675 // Intentionally empty (crbug.com/998165)
33676 // gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/clk.pbzero.cc
33677 // Intentionally empty (crbug.com/998165)
33678 // gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/compaction.pbzero.cc
33679 // Intentionally empty (crbug.com/998165)
33680 // gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/cpuhp.pbzero.cc
33681 // Intentionally empty (crbug.com/998165)
33682 // gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/dmabuf_heap.pbzero.cc
33683 // Intentionally empty (crbug.com/998165)
33684 // gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/dpu.pbzero.cc
33685 // Intentionally empty (crbug.com/998165)
33686 // gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/ext4.pbzero.cc
33687 // Intentionally empty (crbug.com/998165)
33688 // gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/f2fs.pbzero.cc
33689 // Intentionally empty (crbug.com/998165)
33690 // gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/fastrpc.pbzero.cc
33691 // Intentionally empty (crbug.com/998165)
33692 // gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/fence.pbzero.cc
33693 // Intentionally empty (crbug.com/998165)
33694 // gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/filemap.pbzero.cc
33695 // Intentionally empty (crbug.com/998165)
33696 // gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/ftrace.pbzero.cc
33697 // Intentionally empty (crbug.com/998165)
33698 // gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/g2d.pbzero.cc
33699 // Intentionally empty (crbug.com/998165)
33700 // gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/gpu_mem.pbzero.cc
33701 // Intentionally empty (crbug.com/998165)
33702 // gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/i2c.pbzero.cc
33703 // Intentionally empty (crbug.com/998165)
33704 // gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/ion.pbzero.cc
33705 // Intentionally empty (crbug.com/998165)
33706 // gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/ipi.pbzero.cc
33707 // Intentionally empty (crbug.com/998165)
33708 // gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/irq.pbzero.cc
33709 // Intentionally empty (crbug.com/998165)
33710 // gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/kmem.pbzero.cc
33711 // Intentionally empty (crbug.com/998165)
33712 // gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/lowmemorykiller.pbzero.cc
33713 // Intentionally empty (crbug.com/998165)
33714 // gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/mali.pbzero.cc
33715 // Intentionally empty (crbug.com/998165)
33716 // gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/mdss.pbzero.cc
33717 // Intentionally empty (crbug.com/998165)
33718 // gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/mm_event.pbzero.cc
33719 // Intentionally empty (crbug.com/998165)
33720 // gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/oom.pbzero.cc
33721 // Intentionally empty (crbug.com/998165)
33722 // gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/power.pbzero.cc
33723 // Intentionally empty (crbug.com/998165)
33724 // gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/raw_syscalls.pbzero.cc
33725 // Intentionally empty (crbug.com/998165)
33726 // gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/regulator.pbzero.cc
33727 // Intentionally empty (crbug.com/998165)
33728 // gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/sched.pbzero.cc
33729 // Intentionally empty (crbug.com/998165)
33730 // gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/scm.pbzero.cc
33731 // Intentionally empty (crbug.com/998165)
33732 // gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/sde.pbzero.cc
33733 // Intentionally empty (crbug.com/998165)
33734 // gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/signal.pbzero.cc
33735 // Intentionally empty (crbug.com/998165)
33736 // gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/sync.pbzero.cc
33737 // Intentionally empty (crbug.com/998165)
33738 // gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/synthetic.pbzero.cc
33739 // Intentionally empty (crbug.com/998165)
33740 // gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/systrace.pbzero.cc
33741 // Intentionally empty (crbug.com/998165)
33742 // gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/task.pbzero.cc
33743 // Intentionally empty (crbug.com/998165)
33744 // gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/thermal.pbzero.cc
33745 // Intentionally empty (crbug.com/998165)
33746 // gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/vmscan.pbzero.cc
33747 // Intentionally empty (crbug.com/998165)
33748 // gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/workqueue.pbzero.cc
33749 // Intentionally empty (crbug.com/998165)
33750 // gen_amalgamated begin source: gen/protos/perfetto/trace/perfetto/perfetto_metatrace.pbzero.cc
33751 // Intentionally empty (crbug.com/998165)
33752 // gen_amalgamated begin source: gen/protos/perfetto/trace/perfetto/tracing_service_event.pbzero.cc
33753 // Intentionally empty (crbug.com/998165)
33754 // gen_amalgamated begin source: gen/protos/perfetto/trace/power/android_energy_estimation_breakdown.pbzero.cc
33755 // Intentionally empty (crbug.com/998165)
33756 // gen_amalgamated begin source: gen/protos/perfetto/trace/power/battery_counters.pbzero.cc
33757 // Intentionally empty (crbug.com/998165)
33758 // gen_amalgamated begin source: gen/protos/perfetto/trace/power/power_rails.pbzero.cc
33759 // Intentionally empty (crbug.com/998165)
33760 // gen_amalgamated begin source: gen/protos/perfetto/trace/ps/process_stats.pbzero.cc
33761 // Intentionally empty (crbug.com/998165)
33762 // gen_amalgamated begin source: gen/protos/perfetto/trace/ps/process_tree.pbzero.cc
33763 // Intentionally empty (crbug.com/998165)
33764 // gen_amalgamated begin source: gen/protos/perfetto/trace/sys_stats/sys_stats.pbzero.cc
33765 // Intentionally empty (crbug.com/998165)
33766 // gen_amalgamated begin source: gen/protos/perfetto/trace/system_info/cpu_info.pbzero.cc
33767 // Intentionally empty (crbug.com/998165)
33768 // gen_amalgamated begin source: gen/protos/perfetto/trace/trace_packet_defaults.pbzero.cc
33769 // Intentionally empty (crbug.com/998165)
33770 // gen_amalgamated begin source: gen/protos/perfetto/trace/test_event.pbzero.cc
33771 // Intentionally empty (crbug.com/998165)
33772 // gen_amalgamated begin source: gen/protos/perfetto/trace/test_extensions.pbzero.cc
33773 // Intentionally empty (crbug.com/998165)
33774 // gen_amalgamated begin source: gen/protos/perfetto/trace/trace_packet.pbzero.cc
33775 // Intentionally empty (crbug.com/998165)
33776 // gen_amalgamated begin source: gen/protos/perfetto/trace/trace.pbzero.cc
33777 // Intentionally empty (crbug.com/998165)
33778 // gen_amalgamated begin source: gen/protos/perfetto/trace/extension_descriptor.pbzero.cc
33779 // Intentionally empty (crbug.com/998165)
33780 // gen_amalgamated begin source: gen/protos/perfetto/trace/memory_graph.pbzero.cc
33781 // Intentionally empty (crbug.com/998165)
33782 // gen_amalgamated begin source: gen/protos/perfetto/trace/ui_state.pbzero.cc
33783 // Intentionally empty (crbug.com/998165)
33784 // gen_amalgamated begin source: src/tracing/trace_writer_base.cc
33785 /*
33786  * Copyright (C) 2019 The Android Open Source Project
33787  *
33788  * Licensed under the Apache License, Version 2.0 (the "License");
33789  * you may not use this file except in compliance with the License.
33790  * You may obtain a copy of the License at
33791  *
33792  *      http://www.apache.org/licenses/LICENSE-2.0
33793  *
33794  * Unless required by applicable law or agreed to in writing, software
33795  * distributed under the License is distributed on an "AS IS" BASIS,
33796  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
33797  * See the License for the specific language governing permissions and
33798  * limitations under the License.
33799  */
33800 
33801 // gen_amalgamated expanded: #include "perfetto/tracing/trace_writer_base.h"
33802 
33803 namespace perfetto {
33804 
33805 // This destructor needs to be defined in a dedicated translation unit and
33806 // cannot be merged together with the other ones in virtual_destructors.cc.
33807 // This is because trace_writer_base.h/cc  is part of a separate target
33808 // (src/public:common) that is linked also by other part of the codebase.
33809 
33810 TraceWriterBase::~TraceWriterBase() = default;
33811 
33812 }  // namespace perfetto
33813 // gen_amalgamated begin source: src/tracing/core/id_allocator.cc
33814 // gen_amalgamated begin header: src/tracing/core/id_allocator.h
33815 /*
33816  * Copyright (C) 2017 The Android Open Source Project
33817  *
33818  * Licensed under the Apache License, Version 2.0 (the "License");
33819  * you may not use this file except in compliance with the License.
33820  * You may obtain a copy of the License at
33821  *
33822  *      http://www.apache.org/licenses/LICENSE-2.0
33823  *
33824  * Unless required by applicable law or agreed to in writing, software
33825  * distributed under the License is distributed on an "AS IS" BASIS,
33826  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
33827  * See the License for the specific language governing permissions and
33828  * limitations under the License.
33829  */
33830 
33831 #ifndef SRC_TRACING_CORE_ID_ALLOCATOR_H_
33832 #define SRC_TRACING_CORE_ID_ALLOCATOR_H_
33833 
33834 #include <stdint.h>
33835 
33836 #include <type_traits>
33837 #include <vector>
33838 
33839 namespace perfetto {
33840 
33841 // Handles assigment of IDs (int types) from a fixed-size pool.
33842 // Zero is not considered a valid ID.
33843 // The base class takes always a uint32_t and the derived class casts and checks
33844 // bounds at compile time. This is to avoid bloating code with different
33845 // instances of the main class for each size.
33846 class IdAllocatorGeneric {
33847  public:
33848   // |max_id| is inclusive.
33849   explicit IdAllocatorGeneric(uint32_t max_id);
33850   ~IdAllocatorGeneric();
33851 
33852   // Returns an ID in the range [1, max_id] or 0 if no more ids are available.
33853   uint32_t AllocateGeneric();
33854   void FreeGeneric(uint32_t);
33855 
33856   bool IsEmpty() const;
33857 
33858  private:
33859   IdAllocatorGeneric(const IdAllocatorGeneric&) = delete;
33860   IdAllocatorGeneric& operator=(const IdAllocatorGeneric&) = delete;
33861 
33862   const uint32_t max_id_;
33863   uint32_t last_id_ = 0;
33864   std::vector<bool> ids_;
33865 };
33866 
33867 template <typename T = uint32_t>
33868 class IdAllocator : public IdAllocatorGeneric {
33869  public:
IdAllocator(T end)33870   explicit IdAllocator(T end) : IdAllocatorGeneric(end) {
33871     static_assert(std::is_integral<T>::value && std::is_unsigned<T>::value,
33872                   "T must be an unsigned integer");
33873     static_assert(sizeof(T) <= sizeof(uint32_t), "T is too big");
33874   }
33875 
Allocate()33876   T Allocate() { return static_cast<T>(AllocateGeneric()); }
Free(T id)33877   void Free(T id) { FreeGeneric(id); }
33878 };
33879 
33880 }  // namespace perfetto
33881 
33882 #endif  // SRC_TRACING_CORE_ID_ALLOCATOR_H_
33883 /*
33884  * Copyright (C) 2017 The Android Open Source Project
33885  *
33886  * Licensed under the Apache License, Version 2.0 (the "License");
33887  * you may not use this file except in compliance with the License.
33888  * You may obtain a copy of the License at
33889  *
33890  *      http://www.apache.org/licenses/LICENSE-2.0
33891  *
33892  * Unless required by applicable law or agreed to in writing, software
33893  * distributed under the License is distributed on an "AS IS" BASIS,
33894  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
33895  * See the License for the specific language governing permissions and
33896  * limitations under the License.
33897  */
33898 
33899 // gen_amalgamated expanded: #include "src/tracing/core/id_allocator.h"
33900 
33901 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
33902 
33903 namespace perfetto {
33904 
IdAllocatorGeneric(uint32_t max_id)33905 IdAllocatorGeneric::IdAllocatorGeneric(uint32_t max_id) : max_id_(max_id) {
33906   PERFETTO_DCHECK(max_id > 1);
33907 }
33908 
33909 IdAllocatorGeneric::~IdAllocatorGeneric() = default;
33910 
AllocateGeneric()33911 uint32_t IdAllocatorGeneric::AllocateGeneric() {
33912   for (uint32_t ignored = 1; ignored <= max_id_; ignored++) {
33913     last_id_ = last_id_ < max_id_ ? last_id_ + 1 : 1;
33914     const auto id = last_id_;
33915 
33916     // 0 is never a valid ID. So if we are looking for |id| == N and there are
33917     // N or less elements in the vector, they must necessarily be all < N.
33918     // e.g. if |id| == 4 and size() == 4, the vector will contain IDs 0,1,2,3.
33919     if (id >= ids_.size()) {
33920       ids_.resize(id + 1);
33921       ids_[id] = true;
33922       return id;
33923     }
33924 
33925     if (!ids_[id]) {
33926       ids_[id] = true;
33927       return id;
33928     }
33929   }
33930   return 0;
33931 }
33932 
FreeGeneric(uint32_t id)33933 void IdAllocatorGeneric::FreeGeneric(uint32_t id) {
33934   if (id == 0 || id >= ids_.size() || !ids_[id]) {
33935     PERFETTO_DFATAL("Invalid id.");
33936     return;
33937   }
33938   ids_[id] = false;
33939 }
33940 
IsEmpty() const33941 bool IdAllocatorGeneric::IsEmpty() const {
33942   for (auto id : ids_) {
33943     if (id)
33944       return false;
33945   }
33946   return true;
33947 }
33948 
33949 }  // namespace perfetto
33950 // gen_amalgamated begin source: src/tracing/core/null_trace_writer.cc
33951 // gen_amalgamated begin header: src/tracing/core/null_trace_writer.h
33952 // gen_amalgamated begin header: include/perfetto/ext/tracing/core/trace_writer.h
33953 // gen_amalgamated begin header: include/perfetto/ext/tracing/core/basic_types.h
33954 /*
33955  * Copyright (C) 2017 The Android Open Source Project
33956  *
33957  * Licensed under the Apache License, Version 2.0 (the "License");
33958  * you may not use this file except in compliance with the License.
33959  * You may obtain a copy of the License at
33960  *
33961  *      http://www.apache.org/licenses/LICENSE-2.0
33962  *
33963  * Unless required by applicable law or agreed to in writing, software
33964  * distributed under the License is distributed on an "AS IS" BASIS,
33965  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
33966  * See the License for the specific language governing permissions and
33967  * limitations under the License.
33968  */
33969 
33970 #ifndef INCLUDE_PERFETTO_EXT_TRACING_CORE_BASIC_TYPES_H_
33971 #define INCLUDE_PERFETTO_EXT_TRACING_CORE_BASIC_TYPES_H_
33972 
33973 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
33974 
33975 #include <stddef.h>
33976 #include <stdint.h>
33977 #include <sys/types.h>
33978 
33979 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
33980 using uid_t = unsigned int;
33981 #endif
33982 
33983 namespace perfetto {
33984 
33985 // Unique within the scope of the tracing service.
33986 using TracingSessionID = uint64_t;
33987 
33988 // Unique within the scope of the tracing service.
33989 using ProducerID = uint16_t;
33990 
33991 // Unique within the scope of the tracing service.
33992 using DataSourceInstanceID = uint64_t;
33993 
33994 // Unique within the scope of a Producer.
33995 using WriterID = uint16_t;
33996 
33997 // Unique within the scope of the tracing service.
33998 using FlushRequestID = uint64_t;
33999 
34000 // We need one FD per producer and we are not going to be able to keep > 64k FDs
34001 // open in the service.
34002 static constexpr ProducerID kMaxProducerID = static_cast<ProducerID>(-1);
34003 
34004 // 1024 Writers per producer seems a resonable bound. This reduces the ability
34005 // to memory-DoS the service by having to keep track of too many writer IDs.
34006 static constexpr WriterID kMaxWriterID = static_cast<WriterID>((1 << 10) - 1);
34007 
34008 // Unique within the scope of a {ProducerID, WriterID} tuple.
34009 using ChunkID = uint32_t;
34010 static constexpr ChunkID kMaxChunkID = static_cast<ChunkID>(-1);
34011 
34012 // Unique within the scope of the tracing service.
34013 using BufferID = uint16_t;
34014 
34015 // Target buffer ID for SharedMemoryArbiter. Values up to max uint16_t are
34016 // equivalent to a bound BufferID. Values above max uint16_t are reservation IDs
34017 // for the target buffer of a startup trace writer. Reservation IDs will be
34018 // translated to actual BufferIDs after they are bound by
34019 // SharedMemoryArbiter::BindStartupTargetBuffer().
34020 using MaybeUnboundBufferID = uint32_t;
34021 
34022 // Keep this in sync with SharedMemoryABI::PageHeader::target_buffer.
34023 static constexpr BufferID kMaxTraceBufferID = static_cast<BufferID>(-1);
34024 
34025 // Unique within the scope of a tracing session.
34026 using PacketSequenceID = uint32_t;
34027 // Used for extra packets emitted by the service, such as statistics.
34028 static constexpr PacketSequenceID kServicePacketSequenceID = 1;
34029 static constexpr PacketSequenceID kMaxPacketSequenceID =
34030     static_cast<PacketSequenceID>(-1);
34031 
34032 constexpr uid_t kInvalidUid = static_cast<uid_t>(-1);
34033 
34034 constexpr uint32_t kDefaultFlushTimeoutMs = 5000;
34035 
34036 }  // namespace perfetto
34037 
34038 #endif  // INCLUDE_PERFETTO_EXT_TRACING_CORE_BASIC_TYPES_H_
34039 /*
34040  * Copyright (C) 2017 The Android Open Source Project
34041  *
34042  * Licensed under the Apache License, Version 2.0 (the "License");
34043  * you may not use this file except in compliance with the License.
34044  * You may obtain a copy of the License at
34045  *
34046  *      http://www.apache.org/licenses/LICENSE-2.0
34047  *
34048  * Unless required by applicable law or agreed to in writing, software
34049  * distributed under the License is distributed on an "AS IS" BASIS,
34050  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
34051  * See the License for the specific language governing permissions and
34052  * limitations under the License.
34053  */
34054 
34055 #ifndef INCLUDE_PERFETTO_EXT_TRACING_CORE_TRACE_WRITER_H_
34056 #define INCLUDE_PERFETTO_EXT_TRACING_CORE_TRACE_WRITER_H_
34057 
34058 #include <functional>
34059 
34060 // gen_amalgamated expanded: #include "perfetto/base/export.h"
34061 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/basic_types.h"
34062 // gen_amalgamated expanded: #include "perfetto/protozero/message_handle.h"
34063 // gen_amalgamated expanded: #include "perfetto/tracing/trace_writer_base.h"
34064 
34065 namespace perfetto {
34066 
34067 namespace protos {
34068 namespace pbzero {
34069 class TracePacket;
34070 }  // namespace pbzero
34071 }  // namespace protos
34072 
34073 // This is a single-thread write interface that allows to write protobufs
34074 // directly into the tracing shared buffer without making any copies.
34075 // It takes care of acquiring and releasing chunks from the
34076 // SharedMemoryArbiter and splitting protos over chunks.
34077 // The idea is that each data source creates one (or more) TraceWriter for each
34078 // thread it wants to write from. Each TraceWriter will get its own dedicated
34079 // chunk and will write into the shared buffer without any locking most of the
34080 // time. Locking will happen only when a chunk is exhausted and a new one is
34081 // acquired from the arbiter.
34082 
34083 // TODO: TraceWriter needs to keep the shared memory buffer alive (refcount?).
34084 // Otherwise if the shared memory buffer goes away (e.g. the Service crashes)
34085 // the TraceWriter will keep writing into unmapped memory.
34086 
34087 class PERFETTO_EXPORT TraceWriter : public TraceWriterBase {
34088  public:
34089   using TracePacketHandle =
34090       protozero::MessageHandle<protos::pbzero::TracePacket>;
34091 
34092   TraceWriter();
34093   ~TraceWriter() override;
34094 
34095   // Returns a handle to the root proto message for the trace. The message will
34096   // be finalized either by calling directly handle.Finalize() or by letting the
34097   // handle go out of scope. The returned handle can be std::move()'d but cannot
34098   // be used after either: (i) the TraceWriter instance is destroyed, (ii) a
34099   // subsequence NewTracePacket() call is made on the same TraceWriter instance.
34100   // The returned packet handle is always valid, but note that, when using
34101   // BufferExhaustedPolicy::kDrop and the SMB is exhausted, it may be assigned
34102   // a garbage chunk and any trace data written into it will be lost. For more
34103   // details on buffer size choices: https://perfetto.dev/docs/concepts/buffers.
34104   TracePacketHandle NewTracePacket() override = 0;
34105 
34106   // Commits the data pending for the current chunk into the shared memory
34107   // buffer and sends a CommitDataRequest() to the service. This can be called
34108   // only if the handle returned by NewTracePacket() has been destroyed (i.e. we
34109   // cannot Flush() while writing a TracePacket).
34110   // Note: Flush() also happens implicitly when destroying the TraceWriter.
34111   // |callback| is an optional callback. When non-null it will request the
34112   // service to ACK the flush and will be invoked after the service has
34113   // acknowledged it. The callback might be NEVER INVOKED if the service crashes
34114   // or the IPC connection is dropped. The callback should be used only by tests
34115   // and best-effort features (logging).
34116   // TODO(primiano): right now the |callback| will be called on the IPC thread.
34117   // This is fine in the current single-thread scenario, but long-term
34118   // trace_writer_impl.cc should be smarter and post it on the right thread.
34119   void Flush(std::function<void()> callback = {}) override = 0;
34120 
34121   virtual WriterID writer_id() const = 0;
34122 
34123   // Bytes written since creation. Is not reset when new chunks are acquired.
34124   virtual uint64_t written() const override = 0;
34125 
34126  private:
34127   TraceWriter(const TraceWriter&) = delete;
34128   TraceWriter& operator=(const TraceWriter&) = delete;
34129 };
34130 
34131 }  // namespace perfetto
34132 
34133 #endif  // INCLUDE_PERFETTO_EXT_TRACING_CORE_TRACE_WRITER_H_
34134 /*
34135  * Copyright (C) 2018 The Android Open Source Project
34136  *
34137  * Licensed under the Apache License, Version 2.0 (the "License");
34138  * you may not use this file except in compliance with the License.
34139  * You may obtain a copy of the License at
34140  *
34141  *      http://www.apache.org/licenses/LICENSE-2.0
34142  *
34143  * Unless required by applicable law or agreed to in writing, software
34144  * distributed under the License is distributed on an "AS IS" BASIS,
34145  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
34146  * See the License for the specific language governing permissions and
34147  * limitations under the License.
34148  */
34149 
34150 #ifndef SRC_TRACING_CORE_NULL_TRACE_WRITER_H_
34151 #define SRC_TRACING_CORE_NULL_TRACE_WRITER_H_
34152 
34153 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/trace_writer.h"
34154 // gen_amalgamated expanded: #include "perfetto/protozero/message_handle.h"
34155 // gen_amalgamated expanded: #include "perfetto/protozero/root_message.h"
34156 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_stream_null_delegate.h"
34157 
34158 namespace perfetto {
34159 
34160 // A specialization of TraceWriter which no-ops all the writes routing them
34161 // into a fixed region of memory
34162 // See //include/perfetto/tracing/core/trace_writer.h for docs.
34163 class NullTraceWriter : public TraceWriter {
34164  public:
34165   NullTraceWriter();
34166   ~NullTraceWriter() override;
34167 
34168   // TraceWriter implementation. See documentation in trace_writer.h.
34169   // TracePacketHandle is defined in trace_writer.h
34170   TracePacketHandle NewTracePacket() override;
34171   void Flush(std::function<void()> callback = {}) override;
34172   WriterID writer_id() const override;
34173   uint64_t written() const override;
34174 
34175  private:
34176   NullTraceWriter(const NullTraceWriter&) = delete;
34177   NullTraceWriter& operator=(const NullTraceWriter&) = delete;
34178 
34179   protozero::ScatteredStreamWriterNullDelegate delegate_;
34180   protozero::ScatteredStreamWriter stream_;
34181 
34182   // The packet returned via NewTracePacket(). Its owned by this class,
34183   // TracePacketHandle has just a pointer to it.
34184   std::unique_ptr<protozero::RootMessage<protos::pbzero::TracePacket>>
34185       cur_packet_;
34186 };
34187 
34188 }  // namespace perfetto
34189 
34190 #endif  // SRC_TRACING_CORE_NULL_TRACE_WRITER_H_
34191 /*
34192  * Copyright (C) 2018 The Android Open Source Project
34193  *
34194  * Licensed under the Apache License, Version 2.0 (the "License");
34195  * you may not use this file except in compliance with the License.
34196  * You may obtain a copy of the License at
34197  *
34198  *      http://www.apache.org/licenses/LICENSE-2.0
34199  *
34200  * Unless required by applicable law or agreed to in writing, software
34201  * distributed under the License is distributed on an "AS IS" BASIS,
34202  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
34203  * See the License for the specific language governing permissions and
34204  * limitations under the License.
34205  */
34206 
34207 // gen_amalgamated expanded: #include "src/tracing/core/null_trace_writer.h"
34208 
34209 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
34210 // gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
34211 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
34212 
34213 // gen_amalgamated expanded: #include "protos/perfetto/trace/trace_packet.pbzero.h"
34214 
34215 namespace perfetto {
34216 
NullTraceWriter()34217 NullTraceWriter::NullTraceWriter() : delegate_(4096), stream_(&delegate_) {
34218   cur_packet_.reset(new protozero::RootMessage<protos::pbzero::TracePacket>());
34219   cur_packet_->Finalize();  // To avoid the DCHECK in NewTracePacket().
34220 }
34221 
~NullTraceWriter()34222 NullTraceWriter::~NullTraceWriter() {}
34223 
Flush(std::function<void ()> callback)34224 void NullTraceWriter::Flush(std::function<void()> callback) {
34225   // Flush() cannot be called in the middle of a TracePacket.
34226   PERFETTO_CHECK(cur_packet_->is_finalized());
34227 
34228   if (callback)
34229     callback();
34230 }
34231 
NewTracePacket()34232 NullTraceWriter::TracePacketHandle NullTraceWriter::NewTracePacket() {
34233   // If we hit this, the caller is calling NewTracePacket() without having
34234   // finalized the previous packet.
34235   PERFETTO_DCHECK(cur_packet_->is_finalized());
34236   cur_packet_->Reset(&stream_);
34237   return TraceWriter::TracePacketHandle(cur_packet_.get());
34238 }
34239 
writer_id() const34240 WriterID NullTraceWriter::writer_id() const {
34241   return 0;
34242 }
34243 
written() const34244 uint64_t NullTraceWriter::written() const {
34245   return 0;
34246 }
34247 
34248 }  // namespace perfetto
34249 // gen_amalgamated begin source: src/tracing/core/shared_memory_abi.cc
34250 // gen_amalgamated begin header: include/perfetto/ext/tracing/core/shared_memory_abi.h
34251 /*
34252  * Copyright (C) 2017 The Android Open Source Project
34253  *
34254  * Licensed under the Apache License, Version 2.0 (the "License");
34255  * you may not use this file except in compliance with the License.
34256  * You may obtain a copy of the License at
34257  *
34258  *      http://www.apache.org/licenses/LICENSE-2.0
34259  *
34260  * Unless required by applicable law or agreed to in writing, software
34261  * distributed under the License is distributed on an "AS IS" BASIS,
34262  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
34263  * See the License for the specific language governing permissions and
34264  * limitations under the License.
34265  */
34266 
34267 #ifndef INCLUDE_PERFETTO_EXT_TRACING_CORE_SHARED_MEMORY_ABI_H_
34268 #define INCLUDE_PERFETTO_EXT_TRACING_CORE_SHARED_MEMORY_ABI_H_
34269 
34270 #include <stddef.h>
34271 #include <stdint.h>
34272 
34273 #include <array>
34274 #include <atomic>
34275 #include <bitset>
34276 #include <thread>
34277 #include <type_traits>
34278 #include <utility>
34279 
34280 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
34281 // gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
34282 
34283 namespace perfetto {
34284 
34285 // This file defines the binary interface of the memory buffers shared between
34286 // Producer and Service. This is a long-term stable ABI and has to be backwards
34287 // compatible to deal with mismatching Producer and Service versions.
34288 //
34289 // Overview
34290 // --------
34291 // SMB := "Shared Memory Buffer".
34292 // In the most typical case of a multi-process architecture (i.e. Producer and
34293 // Service are hosted by different processes), a Producer means almost always
34294 // a "client process producing data" (almost: in some cases a process might host
34295 // > 1 Producer, if it links two libraries, independent of each other, that both
34296 // use Perfetto tracing).
34297 // The Service has one SMB for each Producer.
34298 // A producer has one or (typically) more data sources. They all share the same
34299 // SMB.
34300 // The SMB is a staging area to decouple data sources living in the Producer
34301 // and allow them to do non-blocking async writes.
34302 // The SMB is *not* the ultimate logging buffer seen by the Consumer. That one
34303 // is larger (~MBs) and not shared with Producers.
34304 // Each SMB is small, typically few KB. Its size is configurable by the producer
34305 // within a max limit of ~MB (see kMaxShmSize in tracing_service_impl.cc).
34306 // The SMB is partitioned into fixed-size Page(s). The size of the Pages are
34307 // determined by each Producer at connection time and cannot be changed.
34308 // Hence, different producers can have SMB(s) that have a different Page size
34309 // from each other, but the page size will be constant throughout all the
34310 // lifetime of the SMB.
34311 // Page(s) are partitioned by the Producer into variable size Chunk(s):
34312 //
34313 // +------------+      +--------------------------+
34314 // | Producer 1 |  <-> |      SMB 1 [~32K - 1MB]  |
34315 // +------------+      +--------+--------+--------+
34316 //                     |  Page  |  Page  |  Page  |
34317 //                     +--------+--------+--------+
34318 //                     | Chunk  |        | Chunk  |
34319 //                     +--------+  Chunk +--------+ <----+
34320 //                     | Chunk  |        | Chunk  |      |
34321 //                     +--------+--------+--------+      +---------------------+
34322 //                                                       |       Service       |
34323 // +------------+      +--------------------------+      +---------------------+
34324 // | Producer 2 |  <-> |      SMB 2 [~32K - 1MB]  |     /| large ring buffers  |
34325 // +------------+      +--------+--------+--------+ <--+ | (100K - several MB) |
34326 //                     |  Page  |  Page  |  Page  |      +---------------------+
34327 //                     +--------+--------+--------+
34328 //                     | Chunk  |        | Chunk  |
34329 //                     +--------+  Chunk +--------+
34330 //                     | Chunk  |        | Chunk  |
34331 //                     +--------+--------+--------+
34332 //
34333 // * Sizes of both SMB and ring buffers are purely indicative and decided at
34334 // configuration time by the Producer (for SMB sizes) and the Consumer (for the
34335 // final ring buffer size).
34336 
34337 // Page
34338 // ----
34339 // A page is a portion of the shared memory buffer and defines the granularity
34340 // of the interaction between the Producer and tracing Service. When scanning
34341 // the shared memory buffer to determine if something should be moved to the
34342 // central logging buffers, the Service most of the times looks at and moves
34343 // whole pages. Similarly, the Producer sends an IPC to invite the Service to
34344 // drain the shared memory buffer only when a whole page is filled.
34345 // Having fixed the total SMB size (hence the total memory overhead), the page
34346 // size is a triangular tradeoff between:
34347 // 1) IPC traffic: smaller pages -> more IPCs.
34348 // 2) Producer lock freedom: larger pages -> larger chunks -> data sources can
34349 //    write more data without needing to swap chunks and synchronize.
34350 // 3) Risk of write-starving the SMB: larger pages -> higher chance that the
34351 //    Service won't manage to drain them and the SMB remains full.
34352 // The page size, on the other side, has no implications on wasted memory due to
34353 // fragmentations (see Chunk below).
34354 // The size of the page is chosen by the Service at connection time and stays
34355 // fixed throughout all the lifetime of the Producer. Different producers (i.e.
34356 // ~ different client processes) can use different page sizes.
34357 // The page size must be an integer multiple of 4k (this is to allow VM page
34358 // stealing optimizations) and obviously has to be an integer divisor of the
34359 // total SMB size.
34360 
34361 // Chunk
34362 // -----
34363 // A chunk is a portion of a Page which is written and handled by a Producer.
34364 // A chunk contains a linear sequence of TracePacket(s) (the root proto).
34365 // A chunk cannot be written concurrently by two data sources. Protobufs must be
34366 // encoded as contiguous byte streams and cannot be interleaved. Therefore, on
34367 // the Producer side, a chunk is almost always owned exclusively by one thread
34368 // (% extremely peculiar slow-path cases).
34369 // Chunks are essentially single-writer single-thread lock-free arenas. Locking
34370 // happens only when a Chunk is full and a new one needs to be acquired.
34371 // Locking happens only within the scope of a Producer process. There is no
34372 // inter-process locking. The Producer cannot lock the Service and viceversa.
34373 // In the worst case, any of the two can starve the SMB, by marking all chunks
34374 // as either being read or written. But that has the only side effect of
34375 // losing the trace data.
34376 // The Producer can decide to partition each page into a number of limited
34377 // configurations (e.g., 1 page == 1 chunk, 1 page == 2 chunks and so on).
34378 
34379 // TracePacket
34380 // -----------
34381 // Is the atom of tracing. Putting aside pages and chunks a trace is merely a
34382 // sequence of TracePacket(s). TracePacket is the root protobuf message.
34383 // A TracePacket can span across several chunks (hence even across several
34384 // pages). A TracePacket can therefore be >> chunk size, >> page size and even
34385 // >> SMB size. The Chunk header carries metadata to deal with the TracePacket
34386 // splitting case.
34387 
34388 // Use only explicitly-sized types below. DO NOT use size_t or any architecture
34389 // dependent size (e.g. size_t) in the struct fields. This buffer will be read
34390 // and written by processes that have a different bitness in the same OS.
34391 // Instead it's fine to assume little-endianess. Big-endian is a dream we are
34392 // not currently pursuing.
34393 
34394 class SharedMemoryABI {
34395  public:
34396   static constexpr size_t kMinPageSize = 4 * 1024;
34397 
34398   // This is due to Chunk::size being 16 bits.
34399   static constexpr size_t kMaxPageSize = 64 * 1024;
34400 
34401   // "14" is the max number that can be encoded in a 32 bit atomic word using
34402   // 2 state bits per Chunk and leaving 4 bits for the page layout.
34403   // See PageLayout below.
34404   static constexpr size_t kMaxChunksPerPage = 14;
34405 
34406   // Each TracePacket in the Chunk is prefixed by a 4 bytes redundant VarInt
34407   // (see proto_utils.h) stating its size.
34408   static constexpr size_t kPacketHeaderSize = 4;
34409 
34410   // TraceWriter specifies this invalid packet/fragment size to signal to the
34411   // service that a packet should be discarded, because the TraceWriter couldn't
34412   // write its remaining fragments (e.g. because the SMB was exhausted).
34413   static constexpr size_t kPacketSizeDropPacket =
34414       protozero::proto_utils::kMaxMessageLength;
34415 
34416   // Chunk states and transitions:
34417   //    kChunkFree  <----------------+
34418   //         |  (Producer)           |
34419   //         V                       |
34420   //  kChunkBeingWritten             |
34421   //         |  (Producer)           |
34422   //         V                       |
34423   //  kChunkComplete                 |
34424   //         |  (Service)            |
34425   //         V                       |
34426   //  kChunkBeingRead                |
34427   //        |   (Service)            |
34428   //        +------------------------+
34429   enum ChunkState : uint32_t {
34430     // The Chunk is free. The Service shall never touch it, the Producer can
34431     // acquire it and transition it into kChunkBeingWritten.
34432     kChunkFree = 0,
34433 
34434     // The Chunk is being used by the Producer and is not complete yet.
34435     // The Service shall never touch kChunkBeingWritten pages.
34436     kChunkBeingWritten = 1,
34437 
34438     // The Service is moving the page into its non-shared ring buffer. The
34439     // Producer shall never touch kChunkBeingRead pages.
34440     kChunkBeingRead = 2,
34441 
34442     // The Producer is done writing the page and won't touch it again. The
34443     // Service can now move it to its non-shared ring buffer.
34444     // kAllChunksComplete relies on this being == 3.
34445     kChunkComplete = 3,
34446   };
34447   static constexpr const char* kChunkStateStr[] = {"Free", "BeingWritten",
34448                                                    "BeingRead", "Complete"};
34449 
34450   enum PageLayout : uint32_t {
34451     // The page is fully free and has not been partitioned yet.
34452     kPageNotPartitioned = 0,
34453 
34454     // TODO(primiano): Aligning a chunk @ 16 bytes could allow to use faster
34455     // intrinsics based on quad-word moves. Do the math and check what is the
34456     // fragmentation loss.
34457 
34458     // align4(X) := the largest integer N s.t. (N % 4) == 0 && N <= X.
34459     // 8 == sizeof(PageHeader).
34460     kPageDiv1 = 1,   // Only one chunk of size: PAGE_SIZE - 8.
34461     kPageDiv2 = 2,   // Two chunks of size: align4((PAGE_SIZE - 8) / 2).
34462     kPageDiv4 = 3,   // Four chunks of size: align4((PAGE_SIZE - 8) / 4).
34463     kPageDiv7 = 4,   // Seven chunks of size: align4((PAGE_SIZE - 8) / 7).
34464     kPageDiv14 = 5,  // Fourteen chunks of size: align4((PAGE_SIZE - 8) / 14).
34465 
34466     // The rationale for 7 and 14 above is to maximize the page usage for the
34467     // likely case of |page_size| == 4096:
34468     // (((4096 - 8) / 14) % 4) == 0, while (((4096 - 8) / 16 % 4)) == 3. So
34469     // Div16 would waste 3 * 16 = 48 bytes per page for chunk alignment gaps.
34470 
34471     kPageDivReserved1 = 6,
34472     kPageDivReserved2 = 7,
34473     kNumPageLayouts = 8,
34474   };
34475 
34476   // Keep this consistent with the PageLayout enum above.
34477   static constexpr uint32_t kNumChunksForLayout[] = {0, 1, 2, 4, 7, 14, 0, 0};
34478 
34479   // Layout of a Page.
34480   // +===================================================+
34481   // | Page header [8 bytes]                             |
34482   // | Tells how many chunks there are, how big they are |
34483   // | and their state (free, read, write, complete).    |
34484   // +===================================================+
34485   // +***************************************************+
34486   // | Chunk #0 header [8 bytes]                         |
34487   // | Tells how many packets there are and whether the  |
34488   // | whether the 1st and last ones are fragmented.     |
34489   // | Also has a chunk id to reassemble fragments.    |
34490   // +***************************************************+
34491   // +---------------------------------------------------+
34492   // | Packet #0 size [varint, up to 4 bytes]            |
34493   // + - - - - - - - - - - - - - - - - - - - - - - - - - +
34494   // | Packet #0 payload                                 |
34495   // | A TracePacket protobuf message                    |
34496   // +---------------------------------------------------+
34497   //                         ...
34498   // + . . . . . . . . . . . . . . . . . . . . . . . . . +
34499   // |      Optional padding to maintain aligment        |
34500   // + . . . . . . . . . . . . . . . . . . . . . . . . . +
34501   // +---------------------------------------------------+
34502   // | Packet #N size [varint, up to 4 bytes]            |
34503   // + - - - - - - - - - - - - - - - - - - - - - - - - - +
34504   // | Packet #N payload                                 |
34505   // | A TracePacket protobuf message                    |
34506   // +---------------------------------------------------+
34507   //                         ...
34508   // +***************************************************+
34509   // | Chunk #M header [8 bytes]                         |
34510   //                         ...
34511 
34512   // Alignment applies to start offset only. The Chunk size is *not* aligned.
34513   static constexpr uint32_t kChunkAlignment = 4;
34514   static constexpr uint32_t kChunkShift = 2;
34515   static constexpr uint32_t kChunkMask = 0x3;
34516   static constexpr uint32_t kLayoutMask = 0x70000000;
34517   static constexpr uint32_t kLayoutShift = 28;
34518   static constexpr uint32_t kAllChunksMask = 0x0FFFFFFF;
34519 
34520   // This assumes that kChunkComplete == 3.
34521   static constexpr uint32_t kAllChunksComplete = 0x0FFFFFFF;
34522   static constexpr uint32_t kAllChunksFree = 0;
34523   static constexpr size_t kInvalidPageIdx = static_cast<size_t>(-1);
34524 
34525   // There is one page header per page, at the beginning of the page.
34526   struct PageHeader {
34527     // |layout| bits:
34528     // [31] [30:28] [27:26] ... [1:0]
34529     //  |      |       |     |    |
34530     //  |      |       |     |    +---------- ChunkState[0]
34531     //  |      |       |     +--------------- ChunkState[12..1]
34532     //  |      |       +--------------------- ChunkState[13]
34533     //  |      +----------------------------- PageLayout (0 == page fully free)
34534     //  +------------------------------------ Reserved for future use
34535     std::atomic<uint32_t> layout;
34536 
34537     // If we'll ever going to use this in the future it might come handy
34538     // reviving the kPageBeingPartitioned logic (look in git log, it was there
34539     // at some point in the past).
34540     uint32_t reserved;
34541   };
34542 
34543   // There is one Chunk header per chunk (hence PageLayout per page) at the
34544   // beginning of each chunk.
34545   struct ChunkHeader {
34546     enum Flags : uint8_t {
34547       // If set, the first TracePacket in the chunk is partial and continues
34548       // from |chunk_id| - 1 (within the same |writer_id|).
34549       kFirstPacketContinuesFromPrevChunk = 1 << 0,
34550 
34551       // If set, the last TracePacket in the chunk is partial and continues on
34552       // |chunk_id| + 1 (within the same |writer_id|).
34553       kLastPacketContinuesOnNextChunk = 1 << 1,
34554 
34555       // If set, the last (fragmented) TracePacket in the chunk has holes (even
34556       // if the chunk is marked as kChunkComplete) that need to be patched
34557       // out-of-band before the chunk can be read.
34558       kChunkNeedsPatching = 1 << 2,
34559     };
34560 
34561     struct Packets {
34562       // Number of valid TracePacket protobuf messages contained in the chunk.
34563       // Each TracePacket is prefixed by its own size. This field is
34564       // monotonically updated by the Producer with release store semantic when
34565       // the packet at position |count| is started. This last packet may not be
34566       // considered complete until |count| is incremented for the subsequent
34567       // packet or the chunk is completed.
34568       uint16_t count : 10;
34569       static constexpr size_t kMaxCount = (1 << 10) - 1;
34570 
34571       // See Flags above.
34572       uint16_t flags : 6;
34573     };
34574 
34575     // A monotonic counter of the chunk within the scoped of a |writer_id|.
34576     // The tuple (ProducerID, WriterID, ChunkID) allows to figure out if two
34577     // chunks are contiguous (and hence a trace packets spanning across them can
34578     // be glued) or we had some holes due to the ring buffer wrapping.
34579     // This is set only when transitioning from kChunkFree to kChunkBeingWritten
34580     // and remains unchanged throughout the remaining lifetime of the chunk.
34581     std::atomic<uint32_t> chunk_id;
34582 
34583     // ID of the writer, unique within the producer.
34584     // Like |chunk_id|, this is set only when transitioning from kChunkFree to
34585     // kChunkBeingWritten.
34586     std::atomic<uint16_t> writer_id;
34587 
34588     // There is no ProducerID here. The service figures that out from the IPC
34589     // channel, which is unspoofable.
34590 
34591     // Updated with release-store semantics.
34592     std::atomic<Packets> packets;
34593   };
34594 
34595   class Chunk {
34596    public:
34597     Chunk();  // Constructs an invalid chunk.
34598 
34599     // Chunk is move-only, to document the scope of the Acquire/Release
34600     // TryLock operations below.
34601     Chunk(const Chunk&) = delete;
34602     Chunk operator=(const Chunk&) = delete;
34603     Chunk(Chunk&&) noexcept;
34604     Chunk& operator=(Chunk&&);
34605 
begin() const34606     uint8_t* begin() const { return begin_; }
end() const34607     uint8_t* end() const { return begin_ + size_; }
34608 
34609     // Size, including Chunk header.
size() const34610     size_t size() const { return size_; }
34611 
34612     // Begin of the first packet (or packet fragment).
payload_begin() const34613     uint8_t* payload_begin() const { return begin_ + sizeof(ChunkHeader); }
payload_size() const34614     size_t payload_size() const {
34615       PERFETTO_DCHECK(size_ >= sizeof(ChunkHeader));
34616       return size_ - sizeof(ChunkHeader);
34617     }
34618 
is_valid() const34619     bool is_valid() const { return begin_ && size_; }
34620 
34621     // Index of the chunk within the page [0..13] (13 comes from kPageDiv14).
chunk_idx() const34622     uint8_t chunk_idx() const { return chunk_idx_; }
34623 
header()34624     ChunkHeader* header() { return reinterpret_cast<ChunkHeader*>(begin_); }
34625 
writer_id()34626     uint16_t writer_id() {
34627       return header()->writer_id.load(std::memory_order_relaxed);
34628     }
34629 
34630     // Returns the count of packets and the flags with acquire-load semantics.
GetPacketCountAndFlags()34631     std::pair<uint16_t, uint8_t> GetPacketCountAndFlags() {
34632       auto packets = header()->packets.load(std::memory_order_acquire);
34633       const uint16_t packets_count = packets.count;
34634       const uint8_t packets_flags = packets.flags;
34635       return std::make_pair(packets_count, packets_flags);
34636     }
34637 
34638     // Increases |packets.count| with release semantics (note, however, that the
34639     // packet count is incremented *before* starting writing a packet). Returns
34640     // the new packet count. The increment is atomic but NOT race-free (i.e. no
34641     // CAS). Only the Producer is supposed to perform this increment, and it's
34642     // supposed to do that in a thread-safe way (holding a lock). A Chunk cannot
34643     // be shared by multiple Producer threads without locking. The packet count
34644     // is cleared by TryAcquireChunk(), when passing the new header for the
34645     // chunk.
IncrementPacketCount()34646     uint16_t IncrementPacketCount() {
34647       ChunkHeader* chunk_header = header();
34648       auto packets = chunk_header->packets.load(std::memory_order_relaxed);
34649       packets.count++;
34650       chunk_header->packets.store(packets, std::memory_order_release);
34651       return packets.count;
34652     }
34653 
34654     // Increases |packets.count| to the given |packet_count|, but only if
34655     // |packet_count| is larger than the current value of |packets.count|.
34656     // Returns the new packet count. Same atomicity guarantees as
34657     // IncrementPacketCount().
IncreasePacketCountTo(uint16_t packet_count)34658     uint16_t IncreasePacketCountTo(uint16_t packet_count) {
34659       ChunkHeader* chunk_header = header();
34660       auto packets = chunk_header->packets.load(std::memory_order_relaxed);
34661       if (packets.count < packet_count)
34662         packets.count = packet_count;
34663       chunk_header->packets.store(packets, std::memory_order_release);
34664       return packets.count;
34665     }
34666 
34667     // Flags are cleared by TryAcquireChunk(), by passing the new header for
34668     // the chunk, or through ClearNeedsPatchingFlag.
SetFlag(ChunkHeader::Flags flag)34669     void SetFlag(ChunkHeader::Flags flag) {
34670       ChunkHeader* chunk_header = header();
34671       auto packets = chunk_header->packets.load(std::memory_order_relaxed);
34672       packets.flags |= flag;
34673       chunk_header->packets.store(packets, std::memory_order_release);
34674     }
34675 
34676     // This flag can only be cleared by the producer while it is still holding
34677     // on to the chunk - i.e. while the chunk is still in state
34678     // ChunkState::kChunkBeingWritten and hasn't been transitioned to
34679     // ChunkState::kChunkComplete. This is ok, because the service is oblivious
34680     // to the needs patching flag before the chunk is released as complete.
ClearNeedsPatchingFlag()34681     void ClearNeedsPatchingFlag() {
34682       ChunkHeader* chunk_header = header();
34683       auto packets = chunk_header->packets.load(std::memory_order_relaxed);
34684       packets.flags &= ~ChunkHeader::kChunkNeedsPatching;
34685       chunk_header->packets.store(packets, std::memory_order_release);
34686     }
34687 
34688    private:
34689     friend class SharedMemoryABI;
34690     Chunk(uint8_t* begin, uint16_t size, uint8_t chunk_idx);
34691 
34692     // Don't add extra fields, keep the move operator fast.
34693     uint8_t* begin_ = nullptr;
34694     uint16_t size_ = 0;
34695     uint8_t chunk_idx_ = 0;
34696   };
34697 
34698   // Construct an instance from an existing shared memory buffer.
34699   SharedMemoryABI(uint8_t* start, size_t size, size_t page_size);
34700   SharedMemoryABI();
34701 
34702   void Initialize(uint8_t* start, size_t size, size_t page_size);
34703 
start() const34704   uint8_t* start() const { return start_; }
end() const34705   uint8_t* end() const { return start_ + size_; }
size() const34706   size_t size() const { return size_; }
page_size() const34707   size_t page_size() const { return page_size_; }
num_pages() const34708   size_t num_pages() const { return num_pages_; }
is_valid()34709   bool is_valid() { return num_pages() > 0; }
34710 
page_start(size_t page_idx)34711   uint8_t* page_start(size_t page_idx) {
34712     PERFETTO_DCHECK(page_idx < num_pages_);
34713     return start_ + page_size_ * page_idx;
34714   }
34715 
page_header(size_t page_idx)34716   PageHeader* page_header(size_t page_idx) {
34717     return reinterpret_cast<PageHeader*>(page_start(page_idx));
34718   }
34719 
34720   // Returns true if the page is fully clear and has not been partitioned yet.
34721   // The state of the page can change at any point after this returns (or even
34722   // before). The Producer should use this only as a hint to decide out whether
34723   // it should TryPartitionPage() or acquire an individual chunk.
is_page_free(size_t page_idx)34724   bool is_page_free(size_t page_idx) {
34725     return page_header(page_idx)->layout.load(std::memory_order_relaxed) == 0;
34726   }
34727 
34728   // Returns true if all chunks in the page are kChunkComplete. As above, this
34729   // is advisory only. The Service is supposed to use this only to decide
34730   // whether to TryAcquireAllChunksForReading() or not.
is_page_complete(size_t page_idx)34731   bool is_page_complete(size_t page_idx) {
34732     auto layout = page_header(page_idx)->layout.load(std::memory_order_relaxed);
34733     const uint32_t num_chunks = GetNumChunksForLayout(layout);
34734     if (num_chunks == 0)
34735       return false;  // Non partitioned pages cannot be complete.
34736     return (layout & kAllChunksMask) ==
34737            (kAllChunksComplete & ((1 << (num_chunks * kChunkShift)) - 1));
34738   }
34739 
34740   // For testing / debugging only.
page_header_dbg(size_t page_idx)34741   std::string page_header_dbg(size_t page_idx) {
34742     uint32_t x = page_header(page_idx)->layout.load(std::memory_order_relaxed);
34743     return std::bitset<32>(x).to_string();
34744   }
34745 
34746   // Returns the page layout, which is a bitmap that specifies the chunking
34747   // layout of the page and each chunk's current state. Reads with an
34748   // acquire-load semantic to ensure a producer's writes corresponding to an
34749   // update of the layout (e.g. clearing a chunk's header) are observed
34750   // consistently.
GetPageLayout(size_t page_idx)34751   uint32_t GetPageLayout(size_t page_idx) {
34752     return page_header(page_idx)->layout.load(std::memory_order_acquire);
34753   }
34754 
34755   // Returns a bitmap in which each bit is set if the corresponding Chunk exists
34756   // in the page (according to the page layout) and is free. If the page is not
34757   // partitioned it returns 0 (as if the page had no free chunks).
34758   uint32_t GetFreeChunks(size_t page_idx);
34759 
34760   // Tries to atomically partition a page with the given |layout|. Returns true
34761   // if the page was free and has been partitioned with the given |layout|,
34762   // false if the page wasn't free anymore by the time we got there.
34763   // If succeeds all the chunks are atomically set in the kChunkFree state.
34764   bool TryPartitionPage(size_t page_idx, PageLayout layout);
34765 
34766   // Tries to atomically mark a single chunk within the page as
34767   // kChunkBeingWritten. Returns an invalid chunk if the page is not partitioned
34768   // or the chunk is not in the kChunkFree state. If succeeds sets the chunk
34769   // header to |header|.
TryAcquireChunkForWriting(size_t page_idx,size_t chunk_idx,const ChunkHeader * header)34770   Chunk TryAcquireChunkForWriting(size_t page_idx,
34771                                   size_t chunk_idx,
34772                                   const ChunkHeader* header) {
34773     return TryAcquireChunk(page_idx, chunk_idx, kChunkBeingWritten, header);
34774   }
34775 
34776   // Similar to TryAcquireChunkForWriting. Fails if the chunk isn't in the
34777   // kChunkComplete state.
TryAcquireChunkForReading(size_t page_idx,size_t chunk_idx)34778   Chunk TryAcquireChunkForReading(size_t page_idx, size_t chunk_idx) {
34779     return TryAcquireChunk(page_idx, chunk_idx, kChunkBeingRead, nullptr);
34780   }
34781 
34782   // The caller must have successfully TryAcquireAllChunksForReading() or it
34783   // needs to guarantee that the chunk is already in the kChunkBeingWritten
34784   // state.
34785   Chunk GetChunkUnchecked(size_t page_idx,
34786                           uint32_t page_layout,
34787                           size_t chunk_idx);
34788 
34789   // Puts a chunk into the kChunkComplete state. Returns the page index.
ReleaseChunkAsComplete(Chunk chunk)34790   size_t ReleaseChunkAsComplete(Chunk chunk) {
34791     return ReleaseChunk(std::move(chunk), kChunkComplete);
34792   }
34793 
34794   // Puts a chunk into the kChunkFree state. Returns the page index.
ReleaseChunkAsFree(Chunk chunk)34795   size_t ReleaseChunkAsFree(Chunk chunk) {
34796     return ReleaseChunk(std::move(chunk), kChunkFree);
34797   }
34798 
GetChunkState(size_t page_idx,size_t chunk_idx)34799   ChunkState GetChunkState(size_t page_idx, size_t chunk_idx) {
34800     PageHeader* phdr = page_header(page_idx);
34801     uint32_t layout = phdr->layout.load(std::memory_order_relaxed);
34802     return GetChunkStateFromLayout(layout, chunk_idx);
34803   }
34804 
34805   std::pair<size_t, size_t> GetPageAndChunkIndex(const Chunk& chunk);
34806 
GetChunkSizeForLayout(uint32_t page_layout) const34807   uint16_t GetChunkSizeForLayout(uint32_t page_layout) const {
34808     return chunk_sizes_[(page_layout & kLayoutMask) >> kLayoutShift];
34809   }
34810 
GetChunkStateFromLayout(uint32_t page_layout,size_t chunk_idx)34811   static ChunkState GetChunkStateFromLayout(uint32_t page_layout,
34812                                             size_t chunk_idx) {
34813     return static_cast<ChunkState>((page_layout >> (chunk_idx * kChunkShift)) &
34814                                    kChunkMask);
34815   }
34816 
GetNumChunksForLayout(uint32_t page_layout)34817   static constexpr uint32_t GetNumChunksForLayout(uint32_t page_layout) {
34818     return kNumChunksForLayout[(page_layout & kLayoutMask) >> kLayoutShift];
34819   }
34820 
34821   // Returns a bitmap in which each bit is set if the corresponding Chunk exists
34822   // in the page (according to the page layout) and is not free. If the page is
34823   // not partitioned it returns 0 (as if the page had no used chunks). Bit N
34824   // corresponds to Chunk N.
GetUsedChunks(uint32_t page_layout)34825   static uint32_t GetUsedChunks(uint32_t page_layout) {
34826     const uint32_t num_chunks = GetNumChunksForLayout(page_layout);
34827     uint32_t res = 0;
34828     for (uint32_t i = 0; i < num_chunks; i++) {
34829       res |= ((page_layout & kChunkMask) != kChunkFree) ? (1 << i) : 0;
34830       page_layout >>= kChunkShift;
34831     }
34832     return res;
34833   }
34834 
34835  private:
34836   SharedMemoryABI(const SharedMemoryABI&) = delete;
34837   SharedMemoryABI& operator=(const SharedMemoryABI&) = delete;
34838 
34839   Chunk TryAcquireChunk(size_t page_idx,
34840                         size_t chunk_idx,
34841                         ChunkState,
34842                         const ChunkHeader*);
34843   size_t ReleaseChunk(Chunk chunk, ChunkState);
34844 
34845   uint8_t* start_ = nullptr;
34846   size_t size_ = 0;
34847   size_t page_size_ = 0;
34848   size_t num_pages_ = 0;
34849   std::array<uint16_t, kNumPageLayouts> chunk_sizes_;
34850 };
34851 
34852 }  // namespace perfetto
34853 
34854 #endif  // INCLUDE_PERFETTO_EXT_TRACING_CORE_SHARED_MEMORY_ABI_H_
34855 /*
34856  * Copyright (C) 2017 The Android Open Source Project
34857  *
34858  * Licensed under the Apache License, Version 2.0 (the "License");
34859  * you may not use this file except in compliance with the
34860  * License. You may obtain a copy of the License at
34861  *
34862  *      http://www.apache.org/licenses/LICENSE-2.0
34863  *
34864  * Unless required by applicable law or agreed to in writing,
34865  * software distributed under the License is distributed on an "AS
34866  * IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
34867  * express or implied. See the License for the specific language
34868  * governing permissions and limitations under the License.
34869  */
34870 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/shared_memory_abi.h"
34871 
34872 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
34873 // gen_amalgamated expanded: #include "perfetto/base/time.h"
34874 
34875 #if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
34876 #include <sys/mman.h>
34877 #endif
34878 
34879 // gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
34880 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/basic_types.h"
34881 
34882 namespace perfetto {
34883 
34884 namespace {
34885 
34886 constexpr int kRetryAttempts = 64;
34887 
WaitBeforeNextAttempt(int attempt)34888 inline void WaitBeforeNextAttempt(int attempt) {
34889   if (attempt < kRetryAttempts / 2) {
34890     std::this_thread::yield();
34891   } else {
34892     base::SleepMicroseconds((unsigned(attempt) / 10) * 1000);
34893   }
34894 }
34895 
34896 // Returns the largest 4-bytes aligned chunk size <= |page_size| / |divider|
34897 // for each divider in PageLayout.
GetChunkSize(size_t page_size,size_t divider)34898 constexpr size_t GetChunkSize(size_t page_size, size_t divider) {
34899   return ((page_size - sizeof(SharedMemoryABI::PageHeader)) / divider) & ~3UL;
34900 }
34901 
34902 // Initializer for the const |chunk_sizes_| array.
InitChunkSizes(size_t page_size)34903 std::array<uint16_t, SharedMemoryABI::kNumPageLayouts> InitChunkSizes(
34904     size_t page_size) {
34905   static_assert(SharedMemoryABI::kNumPageLayouts ==
34906                     base::ArraySize(SharedMemoryABI::kNumChunksForLayout),
34907                 "kNumPageLayouts out of date");
34908   std::array<uint16_t, SharedMemoryABI::kNumPageLayouts> res = {};
34909   for (size_t i = 0; i < SharedMemoryABI::kNumPageLayouts; i++) {
34910     size_t num_chunks = SharedMemoryABI::kNumChunksForLayout[i];
34911     size_t size = num_chunks == 0 ? 0 : GetChunkSize(page_size, num_chunks);
34912     PERFETTO_CHECK(size <= std::numeric_limits<uint16_t>::max());
34913     res[i] = static_cast<uint16_t>(size);
34914   }
34915   return res;
34916 }
34917 
ClearChunkHeader(SharedMemoryABI::ChunkHeader * header)34918 inline void ClearChunkHeader(SharedMemoryABI::ChunkHeader* header) {
34919   header->writer_id.store(0u, std::memory_order_relaxed);
34920   header->chunk_id.store(0u, std::memory_order_relaxed);
34921   header->packets.store({}, std::memory_order_release);
34922 }
34923 
34924 }  // namespace
34925 
34926 // static
34927 constexpr uint32_t SharedMemoryABI::kNumChunksForLayout[];
34928 constexpr const char* SharedMemoryABI::kChunkStateStr[];
34929 constexpr const size_t SharedMemoryABI::kInvalidPageIdx;
34930 constexpr const size_t SharedMemoryABI::kMinPageSize;
34931 constexpr const size_t SharedMemoryABI::kMaxPageSize;
34932 constexpr const size_t SharedMemoryABI::kPacketSizeDropPacket;
34933 
34934 SharedMemoryABI::SharedMemoryABI() = default;
34935 
SharedMemoryABI(uint8_t * start,size_t size,size_t page_size)34936 SharedMemoryABI::SharedMemoryABI(uint8_t* start,
34937                                  size_t size,
34938                                  size_t page_size) {
34939   Initialize(start, size, page_size);
34940 }
34941 
Initialize(uint8_t * start,size_t size,size_t page_size)34942 void SharedMemoryABI::Initialize(uint8_t* start,
34943                                  size_t size,
34944                                  size_t page_size) {
34945   start_ = start;
34946   size_ = size;
34947   page_size_ = page_size;
34948   num_pages_ = size / page_size;
34949   chunk_sizes_ = InitChunkSizes(page_size);
34950   static_assert(sizeof(PageHeader) == 8, "PageHeader size");
34951   static_assert(sizeof(ChunkHeader) == 8, "ChunkHeader size");
34952   static_assert(sizeof(ChunkHeader::chunk_id) == sizeof(ChunkID),
34953                 "ChunkID size");
34954 
34955   static_assert(sizeof(ChunkHeader::Packets) == 2, "ChunkHeader::Packets size");
34956   static_assert(alignof(ChunkHeader) == kChunkAlignment,
34957                 "ChunkHeader alignment");
34958 
34959   // In theory std::atomic does not guarantee that the underlying type
34960   // consists only of the actual atomic word. Theoretically it could have
34961   // locks or other state. In practice most implementations just implement
34962   // them without extra state. The code below overlays the atomic into the
34963   // SMB, hence relies on this implementation detail. This should be fine
34964   // pragmatically (Chrome's base makes the same assumption), but let's have a
34965   // check for this.
34966   static_assert(sizeof(std::atomic<uint32_t>) == sizeof(uint32_t) &&
34967                     sizeof(std::atomic<uint16_t>) == sizeof(uint16_t),
34968                 "Incompatible STL <atomic> implementation");
34969 
34970   // Chec that the kAllChunks(Complete,Free) are consistent with the
34971   // ChunkState enum values.
34972 
34973   // These must be zero because rely on zero-initialized memory being
34974   // interpreted as "free".
34975   static_assert(kChunkFree == 0 && kAllChunksFree == 0,
34976                 "kChunkFree/kAllChunksFree and must be 0");
34977 
34978   static_assert((kAllChunksComplete & kChunkMask) == kChunkComplete,
34979                 "kAllChunksComplete out of sync with kChunkComplete");
34980 
34981   // Check the consistency of the kMax... constants.
34982   static_assert(sizeof(ChunkHeader::writer_id) == sizeof(WriterID),
34983                 "WriterID size");
34984   ChunkHeader chunk_header{};
34985   chunk_header.chunk_id.store(static_cast<uint32_t>(-1));
34986   PERFETTO_CHECK(chunk_header.chunk_id.load() == kMaxChunkID);
34987 
34988   chunk_header.writer_id.store(static_cast<uint16_t>(-1));
34989   PERFETTO_CHECK(kMaxWriterID <= chunk_header.writer_id.load());
34990 
34991   PERFETTO_CHECK(page_size >= kMinPageSize);
34992   PERFETTO_CHECK(page_size <= kMaxPageSize);
34993   PERFETTO_CHECK(page_size % kMinPageSize == 0);
34994   PERFETTO_CHECK(reinterpret_cast<uintptr_t>(start) % kMinPageSize == 0);
34995   PERFETTO_CHECK(size % page_size == 0);
34996 }
34997 
GetChunkUnchecked(size_t page_idx,uint32_t page_layout,size_t chunk_idx)34998 SharedMemoryABI::Chunk SharedMemoryABI::GetChunkUnchecked(size_t page_idx,
34999                                                           uint32_t page_layout,
35000                                                           size_t chunk_idx) {
35001   const size_t num_chunks = GetNumChunksForLayout(page_layout);
35002   PERFETTO_DCHECK(chunk_idx < num_chunks);
35003   // Compute the chunk virtual address and write it into |chunk|.
35004   const uint16_t chunk_size = GetChunkSizeForLayout(page_layout);
35005   size_t chunk_offset_in_page = sizeof(PageHeader) + chunk_idx * chunk_size;
35006 
35007   Chunk chunk(page_start(page_idx) + chunk_offset_in_page, chunk_size,
35008               static_cast<uint8_t>(chunk_idx));
35009   PERFETTO_DCHECK(chunk.end() <= end());
35010   return chunk;
35011 }
35012 
TryAcquireChunk(size_t page_idx,size_t chunk_idx,ChunkState desired_chunk_state,const ChunkHeader * header)35013 SharedMemoryABI::Chunk SharedMemoryABI::TryAcquireChunk(
35014     size_t page_idx,
35015     size_t chunk_idx,
35016     ChunkState desired_chunk_state,
35017     const ChunkHeader* header) {
35018   PERFETTO_DCHECK(desired_chunk_state == kChunkBeingRead ||
35019                   desired_chunk_state == kChunkBeingWritten);
35020   PageHeader* phdr = page_header(page_idx);
35021   for (int attempt = 0; attempt < kRetryAttempts; attempt++) {
35022     uint32_t layout = phdr->layout.load(std::memory_order_acquire);
35023     const size_t num_chunks = GetNumChunksForLayout(layout);
35024 
35025     // The page layout has changed (or the page is free).
35026     if (chunk_idx >= num_chunks)
35027       return Chunk();
35028 
35029     // Verify that the chunk is still in a state that allows the transition to
35030     // |desired_chunk_state|. The only allowed transitions are:
35031     // 1. kChunkFree -> kChunkBeingWritten (Producer).
35032     // 2. kChunkComplete -> kChunkBeingRead (Service).
35033     ChunkState expected_chunk_state =
35034         desired_chunk_state == kChunkBeingWritten ? kChunkFree : kChunkComplete;
35035     auto cur_chunk_state = (layout >> (chunk_idx * kChunkShift)) & kChunkMask;
35036     if (cur_chunk_state != expected_chunk_state)
35037       return Chunk();
35038 
35039     uint32_t next_layout = layout;
35040     next_layout &= ~(kChunkMask << (chunk_idx * kChunkShift));
35041     next_layout |= (desired_chunk_state << (chunk_idx * kChunkShift));
35042     if (phdr->layout.compare_exchange_strong(layout, next_layout,
35043                                              std::memory_order_acq_rel)) {
35044       // Compute the chunk virtual address and write it into |chunk|.
35045       Chunk chunk = GetChunkUnchecked(page_idx, layout, chunk_idx);
35046       if (desired_chunk_state == kChunkBeingWritten) {
35047         PERFETTO_DCHECK(header);
35048         ChunkHeader* new_header = chunk.header();
35049         new_header->writer_id.store(header->writer_id,
35050                                     std::memory_order_relaxed);
35051         new_header->chunk_id.store(header->chunk_id, std::memory_order_relaxed);
35052         new_header->packets.store(header->packets, std::memory_order_release);
35053       }
35054       return chunk;
35055     }
35056     WaitBeforeNextAttempt(attempt);
35057   }
35058   return Chunk();  // All our attempts failed.
35059 }
35060 
TryPartitionPage(size_t page_idx,PageLayout layout)35061 bool SharedMemoryABI::TryPartitionPage(size_t page_idx, PageLayout layout) {
35062   PERFETTO_DCHECK(layout >= kPageDiv1 && layout <= kPageDiv14);
35063   uint32_t expected_layout = 0;  // Free page.
35064   uint32_t next_layout = (layout << kLayoutShift) & kLayoutMask;
35065   PageHeader* phdr = page_header(page_idx);
35066   if (!phdr->layout.compare_exchange_strong(expected_layout, next_layout,
35067                                             std::memory_order_acq_rel)) {
35068     return false;
35069   }
35070   return true;
35071 }
35072 
GetFreeChunks(size_t page_idx)35073 uint32_t SharedMemoryABI::GetFreeChunks(size_t page_idx) {
35074   uint32_t layout =
35075       page_header(page_idx)->layout.load(std::memory_order_relaxed);
35076   const uint32_t num_chunks = GetNumChunksForLayout(layout);
35077   uint32_t res = 0;
35078   for (uint32_t i = 0; i < num_chunks; i++) {
35079     res |= ((layout & kChunkMask) == kChunkFree) ? (1 << i) : 0;
35080     layout >>= kChunkShift;
35081   }
35082   return res;
35083 }
35084 
ReleaseChunk(Chunk chunk,ChunkState desired_chunk_state)35085 size_t SharedMemoryABI::ReleaseChunk(Chunk chunk,
35086                                      ChunkState desired_chunk_state) {
35087   PERFETTO_DCHECK(desired_chunk_state == kChunkComplete ||
35088                   desired_chunk_state == kChunkFree);
35089 
35090   size_t page_idx;
35091   size_t chunk_idx;
35092   std::tie(page_idx, chunk_idx) = GetPageAndChunkIndex(chunk);
35093 
35094   // Reset header fields, so that the service can identify when the chunk's
35095   // header has been initialized by the producer.
35096   if (desired_chunk_state == kChunkFree)
35097     ClearChunkHeader(chunk.header());
35098 
35099   for (int attempt = 0; attempt < kRetryAttempts; attempt++) {
35100     PageHeader* phdr = page_header(page_idx);
35101     uint32_t layout = phdr->layout.load(std::memory_order_relaxed);
35102     const size_t page_chunk_size = GetChunkSizeForLayout(layout);
35103 
35104     // TODO(primiano): this should not be a CHECK, because a malicious producer
35105     // could crash us by putting the chunk in an invalid state. This should
35106     // gracefully fail. Keep a CHECK until then.
35107     PERFETTO_CHECK(chunk.size() == page_chunk_size);
35108     const uint32_t chunk_state =
35109         ((layout >> (chunk_idx * kChunkShift)) & kChunkMask);
35110 
35111     // Verify that the chunk is still in a state that allows the transition to
35112     // |desired_chunk_state|. The only allowed transitions are:
35113     // 1. kChunkBeingWritten -> kChunkComplete (Producer).
35114     // 2. kChunkBeingRead -> kChunkFree (Service).
35115     ChunkState expected_chunk_state;
35116     if (desired_chunk_state == kChunkComplete) {
35117       expected_chunk_state = kChunkBeingWritten;
35118     } else {
35119       expected_chunk_state = kChunkBeingRead;
35120     }
35121 
35122     // TODO(primiano): should not be a CHECK (same rationale of comment above).
35123     PERFETTO_CHECK(chunk_state == expected_chunk_state);
35124     uint32_t next_layout = layout;
35125     next_layout &= ~(kChunkMask << (chunk_idx * kChunkShift));
35126     next_layout |= (desired_chunk_state << (chunk_idx * kChunkShift));
35127 
35128     // If we are freeing a chunk and all the other chunks in the page are free
35129     // we should de-partition the page and mark it as clear.
35130     if ((next_layout & kAllChunksMask) == kAllChunksFree)
35131       next_layout = 0;
35132 
35133     if (phdr->layout.compare_exchange_strong(layout, next_layout,
35134                                              std::memory_order_acq_rel)) {
35135       return page_idx;
35136     }
35137     WaitBeforeNextAttempt(attempt);
35138   }
35139   // Too much contention on this page. Give up. This page will be left pending
35140   // forever but there isn't much more we can do at this point.
35141   PERFETTO_DFATAL("Too much contention on page.");
35142   return kInvalidPageIdx;
35143 }
35144 
35145 SharedMemoryABI::Chunk::Chunk() = default;
35146 
Chunk(uint8_t * begin,uint16_t size,uint8_t chunk_idx)35147 SharedMemoryABI::Chunk::Chunk(uint8_t* begin, uint16_t size, uint8_t chunk_idx)
35148     : begin_(begin), size_(size), chunk_idx_(chunk_idx) {
35149   PERFETTO_CHECK(reinterpret_cast<uintptr_t>(begin) % kChunkAlignment == 0);
35150   PERFETTO_CHECK(size > 0);
35151 }
35152 
Chunk(Chunk && o)35153 SharedMemoryABI::Chunk::Chunk(Chunk&& o) noexcept {
35154   *this = std::move(o);
35155 }
35156 
operator =(Chunk && o)35157 SharedMemoryABI::Chunk& SharedMemoryABI::Chunk::operator=(Chunk&& o) {
35158   begin_ = o.begin_;
35159   size_ = o.size_;
35160   chunk_idx_ = o.chunk_idx_;
35161   o.begin_ = nullptr;
35162   o.size_ = 0;
35163   o.chunk_idx_ = 0;
35164   return *this;
35165 }
35166 
GetPageAndChunkIndex(const Chunk & chunk)35167 std::pair<size_t, size_t> SharedMemoryABI::GetPageAndChunkIndex(
35168     const Chunk& chunk) {
35169   PERFETTO_DCHECK(chunk.is_valid());
35170   PERFETTO_DCHECK(chunk.begin() >= start_);
35171   PERFETTO_DCHECK(chunk.end() <= start_ + size_);
35172 
35173   // TODO(primiano): The divisions below could be avoided if we cached
35174   // |page_shift_|.
35175   const uintptr_t rel_addr = static_cast<uintptr_t>(chunk.begin() - start_);
35176   const size_t page_idx = rel_addr / page_size_;
35177   const size_t offset = rel_addr % page_size_;
35178   PERFETTO_DCHECK(offset >= sizeof(PageHeader));
35179   PERFETTO_DCHECK(offset % kChunkAlignment == 0);
35180   PERFETTO_DCHECK((offset - sizeof(PageHeader)) % chunk.size() == 0);
35181   const size_t chunk_idx = (offset - sizeof(PageHeader)) / chunk.size();
35182   PERFETTO_DCHECK(chunk_idx < kMaxChunksPerPage);
35183   PERFETTO_DCHECK(chunk_idx < GetNumChunksForLayout(GetPageLayout(page_idx)));
35184   return std::make_pair(page_idx, chunk_idx);
35185 }
35186 
35187 }  // namespace perfetto
35188 // gen_amalgamated begin source: src/tracing/core/shared_memory_arbiter_impl.cc
35189 // gen_amalgamated begin header: src/tracing/core/shared_memory_arbiter_impl.h
35190 // gen_amalgamated begin header: include/perfetto/ext/tracing/core/shared_memory_arbiter.h
35191 // gen_amalgamated begin header: include/perfetto/ext/tracing/core/tracing_service.h
35192 // gen_amalgamated begin header: include/perfetto/ext/tracing/core/shared_memory.h
35193 /*
35194  * Copyright (C) 2017 The Android Open Source Project
35195  *
35196  * Licensed under the Apache License, Version 2.0 (the "License");
35197  * you may not use this file except in compliance with the License.
35198  * You may obtain a copy of the License at
35199  *
35200  *      http://www.apache.org/licenses/LICENSE-2.0
35201  *
35202  * Unless required by applicable law or agreed to in writing, software
35203  * distributed under the License is distributed on an "AS IS" BASIS,
35204  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
35205  * See the License for the specific language governing permissions and
35206  * limitations under the License.
35207  */
35208 
35209 #ifndef INCLUDE_PERFETTO_EXT_TRACING_CORE_SHARED_MEMORY_H_
35210 #define INCLUDE_PERFETTO_EXT_TRACING_CORE_SHARED_MEMORY_H_
35211 
35212 #include <stddef.h>
35213 
35214 #include <memory>
35215 
35216 // gen_amalgamated expanded: #include "perfetto/base/export.h"
35217 // gen_amalgamated expanded: #include "perfetto/base/platform_handle.h"
35218 
35219 namespace perfetto {
35220 
35221 // An abstract interface that models the shared memory region shared between
35222 // Service and Producer. The concrete implementation of this is up to the
35223 // transport layer. This can be as simple as a malloc()-ed buffer, if both
35224 // Producer and Service are hosted in the same process, or some posix shared
35225 // memory for the out-of-process case (see src/unix_rpc).
35226 // Both this class and the Factory are subclassed by the transport layer, which
35227 // will attach platform specific fields to it (e.g., a unix file descriptor).
35228 class PERFETTO_EXPORT SharedMemory {
35229  public:
35230   class PERFETTO_EXPORT Factory {
35231    public:
35232     virtual ~Factory();
35233     virtual std::unique_ptr<SharedMemory> CreateSharedMemory(size_t) = 0;
35234   };
35235 
35236   // The transport layer is expected to tear down the resource associated to
35237   // this object region when destroyed.
35238   virtual ~SharedMemory();
35239 
35240   virtual void* start() const = 0;
35241   virtual size_t size() const = 0;
35242 };
35243 
35244 }  // namespace perfetto
35245 
35246 #endif  // INCLUDE_PERFETTO_EXT_TRACING_CORE_SHARED_MEMORY_H_
35247 /*
35248  * Copyright (C) 2017 The Android Open Source Project
35249  *
35250  * Licensed under the Apache License, Version 2.0 (the "License");
35251  * you may not use this file except in compliance with the License.
35252  * You may obtain a copy of the License at
35253  *
35254  *      http://www.apache.org/licenses/LICENSE-2.0
35255  *
35256  * Unless required by applicable law or agreed to in writing, software
35257  * distributed under the License is distributed on an "AS IS" BASIS,
35258  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
35259  * See the License for the specific language governing permissions and
35260  * limitations under the License.
35261  */
35262 
35263 #ifndef INCLUDE_PERFETTO_EXT_TRACING_CORE_TRACING_SERVICE_H_
35264 #define INCLUDE_PERFETTO_EXT_TRACING_CORE_TRACING_SERVICE_H_
35265 
35266 #include <stdint.h>
35267 
35268 #include <functional>
35269 #include <memory>
35270 #include <vector>
35271 
35272 // gen_amalgamated expanded: #include "perfetto/base/export.h"
35273 // gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"
35274 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/basic_types.h"
35275 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/shared_memory.h"
35276 // gen_amalgamated expanded: #include "perfetto/tracing/buffer_exhausted_policy.h"
35277 // gen_amalgamated expanded: #include "perfetto/tracing/core/forward_decls.h"
35278 
35279 namespace perfetto {
35280 
35281 namespace base {
35282 class TaskRunner;
35283 }  // namespace base
35284 
35285 class Consumer;
35286 class Producer;
35287 class SharedMemoryArbiter;
35288 class TraceWriter;
35289 
35290 // Exposed for testing.
35291 std::string GetBugreportPath();
35292 
35293 // TODO: for the moment this assumes that all the calls happen on the same
35294 // thread/sequence. Not sure this will be the case long term in Chrome.
35295 
35296 // The API for the Producer port of the Service.
35297 // Subclassed by:
35298 // 1. The tracing_service_impl.cc business logic when returning it in response
35299 //    to the ConnectProducer() method.
35300 // 2. The transport layer (e.g., src/ipc) when the producer and
35301 //    the service don't talk locally but via some IPC mechanism.
35302 class PERFETTO_EXPORT ProducerEndpoint {
35303  public:
35304   virtual ~ProducerEndpoint();
35305 
35306   // Called by the Producer to (un)register data sources. Data sources are
35307   // identified by their name (i.e. DataSourceDescriptor.name)
35308   virtual void RegisterDataSource(const DataSourceDescriptor&) = 0;
35309   virtual void UpdateDataSource(const DataSourceDescriptor&) = 0;
35310   virtual void UnregisterDataSource(const std::string& name) = 0;
35311 
35312   // Associate the trace writer with the given |writer_id| with
35313   // |target_buffer|. The service may use this information to retrieve and
35314   // copy uncommitted chunks written by the trace writer into its associated
35315   // buffer, e.g. when a producer process crashes or when a flush is
35316   // necessary.
35317   virtual void RegisterTraceWriter(uint32_t writer_id,
35318                                    uint32_t target_buffer) = 0;
35319 
35320   // Remove the association of the trace writer previously created via
35321   // RegisterTraceWriter.
35322   virtual void UnregisterTraceWriter(uint32_t writer_id) = 0;
35323 
35324   // Called by the Producer to signal that some pages in the shared memory
35325   // buffer (shared between Service and Producer) have changed.
35326   // When the Producer and the Service are hosted in the same process and
35327   // hence potentially live on the same task runner, This method must call
35328   // TracingServiceImpl's CommitData synchronously, without any PostTask()s,
35329   // if on the same thread. This is to avoid a deadlock where the Producer
35330   // exhausts its SMB and stalls waiting for the service to catch up with
35331   // reads, but the Service never gets to that because it lives on the same
35332   // thread.
35333   using CommitDataCallback = std::function<void()>;
35334   virtual void CommitData(const CommitDataRequest&,
35335                           CommitDataCallback callback = {}) = 0;
35336 
35337   virtual SharedMemory* shared_memory() const = 0;
35338 
35339   // Size of shared memory buffer pages. It's always a multiple of 4K.
35340   // See shared_memory_abi.h
35341   virtual size_t shared_buffer_page_size_kb() const = 0;
35342 
35343   // Creates a trace writer, which allows to create events, handling the
35344   // underying shared memory buffer and signalling to the Service. This method
35345   // is thread-safe but the returned object is not. A TraceWriter should be
35346   // used only from a single thread, or the caller has to handle sequencing
35347   // via a mutex or equivalent. This method can only be called if
35348   // TracingService::ConnectProducer was called with |in_process=true|.
35349   // Args:
35350   // |target_buffer| is the target buffer ID where the data produced by the
35351   // writer should be stored by the tracing service. This value is passed
35352   // upon creation of the data source (StartDataSource()) in the
35353   // DataSourceConfig.target_buffer().
35354   virtual std::unique_ptr<TraceWriter> CreateTraceWriter(
35355       BufferID target_buffer,
35356       BufferExhaustedPolicy buffer_exhausted_policy =
35357           BufferExhaustedPolicy::kDefault) = 0;
35358 
35359   // TODO(eseckler): Also expose CreateStartupTraceWriter() ?
35360 
35361   // In some cases you can access the producer's SharedMemoryArbiter (for
35362   // example if TracingService::ConnectProducer is called with
35363   // |in_process=true|). The SharedMemoryArbiter can be used to create
35364   // TraceWriters which is able to directly commit chunks. For the
35365   // |in_process=true| case this can be done without going through an IPC layer.
35366   virtual SharedMemoryArbiter* MaybeSharedMemoryArbiter() = 0;
35367 
35368   // Whether the service accepted a shared memory buffer provided by the
35369   // producer.
35370   virtual bool IsShmemProvidedByProducer() const = 0;
35371 
35372   // Called in response to a Producer::Flush(request_id) call after all data
35373   // for the flush request has been committed.
35374   virtual void NotifyFlushComplete(FlushRequestID) = 0;
35375 
35376   // Called in response to one or more Producer::StartDataSource(),
35377   // if the data source registered setting the flag
35378   // DataSourceDescriptor.will_notify_on_start.
35379   virtual void NotifyDataSourceStarted(DataSourceInstanceID) = 0;
35380 
35381   // Called in response to one or more Producer::StopDataSource(),
35382   // if the data source registered setting the flag
35383   // DataSourceDescriptor.will_notify_on_stop.
35384   virtual void NotifyDataSourceStopped(DataSourceInstanceID) = 0;
35385 
35386   // This informs the service to activate any of these triggers if any tracing
35387   // session was waiting for them.
35388   virtual void ActivateTriggers(const std::vector<std::string>&) = 0;
35389 
35390   // Emits a synchronization barrier to linearize with the service. When
35391   // |callback| is invoked, the caller has the guarantee that the service has
35392   // seen and processed all the requests sent by this producer prior to the
35393   // Sync() call. Used mainly in tests.
35394   virtual void Sync(std::function<void()> callback) = 0;
35395 };  // class ProducerEndpoint.
35396 
35397 // The API for the Consumer port of the Service.
35398 // Subclassed by:
35399 // 1. The tracing_service_impl.cc business logic when returning it in response
35400 // to
35401 //    the ConnectConsumer() method.
35402 // 2. The transport layer (e.g., src/ipc) when the consumer and
35403 //    the service don't talk locally but via some IPC mechanism.
35404 class PERFETTO_EXPORT ConsumerEndpoint {
35405  public:
35406   virtual ~ConsumerEndpoint();
35407 
35408   // Enables tracing with the given TraceConfig. The ScopedFile argument is
35409   // used only when TraceConfig.write_into_file == true.
35410   // If TraceConfig.deferred_start == true data sources are configured via
35411   // SetupDataSource() but are not started until StartTracing() is called.
35412   // This is to support pre-initialization and fast triggering of traces.
35413   // The ScopedFile argument is used only when TraceConfig.write_into_file
35414   // == true.
35415   virtual void EnableTracing(const TraceConfig&,
35416                              base::ScopedFile = base::ScopedFile()) = 0;
35417 
35418   // Update the trace config of an existing tracing session; only a subset
35419   // of options can be changed mid-session. Currently the only
35420   // supported functionality is expanding the list of producer_name_filters()
35421   // (or removing the filter entirely) for existing data sources.
35422   virtual void ChangeTraceConfig(const TraceConfig&) = 0;
35423 
35424   // Starts all data sources configured in the trace config. This is used only
35425   // after calling EnableTracing() with TraceConfig.deferred_start=true.
35426   // It's a no-op if called after a regular EnableTracing(), without setting
35427   // deferred_start.
35428   virtual void StartTracing() = 0;
35429 
35430   virtual void DisableTracing() = 0;
35431 
35432   // Requests all data sources to flush their data immediately and invokes the
35433   // passed callback once all of them have acked the flush (in which case
35434   // the callback argument |success| will be true) or |timeout_ms| are elapsed
35435   // (in which case |success| will be false).
35436   // If |timeout_ms| is 0 the TraceConfig's flush_timeout_ms is used, or,
35437   // if that one is not set (or is set to 0), kDefaultFlushTimeoutMs (5s) is
35438   // used.
35439   using FlushCallback = std::function<void(bool /*success*/)>;
35440   virtual void Flush(uint32_t timeout_ms, FlushCallback) = 0;
35441 
35442   // Tracing data will be delivered invoking Consumer::OnTraceData().
35443   virtual void ReadBuffers() = 0;
35444 
35445   virtual void FreeBuffers() = 0;
35446 
35447   // Will call OnDetach().
35448   virtual void Detach(const std::string& key) = 0;
35449 
35450   // Will call OnAttach().
35451   virtual void Attach(const std::string& key) = 0;
35452 
35453   // Will call OnTraceStats().
35454   virtual void GetTraceStats() = 0;
35455 
35456   // Start or stop observing events of selected types. |events_mask| specifies
35457   // the types of events to observe in a bitmask of ObservableEvents::Type.
35458   // To disable observing, pass 0.
35459   // Will call OnObservableEvents() repeatedly whenever an event of an enabled
35460   // ObservableEventType occurs.
35461   // TODO(eseckler): Extend this to support producers & data sources.
35462   virtual void ObserveEvents(uint32_t events_mask) = 0;
35463 
35464   // Used to obtain the list of connected data sources and other info about
35465   // the tracing service.
35466   using QueryServiceStateCallback =
35467       std::function<void(bool success, const TracingServiceState&)>;
35468   virtual void QueryServiceState(QueryServiceStateCallback) = 0;
35469 
35470   // Used for feature detection. Makes sense only when the consumer and the
35471   // service talk over IPC and can be from different versions.
35472   using QueryCapabilitiesCallback =
35473       std::function<void(const TracingServiceCapabilities&)>;
35474   virtual void QueryCapabilities(QueryCapabilitiesCallback) = 0;
35475 
35476   // If any tracing session with TraceConfig.bugreport_score > 0 is running,
35477   // this will pick the highest-score one, stop it and save it into a fixed
35478   // path (See kBugreportTracePath).
35479   // The callback is invoked when the file has been saved, in case of success,
35480   // or whenever an error occurs.
35481   // Args:
35482   // - success: if true, an eligible trace was found and saved into file.
35483   //            If false, either there was no eligible trace running or
35484   //            something else failed (See |msg|).
35485   // - msg: human readable diagnostic messages to debug failures.
35486   using SaveTraceForBugreportCallback =
35487       std::function<void(bool /*success*/, const std::string& /*msg*/)>;
35488   virtual void SaveTraceForBugreport(SaveTraceForBugreportCallback) = 0;
35489 };  // class ConsumerEndpoint.
35490 
35491 // The public API of the tracing Service business logic.
35492 //
35493 // Exposed to:
35494 // 1. The transport layer (e.g., src/unix_rpc/unix_service_host.cc),
35495 //    which forwards commands received from a remote producer or consumer to
35496 //    the actual service implementation.
35497 // 2. Tests.
35498 //
35499 // Subclassed by:
35500 //   The service business logic in src/core/tracing_service_impl.cc.
35501 class PERFETTO_EXPORT TracingService {
35502  public:
35503   using ProducerEndpoint = perfetto::ProducerEndpoint;
35504   using ConsumerEndpoint = perfetto::ConsumerEndpoint;
35505 
35506   enum class ProducerSMBScrapingMode {
35507     // Use service's default setting for SMB scraping. Currently, the default
35508     // mode is to disable SMB scraping, but this may change in the future.
35509     kDefault,
35510 
35511     // Enable scraping of uncommitted chunks in producers' shared memory
35512     // buffers.
35513     kEnabled,
35514 
35515     // Disable scraping of uncommitted chunks in producers' shared memory
35516     // buffers.
35517     kDisabled
35518   };
35519 
35520   // Implemented in src/core/tracing_service_impl.cc .
35521   static std::unique_ptr<TracingService> CreateInstance(
35522       std::unique_ptr<SharedMemory::Factory>,
35523       base::TaskRunner*);
35524 
35525   virtual ~TracingService();
35526 
35527   // Connects a Producer instance and obtains a ProducerEndpoint, which is
35528   // essentially a 1:1 channel between one Producer and the Service.
35529   //
35530   // The caller has to guarantee that the passed Producer will be alive as long
35531   // as the returned ProducerEndpoint is alive. Both the passed Producer and the
35532   // returned ProducerEndpoint must live on the same task runner of the service,
35533   // specifically:
35534   // 1) The Service will call Producer::* methods on the Service's task runner.
35535   // 2) The Producer should call ProducerEndpoint::* methods only on the
35536   //    service's task runner, except for ProducerEndpoint::CreateTraceWriter(),
35537   //    which can be called on any thread. To disconnect just destroy the
35538   //    returned ProducerEndpoint object. It is safe to destroy the Producer
35539   //    once the Producer::OnDisconnect() has been invoked.
35540   //
35541   // |uid| is the trusted user id of the producer process, used by the consumers
35542   // for validating the origin of trace data. |shared_memory_size_hint_bytes|
35543   // and |shared_memory_page_size_hint_bytes| are optional hints on the size of
35544   // the shared memory buffer and its pages. The service can ignore the hints
35545   // (e.g., if the hints are unreasonably large or other sizes were configured
35546   // in a tracing session's config). |in_process| enables the ProducerEndpoint
35547   // to manage its own shared memory and enables use of
35548   // |ProducerEndpoint::CreateTraceWriter|.
35549   //
35550   // The producer can optionally provide a non-null |shm|, which the service
35551   // will adopt for the connection to the producer, provided it is correctly
35552   // sized. In this case, |shared_memory_page_size_hint_bytes| indicates the
35553   // page size used in this SMB. The producer can use this mechanism to record
35554   // tracing data to an SMB even before the tracing session is started by the
35555   // service. This is used in Chrome to implement startup tracing. If the buffer
35556   // is incorrectly sized, the service will discard the SMB and allocate a new
35557   // one, provided to the producer via ProducerEndpoint::shared_memory() after
35558   // OnTracingSetup(). To verify that the service accepted the SMB, the producer
35559   // may check via ProducerEndpoint::IsShmemProvidedByProducer(). If the service
35560   // accepted the SMB, the producer can then commit any data that is already in
35561   // the SMB after the tracing session was started by the service via
35562   // Producer::StartDataSource(). The |shm| will also be rejected when
35563   // connecting to a service that is too old (pre Android-11).
35564   //
35565   // Can return null in the unlikely event that service has too many producers
35566   // connected.
35567   virtual std::unique_ptr<ProducerEndpoint> ConnectProducer(
35568       Producer*,
35569       uid_t uid,
35570       const std::string& name,
35571       size_t shared_memory_size_hint_bytes = 0,
35572       bool in_process = false,
35573       ProducerSMBScrapingMode smb_scraping_mode =
35574           ProducerSMBScrapingMode::kDefault,
35575       size_t shared_memory_page_size_hint_bytes = 0,
35576       std::unique_ptr<SharedMemory> shm = nullptr,
35577       const std::string& sdk_version = {}) = 0;
35578 
35579   // Connects a Consumer instance and obtains a ConsumerEndpoint, which is
35580   // essentially a 1:1 channel between one Consumer and the Service.
35581   // The caller has to guarantee that the passed Consumer will be alive as long
35582   // as the returned ConsumerEndpoint is alive.
35583   // To disconnect just destroy the returned ConsumerEndpoint object. It is safe
35584   // to destroy the Consumer once the Consumer::OnDisconnect() has been invoked.
35585   virtual std::unique_ptr<ConsumerEndpoint> ConnectConsumer(Consumer*,
35586                                                             uid_t) = 0;
35587 
35588   // Enable/disable scraping of chunks in the shared memory buffer. If enabled,
35589   // the service will copy uncommitted but non-empty chunks from the SMB when
35590   // flushing (e.g. to handle unresponsive producers or producers unable to
35591   // flush their active chunks), on producer disconnect (e.g. to recover data
35592   // from crashed producers), and after disabling a tracing session (e.g. to
35593   // gather data from producers that didn't stop their data sources in time).
35594   //
35595   // This feature is currently used by Chrome.
35596   virtual void SetSMBScrapingEnabled(bool enabled) = 0;
35597 };
35598 
35599 }  // namespace perfetto
35600 
35601 #endif  // INCLUDE_PERFETTO_EXT_TRACING_CORE_TRACING_SERVICE_H_
35602 /*
35603  * Copyright (C) 2018 The Android Open Source Project
35604  *
35605  * Licensed under the Apache License, Version 2.0 (the "License");
35606  * you may not use this file except in compliance with the License.
35607  * You may obtain a copy of the License at
35608  *
35609  *      http://www.apache.org/licenses/LICENSE-2.0
35610  *
35611  * Unless required by applicable law or agreed to in writing, software
35612  * distributed under the License is distributed on an "AS IS" BASIS,
35613  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
35614  * See the License for the specific language governing permissions and
35615  * limitations under the License.
35616  */
35617 
35618 #ifndef INCLUDE_PERFETTO_EXT_TRACING_CORE_SHARED_MEMORY_ARBITER_H_
35619 #define INCLUDE_PERFETTO_EXT_TRACING_CORE_SHARED_MEMORY_ARBITER_H_
35620 
35621 #include <stddef.h>
35622 
35623 #include <functional>
35624 #include <memory>
35625 #include <vector>
35626 
35627 // gen_amalgamated expanded: #include "perfetto/base/export.h"
35628 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/basic_types.h"
35629 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/tracing_service.h"
35630 // gen_amalgamated expanded: #include "perfetto/tracing/buffer_exhausted_policy.h"
35631 
35632 namespace perfetto {
35633 
35634 namespace base {
35635 class TaskRunner;
35636 }
35637 
35638 class SharedMemory;
35639 class TraceWriter;
35640 
35641 // Used by the Producer-side of the transport layer to vend TraceWriters
35642 // from the SharedMemory it receives from the Service-side.
35643 class PERFETTO_EXPORT SharedMemoryArbiter {
35644  public:
35645   virtual ~SharedMemoryArbiter();
35646 
35647   // Creates a new TraceWriter and assigns it a new WriterID. The WriterID is
35648   // written in each chunk header owned by a given TraceWriter and is used by
35649   // the Service to reconstruct TracePackets written by the same TraceWriter.
35650   // Returns null impl of TraceWriter if all WriterID slots are exhausted. The
35651   // writer will commit to the provided |target_buffer|. If the arbiter was
35652   // created via CreateUnbound(), only BufferExhaustedPolicy::kDrop is
35653   // supported.
35654   virtual std::unique_ptr<TraceWriter> CreateTraceWriter(
35655       BufferID target_buffer,
35656       BufferExhaustedPolicy buffer_exhausted_policy =
35657           BufferExhaustedPolicy::kDefault) = 0;
35658 
35659   // Creates a TraceWriter that will commit to the target buffer with the given
35660   // reservation ID (creating a new reservation for this ID if none exists yet).
35661   // The buffer reservation should be bound to an actual BufferID via
35662   // BindStartupTargetBuffer() once the actual BufferID is known. Only supported
35663   // if the arbiter was created using CreateUnbound(), and may be called while
35664   // the arbiter is unbound.
35665   //
35666   // While any unbound buffer reservation exists, all commits will be buffered
35667   // until all reservations were bound. Thus, until all reservations are bound,
35668   // the data written to the SMB will not be consumed by the service - the SMB
35669   // size should be chosen with this in mind. Startup writers always use
35670   // BufferExhaustedPolicy::kDrop, as we cannot feasibly stall while not
35671   // flushing to the service.
35672   //
35673   // The |target_buffer_reservation_id| should be greater than 0 but can
35674   // otherwise be freely chosen by the producer and is only used to translate
35675   // packets into the actual buffer id once
35676   // BindStartupTargetBuffer(reservation_id) is called. For example, Chrome uses
35677   // startup tracing not only for the first, but also subsequent tracing
35678   // sessions (to enable tracing in the browser process before it instructs the
35679   // tracing service to start tracing asynchronously, minimizing trace data loss
35680   // in the meantime), and increments the reservation ID between sessions.
35681   // Similarly, if more than a single target buffer per session is required
35682   // (e.g. for two different data sources), different reservation IDs should be
35683   // chosen for different targets buffers.
35684   virtual std::unique_ptr<TraceWriter> CreateStartupTraceWriter(
35685       uint16_t target_buffer_reservation_id) = 0;
35686 
35687   // Should only be called on unbound SharedMemoryArbiters. Binds the arbiter to
35688   // the provided ProducerEndpoint and TaskRunner. Should be called only once
35689   // and on the provided |TaskRunner|. Usually called by the producer (i.e., no
35690   // specific data source) once it connects to the service. Both the endpoint
35691   // and task runner should remain valid for the remainder of the arbiter's
35692   // lifetime.
35693   virtual void BindToProducerEndpoint(TracingService::ProducerEndpoint*,
35694                                       base::TaskRunner*) = 0;
35695 
35696   // Binds commits from TraceWriters created via CreateStartupTraceWriter() with
35697   // the given |target_buffer_reservation_id| to |target_buffer_id|. May only be
35698   // called once per |target_buffer_reservation_id|. Should be called on the
35699   // arbiter's TaskRunner, and after BindToProducerEndpoint() was called.
35700   // Usually, it is called by a specific data source, after it received its
35701   // configuration (including the target buffer ID) from the service.
35702   virtual void BindStartupTargetBuffer(uint16_t target_buffer_reservation_id,
35703                                        BufferID target_buffer_id) = 0;
35704 
35705   // Treat the reservation as resolved to an invalid buffer. Commits for this
35706   // reservation will be flushed to the service ASAP. The service will free
35707   // committed chunks but otherwise ignore them. The producer can call this
35708   // method, for example, if connection to the tracing service failed or the
35709   // session was stopped concurrently before the connection was established.
35710   virtual void AbortStartupTracingForReservation(
35711       uint16_t target_buffer_reservation_id) = 0;
35712 
35713   // Notifies the service that all data for the given FlushRequestID has been
35714   // committed in the shared memory buffer. Should only be called while bound.
35715   virtual void NotifyFlushComplete(FlushRequestID) = 0;
35716 
35717   // Sets the duration during which commits are batched. Args:
35718   // |batch_commits_duration_ms|: The length of the period, during which commits
35719   // by all trace writers are accumulated, before being sent to the service.
35720   // When the period ends, all accumulated commits are flushed. On the first
35721   // commit after the last flush, another delayed flush is scheduled to run in
35722   // |batch_commits_duration_ms|. If an immediate flush occurs (via
35723   // FlushPendingCommitDataRequests()) during a batching period, any
35724   // accumulated commits up to that point will be sent to the service
35725   // immediately. And when the batching period ends, the commits that occurred
35726   // after the immediate flush will also be sent to the service.
35727   //
35728   // If the duration has already been set to a non-zero value before this method
35729   // is called, and there is already a scheduled flush with the previously-set
35730   // duration, the new duration will take effect after the scheduled flush
35731   // occurs.
35732   //
35733   // If |batch_commits_duration_ms| is non-zero, batched data that hasn't been
35734   // sent could be lost at the end of a tracing session. To avoid this,
35735   // producers should make sure that FlushPendingCommitDataRequests is called
35736   // after the last TraceWriter write and before the service has stopped
35737   // listening for commits from the tracing session's data sources (i.e.
35738   // data sources should stop asynchronously, see
35739   // DataSourceDescriptor.will_notify_on_stop=true).
35740   virtual void SetBatchCommitsDuration(uint32_t batch_commits_duration_ms) = 0;
35741 
35742   // Called to enable direct producer-side patching of chunks that have not yet
35743   // been committed to the service. The return value indicates whether direct
35744   // patching was successfully enabled. It will be true if
35745   // SharedMemoryArbiter::SetDirectSMBPatchingSupportedByService has been called
35746   // and false otherwise.
35747   virtual bool EnableDirectSMBPatching() = 0;
35748 
35749   // When the producer and service live in separate processes, this method
35750   // should be called if the producer receives an
35751   // InitializeConnectionResponse.direct_smb_patching_supported set to true by
35752   // the service (see producer_port.proto) .
35753   //
35754   // In the in-process case, the service will always support direct SMB patching
35755   // and this method should always be called.
35756   virtual void SetDirectSMBPatchingSupportedByService() = 0;
35757 
35758   // Forces an immediate commit of the completed packets, without waiting for
35759   // the next task or for a batching period to end. Should only be called while
35760   // bound.
35761   virtual void FlushPendingCommitDataRequests(
35762       std::function<void()> callback = {}) = 0;
35763 
35764   // Attempts to shut down this arbiter. This function prevents new trace
35765   // writers from being created for this this arbiter, but if there are any
35766   // existing trace writers, the shutdown cannot proceed and this funtion
35767   // returns false. The caller should not delete the arbiter before all of its
35768   // associated trace writers have been destroyed and this function returns
35769   // true.
35770   virtual bool TryShutdown() = 0;
35771 
35772   // Create a bound arbiter instance. Args:
35773   // |SharedMemory|: the shared memory buffer to use.
35774   // |page_size|: a multiple of 4KB that defines the granularity of tracing
35775   // pages. See tradeoff considerations in shared_memory_abi.h.
35776   // |ProducerEndpoint|: The service's producer endpoint used e.g. to commit
35777   // chunks and register trace writers.
35778   // |TaskRunner|: Task runner for perfetto's main thread, which executes the
35779   // OnPagesCompleteCallback and IPC calls to the |ProducerEndpoint|.
35780   //
35781   // Implemented in src/core/shared_memory_arbiter_impl.cc.
35782   static std::unique_ptr<SharedMemoryArbiter> CreateInstance(
35783       SharedMemory*,
35784       size_t page_size,
35785       TracingService::ProducerEndpoint*,
35786       base::TaskRunner*);
35787 
35788   // Create an unbound arbiter instance, which should later be bound to a
35789   // ProducerEndpoint and TaskRunner by calling BindToProducerEndpoint(). The
35790   // returned arbiter will ONLY support trace writers with
35791   // BufferExhaustedPolicy::kDrop.
35792   //
35793   // An unbound SharedMemoryArbiter can be used to write to a producer-created
35794   // SharedMemory buffer before the producer connects to the tracing service.
35795   // The producer can then pass this SMB to the service when it connects (see
35796   // TracingService::ConnectProducer).
35797   //
35798   // To trace into the SMB before the service starts the tracing session, trace
35799   // writers can be obtained via CreateStartupTraceWriter() and later associated
35800   // with a target buffer via BindStartupTargetBuffer(), once the target buffer
35801   // is known.
35802   //
35803   // Implemented in src/core/shared_memory_arbiter_impl.cc. See CreateInstance()
35804   // for comments about the arguments.
35805   static std::unique_ptr<SharedMemoryArbiter> CreateUnboundInstance(
35806       SharedMemory*,
35807       size_t page_size);
35808 };
35809 
35810 }  // namespace perfetto
35811 
35812 #endif  // INCLUDE_PERFETTO_EXT_TRACING_CORE_SHARED_MEMORY_ARBITER_H_
35813 /*
35814  * Copyright (C) 2017 The Android Open Source Project
35815  *
35816  * Licensed under the Apache License, Version 2.0 (the "License");
35817  * you may not use this file except in compliance with the License.
35818  * You may obtain a copy of the License at
35819  *
35820  *      http://www.apache.org/licenses/LICENSE-2.0
35821  *
35822  * Unless required by applicable law or agreed to in writing, software
35823  * distributed under the License is distributed on an "AS IS" BASIS,
35824  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
35825  * See the License for the specific language governing permissions and
35826  * limitations under the License.
35827  */
35828 
35829 #ifndef SRC_TRACING_CORE_SHARED_MEMORY_ARBITER_IMPL_H_
35830 #define SRC_TRACING_CORE_SHARED_MEMORY_ARBITER_IMPL_H_
35831 
35832 #include <stdint.h>
35833 
35834 #include <functional>
35835 #include <map>
35836 #include <memory>
35837 #include <mutex>
35838 #include <vector>
35839 
35840 // gen_amalgamated expanded: #include "perfetto/ext/base/weak_ptr.h"
35841 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/basic_types.h"
35842 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/shared_memory_abi.h"
35843 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/shared_memory_arbiter.h"
35844 // gen_amalgamated expanded: #include "perfetto/tracing/core/forward_decls.h"
35845 // gen_amalgamated expanded: #include "src/tracing/core/id_allocator.h"
35846 
35847 namespace perfetto {
35848 
35849 class PatchList;
35850 class Patch;
35851 class TraceWriter;
35852 class TraceWriterImpl;
35853 
35854 namespace base {
35855 class TaskRunner;
35856 }  // namespace base
35857 
35858 // This class handles the shared memory buffer on the producer side. It is used
35859 // to obtain thread-local chunks and to partition pages from several threads.
35860 // There is one arbiter instance per Producer.
35861 // This class is thread-safe and uses locks to do so. Data sources are supposed
35862 // to interact with this sporadically, only when they run out of space on their
35863 // current thread-local chunk.
35864 //
35865 // When the arbiter is created using CreateUnboundInstance(), the following
35866 // state transitions are possible:
35867 //
35868 //   [ !fully_bound_, !endpoint_, 0 unbound buffer reservations ]
35869 //       |     |
35870 //       |     | CreateStartupTraceWriter(buf)
35871 //       |     |  buffer reservations += buf
35872 //       |     |
35873 //       |     |             ----
35874 //       |     |            |    | CreateStartupTraceWriter(buf)
35875 //       |     |            |    |  buffer reservations += buf
35876 //       |     V            |    V
35877 //       |   [ !fully_bound_, !endpoint_, >=1 unbound buffer reservations ]
35878 //       |                                                |
35879 //       |                       BindToProducerEndpoint() |
35880 //       |                                                |
35881 //       | BindToProducerEndpoint()                       |
35882 //       |                                                V
35883 //       |   [ !fully_bound_, endpoint_, >=1 unbound buffer reservations ]
35884 //       |   A    |    A                               |     A
35885 //       |   |    |    |                               |     |
35886 //       |   |     ----                                |     |
35887 //       |   |    CreateStartupTraceWriter(buf)        |     |
35888 //       |   |     buffer reservations += buf          |     |
35889 //       |   |                                         |     |
35890 //       |   | CreateStartupTraceWriter(buf)           |     |
35891 //       |   |  where buf is not yet bound             |     |
35892 //       |   |  buffer reservations += buf             |     | (yes)
35893 //       |   |                                         |     |
35894 //       |   |        BindStartupTargetBuffer(buf, id) |-----
35895 //       |   |           buffer reservations -= buf    | reservations > 0?
35896 //       |   |                                         |
35897 //       |   |                                         | (no)
35898 //       V   |                                         V
35899 //       [ fully_bound_, endpoint_, 0 unbound buffer reservations ]
35900 //          |    A
35901 //          |    | CreateStartupTraceWriter(buf)
35902 //          |    |  where buf is already bound
35903 //           ----
35904 class SharedMemoryArbiterImpl : public SharedMemoryArbiter {
35905  public:
35906   // See SharedMemoryArbiter::CreateInstance(). |start|, |size| define the
35907   // boundaries of the shared memory buffer. ProducerEndpoint and TaskRunner may
35908   // be |nullptr| if created unbound, see
35909   // SharedMemoryArbiter::CreateUnboundInstance().
35910   SharedMemoryArbiterImpl(void* start,
35911                           size_t size,
35912                           size_t page_size,
35913                           TracingService::ProducerEndpoint*,
35914                           base::TaskRunner*);
35915 
35916   // Returns a new Chunk to write tracing data. Depending on the provided
35917   // BufferExhaustedPolicy, this may return an invalid chunk if no valid free
35918   // chunk could be found in the SMB.
35919   SharedMemoryABI::Chunk GetNewChunk(const SharedMemoryABI::ChunkHeader&,
35920                                      BufferExhaustedPolicy,
35921                                      size_t size_hint = 0);
35922 
35923   // Puts back a Chunk that has been completed and sends a request to the
35924   // service to move it to the central tracing buffer. |target_buffer| is the
35925   // absolute trace buffer ID where the service should move the chunk onto (the
35926   // producer is just to copy back the same number received in the
35927   // DataSourceConfig upon the StartDataSource() reques).
35928   // PatchList is a pointer to the list of patches for previous chunks. The
35929   // first patched entries will be removed from the patched list and sent over
35930   // to the service in the same CommitData() IPC request.
35931   void ReturnCompletedChunk(SharedMemoryABI::Chunk,
35932                             MaybeUnboundBufferID target_buffer,
35933                             PatchList*);
35934 
35935   // Send a request to the service to apply completed patches from |patch_list|.
35936   // |writer_id| is the ID of the TraceWriter that calls this method,
35937   // |target_buffer| is the global trace buffer ID of its target buffer.
35938   void SendPatches(WriterID writer_id,
35939                    MaybeUnboundBufferID target_buffer,
35940                    PatchList* patch_list);
35941 
shmem_abi_for_testing()35942   SharedMemoryABI* shmem_abi_for_testing() { return &shmem_abi_; }
35943 
set_default_layout_for_testing(SharedMemoryABI::PageLayout l)35944   static void set_default_layout_for_testing(SharedMemoryABI::PageLayout l) {
35945     default_page_layout = l;
35946   }
35947 
35948   // SharedMemoryArbiter implementation.
35949   // See include/perfetto/tracing/core/shared_memory_arbiter.h for comments.
35950   std::unique_ptr<TraceWriter> CreateTraceWriter(
35951       BufferID target_buffer,
35952       BufferExhaustedPolicy = BufferExhaustedPolicy::kDefault) override;
35953   std::unique_ptr<TraceWriter> CreateStartupTraceWriter(
35954       uint16_t target_buffer_reservation_id) override;
35955   void BindToProducerEndpoint(TracingService::ProducerEndpoint*,
35956                               base::TaskRunner*) override;
35957   void BindStartupTargetBuffer(uint16_t target_buffer_reservation_id,
35958                                BufferID target_buffer_id) override;
35959   void AbortStartupTracingForReservation(
35960       uint16_t target_buffer_reservation_id) override;
35961   void NotifyFlushComplete(FlushRequestID) override;
35962 
35963   void SetBatchCommitsDuration(uint32_t batch_commits_duration_ms) override;
35964 
35965   bool EnableDirectSMBPatching() override;
35966 
35967   void SetDirectSMBPatchingSupportedByService() override;
35968 
35969   void FlushPendingCommitDataRequests(
35970       std::function<void()> callback = {}) override;
35971   bool TryShutdown() override;
35972 
task_runner() const35973   base::TaskRunner* task_runner() const { return task_runner_; }
page_size() const35974   size_t page_size() const { return shmem_abi_.page_size(); }
num_pages() const35975   size_t num_pages() const { return shmem_abi_.num_pages(); }
35976 
GetWeakPtr() const35977   base::WeakPtr<SharedMemoryArbiterImpl> GetWeakPtr() const {
35978     return weak_ptr_factory_.GetWeakPtr();
35979   }
35980 
35981  private:
35982   friend class TraceWriterImpl;
35983   friend class StartupTraceWriterTest;
35984   friend class SharedMemoryArbiterImplTest;
35985 
35986   struct TargetBufferReservation {
35987     bool resolved = false;
35988     BufferID target_buffer = kInvalidBufferId;
35989   };
35990 
35991   // Placeholder for the actual target buffer ID of a startup target buffer
35992   // reservation ID in |target_buffer_reservations_|.
35993   static constexpr BufferID kInvalidBufferId = 0;
35994 
35995   static SharedMemoryABI::PageLayout default_page_layout;
35996 
35997   SharedMemoryArbiterImpl(const SharedMemoryArbiterImpl&) = delete;
35998   SharedMemoryArbiterImpl& operator=(const SharedMemoryArbiterImpl&) = delete;
35999 
36000   void UpdateCommitDataRequest(SharedMemoryABI::Chunk chunk,
36001                                WriterID writer_id,
36002                                MaybeUnboundBufferID target_buffer,
36003                                PatchList* patch_list);
36004 
36005   // Search the chunks that are being batched in |commit_data_req_| for a chunk
36006   // that needs patching and that matches the provided |writer_id| and
36007   // |patch.chunk_id|. If found, apply |patch| to that chunk, and if
36008   // |chunk_needs_more_patching| is true, clear the needs patching flag of the
36009   // chunk and mark it as complete - to allow the service to read it (and other
36010   // chunks after it) during scraping. Returns true if the patch was applied,
36011   // false otherwise.
36012   //
36013   // Note: the caller must be holding |lock_| for the duration of the call.
36014   bool TryDirectPatchLocked(WriterID writer_id,
36015                             const Patch& patch,
36016                             bool chunk_needs_more_patching);
36017   std::unique_ptr<TraceWriter> CreateTraceWriterInternal(
36018       MaybeUnboundBufferID target_buffer,
36019       BufferExhaustedPolicy);
36020 
36021   // Called by the TraceWriter destructor.
36022   void ReleaseWriterID(WriterID);
36023 
36024   void BindStartupTargetBufferImpl(std::unique_lock<std::mutex> scoped_lock,
36025                                    uint16_t target_buffer_reservation_id,
36026                                    BufferID target_buffer_id);
36027 
36028   // If any flush callbacks were queued up while the arbiter or any target
36029   // buffer reservation was unbound, this wraps the pending callbacks into a new
36030   // std::function and returns it. Otherwise returns an invalid std::function.
36031   std::function<void()> TakePendingFlushCallbacksLocked();
36032 
36033   // Replace occurrences of target buffer reservation IDs in |commit_data_req_|
36034   // with their respective actual BufferIDs if they were already bound. Returns
36035   // true iff all occurrences were replaced.
36036   bool ReplaceCommitPlaceholderBufferIdsLocked();
36037 
36038   // Update and return |fully_bound_| based on the arbiter's |pending_writers_|
36039   // state.
36040   bool UpdateFullyBoundLocked();
36041 
36042   const bool initially_bound_;
36043 
36044   // Only accessed on |task_runner_| after the producer endpoint was bound.
36045   TracingService::ProducerEndpoint* producer_endpoint_ = nullptr;
36046 
36047   // --- Begin lock-protected members ---
36048 
36049   std::mutex lock_;
36050 
36051   base::TaskRunner* task_runner_ = nullptr;
36052   SharedMemoryABI shmem_abi_;
36053   size_t page_idx_ = 0;
36054   std::unique_ptr<CommitDataRequest> commit_data_req_;
36055   size_t bytes_pending_commit_ = 0;  // SUM(chunk.size() : commit_data_req_).
36056   IdAllocator<WriterID> active_writer_ids_;
36057   bool did_shutdown_ = false;
36058 
36059   // Whether the arbiter itself and all startup target buffer reservations are
36060   // bound. Note that this can become false again later if a new target buffer
36061   // reservation is created by calling CreateStartupTraceWriter() with a new
36062   // reservation id.
36063   bool fully_bound_;
36064 
36065   // IDs of writers and their assigned target buffers that should be registered
36066   // with the service after the arbiter and/or their startup target buffer is
36067   // bound.
36068   std::map<WriterID, MaybeUnboundBufferID> pending_writers_;
36069 
36070   // Callbacks for flush requests issued while the arbiter or a target buffer
36071   // reservation was unbound.
36072   std::vector<std::function<void()>> pending_flush_callbacks_;
36073 
36074   // See SharedMemoryArbiter::SetBatchCommitsDuration.
36075   uint32_t batch_commits_duration_ms_ = 0;
36076 
36077   // See SharedMemoryArbiter::EnableDirectSMBPatching.
36078   bool direct_patching_enabled_ = false;
36079 
36080   // See SharedMemoryArbiter::SetDirectSMBPatchingSupportedByService.
36081   bool direct_patching_supported_by_service_ = false;
36082 
36083   // Indicates whether we have already scheduled a delayed flush for the
36084   // purposes of batching. Set to true at the beginning of a batching period and
36085   // cleared at the end of the period. Immediate flushes that happen during a
36086   // batching period will empty the |commit_data_req| (triggering an immediate
36087   // IPC to the service), but will not clear this flag and the
36088   // previously-scheduled delayed flush will still occur at the end of the
36089   // batching period.
36090   bool delayed_flush_scheduled_ = false;
36091 
36092   // Stores target buffer reservations for writers created via
36093   // CreateStartupTraceWriter(). A bound reservation sets
36094   // TargetBufferReservation::resolved to true and is associated with the actual
36095   // BufferID supplied in BindStartupTargetBuffer().
36096   //
36097   // TODO(eseckler): Clean up entries from this map. This would probably require
36098   // a method in SharedMemoryArbiter that allows a producer to invalidate a
36099   // reservation ID.
36100   std::map<MaybeUnboundBufferID, TargetBufferReservation>
36101       target_buffer_reservations_;
36102 
36103   // --- End lock-protected members ---
36104 
36105   // Keep at the end.
36106   base::WeakPtrFactory<SharedMemoryArbiterImpl> weak_ptr_factory_;
36107 };
36108 
36109 }  // namespace perfetto
36110 
36111 #endif  // SRC_TRACING_CORE_SHARED_MEMORY_ARBITER_IMPL_H_
36112 // gen_amalgamated begin header: include/perfetto/ext/tracing/core/commit_data_request.h
36113 /*
36114  * Copyright (C) 2017 The Android Open Source Project
36115  *
36116  * Licensed under the Apache License, Version 2.0 (the "License");
36117  * you may not use this file except in compliance with the License.
36118  * You may obtain a copy of the License at
36119  *
36120  *      http://www.apache.org/licenses/LICENSE-2.0
36121  *
36122  * Unless required by applicable law or agreed to in writing, software
36123  * distributed under the License is distributed on an "AS IS" BASIS,
36124  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
36125  * See the License for the specific language governing permissions and
36126  * limitations under the License.
36127  */
36128 
36129 #ifndef INCLUDE_PERFETTO_EXT_TRACING_CORE_COMMIT_DATA_REQUEST_H_
36130 #define INCLUDE_PERFETTO_EXT_TRACING_CORE_COMMIT_DATA_REQUEST_H_
36131 
36132 // Creates the aliases in the ::perfetto namespace, doing things like:
36133 // using ::perfetto::Foo = ::perfetto::protos::gen::Foo.
36134 // See comments in forward_decls.h for the historical reasons of this
36135 // indirection layer.
36136 // gen_amalgamated expanded: #include "perfetto/tracing/core/forward_decls.h"
36137 
36138 // gen_amalgamated expanded: #include "protos/perfetto/common/commit_data_request.gen.h"
36139 
36140 #endif  // INCLUDE_PERFETTO_EXT_TRACING_CORE_COMMIT_DATA_REQUEST_H_
36141 // gen_amalgamated begin header: src/tracing/core/trace_writer_impl.h
36142 // gen_amalgamated begin header: src/tracing/core/patch_list.h
36143 /*
36144  * Copyright (C) 2018 The Android Open Source Project
36145  *
36146  * Licensed under the Apache License, Version 2.0 (the "License");
36147  * you may not use this file except in compliance with the License.
36148  * You may obtain a copy of the License at
36149  *
36150  *      http://www.apache.org/licenses/LICENSE-2.0
36151  *
36152  * Unless required by applicable law or agreed to in writing, software
36153  * distributed under the License is distributed on an "AS IS" BASIS,
36154  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
36155  * See the License for the specific language governing permissions and
36156  * limitations under the License.
36157  */
36158 
36159 #ifndef SRC_TRACING_CORE_PATCH_LIST_H_
36160 #define SRC_TRACING_CORE_PATCH_LIST_H_
36161 
36162 #include <array>
36163 #include <forward_list>
36164 
36165 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
36166 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/basic_types.h"
36167 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/shared_memory_abi.h"
36168 
36169 namespace perfetto {
36170 
36171 // Used to handle the backfilling of the headers (the |size_field|) of nested
36172 // messages when a proto is fragmented over several chunks. These patches are
36173 // sent out-of-band to the tracing service, after having returned the initial
36174 // chunks of the fragment.
36175 // TODO(crbug.com/904477): Re-disable the move constructors when all usses of
36176 // this class have been fixed.
36177 class Patch {
36178  public:
36179   using PatchContent = std::array<uint8_t, SharedMemoryABI::kPacketHeaderSize>;
Patch(ChunkID c,uint16_t o)36180   Patch(ChunkID c, uint16_t o) : chunk_id(c), offset(o) {}
36181   Patch(const Patch&) = default;  // For tests.
36182 
36183   const ChunkID chunk_id;
36184   const uint16_t offset;
36185   PatchContent size_field{};
36186 
36187   // |size_field| contains a varint. Any varint must start with != 0. Even in
36188   // the case we want to encode a size == 0, protozero will write a redundant
36189   // varint for that, that is [0x80, 0x80, 0x80, 0x00]. So the first byte is 0
36190   // iff we never wrote any varint into that.
is_patched() const36191   bool is_patched() const { return size_field[0] != 0; }
36192 
36193   // For tests.
operator ==(const Patch & o) const36194   bool operator==(const Patch& o) const {
36195     return chunk_id == o.chunk_id && offset == o.offset &&
36196            size_field == o.size_field;
36197   }
36198 
36199  private:
36200   Patch& operator=(const Patch&) = delete;
36201 };
36202 
36203 // Note: the protozero::Message(s) will take pointers to the |size_field| of
36204 // these entries. This container must guarantee that the Patch objects are never
36205 // moved around (i.e. cannot be a vector because of reallocations can change
36206 // addresses of pre-existing entries).
36207 class PatchList {
36208  public:
36209   using ListType = std::forward_list<Patch>;
36210   using value_type = ListType::value_type;          // For gtest.
36211   using const_iterator = ListType::const_iterator;  // For gtest.
36212 
PatchList()36213   PatchList() : last_(list_.before_begin()) {}
36214 
emplace_back(ChunkID chunk_id,uint16_t offset)36215   Patch* emplace_back(ChunkID chunk_id, uint16_t offset) {
36216     PERFETTO_DCHECK(empty() || last_->chunk_id != chunk_id ||
36217                     offset >= last_->offset + sizeof(Patch::PatchContent));
36218     last_ = list_.emplace_after(last_, chunk_id, offset);
36219     return &*last_;
36220   }
36221 
pop_front()36222   void pop_front() {
36223     PERFETTO_DCHECK(!list_.empty());
36224     list_.pop_front();
36225     if (empty())
36226       last_ = list_.before_begin();
36227   }
36228 
front() const36229   const Patch& front() const {
36230     PERFETTO_DCHECK(!list_.empty());
36231     return list_.front();
36232   }
36233 
back() const36234   const Patch& back() const {
36235     PERFETTO_DCHECK(!list_.empty());
36236     return *last_;
36237   }
36238 
begin() const36239   ListType::const_iterator begin() const { return list_.begin(); }
end() const36240   ListType::const_iterator end() const { return list_.end(); }
empty() const36241   bool empty() const { return list_.empty(); }
36242 
36243  private:
36244   ListType list_;
36245   ListType::iterator last_;
36246 };
36247 
36248 }  // namespace perfetto
36249 
36250 #endif  // SRC_TRACING_CORE_PATCH_LIST_H_
36251 /*
36252  * Copyright (C) 2017 The Android Open Source Project
36253  *
36254  * Licensed under the Apache License, Version 2.0 (the "License");
36255  * you may not use this file except in compliance with the License.
36256  * You may obtain a copy of the License at
36257  *
36258  *      http://www.apache.org/licenses/LICENSE-2.0
36259  *
36260  * Unless required by applicable law or agreed to in writing, software
36261  * distributed under the License is distributed on an "AS IS" BASIS,
36262  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
36263  * See the License for the specific language governing permissions and
36264  * limitations under the License.
36265  */
36266 
36267 #ifndef SRC_TRACING_CORE_TRACE_WRITER_IMPL_H_
36268 #define SRC_TRACING_CORE_TRACE_WRITER_IMPL_H_
36269 
36270 // gen_amalgamated expanded: #include "perfetto/base/proc_utils.h"
36271 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/basic_types.h"
36272 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/shared_memory_abi.h"
36273 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/shared_memory_arbiter.h"
36274 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/trace_writer.h"
36275 // gen_amalgamated expanded: #include "perfetto/protozero/message_handle.h"
36276 // gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
36277 // gen_amalgamated expanded: #include "perfetto/protozero/root_message.h"
36278 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_stream_writer.h"
36279 // gen_amalgamated expanded: #include "perfetto/tracing/buffer_exhausted_policy.h"
36280 // gen_amalgamated expanded: #include "src/tracing/core/patch_list.h"
36281 
36282 namespace perfetto {
36283 
36284 class SharedMemoryArbiterImpl;
36285 
36286 // See //include/perfetto/tracing/core/trace_writer.h for docs.
36287 class TraceWriterImpl : public TraceWriter,
36288                         public protozero::ScatteredStreamWriter::Delegate {
36289  public:
36290   // TracePacketHandle is defined in trace_writer.h
36291   TraceWriterImpl(SharedMemoryArbiterImpl*,
36292                   WriterID,
36293                   MaybeUnboundBufferID buffer_id,
36294                   BufferExhaustedPolicy);
36295   ~TraceWriterImpl() override;
36296 
36297   // TraceWriter implementation. See documentation in trace_writer.h.
36298   TracePacketHandle NewTracePacket() override;
36299   void Flush(std::function<void()> callback = {}) override;
36300   WriterID writer_id() const override;
written() const36301   uint64_t written() const override {
36302     return protobuf_stream_writer_.written();
36303   }
36304 
ResetChunkForTesting()36305   void ResetChunkForTesting() { cur_chunk_ = SharedMemoryABI::Chunk(); }
drop_packets_for_testing() const36306   bool drop_packets_for_testing() const { return drop_packets_; }
36307 
36308  private:
36309   TraceWriterImpl(const TraceWriterImpl&) = delete;
36310   TraceWriterImpl& operator=(const TraceWriterImpl&) = delete;
36311 
36312   // ScatteredStreamWriter::Delegate implementation.
36313   protozero::ContiguousMemoryRange GetNewBuffer() override;
36314 
36315   // The per-producer arbiter that coordinates access to the shared memory
36316   // buffer from several threads.
36317   SharedMemoryArbiterImpl* const shmem_arbiter_;
36318 
36319   // ID of the current writer.
36320   const WriterID id_;
36321 
36322   // This is copied into the commit request by SharedMemoryArbiter. See comments
36323   // in data_source_config.proto for |target_buffer|. If this is a reservation
36324   // for a buffer ID in case of a startup trace writer, SharedMemoryArbiterImpl
36325   // will also translate the reservation ID to the actual buffer ID.
36326   const MaybeUnboundBufferID target_buffer_;
36327 
36328   // Whether GetNewChunk() should stall or return an invalid chunk if the SMB is
36329   // exhausted.
36330   const BufferExhaustedPolicy buffer_exhausted_policy_;
36331 
36332   // Monotonic (% wrapping) sequence id of the chunk. Together with the WriterID
36333   // this allows the Service to reconstruct the linear sequence of packets.
36334   ChunkID next_chunk_id_ = 0;
36335 
36336   // The chunk we are holding onto (if any).
36337   SharedMemoryABI::Chunk cur_chunk_;
36338 
36339   // Passed to protozero message to write directly into |cur_chunk_|. It
36340   // keeps track of the write pointer. It calls us back (GetNewBuffer()) when
36341   // |cur_chunk_| is filled.
36342   protozero::ScatteredStreamWriter protobuf_stream_writer_;
36343 
36344   // The packet returned via NewTracePacket(). Its owned by this class,
36345   // TracePacketHandle has just a pointer to it.
36346   std::unique_ptr<protozero::RootMessage<protos::pbzero::TracePacket>>
36347       cur_packet_;
36348 
36349   // The start address of |cur_packet_| within |cur_chunk_|. Used to figure out
36350   // fragments sizes when a TracePacket write is interrupted by GetNewBuffer().
36351   uint8_t* cur_fragment_start_ = nullptr;
36352 
36353   // true if we received a call to GetNewBuffer() after NewTracePacket(),
36354   // false if GetNewBuffer() happened during NewTracePacket() prologue, while
36355   // starting the TracePacket header.
36356   bool fragmenting_packet_ = false;
36357 
36358   // Set to |true| when the current chunk contains the maximum number of packets
36359   // a chunk can contain. When this is |true|, the next packet requires starting
36360   // a new chunk.
36361   bool reached_max_packets_per_chunk_ = false;
36362 
36363   // If we fail to acquire a new chunk when the arbiter operates in
36364   // SharedMemory::BufferExhaustedPolicy::kDrop mode, the trace writer enters a
36365   // mode in which data is written to a local garbage chunk and dropped.
36366   bool drop_packets_ = false;
36367 
36368   // Whether the trace writer should try to acquire a new chunk from the SMB
36369   // when the next TracePacket is started because it filled the garbage chunk at
36370   // least once since the last attempt.
36371   bool retry_new_chunk_after_packet_ = false;
36372 
36373   // Points to the size field of the last packet we wrote to the current chunk.
36374   // If the chunk was already returned, this is reset to |nullptr|.
36375   uint8_t* last_packet_size_field_ = nullptr;
36376 
36377   // When a packet is fragmented across different chunks, the |size_field| of
36378   // the outstanding nested protobuf messages is redirected onto Patch entries
36379   // in this list at the time the Chunk is returned (because at that point we
36380   // have to release the ownership of the current Chunk). This list will be
36381   // later sent out-of-band to the tracing service, who will patch the required
36382   // chunks, if they are still around.
36383   PatchList patch_list_;
36384 
36385   // PID of the process that created the trace writer. Used for a DCHECK that
36386   // aims to detect unsupported process forks while tracing.
36387   const base::PlatformProcessId process_id_;
36388 };
36389 
36390 }  // namespace perfetto
36391 
36392 #endif  // SRC_TRACING_CORE_TRACE_WRITER_IMPL_H_
36393 /*
36394  * Copyright (C) 2017 The Android Open Source Project
36395  *
36396  * Licensed under the Apache License, Version 2.0 (the "License");
36397  * you may not use this file except in compliance with the License.
36398  * You may obtain a copy of the License at
36399  *
36400  *      http://www.apache.org/licenses/LICENSE-2.0
36401  *
36402  * Unless required by applicable law or agreed to in writing, software
36403  * distributed under the License is distributed on an "AS IS" BASIS,
36404  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
36405  * See the License for the specific language governing permissions and
36406  * limitations under the License.
36407  */
36408 
36409 // gen_amalgamated expanded: #include "src/tracing/core/shared_memory_arbiter_impl.h"
36410 
36411 #include <algorithm>
36412 #include <limits>
36413 #include <utility>
36414 
36415 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
36416 // gen_amalgamated expanded: #include "perfetto/base/task_runner.h"
36417 // gen_amalgamated expanded: #include "perfetto/base/time.h"
36418 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/commit_data_request.h"
36419 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/shared_memory.h"
36420 // gen_amalgamated expanded: #include "src/tracing/core/null_trace_writer.h"
36421 // gen_amalgamated expanded: #include "src/tracing/core/trace_writer_impl.h"
36422 
36423 namespace perfetto {
36424 
36425 using Chunk = SharedMemoryABI::Chunk;
36426 
36427 namespace {
36428 static_assert(sizeof(BufferID) == sizeof(uint16_t),
36429               "The MaybeUnboundBufferID logic requires BufferID not to grow "
36430               "above uint16_t.");
36431 
MakeTargetBufferIdForReservation(uint16_t reservation_id)36432 MaybeUnboundBufferID MakeTargetBufferIdForReservation(uint16_t reservation_id) {
36433   // Reservation IDs are stored in the upper bits.
36434   PERFETTO_CHECK(reservation_id > 0);
36435   return static_cast<MaybeUnboundBufferID>(reservation_id) << 16;
36436 }
36437 
IsReservationTargetBufferId(MaybeUnboundBufferID buffer_id)36438 bool IsReservationTargetBufferId(MaybeUnboundBufferID buffer_id) {
36439   return (buffer_id >> 16) > 0;
36440 }
36441 }  // namespace
36442 
36443 // static
36444 SharedMemoryABI::PageLayout SharedMemoryArbiterImpl::default_page_layout =
36445     SharedMemoryABI::PageLayout::kPageDiv1;
36446 
36447 // static
36448 constexpr BufferID SharedMemoryArbiterImpl::kInvalidBufferId;
36449 
36450 // static
CreateInstance(SharedMemory * shared_memory,size_t page_size,TracingService::ProducerEndpoint * producer_endpoint,base::TaskRunner * task_runner)36451 std::unique_ptr<SharedMemoryArbiter> SharedMemoryArbiter::CreateInstance(
36452     SharedMemory* shared_memory,
36453     size_t page_size,
36454     TracingService::ProducerEndpoint* producer_endpoint,
36455     base::TaskRunner* task_runner) {
36456   return std::unique_ptr<SharedMemoryArbiterImpl>(
36457       new SharedMemoryArbiterImpl(shared_memory->start(), shared_memory->size(),
36458                                   page_size, producer_endpoint, task_runner));
36459 }
36460 
36461 // static
CreateUnboundInstance(SharedMemory * shared_memory,size_t page_size)36462 std::unique_ptr<SharedMemoryArbiter> SharedMemoryArbiter::CreateUnboundInstance(
36463     SharedMemory* shared_memory,
36464     size_t page_size) {
36465   return std::unique_ptr<SharedMemoryArbiterImpl>(new SharedMemoryArbiterImpl(
36466       shared_memory->start(), shared_memory->size(), page_size,
36467       /*producer_endpoint=*/nullptr, /*task_runner=*/nullptr));
36468 }
36469 
SharedMemoryArbiterImpl(void * start,size_t size,size_t page_size,TracingService::ProducerEndpoint * producer_endpoint,base::TaskRunner * task_runner)36470 SharedMemoryArbiterImpl::SharedMemoryArbiterImpl(
36471     void* start,
36472     size_t size,
36473     size_t page_size,
36474     TracingService::ProducerEndpoint* producer_endpoint,
36475     base::TaskRunner* task_runner)
36476     : initially_bound_(task_runner && producer_endpoint),
36477       producer_endpoint_(producer_endpoint),
36478       task_runner_(task_runner),
36479       shmem_abi_(reinterpret_cast<uint8_t*>(start), size, page_size),
36480       active_writer_ids_(kMaxWriterID),
36481       fully_bound_(initially_bound_),
36482       weak_ptr_factory_(this) {}
36483 
GetNewChunk(const SharedMemoryABI::ChunkHeader & header,BufferExhaustedPolicy buffer_exhausted_policy,size_t size_hint)36484 Chunk SharedMemoryArbiterImpl::GetNewChunk(
36485     const SharedMemoryABI::ChunkHeader& header,
36486     BufferExhaustedPolicy buffer_exhausted_policy,
36487     size_t size_hint) {
36488   PERFETTO_DCHECK(size_hint == 0);  // Not implemented yet.
36489   // If initially unbound, we do not support stalling. In theory, we could
36490   // support stalling for TraceWriters created after the arbiter and startup
36491   // buffer reservations were bound, but to avoid raciness between the creation
36492   // of startup writers and binding, we categorically forbid kStall mode.
36493   PERFETTO_DCHECK(initially_bound_ ||
36494                   buffer_exhausted_policy == BufferExhaustedPolicy::kDrop);
36495 
36496   int stall_count = 0;
36497   unsigned stall_interval_us = 0;
36498   bool task_runner_runs_on_current_thread = false;
36499   static const unsigned kMaxStallIntervalUs = 100000;
36500   static const int kLogAfterNStalls = 3;
36501   static const int kFlushCommitsAfterEveryNStalls = 2;
36502   static const int kAssertAtNStalls = 100;
36503 
36504   for (;;) {
36505     // TODO(primiano): Probably this lock is not really required and this code
36506     // could be rewritten leveraging only the Try* atomic operations in
36507     // SharedMemoryABI. But let's not be too adventurous for the moment.
36508     {
36509       std::unique_lock<std::mutex> scoped_lock(lock_);
36510 
36511       task_runner_runs_on_current_thread =
36512           task_runner_ && task_runner_->RunsTasksOnCurrentThread();
36513 
36514       // If more than half of the SMB.size() is filled with completed chunks for
36515       // which we haven't notified the service yet (i.e. they are still enqueued
36516       // in |commit_data_req_|), force a synchronous CommitDataRequest() even if
36517       // we acquire a chunk, to reduce the likeliness of stalling the writer.
36518       //
36519       // We can only do this if we're writing on the same thread that we access
36520       // the producer endpoint on, since we cannot notify the producer endpoint
36521       // to commit synchronously on a different thread. Attempting to flush
36522       // synchronously on another thread will lead to subtle bugs caused by
36523       // out-of-order commit requests (crbug.com/919187#c28).
36524       bool should_commit_synchronously =
36525           task_runner_runs_on_current_thread &&
36526           buffer_exhausted_policy == BufferExhaustedPolicy::kStall &&
36527           commit_data_req_ && bytes_pending_commit_ >= shmem_abi_.size() / 2;
36528 
36529       const size_t initial_page_idx = page_idx_;
36530       for (size_t i = 0; i < shmem_abi_.num_pages(); i++) {
36531         page_idx_ = (initial_page_idx + i) % shmem_abi_.num_pages();
36532         bool is_new_page = false;
36533 
36534         // TODO(primiano): make the page layout dynamic.
36535         auto layout = SharedMemoryArbiterImpl::default_page_layout;
36536 
36537         if (shmem_abi_.is_page_free(page_idx_)) {
36538           // TODO(primiano): Use the |size_hint| here to decide the layout.
36539           is_new_page = shmem_abi_.TryPartitionPage(page_idx_, layout);
36540         }
36541         uint32_t free_chunks;
36542         if (is_new_page) {
36543           free_chunks = (1 << SharedMemoryABI::kNumChunksForLayout[layout]) - 1;
36544         } else {
36545           free_chunks = shmem_abi_.GetFreeChunks(page_idx_);
36546         }
36547 
36548         for (uint32_t chunk_idx = 0; free_chunks;
36549              chunk_idx++, free_chunks >>= 1) {
36550           if (!(free_chunks & 1))
36551             continue;
36552           // We found a free chunk.
36553           Chunk chunk = shmem_abi_.TryAcquireChunkForWriting(
36554               page_idx_, chunk_idx, &header);
36555           if (!chunk.is_valid())
36556             continue;
36557           if (stall_count > kLogAfterNStalls) {
36558             PERFETTO_LOG("Recovered from stall after %d iterations",
36559                          stall_count);
36560           }
36561 
36562           if (should_commit_synchronously) {
36563             // We can't flush while holding the lock.
36564             scoped_lock.unlock();
36565             FlushPendingCommitDataRequests();
36566             return chunk;
36567           } else {
36568             return chunk;
36569           }
36570         }
36571       }
36572     }  // scoped_lock
36573 
36574     if (buffer_exhausted_policy == BufferExhaustedPolicy::kDrop) {
36575       PERFETTO_DLOG("Shared memory buffer exhaused, returning invalid Chunk!");
36576       return Chunk();
36577     }
36578 
36579     PERFETTO_DCHECK(initially_bound_);
36580 
36581     // All chunks are taken (either kBeingWritten by us or kBeingRead by the
36582     // Service).
36583     if (stall_count++ == kLogAfterNStalls) {
36584       PERFETTO_LOG("Shared memory buffer overrun! Stalling");
36585     }
36586 
36587     if (stall_count == kAssertAtNStalls) {
36588       PERFETTO_FATAL(
36589           "Shared memory buffer max stall count exceeded; possible deadlock");
36590     }
36591 
36592     // If the IPC thread itself is stalled because the current process has
36593     // filled up the SMB, we need to make sure that the service can process and
36594     // purge the chunks written by our process, by flushing any pending commit
36595     // requests. Because other threads in our process can continue to
36596     // concurrently grab, fill and commit any chunks purged by the service, it
36597     // is possible that the SMB remains full and the IPC thread remains stalled,
36598     // needing to flush the concurrently queued up commits again. This is
36599     // particularly likely with in-process perfetto service where the IPC thread
36600     // is the service thread. To avoid remaining stalled forever in such a
36601     // situation, we attempt to flush periodically after every N stalls.
36602     if (stall_count % kFlushCommitsAfterEveryNStalls == 0 &&
36603         task_runner_runs_on_current_thread) {
36604       // TODO(primiano): sending the IPC synchronously is a temporary workaround
36605       // until the backpressure logic in probes_producer is sorted out. Until
36606       // then the risk is that we stall the message loop waiting for the tracing
36607       // service to consume the shared memory buffer (SMB) and, for this reason,
36608       // never run the task that tells the service to purge the SMB. This must
36609       // happen iff we are on the IPC thread, not doing this will cause
36610       // deadlocks, doing this on the wrong thread causes out-of-order data
36611       // commits (crbug.com/919187#c28).
36612       FlushPendingCommitDataRequests();
36613     } else {
36614       base::SleepMicroseconds(stall_interval_us);
36615       stall_interval_us =
36616           std::min(kMaxStallIntervalUs, (stall_interval_us + 1) * 8);
36617     }
36618   }
36619 }
36620 
ReturnCompletedChunk(Chunk chunk,MaybeUnboundBufferID target_buffer,PatchList * patch_list)36621 void SharedMemoryArbiterImpl::ReturnCompletedChunk(
36622     Chunk chunk,
36623     MaybeUnboundBufferID target_buffer,
36624     PatchList* patch_list) {
36625   PERFETTO_DCHECK(chunk.is_valid());
36626   const WriterID writer_id = chunk.writer_id();
36627   UpdateCommitDataRequest(std::move(chunk), writer_id, target_buffer,
36628                           patch_list);
36629 }
36630 
SendPatches(WriterID writer_id,MaybeUnboundBufferID target_buffer,PatchList * patch_list)36631 void SharedMemoryArbiterImpl::SendPatches(WriterID writer_id,
36632                                           MaybeUnboundBufferID target_buffer,
36633                                           PatchList* patch_list) {
36634   PERFETTO_DCHECK(!patch_list->empty() && patch_list->front().is_patched());
36635   UpdateCommitDataRequest(Chunk(), writer_id, target_buffer, patch_list);
36636 }
36637 
UpdateCommitDataRequest(Chunk chunk,WriterID writer_id,MaybeUnboundBufferID target_buffer,PatchList * patch_list)36638 void SharedMemoryArbiterImpl::UpdateCommitDataRequest(
36639     Chunk chunk,
36640     WriterID writer_id,
36641     MaybeUnboundBufferID target_buffer,
36642     PatchList* patch_list) {
36643   // Note: chunk will be invalid if the call came from SendPatches().
36644   base::TaskRunner* task_runner_to_post_delayed_callback_on = nullptr;
36645   // The delay with which the flush will be posted.
36646   uint32_t flush_delay_ms = 0;
36647   base::WeakPtr<SharedMemoryArbiterImpl> weak_this;
36648   {
36649     std::lock_guard<std::mutex> scoped_lock(lock_);
36650 
36651     if (!commit_data_req_) {
36652       commit_data_req_.reset(new CommitDataRequest());
36653 
36654       // Flushing the commit is only supported while we're |fully_bound_|. If we
36655       // aren't, we'll flush when |fully_bound_| is updated.
36656       if (fully_bound_ && !delayed_flush_scheduled_) {
36657         weak_this = weak_ptr_factory_.GetWeakPtr();
36658         task_runner_to_post_delayed_callback_on = task_runner_;
36659         flush_delay_ms = batch_commits_duration_ms_;
36660         delayed_flush_scheduled_ = true;
36661       }
36662     }
36663 
36664     // If a valid chunk is specified, return it and attach it to the request.
36665     if (chunk.is_valid()) {
36666       PERFETTO_DCHECK(chunk.writer_id() == writer_id);
36667       uint8_t chunk_idx = chunk.chunk_idx();
36668       bytes_pending_commit_ += chunk.size();
36669       size_t page_idx;
36670       // If the chunk needs patching, it should not be marked as complete yet,
36671       // because this would indicate to the service that the producer will not
36672       // be writing to it anymore, while the producer might still apply patches
36673       // to the chunk later on. In particular, when re-reading (e.g. because of
36674       // periodic scraping) a completed chunk, the service expects the flags of
36675       // that chunk not to be removed between reads. So, let's say the producer
36676       // marked the chunk as complete here and the service then read it for the
36677       // first time. If the producer then fully patched the chunk, thus removing
36678       // the kChunkNeedsPatching flag, and the service re-read the chunk after
36679       // the patching, the service would be thrown off by the removed flag.
36680       if (direct_patching_enabled_ &&
36681           (chunk.GetPacketCountAndFlags().second &
36682            SharedMemoryABI::ChunkHeader::kChunkNeedsPatching)) {
36683         page_idx = shmem_abi_.GetPageAndChunkIndex(std::move(chunk)).first;
36684       } else {
36685         // If the chunk doesn't need patching, we can mark it as complete
36686         // immediately. This allows the service to read it in full while
36687         // scraping, which would not be the case if the chunk was left in a
36688         // kChunkBeingWritten state.
36689         page_idx = shmem_abi_.ReleaseChunkAsComplete(std::move(chunk));
36690       }
36691 
36692       // DO NOT access |chunk| after this point, it has been std::move()-d
36693       // above.
36694       CommitDataRequest::ChunksToMove* ctm =
36695           commit_data_req_->add_chunks_to_move();
36696       ctm->set_page(static_cast<uint32_t>(page_idx));
36697       ctm->set_chunk(chunk_idx);
36698       ctm->set_target_buffer(target_buffer);
36699     }
36700 
36701     // Process the completed patches for previous chunks from the |patch_list|.
36702     CommitDataRequest::ChunkToPatch* last_patch_req = nullptr;
36703     while (!patch_list->empty() && patch_list->front().is_patched()) {
36704       Patch curr_patch = patch_list->front();
36705       patch_list->pop_front();
36706       // Patches for the same chunk are contiguous in the |patch_list|. So, to
36707       // determine if there are any other patches that apply to the chunk that
36708       // is being patched, check if the next patch in the |patch_list| applies
36709       // to the same chunk.
36710       bool chunk_needs_more_patching =
36711           !patch_list->empty() &&
36712           patch_list->front().chunk_id == curr_patch.chunk_id;
36713 
36714       if (direct_patching_enabled_ &&
36715           TryDirectPatchLocked(writer_id, curr_patch,
36716                                chunk_needs_more_patching)) {
36717         continue;
36718       }
36719 
36720       // The chunk that this patch applies to has already been released to the
36721       // service, so it cannot be patches here. Add the patch to the commit data
36722       // request, so that it can be sent to the service and applied there.
36723       if (!last_patch_req ||
36724           last_patch_req->chunk_id() != curr_patch.chunk_id) {
36725         last_patch_req = commit_data_req_->add_chunks_to_patch();
36726         last_patch_req->set_writer_id(writer_id);
36727         last_patch_req->set_chunk_id(curr_patch.chunk_id);
36728         last_patch_req->set_target_buffer(target_buffer);
36729       }
36730       auto* patch = last_patch_req->add_patches();
36731       patch->set_offset(curr_patch.offset);
36732       patch->set_data(&curr_patch.size_field[0], curr_patch.size_field.size());
36733     }
36734 
36735     // Patches are enqueued in the |patch_list| in order and are notified to
36736     // the service when the chunk is returned. The only case when the current
36737     // patch list is incomplete is if there is an unpatched entry at the head of
36738     // the |patch_list| that belongs to the same ChunkID as the last one we are
36739     // about to send to the service.
36740     if (last_patch_req && !patch_list->empty() &&
36741         patch_list->front().chunk_id == last_patch_req->chunk_id()) {
36742       last_patch_req->set_has_more_patches(true);
36743     }
36744 
36745     // If the buffer is filling up or if we are given a patch for a chunk
36746     // that was already sent to the service, we don't want to wait for the next
36747     // delayed flush to happen and we flush immediately. Otherwise, if we
36748     // accumulate the patch and a crash occurs before the patch is sent, the
36749     // service will not know of the patch and won't be able to reconstruct the
36750     // trace.
36751     if (fully_bound_ &&
36752         (last_patch_req || bytes_pending_commit_ >= shmem_abi_.size() / 2)) {
36753       weak_this = weak_ptr_factory_.GetWeakPtr();
36754       task_runner_to_post_delayed_callback_on = task_runner_;
36755       flush_delay_ms = 0;
36756     }
36757   }  // scoped_lock(lock_)
36758 
36759   // We shouldn't post tasks while locked.
36760   // |task_runner_to_post_delayed_callback_on| remains valid after unlocking,
36761   // because |task_runner_| is never reset.
36762   if (task_runner_to_post_delayed_callback_on) {
36763     task_runner_to_post_delayed_callback_on->PostDelayedTask(
36764         [weak_this] {
36765           if (!weak_this)
36766             return;
36767           {
36768             std::lock_guard<std::mutex> scoped_lock(weak_this->lock_);
36769             // Clear |delayed_flush_scheduled_|, allowing the next call to
36770             // UpdateCommitDataRequest to start another batching period.
36771             weak_this->delayed_flush_scheduled_ = false;
36772           }
36773           weak_this->FlushPendingCommitDataRequests();
36774         },
36775         flush_delay_ms);
36776   }
36777 }
36778 
TryDirectPatchLocked(WriterID writer_id,const Patch & patch,bool chunk_needs_more_patching)36779 bool SharedMemoryArbiterImpl::TryDirectPatchLocked(
36780     WriterID writer_id,
36781     const Patch& patch,
36782     bool chunk_needs_more_patching) {
36783   // Search the chunks that are being batched in |commit_data_req_| for a chunk
36784   // that needs patching and that matches the provided |writer_id| and
36785   // |patch.chunk_id|. Iterate |commit_data_req_| in reverse, since
36786   // |commit_data_req_| is appended to at the end with newly-returned chunks,
36787   // and patches are more likely to apply to chunks that have been returned
36788   // recently.
36789   SharedMemoryABI::Chunk chunk;
36790   bool chunk_found = false;
36791   auto& chunks_to_move = commit_data_req_->chunks_to_move();
36792   for (auto ctm_it = chunks_to_move.rbegin(); ctm_it != chunks_to_move.rend();
36793        ++ctm_it) {
36794     uint32_t layout = shmem_abi_.GetPageLayout(ctm_it->page());
36795     auto chunk_state =
36796         shmem_abi_.GetChunkStateFromLayout(layout, ctm_it->chunk());
36797     // Note: the subset of |commit_data_req_| chunks that still need patching is
36798     // also the subset of chunks that are still being written to. The rest of
36799     // the chunks in |commit_data_req_| do not need patching and have already
36800     // been marked as complete.
36801     if (chunk_state != SharedMemoryABI::kChunkBeingWritten)
36802       continue;
36803 
36804     chunk =
36805         shmem_abi_.GetChunkUnchecked(ctm_it->page(), layout, ctm_it->chunk());
36806     if (chunk.writer_id() == writer_id &&
36807         chunk.header()->chunk_id.load(std::memory_order_relaxed) ==
36808             patch.chunk_id) {
36809       chunk_found = true;
36810       break;
36811     }
36812   }
36813 
36814   if (!chunk_found) {
36815     // The chunk has already been committed to the service and the patch cannot
36816     // be applied in the producer.
36817     return false;
36818   }
36819 
36820   // Apply the patch.
36821   size_t page_idx;
36822   uint8_t chunk_idx;
36823   std::tie(page_idx, chunk_idx) = shmem_abi_.GetPageAndChunkIndex(chunk);
36824   PERFETTO_DCHECK(shmem_abi_.GetChunkState(page_idx, chunk_idx) ==
36825                   SharedMemoryABI::ChunkState::kChunkBeingWritten);
36826   auto chunk_begin = chunk.payload_begin();
36827   uint8_t* ptr = chunk_begin + patch.offset;
36828   PERFETTO_CHECK(ptr <= chunk.end() - SharedMemoryABI::kPacketHeaderSize);
36829   // DCHECK that we are writing into a zero-filled size field and not into
36830   // valid data. It relies on ScatteredStreamWriter::ReserveBytes() to
36831   // zero-fill reservations in debug builds.
36832   const char zero[SharedMemoryABI::kPacketHeaderSize]{};
36833   PERFETTO_DCHECK(memcmp(ptr, &zero, SharedMemoryABI::kPacketHeaderSize) == 0);
36834 
36835   memcpy(ptr, &patch.size_field[0], SharedMemoryABI::kPacketHeaderSize);
36836 
36837   if (!chunk_needs_more_patching) {
36838     // Mark that the chunk doesn't need more patching and mark it as complete,
36839     // as the producer will not write to it anymore. This allows the service to
36840     // read the chunk in full while scraping, which would not be the case if the
36841     // chunk was left in a kChunkBeingWritten state.
36842     chunk.ClearNeedsPatchingFlag();
36843     shmem_abi_.ReleaseChunkAsComplete(std::move(chunk));
36844   }
36845 
36846   return true;
36847 }
36848 
SetBatchCommitsDuration(uint32_t batch_commits_duration_ms)36849 void SharedMemoryArbiterImpl::SetBatchCommitsDuration(
36850     uint32_t batch_commits_duration_ms) {
36851   std::lock_guard<std::mutex> scoped_lock(lock_);
36852   batch_commits_duration_ms_ = batch_commits_duration_ms;
36853 }
36854 
EnableDirectSMBPatching()36855 bool SharedMemoryArbiterImpl::EnableDirectSMBPatching() {
36856   std::lock_guard<std::mutex> scoped_lock(lock_);
36857   if (!direct_patching_supported_by_service_) {
36858     return false;
36859   }
36860 
36861   return direct_patching_enabled_ = true;
36862 }
36863 
SetDirectSMBPatchingSupportedByService()36864 void SharedMemoryArbiterImpl::SetDirectSMBPatchingSupportedByService() {
36865   std::lock_guard<std::mutex> scoped_lock(lock_);
36866   direct_patching_supported_by_service_ = true;
36867 }
36868 
36869 // This function is quite subtle. When making changes keep in mind these two
36870 // challenges:
36871 // 1) If the producer stalls and we happen to be on the |task_runner_| IPC
36872 //    thread (or, for in-process cases, on the same thread where
36873 //    TracingServiceImpl lives), the CommitData() call must be synchronous and
36874 //    not posted, to avoid deadlocks.
36875 // 2) When different threads hit this function, we must guarantee that we don't
36876 //    accidentally make commits out of order. See commit 4e4fe8f56ef and
36877 //    crbug.com/919187 for more context.
FlushPendingCommitDataRequests(std::function<void ()> callback)36878 void SharedMemoryArbiterImpl::FlushPendingCommitDataRequests(
36879     std::function<void()> callback) {
36880   std::unique_ptr<CommitDataRequest> req;
36881   {
36882     std::unique_lock<std::mutex> scoped_lock(lock_);
36883 
36884     // Flushing is only supported while |fully_bound_|, and there may still be
36885     // unbound startup trace writers. If so, skip the commit for now - it'll be
36886     // done when |fully_bound_| is updated.
36887     if (!fully_bound_) {
36888       if (callback)
36889         pending_flush_callbacks_.push_back(callback);
36890       return;
36891     }
36892 
36893     // May be called by TraceWriterImpl on any thread.
36894     base::TaskRunner* task_runner = task_runner_;
36895     if (!task_runner->RunsTasksOnCurrentThread()) {
36896       // We shouldn't post a task while holding a lock. |task_runner| remains
36897       // valid after unlocking, because |task_runner_| is never reset.
36898       scoped_lock.unlock();
36899 
36900       auto weak_this = weak_ptr_factory_.GetWeakPtr();
36901       task_runner->PostTask([weak_this, callback] {
36902         if (weak_this)
36903           weak_this->FlushPendingCommitDataRequests(std::move(callback));
36904       });
36905       return;
36906     }
36907 
36908     // |commit_data_req_| could have become a nullptr, for example when a forced
36909     // sync flush happens in GetNewChunk().
36910     if (commit_data_req_) {
36911       // Make sure any placeholder buffer IDs from StartupWriters are replaced
36912       // before sending the request.
36913       bool all_placeholders_replaced =
36914           ReplaceCommitPlaceholderBufferIdsLocked();
36915       // We're |fully_bound_|, thus all writers are bound and all placeholders
36916       // should have been replaced.
36917       PERFETTO_DCHECK(all_placeholders_replaced);
36918 
36919       // In order to allow patching in the producer we delay the kChunkComplete
36920       // transition and keep batched chunks in the kChunkBeingWritten state.
36921       // Since we are about to notify the service of all batched chunks, it will
36922       // not be possible to apply any more patches to them and we need to move
36923       // them to kChunkComplete - otherwise the service won't look at them.
36924       for (auto& ctm : commit_data_req_->chunks_to_move()) {
36925         uint32_t layout = shmem_abi_.GetPageLayout(ctm.page());
36926         auto chunk_state =
36927             shmem_abi_.GetChunkStateFromLayout(layout, ctm.chunk());
36928         // Note: the subset of |commit_data_req_| chunks that still need
36929         // patching is also the subset of chunks that are still being written
36930         // to. The rest of the chunks in |commit_data_req_| do not need patching
36931         // and have already been marked as complete.
36932         if (chunk_state != SharedMemoryABI::kChunkBeingWritten)
36933           continue;
36934 
36935         SharedMemoryABI::Chunk chunk =
36936             shmem_abi_.GetChunkUnchecked(ctm.page(), layout, ctm.chunk());
36937         shmem_abi_.ReleaseChunkAsComplete(std::move(chunk));
36938       }
36939 
36940       req = std::move(commit_data_req_);
36941       bytes_pending_commit_ = 0;
36942     }
36943   }  // scoped_lock
36944 
36945   if (req) {
36946     producer_endpoint_->CommitData(*req, callback);
36947   } else if (callback) {
36948     // If |req| was nullptr, it means that an enqueued deferred commit was
36949     // executed just before this. At this point send an empty commit request
36950     // to the service, just to linearize with it and give the guarantee to the
36951     // caller that the data has been flushed into the service.
36952     producer_endpoint_->CommitData(CommitDataRequest(), std::move(callback));
36953   }
36954 }
36955 
TryShutdown()36956 bool SharedMemoryArbiterImpl::TryShutdown() {
36957   std::lock_guard<std::mutex> scoped_lock(lock_);
36958   did_shutdown_ = true;
36959   // Shutdown is safe if there are no active trace writers for this arbiter.
36960   return active_writer_ids_.IsEmpty();
36961 }
36962 
CreateTraceWriter(BufferID target_buffer,BufferExhaustedPolicy buffer_exhausted_policy)36963 std::unique_ptr<TraceWriter> SharedMemoryArbiterImpl::CreateTraceWriter(
36964     BufferID target_buffer,
36965     BufferExhaustedPolicy buffer_exhausted_policy) {
36966   PERFETTO_CHECK(target_buffer > 0);
36967   return CreateTraceWriterInternal(target_buffer, buffer_exhausted_policy);
36968 }
36969 
CreateStartupTraceWriter(uint16_t target_buffer_reservation_id)36970 std::unique_ptr<TraceWriter> SharedMemoryArbiterImpl::CreateStartupTraceWriter(
36971     uint16_t target_buffer_reservation_id) {
36972   PERFETTO_CHECK(!initially_bound_);
36973   return CreateTraceWriterInternal(
36974       MakeTargetBufferIdForReservation(target_buffer_reservation_id),
36975       BufferExhaustedPolicy::kDrop);
36976 }
36977 
BindToProducerEndpoint(TracingService::ProducerEndpoint * producer_endpoint,base::TaskRunner * task_runner)36978 void SharedMemoryArbiterImpl::BindToProducerEndpoint(
36979     TracingService::ProducerEndpoint* producer_endpoint,
36980     base::TaskRunner* task_runner) {
36981   PERFETTO_DCHECK(producer_endpoint && task_runner);
36982   PERFETTO_DCHECK(task_runner->RunsTasksOnCurrentThread());
36983   PERFETTO_CHECK(!initially_bound_);
36984 
36985   bool should_flush = false;
36986   std::function<void()> flush_callback;
36987   {
36988     std::lock_guard<std::mutex> scoped_lock(lock_);
36989     PERFETTO_CHECK(!fully_bound_);
36990     PERFETTO_CHECK(!producer_endpoint_ && !task_runner_);
36991 
36992     producer_endpoint_ = producer_endpoint;
36993     task_runner_ = task_runner;
36994 
36995     // Now that we're bound to a task runner, also reset the WeakPtrFactory to
36996     // it. Because this code runs on the task runner, the factory's weak
36997     // pointers will be valid on it.
36998     weak_ptr_factory_.Reset(this);
36999 
37000     // All writers registered so far should be startup trace writers, since
37001     // the producer cannot feasibly know the target buffer for any future
37002     // session yet.
37003     for (const auto& entry : pending_writers_) {
37004       PERFETTO_CHECK(IsReservationTargetBufferId(entry.second));
37005     }
37006 
37007     // If all buffer reservations are bound, we can flush pending commits.
37008     if (UpdateFullyBoundLocked()) {
37009       should_flush = true;
37010       flush_callback = TakePendingFlushCallbacksLocked();
37011     }
37012   }  // scoped_lock
37013 
37014   // Attempt to flush any pending commits (and run pending flush callbacks). If
37015   // there are none, this will have no effect. If we ended up in a race that
37016   // changed |fully_bound_| back to false, the commit will happen once we become
37017   // |fully_bound_| again.
37018   if (should_flush)
37019     FlushPendingCommitDataRequests(flush_callback);
37020 }
37021 
BindStartupTargetBuffer(uint16_t target_buffer_reservation_id,BufferID target_buffer_id)37022 void SharedMemoryArbiterImpl::BindStartupTargetBuffer(
37023     uint16_t target_buffer_reservation_id,
37024     BufferID target_buffer_id) {
37025   PERFETTO_DCHECK(target_buffer_id > 0);
37026   PERFETTO_CHECK(!initially_bound_);
37027 
37028   std::unique_lock<std::mutex> scoped_lock(lock_);
37029 
37030   // We should already be bound to an endpoint, but not fully bound.
37031   PERFETTO_CHECK(!fully_bound_);
37032   PERFETTO_CHECK(producer_endpoint_);
37033   PERFETTO_CHECK(task_runner_);
37034   PERFETTO_CHECK(task_runner_->RunsTasksOnCurrentThread());
37035 
37036   BindStartupTargetBufferImpl(std::move(scoped_lock),
37037                               target_buffer_reservation_id, target_buffer_id);
37038 }
37039 
AbortStartupTracingForReservation(uint16_t target_buffer_reservation_id)37040 void SharedMemoryArbiterImpl::AbortStartupTracingForReservation(
37041     uint16_t target_buffer_reservation_id) {
37042   PERFETTO_CHECK(!initially_bound_);
37043 
37044   std::unique_lock<std::mutex> scoped_lock(lock_);
37045 
37046   // If we are already bound to an arbiter, we may need to flush after aborting
37047   // the session, and thus should be running on the arbiter's task runner.
37048   if (task_runner_ && !task_runner_->RunsTasksOnCurrentThread()) {
37049     // We shouldn't post tasks while locked.
37050     auto* task_runner = task_runner_;
37051     scoped_lock.unlock();
37052 
37053     auto weak_this = weak_ptr_factory_.GetWeakPtr();
37054     task_runner->PostTask([weak_this, target_buffer_reservation_id]() {
37055       if (!weak_this)
37056         return;
37057       weak_this->AbortStartupTracingForReservation(
37058           target_buffer_reservation_id);
37059     });
37060     return;
37061   }
37062 
37063   PERFETTO_CHECK(!fully_bound_);
37064 
37065   // Bind the target buffer reservation to an invalid buffer (ID 0), so that
37066   // existing commits, as well as future commits (of currently acquired chunks),
37067   // will be released as free free by the service but otherwise ignored (i.e.
37068   // not copied into any valid target buffer).
37069   BindStartupTargetBufferImpl(std::move(scoped_lock),
37070                               target_buffer_reservation_id,
37071                               /*target_buffer_id=*/kInvalidBufferId);
37072 }
37073 
BindStartupTargetBufferImpl(std::unique_lock<std::mutex> scoped_lock,uint16_t target_buffer_reservation_id,BufferID target_buffer_id)37074 void SharedMemoryArbiterImpl::BindStartupTargetBufferImpl(
37075     std::unique_lock<std::mutex> scoped_lock,
37076     uint16_t target_buffer_reservation_id,
37077     BufferID target_buffer_id) {
37078   // We should already be bound to an endpoint if the target buffer is valid.
37079   PERFETTO_DCHECK((producer_endpoint_ && task_runner_) ||
37080                   target_buffer_id == kInvalidBufferId);
37081 
37082   MaybeUnboundBufferID reserved_id =
37083       MakeTargetBufferIdForReservation(target_buffer_reservation_id);
37084 
37085   bool should_flush = false;
37086   std::function<void()> flush_callback;
37087   std::vector<std::pair<WriterID, BufferID>> writers_to_register;
37088 
37089   TargetBufferReservation& reservation =
37090       target_buffer_reservations_[reserved_id];
37091   PERFETTO_CHECK(!reservation.resolved);
37092   reservation.resolved = true;
37093   reservation.target_buffer = target_buffer_id;
37094 
37095   // Collect trace writers associated with the reservation.
37096   for (auto it = pending_writers_.begin(); it != pending_writers_.end();) {
37097     if (it->second == reserved_id) {
37098       // No need to register writers that have an invalid target buffer.
37099       if (target_buffer_id != kInvalidBufferId) {
37100         writers_to_register.push_back(
37101             std::make_pair(it->first, target_buffer_id));
37102       }
37103       it = pending_writers_.erase(it);
37104     } else {
37105       it++;
37106     }
37107   }
37108 
37109   // If all buffer reservations are bound, we can flush pending commits.
37110   if (UpdateFullyBoundLocked()) {
37111     should_flush = true;
37112     flush_callback = TakePendingFlushCallbacksLocked();
37113   }
37114 
37115   scoped_lock.unlock();
37116 
37117   // Register any newly bound trace writers with the service.
37118   for (const auto& writer_and_target_buffer : writers_to_register) {
37119     producer_endpoint_->RegisterTraceWriter(writer_and_target_buffer.first,
37120                                             writer_and_target_buffer.second);
37121   }
37122 
37123   // Attempt to flush any pending commits (and run pending flush callbacks). If
37124   // there are none, this will have no effect. If we ended up in a race that
37125   // changed |fully_bound_| back to false, the commit will happen once we become
37126   // |fully_bound_| again.
37127   if (should_flush)
37128     FlushPendingCommitDataRequests(flush_callback);
37129 }
37130 
37131 std::function<void()>
TakePendingFlushCallbacksLocked()37132 SharedMemoryArbiterImpl::TakePendingFlushCallbacksLocked() {
37133   if (pending_flush_callbacks_.empty())
37134     return std::function<void()>();
37135 
37136   std::vector<std::function<void()>> pending_flush_callbacks;
37137   pending_flush_callbacks.swap(pending_flush_callbacks_);
37138   // Capture the callback list into the lambda by copy.
37139   return [pending_flush_callbacks]() {
37140     for (auto& callback : pending_flush_callbacks)
37141       callback();
37142   };
37143 }
37144 
NotifyFlushComplete(FlushRequestID req_id)37145 void SharedMemoryArbiterImpl::NotifyFlushComplete(FlushRequestID req_id) {
37146   base::TaskRunner* task_runner_to_commit_on = nullptr;
37147 
37148   {
37149     std::lock_guard<std::mutex> scoped_lock(lock_);
37150     // If a commit_data_req_ exists it means that somebody else already posted a
37151     // FlushPendingCommitDataRequests() task.
37152     if (!commit_data_req_) {
37153       commit_data_req_.reset(new CommitDataRequest());
37154 
37155       // Flushing the commit is only supported while we're |fully_bound_|. If we
37156       // aren't, we'll flush when |fully_bound_| is updated.
37157       if (fully_bound_)
37158         task_runner_to_commit_on = task_runner_;
37159     } else {
37160       // If there is another request queued and that also contains is a reply
37161       // to a flush request, reply with the highest id.
37162       req_id = std::max(req_id, commit_data_req_->flush_request_id());
37163     }
37164     commit_data_req_->set_flush_request_id(req_id);
37165   }  // scoped_lock
37166 
37167   // We shouldn't post tasks while locked. |task_runner_to_commit_on|
37168   // remains valid after unlocking, because |task_runner_| is never reset.
37169   if (task_runner_to_commit_on) {
37170     auto weak_this = weak_ptr_factory_.GetWeakPtr();
37171     task_runner_to_commit_on->PostTask([weak_this] {
37172       if (weak_this)
37173         weak_this->FlushPendingCommitDataRequests();
37174     });
37175   }
37176 }
37177 
CreateTraceWriterInternal(MaybeUnboundBufferID target_buffer,BufferExhaustedPolicy buffer_exhausted_policy)37178 std::unique_ptr<TraceWriter> SharedMemoryArbiterImpl::CreateTraceWriterInternal(
37179     MaybeUnboundBufferID target_buffer,
37180     BufferExhaustedPolicy buffer_exhausted_policy) {
37181   WriterID id;
37182   base::TaskRunner* task_runner_to_register_on = nullptr;
37183 
37184   {
37185     std::lock_guard<std::mutex> scoped_lock(lock_);
37186     if (did_shutdown_)
37187       return std::unique_ptr<TraceWriter>(new NullTraceWriter());
37188 
37189     id = active_writer_ids_.Allocate();
37190     if (!id)
37191       return std::unique_ptr<TraceWriter>(new NullTraceWriter());
37192 
37193     PERFETTO_DCHECK(!pending_writers_.count(id));
37194 
37195     if (IsReservationTargetBufferId(target_buffer)) {
37196       // If the reservation is new, mark it as unbound in
37197       // |target_buffer_reservations_|. Otherwise, if the reservation was
37198       // already bound, choose the bound buffer ID now.
37199       auto it_and_inserted = target_buffer_reservations_.insert(
37200           {target_buffer, TargetBufferReservation()});
37201       if (it_and_inserted.first->second.resolved)
37202         target_buffer = it_and_inserted.first->second.target_buffer;
37203     }
37204 
37205     if (IsReservationTargetBufferId(target_buffer)) {
37206       // The arbiter and/or startup buffer reservations are not bound yet, so
37207       // buffer the registration of the writer until after we're bound.
37208       pending_writers_[id] = target_buffer;
37209 
37210       // Mark the arbiter as not fully bound, since we now have at least one
37211       // unbound trace writer / target buffer reservation.
37212       fully_bound_ = false;
37213     } else if (target_buffer != kInvalidBufferId) {
37214       // Trace writer is bound, so arbiter should be bound to an endpoint, too.
37215       PERFETTO_CHECK(producer_endpoint_ && task_runner_);
37216       task_runner_to_register_on = task_runner_;
37217     }
37218   }  // scoped_lock
37219 
37220   // We shouldn't post tasks while locked. |task_runner_to_register_on|
37221   // remains valid after unlocking, because |task_runner_| is never reset.
37222   if (task_runner_to_register_on) {
37223     auto weak_this = weak_ptr_factory_.GetWeakPtr();
37224     task_runner_to_register_on->PostTask([weak_this, id, target_buffer] {
37225       if (weak_this)
37226         weak_this->producer_endpoint_->RegisterTraceWriter(id, target_buffer);
37227     });
37228   }
37229 
37230   return std::unique_ptr<TraceWriter>(
37231       new TraceWriterImpl(this, id, target_buffer, buffer_exhausted_policy));
37232 }
37233 
ReleaseWriterID(WriterID id)37234 void SharedMemoryArbiterImpl::ReleaseWriterID(WriterID id) {
37235   base::TaskRunner* task_runner = nullptr;
37236   {
37237     std::lock_guard<std::mutex> scoped_lock(lock_);
37238     active_writer_ids_.Free(id);
37239 
37240     auto it = pending_writers_.find(id);
37241     if (it != pending_writers_.end()) {
37242       // Writer hasn't been bound yet and thus also not yet registered with the
37243       // service.
37244       pending_writers_.erase(it);
37245       return;
37246     }
37247 
37248     // A trace writer from an aborted session may be destroyed before the
37249     // arbiter is bound to a task runner. In that case, it was never registered
37250     // with the service.
37251     if (!task_runner_)
37252       return;
37253 
37254     task_runner = task_runner_;
37255   }  // scoped_lock
37256 
37257   // We shouldn't post tasks while locked. |task_runner| remains valid after
37258   // unlocking, because |task_runner_| is never reset.
37259   auto weak_this = weak_ptr_factory_.GetWeakPtr();
37260   task_runner->PostTask([weak_this, id] {
37261     if (weak_this)
37262       weak_this->producer_endpoint_->UnregisterTraceWriter(id);
37263   });
37264 }
37265 
ReplaceCommitPlaceholderBufferIdsLocked()37266 bool SharedMemoryArbiterImpl::ReplaceCommitPlaceholderBufferIdsLocked() {
37267   if (!commit_data_req_)
37268     return true;
37269 
37270   bool all_placeholders_replaced = true;
37271   for (auto& chunk : *commit_data_req_->mutable_chunks_to_move()) {
37272     if (!IsReservationTargetBufferId(chunk.target_buffer()))
37273       continue;
37274     const auto it = target_buffer_reservations_.find(chunk.target_buffer());
37275     PERFETTO_DCHECK(it != target_buffer_reservations_.end());
37276     if (!it->second.resolved) {
37277       all_placeholders_replaced = false;
37278       continue;
37279     }
37280     chunk.set_target_buffer(it->second.target_buffer);
37281   }
37282   for (auto& chunk : *commit_data_req_->mutable_chunks_to_patch()) {
37283     if (!IsReservationTargetBufferId(chunk.target_buffer()))
37284       continue;
37285     const auto it = target_buffer_reservations_.find(chunk.target_buffer());
37286     PERFETTO_DCHECK(it != target_buffer_reservations_.end());
37287     if (!it->second.resolved) {
37288       all_placeholders_replaced = false;
37289       continue;
37290     }
37291     chunk.set_target_buffer(it->second.target_buffer);
37292   }
37293   return all_placeholders_replaced;
37294 }
37295 
UpdateFullyBoundLocked()37296 bool SharedMemoryArbiterImpl::UpdateFullyBoundLocked() {
37297   if (!producer_endpoint_) {
37298     PERFETTO_DCHECK(!fully_bound_);
37299     return false;
37300   }
37301   // We're fully bound if all target buffer reservations have a valid associated
37302   // BufferID.
37303   fully_bound_ = std::none_of(
37304       target_buffer_reservations_.begin(), target_buffer_reservations_.end(),
37305       [](std::pair<MaybeUnboundBufferID, TargetBufferReservation> entry) {
37306         return !entry.second.resolved;
37307       });
37308   return fully_bound_;
37309 }
37310 
37311 }  // namespace perfetto
37312 // gen_amalgamated begin source: src/tracing/core/trace_packet.cc
37313 // gen_amalgamated begin header: include/perfetto/ext/tracing/core/trace_packet.h
37314 // gen_amalgamated begin header: include/perfetto/ext/tracing/core/slice.h
37315 /*
37316  * Copyright (C) 2017 The Android Open Source Project
37317  *
37318  * Licensed under the Apache License, Version 2.0 (the "License");
37319  * you may not use this file except in compliance with the License.
37320  * You may obtain a copy of the License at
37321  *
37322  *      http://www.apache.org/licenses/LICENSE-2.0
37323  *
37324  * Unless required by applicable law or agreed to in writing, software
37325  * distributed under the License is distributed on an "AS IS" BASIS,
37326  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
37327  * See the License for the specific language governing permissions and
37328  * limitations under the License.
37329  */
37330 
37331 #ifndef INCLUDE_PERFETTO_EXT_TRACING_CORE_SLICE_H_
37332 #define INCLUDE_PERFETTO_EXT_TRACING_CORE_SLICE_H_
37333 
37334 #include <stddef.h>
37335 #include <string.h>
37336 
37337 #include <memory>
37338 #include <string>
37339 #include <vector>
37340 
37341 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
37342 
37343 namespace perfetto {
37344 
37345 // A simple wrapper around a virtually contiguous memory range that contains a
37346 // TracePacket, or just a portion of it.
37347 struct Slice {
Sliceperfetto::Slice37348   Slice() : start(nullptr), size(0) {}
Sliceperfetto::Slice37349   Slice(const void* st, size_t sz) : start(st), size(sz) {}
37350   Slice(Slice&& other) noexcept = default;
37351 
37352   // Create a Slice which owns |size| bytes of memory.
Allocateperfetto::Slice37353   static Slice Allocate(size_t size) {
37354     Slice slice;
37355     slice.own_data_.reset(new uint8_t[size]);
37356     slice.start = &slice.own_data_[0];
37357     slice.size = size;
37358     return slice;
37359   }
37360 
TakeOwnershipperfetto::Slice37361   static Slice TakeOwnership(std::unique_ptr<uint8_t[]> buf, size_t size) {
37362     Slice slice;
37363     slice.own_data_ = std::move(buf);
37364     slice.start = &slice.own_data_[0];
37365     slice.size = size;
37366     return slice;
37367   }
37368 
own_dataperfetto::Slice37369   uint8_t* own_data() {
37370     PERFETTO_DCHECK(own_data_);
37371     return own_data_.get();
37372   }
37373 
37374   const void* start;
37375   size_t size;
37376 
37377  private:
37378   Slice(const Slice&) = delete;
37379   void operator=(const Slice&) = delete;
37380 
37381   std::unique_ptr<uint8_t[]> own_data_;
37382 };
37383 
37384 // TODO(primiano): most TracePacket(s) fit in a slice or two. We need something
37385 // a bit more clever here that has inline capacity for 2 slices and then uses a
37386 // std::forward_list or a std::vector for the less likely cases.
37387 using Slices = std::vector<Slice>;
37388 
37389 }  // namespace perfetto
37390 
37391 #endif  // INCLUDE_PERFETTO_EXT_TRACING_CORE_SLICE_H_
37392 /*
37393  * Copyright (C) 2017 The Android Open Source Project
37394  *
37395  * Licensed under the Apache License, Version 2.0 (the "License");
37396  * you may not use this file except in compliance with the License.
37397  * You may obtain a copy of the License at
37398  *
37399  *      http://www.apache.org/licenses/LICENSE-2.0
37400  *
37401  * Unless required by applicable law or agreed to in writing, software
37402  * distributed under the License is distributed on an "AS IS" BASIS,
37403  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
37404  * See the License for the specific language governing permissions and
37405  * limitations under the License.
37406  */
37407 
37408 #ifndef INCLUDE_PERFETTO_EXT_TRACING_CORE_TRACE_PACKET_H_
37409 #define INCLUDE_PERFETTO_EXT_TRACING_CORE_TRACE_PACKET_H_
37410 
37411 #include <stddef.h>
37412 #include <memory>
37413 #include <tuple>
37414 
37415 // gen_amalgamated expanded: #include "perfetto/base/export.h"
37416 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
37417 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/slice.h"
37418 
37419 namespace perfetto {
37420 
37421 // A wrapper around a byte buffer that contains a protobuf-encoded TracePacket
37422 // (see trace_packet.proto). The TracePacket is decoded only if the Consumer
37423 // requests that. This is to allow Consumer(s) to just stream the packet over
37424 // the network or save it to a file without wasting time decoding it and without
37425 // needing to depend on libprotobuf or the trace_packet.pb.h header.
37426 // If the packets are saved / streamed and not just consumed locally, consumers
37427 // should ensure to preserve the unknown fields in the proto. A consumer, in
37428 // fact, might have an older version .proto which is newer on the producer.
37429 class PERFETTO_EXPORT TracePacket {
37430  public:
37431   using const_iterator = Slices::const_iterator;
37432 
37433   // The field id of protos::Trace::packet, static_assert()-ed in the unittest.
37434   static constexpr uint32_t kPacketFieldNumber = 1;
37435 
37436   // Maximum size of the preamble returned by GetProtoPreamble().
37437   static constexpr size_t kMaxPreambleBytes = 8;
37438 
37439   TracePacket();
37440   ~TracePacket();
37441   TracePacket(TracePacket&&) noexcept;
37442   TracePacket& operator=(TracePacket&&);
37443 
37444   // Accesses all the raw slices in the packet, for saving them to file/network.
slices() const37445   const Slices& slices() const { return slices_; }
37446 
37447   // Mutator, used only by the service and tests.
37448   void AddSlice(Slice);
37449 
37450   // Does not copy / take ownership of the memory of the slice. The TracePacket
37451   // will be valid only as long as the original buffer is valid.
37452   void AddSlice(const void* start, size_t size);
37453 
37454   // Total size of all slices.
size() const37455   size_t size() const { return size_; }
37456 
37457   // Generates a protobuf preamble suitable to represent this packet as a
37458   // repeated field within a root trace.proto message.
37459   // Returns a pointer to a buffer, owned by this class, containing the preamble
37460   // and its size.
37461   std::tuple<char*, size_t> GetProtoPreamble();
37462 
37463   // Returns the raw protobuf bytes of the slices, all stitched together into
37464   // a string. Only for testing.
37465   std::string GetRawBytesForTesting();
37466 
37467  private:
37468   TracePacket(const TracePacket&) = delete;
37469   TracePacket& operator=(const TracePacket&) = delete;
37470 
37471   Slices slices_;     // Not owned.
37472   size_t size_ = 0;   // SUM(slice.size for slice in slices_).
37473   char preamble_[kMaxPreambleBytes];  // Deliberately not initialized.
37474 
37475   // Remember to update the move operators and their unittest if adding new
37476   // fields. ConsumerIPCClientImpl::OnReadBuffersResponse() relies on
37477   // std::move(TracePacket) to clear up the moved-from instance.
37478 };
37479 
37480 }  // namespace perfetto
37481 
37482 #endif  // INCLUDE_PERFETTO_EXT_TRACING_CORE_TRACE_PACKET_H_
37483 /*
37484  * Copyright (C) 2017 The Android Open Source Project
37485  *
37486  * Licensed under the Apache License, Version 2.0 (the "License");
37487  * you may not use this file except in compliance with the License.
37488  * You may obtain a copy of the License at
37489  *
37490  *      http://www.apache.org/licenses/LICENSE-2.0
37491  *
37492  * Unless required by applicable law or agreed to in writing, software
37493  * distributed under the License is distributed on an "AS IS" BASIS,
37494  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
37495  * See the License for the specific language governing permissions and
37496  * limitations under the License.
37497  */
37498 
37499 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/trace_packet.h"
37500 
37501 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
37502 // gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
37503 
37504 namespace perfetto {
37505 
37506 TracePacket::TracePacket() = default;
37507 TracePacket::~TracePacket() = default;
37508 
TracePacket(TracePacket && other)37509 TracePacket::TracePacket(TracePacket&& other) noexcept {
37510   *this = std::move(other);
37511 }
37512 
operator =(TracePacket && other)37513 TracePacket& TracePacket::operator=(TracePacket&& other) {
37514   slices_ = std::move(other.slices_);
37515   other.slices_.clear();
37516   size_ = other.size_;
37517   other.size_ = 0;
37518   return *this;
37519 }
37520 
AddSlice(Slice slice)37521 void TracePacket::AddSlice(Slice slice) {
37522   size_ += slice.size;
37523   slices_.push_back(std::move(slice));
37524 }
37525 
AddSlice(const void * start,size_t size)37526 void TracePacket::AddSlice(const void* start, size_t size) {
37527   size_ += size;
37528   slices_.emplace_back(start, size);
37529 }
37530 
GetProtoPreamble()37531 std::tuple<char*, size_t> TracePacket::GetProtoPreamble() {
37532   using protozero::proto_utils::MakeTagLengthDelimited;
37533   using protozero::proto_utils::WriteVarInt;
37534   uint8_t* ptr = reinterpret_cast<uint8_t*>(&preamble_[0]);
37535 
37536   constexpr uint8_t tag = MakeTagLengthDelimited(kPacketFieldNumber);
37537   static_assert(tag < 0x80, "TracePacket tag should fit in one byte");
37538   *(ptr++) = tag;
37539 
37540   ptr = WriteVarInt(size(), ptr);
37541   size_t preamble_size = reinterpret_cast<uintptr_t>(ptr) -
37542                          reinterpret_cast<uintptr_t>(&preamble_[0]);
37543   PERFETTO_DCHECK(preamble_size <= sizeof(preamble_));
37544   return std::make_tuple(&preamble_[0], preamble_size);
37545 }
37546 
GetRawBytesForTesting()37547 std::string TracePacket::GetRawBytesForTesting() {
37548   std::string data;
37549   data.resize(size());
37550   size_t pos = 0;
37551   for (const Slice& slice : slices()) {
37552     PERFETTO_CHECK(pos + slice.size <= data.size());
37553     memcpy(&data[pos], slice.start, slice.size);
37554     pos += slice.size;
37555   }
37556   return data;
37557 }
37558 
37559 }  // namespace perfetto
37560 // gen_amalgamated begin source: src/tracing/core/trace_writer_impl.cc
37561 /*
37562  * Copyright (C) 2017 The Android Open Source Project
37563  *
37564  * Licensed under the Apache License, Version 2.0 (the "License");
37565  * you may not use this file except in compliance with the License.
37566  * You may obtain a copy of the License at
37567  *
37568  *      http://www.apache.org/licenses/LICENSE-2.0
37569  *
37570  * Unless required by applicable law or agreed to in writing, software
37571  * distributed under the License is distributed on an "AS IS" BASIS,
37572  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
37573  * See the License for the specific language governing permissions and
37574  * limitations under the License.
37575  */
37576 
37577 // gen_amalgamated expanded: #include "src/tracing/core/trace_writer_impl.h"
37578 
37579 #include <string.h>
37580 
37581 #include <algorithm>
37582 #include <type_traits>
37583 #include <utility>
37584 
37585 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
37586 // gen_amalgamated expanded: #include "perfetto/ext/base/thread_annotations.h"
37587 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
37588 // gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
37589 // gen_amalgamated expanded: #include "perfetto/protozero/root_message.h"
37590 // gen_amalgamated expanded: #include "src/tracing/core/shared_memory_arbiter_impl.h"
37591 
37592 // gen_amalgamated expanded: #include "protos/perfetto/trace/trace_packet.pbzero.h"
37593 
37594 using protozero::proto_utils::kMessageLengthFieldSize;
37595 using protozero::proto_utils::WriteRedundantVarInt;
37596 using ChunkHeader = perfetto::SharedMemoryABI::ChunkHeader;
37597 
37598 namespace perfetto {
37599 
37600 namespace {
37601 constexpr size_t kPacketHeaderSize = SharedMemoryABI::kPacketHeaderSize;
37602 uint8_t g_garbage_chunk[1024];
37603 }  // namespace
37604 
TraceWriterImpl(SharedMemoryArbiterImpl * shmem_arbiter,WriterID id,MaybeUnboundBufferID target_buffer,BufferExhaustedPolicy buffer_exhausted_policy)37605 TraceWriterImpl::TraceWriterImpl(SharedMemoryArbiterImpl* shmem_arbiter,
37606                                  WriterID id,
37607                                  MaybeUnboundBufferID target_buffer,
37608                                  BufferExhaustedPolicy buffer_exhausted_policy)
37609     : shmem_arbiter_(shmem_arbiter),
37610       id_(id),
37611       target_buffer_(target_buffer),
37612       buffer_exhausted_policy_(buffer_exhausted_policy),
37613       protobuf_stream_writer_(this),
37614       process_id_(base::GetProcessId()) {
37615   // TODO(primiano): we could handle the case of running out of TraceWriterID(s)
37616   // more gracefully and always return a no-op TracePacket in NewTracePacket().
37617   PERFETTO_CHECK(id_ != 0);
37618 
37619   cur_packet_.reset(new protozero::RootMessage<protos::pbzero::TracePacket>());
37620   cur_packet_->Finalize();  // To avoid the DCHECK in NewTracePacket().
37621 }
37622 
~TraceWriterImpl()37623 TraceWriterImpl::~TraceWriterImpl() {
37624   if (cur_chunk_.is_valid()) {
37625     cur_packet_->Finalize();
37626     Flush();
37627   }
37628   // This call may cause the shared memory arbiter (and the underlying memory)
37629   // to get asynchronously deleted if this was the last trace writer targeting
37630   // the arbiter and the arbiter was marked for shutdown.
37631   shmem_arbiter_->ReleaseWriterID(id_);
37632 }
37633 
Flush(std::function<void ()> callback)37634 void TraceWriterImpl::Flush(std::function<void()> callback) {
37635   // Flush() cannot be called in the middle of a TracePacket.
37636   PERFETTO_CHECK(cur_packet_->is_finalized());
37637 
37638   if (cur_chunk_.is_valid()) {
37639     shmem_arbiter_->ReturnCompletedChunk(std::move(cur_chunk_), target_buffer_,
37640                                          &patch_list_);
37641   } else {
37642     // When in stall mode, all patches should have been returned with the last
37643     // chunk, since the last packet was completed. In drop_packets_ mode, this
37644     // may not be the case because the packet may have been fragmenting when
37645     // SMB exhaustion occurred and |cur_chunk_| became invalid. In this case,
37646     // drop_packets_ should be true.
37647     PERFETTO_DCHECK(patch_list_.empty() || drop_packets_);
37648   }
37649 
37650   // Always issue the Flush request, even if there is nothing to flush, just
37651   // for the sake of getting the callback posted back.
37652   shmem_arbiter_->FlushPendingCommitDataRequests(callback);
37653   protobuf_stream_writer_.Reset({nullptr, nullptr});
37654 
37655   // |last_packet_size_field_| might have pointed into the chunk we returned.
37656   last_packet_size_field_ = nullptr;
37657 }
37658 
NewTracePacket()37659 TraceWriterImpl::TracePacketHandle TraceWriterImpl::NewTracePacket() {
37660   // If we hit this, the caller is calling NewTracePacket() without having
37661   // finalized the previous packet.
37662   PERFETTO_CHECK(cur_packet_->is_finalized());
37663   // If we hit this, this trace writer was created in a different process. This
37664   // likely means that the process forked while tracing was active, and the
37665   // forked child process tried to emit a trace event. This is not supported, as
37666   // it would lead to two processes writing to the same tracing SMB.
37667   PERFETTO_DCHECK(process_id_ == base::GetProcessId());
37668 
37669   fragmenting_packet_ = false;
37670 
37671   // Reserve space for the size of the message. Note: this call might re-enter
37672   // into this class invoking GetNewBuffer() if there isn't enough space or if
37673   // this is the very first call to NewTracePacket().
37674   static_assert(kPacketHeaderSize == kMessageLengthFieldSize,
37675                 "The packet header must match the Message header size");
37676 
37677   bool was_dropping_packets = drop_packets_;
37678 
37679   // It doesn't make sense to begin a packet that is going to fragment
37680   // immediately after (8 is just an arbitrary estimation on the minimum size of
37681   // a realistic packet).
37682   bool chunk_too_full =
37683       protobuf_stream_writer_.bytes_available() < kPacketHeaderSize + 8;
37684   if (chunk_too_full || reached_max_packets_per_chunk_ ||
37685       retry_new_chunk_after_packet_) {
37686     protobuf_stream_writer_.Reset(GetNewBuffer());
37687   }
37688 
37689   // Send any completed patches to the service to facilitate trace data
37690   // recovery by the service. This should only happen when we're completing
37691   // the first packet in a chunk which was a continuation from the previous
37692   // chunk, i.e. at most once per chunk.
37693   if (!patch_list_.empty() && patch_list_.front().is_patched()) {
37694     shmem_arbiter_->SendPatches(id_, target_buffer_, &patch_list_);
37695   }
37696 
37697   cur_packet_->Reset(&protobuf_stream_writer_);
37698   uint8_t* header = protobuf_stream_writer_.ReserveBytes(kPacketHeaderSize);
37699   memset(header, 0, kPacketHeaderSize);
37700   cur_packet_->set_size_field(header);
37701   last_packet_size_field_ = header;
37702 
37703   TracePacketHandle handle(cur_packet_.get());
37704   cur_fragment_start_ = protobuf_stream_writer_.write_ptr();
37705   fragmenting_packet_ = true;
37706 
37707   if (PERFETTO_LIKELY(!drop_packets_)) {
37708     uint16_t new_packet_count = cur_chunk_.IncrementPacketCount();
37709     reached_max_packets_per_chunk_ =
37710         new_packet_count == ChunkHeader::Packets::kMaxCount;
37711 
37712     if (PERFETTO_UNLIKELY(was_dropping_packets)) {
37713       // We've succeeded to get a new chunk from the SMB after we entered
37714       // drop_packets_ mode. Record a marker into the new packet to indicate the
37715       // data loss.
37716       cur_packet_->set_previous_packet_dropped(true);
37717     }
37718   }
37719 
37720   return handle;
37721 }
37722 
37723 // Called by the Message. We can get here in two cases:
37724 // 1. In the middle of writing a Message,
37725 // when |fragmenting_packet_| == true. In this case we want to update the
37726 // chunk header with a partial packet and start a new partial packet in the
37727 // new chunk.
37728 // 2. While calling ReserveBytes() for the packet header in NewTracePacket().
37729 // In this case |fragmenting_packet_| == false and we just want a new chunk
37730 // without creating any fragments.
GetNewBuffer()37731 protozero::ContiguousMemoryRange TraceWriterImpl::GetNewBuffer() {
37732   if (fragmenting_packet_ && drop_packets_) {
37733     // We can't write the remaining data of the fragmenting packet to a new
37734     // chunk, because we have already lost some of its data in the garbage
37735     // chunk. Thus, we will wrap around in the garbage chunk, wait until the
37736     // current packet was completed, and then attempt to get a new chunk from
37737     // the SMB again. Instead, if |drop_packets_| is true and
37738     // |fragmenting_packet_| is false, we try to acquire a valid chunk because
37739     // the SMB exhaustion might be resolved.
37740     retry_new_chunk_after_packet_ = true;
37741     return protozero::ContiguousMemoryRange{
37742         &g_garbage_chunk[0], &g_garbage_chunk[0] + sizeof(g_garbage_chunk)};
37743   }
37744 
37745   // Attempt to grab the next chunk before finalizing the current one, so that
37746   // we know whether we need to start dropping packets before writing the
37747   // current packet fragment's header.
37748   ChunkHeader::Packets packets = {};
37749   if (fragmenting_packet_) {
37750     packets.count = 1;
37751     packets.flags = ChunkHeader::kFirstPacketContinuesFromPrevChunk;
37752   }
37753 
37754   // The memory order of the stores below doesn't really matter. This |header|
37755   // is just a local temporary object. The GetNewChunk() call below will copy it
37756   // into the shared buffer with the proper barriers.
37757   ChunkHeader header = {};
37758   header.writer_id.store(id_, std::memory_order_relaxed);
37759   header.chunk_id.store(next_chunk_id_, std::memory_order_relaxed);
37760   header.packets.store(packets, std::memory_order_relaxed);
37761 
37762   SharedMemoryABI::Chunk new_chunk =
37763       shmem_arbiter_->GetNewChunk(header, buffer_exhausted_policy_);
37764   if (!new_chunk.is_valid()) {
37765     // Shared memory buffer exhausted, switch into |drop_packets_| mode. We'll
37766     // drop data until the garbage chunk has been filled once and then retry.
37767 
37768     // If we started a packet in one of the previous (valid) chunks, we need to
37769     // tell the service to discard it.
37770     if (fragmenting_packet_) {
37771       // We can only end up here if the previous chunk was a valid chunk,
37772       // because we never try to acquire a new chunk in |drop_packets_| mode
37773       // while fragmenting.
37774       PERFETTO_DCHECK(!drop_packets_);
37775 
37776       // Backfill the last fragment's header with an invalid size (too large),
37777       // so that the service's TraceBuffer throws out the incomplete packet.
37778       // It'll restart reading from the next chunk we submit.
37779       WriteRedundantVarInt(SharedMemoryABI::kPacketSizeDropPacket,
37780                            cur_packet_->size_field());
37781 
37782       // Reset the size field, since we should not write the current packet's
37783       // size anymore after this.
37784       cur_packet_->set_size_field(nullptr);
37785 
37786       // We don't set kLastPacketContinuesOnNextChunk or kChunkNeedsPatching on
37787       // the last chunk, because its last fragment will be discarded anyway.
37788       // However, the current packet fragment points to a valid |cur_chunk_| and
37789       // may have non-finalized nested messages which will continue in the
37790       // garbage chunk and currently still point into |cur_chunk_|. As we are
37791       // about to return |cur_chunk_|, we need to invalidate the size fields of
37792       // those nested messages. Normally we move them in the |patch_list_| (see
37793       // below) but in this case, it doesn't make sense to send patches for a
37794       // fragment that will be discarded for sure. Thus, we clean up any size
37795       // field references into |cur_chunk_|.
37796       for (auto* nested_msg = cur_packet_->nested_message(); nested_msg;
37797            nested_msg = nested_msg->nested_message()) {
37798         uint8_t* const cur_hdr = nested_msg->size_field();
37799 
37800         // If this is false the protozero Message has already been instructed to
37801         // write, upon Finalize(), its size into the patch list.
37802         bool size_field_points_within_chunk =
37803             cur_hdr >= cur_chunk_.payload_begin() &&
37804             cur_hdr + kMessageLengthFieldSize <= cur_chunk_.end();
37805 
37806         if (size_field_points_within_chunk)
37807           nested_msg->set_size_field(nullptr);
37808       }
37809     } else if (!drop_packets_ && last_packet_size_field_) {
37810       // If we weren't dropping packets before, we should indicate to the
37811       // service that we're about to lose data. We do this by invalidating the
37812       // size of the last packet in |cur_chunk_|. The service will record
37813       // statistics about packets with kPacketSizeDropPacket size.
37814       PERFETTO_DCHECK(cur_packet_->is_finalized());
37815       PERFETTO_DCHECK(cur_chunk_.is_valid());
37816 
37817       // |last_packet_size_field_| should point within |cur_chunk_|'s payload.
37818       PERFETTO_DCHECK(last_packet_size_field_ >= cur_chunk_.payload_begin() &&
37819                       last_packet_size_field_ + kMessageLengthFieldSize <=
37820                           cur_chunk_.end());
37821 
37822       WriteRedundantVarInt(SharedMemoryABI::kPacketSizeDropPacket,
37823                            last_packet_size_field_);
37824     }
37825 
37826     if (cur_chunk_.is_valid()) {
37827       shmem_arbiter_->ReturnCompletedChunk(std::move(cur_chunk_),
37828                                            target_buffer_, &patch_list_);
37829     }
37830 
37831     drop_packets_ = true;
37832     cur_chunk_ = SharedMemoryABI::Chunk();  // Reset to an invalid chunk.
37833     reached_max_packets_per_chunk_ = false;
37834     retry_new_chunk_after_packet_ = false;
37835     last_packet_size_field_ = nullptr;
37836 
37837     PERFETTO_ANNOTATE_BENIGN_RACE_SIZED(&g_garbage_chunk,
37838                                         sizeof(g_garbage_chunk),
37839                                         "nobody reads the garbage chunk")
37840     return protozero::ContiguousMemoryRange{
37841         &g_garbage_chunk[0], &g_garbage_chunk[0] + sizeof(g_garbage_chunk)};
37842   }  // if (!new_chunk.is_valid())
37843 
37844   PERFETTO_DCHECK(new_chunk.is_valid());
37845 
37846   if (fragmenting_packet_) {
37847     // We should not be fragmenting a packet after we exited drop_packets_ mode,
37848     // because we only retry to get a new chunk when a fresh packet is started.
37849     PERFETTO_DCHECK(!drop_packets_);
37850 
37851     uint8_t* const wptr = protobuf_stream_writer_.write_ptr();
37852     PERFETTO_DCHECK(wptr >= cur_fragment_start_);
37853     uint32_t partial_size = static_cast<uint32_t>(wptr - cur_fragment_start_);
37854     PERFETTO_DCHECK(partial_size < cur_chunk_.size());
37855 
37856     // Backfill the packet header with the fragment size.
37857     PERFETTO_DCHECK(partial_size > 0);
37858     cur_packet_->inc_size_already_written(partial_size);
37859     cur_chunk_.SetFlag(ChunkHeader::kLastPacketContinuesOnNextChunk);
37860     WriteRedundantVarInt(partial_size, cur_packet_->size_field());
37861 
37862     // Descend in the stack of non-finalized nested submessages (if any) and
37863     // detour their |size_field| into the |patch_list_|. At this point we have
37864     // to release the chunk and they cannot write anymore into that.
37865     // TODO(primiano): add tests to cover this logic.
37866     bool chunk_needs_patching = false;
37867     for (auto* nested_msg = cur_packet_->nested_message(); nested_msg;
37868          nested_msg = nested_msg->nested_message()) {
37869       uint8_t* const cur_hdr = nested_msg->size_field();
37870 
37871       // If this is false the protozero Message has already been instructed to
37872       // write, upon Finalize(), its size into the patch list.
37873       bool size_field_points_within_chunk =
37874           cur_hdr >= cur_chunk_.payload_begin() &&
37875           cur_hdr + kMessageLengthFieldSize <= cur_chunk_.end();
37876 
37877       if (size_field_points_within_chunk) {
37878         auto offset =
37879             static_cast<uint16_t>(cur_hdr - cur_chunk_.payload_begin());
37880         const ChunkID cur_chunk_id =
37881             cur_chunk_.header()->chunk_id.load(std::memory_order_relaxed);
37882         Patch* patch = patch_list_.emplace_back(cur_chunk_id, offset);
37883         nested_msg->set_size_field(&patch->size_field[0]);
37884         chunk_needs_patching = true;
37885       } else {
37886 #if PERFETTO_DCHECK_IS_ON()
37887         // Ensure that the size field of the message points to an element of the
37888         // patch list.
37889         auto patch_it = std::find_if(
37890             patch_list_.begin(), patch_list_.end(),
37891             [cur_hdr](const Patch& p) { return &p.size_field[0] == cur_hdr; });
37892         PERFETTO_DCHECK(patch_it != patch_list_.end());
37893 #endif
37894       }
37895     }  // for(nested_msg
37896 
37897     if (chunk_needs_patching)
37898       cur_chunk_.SetFlag(ChunkHeader::kChunkNeedsPatching);
37899   }  // if(fragmenting_packet)
37900 
37901   if (cur_chunk_.is_valid()) {
37902     // ReturnCompletedChunk will consume the first patched entries from
37903     // |patch_list_| and shrink it.
37904     shmem_arbiter_->ReturnCompletedChunk(std::move(cur_chunk_), target_buffer_,
37905                                          &patch_list_);
37906   }
37907 
37908   // Switch to the new chunk.
37909   drop_packets_ = false;
37910   reached_max_packets_per_chunk_ = false;
37911   retry_new_chunk_after_packet_ = false;
37912   next_chunk_id_++;
37913   cur_chunk_ = std::move(new_chunk);
37914   last_packet_size_field_ = nullptr;
37915 
37916   uint8_t* payload_begin = cur_chunk_.payload_begin();
37917   if (fragmenting_packet_) {
37918     cur_packet_->set_size_field(payload_begin);
37919     last_packet_size_field_ = payload_begin;
37920     memset(payload_begin, 0, kPacketHeaderSize);
37921     payload_begin += kPacketHeaderSize;
37922     cur_fragment_start_ = payload_begin;
37923   }
37924 
37925   return protozero::ContiguousMemoryRange{payload_begin, cur_chunk_.end()};
37926 }
37927 
writer_id() const37928 WriterID TraceWriterImpl::writer_id() const {
37929   return id_;
37930 }
37931 
37932 // Base class definitions.
37933 TraceWriter::TraceWriter() = default;
37934 TraceWriter::~TraceWriter() = default;
37935 
37936 }  // namespace perfetto
37937 // gen_amalgamated begin source: src/tracing/core/virtual_destructors.cc
37938 // gen_amalgamated begin header: include/perfetto/ext/tracing/core/consumer.h
37939 // gen_amalgamated begin header: include/perfetto/ext/tracing/core/observable_events.h
37940 /*
37941  * Copyright (C) 2017 The Android Open Source Project
37942  *
37943  * Licensed under the Apache License, Version 2.0 (the "License");
37944  * you may not use this file except in compliance with the License.
37945  * You may obtain a copy of the License at
37946  *
37947  *      http://www.apache.org/licenses/LICENSE-2.0
37948  *
37949  * Unless required by applicable law or agreed to in writing, software
37950  * distributed under the License is distributed on an "AS IS" BASIS,
37951  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
37952  * See the License for the specific language governing permissions and
37953  * limitations under the License.
37954  */
37955 
37956 #ifndef INCLUDE_PERFETTO_EXT_TRACING_CORE_OBSERVABLE_EVENTS_H_
37957 #define INCLUDE_PERFETTO_EXT_TRACING_CORE_OBSERVABLE_EVENTS_H_
37958 
37959 // Creates the aliases in the ::perfetto namespace, doing things like:
37960 // using ::perfetto::Foo = ::perfetto::protos::gen::Foo.
37961 // See comments in forward_decls.h for the historical reasons of this
37962 // indirection layer.
37963 // gen_amalgamated expanded: #include "perfetto/tracing/core/forward_decls.h"
37964 
37965 // gen_amalgamated expanded: #include "protos/perfetto/common/observable_events.gen.h"
37966 
37967 #endif  // INCLUDE_PERFETTO_EXT_TRACING_CORE_OBSERVABLE_EVENTS_H_
37968 /*
37969  * Copyright (C) 2017 The Android Open Source Project
37970  *
37971  * Licensed under the Apache License, Version 2.0 (the "License");
37972  * you may not use this file except in compliance with the License.
37973  * You may obtain a copy of the License at
37974  *
37975  *      http://www.apache.org/licenses/LICENSE-2.0
37976  *
37977  * Unless required by applicable law or agreed to in writing, software
37978  * distributed under the License is distributed on an "AS IS" BASIS,
37979  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
37980  * See the License for the specific language governing permissions and
37981  * limitations under the License.
37982  */
37983 
37984 #ifndef INCLUDE_PERFETTO_EXT_TRACING_CORE_CONSUMER_H_
37985 #define INCLUDE_PERFETTO_EXT_TRACING_CORE_CONSUMER_H_
37986 
37987 #include <vector>
37988 
37989 // gen_amalgamated expanded: #include "perfetto/base/export.h"
37990 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/basic_types.h"
37991 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/observable_events.h"
37992 // gen_amalgamated expanded: #include "perfetto/tracing/core/forward_decls.h"
37993 namespace perfetto {
37994 
37995 class TracePacket;
37996 
37997 class PERFETTO_EXPORT Consumer {
37998  public:
37999   virtual ~Consumer();
38000 
38001   // Called by Service (or more typically by the transport layer, on behalf of
38002   // the remote Service), once the Consumer <> Service connection has been
38003   // established.
38004   virtual void OnConnect() = 0;
38005 
38006   // Called by the Service or by the transport layer if the connection with the
38007   // service drops, either voluntarily (e.g., by destroying the ConsumerEndpoint
38008   // obtained through Service::ConnectConsumer()) or involuntarily (e.g., if the
38009   // Service process crashes).
38010   virtual void OnDisconnect() = 0;
38011 
38012   // Called by the Service after the tracing session has ended. This can happen
38013   // for a variety of reasons:
38014   // - The consumer explicitly called DisableTracing()
38015   // - The TraceConfig's |duration_ms| has been reached.
38016   // - The TraceConfig's |max_file_size_bytes| has been reached.
38017   // - An error occurred while trying to enable tracing. In this case |error|
38018   //   is non-empty.
38019   virtual void OnTracingDisabled(const std::string& error) = 0;
38020 
38021   // Called back by the Service (or transport layer) after invoking
38022   // TracingService::ConsumerEndpoint::ReadBuffers(). This function can be
38023   // called more than once. Each invocation can carry one or more
38024   // TracePacket(s). Upon the last call, |has_more| is set to true (i.e.
38025   // |has_more| is a !EOF).
38026   virtual void OnTraceData(std::vector<TracePacket>, bool has_more) = 0;
38027 
38028   // Called back by the Service (or transport layer) after invoking
38029   // TracingService::ConsumerEndpoint::Detach().
38030   // The consumer can disconnect at this point and the trace session will keep
38031   // on going. A new consumer can later re-attach passing back the same |key|
38032   // passed to Detach(), but only if the two requests come from the same uid.
38033   virtual void OnDetach(bool success) = 0;
38034 
38035   // Called back by the Service (or transport layer) after invoking
38036   // TracingService::ConsumerEndpoint::Attach().
38037   virtual void OnAttach(bool success, const TraceConfig&) = 0;
38038 
38039   // Called back by the Service (or transport layer) after invoking
38040   // TracingService::ConsumerEndpoint::GetTraceStats().
38041   virtual void OnTraceStats(bool success, const TraceStats&) = 0;
38042 
38043   // Called back by the Service (or transport layer) after invoking
38044   // TracingService::ConsumerEndpoint::ObserveEvents() whenever one or more
38045   // ObservableEvents of enabled event types occur.
38046   virtual void OnObservableEvents(const ObservableEvents&) = 0;
38047 };
38048 
38049 }  // namespace perfetto
38050 
38051 #endif  // INCLUDE_PERFETTO_EXT_TRACING_CORE_CONSUMER_H_
38052 // gen_amalgamated begin header: include/perfetto/ext/tracing/core/producer.h
38053 /*
38054  * Copyright (C) 2017 The Android Open Source Project
38055  *
38056  * Licensed under the Apache License, Version 2.0 (the "License");
38057  * you may not use this file except in compliance with the License.
38058  * You may obtain a copy of the License at
38059  *
38060  *      http://www.apache.org/licenses/LICENSE-2.0
38061  *
38062  * Unless required by applicable law or agreed to in writing, software
38063  * distributed under the License is distributed on an "AS IS" BASIS,
38064  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
38065  * See the License for the specific language governing permissions and
38066  * limitations under the License.
38067  */
38068 
38069 #ifndef INCLUDE_PERFETTO_EXT_TRACING_CORE_PRODUCER_H_
38070 #define INCLUDE_PERFETTO_EXT_TRACING_CORE_PRODUCER_H_
38071 
38072 // gen_amalgamated expanded: #include "perfetto/base/export.h"
38073 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/basic_types.h"
38074 // gen_amalgamated expanded: #include "perfetto/tracing/core/forward_decls.h"
38075 namespace perfetto {
38076 
38077 class SharedMemory;
38078 
38079 // A Producer is an entity that connects to the write-only port of the Service
38080 // and exposes the ability to produce performance data on-demand. The lifecycle
38081 // of a Producer is as follows:
38082 // 1. The producer connects to the service and advertises its data sources
38083 //    (e.g., the ability to get kernel ftraces, to list process stats).
38084 // 2. The service acknowledges the connection and sends over the SharedMemory
38085 //    region that will be used to exchange data (together with the signalling
38086 //    API TracingService::ProducerEndpoint::OnPageAcquired()/OnPageReleased()).
38087 // 3. At some point later on, the Service asks the Producer to turn on some of
38088 //    the previously registered data sources, together with some configuration
38089 //    parameters. This happens via the StartDataSource() callback.
38090 // 4. In response to that the Producer will spawn an instance of the given data
38091 //    source and inject its data into the shared memory buffer (obtained during
38092 //    OnConnect).
38093 // This interface is subclassed by:
38094 //  1. The actual producer code in the clients e.g., the ftrace reader process.
38095 //  2. The transport layer when interposing RPC between service and producers.
38096 class PERFETTO_EXPORT Producer {
38097  public:
38098   virtual ~Producer();
38099 
38100   // Called by Service (or more typically by the transport layer, on behalf of
38101   // the remote Service), once the Producer <> Service connection has been
38102   // established.
38103   virtual void OnConnect() = 0;
38104 
38105   // Called by the Service or by the transport layer if the connection with the
38106   // service drops, either voluntarily (e.g., by destroying the ProducerEndpoint
38107   // obtained through Service::ConnectProducer()) or involuntarily (e.g., if the
38108   // Service process crashes).
38109   // The Producer is expected to tear down all its data sources if this happens.
38110   // Once this call returns it is possible to safely destroy the Producer
38111   // instance.
38112   virtual void OnDisconnect() = 0;
38113 
38114   // Called by the Service after OnConnect but before the first DataSource is
38115   // created. Can be used for any setup required before tracing begins.
38116   virtual void OnTracingSetup() = 0;
38117 
38118   // The lifecycle methods below are always called in the following sequence:
38119   // SetupDataSource  -> StartDataSource -> StopDataSource.
38120   // Or, in the edge case where a trace is aborted immediately:
38121   // SetupDataSource  -> StopDataSource.
38122   // The Setup+Start call sequence is always guaranateed, regardless of the
38123   // TraceConfig.deferred_start flags.
38124   // Called by the Service to configure one of the data sources previously
38125   // registered through TracingService::ProducerEndpoint::RegisterDataSource().
38126   // This method is always called before StartDataSource. There is always a
38127   // SetupDataSource() call before each StartDataSource() call.
38128   // Args:
38129   // - DataSourceInstanceID is an identifier chosen by the Service that should
38130   //   be assigned to the newly created data source instance. It is used to
38131   //   match the StopDataSource() request below.
38132   // - DataSourceConfig is the configuration for the new data source (e.g.,
38133   //   tells which trace categories to enable).
38134   virtual void SetupDataSource(DataSourceInstanceID,
38135                                const DataSourceConfig&) = 0;
38136 
38137   // Called by the Service to turn on one of the data sources previously
38138   // registered through TracingService::ProducerEndpoint::RegisterDataSource()
38139   // and initialized through SetupDataSource().
38140   // Both arguments are guaranteed to be identical to the ones passed to the
38141   // prior SetupDataSource() call.
38142   virtual void StartDataSource(DataSourceInstanceID,
38143                                const DataSourceConfig&) = 0;
38144 
38145   // Called by the Service to shut down an existing data source instance.
38146   virtual void StopDataSource(DataSourceInstanceID) = 0;
38147 
38148   // Called by the service to request the Producer to commit the data of the
38149   // given data sources and return their chunks into the shared memory buffer.
38150   // The Producer is expected to invoke NotifyFlushComplete(FlushRequestID) on
38151   // the Service after the data has been committed. The producer has to either
38152   // reply to the flush requests in order, or can just reply to the latest one
38153   // Upon seeing a NotifyFlushComplete(N), the service will assume that all
38154   // flushes < N have also been committed.
38155   virtual void Flush(FlushRequestID,
38156                      const DataSourceInstanceID* data_source_ids,
38157                      size_t num_data_sources) = 0;
38158 
38159   // Called by the service to instruct the given data sources to stop referring
38160   // to any trace contents emitted so far. The intent is that after processing
38161   // this call, the rest of the trace should be parsable even if all of the
38162   // packets emitted so far have been lost (for example due to ring buffer
38163   // overwrites).
38164   //
38165   // Called only for Producers with active data sources that have opted in by
38166   // setting |handles_incremental_state_clear| in their DataSourceDescriptor.
38167   //
38168   // The way this call is handled is up to the individual Producer
38169   // implementation. Some might wish to emit invalidation markers in the trace
38170   // (see TracePacket.incremental_state_cleared for an existing field), and
38171   // handle them when parsing the trace.
38172   virtual void ClearIncrementalState(
38173       const DataSourceInstanceID* data_source_ids,
38174       size_t num_data_sources) = 0;
38175 };
38176 
38177 }  // namespace perfetto
38178 
38179 #endif  // INCLUDE_PERFETTO_EXT_TRACING_CORE_PRODUCER_H_
38180 /*
38181  * Copyright (C) 2018 The Android Open Source Project
38182  *
38183  * Licensed under the Apache License, Version 2.0 (the "License");
38184  * you may not use this file except in compliance with the License.
38185  * You may obtain a copy of the License at
38186  *
38187  *      http://www.apache.org/licenses/LICENSE-2.0
38188  *
38189  * Unless required by applicable law or agreed to in writing, software
38190  * distributed under the License is distributed on an "AS IS" BASIS,
38191  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
38192  * See the License for the specific language governing permissions and
38193  * limitations under the License.
38194  */
38195 
38196 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/consumer.h"
38197 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/producer.h"
38198 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/shared_memory.h"
38199 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/shared_memory_arbiter.h"
38200 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/tracing_service.h"
38201 
38202 // This translation unit contains the definitions for the destructor of pure
38203 // virtual interfaces for the current build target. The alternative would be
38204 // introducing a one-liner .cc file for each pure virtual interface, which is
38205 // overkill. This is for compliance with -Wweak-vtables.
38206 
38207 namespace perfetto {
38208 
38209 Consumer::~Consumer() = default;
38210 Producer::~Producer() = default;
38211 TracingService::~TracingService() = default;
38212 ConsumerEndpoint::~ConsumerEndpoint() = default;
38213 ProducerEndpoint::~ProducerEndpoint() = default;
38214 SharedMemory::~SharedMemory() = default;
38215 SharedMemory::Factory::~Factory() = default;
38216 SharedMemoryArbiter::~SharedMemoryArbiter() = default;
38217 
38218 }  // namespace perfetto
38219 // gen_amalgamated begin source: src/tracing/console_interceptor.cc
38220 // gen_amalgamated begin header: gen/protos/perfetto/config/interceptors/console_config.pbzero.h
38221 // Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
38222 
38223 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_INTERCEPTORS_CONSOLE_CONFIG_PROTO_H_
38224 #define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_INTERCEPTORS_CONSOLE_CONFIG_PROTO_H_
38225 
38226 #include <stddef.h>
38227 #include <stdint.h>
38228 
38229 // gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
38230 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
38231 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
38232 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
38233 // gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
38234 
38235 namespace perfetto {
38236 namespace protos {
38237 namespace pbzero {
38238 
38239 enum ConsoleConfig_Output : int32_t;
38240 
38241 enum ConsoleConfig_Output : int32_t {
38242   ConsoleConfig_Output_OUTPUT_UNSPECIFIED = 0,
38243   ConsoleConfig_Output_OUTPUT_STDOUT = 1,
38244   ConsoleConfig_Output_OUTPUT_STDERR = 2,
38245 };
38246 
38247 const ConsoleConfig_Output ConsoleConfig_Output_MIN = ConsoleConfig_Output_OUTPUT_UNSPECIFIED;
38248 const ConsoleConfig_Output ConsoleConfig_Output_MAX = ConsoleConfig_Output_OUTPUT_STDERR;
38249 
38250 class ConsoleConfig_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
38251  public:
ConsoleConfig_Decoder(const uint8_t * data,size_t len)38252   ConsoleConfig_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
ConsoleConfig_Decoder(const std::string & raw)38253   explicit ConsoleConfig_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
ConsoleConfig_Decoder(const::protozero::ConstBytes & raw)38254   explicit ConsoleConfig_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
has_output() const38255   bool has_output() const { return at<1>().valid(); }
output() const38256   int32_t output() const { return at<1>().as_int32(); }
has_enable_colors() const38257   bool has_enable_colors() const { return at<2>().valid(); }
enable_colors() const38258   bool enable_colors() const { return at<2>().as_bool(); }
38259 };
38260 
38261 class ConsoleConfig : public ::protozero::Message {
38262  public:
38263   using Decoder = ConsoleConfig_Decoder;
38264   enum : int32_t {
38265     kOutputFieldNumber = 1,
38266     kEnableColorsFieldNumber = 2,
38267   };
38268   using Output = ::perfetto::protos::pbzero::ConsoleConfig_Output;
38269   static const Output OUTPUT_UNSPECIFIED = ConsoleConfig_Output_OUTPUT_UNSPECIFIED;
38270   static const Output OUTPUT_STDOUT = ConsoleConfig_Output_OUTPUT_STDOUT;
38271   static const Output OUTPUT_STDERR = ConsoleConfig_Output_OUTPUT_STDERR;
38272 
38273   using FieldMetadata_Output =
38274     ::protozero::proto_utils::FieldMetadata<
38275       1,
38276       ::protozero::proto_utils::RepetitionType::kNotRepeated,
38277       ::protozero::proto_utils::ProtoSchemaType::kEnum,
38278       ::perfetto::protos::pbzero::ConsoleConfig_Output,
38279       ConsoleConfig>;
38280 
38281   // Ceci n'est pas une pipe.
38282   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
38283   // type (and users are expected to use it as such, hence kCamelCase name).
38284   // It is declared as a function to keep protozero bindings header-only as
38285   // inline constexpr variables are not available until C++17 (while inline
38286   // functions are).
38287   // TODO(altimin): Use inline variable instead after adopting C++17.
kOutput()38288   static constexpr FieldMetadata_Output kOutput() { return {}; }
set_output(::perfetto::protos::pbzero::ConsoleConfig_Output value)38289   void set_output(::perfetto::protos::pbzero::ConsoleConfig_Output value) {
38290     static constexpr uint32_t field_id = FieldMetadata_Output::kFieldId;
38291     // Call the appropriate protozero::Message::Append(field_id, ...)
38292     // method based on the type of the field.
38293     ::protozero::internal::FieldWriter<
38294       ::protozero::proto_utils::ProtoSchemaType::kEnum>
38295         ::Append(*this, field_id, value);
38296   }
38297 
38298   using FieldMetadata_EnableColors =
38299     ::protozero::proto_utils::FieldMetadata<
38300       2,
38301       ::protozero::proto_utils::RepetitionType::kNotRepeated,
38302       ::protozero::proto_utils::ProtoSchemaType::kBool,
38303       bool,
38304       ConsoleConfig>;
38305 
38306   // Ceci n'est pas une pipe.
38307   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
38308   // type (and users are expected to use it as such, hence kCamelCase name).
38309   // It is declared as a function to keep protozero bindings header-only as
38310   // inline constexpr variables are not available until C++17 (while inline
38311   // functions are).
38312   // TODO(altimin): Use inline variable instead after adopting C++17.
kEnableColors()38313   static constexpr FieldMetadata_EnableColors kEnableColors() { return {}; }
set_enable_colors(bool value)38314   void set_enable_colors(bool value) {
38315     static constexpr uint32_t field_id = FieldMetadata_EnableColors::kFieldId;
38316     // Call the appropriate protozero::Message::Append(field_id, ...)
38317     // method based on the type of the field.
38318     ::protozero::internal::FieldWriter<
38319       ::protozero::proto_utils::ProtoSchemaType::kBool>
38320         ::Append(*this, field_id, value);
38321   }
38322 };
38323 
38324 } // Namespace.
38325 } // Namespace.
38326 } // Namespace.
38327 #endif  // Include guard.
38328 // gen_amalgamated begin header: gen/protos/perfetto/trace/trace_packet_defaults.pbzero.h
38329 // Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
38330 
38331 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACE_PACKET_DEFAULTS_PROTO_H_
38332 #define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACE_PACKET_DEFAULTS_PROTO_H_
38333 
38334 #include <stddef.h>
38335 #include <stdint.h>
38336 
38337 // gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
38338 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
38339 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
38340 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
38341 // gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
38342 
38343 namespace perfetto {
38344 namespace protos {
38345 namespace pbzero {
38346 
38347 class PerfSampleDefaults;
38348 class TrackEventDefaults;
38349 
38350 class TracePacketDefaults_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/58, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
38351  public:
TracePacketDefaults_Decoder(const uint8_t * data,size_t len)38352   TracePacketDefaults_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
TracePacketDefaults_Decoder(const std::string & raw)38353   explicit TracePacketDefaults_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
TracePacketDefaults_Decoder(const::protozero::ConstBytes & raw)38354   explicit TracePacketDefaults_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
has_timestamp_clock_id() const38355   bool has_timestamp_clock_id() const { return at<58>().valid(); }
timestamp_clock_id() const38356   uint32_t timestamp_clock_id() const { return at<58>().as_uint32(); }
has_track_event_defaults() const38357   bool has_track_event_defaults() const { return at<11>().valid(); }
track_event_defaults() const38358   ::protozero::ConstBytes track_event_defaults() const { return at<11>().as_bytes(); }
has_perf_sample_defaults() const38359   bool has_perf_sample_defaults() const { return at<12>().valid(); }
perf_sample_defaults() const38360   ::protozero::ConstBytes perf_sample_defaults() const { return at<12>().as_bytes(); }
38361 };
38362 
38363 class TracePacketDefaults : public ::protozero::Message {
38364  public:
38365   using Decoder = TracePacketDefaults_Decoder;
38366   enum : int32_t {
38367     kTimestampClockIdFieldNumber = 58,
38368     kTrackEventDefaultsFieldNumber = 11,
38369     kPerfSampleDefaultsFieldNumber = 12,
38370   };
38371 
38372   using FieldMetadata_TimestampClockId =
38373     ::protozero::proto_utils::FieldMetadata<
38374       58,
38375       ::protozero::proto_utils::RepetitionType::kNotRepeated,
38376       ::protozero::proto_utils::ProtoSchemaType::kUint32,
38377       uint32_t,
38378       TracePacketDefaults>;
38379 
38380   // Ceci n'est pas une pipe.
38381   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
38382   // type (and users are expected to use it as such, hence kCamelCase name).
38383   // It is declared as a function to keep protozero bindings header-only as
38384   // inline constexpr variables are not available until C++17 (while inline
38385   // functions are).
38386   // TODO(altimin): Use inline variable instead after adopting C++17.
kTimestampClockId()38387   static constexpr FieldMetadata_TimestampClockId kTimestampClockId() { return {}; }
set_timestamp_clock_id(uint32_t value)38388   void set_timestamp_clock_id(uint32_t value) {
38389     static constexpr uint32_t field_id = FieldMetadata_TimestampClockId::kFieldId;
38390     // Call the appropriate protozero::Message::Append(field_id, ...)
38391     // method based on the type of the field.
38392     ::protozero::internal::FieldWriter<
38393       ::protozero::proto_utils::ProtoSchemaType::kUint32>
38394         ::Append(*this, field_id, value);
38395   }
38396 
38397   using FieldMetadata_TrackEventDefaults =
38398     ::protozero::proto_utils::FieldMetadata<
38399       11,
38400       ::protozero::proto_utils::RepetitionType::kNotRepeated,
38401       ::protozero::proto_utils::ProtoSchemaType::kMessage,
38402       TrackEventDefaults,
38403       TracePacketDefaults>;
38404 
38405   // Ceci n'est pas une pipe.
38406   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
38407   // type (and users are expected to use it as such, hence kCamelCase name).
38408   // It is declared as a function to keep protozero bindings header-only as
38409   // inline constexpr variables are not available until C++17 (while inline
38410   // functions are).
38411   // TODO(altimin): Use inline variable instead after adopting C++17.
kTrackEventDefaults()38412   static constexpr FieldMetadata_TrackEventDefaults kTrackEventDefaults() { return {}; }
set_track_event_defaults()38413   template <typename T = TrackEventDefaults> T* set_track_event_defaults() {
38414     return BeginNestedMessage<T>(11);
38415   }
38416 
38417 
38418   using FieldMetadata_PerfSampleDefaults =
38419     ::protozero::proto_utils::FieldMetadata<
38420       12,
38421       ::protozero::proto_utils::RepetitionType::kNotRepeated,
38422       ::protozero::proto_utils::ProtoSchemaType::kMessage,
38423       PerfSampleDefaults,
38424       TracePacketDefaults>;
38425 
38426   // Ceci n'est pas une pipe.
38427   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
38428   // type (and users are expected to use it as such, hence kCamelCase name).
38429   // It is declared as a function to keep protozero bindings header-only as
38430   // inline constexpr variables are not available until C++17 (while inline
38431   // functions are).
38432   // TODO(altimin): Use inline variable instead after adopting C++17.
kPerfSampleDefaults()38433   static constexpr FieldMetadata_PerfSampleDefaults kPerfSampleDefaults() { return {}; }
set_perf_sample_defaults()38434   template <typename T = PerfSampleDefaults> T* set_perf_sample_defaults() {
38435     return BeginNestedMessage<T>(12);
38436   }
38437 
38438 };
38439 
38440 } // Namespace.
38441 } // Namespace.
38442 } // Namespace.
38443 #endif  // Include guard.
38444 // gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/process_descriptor.pbzero.h
38445 // Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
38446 
38447 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_PROCESS_DESCRIPTOR_PROTO_H_
38448 #define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_PROCESS_DESCRIPTOR_PROTO_H_
38449 
38450 #include <stddef.h>
38451 #include <stdint.h>
38452 
38453 // gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
38454 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
38455 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
38456 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
38457 // gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
38458 
38459 namespace perfetto {
38460 namespace protos {
38461 namespace pbzero {
38462 
38463 enum ProcessDescriptor_ChromeProcessType : int32_t;
38464 
38465 enum ProcessDescriptor_ChromeProcessType : int32_t {
38466   ProcessDescriptor_ChromeProcessType_PROCESS_UNSPECIFIED = 0,
38467   ProcessDescriptor_ChromeProcessType_PROCESS_BROWSER = 1,
38468   ProcessDescriptor_ChromeProcessType_PROCESS_RENDERER = 2,
38469   ProcessDescriptor_ChromeProcessType_PROCESS_UTILITY = 3,
38470   ProcessDescriptor_ChromeProcessType_PROCESS_ZYGOTE = 4,
38471   ProcessDescriptor_ChromeProcessType_PROCESS_SANDBOX_HELPER = 5,
38472   ProcessDescriptor_ChromeProcessType_PROCESS_GPU = 6,
38473   ProcessDescriptor_ChromeProcessType_PROCESS_PPAPI_PLUGIN = 7,
38474   ProcessDescriptor_ChromeProcessType_PROCESS_PPAPI_BROKER = 8,
38475 };
38476 
38477 const ProcessDescriptor_ChromeProcessType ProcessDescriptor_ChromeProcessType_MIN = ProcessDescriptor_ChromeProcessType_PROCESS_UNSPECIFIED;
38478 const ProcessDescriptor_ChromeProcessType ProcessDescriptor_ChromeProcessType_MAX = ProcessDescriptor_ChromeProcessType_PROCESS_PPAPI_BROKER;
38479 
38480 class ProcessDescriptor_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/8, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
38481  public:
ProcessDescriptor_Decoder(const uint8_t * data,size_t len)38482   ProcessDescriptor_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
ProcessDescriptor_Decoder(const std::string & raw)38483   explicit ProcessDescriptor_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
ProcessDescriptor_Decoder(const::protozero::ConstBytes & raw)38484   explicit ProcessDescriptor_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
has_pid() const38485   bool has_pid() const { return at<1>().valid(); }
pid() const38486   int32_t pid() const { return at<1>().as_int32(); }
has_cmdline() const38487   bool has_cmdline() const { return at<2>().valid(); }
cmdline() const38488   ::protozero::RepeatedFieldIterator<::protozero::ConstChars> cmdline() const { return GetRepeated<::protozero::ConstChars>(2); }
has_process_name() const38489   bool has_process_name() const { return at<6>().valid(); }
process_name() const38490   ::protozero::ConstChars process_name() const { return at<6>().as_string(); }
has_process_priority() const38491   bool has_process_priority() const { return at<5>().valid(); }
process_priority() const38492   int32_t process_priority() const { return at<5>().as_int32(); }
has_start_timestamp_ns() const38493   bool has_start_timestamp_ns() const { return at<7>().valid(); }
start_timestamp_ns() const38494   int64_t start_timestamp_ns() const { return at<7>().as_int64(); }
has_chrome_process_type() const38495   bool has_chrome_process_type() const { return at<4>().valid(); }
chrome_process_type() const38496   int32_t chrome_process_type() const { return at<4>().as_int32(); }
has_legacy_sort_index() const38497   bool has_legacy_sort_index() const { return at<3>().valid(); }
legacy_sort_index() const38498   int32_t legacy_sort_index() const { return at<3>().as_int32(); }
has_process_labels() const38499   bool has_process_labels() const { return at<8>().valid(); }
process_labels() const38500   ::protozero::RepeatedFieldIterator<::protozero::ConstChars> process_labels() const { return GetRepeated<::protozero::ConstChars>(8); }
38501 };
38502 
38503 class ProcessDescriptor : public ::protozero::Message {
38504  public:
38505   using Decoder = ProcessDescriptor_Decoder;
38506   enum : int32_t {
38507     kPidFieldNumber = 1,
38508     kCmdlineFieldNumber = 2,
38509     kProcessNameFieldNumber = 6,
38510     kProcessPriorityFieldNumber = 5,
38511     kStartTimestampNsFieldNumber = 7,
38512     kChromeProcessTypeFieldNumber = 4,
38513     kLegacySortIndexFieldNumber = 3,
38514     kProcessLabelsFieldNumber = 8,
38515   };
38516   using ChromeProcessType = ::perfetto::protos::pbzero::ProcessDescriptor_ChromeProcessType;
38517   static const ChromeProcessType PROCESS_UNSPECIFIED = ProcessDescriptor_ChromeProcessType_PROCESS_UNSPECIFIED;
38518   static const ChromeProcessType PROCESS_BROWSER = ProcessDescriptor_ChromeProcessType_PROCESS_BROWSER;
38519   static const ChromeProcessType PROCESS_RENDERER = ProcessDescriptor_ChromeProcessType_PROCESS_RENDERER;
38520   static const ChromeProcessType PROCESS_UTILITY = ProcessDescriptor_ChromeProcessType_PROCESS_UTILITY;
38521   static const ChromeProcessType PROCESS_ZYGOTE = ProcessDescriptor_ChromeProcessType_PROCESS_ZYGOTE;
38522   static const ChromeProcessType PROCESS_SANDBOX_HELPER = ProcessDescriptor_ChromeProcessType_PROCESS_SANDBOX_HELPER;
38523   static const ChromeProcessType PROCESS_GPU = ProcessDescriptor_ChromeProcessType_PROCESS_GPU;
38524   static const ChromeProcessType PROCESS_PPAPI_PLUGIN = ProcessDescriptor_ChromeProcessType_PROCESS_PPAPI_PLUGIN;
38525   static const ChromeProcessType PROCESS_PPAPI_BROKER = ProcessDescriptor_ChromeProcessType_PROCESS_PPAPI_BROKER;
38526 
38527   using FieldMetadata_Pid =
38528     ::protozero::proto_utils::FieldMetadata<
38529       1,
38530       ::protozero::proto_utils::RepetitionType::kNotRepeated,
38531       ::protozero::proto_utils::ProtoSchemaType::kInt32,
38532       int32_t,
38533       ProcessDescriptor>;
38534 
38535   // Ceci n'est pas une pipe.
38536   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
38537   // type (and users are expected to use it as such, hence kCamelCase name).
38538   // It is declared as a function to keep protozero bindings header-only as
38539   // inline constexpr variables are not available until C++17 (while inline
38540   // functions are).
38541   // TODO(altimin): Use inline variable instead after adopting C++17.
kPid()38542   static constexpr FieldMetadata_Pid kPid() { return {}; }
set_pid(int32_t value)38543   void set_pid(int32_t value) {
38544     static constexpr uint32_t field_id = FieldMetadata_Pid::kFieldId;
38545     // Call the appropriate protozero::Message::Append(field_id, ...)
38546     // method based on the type of the field.
38547     ::protozero::internal::FieldWriter<
38548       ::protozero::proto_utils::ProtoSchemaType::kInt32>
38549         ::Append(*this, field_id, value);
38550   }
38551 
38552   using FieldMetadata_Cmdline =
38553     ::protozero::proto_utils::FieldMetadata<
38554       2,
38555       ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
38556       ::protozero::proto_utils::ProtoSchemaType::kString,
38557       std::string,
38558       ProcessDescriptor>;
38559 
38560   // Ceci n'est pas une pipe.
38561   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
38562   // type (and users are expected to use it as such, hence kCamelCase name).
38563   // It is declared as a function to keep protozero bindings header-only as
38564   // inline constexpr variables are not available until C++17 (while inline
38565   // functions are).
38566   // TODO(altimin): Use inline variable instead after adopting C++17.
kCmdline()38567   static constexpr FieldMetadata_Cmdline kCmdline() { return {}; }
add_cmdline(const char * data,size_t size)38568   void add_cmdline(const char* data, size_t size) {
38569     AppendBytes(FieldMetadata_Cmdline::kFieldId, data, size);
38570   }
add_cmdline(std::string value)38571   void add_cmdline(std::string value) {
38572     static constexpr uint32_t field_id = FieldMetadata_Cmdline::kFieldId;
38573     // Call the appropriate protozero::Message::Append(field_id, ...)
38574     // method based on the type of the field.
38575     ::protozero::internal::FieldWriter<
38576       ::protozero::proto_utils::ProtoSchemaType::kString>
38577         ::Append(*this, field_id, value);
38578   }
38579 
38580   using FieldMetadata_ProcessName =
38581     ::protozero::proto_utils::FieldMetadata<
38582       6,
38583       ::protozero::proto_utils::RepetitionType::kNotRepeated,
38584       ::protozero::proto_utils::ProtoSchemaType::kString,
38585       std::string,
38586       ProcessDescriptor>;
38587 
38588   // Ceci n'est pas une pipe.
38589   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
38590   // type (and users are expected to use it as such, hence kCamelCase name).
38591   // It is declared as a function to keep protozero bindings header-only as
38592   // inline constexpr variables are not available until C++17 (while inline
38593   // functions are).
38594   // TODO(altimin): Use inline variable instead after adopting C++17.
kProcessName()38595   static constexpr FieldMetadata_ProcessName kProcessName() { return {}; }
set_process_name(const char * data,size_t size)38596   void set_process_name(const char* data, size_t size) {
38597     AppendBytes(FieldMetadata_ProcessName::kFieldId, data, size);
38598   }
set_process_name(std::string value)38599   void set_process_name(std::string value) {
38600     static constexpr uint32_t field_id = FieldMetadata_ProcessName::kFieldId;
38601     // Call the appropriate protozero::Message::Append(field_id, ...)
38602     // method based on the type of the field.
38603     ::protozero::internal::FieldWriter<
38604       ::protozero::proto_utils::ProtoSchemaType::kString>
38605         ::Append(*this, field_id, value);
38606   }
38607 
38608   using FieldMetadata_ProcessPriority =
38609     ::protozero::proto_utils::FieldMetadata<
38610       5,
38611       ::protozero::proto_utils::RepetitionType::kNotRepeated,
38612       ::protozero::proto_utils::ProtoSchemaType::kInt32,
38613       int32_t,
38614       ProcessDescriptor>;
38615 
38616   // Ceci n'est pas une pipe.
38617   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
38618   // type (and users are expected to use it as such, hence kCamelCase name).
38619   // It is declared as a function to keep protozero bindings header-only as
38620   // inline constexpr variables are not available until C++17 (while inline
38621   // functions are).
38622   // TODO(altimin): Use inline variable instead after adopting C++17.
kProcessPriority()38623   static constexpr FieldMetadata_ProcessPriority kProcessPriority() { return {}; }
set_process_priority(int32_t value)38624   void set_process_priority(int32_t value) {
38625     static constexpr uint32_t field_id = FieldMetadata_ProcessPriority::kFieldId;
38626     // Call the appropriate protozero::Message::Append(field_id, ...)
38627     // method based on the type of the field.
38628     ::protozero::internal::FieldWriter<
38629       ::protozero::proto_utils::ProtoSchemaType::kInt32>
38630         ::Append(*this, field_id, value);
38631   }
38632 
38633   using FieldMetadata_StartTimestampNs =
38634     ::protozero::proto_utils::FieldMetadata<
38635       7,
38636       ::protozero::proto_utils::RepetitionType::kNotRepeated,
38637       ::protozero::proto_utils::ProtoSchemaType::kInt64,
38638       int64_t,
38639       ProcessDescriptor>;
38640 
38641   // Ceci n'est pas une pipe.
38642   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
38643   // type (and users are expected to use it as such, hence kCamelCase name).
38644   // It is declared as a function to keep protozero bindings header-only as
38645   // inline constexpr variables are not available until C++17 (while inline
38646   // functions are).
38647   // TODO(altimin): Use inline variable instead after adopting C++17.
kStartTimestampNs()38648   static constexpr FieldMetadata_StartTimestampNs kStartTimestampNs() { return {}; }
set_start_timestamp_ns(int64_t value)38649   void set_start_timestamp_ns(int64_t value) {
38650     static constexpr uint32_t field_id = FieldMetadata_StartTimestampNs::kFieldId;
38651     // Call the appropriate protozero::Message::Append(field_id, ...)
38652     // method based on the type of the field.
38653     ::protozero::internal::FieldWriter<
38654       ::protozero::proto_utils::ProtoSchemaType::kInt64>
38655         ::Append(*this, field_id, value);
38656   }
38657 
38658   using FieldMetadata_ChromeProcessType =
38659     ::protozero::proto_utils::FieldMetadata<
38660       4,
38661       ::protozero::proto_utils::RepetitionType::kNotRepeated,
38662       ::protozero::proto_utils::ProtoSchemaType::kEnum,
38663       ::perfetto::protos::pbzero::ProcessDescriptor_ChromeProcessType,
38664       ProcessDescriptor>;
38665 
38666   // Ceci n'est pas une pipe.
38667   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
38668   // type (and users are expected to use it as such, hence kCamelCase name).
38669   // It is declared as a function to keep protozero bindings header-only as
38670   // inline constexpr variables are not available until C++17 (while inline
38671   // functions are).
38672   // TODO(altimin): Use inline variable instead after adopting C++17.
kChromeProcessType()38673   static constexpr FieldMetadata_ChromeProcessType kChromeProcessType() { return {}; }
set_chrome_process_type(::perfetto::protos::pbzero::ProcessDescriptor_ChromeProcessType value)38674   void set_chrome_process_type(::perfetto::protos::pbzero::ProcessDescriptor_ChromeProcessType value) {
38675     static constexpr uint32_t field_id = FieldMetadata_ChromeProcessType::kFieldId;
38676     // Call the appropriate protozero::Message::Append(field_id, ...)
38677     // method based on the type of the field.
38678     ::protozero::internal::FieldWriter<
38679       ::protozero::proto_utils::ProtoSchemaType::kEnum>
38680         ::Append(*this, field_id, value);
38681   }
38682 
38683   using FieldMetadata_LegacySortIndex =
38684     ::protozero::proto_utils::FieldMetadata<
38685       3,
38686       ::protozero::proto_utils::RepetitionType::kNotRepeated,
38687       ::protozero::proto_utils::ProtoSchemaType::kInt32,
38688       int32_t,
38689       ProcessDescriptor>;
38690 
38691   // Ceci n'est pas une pipe.
38692   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
38693   // type (and users are expected to use it as such, hence kCamelCase name).
38694   // It is declared as a function to keep protozero bindings header-only as
38695   // inline constexpr variables are not available until C++17 (while inline
38696   // functions are).
38697   // TODO(altimin): Use inline variable instead after adopting C++17.
kLegacySortIndex()38698   static constexpr FieldMetadata_LegacySortIndex kLegacySortIndex() { return {}; }
set_legacy_sort_index(int32_t value)38699   void set_legacy_sort_index(int32_t value) {
38700     static constexpr uint32_t field_id = FieldMetadata_LegacySortIndex::kFieldId;
38701     // Call the appropriate protozero::Message::Append(field_id, ...)
38702     // method based on the type of the field.
38703     ::protozero::internal::FieldWriter<
38704       ::protozero::proto_utils::ProtoSchemaType::kInt32>
38705         ::Append(*this, field_id, value);
38706   }
38707 
38708   using FieldMetadata_ProcessLabels =
38709     ::protozero::proto_utils::FieldMetadata<
38710       8,
38711       ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
38712       ::protozero::proto_utils::ProtoSchemaType::kString,
38713       std::string,
38714       ProcessDescriptor>;
38715 
38716   // Ceci n'est pas une pipe.
38717   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
38718   // type (and users are expected to use it as such, hence kCamelCase name).
38719   // It is declared as a function to keep protozero bindings header-only as
38720   // inline constexpr variables are not available until C++17 (while inline
38721   // functions are).
38722   // TODO(altimin): Use inline variable instead after adopting C++17.
kProcessLabels()38723   static constexpr FieldMetadata_ProcessLabels kProcessLabels() { return {}; }
add_process_labels(const char * data,size_t size)38724   void add_process_labels(const char* data, size_t size) {
38725     AppendBytes(FieldMetadata_ProcessLabels::kFieldId, data, size);
38726   }
add_process_labels(std::string value)38727   void add_process_labels(std::string value) {
38728     static constexpr uint32_t field_id = FieldMetadata_ProcessLabels::kFieldId;
38729     // Call the appropriate protozero::Message::Append(field_id, ...)
38730     // method based on the type of the field.
38731     ::protozero::internal::FieldWriter<
38732       ::protozero::proto_utils::ProtoSchemaType::kString>
38733         ::Append(*this, field_id, value);
38734   }
38735 };
38736 
38737 } // Namespace.
38738 } // Namespace.
38739 } // Namespace.
38740 #endif  // Include guard.
38741 // gen_amalgamated begin header: gen/protos/perfetto/trace/track_event/thread_descriptor.pbzero.h
38742 // Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
38743 
38744 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_THREAD_DESCRIPTOR_PROTO_H_
38745 #define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRACK_EVENT_THREAD_DESCRIPTOR_PROTO_H_
38746 
38747 #include <stddef.h>
38748 #include <stdint.h>
38749 
38750 // gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
38751 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
38752 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
38753 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
38754 // gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
38755 
38756 namespace perfetto {
38757 namespace protos {
38758 namespace pbzero {
38759 
38760 enum ThreadDescriptor_ChromeThreadType : int32_t;
38761 
38762 enum ThreadDescriptor_ChromeThreadType : int32_t {
38763   ThreadDescriptor_ChromeThreadType_CHROME_THREAD_UNSPECIFIED = 0,
38764   ThreadDescriptor_ChromeThreadType_CHROME_THREAD_MAIN = 1,
38765   ThreadDescriptor_ChromeThreadType_CHROME_THREAD_IO = 2,
38766   ThreadDescriptor_ChromeThreadType_CHROME_THREAD_POOL_BG_WORKER = 3,
38767   ThreadDescriptor_ChromeThreadType_CHROME_THREAD_POOL_FG_WORKER = 4,
38768   ThreadDescriptor_ChromeThreadType_CHROME_THREAD_POOL_FB_BLOCKING = 5,
38769   ThreadDescriptor_ChromeThreadType_CHROME_THREAD_POOL_BG_BLOCKING = 6,
38770   ThreadDescriptor_ChromeThreadType_CHROME_THREAD_POOL_SERVICE = 7,
38771   ThreadDescriptor_ChromeThreadType_CHROME_THREAD_COMPOSITOR = 8,
38772   ThreadDescriptor_ChromeThreadType_CHROME_THREAD_VIZ_COMPOSITOR = 9,
38773   ThreadDescriptor_ChromeThreadType_CHROME_THREAD_COMPOSITOR_WORKER = 10,
38774   ThreadDescriptor_ChromeThreadType_CHROME_THREAD_SERVICE_WORKER = 11,
38775   ThreadDescriptor_ChromeThreadType_CHROME_THREAD_MEMORY_INFRA = 50,
38776   ThreadDescriptor_ChromeThreadType_CHROME_THREAD_SAMPLING_PROFILER = 51,
38777 };
38778 
38779 const ThreadDescriptor_ChromeThreadType ThreadDescriptor_ChromeThreadType_MIN = ThreadDescriptor_ChromeThreadType_CHROME_THREAD_UNSPECIFIED;
38780 const ThreadDescriptor_ChromeThreadType ThreadDescriptor_ChromeThreadType_MAX = ThreadDescriptor_ChromeThreadType_CHROME_THREAD_SAMPLING_PROFILER;
38781 
38782 class ThreadDescriptor_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/8, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
38783  public:
ThreadDescriptor_Decoder(const uint8_t * data,size_t len)38784   ThreadDescriptor_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
ThreadDescriptor_Decoder(const std::string & raw)38785   explicit ThreadDescriptor_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
ThreadDescriptor_Decoder(const::protozero::ConstBytes & raw)38786   explicit ThreadDescriptor_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
has_pid() const38787   bool has_pid() const { return at<1>().valid(); }
pid() const38788   int32_t pid() const { return at<1>().as_int32(); }
has_tid() const38789   bool has_tid() const { return at<2>().valid(); }
tid() const38790   int32_t tid() const { return at<2>().as_int32(); }
has_thread_name() const38791   bool has_thread_name() const { return at<5>().valid(); }
thread_name() const38792   ::protozero::ConstChars thread_name() const { return at<5>().as_string(); }
has_chrome_thread_type() const38793   bool has_chrome_thread_type() const { return at<4>().valid(); }
chrome_thread_type() const38794   int32_t chrome_thread_type() const { return at<4>().as_int32(); }
has_reference_timestamp_us() const38795   bool has_reference_timestamp_us() const { return at<6>().valid(); }
reference_timestamp_us() const38796   int64_t reference_timestamp_us() const { return at<6>().as_int64(); }
has_reference_thread_time_us() const38797   bool has_reference_thread_time_us() const { return at<7>().valid(); }
reference_thread_time_us() const38798   int64_t reference_thread_time_us() const { return at<7>().as_int64(); }
has_reference_thread_instruction_count() const38799   bool has_reference_thread_instruction_count() const { return at<8>().valid(); }
reference_thread_instruction_count() const38800   int64_t reference_thread_instruction_count() const { return at<8>().as_int64(); }
has_legacy_sort_index() const38801   bool has_legacy_sort_index() const { return at<3>().valid(); }
legacy_sort_index() const38802   int32_t legacy_sort_index() const { return at<3>().as_int32(); }
38803 };
38804 
38805 class ThreadDescriptor : public ::protozero::Message {
38806  public:
38807   using Decoder = ThreadDescriptor_Decoder;
38808   enum : int32_t {
38809     kPidFieldNumber = 1,
38810     kTidFieldNumber = 2,
38811     kThreadNameFieldNumber = 5,
38812     kChromeThreadTypeFieldNumber = 4,
38813     kReferenceTimestampUsFieldNumber = 6,
38814     kReferenceThreadTimeUsFieldNumber = 7,
38815     kReferenceThreadInstructionCountFieldNumber = 8,
38816     kLegacySortIndexFieldNumber = 3,
38817   };
38818   using ChromeThreadType = ::perfetto::protos::pbzero::ThreadDescriptor_ChromeThreadType;
38819   static const ChromeThreadType CHROME_THREAD_UNSPECIFIED = ThreadDescriptor_ChromeThreadType_CHROME_THREAD_UNSPECIFIED;
38820   static const ChromeThreadType CHROME_THREAD_MAIN = ThreadDescriptor_ChromeThreadType_CHROME_THREAD_MAIN;
38821   static const ChromeThreadType CHROME_THREAD_IO = ThreadDescriptor_ChromeThreadType_CHROME_THREAD_IO;
38822   static const ChromeThreadType CHROME_THREAD_POOL_BG_WORKER = ThreadDescriptor_ChromeThreadType_CHROME_THREAD_POOL_BG_WORKER;
38823   static const ChromeThreadType CHROME_THREAD_POOL_FG_WORKER = ThreadDescriptor_ChromeThreadType_CHROME_THREAD_POOL_FG_WORKER;
38824   static const ChromeThreadType CHROME_THREAD_POOL_FB_BLOCKING = ThreadDescriptor_ChromeThreadType_CHROME_THREAD_POOL_FB_BLOCKING;
38825   static const ChromeThreadType CHROME_THREAD_POOL_BG_BLOCKING = ThreadDescriptor_ChromeThreadType_CHROME_THREAD_POOL_BG_BLOCKING;
38826   static const ChromeThreadType CHROME_THREAD_POOL_SERVICE = ThreadDescriptor_ChromeThreadType_CHROME_THREAD_POOL_SERVICE;
38827   static const ChromeThreadType CHROME_THREAD_COMPOSITOR = ThreadDescriptor_ChromeThreadType_CHROME_THREAD_COMPOSITOR;
38828   static const ChromeThreadType CHROME_THREAD_VIZ_COMPOSITOR = ThreadDescriptor_ChromeThreadType_CHROME_THREAD_VIZ_COMPOSITOR;
38829   static const ChromeThreadType CHROME_THREAD_COMPOSITOR_WORKER = ThreadDescriptor_ChromeThreadType_CHROME_THREAD_COMPOSITOR_WORKER;
38830   static const ChromeThreadType CHROME_THREAD_SERVICE_WORKER = ThreadDescriptor_ChromeThreadType_CHROME_THREAD_SERVICE_WORKER;
38831   static const ChromeThreadType CHROME_THREAD_MEMORY_INFRA = ThreadDescriptor_ChromeThreadType_CHROME_THREAD_MEMORY_INFRA;
38832   static const ChromeThreadType CHROME_THREAD_SAMPLING_PROFILER = ThreadDescriptor_ChromeThreadType_CHROME_THREAD_SAMPLING_PROFILER;
38833 
38834   using FieldMetadata_Pid =
38835     ::protozero::proto_utils::FieldMetadata<
38836       1,
38837       ::protozero::proto_utils::RepetitionType::kNotRepeated,
38838       ::protozero::proto_utils::ProtoSchemaType::kInt32,
38839       int32_t,
38840       ThreadDescriptor>;
38841 
38842   // Ceci n'est pas une pipe.
38843   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
38844   // type (and users are expected to use it as such, hence kCamelCase name).
38845   // It is declared as a function to keep protozero bindings header-only as
38846   // inline constexpr variables are not available until C++17 (while inline
38847   // functions are).
38848   // TODO(altimin): Use inline variable instead after adopting C++17.
kPid()38849   static constexpr FieldMetadata_Pid kPid() { return {}; }
set_pid(int32_t value)38850   void set_pid(int32_t value) {
38851     static constexpr uint32_t field_id = FieldMetadata_Pid::kFieldId;
38852     // Call the appropriate protozero::Message::Append(field_id, ...)
38853     // method based on the type of the field.
38854     ::protozero::internal::FieldWriter<
38855       ::protozero::proto_utils::ProtoSchemaType::kInt32>
38856         ::Append(*this, field_id, value);
38857   }
38858 
38859   using FieldMetadata_Tid =
38860     ::protozero::proto_utils::FieldMetadata<
38861       2,
38862       ::protozero::proto_utils::RepetitionType::kNotRepeated,
38863       ::protozero::proto_utils::ProtoSchemaType::kInt32,
38864       int32_t,
38865       ThreadDescriptor>;
38866 
38867   // Ceci n'est pas une pipe.
38868   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
38869   // type (and users are expected to use it as such, hence kCamelCase name).
38870   // It is declared as a function to keep protozero bindings header-only as
38871   // inline constexpr variables are not available until C++17 (while inline
38872   // functions are).
38873   // TODO(altimin): Use inline variable instead after adopting C++17.
kTid()38874   static constexpr FieldMetadata_Tid kTid() { return {}; }
set_tid(int32_t value)38875   void set_tid(int32_t value) {
38876     static constexpr uint32_t field_id = FieldMetadata_Tid::kFieldId;
38877     // Call the appropriate protozero::Message::Append(field_id, ...)
38878     // method based on the type of the field.
38879     ::protozero::internal::FieldWriter<
38880       ::protozero::proto_utils::ProtoSchemaType::kInt32>
38881         ::Append(*this, field_id, value);
38882   }
38883 
38884   using FieldMetadata_ThreadName =
38885     ::protozero::proto_utils::FieldMetadata<
38886       5,
38887       ::protozero::proto_utils::RepetitionType::kNotRepeated,
38888       ::protozero::proto_utils::ProtoSchemaType::kString,
38889       std::string,
38890       ThreadDescriptor>;
38891 
38892   // Ceci n'est pas une pipe.
38893   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
38894   // type (and users are expected to use it as such, hence kCamelCase name).
38895   // It is declared as a function to keep protozero bindings header-only as
38896   // inline constexpr variables are not available until C++17 (while inline
38897   // functions are).
38898   // TODO(altimin): Use inline variable instead after adopting C++17.
kThreadName()38899   static constexpr FieldMetadata_ThreadName kThreadName() { return {}; }
set_thread_name(const char * data,size_t size)38900   void set_thread_name(const char* data, size_t size) {
38901     AppendBytes(FieldMetadata_ThreadName::kFieldId, data, size);
38902   }
set_thread_name(std::string value)38903   void set_thread_name(std::string value) {
38904     static constexpr uint32_t field_id = FieldMetadata_ThreadName::kFieldId;
38905     // Call the appropriate protozero::Message::Append(field_id, ...)
38906     // method based on the type of the field.
38907     ::protozero::internal::FieldWriter<
38908       ::protozero::proto_utils::ProtoSchemaType::kString>
38909         ::Append(*this, field_id, value);
38910   }
38911 
38912   using FieldMetadata_ChromeThreadType =
38913     ::protozero::proto_utils::FieldMetadata<
38914       4,
38915       ::protozero::proto_utils::RepetitionType::kNotRepeated,
38916       ::protozero::proto_utils::ProtoSchemaType::kEnum,
38917       ::perfetto::protos::pbzero::ThreadDescriptor_ChromeThreadType,
38918       ThreadDescriptor>;
38919 
38920   // Ceci n'est pas une pipe.
38921   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
38922   // type (and users are expected to use it as such, hence kCamelCase name).
38923   // It is declared as a function to keep protozero bindings header-only as
38924   // inline constexpr variables are not available until C++17 (while inline
38925   // functions are).
38926   // TODO(altimin): Use inline variable instead after adopting C++17.
kChromeThreadType()38927   static constexpr FieldMetadata_ChromeThreadType kChromeThreadType() { return {}; }
set_chrome_thread_type(::perfetto::protos::pbzero::ThreadDescriptor_ChromeThreadType value)38928   void set_chrome_thread_type(::perfetto::protos::pbzero::ThreadDescriptor_ChromeThreadType value) {
38929     static constexpr uint32_t field_id = FieldMetadata_ChromeThreadType::kFieldId;
38930     // Call the appropriate protozero::Message::Append(field_id, ...)
38931     // method based on the type of the field.
38932     ::protozero::internal::FieldWriter<
38933       ::protozero::proto_utils::ProtoSchemaType::kEnum>
38934         ::Append(*this, field_id, value);
38935   }
38936 
38937   using FieldMetadata_ReferenceTimestampUs =
38938     ::protozero::proto_utils::FieldMetadata<
38939       6,
38940       ::protozero::proto_utils::RepetitionType::kNotRepeated,
38941       ::protozero::proto_utils::ProtoSchemaType::kInt64,
38942       int64_t,
38943       ThreadDescriptor>;
38944 
38945   // Ceci n'est pas une pipe.
38946   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
38947   // type (and users are expected to use it as such, hence kCamelCase name).
38948   // It is declared as a function to keep protozero bindings header-only as
38949   // inline constexpr variables are not available until C++17 (while inline
38950   // functions are).
38951   // TODO(altimin): Use inline variable instead after adopting C++17.
kReferenceTimestampUs()38952   static constexpr FieldMetadata_ReferenceTimestampUs kReferenceTimestampUs() { return {}; }
set_reference_timestamp_us(int64_t value)38953   void set_reference_timestamp_us(int64_t value) {
38954     static constexpr uint32_t field_id = FieldMetadata_ReferenceTimestampUs::kFieldId;
38955     // Call the appropriate protozero::Message::Append(field_id, ...)
38956     // method based on the type of the field.
38957     ::protozero::internal::FieldWriter<
38958       ::protozero::proto_utils::ProtoSchemaType::kInt64>
38959         ::Append(*this, field_id, value);
38960   }
38961 
38962   using FieldMetadata_ReferenceThreadTimeUs =
38963     ::protozero::proto_utils::FieldMetadata<
38964       7,
38965       ::protozero::proto_utils::RepetitionType::kNotRepeated,
38966       ::protozero::proto_utils::ProtoSchemaType::kInt64,
38967       int64_t,
38968       ThreadDescriptor>;
38969 
38970   // Ceci n'est pas une pipe.
38971   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
38972   // type (and users are expected to use it as such, hence kCamelCase name).
38973   // It is declared as a function to keep protozero bindings header-only as
38974   // inline constexpr variables are not available until C++17 (while inline
38975   // functions are).
38976   // TODO(altimin): Use inline variable instead after adopting C++17.
kReferenceThreadTimeUs()38977   static constexpr FieldMetadata_ReferenceThreadTimeUs kReferenceThreadTimeUs() { return {}; }
set_reference_thread_time_us(int64_t value)38978   void set_reference_thread_time_us(int64_t value) {
38979     static constexpr uint32_t field_id = FieldMetadata_ReferenceThreadTimeUs::kFieldId;
38980     // Call the appropriate protozero::Message::Append(field_id, ...)
38981     // method based on the type of the field.
38982     ::protozero::internal::FieldWriter<
38983       ::protozero::proto_utils::ProtoSchemaType::kInt64>
38984         ::Append(*this, field_id, value);
38985   }
38986 
38987   using FieldMetadata_ReferenceThreadInstructionCount =
38988     ::protozero::proto_utils::FieldMetadata<
38989       8,
38990       ::protozero::proto_utils::RepetitionType::kNotRepeated,
38991       ::protozero::proto_utils::ProtoSchemaType::kInt64,
38992       int64_t,
38993       ThreadDescriptor>;
38994 
38995   // Ceci n'est pas une pipe.
38996   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
38997   // type (and users are expected to use it as such, hence kCamelCase name).
38998   // It is declared as a function to keep protozero bindings header-only as
38999   // inline constexpr variables are not available until C++17 (while inline
39000   // functions are).
39001   // TODO(altimin): Use inline variable instead after adopting C++17.
kReferenceThreadInstructionCount()39002   static constexpr FieldMetadata_ReferenceThreadInstructionCount kReferenceThreadInstructionCount() { return {}; }
set_reference_thread_instruction_count(int64_t value)39003   void set_reference_thread_instruction_count(int64_t value) {
39004     static constexpr uint32_t field_id = FieldMetadata_ReferenceThreadInstructionCount::kFieldId;
39005     // Call the appropriate protozero::Message::Append(field_id, ...)
39006     // method based on the type of the field.
39007     ::protozero::internal::FieldWriter<
39008       ::protozero::proto_utils::ProtoSchemaType::kInt64>
39009         ::Append(*this, field_id, value);
39010   }
39011 
39012   using FieldMetadata_LegacySortIndex =
39013     ::protozero::proto_utils::FieldMetadata<
39014       3,
39015       ::protozero::proto_utils::RepetitionType::kNotRepeated,
39016       ::protozero::proto_utils::ProtoSchemaType::kInt32,
39017       int32_t,
39018       ThreadDescriptor>;
39019 
39020   // Ceci n'est pas une pipe.
39021   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
39022   // type (and users are expected to use it as such, hence kCamelCase name).
39023   // It is declared as a function to keep protozero bindings header-only as
39024   // inline constexpr variables are not available until C++17 (while inline
39025   // functions are).
39026   // TODO(altimin): Use inline variable instead after adopting C++17.
kLegacySortIndex()39027   static constexpr FieldMetadata_LegacySortIndex kLegacySortIndex() { return {}; }
set_legacy_sort_index(int32_t value)39028   void set_legacy_sort_index(int32_t value) {
39029     static constexpr uint32_t field_id = FieldMetadata_LegacySortIndex::kFieldId;
39030     // Call the appropriate protozero::Message::Append(field_id, ...)
39031     // method based on the type of the field.
39032     ::protozero::internal::FieldWriter<
39033       ::protozero::proto_utils::ProtoSchemaType::kInt32>
39034         ::Append(*this, field_id, value);
39035   }
39036 };
39037 
39038 } // Namespace.
39039 } // Namespace.
39040 } // Namespace.
39041 #endif  // Include guard.
39042 /*
39043  * Copyright (C) 2020 The Android Open Source Project
39044  *
39045  * Licensed under the Apache License, Version 2.0 (the "License");
39046  * you may not use this file except in compliance with the License.
39047  * You may obtain a copy of the License at
39048  *
39049  *      http://www.apache.org/licenses/LICENSE-2.0
39050  *
39051  * Unless required by applicable law or agreed to in writing, software
39052  * distributed under the License is distributed on an "AS IS" BASIS,
39053  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
39054  * See the License for the specific language governing permissions and
39055  * limitations under the License.
39056  */
39057 
39058 // gen_amalgamated expanded: #include "perfetto/tracing/console_interceptor.h"
39059 
39060 #include <stdarg.h>
39061 
39062 #include <algorithm>
39063 #include <cmath>
39064 #include <tuple>
39065 
39066 // gen_amalgamated expanded: #include "perfetto/ext/base/file_utils.h"
39067 // gen_amalgamated expanded: #include "perfetto/ext/base/hash.h"
39068 // gen_amalgamated expanded: #include "perfetto/ext/base/optional.h"
39069 // gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"
39070 // gen_amalgamated expanded: #include "perfetto/ext/base/string_utils.h"
39071 // gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
39072 // gen_amalgamated expanded: #include "perfetto/tracing/internal/track_event_internal.h"
39073 
39074 // gen_amalgamated expanded: #include "protos/perfetto/common/interceptor_descriptor.gen.h"
39075 // gen_amalgamated expanded: #include "protos/perfetto/config/data_source_config.gen.h"
39076 // gen_amalgamated expanded: #include "protos/perfetto/config/interceptor_config.gen.h"
39077 // gen_amalgamated expanded: #include "protos/perfetto/config/interceptors/console_config.pbzero.h"
39078 // gen_amalgamated expanded: #include "protos/perfetto/trace/interned_data/interned_data.pbzero.h"
39079 // gen_amalgamated expanded: #include "protos/perfetto/trace/trace_packet.pbzero.h"
39080 // gen_amalgamated expanded: #include "protos/perfetto/trace/trace_packet_defaults.pbzero.h"
39081 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/process_descriptor.pbzero.h"
39082 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/thread_descriptor.pbzero.h"
39083 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/track_descriptor.pbzero.h"
39084 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/track_event.pbzero.h"
39085 
39086 namespace perfetto {
39087 
39088 // sRGB color.
39089 struct ConsoleColor {
39090   uint8_t r;
39091   uint8_t g;
39092   uint8_t b;
39093 };
39094 
39095 namespace {
39096 
39097 int g_output_fd_for_testing;
39098 
39099 // Google Turbo colormap.
39100 constexpr std::array<ConsoleColor, 16> kTurboColors = {{
39101     ConsoleColor{0x30, 0x12, 0x3b},
39102     ConsoleColor{0x40, 0x40, 0xa1},
39103     ConsoleColor{0x46, 0x6b, 0xe3},
39104     ConsoleColor{0x41, 0x93, 0xfe},
39105     ConsoleColor{0x28, 0xbb, 0xeb},
39106     ConsoleColor{0x17, 0xdc, 0xc2},
39107     ConsoleColor{0x32, 0xf1, 0x97},
39108     ConsoleColor{0x6d, 0xfd, 0x62},
39109     ConsoleColor{0xa4, 0xfc, 0x3b},
39110     ConsoleColor{0xcd, 0xeb, 0x34},
39111     ConsoleColor{0xed, 0xcf, 0x39},
39112     ConsoleColor{0xfd, 0xab, 0x33},
39113     ConsoleColor{0xfa, 0x7d, 0x20},
39114     ConsoleColor{0xea, 0x50, 0x0d},
39115     ConsoleColor{0xd0, 0x2f, 0x04},
39116     ConsoleColor{0xa9, 0x15, 0x01},
39117 }};
39118 
39119 constexpr size_t kHueBits = 4;
39120 constexpr uint32_t kMaxHue = kTurboColors.size() << kHueBits;
39121 constexpr uint8_t kLightness = 128u;
39122 constexpr ConsoleColor kWhiteColor{0xff, 0xff, 0xff};
39123 
39124 const char kDim[] = "\x1b[90m";
39125 const char kDefault[] = "\x1b[39m";
39126 const char kReset[] = "\x1b[0m";
39127 
39128 #define FMT_RGB_SET "\x1b[38;2;%d;%d;%dm"
39129 #define FMT_RGB_SET_BG "\x1b[48;2;%d;%d;%dm"
39130 
Mix(ConsoleColor a,ConsoleColor b,uint8_t ratio)39131 ConsoleColor Mix(ConsoleColor a, ConsoleColor b, uint8_t ratio) {
39132   return {
39133       static_cast<uint8_t>(a.r + (((b.r - a.r) * ratio) >> 8)),
39134       static_cast<uint8_t>(a.g + (((b.g - a.g) * ratio) >> 8)),
39135       static_cast<uint8_t>(a.b + (((b.b - a.b) * ratio) >> 8)),
39136   };
39137 }
39138 
HueToRGB(uint32_t hue)39139 ConsoleColor HueToRGB(uint32_t hue) {
39140   PERFETTO_DCHECK(hue < kMaxHue);
39141   uint32_t c1 = hue >> kHueBits;
39142   uint32_t c2 =
39143       std::min(static_cast<uint32_t>(kTurboColors.size() - 1), c1 + 1u);
39144   uint32_t ratio = hue & ((1 << kHueBits) - 1);
39145   return Mix(kTurboColors[c1], kTurboColors[c2],
39146              static_cast<uint8_t>(ratio | (ratio << kHueBits)));
39147 }
39148 
CounterToHue(uint32_t counter)39149 uint32_t CounterToHue(uint32_t counter) {
39150   // We split the hue space into 8 segments, reversing the order of bits so
39151   // successive counter values will be far from each other.
39152   uint32_t reversed =
39153       ((counter & 0x7) >> 2) | ((counter & 0x3)) | ((counter & 0x1) << 2);
39154   return reversed * kMaxHue / 8;
39155 }
39156 
39157 }  // namespace
39158 
39159 class ConsoleInterceptor::Delegate : public TrackEventStateTracker::Delegate {
39160  public:
39161   explicit Delegate(InterceptorContext&);
39162   ~Delegate() override;
39163 
39164   TrackEventStateTracker::SessionState* GetSessionState() override;
39165   void OnTrackUpdated(TrackEventStateTracker::Track&) override;
39166   void OnTrackEvent(const TrackEventStateTracker::Track&,
39167                     const TrackEventStateTracker::ParsedTrackEvent&) override;
39168 
39169  private:
39170   using SelfHandle = LockedHandle<ConsoleInterceptor>;
39171 
39172   InterceptorContext& context_;
39173   base::Optional<SelfHandle> locked_self_;
39174 };
39175 
39176 ConsoleInterceptor::~ConsoleInterceptor() = default;
39177 
ThreadLocalState(ThreadLocalStateArgs & args)39178 ConsoleInterceptor::ThreadLocalState::ThreadLocalState(
39179     ThreadLocalStateArgs& args) {
39180   if (auto self = args.GetInterceptorLocked()) {
39181     start_time_ns = self->start_time_ns_;
39182     use_colors = self->use_colors_;
39183     fd = self->fd_;
39184   }
39185 }
39186 
39187 ConsoleInterceptor::ThreadLocalState::~ThreadLocalState() = default;
39188 
Delegate(InterceptorContext & context)39189 ConsoleInterceptor::Delegate::Delegate(InterceptorContext& context)
39190     : context_(context) {}
39191 ConsoleInterceptor::Delegate::~Delegate() = default;
39192 
39193 TrackEventStateTracker::SessionState*
GetSessionState()39194 ConsoleInterceptor::Delegate::GetSessionState() {
39195   // When the session state is retrieved for the first time, it is cached (and
39196   // kept locked) until we return from OnTracePacket. This avoids having to lock
39197   // and unlock the instance multiple times per invocation.
39198   if (locked_self_.has_value())
39199     return &locked_self_.value()->session_state_;
39200   locked_self_ =
39201       base::make_optional<SelfHandle>(context_.GetInterceptorLocked());
39202   return &locked_self_.value()->session_state_;
39203 }
39204 
OnTrackUpdated(TrackEventStateTracker::Track & track)39205 void ConsoleInterceptor::Delegate::OnTrackUpdated(
39206     TrackEventStateTracker::Track& track) {
39207   auto track_color = HueToRGB(CounterToHue(track.index));
39208   std::array<char, 16> title;
39209   if (!track.name.empty()) {
39210     snprintf(title.data(), title.size(), "%s", track.name.c_str());
39211   } else if (track.pid && track.tid) {
39212     snprintf(title.data(), title.size(), "%u:%u",
39213              static_cast<uint32_t>(track.pid),
39214              static_cast<uint32_t>(track.tid));
39215   } else if (track.pid) {
39216     snprintf(title.data(), title.size(), "%" PRId64, track.pid);
39217   } else {
39218     snprintf(title.data(), title.size(), "%" PRIu64, track.uuid);
39219   }
39220   int title_width = static_cast<int>(title.size());
39221 
39222   auto& tls = context_.GetThreadLocalState();
39223   std::array<char, 128> message_prefix{};
39224   size_t written = 0;
39225   if (tls.use_colors) {
39226     written = base::SprintfTrunc(message_prefix.data(), message_prefix.size(),
39227                                  FMT_RGB_SET_BG " %s%s %-*.*s", track_color.r,
39228                                  track_color.g, track_color.b, kReset, kDim,
39229                                  title_width, title_width, title.data());
39230   } else {
39231     written = base::SprintfTrunc(message_prefix.data(), message_prefix.size(),
39232                                  "%-*.*s", title_width + 2, title_width,
39233                                  title.data());
39234   }
39235   track.user_data.assign(message_prefix.begin(),
39236                          message_prefix.begin() + written);
39237 }
39238 
OnTrackEvent(const TrackEventStateTracker::Track & track,const TrackEventStateTracker::ParsedTrackEvent & event)39239 void ConsoleInterceptor::Delegate::OnTrackEvent(
39240     const TrackEventStateTracker::Track& track,
39241     const TrackEventStateTracker::ParsedTrackEvent& event) {
39242   // Start printing.
39243   auto& tls = context_.GetThreadLocalState();
39244   tls.buffer_pos = 0;
39245 
39246   // Print timestamp and track identifier.
39247   SetColor(context_, kDim);
39248   Printf(context_, "[%7.3lf] %.*s",
39249          static_cast<double>(event.timestamp_ns - tls.start_time_ns) / 1e9,
39250          static_cast<int>(track.user_data.size()), track.user_data.data());
39251 
39252   // Print category.
39253   Printf(context_, "%-5.*s ",
39254          std::min(5, static_cast<int>(event.category.size)),
39255          event.category.data);
39256 
39257   // Print stack depth.
39258   for (size_t i = 0; i < event.stack_depth; i++) {
39259     Printf(context_, "-  ");
39260   }
39261 
39262   // Print slice name.
39263   auto slice_color = HueToRGB(event.name_hash % kMaxHue);
39264   auto highlight_color = Mix(slice_color, kWhiteColor, kLightness);
39265   if (event.track_event.type() == protos::pbzero::TrackEvent::TYPE_SLICE_END) {
39266     SetColor(context_, kDefault);
39267     Printf(context_, "} ");
39268   }
39269   SetColor(context_, highlight_color);
39270   Printf(context_, "%.*s", static_cast<int>(event.name.size), event.name.data);
39271   SetColor(context_, kReset);
39272   if (event.track_event.type() ==
39273       protos::pbzero::TrackEvent::TYPE_SLICE_BEGIN) {
39274     SetColor(context_, kDefault);
39275     Printf(context_, " {");
39276   }
39277 
39278   // Print annotations.
39279   if (event.track_event.has_debug_annotations()) {
39280     PrintDebugAnnotations(context_, event.track_event, slice_color,
39281                           highlight_color);
39282   }
39283 
39284   // TODO(skyostil): Print typed arguments.
39285 
39286   // Print duration for longer events.
39287   constexpr uint64_t kNsPerMillisecond = 1000000u;
39288   if (event.duration_ns >= 10 * kNsPerMillisecond) {
39289     SetColor(context_, kDim);
39290     Printf(context_, " +%" PRIu64 "ms", event.duration_ns / kNsPerMillisecond);
39291   }
39292   SetColor(context_, kReset);
39293   Printf(context_, "\n");
39294 }
39295 
39296 // static
Register()39297 void ConsoleInterceptor::Register() {
39298   perfetto::protos::gen::InterceptorDescriptor desc;
39299   desc.set_name("console");
39300   Interceptor<ConsoleInterceptor>::Register(desc);
39301 }
39302 
39303 // static
SetOutputFdForTesting(int fd)39304 void ConsoleInterceptor::SetOutputFdForTesting(int fd) {
39305   g_output_fd_for_testing = fd;
39306 }
39307 
OnSetup(const SetupArgs & args)39308 void ConsoleInterceptor::OnSetup(const SetupArgs& args) {
39309   int fd = STDOUT_FILENO;
39310   if (g_output_fd_for_testing)
39311     fd = g_output_fd_for_testing;
39312 #if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) && \
39313     !PERFETTO_BUILDFLAG(PERFETTO_OS_WASM)
39314   bool use_colors = isatty(fd);
39315 #else
39316   bool use_colors = false;
39317 #endif
39318   protos::pbzero::ConsoleConfig::Decoder config(
39319       args.config.interceptor_config().console_config_raw());
39320   if (config.has_enable_colors())
39321     use_colors = config.enable_colors();
39322   if (config.output() == protos::pbzero::ConsoleConfig::OUTPUT_STDOUT) {
39323     fd = STDOUT_FILENO;
39324   } else if (config.output() == protos::pbzero::ConsoleConfig::OUTPUT_STDERR) {
39325     fd = STDERR_FILENO;
39326   }
39327   fd_ = fd;
39328   use_colors_ = use_colors;
39329 }
39330 
OnStart(const StartArgs &)39331 void ConsoleInterceptor::OnStart(const StartArgs&) {
39332   start_time_ns_ = internal::TrackEventInternal::GetTimeNs();
39333 }
39334 
OnStop(const StopArgs &)39335 void ConsoleInterceptor::OnStop(const StopArgs&) {}
39336 
39337 // static
OnTracePacket(InterceptorContext context)39338 void ConsoleInterceptor::OnTracePacket(InterceptorContext context) {
39339   {
39340     auto& tls = context.GetThreadLocalState();
39341     Delegate delegate(context);
39342     perfetto::protos::pbzero::TracePacket::Decoder packet(
39343         context.packet_data.data, context.packet_data.size);
39344     TrackEventStateTracker::ProcessTracePacket(delegate, tls.sequence_state,
39345                                                packet);
39346   }  // (Potential) lock scope for session state.
39347   Flush(context);
39348 }
39349 
39350 // static
Printf(InterceptorContext & context,const char * format,...)39351 void ConsoleInterceptor::Printf(InterceptorContext& context,
39352                                 const char* format,
39353                                 ...) {
39354   auto& tls = context.GetThreadLocalState();
39355   ssize_t remaining = static_cast<ssize_t>(tls.message_buffer.size()) -
39356                       static_cast<ssize_t>(tls.buffer_pos);
39357   int written = 0;
39358   if (remaining > 0) {
39359     va_list args;
39360     va_start(args, format);
39361     written = vsnprintf(&tls.message_buffer[tls.buffer_pos],
39362                         static_cast<size_t>(remaining), format, args);
39363     PERFETTO_DCHECK(written >= 0);
39364     va_end(args);
39365   }
39366 
39367   // In case of buffer overflow, flush to the fd and write the latest message to
39368   // it directly instead.
39369   if (remaining <= 0 || written > remaining) {
39370     FILE* output = (tls.fd == STDOUT_FILENO) ? stdout : stderr;
39371     if (g_output_fd_for_testing) {
39372       output = fdopen(dup(g_output_fd_for_testing), "w");
39373     }
39374     Flush(context);
39375     va_list args;
39376     va_start(args, format);
39377     vfprintf(output, format, args);
39378     va_end(args);
39379     if (g_output_fd_for_testing) {
39380       fclose(output);
39381     }
39382   } else if (written > 0) {
39383     tls.buffer_pos += static_cast<size_t>(written);
39384   }
39385 }
39386 
39387 // static
Flush(InterceptorContext & context)39388 void ConsoleInterceptor::Flush(InterceptorContext& context) {
39389   auto& tls = context.GetThreadLocalState();
39390   ssize_t res = base::WriteAll(tls.fd, &tls.message_buffer[0], tls.buffer_pos);
39391   PERFETTO_DCHECK(res == static_cast<ssize_t>(tls.buffer_pos));
39392   tls.buffer_pos = 0;
39393 }
39394 
39395 // static
SetColor(InterceptorContext & context,const ConsoleColor & color)39396 void ConsoleInterceptor::SetColor(InterceptorContext& context,
39397                                   const ConsoleColor& color) {
39398   auto& tls = context.GetThreadLocalState();
39399   if (!tls.use_colors)
39400     return;
39401   Printf(context, FMT_RGB_SET, color.r, color.g, color.b);
39402 }
39403 
39404 // static
SetColor(InterceptorContext & context,const char * color)39405 void ConsoleInterceptor::SetColor(InterceptorContext& context,
39406                                   const char* color) {
39407   auto& tls = context.GetThreadLocalState();
39408   if (!tls.use_colors)
39409     return;
39410   Printf(context, "%s", color);
39411 }
39412 
39413 // static
PrintDebugAnnotations(InterceptorContext & context,const protos::pbzero::TrackEvent_Decoder & track_event,const ConsoleColor & slice_color,const ConsoleColor & highlight_color)39414 void ConsoleInterceptor::PrintDebugAnnotations(
39415     InterceptorContext& context,
39416     const protos::pbzero::TrackEvent_Decoder& track_event,
39417     const ConsoleColor& slice_color,
39418     const ConsoleColor& highlight_color) {
39419   SetColor(context, slice_color);
39420   Printf(context, "(");
39421 
39422   bool is_first = true;
39423   for (auto it = track_event.debug_annotations(); it; it++) {
39424     perfetto::protos::pbzero::DebugAnnotation::Decoder annotation(*it);
39425     SetColor(context, slice_color);
39426     if (!is_first)
39427       Printf(context, ", ");
39428 
39429     PrintDebugAnnotationName(context, annotation);
39430     Printf(context, ":");
39431 
39432     SetColor(context, highlight_color);
39433     PrintDebugAnnotationValue(context, annotation);
39434 
39435     is_first = false;
39436   }
39437   SetColor(context, slice_color);
39438   Printf(context, ")");
39439 }
39440 
39441 // static
PrintDebugAnnotationName(InterceptorContext & context,const perfetto::protos::pbzero::DebugAnnotation::Decoder & annotation)39442 void ConsoleInterceptor::PrintDebugAnnotationName(
39443     InterceptorContext& context,
39444     const perfetto::protos::pbzero::DebugAnnotation::Decoder& annotation) {
39445   auto& tls = context.GetThreadLocalState();
39446   protozero::ConstChars name{};
39447   if (annotation.name_iid()) {
39448     name.data =
39449         tls.sequence_state.debug_annotation_names[annotation.name_iid()].data();
39450     name.size =
39451         tls.sequence_state.debug_annotation_names[annotation.name_iid()].size();
39452   } else if (annotation.has_name()) {
39453     name.data = annotation.name().data;
39454     name.size = annotation.name().size;
39455   }
39456   Printf(context, "%.*s", static_cast<int>(name.size), name.data);
39457 }
39458 
39459 // static
PrintDebugAnnotationValue(InterceptorContext & context,const perfetto::protos::pbzero::DebugAnnotation::Decoder & annotation)39460 void ConsoleInterceptor::PrintDebugAnnotationValue(
39461     InterceptorContext& context,
39462     const perfetto::protos::pbzero::DebugAnnotation::Decoder& annotation) {
39463   if (annotation.has_bool_value()) {
39464     Printf(context, "%s", annotation.bool_value() ? "true" : "false");
39465   } else if (annotation.has_uint_value()) {
39466     Printf(context, "%" PRIu64, annotation.uint_value());
39467   } else if (annotation.has_int_value()) {
39468     Printf(context, "%" PRId64, annotation.int_value());
39469   } else if (annotation.has_double_value()) {
39470     Printf(context, "%f", annotation.double_value());
39471   } else if (annotation.has_string_value()) {
39472     Printf(context, "%.*s", static_cast<int>(annotation.string_value().size),
39473            annotation.string_value().data);
39474   } else if (annotation.has_pointer_value()) {
39475     Printf(context, "%p", reinterpret_cast<void*>(annotation.pointer_value()));
39476   } else if (annotation.has_legacy_json_value()) {
39477     Printf(context, "%.*s",
39478            static_cast<int>(annotation.legacy_json_value().size),
39479            annotation.legacy_json_value().data);
39480   } else if (annotation.has_dict_entries()) {
39481     Printf(context, "{");
39482     bool is_first = true;
39483     for (auto it = annotation.dict_entries(); it; ++it) {
39484       if (!is_first)
39485         Printf(context, ", ");
39486       perfetto::protos::pbzero::DebugAnnotation::Decoder key_value(*it);
39487       PrintDebugAnnotationName(context, key_value);
39488       Printf(context, ":");
39489       PrintDebugAnnotationValue(context, key_value);
39490       is_first = false;
39491     }
39492     Printf(context, "}");
39493   } else if (annotation.has_array_values()) {
39494     Printf(context, "[");
39495     bool is_first = true;
39496     for (auto it = annotation.array_values(); it; ++it) {
39497       if (!is_first)
39498         Printf(context, ", ");
39499       perfetto::protos::pbzero::DebugAnnotation::Decoder key_value(*it);
39500       PrintDebugAnnotationValue(context, key_value);
39501       is_first = false;
39502     }
39503     Printf(context, "]");
39504   } else {
39505     Printf(context, "{}");
39506   }
39507 }
39508 
39509 }  // namespace perfetto
39510 // gen_amalgamated begin source: src/tracing/data_source.cc
39511 /*
39512  * Copyright (C) 2019 The Android Open Source Project
39513  *
39514  * Licensed under the Apache License, Version 2.0 (the "License");
39515  * you may not use this file except in compliance with the License.
39516  * You may obtain a copy of the License at
39517  *
39518  *      http://www.apache.org/licenses/LICENSE-2.0
39519  *
39520  * Unless required by applicable law or agreed to in writing, software
39521  * distributed under the License is distributed on an "AS IS" BASIS,
39522  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
39523  * See the License for the specific language governing permissions and
39524  * limitations under the License.
39525  */
39526 
39527 // gen_amalgamated expanded: #include "perfetto/tracing/data_source.h"
39528 
39529 namespace perfetto {
39530 
39531 DataSourceBase::StopArgs::~StopArgs() = default;
39532 DataSourceBase::~DataSourceBase() = default;
OnSetup(const SetupArgs &)39533 void DataSourceBase::OnSetup(const SetupArgs&) {}
OnStart(const StartArgs &)39534 void DataSourceBase::OnStart(const StartArgs&) {}
OnStop(const StopArgs &)39535 void DataSourceBase::OnStop(const StopArgs&) {}
39536 
39537 }  // namespace perfetto
39538 // gen_amalgamated begin source: src/tracing/debug_annotation.cc
39539 /*
39540  * Copyright (C) 2019 The Android Open Source Project
39541  *
39542  * Licensed under the Apache License, Version 2.0 (the "License");
39543  * you may not use this file except in compliance with the License.
39544  * You may obtain a copy of the License at
39545  *
39546  *      http://www.apache.org/licenses/LICENSE-2.0
39547  *
39548  * Unless required by applicable law or agreed to in writing, software
39549  * distributed under the License is distributed on an "AS IS" BASIS,
39550  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
39551  * See the License for the specific language governing permissions and
39552  * limitations under the License.
39553  */
39554 
39555 // gen_amalgamated expanded: #include "perfetto/tracing/debug_annotation.h"
39556 
39557 // gen_amalgamated expanded: #include "perfetto/tracing/traced_value.h"
39558 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/debug_annotation.pbzero.h"
39559 
39560 namespace perfetto {
39561 
39562 DebugAnnotation::~DebugAnnotation() = default;
39563 
WriteIntoTracedValue(TracedValue context) const39564 void DebugAnnotation::WriteIntoTracedValue(TracedValue context) const {
39565   Add(context.context_);
39566 }
39567 
39568 }  // namespace perfetto
39569 // gen_amalgamated begin source: src/tracing/event_context.cc
39570 // gen_amalgamated begin header: include/perfetto/tracing/internal/track_event_interned_fields.h
39571 /*
39572  * Copyright (C) 2021 The Android Open Source Project
39573  *
39574  * Licensed under the Apache License, Version 2.0 (the "License");
39575  * you may not use this file except in compliance with the License.
39576  * You may obtain a copy of the License at
39577  *
39578  *      http://www.apache.org/licenses/LICENSE-2.0
39579  *
39580  * Unless required by applicable law or agreed to in writing, software
39581  * distributed under the License is distributed on an "AS IS" BASIS,
39582  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
39583  * See the License for the specific language governing permissions and
39584  * limitations under the License.
39585  */
39586 
39587 // gen_amalgamated expanded: #include "perfetto/base/export.h"
39588 // gen_amalgamated expanded: #include "perfetto/tracing/track_event_interned_data_index.h"
39589 
39590 #ifndef INCLUDE_PERFETTO_TRACING_INTERNAL_TRACK_EVENT_INTERNED_FIELDS_H_
39591 #define INCLUDE_PERFETTO_TRACING_INTERNAL_TRACK_EVENT_INTERNED_FIELDS_H_
39592 
39593 namespace perfetto {
39594 namespace internal {
39595 
39596 // These helpers are exposed here to allow Chromium-without-client library
39597 // to share the interning buffers with Perfetto internals (e.g.
39598 // perfetto::TracedValue implementation).
39599 
39600 struct PERFETTO_EXPORT InternedEventCategory
39601     : public TrackEventInternedDataIndex<
39602           InternedEventCategory,
39603           perfetto::protos::pbzero::InternedData::kEventCategoriesFieldNumber,
39604           const char*,
39605           SmallInternedDataTraits> {
39606   ~InternedEventCategory() override;
39607 
39608   static void Add(protos::pbzero::InternedData* interned_data,
39609                   size_t iid,
39610                   const char* value,
39611                   size_t length);
39612 };
39613 
39614 struct PERFETTO_EXPORT InternedEventName
39615     : public TrackEventInternedDataIndex<
39616           InternedEventName,
39617           perfetto::protos::pbzero::InternedData::kEventNamesFieldNumber,
39618           const char*,
39619           SmallInternedDataTraits> {
39620   ~InternedEventName() override;
39621 
39622   static void Add(protos::pbzero::InternedData* interned_data,
39623                   size_t iid,
39624                   const char* value);
39625 };
39626 
39627 struct PERFETTO_EXPORT InternedDebugAnnotationName
39628     : public TrackEventInternedDataIndex<
39629           InternedDebugAnnotationName,
39630           perfetto::protos::pbzero::InternedData::
39631               kDebugAnnotationNamesFieldNumber,
39632           const char*,
39633           SmallInternedDataTraits> {
39634   ~InternedDebugAnnotationName() override;
39635 
39636   static void Add(protos::pbzero::InternedData* interned_data,
39637                   size_t iid,
39638                   const char* value);
39639 };
39640 
39641 }  // namespace internal
39642 }  // namespace perfetto
39643 
39644 #endif  // INCLUDE_PERFETTO_TRACING_INTERNAL_TRACK_EVENT_INTERNED_FIELDS_H_
39645 /*
39646  * Copyright (C) 2019 The Android Open Source Project
39647  *
39648  * Licensed under the Apache License, Version 2.0 (the "License");
39649  * you may not use this file except in compliance with the License.
39650  * You may obtain a copy of the License at
39651  *
39652  *      http://www.apache.org/licenses/LICENSE-2.0
39653  *
39654  * Unless required by applicable law or agreed to in writing, software
39655  * distributed under the License is distributed on an "AS IS" BASIS,
39656  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
39657  * See the License for the specific language governing permissions and
39658  * limitations under the License.
39659  */
39660 
39661 // gen_amalgamated expanded: #include "perfetto/tracing/event_context.h"
39662 
39663 // gen_amalgamated expanded: #include "perfetto/tracing/internal/track_event_interned_fields.h"
39664 // gen_amalgamated expanded: #include "protos/perfetto/trace/interned_data/interned_data.pbzero.h"
39665 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/track_event.pbzero.h"
39666 
39667 namespace perfetto {
39668 
EventContext(EventContext::TracePacketHandle trace_packet,internal::TrackEventIncrementalState * incremental_state)39669 EventContext::EventContext(
39670     EventContext::TracePacketHandle trace_packet,
39671     internal::TrackEventIncrementalState* incremental_state)
39672     : trace_packet_(std::move(trace_packet)),
39673       event_(trace_packet_->set_track_event()),
39674       incremental_state_(incremental_state) {}
39675 
~EventContext()39676 EventContext::~EventContext() {
39677   if (!trace_packet_)
39678     return;
39679 
39680   // When the track event is finalized (i.e., the context is destroyed), we
39681   // should flush any newly seen interned data to the trace. The data has
39682   // earlier been written to a heap allocated protobuf message
39683   // (|serialized_interned_data|). Here we just need to flush it to the main
39684   // trace.
39685   auto& serialized_interned_data = incremental_state_->serialized_interned_data;
39686   if (PERFETTO_LIKELY(serialized_interned_data.empty()))
39687     return;
39688 
39689   auto ranges = serialized_interned_data.GetRanges();
39690   trace_packet_->AppendScatteredBytes(
39691       perfetto::protos::pbzero::TracePacket::kInternedDataFieldNumber,
39692       &ranges[0], ranges.size());
39693 
39694   // Reset the message but keep one buffer allocated for future use.
39695   serialized_interned_data.Reset();
39696 }
39697 
AddDebugAnnotation(const char * name)39698 protos::pbzero::DebugAnnotation* EventContext::AddDebugAnnotation(
39699     const char* name) {
39700   auto annotation = event()->add_debug_annotations();
39701   annotation->set_name_iid(
39702       internal::InternedDebugAnnotationName::Get(this, name));
39703   return annotation;
39704 }
39705 
39706 }  // namespace perfetto
39707 // gen_amalgamated begin source: src/tracing/interceptor.cc
39708 /*
39709  * Copyright (C) 2020 The Android Open Source Project
39710  *
39711  * Licensed under the Apache License, Version 2.0 (the "License");
39712  * you may not use this file except in compliance with the License.
39713  * You may obtain a copy of the License at
39714  *
39715  *      http://www.apache.org/licenses/LICENSE-2.0
39716  *
39717  * Unless required by applicable law or agreed to in writing, software
39718  * distributed under the License is distributed on an "AS IS" BASIS,
39719  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
39720  * See the License for the specific language governing permissions and
39721  * limitations under the License.
39722  */
39723 
39724 // gen_amalgamated expanded: #include "perfetto/tracing/interceptor.h"
39725 
39726 // gen_amalgamated expanded: #include "perfetto/tracing/internal/tracing_muxer.h"
39727 
39728 namespace perfetto {
39729 
39730 InterceptorBase::~InterceptorBase() = default;
39731 InterceptorBase::ThreadLocalState::~ThreadLocalState() = default;
39732 
39733 // static
RegisterImpl(const InterceptorDescriptor & descriptor,std::function<std::unique_ptr<InterceptorBase> ()> factory,InterceptorBase::TLSFactory tls_factory,InterceptorBase::TracePacketCallback on_trace_packet)39734 void InterceptorBase::RegisterImpl(
39735     const InterceptorDescriptor& descriptor,
39736     std::function<std::unique_ptr<InterceptorBase>()> factory,
39737     InterceptorBase::TLSFactory tls_factory,
39738     InterceptorBase::TracePacketCallback on_trace_packet) {
39739   auto* tracing_impl = internal::TracingMuxer::Get();
39740   tracing_impl->RegisterInterceptor(descriptor, factory, tls_factory,
39741                                     on_trace_packet);
39742 }
39743 
39744 }  // namespace perfetto
39745 // gen_amalgamated begin source: src/tracing/internal/checked_scope.cc
39746 /*
39747  * Copyright (C) 2021 The Android Open Source Project
39748  *
39749  * Licensed under the Apache License, Version 2.0 (the "License");
39750  * you may not use this file except in compliance with the License.
39751  * You may obtain a copy of the License at
39752  *
39753  *      http://www.apache.org/licenses/LICENSE-2.0
39754  *
39755  * Unless required by applicable law or agreed to in writing, software
39756  * distributed under the License is distributed on an "AS IS" BASIS,
39757  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
39758  * See the License for the specific language governing permissions and
39759  * limitations under the License.
39760  */
39761 
39762 // gen_amalgamated expanded: #include "perfetto/tracing/internal/checked_scope.h"
39763 
39764 #include <utility>
39765 
39766 namespace perfetto {
39767 namespace internal {
39768 
39769 #if PERFETTO_DCHECK_IS_ON()
CheckedScope(CheckedScope * parent_scope)39770 CheckedScope::CheckedScope(CheckedScope* parent_scope)
39771     : parent_scope_(parent_scope) {
39772   if (parent_scope_) {
39773     PERFETTO_DCHECK(parent_scope_->is_active());
39774     parent_scope_->set_is_active(false);
39775   }
39776 }
39777 
~CheckedScope()39778 CheckedScope::~CheckedScope() {
39779   Reset();
39780 }
39781 
Reset()39782 void CheckedScope::Reset() {
39783   if (!is_active_) {
39784     // The only case when inactive scope could be destroyed is when Reset() was
39785     // called explicitly or the contents of the object were moved away.
39786     PERFETTO_DCHECK(deleted_);
39787     return;
39788   }
39789   is_active_ = false;
39790   deleted_ = true;
39791   if (parent_scope_)
39792     parent_scope_->set_is_active(true);
39793 }
39794 
CheckedScope(CheckedScope && other)39795 CheckedScope::CheckedScope(CheckedScope&& other) {
39796   *this = std::move(other);
39797 }
39798 
operator =(CheckedScope && other)39799 CheckedScope& CheckedScope::operator=(CheckedScope&& other) {
39800   is_active_ = other.is_active_;
39801   parent_scope_ = other.parent_scope_;
39802   deleted_ = other.deleted_;
39803 
39804   other.is_active_ = false;
39805   other.parent_scope_ = nullptr;
39806   other.deleted_ = true;
39807 
39808   return *this;
39809 }
39810 #endif
39811 
39812 }  // namespace internal
39813 }  // namespace perfetto
39814 // gen_amalgamated begin source: src/tracing/internal/interceptor_trace_writer.cc
39815 // gen_amalgamated begin header: include/perfetto/tracing/internal/interceptor_trace_writer.h
39816 /*
39817  * Copyright (C) 2020 The Android Open Source Project
39818  *
39819  * Licensed under the Apache License, Version 2.0 (the "License");
39820  * you may not use this file except in compliance with the License.
39821  * You may obtain a copy of the License at
39822  *
39823  *      http://www.apache.org/licenses/LICENSE-2.0
39824  *
39825  * Unless required by applicable law or agreed to in writing, software
39826  * distributed under the License is distributed on an "AS IS" BASIS,
39827  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
39828  * See the License for the specific language governing permissions and
39829  * limitations under the License.
39830  */
39831 
39832 #ifndef INCLUDE_PERFETTO_TRACING_INTERNAL_INTERCEPTOR_TRACE_WRITER_H_
39833 #define INCLUDE_PERFETTO_TRACING_INTERNAL_INTERCEPTOR_TRACE_WRITER_H_
39834 
39835 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
39836 // gen_amalgamated expanded: #include "perfetto/tracing/interceptor.h"
39837 // gen_amalgamated expanded: #include "perfetto/tracing/internal/basic_types.h"
39838 // gen_amalgamated expanded: #include "perfetto/tracing/trace_writer_base.h"
39839 // gen_amalgamated expanded: #include "protos/perfetto/trace/trace_packet.pbzero.h"
39840 
39841 namespace perfetto {
39842 namespace internal {
39843 
39844 // A heap-backed trace writer used to reroute trace packets to an interceptor.
39845 class InterceptorTraceWriter : public TraceWriterBase {
39846  public:
39847   InterceptorTraceWriter(std::unique_ptr<InterceptorBase::ThreadLocalState> tls,
39848                          InterceptorBase::TracePacketCallback packet_callback,
39849                          DataSourceStaticState* static_state,
39850                          uint32_t instance_index);
39851   ~InterceptorTraceWriter() override;
39852 
39853   // TraceWriterBase implementation.
39854   protozero::MessageHandle<protos::pbzero::TracePacket> NewTracePacket()
39855       override;
39856   void Flush(std::function<void()> callback = {}) override;
39857   uint64_t written() const override;
39858 
39859  private:
39860   std::unique_ptr<InterceptorBase::ThreadLocalState> tls_;
39861   InterceptorBase::TracePacketCallback packet_callback_;
39862 
39863   protozero::HeapBuffered<protos::pbzero::TracePacket> cur_packet_;
39864   uint64_t bytes_written_ = 0;
39865 
39866   // Static state of the data source we are intercepting.
39867   DataSourceStaticState* const static_state_;
39868 
39869   // Index of the data source tracing session which we are intercepting
39870   // (0...kMaxDataSourceInstances - 1). Used to look up this interceptor's
39871   // session state (i.e., the Interceptor class instance) in the
39872   // DataSourceStaticState::instances array.
39873   const uint32_t instance_index_;
39874 
39875   const uint32_t sequence_id_;
39876 
39877   static std::atomic<uint32_t> next_sequence_id_;
39878 };
39879 
39880 }  // namespace internal
39881 }  // namespace perfetto
39882 
39883 #endif  // INCLUDE_PERFETTO_TRACING_INTERNAL_INTERCEPTOR_TRACE_WRITER_H_
39884 /*
39885  * Copyright (C) 2020 The Android Open Source Project
39886  *
39887  * Licensed under the Apache License, Version 2.0 (the "License");
39888  * you may not use this file except in compliance with the License.
39889  * You may obtain a copy of the License at
39890  *
39891  *      http://www.apache.org/licenses/LICENSE-2.0
39892  *
39893  * Unless required by applicable law or agreed to in writing, software
39894  * distributed under the License is distributed on an "AS IS" BASIS,
39895  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
39896  * See the License for the specific language governing permissions and
39897  * limitations under the License.
39898  */
39899 
39900 // gen_amalgamated expanded: #include "perfetto/tracing/internal/interceptor_trace_writer.h"
39901 
39902 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/trace_writer.h"
39903 
39904 namespace perfetto {
39905 namespace internal {
39906 
39907 // static
39908 std::atomic<uint32_t> InterceptorTraceWriter::next_sequence_id_{};
39909 
InterceptorTraceWriter(std::unique_ptr<InterceptorBase::ThreadLocalState> tls,InterceptorBase::TracePacketCallback packet_callback,DataSourceStaticState * static_state,uint32_t instance_index)39910 InterceptorTraceWriter::InterceptorTraceWriter(
39911     std::unique_ptr<InterceptorBase::ThreadLocalState> tls,
39912     InterceptorBase::TracePacketCallback packet_callback,
39913     DataSourceStaticState* static_state,
39914     uint32_t instance_index)
39915     : tls_(std::move(tls)),
39916       packet_callback_(std::move(packet_callback)),
39917       static_state_(static_state),
39918       instance_index_(instance_index),
39919       sequence_id_(++next_sequence_id_) {}
39920 
39921 InterceptorTraceWriter::~InterceptorTraceWriter() = default;
39922 
39923 protozero::MessageHandle<protos::pbzero::TracePacket>
NewTracePacket()39924 InterceptorTraceWriter::NewTracePacket() {
39925   Flush();
39926   auto packet = TraceWriter::TracePacketHandle(cur_packet_.get());
39927   packet->set_trusted_packet_sequence_id(sequence_id_);
39928   return packet;
39929 }
39930 
Flush(std::function<void ()> callback)39931 void InterceptorTraceWriter::Flush(std::function<void()> callback) {
39932   if (!cur_packet_.empty()) {
39933     InterceptorBase::TracePacketCallbackArgs args{};
39934     args.static_state = static_state_;
39935     args.instance_index = instance_index_;
39936     args.tls = tls_.get();
39937 
39938     const auto& slices = cur_packet_.GetSlices();
39939     if (slices.size() == 1) {
39940       // Fast path: the current packet fits into a single slice.
39941       auto slice_range = slices.begin()->GetUsedRange();
39942       args.packet_data = protozero::ConstBytes{
39943           slice_range.begin,
39944           static_cast<size_t>(slice_range.end - slice_range.begin)};
39945       bytes_written_ += static_cast<uint64_t>(args.packet_data.size);
39946       packet_callback_(std::move(args));
39947     } else {
39948       // Fallback: stitch together multiple slices.
39949       auto stitched_data = cur_packet_.SerializeAsArray();
39950       args.packet_data =
39951           protozero::ConstBytes{stitched_data.data(), stitched_data.size()};
39952       bytes_written_ += static_cast<uint64_t>(stitched_data.size());
39953       packet_callback_(std::move(args));
39954     }
39955     cur_packet_.Reset();
39956   }
39957   if (callback)
39958     callback();
39959 }
39960 
written() const39961 uint64_t InterceptorTraceWriter::written() const {
39962   return bytes_written_;
39963 }
39964 
39965 }  // namespace internal
39966 }  // namespace perfetto
39967 // gen_amalgamated begin source: src/tracing/internal/tracing_backend_fake.cc
39968 // gen_amalgamated begin header: include/perfetto/tracing/internal/tracing_backend_fake.h
39969 /*
39970  * Copyright (C) 2021 The Android Open Source Project
39971  *
39972  * Licensed under the Apache License, Version 2.0 (the "License");
39973  * you may not use this file except in compliance with the License.
39974  * You may obtain a copy of the License at
39975  *
39976  *      http://www.apache.org/licenses/LICENSE-2.0
39977  *
39978  * Unless required by applicable law or agreed to in writing, software
39979  * distributed under the License is distributed on an "AS IS" BASIS,
39980  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
39981  * See the License for the specific language governing permissions and
39982  * limitations under the License.
39983  */
39984 
39985 #ifndef INCLUDE_PERFETTO_TRACING_INTERNAL_TRACING_BACKEND_FAKE_H_
39986 #define INCLUDE_PERFETTO_TRACING_INTERNAL_TRACING_BACKEND_FAKE_H_
39987 
39988 // gen_amalgamated expanded: #include "perfetto/base/export.h"
39989 // gen_amalgamated expanded: #include "perfetto/tracing/tracing_backend.h"
39990 
39991 namespace perfetto {
39992 namespace internal {
39993 
39994 // A built-in implementation of TracingBackend that fails any attempt to create
39995 // a tracing session.
39996 class PERFETTO_EXPORT TracingBackendFake : public TracingBackend {
39997  public:
39998   static TracingBackend* GetInstance();
39999 
40000   // TracingBackend implementation.
40001   std::unique_ptr<ProducerEndpoint> ConnectProducer(
40002       const ConnectProducerArgs&) override;
40003   std::unique_ptr<ConsumerEndpoint> ConnectConsumer(
40004       const ConnectConsumerArgs&) override;
40005 
40006  private:
40007   TracingBackendFake();
40008 };
40009 
40010 }  // namespace internal
40011 }  // namespace perfetto
40012 
40013 #endif  // INCLUDE_PERFETTO_TRACING_INTERNAL_TRACING_BACKEND_FAKE_H_
40014 /*
40015  * Copyright (C) 2021 The Android Open Source Project
40016  *
40017  * Licensed under the Apache License, Version 2.0 (the "License");
40018  * you may not use this file except in compliance with the License.
40019  * You may obtain a copy of the License at
40020  *
40021  *      http://www.apache.org/licenses/LICENSE-2.0
40022  *
40023  * Unless required by applicable law or agreed to in writing, software
40024  * distributed under the License is distributed on an "AS IS" BASIS,
40025  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
40026  * See the License for the specific language governing permissions and
40027  * limitations under the License.
40028  */
40029 
40030 // gen_amalgamated expanded: #include "perfetto/tracing/internal/tracing_backend_fake.h"
40031 
40032 // gen_amalgamated expanded: #include "perfetto/base/task_runner.h"
40033 // gen_amalgamated expanded: #include "perfetto/ext/base/weak_ptr.h"
40034 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/consumer.h"
40035 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/producer.h"
40036 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/trace_writer.h"
40037 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/tracing_service.h"
40038 
40039 namespace perfetto {
40040 namespace internal {
40041 
40042 namespace {
40043 
40044 class UnsupportedProducerEndpoint : public ProducerEndpoint {
40045  public:
UnsupportedProducerEndpoint(Producer * producer,base::TaskRunner * task_runner)40046   UnsupportedProducerEndpoint(Producer* producer, base::TaskRunner* task_runner)
40047       : producer_(producer), task_runner_(task_runner) {
40048     // The SDK will attempt to reconnect the producer, so instead we allow it
40049     // to connect successfully, but never start any sessions.
40050     auto weak_ptr = weak_ptr_factory_.GetWeakPtr();
40051     task_runner_->PostTask([weak_ptr] {
40052       if (weak_ptr)
40053         weak_ptr->producer_->OnConnect();
40054     });
40055   }
~UnsupportedProducerEndpoint()40056   ~UnsupportedProducerEndpoint() override { producer_->OnDisconnect(); }
40057 
RegisterDataSource(const DataSourceDescriptor &)40058   void RegisterDataSource(const DataSourceDescriptor&) override {}
UpdateDataSource(const DataSourceDescriptor &)40059   void UpdateDataSource(const DataSourceDescriptor&) override {}
UnregisterDataSource(const std::string &)40060   void UnregisterDataSource(const std::string& /*name*/) override {}
40061 
RegisterTraceWriter(uint32_t,uint32_t)40062   void RegisterTraceWriter(uint32_t /*writer_id*/,
40063                            uint32_t /*target_buffer*/) override {}
UnregisterTraceWriter(uint32_t)40064   void UnregisterTraceWriter(uint32_t /*writer_id*/) override {}
40065 
CommitData(const CommitDataRequest &,CommitDataCallback callback={})40066   void CommitData(const CommitDataRequest&,
40067                   CommitDataCallback callback = {}) override {
40068     callback();
40069   }
40070 
shared_memory() const40071   SharedMemory* shared_memory() const override { return nullptr; }
shared_buffer_page_size_kb() const40072   size_t shared_buffer_page_size_kb() const override { return 0; }
40073 
CreateTraceWriter(BufferID,BufferExhaustedPolicy=BufferExhaustedPolicy::kDefault)40074   std::unique_ptr<TraceWriter> CreateTraceWriter(
40075       BufferID /*target_buffer*/,
40076       BufferExhaustedPolicy = BufferExhaustedPolicy::kDefault) override {
40077     return nullptr;
40078   }
40079 
MaybeSharedMemoryArbiter()40080   SharedMemoryArbiter* MaybeSharedMemoryArbiter() override { return nullptr; }
IsShmemProvidedByProducer() const40081   bool IsShmemProvidedByProducer() const override { return false; }
40082 
NotifyFlushComplete(FlushRequestID)40083   void NotifyFlushComplete(FlushRequestID) override {}
NotifyDataSourceStarted(DataSourceInstanceID)40084   void NotifyDataSourceStarted(DataSourceInstanceID) override {}
NotifyDataSourceStopped(DataSourceInstanceID)40085   void NotifyDataSourceStopped(DataSourceInstanceID) override {}
ActivateTriggers(const std::vector<std::string> &)40086   void ActivateTriggers(const std::vector<std::string>&) override {}
40087 
Sync(std::function<void ()> callback)40088   void Sync(std::function<void()> callback) override { callback(); }
40089 
40090  private:
40091   Producer* const producer_;
40092   base::TaskRunner* const task_runner_;
40093   base::WeakPtrFactory<UnsupportedProducerEndpoint> weak_ptr_factory_{
40094       this};  // Keep last.
40095 };
40096 
40097 class UnsupportedConsumerEndpoint : public ConsumerEndpoint {
40098  public:
UnsupportedConsumerEndpoint(Consumer * consumer,base::TaskRunner * task_runner)40099   UnsupportedConsumerEndpoint(Consumer* consumer, base::TaskRunner* task_runner)
40100       : consumer_(consumer), task_runner_(task_runner) {
40101     // The SDK will not to reconnect the consumer, so we just disconnect it
40102     // immediately, which will cancel the tracing session.
40103     auto weak_this = weak_ptr_factory_.GetWeakPtr();
40104     task_runner_->PostTask([weak_this] {
40105       if (weak_this)
40106         weak_this->consumer_->OnDisconnect();
40107     });
40108   }
40109   ~UnsupportedConsumerEndpoint() override = default;
40110 
EnableTracing(const TraceConfig &,base::ScopedFile=base::ScopedFile ())40111   void EnableTracing(const TraceConfig&,
40112                      base::ScopedFile = base::ScopedFile()) override {}
ChangeTraceConfig(const TraceConfig &)40113   void ChangeTraceConfig(const TraceConfig&) override {}
40114 
StartTracing()40115   void StartTracing() override {}
DisableTracing()40116   void DisableTracing() override {}
40117 
Flush(uint32_t,FlushCallback callback)40118   void Flush(uint32_t /*timeout_ms*/, FlushCallback callback) override {
40119     callback(/*success=*/false);
40120   }
40121 
ReadBuffers()40122   void ReadBuffers() override {}
FreeBuffers()40123   void FreeBuffers() override {}
40124 
Detach(const std::string &)40125   void Detach(const std::string& /*key*/) override {}
Attach(const std::string &)40126   void Attach(const std::string& /*key*/) override {}
40127 
GetTraceStats()40128   void GetTraceStats() override {}
ObserveEvents(uint32_t)40129   void ObserveEvents(uint32_t /*events_mask*/) override {}
QueryServiceState(QueryServiceStateCallback)40130   void QueryServiceState(QueryServiceStateCallback) override {}
QueryCapabilities(QueryCapabilitiesCallback)40131   void QueryCapabilities(QueryCapabilitiesCallback) override {}
40132 
SaveTraceForBugreport(SaveTraceForBugreportCallback)40133   void SaveTraceForBugreport(SaveTraceForBugreportCallback) override {}
40134 
40135  private:
40136   Consumer* const consumer_;
40137   base::TaskRunner* const task_runner_;
40138   base::WeakPtrFactory<UnsupportedConsumerEndpoint> weak_ptr_factory_{
40139       this};  // Keep last.
40140 };
40141 
40142 }  // namespace
40143 
40144 // static
GetInstance()40145 TracingBackend* TracingBackendFake::GetInstance() {
40146   static auto* instance = new TracingBackendFake();
40147   return instance;
40148 }
40149 
40150 TracingBackendFake::TracingBackendFake() = default;
40151 
ConnectProducer(const ConnectProducerArgs & args)40152 std::unique_ptr<ProducerEndpoint> TracingBackendFake::ConnectProducer(
40153     const ConnectProducerArgs& args) {
40154   return std::unique_ptr<ProducerEndpoint>(
40155       new UnsupportedProducerEndpoint(args.producer, args.task_runner));
40156 }
40157 
ConnectConsumer(const ConnectConsumerArgs & args)40158 std::unique_ptr<ConsumerEndpoint> TracingBackendFake::ConnectConsumer(
40159     const ConnectConsumerArgs& args) {
40160   return std::unique_ptr<ConsumerEndpoint>(
40161       new UnsupportedConsumerEndpoint(args.consumer, args.task_runner));
40162 }
40163 
40164 }  // namespace internal
40165 }  // namespace perfetto
40166 // gen_amalgamated begin source: src/tracing/internal/tracing_muxer_fake.cc
40167 // gen_amalgamated begin header: src/tracing/internal/tracing_muxer_fake.h
40168 /*
40169  * Copyright (C) 2021 The Android Open Source Project
40170  *
40171  * Licensed under the Apache License, Version 2.0 (the "License");
40172  * you may not use this file except in compliance with the License.
40173  * You may obtain a copy of the License at
40174  *
40175  *      http://www.apache.org/licenses/LICENSE-2.0
40176  *
40177  * Unless required by applicable law or agreed to in writing, software
40178  * distributed under the License is distributed on an "AS IS" BASIS,
40179  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
40180  * See the License for the specific language governing permissions and
40181  * limitations under the License.
40182  */
40183 
40184 #ifndef SRC_TRACING_INTERNAL_TRACING_MUXER_FAKE_H_
40185 #define SRC_TRACING_INTERNAL_TRACING_MUXER_FAKE_H_
40186 
40187 // gen_amalgamated expanded: #include "perfetto/base/compiler.h"
40188 // gen_amalgamated expanded: #include "perfetto/tracing/internal/tracing_muxer.h"
40189 
40190 namespace perfetto {
40191 namespace internal {
40192 
40193 // An always-fail implementation of TracingMuxer. Before tracing has been
40194 // initialiazed, all muxer operations will route here and fail with a helpful
40195 // error message. This is to avoid introducing null checks in
40196 // performance-critical parts of the codebase.
40197 class TracingMuxerFake : public TracingMuxer {
40198   class FakePlatform : public Platform {
40199    public:
40200     ~FakePlatform() override;
40201     ThreadLocalObject* GetOrCreateThreadLocalObject() override;
40202     std::unique_ptr<base::TaskRunner> CreateTaskRunner(
40203         const CreateTaskRunnerArgs&) override;
40204     std::string GetCurrentProcessName() override;
40205 
40206     static FakePlatform instance;
40207   };
40208 
40209  public:
TracingMuxerFake()40210   TracingMuxerFake() : TracingMuxer(&FakePlatform::instance) {}
40211   ~TracingMuxerFake() override;
40212 
Get()40213   static constexpr TracingMuxerFake* Get() {
40214 #if PERFETTO_HAS_NO_DESTROY()
40215     return &instance;
40216 #else
40217     return nullptr;
40218 #endif
40219   }
40220 
40221   // TracingMuxer implementation.
40222   bool RegisterDataSource(const DataSourceDescriptor&,
40223                           DataSourceFactory,
40224                           DataSourceStaticState*) override;
40225   void UpdateDataSourceDescriptor(const DataSourceDescriptor&,
40226                                   const DataSourceStaticState*) override;
40227   std::unique_ptr<TraceWriterBase> CreateTraceWriter(
40228       DataSourceStaticState*,
40229       uint32_t data_source_instance_index,
40230       DataSourceState*,
40231       BufferExhaustedPolicy buffer_exhausted_policy) override;
40232   void DestroyStoppedTraceWritersForCurrentThread() override;
40233   void RegisterInterceptor(const InterceptorDescriptor&,
40234                            InterceptorFactory,
40235                            InterceptorBase::TLSFactory,
40236                            InterceptorBase::TracePacketCallback) override;
40237 
40238  private:
40239   static TracingMuxerFake instance;
40240 };
40241 
40242 }  // namespace internal
40243 }  // namespace perfetto
40244 
40245 #endif  // SRC_TRACING_INTERNAL_TRACING_MUXER_FAKE_H_
40246 /*
40247  * Copyright (C) 2021 The Android Open Source Project
40248  *
40249  * Licensed under the Apache License, Version 2.0 (the "License");
40250  * you may not use this file except in compliance with the License.
40251  * You may obtain a copy of the License at
40252  *
40253  *      http://www.apache.org/licenses/LICENSE-2.0
40254  *
40255  * Unless required by applicable law or agreed to in writing, software
40256  * distributed under the License is distributed on an "AS IS" BASIS,
40257  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
40258  * See the License for the specific language governing permissions and
40259  * limitations under the License.
40260  */
40261 
40262 // gen_amalgamated expanded: #include "src/tracing/internal/tracing_muxer_fake.h"
40263 
40264 namespace perfetto {
40265 namespace internal {
40266 namespace {
40267 
FailUninitialized()40268 PERFETTO_NORETURN void FailUninitialized() {
40269   PERFETTO_FATAL(
40270       "Tracing not initialized. Call perfetto::Tracing::Initialize() first.");
40271 }
40272 
40273 }  // namespace
40274 
40275 #if PERFETTO_HAS_NO_DESTROY()
40276 // static
40277 PERFETTO_NO_DESTROY TracingMuxerFake::FakePlatform
40278     TracingMuxerFake::FakePlatform::instance{};
40279 // static
40280 PERFETTO_NO_DESTROY TracingMuxerFake TracingMuxerFake::instance{};
40281 #endif  // PERFETTO_HAS_NO_DESTROY()
40282 
40283 TracingMuxerFake::~TracingMuxerFake() = default;
40284 
40285 TracingMuxerFake::FakePlatform::~FakePlatform() = default;
40286 
40287 Platform::ThreadLocalObject*
GetOrCreateThreadLocalObject()40288 TracingMuxerFake::FakePlatform::GetOrCreateThreadLocalObject() {
40289   FailUninitialized();
40290 }
40291 
40292 std::unique_ptr<base::TaskRunner>
CreateTaskRunner(const CreateTaskRunnerArgs &)40293 TracingMuxerFake::FakePlatform::CreateTaskRunner(const CreateTaskRunnerArgs&) {
40294   FailUninitialized();
40295 }
40296 
GetCurrentProcessName()40297 std::string TracingMuxerFake::FakePlatform::GetCurrentProcessName() {
40298   FailUninitialized();
40299 }
40300 
RegisterDataSource(const DataSourceDescriptor &,DataSourceFactory,DataSourceStaticState *)40301 bool TracingMuxerFake::RegisterDataSource(const DataSourceDescriptor&,
40302                                           DataSourceFactory,
40303                                           DataSourceStaticState*) {
40304   FailUninitialized();
40305 }
40306 
UpdateDataSourceDescriptor(const DataSourceDescriptor &,const DataSourceStaticState *)40307 void TracingMuxerFake::UpdateDataSourceDescriptor(
40308     const DataSourceDescriptor&,
40309     const DataSourceStaticState*) {
40310   FailUninitialized();
40311 }
40312 
CreateTraceWriter(DataSourceStaticState *,uint32_t,DataSourceState *,BufferExhaustedPolicy)40313 std::unique_ptr<TraceWriterBase> TracingMuxerFake::CreateTraceWriter(
40314     DataSourceStaticState*,
40315     uint32_t,
40316     DataSourceState*,
40317     BufferExhaustedPolicy) {
40318   FailUninitialized();
40319 }
40320 
DestroyStoppedTraceWritersForCurrentThread()40321 void TracingMuxerFake::DestroyStoppedTraceWritersForCurrentThread() {
40322   FailUninitialized();
40323 }
40324 
RegisterInterceptor(const InterceptorDescriptor &,InterceptorFactory,InterceptorBase::TLSFactory,InterceptorBase::TracePacketCallback)40325 void TracingMuxerFake::RegisterInterceptor(
40326     const InterceptorDescriptor&,
40327     InterceptorFactory,
40328     InterceptorBase::TLSFactory,
40329     InterceptorBase::TracePacketCallback) {
40330   FailUninitialized();
40331 }
40332 
40333 }  // namespace internal
40334 }  // namespace perfetto
40335 // gen_amalgamated begin source: src/tracing/internal/tracing_muxer_impl.cc
40336 // gen_amalgamated begin header: src/tracing/internal/tracing_muxer_impl.h
40337 /*
40338  * Copyright (C) 2019 The Android Open Source Project
40339  *
40340  * Licensed under the Apache License, Version 2.0 (the "License");
40341  * you may not use this file except in compliance with the License.
40342  * You may obtain a copy of the License at
40343  *
40344  *      http://www.apache.org/licenses/LICENSE-2.0
40345  *
40346  * Unless required by applicable law or agreed to in writing, software
40347  * distributed under the License is distributed on an "AS IS" BASIS,
40348  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
40349  * See the License for the specific language governing permissions and
40350  * limitations under the License.
40351  */
40352 
40353 #ifndef SRC_TRACING_INTERNAL_TRACING_MUXER_IMPL_H_
40354 #define SRC_TRACING_INTERNAL_TRACING_MUXER_IMPL_H_
40355 
40356 #include <stddef.h>
40357 #include <stdint.h>
40358 
40359 #include <array>
40360 #include <atomic>
40361 #include <bitset>
40362 #include <list>
40363 #include <map>
40364 #include <memory>
40365 #include <vector>
40366 
40367 // gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"
40368 // gen_amalgamated expanded: #include "perfetto/ext/base/thread_checker.h"
40369 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/basic_types.h"
40370 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/consumer.h"
40371 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/producer.h"
40372 // gen_amalgamated expanded: #include "perfetto/tracing/core/data_source_descriptor.h"
40373 // gen_amalgamated expanded: #include "perfetto/tracing/core/forward_decls.h"
40374 // gen_amalgamated expanded: #include "perfetto/tracing/core/trace_config.h"
40375 // gen_amalgamated expanded: #include "perfetto/tracing/internal/basic_types.h"
40376 // gen_amalgamated expanded: #include "perfetto/tracing/internal/tracing_muxer.h"
40377 // gen_amalgamated expanded: #include "perfetto/tracing/tracing.h"
40378 
40379 // gen_amalgamated expanded: #include "protos/perfetto/common/interceptor_descriptor.gen.h"
40380 
40381 namespace perfetto {
40382 
40383 class ConsumerEndpoint;
40384 class DataSourceBase;
40385 class ProducerEndpoint;
40386 class TraceWriterBase;
40387 class TracingBackend;
40388 class TracingSession;
40389 struct TracingInitArgs;
40390 
40391 namespace base {
40392 class TaskRunner;
40393 }
40394 
40395 namespace internal {
40396 
40397 struct DataSourceStaticState;
40398 
40399 // This class acts as a bridge between the public API and the TracingBackend(s).
40400 // It exposes a simplified view of the world to the API methods handling all the
40401 // bookkeeping to map data source instances and trace writers to the various
40402 // backends. It deals with N data sources, M backends (1 backend == 1 tracing
40403 // service == 1 producer connection) and T concurrent tracing sessions.
40404 //
40405 // Handing data source registration and start/stop flows [producer side]:
40406 // ----------------------------------------------------------------------
40407 // 1. The API client subclasses perfetto::DataSource and calls
40408 //    DataSource::Register<MyDataSource>(). In turn this calls into the
40409 //    TracingMuxer.
40410 // 2. The tracing muxer iterates through all the backends (1 backend == 1
40411 //    service == 1 producer connection) and registers the data source on each
40412 //    backend.
40413 // 3. When any (services behind a) backend starts tracing and requests to start
40414 //    that specific data source, the TracingMuxerImpl constructs a new instance
40415 //    of MyDataSource and calls the OnStart() method.
40416 //
40417 // Controlling trace and retrieving trace data [consumer side]:
40418 // ------------------------------------------------------------
40419 // 1. The API client calls Tracing::NewTrace(), returns a RAII TracingSession
40420 //    object.
40421 // 2. NewTrace() calls into internal::TracingMuxer(Impl). TracingMuxer
40422 //    subclasses the TracingSession object (TracingSessionImpl) and returns it.
40423 // 3. The tracing muxer identifies the backend (according to the args passed to
40424 //    NewTrace), creates a new Consumer and connects to it.
40425 // 4. When the API client calls Start()/Stop()/ReadTrace() methods, the
40426 //    TracingMuxer forwards them to the consumer associated to the
40427 //    TracingSession. Likewise for callbacks coming from the consumer-side of
40428 //    the service.
40429 class TracingMuxerImpl : public TracingMuxer {
40430  public:
40431   // This is different than TracingSessionID because it's global across all
40432   // backends. TracingSessionID is global only within the scope of one service.
40433   using TracingSessionGlobalID = uint64_t;
40434 
40435   static void InitializeInstance(const TracingInitArgs&);
40436   static void ResetForTesting();
40437 
40438   // TracingMuxer implementation.
40439   bool RegisterDataSource(const DataSourceDescriptor&,
40440                           DataSourceFactory,
40441                           DataSourceStaticState*) override;
40442   void UpdateDataSourceDescriptor(const DataSourceDescriptor&,
40443                                   const DataSourceStaticState*) override;
40444   std::unique_ptr<TraceWriterBase> CreateTraceWriter(
40445       DataSourceStaticState*,
40446       uint32_t data_source_instance_index,
40447       DataSourceState*,
40448       BufferExhaustedPolicy buffer_exhausted_policy) override;
40449   void DestroyStoppedTraceWritersForCurrentThread() override;
40450   void RegisterInterceptor(const InterceptorDescriptor&,
40451                            InterceptorFactory,
40452                            InterceptorBase::TLSFactory,
40453                            InterceptorBase::TracePacketCallback) override;
40454 
40455   std::unique_ptr<TracingSession> CreateTracingSession(BackendType);
40456 
40457   // Producer-side bookkeeping methods.
40458   void UpdateDataSourcesOnAllBackends();
40459   void SetupDataSource(TracingBackendId,
40460                        uint32_t backend_connection_id,
40461                        DataSourceInstanceID,
40462                        const DataSourceConfig&);
40463   void StartDataSource(TracingBackendId, DataSourceInstanceID);
40464   void StopDataSource_AsyncBegin(TracingBackendId, DataSourceInstanceID);
40465   void StopDataSource_AsyncEnd(TracingBackendId, DataSourceInstanceID);
40466   void ClearDataSourceIncrementalState(TracingBackendId, DataSourceInstanceID);
40467   void SyncProducersForTesting();
40468 
40469   // Consumer-side bookkeeping methods.
40470   void SetupTracingSession(TracingSessionGlobalID,
40471                            const std::shared_ptr<TraceConfig>&,
40472                            base::ScopedFile trace_fd = base::ScopedFile());
40473   void StartTracingSession(TracingSessionGlobalID);
40474   void ChangeTracingSessionConfig(TracingSessionGlobalID, const TraceConfig&);
40475   void StopTracingSession(TracingSessionGlobalID);
40476   void DestroyTracingSession(TracingSessionGlobalID);
40477   void FlushTracingSession(TracingSessionGlobalID,
40478                            uint32_t,
40479                            std::function<void(bool)>);
40480   void ReadTracingSessionData(
40481       TracingSessionGlobalID,
40482       std::function<void(TracingSession::ReadTraceCallbackArgs)>);
40483   void GetTraceStats(TracingSessionGlobalID,
40484                      TracingSession::GetTraceStatsCallback);
40485   void QueryServiceState(TracingSessionGlobalID,
40486                          TracingSession::QueryServiceStateCallback);
40487 
40488   // Sets the batching period to |batch_commits_duration_ms| on the backends
40489   // with type |backend_type|.
40490   void SetBatchCommitsDurationForTesting(uint32_t batch_commits_duration_ms,
40491                                          BackendType backend_type);
40492 
40493   // Enables direct SMB patching on the backends with type |backend_type| (see
40494   // SharedMemoryArbiter::EnableDirectSMBPatching). Returns true if the
40495   // operation succeeded for all backends with type |backend_type|, false
40496   // otherwise.
40497   bool EnableDirectSMBPatchingForTesting(BackendType backend_type);
40498 
40499   void SetMaxProducerReconnectionsForTesting(uint32_t count);
40500 
40501  private:
40502   // For each TracingBackend we create and register one ProducerImpl instance.
40503   // This talks to the producer-side of the service, gets start/stop requests
40504   // from it and routes them to the registered data sources.
40505   // One ProducerImpl == one backend == one tracing service.
40506   // This class is needed to disambiguate callbacks coming from different
40507   // services. TracingMuxerImpl can't directly implement the Producer interface
40508   // because the Producer virtual methods don't allow to identify the service.
40509   class ProducerImpl : public Producer {
40510    public:
40511     ProducerImpl(TracingMuxerImpl*,
40512                  TracingBackendId,
40513                  uint32_t shmem_batch_commits_duration_ms);
40514     ~ProducerImpl() override;
40515 
40516     void Initialize(std::unique_ptr<ProducerEndpoint> endpoint);
40517     void RegisterDataSource(const DataSourceDescriptor&,
40518                             DataSourceFactory,
40519                             DataSourceStaticState*);
40520     void DisposeConnection();
40521 
40522     // perfetto::Producer implementation.
40523     void OnConnect() override;
40524     void OnDisconnect() override;
40525     void OnTracingSetup() override;
40526     void SetupDataSource(DataSourceInstanceID,
40527                          const DataSourceConfig&) override;
40528     void StartDataSource(DataSourceInstanceID,
40529                          const DataSourceConfig&) override;
40530     void StopDataSource(DataSourceInstanceID) override;
40531     void Flush(FlushRequestID, const DataSourceInstanceID*, size_t) override;
40532     void ClearIncrementalState(const DataSourceInstanceID*, size_t) override;
40533 
40534     bool SweepDeadServices();
40535 
40536     PERFETTO_THREAD_CHECKER(thread_checker_)
40537     TracingMuxerImpl* muxer_;
40538     TracingBackendId const backend_id_;
40539     bool connected_ = false;
40540     bool did_setup_tracing_ = false;
40541     uint32_t connection_id_ = 0;
40542 
40543     const uint32_t shmem_batch_commits_duration_ms_ = 0;
40544 
40545     // Set of data sources that have been actually registered on this producer.
40546     // This can be a subset of the global |data_sources_|, because data sources
40547     // can register before the producer is fully connected.
40548     std::bitset<kMaxDataSources> registered_data_sources_{};
40549 
40550     // A collection of disconnected service endpoints. Since trace writers on
40551     // arbitrary threads might continue writing data to disconnected services,
40552     // we keep the old services around and periodically try to clean up ones
40553     // that no longer have any writers (see SweepDeadServices).
40554     std::list<std::shared_ptr<ProducerEndpoint>> dead_services_;
40555 
40556     // The currently active service endpoint is maintained as an atomic shared
40557     // pointer so it won't get deleted from underneath threads that are creating
40558     // trace writers. At any given time one endpoint can be shared (and thus
40559     // kept alive) by the |service_| pointer, an entry in |dead_services_| and
40560     // as a pointer on the stack in CreateTraceWriter() (on an arbitrary
40561     // thread). The endpoint is never shared outside ProducerImpl itself.
40562     //
40563     // WARNING: Any *write* access to this variable or any *read* access from a
40564     // non-muxer thread must be done through std::atomic_{load,store} to avoid
40565     // data races.
40566     std::shared_ptr<ProducerEndpoint> service_;  // Keep last.
40567   };
40568 
40569   // For each TracingSession created by the API client (Tracing::NewTrace() we
40570   // create and register one ConsumerImpl instance.
40571   // This talks to the consumer-side of the service, gets end-of-trace and
40572   // on-trace-data callbacks and routes them to the API client callbacks.
40573   // This class is needed to disambiguate callbacks coming from different
40574   // tracing sessions.
40575   class ConsumerImpl : public Consumer {
40576    public:
40577     ConsumerImpl(TracingMuxerImpl*,
40578                  BackendType,
40579                  TracingBackendId,
40580                  TracingSessionGlobalID);
40581     ~ConsumerImpl() override;
40582 
40583     void Initialize(std::unique_ptr<ConsumerEndpoint> endpoint);
40584 
40585     // perfetto::Consumer implementation.
40586     void OnConnect() override;
40587     void OnDisconnect() override;
40588     void OnTracingDisabled(const std::string& error) override;
40589     void OnTraceData(std::vector<TracePacket>, bool has_more) override;
40590     void OnDetach(bool success) override;
40591     void OnAttach(bool success, const TraceConfig&) override;
40592     void OnTraceStats(bool success, const TraceStats&) override;
40593     void OnObservableEvents(const ObservableEvents&) override;
40594 
40595     void NotifyStartComplete();
40596     void NotifyError(const TracingError&);
40597     void NotifyStopComplete();
40598 
40599     // Will eventually inform the |muxer_| when it is safe to remove |this|.
40600     void Disconnect();
40601 
40602     TracingMuxerImpl* muxer_;
40603     BackendType const backend_type_;
40604     TracingBackendId const backend_id_;
40605     TracingSessionGlobalID const session_id_;
40606     bool connected_ = false;
40607 
40608     // This is to handle the case where the Setup call from the API client
40609     // arrives before the consumer has connected. In this case we keep around
40610     // the config and check if we have it after connection.
40611     bool start_pending_ = false;
40612 
40613     // Similarly if the session is stopped before the consumer was connected, we
40614     // need to wait until the session has started before stopping it.
40615     bool stop_pending_ = false;
40616 
40617     // Similarly we need to buffer a call to get trace statistics if the
40618     // consumer wasn't connected yet.
40619     bool get_trace_stats_pending_ = false;
40620 
40621     // Whether this session was already stopped. This will happen in response to
40622     // Stop{,Blocking}, but also if the service stops the session for us
40623     // automatically (e.g., when there are no data sources).
40624     bool stopped_ = false;
40625 
40626     // shared_ptr because it's posted across threads. This is to avoid copying
40627     // it more than once.
40628     std::shared_ptr<TraceConfig> trace_config_;
40629     base::ScopedFile trace_fd_;
40630 
40631     // If the API client passes a callback to start, we should invoke this when
40632     // NotifyStartComplete() is invoked.
40633     std::function<void()> start_complete_callback_;
40634 
40635     // An internal callback used to implement StartBlocking().
40636     std::function<void()> blocking_start_complete_callback_;
40637 
40638     // If the API client passes a callback to get notification about the
40639     // errors, we should invoke this when NotifyError() is invoked.
40640     std::function<void(TracingError)> error_callback_;
40641 
40642     // If the API client passes a callback to stop, we should invoke this when
40643     // OnTracingDisabled() is invoked.
40644     std::function<void()> stop_complete_callback_;
40645 
40646     // An internal callback used to implement StopBlocking().
40647     std::function<void()> blocking_stop_complete_callback_;
40648 
40649     // Callback passed to ReadTrace().
40650     std::function<void(TracingSession::ReadTraceCallbackArgs)>
40651         read_trace_callback_;
40652 
40653     // Callback passed to GetTraceStats().
40654     TracingSession::GetTraceStatsCallback get_trace_stats_callback_;
40655 
40656     // Callback for a pending call to QueryServiceState().
40657     TracingSession::QueryServiceStateCallback query_service_state_callback_;
40658 
40659     // The states of all data sources in this tracing session. |true| means the
40660     // data source has started tracing.
40661     using DataSourceHandle = std::pair<std::string, std::string>;
40662     std::map<DataSourceHandle, bool> data_source_states_;
40663 
40664     std::unique_ptr<ConsumerEndpoint> service_;  // Keep before last.
40665     PERFETTO_THREAD_CHECKER(thread_checker_)     // Keep last.
40666   };
40667 
40668   // This object is returned to API clients when they call
40669   // Tracing::CreateTracingSession().
40670   class TracingSessionImpl : public TracingSession {
40671    public:
40672     TracingSessionImpl(TracingMuxerImpl*, TracingSessionGlobalID, BackendType);
40673     ~TracingSessionImpl() override;
40674     void Setup(const TraceConfig&, int fd) override;
40675     void Start() override;
40676     void StartBlocking() override;
40677     void SetOnStartCallback(std::function<void()>) override;
40678     void SetOnErrorCallback(std::function<void(TracingError)>) override;
40679     void Stop() override;
40680     void StopBlocking() override;
40681     void Flush(std::function<void(bool)>, uint32_t timeout_ms) override;
40682     void ReadTrace(ReadTraceCallback) override;
40683     void SetOnStopCallback(std::function<void()>) override;
40684     void GetTraceStats(GetTraceStatsCallback) override;
40685     void QueryServiceState(QueryServiceStateCallback) override;
40686     void ChangeTraceConfig(const TraceConfig&) override;
40687 
40688    private:
40689     TracingMuxerImpl* const muxer_;
40690     TracingSessionGlobalID const session_id_;
40691     BackendType const backend_type_;
40692   };
40693 
40694   struct RegisteredDataSource {
40695     DataSourceDescriptor descriptor;
40696     DataSourceFactory factory{};
40697     DataSourceStaticState* static_state = nullptr;
40698   };
40699 
40700   struct RegisteredInterceptor {
40701     protos::gen::InterceptorDescriptor descriptor;
40702     InterceptorFactory factory{};
40703     InterceptorBase::TLSFactory tls_factory{};
40704     InterceptorBase::TracePacketCallback packet_callback{};
40705   };
40706 
40707   struct RegisteredBackend {
40708     // Backends are supposed to have static lifetime.
40709     TracingBackend* backend = nullptr;
40710     TracingBackendId id = 0;
40711     BackendType type{};
40712 
40713     TracingBackend::ConnectProducerArgs producer_conn_args;
40714     std::unique_ptr<ProducerImpl> producer;
40715 
40716     // The calling code can request more than one concurrently active tracing
40717     // session for the same backend. We need to create one consumer per session.
40718     std::vector<std::unique_ptr<ConsumerImpl>> consumers;
40719   };
40720 
40721   void UpdateDataSourceOnAllBackends(RegisteredDataSource& rds,
40722                                      bool is_changed);
40723   explicit TracingMuxerImpl(const TracingInitArgs&);
40724   void Initialize(const TracingInitArgs& args);
40725   ConsumerImpl* FindConsumer(TracingSessionGlobalID session_id);
40726   void InitializeConsumer(TracingSessionGlobalID session_id);
40727   void OnConsumerDisconnected(ConsumerImpl* consumer);
40728   void OnProducerDisconnected(ProducerImpl* producer);
40729   void SweepDeadBackends();
40730 
40731   struct FindDataSourceRes {
40732     FindDataSourceRes() = default;
FindDataSourceResperfetto::internal::TracingMuxerImpl::FindDataSourceRes40733     FindDataSourceRes(DataSourceStaticState* a, DataSourceState* b, uint32_t c)
40734         : static_state(a), internal_state(b), instance_idx(c) {}
operator boolperfetto::internal::TracingMuxerImpl::FindDataSourceRes40735     explicit operator bool() const { return !!internal_state; }
40736 
40737     DataSourceStaticState* static_state = nullptr;
40738     DataSourceState* internal_state = nullptr;
40739     uint32_t instance_idx = 0;
40740   };
40741   FindDataSourceRes FindDataSource(TracingBackendId, DataSourceInstanceID);
40742 
40743   // WARNING: If you add new state here, be sure to update ResetForTesting.
40744   std::unique_ptr<base::TaskRunner> task_runner_;
40745   std::vector<RegisteredDataSource> data_sources_;
40746   std::vector<RegisteredBackend> backends_;
40747   std::vector<RegisteredInterceptor> interceptors_;
40748   TracingPolicy* policy_ = nullptr;
40749 
40750   std::atomic<TracingSessionGlobalID> next_tracing_session_id_{};
40751   std::atomic<uint32_t> next_data_source_index_{};
40752   uint32_t muxer_id_for_testing_{};
40753 
40754   // Maximum number of times we will try to reconnect producer backend.
40755   // Should only be modified for testing purposes.
40756   std::atomic<uint32_t> max_producer_reconnections_{100u};
40757 
40758   // After ResetForTesting() is called, holds tracing backends which needs to be
40759   // kept alive until all inbound references have gone away. See
40760   // SweepDeadBackends().
40761   std::list<RegisteredBackend> dead_backends_;
40762 
40763   PERFETTO_THREAD_CHECKER(thread_checker_)
40764 };
40765 
40766 }  // namespace internal
40767 }  // namespace perfetto
40768 
40769 #endif  // SRC_TRACING_INTERNAL_TRACING_MUXER_IMPL_H_
40770 // gen_amalgamated begin header: include/perfetto/ext/tracing/core/trace_stats.h
40771 /*
40772  * Copyright (C) 2017 The Android Open Source Project
40773  *
40774  * Licensed under the Apache License, Version 2.0 (the "License");
40775  * you may not use this file except in compliance with the License.
40776  * You may obtain a copy of the License at
40777  *
40778  *      http://www.apache.org/licenses/LICENSE-2.0
40779  *
40780  * Unless required by applicable law or agreed to in writing, software
40781  * distributed under the License is distributed on an "AS IS" BASIS,
40782  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
40783  * See the License for the specific language governing permissions and
40784  * limitations under the License.
40785  */
40786 
40787 #ifndef INCLUDE_PERFETTO_EXT_TRACING_CORE_TRACE_STATS_H_
40788 #define INCLUDE_PERFETTO_EXT_TRACING_CORE_TRACE_STATS_H_
40789 
40790 // Creates the aliases in the ::perfetto namespace, doing things like:
40791 // using ::perfetto::Foo = ::perfetto::protos::gen::Foo.
40792 // See comments in forward_decls.h for the historical reasons of this
40793 // indirection layer.
40794 // gen_amalgamated expanded: #include "perfetto/tracing/core/forward_decls.h"
40795 
40796 // gen_amalgamated expanded: #include "protos/perfetto/common/trace_stats.gen.h"
40797 
40798 #endif  // INCLUDE_PERFETTO_EXT_TRACING_CORE_TRACE_STATS_H_
40799 // gen_amalgamated begin header: include/perfetto/tracing/core/tracing_service_state.h
40800 /*
40801  * Copyright (C) 2017 The Android Open Source Project
40802  *
40803  * Licensed under the Apache License, Version 2.0 (the "License");
40804  * you may not use this file except in compliance with the License.
40805  * You may obtain a copy of the License at
40806  *
40807  *      http://www.apache.org/licenses/LICENSE-2.0
40808  *
40809  * Unless required by applicable law or agreed to in writing, software
40810  * distributed under the License is distributed on an "AS IS" BASIS,
40811  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
40812  * See the License for the specific language governing permissions and
40813  * limitations under the License.
40814  */
40815 
40816 
40817 #ifndef INCLUDE_PERFETTO_TRACING_CORE_TRACING_SERVICE_STATE_H_
40818 #define INCLUDE_PERFETTO_TRACING_CORE_TRACING_SERVICE_STATE_H_
40819 
40820 // Creates the aliases in the ::perfetto namespace, doing things like:
40821 // using ::perfetto::Foo = ::perfetto::protos::gen::Foo.
40822 // See comments in forward_decls.h for the historical reasons of this
40823 // indirection layer.
40824 // gen_amalgamated expanded: #include "perfetto/tracing/core/forward_decls.h"
40825 
40826 // gen_amalgamated expanded: #include "protos/perfetto/common/tracing_service_state.gen.h"
40827 
40828 #endif  // INCLUDE_PERFETTO_TRACING_CORE_TRACING_SERVICE_STATE_H_
40829 /*
40830  * Copyright (C) 2019 The Android Open Source Project
40831  *
40832  * Licensed under the Apache License, Version 2.0 (the "License");
40833  * you may not use this file except in compliance with the License.
40834  * You may obtain a copy of the License at
40835  *
40836  *      http://www.apache.org/licenses/LICENSE-2.0
40837  *
40838  * Unless required by applicable law or agreed to in writing, software
40839  * distributed under the License is distributed on an "AS IS" BASIS,
40840  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
40841  * See the License for the specific language governing permissions and
40842  * limitations under the License.
40843  */
40844 
40845 // gen_amalgamated expanded: #include "src/tracing/internal/tracing_muxer_impl.h"
40846 
40847 #include <algorithm>
40848 #include <atomic>
40849 #include <mutex>
40850 #include <vector>
40851 
40852 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
40853 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
40854 // gen_amalgamated expanded: #include "perfetto/base/task_runner.h"
40855 // gen_amalgamated expanded: #include "perfetto/base/time.h"
40856 // gen_amalgamated expanded: #include "perfetto/ext/base/hash.h"
40857 // gen_amalgamated expanded: #include "perfetto/ext/base/thread_checker.h"
40858 // gen_amalgamated expanded: #include "perfetto/ext/base/waitable_event.h"
40859 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/shared_memory_arbiter.h"
40860 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/trace_packet.h"
40861 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/trace_stats.h"
40862 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/trace_writer.h"
40863 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/tracing_service.h"
40864 // gen_amalgamated expanded: #include "perfetto/tracing/buffer_exhausted_policy.h"
40865 // gen_amalgamated expanded: #include "perfetto/tracing/core/data_source_config.h"
40866 // gen_amalgamated expanded: #include "perfetto/tracing/core/tracing_service_state.h"
40867 // gen_amalgamated expanded: #include "perfetto/tracing/data_source.h"
40868 // gen_amalgamated expanded: #include "perfetto/tracing/internal/data_source_internal.h"
40869 // gen_amalgamated expanded: #include "perfetto/tracing/internal/interceptor_trace_writer.h"
40870 // gen_amalgamated expanded: #include "perfetto/tracing/internal/tracing_backend_fake.h"
40871 // gen_amalgamated expanded: #include "perfetto/tracing/trace_writer_base.h"
40872 // gen_amalgamated expanded: #include "perfetto/tracing/tracing.h"
40873 // gen_amalgamated expanded: #include "perfetto/tracing/tracing_backend.h"
40874 
40875 // gen_amalgamated expanded: #include "protos/perfetto/config/interceptor_config.gen.h"
40876 
40877 // gen_amalgamated expanded: #include "src/tracing/internal/tracing_muxer_fake.h"
40878 
40879 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
40880 #include <io.h>  // For dup()
40881 #else
40882 #include <unistd.h>  // For dup()
40883 #endif
40884 
40885 namespace perfetto {
40886 namespace internal {
40887 
40888 namespace {
40889 
40890 // A task runner which prevents calls to DataSource::Trace() while an operation
40891 // is in progress. Used to guard against unexpected re-entrancy where the
40892 // user-provided task runner implementation tries to enter a trace point under
40893 // the hood.
40894 class NonReentrantTaskRunner : public base::TaskRunner {
40895  public:
NonReentrantTaskRunner(TracingMuxer * muxer,std::unique_ptr<base::TaskRunner> task_runner)40896   NonReentrantTaskRunner(TracingMuxer* muxer,
40897                          std::unique_ptr<base::TaskRunner> task_runner)
40898       : muxer_(muxer), task_runner_(std::move(task_runner)) {}
40899 
40900   // base::TaskRunner implementation.
PostTask(std::function<void ()> task)40901   void PostTask(std::function<void()> task) override {
40902     CallWithGuard([&] { task_runner_->PostTask(std::move(task)); });
40903   }
40904 
PostDelayedTask(std::function<void ()> task,uint32_t delay_ms)40905   void PostDelayedTask(std::function<void()> task, uint32_t delay_ms) override {
40906     CallWithGuard(
40907         [&] { task_runner_->PostDelayedTask(std::move(task), delay_ms); });
40908   }
40909 
AddFileDescriptorWatch(base::PlatformHandle fd,std::function<void ()> callback)40910   void AddFileDescriptorWatch(base::PlatformHandle fd,
40911                               std::function<void()> callback) override {
40912     CallWithGuard(
40913         [&] { task_runner_->AddFileDescriptorWatch(fd, std::move(callback)); });
40914   }
40915 
RemoveFileDescriptorWatch(base::PlatformHandle fd)40916   void RemoveFileDescriptorWatch(base::PlatformHandle fd) override {
40917     CallWithGuard([&] { task_runner_->RemoveFileDescriptorWatch(fd); });
40918   }
40919 
RunsTasksOnCurrentThread() const40920   bool RunsTasksOnCurrentThread() const override {
40921     bool result;
40922     CallWithGuard([&] { result = task_runner_->RunsTasksOnCurrentThread(); });
40923     return result;
40924   }
40925 
40926  private:
40927   template <typename T>
CallWithGuard(T lambda) const40928   void CallWithGuard(T lambda) const {
40929     auto* root_tls = muxer_->GetOrCreateTracingTLS();
40930     if (PERFETTO_UNLIKELY(root_tls->is_in_trace_point)) {
40931       lambda();
40932       return;
40933     }
40934     ScopedReentrancyAnnotator scoped_annotator(*root_tls);
40935     lambda();
40936   }
40937 
40938   TracingMuxer* const muxer_;
40939   std::unique_ptr<base::TaskRunner> task_runner_;
40940 };
40941 
40942 class StopArgsImpl : public DataSourceBase::StopArgs {
40943  public:
HandleStopAsynchronously() const40944   std::function<void()> HandleStopAsynchronously() const override {
40945     auto closure = std::move(async_stop_closure);
40946     async_stop_closure = std::function<void()>();
40947     return closure;
40948   }
40949 
40950   mutable std::function<void()> async_stop_closure;
40951 };
40952 
ComputeConfigHash(const DataSourceConfig & config)40953 uint64_t ComputeConfigHash(const DataSourceConfig& config) {
40954   base::Hash hasher;
40955   std::string config_bytes = config.SerializeAsString();
40956   hasher.Update(config_bytes.data(), config_bytes.size());
40957   return hasher.digest();
40958 }
40959 
40960 // Holds an earlier TracingMuxerImpl instance after ResetForTesting() is called.
40961 static TracingMuxerImpl* g_prev_instance{};
40962 
40963 }  // namespace
40964 
40965 // ----- Begin of TracingMuxerImpl::ProducerImpl
ProducerImpl(TracingMuxerImpl * muxer,TracingBackendId backend_id,uint32_t shmem_batch_commits_duration_ms)40966 TracingMuxerImpl::ProducerImpl::ProducerImpl(
40967     TracingMuxerImpl* muxer,
40968     TracingBackendId backend_id,
40969     uint32_t shmem_batch_commits_duration_ms)
40970     : muxer_(muxer),
40971       backend_id_(backend_id),
40972       shmem_batch_commits_duration_ms_(shmem_batch_commits_duration_ms) {}
40973 
~ProducerImpl()40974 TracingMuxerImpl::ProducerImpl::~ProducerImpl() {
40975   muxer_ = nullptr;
40976 }
40977 
Initialize(std::unique_ptr<ProducerEndpoint> endpoint)40978 void TracingMuxerImpl::ProducerImpl::Initialize(
40979     std::unique_ptr<ProducerEndpoint> endpoint) {
40980   PERFETTO_DCHECK_THREAD(thread_checker_);
40981   PERFETTO_DCHECK(!connected_);
40982   connection_id_++;
40983 
40984   // Adopt the endpoint into a shared pointer so that we can safely share it
40985   // across threads that create trace writers. The custom deleter function
40986   // ensures that the endpoint is always destroyed on the muxer's thread. (Note
40987   // that |task_runner| is assumed to outlive tracing sessions on all threads.)
40988   auto* task_runner = muxer_->task_runner_.get();
40989   auto deleter = [task_runner](ProducerEndpoint* e) {
40990     if (task_runner->RunsTasksOnCurrentThread()) {
40991       delete e;
40992       return;
40993     }
40994     task_runner->PostTask([e] { delete e; });
40995   };
40996   std::shared_ptr<ProducerEndpoint> service(endpoint.release(), deleter);
40997   // This atomic store is needed because another thread might be concurrently
40998   // creating a trace writer using the previous (disconnected) |service_|. See
40999   // CreateTraceWriter().
41000   std::atomic_store(&service_, std::move(service));
41001   // Don't try to use the service here since it may not have connected yet. See
41002   // OnConnect().
41003 }
41004 
OnConnect()41005 void TracingMuxerImpl::ProducerImpl::OnConnect() {
41006   PERFETTO_DLOG("Producer connected");
41007   PERFETTO_DCHECK_THREAD(thread_checker_);
41008   PERFETTO_DCHECK(!connected_);
41009   connected_ = true;
41010   muxer_->UpdateDataSourcesOnAllBackends();
41011 }
41012 
OnDisconnect()41013 void TracingMuxerImpl::ProducerImpl::OnDisconnect() {
41014   PERFETTO_DCHECK_THREAD(thread_checker_);
41015   // If we're being destroyed, bail out.
41016   if (!muxer_)
41017     return;
41018   connected_ = false;
41019   // Active data sources for this producer will be stopped by
41020   // DestroyStoppedTraceWritersForCurrentThread() since the reconnected producer
41021   // will have a different connection id (even before it has finished
41022   // connecting).
41023   registered_data_sources_.reset();
41024   DisposeConnection();
41025 
41026   // Try reconnecting the producer.
41027   muxer_->OnProducerDisconnected(this);
41028 }
41029 
DisposeConnection()41030 void TracingMuxerImpl::ProducerImpl::DisposeConnection() {
41031   // Keep the old service around as a dead connection in case it has active
41032   // trace writers. If any tracing sessions were created, we can't clear
41033   // |service_| here because other threads may be concurrently creating new
41034   // trace writers. Any reconnection attempt will atomically swap the new
41035   // service in place of the old one.
41036   if (did_setup_tracing_) {
41037     dead_services_.push_back(service_);
41038   } else {
41039     service_.reset();
41040   }
41041 }
41042 
OnTracingSetup()41043 void TracingMuxerImpl::ProducerImpl::OnTracingSetup() {
41044   PERFETTO_DCHECK_THREAD(thread_checker_);
41045   did_setup_tracing_ = true;
41046   service_->MaybeSharedMemoryArbiter()->SetBatchCommitsDuration(
41047       shmem_batch_commits_duration_ms_);
41048 }
41049 
SetupDataSource(DataSourceInstanceID id,const DataSourceConfig & cfg)41050 void TracingMuxerImpl::ProducerImpl::SetupDataSource(
41051     DataSourceInstanceID id,
41052     const DataSourceConfig& cfg) {
41053   PERFETTO_DCHECK_THREAD(thread_checker_);
41054   if (!muxer_)
41055     return;
41056   muxer_->SetupDataSource(backend_id_, connection_id_, id, cfg);
41057 }
41058 
StartDataSource(DataSourceInstanceID id,const DataSourceConfig &)41059 void TracingMuxerImpl::ProducerImpl::StartDataSource(DataSourceInstanceID id,
41060                                                      const DataSourceConfig&) {
41061   PERFETTO_DCHECK_THREAD(thread_checker_);
41062   if (!muxer_)
41063     return;
41064   muxer_->StartDataSource(backend_id_, id);
41065   service_->NotifyDataSourceStarted(id);
41066 }
41067 
StopDataSource(DataSourceInstanceID id)41068 void TracingMuxerImpl::ProducerImpl::StopDataSource(DataSourceInstanceID id) {
41069   PERFETTO_DCHECK_THREAD(thread_checker_);
41070   if (!muxer_)
41071     return;
41072   muxer_->StopDataSource_AsyncBegin(backend_id_, id);
41073 }
41074 
Flush(FlushRequestID flush_id,const DataSourceInstanceID *,size_t)41075 void TracingMuxerImpl::ProducerImpl::Flush(FlushRequestID flush_id,
41076                                            const DataSourceInstanceID*,
41077                                            size_t) {
41078   // Flush is not plumbed for now, we just ack straight away.
41079   PERFETTO_DCHECK_THREAD(thread_checker_);
41080   service_->NotifyFlushComplete(flush_id);
41081 }
41082 
ClearIncrementalState(const DataSourceInstanceID * instances,size_t instance_count)41083 void TracingMuxerImpl::ProducerImpl::ClearIncrementalState(
41084     const DataSourceInstanceID* instances,
41085     size_t instance_count) {
41086   PERFETTO_DCHECK_THREAD(thread_checker_);
41087   if (!muxer_)
41088     return;
41089   for (size_t inst_idx = 0; inst_idx < instance_count; inst_idx++) {
41090     muxer_->ClearDataSourceIncrementalState(backend_id_, instances[inst_idx]);
41091   }
41092 }
41093 
SweepDeadServices()41094 bool TracingMuxerImpl::ProducerImpl::SweepDeadServices() {
41095   PERFETTO_DCHECK_THREAD(thread_checker_);
41096   auto is_unused = [](const std::shared_ptr<ProducerEndpoint>& endpoint) {
41097     auto* arbiter = endpoint->MaybeSharedMemoryArbiter();
41098     return !arbiter || arbiter->TryShutdown();
41099   };
41100   for (auto it = dead_services_.begin(); it != dead_services_.end();) {
41101     auto next_it = it;
41102     next_it++;
41103     if (is_unused(*it)) {
41104       dead_services_.erase(it);
41105     }
41106     it = next_it;
41107   }
41108   return dead_services_.empty();
41109 }
41110 
41111 // ----- End of TracingMuxerImpl::ProducerImpl methods.
41112 
41113 // ----- Begin of TracingMuxerImpl::ConsumerImpl
ConsumerImpl(TracingMuxerImpl * muxer,BackendType backend_type,TracingBackendId backend_id,TracingSessionGlobalID session_id)41114 TracingMuxerImpl::ConsumerImpl::ConsumerImpl(TracingMuxerImpl* muxer,
41115                                              BackendType backend_type,
41116                                              TracingBackendId backend_id,
41117                                              TracingSessionGlobalID session_id)
41118     : muxer_(muxer),
41119       backend_type_(backend_type),
41120       backend_id_(backend_id),
41121       session_id_(session_id) {}
41122 
~ConsumerImpl()41123 TracingMuxerImpl::ConsumerImpl::~ConsumerImpl() {
41124   muxer_ = nullptr;
41125 }
41126 
Initialize(std::unique_ptr<ConsumerEndpoint> endpoint)41127 void TracingMuxerImpl::ConsumerImpl::Initialize(
41128     std::unique_ptr<ConsumerEndpoint> endpoint) {
41129   PERFETTO_DCHECK_THREAD(thread_checker_);
41130   service_ = std::move(endpoint);
41131   // Don't try to use the service here since it may not have connected yet. See
41132   // OnConnect().
41133 }
41134 
OnConnect()41135 void TracingMuxerImpl::ConsumerImpl::OnConnect() {
41136   PERFETTO_DCHECK_THREAD(thread_checker_);
41137   PERFETTO_DCHECK(!connected_);
41138   connected_ = true;
41139 
41140   // Observe data source instance events so we get notified when tracing starts.
41141   service_->ObserveEvents(ObservableEvents::TYPE_DATA_SOURCES_INSTANCES |
41142                           ObservableEvents::TYPE_ALL_DATA_SOURCES_STARTED);
41143 
41144   // If the API client configured and started tracing before we connected,
41145   // tell the backend about it now.
41146   if (trace_config_)
41147     muxer_->SetupTracingSession(session_id_, trace_config_);
41148   if (start_pending_)
41149     muxer_->StartTracingSession(session_id_);
41150   if (get_trace_stats_pending_) {
41151     auto callback = std::move(get_trace_stats_callback_);
41152     get_trace_stats_callback_ = nullptr;
41153     muxer_->GetTraceStats(session_id_, std::move(callback));
41154   }
41155   if (query_service_state_callback_) {
41156     auto callback = std::move(query_service_state_callback_);
41157     query_service_state_callback_ = nullptr;
41158     muxer_->QueryServiceState(session_id_, std::move(callback));
41159   }
41160   if (stop_pending_)
41161     muxer_->StopTracingSession(session_id_);
41162 }
41163 
OnDisconnect()41164 void TracingMuxerImpl::ConsumerImpl::OnDisconnect() {
41165   PERFETTO_DCHECK_THREAD(thread_checker_);
41166   // If we're being destroyed, bail out.
41167   if (!muxer_)
41168     return;
41169 #if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
41170   if (!connected_ && backend_type_ == kSystemBackend) {
41171     PERFETTO_ELOG(
41172         "Unable to connect to the system tracing service as a consumer. On "
41173         "Android, use the \"perfetto\" command line tool instead to start "
41174         "system-wide tracing sessions");
41175   }
41176 #endif  // PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
41177 
41178   // Notify the client about disconnection.
41179   NotifyError(TracingError{TracingError::kDisconnected, "Peer disconnected"});
41180 
41181   // Make sure the client doesn't hang in a blocking start/stop because of the
41182   // disconnection.
41183   NotifyStartComplete();
41184   NotifyStopComplete();
41185 
41186   // It shouldn't be necessary to call StopTracingSession. If we get this call
41187   // it means that the service did shutdown before us, so there is no point
41188   // trying it to ask it to stop the session. We should just remember to cleanup
41189   // the consumer vector.
41190   connected_ = false;
41191 
41192   // Notify the muxer that it is safe to destroy |this|. This is needed because
41193   // the ConsumerEndpoint stored in |service_| requires that |this| be safe to
41194   // access until OnDisconnect() is called.
41195   muxer_->OnConsumerDisconnected(this);
41196 }
41197 
Disconnect()41198 void TracingMuxerImpl::ConsumerImpl::Disconnect() {
41199   // This is weird and deserves a comment.
41200   //
41201   // When we called the ConnectConsumer method on the service it returns
41202   // us a ConsumerEndpoint which we stored in |service_|, however this
41203   // ConsumerEndpoint holds a pointer to the ConsumerImpl pointed to by
41204   // |this|. Part of the API contract to TracingService::ConnectConsumer is that
41205   // the ConsumerImpl pointer has to be valid until the
41206   // ConsumerImpl::OnDisconnect method is called. Therefore we reset the
41207   // ConsumerEndpoint |service_|. Eventually this will call
41208   // ConsumerImpl::OnDisconnect and we will inform the muxer it is safe to
41209   // call the destructor of |this|.
41210   service_.reset();
41211 }
41212 
OnTracingDisabled(const std::string & error)41213 void TracingMuxerImpl::ConsumerImpl::OnTracingDisabled(
41214     const std::string& error) {
41215   PERFETTO_DCHECK_THREAD(thread_checker_);
41216   PERFETTO_DCHECK(!stopped_);
41217   stopped_ = true;
41218 
41219   if (!error.empty())
41220     NotifyError(TracingError{TracingError::kTracingFailed, error});
41221 
41222   // If we're still waiting for the start event, fire it now. This may happen if
41223   // there are no active data sources in the session.
41224   NotifyStartComplete();
41225   NotifyStopComplete();
41226 }
41227 
NotifyStartComplete()41228 void TracingMuxerImpl::ConsumerImpl::NotifyStartComplete() {
41229   PERFETTO_DCHECK_THREAD(thread_checker_);
41230   if (start_complete_callback_) {
41231     muxer_->task_runner_->PostTask(std::move(start_complete_callback_));
41232     start_complete_callback_ = nullptr;
41233   }
41234   if (blocking_start_complete_callback_) {
41235     muxer_->task_runner_->PostTask(
41236         std::move(blocking_start_complete_callback_));
41237     blocking_start_complete_callback_ = nullptr;
41238   }
41239 }
41240 
NotifyError(const TracingError & error)41241 void TracingMuxerImpl::ConsumerImpl::NotifyError(const TracingError& error) {
41242   PERFETTO_DCHECK_THREAD(thread_checker_);
41243   if (error_callback_) {
41244     muxer_->task_runner_->PostTask(
41245         std::bind(std::move(error_callback_), error));
41246   }
41247 }
41248 
NotifyStopComplete()41249 void TracingMuxerImpl::ConsumerImpl::NotifyStopComplete() {
41250   PERFETTO_DCHECK_THREAD(thread_checker_);
41251   if (stop_complete_callback_) {
41252     muxer_->task_runner_->PostTask(std::move(stop_complete_callback_));
41253     stop_complete_callback_ = nullptr;
41254   }
41255   if (blocking_stop_complete_callback_) {
41256     muxer_->task_runner_->PostTask(std::move(blocking_stop_complete_callback_));
41257     blocking_stop_complete_callback_ = nullptr;
41258   }
41259 }
41260 
OnTraceData(std::vector<TracePacket> packets,bool has_more)41261 void TracingMuxerImpl::ConsumerImpl::OnTraceData(
41262     std::vector<TracePacket> packets,
41263     bool has_more) {
41264   PERFETTO_DCHECK_THREAD(thread_checker_);
41265   if (!read_trace_callback_)
41266     return;
41267 
41268   size_t capacity = 0;
41269   for (const auto& packet : packets) {
41270     // 16 is an over-estimation of the proto preamble size
41271     capacity += packet.size() + 16;
41272   }
41273 
41274   // The shared_ptr is to avoid making a copy of the buffer when PostTask-ing.
41275   std::shared_ptr<std::vector<char>> buf(new std::vector<char>());
41276   buf->reserve(capacity);
41277   for (auto& packet : packets) {
41278     char* start;
41279     size_t size;
41280     std::tie(start, size) = packet.GetProtoPreamble();
41281     buf->insert(buf->end(), start, start + size);
41282     for (auto& slice : packet.slices()) {
41283       const auto* slice_data = reinterpret_cast<const char*>(slice.start);
41284       buf->insert(buf->end(), slice_data, slice_data + slice.size);
41285     }
41286   }
41287 
41288   auto callback = read_trace_callback_;
41289   muxer_->task_runner_->PostTask([callback, buf, has_more] {
41290     TracingSession::ReadTraceCallbackArgs callback_arg{};
41291     callback_arg.data = buf->empty() ? nullptr : &(*buf)[0];
41292     callback_arg.size = buf->size();
41293     callback_arg.has_more = has_more;
41294     callback(callback_arg);
41295   });
41296 
41297   if (!has_more)
41298     read_trace_callback_ = nullptr;
41299 }
41300 
OnObservableEvents(const ObservableEvents & events)41301 void TracingMuxerImpl::ConsumerImpl::OnObservableEvents(
41302     const ObservableEvents& events) {
41303   if (events.instance_state_changes_size()) {
41304     for (const auto& state_change : events.instance_state_changes()) {
41305       DataSourceHandle handle{state_change.producer_name(),
41306                               state_change.data_source_name()};
41307       data_source_states_[handle] =
41308           state_change.state() ==
41309           ObservableEvents::DATA_SOURCE_INSTANCE_STATE_STARTED;
41310     }
41311   }
41312 
41313   if (events.instance_state_changes_size() ||
41314       events.all_data_sources_started()) {
41315     // Data sources are first reported as being stopped before starting, so once
41316     // all the data sources we know about have started we can declare tracing
41317     // begun. In the case where there are no matching data sources for the
41318     // session, the service will report the all_data_sources_started() event
41319     // without adding any instances (only since Android S / Perfetto v10.0).
41320     if (start_complete_callback_ || blocking_start_complete_callback_) {
41321       bool all_data_sources_started = std::all_of(
41322           data_source_states_.cbegin(), data_source_states_.cend(),
41323           [](std::pair<DataSourceHandle, bool> state) { return state.second; });
41324       if (all_data_sources_started)
41325         NotifyStartComplete();
41326     }
41327   }
41328 }
41329 
OnTraceStats(bool success,const TraceStats & trace_stats)41330 void TracingMuxerImpl::ConsumerImpl::OnTraceStats(
41331     bool success,
41332     const TraceStats& trace_stats) {
41333   if (!get_trace_stats_callback_)
41334     return;
41335   TracingSession::GetTraceStatsCallbackArgs callback_arg{};
41336   callback_arg.success = success;
41337   callback_arg.trace_stats_data = trace_stats.SerializeAsArray();
41338   muxer_->task_runner_->PostTask(
41339       std::bind(std::move(get_trace_stats_callback_), std::move(callback_arg)));
41340   get_trace_stats_callback_ = nullptr;
41341 }
41342 
41343 // The callbacks below are not used.
OnDetach(bool)41344 void TracingMuxerImpl::ConsumerImpl::OnDetach(bool) {}
OnAttach(bool,const TraceConfig &)41345 void TracingMuxerImpl::ConsumerImpl::OnAttach(bool, const TraceConfig&) {}
41346 // ----- End of TracingMuxerImpl::ConsumerImpl
41347 
41348 // ----- Begin of TracingMuxerImpl::TracingSessionImpl
41349 
41350 // TracingSessionImpl is the RAII object returned to API clients when they
41351 // invoke Tracing::CreateTracingSession. They use it for starting/stopping
41352 // tracing.
41353 
TracingSessionImpl(TracingMuxerImpl * muxer,TracingSessionGlobalID session_id,BackendType backend_type)41354 TracingMuxerImpl::TracingSessionImpl::TracingSessionImpl(
41355     TracingMuxerImpl* muxer,
41356     TracingSessionGlobalID session_id,
41357     BackendType backend_type)
41358     : muxer_(muxer), session_id_(session_id), backend_type_(backend_type) {}
41359 
41360 // Can be destroyed from any thread.
~TracingSessionImpl()41361 TracingMuxerImpl::TracingSessionImpl::~TracingSessionImpl() {
41362   auto* muxer = muxer_;
41363   auto session_id = session_id_;
41364   muxer->task_runner_->PostTask(
41365       [muxer, session_id] { muxer->DestroyTracingSession(session_id); });
41366 }
41367 
41368 // Can be called from any thread.
Setup(const TraceConfig & cfg,int fd)41369 void TracingMuxerImpl::TracingSessionImpl::Setup(const TraceConfig& cfg,
41370                                                  int fd) {
41371   auto* muxer = muxer_;
41372   auto session_id = session_id_;
41373   std::shared_ptr<TraceConfig> trace_config(new TraceConfig(cfg));
41374   if (fd >= 0) {
41375     base::ignore_result(backend_type_);  // For -Wunused in the amalgamation.
41376 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
41377     if (backend_type_ != kInProcessBackend) {
41378       PERFETTO_FATAL(
41379           "Passing a file descriptor to TracingSession::Setup() is only "
41380           "supported with the kInProcessBackend on Windows. Use "
41381           "TracingSession::ReadTrace() instead");
41382     }
41383 #endif
41384     trace_config->set_write_into_file(true);
41385     fd = dup(fd);
41386   }
41387   muxer->task_runner_->PostTask([muxer, session_id, trace_config, fd] {
41388     muxer->SetupTracingSession(session_id, trace_config, base::ScopedFile(fd));
41389   });
41390 }
41391 
41392 // Can be called from any thread.
Start()41393 void TracingMuxerImpl::TracingSessionImpl::Start() {
41394   auto* muxer = muxer_;
41395   auto session_id = session_id_;
41396   muxer->task_runner_->PostTask(
41397       [muxer, session_id] { muxer->StartTracingSession(session_id); });
41398 }
41399 
41400 // Can be called from any thread.
ChangeTraceConfig(const TraceConfig & cfg)41401 void TracingMuxerImpl::TracingSessionImpl::ChangeTraceConfig(
41402     const TraceConfig& cfg) {
41403   auto* muxer = muxer_;
41404   auto session_id = session_id_;
41405   muxer->task_runner_->PostTask([muxer, session_id, cfg] {
41406     muxer->ChangeTracingSessionConfig(session_id, cfg);
41407   });
41408 }
41409 
41410 // Can be called from any thread except the service thread.
StartBlocking()41411 void TracingMuxerImpl::TracingSessionImpl::StartBlocking() {
41412   PERFETTO_DCHECK(!muxer_->task_runner_->RunsTasksOnCurrentThread());
41413   auto* muxer = muxer_;
41414   auto session_id = session_id_;
41415   base::WaitableEvent tracing_started;
41416   muxer->task_runner_->PostTask([muxer, session_id, &tracing_started] {
41417     auto* consumer = muxer->FindConsumer(session_id);
41418     if (!consumer) {
41419       // TODO(skyostil): Signal an error to the user.
41420       tracing_started.Notify();
41421       return;
41422     }
41423     PERFETTO_DCHECK(!consumer->blocking_start_complete_callback_);
41424     consumer->blocking_start_complete_callback_ = [&] {
41425       tracing_started.Notify();
41426     };
41427     muxer->StartTracingSession(session_id);
41428   });
41429   tracing_started.Wait();
41430 }
41431 
41432 // Can be called from any thread.
Flush(std::function<void (bool)> user_callback,uint32_t timeout_ms)41433 void TracingMuxerImpl::TracingSessionImpl::Flush(
41434     std::function<void(bool)> user_callback,
41435     uint32_t timeout_ms) {
41436   auto* muxer = muxer_;
41437   auto session_id = session_id_;
41438   muxer->task_runner_->PostTask([muxer, session_id, timeout_ms, user_callback] {
41439     auto* consumer = muxer->FindConsumer(session_id);
41440     if (!consumer) {
41441       std::move(user_callback)(false);
41442       return;
41443     }
41444     muxer->FlushTracingSession(session_id, timeout_ms,
41445                                std::move(user_callback));
41446   });
41447 }
41448 
41449 // Can be called from any thread.
Stop()41450 void TracingMuxerImpl::TracingSessionImpl::Stop() {
41451   auto* muxer = muxer_;
41452   auto session_id = session_id_;
41453   muxer->task_runner_->PostTask(
41454       [muxer, session_id] { muxer->StopTracingSession(session_id); });
41455 }
41456 
41457 // Can be called from any thread except the service thread.
StopBlocking()41458 void TracingMuxerImpl::TracingSessionImpl::StopBlocking() {
41459   PERFETTO_DCHECK(!muxer_->task_runner_->RunsTasksOnCurrentThread());
41460   auto* muxer = muxer_;
41461   auto session_id = session_id_;
41462   base::WaitableEvent tracing_stopped;
41463   muxer->task_runner_->PostTask([muxer, session_id, &tracing_stopped] {
41464     auto* consumer = muxer->FindConsumer(session_id);
41465     if (!consumer) {
41466       // TODO(skyostil): Signal an error to the user.
41467       tracing_stopped.Notify();
41468       return;
41469     }
41470     PERFETTO_DCHECK(!consumer->blocking_stop_complete_callback_);
41471     consumer->blocking_stop_complete_callback_ = [&] {
41472       tracing_stopped.Notify();
41473     };
41474     muxer->StopTracingSession(session_id);
41475   });
41476   tracing_stopped.Wait();
41477 }
41478 
41479 // Can be called from any thread.
ReadTrace(ReadTraceCallback cb)41480 void TracingMuxerImpl::TracingSessionImpl::ReadTrace(ReadTraceCallback cb) {
41481   auto* muxer = muxer_;
41482   auto session_id = session_id_;
41483   muxer->task_runner_->PostTask([muxer, session_id, cb] {
41484     muxer->ReadTracingSessionData(session_id, std::move(cb));
41485   });
41486 }
41487 
41488 // Can be called from any thread.
SetOnStartCallback(std::function<void ()> cb)41489 void TracingMuxerImpl::TracingSessionImpl::SetOnStartCallback(
41490     std::function<void()> cb) {
41491   auto* muxer = muxer_;
41492   auto session_id = session_id_;
41493   muxer->task_runner_->PostTask([muxer, session_id, cb] {
41494     auto* consumer = muxer->FindConsumer(session_id);
41495     if (!consumer)
41496       return;
41497     consumer->start_complete_callback_ = cb;
41498   });
41499 }
41500 
41501 // Can be called from any thread
SetOnErrorCallback(std::function<void (TracingError)> cb)41502 void TracingMuxerImpl::TracingSessionImpl::SetOnErrorCallback(
41503     std::function<void(TracingError)> cb) {
41504   auto* muxer = muxer_;
41505   auto session_id = session_id_;
41506   muxer->task_runner_->PostTask([muxer, session_id, cb] {
41507     auto* consumer = muxer->FindConsumer(session_id);
41508     if (!consumer) {
41509       // Notify the client about concurrent disconnection of the session.
41510       if (cb)
41511         cb(TracingError{TracingError::kDisconnected, "Peer disconnected"});
41512       return;
41513     }
41514     consumer->error_callback_ = cb;
41515   });
41516 }
41517 
41518 // Can be called from any thread.
SetOnStopCallback(std::function<void ()> cb)41519 void TracingMuxerImpl::TracingSessionImpl::SetOnStopCallback(
41520     std::function<void()> cb) {
41521   auto* muxer = muxer_;
41522   auto session_id = session_id_;
41523   muxer->task_runner_->PostTask([muxer, session_id, cb] {
41524     auto* consumer = muxer->FindConsumer(session_id);
41525     if (!consumer)
41526       return;
41527     consumer->stop_complete_callback_ = cb;
41528   });
41529 }
41530 
41531 // Can be called from any thread.
GetTraceStats(GetTraceStatsCallback cb)41532 void TracingMuxerImpl::TracingSessionImpl::GetTraceStats(
41533     GetTraceStatsCallback cb) {
41534   auto* muxer = muxer_;
41535   auto session_id = session_id_;
41536   muxer->task_runner_->PostTask([muxer, session_id, cb] {
41537     muxer->GetTraceStats(session_id, std::move(cb));
41538   });
41539 }
41540 
41541 // Can be called from any thread.
QueryServiceState(QueryServiceStateCallback cb)41542 void TracingMuxerImpl::TracingSessionImpl::QueryServiceState(
41543     QueryServiceStateCallback cb) {
41544   auto* muxer = muxer_;
41545   auto session_id = session_id_;
41546   muxer->task_runner_->PostTask([muxer, session_id, cb] {
41547     muxer->QueryServiceState(session_id, std::move(cb));
41548   });
41549 }
41550 
41551 // ----- End of TracingMuxerImpl::TracingSessionImpl
41552 
41553 // static
41554 TracingMuxer* TracingMuxer::instance_ = TracingMuxerFake::Get();
41555 
41556 // This is called by perfetto::Tracing::Initialize().
41557 // Can be called on any thread. Typically, but not necessarily, that will be
41558 // the embedder's main thread.
TracingMuxerImpl(const TracingInitArgs & args)41559 TracingMuxerImpl::TracingMuxerImpl(const TracingInitArgs& args)
41560     : TracingMuxer(args.platform ? args.platform
41561                                  : Platform::GetDefaultPlatform()) {
41562   PERFETTO_DETACH_FROM_THREAD(thread_checker_);
41563   instance_ = this;
41564 
41565   // Create the thread where muxer, producers and service will live.
41566   Platform::CreateTaskRunnerArgs tr_args{/*name_for_debugging=*/"TracingMuxer"};
41567   task_runner_.reset(new NonReentrantTaskRunner(
41568       this, platform_->CreateTaskRunner(std::move(tr_args))));
41569 
41570   // Run the initializer on that thread.
41571   task_runner_->PostTask([this, args] { Initialize(args); });
41572 }
41573 
Initialize(const TracingInitArgs & args)41574 void TracingMuxerImpl::Initialize(const TracingInitArgs& args) {
41575   PERFETTO_DCHECK_THREAD(thread_checker_);  // Rebind the thread checker.
41576 
41577   policy_ = args.tracing_policy;
41578 
41579   auto add_backend = [this, &args](TracingBackend* backend, BackendType type) {
41580     if (!backend) {
41581       // We skip the log in release builds because the *_backend_fake.cc code
41582       // has already an ELOG before returning a nullptr.
41583       PERFETTO_DLOG("Backend creation failed, type %d", static_cast<int>(type));
41584       return;
41585     }
41586     TracingBackendId backend_id = backends_.size();
41587     backends_.emplace_back();
41588     RegisteredBackend& rb = backends_.back();
41589     rb.backend = backend;
41590     rb.id = backend_id;
41591     rb.type = type;
41592     rb.producer.reset(new ProducerImpl(this, backend_id,
41593                                        args.shmem_batch_commits_duration_ms));
41594     rb.producer_conn_args.producer = rb.producer.get();
41595     rb.producer_conn_args.producer_name = platform_->GetCurrentProcessName();
41596     rb.producer_conn_args.task_runner = task_runner_.get();
41597     rb.producer_conn_args.shmem_size_hint_bytes =
41598         args.shmem_size_hint_kb * 1024;
41599     rb.producer_conn_args.shmem_page_size_hint_bytes =
41600         args.shmem_page_size_hint_kb * 1024;
41601     rb.producer->Initialize(rb.backend->ConnectProducer(rb.producer_conn_args));
41602   };
41603 
41604   if (args.backends & kSystemBackend) {
41605     PERFETTO_CHECK(args.system_backend_factory_);
41606     add_backend(args.system_backend_factory_(), kSystemBackend);
41607   }
41608 
41609   if (args.backends & kInProcessBackend) {
41610     PERFETTO_CHECK(args.in_process_backend_factory_);
41611     add_backend(args.in_process_backend_factory_(), kInProcessBackend);
41612   }
41613 
41614   if (args.backends & kCustomBackend) {
41615     PERFETTO_CHECK(args.custom_backend);
41616     add_backend(args.custom_backend, kCustomBackend);
41617   }
41618 
41619   if (args.backends & ~(kSystemBackend | kInProcessBackend | kCustomBackend)) {
41620     PERFETTO_FATAL("Unsupported tracing backend type");
41621   }
41622 
41623   // Fallback backend for consumer creation for an unsupported backend type.
41624   // This backend simply fails any attempt to start a tracing session.
41625   // NOTE: This backend instance has to be added last.
41626   add_backend(internal::TracingBackendFake::GetInstance(),
41627               BackendType::kUnspecifiedBackend);
41628 }
41629 
41630 // Can be called from any thread (but not concurrently).
RegisterDataSource(const DataSourceDescriptor & descriptor,DataSourceFactory factory,DataSourceStaticState * static_state)41631 bool TracingMuxerImpl::RegisterDataSource(
41632     const DataSourceDescriptor& descriptor,
41633     DataSourceFactory factory,
41634     DataSourceStaticState* static_state) {
41635   // Ignore repeated registrations.
41636   if (static_state->index != kMaxDataSources)
41637     return true;
41638 
41639   uint32_t new_index = next_data_source_index_++;
41640   if (new_index >= kMaxDataSources) {
41641     PERFETTO_DLOG(
41642         "RegisterDataSource failed: too many data sources already registered");
41643     return false;
41644   }
41645 
41646   // Initialize the static state.
41647   static_assert(sizeof(static_state->instances[0]) >= sizeof(DataSourceState),
41648                 "instances[] size mismatch");
41649   for (size_t i = 0; i < static_state->instances.size(); i++)
41650     new (&static_state->instances[i]) DataSourceState{};
41651 
41652   static_state->index = new_index;
41653 
41654   // Generate a semi-unique id for this data source.
41655   base::Hash hash;
41656   hash.Update(reinterpret_cast<intptr_t>(static_state));
41657   hash.Update(base::GetWallTimeNs().count());
41658   static_state->id = hash.digest() ? hash.digest() : 1;
41659 
41660   task_runner_->PostTask([this, descriptor, factory, static_state] {
41661     data_sources_.emplace_back();
41662     RegisteredDataSource& rds = data_sources_.back();
41663     rds.descriptor = descriptor;
41664     rds.factory = factory;
41665     rds.static_state = static_state;
41666 
41667     UpdateDataSourceOnAllBackends(rds, /*is_changed=*/false);
41668   });
41669   return true;
41670 }
41671 
41672 // Can be called from any thread (but not concurrently).
UpdateDataSourceDescriptor(const DataSourceDescriptor & descriptor,const DataSourceStaticState * static_state)41673 void TracingMuxerImpl::UpdateDataSourceDescriptor(
41674     const DataSourceDescriptor& descriptor,
41675     const DataSourceStaticState* static_state) {
41676   task_runner_->PostTask([this, descriptor, static_state] {
41677     for (auto& rds : data_sources_) {
41678       if (rds.static_state == static_state) {
41679         PERFETTO_CHECK(rds.descriptor.name() == descriptor.name());
41680         rds.descriptor = descriptor;
41681         rds.descriptor.set_id(static_state->id);
41682         UpdateDataSourceOnAllBackends(rds, /*is_changed=*/true);
41683         return;
41684       }
41685     }
41686   });
41687 }
41688 
41689 // Can be called from any thread (but not concurrently).
RegisterInterceptor(const InterceptorDescriptor & descriptor,InterceptorFactory factory,InterceptorBase::TLSFactory tls_factory,InterceptorBase::TracePacketCallback packet_callback)41690 void TracingMuxerImpl::RegisterInterceptor(
41691     const InterceptorDescriptor& descriptor,
41692     InterceptorFactory factory,
41693     InterceptorBase::TLSFactory tls_factory,
41694     InterceptorBase::TracePacketCallback packet_callback) {
41695   task_runner_->PostTask(
41696       [this, descriptor, factory, tls_factory, packet_callback] {
41697         // Ignore repeated registrations.
41698         for (const auto& interceptor : interceptors_) {
41699           if (interceptor.descriptor.name() == descriptor.name()) {
41700             PERFETTO_DCHECK(interceptor.tls_factory == tls_factory);
41701             PERFETTO_DCHECK(interceptor.packet_callback == packet_callback);
41702             return;
41703           }
41704         }
41705         // Only allow certain interceptors for now.
41706         if (descriptor.name() != "test_interceptor" &&
41707             descriptor.name() != "console") {
41708           PERFETTO_ELOG(
41709               "Interceptors are experimental. If you want to use them, please "
41710               "get in touch with the project maintainers "
41711               "(https://perfetto.dev/docs/contributing/"
41712               "getting-started#community).");
41713           return;
41714         }
41715         interceptors_.emplace_back();
41716         RegisteredInterceptor& interceptor = interceptors_.back();
41717         interceptor.descriptor = descriptor;
41718         interceptor.factory = factory;
41719         interceptor.tls_factory = tls_factory;
41720         interceptor.packet_callback = packet_callback;
41721       });
41722 }
41723 
41724 // Called by the service of one of the backends.
SetupDataSource(TracingBackendId backend_id,uint32_t backend_connection_id,DataSourceInstanceID instance_id,const DataSourceConfig & cfg)41725 void TracingMuxerImpl::SetupDataSource(TracingBackendId backend_id,
41726                                        uint32_t backend_connection_id,
41727                                        DataSourceInstanceID instance_id,
41728                                        const DataSourceConfig& cfg) {
41729   PERFETTO_DCHECK_THREAD(thread_checker_);
41730   PERFETTO_DLOG("Setting up data source %" PRIu64 " %s", instance_id,
41731                 cfg.name().c_str());
41732   uint64_t config_hash = ComputeConfigHash(cfg);
41733 
41734   for (const auto& rds : data_sources_) {
41735     if (rds.descriptor.name() != cfg.name())
41736       continue;
41737     DataSourceStaticState& static_state = *rds.static_state;
41738 
41739     // If this data source is already active for this exact config, don't start
41740     // another instance. This happens when we have several data sources with the
41741     // same name, in which case the service sends one SetupDataSource event for
41742     // each one. Since we can't map which event maps to which data source, we
41743     // ensure each event only starts one data source instance.
41744     // TODO(skyostil): Register a unique id with each data source to the service
41745     // to disambiguate.
41746     bool active_for_config = false;
41747     for (uint32_t i = 0; i < kMaxDataSourceInstances; i++) {
41748       if (!static_state.TryGet(i))
41749         continue;
41750       auto* internal_state =
41751           reinterpret_cast<DataSourceState*>(&static_state.instances[i]);
41752       if (internal_state->backend_id == backend_id &&
41753           internal_state->config_hash == config_hash) {
41754         active_for_config = true;
41755         break;
41756       }
41757     }
41758     if (active_for_config) {
41759       PERFETTO_DLOG(
41760           "Data source %s is already active with this config, skipping",
41761           cfg.name().c_str());
41762       continue;
41763     }
41764 
41765     for (uint32_t i = 0; i < kMaxDataSourceInstances; i++) {
41766       // Find a free slot.
41767       if (static_state.TryGet(i))
41768         continue;
41769 
41770       auto* internal_state =
41771           reinterpret_cast<DataSourceState*>(&static_state.instances[i]);
41772       std::lock_guard<std::recursive_mutex> guard(internal_state->lock);
41773       static_assert(
41774           std::is_same<decltype(internal_state->data_source_instance_id),
41775                        DataSourceInstanceID>::value,
41776           "data_source_instance_id type mismatch");
41777       internal_state->muxer_id_for_testing = muxer_id_for_testing_;
41778       internal_state->backend_id = backend_id;
41779       internal_state->backend_connection_id = backend_connection_id;
41780       internal_state->data_source_instance_id = instance_id;
41781       internal_state->buffer_id =
41782           static_cast<internal::BufferId>(cfg.target_buffer());
41783       internal_state->config_hash = config_hash;
41784       internal_state->data_source = rds.factory();
41785       internal_state->interceptor = nullptr;
41786       internal_state->interceptor_id = 0;
41787 
41788       if (cfg.has_interceptor_config()) {
41789         for (size_t j = 0; j < interceptors_.size(); j++) {
41790           if (cfg.interceptor_config().name() ==
41791               interceptors_[j].descriptor.name()) {
41792             PERFETTO_DLOG("Intercepting data source %" PRIu64
41793                           " \"%s\" into \"%s\"",
41794                           instance_id, cfg.name().c_str(),
41795                           cfg.interceptor_config().name().c_str());
41796             internal_state->interceptor_id = static_cast<uint32_t>(j + 1);
41797             internal_state->interceptor = interceptors_[j].factory();
41798             internal_state->interceptor->OnSetup({cfg});
41799             break;
41800           }
41801         }
41802         if (!internal_state->interceptor_id) {
41803           PERFETTO_ELOG("Unknown interceptor configured for data source: %s",
41804                         cfg.interceptor_config().name().c_str());
41805         }
41806       }
41807 
41808       // This must be made at the end. See matching acquire-load in
41809       // DataSource::Trace().
41810       static_state.valid_instances.fetch_or(1 << i, std::memory_order_release);
41811 
41812       DataSourceBase::SetupArgs setup_args;
41813       setup_args.config = &cfg;
41814       setup_args.internal_instance_index = i;
41815       internal_state->data_source->OnSetup(setup_args);
41816       return;
41817     }
41818     PERFETTO_ELOG(
41819         "Maximum number of data source instances exhausted. "
41820         "Dropping data source %" PRIu64,
41821         instance_id);
41822     break;
41823   }
41824 }
41825 
41826 // Called by the service of one of the backends.
StartDataSource(TracingBackendId backend_id,DataSourceInstanceID instance_id)41827 void TracingMuxerImpl::StartDataSource(TracingBackendId backend_id,
41828                                        DataSourceInstanceID instance_id) {
41829   PERFETTO_DLOG("Starting data source %" PRIu64, instance_id);
41830   PERFETTO_DCHECK_THREAD(thread_checker_);
41831 
41832   auto ds = FindDataSource(backend_id, instance_id);
41833   if (!ds) {
41834     PERFETTO_ELOG("Could not find data source to start");
41835     return;
41836   }
41837 
41838   DataSourceBase::StartArgs start_args{};
41839   start_args.internal_instance_index = ds.instance_idx;
41840 
41841   std::lock_guard<std::recursive_mutex> guard(ds.internal_state->lock);
41842   if (ds.internal_state->interceptor)
41843     ds.internal_state->interceptor->OnStart({});
41844   ds.internal_state->trace_lambda_enabled = true;
41845   ds.internal_state->data_source->OnStart(start_args);
41846 }
41847 
41848 // Called by the service of one of the backends.
StopDataSource_AsyncBegin(TracingBackendId backend_id,DataSourceInstanceID instance_id)41849 void TracingMuxerImpl::StopDataSource_AsyncBegin(
41850     TracingBackendId backend_id,
41851     DataSourceInstanceID instance_id) {
41852   PERFETTO_DLOG("Stopping data source %" PRIu64, instance_id);
41853   PERFETTO_DCHECK_THREAD(thread_checker_);
41854 
41855   auto ds = FindDataSource(backend_id, instance_id);
41856   if (!ds) {
41857     PERFETTO_ELOG("Could not find data source to stop");
41858     return;
41859   }
41860 
41861   StopArgsImpl stop_args{};
41862   stop_args.internal_instance_index = ds.instance_idx;
41863   stop_args.async_stop_closure = [this, backend_id, instance_id] {
41864     // TracingMuxerImpl is long lived, capturing |this| is okay.
41865     // The notification closure can be moved out of the StopArgs by the
41866     // embedder to handle stop asynchronously. The embedder might then
41867     // call the closure on a different thread than the current one, hence
41868     // this nested PostTask().
41869     task_runner_->PostTask([this, backend_id, instance_id] {
41870       StopDataSource_AsyncEnd(backend_id, instance_id);
41871     });
41872   };
41873 
41874   {
41875     std::lock_guard<std::recursive_mutex> guard(ds.internal_state->lock);
41876     if (ds.internal_state->interceptor)
41877       ds.internal_state->interceptor->OnStop({});
41878     ds.internal_state->data_source->OnStop(stop_args);
41879   }
41880 
41881   // If the embedder hasn't called StopArgs.HandleStopAsynchronously() run the
41882   // async closure here. In theory we could avoid the PostTask and call
41883   // straight into CompleteDataSourceAsyncStop(). We keep that to reduce
41884   // divergencies between the deferred-stop vs non-deferred-stop code paths.
41885   if (stop_args.async_stop_closure)
41886     std::move(stop_args.async_stop_closure)();
41887 }
41888 
StopDataSource_AsyncEnd(TracingBackendId backend_id,DataSourceInstanceID instance_id)41889 void TracingMuxerImpl::StopDataSource_AsyncEnd(
41890     TracingBackendId backend_id,
41891     DataSourceInstanceID instance_id) {
41892   PERFETTO_DLOG("Ending async stop of data source %" PRIu64, instance_id);
41893   PERFETTO_DCHECK_THREAD(thread_checker_);
41894 
41895   auto ds = FindDataSource(backend_id, instance_id);
41896   if (!ds) {
41897     PERFETTO_ELOG(
41898         "Async stop of data source %" PRIu64
41899         " failed. This might be due to calling the async_stop_closure twice.",
41900         instance_id);
41901     return;
41902   }
41903 
41904   const uint32_t mask = ~(1 << ds.instance_idx);
41905   ds.static_state->valid_instances.fetch_and(mask, std::memory_order_acq_rel);
41906 
41907   // Take the mutex to prevent that the data source is in the middle of
41908   // a Trace() execution where it called GetDataSourceLocked() while we
41909   // destroy it.
41910   {
41911     std::lock_guard<std::recursive_mutex> guard(ds.internal_state->lock);
41912     ds.internal_state->trace_lambda_enabled = false;
41913     ds.internal_state->data_source.reset();
41914     ds.internal_state->interceptor.reset();
41915   }
41916 
41917   // The other fields of internal_state are deliberately *not* cleared.
41918   // See races-related comments of DataSource::Trace().
41919 
41920   TracingMuxer::generation_++;
41921 
41922   // |backends_| is append-only, Backend instances are always valid.
41923   PERFETTO_CHECK(backend_id < backends_.size());
41924   ProducerImpl* producer = backends_[backend_id].producer.get();
41925   if (!producer)
41926     return;
41927   if (producer->connected_) {
41928     // Flush any commits that might have been batched by SharedMemoryArbiter.
41929     producer->service_->MaybeSharedMemoryArbiter()
41930         ->FlushPendingCommitDataRequests();
41931     producer->service_->NotifyDataSourceStopped(instance_id);
41932   }
41933   producer->SweepDeadServices();
41934 }
41935 
ClearDataSourceIncrementalState(TracingBackendId backend_id,DataSourceInstanceID instance_id)41936 void TracingMuxerImpl::ClearDataSourceIncrementalState(
41937     TracingBackendId backend_id,
41938     DataSourceInstanceID instance_id) {
41939   PERFETTO_DCHECK_THREAD(thread_checker_);
41940   PERFETTO_DLOG("Clearing incremental state for data source %" PRIu64,
41941                 instance_id);
41942   auto ds = FindDataSource(backend_id, instance_id);
41943   if (!ds) {
41944     PERFETTO_ELOG("Could not find data source to clear incremental state for");
41945     return;
41946   }
41947   // Make DataSource::TraceContext::GetIncrementalState() eventually notice that
41948   // the incremental state should be cleared.
41949   ds.static_state->incremental_state_generation.fetch_add(
41950       1, std::memory_order_relaxed);
41951 }
41952 
SyncProducersForTesting()41953 void TracingMuxerImpl::SyncProducersForTesting() {
41954   std::mutex mutex;
41955   std::condition_variable cv;
41956 
41957   // IPC-based producers don't report connection errors explicitly for each
41958   // command, but instead with an asynchronous callback
41959   // (ProducerImpl::OnDisconnected). This means that the sync command below
41960   // may have completed but failed to reach the service because of a
41961   // disconnection, but we can't tell until the disconnection message comes
41962   // through. To guard against this, we run two whole rounds of sync round-trips
41963   // before returning; the first one will detect any disconnected producers and
41964   // the second one will ensure any reconnections have completed and all data
41965   // sources are registered in the service again.
41966   for (size_t i = 0; i < 2; i++) {
41967     size_t countdown = std::numeric_limits<size_t>::max();
41968     task_runner_->PostTask([this, &mutex, &cv, &countdown] {
41969       {
41970         std::unique_lock<std::mutex> countdown_lock(mutex);
41971         countdown = backends_.size();
41972       }
41973       for (auto& backend : backends_) {
41974         auto* producer = backend.producer.get();
41975         producer->service_->Sync([&mutex, &cv, &countdown] {
41976           std::unique_lock<std::mutex> countdown_lock(mutex);
41977           countdown--;
41978           cv.notify_one();
41979         });
41980       }
41981     });
41982 
41983     {
41984       std::unique_lock<std::mutex> countdown_lock(mutex);
41985       cv.wait(countdown_lock, [&countdown] { return !countdown; });
41986     }
41987   }
41988 
41989   // Check that all producers are indeed connected.
41990   bool done = false;
41991   bool all_producers_connected = true;
41992   task_runner_->PostTask([this, &mutex, &cv, &done, &all_producers_connected] {
41993     for (auto& backend : backends_)
41994       all_producers_connected &= backend.producer->connected_;
41995     std::unique_lock<std::mutex> lock(mutex);
41996     done = true;
41997     cv.notify_one();
41998   });
41999 
42000   {
42001     std::unique_lock<std::mutex> lock(mutex);
42002     cv.wait(lock, [&done] { return done; });
42003   }
42004   PERFETTO_DCHECK(all_producers_connected);
42005 }
42006 
DestroyStoppedTraceWritersForCurrentThread()42007 void TracingMuxerImpl::DestroyStoppedTraceWritersForCurrentThread() {
42008   // Iterate across all possible data source types.
42009   auto cur_generation = generation_.load(std::memory_order_acquire);
42010   auto* root_tls = GetOrCreateTracingTLS();
42011 
42012   auto destroy_stopped_instances = [](DataSourceThreadLocalState& tls) {
42013     // |tls| has a vector of per-data-source-instance thread-local state.
42014     DataSourceStaticState* static_state = tls.static_state;
42015     if (!static_state)
42016       return;  // Slot not used.
42017 
42018     // Iterate across all possible instances for this data source.
42019     for (uint32_t inst = 0; inst < kMaxDataSourceInstances; inst++) {
42020       DataSourceInstanceThreadLocalState& ds_tls = tls.per_instance[inst];
42021       if (!ds_tls.trace_writer)
42022         continue;
42023 
42024       DataSourceState* ds_state = static_state->TryGet(inst);
42025       if (ds_state &&
42026           ds_state->muxer_id_for_testing == ds_tls.muxer_id_for_testing &&
42027           ds_state->backend_id == ds_tls.backend_id &&
42028           ds_state->backend_connection_id == ds_tls.backend_connection_id &&
42029           ds_state->buffer_id == ds_tls.buffer_id &&
42030           ds_state->data_source_instance_id == ds_tls.data_source_instance_id) {
42031         continue;
42032       }
42033 
42034       // The DataSource instance has been destroyed or recycled.
42035       ds_tls.Reset();  // Will also destroy the |ds_tls.trace_writer|.
42036     }
42037   };
42038 
42039   for (size_t ds_idx = 0; ds_idx < kMaxDataSources; ds_idx++) {
42040     // |tls| has a vector of per-data-source-instance thread-local state.
42041     DataSourceThreadLocalState& tls = root_tls->data_sources_tls[ds_idx];
42042     destroy_stopped_instances(tls);
42043   }
42044   destroy_stopped_instances(root_tls->track_event_tls);
42045   root_tls->generation = cur_generation;
42046 }
42047 
42048 // Called both when a new data source is registered or when a new backend
42049 // connects. In both cases we want to be sure we reflected the data source
42050 // registrations on the backends.
UpdateDataSourcesOnAllBackends()42051 void TracingMuxerImpl::UpdateDataSourcesOnAllBackends() {
42052   PERFETTO_DCHECK_THREAD(thread_checker_);
42053   for (RegisteredDataSource& rds : data_sources_) {
42054     UpdateDataSourceOnAllBackends(rds, /*is_changed=*/false);
42055   }
42056 }
42057 
UpdateDataSourceOnAllBackends(RegisteredDataSource & rds,bool is_changed)42058 void TracingMuxerImpl::UpdateDataSourceOnAllBackends(RegisteredDataSource& rds,
42059                                                      bool is_changed) {
42060   PERFETTO_DCHECK_THREAD(thread_checker_);
42061   for (RegisteredBackend& backend : backends_) {
42062     // We cannot call RegisterDataSource on the backend before it connects.
42063     if (!backend.producer->connected_)
42064       continue;
42065 
42066     PERFETTO_DCHECK(rds.static_state->index < kMaxDataSources);
42067     bool is_registered = backend.producer->registered_data_sources_.test(
42068         rds.static_state->index);
42069     if (is_registered && !is_changed)
42070       continue;
42071 
42072     rds.descriptor.set_will_notify_on_start(true);
42073     rds.descriptor.set_will_notify_on_stop(true);
42074     rds.descriptor.set_handles_incremental_state_clear(true);
42075     rds.descriptor.set_id(rds.static_state->id);
42076     if (is_registered) {
42077       backend.producer->service_->UpdateDataSource(rds.descriptor);
42078     } else {
42079       backend.producer->service_->RegisterDataSource(rds.descriptor);
42080     }
42081     backend.producer->registered_data_sources_.set(rds.static_state->index);
42082   }
42083 }
42084 
SetupTracingSession(TracingSessionGlobalID session_id,const std::shared_ptr<TraceConfig> & trace_config,base::ScopedFile trace_fd)42085 void TracingMuxerImpl::SetupTracingSession(
42086     TracingSessionGlobalID session_id,
42087     const std::shared_ptr<TraceConfig>& trace_config,
42088     base::ScopedFile trace_fd) {
42089   PERFETTO_DCHECK_THREAD(thread_checker_);
42090   PERFETTO_CHECK(!trace_fd || trace_config->write_into_file());
42091 
42092   auto* consumer = FindConsumer(session_id);
42093   if (!consumer)
42094     return;
42095 
42096   consumer->trace_config_ = trace_config;
42097   if (trace_fd)
42098     consumer->trace_fd_ = std::move(trace_fd);
42099 
42100   if (!consumer->connected_)
42101     return;
42102 
42103   // Only used in the deferred start mode.
42104   if (trace_config->deferred_start()) {
42105     consumer->service_->EnableTracing(*trace_config,
42106                                       std::move(consumer->trace_fd_));
42107   }
42108 }
42109 
StartTracingSession(TracingSessionGlobalID session_id)42110 void TracingMuxerImpl::StartTracingSession(TracingSessionGlobalID session_id) {
42111   PERFETTO_DCHECK_THREAD(thread_checker_);
42112 
42113   auto* consumer = FindConsumer(session_id);
42114 
42115   if (!consumer)
42116     return;
42117 
42118   if (!consumer->trace_config_) {
42119     PERFETTO_ELOG("Must call Setup(config) first");
42120     return;
42121   }
42122 
42123   if (!consumer->connected_) {
42124     consumer->start_pending_ = true;
42125     return;
42126   }
42127 
42128   consumer->start_pending_ = false;
42129   if (consumer->trace_config_->deferred_start()) {
42130     consumer->service_->StartTracing();
42131   } else {
42132     consumer->service_->EnableTracing(*consumer->trace_config_,
42133                                       std::move(consumer->trace_fd_));
42134   }
42135 
42136   // TODO implement support for the deferred-start + fast-triggering case.
42137 }
42138 
ChangeTracingSessionConfig(TracingSessionGlobalID session_id,const TraceConfig & trace_config)42139 void TracingMuxerImpl::ChangeTracingSessionConfig(
42140     TracingSessionGlobalID session_id,
42141     const TraceConfig& trace_config) {
42142   PERFETTO_DCHECK_THREAD(thread_checker_);
42143 
42144   auto* consumer = FindConsumer(session_id);
42145 
42146   if (!consumer)
42147     return;
42148 
42149   if (!consumer->trace_config_) {
42150     // Changing the config is only supported for started sessions.
42151     PERFETTO_ELOG("Must call Setup(config) and Start() first");
42152     return;
42153   }
42154 
42155   consumer->trace_config_ = std::make_shared<TraceConfig>(trace_config);
42156   if (consumer->connected_)
42157     consumer->service_->ChangeTraceConfig(trace_config);
42158 }
42159 
FlushTracingSession(TracingSessionGlobalID session_id,uint32_t timeout_ms,std::function<void (bool)> callback)42160 void TracingMuxerImpl::FlushTracingSession(TracingSessionGlobalID session_id,
42161                                            uint32_t timeout_ms,
42162                                            std::function<void(bool)> callback) {
42163   PERFETTO_DCHECK_THREAD(thread_checker_);
42164   auto* consumer = FindConsumer(session_id);
42165   if (!consumer || consumer->start_pending_ || consumer->stop_pending_ ||
42166       !consumer->trace_config_) {
42167     PERFETTO_ELOG("Flush() can be called only after Start() and before Stop()");
42168     std::move(callback)(false);
42169     return;
42170   }
42171 
42172   consumer->service_->Flush(timeout_ms, std::move(callback));
42173 }
42174 
StopTracingSession(TracingSessionGlobalID session_id)42175 void TracingMuxerImpl::StopTracingSession(TracingSessionGlobalID session_id) {
42176   PERFETTO_DCHECK_THREAD(thread_checker_);
42177   auto* consumer = FindConsumer(session_id);
42178   if (!consumer)
42179     return;
42180 
42181   if (consumer->start_pending_) {
42182     // If the session hasn't started yet, wait until it does before stopping.
42183     consumer->stop_pending_ = true;
42184     return;
42185   }
42186 
42187   consumer->stop_pending_ = false;
42188   if (consumer->stopped_) {
42189     // If the session was already stopped (e.g., it failed to start), don't try
42190     // stopping again.
42191     consumer->NotifyStopComplete();
42192   } else if (!consumer->trace_config_) {
42193     PERFETTO_ELOG("Must call Setup(config) and Start() first");
42194     return;
42195   } else {
42196     consumer->service_->DisableTracing();
42197   }
42198 
42199   consumer->trace_config_.reset();
42200 }
42201 
DestroyTracingSession(TracingSessionGlobalID session_id)42202 void TracingMuxerImpl::DestroyTracingSession(
42203     TracingSessionGlobalID session_id) {
42204   PERFETTO_DCHECK_THREAD(thread_checker_);
42205   for (RegisteredBackend& backend : backends_) {
42206     // We need to find the consumer (if any) and call Disconnect as we destroy
42207     // the tracing session. We can't call Disconnect() inside this for loop
42208     // because in the in-process case this will end up to a synchronous call to
42209     // OnConsumerDisconnect which will invalidate all the iterators to
42210     // |backend.consumers|.
42211     ConsumerImpl* consumer = nullptr;
42212     for (auto& con : backend.consumers) {
42213       if (con->session_id_ == session_id) {
42214         consumer = con.get();
42215         break;
42216       }
42217     }
42218     if (consumer) {
42219       // We broke out of the loop above on the assumption that each backend will
42220       // only have a single consumer per session. This DCHECK ensures that
42221       // this is the case.
42222       PERFETTO_DCHECK(
42223           std::count_if(backend.consumers.begin(), backend.consumers.end(),
42224                         [session_id](const std::unique_ptr<ConsumerImpl>& con) {
42225                           return con->session_id_ == session_id;
42226                         }) == 1u);
42227       consumer->Disconnect();
42228     }
42229   }
42230 }
42231 
ReadTracingSessionData(TracingSessionGlobalID session_id,std::function<void (TracingSession::ReadTraceCallbackArgs)> callback)42232 void TracingMuxerImpl::ReadTracingSessionData(
42233     TracingSessionGlobalID session_id,
42234     std::function<void(TracingSession::ReadTraceCallbackArgs)> callback) {
42235   PERFETTO_DCHECK_THREAD(thread_checker_);
42236   auto* consumer = FindConsumer(session_id);
42237   if (!consumer) {
42238     // TODO(skyostil): Signal an error to the user.
42239     TracingSession::ReadTraceCallbackArgs callback_arg{};
42240     callback(callback_arg);
42241     return;
42242   }
42243   PERFETTO_DCHECK(!consumer->read_trace_callback_);
42244   consumer->read_trace_callback_ = std::move(callback);
42245   consumer->service_->ReadBuffers();
42246 }
42247 
GetTraceStats(TracingSessionGlobalID session_id,TracingSession::GetTraceStatsCallback callback)42248 void TracingMuxerImpl::GetTraceStats(
42249     TracingSessionGlobalID session_id,
42250     TracingSession::GetTraceStatsCallback callback) {
42251   PERFETTO_DCHECK_THREAD(thread_checker_);
42252   auto* consumer = FindConsumer(session_id);
42253   if (!consumer) {
42254     TracingSession::GetTraceStatsCallbackArgs callback_arg{};
42255     callback_arg.success = false;
42256     callback(std::move(callback_arg));
42257     return;
42258   }
42259   PERFETTO_DCHECK(!consumer->get_trace_stats_callback_);
42260   consumer->get_trace_stats_callback_ = std::move(callback);
42261   if (!consumer->connected_) {
42262     consumer->get_trace_stats_pending_ = true;
42263     return;
42264   }
42265   consumer->get_trace_stats_pending_ = false;
42266   consumer->service_->GetTraceStats();
42267 }
42268 
QueryServiceState(TracingSessionGlobalID session_id,TracingSession::QueryServiceStateCallback callback)42269 void TracingMuxerImpl::QueryServiceState(
42270     TracingSessionGlobalID session_id,
42271     TracingSession::QueryServiceStateCallback callback) {
42272   PERFETTO_DCHECK_THREAD(thread_checker_);
42273   auto* consumer = FindConsumer(session_id);
42274   if (!consumer) {
42275     TracingSession::QueryServiceStateCallbackArgs callback_arg{};
42276     callback_arg.success = false;
42277     callback(std::move(callback_arg));
42278     return;
42279   }
42280   PERFETTO_DCHECK(!consumer->query_service_state_callback_);
42281   if (!consumer->connected_) {
42282     consumer->query_service_state_callback_ = std::move(callback);
42283     return;
42284   }
42285   auto callback_wrapper = [callback](bool success,
42286                                      protos::gen::TracingServiceState state) {
42287     TracingSession::QueryServiceStateCallbackArgs callback_arg{};
42288     callback_arg.success = success;
42289     callback_arg.service_state_data = state.SerializeAsArray();
42290     callback(std::move(callback_arg));
42291   };
42292   consumer->service_->QueryServiceState(std::move(callback_wrapper));
42293 }
42294 
SetBatchCommitsDurationForTesting(uint32_t batch_commits_duration_ms,BackendType backend_type)42295 void TracingMuxerImpl::SetBatchCommitsDurationForTesting(
42296     uint32_t batch_commits_duration_ms,
42297     BackendType backend_type) {
42298   for (RegisteredBackend& backend : backends_) {
42299     if (backend.producer && backend.producer->connected_ &&
42300         backend.type == backend_type) {
42301       backend.producer->service_->MaybeSharedMemoryArbiter()
42302           ->SetBatchCommitsDuration(batch_commits_duration_ms);
42303     }
42304   }
42305 }
42306 
EnableDirectSMBPatchingForTesting(BackendType backend_type)42307 bool TracingMuxerImpl::EnableDirectSMBPatchingForTesting(
42308     BackendType backend_type) {
42309   for (RegisteredBackend& backend : backends_) {
42310     if (backend.producer && backend.producer->connected_ &&
42311         backend.type == backend_type &&
42312         !backend.producer->service_->MaybeSharedMemoryArbiter()
42313              ->EnableDirectSMBPatching()) {
42314       return false;
42315     }
42316   }
42317   return true;
42318 }
42319 
FindConsumer(TracingSessionGlobalID session_id)42320 TracingMuxerImpl::ConsumerImpl* TracingMuxerImpl::FindConsumer(
42321     TracingSessionGlobalID session_id) {
42322   PERFETTO_DCHECK_THREAD(thread_checker_);
42323   for (RegisteredBackend& backend : backends_) {
42324     for (auto& consumer : backend.consumers) {
42325       if (consumer->session_id_ == session_id) {
42326         return consumer.get();
42327       }
42328     }
42329   }
42330   return nullptr;
42331 }
42332 
InitializeConsumer(TracingSessionGlobalID session_id)42333 void TracingMuxerImpl::InitializeConsumer(TracingSessionGlobalID session_id) {
42334   PERFETTO_DCHECK_THREAD(thread_checker_);
42335 
42336   auto* consumer = FindConsumer(session_id);
42337   if (!consumer)
42338     return;
42339 
42340   TracingBackendId backend_id = consumer->backend_id_;
42341   // |backends_| is append-only, Backend instances are always valid.
42342   PERFETTO_CHECK(backend_id < backends_.size());
42343   RegisteredBackend& backend = backends_[backend_id];
42344 
42345   TracingBackend::ConnectConsumerArgs conn_args;
42346   conn_args.consumer = consumer;
42347   conn_args.task_runner = task_runner_.get();
42348   consumer->Initialize(backend.backend->ConnectConsumer(conn_args));
42349 }
42350 
OnConsumerDisconnected(ConsumerImpl * consumer)42351 void TracingMuxerImpl::OnConsumerDisconnected(ConsumerImpl* consumer) {
42352   PERFETTO_DCHECK_THREAD(thread_checker_);
42353   for (RegisteredBackend& backend : backends_) {
42354     auto pred = [consumer](const std::unique_ptr<ConsumerImpl>& con) {
42355       return con.get() == consumer;
42356     };
42357     backend.consumers.erase(std::remove_if(backend.consumers.begin(),
42358                                            backend.consumers.end(), pred),
42359                             backend.consumers.end());
42360   }
42361 }
42362 
SetMaxProducerReconnectionsForTesting(uint32_t count)42363 void TracingMuxerImpl::SetMaxProducerReconnectionsForTesting(uint32_t count) {
42364   max_producer_reconnections_.store(count);
42365 }
42366 
OnProducerDisconnected(ProducerImpl * producer)42367 void TracingMuxerImpl::OnProducerDisconnected(ProducerImpl* producer) {
42368   PERFETTO_DCHECK_THREAD(thread_checker_);
42369   for (RegisteredBackend& backend : backends_) {
42370     if (backend.producer.get() != producer)
42371       continue;
42372     // Try reconnecting the disconnected producer. If the connection succeeds,
42373     // all the data sources will be automatically re-registered.
42374     if (producer->connection_id_ > max_producer_reconnections_.load()) {
42375       // Avoid reconnecting a failing producer too many times. Instead we just
42376       // leak the producer instead of trying to avoid further complicating
42377       // cross-thread trace writer creation.
42378       PERFETTO_ELOG("Producer disconnected too many times; not reconnecting");
42379       continue;
42380     }
42381     backend.producer->Initialize(
42382         backend.backend->ConnectProducer(backend.producer_conn_args));
42383   }
42384 
42385   // Increment the generation counter to atomically ensure that:
42386   // 1. Old trace writers from the severed connection eventually get cleaned up
42387   //    by DestroyStoppedTraceWritersForCurrentThread().
42388   // 2. No new trace writers can be created for the SharedMemoryArbiter from the
42389   //    old connection.
42390   TracingMuxer::generation_++;
42391 }
42392 
SweepDeadBackends()42393 void TracingMuxerImpl::SweepDeadBackends() {
42394   PERFETTO_DCHECK_THREAD(thread_checker_);
42395   for (auto it = dead_backends_.begin(); it != dead_backends_.end();) {
42396     auto next_it = it;
42397     next_it++;
42398     if (it->producer->SweepDeadServices())
42399       dead_backends_.erase(it);
42400     it = next_it;
42401   }
42402 }
42403 
FindDataSource(TracingBackendId backend_id,DataSourceInstanceID instance_id)42404 TracingMuxerImpl::FindDataSourceRes TracingMuxerImpl::FindDataSource(
42405     TracingBackendId backend_id,
42406     DataSourceInstanceID instance_id) {
42407   PERFETTO_DCHECK_THREAD(thread_checker_);
42408   for (const auto& rds : data_sources_) {
42409     DataSourceStaticState* static_state = rds.static_state;
42410     for (uint32_t i = 0; i < kMaxDataSourceInstances; i++) {
42411       auto* internal_state = static_state->TryGet(i);
42412       if (internal_state && internal_state->backend_id == backend_id &&
42413           internal_state->data_source_instance_id == instance_id) {
42414         return FindDataSourceRes(static_state, internal_state, i);
42415       }
42416     }
42417   }
42418   return FindDataSourceRes();
42419 }
42420 
42421 // Can be called from any thread.
CreateTraceWriter(DataSourceStaticState * static_state,uint32_t data_source_instance_index,DataSourceState * data_source,BufferExhaustedPolicy buffer_exhausted_policy)42422 std::unique_ptr<TraceWriterBase> TracingMuxerImpl::CreateTraceWriter(
42423     DataSourceStaticState* static_state,
42424     uint32_t data_source_instance_index,
42425     DataSourceState* data_source,
42426     BufferExhaustedPolicy buffer_exhausted_policy) {
42427   if (PERFETTO_UNLIKELY(data_source->interceptor_id)) {
42428     // If the session is being intercepted, return a heap-backed trace writer
42429     // instead. This is safe because all the data given to the interceptor is
42430     // either thread-local (|instance_index|), statically allocated
42431     // (|static_state|) or constant after initialization (|interceptor|). Access
42432     // to the interceptor instance itself through |data_source| is protected by
42433     // a statically allocated lock (similarly to the data source instance).
42434     auto& interceptor = interceptors_[data_source->interceptor_id - 1];
42435     return std::unique_ptr<TraceWriterBase>(new InterceptorTraceWriter(
42436         interceptor.tls_factory(static_state, data_source_instance_index),
42437         interceptor.packet_callback, static_state, data_source_instance_index));
42438   }
42439   ProducerImpl* producer = backends_[data_source->backend_id].producer.get();
42440   // Atomically load the current service endpoint. We keep the pointer as a
42441   // shared pointer on the stack to guard against it from being concurrently
42442   // modified on the thread by ProducerImpl::Initialize() swapping in a
42443   // reconnected service on the muxer task runner thread.
42444   //
42445   // The endpoint may also be concurrently modified by SweepDeadServices()
42446   // clearing out old disconnected services. We guard against that by
42447   // SharedMemoryArbiter keeping track of any outstanding trace writers. After
42448   // shutdown has started, the trace writer created below will be a null one
42449   // which will drop any written data. See SharedMemoryArbiter::TryShutdown().
42450   //
42451   // We use an atomic pointer instead of holding a lock because
42452   // CreateTraceWriter posts tasks under the hood.
42453   std::shared_ptr<ProducerEndpoint> service =
42454       std::atomic_load(&producer->service_);
42455   return service->CreateTraceWriter(data_source->buffer_id,
42456                                     buffer_exhausted_policy);
42457 }
42458 
42459 // This is called via the public API Tracing::NewTrace().
42460 // Can be called from any thread.
CreateTracingSession(BackendType requested_backend_type)42461 std::unique_ptr<TracingSession> TracingMuxerImpl::CreateTracingSession(
42462     BackendType requested_backend_type) {
42463   TracingSessionGlobalID session_id = ++next_tracing_session_id_;
42464 
42465   // |backend_type| can only specify one backend, not an OR-ed mask.
42466   PERFETTO_CHECK((requested_backend_type & (requested_backend_type - 1)) == 0);
42467 
42468   // Capturing |this| is fine because the TracingMuxer is a leaky singleton.
42469   task_runner_->PostTask([this, requested_backend_type, session_id] {
42470     for (RegisteredBackend& backend : backends_) {
42471       if (requested_backend_type && backend.type &&
42472           backend.type != requested_backend_type) {
42473         continue;
42474       }
42475 
42476       TracingBackendId backend_id = backend.id;
42477 
42478       // Create the consumer now, even if we have to ask the embedder below, so
42479       // that any other tasks executing after this one can find the consumer and
42480       // change its pending attributes.
42481       backend.consumers.emplace_back(
42482           new ConsumerImpl(this, backend.type, backend.id, session_id));
42483 
42484       // The last registered backend in |backends_| is the unsupported backend
42485       // without a valid type.
42486       if (!backend.type) {
42487         PERFETTO_ELOG(
42488             "No tracing backend ready for type=%d, consumer will disconnect",
42489             requested_backend_type);
42490         InitializeConsumer(session_id);
42491         return;
42492       }
42493 
42494       // Check if the embedder wants to be asked for permission before
42495       // connecting the consumer.
42496       if (!policy_) {
42497         InitializeConsumer(session_id);
42498         return;
42499       }
42500 
42501       TracingPolicy::ShouldAllowConsumerSessionArgs args;
42502       args.backend_type = backend.type;
42503       args.result_callback = [this, backend_id, session_id](bool allow) {
42504         task_runner_->PostTask([this, backend_id, session_id, allow] {
42505           if (allow) {
42506             InitializeConsumer(session_id);
42507             return;
42508           }
42509 
42510           PERFETTO_ELOG(
42511               "Consumer session for backend type type=%d forbidden, "
42512               "consumer will disconnect",
42513               backends_[backend_id].type);
42514 
42515           auto* consumer = FindConsumer(session_id);
42516           if (!consumer)
42517             return;
42518 
42519           consumer->OnDisconnect();
42520         });
42521       };
42522       policy_->ShouldAllowConsumerSession(args);
42523       return;
42524     }
42525     PERFETTO_DFATAL("Not reached");
42526   });
42527 
42528   return std::unique_ptr<TracingSession>(
42529       new TracingSessionImpl(this, session_id, requested_backend_type));
42530 }
42531 
42532 // static
InitializeInstance(const TracingInitArgs & args)42533 void TracingMuxerImpl::InitializeInstance(const TracingInitArgs& args) {
42534   if (instance_ != TracingMuxerFake::Get())
42535     PERFETTO_FATAL("Tracing already initialized");
42536   // If we previously had a TracingMuxerImpl instance which was reset,
42537   // reinitialize and reuse it instead of trying to create a new one. See
42538   // ResetForTesting().
42539   if (g_prev_instance) {
42540     auto* muxer = g_prev_instance;
42541     g_prev_instance = nullptr;
42542     instance_ = muxer;
42543     muxer->task_runner_->PostTask([muxer, args] { muxer->Initialize(args); });
42544   } else {
42545     new TracingMuxerImpl(args);
42546   }
42547 }
42548 
42549 // static
ResetForTesting()42550 void TracingMuxerImpl::ResetForTesting() {
42551   // Ideally we'd tear down the entire TracingMuxerImpl, but the lifetimes of
42552   // various objects make that a non-starter. In particular:
42553   //
42554   // 1) Any thread that has entered a trace event has a TraceWriter, which holds
42555   //    a reference back to ProducerImpl::service_.
42556   //
42557   // 2) ProducerImpl::service_ has a reference back to the ProducerImpl.
42558   //
42559   // 3) ProducerImpl holds reference to TracingMuxerImpl::task_runner_, which in
42560   //    turn depends on TracingMuxerImpl itself.
42561   //
42562   // Because of this, it's not safe to deallocate TracingMuxerImpl until all
42563   // threads have dropped their TraceWriters. Since we can't really ask the
42564   // caller to guarantee this, we'll instead reset enough of the muxer's state
42565   // so that it can be reinitialized later and ensure all necessary objects from
42566   // the old state remain alive until all references have gone away.
42567   auto* muxer = reinterpret_cast<TracingMuxerImpl*>(instance_);
42568 
42569   base::WaitableEvent reset_done;
42570   auto do_reset = [muxer, &reset_done] {
42571     // Unregister all data sources so they don't interfere with any future
42572     // tracing sessions.
42573     for (RegisteredDataSource& rds : muxer->data_sources_) {
42574       for (RegisteredBackend& backend : muxer->backends_) {
42575         if (!backend.producer->service_)
42576           continue;
42577         backend.producer->service_->UnregisterDataSource(rds.descriptor.name());
42578       }
42579     }
42580     for (auto& backend : muxer->backends_) {
42581       // Check that no consumer session is currently active on any backend.
42582       for (auto& consumer : backend.consumers)
42583         PERFETTO_CHECK(!consumer->service_);
42584       backend.producer->muxer_ = nullptr;
42585       backend.producer->DisposeConnection();
42586       muxer->dead_backends_.push_back(std::move(backend));
42587     }
42588     muxer->backends_.clear();
42589     muxer->interceptors_.clear();
42590 
42591     for (auto& ds : muxer->data_sources_) {
42592       ds.static_state->~DataSourceStaticState();
42593       new (ds.static_state) DataSourceStaticState{};
42594     }
42595     muxer->data_sources_.clear();
42596     muxer->next_data_source_index_ = 0;
42597 
42598     // Free all backends without active trace writers or other inbound
42599     // references. Note that even if all the backends get swept, the muxer still
42600     // needs to stay around since |task_runner_| is assumed to be long-lived.
42601     muxer->SweepDeadBackends();
42602 
42603     // Make sure we eventually discard any per-thread trace writers from the
42604     // previous instance.
42605     muxer->muxer_id_for_testing_++;
42606 
42607     g_prev_instance = muxer;
42608     instance_ = TracingMuxerFake::Get();
42609     reset_done.Notify();
42610   };
42611 
42612   // Some tests run the muxer and the test on the same thread. In these cases,
42613   // we can reset synchronously.
42614   if (muxer->task_runner_->RunsTasksOnCurrentThread()) {
42615     do_reset();
42616   } else {
42617     muxer->task_runner_->PostTask(std::move(do_reset));
42618     reset_done.Wait();
42619   }
42620 }
42621 
42622 TracingMuxer::~TracingMuxer() = default;
42623 
42624 static_assert(std::is_same<internal::BufferId, BufferID>::value,
42625               "public's BufferId and tracing/core's BufferID diverged");
42626 
42627 }  // namespace internal
42628 }  // namespace perfetto
42629 // gen_amalgamated begin source: src/tracing/internal/track_event_internal.cc
42630 // gen_amalgamated begin header: gen/protos/perfetto/common/track_event_descriptor.pbzero.h
42631 // Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
42632 
42633 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_TRACK_EVENT_DESCRIPTOR_PROTO_H_
42634 #define PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_TRACK_EVENT_DESCRIPTOR_PROTO_H_
42635 
42636 #include <stddef.h>
42637 #include <stdint.h>
42638 
42639 // gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
42640 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
42641 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
42642 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
42643 // gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
42644 
42645 namespace perfetto {
42646 namespace protos {
42647 namespace pbzero {
42648 
42649 class TrackEventCategory;
42650 
42651 class TrackEventDescriptor_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
42652  public:
TrackEventDescriptor_Decoder(const uint8_t * data,size_t len)42653   TrackEventDescriptor_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
TrackEventDescriptor_Decoder(const std::string & raw)42654   explicit TrackEventDescriptor_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
TrackEventDescriptor_Decoder(const::protozero::ConstBytes & raw)42655   explicit TrackEventDescriptor_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
has_available_categories() const42656   bool has_available_categories() const { return at<1>().valid(); }
available_categories() const42657   ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> available_categories() const { return GetRepeated<::protozero::ConstBytes>(1); }
42658 };
42659 
42660 class TrackEventDescriptor : public ::protozero::Message {
42661  public:
42662   using Decoder = TrackEventDescriptor_Decoder;
42663   enum : int32_t {
42664     kAvailableCategoriesFieldNumber = 1,
42665   };
42666 
42667   using FieldMetadata_AvailableCategories =
42668     ::protozero::proto_utils::FieldMetadata<
42669       1,
42670       ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
42671       ::protozero::proto_utils::ProtoSchemaType::kMessage,
42672       TrackEventCategory,
42673       TrackEventDescriptor>;
42674 
42675   // Ceci n'est pas une pipe.
42676   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
42677   // type (and users are expected to use it as such, hence kCamelCase name).
42678   // It is declared as a function to keep protozero bindings header-only as
42679   // inline constexpr variables are not available until C++17 (while inline
42680   // functions are).
42681   // TODO(altimin): Use inline variable instead after adopting C++17.
kAvailableCategories()42682   static constexpr FieldMetadata_AvailableCategories kAvailableCategories() { return {}; }
add_available_categories()42683   template <typename T = TrackEventCategory> T* add_available_categories() {
42684     return BeginNestedMessage<T>(1);
42685   }
42686 
42687 };
42688 
42689 class TrackEventCategory_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
42690  public:
TrackEventCategory_Decoder(const uint8_t * data,size_t len)42691   TrackEventCategory_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
TrackEventCategory_Decoder(const std::string & raw)42692   explicit TrackEventCategory_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
TrackEventCategory_Decoder(const::protozero::ConstBytes & raw)42693   explicit TrackEventCategory_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
has_name() const42694   bool has_name() const { return at<1>().valid(); }
name() const42695   ::protozero::ConstChars name() const { return at<1>().as_string(); }
has_description() const42696   bool has_description() const { return at<2>().valid(); }
description() const42697   ::protozero::ConstChars description() const { return at<2>().as_string(); }
has_tags() const42698   bool has_tags() const { return at<3>().valid(); }
tags() const42699   ::protozero::RepeatedFieldIterator<::protozero::ConstChars> tags() const { return GetRepeated<::protozero::ConstChars>(3); }
42700 };
42701 
42702 class TrackEventCategory : public ::protozero::Message {
42703  public:
42704   using Decoder = TrackEventCategory_Decoder;
42705   enum : int32_t {
42706     kNameFieldNumber = 1,
42707     kDescriptionFieldNumber = 2,
42708     kTagsFieldNumber = 3,
42709   };
42710 
42711   using FieldMetadata_Name =
42712     ::protozero::proto_utils::FieldMetadata<
42713       1,
42714       ::protozero::proto_utils::RepetitionType::kNotRepeated,
42715       ::protozero::proto_utils::ProtoSchemaType::kString,
42716       std::string,
42717       TrackEventCategory>;
42718 
42719   // Ceci n'est pas une pipe.
42720   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
42721   // type (and users are expected to use it as such, hence kCamelCase name).
42722   // It is declared as a function to keep protozero bindings header-only as
42723   // inline constexpr variables are not available until C++17 (while inline
42724   // functions are).
42725   // TODO(altimin): Use inline variable instead after adopting C++17.
kName()42726   static constexpr FieldMetadata_Name kName() { return {}; }
set_name(const char * data,size_t size)42727   void set_name(const char* data, size_t size) {
42728     AppendBytes(FieldMetadata_Name::kFieldId, data, size);
42729   }
set_name(std::string value)42730   void set_name(std::string value) {
42731     static constexpr uint32_t field_id = FieldMetadata_Name::kFieldId;
42732     // Call the appropriate protozero::Message::Append(field_id, ...)
42733     // method based on the type of the field.
42734     ::protozero::internal::FieldWriter<
42735       ::protozero::proto_utils::ProtoSchemaType::kString>
42736         ::Append(*this, field_id, value);
42737   }
42738 
42739   using FieldMetadata_Description =
42740     ::protozero::proto_utils::FieldMetadata<
42741       2,
42742       ::protozero::proto_utils::RepetitionType::kNotRepeated,
42743       ::protozero::proto_utils::ProtoSchemaType::kString,
42744       std::string,
42745       TrackEventCategory>;
42746 
42747   // Ceci n'est pas une pipe.
42748   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
42749   // type (and users are expected to use it as such, hence kCamelCase name).
42750   // It is declared as a function to keep protozero bindings header-only as
42751   // inline constexpr variables are not available until C++17 (while inline
42752   // functions are).
42753   // TODO(altimin): Use inline variable instead after adopting C++17.
kDescription()42754   static constexpr FieldMetadata_Description kDescription() { return {}; }
set_description(const char * data,size_t size)42755   void set_description(const char* data, size_t size) {
42756     AppendBytes(FieldMetadata_Description::kFieldId, data, size);
42757   }
set_description(std::string value)42758   void set_description(std::string value) {
42759     static constexpr uint32_t field_id = FieldMetadata_Description::kFieldId;
42760     // Call the appropriate protozero::Message::Append(field_id, ...)
42761     // method based on the type of the field.
42762     ::protozero::internal::FieldWriter<
42763       ::protozero::proto_utils::ProtoSchemaType::kString>
42764         ::Append(*this, field_id, value);
42765   }
42766 
42767   using FieldMetadata_Tags =
42768     ::protozero::proto_utils::FieldMetadata<
42769       3,
42770       ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
42771       ::protozero::proto_utils::ProtoSchemaType::kString,
42772       std::string,
42773       TrackEventCategory>;
42774 
42775   // Ceci n'est pas une pipe.
42776   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
42777   // type (and users are expected to use it as such, hence kCamelCase name).
42778   // It is declared as a function to keep protozero bindings header-only as
42779   // inline constexpr variables are not available until C++17 (while inline
42780   // functions are).
42781   // TODO(altimin): Use inline variable instead after adopting C++17.
kTags()42782   static constexpr FieldMetadata_Tags kTags() { return {}; }
add_tags(const char * data,size_t size)42783   void add_tags(const char* data, size_t size) {
42784     AppendBytes(FieldMetadata_Tags::kFieldId, data, size);
42785   }
add_tags(std::string value)42786   void add_tags(std::string value) {
42787     static constexpr uint32_t field_id = FieldMetadata_Tags::kFieldId;
42788     // Call the appropriate protozero::Message::Append(field_id, ...)
42789     // method based on the type of the field.
42790     ::protozero::internal::FieldWriter<
42791       ::protozero::proto_utils::ProtoSchemaType::kString>
42792         ::Append(*this, field_id, value);
42793   }
42794 };
42795 
42796 } // Namespace.
42797 } // Namespace.
42798 } // Namespace.
42799 #endif  // Include guard.
42800 /*
42801  * Copyright (C) 2019 The Android Open Source Project
42802  *
42803  * Licensed under the Apache License, Version 2.0 (the "License");
42804  * you may not use this file except in compliance with the License.
42805  * You may obtain a copy of the License at
42806  *
42807  *      http://www.apache.org/licenses/LICENSE-2.0
42808  *
42809  * Unless required by applicable law or agreed to in writing, software
42810  * distributed under the License is distributed on an "AS IS" BASIS,
42811  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
42812  * See the License for the specific language governing permissions and
42813  * limitations under the License.
42814  */
42815 
42816 // gen_amalgamated expanded: #include "perfetto/tracing/internal/track_event_internal.h"
42817 
42818 // gen_amalgamated expanded: #include "perfetto/base/proc_utils.h"
42819 // gen_amalgamated expanded: #include "perfetto/base/thread_utils.h"
42820 // gen_amalgamated expanded: #include "perfetto/base/time.h"
42821 // gen_amalgamated expanded: #include "perfetto/tracing/core/data_source_config.h"
42822 // gen_amalgamated expanded: #include "perfetto/tracing/internal/track_event_interned_fields.h"
42823 // gen_amalgamated expanded: #include "perfetto/tracing/track_event.h"
42824 // gen_amalgamated expanded: #include "perfetto/tracing/track_event_category_registry.h"
42825 // gen_amalgamated expanded: #include "perfetto/tracing/track_event_interned_data_index.h"
42826 // gen_amalgamated expanded: #include "protos/perfetto/common/data_source_descriptor.gen.h"
42827 // gen_amalgamated expanded: #include "protos/perfetto/common/track_event_descriptor.pbzero.h"
42828 // gen_amalgamated expanded: #include "protos/perfetto/trace/interned_data/interned_data.pbzero.h"
42829 // gen_amalgamated expanded: #include "protos/perfetto/trace/trace_packet_defaults.pbzero.h"
42830 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/debug_annotation.pbzero.h"
42831 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/track_descriptor.pbzero.h"
42832 
42833 namespace perfetto {
42834 
42835 TrackEventSessionObserver::~TrackEventSessionObserver() = default;
OnSetup(const DataSourceBase::SetupArgs &)42836 void TrackEventSessionObserver::OnSetup(const DataSourceBase::SetupArgs&) {}
OnStart(const DataSourceBase::StartArgs &)42837 void TrackEventSessionObserver::OnStart(const DataSourceBase::StartArgs&) {}
OnStop(const DataSourceBase::StopArgs &)42838 void TrackEventSessionObserver::OnStop(const DataSourceBase::StopArgs&) {}
42839 
42840 namespace internal {
42841 
42842 BaseTrackEventInternedDataIndex::~BaseTrackEventInternedDataIndex() = default;
42843 
42844 namespace {
42845 
42846 std::atomic<perfetto::base::PlatformThreadId> g_main_thread;
42847 static constexpr const char kLegacySlowPrefix[] = "disabled-by-default-";
42848 static constexpr const char kSlowTag[] = "slow";
42849 static constexpr const char kDebugTag[] = "debug";
42850 
ForEachObserver(std::function<bool (TrackEventSessionObserver * &)> callback)42851 void ForEachObserver(
42852     std::function<bool(TrackEventSessionObserver*&)> callback) {
42853   // Session observers, shared by all track event data source instances.
42854   static constexpr int kMaxObservers = 8;
42855   static std::recursive_mutex* mutex = new std::recursive_mutex{};  // Leaked.
42856   static std::array<TrackEventSessionObserver*, kMaxObservers> observers{};
42857   std::unique_lock<std::recursive_mutex> lock(*mutex);
42858   for (auto& o : observers) {
42859     if (!callback(o))
42860       break;
42861   }
42862 }
42863 
42864 enum class MatchType { kExact, kPattern };
42865 
NameMatchesPattern(const std::string & pattern,const std::string & name,MatchType match_type)42866 bool NameMatchesPattern(const std::string& pattern,
42867                         const std::string& name,
42868                         MatchType match_type) {
42869   // To avoid pulling in all of std::regex, for now we only support a single "*"
42870   // wildcard at the end of the pattern.
42871   size_t i = pattern.find('*');
42872   if (i != std::string::npos) {
42873     PERFETTO_DCHECK(i == pattern.size() - 1);
42874     if (match_type != MatchType::kPattern)
42875       return false;
42876     return name.substr(0, i) == pattern.substr(0, i);
42877   }
42878   return name == pattern;
42879 }
42880 
NameMatchesPatternList(const std::vector<std::string> & patterns,const std::string & name,MatchType match_type)42881 bool NameMatchesPatternList(const std::vector<std::string>& patterns,
42882                             const std::string& name,
42883                             MatchType match_type) {
42884   for (const auto& pattern : patterns) {
42885     if (NameMatchesPattern(pattern, name, match_type))
42886       return true;
42887   }
42888   return false;
42889 }
42890 
42891 }  // namespace
42892 
42893 // static
42894 const Track TrackEventInternal::kDefaultTrack{};
42895 
42896 // static
42897 std::atomic<int> TrackEventInternal::session_count_{};
42898 
42899 // static
Initialize(const TrackEventCategoryRegistry & registry,bool (* register_data_source)(const DataSourceDescriptor &))42900 bool TrackEventInternal::Initialize(
42901     const TrackEventCategoryRegistry& registry,
42902     bool (*register_data_source)(const DataSourceDescriptor&)) {
42903   if (!g_main_thread)
42904     g_main_thread = perfetto::base::GetThreadId();
42905 
42906   DataSourceDescriptor dsd;
42907   dsd.set_name("track_event");
42908 
42909   protozero::HeapBuffered<protos::pbzero::TrackEventDescriptor> ted;
42910   for (size_t i = 0; i < registry.category_count(); i++) {
42911     auto category = registry.GetCategory(i);
42912     // Don't register group categories.
42913     if (category->IsGroup())
42914       continue;
42915     auto cat = ted->add_available_categories();
42916     cat->set_name(category->name);
42917     if (category->description)
42918       cat->set_description(category->description);
42919     for (const auto& tag : category->tags) {
42920       if (tag)
42921         cat->add_tags(tag);
42922     }
42923     // Disabled-by-default categories get a "slow" tag.
42924     if (!strncmp(category->name, kLegacySlowPrefix, strlen(kLegacySlowPrefix)))
42925       cat->add_tags(kSlowTag);
42926   }
42927   dsd.set_track_event_descriptor_raw(ted.SerializeAsString());
42928 
42929   return register_data_source(dsd);
42930 }
42931 
42932 // static
AddSessionObserver(TrackEventSessionObserver * observer)42933 bool TrackEventInternal::AddSessionObserver(
42934     TrackEventSessionObserver* observer) {
42935   bool result = false;
42936   ForEachObserver([&](TrackEventSessionObserver*& o) {
42937     if (!o) {
42938       o = observer;
42939       result = true;
42940       return false;
42941     }
42942     return true;
42943   });
42944   return result;
42945 }
42946 
42947 // static
RemoveSessionObserver(TrackEventSessionObserver * observer)42948 void TrackEventInternal::RemoveSessionObserver(
42949     TrackEventSessionObserver* observer) {
42950   ForEachObserver([&](TrackEventSessionObserver*& o) {
42951     if (o == observer) {
42952       o = nullptr;
42953       return false;
42954     }
42955     return true;
42956   });
42957 }
42958 
42959 // static
EnableTracing(const TrackEventCategoryRegistry & registry,const protos::gen::TrackEventConfig & config,const DataSourceBase::SetupArgs & args)42960 void TrackEventInternal::EnableTracing(
42961     const TrackEventCategoryRegistry& registry,
42962     const protos::gen::TrackEventConfig& config,
42963     const DataSourceBase::SetupArgs& args) {
42964   for (size_t i = 0; i < registry.category_count(); i++) {
42965     if (IsCategoryEnabled(registry, config, *registry.GetCategory(i)))
42966       registry.EnableCategoryForInstance(i, args.internal_instance_index);
42967   }
42968   ForEachObserver([&](TrackEventSessionObserver*& o) {
42969     if (o)
42970       o->OnSetup(args);
42971     return true;
42972   });
42973 }
42974 
42975 // static
OnStart(const DataSourceBase::StartArgs & args)42976 void TrackEventInternal::OnStart(const DataSourceBase::StartArgs& args) {
42977   session_count_.fetch_add(1);
42978   ForEachObserver([&](TrackEventSessionObserver*& o) {
42979     if (o)
42980       o->OnStart(args);
42981     return true;
42982   });
42983 }
42984 
42985 // static
DisableTracing(const TrackEventCategoryRegistry & registry,const DataSourceBase::StopArgs & args)42986 void TrackEventInternal::DisableTracing(
42987     const TrackEventCategoryRegistry& registry,
42988     const DataSourceBase::StopArgs& args) {
42989   ForEachObserver([&](TrackEventSessionObserver*& o) {
42990     if (o)
42991       o->OnStop(args);
42992     return true;
42993   });
42994   for (size_t i = 0; i < registry.category_count(); i++)
42995     registry.DisableCategoryForInstance(i, args.internal_instance_index);
42996 }
42997 
42998 // static
IsCategoryEnabled(const TrackEventCategoryRegistry & registry,const protos::gen::TrackEventConfig & config,const Category & category)42999 bool TrackEventInternal::IsCategoryEnabled(
43000     const TrackEventCategoryRegistry& registry,
43001     const protos::gen::TrackEventConfig& config,
43002     const Category& category) {
43003   // If this is a group category, check if any of its constituent categories are
43004   // enabled. If so, then this one is enabled too.
43005   if (category.IsGroup()) {
43006     bool result = false;
43007     category.ForEachGroupMember([&](const char* member_name, size_t name_size) {
43008       for (size_t i = 0; i < registry.category_count(); i++) {
43009         const auto ref_category = registry.GetCategory(i);
43010         // Groups can't refer to other groups.
43011         if (ref_category->IsGroup())
43012           continue;
43013         // Require an exact match.
43014         if (ref_category->name_size() != name_size ||
43015             strncmp(ref_category->name, member_name, name_size)) {
43016           continue;
43017         }
43018         if (IsCategoryEnabled(registry, config, *ref_category)) {
43019           result = true;
43020           // Break ForEachGroupMember() loop.
43021           return false;
43022         }
43023         break;
43024       }
43025       // No match? Must be a dynamic category.
43026       DynamicCategory dyn_category(std::string(member_name, name_size));
43027       Category ref_category{Category::FromDynamicCategory(dyn_category)};
43028       if (IsCategoryEnabled(registry, config, ref_category)) {
43029         result = true;
43030         // Break ForEachGroupMember() loop.
43031         return false;
43032       }
43033       // No match found => keep iterating.
43034       return true;
43035     });
43036     return result;
43037   }
43038 
43039   auto has_matching_tag = [&](std::function<bool(const char*)> matcher) {
43040     for (const auto& tag : category.tags) {
43041       if (!tag)
43042         break;
43043       if (matcher(tag))
43044         return true;
43045     }
43046     // Legacy "disabled-by-default" categories automatically get the "slow" tag.
43047     if (!strncmp(category.name, kLegacySlowPrefix, strlen(kLegacySlowPrefix)) &&
43048         matcher(kSlowTag)) {
43049       return true;
43050     }
43051     return false;
43052   };
43053 
43054   // First try exact matches, then pattern matches.
43055   const std::array<MatchType, 2> match_types = {
43056       {MatchType::kExact, MatchType::kPattern}};
43057   for (auto match_type : match_types) {
43058     // 1. Enabled categories.
43059     if (NameMatchesPatternList(config.enabled_categories(), category.name,
43060                                match_type)) {
43061       return true;
43062     }
43063 
43064     // 2. Enabled tags.
43065     if (has_matching_tag([&](const char* tag) {
43066           return NameMatchesPatternList(config.enabled_tags(), tag, match_type);
43067         })) {
43068       return true;
43069     }
43070 
43071     // 3. Disabled categories.
43072     if (NameMatchesPatternList(config.disabled_categories(), category.name,
43073                                match_type)) {
43074       return false;
43075     }
43076 
43077     // 4. Disabled tags.
43078     if (has_matching_tag([&](const char* tag) {
43079           if (config.disabled_tags_size()) {
43080             return NameMatchesPatternList(config.disabled_tags(), tag,
43081                                           match_type);
43082           } else {
43083             // The "slow" and "debug" tags are disabled by default.
43084             return NameMatchesPattern(kSlowTag, tag, match_type) ||
43085                    NameMatchesPattern(kDebugTag, tag, match_type);
43086           }
43087         })) {
43088       return false;
43089     }
43090   }
43091 
43092   // If nothing matched, enable the category by default.
43093   return true;
43094 }
43095 
43096 // static
GetTimeNs()43097 uint64_t TrackEventInternal::GetTimeNs() {
43098   if (GetClockId() == protos::pbzero::BUILTIN_CLOCK_BOOTTIME)
43099     return static_cast<uint64_t>(perfetto::base::GetBootTimeNs().count());
43100   PERFETTO_DCHECK(GetClockId() == protos::pbzero::BUILTIN_CLOCK_MONOTONIC);
43101   return static_cast<uint64_t>(perfetto::base::GetWallTimeNs().count());
43102 }
43103 
43104 // static
GetSessionCount()43105 int TrackEventInternal::GetSessionCount() {
43106   return session_count_.load();
43107 }
43108 
43109 // static
ResetIncrementalState(TraceWriterBase * trace_writer,TraceTimestamp timestamp)43110 void TrackEventInternal::ResetIncrementalState(TraceWriterBase* trace_writer,
43111                                                TraceTimestamp timestamp) {
43112   auto default_track = ThreadTrack::Current();
43113   {
43114     // Mark any incremental state before this point invalid. Also set up
43115     // defaults so that we don't need to repeat constant data for each packet.
43116     auto packet = NewTracePacket(
43117         trace_writer, timestamp,
43118         protos::pbzero::TracePacket::SEQ_INCREMENTAL_STATE_CLEARED);
43119     auto defaults = packet->set_trace_packet_defaults();
43120     defaults->set_timestamp_clock_id(GetClockId());
43121 
43122     // Establish the default track for this event sequence.
43123     auto track_defaults = defaults->set_track_event_defaults();
43124     track_defaults->set_track_uuid(default_track.uuid);
43125   }
43126 
43127   // Every thread should write a descriptor for its default track, because most
43128   // trace points won't explicitly reference it. We also write the process
43129   // descriptor from every thread that writes trace events to ensure it gets
43130   // emitted at least once.
43131   WriteTrackDescriptor(default_track, trace_writer);
43132   WriteTrackDescriptor(ProcessTrack::Current(), trace_writer);
43133 }
43134 
43135 // static
43136 protozero::MessageHandle<protos::pbzero::TracePacket>
NewTracePacket(TraceWriterBase * trace_writer,TraceTimestamp timestamp,uint32_t seq_flags)43137 TrackEventInternal::NewTracePacket(TraceWriterBase* trace_writer,
43138                                    TraceTimestamp timestamp,
43139                                    uint32_t seq_flags) {
43140   auto packet = trace_writer->NewTracePacket();
43141   packet->set_timestamp(timestamp.nanoseconds);
43142   if (timestamp.clock_id != GetClockId()) {
43143     packet->set_timestamp_clock_id(static_cast<uint32_t>(timestamp.clock_id));
43144   } else if (GetClockId() != protos::pbzero::BUILTIN_CLOCK_BOOTTIME) {
43145     // TODO(skyostil): Stop emitting the clock id for the default trace clock
43146     // for every event once the trace processor understands trace packet
43147     // defaults.
43148     packet->set_timestamp_clock_id(GetClockId());
43149   }
43150   packet->set_sequence_flags(seq_flags);
43151   return packet;
43152 }
43153 
43154 // static
WriteEvent(TraceWriterBase * trace_writer,TrackEventIncrementalState * incr_state,const Category * category,const char * name,perfetto::protos::pbzero::TrackEvent::Type type,TraceTimestamp timestamp)43155 EventContext TrackEventInternal::WriteEvent(
43156     TraceWriterBase* trace_writer,
43157     TrackEventIncrementalState* incr_state,
43158     const Category* category,
43159     const char* name,
43160     perfetto::protos::pbzero::TrackEvent::Type type,
43161     TraceTimestamp timestamp) {
43162   PERFETTO_DCHECK(g_main_thread);
43163   PERFETTO_DCHECK(!incr_state->was_cleared);
43164 
43165   auto packet = NewTracePacket(trace_writer, timestamp);
43166   EventContext ctx(std::move(packet), incr_state);
43167 
43168   auto track_event = ctx.event();
43169   if (type != protos::pbzero::TrackEvent::TYPE_UNSPECIFIED)
43170     track_event->set_type(type);
43171 
43172   // We assume that |category| and |name| point to strings with static lifetime.
43173   // This means we can use their addresses as interning keys.
43174   // TODO(skyostil): Intern categories at compile time.
43175   if (category && type != protos::pbzero::TrackEvent::TYPE_SLICE_END &&
43176       type != protos::pbzero::TrackEvent::TYPE_COUNTER) {
43177     category->ForEachGroupMember(
43178         [&](const char* member_name, size_t name_size) {
43179           size_t category_iid =
43180               InternedEventCategory::Get(&ctx, member_name, name_size);
43181           track_event->add_category_iids(category_iid);
43182           return true;
43183         });
43184   }
43185   if (name && type != protos::pbzero::TrackEvent::TYPE_SLICE_END) {
43186     size_t name_iid = InternedEventName::Get(&ctx, name);
43187     track_event->set_name_iid(name_iid);
43188   }
43189   return ctx;
43190 }
43191 
43192 // static
AddDebugAnnotation(perfetto::EventContext * event_ctx,const char * name)43193 protos::pbzero::DebugAnnotation* TrackEventInternal::AddDebugAnnotation(
43194     perfetto::EventContext* event_ctx,
43195     const char* name) {
43196   auto annotation = event_ctx->event()->add_debug_annotations();
43197   annotation->set_name_iid(InternedDebugAnnotationName::Get(event_ctx, name));
43198   return annotation;
43199 }
43200 
43201 }  // namespace internal
43202 }  // namespace perfetto
43203 // gen_amalgamated begin source: src/tracing/internal/track_event_interned_fields.cc
43204 /*
43205  * Copyright (C) 2021 The Android Open Source Project
43206  *
43207  * Licensed under the Apache License, Version 2.0 (the "License");
43208  * you may not use this file except in compliance with the License.
43209  * You may obtain a copy of the License at
43210  *
43211  *      http://www.apache.org/licenses/LICENSE-2.0
43212  *
43213  * Unless required by applicable law or agreed to in writing, software
43214  * distributed under the License is distributed on an "AS IS" BASIS,
43215  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
43216  * See the License for the specific language governing permissions and
43217  * limitations under the License.
43218  */
43219 
43220 // gen_amalgamated expanded: #include "perfetto/tracing/internal/track_event_interned_fields.h"
43221 
43222 namespace perfetto {
43223 namespace internal {
43224 
43225 InternedEventCategory::~InternedEventCategory() = default;
43226 
43227 // static
Add(protos::pbzero::InternedData * interned_data,size_t iid,const char * value,size_t length)43228 void InternedEventCategory::Add(protos::pbzero::InternedData* interned_data,
43229                                 size_t iid,
43230                                 const char* value,
43231                                 size_t length) {
43232   auto category = interned_data->add_event_categories();
43233   category->set_iid(iid);
43234   category->set_name(value, length);
43235 }
43236 
43237 InternedEventName::~InternedEventName() = default;
43238 
43239 // static
Add(protos::pbzero::InternedData * interned_data,size_t iid,const char * value)43240 void InternedEventName::Add(protos::pbzero::InternedData* interned_data,
43241                             size_t iid,
43242                             const char* value) {
43243   auto name = interned_data->add_event_names();
43244   name->set_iid(iid);
43245   name->set_name(value);
43246 }
43247 
43248 InternedDebugAnnotationName::~InternedDebugAnnotationName() = default;
43249 
43250 // static
Add(protos::pbzero::InternedData * interned_data,size_t iid,const char * value)43251 void InternedDebugAnnotationName::Add(
43252     protos::pbzero::InternedData* interned_data,
43253     size_t iid,
43254     const char* value) {
43255   auto name = interned_data->add_debug_annotation_names();
43256   name->set_iid(iid);
43257   name->set_name(value);
43258 }
43259 
43260 }  // namespace internal
43261 }  // namespace perfetto
43262 // gen_amalgamated begin source: src/tracing/platform.cc
43263 /*
43264  * Copyright (C) 2019 The Android Open Source Project
43265  *
43266  * Licensed under the Apache License, Version 2.0 (the "License");
43267  * you may not use this file except in compliance with the License.
43268  * You may obtain a copy of the License at
43269  *
43270  *      http://www.apache.org/licenses/LICENSE-2.0
43271  *
43272  * Unless required by applicable law or agreed to in writing, software
43273  * distributed under the License is distributed on an "AS IS" BASIS,
43274  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
43275  * See the License for the specific language governing permissions and
43276  * limitations under the License.
43277  */
43278 
43279 // gen_amalgamated expanded: #include "perfetto/tracing/platform.h"
43280 // gen_amalgamated expanded: #include "perfetto/tracing/internal/tracing_tls.h"
43281 // gen_amalgamated expanded: #include "perfetto/tracing/trace_writer_base.h"
43282 
43283 namespace perfetto {
43284 
43285 PlatformThreadLocalObject::~PlatformThreadLocalObject() = default;
43286 Platform::~Platform() = default;
43287 
43288 // static
43289 std::unique_ptr<PlatformThreadLocalObject>
CreateInstance()43290 PlatformThreadLocalObject::CreateInstance() {
43291   return std::unique_ptr<PlatformThreadLocalObject>(new internal::TracingTLS());
43292 }
43293 
43294 }  // namespace perfetto
43295 // gen_amalgamated begin source: src/tracing/traced_value.cc
43296 /*
43297  * Copyright (C) 2021 The Android Open Source Project
43298  *
43299  * Licensed under the Apache License, Version 2.0 (the "License");
43300  * you may not use this file except in compliance with the License.
43301  * You may obtain a copy of the License at
43302  *
43303  *      http://www.apache.org/licenses/LICENSE-2.0
43304  *
43305  * Unless required by applicable law or agreed to in writing, software
43306  * distributed under the License is distributed on an "AS IS" BASIS,
43307  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
43308  * See the License for the specific language governing permissions and
43309  * limitations under the License.
43310  */
43311 
43312 // gen_amalgamated expanded: #include "perfetto/tracing/traced_value.h"
43313 
43314 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
43315 // gen_amalgamated expanded: #include "perfetto/tracing/debug_annotation.h"
43316 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/debug_annotation.pbzero.h"
43317 
43318 namespace perfetto {
43319 
43320 namespace internal {
43321 
CreateTracedValueFromProto(protos::pbzero::DebugAnnotation * context)43322 TracedValue CreateTracedValueFromProto(
43323     protos::pbzero::DebugAnnotation* context) {
43324   return TracedValue::CreateFromProto(context);
43325 }
43326 
43327 }  // namespace internal
43328 
43329 // static
CreateFromProto(protos::pbzero::DebugAnnotation * context)43330 TracedValue TracedValue::CreateFromProto(
43331     protos::pbzero::DebugAnnotation* context) {
43332   return TracedValue(context, nullptr);
43333 }
43334 
WriteInt64(int64_t value)43335 void TracedValue::WriteInt64(int64_t value) && {
43336   PERFETTO_DCHECK(checked_scope_.is_active());
43337   context_->set_int_value(value);
43338 }
43339 
WriteUInt64(uint64_t value)43340 void TracedValue::WriteUInt64(uint64_t value) && {
43341   PERFETTO_DCHECK(checked_scope_.is_active());
43342   context_->set_uint_value(value);
43343 }
43344 
WriteDouble(double value)43345 void TracedValue::WriteDouble(double value) && {
43346   PERFETTO_DCHECK(checked_scope_.is_active());
43347   context_->set_double_value(value);
43348 }
43349 
WriteBoolean(bool value)43350 void TracedValue::WriteBoolean(bool value) && {
43351   PERFETTO_DCHECK(checked_scope_.is_active());
43352   context_->set_bool_value(value);
43353 }
43354 
WriteString(const char * value)43355 void TracedValue::WriteString(const char* value) && {
43356   PERFETTO_DCHECK(checked_scope_.is_active());
43357   context_->set_string_value(value);
43358 }
43359 
WriteString(const char * value,size_t len)43360 void TracedValue::WriteString(const char* value, size_t len) && {
43361   PERFETTO_DCHECK(checked_scope_.is_active());
43362   context_->set_string_value(value, len);
43363 }
43364 
WriteString(const std::string & value)43365 void TracedValue::WriteString(const std::string& value) && {
43366   PERFETTO_DCHECK(checked_scope_.is_active());
43367   context_->set_string_value(value);
43368 }
43369 
WritePointer(const void * value)43370 void TracedValue::WritePointer(const void* value) && {
43371   PERFETTO_DCHECK(checked_scope_.is_active());
43372   context_->set_pointer_value(reinterpret_cast<uint64_t>(value));
43373 }
43374 
WriteDictionary()43375 TracedDictionary TracedValue::WriteDictionary() && {
43376   // Note: this passes |checked_scope_.is_active_| bit to the parent to be
43377   // picked up later by the new TracedDictionary.
43378   PERFETTO_DCHECK(checked_scope_.is_active());
43379   checked_scope_.Reset();
43380 
43381   PERFETTO_DCHECK(!context_->is_finalized());
43382   return TracedDictionary(context_,
43383                           protos::pbzero::DebugAnnotation::kDictEntries,
43384                           checked_scope_.parent_scope());
43385 }
43386 
WriteArray()43387 TracedArray TracedValue::WriteArray() && {
43388   // Note: this passes |checked_scope_.is_active_| bit to the parent to be
43389   // picked up later by the new TracedDictionary.
43390   PERFETTO_DCHECK(checked_scope_.is_active());
43391   checked_scope_.Reset();
43392 
43393   PERFETTO_DCHECK(!context_->is_finalized());
43394   return TracedArray(context_, checked_scope_.parent_scope());
43395 }
43396 
AppendItem()43397 TracedValue TracedArray::AppendItem() {
43398   PERFETTO_DCHECK(checked_scope_.is_active());
43399   return TracedValue(context_->add_array_values(), &checked_scope_);
43400 }
43401 
AppendDictionary()43402 TracedDictionary TracedArray::AppendDictionary() {
43403   PERFETTO_DCHECK(checked_scope_.is_active());
43404   return AppendItem().WriteDictionary();
43405 }
43406 
AppendArray()43407 TracedArray TracedArray::AppendArray() {
43408   PERFETTO_DCHECK(checked_scope_.is_active());
43409   return AppendItem().WriteArray();
43410 }
43411 
AddItem(StaticString key)43412 TracedValue TracedDictionary::AddItem(StaticString key) {
43413   PERFETTO_DCHECK(checked_scope_.is_active());
43414   protos::pbzero::DebugAnnotation* item =
43415       message_->BeginNestedMessage<protos::pbzero::DebugAnnotation>(field_id_);
43416   item->set_name(key.value);
43417   return TracedValue(item, &checked_scope_);
43418 }
43419 
AddItem(DynamicString key)43420 TracedValue TracedDictionary::AddItem(DynamicString key) {
43421   PERFETTO_DCHECK(checked_scope_.is_active());
43422   protos::pbzero::DebugAnnotation* item =
43423       message_->BeginNestedMessage<protos::pbzero::DebugAnnotation>(field_id_);
43424   item->set_name(key.value);
43425   return TracedValue(item, &checked_scope_);
43426 }
43427 
AddDictionary(StaticString key)43428 TracedDictionary TracedDictionary::AddDictionary(StaticString key) {
43429   PERFETTO_DCHECK(checked_scope_.is_active());
43430   return AddItem(key).WriteDictionary();
43431 }
43432 
AddDictionary(DynamicString key)43433 TracedDictionary TracedDictionary::AddDictionary(DynamicString key) {
43434   PERFETTO_DCHECK(checked_scope_.is_active());
43435   return AddItem(key).WriteDictionary();
43436 }
43437 
AddArray(StaticString key)43438 TracedArray TracedDictionary::AddArray(StaticString key) {
43439   PERFETTO_DCHECK(checked_scope_.is_active());
43440   return AddItem(key).WriteArray();
43441 }
43442 
AddArray(DynamicString key)43443 TracedArray TracedDictionary::AddArray(DynamicString key) {
43444   PERFETTO_DCHECK(checked_scope_.is_active());
43445   return AddItem(key).WriteArray();
43446 }
43447 
43448 }  // namespace perfetto
43449 // gen_amalgamated begin source: src/tracing/tracing.cc
43450 /*
43451  * Copyright (C) 2019 The Android Open Source Project
43452  *
43453  * Licensed under the Apache License, Version 2.0 (the "License");
43454  * you may not use this file except in compliance with the License.
43455  * You may obtain a copy of the License at
43456  *
43457  *      http://www.apache.org/licenses/LICENSE-2.0
43458  *
43459  * Unless required by applicable law or agreed to in writing, software
43460  * distributed under the License is distributed on an "AS IS" BASIS,
43461  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
43462  * See the License for the specific language governing permissions and
43463  * limitations under the License.
43464  */
43465 
43466 // gen_amalgamated expanded: #include "perfetto/tracing/tracing.h"
43467 
43468 #include <atomic>
43469 #include <condition_variable>
43470 #include <mutex>
43471 
43472 // gen_amalgamated expanded: #include "perfetto/ext/base/waitable_event.h"
43473 // gen_amalgamated expanded: #include "perfetto/tracing/internal/track_event_internal.h"
43474 // gen_amalgamated expanded: #include "src/tracing/internal/tracing_muxer_impl.h"
43475 
43476 namespace perfetto {
43477 namespace {
43478 bool g_was_initialized = false;
43479 }
43480 
43481 // static
InitializeInternal(const TracingInitArgs & args)43482 void Tracing::InitializeInternal(const TracingInitArgs& args) {
43483   static TracingInitArgs init_args;
43484   if (g_was_initialized) {
43485     if (!(init_args == args)) {
43486       PERFETTO_ELOG(
43487           "Tracing::Initialize() called more than once with different args. "
43488           "This is not supported, only the first call will have effect.");
43489       PERFETTO_DCHECK(false);
43490     }
43491     return;
43492   }
43493 
43494   // Make sure the headers and implementation files agree on the build config.
43495   PERFETTO_CHECK(args.dcheck_is_on_ == PERFETTO_DCHECK_IS_ON());
43496   if (args.log_message_callback) {
43497     base::SetLogMessageCallback(args.log_message_callback);
43498   }
43499   internal::TracingMuxerImpl::InitializeInstance(args);
43500   internal::TrackRegistry::InitializeInstance();
43501   g_was_initialized = true;
43502   init_args = args;
43503 }
43504 
43505 // static
IsInitialized()43506 bool Tracing::IsInitialized() {
43507   return g_was_initialized;
43508 }
43509 
43510 // static
ResetForTesting()43511 void Tracing::ResetForTesting() {
43512   if (!g_was_initialized)
43513     return;
43514   base::SetLogMessageCallback(nullptr);
43515   internal::TracingMuxerImpl::ResetForTesting();
43516   internal::TrackRegistry::ResetForTesting();
43517   g_was_initialized = false;
43518 }
43519 
43520 //  static
NewTrace(BackendType backend)43521 std::unique_ptr<TracingSession> Tracing::NewTrace(BackendType backend) {
43522   return static_cast<internal::TracingMuxerImpl*>(internal::TracingMuxer::Get())
43523       ->CreateTracingSession(backend);
43524 }
43525 
43526 // Can be called from any thread.
FlushBlocking(uint32_t timeout_ms)43527 bool TracingSession::FlushBlocking(uint32_t timeout_ms) {
43528   std::atomic<bool> flush_result;
43529   base::WaitableEvent flush_ack;
43530 
43531   // The non blocking Flush() can be called on any thread. It does the PostTask
43532   // internally.
43533   Flush(
43534       [&flush_ack, &flush_result](bool res) {
43535         flush_result = res;
43536         flush_ack.Notify();
43537       },
43538       timeout_ms);
43539   flush_ack.Wait();
43540   return flush_result;
43541 }
43542 
ReadTraceBlocking()43543 std::vector<char> TracingSession::ReadTraceBlocking() {
43544   std::vector<char> raw_trace;
43545   std::mutex mutex;
43546   std::condition_variable cv;
43547 
43548   bool all_read = false;
43549 
43550   ReadTrace([&mutex, &raw_trace, &all_read, &cv](ReadTraceCallbackArgs cb) {
43551     raw_trace.insert(raw_trace.end(), cb.data, cb.data + cb.size);
43552     std::unique_lock<std::mutex> lock(mutex);
43553     all_read = !cb.has_more;
43554     if (all_read)
43555       cv.notify_one();
43556   });
43557 
43558   {
43559     std::unique_lock<std::mutex> lock(mutex);
43560     cv.wait(lock, [&all_read] { return all_read; });
43561   }
43562   return raw_trace;
43563 }
43564 
43565 TracingSession::GetTraceStatsCallbackArgs
GetTraceStatsBlocking()43566 TracingSession::GetTraceStatsBlocking() {
43567   std::mutex mutex;
43568   std::condition_variable cv;
43569   GetTraceStatsCallbackArgs result;
43570   bool stats_read = false;
43571 
43572   GetTraceStats(
43573       [&mutex, &result, &stats_read, &cv](GetTraceStatsCallbackArgs args) {
43574         result = std::move(args);
43575         std::unique_lock<std::mutex> lock(mutex);
43576         stats_read = true;
43577         cv.notify_one();
43578       });
43579 
43580   {
43581     std::unique_lock<std::mutex> lock(mutex);
43582     cv.wait(lock, [&stats_read] { return stats_read; });
43583   }
43584   return result;
43585 }
43586 
43587 TracingSession::QueryServiceStateCallbackArgs
QueryServiceStateBlocking()43588 TracingSession::QueryServiceStateBlocking() {
43589   std::mutex mutex;
43590   std::condition_variable cv;
43591   QueryServiceStateCallbackArgs result;
43592   bool status_read = false;
43593 
43594   QueryServiceState(
43595       [&mutex, &result, &status_read, &cv](QueryServiceStateCallbackArgs args) {
43596         result = std::move(args);
43597         std::unique_lock<std::mutex> lock(mutex);
43598         status_read = true;
43599         cv.notify_one();
43600       });
43601 
43602   {
43603     std::unique_lock<std::mutex> lock(mutex);
43604     cv.wait(lock, [&status_read] { return status_read; });
43605   }
43606   return result;
43607 }
43608 
43609 }  // namespace perfetto
43610 // gen_amalgamated begin source: src/tracing/tracing_policy.cc
43611 /*
43612  * Copyright (C) 2021 The Android Open Source Project
43613  *
43614  * Licensed under the Apache License, Version 2.0 (the "License");
43615  * you may not use this file except in compliance with the License.
43616  * You may obtain a copy of the License at
43617  *
43618  *      http://www.apache.org/licenses/LICENSE-2.0
43619  *
43620  * Unless required by applicable law or agreed to in writing, software
43621  * distributed under the License is distributed on an "AS IS" BASIS,
43622  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
43623  * See the License for the specific language governing permissions and
43624  * limitations under the License.
43625  */
43626 
43627 // gen_amalgamated expanded: #include "perfetto/tracing/tracing_policy.h"
43628 
43629 namespace perfetto {
43630 
43631 TracingPolicy::~TracingPolicy() = default;
43632 
43633 }  // namespace perfetto
43634 // gen_amalgamated begin source: src/tracing/track.cc
43635 /*
43636  * Copyright (C) 2019 The Android Open Source Project
43637  *
43638  * Licensed under the Apache License, Version 2.0 (the "License");
43639  * you may not use this file except in compliance with the License.
43640  * You may obtain a copy of the License at
43641  *
43642  *      http://www.apache.org/licenses/LICENSE-2.0
43643  *
43644  * Unless required by applicable law or agreed to in writing, software
43645  * distributed under the License is distributed on an "AS IS" BASIS,
43646  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
43647  * See the License for the specific language governing permissions and
43648  * limitations under the License.
43649  */
43650 
43651 // gen_amalgamated expanded: #include "perfetto/tracing/track.h"
43652 
43653 // gen_amalgamated expanded: #include "perfetto/ext/base/file_utils.h"
43654 // gen_amalgamated expanded: #include "perfetto/ext/base/hash.h"
43655 // gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"
43656 // gen_amalgamated expanded: #include "perfetto/ext/base/string_splitter.h"
43657 // gen_amalgamated expanded: #include "perfetto/ext/base/string_utils.h"
43658 // gen_amalgamated expanded: #include "perfetto/ext/base/thread_utils.h"
43659 // gen_amalgamated expanded: #include "perfetto/ext/base/uuid.h"
43660 // gen_amalgamated expanded: #include "perfetto/tracing/internal/track_event_data_source.h"
43661 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/counter_descriptor.gen.h"
43662 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/process_descriptor.gen.h"
43663 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/process_descriptor.pbzero.h"
43664 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/thread_descriptor.gen.h"
43665 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/thread_descriptor.pbzero.h"
43666 
43667 namespace perfetto {
43668 
43669 // static
43670 uint64_t Track::process_uuid;
43671 
Serialize() const43672 protos::gen::TrackDescriptor Track::Serialize() const {
43673   protos::gen::TrackDescriptor desc;
43674   desc.set_uuid(uuid);
43675   if (parent_uuid)
43676     desc.set_parent_uuid(parent_uuid);
43677   return desc;
43678 }
43679 
Serialize(protos::pbzero::TrackDescriptor * desc) const43680 void Track::Serialize(protos::pbzero::TrackDescriptor* desc) const {
43681   auto bytes = Serialize().SerializeAsString();
43682   desc->AppendRawProtoBytes(bytes.data(), bytes.size());
43683 }
43684 
Serialize() const43685 protos::gen::TrackDescriptor ProcessTrack::Serialize() const {
43686   auto desc = Track::Serialize();
43687   auto pd = desc.mutable_process();
43688   pd->set_pid(static_cast<int32_t>(pid));
43689 #if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
43690     PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
43691   std::string cmdline;
43692   if (base::ReadFile("/proc/self/cmdline", &cmdline)) {
43693     // Since cmdline is a zero-terminated list of arguments, this ends up
43694     // writing just the first element, i.e., the process name, into the process
43695     // name field.
43696     pd->set_process_name(cmdline.c_str());
43697     base::StringSplitter splitter(std::move(cmdline), '\0');
43698     while (splitter.Next()) {
43699       pd->add_cmdline(
43700           std::string(splitter.cur_token(), splitter.cur_token_size()));
43701     }
43702   }
43703   // TODO(skyostil): Record command line on Windows and Mac.
43704 #endif
43705   return desc;
43706 }
43707 
Serialize(protos::pbzero::TrackDescriptor * desc) const43708 void ProcessTrack::Serialize(protos::pbzero::TrackDescriptor* desc) const {
43709   auto bytes = Serialize().SerializeAsString();
43710   desc->AppendRawProtoBytes(bytes.data(), bytes.size());
43711 }
43712 
Serialize() const43713 protos::gen::TrackDescriptor ThreadTrack::Serialize() const {
43714   auto desc = Track::Serialize();
43715   auto td = desc.mutable_thread();
43716   td->set_pid(static_cast<int32_t>(pid));
43717   td->set_tid(static_cast<int32_t>(tid));
43718   std::string thread_name;
43719   if (base::GetThreadName(thread_name))
43720     td->set_thread_name(thread_name);
43721   return desc;
43722 }
43723 
Serialize(protos::pbzero::TrackDescriptor * desc) const43724 void ThreadTrack::Serialize(protos::pbzero::TrackDescriptor* desc) const {
43725   auto bytes = Serialize().SerializeAsString();
43726   desc->AppendRawProtoBytes(bytes.data(), bytes.size());
43727 }
43728 
Serialize() const43729 protos::gen::TrackDescriptor CounterTrack::Serialize() const {
43730   auto desc = Track::Serialize();
43731   desc.set_name(name_);
43732   auto* counter = desc.mutable_counter();
43733   if (category_)
43734     counter->add_categories(category_);
43735   if (unit_ != perfetto::protos::pbzero::CounterDescriptor::UNIT_UNSPECIFIED)
43736     counter->set_unit(static_cast<protos::gen::CounterDescriptor_Unit>(unit_));
43737   if (unit_name_)
43738     counter->set_unit_name(unit_name_);
43739   if (unit_multiplier_ != 1)
43740     counter->set_unit_multiplier(unit_multiplier_);
43741   if (is_incremental_)
43742     counter->set_is_incremental(is_incremental_);
43743   return desc;
43744 }
43745 
Serialize(protos::pbzero::TrackDescriptor * desc) const43746 void CounterTrack::Serialize(protos::pbzero::TrackDescriptor* desc) const {
43747   auto bytes = Serialize().SerializeAsString();
43748   desc->AppendRawProtoBytes(bytes.data(), bytes.size());
43749 }
43750 
43751 namespace internal {
43752 namespace {
43753 
GetProcessStartTime()43754 uint64_t GetProcessStartTime() {
43755 #if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
43756   std::string stat;
43757   if (!base::ReadFile("/proc/self/stat", &stat))
43758     return 0u;
43759   // The stat file is a single line split into space-separated fields as "pid
43760   // (comm) state ppid ...". However because the command name can contain any
43761   // characters (including parentheses and spaces), we need to skip past it
43762   // before parsing the rest of the fields. To do that, we look for the last
43763   // instance of ") " (parentheses followed by space) and parse forward from
43764   // that point.
43765   size_t comm_end = stat.rfind(") ");
43766   if (comm_end == std::string::npos)
43767     return 0u;
43768   stat = stat.substr(comm_end + strlen(") "));
43769   base::StringSplitter splitter(stat, ' ');
43770   for (size_t skip = 0; skip < 20; skip++) {
43771     if (!splitter.Next())
43772       return 0u;
43773   }
43774   return base::CStringToUInt64(splitter.cur_token()).value_or(0u);
43775 #else
43776   return 0;
43777 #endif  // !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
43778 }
43779 
43780 }  // namespace
43781 
43782 // static
43783 TrackRegistry* TrackRegistry::instance_;
43784 
43785 TrackRegistry::TrackRegistry() = default;
43786 TrackRegistry::~TrackRegistry() = default;
43787 
43788 // static
InitializeInstance()43789 void TrackRegistry::InitializeInstance() {
43790   // TODO(eseckler): Chrome may call this more than once. Once Chrome doesn't
43791   // call this directly anymore, bring back DCHECK(!instance_) instead.
43792   if (instance_)
43793     return;
43794   instance_ = new TrackRegistry();
43795 
43796   // Use the process start time + pid as the unique identifier for this process.
43797   // This ensures that if there are two independent copies of the Perfetto SDK
43798   // in the same process (e.g., one in the app and another in a system
43799   // framework), events emitted by each will be consistently interleaved on
43800   // common thread and process tracks.
43801   if (uint64_t start_time = GetProcessStartTime()) {
43802     base::Hash hash;
43803     hash.Update(start_time);
43804     hash.Update(base::GetProcessId());
43805     Track::process_uuid = hash.digest();
43806   } else {
43807     // Fall back to a randomly generated identifier.
43808     Track::process_uuid = static_cast<uint64_t>(base::Uuidv4().lsb());
43809   }
43810 }
43811 
ResetForTesting()43812 void TrackRegistry::ResetForTesting() {
43813   delete instance_;
43814   instance_ = nullptr;
43815 }
43816 
UpdateTrack(Track track,const std::string & serialized_desc)43817 void TrackRegistry::UpdateTrack(Track track,
43818                                 const std::string& serialized_desc) {
43819   std::lock_guard<std::mutex> lock(mutex_);
43820   tracks_[track.uuid] = std::move(serialized_desc);
43821 }
43822 
UpdateTrackImpl(Track track,std::function<void (protos::pbzero::TrackDescriptor *)> fill_function)43823 void TrackRegistry::UpdateTrackImpl(
43824     Track track,
43825     std::function<void(protos::pbzero::TrackDescriptor*)> fill_function) {
43826   constexpr size_t kInitialSliceSize = 32;
43827   constexpr size_t kMaximumSliceSize = 4096;
43828   protozero::HeapBuffered<protos::pbzero::TrackDescriptor> new_descriptor(
43829       kInitialSliceSize, kMaximumSliceSize);
43830   fill_function(new_descriptor.get());
43831   auto serialized_desc = new_descriptor.SerializeAsString();
43832   UpdateTrack(track, serialized_desc);
43833 }
43834 
EraseTrack(Track track)43835 void TrackRegistry::EraseTrack(Track track) {
43836   std::lock_guard<std::mutex> lock(mutex_);
43837   tracks_.erase(track.uuid);
43838 }
43839 
43840 // static
WriteTrackDescriptor(const SerializedTrackDescriptor & desc,protozero::MessageHandle<protos::pbzero::TracePacket> packet)43841 void TrackRegistry::WriteTrackDescriptor(
43842     const SerializedTrackDescriptor& desc,
43843     protozero::MessageHandle<protos::pbzero::TracePacket> packet) {
43844   packet->AppendString(
43845       perfetto::protos::pbzero::TracePacket::kTrackDescriptorFieldNumber, desc);
43846 }
43847 
43848 }  // namespace internal
43849 }  // namespace perfetto
43850 // gen_amalgamated begin source: src/tracing/track_event_category_registry.cc
43851 /*
43852  * Copyright (C) 2019 The Android Open Source Project
43853  *
43854  * Licensed under the Apache License, Version 2.0 (the "License");
43855  * you may not use this file except in compliance with the License.
43856  * You may obtain a copy of the License at
43857  *
43858  *      http://www.apache.org/licenses/LICENSE-2.0
43859  *
43860  * Unless required by applicable law or agreed to in writing, software
43861  * distributed under the License is distributed on an "AS IS" BASIS,
43862  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
43863  * See the License for the specific language governing permissions and
43864  * limitations under the License.
43865  */
43866 
43867 // gen_amalgamated expanded: #include "perfetto/tracing/track_event_category_registry.h"
43868 
43869 namespace perfetto {
43870 
43871 // static
FromDynamicCategory(const char * name)43872 Category Category::FromDynamicCategory(const char* name) {
43873   if (GetNthNameSize(1, name, name)) {
43874     Category group(Group(name));
43875     PERFETTO_DCHECK(group.name);
43876     return group;
43877   }
43878   Category category(name);
43879   PERFETTO_DCHECK(category.name);
43880   return category;
43881 }
43882 
FromDynamicCategory(const DynamicCategory & dynamic_category)43883 Category Category::FromDynamicCategory(
43884     const DynamicCategory& dynamic_category) {
43885   return FromDynamicCategory(dynamic_category.name.c_str());
43886 }
43887 
43888 namespace internal {
43889 
NullCategory(const perfetto::DynamicCategory &)43890 perfetto::DynamicCategory NullCategory(const perfetto::DynamicCategory&) {
43891   return perfetto::DynamicCategory{};
43892 }
43893 
EnableCategoryForInstance(size_t category_index,uint32_t instance_index) const43894 void TrackEventCategoryRegistry::EnableCategoryForInstance(
43895     size_t category_index,
43896     uint32_t instance_index) const {
43897   PERFETTO_DCHECK(instance_index < kMaxDataSourceInstances);
43898   PERFETTO_DCHECK(category_index < category_count_);
43899   // Matches the acquire_load in DataSource::Trace().
43900   state_storage_[category_index].fetch_or(
43901       static_cast<uint8_t>(1u << instance_index), std::memory_order_release);
43902 }
43903 
DisableCategoryForInstance(size_t category_index,uint32_t instance_index) const43904 void TrackEventCategoryRegistry::DisableCategoryForInstance(
43905     size_t category_index,
43906     uint32_t instance_index) const {
43907   PERFETTO_DCHECK(instance_index < kMaxDataSourceInstances);
43908   PERFETTO_DCHECK(category_index < category_count_);
43909   // Matches the acquire_load in DataSource::Trace().
43910   state_storage_[category_index].fetch_and(
43911       static_cast<uint8_t>(~(1u << instance_index)), std::memory_order_release);
43912 }
43913 
43914 }  // namespace internal
43915 }  // namespace perfetto
43916 // gen_amalgamated begin source: src/tracing/track_event_legacy.cc
43917 /*
43918  * Copyright (C) 2020 The Android Open Source Project
43919  *
43920  * Licensed under the Apache License, Version 2.0 (the "License");
43921  * you may not use this file except in compliance with the License.
43922  * You may obtain a copy of the License at
43923  *
43924  *      http://www.apache.org/licenses/LICENSE-2.0
43925  *
43926  * Unless required by applicable law or agreed to in writing, software
43927  * distributed under the License is distributed on an "AS IS" BASIS,
43928  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
43929  * See the License for the specific language governing permissions and
43930  * limitations under the License.
43931  */
43932 
43933 // gen_amalgamated expanded: #include "perfetto/tracing/track_event_legacy.h"
43934 
43935 // gen_amalgamated expanded: #include "perfetto/tracing/track.h"
43936 
43937 namespace perfetto {
43938 namespace legacy {
43939 
43940 template <>
ConvertThreadId(const PerfettoLegacyCurrentThreadId &)43941 ThreadTrack ConvertThreadId(const PerfettoLegacyCurrentThreadId&) {
43942   // Because of the short-circuit in PERFETTO_INTERNAL_LEGACY_EVENT, we should
43943   // never get here.
43944   PERFETTO_DCHECK(false);
43945   return ThreadTrack::Current();
43946 }
43947 
43948 }  // namespace legacy
43949 
43950 namespace internal {
43951 
Write(protos::pbzero::TrackEvent::LegacyEvent * event,uint32_t event_flags) const43952 void LegacyTraceId::Write(protos::pbzero::TrackEvent::LegacyEvent* event,
43953                           uint32_t event_flags) const {
43954   // Legacy flow events always use bind_id.
43955   if (event_flags &
43956       (legacy::kTraceEventFlagFlowOut | legacy::kTraceEventFlagFlowIn)) {
43957     // Flow bind_ids don't have scopes, so we need to mangle in-process ones to
43958     // avoid collisions.
43959     if (id_flags_ & legacy::kTraceEventFlagHasLocalId) {
43960       event->set_bind_id(raw_id_ ^ ProcessTrack::Current().uuid);
43961     } else {
43962       event->set_bind_id(raw_id_);
43963     }
43964     return;
43965   }
43966 
43967   uint32_t scope_flags = id_flags_ & (legacy::kTraceEventFlagHasId |
43968                                       legacy::kTraceEventFlagHasLocalId |
43969                                       legacy::kTraceEventFlagHasGlobalId);
43970   switch (scope_flags) {
43971     case legacy::kTraceEventFlagHasId:
43972       event->set_unscoped_id(raw_id_);
43973       break;
43974     case legacy::kTraceEventFlagHasLocalId:
43975       event->set_local_id(raw_id_);
43976       break;
43977     case legacy::kTraceEventFlagHasGlobalId:
43978       event->set_global_id(raw_id_);
43979       break;
43980   }
43981   if (scope_)
43982     event->set_id_scope(scope_);
43983 }
43984 
43985 }  // namespace internal
43986 }  // namespace perfetto
43987 // gen_amalgamated begin source: src/tracing/track_event_state_tracker.cc
43988 /*
43989  * Copyright (C) 2020 The Android Open Source Project
43990  *
43991  * Licensed under the Apache License, Version 2.0 (the "License");
43992  * you may not use this file except in compliance with the License.
43993  * You may obtain a copy of the License at
43994  *
43995  *      http://www.apache.org/licenses/LICENSE-2.0
43996  *
43997  * Unless required by applicable law or agreed to in writing, software
43998  * distributed under the License is distributed on an "AS IS" BASIS,
43999  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
44000  * See the License for the specific language governing permissions and
44001  * limitations under the License.
44002  */
44003 
44004 // gen_amalgamated expanded: #include "perfetto/tracing/track_event_state_tracker.h"
44005 
44006 // gen_amalgamated expanded: #include "perfetto/ext/base/hash.h"
44007 
44008 // gen_amalgamated expanded: #include "protos/perfetto/common/interceptor_descriptor.gen.h"
44009 // gen_amalgamated expanded: #include "protos/perfetto/trace/interned_data/interned_data.pbzero.h"
44010 // gen_amalgamated expanded: #include "protos/perfetto/trace/trace_packet.pbzero.h"
44011 // gen_amalgamated expanded: #include "protos/perfetto/trace/trace_packet_defaults.pbzero.h"
44012 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/debug_annotation.pbzero.h"
44013 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/process_descriptor.pbzero.h"
44014 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/thread_descriptor.pbzero.h"
44015 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/track_descriptor.pbzero.h"
44016 // gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/track_event.pbzero.h"
44017 
44018 namespace perfetto {
44019 
44020 TrackEventStateTracker::~TrackEventStateTracker() = default;
44021 TrackEventStateTracker::Delegate::~Delegate() = default;
44022 
44023 // static
ProcessTracePacket(Delegate & delegate,SequenceState & sequence_state,const protos::pbzero::TracePacket_Decoder & packet)44024 void TrackEventStateTracker::ProcessTracePacket(
44025     Delegate& delegate,
44026     SequenceState& sequence_state,
44027     const protos::pbzero::TracePacket_Decoder& packet) {
44028   UpdateIncrementalState(delegate, sequence_state, packet);
44029 
44030   if (!packet.has_track_event())
44031     return;
44032   perfetto::protos::pbzero::TrackEvent::Decoder track_event(
44033       packet.track_event());
44034 
44035   // TODO(skyostil): Support incremental timestamps.
44036   uint64_t timestamp = packet.timestamp();
44037 
44038   Track* track = &sequence_state.track;
44039   if (track_event.has_track_uuid()) {
44040     auto* session_state = delegate.GetSessionState();
44041     if (!session_state)
44042       return;  // Tracing must have ended.
44043     track = &session_state->tracks[track_event.track_uuid()];
44044   }
44045 
44046   // We only log the first category of each event.
44047   protozero::ConstChars category{};
44048   uint64_t category_iid = 0;
44049   if (auto iid_it = track_event.category_iids()) {
44050     category_iid = *iid_it;
44051     category.data = sequence_state.event_categories[category_iid].data();
44052     category.size = sequence_state.event_categories[category_iid].size();
44053   } else if (auto cat_it = track_event.categories()) {
44054     category.data = reinterpret_cast<const char*>(cat_it->data());
44055     category.size = cat_it->size();
44056   }
44057 
44058   protozero::ConstChars name{};
44059   uint64_t name_iid = track_event.name_iid();
44060   uint64_t name_hash = 0;
44061   uint64_t duration = 0;
44062   if (name_iid) {
44063     name.data = sequence_state.event_names[name_iid].data();
44064     name.size = sequence_state.event_names[name_iid].size();
44065   } else if (track_event.has_name()) {
44066     name.data = track_event.name().data;
44067     name.size = track_event.name().size;
44068   }
44069 
44070   if (name.data) {
44071     base::Hash hash;
44072     hash.Update(name.data, name.size);
44073     name_hash = hash.digest();
44074   }
44075 
44076   size_t depth = track->stack.size();
44077   switch (track_event.type()) {
44078     case protos::pbzero::TrackEvent::TYPE_SLICE_BEGIN: {
44079       StackFrame frame;
44080       frame.timestamp = timestamp;
44081       frame.name_hash = name_hash;
44082       if (track_event.has_track_uuid()) {
44083         frame.name = name.ToStdString();
44084         frame.category = category.ToStdString();
44085       } else {
44086         frame.name_iid = name_iid;
44087         frame.category_iid = category_iid;
44088       }
44089       track->stack.push_back(std::move(frame));
44090       break;
44091     }
44092     case protos::pbzero::TrackEvent::TYPE_SLICE_END:
44093       if (!track->stack.empty()) {
44094         const auto& prev_frame = track->stack.back();
44095         if (prev_frame.name_iid) {
44096           name.data = sequence_state.event_names[prev_frame.name_iid].data();
44097           name.size = sequence_state.event_names[prev_frame.name_iid].size();
44098         } else {
44099           name.data = prev_frame.name.data();
44100           name.size = prev_frame.name.size();
44101         }
44102         name_hash = prev_frame.name_hash;
44103         if (prev_frame.category_iid) {
44104           category.data =
44105               sequence_state.event_categories[prev_frame.category_iid].data();
44106           category.size =
44107               sequence_state.event_categories[prev_frame.category_iid].size();
44108         } else {
44109           category.data = prev_frame.category.data();
44110           category.size = prev_frame.category.size();
44111         }
44112         duration = timestamp - prev_frame.timestamp;
44113         depth--;
44114       }
44115       break;
44116     case protos::pbzero::TrackEvent::TYPE_INSTANT:
44117       break;
44118     case protos::pbzero::TrackEvent::TYPE_COUNTER:
44119     case protos::pbzero::TrackEvent::TYPE_UNSPECIFIED:
44120       // TODO(skyostil): Support counters.
44121       return;
44122   }
44123 
44124   ParsedTrackEvent parsed_event{track_event};
44125   parsed_event.timestamp_ns = timestamp;
44126   parsed_event.duration_ns = duration;
44127   parsed_event.stack_depth = depth;
44128   parsed_event.category = category;
44129   parsed_event.name = name;
44130   parsed_event.name_hash = name_hash;
44131   delegate.OnTrackEvent(*track, parsed_event);
44132 
44133   if (track_event.type() == protos::pbzero::TrackEvent::TYPE_SLICE_END &&
44134       !track->stack.empty()) {
44135     track->stack.pop_back();
44136   }
44137 }
44138 
44139 // static
UpdateIncrementalState(Delegate & delegate,SequenceState & sequence_state,const protos::pbzero::TracePacket_Decoder & packet)44140 void TrackEventStateTracker::UpdateIncrementalState(
44141     Delegate& delegate,
44142     SequenceState& sequence_state,
44143     const protos::pbzero::TracePacket_Decoder& packet) {
44144 #if PERFETTO_DCHECK_IS_ON()
44145   if (!sequence_state.sequence_id) {
44146     sequence_state.sequence_id = packet.trusted_packet_sequence_id();
44147   } else {
44148     PERFETTO_DCHECK(sequence_state.sequence_id ==
44149                     packet.trusted_packet_sequence_id());
44150   }
44151 #endif
44152 
44153   if (packet.sequence_flags() &
44154       perfetto::protos::pbzero::TracePacket::SEQ_INCREMENTAL_STATE_CLEARED) {
44155     // Convert any existing event names and categories on the stack to
44156     // non-interned strings so we can look up their names even after the
44157     // incremental state is gone.
44158     for (auto& frame : sequence_state.track.stack) {
44159       if (frame.name_iid) {
44160         frame.name = sequence_state.event_names[frame.name_iid];
44161         frame.name_iid = 0u;
44162       }
44163       if (frame.category_iid) {
44164         frame.category = sequence_state.event_categories[frame.category_iid];
44165         frame.category_iid = 0u;
44166       }
44167     }
44168     sequence_state.event_names.clear();
44169     sequence_state.event_categories.clear();
44170     sequence_state.debug_annotation_names.clear();
44171     sequence_state.track.uuid = 0u;
44172     sequence_state.track.index = 0u;
44173   }
44174   if (packet.has_interned_data()) {
44175     perfetto::protos::pbzero::InternedData::Decoder interned_data(
44176         packet.interned_data());
44177     for (auto it = interned_data.event_names(); it; it++) {
44178       perfetto::protos::pbzero::EventName::Decoder entry(*it);
44179       sequence_state.event_names[entry.iid()] = entry.name().ToStdString();
44180     }
44181     for (auto it = interned_data.event_categories(); it; it++) {
44182       perfetto::protos::pbzero::EventCategory::Decoder entry(*it);
44183       sequence_state.event_categories[entry.iid()] = entry.name().ToStdString();
44184     }
44185     for (auto it = interned_data.debug_annotation_names(); it; it++) {
44186       perfetto::protos::pbzero::DebugAnnotationName::Decoder entry(*it);
44187       sequence_state.debug_annotation_names[entry.iid()] =
44188           entry.name().ToStdString();
44189     }
44190   }
44191   if (packet.has_trace_packet_defaults()) {
44192     perfetto::protos::pbzero::TracePacketDefaults::Decoder defaults(
44193         packet.trace_packet_defaults());
44194     if (defaults.has_track_event_defaults()) {
44195       perfetto::protos::pbzero::TrackEventDefaults::Decoder
44196           track_event_defaults(defaults.track_event_defaults());
44197       sequence_state.track.uuid = track_event_defaults.track_uuid();
44198     }
44199   }
44200   if (packet.has_track_descriptor()) {
44201     perfetto::protos::pbzero::TrackDescriptor::Decoder track_descriptor(
44202         packet.track_descriptor());
44203     auto* session_state = delegate.GetSessionState();
44204     auto& track = session_state->tracks[track_descriptor.uuid()];
44205     if (!track.index)
44206       track.index = static_cast<uint32_t>(session_state->tracks.size() + 1);
44207     track.uuid = track_descriptor.uuid();
44208 
44209     track.name = track_descriptor.name().ToStdString();
44210     track.pid = 0;
44211     track.tid = 0;
44212     if (track_descriptor.has_process()) {
44213       perfetto::protos::pbzero::ProcessDescriptor::Decoder process(
44214           track_descriptor.process());
44215       track.pid = process.pid();
44216       if (track.name.empty())
44217         track.name = process.process_name().ToStdString();
44218     } else if (track_descriptor.has_thread()) {
44219       perfetto::protos::pbzero::ThreadDescriptor::Decoder thread(
44220           track_descriptor.thread());
44221       track.pid = thread.pid();
44222       track.tid = thread.tid();
44223       if (track.name.empty())
44224         track.name = thread.thread_name().ToStdString();
44225     }
44226     delegate.OnTrackUpdated(track);
44227 
44228     // Mirror properties to the default track of the sequence. Note that
44229     // this does not catch updates to the default track written through other
44230     // sequences.
44231     if (track.uuid == sequence_state.track.uuid) {
44232       sequence_state.track.index = track.index;
44233       sequence_state.track.name = track.name;
44234       sequence_state.track.pid = track.pid;
44235       sequence_state.track.tid = track.tid;
44236       sequence_state.track.user_data = track.user_data;
44237     }
44238   }
44239 }
44240 
ParsedTrackEvent(const perfetto::protos::pbzero::TrackEvent::Decoder & track_event_)44241 TrackEventStateTracker::ParsedTrackEvent::ParsedTrackEvent(
44242     const perfetto::protos::pbzero::TrackEvent::Decoder& track_event_)
44243     : track_event(track_event_) {}
44244 
44245 }  // namespace perfetto
44246 // gen_amalgamated begin source: src/tracing/virtual_destructors.cc
44247 /*
44248  * Copyright (C) 2019 The Android Open Source Project
44249  *
44250  * Licensed under the Apache License, Version 2.0 (the "License");
44251  * you may not use this file except in compliance with the License.
44252  * You may obtain a copy of the License at
44253  *
44254  *      http://www.apache.org/licenses/LICENSE-2.0
44255  *
44256  * Unless required by applicable law or agreed to in writing, software
44257  * distributed under the License is distributed on an "AS IS" BASIS,
44258  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
44259  * See the License for the specific language governing permissions and
44260  * limitations under the License.
44261  */
44262 
44263 // gen_amalgamated expanded: #include "perfetto/tracing/internal/tracing_tls.h"
44264 // gen_amalgamated expanded: #include "perfetto/tracing/tracing.h"
44265 // gen_amalgamated expanded: #include "perfetto/tracing/tracing_backend.h"
44266 
44267 // This translation unit contains the definitions for the destructor of pure
44268 // virtual interfaces for the src/public:public target. The alternative would be
44269 // introducing a one-liner .cc file for each pure virtual interface, which is
44270 // overkill. This is for compliance with -Wweak-vtables.
44271 
44272 namespace perfetto {
44273 namespace internal {
44274 
~TracingTLS()44275 TracingTLS::~TracingTLS() {
44276   // Avoid entering trace points while the thread is being torn down.
44277   // This is the problem: when a thread exits, the at-thread-exit destroys the
44278   // TracingTLS. As part of that the various TraceWriter for the active data
44279   // sources are destroyd. A TraceWriter dtor will issue a PostTask on the IPC
44280   // thread to issue a final flush and unregister its ID with the service.
44281   // The PostTask, in chromium, might have a trace event that will try to
44282   // re-enter the tracing system.
44283   // We fix this by resetting the TLS key to the TracingTLS object that is
44284   // being destroyed in the platform impl (platform_posix.cc,
44285   // platform_windows.cc, chromium's platform.cc). We carefully rely on the fact
44286   // that all the tracing path that will be invoked during thread exit will
44287   // early out if |is_in_trace_point| == true and will not depend on the other
44288   // TLS state that has been destroyed.
44289   is_in_trace_point = true;
44290 }
44291 
44292 }  // namespace internal
44293 
44294 TracingBackend::~TracingBackend() = default;
44295 TracingSession::~TracingSession() = default;
44296 
44297 }  // namespace perfetto
44298 // gen_amalgamated begin source: src/android_stats/statsd_logging_helper.cc
44299 // gen_amalgamated begin header: src/android_stats/statsd_logging_helper.h
44300 // gen_amalgamated begin header: src/android_stats/perfetto_atoms.h
44301 /*
44302  * Copyright (C) 2020 The Android Open Source Project
44303  *
44304  * Licensed under the Apache License, Version 2.0 (the "License");
44305  * you may not use this file except in compliance with the License.
44306  * You may obtain a copy of the License at
44307  *
44308  *      http://www.apache.org/licenses/LICENSE-2.0
44309  *
44310  * Unless required by applicable law or agreed to in writing, software
44311  * distributed under the License is distributed on an "AS IS" BASIS,
44312  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
44313  * See the License for the specific language governing permissions and
44314  * limitations under the License.
44315  */
44316 
44317 #ifndef SRC_ANDROID_STATS_PERFETTO_ATOMS_H_
44318 #define SRC_ANDROID_STATS_PERFETTO_ATOMS_H_
44319 
44320 namespace perfetto {
44321 
44322 // This must match the values of the PerfettoUploadEvent enum in:
44323 // frameworks/proto_logging/stats/atoms.proto
44324 enum class PerfettoStatsdAtom {
44325   kUndefined = 0,
44326 
44327   // Checkpoints inside perfetto_cmd before tracing is finished.
44328   kTraceBegin = 1,
44329   kBackgroundTraceBegin = 2,
44330   kOnConnect = 3,
44331 
44332   // Guardrails inside perfetto_cmd before tracing is finished.
44333   kOnTimeout = 16,
44334   kCmdUserBuildTracingNotAllowed = 43,
44335   kCmdFailedToInitGuardrailState = 44,
44336   kCmdInvalidGuardrailState = 45,
44337   kCmdHitUploadLimit = 46,
44338 
44339   // Checkpoints inside traced.
44340   kTracedEnableTracing = 37,
44341   kTracedStartTracing = 38,
44342   kTracedDisableTracing = 39,
44343   kTracedNotifyTracingDisabled = 40,
44344 
44345   // Trigger checkpoints inside traced.
44346   // These atoms are special because, along with the UUID,
44347   // they log the trigger name.
44348   kTracedTriggerStartTracing = 41,
44349   kTracedTriggerStopTracing = 42,
44350 
44351   // Guardrails inside traced.
44352   kTracedEnableTracingExistingTraceSession = 18,
44353   kTracedEnableTracingTooLongTrace = 19,
44354   kTracedEnableTracingInvalidTriggerTimeout = 20,
44355   kTracedEnableTracingDurationWithTrigger = 21,
44356   kTracedEnableTracingStopTracingWriteIntoFile = 22,
44357   kTracedEnableTracingDuplicateTriggerName = 23,
44358   kTracedEnableTracingInvalidDeferredStart = 24,
44359   kTracedEnableTracingInvalidBufferSize = 25,
44360   kTracedEnableTracingBufferSizeTooLarge = 26,
44361   kTracedEnableTracingTooManyBuffers = 27,
44362   kTracedEnableTracingDuplicateSessionName = 28,
44363   kTracedEnableTracingSessionNameTooRecent = 29,
44364   kTracedEnableTracingTooManySessionsForUid = 30,
44365   kTracedEnableTracingTooManyConcurrentSessions = 31,
44366   kTracedEnableTracingInvalidFdOutputFile = 32,
44367   kTracedEnableTracingFailedToCreateFile = 33,
44368   kTracedEnableTracingOom = 34,
44369   kTracedEnableTracingUnknown = 35,
44370   kTracedStartTracingInvalidSessionState = 36,
44371   kTracedEnableTracingInvalidFilter = 47,
44372   kTracedEnableTracingOobTargetBuffer = 48,
44373 
44374   // Checkpoints inside perfetto_cmd after tracing has finished.
44375   kOnTracingDisabled = 4,
44376   kUploadIncidentBegin = 8,
44377   kFinalizeTraceAndExit = 11,
44378   kNotUploadingEmptyTrace = 17,
44379 
44380   // Guardrails inside perfetto_cmd after tracing has finished.
44381   kUploadIncidentFailure = 10,
44382 
44383   // Deprecated as "success" is misleading; it simply means we were
44384   // able to communicate with incidentd. Will be removed once
44385   // incidentd is properly instrumented.
44386   kUploadIncidentSuccess = 9,
44387 
44388   // Deprecated as has the potential to be too spammy. Will be
44389   // replaced with a whole new atom proto which uses a count metric
44390   // instead of the event metric used for this proto.
44391   kTriggerBegin = 12,
44392   kTriggerSuccess = 13,
44393   kTriggerFailure = 14,
44394 
44395   // Deprecated as too coarse grained to be useful. Will be replaced
44396   // with better broken down atoms as we do with traced.
44397   kHitGuardrails = 15,
44398 
44399   // Contained status of Dropbox uploads. Removed as Perfetto no
44400   // longer supports uploading traces using Dropbox.
44401   // reserved 5, 6, 7;
44402 };
44403 
44404 // This must match the values of the PerfettoTrigger::TriggerType enum in:
44405 // frameworks/base/cmds/statsd/src/atoms.proto
44406 enum PerfettoTriggerAtom {
44407   kUndefined = 0,
44408 
44409   kCmdTrigger = 1,
44410   kCmdTriggerFail = 2,
44411 
44412   kTriggerPerfettoTrigger = 3,
44413   kTriggerPerfettoTriggerFail = 4,
44414 
44415   kTracedLimitProbability = 5,
44416   kTracedLimitMaxPer24h = 6,
44417 
44418   kProbesProducerTrigger = 7,
44419   kProbesProducerTriggerFail = 8,
44420 };
44421 
44422 }  // namespace perfetto
44423 
44424 #endif  // SRC_ANDROID_STATS_PERFETTO_ATOMS_H_
44425 /*
44426  * Copyright (C) 2020 The Android Open Source Project
44427  *
44428  * Licensed under the Apache License, Version 2.0 (the "License");
44429  * you may not use this file except in compliance with the License.
44430  * You may obtain a copy of the License at
44431  *
44432  *      http://www.apache.org/licenses/LICENSE-2.0
44433  *
44434  * Unless required by applicable law or agreed to in writing, software
44435  * distributed under the License is distributed on an "AS IS" BASIS,
44436  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
44437  * See the License for the specific language governing permissions and
44438  * limitations under the License.
44439  */
44440 
44441 #ifndef SRC_ANDROID_STATS_STATSD_LOGGING_HELPER_H_
44442 #define SRC_ANDROID_STATS_STATSD_LOGGING_HELPER_H_
44443 
44444 #include <stdint.h>
44445 #include <string>
44446 #include <vector>
44447 
44448 // gen_amalgamated expanded: #include "src/android_stats/perfetto_atoms.h"
44449 
44450 namespace perfetto {
44451 namespace android_stats {
44452 
44453 // Functions in this file are only active on built in the Android
44454 // tree. On other platforms (including Android standalone and Chromium
44455 // on Android) these functions are a noop.
44456 
44457 // Logs the upload event to statsd if built in the Android tree.
44458 void MaybeLogUploadEvent(PerfettoStatsdAtom atom,
44459                          int64_t uuid_lsb,
44460                          int64_t uuid_msb,
44461                          const std::string& trigger_name = "");
44462 
44463 // Logs the trigger events to statsd if built in the Android tree.
44464 void MaybeLogTriggerEvent(PerfettoTriggerAtom atom, const std::string& trigger);
44465 
44466 // Logs the trigger events to statsd if built in the Android tree.
44467 void MaybeLogTriggerEvents(PerfettoTriggerAtom atom,
44468                            const std::vector<std::string>& triggers);
44469 
44470 }  // namespace android_stats
44471 }  // namespace perfetto
44472 
44473 #endif  // SRC_ANDROID_STATS_STATSD_LOGGING_HELPER_H_
44474 /*
44475  * Copyright (C) 2020 The Android Open Source Project
44476  *
44477  * Licensed under the Apache License, Version 2.0 (the "License");
44478  * you may not use this file except in compliance with the License.
44479  * You may obtain a copy of the License at
44480  *
44481  *      http://www.apache.org/licenses/LICENSE-2.0
44482  *
44483  * Unless required by applicable law or agreed to in writing, software
44484  * distributed under the License is distributed on an "AS IS" BASIS,
44485  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
44486  * See the License for the specific language governing permissions and
44487  * limitations under the License.
44488  */
44489 
44490 // gen_amalgamated expanded: #include "src/android_stats/statsd_logging_helper.h"
44491 
44492 #include <string>
44493 
44494 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
44495 // gen_amalgamated expanded: #include "perfetto/base/compiler.h"
44496 
44497 #if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) && \
44498     PERFETTO_BUILDFLAG(PERFETTO_ANDROID_BUILD)
44499 // gen_amalgamated expanded: #include "src/android_internal/lazy_library_loader.h"  // nogncheck
44500 // gen_amalgamated expanded: #include "src/android_internal/statsd_logging.h"       // nogncheck
44501 #endif
44502 
44503 namespace perfetto {
44504 namespace android_stats {
44505 
44506 // Make sure we don't accidentally log on non-Android tree build. Note that even
44507 // removing this ifdef still doesn't make uploads work on OS_ANDROID.
44508 // PERFETTO_LAZY_LOAD will return a nullptr on non-Android and non-in-tree
44509 // builds as libperfetto_android_internal will not be available.
44510 #if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) && \
44511     PERFETTO_BUILDFLAG(PERFETTO_ANDROID_BUILD)
44512 
MaybeLogUploadEvent(PerfettoStatsdAtom atom,int64_t uuid_lsb,int64_t uuid_msb,const std::string & trigger_name)44513 void MaybeLogUploadEvent(PerfettoStatsdAtom atom,
44514                          int64_t uuid_lsb,
44515                          int64_t uuid_msb,
44516                          const std::string& trigger_name) {
44517   PERFETTO_LAZY_LOAD(android_internal::StatsdLogUploadEvent, log_event_fn);
44518   if (log_event_fn) {
44519     log_event_fn(atom, uuid_lsb, uuid_msb, trigger_name.c_str());
44520   }
44521 }
44522 
MaybeLogTriggerEvent(PerfettoTriggerAtom atom,const std::string & trigger_name)44523 void MaybeLogTriggerEvent(PerfettoTriggerAtom atom,
44524                           const std::string& trigger_name) {
44525   PERFETTO_LAZY_LOAD(android_internal::StatsdLogTriggerEvent, log_event_fn);
44526   if (log_event_fn) {
44527     log_event_fn(atom, trigger_name.c_str());
44528   }
44529 }
44530 
MaybeLogTriggerEvents(PerfettoTriggerAtom atom,const std::vector<std::string> & triggers)44531 void MaybeLogTriggerEvents(PerfettoTriggerAtom atom,
44532                            const std::vector<std::string>& triggers) {
44533   PERFETTO_LAZY_LOAD(android_internal::StatsdLogTriggerEvent, log_event_fn);
44534   if (log_event_fn) {
44535     for (const std::string& trigger_name : triggers) {
44536       log_event_fn(atom, trigger_name.c_str());
44537     }
44538   }
44539 }
44540 
44541 #else
44542 void MaybeLogUploadEvent(PerfettoStatsdAtom,
44543                          int64_t,
44544                          int64_t,
44545                          const std::string&) {}
44546 void MaybeLogTriggerEvent(PerfettoTriggerAtom, const std::string&) {}
44547 void MaybeLogTriggerEvents(PerfettoTriggerAtom,
44548                            const std::vector<std::string>&) {}
44549 #endif
44550 
44551 }  // namespace android_stats
44552 }  // namespace perfetto
44553 // gen_amalgamated begin source: src/protozero/filtering/filter_bytecode_parser.cc
44554 // gen_amalgamated begin header: src/protozero/filtering/filter_bytecode_parser.h
44555 /*
44556  * Copyright (C) 2021 The Android Open Source Project
44557  *
44558  * Licensed under the Apache License, Version 2.0 (the "License");
44559  * you may not use this file except in compliance with the License.
44560  * You may obtain a copy of the License at
44561  *
44562  *      http://www.apache.org/licenses/LICENSE-2.0
44563  *
44564  * Unless required by applicable law or agreed to in writing, software
44565  * distributed under the License is distributed on an "AS IS" BASIS,
44566  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
44567  * See the License for the specific language governing permissions and
44568  * limitations under the License.
44569  */
44570 
44571 #ifndef SRC_PROTOZERO_FILTERING_FILTER_BYTECODE_PARSER_H_
44572 #define SRC_PROTOZERO_FILTERING_FILTER_BYTECODE_PARSER_H_
44573 
44574 #include <stddef.h>
44575 #include <stdint.h>
44576 
44577 #include <vector>
44578 
44579 namespace protozero {
44580 
44581 // Loads the proto-encoded bytecode in memory and allows fast lookups for tuples
44582 // (msg_index, field_id) to tell if a given field should be allowed or not and,
44583 // in the case of nested fields, what is the next message index to recurse into.
44584 // This class does two things:
44585 // 1. Expands the array of varint from the proto into a vector<uint32_t>. This
44586 //    is to avoid performing varint decoding on every lookup, at the cost of
44587 //    some extra memory (2KB-4KB). Note that the expanded vector is not just a
44588 //    1:1 copy of the proto one (more below). This is to avoid O(Fields) linear
44589 //    lookup complexity.
44590 // 2. Creates an index of offsets to remember the start word for each message.
44591 //    This is so we can jump to O(1) to the N-th message when recursing into a
44592 //    nested fields, without having to scan and find the (N-1)-th END_OF_MESSAGE
44593 //    marker.
44594 // Overall lookups are O(1) for field ids < 128 (kDirectlyIndexLimit) and O(N),
44595 // with N being the number of allowed field ranges for other fields.
44596 // See comments around |word_| below for the structure of the word vector.
44597 class FilterBytecodeParser {
44598  public:
44599   // Result of a Query() operation
44600   struct QueryResult {
44601     bool allowed;  // Whether the field is allowed at all or no.
44602 
44603     // If |allowed|==true && simple_field()==false, this tells the message index
44604     // of the nested field that should be used when recursing in the parser.
44605     uint32_t nested_msg_index;
44606 
44607     // If |allowed|==true, specifies if the field is of a simple type (varint,
44608     // fixed32/64, string or byte) or a nested field that needs recursion.
44609     // In the latter case the caller is expected to use |nested_msg_index| for
44610     // the next Query() calls.
simple_fieldprotozero::FilterBytecodeParser::QueryResult44611     bool simple_field() const { return nested_msg_index == kSimpleField; }
44612   };
44613 
44614   // Loads a filter. The filter data consists of a sequence of varints which
44615   // contains the filter opcodes and a final checksum.
44616   bool Load(const void* filter_data, size_t len);
44617 
44618   // Checks wheter a given field is allowed or not.
44619   // msg_index = 0 is the index of the root message, where all queries should
44620   // start from (typically perfetto.protos.Trace).
44621   QueryResult Query(uint32_t msg_index, uint32_t field_id);
44622 
44623   void Reset();
set_suppress_logs_for_fuzzer(bool x)44624   void set_suppress_logs_for_fuzzer(bool x) { suppress_logs_for_fuzzer_ = x; }
44625 
44626  private:
44627   static constexpr uint32_t kDirectlyIndexLimit = 128;
44628   static constexpr uint32_t kAllowed = 1u << 31u;
44629   static constexpr uint32_t kSimpleField = 0x7fffffff;
44630 
44631   bool LoadInternal(const uint8_t* filter_data, size_t len);
44632 
44633   // The state of all fields for all messages is stored in one contiguous array.
44634   // This is to avoid memory fragmentation and allocator overhead.
44635   // We expect a high number of messages (hundreds), but each message is small.
44636   // For each message we store two sets of uint32:
44637   // 1. A set of "directly indexed" fields, for field ids < 128.
44638   // 2. The remainder is a set of ranges.
44639   // So each message descriptor consists of a sequence of words as follows:
44640   //
44641   // [0] -> how many directly indexed fields are stored next (up to 128)
44642   //
44643   // [1..N] -> One word per field id (See "field state" below).
44644   //
44645   // [N + 1] -> Start of field id range 1
44646   // [N + 2] -> End of field id range 1 (exclusive, STL-style).
44647   // [N + 3] -> Field state for fields in range 1 (below)
44648   //
44649   // [N + 4] -> Start of field id range 2
44650   // [N + 5] -> End of field id range 2 (exclusive, STL-style).
44651   // [N + 6] -> Field state for fields in range 2 (below)
44652 
44653   // The "field state" word is as follows:
44654   // Bit 31: 0 if the field is disallowed, 1 if allowed.
44655   //         Only directly indexed fields can be 0 (it doesn't make sense to add
44656   //         a range and then say "btw it's NOT allowed".. don't add it then.
44657   //         0 is only used for filling gaps in the directly indexed bucket.
44658   // Bits [30..0] (only when MSB == allowed):
44659   //  0x7fffffff: The field is "simple" (varint, fixed32/64, string, bytes) and
44660   //      can be directly passed through in output. No recursion is needed.
44661   //  [0, 7ffffffe]: The field is a nested submessage. The value is the index
44662   //     that must be passed as first argument to the next Query() calls.
44663   //     Note that the message index is purely a monotonic counter in the
44664   //     filter bytecode, has no proto-equivalent match (unlike field ids).
44665   std::vector<uint32_t> words_;
44666 
44667   // One entry for each message index stored in the filter plus a sentinel at
44668   // the end. Maps each message index to the offset in |words_| where the
44669   // Nth message start.
44670   // message_offset_.size() - 2 == the max message id that can be parsed.
44671   std::vector<uint32_t> message_offset_;
44672 
44673   bool suppress_logs_for_fuzzer_ = false;
44674 };
44675 
44676 }  // namespace protozero
44677 
44678 #endif  // SRC_PROTOZERO_FILTERING_FILTER_BYTECODE_PARSER_H_
44679 // gen_amalgamated begin header: src/protozero/filtering/filter_bytecode_common.h
44680 /*
44681  * Copyright (C) 2021 The Android Open Source Project
44682  *
44683  * Licensed under the Apache License, Version 2.0 (the "License");
44684  * you may not use this file except in compliance with the License.
44685  * You may obtain a copy of the License at
44686  *
44687  *      http://www.apache.org/licenses/LICENSE-2.0
44688  *
44689  * Unless required by applicable law or agreed to in writing, software
44690  * distributed under the License is distributed on an "AS IS" BASIS,
44691  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
44692  * See the License for the specific language governing permissions and
44693  * limitations under the License.
44694  */
44695 
44696 #ifndef SRC_PROTOZERO_FILTERING_FILTER_BYTECODE_COMMON_H_
44697 #define SRC_PROTOZERO_FILTERING_FILTER_BYTECODE_COMMON_H_
44698 
44699 #include <stdint.h>
44700 
44701 namespace protozero {
44702 
44703 enum FilterOpcode : uint32_t {
44704   // The immediate value is 0 in this case.
44705   kFilterOpcode_EndOfMessage = 0,
44706 
44707   // The immediate value is the id of the allowed field.
44708   kFilterOpcode_SimpleField = 1,
44709 
44710   // The immediate value is the start of the range. The next word (without
44711   // any shifting) is the length of the range.
44712   kFilterOpcode_SimpleFieldRange = 2,
44713 
44714   // The immediate value is the id of the allowed field. The next word
44715   // (without any shifting) is the index of the filter that should be used to
44716   // recurse into the nested message.
44717   kFilterOpcode_NestedField = 3,
44718 };
44719 }  // namespace protozero
44720 
44721 #endif  // SRC_PROTOZERO_FILTERING_FILTER_BYTECODE_COMMON_H_
44722 /*
44723  * Copyright (C) 2021 The Android Open Source Project
44724  *
44725  * Licensed under the Apache License, Version 2.0 (the "License");
44726  * you may not use this file except in compliance with the License.
44727  * You may obtain a copy of the License at
44728  *
44729  *      http://www.apache.org/licenses/LICENSE-2.0
44730  *
44731  * Unless required by applicable law or agreed to in writing, software
44732  * distributed under the License is distributed on an "AS IS" BASIS,
44733  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
44734  * See the License for the specific language governing permissions and
44735  * limitations under the License.
44736  */
44737 
44738 // gen_amalgamated expanded: #include "src/protozero/filtering/filter_bytecode_parser.h"
44739 
44740 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
44741 // gen_amalgamated expanded: #include "perfetto/ext/base/hash.h"
44742 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
44743 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
44744 // gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
44745 // gen_amalgamated expanded: #include "src/protozero/filtering/filter_bytecode_common.h"
44746 
44747 namespace protozero {
44748 
Reset()44749 void FilterBytecodeParser::Reset() {
44750   bool suppress = suppress_logs_for_fuzzer_;
44751   *this = FilterBytecodeParser();
44752   suppress_logs_for_fuzzer_ = suppress;
44753 }
44754 
Load(const void * filter_data,size_t len)44755 bool FilterBytecodeParser::Load(const void* filter_data, size_t len) {
44756   Reset();
44757   bool res = LoadInternal(static_cast<const uint8_t*>(filter_data), len);
44758   // If load fails, don't leave the parser in a half broken state.
44759   if (!res)
44760     Reset();
44761   return res;
44762 }
44763 
LoadInternal(const uint8_t * bytecode_data,size_t len)44764 bool FilterBytecodeParser::LoadInternal(const uint8_t* bytecode_data,
44765                                         size_t len) {
44766   // First unpack the varints into a plain uint32 vector, so it's easy to
44767   // iterate through them and look ahead.
44768   std::vector<uint32_t> words;
44769   bool packed_parse_err = false;
44770   words.reserve(len);  // An overestimation, but avoids reallocations.
44771   using BytecodeDecoder =
44772       PackedRepeatedFieldIterator<proto_utils::ProtoWireType::kVarInt,
44773                                   uint32_t>;
44774   for (BytecodeDecoder it(bytecode_data, len, &packed_parse_err); it; ++it)
44775     words.emplace_back(*it);
44776 
44777   if (packed_parse_err || words.empty())
44778     return false;
44779 
44780   perfetto::base::Hash hasher;
44781   for (size_t i = 0; i < words.size() - 1; ++i)
44782     hasher.Update(words[i]);
44783 
44784   uint32_t expected_csum = static_cast<uint32_t>(hasher.digest());
44785   if (expected_csum != words.back()) {
44786     if (!suppress_logs_for_fuzzer_) {
44787       PERFETTO_ELOG("Filter bytecode checksum failed. Expected: %x, actual: %x",
44788                     expected_csum, words.back());
44789     }
44790     return false;
44791   }
44792 
44793   words.pop_back();  // Pop the checksum.
44794 
44795   // Temporay storage for each message. Cleared on every END_OF_MESSAGE.
44796   std::vector<uint32_t> direct_indexed_fields;
44797   std::vector<uint32_t> ranges;
44798   uint32_t max_msg_index = 0;
44799 
44800   auto add_directly_indexed_field = [&](uint32_t field_id, uint32_t msg_id) {
44801     PERFETTO_DCHECK(field_id > 0 && field_id < kDirectlyIndexLimit);
44802     direct_indexed_fields.resize(std::max(direct_indexed_fields.size(),
44803                                           static_cast<size_t>(field_id) + 1));
44804     direct_indexed_fields[field_id] = kAllowed | msg_id;
44805   };
44806 
44807   auto add_range = [&](uint32_t id_start, uint32_t id_end, uint32_t msg_id) {
44808     PERFETTO_DCHECK(id_end > id_start);
44809     PERFETTO_DCHECK(id_start >= kDirectlyIndexLimit);
44810     ranges.emplace_back(id_start);
44811     ranges.emplace_back(id_end);
44812     ranges.emplace_back(kAllowed | msg_id);
44813   };
44814 
44815   for (size_t i = 0; i < words.size(); ++i) {
44816     const uint32_t word = words[i];
44817     const bool has_next_word = i < words.size() - 1;
44818     const uint32_t opcode = word & 0x7u;
44819     const uint32_t field_id = word >> 3;
44820 
44821     if (field_id == 0 && opcode != kFilterOpcode_EndOfMessage) {
44822       PERFETTO_DLOG("bytecode error @ word %zu, invalid field id (0)", i);
44823       return false;
44824     }
44825 
44826     if (opcode == kFilterOpcode_SimpleField ||
44827         opcode == kFilterOpcode_NestedField) {
44828       // Field words are organized as follow:
44829       // MSB: 1 if allowed, 0 if not allowed.
44830       // Remaining bits:
44831       //   Message index in the case of nested (non-simple) messages.
44832       //   0x7f..f in the case of simple messages.
44833       uint32_t msg_id;
44834       if (opcode == kFilterOpcode_SimpleField) {
44835         msg_id = kSimpleField;
44836       } else {  // FILTER_OPCODE_NESTED_FIELD
44837         // The next word in the bytecode contains the message index.
44838         if (!has_next_word) {
44839           PERFETTO_DLOG("bytecode error @ word %zu: unterminated nested field",
44840                         i);
44841           return false;
44842         }
44843         msg_id = words[++i];
44844         max_msg_index = std::max(max_msg_index, msg_id);
44845       }
44846 
44847       if (field_id < kDirectlyIndexLimit) {
44848         add_directly_indexed_field(field_id, msg_id);
44849       } else {
44850         // In the case of a large field id (rare) we waste an extra word and
44851         // represent it as a range. Doesn't make sense to introduce extra
44852         // complexity to deal with rare cases like this.
44853         add_range(field_id, field_id + 1, msg_id);
44854       }
44855     } else if (opcode == kFilterOpcode_SimpleFieldRange) {
44856       if (!has_next_word) {
44857         PERFETTO_DLOG("bytecode error @ word %zu: unterminated range", i);
44858         return false;
44859       }
44860       const uint32_t range_len = words[++i];
44861       const uint32_t range_end = field_id + range_len;  // STL-style, excl.
44862       uint32_t id = field_id;
44863 
44864       // Here's the subtle complexity: at the bytecode level, we don't know
44865       // anything about the kDirectlyIndexLimit. It is legit to define a range
44866       // that spans across the direct-indexing threshold (e.g. 126-132). In that
44867       // case we want to add all the elements < the indexing to the O(1) bucket
44868       // and add only the remaining range as a non-indexed range.
44869       for (; id < range_end && id < kDirectlyIndexLimit; ++id)
44870         add_directly_indexed_field(id, kAllowed | kSimpleField);
44871       PERFETTO_DCHECK(id >= kDirectlyIndexLimit || id == range_end);
44872       if (id < range_end)
44873         add_range(id, range_end, kSimpleField);
44874     } else if (opcode == kFilterOpcode_EndOfMessage) {
44875       // For each message append:
44876       // 1. The "header" word telling how many directly indexed fields there
44877       //    are.
44878       // 2. The words for the directly indexed fields (id < 128).
44879       // 3. The rest of the fields, encoded as ranges.
44880       // Also update the |message_offset_| index to remember the word offset for
44881       // the current message.
44882       message_offset_.emplace_back(static_cast<uint32_t>(words_.size()));
44883       words_.emplace_back(static_cast<uint32_t>(direct_indexed_fields.size()));
44884       words_.insert(words_.end(), direct_indexed_fields.begin(),
44885                     direct_indexed_fields.end());
44886       words_.insert(words_.end(), ranges.begin(), ranges.end());
44887       direct_indexed_fields.clear();
44888       ranges.clear();
44889     } else {
44890       PERFETTO_DLOG("bytecode error @ word %zu: invalid opcode (%x)", i, word);
44891       return false;
44892     }
44893   }  // (for word in bytecode).
44894 
44895   if (max_msg_index > 0 && max_msg_index >= message_offset_.size()) {
44896     PERFETTO_DLOG(
44897         "bytecode error: a message index (%u) is out of range "
44898         "(num_messages=%zu)",
44899         max_msg_index, message_offset_.size());
44900     return false;
44901   }
44902 
44903   // Add a final entry to |message_offset_| so we can tell where the last
44904   // message ends without an extra branch in the Query() hotpath.
44905   message_offset_.emplace_back(static_cast<uint32_t>(words_.size()));
44906 
44907   return true;
44908 }
44909 
Query(uint32_t msg_index,uint32_t field_id)44910 FilterBytecodeParser::QueryResult FilterBytecodeParser::Query(
44911     uint32_t msg_index,
44912     uint32_t field_id) {
44913   FilterBytecodeParser::QueryResult res{false, 0u};
44914   if (static_cast<uint64_t>(msg_index) + 1 >=
44915       static_cast<uint64_t>(message_offset_.size())) {
44916     return res;
44917   }
44918   const uint32_t start_offset = message_offset_[msg_index];
44919   // These are DCHECKs and not just CHECKS because the |words_| is populated
44920   // by the LoadInternal call above. These cannot be violated with a malformed
44921   // bytecode.
44922   PERFETTO_DCHECK(start_offset < words_.size());
44923   const uint32_t* word = &words_[start_offset];
44924   const uint32_t end_off = message_offset_[msg_index + 1];
44925   const uint32_t* const end = words_.data() + end_off;
44926   PERFETTO_DCHECK(end > word && end <= words_.data() + words_.size());
44927   const uint32_t num_directly_indexed = *(word++);
44928   PERFETTO_DCHECK(num_directly_indexed <= kDirectlyIndexLimit);
44929   PERFETTO_DCHECK(word + num_directly_indexed <= end);
44930   uint32_t field_state = 0;
44931   if (PERFETTO_LIKELY(field_id < num_directly_indexed)) {
44932     PERFETTO_DCHECK(&word[field_id] < end);
44933     field_state = word[field_id];
44934   } else {
44935     for (word = word + num_directly_indexed; word + 2 < end;) {
44936       const uint32_t range_start = *(word++);
44937       const uint32_t range_end = *(word++);
44938       const uint32_t range_state = *(word++);
44939       if (field_id >= range_start && field_id < range_end) {
44940         field_state = range_state;
44941         break;
44942       }
44943     }  // for (word in ranges)
44944   }    // if (field_id >= num_directly_indexed)
44945 
44946   res.allowed = (field_state & kAllowed) != 0;
44947   res.nested_msg_index = field_state & ~kAllowed;
44948   PERFETTO_DCHECK(res.simple_field() ||
44949                   res.nested_msg_index < message_offset_.size() - 1);
44950   return res;
44951 }
44952 
44953 }  // namespace protozero
44954 // gen_amalgamated begin source: src/protozero/filtering/message_filter.cc
44955 // gen_amalgamated begin header: src/protozero/filtering/message_filter.h
44956 // gen_amalgamated begin header: src/protozero/filtering/message_tokenizer.h
44957 /*
44958  * Copyright (C) 2021 The Android Open Source Project
44959  *
44960  * Licensed under the Apache License, Version 2.0 (the "License");
44961  * you may not use this file except in compliance with the License.
44962  * You may obtain a copy of the License at
44963  *
44964  *      http://www.apache.org/licenses/LICENSE-2.0
44965  *
44966  * Unless required by applicable law or agreed to in writing, software
44967  * distributed under the License is distributed on an "AS IS" BASIS,
44968  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
44969  * See the License for the specific language governing permissions and
44970  * limitations under the License.
44971  */
44972 
44973 #ifndef SRC_PROTOZERO_FILTERING_MESSAGE_TOKENIZER_H_
44974 #define SRC_PROTOZERO_FILTERING_MESSAGE_TOKENIZER_H_
44975 
44976 #include <stdint.h>
44977 
44978 // gen_amalgamated expanded: #include "perfetto/base/compiler.h"
44979 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
44980 // gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
44981 
44982 namespace protozero {
44983 
44984 // A helper class for schema-less tokenizing of protobuf messages.
44985 // This class takes a stream of proto-encoded bytes, pushed one by one in input
44986 // via Push(octet), and returns a stream of tokens (each Push() call can return
44987 // 0 or 1 token).
44988 // A "token" contains metadata about a field, specifically: its ID, its wire
44989 // type and:
44990 //  - For varint and fixed32/64 fields: its payload.
44991 //  - For string and bytes fields: the length of its payload.
44992 //    In this case the caller is supposed to "eat" those N bytes before calling
44993 //    Push() again.
44994 // Note that this class cannot differentiate between a string/bytes field or
44995 // a submessage, because they are encoded in the same way. The caller is
44996 // supposed to know whether a field can be recursed into by just keep calling
44997 // Push() or is a string that should be skipped.
44998 // This is inline to allow the compiler to see through the Push method and
44999 // avoid a function call for each byte.
45000 class MessageTokenizer {
45001  public:
45002   struct Token {
45003     uint32_t field_id;  // 0 == not valid.
45004     proto_utils::ProtoWireType type;
45005 
45006     // For kLengthDelimited, |value| represent the length of the payload.
45007     uint64_t value;
45008 
validprotozero::MessageTokenizer::Token45009     inline bool valid() const { return field_id != 0; }
operator ==protozero::MessageTokenizer::Token45010     bool operator==(const Token& o) const {
45011       return field_id == o.field_id && type == o.type && value == o.value;
45012     }
45013   };
45014 
45015   // Pushes a byte in input and returns a token, only when getting to the last
45016   // byte of each field. Specifically:
45017   // - For varint and fixed32 fields, the Token is returned after the last byte
45018   //   of the numeric payload is pushed.
45019   // - For length-delimited fields, this returns after the last byte of the
45020   //   length is pushed (i.e. right before the payload starts). The caller is
45021   //   expected to either skip the next |value| bytes (in the case of a string
45022   //   or bytes fields) or keep calling Push, in the case of a submessage.
Push(uint8_t octet)45023   inline Token Push(uint8_t octet) {
45024     using protozero::proto_utils::ProtoWireType;
45025 
45026     // Parsing a fixed32/64 field is the only case where we don't have to do
45027     // any varint decoding. This is why this block is before the remaining
45028     // switch statement below (all the rest is a varint).
45029     if (PERFETTO_UNLIKELY(state_ == kFixedIntValue)) {
45030       PERFETTO_DCHECK(fixed_int_bits_ == 32 || fixed_int_bits_ == 64);
45031       fixed_int_value_ |= static_cast<uint64_t>(octet) << fixed_int_shift_;
45032       fixed_int_shift_ += 8;
45033       if (fixed_int_shift_ < fixed_int_bits_)
45034         return Token{};  // Intermediate byte of a fixed32/64.
45035       auto wire_type = fixed_int_bits_ == 32 ? ProtoWireType::kFixed32
45036                                              : ProtoWireType::kFixed64;
45037       uint64_t fixed_int_value = fixed_int_value_;
45038       fixed_int_value_ = fixed_int_shift_ = fixed_int_bits_ = 0;
45039       state_ = kFieldPreamble;
45040       return Token{field_id_, wire_type, fixed_int_value};
45041     }
45042 
45043     // At this point either we are: (i) parsing a field preamble; (ii) parsing a
45044     // varint field paylod; (iii) parsing the length of a length-delimited
45045     // field. In all cases, we need to decode a varint before proceeding.
45046     varint_ |= static_cast<uint64_t>(octet & 0x7F) << varint_shift_;
45047     if (octet & 0x80) {
45048       varint_shift_ += 7;
45049       if (PERFETTO_UNLIKELY(varint_shift_ >= 64)) {
45050         varint_shift_ = 0;
45051         state_ = kInvalidVarInt;
45052       }
45053       return Token{};  // Still parsing a varint.
45054     }
45055 
45056     uint64_t varint = varint_;
45057     varint_ = 0;
45058     varint_shift_ = 0;
45059 
45060     switch (state_) {
45061       case kFieldPreamble: {
45062         auto field_type = static_cast<uint32_t>(varint & 7u);  // 7 = 0..0111
45063         field_id_ = static_cast<uint32_t>(varint >> 3);
45064 
45065         // The field type is legit, now check it's well formed and within
45066         // boundaries.
45067         if (field_type == static_cast<uint32_t>(ProtoWireType::kVarInt)) {
45068           state_ = kVarIntValue;
45069         } else if (field_type ==
45070                        static_cast<uint32_t>(ProtoWireType::kFixed32) ||
45071                    field_type ==
45072                        static_cast<uint32_t>(ProtoWireType::kFixed64)) {
45073           state_ = kFixedIntValue;
45074           fixed_int_shift_ = 0;
45075           fixed_int_value_ = 0;
45076           fixed_int_bits_ =
45077               field_type == static_cast<uint32_t>(ProtoWireType::kFixed32) ? 32
45078                                                                            : 64;
45079         } else if (field_type ==
45080                    static_cast<uint32_t>(ProtoWireType::kLengthDelimited)) {
45081           state_ = kLenDelimited;
45082         } else {
45083           state_ = kInvalidFieldType;
45084         }
45085         return Token{};
45086       }
45087 
45088       case kVarIntValue: {
45089         // Return the varint field payload and go back to the next field.
45090         state_ = kFieldPreamble;
45091         return Token{field_id_, ProtoWireType::kVarInt, varint};
45092       }
45093 
45094       case kLenDelimited: {
45095         const auto payload_len = varint;
45096         if (payload_len > protozero::proto_utils::kMaxMessageLength) {
45097           state_ = kMessageTooBig;
45098           return Token{};
45099         }
45100         state_ = kFieldPreamble;
45101         // At this point the caller is expected to consume the next
45102         // |payload_len| bytes.
45103         return Token{field_id_, ProtoWireType::kLengthDelimited, payload_len};
45104       }
45105 
45106       case kFixedIntValue:
45107         // Unreacheable because of the if before the switch.
45108         PERFETTO_DCHECK(false);
45109         break;
45110 
45111       // Unrecoverable error states.
45112       case kInvalidFieldType:
45113       case kMessageTooBig:
45114       case kInvalidVarInt:
45115         break;
45116     }  // switch(state_)
45117 
45118     return Token{};  // Keep GCC happy.
45119   }
45120 
45121   // Returns true if the tokenizer FSM has reached quiescence (i.e. if we are
45122   // NOT in the middle of parsing a field).
idle() const45123   bool idle() const {
45124     return state_ == kFieldPreamble && varint_shift_ == 0 &&
45125            fixed_int_shift_ == 0;
45126   }
45127 
45128   // Only for reporting parser errors in the trace.
state() const45129   uint32_t state() const { return static_cast<uint32_t>(state_); }
45130 
45131  private:
45132   enum State {
45133     kFieldPreamble = 0,  // Parsing the varint for the field preamble.
45134     kVarIntValue = 1,    // Parsing the payload of a varint field.
45135     kFixedIntValue = 2,  // Parsing the payload of a fixed32/64 field.
45136     kLenDelimited = 3,   // Parsing the length of a length-delimited field.
45137 
45138     // Unrecoverable error states:
45139     kInvalidFieldType = 4,  // Encountered an invalid field type.
45140     kMessageTooBig = 5,     // Size of the length delimited message was too big.
45141     kInvalidVarInt = 6,     // Varint larger than 64 bits.
45142   };
45143 
45144   State state_ = kFieldPreamble;
45145   uint32_t field_id_ = 0;
45146   uint64_t varint_ = 0;
45147   uint32_t varint_shift_ = 0;
45148   uint32_t fixed_int_shift_ = 0;
45149   uint32_t fixed_int_bits_ = 0;
45150   uint64_t fixed_int_value_ = 0;
45151 };
45152 
45153 }  // namespace protozero
45154 
45155 #endif  // SRC_PROTOZERO_FILTERING_MESSAGE_TOKENIZER_H_
45156 /*
45157  * Copyright (C) 2021 The Android Open Source Project
45158  *
45159  * Licensed under the Apache License, Version 2.0 (the "License");
45160  * you may not use this file except in compliance with the License.
45161  * You may obtain a copy of the License at
45162  *
45163  *      http://www.apache.org/licenses/LICENSE-2.0
45164  *
45165  * Unless required by applicable law or agreed to in writing, software
45166  * distributed under the License is distributed on an "AS IS" BASIS,
45167  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
45168  * See the License for the specific language governing permissions and
45169  * limitations under the License.
45170  */
45171 
45172 #ifndef SRC_PROTOZERO_FILTERING_MESSAGE_FILTER_H_
45173 #define SRC_PROTOZERO_FILTERING_MESSAGE_FILTER_H_
45174 
45175 #include <stdint.h>
45176 
45177 #include <memory>
45178 #include <string>
45179 #include <unordered_map>
45180 
45181 // gen_amalgamated expanded: #include "src/protozero/filtering/filter_bytecode_parser.h"
45182 // gen_amalgamated expanded: #include "src/protozero/filtering/message_tokenizer.h"
45183 
45184 namespace protozero {
45185 
45186 // A class to filter binary-encoded proto messages using an allow-list of field
45187 // ids, also known as "filter bytecode". The filter determines which fields are
45188 // allowed to be passed through in output and strips all the other fields.
45189 // See go/trace-filtering for full design.
45190 // This class takes in input:
45191 // 1) The filter bytecode, loaded once via the LoadFilterBytecode() method.
45192 // 2) A proto-encoded binary message. The message doesn't have to be contiguous,
45193 //    it can be passed as an array of arbitrarily chunked fragments.
45194 // The FilterMessage*() method returns in output a proto message, stripping out
45195 // all unknown fields. If the input is malformed (e.g., unknown proto field wire
45196 // types, lengths out of bound) the whole filtering failed and the |error| flag
45197 // of the FilteredMessage object is set to true.
45198 // The filtering operation is based on rewriting a copy of the message into a
45199 // self-allocated buffer, which is then returned in the output. The input buffer
45200 // is NOT altered.
45201 // Note also that the process of rewriting the protos gets rid of most redundant
45202 // varint encoding (if present). So even if all fields are allow-listed, the
45203 // output might NOT be bitwise identical to the input (but it will be
45204 // semantically equivalent).
45205 // Furthermore the enable_field_usage_tracking() method allows to keep track of
45206 // a histogram of allowed / denied fields. It slows down filtering and is
45207 // intended only on host tools.
45208 class MessageFilter {
45209  public:
45210   MessageFilter();
45211   ~MessageFilter();
45212 
45213   struct InputSlice {
45214     const void* data;
45215     size_t len;
45216   };
45217 
45218   struct FilteredMessage {
FilteredMessageprotozero::MessageFilter::FilteredMessage45219     FilteredMessage(std::unique_ptr<uint8_t[]> d, size_t s)
45220         : data(std::move(d)), size(s) {}
45221     std::unique_ptr<uint8_t[]> data;
45222     size_t size;  // The used bytes in |data|. This is <= sizeof(data).
45223     bool error = false;
45224   };
45225 
45226   // Loads the filter bytecode that will be used to filter any subsequent
45227   // message. Must be called before the first call to FilterMessage*().
45228   // |filter_data| must point to a byte buffer for a proto-encoded ProtoFilter
45229   // message (see proto_filter.proto).
45230   bool LoadFilterBytecode(const void* filter_data, size_t len);
45231 
45232   // This affects the filter starting point of the subsequent FilterMessage*()
45233   // calls. By default the filtering process starts from the message @ index 0,
45234   // the root message passed to proto_filter when generating the bytecode
45235   // (in typical tracing use-cases, this is perfetto.protos.Trace). However, the
45236   // caller (TracingServiceImpl) might want to filter packets from the 2nd level
45237   // (perfetto.protos.TracePacket) because the root level is pre-pended after
45238   // the fact. This call allows to change the root message for the filter.
45239   // The argument |field_ids| is an array of proto field ids and determines the
45240   // path to the new root. For instance, in the case of [1,2,3] SetFilterRoot
45241   // will identify the sub-message for the field "root.1.2.3" and use that.
45242   // In order for this to succeed all the fields in the path must be allowed
45243   // in the filter and must be a nested message type.
45244   bool SetFilterRoot(const uint32_t* field_ids, size_t num_fields);
45245 
45246   // Takes an input message, fragmented in arbitrary slices, and returns a
45247   // filtered message in output.
45248   FilteredMessage FilterMessageFragments(const InputSlice*, size_t num_slices);
45249 
45250   // Helper for tests, where the input is a contiguous buffer.
FilterMessage(const void * data,size_t len)45251   FilteredMessage FilterMessage(const void* data, size_t len) {
45252     InputSlice slice{data, len};
45253     return FilterMessageFragments(&slice, 1);
45254   }
45255 
45256   // When enabled returns a map of "field path" to "usage counter".
45257   // The key (std::string) is a binary buffer (i.e. NOT an ASCII/UTF-8 string)
45258   // which contains a varint for each field. Consider the following:
45259   // message Root { Sub1 f1 = 1; };
45260   // message Sub1 { Sub2 f2 = 7;}
45261   // message Sub2 { string f3 = 5; }
45262   // The field .f1.f2.f3 will be encoded as \x01\0x07\x05.
45263   // The value is the number of times that field has been encountered. If the
45264   // field is not allow-listed in the bytecode (the field is stripped in output)
45265   // the count will be negative.
enable_field_usage_tracking(bool x)45266   void enable_field_usage_tracking(bool x) { track_field_usage_ = x; }
field_usage() const45267   const std::unordered_map<std::string, int32_t>& field_usage() const {
45268     return field_usage_;
45269   }
45270 
45271   // Exposed only for DCHECKS in TracingServiceImpl.
root_msg_index()45272   uint32_t root_msg_index() { return root_msg_index_; }
45273 
45274  private:
45275   // This is called by FilterMessageFragments().
45276   // Inlining allows the compiler turn the per-byte call/return into a for loop,
45277   // while, at the same time, keeping the code easy to read and reason about.
45278   // It gives a 20-25% speedup (265ms vs 215ms for a 25MB trace).
45279   void FilterOneByte(uint8_t octet) PERFETTO_ALWAYS_INLINE;
45280 
45281   // No-inline because this is a slowpath (only when usage tracking is enabled).
45282   void IncrementCurrentFieldUsage(uint32_t field_id,
45283                                   bool allowed) PERFETTO_NO_INLINE;
45284 
45285   // Gets into an error state which swallows all the input and emits no output.
45286   void SetUnrecoverableErrorState();
45287 
45288   // We keep track of the nest of messages in a stack. Each StackState
45289   // object corresponds to a level of nesting in the proto message structure.
45290   // Every time a new field of type len-delimited that has a corresponding
45291   // sub-message in the bytecode is encountered, a new StackState is pushed in
45292   // |stack_|. stack_[0] is a sentinel to prevent over-popping without adding
45293   // extra branches in the fastpath.
45294   // |stack_|. stack_[1] is the state of the root message.
45295   struct StackState {
45296     uint32_t in_bytes = 0;  // Number of input bytes processed.
45297 
45298     // When |in_bytes| reaches this value, the current state should be popped.
45299     // This is set when recursing into nested submessages. This is 0 only for
45300     // stack_[0] (we don't know the size of the root message upfront).
45301     uint32_t in_bytes_limit = 0;
45302 
45303     // This is set when a len-delimited message is encountered, either a string
45304     // or a nested submessage that is NOT allow-listed in the bytecode.
45305     // This causes input bytes to be consumed without being parsed from the
45306     // input stream. If |passthrough_eaten_bytes| == true, they will be copied
45307     // as-is in output (e.g. in the case of an allowed string/bytes field).
45308     uint32_t eat_next_bytes = 0;
45309 
45310     // Keeps tracks of the stream_writer output counter (out_.written()) then
45311     // the StackState is pushed. This is used to work out, when popping, how
45312     // many bytes have been written for the current submessage.
45313     uint32_t out_bytes_written_at_start = 0;
45314 
45315     uint32_t field_id = 0;   // The proto field id for the current message.
45316     uint32_t msg_index = 0;  // The index of the message filter in the bytecode.
45317 
45318     // This is a pointer to the proto preamble for the current submessage
45319     // (it's nullptr for stack_[0] and non-null elsewhere). This will be filled
45320     // with the actual size of the message (out_.written() -
45321     // |out_bytes_written_at_start|) when finishing (popping) the message.
45322     // This must be filled using WriteRedundantVarint(). Note that the
45323     // |size_field_len| is variable and depends on the actual length of the
45324     // input message. If the output message has roughly the same size of the
45325     // input message, the length will not be redundant.
45326     // In other words: the length of the field is reserved when the submessage
45327     // starts. At that point we know the upper-bound for the output message
45328     // (a filtered submessage can be <= the original one, but not >). So we
45329     // reserve as many bytes it takes to write the input length in varint.
45330     // Then, when the message is finalized and we know the actual output size
45331     // we backfill the field.
45332     // Consider the example of a submessage where the input size = 130 (>127,
45333     // 2 varint bytes) and the output is 120 bytes. The length will be 2 bytes
45334     // wide even though could have been encoded with just one byte.
45335     uint8_t* size_field = nullptr;
45336     uint32_t size_field_len = 0;
45337 
45338     // When true the next |eat_next_bytes| are copied as-is in output.
45339     // It seems that keeping this field at the end rather than next to
45340     // |eat_next_bytes| makes the filter a little (but measurably) faster.
45341     // (likely something related with struct layout vs cache sizes).
45342     bool passthrough_eaten_bytes = false;
45343   };
45344 
out_written()45345   uint32_t out_written() { return static_cast<uint32_t>(out_ - &out_buf_[0]); }
45346 
45347   std::unique_ptr<uint8_t[]> out_buf_;
45348   uint8_t* out_ = nullptr;
45349   uint8_t* out_end_ = nullptr;
45350   uint32_t root_msg_index_ = 0;
45351 
45352   FilterBytecodeParser filter_;
45353   MessageTokenizer tokenizer_;
45354   std::vector<StackState> stack_;
45355 
45356   bool error_ = false;
45357   bool track_field_usage_ = false;
45358   std::unordered_map<std::string, int32_t> field_usage_;
45359 };
45360 
45361 }  // namespace protozero
45362 
45363 #endif  // SRC_PROTOZERO_FILTERING_MESSAGE_FILTER_H_
45364 /*
45365  * Copyright (C) 2021 The Android Open Source Project
45366  *
45367  * Licensed under the Apache License, Version 2.0 (the "License");
45368  * you may not use this file except in compliance with the License.
45369  * You may obtain a copy of the License at
45370  *
45371  *      http://www.apache.org/licenses/LICENSE-2.0
45372  *
45373  * Unless required by applicable law or agreed to in writing, software
45374  * distributed under the License is distributed on an "AS IS" BASIS,
45375  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
45376  * See the License for the specific language governing permissions and
45377  * limitations under the License.
45378  */
45379 
45380 // gen_amalgamated expanded: #include "src/protozero/filtering/message_filter.h"
45381 
45382 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
45383 // gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
45384 
45385 namespace protozero {
45386 
45387 namespace {
45388 
45389 // Inline helpers to append proto fields in output. They are the equivalent of
45390 // the protozero::Message::AppendXXX() fields but don't require building and
45391 // maintaining a full protozero::Message object or dealing with scattered
45392 // output slices.
45393 // All these functions assume there is enough space in the output buffer, which
45394 // should be always the case assuming that we don't end up generating more
45395 // output than input.
45396 
AppendVarInt(uint32_t field_id,uint64_t value,uint8_t ** out)45397 inline void AppendVarInt(uint32_t field_id, uint64_t value, uint8_t** out) {
45398   *out = proto_utils::WriteVarInt(proto_utils::MakeTagVarInt(field_id), *out);
45399   *out = proto_utils::WriteVarInt(value, *out);
45400 }
45401 
45402 // For fixed32 / fixed64.
45403 template <typename INT_T /* uint32_t | uint64_t*/>
AppendFixed(uint32_t field_id,INT_T value,uint8_t ** out)45404 inline void AppendFixed(uint32_t field_id, INT_T value, uint8_t** out) {
45405   *out = proto_utils::WriteVarInt(proto_utils::MakeTagFixed<INT_T>(field_id),
45406                                   *out);
45407   memcpy(*out, &value, sizeof(value));
45408   *out += sizeof(value);
45409 }
45410 
45411 // For length-delimited (string, bytes) fields. Note: this function appends only
45412 // the proto preamble and the varint field that states the length of the payload
45413 // not the payload itself.
45414 // In the case of submessages, the caller needs to re-write the length at the
45415 // end in the in the returned memory area.
45416 // The problem here is that, because of filtering, the length of a submessage
45417 // might be < original length (the original length is still an upper-bound).
45418 // Returns a pair with: (1) the pointer where the final length should be written
45419 // into, (2) the length of the size field.
45420 // The caller must write a redundant varint to match the original size (i.e.
45421 // needs to use WriteRedundantVarInt()).
AppendLenDelim(uint32_t field_id,uint32_t len,uint8_t ** out)45422 inline std::pair<uint8_t*, uint32_t> AppendLenDelim(uint32_t field_id,
45423                                                     uint32_t len,
45424                                                     uint8_t** out) {
45425   *out = proto_utils::WriteVarInt(proto_utils::MakeTagLengthDelimited(field_id),
45426                                   *out);
45427   uint8_t* size_field_start = *out;
45428   *out = proto_utils::WriteVarInt(len, *out);
45429   const size_t size_field_len = static_cast<size_t>(*out - size_field_start);
45430   return std::make_pair(size_field_start, size_field_len);
45431 }
45432 }  // namespace
45433 
MessageFilter()45434 MessageFilter::MessageFilter() {
45435   // Push a state on the stack for the implicit root message.
45436   stack_.emplace_back();
45437 }
45438 
45439 MessageFilter::~MessageFilter() = default;
45440 
LoadFilterBytecode(const void * filter_data,size_t len)45441 bool MessageFilter::LoadFilterBytecode(const void* filter_data, size_t len) {
45442   return filter_.Load(filter_data, len);
45443 }
45444 
SetFilterRoot(const uint32_t * field_ids,size_t num_fields)45445 bool MessageFilter::SetFilterRoot(const uint32_t* field_ids,
45446                                   size_t num_fields) {
45447   uint32_t root_msg_idx = 0;
45448   for (const uint32_t* it = field_ids; it < field_ids + num_fields; ++it) {
45449     uint32_t field_id = *it;
45450     auto res = filter_.Query(root_msg_idx, field_id);
45451     if (!res.allowed || res.simple_field())
45452       return false;
45453     root_msg_idx = res.nested_msg_index;
45454   }
45455   root_msg_index_ = root_msg_idx;
45456   return true;
45457 }
45458 
FilterMessageFragments(const InputSlice * slices,size_t num_slices)45459 MessageFilter::FilteredMessage MessageFilter::FilterMessageFragments(
45460     const InputSlice* slices,
45461     size_t num_slices) {
45462   // First compute the upper bound for the output. The filtered message cannot
45463   // be > the original message.
45464   uint32_t total_len = 0;
45465   for (size_t i = 0; i < num_slices; ++i)
45466     total_len += slices[i].len;
45467   out_buf_.reset(new uint8_t[total_len]);
45468   out_ = out_buf_.get();
45469   out_end_ = out_ + total_len;
45470 
45471   // Reset the parser state.
45472   tokenizer_ = MessageTokenizer();
45473   error_ = false;
45474   stack_.clear();
45475   stack_.resize(2);
45476   // stack_[0] is a sentinel and should never be hit in nominal cases. If we
45477   // end up there we will just keep consuming the input stream and detecting
45478   // at the end, without hurting the fastpath.
45479   stack_[0].in_bytes_limit = UINT32_MAX;
45480   stack_[0].eat_next_bytes = UINT32_MAX;
45481   // stack_[1] is the actual root message.
45482   stack_[1].in_bytes_limit = total_len;
45483   stack_[1].msg_index = root_msg_index_;
45484 
45485   // Process the input data and write the output.
45486   for (size_t slice_idx = 0; slice_idx < num_slices; ++slice_idx) {
45487     const InputSlice& slice = slices[slice_idx];
45488     const uint8_t* data = static_cast<const uint8_t*>(slice.data);
45489     for (size_t i = 0; i < slice.len; ++i)
45490       FilterOneByte(data[i]);
45491   }
45492 
45493   // Construct the output object.
45494   PERFETTO_CHECK(out_ >= out_buf_.get() && out_ <= out_end_);
45495   auto used_size = static_cast<size_t>(out_ - out_buf_.get());
45496   FilteredMessage res{std::move(out_buf_), used_size};
45497   res.error = error_;
45498   if (stack_.size() != 1 || !tokenizer_.idle() ||
45499       stack_[0].in_bytes != total_len) {
45500     res.error = true;
45501   }
45502   return res;
45503 }
45504 
FilterOneByte(uint8_t octet)45505 void MessageFilter::FilterOneByte(uint8_t octet) {
45506   PERFETTO_DCHECK(!stack_.empty());
45507 
45508   auto* state = &stack_.back();
45509   StackState next_state{};
45510   bool push_next_state = false;
45511 
45512   if (state->eat_next_bytes > 0) {
45513     // This is the case where the previous tokenizer_.Push() call returned a
45514     // length delimited message which is NOT a submessage (a string or a bytes
45515     // field). We just want to consume it, and pass it through in output
45516     // if the field was allowed.
45517     --state->eat_next_bytes;
45518     if (state->passthrough_eaten_bytes)
45519       *(out_++) = octet;
45520   } else {
45521     MessageTokenizer::Token token = tokenizer_.Push(octet);
45522     // |token| will not be valid() in most cases and this is WAI. When pushing
45523     // a varint field, only the last byte yields a token, all the other bytes
45524     // return an invalid token, they just update the internal tokenizer state.
45525     if (token.valid()) {
45526       auto filter = filter_.Query(state->msg_index, token.field_id);
45527       switch (token.type) {
45528         case proto_utils::ProtoWireType::kVarInt:
45529           if (filter.allowed && filter.simple_field())
45530             AppendVarInt(token.field_id, token.value, &out_);
45531           break;
45532         case proto_utils::ProtoWireType::kFixed32:
45533           if (filter.allowed && filter.simple_field())
45534             AppendFixed(token.field_id, static_cast<uint32_t>(token.value),
45535                         &out_);
45536           break;
45537         case proto_utils::ProtoWireType::kFixed64:
45538           if (filter.allowed && filter.simple_field())
45539             AppendFixed(token.field_id, static_cast<uint64_t>(token.value),
45540                         &out_);
45541           break;
45542         case proto_utils::ProtoWireType::kLengthDelimited:
45543           // Here we have two cases:
45544           // A. A simple string/bytes field: we just want to consume the next
45545           //    bytes (the string payload), optionally passing them through in
45546           //    output if the field is allowed.
45547           // B. This is a nested submessage. In this case we want to recurse and
45548           //    push a new state on the stack.
45549           // Note that we can't tell the difference between a
45550           // "non-allowed string" and a "non-allowed submessage". But it doesn't
45551           // matter because in both cases we just want to skip the next N bytes.
45552           const auto submessage_len = static_cast<uint32_t>(token.value);
45553           auto in_bytes_left = state->in_bytes_limit - state->in_bytes - 1;
45554           if (PERFETTO_UNLIKELY(submessage_len > in_bytes_left)) {
45555             // This is a malicious / malformed string/bytes/submessage that
45556             // claims to be larger than the outer message that contains it.
45557             return SetUnrecoverableErrorState();
45558           }
45559 
45560           if (filter.allowed && !filter.simple_field() && submessage_len > 0) {
45561             // submessage_len == 0 is the edge case of a message with a 0-len
45562             // (but present) submessage. In this case, if allowed, we don't want
45563             // to push any further state (doing so would desync the FSM) but we
45564             // still want to emit it.
45565             // At this point |submessage_len| is only an upper bound. The
45566             // final message written in output can be <= the one in input,
45567             // only some of its fields might be allowed (also remember that
45568             // this class implicitly removes redundancy varint encoding of
45569             // len-delimited field lengths). The final length varint (the
45570             // return value of AppendLenDelim()) will be filled when popping
45571             // from |stack_|.
45572             auto size_field =
45573                 AppendLenDelim(token.field_id, submessage_len, &out_);
45574             push_next_state = true;
45575             next_state.field_id = token.field_id;
45576             next_state.msg_index = filter.nested_msg_index;
45577             next_state.in_bytes_limit = submessage_len;
45578             next_state.size_field = size_field.first;
45579             next_state.size_field_len = size_field.second;
45580             next_state.out_bytes_written_at_start = out_written();
45581           } else {
45582             // A string or bytes field, or a 0 length submessage.
45583             state->eat_next_bytes = submessage_len;
45584             state->passthrough_eaten_bytes = filter.allowed;
45585             if (filter.allowed)
45586               AppendLenDelim(token.field_id, submessage_len, &out_);
45587           }
45588           break;
45589       }  // switch(type)
45590 
45591       if (PERFETTO_UNLIKELY(track_field_usage_)) {
45592         IncrementCurrentFieldUsage(token.field_id, filter.allowed);
45593       }
45594     }  // if (token.valid)
45595   }    // if (eat_next_bytes == 0)
45596 
45597   ++state->in_bytes;
45598   while (state->in_bytes >= state->in_bytes_limit) {
45599     PERFETTO_DCHECK(state->in_bytes == state->in_bytes_limit);
45600     push_next_state = false;
45601 
45602     // We can't possibly write more than we read.
45603     const uint32_t msg_bytes_written = static_cast<uint32_t>(
45604         out_written() - state->out_bytes_written_at_start);
45605     PERFETTO_DCHECK(msg_bytes_written <= state->in_bytes_limit);
45606 
45607     // Backfill the length field of the
45608     proto_utils::WriteRedundantVarInt(msg_bytes_written, state->size_field,
45609                                       state->size_field_len);
45610 
45611     const uint32_t in_bytes_processes_for_last_msg = state->in_bytes;
45612     stack_.pop_back();
45613     PERFETTO_CHECK(!stack_.empty());
45614     state = &stack_.back();
45615     state->in_bytes += in_bytes_processes_for_last_msg;
45616     if (PERFETTO_UNLIKELY(!tokenizer_.idle())) {
45617       // If we hit this case, it means that we got to the end of a submessage
45618       // while decoding a field. We can't recover from this and we don't want to
45619       // propagate a broken sub-message.
45620       return SetUnrecoverableErrorState();
45621     }
45622   }
45623 
45624   if (push_next_state) {
45625     PERFETTO_DCHECK(tokenizer_.idle());
45626     stack_.emplace_back(std::move(next_state));
45627     state = &stack_.back();
45628   }
45629 }
45630 
SetUnrecoverableErrorState()45631 void MessageFilter::SetUnrecoverableErrorState() {
45632   error_ = true;
45633   stack_.clear();
45634   stack_.resize(1);
45635   auto& state = stack_[0];
45636   state.eat_next_bytes = UINT32_MAX;
45637   state.in_bytes_limit = UINT32_MAX;
45638   state.passthrough_eaten_bytes = false;
45639   out_ = out_buf_.get();  // Reset the write pointer.
45640 }
45641 
IncrementCurrentFieldUsage(uint32_t field_id,bool allowed)45642 void MessageFilter::IncrementCurrentFieldUsage(uint32_t field_id,
45643                                                bool allowed) {
45644   // Slowpath. Used mainly in offline tools and tests to workout used fields in
45645   // a proto.
45646   PERFETTO_DCHECK(track_field_usage_);
45647 
45648   // Field path contains a concatenation of varints, one for each nesting level.
45649   // e.g. y in message Root { Sub x = 2; }; message Sub { SubSub y = 7; }
45650   // is encoded as [varint(2) + varint(7)].
45651   // We use varint to take the most out of SSO (small string opt). In most cases
45652   // the path will fit in the on-stack 22 bytes, requiring no heap.
45653   std::string field_path;
45654 
45655   auto append_field_id = [&field_path](uint32_t id) {
45656     uint8_t buf[10];
45657     uint8_t* end = proto_utils::WriteVarInt(id, buf);
45658     field_path.append(reinterpret_cast<char*>(buf),
45659                       static_cast<size_t>(end - buf));
45660   };
45661 
45662   // Append all the ancestors IDs from the state stack.
45663   // The first entry of the stack has always ID 0 and we skip it (we don't know
45664   // the ID of the root message itself).
45665   PERFETTO_DCHECK(stack_.size() >= 2 && stack_[1].field_id == 0);
45666   for (size_t i = 2; i < stack_.size(); ++i)
45667     append_field_id(stack_[i].field_id);
45668   // Append the id of the field in the current message.
45669   append_field_id(field_id);
45670   field_usage_[field_path] += allowed ? 1 : -1;
45671 }
45672 
45673 }  // namespace protozero
45674 // gen_amalgamated begin source: src/tracing/core/metatrace_writer.cc
45675 // gen_amalgamated begin header: src/tracing/core/metatrace_writer.h
45676 /*
45677  * Copyright (C) 2019 The Android Open Source Project
45678  *
45679  * Licensed under the Apache License, Version 2.0 (the "License");
45680  * you may not use this file except in compliance with the License.
45681  * You may obtain a copy of the License at
45682  *
45683  *      http://www.apache.org/licenses/LICENSE-2.0
45684  *
45685  * Unless required by applicable law or agreed to in writing, software
45686  * distributed under the License is distributed on an "AS IS" BASIS,
45687  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
45688  * See the License for the specific language governing permissions and
45689  * limitations under the License.
45690  */
45691 
45692 #ifndef SRC_TRACING_CORE_METATRACE_WRITER_H_
45693 #define SRC_TRACING_CORE_METATRACE_WRITER_H_
45694 
45695 #include <functional>
45696 #include <memory>
45697 
45698 // gen_amalgamated expanded: #include "perfetto/ext/base/metatrace.h"
45699 // gen_amalgamated expanded: #include "perfetto/ext/base/thread_checker.h"
45700 // gen_amalgamated expanded: #include "perfetto/ext/base/weak_ptr.h"
45701 
45702 namespace perfetto {
45703 
45704 namespace base {
45705 class TaskRunner;
45706 }
45707 
45708 class TraceWriter;
45709 
45710 // Complements the base::metatrace infrastructure.
45711 // It hooks a callback to metatrace::Enable() and writes metatrace events into
45712 // a TraceWriter whenever the metatrace ring buffer is half full.
45713 // It is safe to create and attempt to start multiple instances of this class,
45714 // however only the first one will succeed because the metatrace framework
45715 // doesn't support multiple instances.
45716 // This class is defined here (instead of directly in src/probes/) so it can
45717 // be reused by other components (e.g. heapprofd).
45718 class MetatraceWriter {
45719  public:
45720   static constexpr char kDataSourceName[] = "perfetto.metatrace";
45721 
45722   MetatraceWriter();
45723   ~MetatraceWriter();
45724 
45725   MetatraceWriter(const MetatraceWriter&) = delete;
45726   MetatraceWriter& operator=(const MetatraceWriter&) = delete;
45727   MetatraceWriter(MetatraceWriter&&) = delete;
45728   MetatraceWriter& operator=(MetatraceWriter&&) = delete;
45729 
45730   void Enable(base::TaskRunner*, std::unique_ptr<TraceWriter>, uint32_t tags);
45731   void Disable();
45732   void WriteAllAndFlushTraceWriter(std::function<void()> callback);
45733 
45734  private:
45735   void WriteAllAvailableEvents();
45736 
45737   bool started_ = false;
45738   base::TaskRunner* task_runner_ = nullptr;
45739   std::unique_ptr<TraceWriter> trace_writer_;
45740   PERFETTO_THREAD_CHECKER(thread_checker_)
45741   base::WeakPtrFactory<MetatraceWriter> weak_ptr_factory_;  // Keep last.
45742 };
45743 
45744 }  // namespace perfetto
45745 
45746 #endif  // SRC_TRACING_CORE_METATRACE_WRITER_H_
45747 // gen_amalgamated begin header: gen/protos/perfetto/trace/perfetto/perfetto_metatrace.pbzero.h
45748 // Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
45749 
45750 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_PERFETTO_PERFETTO_METATRACE_PROTO_H_
45751 #define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_PERFETTO_PERFETTO_METATRACE_PROTO_H_
45752 
45753 #include <stddef.h>
45754 #include <stdint.h>
45755 
45756 // gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
45757 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
45758 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
45759 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
45760 // gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
45761 
45762 namespace perfetto {
45763 namespace protos {
45764 namespace pbzero {
45765 
45766 class PerfettoMetatrace_Arg;
45767 
45768 class PerfettoMetatrace_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/9, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
45769  public:
PerfettoMetatrace_Decoder(const uint8_t * data,size_t len)45770   PerfettoMetatrace_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
PerfettoMetatrace_Decoder(const std::string & raw)45771   explicit PerfettoMetatrace_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
PerfettoMetatrace_Decoder(const::protozero::ConstBytes & raw)45772   explicit PerfettoMetatrace_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
has_event_id() const45773   bool has_event_id() const { return at<1>().valid(); }
event_id() const45774   uint32_t event_id() const { return at<1>().as_uint32(); }
has_counter_id() const45775   bool has_counter_id() const { return at<2>().valid(); }
counter_id() const45776   uint32_t counter_id() const { return at<2>().as_uint32(); }
has_event_name() const45777   bool has_event_name() const { return at<8>().valid(); }
event_name() const45778   ::protozero::ConstChars event_name() const { return at<8>().as_string(); }
has_counter_name() const45779   bool has_counter_name() const { return at<9>().valid(); }
counter_name() const45780   ::protozero::ConstChars counter_name() const { return at<9>().as_string(); }
has_event_duration_ns() const45781   bool has_event_duration_ns() const { return at<3>().valid(); }
event_duration_ns() const45782   uint64_t event_duration_ns() const { return at<3>().as_uint64(); }
has_counter_value() const45783   bool has_counter_value() const { return at<4>().valid(); }
counter_value() const45784   int32_t counter_value() const { return at<4>().as_int32(); }
has_thread_id() const45785   bool has_thread_id() const { return at<5>().valid(); }
thread_id() const45786   uint32_t thread_id() const { return at<5>().as_uint32(); }
has_has_overruns() const45787   bool has_has_overruns() const { return at<6>().valid(); }
has_overruns() const45788   bool has_overruns() const { return at<6>().as_bool(); }
has_args() const45789   bool has_args() const { return at<7>().valid(); }
args() const45790   ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> args() const { return GetRepeated<::protozero::ConstBytes>(7); }
45791 };
45792 
45793 class PerfettoMetatrace : public ::protozero::Message {
45794  public:
45795   using Decoder = PerfettoMetatrace_Decoder;
45796   enum : int32_t {
45797     kEventIdFieldNumber = 1,
45798     kCounterIdFieldNumber = 2,
45799     kEventNameFieldNumber = 8,
45800     kCounterNameFieldNumber = 9,
45801     kEventDurationNsFieldNumber = 3,
45802     kCounterValueFieldNumber = 4,
45803     kThreadIdFieldNumber = 5,
45804     kHasOverrunsFieldNumber = 6,
45805     kArgsFieldNumber = 7,
45806   };
45807   using Arg = ::perfetto::protos::pbzero::PerfettoMetatrace_Arg;
45808 
45809   using FieldMetadata_EventId =
45810     ::protozero::proto_utils::FieldMetadata<
45811       1,
45812       ::protozero::proto_utils::RepetitionType::kNotRepeated,
45813       ::protozero::proto_utils::ProtoSchemaType::kUint32,
45814       uint32_t,
45815       PerfettoMetatrace>;
45816 
45817   // Ceci n'est pas une pipe.
45818   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
45819   // type (and users are expected to use it as such, hence kCamelCase name).
45820   // It is declared as a function to keep protozero bindings header-only as
45821   // inline constexpr variables are not available until C++17 (while inline
45822   // functions are).
45823   // TODO(altimin): Use inline variable instead after adopting C++17.
kEventId()45824   static constexpr FieldMetadata_EventId kEventId() { return {}; }
set_event_id(uint32_t value)45825   void set_event_id(uint32_t value) {
45826     static constexpr uint32_t field_id = FieldMetadata_EventId::kFieldId;
45827     // Call the appropriate protozero::Message::Append(field_id, ...)
45828     // method based on the type of the field.
45829     ::protozero::internal::FieldWriter<
45830       ::protozero::proto_utils::ProtoSchemaType::kUint32>
45831         ::Append(*this, field_id, value);
45832   }
45833 
45834   using FieldMetadata_CounterId =
45835     ::protozero::proto_utils::FieldMetadata<
45836       2,
45837       ::protozero::proto_utils::RepetitionType::kNotRepeated,
45838       ::protozero::proto_utils::ProtoSchemaType::kUint32,
45839       uint32_t,
45840       PerfettoMetatrace>;
45841 
45842   // Ceci n'est pas une pipe.
45843   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
45844   // type (and users are expected to use it as such, hence kCamelCase name).
45845   // It is declared as a function to keep protozero bindings header-only as
45846   // inline constexpr variables are not available until C++17 (while inline
45847   // functions are).
45848   // TODO(altimin): Use inline variable instead after adopting C++17.
kCounterId()45849   static constexpr FieldMetadata_CounterId kCounterId() { return {}; }
set_counter_id(uint32_t value)45850   void set_counter_id(uint32_t value) {
45851     static constexpr uint32_t field_id = FieldMetadata_CounterId::kFieldId;
45852     // Call the appropriate protozero::Message::Append(field_id, ...)
45853     // method based on the type of the field.
45854     ::protozero::internal::FieldWriter<
45855       ::protozero::proto_utils::ProtoSchemaType::kUint32>
45856         ::Append(*this, field_id, value);
45857   }
45858 
45859   using FieldMetadata_EventName =
45860     ::protozero::proto_utils::FieldMetadata<
45861       8,
45862       ::protozero::proto_utils::RepetitionType::kNotRepeated,
45863       ::protozero::proto_utils::ProtoSchemaType::kString,
45864       std::string,
45865       PerfettoMetatrace>;
45866 
45867   // Ceci n'est pas une pipe.
45868   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
45869   // type (and users are expected to use it as such, hence kCamelCase name).
45870   // It is declared as a function to keep protozero bindings header-only as
45871   // inline constexpr variables are not available until C++17 (while inline
45872   // functions are).
45873   // TODO(altimin): Use inline variable instead after adopting C++17.
kEventName()45874   static constexpr FieldMetadata_EventName kEventName() { return {}; }
set_event_name(const char * data,size_t size)45875   void set_event_name(const char* data, size_t size) {
45876     AppendBytes(FieldMetadata_EventName::kFieldId, data, size);
45877   }
set_event_name(std::string value)45878   void set_event_name(std::string value) {
45879     static constexpr uint32_t field_id = FieldMetadata_EventName::kFieldId;
45880     // Call the appropriate protozero::Message::Append(field_id, ...)
45881     // method based on the type of the field.
45882     ::protozero::internal::FieldWriter<
45883       ::protozero::proto_utils::ProtoSchemaType::kString>
45884         ::Append(*this, field_id, value);
45885   }
45886 
45887   using FieldMetadata_CounterName =
45888     ::protozero::proto_utils::FieldMetadata<
45889       9,
45890       ::protozero::proto_utils::RepetitionType::kNotRepeated,
45891       ::protozero::proto_utils::ProtoSchemaType::kString,
45892       std::string,
45893       PerfettoMetatrace>;
45894 
45895   // Ceci n'est pas une pipe.
45896   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
45897   // type (and users are expected to use it as such, hence kCamelCase name).
45898   // It is declared as a function to keep protozero bindings header-only as
45899   // inline constexpr variables are not available until C++17 (while inline
45900   // functions are).
45901   // TODO(altimin): Use inline variable instead after adopting C++17.
kCounterName()45902   static constexpr FieldMetadata_CounterName kCounterName() { return {}; }
set_counter_name(const char * data,size_t size)45903   void set_counter_name(const char* data, size_t size) {
45904     AppendBytes(FieldMetadata_CounterName::kFieldId, data, size);
45905   }
set_counter_name(std::string value)45906   void set_counter_name(std::string value) {
45907     static constexpr uint32_t field_id = FieldMetadata_CounterName::kFieldId;
45908     // Call the appropriate protozero::Message::Append(field_id, ...)
45909     // method based on the type of the field.
45910     ::protozero::internal::FieldWriter<
45911       ::protozero::proto_utils::ProtoSchemaType::kString>
45912         ::Append(*this, field_id, value);
45913   }
45914 
45915   using FieldMetadata_EventDurationNs =
45916     ::protozero::proto_utils::FieldMetadata<
45917       3,
45918       ::protozero::proto_utils::RepetitionType::kNotRepeated,
45919       ::protozero::proto_utils::ProtoSchemaType::kUint64,
45920       uint64_t,
45921       PerfettoMetatrace>;
45922 
45923   // Ceci n'est pas une pipe.
45924   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
45925   // type (and users are expected to use it as such, hence kCamelCase name).
45926   // It is declared as a function to keep protozero bindings header-only as
45927   // inline constexpr variables are not available until C++17 (while inline
45928   // functions are).
45929   // TODO(altimin): Use inline variable instead after adopting C++17.
kEventDurationNs()45930   static constexpr FieldMetadata_EventDurationNs kEventDurationNs() { return {}; }
set_event_duration_ns(uint64_t value)45931   void set_event_duration_ns(uint64_t value) {
45932     static constexpr uint32_t field_id = FieldMetadata_EventDurationNs::kFieldId;
45933     // Call the appropriate protozero::Message::Append(field_id, ...)
45934     // method based on the type of the field.
45935     ::protozero::internal::FieldWriter<
45936       ::protozero::proto_utils::ProtoSchemaType::kUint64>
45937         ::Append(*this, field_id, value);
45938   }
45939 
45940   using FieldMetadata_CounterValue =
45941     ::protozero::proto_utils::FieldMetadata<
45942       4,
45943       ::protozero::proto_utils::RepetitionType::kNotRepeated,
45944       ::protozero::proto_utils::ProtoSchemaType::kInt32,
45945       int32_t,
45946       PerfettoMetatrace>;
45947 
45948   // Ceci n'est pas une pipe.
45949   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
45950   // type (and users are expected to use it as such, hence kCamelCase name).
45951   // It is declared as a function to keep protozero bindings header-only as
45952   // inline constexpr variables are not available until C++17 (while inline
45953   // functions are).
45954   // TODO(altimin): Use inline variable instead after adopting C++17.
kCounterValue()45955   static constexpr FieldMetadata_CounterValue kCounterValue() { return {}; }
set_counter_value(int32_t value)45956   void set_counter_value(int32_t value) {
45957     static constexpr uint32_t field_id = FieldMetadata_CounterValue::kFieldId;
45958     // Call the appropriate protozero::Message::Append(field_id, ...)
45959     // method based on the type of the field.
45960     ::protozero::internal::FieldWriter<
45961       ::protozero::proto_utils::ProtoSchemaType::kInt32>
45962         ::Append(*this, field_id, value);
45963   }
45964 
45965   using FieldMetadata_ThreadId =
45966     ::protozero::proto_utils::FieldMetadata<
45967       5,
45968       ::protozero::proto_utils::RepetitionType::kNotRepeated,
45969       ::protozero::proto_utils::ProtoSchemaType::kUint32,
45970       uint32_t,
45971       PerfettoMetatrace>;
45972 
45973   // Ceci n'est pas une pipe.
45974   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
45975   // type (and users are expected to use it as such, hence kCamelCase name).
45976   // It is declared as a function to keep protozero bindings header-only as
45977   // inline constexpr variables are not available until C++17 (while inline
45978   // functions are).
45979   // TODO(altimin): Use inline variable instead after adopting C++17.
kThreadId()45980   static constexpr FieldMetadata_ThreadId kThreadId() { return {}; }
set_thread_id(uint32_t value)45981   void set_thread_id(uint32_t value) {
45982     static constexpr uint32_t field_id = FieldMetadata_ThreadId::kFieldId;
45983     // Call the appropriate protozero::Message::Append(field_id, ...)
45984     // method based on the type of the field.
45985     ::protozero::internal::FieldWriter<
45986       ::protozero::proto_utils::ProtoSchemaType::kUint32>
45987         ::Append(*this, field_id, value);
45988   }
45989 
45990   using FieldMetadata_HasOverruns =
45991     ::protozero::proto_utils::FieldMetadata<
45992       6,
45993       ::protozero::proto_utils::RepetitionType::kNotRepeated,
45994       ::protozero::proto_utils::ProtoSchemaType::kBool,
45995       bool,
45996       PerfettoMetatrace>;
45997 
45998   // Ceci n'est pas une pipe.
45999   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
46000   // type (and users are expected to use it as such, hence kCamelCase name).
46001   // It is declared as a function to keep protozero bindings header-only as
46002   // inline constexpr variables are not available until C++17 (while inline
46003   // functions are).
46004   // TODO(altimin): Use inline variable instead after adopting C++17.
kHasOverruns()46005   static constexpr FieldMetadata_HasOverruns kHasOverruns() { return {}; }
set_has_overruns(bool value)46006   void set_has_overruns(bool value) {
46007     static constexpr uint32_t field_id = FieldMetadata_HasOverruns::kFieldId;
46008     // Call the appropriate protozero::Message::Append(field_id, ...)
46009     // method based on the type of the field.
46010     ::protozero::internal::FieldWriter<
46011       ::protozero::proto_utils::ProtoSchemaType::kBool>
46012         ::Append(*this, field_id, value);
46013   }
46014 
46015   using FieldMetadata_Args =
46016     ::protozero::proto_utils::FieldMetadata<
46017       7,
46018       ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
46019       ::protozero::proto_utils::ProtoSchemaType::kMessage,
46020       PerfettoMetatrace_Arg,
46021       PerfettoMetatrace>;
46022 
46023   // Ceci n'est pas une pipe.
46024   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
46025   // type (and users are expected to use it as such, hence kCamelCase name).
46026   // It is declared as a function to keep protozero bindings header-only as
46027   // inline constexpr variables are not available until C++17 (while inline
46028   // functions are).
46029   // TODO(altimin): Use inline variable instead after adopting C++17.
kArgs()46030   static constexpr FieldMetadata_Args kArgs() { return {}; }
add_args()46031   template <typename T = PerfettoMetatrace_Arg> T* add_args() {
46032     return BeginNestedMessage<T>(7);
46033   }
46034 
46035 };
46036 
46037 class PerfettoMetatrace_Arg_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
46038  public:
PerfettoMetatrace_Arg_Decoder(const uint8_t * data,size_t len)46039   PerfettoMetatrace_Arg_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
PerfettoMetatrace_Arg_Decoder(const std::string & raw)46040   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)46041   explicit PerfettoMetatrace_Arg_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
has_key() const46042   bool has_key() const { return at<1>().valid(); }
key() const46043   ::protozero::ConstChars key() const { return at<1>().as_string(); }
has_value() const46044   bool has_value() const { return at<2>().valid(); }
value() const46045   ::protozero::ConstChars value() const { return at<2>().as_string(); }
46046 };
46047 
46048 class PerfettoMetatrace_Arg : public ::protozero::Message {
46049  public:
46050   using Decoder = PerfettoMetatrace_Arg_Decoder;
46051   enum : int32_t {
46052     kKeyFieldNumber = 1,
46053     kValueFieldNumber = 2,
46054   };
46055 
46056   using FieldMetadata_Key =
46057     ::protozero::proto_utils::FieldMetadata<
46058       1,
46059       ::protozero::proto_utils::RepetitionType::kNotRepeated,
46060       ::protozero::proto_utils::ProtoSchemaType::kString,
46061       std::string,
46062       PerfettoMetatrace_Arg>;
46063 
46064   // Ceci n'est pas une pipe.
46065   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
46066   // type (and users are expected to use it as such, hence kCamelCase name).
46067   // It is declared as a function to keep protozero bindings header-only as
46068   // inline constexpr variables are not available until C++17 (while inline
46069   // functions are).
46070   // TODO(altimin): Use inline variable instead after adopting C++17.
kKey()46071   static constexpr FieldMetadata_Key kKey() { return {}; }
set_key(const char * data,size_t size)46072   void set_key(const char* data, size_t size) {
46073     AppendBytes(FieldMetadata_Key::kFieldId, data, size);
46074   }
set_key(std::string value)46075   void set_key(std::string value) {
46076     static constexpr uint32_t field_id = FieldMetadata_Key::kFieldId;
46077     // Call the appropriate protozero::Message::Append(field_id, ...)
46078     // method based on the type of the field.
46079     ::protozero::internal::FieldWriter<
46080       ::protozero::proto_utils::ProtoSchemaType::kString>
46081         ::Append(*this, field_id, value);
46082   }
46083 
46084   using FieldMetadata_Value =
46085     ::protozero::proto_utils::FieldMetadata<
46086       2,
46087       ::protozero::proto_utils::RepetitionType::kNotRepeated,
46088       ::protozero::proto_utils::ProtoSchemaType::kString,
46089       std::string,
46090       PerfettoMetatrace_Arg>;
46091 
46092   // Ceci n'est pas une pipe.
46093   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
46094   // type (and users are expected to use it as such, hence kCamelCase name).
46095   // It is declared as a function to keep protozero bindings header-only as
46096   // inline constexpr variables are not available until C++17 (while inline
46097   // functions are).
46098   // TODO(altimin): Use inline variable instead after adopting C++17.
kValue()46099   static constexpr FieldMetadata_Value kValue() { return {}; }
set_value(const char * data,size_t size)46100   void set_value(const char* data, size_t size) {
46101     AppendBytes(FieldMetadata_Value::kFieldId, data, size);
46102   }
set_value(std::string value)46103   void set_value(std::string value) {
46104     static constexpr uint32_t field_id = FieldMetadata_Value::kFieldId;
46105     // Call the appropriate protozero::Message::Append(field_id, ...)
46106     // method based on the type of the field.
46107     ::protozero::internal::FieldWriter<
46108       ::protozero::proto_utils::ProtoSchemaType::kString>
46109         ::Append(*this, field_id, value);
46110   }
46111 };
46112 
46113 } // Namespace.
46114 } // Namespace.
46115 } // Namespace.
46116 #endif  // Include guard.
46117 /*
46118  * Copyright (C) 2019 The Android Open Source Project
46119  *
46120  * Licensed under the Apache License, Version 2.0 (the "License");
46121  * you may not use this file except in compliance with the License.
46122  * You may obtain a copy of the License at
46123  *
46124  *      http://www.apache.org/licenses/LICENSE-2.0
46125  *
46126  * Unless required by applicable law or agreed to in writing, software
46127  * distributed under the License is distributed on an "AS IS" BASIS,
46128  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
46129  * See the License for the specific language governing permissions and
46130  * limitations under the License.
46131  */
46132 
46133 // gen_amalgamated expanded: #include "src/tracing/core/metatrace_writer.h"
46134 
46135 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
46136 // gen_amalgamated expanded: #include "perfetto/base/task_runner.h"
46137 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/trace_writer.h"
46138 // gen_amalgamated expanded: #include "perfetto/tracing/core/data_source_descriptor.h"
46139 
46140 // gen_amalgamated expanded: #include "protos/perfetto/trace/perfetto/perfetto_metatrace.pbzero.h"
46141 // gen_amalgamated expanded: #include "protos/perfetto/trace/trace_packet.pbzero.h"
46142 
46143 namespace perfetto {
46144 
46145 // static
46146 constexpr char MetatraceWriter::kDataSourceName[];
46147 
MetatraceWriter()46148 MetatraceWriter::MetatraceWriter() : weak_ptr_factory_(this) {}
46149 
~MetatraceWriter()46150 MetatraceWriter::~MetatraceWriter() {
46151   Disable();
46152 }
46153 
Enable(base::TaskRunner * task_runner,std::unique_ptr<TraceWriter> trace_writer,uint32_t tags)46154 void MetatraceWriter::Enable(base::TaskRunner* task_runner,
46155                              std::unique_ptr<TraceWriter> trace_writer,
46156                              uint32_t tags) {
46157   PERFETTO_DCHECK_THREAD(thread_checker_);
46158   if (started_) {
46159     PERFETTO_DFATAL_OR_ELOG("Metatrace already started from this instance");
46160     return;
46161   }
46162   task_runner_ = task_runner;
46163   trace_writer_ = std::move(trace_writer);
46164   auto weak_ptr = weak_ptr_factory_.GetWeakPtr();
46165   bool enabled = metatrace::Enable(
46166       [weak_ptr] {
46167         if (weak_ptr)
46168           weak_ptr->WriteAllAvailableEvents();
46169       },
46170       task_runner, tags);
46171   if (!enabled)
46172     return;
46173   started_ = true;
46174 }
46175 
Disable()46176 void MetatraceWriter::Disable() {
46177   PERFETTO_DCHECK_THREAD(thread_checker_);
46178   if (!started_)
46179     return;
46180   metatrace::Disable();
46181   started_ = false;
46182   trace_writer_.reset();
46183 }
46184 
WriteAllAvailableEvents()46185 void MetatraceWriter::WriteAllAvailableEvents() {
46186   PERFETTO_DCHECK_THREAD(thread_checker_);
46187   if (!started_)
46188     return;
46189   for (auto it = metatrace::RingBuffer::GetReadIterator(); it; ++it) {
46190     auto type_and_id = it->type_and_id.load(std::memory_order_acquire);
46191     if (type_and_id == 0)
46192       break;  // Stop at the first incomplete event.
46193 
46194     auto packet = trace_writer_->NewTracePacket();
46195     packet->set_timestamp(it->timestamp_ns());
46196     auto* evt = packet->set_perfetto_metatrace();
46197     uint16_t type = type_and_id & metatrace::Record::kTypeMask;
46198     uint16_t id = type_and_id & ~metatrace::Record::kTypeMask;
46199     if (type == metatrace::Record::kTypeCounter) {
46200       evt->set_counter_id(id);
46201       evt->set_counter_value(it->counter_value);
46202     } else {
46203       evt->set_event_id(id);
46204       evt->set_event_duration_ns(it->duration_ns);
46205     }
46206 
46207     evt->set_thread_id(static_cast<uint32_t>(it->thread_id));
46208 
46209     if (metatrace::RingBuffer::has_overruns())
46210       evt->set_has_overruns(true);
46211   }
46212   // The |it| destructor will automatically update the read index position in
46213   // the meta-trace ring buffer.
46214 }
46215 
WriteAllAndFlushTraceWriter(std::function<void ()> callback)46216 void MetatraceWriter::WriteAllAndFlushTraceWriter(
46217     std::function<void()> callback) {
46218   PERFETTO_DCHECK_THREAD(thread_checker_);
46219   if (!started_)
46220     return;
46221   WriteAllAvailableEvents();
46222   trace_writer_->Flush(std::move(callback));
46223 }
46224 
46225 }  // namespace perfetto
46226 // gen_amalgamated begin source: src/tracing/core/packet_stream_validator.cc
46227 // gen_amalgamated begin header: src/tracing/core/packet_stream_validator.h
46228 /*
46229  * Copyright (C) 2018 The Android Open Source Project
46230  *
46231  * Licensed under the Apache License, Version 2.0 (the "License");
46232  * you may not use this file except in compliance with the License.
46233  * You may obtain a copy of the License at
46234  *
46235  *      http://www.apache.org/licenses/LICENSE-2.0
46236  *
46237  * Unless required by applicable law or agreed to in writing, software
46238  * distributed under the License is distributed on an "AS IS" BASIS,
46239  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
46240  * See the License for the specific language governing permissions and
46241  * limitations under the License.
46242  */
46243 
46244 #ifndef SRC_TRACING_CORE_PACKET_STREAM_VALIDATOR_H_
46245 #define SRC_TRACING_CORE_PACKET_STREAM_VALIDATOR_H_
46246 
46247 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/slice.h"
46248 
46249 namespace perfetto {
46250 
46251 // Checks that the stream of trace packets sent by the producer is well formed.
46252 // This includes:
46253 //
46254 // - Checking that the packets are not truncated.
46255 // - There are no dangling bytes left over in the packets.
46256 // - Any trusted fields (e.g., uid) are not set.
46257 //
46258 // Note that we only validate top-level fields in the trace proto; sub-messages
46259 // are simply skipped.
46260 class PacketStreamValidator {
46261  public:
46262   PacketStreamValidator() = delete;
46263 
46264   static bool Validate(const Slices&);
46265 };
46266 
46267 }  // namespace perfetto
46268 
46269 #endif  // SRC_TRACING_CORE_PACKET_STREAM_VALIDATOR_H_
46270 /*
46271  * Copyright (C) 2018 The Android Open Source Project
46272  *
46273  * Licensed under the Apache License, Version 2.0 (the "License");
46274  * you may not use this file except in compliance with the License.
46275  * You may obtain a copy of the License at
46276  *
46277  *      http://www.apache.org/licenses/LICENSE-2.0
46278  *
46279  * Unless required by applicable law or agreed to in writing, software
46280  * distributed under the License is distributed on an "AS IS" BASIS,
46281  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
46282  * See the License for the specific language governing permissions and
46283  * limitations under the License.
46284  */
46285 
46286 // gen_amalgamated expanded: #include "src/tracing/core/packet_stream_validator.h"
46287 
46288 #include <stddef.h>
46289 
46290 #include <cinttypes>
46291 
46292 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
46293 // gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
46294 // gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
46295 
46296 // gen_amalgamated expanded: #include "protos/perfetto/trace/trace_packet.pbzero.h"
46297 
46298 namespace perfetto {
46299 
46300 namespace {
46301 
46302 using protozero::proto_utils::ProtoWireType;
46303 
46304 const uint32_t kReservedFieldIds[] = {
46305     protos::pbzero::TracePacket::kTrustedUidFieldNumber,
46306     protos::pbzero::TracePacket::kTrustedPacketSequenceIdFieldNumber,
46307     protos::pbzero::TracePacket::kTraceConfigFieldNumber,
46308     protos::pbzero::TracePacket::kTraceStatsFieldNumber,
46309     protos::pbzero::TracePacket::kCompressedPacketsFieldNumber,
46310     protos::pbzero::TracePacket::kSynchronizationMarkerFieldNumber,
46311 };
46312 
46313 // This translation unit is quite subtle and perf-sensitive. Remember to check
46314 // BM_PacketStreamValidator in perfetto_benchmarks when making changes.
46315 
46316 // Checks that a packet, spread over several slices, is well-formed and doesn't
46317 // contain reserved top-level fields.
46318 // The checking logic is based on a state-machine that skips the fields' payload
46319 // and operates as follows:
46320 //              +-------------------------------+ <-------------------------+
46321 // +----------> | Read field preamble (varint)  | <----------------------+  |
46322 // |            +-------------------------------+                        |  |
46323 // |              |              |            |                          |  |
46324 // |       <Varint>        <Fixed 32/64>     <Length-delimited field>    |  |
46325 // |          V                  |                      V                |  |
46326 // |  +------------------+       |               +--------------+        |  |
46327 // |  | Read field value |       |               | Read length  |        |  |
46328 // |  | (another varint) |       |               |   (varint)   |        |  |
46329 // |  +------------------+       |               +--------------+        |  |
46330 // |           |                 V                      V                |  |
46331 // +-----------+        +----------------+     +-----------------+       |  |
46332 //                      | Skip 4/8 Bytes |     | Skip $len Bytes |-------+  |
46333 //                      +----------------+     +-----------------+          |
46334 //                               |                                          |
46335 //                               +------------------------------------------+
46336 class ProtoFieldParserFSM {
46337  public:
46338   // This method effectively continuously parses varints (either for the field
46339   // preamble or the payload or the submessage length) and tells the caller
46340   // (the Validate() method) how many bytes to skip until the next field.
Push(uint8_t octet)46341   size_t Push(uint8_t octet) {
46342     varint_ |= static_cast<uint64_t>(octet & 0x7F) << varint_shift_;
46343     if (octet & 0x80) {
46344       varint_shift_ += 7;
46345       if (varint_shift_ >= 64) {
46346         // Do not invoke UB on next call.
46347         varint_shift_ = 0;
46348         state_ = kInvalidVarInt;
46349       }
46350       return 0;
46351     }
46352     uint64_t varint = varint_;
46353     varint_ = 0;
46354     varint_shift_ = 0;
46355 
46356     switch (state_) {
46357       case kFieldPreamble: {
46358         uint64_t field_type = varint & 7;  // 7 = 0..0111
46359         auto field_id = static_cast<uint32_t>(varint >> 3);
46360         // Check if the field id is reserved, go into an error state if it is.
46361         for (size_t i = 0; i < base::ArraySize(kReservedFieldIds); ++i) {
46362           if (field_id == kReservedFieldIds[i]) {
46363             state_ = kWroteReservedField;
46364             return 0;
46365           }
46366         }
46367         // The field type is legit, now check it's well formed and within
46368         // boundaries.
46369         if (field_type == static_cast<uint64_t>(ProtoWireType::kVarInt)) {
46370           state_ = kVarIntValue;
46371         } else if (field_type ==
46372                    static_cast<uint64_t>(ProtoWireType::kFixed32)) {
46373           return 4;
46374         } else if (field_type ==
46375                    static_cast<uint64_t>(ProtoWireType::kFixed64)) {
46376           return 8;
46377         } else if (field_type ==
46378                    static_cast<uint64_t>(ProtoWireType::kLengthDelimited)) {
46379           state_ = kLenDelimitedLen;
46380         } else {
46381           state_ = kUnknownFieldType;
46382         }
46383         return 0;
46384       }
46385 
46386       case kVarIntValue: {
46387         // Consume the int field payload and go back to the next field.
46388         state_ = kFieldPreamble;
46389         return 0;
46390       }
46391 
46392       case kLenDelimitedLen: {
46393         if (varint > protozero::proto_utils::kMaxMessageLength) {
46394           state_ = kMessageTooBig;
46395           return 0;
46396         }
46397         state_ = kFieldPreamble;
46398         return static_cast<size_t>(varint);
46399       }
46400 
46401       case kWroteReservedField:
46402       case kUnknownFieldType:
46403       case kMessageTooBig:
46404       case kInvalidVarInt:
46405         // Persistent error states.
46406         return 0;
46407 
46408     }          // switch(state_)
46409     return 0;  // To keep GCC happy.
46410   }
46411 
46412   // Queried at the end of the all payload. A message is well-formed only
46413   // if the FSM is back to the state where it should parse the next field and
46414   // hasn't started parsing any preamble.
valid() const46415   bool valid() const { return state_ == kFieldPreamble && varint_shift_ == 0; }
state() const46416   int state() const { return static_cast<int>(state_); }
46417 
46418  private:
46419   enum State {
46420     kFieldPreamble = 0,  // Parsing the varint for the field preamble.
46421     kVarIntValue,        // Parsing the varint value for the field payload.
46422     kLenDelimitedLen,    // Parsing the length of the length-delimited field.
46423 
46424     // Error states:
46425     kWroteReservedField,  // Tried to set a reserved field id.
46426     kUnknownFieldType,    // Encountered an invalid field type.
46427     kMessageTooBig,       // Size of the length delimited message was too big.
46428     kInvalidVarInt,       // VarInt larger than 64 bits.
46429   };
46430 
46431   State state_ = kFieldPreamble;
46432   uint64_t varint_ = 0;
46433   uint32_t varint_shift_ = 0;
46434 };
46435 
46436 }  // namespace
46437 
46438 // static
Validate(const Slices & slices)46439 bool PacketStreamValidator::Validate(const Slices& slices) {
46440   ProtoFieldParserFSM parser;
46441   size_t skip_bytes = 0;
46442   for (const Slice& slice : slices) {
46443     for (size_t i = 0; i < slice.size;) {
46444       const size_t skip_bytes_cur_slice = std::min(skip_bytes, slice.size - i);
46445       if (skip_bytes_cur_slice > 0) {
46446         i += skip_bytes_cur_slice;
46447         skip_bytes -= skip_bytes_cur_slice;
46448       } else {
46449         uint8_t octet = *(reinterpret_cast<const uint8_t*>(slice.start) + i);
46450         skip_bytes = parser.Push(octet);
46451         i++;
46452       }
46453     }
46454   }
46455   if (skip_bytes == 0 && parser.valid())
46456     return true;
46457 
46458   PERFETTO_DLOG("Packet validation error (state %d, skip = %zu)",
46459                 parser.state(), skip_bytes);
46460   return false;
46461 }
46462 
46463 }  // namespace perfetto
46464 // gen_amalgamated begin source: src/tracing/core/trace_buffer.cc
46465 // gen_amalgamated begin header: src/tracing/core/trace_buffer.h
46466 /*
46467  * Copyright (C) 2018 The Android Open Source Project
46468  *
46469  * Licensed under the Apache License, Version 2.0 (the "License");
46470  * you may not use this file except in compliance with the License.
46471  * You may obtain a copy of the License at
46472  *
46473  *      http://www.apache.org/licenses/LICENSE-2.0
46474  *
46475  * Unless required by applicable law or agreed to in writing, software
46476  * distributed under the License is distributed on an "AS IS" BASIS,
46477  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
46478  * See the License for the specific language governing permissions and
46479  * limitations under the License.
46480  */
46481 
46482 #ifndef SRC_TRACING_CORE_TRACE_BUFFER_H_
46483 #define SRC_TRACING_CORE_TRACE_BUFFER_H_
46484 
46485 #include <stdint.h>
46486 #include <string.h>
46487 
46488 #include <array>
46489 #include <limits>
46490 #include <map>
46491 #include <tuple>
46492 
46493 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
46494 // gen_amalgamated expanded: #include "perfetto/ext/base/paged_memory.h"
46495 // gen_amalgamated expanded: #include "perfetto/ext/base/thread_annotations.h"
46496 // gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
46497 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/basic_types.h"
46498 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/slice.h"
46499 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/trace_stats.h"
46500 
46501 namespace perfetto {
46502 
46503 class TracePacket;
46504 
46505 // The main buffer, owned by the tracing service, where all the trace data is
46506 // ultimately stored into. The service will own several instances of this class,
46507 // at least one per active consumer (as defined in the |buffers| section of
46508 // trace_config.proto) and will copy chunks from the producer's shared memory
46509 // buffers into here when a CommitData IPC is received.
46510 //
46511 // Writing into the buffer
46512 // -----------------------
46513 // Data is copied from the SMB(s) using CopyChunkUntrusted(). The buffer will
46514 // hence contain data coming from different producers and different writer
46515 // sequences, more specifically:
46516 // - The service receives data by several producer(s), identified by their ID.
46517 // - Each producer writes several sequences identified by the same WriterID.
46518 //   (they correspond to TraceWriter instances in the producer).
46519 // - Each Writer writes, in order, several chunks.
46520 // - Each chunk contains zero, one, or more TracePacket(s), or even just
46521 //   fragments of packets (when they span across several chunks).
46522 //
46523 // So at any point in time, the buffer will contain a variable number of logical
46524 // sequences identified by the {ProducerID, WriterID} tuple. Any given chunk
46525 // will only contain packets (or fragments) belonging to the same sequence.
46526 //
46527 // The buffer operates by default as a ring buffer.
46528 // It has two overwrite policies:
46529 //  1. kOverwrite (default): if the write pointer reaches the read pointer, old
46530 //     unread chunks will be overwritten by new chunks.
46531 //  2. kDiscard: if the write pointer reaches the read pointer, unread chunks
46532 //     are preserved and the new chunks are discarded. Any future write becomes
46533 //     a no-op, even if the reader manages to fully catch up. This is because
46534 //     once a chunk is discarded, the sequence of packets is broken and trying
46535 //     to recover would be too hard (also due to the fact that, at the same
46536 //     time, we allow out-of-order commits and chunk re-writes).
46537 //
46538 // Chunks are (over)written in the same order of the CopyChunkUntrusted() calls.
46539 // When overwriting old content, entire chunks are overwritten or clobbered.
46540 // The buffer never leaves a partial chunk around. Chunks' payload is copied
46541 // as-is, but their header is not and is repacked in order to keep the
46542 // ProducerID around.
46543 //
46544 // Chunks are stored in the buffer next to each other. Each chunk is prefixed by
46545 // an inline header (ChunkRecord), which contains most of the fields of the
46546 // SharedMemoryABI ChunkHeader + the ProducerID + the size of the payload.
46547 // It's a conventional binary object stream essentially, where each ChunkRecord
46548 // tells where it ends and hence where to find the next one, like this:
46549 //
46550 //          .-------------------------. 16 byte boundary
46551 //          | ChunkRecord:   16 bytes |
46552 //          | - chunk id:     4 bytes |
46553 //          | - producer id:  2 bytes |
46554 //          | - writer id:    2 bytes |
46555 //          | - #fragments:   2 bytes |
46556 //    +-----+ - record size:  2 bytes |
46557 //    |     | - flags+pad:    4 bytes |
46558 //    |     +-------------------------+
46559 //    |     |                         |
46560 //    |     :     Chunk payload       :
46561 //    |     |                         |
46562 //    |     +-------------------------+
46563 //    |     |    Optional padding     |
46564 //    +---> +-------------------------+ 16 byte boundary
46565 //          |      ChunkRecord        |
46566 //          :                         :
46567 // Chunks stored in the buffer are always rounded up to 16 bytes (that is
46568 // sizeof(ChunkRecord)), in order to avoid further inner fragmentation.
46569 // Special "padding" chunks can be put in the buffer, e.g. in the case when we
46570 // try to write a chunk of size N while the write pointer is at the end of the
46571 // buffer, but the write pointer is < N bytes from the end (and hence needs to
46572 // wrap over).
46573 // Because of this, the buffer is self-describing: the contents of the buffer
46574 // can be reconstructed by just looking at the buffer content (this will be
46575 // quite useful in future to recover the buffer from crash reports).
46576 //
46577 // However, in order to keep some operations (patching and reading) fast, a
46578 // lookaside index is maintained (in |index_|), keeping each chunk in the buffer
46579 // indexed by their {ProducerID, WriterID, ChunkID} tuple.
46580 //
46581 // Patching data out-of-band
46582 // -------------------------
46583 // This buffer also supports patching chunks' payload out-of-band, after they
46584 // have been stored. This is to allow producers to backfill the "size" fields
46585 // of the protos that spawn across several chunks, when the previous chunks are
46586 // returned to the service. The MaybePatchChunkContents() deals with the fact
46587 // that a chunk might have been lost (because of wrapping) by the time the OOB
46588 // IPC comes.
46589 //
46590 // Reading from the buffer
46591 // -----------------------
46592 // This class supports one reader only (the consumer). Reads are NOT idempotent
46593 // as they move the read cursors around. Reading back the buffer is the most
46594 // conceptually complex part. The ReadNextTracePacket() method operates with
46595 // whole packet granularity. Packets are returned only when all their fragments
46596 // are available.
46597 // This class takes care of:
46598 // - Gluing packets within the same sequence, even if they are not stored
46599 //   adjacently in the buffer.
46600 // - Re-ordering chunks within a sequence (using the ChunkID, which wraps).
46601 // - Detecting holes in packet fragments (because of loss of chunks).
46602 // Reads guarantee that packets for the same sequence are read in FIFO order
46603 // (according to their ChunkID), but don't give any guarantee about the read
46604 // order of packets from different sequences, see comments in
46605 // ReadNextTracePacket() below.
46606 class TraceBuffer {
46607  public:
46608   static const size_t InlineChunkHeaderSize;  // For test/fake_packet.{cc,h}.
46609 
46610   // See comment in the header above.
46611   enum OverwritePolicy { kOverwrite, kDiscard };
46612 
46613   // Argument for out-of-band patches applied through TryPatchChunkContents().
46614   struct Patch {
46615     // From SharedMemoryABI::kPacketHeaderSize.
46616     static constexpr size_t kSize = 4;
46617 
46618     size_t offset_untrusted;
46619     std::array<uint8_t, kSize> data;
46620   };
46621 
46622   // Identifiers that are constant for a packet sequence.
46623   struct PacketSequenceProperties {
46624     ProducerID producer_id_trusted;
46625     uid_t producer_uid_trusted;
46626     WriterID writer_id;
46627   };
46628 
46629   // Can return nullptr if the memory allocation fails.
46630   static std::unique_ptr<TraceBuffer> Create(size_t size_in_bytes,
46631                                              OverwritePolicy = kOverwrite);
46632 
46633   ~TraceBuffer();
46634 
46635   // Copies a Chunk from a producer Shared Memory Buffer into the trace buffer.
46636   // |src| points to the first packet in the SharedMemoryABI's chunk shared with
46637   // an untrusted producer. "untrusted" here means: the producer might be
46638   // malicious and might change |src| concurrently while we read it (internally
46639   // this method memcpy()-s first the chunk before processing it). None of the
46640   // arguments should be trusted, unless otherwise stated. We can trust that
46641   // |src| points to a valid memory area, but not its contents.
46642   //
46643   // This method may be called multiple times for the same chunk. In this case,
46644   // the original chunk's payload will be overridden and its number of fragments
46645   // and flags adjusted to match |num_fragments| and |chunk_flags|. The service
46646   // may use this to insert partial chunks (|chunk_complete = false|) before the
46647   // producer has committed them.
46648   //
46649   // If |chunk_complete| is |false|, the TraceBuffer will only consider the
46650   // first |num_fragments - 1| packets to be complete, since the producer may
46651   // not have finished writing the latest packet. Reading from a sequence will
46652   // also not progress past any incomplete chunks until they were rewritten with
46653   // |chunk_complete = true|, e.g. after a producer's commit.
46654   //
46655   // TODO(eseckler): Pass in a PacketStreamProperties instead of individual IDs.
46656   void CopyChunkUntrusted(ProducerID producer_id_trusted,
46657                           uid_t producer_uid_trusted,
46658                           WriterID writer_id,
46659                           ChunkID chunk_id,
46660                           uint16_t num_fragments,
46661                           uint8_t chunk_flags,
46662                           bool chunk_complete,
46663                           const uint8_t* src,
46664                           size_t size);
46665   // Applies a batch of |patches| to the given chunk, if the given chunk is
46666   // still in the buffer. Does nothing if the given ChunkID is gone.
46667   // Returns true if the chunk has been found and patched, false otherwise.
46668   // |other_patches_pending| is used to determine whether this is the only
46669   // batch of patches for the chunk or there is more.
46670   // If |other_patches_pending| == false, the chunk is marked as ready to be
46671   // consumed. If true, the state of the chunk is not altered.
46672   //
46673   // Note: If the producer is batching commits (see shared_memory_arbiter.h), it
46674   // will also attempt to do patching locally. Namely, if nested messages are
46675   // completed while the chunk on which they started is being batched (i.e.
46676   // before it has been committed to the service), the producer will apply the
46677   // respective patches to the batched chunk. These patches will not be sent to
46678   // the service - i.e. only the patches that the producer did not manage to
46679   // apply before committing the chunk will be applied here.
46680   bool TryPatchChunkContents(ProducerID,
46681                              WriterID,
46682                              ChunkID,
46683                              const Patch* patches,
46684                              size_t patches_size,
46685                              bool other_patches_pending);
46686 
46687   // To read the contents of the buffer the caller needs to:
46688   //   BeginRead()
46689   //   while (ReadNextTracePacket(packet_fragments)) { ... }
46690   // No other calls to any other method should be interleaved between
46691   // BeginRead() and ReadNextTracePacket().
46692   // Reads in the TraceBuffer are NOT idempotent.
46693   void BeginRead();
46694 
46695   // Returns the next packet in the buffer, if any, and the producer_id,
46696   // producer_uid, and writer_id of the producer/writer that wrote it (as passed
46697   // in the CopyChunkUntrusted() call). Returns false if no packets can be read
46698   // at this point. If a packet was read successfully,
46699   // |previous_packet_on_sequence_dropped| is set to |true| if the previous
46700   // packet on the sequence was dropped from the buffer before it could be read
46701   // (e.g. because its chunk was overridden due to the ring buffer wrapping or
46702   // due to an ABI violation), and to |false| otherwise.
46703   //
46704   // This function returns only complete packets. Specifically:
46705   // When there is at least one complete packet in the buffer, this function
46706   // returns true and populates the TracePacket argument with the boundaries of
46707   // each fragment for one packet.
46708   // TracePacket will have at least one slice when this function returns true.
46709   // When there are no whole packets eligible to read (e.g. we are still missing
46710   // fragments) this function returns false.
46711   // This function guarantees also that packets for a given
46712   // {ProducerID, WriterID} are read in FIFO order.
46713   // This function does not guarantee any ordering w.r.t. packets belonging to
46714   // different WriterID(s). For instance, given the following packets copied
46715   // into the buffer:
46716   //   {ProducerID: 1, WriterID: 1}: P1 P2 P3
46717   //   {ProducerID: 1, WriterID: 2}: P4 P5 P6
46718   //   {ProducerID: 2, WriterID: 1}: P7 P8 P9
46719   // The following read sequence is possible:
46720   //   P1, P4, P7, P2, P3, P5, P8, P9, P6
46721   // But the following is guaranteed to NOT happen:
46722   //   P1, P5, P7, P4 (P4 cannot come after P5)
46723   bool ReadNextTracePacket(TracePacket*,
46724                            PacketSequenceProperties* sequence_properties,
46725                            bool* previous_packet_on_sequence_dropped);
46726 
stats() const46727   const TraceStats::BufferStats& stats() const { return stats_; }
size() const46728   size_t size() const { return size_; }
46729 
46730  private:
46731   friend class TraceBufferTest;
46732 
46733   // ChunkRecord is a Chunk header stored inline in the |data_| buffer, before
46734   // the chunk payload (the packets' data). The |data_| buffer looks like this:
46735   // +---------------+------------------++---------------+-----------------+
46736   // | ChunkRecord 1 | Chunk payload 1  || ChunkRecord 2 | Chunk payload 2 | ...
46737   // +---------------+------------------++---------------+-----------------+
46738   // Most of the ChunkRecord fields are copied from SharedMemoryABI::ChunkHeader
46739   // (the chunk header used in the shared memory buffers).
46740   // A ChunkRecord can be a special "padding" record. In this case its payload
46741   // should be ignored and the record should be just skipped.
46742   //
46743   // Full page move optimization:
46744   // This struct has to be exactly (sizeof(PageHeader) + sizeof(ChunkHeader))
46745   // (from shared_memory_abi.h) to allow full page move optimizations
46746   // (TODO(primiano): not implemented yet). In the special case of moving a full
46747   // 4k page that contains only one chunk, in fact, we can just ask the kernel
46748   // to move the full SHM page (see SPLICE_F_{GIFT,MOVE}) and overlay the
46749   // ChunkRecord on top of the moved SMB's header (page + chunk header).
46750   // This special requirement is covered by static_assert(s) in the .cc file.
46751   struct ChunkRecord {
ChunkRecordperfetto::TraceBuffer::ChunkRecord46752     explicit ChunkRecord(size_t sz) : flags{0}, is_padding{0} {
46753       PERFETTO_DCHECK(sz >= sizeof(ChunkRecord) &&
46754                       sz % sizeof(ChunkRecord) == 0 && sz <= kMaxSize);
46755       size = static_cast<decltype(size)>(sz);
46756     }
46757 
is_validperfetto::TraceBuffer::ChunkRecord46758     bool is_valid() const { return size != 0; }
46759 
46760     // Keep this structure packed and exactly 16 bytes (128 bits) big.
46761 
46762     // [32 bits] Monotonic counter within the same writer_id.
46763     ChunkID chunk_id = 0;
46764 
46765     // [16 bits] ID of the Producer from which the Chunk was copied from.
46766     ProducerID producer_id = 0;
46767 
46768     // [16 bits] Unique per Producer (but not within the service).
46769     // If writer_id == kWriterIdPadding the record should just be skipped.
46770     WriterID writer_id = 0;
46771 
46772     // Number of fragments contained in the chunk.
46773     uint16_t num_fragments = 0;
46774 
46775     // Size in bytes, including sizeof(ChunkRecord) itself.
46776     uint16_t size;
46777 
46778     uint8_t flags : 6;  // See SharedMemoryABI::ChunkHeader::flags.
46779     uint8_t is_padding : 1;
46780     uint8_t unused_flag : 1;
46781 
46782     // Not strictly needed, can be reused for more fields in the future. But
46783     // right now helps to spot chunks in hex dumps.
46784     char unused[3] = {'C', 'H', 'U'};
46785 
46786     static constexpr size_t kMaxSize =
46787         std::numeric_limits<decltype(size)>::max();
46788   };
46789 
46790   // Lookaside index entry. This serves two purposes:
46791   // 1) Allow a fast lookup of ChunkRecord by their ID (the tuple
46792   //   {ProducerID, WriterID, ChunkID}). This is used when applying out-of-band
46793   //   patches to the contents of the chunks after they have been copied into
46794   //   the TraceBuffer.
46795   // 2) keep the chunks ordered by their ID. This is used when reading back.
46796   // 3) Keep metadata about the status of the chunk, e.g. whether the contents
46797   //    have been read already and should be skipped in a future read pass.
46798   // This struct should not have any field that is essential for reconstructing
46799   // the contents of the buffer from a crash dump.
46800   struct ChunkMeta {
46801     // Key used for sorting in the map.
46802     struct Key {
Keyperfetto::TraceBuffer::ChunkMeta::Key46803       Key(ProducerID p, WriterID w, ChunkID c)
46804           : producer_id{p}, writer_id{w}, chunk_id{c} {}
46805 
Keyperfetto::TraceBuffer::ChunkMeta::Key46806       explicit Key(const ChunkRecord& cr)
46807           : Key(cr.producer_id, cr.writer_id, cr.chunk_id) {}
46808 
46809       // Note that this sorting doesn't keep into account the fact that ChunkID
46810       // will wrap over at some point. The extra logic in SequenceIterator deals
46811       // with that.
operator <perfetto::TraceBuffer::ChunkMeta::Key46812       bool operator<(const Key& other) const {
46813         return std::tie(producer_id, writer_id, chunk_id) <
46814                std::tie(other.producer_id, other.writer_id, other.chunk_id);
46815       }
46816 
operator ==perfetto::TraceBuffer::ChunkMeta::Key46817       bool operator==(const Key& other) const {
46818         return std::tie(producer_id, writer_id, chunk_id) ==
46819                std::tie(other.producer_id, other.writer_id, other.chunk_id);
46820       }
46821 
operator !=perfetto::TraceBuffer::ChunkMeta::Key46822       bool operator!=(const Key& other) const { return !(*this == other); }
46823 
46824       // These fields should match at all times the corresponding fields in
46825       // the |chunk_record|. They are copied here purely for efficiency to avoid
46826       // dereferencing the buffer all the time.
46827       ProducerID producer_id;
46828       WriterID writer_id;
46829       ChunkID chunk_id;
46830     };
46831 
46832     enum IndexFlags : uint8_t {
46833       // If set, the chunk state was kChunkComplete at the time it was copied.
46834       // If unset, the chunk was still kChunkBeingWritten while copied. When
46835       // reading from the chunk's sequence, the sequence will not advance past
46836       // this chunk until this flag is set.
46837       kComplete = 1 << 0,
46838 
46839       // If set, we skipped the last packet that we read from this chunk e.g.
46840       // because we it was a continuation from a previous chunk that was dropped
46841       // or due to an ABI violation.
46842       kLastReadPacketSkipped = 1 << 1
46843     };
46844 
ChunkMetaperfetto::TraceBuffer::ChunkMeta46845     ChunkMeta(ChunkRecord* r, uint16_t p, bool complete, uint8_t f, uid_t u)
46846         : chunk_record{r}, trusted_uid{u}, flags{f}, num_fragments{p} {
46847       if (complete)
46848         index_flags = kComplete;
46849     }
46850 
is_completeperfetto::TraceBuffer::ChunkMeta46851     bool is_complete() const { return index_flags & kComplete; }
46852 
set_completeperfetto::TraceBuffer::ChunkMeta46853     void set_complete(bool complete) {
46854       if (complete) {
46855         index_flags |= kComplete;
46856       } else {
46857         index_flags &= ~kComplete;
46858       }
46859     }
46860 
last_read_packet_skippedperfetto::TraceBuffer::ChunkMeta46861     bool last_read_packet_skipped() const {
46862       return index_flags & kLastReadPacketSkipped;
46863     }
46864 
set_last_read_packet_skippedperfetto::TraceBuffer::ChunkMeta46865     void set_last_read_packet_skipped(bool skipped) {
46866       if (skipped) {
46867         index_flags |= kLastReadPacketSkipped;
46868       } else {
46869         index_flags &= ~kLastReadPacketSkipped;
46870       }
46871     }
46872 
46873     ChunkRecord* const chunk_record;  // Addr of ChunkRecord within |data_|.
46874     const uid_t trusted_uid;          // uid of the producer.
46875 
46876     // Flags set by TraceBuffer to track the state of the chunk in the index.
46877     uint8_t index_flags = 0;
46878 
46879     // Correspond to |chunk_record->flags| and |chunk_record->num_fragments|.
46880     // Copied here for performance reasons (avoids having to dereference
46881     // |chunk_record| while iterating over ChunkMeta) and to aid debugging in
46882     // case the buffer gets corrupted.
46883     uint8_t flags = 0;           // See SharedMemoryABI::ChunkHeader::flags.
46884     uint16_t num_fragments = 0;  // Total number of packet fragments.
46885 
46886     uint16_t num_fragments_read = 0;  // Number of fragments already read.
46887 
46888     // The start offset of the next fragment (the |num_fragments_read|-th) to be
46889     // read. This is the offset in bytes from the beginning of the ChunkRecord's
46890     // payload (the 1st fragment starts at |chunk_record| +
46891     // sizeof(ChunkRecord)).
46892     uint16_t cur_fragment_offset = 0;
46893   };
46894 
46895   using ChunkMap = std::map<ChunkMeta::Key, ChunkMeta>;
46896 
46897   // Allows to iterate over a sub-sequence of |index_| for all keys belonging to
46898   // the same {ProducerID,WriterID}. Furthermore takes into account the wrapping
46899   // of ChunkID. Instances are valid only as long as the |index_| is not altered
46900   // (can be used safely only between adjacent ReadNextTracePacket() calls).
46901   // The order of the iteration will proceed in the following order:
46902   // |wrapping_id| + 1 -> |seq_end|, |seq_begin| -> |wrapping_id|.
46903   // Practical example:
46904   // - Assume that kMaxChunkID == 7
46905   // - Assume that we have all 8 chunks in the range (0..7).
46906   // - Hence, |seq_begin| == c0, |seq_end| == c7
46907   // - Assume |wrapping_id| = 4 (c4 is the last chunk copied over
46908   //   through a CopyChunkUntrusted()).
46909   // The resulting iteration order will be: c5, c6, c7, c0, c1, c2, c3, c4.
46910   struct SequenceIterator {
46911     // Points to the 1st key (the one with the numerically min ChunkID).
46912     ChunkMap::iterator seq_begin;
46913 
46914     // Points one past the last key (the one with the numerically max ChunkID).
46915     ChunkMap::iterator seq_end;
46916 
46917     // Current iterator, always >= seq_begin && <= seq_end.
46918     ChunkMap::iterator cur;
46919 
46920     // The latest ChunkID written. Determines the start/end of the sequence.
46921     ChunkID wrapping_id;
46922 
is_validperfetto::TraceBuffer::SequenceIterator46923     bool is_valid() const { return cur != seq_end; }
46924 
producer_idperfetto::TraceBuffer::SequenceIterator46925     ProducerID producer_id() const {
46926       PERFETTO_DCHECK(is_valid());
46927       return cur->first.producer_id;
46928     }
46929 
writer_idperfetto::TraceBuffer::SequenceIterator46930     WriterID writer_id() const {
46931       PERFETTO_DCHECK(is_valid());
46932       return cur->first.writer_id;
46933     }
46934 
chunk_idperfetto::TraceBuffer::SequenceIterator46935     ChunkID chunk_id() const {
46936       PERFETTO_DCHECK(is_valid());
46937       return cur->first.chunk_id;
46938     }
46939 
operator *perfetto::TraceBuffer::SequenceIterator46940     ChunkMeta& operator*() {
46941       PERFETTO_DCHECK(is_valid());
46942       return cur->second;
46943     }
46944 
46945     // Moves |cur| to the next chunk in the index.
46946     // is_valid() will become false after calling this, if this was the last
46947     // entry of the sequence.
46948     void MoveNext();
46949 
MoveToEndperfetto::TraceBuffer::SequenceIterator46950     void MoveToEnd() { cur = seq_end; }
46951   };
46952 
46953   enum class ReadAheadResult {
46954     kSucceededReturnSlices,
46955     kFailedMoveToNextSequence,
46956     kFailedStayOnSameSequence,
46957   };
46958 
46959   enum class ReadPacketResult {
46960     kSucceeded,
46961     kFailedInvalidPacket,
46962     kFailedEmptyPacket,
46963   };
46964 
46965   explicit TraceBuffer(OverwritePolicy);
46966   TraceBuffer(const TraceBuffer&) = delete;
46967   TraceBuffer& operator=(const TraceBuffer&) = delete;
46968 
46969   bool Initialize(size_t size);
46970 
46971   // Returns an object that allows to iterate over chunks in the |index_| that
46972   // have the same {ProducerID, WriterID} of
46973   // |seq_begin.first.{producer,writer}_id|. |seq_begin| must be an iterator to
46974   // the first entry in the |index_| that has a different {ProducerID, WriterID}
46975   // from the previous one. It is valid for |seq_begin| to be == index_.end()
46976   // (i.e. if the index is empty). The iteration takes care of ChunkID wrapping,
46977   // by using |last_chunk_id_|.
46978   SequenceIterator GetReadIterForSequence(ChunkMap::iterator seq_begin);
46979 
46980   // Used as a last resort when a buffer corruption is detected.
46981   void ClearContentsAndResetRWCursors();
46982 
46983   // Adds a padding record of the given size (must be a multiple of
46984   // sizeof(ChunkRecord)).
46985   void AddPaddingRecord(size_t);
46986 
46987   // Look for contiguous fragment of the same packet starting from |read_iter_|.
46988   // If a contiguous packet is found, all the fragments are pushed into
46989   // TracePacket and the function returns kSucceededReturnSlices. If not, the
46990   // function returns either kFailedMoveToNextSequence or
46991   // kFailedStayOnSameSequence, telling the caller to continue looking for
46992   // packets.
46993   ReadAheadResult ReadAhead(TracePacket*);
46994 
46995   // Deletes (by marking the record invalid and removing form the index) all
46996   // chunks from |wptr_| to |wptr_| + |bytes_to_clear|.
46997   // Returns:
46998   //   * The size of the gap left between the next valid Chunk and the end of
46999   //     the deletion range.
47000   //   * 0 if no next valid chunk exists (if the buffer is still zeroed).
47001   //   * -1 if the buffer |overwrite_policy_| == kDiscard and the deletion would
47002   //     cause unread chunks to be overwritten. In this case the buffer is left
47003   //     untouched.
47004   // Graphically, assume the initial situation is the following (|wptr_| = 10).
47005   // |0        |10 (wptr_)       |30       |40                 |60
47006   // +---------+-----------------+---------+-------------------+---------+
47007   // | Chunk 1 | Chunk 2         | Chunk 3 | Chunk 4           | Chunk 5 |
47008   // +---------+-----------------+---------+-------------------+---------+
47009   //           |_________Deletion range_______|~~return value~~|
47010   //
47011   // A call to DeleteNextChunksFor(32) will remove chunks 2,3,4 and return 18
47012   // (60 - 42), the distance between chunk 5 and the end of the deletion range.
47013   ssize_t DeleteNextChunksFor(size_t bytes_to_clear);
47014 
47015   // Decodes the boundaries of the next packet (or a fragment) pointed by
47016   // ChunkMeta and pushes that into |TracePacket|. It also increments the
47017   // |num_fragments_read| counter.
47018   // TracePacket can be nullptr, in which case the read state is still advanced.
47019   // When TracePacket is not nullptr, ProducerID must also be not null and will
47020   // be updated with the ProducerID that originally wrote the chunk.
47021   ReadPacketResult ReadNextPacketInChunk(ChunkMeta*, TracePacket*);
47022 
DcheckIsAlignedAndWithinBounds(const uint8_t * ptr) const47023   void DcheckIsAlignedAndWithinBounds(const uint8_t* ptr) const {
47024     PERFETTO_DCHECK(ptr >= begin() && ptr <= end() - sizeof(ChunkRecord));
47025     PERFETTO_DCHECK(
47026         (reinterpret_cast<uintptr_t>(ptr) & (alignof(ChunkRecord) - 1)) == 0);
47027   }
47028 
GetChunkRecordAt(uint8_t * ptr)47029   ChunkRecord* GetChunkRecordAt(uint8_t* ptr) {
47030     DcheckIsAlignedAndWithinBounds(ptr);
47031     // We may be accessing a new (empty) record.
47032     data_.EnsureCommitted(
47033         static_cast<size_t>(ptr + sizeof(ChunkRecord) - begin()));
47034     return reinterpret_cast<ChunkRecord*>(ptr);
47035   }
47036 
47037   void DiscardWrite();
47038 
47039   // |src| can be nullptr (in which case |size| must be ==
47040   // record.size - sizeof(ChunkRecord)), for the case of writing a padding
47041   // 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)47042   void WriteChunkRecord(uint8_t* wptr,
47043                         const ChunkRecord& record,
47044                         const uint8_t* src,
47045                         size_t size) {
47046     // Note: |record.size| will be slightly bigger than |size| because of the
47047     // ChunkRecord header and rounding, to ensure that all ChunkRecord(s) are
47048     // multiple of sizeof(ChunkRecord). The invariant is:
47049     // record.size >= |size| + sizeof(ChunkRecord) (== if no rounding).
47050     PERFETTO_DCHECK(size <= ChunkRecord::kMaxSize);
47051     PERFETTO_DCHECK(record.size >= sizeof(record));
47052     PERFETTO_DCHECK(record.size % sizeof(record) == 0);
47053     PERFETTO_DCHECK(record.size >= size + sizeof(record));
47054     PERFETTO_CHECK(record.size <= size_to_end());
47055     DcheckIsAlignedAndWithinBounds(wptr);
47056 
47057     // We may be writing to this area for the first time.
47058     data_.EnsureCommitted(static_cast<size_t>(wptr + record.size - begin()));
47059 
47060     // Deliberately not a *D*CHECK.
47061     PERFETTO_CHECK(wptr + sizeof(record) + size <= end());
47062     memcpy(wptr, &record, sizeof(record));
47063     if (PERFETTO_LIKELY(src)) {
47064       // If the producer modifies the data in the shared memory buffer while we
47065       // are copying it to the central buffer, TSAN will (rightfully) flag that
47066       // as a race. However the entire purpose of copying the data into the
47067       // central buffer is that we can validate it without worrying that the
47068       // producer changes it from under our feet, so this race is benign. The
47069       // alternative would be to try computing which part of the buffer is safe
47070       // to read (assuming a well-behaving client), but the risk of introducing
47071       // a bug that way outweighs the benefit.
47072       PERFETTO_ANNOTATE_BENIGN_RACE_SIZED(
47073           src, size, "Benign race when copying chunk from shared memory.")
47074       memcpy(wptr + sizeof(record), src, size);
47075     } else {
47076       PERFETTO_DCHECK(size == record.size - sizeof(record));
47077     }
47078     const size_t rounding_size = record.size - sizeof(record) - size;
47079     memset(wptr + sizeof(record) + size, 0, rounding_size);
47080   }
47081 
begin() const47082   uint8_t* begin() const { return reinterpret_cast<uint8_t*>(data_.Get()); }
end() const47083   uint8_t* end() const { return begin() + size_; }
size_to_end() const47084   size_t size_to_end() const { return static_cast<size_t>(end() - wptr_); }
47085 
47086   base::PagedMemory data_;
47087   size_t size_ = 0;            // Size in bytes of |data_|.
47088   size_t max_chunk_size_ = 0;  // Max size in bytes allowed for a chunk.
47089   uint8_t* wptr_ = nullptr;    // Write pointer.
47090 
47091   // An index that keeps track of the positions and metadata of each
47092   // ChunkRecord.
47093   ChunkMap index_;
47094 
47095   // Read iterator used for ReadNext(). It is reset by calling BeginRead().
47096   // It becomes invalid after any call to methods that alters the |index_|.
47097   SequenceIterator read_iter_;
47098 
47099   // See comments at the top of the file.
47100   OverwritePolicy overwrite_policy_ = kOverwrite;
47101 
47102   // Only used when |overwrite_policy_ == kDiscard|. This is set the first time
47103   // a write fails because it would overwrite unread chunks.
47104   bool discard_writes_ = false;
47105 
47106   // Keeps track of the highest ChunkID written for a given sequence, taking
47107   // into account a potential overflow of ChunkIDs. In the case of overflow,
47108   // stores the highest ChunkID written since the overflow.
47109   //
47110   // TODO(primiano): should clean up keys from this map. Right now it grows
47111   // without bounds (although realistically is not a problem unless we have too
47112   // many producers/writers within the same trace session).
47113   std::map<std::pair<ProducerID, WriterID>, ChunkID> last_chunk_id_written_;
47114 
47115   // Statistics about buffer usage.
47116   TraceStats::BufferStats stats_;
47117 
47118 #if PERFETTO_DCHECK_IS_ON()
47119   bool changed_since_last_read_ = false;
47120 #endif
47121 
47122   // When true disable some DCHECKs that have been put in place to detect
47123   // bugs in the producers. This is for tests that feed malicious inputs and
47124   // hence mimic a buggy producer.
47125   bool suppress_client_dchecks_for_testing_ = false;
47126 };
47127 
47128 }  // namespace perfetto
47129 
47130 #endif  // SRC_TRACING_CORE_TRACE_BUFFER_H_
47131 /*
47132  * Copyright (C) 2018 The Android Open Source Project
47133  *
47134  * Licensed under the Apache License, Version 2.0 (the "License");
47135  * you may not use this file except in compliance with the License.
47136  * You may obtain a copy of the License at
47137  *
47138  *      http://www.apache.org/licenses/LICENSE-2.0
47139  *
47140  * Unless required by applicable law or agreed to in writing, software
47141  * distributed under the License is distributed on an "AS IS" BASIS,
47142  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
47143  * See the License for the specific language governing permissions and
47144  * limitations under the License.
47145  */
47146 
47147 // gen_amalgamated expanded: #include "src/tracing/core/trace_buffer.h"
47148 
47149 #include <limits>
47150 
47151 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
47152 // gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
47153 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/shared_memory_abi.h"
47154 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/trace_packet.h"
47155 // gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
47156 
47157 #define TRACE_BUFFER_VERBOSE_LOGGING() 0  // Set to 1 when debugging unittests.
47158 #if TRACE_BUFFER_VERBOSE_LOGGING()
47159 #define TRACE_BUFFER_DLOG PERFETTO_DLOG
47160 #else
47161 #define TRACE_BUFFER_DLOG(...) void()
47162 #endif
47163 
47164 namespace perfetto {
47165 
47166 namespace {
47167 constexpr uint8_t kFirstPacketContinuesFromPrevChunk =
47168     SharedMemoryABI::ChunkHeader::kFirstPacketContinuesFromPrevChunk;
47169 constexpr uint8_t kLastPacketContinuesOnNextChunk =
47170     SharedMemoryABI::ChunkHeader::kLastPacketContinuesOnNextChunk;
47171 constexpr uint8_t kChunkNeedsPatching =
47172     SharedMemoryABI::ChunkHeader::kChunkNeedsPatching;
47173 }  // namespace.
47174 
47175 constexpr size_t TraceBuffer::ChunkRecord::kMaxSize;
47176 constexpr size_t TraceBuffer::InlineChunkHeaderSize = sizeof(ChunkRecord);
47177 
47178 // static
Create(size_t size_in_bytes,OverwritePolicy pol)47179 std::unique_ptr<TraceBuffer> TraceBuffer::Create(size_t size_in_bytes,
47180                                                  OverwritePolicy pol) {
47181   std::unique_ptr<TraceBuffer> trace_buffer(new TraceBuffer(pol));
47182   if (!trace_buffer->Initialize(size_in_bytes))
47183     return nullptr;
47184   return trace_buffer;
47185 }
47186 
TraceBuffer(OverwritePolicy pol)47187 TraceBuffer::TraceBuffer(OverwritePolicy pol) : overwrite_policy_(pol) {
47188   // See comments in ChunkRecord for the rationale of this.
47189   static_assert(sizeof(ChunkRecord) == sizeof(SharedMemoryABI::PageHeader) +
47190                                            sizeof(SharedMemoryABI::ChunkHeader),
47191                 "ChunkRecord out of sync with the layout of SharedMemoryABI");
47192 }
47193 
47194 TraceBuffer::~TraceBuffer() = default;
47195 
Initialize(size_t size)47196 bool TraceBuffer::Initialize(size_t size) {
47197   static_assert(
47198       SharedMemoryABI::kMinPageSize % sizeof(ChunkRecord) == 0,
47199       "sizeof(ChunkRecord) must be an integer divider of a page size");
47200   data_ = base::PagedMemory::Allocate(
47201       size, base::PagedMemory::kMayFail | base::PagedMemory::kDontCommit);
47202   if (!data_.IsValid()) {
47203     PERFETTO_ELOG("Trace buffer allocation failed (size: %zu)", size);
47204     return false;
47205   }
47206   size_ = size;
47207   stats_.set_buffer_size(size);
47208   max_chunk_size_ = std::min(size, ChunkRecord::kMaxSize);
47209   wptr_ = begin();
47210   index_.clear();
47211   last_chunk_id_written_.clear();
47212   read_iter_ = GetReadIterForSequence(index_.end());
47213   return true;
47214 }
47215 
47216 // Note: |src| points to a shmem region that is shared with the producer. Assume
47217 // that the producer is malicious and will change the content of |src|
47218 // 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)47219 void TraceBuffer::CopyChunkUntrusted(ProducerID producer_id_trusted,
47220                                      uid_t producer_uid_trusted,
47221                                      WriterID writer_id,
47222                                      ChunkID chunk_id,
47223                                      uint16_t num_fragments,
47224                                      uint8_t chunk_flags,
47225                                      bool chunk_complete,
47226                                      const uint8_t* src,
47227                                      size_t size) {
47228   // |record_size| = |size| + sizeof(ChunkRecord), rounded up to avoid to end
47229   // up in a fragmented state where size_to_end() < sizeof(ChunkRecord).
47230   const size_t record_size =
47231       base::AlignUp<sizeof(ChunkRecord)>(size + sizeof(ChunkRecord));
47232   if (PERFETTO_UNLIKELY(record_size > max_chunk_size_)) {
47233     stats_.set_abi_violations(stats_.abi_violations() + 1);
47234     PERFETTO_DCHECK(suppress_client_dchecks_for_testing_);
47235     return;
47236   }
47237 
47238   TRACE_BUFFER_DLOG("CopyChunk @ %lu, size=%zu", wptr_ - begin(), record_size);
47239 
47240 #if PERFETTO_DCHECK_IS_ON()
47241   changed_since_last_read_ = true;
47242 #endif
47243 
47244   // If the chunk hasn't been completed, we should only consider the first
47245   // |num_fragments - 1| packets complete. For simplicity, we simply disregard
47246   // the last one when we copy the chunk.
47247   if (PERFETTO_UNLIKELY(!chunk_complete)) {
47248     if (num_fragments > 0) {
47249       num_fragments--;
47250       // These flags should only affect the last packet in the chunk. We clear
47251       // them, so that TraceBuffer is able to look at the remaining packets in
47252       // this chunk.
47253       chunk_flags &= ~kLastPacketContinuesOnNextChunk;
47254       chunk_flags &= ~kChunkNeedsPatching;
47255     }
47256   }
47257 
47258   ChunkRecord record(record_size);
47259   record.producer_id = producer_id_trusted;
47260   record.chunk_id = chunk_id;
47261   record.writer_id = writer_id;
47262   record.num_fragments = num_fragments;
47263   record.flags = chunk_flags;
47264   ChunkMeta::Key key(record);
47265 
47266   // Check whether we have already copied the same chunk previously. This may
47267   // happen if the service scrapes chunks in a potentially incomplete state
47268   // before receiving commit requests for them from the producer. Note that the
47269   // service may scrape and thus override chunks in arbitrary order since the
47270   // chunks aren't ordered in the SMB.
47271   const auto it = index_.find(key);
47272   if (PERFETTO_UNLIKELY(it != index_.end())) {
47273     ChunkMeta* record_meta = &it->second;
47274     ChunkRecord* prev = record_meta->chunk_record;
47275 
47276     // Verify that the old chunk's metadata corresponds to the new one.
47277     // Overridden chunks should never change size, since the page layout is
47278     // fixed per writer. The number of fragments should also never decrease and
47279     // flags should not be removed.
47280     if (PERFETTO_UNLIKELY(ChunkMeta::Key(*prev) != key ||
47281                           prev->size != record_size ||
47282                           prev->num_fragments > num_fragments ||
47283                           (prev->flags & chunk_flags) != prev->flags)) {
47284       stats_.set_abi_violations(stats_.abi_violations() + 1);
47285       PERFETTO_DCHECK(suppress_client_dchecks_for_testing_);
47286       return;
47287     }
47288 
47289     // If this chunk was previously copied with the same number of fragments and
47290     // the number didn't change, there's no need to copy it again. If the
47291     // previous chunk was complete already, this should always be the case.
47292     PERFETTO_DCHECK(suppress_client_dchecks_for_testing_ ||
47293                     !record_meta->is_complete() ||
47294                     (chunk_complete && prev->num_fragments == num_fragments));
47295     if (prev->num_fragments == num_fragments) {
47296       TRACE_BUFFER_DLOG("  skipping recommit of identical chunk");
47297       return;
47298     }
47299 
47300     // If we've already started reading from chunk N+1 following this chunk N,
47301     // don't override chunk N. Otherwise we may end up reading a packet from
47302     // chunk N after having read from chunk N+1, thereby violating sequential
47303     // read of packets. This shouldn't happen if the producer is well-behaved,
47304     // because it shouldn't start chunk N+1 before completing chunk N.
47305     ChunkMeta::Key subsequent_key = key;
47306     static_assert(std::numeric_limits<ChunkID>::max() == kMaxChunkID,
47307                   "ChunkID wraps");
47308     subsequent_key.chunk_id++;
47309     const auto subsequent_it = index_.find(subsequent_key);
47310     if (subsequent_it != index_.end() &&
47311         subsequent_it->second.num_fragments_read > 0) {
47312       stats_.set_abi_violations(stats_.abi_violations() + 1);
47313       PERFETTO_DCHECK(suppress_client_dchecks_for_testing_);
47314       return;
47315     }
47316 
47317     // We should not have read past the last packet.
47318     if (record_meta->num_fragments_read > prev->num_fragments) {
47319       PERFETTO_ELOG(
47320           "TraceBuffer read too many fragments from an incomplete chunk");
47321       PERFETTO_DCHECK(suppress_client_dchecks_for_testing_);
47322       return;
47323     }
47324 
47325     uint8_t* wptr = reinterpret_cast<uint8_t*>(prev);
47326     TRACE_BUFFER_DLOG("  overriding chunk @ %lu, size=%zu", wptr - begin(),
47327                       record_size);
47328 
47329     // Update chunk meta data stored in the index, as it may have changed.
47330     record_meta->num_fragments = num_fragments;
47331     record_meta->flags = chunk_flags;
47332     record_meta->set_complete(chunk_complete);
47333 
47334     // Override the ChunkRecord contents at the original |wptr|.
47335     TRACE_BUFFER_DLOG("  copying @ [%lu - %lu] %zu", wptr - begin(),
47336                       uintptr_t(wptr - begin()) + record_size, record_size);
47337     WriteChunkRecord(wptr, record, src, size);
47338     TRACE_BUFFER_DLOG("Chunk raw: %s",
47339                       base::HexDump(wptr, record_size).c_str());
47340     stats_.set_chunks_rewritten(stats_.chunks_rewritten() + 1);
47341     return;
47342   }
47343 
47344   if (PERFETTO_UNLIKELY(discard_writes_))
47345     return DiscardWrite();
47346 
47347   // If there isn't enough room from the given write position. Write a padding
47348   // record to clear the end of the buffer and wrap back.
47349   const size_t cached_size_to_end = size_to_end();
47350   if (PERFETTO_UNLIKELY(record_size > cached_size_to_end)) {
47351     ssize_t res = DeleteNextChunksFor(cached_size_to_end);
47352     if (res == -1)
47353       return DiscardWrite();
47354     PERFETTO_DCHECK(static_cast<size_t>(res) <= cached_size_to_end);
47355     AddPaddingRecord(cached_size_to_end);
47356     wptr_ = begin();
47357     stats_.set_write_wrap_count(stats_.write_wrap_count() + 1);
47358     PERFETTO_DCHECK(size_to_end() >= record_size);
47359   }
47360 
47361   // At this point either |wptr_| points to an untouched part of the buffer
47362   // (i.e. *wptr_ == 0) or we are about to overwrite one or more ChunkRecord(s).
47363   // In the latter case we need to first figure out where the next valid
47364   // ChunkRecord is (if it exists) and add padding between the new record.
47365   // Example ((w) == write cursor):
47366   //
47367   // Initial state (wtpr_ == 0):
47368   // |0 (w)    |10               |30                  |50
47369   // +---------+-----------------+--------------------+--------------------+
47370   // | Chunk 1 | Chunk 2         | Chunk 3            | Chunk 4            |
47371   // +---------+-----------------+--------------------+--------------------+
47372   //
47373   // Let's assume we now want now write a 5th Chunk of size == 35. The final
47374   // state should look like this:
47375   // |0                                |35 (w)         |50
47376   // +---------------------------------+---------------+--------------------+
47377   // | Chunk 5                         | Padding Chunk | Chunk 4            |
47378   // +---------------------------------+---------------+--------------------+
47379 
47380   // Deletes all chunks from |wptr_| to |wptr_| + |record_size|.
47381   ssize_t del_res = DeleteNextChunksFor(record_size);
47382   if (del_res == -1)
47383     return DiscardWrite();
47384   size_t padding_size = static_cast<size_t>(del_res);
47385 
47386   // Now first insert the new chunk. At the end, if necessary, add the padding.
47387   stats_.set_chunks_written(stats_.chunks_written() + 1);
47388   stats_.set_bytes_written(stats_.bytes_written() + record_size);
47389   auto it_and_inserted = index_.emplace(
47390       key, ChunkMeta(GetChunkRecordAt(wptr_), num_fragments, chunk_complete,
47391                      chunk_flags, producer_uid_trusted));
47392   PERFETTO_DCHECK(it_and_inserted.second);
47393   TRACE_BUFFER_DLOG("  copying @ [%lu - %lu] %zu", wptr_ - begin(),
47394                     uintptr_t(wptr_ - begin()) + record_size, record_size);
47395   WriteChunkRecord(wptr_, record, src, size);
47396   TRACE_BUFFER_DLOG("Chunk raw: %s", base::HexDump(wptr_, record_size).c_str());
47397   wptr_ += record_size;
47398   if (wptr_ >= end()) {
47399     PERFETTO_DCHECK(padding_size == 0);
47400     wptr_ = begin();
47401     stats_.set_write_wrap_count(stats_.write_wrap_count() + 1);
47402   }
47403   DcheckIsAlignedAndWithinBounds(wptr_);
47404 
47405   // Chunks may be received out of order, so only update last_chunk_id if the
47406   // new chunk_id is larger. But take into account overflows by only selecting
47407   // the new ID if its distance to the latest ID is smaller than half the number
47408   // space.
47409   //
47410   // This accounts for both the case where the new ID has just overflown and
47411   // last_chunk_id be updated even though it's smaller (e.g. |chunk_id| = 1 and
47412   // |last_chunk_id| = kMaxChunkId; chunk_id - last_chunk_id = 0) and the case
47413   // where the new ID is an out-of-order ID right after an overflow and
47414   // last_chunk_id shouldn't be updated even though it's larger (e.g. |chunk_id|
47415   // = kMaxChunkId and |last_chunk_id| = 1; chunk_id - last_chunk_id =
47416   // kMaxChunkId - 1).
47417   auto producer_and_writer_id = std::make_pair(producer_id_trusted, writer_id);
47418   ChunkID& last_chunk_id = last_chunk_id_written_[producer_and_writer_id];
47419   static_assert(std::numeric_limits<ChunkID>::max() == kMaxChunkID,
47420                 "This code assumes that ChunkID wraps at kMaxChunkID");
47421   if (chunk_id - last_chunk_id < kMaxChunkID / 2) {
47422     last_chunk_id = chunk_id;
47423   } else {
47424     stats_.set_chunks_committed_out_of_order(
47425         stats_.chunks_committed_out_of_order() + 1);
47426   }
47427 
47428   if (padding_size)
47429     AddPaddingRecord(padding_size);
47430 }
47431 
DeleteNextChunksFor(size_t bytes_to_clear)47432 ssize_t TraceBuffer::DeleteNextChunksFor(size_t bytes_to_clear) {
47433   PERFETTO_CHECK(!discard_writes_);
47434 
47435   // Find the position of the first chunk which begins at or after
47436   // (|wptr_| + |bytes|). Note that such a chunk might not exist and we might
47437   // either reach the end of the buffer or a zeroed region of the buffer.
47438   uint8_t* next_chunk_ptr = wptr_;
47439   uint8_t* search_end = wptr_ + bytes_to_clear;
47440   TRACE_BUFFER_DLOG("Delete [%zu %zu]", wptr_ - begin(), search_end - begin());
47441   DcheckIsAlignedAndWithinBounds(wptr_);
47442   PERFETTO_DCHECK(search_end <= end());
47443   std::vector<ChunkMap::iterator> index_delete;
47444   uint64_t chunks_overwritten = stats_.chunks_overwritten();
47445   uint64_t bytes_overwritten = stats_.bytes_overwritten();
47446   uint64_t padding_bytes_cleared = stats_.padding_bytes_cleared();
47447   while (next_chunk_ptr < search_end) {
47448     const ChunkRecord& next_chunk = *GetChunkRecordAt(next_chunk_ptr);
47449     TRACE_BUFFER_DLOG(
47450         "  scanning chunk [%zu %zu] (valid=%d)", next_chunk_ptr - begin(),
47451         next_chunk_ptr - begin() + next_chunk.size, next_chunk.is_valid());
47452 
47453     // We just reached the untouched part of the buffer, it's going to be all
47454     // zeroes from here to end().
47455     // Optimization: if during Initialize() we fill the buffer with padding
47456     // records we could get rid of this branch.
47457     if (PERFETTO_UNLIKELY(!next_chunk.is_valid())) {
47458       // This should happen only at the first iteration. The zeroed area can
47459       // only begin precisely at the |wptr_|, not after. Otherwise it means that
47460       // we wrapped but screwed up the ChunkRecord chain.
47461       PERFETTO_DCHECK(next_chunk_ptr == wptr_);
47462       return 0;
47463     }
47464 
47465     // Remove |next_chunk| from the index, unless it's a padding record (padding
47466     // records are not part of the index).
47467     if (PERFETTO_LIKELY(!next_chunk.is_padding)) {
47468       ChunkMeta::Key key(next_chunk);
47469       auto it = index_.find(key);
47470       bool will_remove = false;
47471       if (PERFETTO_LIKELY(it != index_.end())) {
47472         const ChunkMeta& meta = it->second;
47473         if (PERFETTO_UNLIKELY(meta.num_fragments_read < meta.num_fragments)) {
47474           if (overwrite_policy_ == kDiscard)
47475             return -1;
47476           chunks_overwritten++;
47477           bytes_overwritten += next_chunk.size;
47478         }
47479         index_delete.push_back(it);
47480         will_remove = true;
47481       }
47482       TRACE_BUFFER_DLOG(
47483           "  del index {%" PRIu32 ",%" PRIu32 ",%u} @ [%lu - %lu] %d",
47484           key.producer_id, key.writer_id, key.chunk_id,
47485           next_chunk_ptr - begin(), next_chunk_ptr - begin() + next_chunk.size,
47486           will_remove);
47487       PERFETTO_DCHECK(will_remove);
47488     } else {
47489       padding_bytes_cleared += next_chunk.size;
47490     }
47491 
47492     next_chunk_ptr += next_chunk.size;
47493 
47494     // We should never hit this, unless we managed to screw up while writing
47495     // to the buffer and breaking the ChunkRecord(s) chain.
47496     // TODO(primiano): Write more meaningful logging with the status of the
47497     // buffer, to get more actionable bugs in case we hit this.
47498     PERFETTO_CHECK(next_chunk_ptr <= end());
47499   }
47500 
47501   // Remove from the index.
47502   for (auto it : index_delete) {
47503     index_.erase(it);
47504   }
47505   stats_.set_chunks_overwritten(chunks_overwritten);
47506   stats_.set_bytes_overwritten(bytes_overwritten);
47507   stats_.set_padding_bytes_cleared(padding_bytes_cleared);
47508 
47509   PERFETTO_DCHECK(next_chunk_ptr >= search_end && next_chunk_ptr <= end());
47510   return static_cast<ssize_t>(next_chunk_ptr - search_end);
47511 }
47512 
AddPaddingRecord(size_t size)47513 void TraceBuffer::AddPaddingRecord(size_t size) {
47514   PERFETTO_DCHECK(size >= sizeof(ChunkRecord) && size <= ChunkRecord::kMaxSize);
47515   ChunkRecord record(size);
47516   record.is_padding = 1;
47517   TRACE_BUFFER_DLOG("AddPaddingRecord @ [%lu - %lu] %zu", wptr_ - begin(),
47518                     uintptr_t(wptr_ - begin()) + size, size);
47519   WriteChunkRecord(wptr_, record, nullptr, size - sizeof(ChunkRecord));
47520   stats_.set_padding_bytes_written(stats_.padding_bytes_written() + size);
47521   // |wptr_| is deliberately not advanced when writing a padding record.
47522 }
47523 
TryPatchChunkContents(ProducerID producer_id,WriterID writer_id,ChunkID chunk_id,const Patch * patches,size_t patches_size,bool other_patches_pending)47524 bool TraceBuffer::TryPatchChunkContents(ProducerID producer_id,
47525                                         WriterID writer_id,
47526                                         ChunkID chunk_id,
47527                                         const Patch* patches,
47528                                         size_t patches_size,
47529                                         bool other_patches_pending) {
47530   ChunkMeta::Key key(producer_id, writer_id, chunk_id);
47531   auto it = index_.find(key);
47532   if (it == index_.end()) {
47533     stats_.set_patches_failed(stats_.patches_failed() + 1);
47534     return false;
47535   }
47536   ChunkMeta& chunk_meta = it->second;
47537 
47538   // Check that the index is consistent with the actual ProducerID/WriterID
47539   // stored in the ChunkRecord.
47540   PERFETTO_DCHECK(ChunkMeta::Key(*chunk_meta.chunk_record) == key);
47541   uint8_t* chunk_begin = reinterpret_cast<uint8_t*>(chunk_meta.chunk_record);
47542   PERFETTO_DCHECK(chunk_begin >= begin());
47543   uint8_t* chunk_end = chunk_begin + chunk_meta.chunk_record->size;
47544   PERFETTO_DCHECK(chunk_end <= end());
47545 
47546   static_assert(Patch::kSize == SharedMemoryABI::kPacketHeaderSize,
47547                 "Patch::kSize out of sync with SharedMemoryABI");
47548 
47549   for (size_t i = 0; i < patches_size; i++) {
47550     uint8_t* ptr =
47551         chunk_begin + sizeof(ChunkRecord) + patches[i].offset_untrusted;
47552     TRACE_BUFFER_DLOG("PatchChunk {%" PRIu32 ",%" PRIu32
47553                       ",%u} size=%zu @ %zu with {%02x %02x %02x %02x} cur "
47554                       "{%02x %02x %02x %02x}",
47555                       producer_id, writer_id, chunk_id, chunk_end - chunk_begin,
47556                       patches[i].offset_untrusted, patches[i].data[0],
47557                       patches[i].data[1], patches[i].data[2],
47558                       patches[i].data[3], ptr[0], ptr[1], ptr[2], ptr[3]);
47559     if (ptr < chunk_begin + sizeof(ChunkRecord) ||
47560         ptr > chunk_end - Patch::kSize) {
47561       // Either the IPC was so slow and in the meantime the writer managed to
47562       // wrap over |chunk_id| or the producer sent a malicious IPC.
47563       stats_.set_patches_failed(stats_.patches_failed() + 1);
47564       return false;
47565     }
47566 
47567     memcpy(ptr, &patches[i].data[0], Patch::kSize);
47568   }
47569   TRACE_BUFFER_DLOG(
47570       "Chunk raw (after patch): %s",
47571       base::HexDump(chunk_begin, chunk_meta.chunk_record->size).c_str());
47572 
47573   stats_.set_patches_succeeded(stats_.patches_succeeded() + patches_size);
47574   if (!other_patches_pending) {
47575     chunk_meta.flags &= ~kChunkNeedsPatching;
47576     chunk_meta.chunk_record->flags = chunk_meta.flags;
47577   }
47578   return true;
47579 }
47580 
BeginRead()47581 void TraceBuffer::BeginRead() {
47582   read_iter_ = GetReadIterForSequence(index_.begin());
47583 #if PERFETTO_DCHECK_IS_ON()
47584   changed_since_last_read_ = false;
47585 #endif
47586 }
47587 
GetReadIterForSequence(ChunkMap::iterator seq_begin)47588 TraceBuffer::SequenceIterator TraceBuffer::GetReadIterForSequence(
47589     ChunkMap::iterator seq_begin) {
47590   SequenceIterator iter;
47591   iter.seq_begin = seq_begin;
47592   if (seq_begin == index_.end()) {
47593     iter.cur = iter.seq_end = index_.end();
47594     return iter;
47595   }
47596 
47597 #if PERFETTO_DCHECK_IS_ON()
47598   // Either |seq_begin| is == index_.begin() or the item immediately before must
47599   // belong to a different {ProducerID, WriterID} sequence.
47600   if (seq_begin != index_.begin() && seq_begin != index_.end()) {
47601     auto prev_it = seq_begin;
47602     prev_it--;
47603     PERFETTO_DCHECK(
47604         seq_begin == index_.begin() ||
47605         std::tie(prev_it->first.producer_id, prev_it->first.writer_id) <
47606             std::tie(seq_begin->first.producer_id, seq_begin->first.writer_id));
47607   }
47608 #endif
47609 
47610   // Find the first entry that has a greater {ProducerID, WriterID} (or just
47611   // index_.end() if we reached the end).
47612   ChunkMeta::Key key = seq_begin->first;  // Deliberate copy.
47613   key.chunk_id = kMaxChunkID;
47614   iter.seq_end = index_.upper_bound(key);
47615   PERFETTO_DCHECK(iter.seq_begin != iter.seq_end);
47616 
47617   // Now find the first entry between [seq_begin, seq_end) that is
47618   // > last_chunk_id_written_. This is where we the sequence will start (see
47619   // notes about wrapping of IDs in the header).
47620   auto producer_and_writer_id = std::make_pair(key.producer_id, key.writer_id);
47621   PERFETTO_DCHECK(last_chunk_id_written_.count(producer_and_writer_id));
47622   iter.wrapping_id = last_chunk_id_written_[producer_and_writer_id];
47623   key.chunk_id = iter.wrapping_id;
47624   iter.cur = index_.upper_bound(key);
47625   if (iter.cur == iter.seq_end)
47626     iter.cur = iter.seq_begin;
47627   return iter;
47628 }
47629 
MoveNext()47630 void TraceBuffer::SequenceIterator::MoveNext() {
47631   // Stop iterating when we reach the end of the sequence.
47632   // Note: |seq_begin| might be == |seq_end|.
47633   if (cur == seq_end || cur->first.chunk_id == wrapping_id) {
47634     cur = seq_end;
47635     return;
47636   }
47637 
47638   // If the current chunk wasn't completed yet, we shouldn't advance past it as
47639   // it may be rewritten with additional packets.
47640   if (!cur->second.is_complete()) {
47641     cur = seq_end;
47642     return;
47643   }
47644 
47645   ChunkID last_chunk_id = cur->first.chunk_id;
47646   if (++cur == seq_end)
47647     cur = seq_begin;
47648 
47649   // There may be a missing chunk in the sequence of chunks, in which case the
47650   // next chunk's ID won't follow the last one's. If so, skip the rest of the
47651   // sequence. We'll return to it later once the hole is filled.
47652   if (last_chunk_id + 1 != cur->first.chunk_id)
47653     cur = seq_end;
47654 }
47655 
ReadNextTracePacket(TracePacket * packet,PacketSequenceProperties * sequence_properties,bool * previous_packet_on_sequence_dropped)47656 bool TraceBuffer::ReadNextTracePacket(
47657     TracePacket* packet,
47658     PacketSequenceProperties* sequence_properties,
47659     bool* previous_packet_on_sequence_dropped) {
47660   // Note: MoveNext() moves only within the next chunk within the same
47661   // {ProducerID, WriterID} sequence. Here we want to:
47662   // - return the next patched+complete packet in the current sequence, if any.
47663   // - return the first patched+complete packet in the next sequence, if any.
47664   // - return false if none of the above is found.
47665   TRACE_BUFFER_DLOG("ReadNextTracePacket()");
47666 
47667   // Just in case we forget to initialize these below.
47668   *sequence_properties = {0, kInvalidUid, 0};
47669   *previous_packet_on_sequence_dropped = false;
47670 
47671   // At the start of each sequence iteration, we consider the last read packet
47672   // dropped. While iterating over the chunks in the sequence, we update this
47673   // flag based on our knowledge about the last packet that was read from each
47674   // chunk (|last_read_packet_skipped| in ChunkMeta).
47675   bool previous_packet_dropped = true;
47676 
47677 #if PERFETTO_DCHECK_IS_ON()
47678   PERFETTO_DCHECK(!changed_since_last_read_);
47679 #endif
47680   for (;; read_iter_.MoveNext()) {
47681     if (PERFETTO_UNLIKELY(!read_iter_.is_valid())) {
47682       // We ran out of chunks in the current {ProducerID, WriterID} sequence or
47683       // we just reached the index_.end().
47684 
47685       if (PERFETTO_UNLIKELY(read_iter_.seq_end == index_.end()))
47686         return false;
47687 
47688       // We reached the end of sequence, move to the next one.
47689       // Note: ++read_iter_.seq_end might become index_.end(), but
47690       // GetReadIterForSequence() knows how to deal with that.
47691       read_iter_ = GetReadIterForSequence(read_iter_.seq_end);
47692       PERFETTO_DCHECK(read_iter_.is_valid() && read_iter_.cur != index_.end());
47693       previous_packet_dropped = true;
47694     }
47695 
47696     ChunkMeta* chunk_meta = &*read_iter_;
47697 
47698     // If the chunk has holes that are awaiting to be patched out-of-band,
47699     // skip the current sequence and move to the next one.
47700     if (chunk_meta->flags & kChunkNeedsPatching) {
47701       read_iter_.MoveToEnd();
47702       continue;
47703     }
47704 
47705     const ProducerID trusted_producer_id = read_iter_.producer_id();
47706     const WriterID writer_id = read_iter_.writer_id();
47707     const uid_t trusted_uid = chunk_meta->trusted_uid;
47708 
47709     // At this point we have a chunk in |chunk_meta| that has not been fully
47710     // read. We don't know yet whether we have enough data to read the full
47711     // packet (in the case it's fragmented over several chunks) and we are about
47712     // to find that out. Specifically:
47713     // A) If the first fragment is unread and is a fragment continuing from a
47714     //    previous chunk, it means we have missed the previous ChunkID. In
47715     //    fact, if this wasn't the case, a previous call to ReadNext() shouldn't
47716     //    have moved the cursor to this chunk.
47717     // B) Any fragment > 0 && < last is always readable. By definition an inner
47718     //    packet is never fragmented and hence doesn't require neither stitching
47719     //    nor any out-of-band patching. The same applies to the last packet
47720     //    iff it doesn't continue on the next chunk.
47721     // C) If the last packet (which might be also the only packet in the chunk)
47722     //    is a fragment and continues on the next chunk, we peek at the next
47723     //    chunks and, if we have all of them, mark as read and move the cursor.
47724     //
47725     // +---------------+   +-------------------+  +---------------+
47726     // | ChunkID: 1    |   | ChunkID: 2        |  | ChunkID: 3    |
47727     // |---------------+   +-------------------+  +---------------+
47728     // | Packet 1      |   |                   |  | ... Packet 3  |
47729     // | Packet 2      |   | ... Packet 3  ... |  | Packet 4      |
47730     // | Packet 3  ... |   |                   |  | Packet 5 ...  |
47731     // +---------------+   +-------------------+  +---------------+
47732 
47733     PERFETTO_DCHECK(chunk_meta->num_fragments_read <=
47734                     chunk_meta->num_fragments);
47735 
47736     // If we didn't read any packets from this chunk, the last packet was from
47737     // the previous chunk we iterated over; so don't update
47738     // |previous_packet_dropped| in this case.
47739     if (chunk_meta->num_fragments_read > 0)
47740       previous_packet_dropped = chunk_meta->last_read_packet_skipped();
47741 
47742     while (chunk_meta->num_fragments_read < chunk_meta->num_fragments) {
47743       enum { kSkip = 0, kReadOnePacket, kTryReadAhead } action;
47744       if (chunk_meta->num_fragments_read == 0) {
47745         if (chunk_meta->flags & kFirstPacketContinuesFromPrevChunk) {
47746           action = kSkip;  // Case A.
47747         } else if (chunk_meta->num_fragments == 1 &&
47748                    (chunk_meta->flags & kLastPacketContinuesOnNextChunk)) {
47749           action = kTryReadAhead;  // Case C.
47750         } else {
47751           action = kReadOnePacket;  // Case B.
47752         }
47753       } else if (chunk_meta->num_fragments_read <
47754                      chunk_meta->num_fragments - 1 ||
47755                  !(chunk_meta->flags & kLastPacketContinuesOnNextChunk)) {
47756         action = kReadOnePacket;  // Case B.
47757       } else {
47758         action = kTryReadAhead;  // Case C.
47759       }
47760 
47761       TRACE_BUFFER_DLOG("  chunk %u, packet %hu of %hu, action=%d",
47762                         read_iter_.chunk_id(), chunk_meta->num_fragments_read,
47763                         chunk_meta->num_fragments, action);
47764 
47765       if (action == kSkip) {
47766         // This fragment will be skipped forever, not just in this ReadPacket()
47767         // iteration. This happens by virtue of ReadNextPacketInChunk()
47768         // incrementing the |num_fragments_read| and marking the fragment as
47769         // read even if we didn't really.
47770         ReadNextPacketInChunk(chunk_meta, nullptr);
47771         chunk_meta->set_last_read_packet_skipped(true);
47772         previous_packet_dropped = true;
47773         continue;
47774       }
47775 
47776       if (action == kReadOnePacket) {
47777         // The easy peasy case B.
47778         ReadPacketResult result = ReadNextPacketInChunk(chunk_meta, packet);
47779 
47780         if (PERFETTO_LIKELY(result == ReadPacketResult::kSucceeded)) {
47781           *sequence_properties = {trusted_producer_id, trusted_uid, writer_id};
47782           *previous_packet_on_sequence_dropped = previous_packet_dropped;
47783           return true;
47784         } else if (result == ReadPacketResult::kFailedEmptyPacket) {
47785           // We can ignore and skip empty packets.
47786           PERFETTO_DCHECK(packet->slices().empty());
47787           continue;
47788         }
47789 
47790         // In extremely rare cases (producer bugged / malicious) the chunk might
47791         // contain an invalid fragment. In such case we don't want to stall the
47792         // sequence but just skip the chunk and move on. ReadNextPacketInChunk()
47793         // marks the chunk as fully read, so we don't attempt to read from it
47794         // again in a future call to ReadBuffers(). It also already records an
47795         // abi violation for this.
47796         PERFETTO_DCHECK(result == ReadPacketResult::kFailedInvalidPacket);
47797         chunk_meta->set_last_read_packet_skipped(true);
47798         previous_packet_dropped = true;
47799         break;
47800       }
47801 
47802       PERFETTO_DCHECK(action == kTryReadAhead);
47803       ReadAheadResult ra_res = ReadAhead(packet);
47804       if (ra_res == ReadAheadResult::kSucceededReturnSlices) {
47805         stats_.set_readaheads_succeeded(stats_.readaheads_succeeded() + 1);
47806         *sequence_properties = {trusted_producer_id, trusted_uid, writer_id};
47807         *previous_packet_on_sequence_dropped = previous_packet_dropped;
47808         return true;
47809       }
47810 
47811       if (ra_res == ReadAheadResult::kFailedMoveToNextSequence) {
47812         // readahead didn't find a contiguous packet sequence. We'll try again
47813         // on the next ReadPacket() call.
47814         stats_.set_readaheads_failed(stats_.readaheads_failed() + 1);
47815 
47816         // TODO(primiano): optimization: this MoveToEnd() is the reason why
47817         // MoveNext() (that is called in the outer for(;;MoveNext)) needs to
47818         // deal gracefully with the case of |cur|==|seq_end|. Maybe we can do
47819         // something to avoid that check by reshuffling the code here?
47820         read_iter_.MoveToEnd();
47821 
47822         // This break will go back to beginning of the for(;;MoveNext()). That
47823         // will move to the next sequence because we set the read iterator to
47824         // its end.
47825         break;
47826       }
47827 
47828       PERFETTO_DCHECK(ra_res == ReadAheadResult::kFailedStayOnSameSequence);
47829 
47830       // In this case ReadAhead() might advance |read_iter_|, so we need to
47831       // re-cache the |chunk_meta| pointer to point to the current chunk.
47832       chunk_meta = &*read_iter_;
47833       chunk_meta->set_last_read_packet_skipped(true);
47834       previous_packet_dropped = true;
47835     }  // while(...)  [iterate over packet fragments for the current chunk].
47836   }    // for(;;MoveNext()) [iterate over chunks].
47837 }
47838 
ReadAhead(TracePacket * packet)47839 TraceBuffer::ReadAheadResult TraceBuffer::ReadAhead(TracePacket* packet) {
47840   static_assert(static_cast<ChunkID>(kMaxChunkID + 1) == 0,
47841                 "relying on kMaxChunkID to wrap naturally");
47842   TRACE_BUFFER_DLOG(" readahead start @ chunk %u", read_iter_.chunk_id());
47843   ChunkID next_chunk_id = read_iter_.chunk_id() + 1;
47844   SequenceIterator it = read_iter_;
47845   for (it.MoveNext(); it.is_valid(); it.MoveNext(), next_chunk_id++) {
47846     // We should stay within the same sequence while iterating here.
47847     PERFETTO_DCHECK(it.producer_id() == read_iter_.producer_id() &&
47848                     it.writer_id() == read_iter_.writer_id());
47849 
47850     TRACE_BUFFER_DLOG("   expected chunk ID: %u, actual ID: %u", next_chunk_id,
47851                       it.chunk_id());
47852 
47853     if (PERFETTO_UNLIKELY((*it).num_fragments == 0))
47854       continue;
47855 
47856     // If we miss the next chunk, stop looking in the current sequence and
47857     // try another sequence. This chunk might come in the near future.
47858     // The second condition is the edge case of a buggy/malicious
47859     // producer. The ChunkID is contiguous but its flags don't make sense.
47860     if (it.chunk_id() != next_chunk_id ||
47861         PERFETTO_UNLIKELY(
47862             !((*it).flags & kFirstPacketContinuesFromPrevChunk))) {
47863       return ReadAheadResult::kFailedMoveToNextSequence;
47864     }
47865 
47866     // If the chunk is contiguous but has not been patched yet move to the next
47867     // sequence and try coming back here on the next ReadNextTracePacket() call.
47868     // TODO(primiano): add a test to cover this, it's a subtle case.
47869     if ((*it).flags & kChunkNeedsPatching)
47870       return ReadAheadResult::kFailedMoveToNextSequence;
47871 
47872     // This is the case of an intermediate chunk which contains only one
47873     // fragment which continues on the next chunk. This is the case for large
47874     // packets, e.g.: [Packet0, Packet1(0)] [Packet1(1)] [Packet1(2), ...]
47875     // (Packet1(X) := fragment X of Packet1).
47876     if ((*it).num_fragments == 1 &&
47877         ((*it).flags & kLastPacketContinuesOnNextChunk)) {
47878       continue;
47879     }
47880 
47881     // We made it! We got all fragments for the packet without holes.
47882     TRACE_BUFFER_DLOG("  readahead success @ chunk %u", it.chunk_id());
47883     PERFETTO_DCHECK(((*it).num_fragments == 1 &&
47884                      !((*it).flags & kLastPacketContinuesOnNextChunk)) ||
47885                     (*it).num_fragments > 1);
47886 
47887     // Now let's re-iterate over the [read_iter_, it] sequence and mark
47888     // all the fragments as read.
47889     bool packet_corruption = false;
47890     for (;;) {
47891       PERFETTO_DCHECK(read_iter_.is_valid());
47892       TRACE_BUFFER_DLOG("    commit chunk %u", read_iter_.chunk_id());
47893       if (PERFETTO_LIKELY((*read_iter_).num_fragments > 0)) {
47894         // In the unlikely case of a corrupted packet (corrupted or empty
47895         // fragment), invalidate the all stitching and move on to the next chunk
47896         // in the same sequence, if any.
47897         packet_corruption |= ReadNextPacketInChunk(&*read_iter_, packet) ==
47898                              ReadPacketResult::kFailedInvalidPacket;
47899       }
47900       if (read_iter_.cur == it.cur)
47901         break;
47902       read_iter_.MoveNext();
47903     }  // for(;;)
47904     PERFETTO_DCHECK(read_iter_.cur == it.cur);
47905 
47906     if (PERFETTO_UNLIKELY(packet_corruption)) {
47907       // ReadNextPacketInChunk() already records an abi violation for this case.
47908       *packet = TracePacket();  // clear.
47909       return ReadAheadResult::kFailedStayOnSameSequence;
47910     }
47911 
47912     return ReadAheadResult::kSucceededReturnSlices;
47913   }  // for(it...)  [readahead loop]
47914   return ReadAheadResult::kFailedMoveToNextSequence;
47915 }
47916 
ReadNextPacketInChunk(ChunkMeta * chunk_meta,TracePacket * packet)47917 TraceBuffer::ReadPacketResult TraceBuffer::ReadNextPacketInChunk(
47918     ChunkMeta* chunk_meta,
47919     TracePacket* packet) {
47920   PERFETTO_DCHECK(chunk_meta->num_fragments_read < chunk_meta->num_fragments);
47921   PERFETTO_DCHECK(!(chunk_meta->flags & kChunkNeedsPatching));
47922 
47923   const uint8_t* record_begin =
47924       reinterpret_cast<const uint8_t*>(chunk_meta->chunk_record);
47925   const uint8_t* record_end = record_begin + chunk_meta->chunk_record->size;
47926   const uint8_t* packets_begin = record_begin + sizeof(ChunkRecord);
47927   const uint8_t* packet_begin = packets_begin + chunk_meta->cur_fragment_offset;
47928 
47929   if (PERFETTO_UNLIKELY(packet_begin < packets_begin ||
47930                         packet_begin >= record_end)) {
47931     // The producer has a bug or is malicious and did declare that the chunk
47932     // contains more packets beyond its boundaries.
47933     stats_.set_abi_violations(stats_.abi_violations() + 1);
47934     PERFETTO_DCHECK(suppress_client_dchecks_for_testing_);
47935     chunk_meta->cur_fragment_offset = 0;
47936     chunk_meta->num_fragments_read = chunk_meta->num_fragments;
47937     if (PERFETTO_LIKELY(chunk_meta->is_complete())) {
47938       stats_.set_chunks_read(stats_.chunks_read() + 1);
47939       stats_.set_bytes_read(stats_.bytes_read() +
47940                             chunk_meta->chunk_record->size);
47941     }
47942     return ReadPacketResult::kFailedInvalidPacket;
47943   }
47944 
47945   // A packet (or a fragment) starts with a varint stating its size, followed
47946   // by its content. The varint shouldn't be larger than 4 bytes (just in case
47947   // the producer is using a redundant encoding)
47948   uint64_t packet_size = 0;
47949   const uint8_t* header_end =
47950       std::min(packet_begin + protozero::proto_utils::kMessageLengthFieldSize,
47951                record_end);
47952   const uint8_t* packet_data = protozero::proto_utils::ParseVarInt(
47953       packet_begin, header_end, &packet_size);
47954 
47955   const uint8_t* next_packet = packet_data + packet_size;
47956   if (PERFETTO_UNLIKELY(next_packet <= packet_begin ||
47957                         next_packet > record_end)) {
47958     // In BufferExhaustedPolicy::kDrop mode, TraceWriter may abort a fragmented
47959     // packet by writing an invalid size in the last fragment's header. We
47960     // should handle this case without recording an ABI violation (since Android
47961     // R).
47962     if (packet_size != SharedMemoryABI::kPacketSizeDropPacket) {
47963       stats_.set_abi_violations(stats_.abi_violations() + 1);
47964       PERFETTO_DCHECK(suppress_client_dchecks_for_testing_);
47965     } else {
47966       stats_.set_trace_writer_packet_loss(stats_.trace_writer_packet_loss() +
47967                                           1);
47968     }
47969     chunk_meta->cur_fragment_offset = 0;
47970     chunk_meta->num_fragments_read = chunk_meta->num_fragments;
47971     if (PERFETTO_LIKELY(chunk_meta->is_complete())) {
47972       stats_.set_chunks_read(stats_.chunks_read() + 1);
47973       stats_.set_bytes_read(stats_.bytes_read() +
47974                             chunk_meta->chunk_record->size);
47975     }
47976     return ReadPacketResult::kFailedInvalidPacket;
47977   }
47978 
47979   chunk_meta->cur_fragment_offset =
47980       static_cast<uint16_t>(next_packet - packets_begin);
47981   chunk_meta->num_fragments_read++;
47982 
47983   if (PERFETTO_UNLIKELY(chunk_meta->num_fragments_read ==
47984                             chunk_meta->num_fragments &&
47985                         chunk_meta->is_complete())) {
47986     stats_.set_chunks_read(stats_.chunks_read() + 1);
47987     stats_.set_bytes_read(stats_.bytes_read() + chunk_meta->chunk_record->size);
47988   } else {
47989     // We have at least one more packet to parse. It should be within the chunk.
47990     if (chunk_meta->cur_fragment_offset + sizeof(ChunkRecord) >=
47991         chunk_meta->chunk_record->size) {
47992       PERFETTO_DCHECK(suppress_client_dchecks_for_testing_);
47993     }
47994   }
47995 
47996   chunk_meta->set_last_read_packet_skipped(false);
47997 
47998   if (PERFETTO_UNLIKELY(packet_size == 0))
47999     return ReadPacketResult::kFailedEmptyPacket;
48000 
48001   if (PERFETTO_LIKELY(packet))
48002     packet->AddSlice(packet_data, static_cast<size_t>(packet_size));
48003 
48004   return ReadPacketResult::kSucceeded;
48005 }
48006 
DiscardWrite()48007 void TraceBuffer::DiscardWrite() {
48008   PERFETTO_DCHECK(overwrite_policy_ == kDiscard);
48009   discard_writes_ = true;
48010   stats_.set_chunks_discarded(stats_.chunks_discarded() + 1);
48011   TRACE_BUFFER_DLOG("  discarding write");
48012 }
48013 
48014 }  // namespace perfetto
48015 // gen_amalgamated begin source: src/tracing/core/tracing_service_impl.cc
48016 // gen_amalgamated begin header: src/tracing/core/tracing_service_impl.h
48017 // gen_amalgamated begin header: include/perfetto/ext/base/circular_queue.h
48018 /*
48019  * Copyright (C) 2019 The Android Open Source Project
48020  *
48021  * Licensed under the Apache License, Version 2.0 (the "License");
48022  * you may not use this file except in compliance with the License.
48023  * You may obtain a copy of the License at
48024  *
48025  *      http://www.apache.org/licenses/LICENSE-2.0
48026  *
48027  * Unless required by applicable law or agreed to in writing, software
48028  * distributed under the License is distributed on an "AS IS" BASIS,
48029  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
48030  * See the License for the specific language governing permissions and
48031  * limitations under the License.
48032  */
48033 
48034 #ifndef INCLUDE_PERFETTO_EXT_BASE_CIRCULAR_QUEUE_H_
48035 #define INCLUDE_PERFETTO_EXT_BASE_CIRCULAR_QUEUE_H_
48036 
48037 #include <stdint.h>
48038 #include <stdlib.h>
48039 
48040 #include <iterator>
48041 
48042 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
48043 // gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
48044 
48045 namespace perfetto {
48046 namespace base {
48047 
48048 // CircularQueue is a push-back-only / pop-front-only queue with the following
48049 // characteristics:
48050 // - The storage is based on a flat circular buffer. Beginning and end wrap
48051 //   as necessary, to keep pushes and pops O(1) as long as capacity expansion is
48052 //   not required.
48053 // - Capacity is automatically expanded like in a std::vector. Expansion has a
48054 //   O(N) cost.
48055 // - It allows random access, allowing in-place std::sort.
48056 // - Iterators are not stable. Mutating the container invalidates all iterators.
48057 // - It doesn't bother with const-correctness.
48058 //
48059 // Implementation details:
48060 // Internally, |begin|, |end| and iterators use 64-bit monotonic indexes, which
48061 // are incremented as if the queue was backed by unlimited storage.
48062 // Even assuming that elements are inserted and removed every nanosecond, 64 bit
48063 // is enough for 584 years.
48064 // Wrapping happens only when addressing elements in the underlying circular
48065 // storage. This limits the complexity and avoiding dealing with modular
48066 // arithmetic all over the places.
48067 template <class T>
48068 class CircularQueue {
48069  public:
48070   class Iterator {
48071    public:
48072     using difference_type = ptrdiff_t;
48073     using value_type = T;
48074     using pointer = T*;
48075     using reference = T&;
48076     using iterator_category = std::random_access_iterator_tag;
48077 
Iterator(CircularQueue * queue,uint64_t pos,uint32_t generation)48078     Iterator(CircularQueue* queue, uint64_t pos, uint32_t generation)
48079         : queue_(queue),
48080           pos_(pos)
48081 #if PERFETTO_DCHECK_IS_ON()
48082           ,
48083           generation_(generation)
48084 #endif
48085     {
48086       ignore_result(generation);
48087     }
48088 
48089     Iterator(const Iterator&) noexcept = default;
48090     Iterator& operator=(const Iterator&) noexcept = default;
48091     Iterator(Iterator&&) noexcept = default;
48092     Iterator& operator=(Iterator&&) noexcept = default;
48093 
operator ->() const48094     T* operator->() const {
48095 #if PERFETTO_DCHECK_IS_ON()
48096       PERFETTO_DCHECK(generation_ == queue_->generation());
48097 #endif
48098       return queue_->Get(pos_);
48099     }
48100 
operator *() const48101     T& operator*() const { return *(operator->()); }
48102 
operator [](difference_type i)48103     value_type& operator[](difference_type i) { return *(*this + i); }
48104 
operator ++()48105     Iterator& operator++() {
48106       Add(1);
48107       return *this;
48108     }
48109 
operator ++(int)48110     Iterator operator++(int) {
48111       Iterator ret = *this;
48112       Add(1);
48113       return ret;
48114     }
48115 
operator --()48116     Iterator& operator--() {
48117       Add(-1);
48118       return *this;
48119     }
48120 
operator --(int)48121     Iterator operator--(int) {
48122       Iterator ret = *this;
48123       Add(-1);
48124       return ret;
48125     }
48126 
operator +(const Iterator & iter,difference_type offset)48127     friend Iterator operator+(const Iterator& iter, difference_type offset) {
48128       Iterator ret = iter;
48129       ret.Add(offset);
48130       return ret;
48131     }
48132 
operator +=(difference_type offset)48133     Iterator& operator+=(difference_type offset) {
48134       Add(offset);
48135       return *this;
48136     }
48137 
operator -(const Iterator & iter,difference_type offset)48138     friend Iterator operator-(const Iterator& iter, difference_type offset) {
48139       Iterator ret = iter;
48140       ret.Add(-offset);
48141       return ret;
48142     }
48143 
operator -=(difference_type offset)48144     Iterator& operator-=(difference_type offset) {
48145       Add(-offset);
48146       return *this;
48147     }
48148 
operator -(const Iterator & lhs,const Iterator & rhs)48149     friend ptrdiff_t operator-(const Iterator& lhs, const Iterator& rhs) {
48150       return static_cast<ptrdiff_t>(lhs.pos_) -
48151              static_cast<ptrdiff_t>(rhs.pos_);
48152     }
48153 
operator ==(const Iterator & lhs,const Iterator & rhs)48154     friend bool operator==(const Iterator& lhs, const Iterator& rhs) {
48155       return lhs.pos_ == rhs.pos_;
48156     }
48157 
operator !=(const Iterator & lhs,const Iterator & rhs)48158     friend bool operator!=(const Iterator& lhs, const Iterator& rhs) {
48159       return lhs.pos_ != rhs.pos_;
48160     }
48161 
operator <(const Iterator & lhs,const Iterator & rhs)48162     friend bool operator<(const Iterator& lhs, const Iterator& rhs) {
48163       return lhs.pos_ < rhs.pos_;
48164     }
48165 
operator <=(const Iterator & lhs,const Iterator & rhs)48166     friend bool operator<=(const Iterator& lhs, const Iterator& rhs) {
48167       return lhs.pos_ <= rhs.pos_;
48168     }
48169 
operator >(const Iterator & lhs,const Iterator & rhs)48170     friend bool operator>(const Iterator& lhs, const Iterator& rhs) {
48171       return lhs.pos_ > rhs.pos_;
48172     }
48173 
operator >=(const Iterator & lhs,const Iterator & rhs)48174     friend bool operator>=(const Iterator& lhs, const Iterator& rhs) {
48175       return lhs.pos_ >= rhs.pos_;
48176     }
48177 
48178    private:
Add(difference_type offset)48179     inline void Add(difference_type offset) {
48180       pos_ = static_cast<uint64_t>(static_cast<difference_type>(pos_) + offset);
48181       PERFETTO_DCHECK(pos_ <= queue_->end_);
48182     }
48183 
48184     CircularQueue* queue_;
48185     uint64_t pos_;
48186 
48187 #if PERFETTO_DCHECK_IS_ON()
48188     uint32_t generation_;
48189 #endif
48190   };
48191 
CircularQueue(size_t initial_capacity=1024)48192   explicit CircularQueue(size_t initial_capacity = 1024) {
48193     Grow(initial_capacity);
48194   }
48195 
CircularQueue(CircularQueue && other)48196   CircularQueue(CircularQueue&& other) noexcept
48197       : entries_(std::move(other.entries_)),
48198         capacity_(other.capacity_),
48199         begin_(other.begin_),
48200         end_(other.end_) {
48201     increment_generation();
48202     new (&other) CircularQueue();  // Reset the old queue so it's still usable.
48203   }
48204 
operator =(CircularQueue && other)48205   CircularQueue& operator=(CircularQueue&& other) noexcept {
48206     this->~CircularQueue();                      // Destroy the current state.
48207     new (this) CircularQueue(std::move(other));  // Use the move ctor above.
48208     return *this;
48209   }
48210 
~CircularQueue()48211   ~CircularQueue() {
48212     if (!entries_) {
48213       PERFETTO_DCHECK(empty());
48214       return;
48215     }
48216     clear();  // Invoke destructors on all alive entries.
48217     PERFETTO_DCHECK(empty());
48218   }
48219 
48220   template <typename... Args>
emplace_back(Args &&...args)48221   void emplace_back(Args&&... args) {
48222     increment_generation();
48223     if (PERFETTO_UNLIKELY(size() >= capacity_))
48224       Grow();
48225     T* slot = Get(end_++);
48226     new (slot) T(std::forward<Args>(args)...);
48227   }
48228 
erase_front(size_t n)48229   void erase_front(size_t n) {
48230     increment_generation();
48231     for (; n && (begin_ < end_); --n) {
48232       Get(begin_)->~T();
48233       begin_++;  // This needs to be its own statement, Get() checks begin_.
48234     }
48235   }
48236 
pop_front()48237   void pop_front() { erase_front(1); }
48238 
clear()48239   void clear() { erase_front(size()); }
48240 
at(size_t idx)48241   T& at(size_t idx) {
48242     PERFETTO_DCHECK(idx < size());
48243     return *Get(begin_ + idx);
48244   }
48245 
begin()48246   Iterator begin() { return Iterator(this, begin_, generation()); }
end()48247   Iterator end() { return Iterator(this, end_, generation()); }
front()48248   T& front() { return *begin(); }
back()48249   T& back() { return *(end() - 1); }
48250 
empty() const48251   bool empty() const { return size() == 0; }
48252 
size() const48253   size_t size() const {
48254     PERFETTO_DCHECK(end_ - begin_ <= capacity_);
48255     return static_cast<size_t>(end_ - begin_);
48256   }
48257 
capacity() const48258   size_t capacity() const { return capacity_; }
48259 
48260 #if PERFETTO_DCHECK_IS_ON()
generation() const48261   uint32_t generation() const { return generation_; }
increment_generation()48262   void increment_generation() { ++generation_; }
48263 #else
generation() const48264   uint32_t generation() const { return 0; }
increment_generation()48265   void increment_generation() {}
48266 #endif
48267 
48268  private:
48269   CircularQueue(const CircularQueue&) = delete;
48270   CircularQueue& operator=(const CircularQueue&) = delete;
48271 
Grow(size_t new_capacity=0)48272   void Grow(size_t new_capacity = 0) {
48273     // Capacity must be always a power of two. This allows Get() to use a simple
48274     // bitwise-AND for handling the wrapping instead of a full division.
48275     new_capacity = new_capacity ? new_capacity : capacity_ * 2;
48276     PERFETTO_CHECK((new_capacity & (new_capacity - 1)) == 0);  // Must be pow2.
48277 
48278     // On 32-bit systems this might hit the 4GB wall and overflow. We can't do
48279     // anything other than crash in this case.
48280     PERFETTO_CHECK(new_capacity > capacity_);
48281 
48282     AlignedUniquePtr<T[]> new_vec = AlignedAllocTyped<T[]>(new_capacity);
48283 
48284     // Move all elements in the expanded array.
48285     size_t new_size = 0;
48286     for (uint64_t i = begin_; i < end_; i++)
48287       new (&new_vec[new_size++]) T(std::move(*Get(i)));  // Placement move ctor.
48288 
48289     // Even if all the elements are std::move()-d and likely empty, we are still
48290     // required to call the dtor for them.
48291     for (uint64_t i = begin_; i < end_; i++)
48292       Get(i)->~T();
48293 
48294     begin_ = 0;
48295     end_ = new_size;
48296     capacity_ = new_capacity;
48297     entries_ = std::move(new_vec);
48298   }
48299 
Get(uint64_t pos)48300   inline T* Get(uint64_t pos) {
48301     PERFETTO_DCHECK(pos >= begin_ && pos < end_);
48302     PERFETTO_DCHECK((capacity_ & (capacity_ - 1)) == 0);  // Must be a pow2.
48303     auto index = static_cast<size_t>(pos & (capacity_ - 1));
48304     return &entries_[index];
48305   }
48306 
48307   // Underlying storage. It's raw malloc-ed rather than being a unique_ptr<T[]>
48308   // to allow having uninitialized entries inside it.
48309   AlignedUniquePtr<T[]> entries_;
48310   size_t capacity_ = 0;  // Number of allocated slots (NOT bytes) in |entries_|.
48311 
48312   // The |begin_| and |end_| indexes are monotonic and never wrap. Modular arith
48313   // is used only when dereferencing entries in the vector.
48314   uint64_t begin_ = 0;
48315   uint64_t end_ = 0;
48316 
48317 // Generation is used in debug builds only for checking iterator validity.
48318 #if PERFETTO_DCHECK_IS_ON()
48319   uint32_t generation_ = 0;
48320 #endif
48321 };
48322 
48323 }  // namespace base
48324 }  // namespace perfetto
48325 
48326 #endif  // INCLUDE_PERFETTO_EXT_BASE_CIRCULAR_QUEUE_H_
48327 /*
48328  * Copyright (C) 2017 The Android Open Source Project
48329  *
48330  * Licensed under the Apache License, Version 2.0 (the "License");
48331  * you may not use this file except in compliance with the License.
48332  * You may obtain a copy of the License at
48333  *
48334  *      http://www.apache.org/licenses/LICENSE-2.0
48335  *
48336  * Unless required by applicable law or agreed to in writing, software
48337  * distributed under the License is distributed on an "AS IS" BASIS,
48338  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
48339  * See the License for the specific language governing permissions and
48340  * limitations under the License.
48341  */
48342 
48343 #ifndef SRC_TRACING_CORE_TRACING_SERVICE_IMPL_H_
48344 #define SRC_TRACING_CORE_TRACING_SERVICE_IMPL_H_
48345 
48346 #include <algorithm>
48347 #include <functional>
48348 #include <map>
48349 #include <memory>
48350 #include <mutex>
48351 #include <random>
48352 #include <set>
48353 #include <utility>
48354 #include <vector>
48355 
48356 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
48357 // gen_amalgamated expanded: #include "perfetto/base/status.h"
48358 // gen_amalgamated expanded: #include "perfetto/base/time.h"
48359 // gen_amalgamated expanded: #include "perfetto/ext/base/circular_queue.h"
48360 // gen_amalgamated expanded: #include "perfetto/ext/base/optional.h"
48361 // gen_amalgamated expanded: #include "perfetto/ext/base/periodic_task.h"
48362 // gen_amalgamated expanded: #include "perfetto/ext/base/weak_ptr.h"
48363 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/basic_types.h"
48364 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/commit_data_request.h"
48365 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/observable_events.h"
48366 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/shared_memory_abi.h"
48367 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/trace_stats.h"
48368 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/tracing_service.h"
48369 // gen_amalgamated expanded: #include "perfetto/tracing/core/data_source_config.h"
48370 // gen_amalgamated expanded: #include "perfetto/tracing/core/data_source_descriptor.h"
48371 // gen_amalgamated expanded: #include "perfetto/tracing/core/forward_decls.h"
48372 // gen_amalgamated expanded: #include "perfetto/tracing/core/trace_config.h"
48373 // gen_amalgamated expanded: #include "src/android_stats/perfetto_atoms.h"
48374 // gen_amalgamated expanded: #include "src/tracing/core/id_allocator.h"
48375 
48376 namespace protozero {
48377 class MessageFilter;
48378 }
48379 
48380 namespace perfetto {
48381 
48382 namespace base {
48383 class TaskRunner;
48384 }  // namespace base
48385 
48386 class Consumer;
48387 class Producer;
48388 class SharedMemory;
48389 class SharedMemoryArbiterImpl;
48390 class TraceBuffer;
48391 class TracePacket;
48392 
48393 // The tracing service business logic.
48394 class TracingServiceImpl : public TracingService {
48395  private:
48396   struct DataSourceInstance;
48397 
48398  public:
48399   static constexpr size_t kDefaultShmPageSize = 4096ul;
48400   static constexpr size_t kDefaultShmSize = 256 * 1024ul;
48401   static constexpr size_t kMaxShmSize = 32 * 1024 * 1024ul;
48402   static constexpr uint32_t kDataSourceStopTimeoutMs = 5000;
48403   static constexpr uint8_t kSyncMarker[] = {0x82, 0x47, 0x7a, 0x76, 0xb2, 0x8d,
48404                                             0x42, 0xba, 0x81, 0xdc, 0x33, 0x32,
48405                                             0x6d, 0x57, 0xa0, 0x79};
48406   static constexpr size_t kMaxTracePacketSliceSize =
48407       128 * 1024 - 512;  // This is ipc::kIPCBufferSize - 512, see assertion in
48408                          // tracing_integration_test.cc and b/195065199
48409 
48410   // The implementation behind the service endpoint exposed to each producer.
48411   class ProducerEndpointImpl : public TracingService::ProducerEndpoint {
48412    public:
48413     ProducerEndpointImpl(ProducerID,
48414                          uid_t uid,
48415                          TracingServiceImpl*,
48416                          base::TaskRunner*,
48417                          Producer*,
48418                          const std::string& producer_name,
48419                          const std::string& sdk_version,
48420                          bool in_process,
48421                          bool smb_scraping_enabled);
48422     ~ProducerEndpointImpl() override;
48423 
48424     // TracingService::ProducerEndpoint implementation.
48425     void RegisterDataSource(const DataSourceDescriptor&) override;
48426     void UpdateDataSource(const DataSourceDescriptor&) override;
48427     void UnregisterDataSource(const std::string& name) override;
48428     void RegisterTraceWriter(uint32_t writer_id,
48429                              uint32_t target_buffer) override;
48430     void UnregisterTraceWriter(uint32_t writer_id) override;
48431     void CommitData(const CommitDataRequest&, CommitDataCallback) override;
48432     void SetupSharedMemory(std::unique_ptr<SharedMemory>,
48433                            size_t page_size_bytes,
48434                            bool provided_by_producer);
48435     std::unique_ptr<TraceWriter> CreateTraceWriter(
48436         BufferID,
48437         BufferExhaustedPolicy) override;
48438     SharedMemoryArbiter* MaybeSharedMemoryArbiter() override;
48439     bool IsShmemProvidedByProducer() const override;
48440     void NotifyFlushComplete(FlushRequestID) override;
48441     void NotifyDataSourceStarted(DataSourceInstanceID) override;
48442     void NotifyDataSourceStopped(DataSourceInstanceID) override;
48443     SharedMemory* shared_memory() const override;
48444     size_t shared_buffer_page_size_kb() const override;
48445     void ActivateTriggers(const std::vector<std::string>&) override;
48446     void Sync(std::function<void()> callback) override;
48447 
48448     void OnTracingSetup();
48449     void SetupDataSource(DataSourceInstanceID, const DataSourceConfig&);
48450     void StartDataSource(DataSourceInstanceID, const DataSourceConfig&);
48451     void StopDataSource(DataSourceInstanceID);
48452     void Flush(FlushRequestID, const std::vector<DataSourceInstanceID>&);
48453     void OnFreeBuffers(const std::vector<BufferID>& target_buffers);
48454     void ClearIncrementalState(const std::vector<DataSourceInstanceID>&);
48455 
is_allowed_target_buffer(BufferID buffer_id) const48456     bool is_allowed_target_buffer(BufferID buffer_id) const {
48457       return allowed_target_buffers_.count(buffer_id);
48458     }
48459 
buffer_id_for_writer(WriterID writer_id) const48460     base::Optional<BufferID> buffer_id_for_writer(WriterID writer_id) const {
48461       const auto it = writers_.find(writer_id);
48462       if (it != writers_.end())
48463         return it->second;
48464       return base::nullopt;
48465     }
48466 
uid() const48467     uid_t uid() const { return uid_; }
48468 
48469    private:
48470     friend class TracingServiceImpl;
48471     friend class TracingServiceImplTest;
48472     friend class TracingIntegrationTest;
48473     ProducerEndpointImpl(const ProducerEndpointImpl&) = delete;
48474     ProducerEndpointImpl& operator=(const ProducerEndpointImpl&) = delete;
48475 
48476     ProducerID const id_;
48477     const uid_t uid_;
48478     TracingServiceImpl* const service_;
48479     base::TaskRunner* const task_runner_;
48480     Producer* producer_;
48481     std::unique_ptr<SharedMemory> shared_memory_;
48482     size_t shared_buffer_page_size_kb_ = 0;
48483     SharedMemoryABI shmem_abi_;
48484     size_t shmem_size_hint_bytes_ = 0;
48485     size_t shmem_page_size_hint_bytes_ = 0;
48486     bool is_shmem_provided_by_producer_ = false;
48487     const std::string name_;
48488     std::string sdk_version_;
48489     bool in_process_;
48490     bool smb_scraping_enabled_;
48491 
48492     // Set of the global target_buffer IDs that the producer is configured to
48493     // write into in any active tracing session.
48494     std::set<BufferID> allowed_target_buffers_;
48495 
48496     // Maps registered TraceWriter IDs to their target buffers as registered by
48497     // the producer. Note that producers aren't required to register their
48498     // writers, so we may see commits of chunks with WriterIDs that aren't
48499     // contained in this map. However, if a producer does register a writer, the
48500     // service will prevent the writer from writing into any other buffer than
48501     // the one associated with it here. The BufferIDs stored in this map are
48502     // untrusted, so need to be verified against |allowed_target_buffers_|
48503     // before use.
48504     std::map<WriterID, BufferID> writers_;
48505 
48506     // This is used only in in-process configurations.
48507     // SharedMemoryArbiterImpl methods themselves are thread-safe.
48508     std::unique_ptr<SharedMemoryArbiterImpl> inproc_shmem_arbiter_;
48509 
48510     PERFETTO_THREAD_CHECKER(thread_checker_)
48511     base::WeakPtrFactory<ProducerEndpointImpl> weak_ptr_factory_;  // Keep last.
48512   };
48513 
48514   // The implementation behind the service endpoint exposed to each consumer.
48515   class ConsumerEndpointImpl : public TracingService::ConsumerEndpoint {
48516    public:
48517     ConsumerEndpointImpl(TracingServiceImpl*,
48518                          base::TaskRunner*,
48519                          Consumer*,
48520                          uid_t uid);
48521     ~ConsumerEndpointImpl() override;
48522 
48523     void NotifyOnTracingDisabled(const std::string& error);
48524 
48525     // TracingService::ConsumerEndpoint implementation.
48526     void EnableTracing(const TraceConfig&, base::ScopedFile) override;
48527     void ChangeTraceConfig(const TraceConfig& cfg) override;
48528     void StartTracing() override;
48529     void DisableTracing() override;
48530     void ReadBuffers() override;
48531     void FreeBuffers() override;
48532     void Flush(uint32_t timeout_ms, FlushCallback) override;
48533     void Detach(const std::string& key) override;
48534     void Attach(const std::string& key) override;
48535     void GetTraceStats() override;
48536     void ObserveEvents(uint32_t enabled_event_types) override;
48537     void QueryServiceState(QueryServiceStateCallback) override;
48538     void QueryCapabilities(QueryCapabilitiesCallback) override;
48539     void SaveTraceForBugreport(SaveTraceForBugreportCallback) override;
48540 
48541     // Will queue a task to notify the consumer about the state change.
48542     void OnDataSourceInstanceStateChange(const ProducerEndpointImpl&,
48543                                          const DataSourceInstance&);
48544     void OnAllDataSourcesStarted();
48545 
48546    private:
48547     friend class TracingServiceImpl;
48548     ConsumerEndpointImpl(const ConsumerEndpointImpl&) = delete;
48549     ConsumerEndpointImpl& operator=(const ConsumerEndpointImpl&) = delete;
48550 
48551     // Returns a pointer to an ObservableEvents object that the caller can fill
48552     // and schedules a task to send the ObservableEvents to the consumer.
48553     ObservableEvents* AddObservableEvents();
48554 
48555     base::TaskRunner* const task_runner_;
48556     TracingServiceImpl* const service_;
48557     Consumer* const consumer_;
48558     uid_t const uid_;
48559     TracingSessionID tracing_session_id_ = 0;
48560 
48561     // Whether the consumer is interested in DataSourceInstance state change
48562     // events.
48563     uint32_t observable_events_mask_ = 0;
48564 
48565     // ObservableEvents that will be sent to the consumer. If set, a task to
48566     // flush the events to the consumer has been queued.
48567     std::unique_ptr<ObservableEvents> observable_events_;
48568 
48569     PERFETTO_THREAD_CHECKER(thread_checker_)
48570     base::WeakPtrFactory<ConsumerEndpointImpl> weak_ptr_factory_;  // Keep last.
48571   };
48572 
48573   explicit TracingServiceImpl(std::unique_ptr<SharedMemory::Factory>,
48574                               base::TaskRunner*);
48575   ~TracingServiceImpl() override;
48576 
48577   // Called by ProducerEndpointImpl.
48578   void DisconnectProducer(ProducerID);
48579   void RegisterDataSource(ProducerID, const DataSourceDescriptor&);
48580   void UpdateDataSource(ProducerID, const DataSourceDescriptor&);
48581   void UnregisterDataSource(ProducerID, const std::string& name);
48582   void CopyProducerPageIntoLogBuffer(ProducerID,
48583                                      uid_t,
48584                                      WriterID,
48585                                      ChunkID,
48586                                      BufferID,
48587                                      uint16_t num_fragments,
48588                                      uint8_t chunk_flags,
48589                                      bool chunk_complete,
48590                                      const uint8_t* src,
48591                                      size_t size);
48592   void ApplyChunkPatches(ProducerID,
48593                          const std::vector<CommitDataRequest::ChunkToPatch>&);
48594   void NotifyFlushDoneForProducer(ProducerID, FlushRequestID);
48595   void NotifyDataSourceStarted(ProducerID, const DataSourceInstanceID);
48596   void NotifyDataSourceStopped(ProducerID, const DataSourceInstanceID);
48597   void ActivateTriggers(ProducerID, const std::vector<std::string>& triggers);
48598 
48599   // Called by ConsumerEndpointImpl.
48600   bool DetachConsumer(ConsumerEndpointImpl*, const std::string& key);
48601   bool AttachConsumer(ConsumerEndpointImpl*, const std::string& key);
48602   void DisconnectConsumer(ConsumerEndpointImpl*);
48603   base::Status EnableTracing(ConsumerEndpointImpl*,
48604                              const TraceConfig&,
48605                              base::ScopedFile);
48606   void ChangeTraceConfig(ConsumerEndpointImpl*, const TraceConfig&);
48607 
48608   base::Status StartTracing(TracingSessionID);
48609   void DisableTracing(TracingSessionID, bool disable_immediately = false);
48610   void Flush(TracingSessionID tsid,
48611              uint32_t timeout_ms,
48612              ConsumerEndpoint::FlushCallback);
48613   void FlushAndDisableTracing(TracingSessionID);
48614 
48615   // Starts reading the internal tracing buffers from the tracing session `tsid`
48616   // and sends them to `*consumer` (which must be != nullptr).
48617   //
48618   // Only reads a limited amount of data in one call. If there's more data,
48619   // immediately schedules itself on a PostTask.
48620   //
48621   // Returns false in case of error.
48622   bool ReadBuffersIntoConsumer(TracingSessionID tsid,
48623                                ConsumerEndpointImpl* consumer);
48624 
48625   // Reads all the tracing buffers from the tracing session `tsid` and writes
48626   // them into the associated file.
48627   //
48628   // Reads all the data in the buffers (or until the file is full) before
48629   // returning.
48630   //
48631   // If the tracing session write_period_ms is 0, the file is full or there has
48632   // been an error, flushes the file and closes it. Otherwise, schedules itself
48633   // to be executed after write_period_ms.
48634   //
48635   // Returns false in case of error.
48636   bool ReadBuffersIntoFile(TracingSessionID);
48637 
48638   void FreeBuffers(TracingSessionID);
48639 
48640   // Service implementation.
48641   std::unique_ptr<TracingService::ProducerEndpoint> ConnectProducer(
48642       Producer*,
48643       uid_t uid,
48644       const std::string& producer_name,
48645       size_t shared_memory_size_hint_bytes = 0,
48646       bool in_process = false,
48647       ProducerSMBScrapingMode smb_scraping_mode =
48648           ProducerSMBScrapingMode::kDefault,
48649       size_t shared_memory_page_size_hint_bytes = 0,
48650       std::unique_ptr<SharedMemory> shm = nullptr,
48651       const std::string& sdk_version = {}) override;
48652 
48653   std::unique_ptr<TracingService::ConsumerEndpoint> ConnectConsumer(
48654       Consumer*,
48655       uid_t) override;
48656 
48657   // Set whether SMB scraping should be enabled by default or not. Producers can
48658   // override this setting for their own SMBs.
SetSMBScrapingEnabled(bool enabled)48659   void SetSMBScrapingEnabled(bool enabled) override {
48660     smb_scraping_enabled_ = enabled;
48661   }
48662 
48663   // Exposed mainly for testing.
num_producers() const48664   size_t num_producers() const { return producers_.size(); }
48665   ProducerEndpointImpl* GetProducer(ProducerID) const;
48666 
48667  private:
48668   friend class TracingServiceImplTest;
48669   friend class TracingIntegrationTest;
48670 
48671   static constexpr int64_t kOneDayInNs = 24ll * 60 * 60 * 1000 * 1000 * 1000;
48672 
48673   struct TriggerHistory {
48674     int64_t timestamp_ns;
48675     uint64_t name_hash;
48676 
operator <perfetto::TracingServiceImpl::TriggerHistory48677     bool operator<(const TriggerHistory& other) const {
48678       return timestamp_ns < other.timestamp_ns;
48679     }
48680   };
48681 
48682   struct RegisteredDataSource {
48683     ProducerID producer_id;
48684     DataSourceDescriptor descriptor;
48685   };
48686 
48687   // Represents an active data source for a tracing session.
48688   struct DataSourceInstance {
DataSourceInstanceperfetto::TracingServiceImpl::DataSourceInstance48689     DataSourceInstance(DataSourceInstanceID id,
48690                        const DataSourceConfig& cfg,
48691                        const std::string& ds_name,
48692                        bool notify_on_start,
48693                        bool notify_on_stop,
48694                        bool handles_incremental_state_invalidation)
48695         : instance_id(id),
48696           config(cfg),
48697           data_source_name(ds_name),
48698           will_notify_on_start(notify_on_start),
48699           will_notify_on_stop(notify_on_stop),
48700           handles_incremental_state_clear(
48701               handles_incremental_state_invalidation) {}
48702     DataSourceInstance(const DataSourceInstance&) = delete;
48703     DataSourceInstance& operator=(const DataSourceInstance&) = delete;
48704 
48705     DataSourceInstanceID instance_id;
48706     DataSourceConfig config;
48707     std::string data_source_name;
48708     bool will_notify_on_start;
48709     bool will_notify_on_stop;
48710     bool handles_incremental_state_clear;
48711 
48712     enum DataSourceInstanceState {
48713       CONFIGURED,
48714       STARTING,
48715       STARTED,
48716       STOPPING,
48717       STOPPED
48718     };
48719     DataSourceInstanceState state = CONFIGURED;
48720   };
48721 
48722   struct PendingFlush {
48723     std::set<ProducerID> producers;
48724     ConsumerEndpoint::FlushCallback callback;
PendingFlushperfetto::TracingServiceImpl::PendingFlush48725     explicit PendingFlush(decltype(callback) cb) : callback(std::move(cb)) {}
48726   };
48727 
48728   // Holds the state of a tracing session. A tracing session is uniquely bound
48729   // a specific Consumer. Each Consumer can own one or more sessions.
48730   struct TracingSession {
48731     enum State {
48732       DISABLED = 0,
48733       CONFIGURED,
48734       STARTED,
48735       DISABLING_WAITING_STOP_ACKS
48736     };
48737 
48738     TracingSession(TracingSessionID,
48739                    ConsumerEndpointImpl*,
48740                    const TraceConfig&,
48741                    base::TaskRunner*);
48742     TracingSession(TracingSession&&) = delete;
48743     TracingSession& operator=(TracingSession&&) = delete;
48744 
num_buffersperfetto::TracingServiceImpl::TracingSession48745     size_t num_buffers() const { return buffers_index.size(); }
48746 
delay_to_next_write_period_msperfetto::TracingServiceImpl::TracingSession48747     uint32_t delay_to_next_write_period_ms() const {
48748       PERFETTO_DCHECK(write_period_ms > 0);
48749       return write_period_ms -
48750              static_cast<uint32_t>(base::GetWallTimeMs().count() %
48751                                    write_period_ms);
48752     }
48753 
flush_timeout_msperfetto::TracingServiceImpl::TracingSession48754     uint32_t flush_timeout_ms() {
48755       uint32_t timeout_ms = config.flush_timeout_ms();
48756       return timeout_ms ? timeout_ms : kDefaultFlushTimeoutMs;
48757     }
48758 
data_source_stop_timeout_msperfetto::TracingServiceImpl::TracingSession48759     uint32_t data_source_stop_timeout_ms() {
48760       uint32_t timeout_ms = config.data_source_stop_timeout_ms();
48761       return timeout_ms ? timeout_ms : kDataSourceStopTimeoutMs;
48762     }
48763 
GetPacketSequenceIDperfetto::TracingServiceImpl::TracingSession48764     PacketSequenceID GetPacketSequenceID(ProducerID producer_id,
48765                                          WriterID writer_id) {
48766       auto key = std::make_pair(producer_id, writer_id);
48767       auto it = packet_sequence_ids.find(key);
48768       if (it != packet_sequence_ids.end())
48769         return it->second;
48770       // We shouldn't run out of sequence IDs (producer ID is 16 bit, writer IDs
48771       // are limited to 1024).
48772       static_assert(kMaxPacketSequenceID > kMaxProducerID * kMaxWriterID,
48773                     "PacketSequenceID value space doesn't cover service "
48774                     "sequence ID and all producer/writer ID combinations!");
48775       PERFETTO_DCHECK(last_packet_sequence_id < kMaxPacketSequenceID);
48776       PacketSequenceID sequence_id = ++last_packet_sequence_id;
48777       packet_sequence_ids[key] = sequence_id;
48778       return sequence_id;
48779     }
48780 
GetDataSourceInstanceperfetto::TracingServiceImpl::TracingSession48781     DataSourceInstance* GetDataSourceInstance(
48782         ProducerID producer_id,
48783         DataSourceInstanceID instance_id) {
48784       for (auto& inst_kv : data_source_instances) {
48785         if (inst_kv.first != producer_id ||
48786             inst_kv.second.instance_id != instance_id) {
48787           continue;
48788         }
48789         return &inst_kv.second;
48790       }
48791       return nullptr;
48792     }
48793 
AllDataSourceInstancesStartedperfetto::TracingServiceImpl::TracingSession48794     bool AllDataSourceInstancesStarted() {
48795       return std::all_of(
48796           data_source_instances.begin(), data_source_instances.end(),
48797           [](decltype(data_source_instances)::const_reference x) {
48798             return x.second.state == DataSourceInstance::STARTED;
48799           });
48800     }
48801 
AllDataSourceInstancesStoppedperfetto::TracingServiceImpl::TracingSession48802     bool AllDataSourceInstancesStopped() {
48803       return std::all_of(
48804           data_source_instances.begin(), data_source_instances.end(),
48805           [](decltype(data_source_instances)::const_reference x) {
48806             return x.second.state == DataSourceInstance::STOPPED;
48807           });
48808     }
48809 
48810     const TracingSessionID id;
48811 
48812     // The consumer that started the session.
48813     // Can be nullptr if the consumer detached from the session.
48814     ConsumerEndpointImpl* consumer_maybe_null;
48815 
48816     // Unix uid of the consumer. This is valid even after the consumer detaches
48817     // and does not change for the entire duration of the session. It is used to
48818     // prevent that a consumer re-attaches to a session from a different uid.
48819     uid_t const consumer_uid;
48820 
48821     // The list of triggers this session received while alive and the time they
48822     // were received at. This is used to insert 'fake' packets back to the
48823     // consumer so they can tell when some event happened. The order matches the
48824     // order they were received.
48825     struct TriggerInfo {
48826       uint64_t boot_time_ns;
48827       std::string trigger_name;
48828       std::string producer_name;
48829       uid_t producer_uid;
48830     };
48831     std::vector<TriggerInfo> received_triggers;
48832 
48833     // The trace config provided by the Consumer when calling
48834     // EnableTracing(), plus any updates performed by ChangeTraceConfig.
48835     TraceConfig config;
48836 
48837     // List of data source instances that have been enabled on the various
48838     // producers for this tracing session.
48839     // TODO(rsavitski): at the time of writing, the map structure is unused
48840     // (even when the calling code has a key). This is also an opportunity to
48841     // consider an alternative data type, e.g. a map of vectors.
48842     std::multimap<ProducerID, DataSourceInstance> data_source_instances;
48843 
48844     // For each Flush(N) request, keeps track of the set of producers for which
48845     // we are still awaiting a NotifyFlushComplete(N) ack.
48846     std::map<FlushRequestID, PendingFlush> pending_flushes;
48847 
48848     // Maps a per-trace-session buffer index into the corresponding global
48849     // BufferID (shared namespace amongst all consumers). This vector has as
48850     // many entries as |config.buffers_size()|.
48851     std::vector<BufferID> buffers_index;
48852 
48853     std::map<std::pair<ProducerID, WriterID>, PacketSequenceID>
48854         packet_sequence_ids;
48855     PacketSequenceID last_packet_sequence_id = kServicePacketSequenceID;
48856 
48857     // Whether we should emit the trace stats next time we reach EOF while
48858     // performing ReadBuffers.
48859     bool should_emit_stats = false;
48860 
48861     // Whether we should emit the sync marker the next time ReadBuffers() is
48862     // called.
48863     bool should_emit_sync_marker = false;
48864 
48865     // Whether we mirrored the trace config back to the trace output yet.
48866     bool did_emit_config = false;
48867 
48868     // Whether we put the system info into the trace output yet.
48869     bool did_emit_system_info = false;
48870 
48871     // The number of received triggers we've emitted into the trace output.
48872     size_t num_triggers_emitted_into_trace = 0;
48873 
48874     // Packets that failed validation of the TrustedPacket.
48875     uint64_t invalid_packets = 0;
48876 
48877     // Set to true on the first call to MaybeNotifyAllDataSourcesStarted().
48878     bool did_notify_all_data_source_started = false;
48879 
48880     // Stores all lifecycle events of a particular type (i.e. associated with a
48881     // single field id in the TracingServiceEvent proto).
48882     struct LifecycleEvent {
LifecycleEventperfetto::TracingServiceImpl::TracingSession::LifecycleEvent48883       LifecycleEvent(uint32_t f_id, uint32_t m_size = 1)
48884           : field_id(f_id), max_size(m_size), timestamps(m_size) {}
48885 
48886       // The field id of the event in the TracingServiceEvent proto.
48887       uint32_t field_id;
48888 
48889       // Stores the max size of |timestamps|. Set to 1 by default (in
48890       // the constructor) but can be overriden in TraceSession constructor
48891       // if a larger size is required.
48892       uint32_t max_size;
48893 
48894       // Stores the timestamps emitted for each event type (in nanoseconds).
48895       // Emitted into the trace and cleared when the consumer next calls
48896       // ReadBuffers.
48897       base::CircularQueue<int64_t> timestamps;
48898     };
48899     std::vector<LifecycleEvent> lifecycle_events;
48900 
48901     using ClockSnapshotData =
48902         std::vector<std::pair<uint32_t /*clock_id*/, uint64_t /*ts*/>>;
48903 
48904     // Initial clock snapshot, captured at trace start time (when state goes to
48905     // TracingSession::STARTED). Emitted into the trace when the consumer first
48906     // calls ReadBuffers().
48907     ClockSnapshotData initial_clock_snapshot;
48908 
48909     // Stores clock snapshots to emit into the trace as a ring buffer. This
48910     // buffer is populated both periodically and when lifecycle events happen
48911     // but only when significant clock drift is detected. Emitted into the trace
48912     // and cleared when the consumer next calls ReadBuffers().
48913     base::CircularQueue<ClockSnapshotData> clock_snapshot_ring_buffer;
48914 
48915     State state = DISABLED;
48916 
48917     // If the consumer detached the session, this variable defines the key used
48918     // for identifying the session later when reattaching.
48919     std::string detach_key;
48920 
48921     // This is set when the Consumer calls sets |write_into_file| == true in the
48922     // TraceConfig. In this case this represents the file we should stream the
48923     // trace packets into, rather than returning it to the consumer via
48924     // OnTraceData().
48925     base::ScopedFile write_into_file;
48926     uint32_t write_period_ms = 0;
48927     uint64_t max_file_size_bytes = 0;
48928     uint64_t bytes_written_into_file = 0;
48929 
48930     // Set when using SaveTraceForBugreport(). This callback will be called
48931     // when the tracing session ends and the data has been saved into the file.
48932     std::function<void()> on_disable_callback_for_bugreport;
48933     bool seized_for_bugreport = false;
48934 
48935     // Periodic task for snapshotting service events (e.g. clocks, sync markers
48936     // etc)
48937     base::PeriodicTask snapshot_periodic_task;
48938 
48939     // When non-NULL the packets should be post-processed using the filter.
48940     std::unique_ptr<protozero::MessageFilter> trace_filter;
48941     uint64_t filter_input_packets = 0;
48942     uint64_t filter_input_bytes = 0;
48943     uint64_t filter_output_bytes = 0;
48944     uint64_t filter_errors = 0;
48945   };
48946 
48947   TracingServiceImpl(const TracingServiceImpl&) = delete;
48948   TracingServiceImpl& operator=(const TracingServiceImpl&) = delete;
48949 
48950   DataSourceInstance* SetupDataSource(const TraceConfig::DataSource&,
48951                                       const TraceConfig::ProducerConfig&,
48952                                       const RegisteredDataSource&,
48953                                       TracingSession*);
48954 
48955   // Returns the next available ProducerID that is not in |producers_|.
48956   ProducerID GetNextProducerID();
48957 
48958   // Returns a pointer to the |tracing_sessions_| entry or nullptr if the
48959   // session doesn't exists.
48960   TracingSession* GetTracingSession(TracingSessionID);
48961 
48962   // Returns a pointer to the |tracing_sessions_| entry, matching the given
48963   // uid and detach key, or nullptr if no such session exists.
48964   TracingSession* GetDetachedSession(uid_t, const std::string& key);
48965 
48966   // Update the memory guard rail by using the latest information from the
48967   // shared memory and trace buffers.
48968   void UpdateMemoryGuardrail();
48969 
48970   void StartDataSourceInstance(ProducerEndpointImpl*,
48971                                TracingSession*,
48972                                DataSourceInstance*);
48973   void StopDataSourceInstance(ProducerEndpointImpl*,
48974                               TracingSession*,
48975                               DataSourceInstance*,
48976                               bool disable_immediately);
48977   void PeriodicSnapshotTask(TracingSessionID);
48978   void MaybeSnapshotClocksIntoRingBuffer(TracingSession*);
48979   bool SnapshotClocks(TracingSession::ClockSnapshotData*);
48980   void SnapshotLifecyleEvent(TracingSession*,
48981                              uint32_t field_id,
48982                              bool snapshot_clocks);
48983   void EmitClockSnapshot(TracingSession*,
48984                          TracingSession::ClockSnapshotData,
48985                          std::vector<TracePacket>*);
48986   void EmitSyncMarker(std::vector<TracePacket>*);
48987   void EmitStats(TracingSession*, std::vector<TracePacket>*);
48988   TraceStats GetTraceStats(TracingSession*);
48989   void EmitLifecycleEvents(TracingSession*, std::vector<TracePacket>*);
48990   void EmitSeizedForBugreportLifecycleEvent(std::vector<TracePacket>*);
48991   void MaybeEmitTraceConfig(TracingSession*, std::vector<TracePacket>*);
48992   void MaybeEmitSystemInfo(TracingSession*, std::vector<TracePacket>*);
48993   void MaybeEmitReceivedTriggers(TracingSession*, std::vector<TracePacket>*);
48994   void MaybeNotifyAllDataSourcesStarted(TracingSession*);
48995   bool MaybeSaveTraceForBugreport(std::function<void()> callback);
48996   void OnFlushTimeout(TracingSessionID, FlushRequestID);
48997   void OnDisableTracingTimeout(TracingSessionID);
48998   void DisableTracingNotifyConsumerAndFlushFile(TracingSession*);
48999   void PeriodicFlushTask(TracingSessionID, bool post_next_only);
49000   void CompleteFlush(TracingSessionID tsid,
49001                      ConsumerEndpoint::FlushCallback callback,
49002                      bool success);
49003   void ScrapeSharedMemoryBuffers(TracingSession*, ProducerEndpointImpl*);
49004   void PeriodicClearIncrementalStateTask(TracingSessionID, bool post_next_only);
49005   TraceBuffer* GetBufferByID(BufferID);
49006   bool ReadBuffers(TracingSessionID, TracingSession*, ConsumerEndpointImpl*);
49007   // Returns true if `*tracing_session` is waiting for a trigger that hasn't
49008   // happened.
49009   static bool IsWaitingForTrigger(TracingSession*);
49010   void OnStartTriggersTimeout(TracingSessionID tsid);
49011   void MaybeLogUploadEvent(const TraceConfig&,
49012                            PerfettoStatsdAtom atom,
49013                            const std::string& trigger_name = "");
49014   void MaybeLogTriggerEvent(const TraceConfig&,
49015                             PerfettoTriggerAtom atom,
49016                             const std::string& trigger_name);
49017   size_t PurgeExpiredAndCountTriggerInWindow(int64_t now_ns,
49018                                              uint64_t trigger_name_hash);
49019 
49020   base::TaskRunner* const task_runner_;
49021   std::unique_ptr<SharedMemory::Factory> shm_factory_;
49022   ProducerID last_producer_id_ = 0;
49023   DataSourceInstanceID last_data_source_instance_id_ = 0;
49024   TracingSessionID last_tracing_session_id_ = 0;
49025   FlushRequestID last_flush_request_id_ = 0;
49026   uid_t uid_ = 0;
49027 
49028   // Buffer IDs are global across all consumers (because a Producer can produce
49029   // data for more than one trace session, hence more than one consumer).
49030   IdAllocator<BufferID> buffer_ids_;
49031 
49032   std::multimap<std::string /*name*/, RegisteredDataSource> data_sources_;
49033   std::map<ProducerID, ProducerEndpointImpl*> producers_;
49034   std::set<ConsumerEndpointImpl*> consumers_;
49035   std::map<TracingSessionID, TracingSession> tracing_sessions_;
49036   std::map<BufferID, std::unique_ptr<TraceBuffer>> buffers_;
49037   std::map<std::string, int64_t> session_to_last_trace_s_;
49038 
49039   // Contains timestamps of triggers.
49040   // The queue is sorted by timestamp and invocations older than
49041   // |trigger_window_ns_| are purged when a trigger happens.
49042   base::CircularQueue<TriggerHistory> trigger_history_;
49043 
49044   bool smb_scraping_enabled_ = false;
49045   bool lockdown_mode_ = false;
49046   uint32_t min_write_period_ms_ = 100;       // Overridable for testing.
49047   int64_t trigger_window_ns_ = kOneDayInNs;  // Overridable for testing.
49048 
49049   std::minstd_rand trigger_probability_rand_;
49050   std::uniform_real_distribution<> trigger_probability_dist_;
49051   double trigger_rnd_override_for_testing_ = 0;  // Overridable for testing.
49052 
49053   uint8_t sync_marker_packet_[32];  // Lazily initialized.
49054   size_t sync_marker_packet_size_ = 0;
49055 
49056   // Stats.
49057   uint64_t chunks_discarded_ = 0;
49058   uint64_t patches_discarded_ = 0;
49059 
49060   PERFETTO_THREAD_CHECKER(thread_checker_)
49061 
49062   base::WeakPtrFactory<TracingServiceImpl>
49063       weak_ptr_factory_;  // Keep at the end.
49064 };
49065 
49066 }  // namespace perfetto
49067 
49068 #endif  // SRC_TRACING_CORE_TRACING_SERVICE_IMPL_H_
49069 // gen_amalgamated begin header: include/perfetto/tracing/core/tracing_service_capabilities.h
49070 /*
49071  * Copyright (C) 2020 The Android Open Source Project
49072  *
49073  * Licensed under the Apache License, Version 2.0 (the "License");
49074  * you may not use this file except in compliance with the License.
49075  * You may obtain a copy of the License at
49076  *
49077  *      http://www.apache.org/licenses/LICENSE-2.0
49078  *
49079  * Unless required by applicable law or agreed to in writing, software
49080  * distributed under the License is distributed on an "AS IS" BASIS,
49081  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
49082  * See the License for the specific language governing permissions and
49083  * limitations under the License.
49084  */
49085 
49086 #ifndef INCLUDE_PERFETTO_TRACING_CORE_TRACING_SERVICE_CAPABILITIES_H_
49087 #define INCLUDE_PERFETTO_TRACING_CORE_TRACING_SERVICE_CAPABILITIES_H_
49088 
49089 // Creates the aliases in the ::perfetto namespace, doing things like:
49090 // using ::perfetto::Foo = ::perfetto::protos::gen::Foo.
49091 // See comments in forward_decls.h for the historical reasons of this
49092 // indirection layer.
49093 // gen_amalgamated expanded: #include "perfetto/tracing/core/forward_decls.h"
49094 
49095 // gen_amalgamated expanded: #include "protos/perfetto/common/tracing_service_capabilities.gen.h"
49096 
49097 #endif  // INCLUDE_PERFETTO_TRACING_CORE_TRACING_SERVICE_CAPABILITIES_H_
49098 // gen_amalgamated begin header: gen/protos/perfetto/common/trace_stats.pbzero.h
49099 // Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
49100 
49101 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_TRACE_STATS_PROTO_H_
49102 #define PERFETTO_PROTOS_PROTOS_PERFETTO_COMMON_TRACE_STATS_PROTO_H_
49103 
49104 #include <stddef.h>
49105 #include <stdint.h>
49106 
49107 // gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
49108 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
49109 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
49110 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
49111 // gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
49112 
49113 namespace perfetto {
49114 namespace protos {
49115 namespace pbzero {
49116 
49117 class TraceStats_BufferStats;
49118 class TraceStats_FilterStats;
49119 
49120 class TraceStats_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/11, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
49121  public:
TraceStats_Decoder(const uint8_t * data,size_t len)49122   TraceStats_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
TraceStats_Decoder(const std::string & raw)49123   explicit TraceStats_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
TraceStats_Decoder(const::protozero::ConstBytes & raw)49124   explicit TraceStats_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
has_buffer_stats() const49125   bool has_buffer_stats() const { return at<1>().valid(); }
buffer_stats() const49126   ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> buffer_stats() const { return GetRepeated<::protozero::ConstBytes>(1); }
has_producers_connected() const49127   bool has_producers_connected() const { return at<2>().valid(); }
producers_connected() const49128   uint32_t producers_connected() const { return at<2>().as_uint32(); }
has_producers_seen() const49129   bool has_producers_seen() const { return at<3>().valid(); }
producers_seen() const49130   uint64_t producers_seen() const { return at<3>().as_uint64(); }
has_data_sources_registered() const49131   bool has_data_sources_registered() const { return at<4>().valid(); }
data_sources_registered() const49132   uint32_t data_sources_registered() const { return at<4>().as_uint32(); }
has_data_sources_seen() const49133   bool has_data_sources_seen() const { return at<5>().valid(); }
data_sources_seen() const49134   uint64_t data_sources_seen() const { return at<5>().as_uint64(); }
has_tracing_sessions() const49135   bool has_tracing_sessions() const { return at<6>().valid(); }
tracing_sessions() const49136   uint32_t tracing_sessions() const { return at<6>().as_uint32(); }
has_total_buffers() const49137   bool has_total_buffers() const { return at<7>().valid(); }
total_buffers() const49138   uint32_t total_buffers() const { return at<7>().as_uint32(); }
has_chunks_discarded() const49139   bool has_chunks_discarded() const { return at<8>().valid(); }
chunks_discarded() const49140   uint64_t chunks_discarded() const { return at<8>().as_uint64(); }
has_patches_discarded() const49141   bool has_patches_discarded() const { return at<9>().valid(); }
patches_discarded() const49142   uint64_t patches_discarded() const { return at<9>().as_uint64(); }
has_invalid_packets() const49143   bool has_invalid_packets() const { return at<10>().valid(); }
invalid_packets() const49144   uint64_t invalid_packets() const { return at<10>().as_uint64(); }
has_filter_stats() const49145   bool has_filter_stats() const { return at<11>().valid(); }
filter_stats() const49146   ::protozero::ConstBytes filter_stats() const { return at<11>().as_bytes(); }
49147 };
49148 
49149 class TraceStats : public ::protozero::Message {
49150  public:
49151   using Decoder = TraceStats_Decoder;
49152   enum : int32_t {
49153     kBufferStatsFieldNumber = 1,
49154     kProducersConnectedFieldNumber = 2,
49155     kProducersSeenFieldNumber = 3,
49156     kDataSourcesRegisteredFieldNumber = 4,
49157     kDataSourcesSeenFieldNumber = 5,
49158     kTracingSessionsFieldNumber = 6,
49159     kTotalBuffersFieldNumber = 7,
49160     kChunksDiscardedFieldNumber = 8,
49161     kPatchesDiscardedFieldNumber = 9,
49162     kInvalidPacketsFieldNumber = 10,
49163     kFilterStatsFieldNumber = 11,
49164   };
49165   using BufferStats = ::perfetto::protos::pbzero::TraceStats_BufferStats;
49166   using FilterStats = ::perfetto::protos::pbzero::TraceStats_FilterStats;
49167 
49168   using FieldMetadata_BufferStats =
49169     ::protozero::proto_utils::FieldMetadata<
49170       1,
49171       ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
49172       ::protozero::proto_utils::ProtoSchemaType::kMessage,
49173       TraceStats_BufferStats,
49174       TraceStats>;
49175 
49176   // Ceci n'est pas une pipe.
49177   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
49178   // type (and users are expected to use it as such, hence kCamelCase name).
49179   // It is declared as a function to keep protozero bindings header-only as
49180   // inline constexpr variables are not available until C++17 (while inline
49181   // functions are).
49182   // TODO(altimin): Use inline variable instead after adopting C++17.
kBufferStats()49183   static constexpr FieldMetadata_BufferStats kBufferStats() { return {}; }
add_buffer_stats()49184   template <typename T = TraceStats_BufferStats> T* add_buffer_stats() {
49185     return BeginNestedMessage<T>(1);
49186   }
49187 
49188 
49189   using FieldMetadata_ProducersConnected =
49190     ::protozero::proto_utils::FieldMetadata<
49191       2,
49192       ::protozero::proto_utils::RepetitionType::kNotRepeated,
49193       ::protozero::proto_utils::ProtoSchemaType::kUint32,
49194       uint32_t,
49195       TraceStats>;
49196 
49197   // Ceci n'est pas une pipe.
49198   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
49199   // type (and users are expected to use it as such, hence kCamelCase name).
49200   // It is declared as a function to keep protozero bindings header-only as
49201   // inline constexpr variables are not available until C++17 (while inline
49202   // functions are).
49203   // TODO(altimin): Use inline variable instead after adopting C++17.
kProducersConnected()49204   static constexpr FieldMetadata_ProducersConnected kProducersConnected() { return {}; }
set_producers_connected(uint32_t value)49205   void set_producers_connected(uint32_t value) {
49206     static constexpr uint32_t field_id = FieldMetadata_ProducersConnected::kFieldId;
49207     // Call the appropriate protozero::Message::Append(field_id, ...)
49208     // method based on the type of the field.
49209     ::protozero::internal::FieldWriter<
49210       ::protozero::proto_utils::ProtoSchemaType::kUint32>
49211         ::Append(*this, field_id, value);
49212   }
49213 
49214   using FieldMetadata_ProducersSeen =
49215     ::protozero::proto_utils::FieldMetadata<
49216       3,
49217       ::protozero::proto_utils::RepetitionType::kNotRepeated,
49218       ::protozero::proto_utils::ProtoSchemaType::kUint64,
49219       uint64_t,
49220       TraceStats>;
49221 
49222   // Ceci n'est pas une pipe.
49223   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
49224   // type (and users are expected to use it as such, hence kCamelCase name).
49225   // It is declared as a function to keep protozero bindings header-only as
49226   // inline constexpr variables are not available until C++17 (while inline
49227   // functions are).
49228   // TODO(altimin): Use inline variable instead after adopting C++17.
kProducersSeen()49229   static constexpr FieldMetadata_ProducersSeen kProducersSeen() { return {}; }
set_producers_seen(uint64_t value)49230   void set_producers_seen(uint64_t value) {
49231     static constexpr uint32_t field_id = FieldMetadata_ProducersSeen::kFieldId;
49232     // Call the appropriate protozero::Message::Append(field_id, ...)
49233     // method based on the type of the field.
49234     ::protozero::internal::FieldWriter<
49235       ::protozero::proto_utils::ProtoSchemaType::kUint64>
49236         ::Append(*this, field_id, value);
49237   }
49238 
49239   using FieldMetadata_DataSourcesRegistered =
49240     ::protozero::proto_utils::FieldMetadata<
49241       4,
49242       ::protozero::proto_utils::RepetitionType::kNotRepeated,
49243       ::protozero::proto_utils::ProtoSchemaType::kUint32,
49244       uint32_t,
49245       TraceStats>;
49246 
49247   // Ceci n'est pas une pipe.
49248   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
49249   // type (and users are expected to use it as such, hence kCamelCase name).
49250   // It is declared as a function to keep protozero bindings header-only as
49251   // inline constexpr variables are not available until C++17 (while inline
49252   // functions are).
49253   // TODO(altimin): Use inline variable instead after adopting C++17.
kDataSourcesRegistered()49254   static constexpr FieldMetadata_DataSourcesRegistered kDataSourcesRegistered() { return {}; }
set_data_sources_registered(uint32_t value)49255   void set_data_sources_registered(uint32_t value) {
49256     static constexpr uint32_t field_id = FieldMetadata_DataSourcesRegistered::kFieldId;
49257     // Call the appropriate protozero::Message::Append(field_id, ...)
49258     // method based on the type of the field.
49259     ::protozero::internal::FieldWriter<
49260       ::protozero::proto_utils::ProtoSchemaType::kUint32>
49261         ::Append(*this, field_id, value);
49262   }
49263 
49264   using FieldMetadata_DataSourcesSeen =
49265     ::protozero::proto_utils::FieldMetadata<
49266       5,
49267       ::protozero::proto_utils::RepetitionType::kNotRepeated,
49268       ::protozero::proto_utils::ProtoSchemaType::kUint64,
49269       uint64_t,
49270       TraceStats>;
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.
kDataSourcesSeen()49279   static constexpr FieldMetadata_DataSourcesSeen kDataSourcesSeen() { return {}; }
set_data_sources_seen(uint64_t value)49280   void set_data_sources_seen(uint64_t value) {
49281     static constexpr uint32_t field_id = FieldMetadata_DataSourcesSeen::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::kUint64>
49286         ::Append(*this, field_id, value);
49287   }
49288 
49289   using FieldMetadata_TracingSessions =
49290     ::protozero::proto_utils::FieldMetadata<
49291       6,
49292       ::protozero::proto_utils::RepetitionType::kNotRepeated,
49293       ::protozero::proto_utils::ProtoSchemaType::kUint32,
49294       uint32_t,
49295       TraceStats>;
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.
kTracingSessions()49304   static constexpr FieldMetadata_TracingSessions kTracingSessions() { return {}; }
set_tracing_sessions(uint32_t value)49305   void set_tracing_sessions(uint32_t value) {
49306     static constexpr uint32_t field_id = FieldMetadata_TracingSessions::kFieldId;
49307     // Call the appropriate protozero::Message::Append(field_id, ...)
49308     // method based on the type of the field.
49309     ::protozero::internal::FieldWriter<
49310       ::protozero::proto_utils::ProtoSchemaType::kUint32>
49311         ::Append(*this, field_id, value);
49312   }
49313 
49314   using FieldMetadata_TotalBuffers =
49315     ::protozero::proto_utils::FieldMetadata<
49316       7,
49317       ::protozero::proto_utils::RepetitionType::kNotRepeated,
49318       ::protozero::proto_utils::ProtoSchemaType::kUint32,
49319       uint32_t,
49320       TraceStats>;
49321 
49322   // Ceci n'est pas une pipe.
49323   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
49324   // type (and users are expected to use it as such, hence kCamelCase name).
49325   // It is declared as a function to keep protozero bindings header-only as
49326   // inline constexpr variables are not available until C++17 (while inline
49327   // functions are).
49328   // TODO(altimin): Use inline variable instead after adopting C++17.
kTotalBuffers()49329   static constexpr FieldMetadata_TotalBuffers kTotalBuffers() { return {}; }
set_total_buffers(uint32_t value)49330   void set_total_buffers(uint32_t value) {
49331     static constexpr uint32_t field_id = FieldMetadata_TotalBuffers::kFieldId;
49332     // Call the appropriate protozero::Message::Append(field_id, ...)
49333     // method based on the type of the field.
49334     ::protozero::internal::FieldWriter<
49335       ::protozero::proto_utils::ProtoSchemaType::kUint32>
49336         ::Append(*this, field_id, value);
49337   }
49338 
49339   using FieldMetadata_ChunksDiscarded =
49340     ::protozero::proto_utils::FieldMetadata<
49341       8,
49342       ::protozero::proto_utils::RepetitionType::kNotRepeated,
49343       ::protozero::proto_utils::ProtoSchemaType::kUint64,
49344       uint64_t,
49345       TraceStats>;
49346 
49347   // Ceci n'est pas une pipe.
49348   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
49349   // type (and users are expected to use it as such, hence kCamelCase name).
49350   // It is declared as a function to keep protozero bindings header-only as
49351   // inline constexpr variables are not available until C++17 (while inline
49352   // functions are).
49353   // TODO(altimin): Use inline variable instead after adopting C++17.
kChunksDiscarded()49354   static constexpr FieldMetadata_ChunksDiscarded kChunksDiscarded() { return {}; }
set_chunks_discarded(uint64_t value)49355   void set_chunks_discarded(uint64_t value) {
49356     static constexpr uint32_t field_id = FieldMetadata_ChunksDiscarded::kFieldId;
49357     // Call the appropriate protozero::Message::Append(field_id, ...)
49358     // method based on the type of the field.
49359     ::protozero::internal::FieldWriter<
49360       ::protozero::proto_utils::ProtoSchemaType::kUint64>
49361         ::Append(*this, field_id, value);
49362   }
49363 
49364   using FieldMetadata_PatchesDiscarded =
49365     ::protozero::proto_utils::FieldMetadata<
49366       9,
49367       ::protozero::proto_utils::RepetitionType::kNotRepeated,
49368       ::protozero::proto_utils::ProtoSchemaType::kUint64,
49369       uint64_t,
49370       TraceStats>;
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.
kPatchesDiscarded()49379   static constexpr FieldMetadata_PatchesDiscarded kPatchesDiscarded() { return {}; }
set_patches_discarded(uint64_t value)49380   void set_patches_discarded(uint64_t value) {
49381     static constexpr uint32_t field_id = FieldMetadata_PatchesDiscarded::kFieldId;
49382     // Call the appropriate protozero::Message::Append(field_id, ...)
49383     // method based on the type of the field.
49384     ::protozero::internal::FieldWriter<
49385       ::protozero::proto_utils::ProtoSchemaType::kUint64>
49386         ::Append(*this, field_id, value);
49387   }
49388 
49389   using FieldMetadata_InvalidPackets =
49390     ::protozero::proto_utils::FieldMetadata<
49391       10,
49392       ::protozero::proto_utils::RepetitionType::kNotRepeated,
49393       ::protozero::proto_utils::ProtoSchemaType::kUint64,
49394       uint64_t,
49395       TraceStats>;
49396 
49397   // Ceci n'est pas une pipe.
49398   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
49399   // type (and users are expected to use it as such, hence kCamelCase name).
49400   // It is declared as a function to keep protozero bindings header-only as
49401   // inline constexpr variables are not available until C++17 (while inline
49402   // functions are).
49403   // TODO(altimin): Use inline variable instead after adopting C++17.
kInvalidPackets()49404   static constexpr FieldMetadata_InvalidPackets kInvalidPackets() { return {}; }
set_invalid_packets(uint64_t value)49405   void set_invalid_packets(uint64_t value) {
49406     static constexpr uint32_t field_id = FieldMetadata_InvalidPackets::kFieldId;
49407     // Call the appropriate protozero::Message::Append(field_id, ...)
49408     // method based on the type of the field.
49409     ::protozero::internal::FieldWriter<
49410       ::protozero::proto_utils::ProtoSchemaType::kUint64>
49411         ::Append(*this, field_id, value);
49412   }
49413 
49414   using FieldMetadata_FilterStats =
49415     ::protozero::proto_utils::FieldMetadata<
49416       11,
49417       ::protozero::proto_utils::RepetitionType::kNotRepeated,
49418       ::protozero::proto_utils::ProtoSchemaType::kMessage,
49419       TraceStats_FilterStats,
49420       TraceStats>;
49421 
49422   // Ceci n'est pas une pipe.
49423   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
49424   // type (and users are expected to use it as such, hence kCamelCase name).
49425   // It is declared as a function to keep protozero bindings header-only as
49426   // inline constexpr variables are not available until C++17 (while inline
49427   // functions are).
49428   // TODO(altimin): Use inline variable instead after adopting C++17.
kFilterStats()49429   static constexpr FieldMetadata_FilterStats kFilterStats() { return {}; }
set_filter_stats()49430   template <typename T = TraceStats_FilterStats> T* set_filter_stats() {
49431     return BeginNestedMessage<T>(11);
49432   }
49433 
49434 };
49435 
49436 class TraceStats_FilterStats_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
49437  public:
TraceStats_FilterStats_Decoder(const uint8_t * data,size_t len)49438   TraceStats_FilterStats_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
TraceStats_FilterStats_Decoder(const std::string & raw)49439   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)49440   explicit TraceStats_FilterStats_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
has_input_packets() const49441   bool has_input_packets() const { return at<1>().valid(); }
input_packets() const49442   uint64_t input_packets() const { return at<1>().as_uint64(); }
has_input_bytes() const49443   bool has_input_bytes() const { return at<2>().valid(); }
input_bytes() const49444   uint64_t input_bytes() const { return at<2>().as_uint64(); }
has_output_bytes() const49445   bool has_output_bytes() const { return at<3>().valid(); }
output_bytes() const49446   uint64_t output_bytes() const { return at<3>().as_uint64(); }
has_errors() const49447   bool has_errors() const { return at<4>().valid(); }
errors() const49448   uint64_t errors() const { return at<4>().as_uint64(); }
49449 };
49450 
49451 class TraceStats_FilterStats : public ::protozero::Message {
49452  public:
49453   using Decoder = TraceStats_FilterStats_Decoder;
49454   enum : int32_t {
49455     kInputPacketsFieldNumber = 1,
49456     kInputBytesFieldNumber = 2,
49457     kOutputBytesFieldNumber = 3,
49458     kErrorsFieldNumber = 4,
49459   };
49460 
49461   using FieldMetadata_InputPackets =
49462     ::protozero::proto_utils::FieldMetadata<
49463       1,
49464       ::protozero::proto_utils::RepetitionType::kNotRepeated,
49465       ::protozero::proto_utils::ProtoSchemaType::kUint64,
49466       uint64_t,
49467       TraceStats_FilterStats>;
49468 
49469   // Ceci n'est pas une pipe.
49470   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
49471   // type (and users are expected to use it as such, hence kCamelCase name).
49472   // It is declared as a function to keep protozero bindings header-only as
49473   // inline constexpr variables are not available until C++17 (while inline
49474   // functions are).
49475   // TODO(altimin): Use inline variable instead after adopting C++17.
kInputPackets()49476   static constexpr FieldMetadata_InputPackets kInputPackets() { return {}; }
set_input_packets(uint64_t value)49477   void set_input_packets(uint64_t value) {
49478     static constexpr uint32_t field_id = FieldMetadata_InputPackets::kFieldId;
49479     // Call the appropriate protozero::Message::Append(field_id, ...)
49480     // method based on the type of the field.
49481     ::protozero::internal::FieldWriter<
49482       ::protozero::proto_utils::ProtoSchemaType::kUint64>
49483         ::Append(*this, field_id, value);
49484   }
49485 
49486   using FieldMetadata_InputBytes =
49487     ::protozero::proto_utils::FieldMetadata<
49488       2,
49489       ::protozero::proto_utils::RepetitionType::kNotRepeated,
49490       ::protozero::proto_utils::ProtoSchemaType::kUint64,
49491       uint64_t,
49492       TraceStats_FilterStats>;
49493 
49494   // Ceci n'est pas une pipe.
49495   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
49496   // type (and users are expected to use it as such, hence kCamelCase name).
49497   // It is declared as a function to keep protozero bindings header-only as
49498   // inline constexpr variables are not available until C++17 (while inline
49499   // functions are).
49500   // TODO(altimin): Use inline variable instead after adopting C++17.
kInputBytes()49501   static constexpr FieldMetadata_InputBytes kInputBytes() { return {}; }
set_input_bytes(uint64_t value)49502   void set_input_bytes(uint64_t value) {
49503     static constexpr uint32_t field_id = FieldMetadata_InputBytes::kFieldId;
49504     // Call the appropriate protozero::Message::Append(field_id, ...)
49505     // method based on the type of the field.
49506     ::protozero::internal::FieldWriter<
49507       ::protozero::proto_utils::ProtoSchemaType::kUint64>
49508         ::Append(*this, field_id, value);
49509   }
49510 
49511   using FieldMetadata_OutputBytes =
49512     ::protozero::proto_utils::FieldMetadata<
49513       3,
49514       ::protozero::proto_utils::RepetitionType::kNotRepeated,
49515       ::protozero::proto_utils::ProtoSchemaType::kUint64,
49516       uint64_t,
49517       TraceStats_FilterStats>;
49518 
49519   // Ceci n'est pas une pipe.
49520   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
49521   // type (and users are expected to use it as such, hence kCamelCase name).
49522   // It is declared as a function to keep protozero bindings header-only as
49523   // inline constexpr variables are not available until C++17 (while inline
49524   // functions are).
49525   // TODO(altimin): Use inline variable instead after adopting C++17.
kOutputBytes()49526   static constexpr FieldMetadata_OutputBytes kOutputBytes() { return {}; }
set_output_bytes(uint64_t value)49527   void set_output_bytes(uint64_t value) {
49528     static constexpr uint32_t field_id = FieldMetadata_OutputBytes::kFieldId;
49529     // Call the appropriate protozero::Message::Append(field_id, ...)
49530     // method based on the type of the field.
49531     ::protozero::internal::FieldWriter<
49532       ::protozero::proto_utils::ProtoSchemaType::kUint64>
49533         ::Append(*this, field_id, value);
49534   }
49535 
49536   using FieldMetadata_Errors =
49537     ::protozero::proto_utils::FieldMetadata<
49538       4,
49539       ::protozero::proto_utils::RepetitionType::kNotRepeated,
49540       ::protozero::proto_utils::ProtoSchemaType::kUint64,
49541       uint64_t,
49542       TraceStats_FilterStats>;
49543 
49544   // Ceci n'est pas une pipe.
49545   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
49546   // type (and users are expected to use it as such, hence kCamelCase name).
49547   // It is declared as a function to keep protozero bindings header-only as
49548   // inline constexpr variables are not available until C++17 (while inline
49549   // functions are).
49550   // TODO(altimin): Use inline variable instead after adopting C++17.
kErrors()49551   static constexpr FieldMetadata_Errors kErrors() { return {}; }
set_errors(uint64_t value)49552   void set_errors(uint64_t value) {
49553     static constexpr uint32_t field_id = FieldMetadata_Errors::kFieldId;
49554     // Call the appropriate protozero::Message::Append(field_id, ...)
49555     // method based on the type of the field.
49556     ::protozero::internal::FieldWriter<
49557       ::protozero::proto_utils::ProtoSchemaType::kUint64>
49558         ::Append(*this, field_id, value);
49559   }
49560 };
49561 
49562 class TraceStats_BufferStats_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/19, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
49563  public:
TraceStats_BufferStats_Decoder(const uint8_t * data,size_t len)49564   TraceStats_BufferStats_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
TraceStats_BufferStats_Decoder(const std::string & raw)49565   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)49566   explicit TraceStats_BufferStats_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
has_buffer_size() const49567   bool has_buffer_size() const { return at<12>().valid(); }
buffer_size() const49568   uint64_t buffer_size() const { return at<12>().as_uint64(); }
has_bytes_written() const49569   bool has_bytes_written() const { return at<1>().valid(); }
bytes_written() const49570   uint64_t bytes_written() const { return at<1>().as_uint64(); }
has_bytes_overwritten() const49571   bool has_bytes_overwritten() const { return at<13>().valid(); }
bytes_overwritten() const49572   uint64_t bytes_overwritten() const { return at<13>().as_uint64(); }
has_bytes_read() const49573   bool has_bytes_read() const { return at<14>().valid(); }
bytes_read() const49574   uint64_t bytes_read() const { return at<14>().as_uint64(); }
has_padding_bytes_written() const49575   bool has_padding_bytes_written() const { return at<15>().valid(); }
padding_bytes_written() const49576   uint64_t padding_bytes_written() const { return at<15>().as_uint64(); }
has_padding_bytes_cleared() const49577   bool has_padding_bytes_cleared() const { return at<16>().valid(); }
padding_bytes_cleared() const49578   uint64_t padding_bytes_cleared() const { return at<16>().as_uint64(); }
has_chunks_written() const49579   bool has_chunks_written() const { return at<2>().valid(); }
chunks_written() const49580   uint64_t chunks_written() const { return at<2>().as_uint64(); }
has_chunks_rewritten() const49581   bool has_chunks_rewritten() const { return at<10>().valid(); }
chunks_rewritten() const49582   uint64_t chunks_rewritten() const { return at<10>().as_uint64(); }
has_chunks_overwritten() const49583   bool has_chunks_overwritten() const { return at<3>().valid(); }
chunks_overwritten() const49584   uint64_t chunks_overwritten() const { return at<3>().as_uint64(); }
has_chunks_discarded() const49585   bool has_chunks_discarded() const { return at<18>().valid(); }
chunks_discarded() const49586   uint64_t chunks_discarded() const { return at<18>().as_uint64(); }
has_chunks_read() const49587   bool has_chunks_read() const { return at<17>().valid(); }
chunks_read() const49588   uint64_t chunks_read() const { return at<17>().as_uint64(); }
has_chunks_committed_out_of_order() const49589   bool has_chunks_committed_out_of_order() const { return at<11>().valid(); }
chunks_committed_out_of_order() const49590   uint64_t chunks_committed_out_of_order() const { return at<11>().as_uint64(); }
has_write_wrap_count() const49591   bool has_write_wrap_count() const { return at<4>().valid(); }
write_wrap_count() const49592   uint64_t write_wrap_count() const { return at<4>().as_uint64(); }
has_patches_succeeded() const49593   bool has_patches_succeeded() const { return at<5>().valid(); }
patches_succeeded() const49594   uint64_t patches_succeeded() const { return at<5>().as_uint64(); }
has_patches_failed() const49595   bool has_patches_failed() const { return at<6>().valid(); }
patches_failed() const49596   uint64_t patches_failed() const { return at<6>().as_uint64(); }
has_readaheads_succeeded() const49597   bool has_readaheads_succeeded() const { return at<7>().valid(); }
readaheads_succeeded() const49598   uint64_t readaheads_succeeded() const { return at<7>().as_uint64(); }
has_readaheads_failed() const49599   bool has_readaheads_failed() const { return at<8>().valid(); }
readaheads_failed() const49600   uint64_t readaheads_failed() const { return at<8>().as_uint64(); }
has_abi_violations() const49601   bool has_abi_violations() const { return at<9>().valid(); }
abi_violations() const49602   uint64_t abi_violations() const { return at<9>().as_uint64(); }
has_trace_writer_packet_loss() const49603   bool has_trace_writer_packet_loss() const { return at<19>().valid(); }
trace_writer_packet_loss() const49604   uint64_t trace_writer_packet_loss() const { return at<19>().as_uint64(); }
49605 };
49606 
49607 class TraceStats_BufferStats : public ::protozero::Message {
49608  public:
49609   using Decoder = TraceStats_BufferStats_Decoder;
49610   enum : int32_t {
49611     kBufferSizeFieldNumber = 12,
49612     kBytesWrittenFieldNumber = 1,
49613     kBytesOverwrittenFieldNumber = 13,
49614     kBytesReadFieldNumber = 14,
49615     kPaddingBytesWrittenFieldNumber = 15,
49616     kPaddingBytesClearedFieldNumber = 16,
49617     kChunksWrittenFieldNumber = 2,
49618     kChunksRewrittenFieldNumber = 10,
49619     kChunksOverwrittenFieldNumber = 3,
49620     kChunksDiscardedFieldNumber = 18,
49621     kChunksReadFieldNumber = 17,
49622     kChunksCommittedOutOfOrderFieldNumber = 11,
49623     kWriteWrapCountFieldNumber = 4,
49624     kPatchesSucceededFieldNumber = 5,
49625     kPatchesFailedFieldNumber = 6,
49626     kReadaheadsSucceededFieldNumber = 7,
49627     kReadaheadsFailedFieldNumber = 8,
49628     kAbiViolationsFieldNumber = 9,
49629     kTraceWriterPacketLossFieldNumber = 19,
49630   };
49631 
49632   using FieldMetadata_BufferSize =
49633     ::protozero::proto_utils::FieldMetadata<
49634       12,
49635       ::protozero::proto_utils::RepetitionType::kNotRepeated,
49636       ::protozero::proto_utils::ProtoSchemaType::kUint64,
49637       uint64_t,
49638       TraceStats_BufferStats>;
49639 
49640   // Ceci n'est pas une pipe.
49641   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
49642   // type (and users are expected to use it as such, hence kCamelCase name).
49643   // It is declared as a function to keep protozero bindings header-only as
49644   // inline constexpr variables are not available until C++17 (while inline
49645   // functions are).
49646   // TODO(altimin): Use inline variable instead after adopting C++17.
kBufferSize()49647   static constexpr FieldMetadata_BufferSize kBufferSize() { return {}; }
set_buffer_size(uint64_t value)49648   void set_buffer_size(uint64_t value) {
49649     static constexpr uint32_t field_id = FieldMetadata_BufferSize::kFieldId;
49650     // Call the appropriate protozero::Message::Append(field_id, ...)
49651     // method based on the type of the field.
49652     ::protozero::internal::FieldWriter<
49653       ::protozero::proto_utils::ProtoSchemaType::kUint64>
49654         ::Append(*this, field_id, value);
49655   }
49656 
49657   using FieldMetadata_BytesWritten =
49658     ::protozero::proto_utils::FieldMetadata<
49659       1,
49660       ::protozero::proto_utils::RepetitionType::kNotRepeated,
49661       ::protozero::proto_utils::ProtoSchemaType::kUint64,
49662       uint64_t,
49663       TraceStats_BufferStats>;
49664 
49665   // Ceci n'est pas une pipe.
49666   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
49667   // type (and users are expected to use it as such, hence kCamelCase name).
49668   // It is declared as a function to keep protozero bindings header-only as
49669   // inline constexpr variables are not available until C++17 (while inline
49670   // functions are).
49671   // TODO(altimin): Use inline variable instead after adopting C++17.
kBytesWritten()49672   static constexpr FieldMetadata_BytesWritten kBytesWritten() { return {}; }
set_bytes_written(uint64_t value)49673   void set_bytes_written(uint64_t value) {
49674     static constexpr uint32_t field_id = FieldMetadata_BytesWritten::kFieldId;
49675     // Call the appropriate protozero::Message::Append(field_id, ...)
49676     // method based on the type of the field.
49677     ::protozero::internal::FieldWriter<
49678       ::protozero::proto_utils::ProtoSchemaType::kUint64>
49679         ::Append(*this, field_id, value);
49680   }
49681 
49682   using FieldMetadata_BytesOverwritten =
49683     ::protozero::proto_utils::FieldMetadata<
49684       13,
49685       ::protozero::proto_utils::RepetitionType::kNotRepeated,
49686       ::protozero::proto_utils::ProtoSchemaType::kUint64,
49687       uint64_t,
49688       TraceStats_BufferStats>;
49689 
49690   // Ceci n'est pas une pipe.
49691   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
49692   // type (and users are expected to use it as such, hence kCamelCase name).
49693   // It is declared as a function to keep protozero bindings header-only as
49694   // inline constexpr variables are not available until C++17 (while inline
49695   // functions are).
49696   // TODO(altimin): Use inline variable instead after adopting C++17.
kBytesOverwritten()49697   static constexpr FieldMetadata_BytesOverwritten kBytesOverwritten() { return {}; }
set_bytes_overwritten(uint64_t value)49698   void set_bytes_overwritten(uint64_t value) {
49699     static constexpr uint32_t field_id = FieldMetadata_BytesOverwritten::kFieldId;
49700     // Call the appropriate protozero::Message::Append(field_id, ...)
49701     // method based on the type of the field.
49702     ::protozero::internal::FieldWriter<
49703       ::protozero::proto_utils::ProtoSchemaType::kUint64>
49704         ::Append(*this, field_id, value);
49705   }
49706 
49707   using FieldMetadata_BytesRead =
49708     ::protozero::proto_utils::FieldMetadata<
49709       14,
49710       ::protozero::proto_utils::RepetitionType::kNotRepeated,
49711       ::protozero::proto_utils::ProtoSchemaType::kUint64,
49712       uint64_t,
49713       TraceStats_BufferStats>;
49714 
49715   // Ceci n'est pas une pipe.
49716   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
49717   // type (and users are expected to use it as such, hence kCamelCase name).
49718   // It is declared as a function to keep protozero bindings header-only as
49719   // inline constexpr variables are not available until C++17 (while inline
49720   // functions are).
49721   // TODO(altimin): Use inline variable instead after adopting C++17.
kBytesRead()49722   static constexpr FieldMetadata_BytesRead kBytesRead() { return {}; }
set_bytes_read(uint64_t value)49723   void set_bytes_read(uint64_t value) {
49724     static constexpr uint32_t field_id = FieldMetadata_BytesRead::kFieldId;
49725     // Call the appropriate protozero::Message::Append(field_id, ...)
49726     // method based on the type of the field.
49727     ::protozero::internal::FieldWriter<
49728       ::protozero::proto_utils::ProtoSchemaType::kUint64>
49729         ::Append(*this, field_id, value);
49730   }
49731 
49732   using FieldMetadata_PaddingBytesWritten =
49733     ::protozero::proto_utils::FieldMetadata<
49734       15,
49735       ::protozero::proto_utils::RepetitionType::kNotRepeated,
49736       ::protozero::proto_utils::ProtoSchemaType::kUint64,
49737       uint64_t,
49738       TraceStats_BufferStats>;
49739 
49740   // Ceci n'est pas une pipe.
49741   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
49742   // type (and users are expected to use it as such, hence kCamelCase name).
49743   // It is declared as a function to keep protozero bindings header-only as
49744   // inline constexpr variables are not available until C++17 (while inline
49745   // functions are).
49746   // TODO(altimin): Use inline variable instead after adopting C++17.
kPaddingBytesWritten()49747   static constexpr FieldMetadata_PaddingBytesWritten kPaddingBytesWritten() { return {}; }
set_padding_bytes_written(uint64_t value)49748   void set_padding_bytes_written(uint64_t value) {
49749     static constexpr uint32_t field_id = FieldMetadata_PaddingBytesWritten::kFieldId;
49750     // Call the appropriate protozero::Message::Append(field_id, ...)
49751     // method based on the type of the field.
49752     ::protozero::internal::FieldWriter<
49753       ::protozero::proto_utils::ProtoSchemaType::kUint64>
49754         ::Append(*this, field_id, value);
49755   }
49756 
49757   using FieldMetadata_PaddingBytesCleared =
49758     ::protozero::proto_utils::FieldMetadata<
49759       16,
49760       ::protozero::proto_utils::RepetitionType::kNotRepeated,
49761       ::protozero::proto_utils::ProtoSchemaType::kUint64,
49762       uint64_t,
49763       TraceStats_BufferStats>;
49764 
49765   // Ceci n'est pas une pipe.
49766   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
49767   // type (and users are expected to use it as such, hence kCamelCase name).
49768   // It is declared as a function to keep protozero bindings header-only as
49769   // inline constexpr variables are not available until C++17 (while inline
49770   // functions are).
49771   // TODO(altimin): Use inline variable instead after adopting C++17.
kPaddingBytesCleared()49772   static constexpr FieldMetadata_PaddingBytesCleared kPaddingBytesCleared() { return {}; }
set_padding_bytes_cleared(uint64_t value)49773   void set_padding_bytes_cleared(uint64_t value) {
49774     static constexpr uint32_t field_id = FieldMetadata_PaddingBytesCleared::kFieldId;
49775     // Call the appropriate protozero::Message::Append(field_id, ...)
49776     // method based on the type of the field.
49777     ::protozero::internal::FieldWriter<
49778       ::protozero::proto_utils::ProtoSchemaType::kUint64>
49779         ::Append(*this, field_id, value);
49780   }
49781 
49782   using FieldMetadata_ChunksWritten =
49783     ::protozero::proto_utils::FieldMetadata<
49784       2,
49785       ::protozero::proto_utils::RepetitionType::kNotRepeated,
49786       ::protozero::proto_utils::ProtoSchemaType::kUint64,
49787       uint64_t,
49788       TraceStats_BufferStats>;
49789 
49790   // Ceci n'est pas une pipe.
49791   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
49792   // type (and users are expected to use it as such, hence kCamelCase name).
49793   // It is declared as a function to keep protozero bindings header-only as
49794   // inline constexpr variables are not available until C++17 (while inline
49795   // functions are).
49796   // TODO(altimin): Use inline variable instead after adopting C++17.
kChunksWritten()49797   static constexpr FieldMetadata_ChunksWritten kChunksWritten() { return {}; }
set_chunks_written(uint64_t value)49798   void set_chunks_written(uint64_t value) {
49799     static constexpr uint32_t field_id = FieldMetadata_ChunksWritten::kFieldId;
49800     // Call the appropriate protozero::Message::Append(field_id, ...)
49801     // method based on the type of the field.
49802     ::protozero::internal::FieldWriter<
49803       ::protozero::proto_utils::ProtoSchemaType::kUint64>
49804         ::Append(*this, field_id, value);
49805   }
49806 
49807   using FieldMetadata_ChunksRewritten =
49808     ::protozero::proto_utils::FieldMetadata<
49809       10,
49810       ::protozero::proto_utils::RepetitionType::kNotRepeated,
49811       ::protozero::proto_utils::ProtoSchemaType::kUint64,
49812       uint64_t,
49813       TraceStats_BufferStats>;
49814 
49815   // Ceci n'est pas une pipe.
49816   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
49817   // type (and users are expected to use it as such, hence kCamelCase name).
49818   // It is declared as a function to keep protozero bindings header-only as
49819   // inline constexpr variables are not available until C++17 (while inline
49820   // functions are).
49821   // TODO(altimin): Use inline variable instead after adopting C++17.
kChunksRewritten()49822   static constexpr FieldMetadata_ChunksRewritten kChunksRewritten() { return {}; }
set_chunks_rewritten(uint64_t value)49823   void set_chunks_rewritten(uint64_t value) {
49824     static constexpr uint32_t field_id = FieldMetadata_ChunksRewritten::kFieldId;
49825     // Call the appropriate protozero::Message::Append(field_id, ...)
49826     // method based on the type of the field.
49827     ::protozero::internal::FieldWriter<
49828       ::protozero::proto_utils::ProtoSchemaType::kUint64>
49829         ::Append(*this, field_id, value);
49830   }
49831 
49832   using FieldMetadata_ChunksOverwritten =
49833     ::protozero::proto_utils::FieldMetadata<
49834       3,
49835       ::protozero::proto_utils::RepetitionType::kNotRepeated,
49836       ::protozero::proto_utils::ProtoSchemaType::kUint64,
49837       uint64_t,
49838       TraceStats_BufferStats>;
49839 
49840   // Ceci n'est pas une pipe.
49841   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
49842   // type (and users are expected to use it as such, hence kCamelCase name).
49843   // It is declared as a function to keep protozero bindings header-only as
49844   // inline constexpr variables are not available until C++17 (while inline
49845   // functions are).
49846   // TODO(altimin): Use inline variable instead after adopting C++17.
kChunksOverwritten()49847   static constexpr FieldMetadata_ChunksOverwritten kChunksOverwritten() { return {}; }
set_chunks_overwritten(uint64_t value)49848   void set_chunks_overwritten(uint64_t value) {
49849     static constexpr uint32_t field_id = FieldMetadata_ChunksOverwritten::kFieldId;
49850     // Call the appropriate protozero::Message::Append(field_id, ...)
49851     // method based on the type of the field.
49852     ::protozero::internal::FieldWriter<
49853       ::protozero::proto_utils::ProtoSchemaType::kUint64>
49854         ::Append(*this, field_id, value);
49855   }
49856 
49857   using FieldMetadata_ChunksDiscarded =
49858     ::protozero::proto_utils::FieldMetadata<
49859       18,
49860       ::protozero::proto_utils::RepetitionType::kNotRepeated,
49861       ::protozero::proto_utils::ProtoSchemaType::kUint64,
49862       uint64_t,
49863       TraceStats_BufferStats>;
49864 
49865   // Ceci n'est pas une pipe.
49866   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
49867   // type (and users are expected to use it as such, hence kCamelCase name).
49868   // It is declared as a function to keep protozero bindings header-only as
49869   // inline constexpr variables are not available until C++17 (while inline
49870   // functions are).
49871   // TODO(altimin): Use inline variable instead after adopting C++17.
kChunksDiscarded()49872   static constexpr FieldMetadata_ChunksDiscarded kChunksDiscarded() { return {}; }
set_chunks_discarded(uint64_t value)49873   void set_chunks_discarded(uint64_t value) {
49874     static constexpr uint32_t field_id = FieldMetadata_ChunksDiscarded::kFieldId;
49875     // Call the appropriate protozero::Message::Append(field_id, ...)
49876     // method based on the type of the field.
49877     ::protozero::internal::FieldWriter<
49878       ::protozero::proto_utils::ProtoSchemaType::kUint64>
49879         ::Append(*this, field_id, value);
49880   }
49881 
49882   using FieldMetadata_ChunksRead =
49883     ::protozero::proto_utils::FieldMetadata<
49884       17,
49885       ::protozero::proto_utils::RepetitionType::kNotRepeated,
49886       ::protozero::proto_utils::ProtoSchemaType::kUint64,
49887       uint64_t,
49888       TraceStats_BufferStats>;
49889 
49890   // Ceci n'est pas une pipe.
49891   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
49892   // type (and users are expected to use it as such, hence kCamelCase name).
49893   // It is declared as a function to keep protozero bindings header-only as
49894   // inline constexpr variables are not available until C++17 (while inline
49895   // functions are).
49896   // TODO(altimin): Use inline variable instead after adopting C++17.
kChunksRead()49897   static constexpr FieldMetadata_ChunksRead kChunksRead() { return {}; }
set_chunks_read(uint64_t value)49898   void set_chunks_read(uint64_t value) {
49899     static constexpr uint32_t field_id = FieldMetadata_ChunksRead::kFieldId;
49900     // Call the appropriate protozero::Message::Append(field_id, ...)
49901     // method based on the type of the field.
49902     ::protozero::internal::FieldWriter<
49903       ::protozero::proto_utils::ProtoSchemaType::kUint64>
49904         ::Append(*this, field_id, value);
49905   }
49906 
49907   using FieldMetadata_ChunksCommittedOutOfOrder =
49908     ::protozero::proto_utils::FieldMetadata<
49909       11,
49910       ::protozero::proto_utils::RepetitionType::kNotRepeated,
49911       ::protozero::proto_utils::ProtoSchemaType::kUint64,
49912       uint64_t,
49913       TraceStats_BufferStats>;
49914 
49915   // Ceci n'est pas une pipe.
49916   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
49917   // type (and users are expected to use it as such, hence kCamelCase name).
49918   // It is declared as a function to keep protozero bindings header-only as
49919   // inline constexpr variables are not available until C++17 (while inline
49920   // functions are).
49921   // TODO(altimin): Use inline variable instead after adopting C++17.
kChunksCommittedOutOfOrder()49922   static constexpr FieldMetadata_ChunksCommittedOutOfOrder kChunksCommittedOutOfOrder() { return {}; }
set_chunks_committed_out_of_order(uint64_t value)49923   void set_chunks_committed_out_of_order(uint64_t value) {
49924     static constexpr uint32_t field_id = FieldMetadata_ChunksCommittedOutOfOrder::kFieldId;
49925     // Call the appropriate protozero::Message::Append(field_id, ...)
49926     // method based on the type of the field.
49927     ::protozero::internal::FieldWriter<
49928       ::protozero::proto_utils::ProtoSchemaType::kUint64>
49929         ::Append(*this, field_id, value);
49930   }
49931 
49932   using FieldMetadata_WriteWrapCount =
49933     ::protozero::proto_utils::FieldMetadata<
49934       4,
49935       ::protozero::proto_utils::RepetitionType::kNotRepeated,
49936       ::protozero::proto_utils::ProtoSchemaType::kUint64,
49937       uint64_t,
49938       TraceStats_BufferStats>;
49939 
49940   // Ceci n'est pas une pipe.
49941   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
49942   // type (and users are expected to use it as such, hence kCamelCase name).
49943   // It is declared as a function to keep protozero bindings header-only as
49944   // inline constexpr variables are not available until C++17 (while inline
49945   // functions are).
49946   // TODO(altimin): Use inline variable instead after adopting C++17.
kWriteWrapCount()49947   static constexpr FieldMetadata_WriteWrapCount kWriteWrapCount() { return {}; }
set_write_wrap_count(uint64_t value)49948   void set_write_wrap_count(uint64_t value) {
49949     static constexpr uint32_t field_id = FieldMetadata_WriteWrapCount::kFieldId;
49950     // Call the appropriate protozero::Message::Append(field_id, ...)
49951     // method based on the type of the field.
49952     ::protozero::internal::FieldWriter<
49953       ::protozero::proto_utils::ProtoSchemaType::kUint64>
49954         ::Append(*this, field_id, value);
49955   }
49956 
49957   using FieldMetadata_PatchesSucceeded =
49958     ::protozero::proto_utils::FieldMetadata<
49959       5,
49960       ::protozero::proto_utils::RepetitionType::kNotRepeated,
49961       ::protozero::proto_utils::ProtoSchemaType::kUint64,
49962       uint64_t,
49963       TraceStats_BufferStats>;
49964 
49965   // Ceci n'est pas une pipe.
49966   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
49967   // type (and users are expected to use it as such, hence kCamelCase name).
49968   // It is declared as a function to keep protozero bindings header-only as
49969   // inline constexpr variables are not available until C++17 (while inline
49970   // functions are).
49971   // TODO(altimin): Use inline variable instead after adopting C++17.
kPatchesSucceeded()49972   static constexpr FieldMetadata_PatchesSucceeded kPatchesSucceeded() { return {}; }
set_patches_succeeded(uint64_t value)49973   void set_patches_succeeded(uint64_t value) {
49974     static constexpr uint32_t field_id = FieldMetadata_PatchesSucceeded::kFieldId;
49975     // Call the appropriate protozero::Message::Append(field_id, ...)
49976     // method based on the type of the field.
49977     ::protozero::internal::FieldWriter<
49978       ::protozero::proto_utils::ProtoSchemaType::kUint64>
49979         ::Append(*this, field_id, value);
49980   }
49981 
49982   using FieldMetadata_PatchesFailed =
49983     ::protozero::proto_utils::FieldMetadata<
49984       6,
49985       ::protozero::proto_utils::RepetitionType::kNotRepeated,
49986       ::protozero::proto_utils::ProtoSchemaType::kUint64,
49987       uint64_t,
49988       TraceStats_BufferStats>;
49989 
49990   // Ceci n'est pas une pipe.
49991   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
49992   // type (and users are expected to use it as such, hence kCamelCase name).
49993   // It is declared as a function to keep protozero bindings header-only as
49994   // inline constexpr variables are not available until C++17 (while inline
49995   // functions are).
49996   // TODO(altimin): Use inline variable instead after adopting C++17.
kPatchesFailed()49997   static constexpr FieldMetadata_PatchesFailed kPatchesFailed() { return {}; }
set_patches_failed(uint64_t value)49998   void set_patches_failed(uint64_t value) {
49999     static constexpr uint32_t field_id = FieldMetadata_PatchesFailed::kFieldId;
50000     // Call the appropriate protozero::Message::Append(field_id, ...)
50001     // method based on the type of the field.
50002     ::protozero::internal::FieldWriter<
50003       ::protozero::proto_utils::ProtoSchemaType::kUint64>
50004         ::Append(*this, field_id, value);
50005   }
50006 
50007   using FieldMetadata_ReadaheadsSucceeded =
50008     ::protozero::proto_utils::FieldMetadata<
50009       7,
50010       ::protozero::proto_utils::RepetitionType::kNotRepeated,
50011       ::protozero::proto_utils::ProtoSchemaType::kUint64,
50012       uint64_t,
50013       TraceStats_BufferStats>;
50014 
50015   // Ceci n'est pas une pipe.
50016   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
50017   // type (and users are expected to use it as such, hence kCamelCase name).
50018   // It is declared as a function to keep protozero bindings header-only as
50019   // inline constexpr variables are not available until C++17 (while inline
50020   // functions are).
50021   // TODO(altimin): Use inline variable instead after adopting C++17.
kReadaheadsSucceeded()50022   static constexpr FieldMetadata_ReadaheadsSucceeded kReadaheadsSucceeded() { return {}; }
set_readaheads_succeeded(uint64_t value)50023   void set_readaheads_succeeded(uint64_t value) {
50024     static constexpr uint32_t field_id = FieldMetadata_ReadaheadsSucceeded::kFieldId;
50025     // Call the appropriate protozero::Message::Append(field_id, ...)
50026     // method based on the type of the field.
50027     ::protozero::internal::FieldWriter<
50028       ::protozero::proto_utils::ProtoSchemaType::kUint64>
50029         ::Append(*this, field_id, value);
50030   }
50031 
50032   using FieldMetadata_ReadaheadsFailed =
50033     ::protozero::proto_utils::FieldMetadata<
50034       8,
50035       ::protozero::proto_utils::RepetitionType::kNotRepeated,
50036       ::protozero::proto_utils::ProtoSchemaType::kUint64,
50037       uint64_t,
50038       TraceStats_BufferStats>;
50039 
50040   // Ceci n'est pas une pipe.
50041   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
50042   // type (and users are expected to use it as such, hence kCamelCase name).
50043   // It is declared as a function to keep protozero bindings header-only as
50044   // inline constexpr variables are not available until C++17 (while inline
50045   // functions are).
50046   // TODO(altimin): Use inline variable instead after adopting C++17.
kReadaheadsFailed()50047   static constexpr FieldMetadata_ReadaheadsFailed kReadaheadsFailed() { return {}; }
set_readaheads_failed(uint64_t value)50048   void set_readaheads_failed(uint64_t value) {
50049     static constexpr uint32_t field_id = FieldMetadata_ReadaheadsFailed::kFieldId;
50050     // Call the appropriate protozero::Message::Append(field_id, ...)
50051     // method based on the type of the field.
50052     ::protozero::internal::FieldWriter<
50053       ::protozero::proto_utils::ProtoSchemaType::kUint64>
50054         ::Append(*this, field_id, value);
50055   }
50056 
50057   using FieldMetadata_AbiViolations =
50058     ::protozero::proto_utils::FieldMetadata<
50059       9,
50060       ::protozero::proto_utils::RepetitionType::kNotRepeated,
50061       ::protozero::proto_utils::ProtoSchemaType::kUint64,
50062       uint64_t,
50063       TraceStats_BufferStats>;
50064 
50065   // Ceci n'est pas une pipe.
50066   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
50067   // type (and users are expected to use it as such, hence kCamelCase name).
50068   // It is declared as a function to keep protozero bindings header-only as
50069   // inline constexpr variables are not available until C++17 (while inline
50070   // functions are).
50071   // TODO(altimin): Use inline variable instead after adopting C++17.
kAbiViolations()50072   static constexpr FieldMetadata_AbiViolations kAbiViolations() { return {}; }
set_abi_violations(uint64_t value)50073   void set_abi_violations(uint64_t value) {
50074     static constexpr uint32_t field_id = FieldMetadata_AbiViolations::kFieldId;
50075     // Call the appropriate protozero::Message::Append(field_id, ...)
50076     // method based on the type of the field.
50077     ::protozero::internal::FieldWriter<
50078       ::protozero::proto_utils::ProtoSchemaType::kUint64>
50079         ::Append(*this, field_id, value);
50080   }
50081 
50082   using FieldMetadata_TraceWriterPacketLoss =
50083     ::protozero::proto_utils::FieldMetadata<
50084       19,
50085       ::protozero::proto_utils::RepetitionType::kNotRepeated,
50086       ::protozero::proto_utils::ProtoSchemaType::kUint64,
50087       uint64_t,
50088       TraceStats_BufferStats>;
50089 
50090   // Ceci n'est pas une pipe.
50091   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
50092   // type (and users are expected to use it as such, hence kCamelCase name).
50093   // It is declared as a function to keep protozero bindings header-only as
50094   // inline constexpr variables are not available until C++17 (while inline
50095   // functions are).
50096   // TODO(altimin): Use inline variable instead after adopting C++17.
kTraceWriterPacketLoss()50097   static constexpr FieldMetadata_TraceWriterPacketLoss kTraceWriterPacketLoss() { return {}; }
set_trace_writer_packet_loss(uint64_t value)50098   void set_trace_writer_packet_loss(uint64_t value) {
50099     static constexpr uint32_t field_id = FieldMetadata_TraceWriterPacketLoss::kFieldId;
50100     // Call the appropriate protozero::Message::Append(field_id, ...)
50101     // method based on the type of the field.
50102     ::protozero::internal::FieldWriter<
50103       ::protozero::proto_utils::ProtoSchemaType::kUint64>
50104         ::Append(*this, field_id, value);
50105   }
50106 };
50107 
50108 } // Namespace.
50109 } // Namespace.
50110 } // Namespace.
50111 #endif  // Include guard.
50112 // gen_amalgamated begin header: gen/protos/perfetto/config/trace_config.pbzero.h
50113 // Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
50114 
50115 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_TRACE_CONFIG_PROTO_H_
50116 #define PERFETTO_PROTOS_PROTOS_PERFETTO_CONFIG_TRACE_CONFIG_PROTO_H_
50117 
50118 #include <stddef.h>
50119 #include <stdint.h>
50120 
50121 // gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
50122 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
50123 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
50124 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
50125 // gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
50126 
50127 namespace perfetto {
50128 namespace protos {
50129 namespace pbzero {
50130 
50131 class DataSourceConfig;
50132 class TraceConfig_BufferConfig;
50133 class TraceConfig_BuiltinDataSource;
50134 class TraceConfig_DataSource;
50135 class TraceConfig_GuardrailOverrides;
50136 class TraceConfig_IncidentReportConfig;
50137 class TraceConfig_IncrementalStateConfig;
50138 class TraceConfig_ProducerConfig;
50139 class TraceConfig_StatsdMetadata;
50140 class TraceConfig_TraceFilter;
50141 class TraceConfig_TriggerConfig;
50142 class TraceConfig_TriggerConfig_Trigger;
50143 enum BuiltinClock : int32_t;
50144 enum TraceConfig_BufferConfig_FillPolicy : int32_t;
50145 enum TraceConfig_CompressionType : int32_t;
50146 enum TraceConfig_LockdownModeOperation : int32_t;
50147 enum TraceConfig_StatsdLogging : int32_t;
50148 enum TraceConfig_TriggerConfig_TriggerMode : int32_t;
50149 
50150 enum TraceConfig_LockdownModeOperation : int32_t {
50151   TraceConfig_LockdownModeOperation_LOCKDOWN_UNCHANGED = 0,
50152   TraceConfig_LockdownModeOperation_LOCKDOWN_CLEAR = 1,
50153   TraceConfig_LockdownModeOperation_LOCKDOWN_SET = 2,
50154 };
50155 
50156 const TraceConfig_LockdownModeOperation TraceConfig_LockdownModeOperation_MIN = TraceConfig_LockdownModeOperation_LOCKDOWN_UNCHANGED;
50157 const TraceConfig_LockdownModeOperation TraceConfig_LockdownModeOperation_MAX = TraceConfig_LockdownModeOperation_LOCKDOWN_SET;
50158 
50159 enum TraceConfig_CompressionType : int32_t {
50160   TraceConfig_CompressionType_COMPRESSION_TYPE_UNSPECIFIED = 0,
50161   TraceConfig_CompressionType_COMPRESSION_TYPE_DEFLATE = 1,
50162 };
50163 
50164 const TraceConfig_CompressionType TraceConfig_CompressionType_MIN = TraceConfig_CompressionType_COMPRESSION_TYPE_UNSPECIFIED;
50165 const TraceConfig_CompressionType TraceConfig_CompressionType_MAX = TraceConfig_CompressionType_COMPRESSION_TYPE_DEFLATE;
50166 
50167 enum TraceConfig_StatsdLogging : int32_t {
50168   TraceConfig_StatsdLogging_STATSD_LOGGING_UNSPECIFIED = 0,
50169   TraceConfig_StatsdLogging_STATSD_LOGGING_ENABLED = 1,
50170   TraceConfig_StatsdLogging_STATSD_LOGGING_DISABLED = 2,
50171 };
50172 
50173 const TraceConfig_StatsdLogging TraceConfig_StatsdLogging_MIN = TraceConfig_StatsdLogging_STATSD_LOGGING_UNSPECIFIED;
50174 const TraceConfig_StatsdLogging TraceConfig_StatsdLogging_MAX = TraceConfig_StatsdLogging_STATSD_LOGGING_DISABLED;
50175 
50176 enum TraceConfig_TriggerConfig_TriggerMode : int32_t {
50177   TraceConfig_TriggerConfig_TriggerMode_UNSPECIFIED = 0,
50178   TraceConfig_TriggerConfig_TriggerMode_START_TRACING = 1,
50179   TraceConfig_TriggerConfig_TriggerMode_STOP_TRACING = 2,
50180 };
50181 
50182 const TraceConfig_TriggerConfig_TriggerMode TraceConfig_TriggerConfig_TriggerMode_MIN = TraceConfig_TriggerConfig_TriggerMode_UNSPECIFIED;
50183 const TraceConfig_TriggerConfig_TriggerMode TraceConfig_TriggerConfig_TriggerMode_MAX = TraceConfig_TriggerConfig_TriggerMode_STOP_TRACING;
50184 
50185 enum TraceConfig_BufferConfig_FillPolicy : int32_t {
50186   TraceConfig_BufferConfig_FillPolicy_UNSPECIFIED = 0,
50187   TraceConfig_BufferConfig_FillPolicy_RING_BUFFER = 1,
50188   TraceConfig_BufferConfig_FillPolicy_DISCARD = 2,
50189 };
50190 
50191 const TraceConfig_BufferConfig_FillPolicy TraceConfig_BufferConfig_FillPolicy_MIN = TraceConfig_BufferConfig_FillPolicy_UNSPECIFIED;
50192 const TraceConfig_BufferConfig_FillPolicy TraceConfig_BufferConfig_FillPolicy_MAX = TraceConfig_BufferConfig_FillPolicy_DISCARD;
50193 
50194 class TraceConfig_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/33, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
50195  public:
TraceConfig_Decoder(const uint8_t * data,size_t len)50196   TraceConfig_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
TraceConfig_Decoder(const std::string & raw)50197   explicit TraceConfig_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
TraceConfig_Decoder(const::protozero::ConstBytes & raw)50198   explicit TraceConfig_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
has_buffers() const50199   bool has_buffers() const { return at<1>().valid(); }
buffers() const50200   ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> buffers() const { return GetRepeated<::protozero::ConstBytes>(1); }
has_data_sources() const50201   bool has_data_sources() const { return at<2>().valid(); }
data_sources() const50202   ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> data_sources() const { return GetRepeated<::protozero::ConstBytes>(2); }
has_builtin_data_sources() const50203   bool has_builtin_data_sources() const { return at<20>().valid(); }
builtin_data_sources() const50204   ::protozero::ConstBytes builtin_data_sources() const { return at<20>().as_bytes(); }
has_duration_ms() const50205   bool has_duration_ms() const { return at<3>().valid(); }
duration_ms() const50206   uint32_t duration_ms() const { return at<3>().as_uint32(); }
has_enable_extra_guardrails() const50207   bool has_enable_extra_guardrails() const { return at<4>().valid(); }
enable_extra_guardrails() const50208   bool enable_extra_guardrails() const { return at<4>().as_bool(); }
has_lockdown_mode() const50209   bool has_lockdown_mode() const { return at<5>().valid(); }
lockdown_mode() const50210   int32_t lockdown_mode() const { return at<5>().as_int32(); }
has_producers() const50211   bool has_producers() const { return at<6>().valid(); }
producers() const50212   ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> producers() const { return GetRepeated<::protozero::ConstBytes>(6); }
has_statsd_metadata() const50213   bool has_statsd_metadata() const { return at<7>().valid(); }
statsd_metadata() const50214   ::protozero::ConstBytes statsd_metadata() const { return at<7>().as_bytes(); }
has_write_into_file() const50215   bool has_write_into_file() const { return at<8>().valid(); }
write_into_file() const50216   bool write_into_file() const { return at<8>().as_bool(); }
has_output_path() const50217   bool has_output_path() const { return at<29>().valid(); }
output_path() const50218   ::protozero::ConstChars output_path() const { return at<29>().as_string(); }
has_file_write_period_ms() const50219   bool has_file_write_period_ms() const { return at<9>().valid(); }
file_write_period_ms() const50220   uint32_t file_write_period_ms() const { return at<9>().as_uint32(); }
has_max_file_size_bytes() const50221   bool has_max_file_size_bytes() const { return at<10>().valid(); }
max_file_size_bytes() const50222   uint64_t max_file_size_bytes() const { return at<10>().as_uint64(); }
has_guardrail_overrides() const50223   bool has_guardrail_overrides() const { return at<11>().valid(); }
guardrail_overrides() const50224   ::protozero::ConstBytes guardrail_overrides() const { return at<11>().as_bytes(); }
has_deferred_start() const50225   bool has_deferred_start() const { return at<12>().valid(); }
deferred_start() const50226   bool deferred_start() const { return at<12>().as_bool(); }
has_flush_period_ms() const50227   bool has_flush_period_ms() const { return at<13>().valid(); }
flush_period_ms() const50228   uint32_t flush_period_ms() const { return at<13>().as_uint32(); }
has_flush_timeout_ms() const50229   bool has_flush_timeout_ms() const { return at<14>().valid(); }
flush_timeout_ms() const50230   uint32_t flush_timeout_ms() const { return at<14>().as_uint32(); }
has_data_source_stop_timeout_ms() const50231   bool has_data_source_stop_timeout_ms() const { return at<23>().valid(); }
data_source_stop_timeout_ms() const50232   uint32_t data_source_stop_timeout_ms() const { return at<23>().as_uint32(); }
has_notify_traceur() const50233   bool has_notify_traceur() const { return at<16>().valid(); }
notify_traceur() const50234   bool notify_traceur() const { return at<16>().as_bool(); }
has_bugreport_score() const50235   bool has_bugreport_score() const { return at<30>().valid(); }
bugreport_score() const50236   int32_t bugreport_score() const { return at<30>().as_int32(); }
has_trigger_config() const50237   bool has_trigger_config() const { return at<17>().valid(); }
trigger_config() const50238   ::protozero::ConstBytes trigger_config() const { return at<17>().as_bytes(); }
has_activate_triggers() const50239   bool has_activate_triggers() const { return at<18>().valid(); }
activate_triggers() const50240   ::protozero::RepeatedFieldIterator<::protozero::ConstChars> activate_triggers() const { return GetRepeated<::protozero::ConstChars>(18); }
has_incremental_state_config() const50241   bool has_incremental_state_config() const { return at<21>().valid(); }
incremental_state_config() const50242   ::protozero::ConstBytes incremental_state_config() const { return at<21>().as_bytes(); }
has_allow_user_build_tracing() const50243   bool has_allow_user_build_tracing() const { return at<19>().valid(); }
allow_user_build_tracing() const50244   bool allow_user_build_tracing() const { return at<19>().as_bool(); }
has_unique_session_name() const50245   bool has_unique_session_name() const { return at<22>().valid(); }
unique_session_name() const50246   ::protozero::ConstChars unique_session_name() const { return at<22>().as_string(); }
has_compression_type() const50247   bool has_compression_type() const { return at<24>().valid(); }
compression_type() const50248   int32_t compression_type() const { return at<24>().as_int32(); }
has_incident_report_config() const50249   bool has_incident_report_config() const { return at<25>().valid(); }
incident_report_config() const50250   ::protozero::ConstBytes incident_report_config() const { return at<25>().as_bytes(); }
has_statsd_logging() const50251   bool has_statsd_logging() const { return at<31>().valid(); }
statsd_logging() const50252   int32_t statsd_logging() const { return at<31>().as_int32(); }
has_trace_uuid_msb() const50253   bool has_trace_uuid_msb() const { return at<27>().valid(); }
trace_uuid_msb() const50254   int64_t trace_uuid_msb() const { return at<27>().as_int64(); }
has_trace_uuid_lsb() const50255   bool has_trace_uuid_lsb() const { return at<28>().valid(); }
trace_uuid_lsb() const50256   int64_t trace_uuid_lsb() const { return at<28>().as_int64(); }
has_trace_filter() const50257   bool has_trace_filter() const { return at<33>().valid(); }
trace_filter() const50258   ::protozero::ConstBytes trace_filter() const { return at<33>().as_bytes(); }
50259 };
50260 
50261 class TraceConfig : public ::protozero::Message {
50262  public:
50263   using Decoder = TraceConfig_Decoder;
50264   enum : int32_t {
50265     kBuffersFieldNumber = 1,
50266     kDataSourcesFieldNumber = 2,
50267     kBuiltinDataSourcesFieldNumber = 20,
50268     kDurationMsFieldNumber = 3,
50269     kEnableExtraGuardrailsFieldNumber = 4,
50270     kLockdownModeFieldNumber = 5,
50271     kProducersFieldNumber = 6,
50272     kStatsdMetadataFieldNumber = 7,
50273     kWriteIntoFileFieldNumber = 8,
50274     kOutputPathFieldNumber = 29,
50275     kFileWritePeriodMsFieldNumber = 9,
50276     kMaxFileSizeBytesFieldNumber = 10,
50277     kGuardrailOverridesFieldNumber = 11,
50278     kDeferredStartFieldNumber = 12,
50279     kFlushPeriodMsFieldNumber = 13,
50280     kFlushTimeoutMsFieldNumber = 14,
50281     kDataSourceStopTimeoutMsFieldNumber = 23,
50282     kNotifyTraceurFieldNumber = 16,
50283     kBugreportScoreFieldNumber = 30,
50284     kTriggerConfigFieldNumber = 17,
50285     kActivateTriggersFieldNumber = 18,
50286     kIncrementalStateConfigFieldNumber = 21,
50287     kAllowUserBuildTracingFieldNumber = 19,
50288     kUniqueSessionNameFieldNumber = 22,
50289     kCompressionTypeFieldNumber = 24,
50290     kIncidentReportConfigFieldNumber = 25,
50291     kStatsdLoggingFieldNumber = 31,
50292     kTraceUuidMsbFieldNumber = 27,
50293     kTraceUuidLsbFieldNumber = 28,
50294     kTraceFilterFieldNumber = 33,
50295   };
50296   using BufferConfig = ::perfetto::protos::pbzero::TraceConfig_BufferConfig;
50297   using DataSource = ::perfetto::protos::pbzero::TraceConfig_DataSource;
50298   using BuiltinDataSource = ::perfetto::protos::pbzero::TraceConfig_BuiltinDataSource;
50299   using ProducerConfig = ::perfetto::protos::pbzero::TraceConfig_ProducerConfig;
50300   using StatsdMetadata = ::perfetto::protos::pbzero::TraceConfig_StatsdMetadata;
50301   using GuardrailOverrides = ::perfetto::protos::pbzero::TraceConfig_GuardrailOverrides;
50302   using TriggerConfig = ::perfetto::protos::pbzero::TraceConfig_TriggerConfig;
50303   using IncrementalStateConfig = ::perfetto::protos::pbzero::TraceConfig_IncrementalStateConfig;
50304   using IncidentReportConfig = ::perfetto::protos::pbzero::TraceConfig_IncidentReportConfig;
50305   using TraceFilter = ::perfetto::protos::pbzero::TraceConfig_TraceFilter;
50306   using LockdownModeOperation = ::perfetto::protos::pbzero::TraceConfig_LockdownModeOperation;
50307   using CompressionType = ::perfetto::protos::pbzero::TraceConfig_CompressionType;
50308   using StatsdLogging = ::perfetto::protos::pbzero::TraceConfig_StatsdLogging;
50309   static const LockdownModeOperation LOCKDOWN_UNCHANGED = TraceConfig_LockdownModeOperation_LOCKDOWN_UNCHANGED;
50310   static const LockdownModeOperation LOCKDOWN_CLEAR = TraceConfig_LockdownModeOperation_LOCKDOWN_CLEAR;
50311   static const LockdownModeOperation LOCKDOWN_SET = TraceConfig_LockdownModeOperation_LOCKDOWN_SET;
50312   static const CompressionType COMPRESSION_TYPE_UNSPECIFIED = TraceConfig_CompressionType_COMPRESSION_TYPE_UNSPECIFIED;
50313   static const CompressionType COMPRESSION_TYPE_DEFLATE = TraceConfig_CompressionType_COMPRESSION_TYPE_DEFLATE;
50314   static const StatsdLogging STATSD_LOGGING_UNSPECIFIED = TraceConfig_StatsdLogging_STATSD_LOGGING_UNSPECIFIED;
50315   static const StatsdLogging STATSD_LOGGING_ENABLED = TraceConfig_StatsdLogging_STATSD_LOGGING_ENABLED;
50316   static const StatsdLogging STATSD_LOGGING_DISABLED = TraceConfig_StatsdLogging_STATSD_LOGGING_DISABLED;
50317 
50318   using FieldMetadata_Buffers =
50319     ::protozero::proto_utils::FieldMetadata<
50320       1,
50321       ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
50322       ::protozero::proto_utils::ProtoSchemaType::kMessage,
50323       TraceConfig_BufferConfig,
50324       TraceConfig>;
50325 
50326   // Ceci n'est pas une pipe.
50327   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
50328   // type (and users are expected to use it as such, hence kCamelCase name).
50329   // It is declared as a function to keep protozero bindings header-only as
50330   // inline constexpr variables are not available until C++17 (while inline
50331   // functions are).
50332   // TODO(altimin): Use inline variable instead after adopting C++17.
kBuffers()50333   static constexpr FieldMetadata_Buffers kBuffers() { return {}; }
add_buffers()50334   template <typename T = TraceConfig_BufferConfig> T* add_buffers() {
50335     return BeginNestedMessage<T>(1);
50336   }
50337 
50338 
50339   using FieldMetadata_DataSources =
50340     ::protozero::proto_utils::FieldMetadata<
50341       2,
50342       ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
50343       ::protozero::proto_utils::ProtoSchemaType::kMessage,
50344       TraceConfig_DataSource,
50345       TraceConfig>;
50346 
50347   // Ceci n'est pas une pipe.
50348   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
50349   // type (and users are expected to use it as such, hence kCamelCase name).
50350   // It is declared as a function to keep protozero bindings header-only as
50351   // inline constexpr variables are not available until C++17 (while inline
50352   // functions are).
50353   // TODO(altimin): Use inline variable instead after adopting C++17.
kDataSources()50354   static constexpr FieldMetadata_DataSources kDataSources() { return {}; }
add_data_sources()50355   template <typename T = TraceConfig_DataSource> T* add_data_sources() {
50356     return BeginNestedMessage<T>(2);
50357   }
50358 
50359 
50360   using FieldMetadata_BuiltinDataSources =
50361     ::protozero::proto_utils::FieldMetadata<
50362       20,
50363       ::protozero::proto_utils::RepetitionType::kNotRepeated,
50364       ::protozero::proto_utils::ProtoSchemaType::kMessage,
50365       TraceConfig_BuiltinDataSource,
50366       TraceConfig>;
50367 
50368   // Ceci n'est pas une pipe.
50369   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
50370   // type (and users are expected to use it as such, hence kCamelCase name).
50371   // It is declared as a function to keep protozero bindings header-only as
50372   // inline constexpr variables are not available until C++17 (while inline
50373   // functions are).
50374   // TODO(altimin): Use inline variable instead after adopting C++17.
kBuiltinDataSources()50375   static constexpr FieldMetadata_BuiltinDataSources kBuiltinDataSources() { return {}; }
set_builtin_data_sources()50376   template <typename T = TraceConfig_BuiltinDataSource> T* set_builtin_data_sources() {
50377     return BeginNestedMessage<T>(20);
50378   }
50379 
50380 
50381   using FieldMetadata_DurationMs =
50382     ::protozero::proto_utils::FieldMetadata<
50383       3,
50384       ::protozero::proto_utils::RepetitionType::kNotRepeated,
50385       ::protozero::proto_utils::ProtoSchemaType::kUint32,
50386       uint32_t,
50387       TraceConfig>;
50388 
50389   // Ceci n'est pas une pipe.
50390   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
50391   // type (and users are expected to use it as such, hence kCamelCase name).
50392   // It is declared as a function to keep protozero bindings header-only as
50393   // inline constexpr variables are not available until C++17 (while inline
50394   // functions are).
50395   // TODO(altimin): Use inline variable instead after adopting C++17.
kDurationMs()50396   static constexpr FieldMetadata_DurationMs kDurationMs() { return {}; }
set_duration_ms(uint32_t value)50397   void set_duration_ms(uint32_t value) {
50398     static constexpr uint32_t field_id = FieldMetadata_DurationMs::kFieldId;
50399     // Call the appropriate protozero::Message::Append(field_id, ...)
50400     // method based on the type of the field.
50401     ::protozero::internal::FieldWriter<
50402       ::protozero::proto_utils::ProtoSchemaType::kUint32>
50403         ::Append(*this, field_id, value);
50404   }
50405 
50406   using FieldMetadata_EnableExtraGuardrails =
50407     ::protozero::proto_utils::FieldMetadata<
50408       4,
50409       ::protozero::proto_utils::RepetitionType::kNotRepeated,
50410       ::protozero::proto_utils::ProtoSchemaType::kBool,
50411       bool,
50412       TraceConfig>;
50413 
50414   // Ceci n'est pas une pipe.
50415   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
50416   // type (and users are expected to use it as such, hence kCamelCase name).
50417   // It is declared as a function to keep protozero bindings header-only as
50418   // inline constexpr variables are not available until C++17 (while inline
50419   // functions are).
50420   // TODO(altimin): Use inline variable instead after adopting C++17.
kEnableExtraGuardrails()50421   static constexpr FieldMetadata_EnableExtraGuardrails kEnableExtraGuardrails() { return {}; }
set_enable_extra_guardrails(bool value)50422   void set_enable_extra_guardrails(bool value) {
50423     static constexpr uint32_t field_id = FieldMetadata_EnableExtraGuardrails::kFieldId;
50424     // Call the appropriate protozero::Message::Append(field_id, ...)
50425     // method based on the type of the field.
50426     ::protozero::internal::FieldWriter<
50427       ::protozero::proto_utils::ProtoSchemaType::kBool>
50428         ::Append(*this, field_id, value);
50429   }
50430 
50431   using FieldMetadata_LockdownMode =
50432     ::protozero::proto_utils::FieldMetadata<
50433       5,
50434       ::protozero::proto_utils::RepetitionType::kNotRepeated,
50435       ::protozero::proto_utils::ProtoSchemaType::kEnum,
50436       ::perfetto::protos::pbzero::TraceConfig_LockdownModeOperation,
50437       TraceConfig>;
50438 
50439   // Ceci n'est pas une pipe.
50440   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
50441   // type (and users are expected to use it as such, hence kCamelCase name).
50442   // It is declared as a function to keep protozero bindings header-only as
50443   // inline constexpr variables are not available until C++17 (while inline
50444   // functions are).
50445   // TODO(altimin): Use inline variable instead after adopting C++17.
kLockdownMode()50446   static constexpr FieldMetadata_LockdownMode kLockdownMode() { return {}; }
set_lockdown_mode(::perfetto::protos::pbzero::TraceConfig_LockdownModeOperation value)50447   void set_lockdown_mode(::perfetto::protos::pbzero::TraceConfig_LockdownModeOperation value) {
50448     static constexpr uint32_t field_id = FieldMetadata_LockdownMode::kFieldId;
50449     // Call the appropriate protozero::Message::Append(field_id, ...)
50450     // method based on the type of the field.
50451     ::protozero::internal::FieldWriter<
50452       ::protozero::proto_utils::ProtoSchemaType::kEnum>
50453         ::Append(*this, field_id, value);
50454   }
50455 
50456   using FieldMetadata_Producers =
50457     ::protozero::proto_utils::FieldMetadata<
50458       6,
50459       ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
50460       ::protozero::proto_utils::ProtoSchemaType::kMessage,
50461       TraceConfig_ProducerConfig,
50462       TraceConfig>;
50463 
50464   // Ceci n'est pas une pipe.
50465   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
50466   // type (and users are expected to use it as such, hence kCamelCase name).
50467   // It is declared as a function to keep protozero bindings header-only as
50468   // inline constexpr variables are not available until C++17 (while inline
50469   // functions are).
50470   // TODO(altimin): Use inline variable instead after adopting C++17.
kProducers()50471   static constexpr FieldMetadata_Producers kProducers() { return {}; }
add_producers()50472   template <typename T = TraceConfig_ProducerConfig> T* add_producers() {
50473     return BeginNestedMessage<T>(6);
50474   }
50475 
50476 
50477   using FieldMetadata_StatsdMetadata =
50478     ::protozero::proto_utils::FieldMetadata<
50479       7,
50480       ::protozero::proto_utils::RepetitionType::kNotRepeated,
50481       ::protozero::proto_utils::ProtoSchemaType::kMessage,
50482       TraceConfig_StatsdMetadata,
50483       TraceConfig>;
50484 
50485   // Ceci n'est pas une pipe.
50486   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
50487   // type (and users are expected to use it as such, hence kCamelCase name).
50488   // It is declared as a function to keep protozero bindings header-only as
50489   // inline constexpr variables are not available until C++17 (while inline
50490   // functions are).
50491   // TODO(altimin): Use inline variable instead after adopting C++17.
kStatsdMetadata()50492   static constexpr FieldMetadata_StatsdMetadata kStatsdMetadata() { return {}; }
set_statsd_metadata()50493   template <typename T = TraceConfig_StatsdMetadata> T* set_statsd_metadata() {
50494     return BeginNestedMessage<T>(7);
50495   }
50496 
50497 
50498   using FieldMetadata_WriteIntoFile =
50499     ::protozero::proto_utils::FieldMetadata<
50500       8,
50501       ::protozero::proto_utils::RepetitionType::kNotRepeated,
50502       ::protozero::proto_utils::ProtoSchemaType::kBool,
50503       bool,
50504       TraceConfig>;
50505 
50506   // Ceci n'est pas une pipe.
50507   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
50508   // type (and users are expected to use it as such, hence kCamelCase name).
50509   // It is declared as a function to keep protozero bindings header-only as
50510   // inline constexpr variables are not available until C++17 (while inline
50511   // functions are).
50512   // TODO(altimin): Use inline variable instead after adopting C++17.
kWriteIntoFile()50513   static constexpr FieldMetadata_WriteIntoFile kWriteIntoFile() { return {}; }
set_write_into_file(bool value)50514   void set_write_into_file(bool value) {
50515     static constexpr uint32_t field_id = FieldMetadata_WriteIntoFile::kFieldId;
50516     // Call the appropriate protozero::Message::Append(field_id, ...)
50517     // method based on the type of the field.
50518     ::protozero::internal::FieldWriter<
50519       ::protozero::proto_utils::ProtoSchemaType::kBool>
50520         ::Append(*this, field_id, value);
50521   }
50522 
50523   using FieldMetadata_OutputPath =
50524     ::protozero::proto_utils::FieldMetadata<
50525       29,
50526       ::protozero::proto_utils::RepetitionType::kNotRepeated,
50527       ::protozero::proto_utils::ProtoSchemaType::kString,
50528       std::string,
50529       TraceConfig>;
50530 
50531   // Ceci n'est pas une pipe.
50532   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
50533   // type (and users are expected to use it as such, hence kCamelCase name).
50534   // It is declared as a function to keep protozero bindings header-only as
50535   // inline constexpr variables are not available until C++17 (while inline
50536   // functions are).
50537   // TODO(altimin): Use inline variable instead after adopting C++17.
kOutputPath()50538   static constexpr FieldMetadata_OutputPath kOutputPath() { return {}; }
set_output_path(const char * data,size_t size)50539   void set_output_path(const char* data, size_t size) {
50540     AppendBytes(FieldMetadata_OutputPath::kFieldId, data, size);
50541   }
set_output_path(std::string value)50542   void set_output_path(std::string value) {
50543     static constexpr uint32_t field_id = FieldMetadata_OutputPath::kFieldId;
50544     // Call the appropriate protozero::Message::Append(field_id, ...)
50545     // method based on the type of the field.
50546     ::protozero::internal::FieldWriter<
50547       ::protozero::proto_utils::ProtoSchemaType::kString>
50548         ::Append(*this, field_id, value);
50549   }
50550 
50551   using FieldMetadata_FileWritePeriodMs =
50552     ::protozero::proto_utils::FieldMetadata<
50553       9,
50554       ::protozero::proto_utils::RepetitionType::kNotRepeated,
50555       ::protozero::proto_utils::ProtoSchemaType::kUint32,
50556       uint32_t,
50557       TraceConfig>;
50558 
50559   // Ceci n'est pas une pipe.
50560   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
50561   // type (and users are expected to use it as such, hence kCamelCase name).
50562   // It is declared as a function to keep protozero bindings header-only as
50563   // inline constexpr variables are not available until C++17 (while inline
50564   // functions are).
50565   // TODO(altimin): Use inline variable instead after adopting C++17.
kFileWritePeriodMs()50566   static constexpr FieldMetadata_FileWritePeriodMs kFileWritePeriodMs() { return {}; }
set_file_write_period_ms(uint32_t value)50567   void set_file_write_period_ms(uint32_t value) {
50568     static constexpr uint32_t field_id = FieldMetadata_FileWritePeriodMs::kFieldId;
50569     // Call the appropriate protozero::Message::Append(field_id, ...)
50570     // method based on the type of the field.
50571     ::protozero::internal::FieldWriter<
50572       ::protozero::proto_utils::ProtoSchemaType::kUint32>
50573         ::Append(*this, field_id, value);
50574   }
50575 
50576   using FieldMetadata_MaxFileSizeBytes =
50577     ::protozero::proto_utils::FieldMetadata<
50578       10,
50579       ::protozero::proto_utils::RepetitionType::kNotRepeated,
50580       ::protozero::proto_utils::ProtoSchemaType::kUint64,
50581       uint64_t,
50582       TraceConfig>;
50583 
50584   // Ceci n'est pas une pipe.
50585   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
50586   // type (and users are expected to use it as such, hence kCamelCase name).
50587   // It is declared as a function to keep protozero bindings header-only as
50588   // inline constexpr variables are not available until C++17 (while inline
50589   // functions are).
50590   // TODO(altimin): Use inline variable instead after adopting C++17.
kMaxFileSizeBytes()50591   static constexpr FieldMetadata_MaxFileSizeBytes kMaxFileSizeBytes() { return {}; }
set_max_file_size_bytes(uint64_t value)50592   void set_max_file_size_bytes(uint64_t value) {
50593     static constexpr uint32_t field_id = FieldMetadata_MaxFileSizeBytes::kFieldId;
50594     // Call the appropriate protozero::Message::Append(field_id, ...)
50595     // method based on the type of the field.
50596     ::protozero::internal::FieldWriter<
50597       ::protozero::proto_utils::ProtoSchemaType::kUint64>
50598         ::Append(*this, field_id, value);
50599   }
50600 
50601   using FieldMetadata_GuardrailOverrides =
50602     ::protozero::proto_utils::FieldMetadata<
50603       11,
50604       ::protozero::proto_utils::RepetitionType::kNotRepeated,
50605       ::protozero::proto_utils::ProtoSchemaType::kMessage,
50606       TraceConfig_GuardrailOverrides,
50607       TraceConfig>;
50608 
50609   // Ceci n'est pas une pipe.
50610   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
50611   // type (and users are expected to use it as such, hence kCamelCase name).
50612   // It is declared as a function to keep protozero bindings header-only as
50613   // inline constexpr variables are not available until C++17 (while inline
50614   // functions are).
50615   // TODO(altimin): Use inline variable instead after adopting C++17.
kGuardrailOverrides()50616   static constexpr FieldMetadata_GuardrailOverrides kGuardrailOverrides() { return {}; }
set_guardrail_overrides()50617   template <typename T = TraceConfig_GuardrailOverrides> T* set_guardrail_overrides() {
50618     return BeginNestedMessage<T>(11);
50619   }
50620 
50621 
50622   using FieldMetadata_DeferredStart =
50623     ::protozero::proto_utils::FieldMetadata<
50624       12,
50625       ::protozero::proto_utils::RepetitionType::kNotRepeated,
50626       ::protozero::proto_utils::ProtoSchemaType::kBool,
50627       bool,
50628       TraceConfig>;
50629 
50630   // Ceci n'est pas une pipe.
50631   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
50632   // type (and users are expected to use it as such, hence kCamelCase name).
50633   // It is declared as a function to keep protozero bindings header-only as
50634   // inline constexpr variables are not available until C++17 (while inline
50635   // functions are).
50636   // TODO(altimin): Use inline variable instead after adopting C++17.
kDeferredStart()50637   static constexpr FieldMetadata_DeferredStart kDeferredStart() { return {}; }
set_deferred_start(bool value)50638   void set_deferred_start(bool value) {
50639     static constexpr uint32_t field_id = FieldMetadata_DeferredStart::kFieldId;
50640     // Call the appropriate protozero::Message::Append(field_id, ...)
50641     // method based on the type of the field.
50642     ::protozero::internal::FieldWriter<
50643       ::protozero::proto_utils::ProtoSchemaType::kBool>
50644         ::Append(*this, field_id, value);
50645   }
50646 
50647   using FieldMetadata_FlushPeriodMs =
50648     ::protozero::proto_utils::FieldMetadata<
50649       13,
50650       ::protozero::proto_utils::RepetitionType::kNotRepeated,
50651       ::protozero::proto_utils::ProtoSchemaType::kUint32,
50652       uint32_t,
50653       TraceConfig>;
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.
kFlushPeriodMs()50662   static constexpr FieldMetadata_FlushPeriodMs kFlushPeriodMs() { return {}; }
set_flush_period_ms(uint32_t value)50663   void set_flush_period_ms(uint32_t value) {
50664     static constexpr uint32_t field_id = FieldMetadata_FlushPeriodMs::kFieldId;
50665     // Call the appropriate protozero::Message::Append(field_id, ...)
50666     // method based on the type of the field.
50667     ::protozero::internal::FieldWriter<
50668       ::protozero::proto_utils::ProtoSchemaType::kUint32>
50669         ::Append(*this, field_id, value);
50670   }
50671 
50672   using FieldMetadata_FlushTimeoutMs =
50673     ::protozero::proto_utils::FieldMetadata<
50674       14,
50675       ::protozero::proto_utils::RepetitionType::kNotRepeated,
50676       ::protozero::proto_utils::ProtoSchemaType::kUint32,
50677       uint32_t,
50678       TraceConfig>;
50679 
50680   // Ceci n'est pas une pipe.
50681   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
50682   // type (and users are expected to use it as such, hence kCamelCase name).
50683   // It is declared as a function to keep protozero bindings header-only as
50684   // inline constexpr variables are not available until C++17 (while inline
50685   // functions are).
50686   // TODO(altimin): Use inline variable instead after adopting C++17.
kFlushTimeoutMs()50687   static constexpr FieldMetadata_FlushTimeoutMs kFlushTimeoutMs() { return {}; }
set_flush_timeout_ms(uint32_t value)50688   void set_flush_timeout_ms(uint32_t value) {
50689     static constexpr uint32_t field_id = FieldMetadata_FlushTimeoutMs::kFieldId;
50690     // Call the appropriate protozero::Message::Append(field_id, ...)
50691     // method based on the type of the field.
50692     ::protozero::internal::FieldWriter<
50693       ::protozero::proto_utils::ProtoSchemaType::kUint32>
50694         ::Append(*this, field_id, value);
50695   }
50696 
50697   using FieldMetadata_DataSourceStopTimeoutMs =
50698     ::protozero::proto_utils::FieldMetadata<
50699       23,
50700       ::protozero::proto_utils::RepetitionType::kNotRepeated,
50701       ::protozero::proto_utils::ProtoSchemaType::kUint32,
50702       uint32_t,
50703       TraceConfig>;
50704 
50705   // Ceci n'est pas une pipe.
50706   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
50707   // type (and users are expected to use it as such, hence kCamelCase name).
50708   // It is declared as a function to keep protozero bindings header-only as
50709   // inline constexpr variables are not available until C++17 (while inline
50710   // functions are).
50711   // TODO(altimin): Use inline variable instead after adopting C++17.
kDataSourceStopTimeoutMs()50712   static constexpr FieldMetadata_DataSourceStopTimeoutMs kDataSourceStopTimeoutMs() { return {}; }
set_data_source_stop_timeout_ms(uint32_t value)50713   void set_data_source_stop_timeout_ms(uint32_t value) {
50714     static constexpr uint32_t field_id = FieldMetadata_DataSourceStopTimeoutMs::kFieldId;
50715     // Call the appropriate protozero::Message::Append(field_id, ...)
50716     // method based on the type of the field.
50717     ::protozero::internal::FieldWriter<
50718       ::protozero::proto_utils::ProtoSchemaType::kUint32>
50719         ::Append(*this, field_id, value);
50720   }
50721 
50722   using FieldMetadata_NotifyTraceur =
50723     ::protozero::proto_utils::FieldMetadata<
50724       16,
50725       ::protozero::proto_utils::RepetitionType::kNotRepeated,
50726       ::protozero::proto_utils::ProtoSchemaType::kBool,
50727       bool,
50728       TraceConfig>;
50729 
50730   // Ceci n'est pas une pipe.
50731   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
50732   // type (and users are expected to use it as such, hence kCamelCase name).
50733   // It is declared as a function to keep protozero bindings header-only as
50734   // inline constexpr variables are not available until C++17 (while inline
50735   // functions are).
50736   // TODO(altimin): Use inline variable instead after adopting C++17.
kNotifyTraceur()50737   static constexpr FieldMetadata_NotifyTraceur kNotifyTraceur() { return {}; }
set_notify_traceur(bool value)50738   void set_notify_traceur(bool value) {
50739     static constexpr uint32_t field_id = FieldMetadata_NotifyTraceur::kFieldId;
50740     // Call the appropriate protozero::Message::Append(field_id, ...)
50741     // method based on the type of the field.
50742     ::protozero::internal::FieldWriter<
50743       ::protozero::proto_utils::ProtoSchemaType::kBool>
50744         ::Append(*this, field_id, value);
50745   }
50746 
50747   using FieldMetadata_BugreportScore =
50748     ::protozero::proto_utils::FieldMetadata<
50749       30,
50750       ::protozero::proto_utils::RepetitionType::kNotRepeated,
50751       ::protozero::proto_utils::ProtoSchemaType::kInt32,
50752       int32_t,
50753       TraceConfig>;
50754 
50755   // Ceci n'est pas une pipe.
50756   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
50757   // type (and users are expected to use it as such, hence kCamelCase name).
50758   // It is declared as a function to keep protozero bindings header-only as
50759   // inline constexpr variables are not available until C++17 (while inline
50760   // functions are).
50761   // TODO(altimin): Use inline variable instead after adopting C++17.
kBugreportScore()50762   static constexpr FieldMetadata_BugreportScore kBugreportScore() { return {}; }
set_bugreport_score(int32_t value)50763   void set_bugreport_score(int32_t value) {
50764     static constexpr uint32_t field_id = FieldMetadata_BugreportScore::kFieldId;
50765     // Call the appropriate protozero::Message::Append(field_id, ...)
50766     // method based on the type of the field.
50767     ::protozero::internal::FieldWriter<
50768       ::protozero::proto_utils::ProtoSchemaType::kInt32>
50769         ::Append(*this, field_id, value);
50770   }
50771 
50772   using FieldMetadata_TriggerConfig =
50773     ::protozero::proto_utils::FieldMetadata<
50774       17,
50775       ::protozero::proto_utils::RepetitionType::kNotRepeated,
50776       ::protozero::proto_utils::ProtoSchemaType::kMessage,
50777       TraceConfig_TriggerConfig,
50778       TraceConfig>;
50779 
50780   // Ceci n'est pas une pipe.
50781   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
50782   // type (and users are expected to use it as such, hence kCamelCase name).
50783   // It is declared as a function to keep protozero bindings header-only as
50784   // inline constexpr variables are not available until C++17 (while inline
50785   // functions are).
50786   // TODO(altimin): Use inline variable instead after adopting C++17.
kTriggerConfig()50787   static constexpr FieldMetadata_TriggerConfig kTriggerConfig() { return {}; }
set_trigger_config()50788   template <typename T = TraceConfig_TriggerConfig> T* set_trigger_config() {
50789     return BeginNestedMessage<T>(17);
50790   }
50791 
50792 
50793   using FieldMetadata_ActivateTriggers =
50794     ::protozero::proto_utils::FieldMetadata<
50795       18,
50796       ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
50797       ::protozero::proto_utils::ProtoSchemaType::kString,
50798       std::string,
50799       TraceConfig>;
50800 
50801   // Ceci n'est pas une pipe.
50802   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
50803   // type (and users are expected to use it as such, hence kCamelCase name).
50804   // It is declared as a function to keep protozero bindings header-only as
50805   // inline constexpr variables are not available until C++17 (while inline
50806   // functions are).
50807   // TODO(altimin): Use inline variable instead after adopting C++17.
kActivateTriggers()50808   static constexpr FieldMetadata_ActivateTriggers kActivateTriggers() { return {}; }
add_activate_triggers(const char * data,size_t size)50809   void add_activate_triggers(const char* data, size_t size) {
50810     AppendBytes(FieldMetadata_ActivateTriggers::kFieldId, data, size);
50811   }
add_activate_triggers(std::string value)50812   void add_activate_triggers(std::string value) {
50813     static constexpr uint32_t field_id = FieldMetadata_ActivateTriggers::kFieldId;
50814     // Call the appropriate protozero::Message::Append(field_id, ...)
50815     // method based on the type of the field.
50816     ::protozero::internal::FieldWriter<
50817       ::protozero::proto_utils::ProtoSchemaType::kString>
50818         ::Append(*this, field_id, value);
50819   }
50820 
50821   using FieldMetadata_IncrementalStateConfig =
50822     ::protozero::proto_utils::FieldMetadata<
50823       21,
50824       ::protozero::proto_utils::RepetitionType::kNotRepeated,
50825       ::protozero::proto_utils::ProtoSchemaType::kMessage,
50826       TraceConfig_IncrementalStateConfig,
50827       TraceConfig>;
50828 
50829   // Ceci n'est pas une pipe.
50830   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
50831   // type (and users are expected to use it as such, hence kCamelCase name).
50832   // It is declared as a function to keep protozero bindings header-only as
50833   // inline constexpr variables are not available until C++17 (while inline
50834   // functions are).
50835   // TODO(altimin): Use inline variable instead after adopting C++17.
kIncrementalStateConfig()50836   static constexpr FieldMetadata_IncrementalStateConfig kIncrementalStateConfig() { return {}; }
set_incremental_state_config()50837   template <typename T = TraceConfig_IncrementalStateConfig> T* set_incremental_state_config() {
50838     return BeginNestedMessage<T>(21);
50839   }
50840 
50841 
50842   using FieldMetadata_AllowUserBuildTracing =
50843     ::protozero::proto_utils::FieldMetadata<
50844       19,
50845       ::protozero::proto_utils::RepetitionType::kNotRepeated,
50846       ::protozero::proto_utils::ProtoSchemaType::kBool,
50847       bool,
50848       TraceConfig>;
50849 
50850   // Ceci n'est pas une pipe.
50851   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
50852   // type (and users are expected to use it as such, hence kCamelCase name).
50853   // It is declared as a function to keep protozero bindings header-only as
50854   // inline constexpr variables are not available until C++17 (while inline
50855   // functions are).
50856   // TODO(altimin): Use inline variable instead after adopting C++17.
kAllowUserBuildTracing()50857   static constexpr FieldMetadata_AllowUserBuildTracing kAllowUserBuildTracing() { return {}; }
set_allow_user_build_tracing(bool value)50858   void set_allow_user_build_tracing(bool value) {
50859     static constexpr uint32_t field_id = FieldMetadata_AllowUserBuildTracing::kFieldId;
50860     // Call the appropriate protozero::Message::Append(field_id, ...)
50861     // method based on the type of the field.
50862     ::protozero::internal::FieldWriter<
50863       ::protozero::proto_utils::ProtoSchemaType::kBool>
50864         ::Append(*this, field_id, value);
50865   }
50866 
50867   using FieldMetadata_UniqueSessionName =
50868     ::protozero::proto_utils::FieldMetadata<
50869       22,
50870       ::protozero::proto_utils::RepetitionType::kNotRepeated,
50871       ::protozero::proto_utils::ProtoSchemaType::kString,
50872       std::string,
50873       TraceConfig>;
50874 
50875   // Ceci n'est pas une pipe.
50876   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
50877   // type (and users are expected to use it as such, hence kCamelCase name).
50878   // It is declared as a function to keep protozero bindings header-only as
50879   // inline constexpr variables are not available until C++17 (while inline
50880   // functions are).
50881   // TODO(altimin): Use inline variable instead after adopting C++17.
kUniqueSessionName()50882   static constexpr FieldMetadata_UniqueSessionName kUniqueSessionName() { return {}; }
set_unique_session_name(const char * data,size_t size)50883   void set_unique_session_name(const char* data, size_t size) {
50884     AppendBytes(FieldMetadata_UniqueSessionName::kFieldId, data, size);
50885   }
set_unique_session_name(std::string value)50886   void set_unique_session_name(std::string value) {
50887     static constexpr uint32_t field_id = FieldMetadata_UniqueSessionName::kFieldId;
50888     // Call the appropriate protozero::Message::Append(field_id, ...)
50889     // method based on the type of the field.
50890     ::protozero::internal::FieldWriter<
50891       ::protozero::proto_utils::ProtoSchemaType::kString>
50892         ::Append(*this, field_id, value);
50893   }
50894 
50895   using FieldMetadata_CompressionType =
50896     ::protozero::proto_utils::FieldMetadata<
50897       24,
50898       ::protozero::proto_utils::RepetitionType::kNotRepeated,
50899       ::protozero::proto_utils::ProtoSchemaType::kEnum,
50900       ::perfetto::protos::pbzero::TraceConfig_CompressionType,
50901       TraceConfig>;
50902 
50903   // Ceci n'est pas une pipe.
50904   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
50905   // type (and users are expected to use it as such, hence kCamelCase name).
50906   // It is declared as a function to keep protozero bindings header-only as
50907   // inline constexpr variables are not available until C++17 (while inline
50908   // functions are).
50909   // TODO(altimin): Use inline variable instead after adopting C++17.
kCompressionType()50910   static constexpr FieldMetadata_CompressionType kCompressionType() { return {}; }
set_compression_type(::perfetto::protos::pbzero::TraceConfig_CompressionType value)50911   void set_compression_type(::perfetto::protos::pbzero::TraceConfig_CompressionType value) {
50912     static constexpr uint32_t field_id = FieldMetadata_CompressionType::kFieldId;
50913     // Call the appropriate protozero::Message::Append(field_id, ...)
50914     // method based on the type of the field.
50915     ::protozero::internal::FieldWriter<
50916       ::protozero::proto_utils::ProtoSchemaType::kEnum>
50917         ::Append(*this, field_id, value);
50918   }
50919 
50920   using FieldMetadata_IncidentReportConfig =
50921     ::protozero::proto_utils::FieldMetadata<
50922       25,
50923       ::protozero::proto_utils::RepetitionType::kNotRepeated,
50924       ::protozero::proto_utils::ProtoSchemaType::kMessage,
50925       TraceConfig_IncidentReportConfig,
50926       TraceConfig>;
50927 
50928   // Ceci n'est pas une pipe.
50929   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
50930   // type (and users are expected to use it as such, hence kCamelCase name).
50931   // It is declared as a function to keep protozero bindings header-only as
50932   // inline constexpr variables are not available until C++17 (while inline
50933   // functions are).
50934   // TODO(altimin): Use inline variable instead after adopting C++17.
kIncidentReportConfig()50935   static constexpr FieldMetadata_IncidentReportConfig kIncidentReportConfig() { return {}; }
set_incident_report_config()50936   template <typename T = TraceConfig_IncidentReportConfig> T* set_incident_report_config() {
50937     return BeginNestedMessage<T>(25);
50938   }
50939 
50940 
50941   using FieldMetadata_StatsdLogging =
50942     ::protozero::proto_utils::FieldMetadata<
50943       31,
50944       ::protozero::proto_utils::RepetitionType::kNotRepeated,
50945       ::protozero::proto_utils::ProtoSchemaType::kEnum,
50946       ::perfetto::protos::pbzero::TraceConfig_StatsdLogging,
50947       TraceConfig>;
50948 
50949   // Ceci n'est pas une pipe.
50950   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
50951   // type (and users are expected to use it as such, hence kCamelCase name).
50952   // It is declared as a function to keep protozero bindings header-only as
50953   // inline constexpr variables are not available until C++17 (while inline
50954   // functions are).
50955   // TODO(altimin): Use inline variable instead after adopting C++17.
kStatsdLogging()50956   static constexpr FieldMetadata_StatsdLogging kStatsdLogging() { return {}; }
set_statsd_logging(::perfetto::protos::pbzero::TraceConfig_StatsdLogging value)50957   void set_statsd_logging(::perfetto::protos::pbzero::TraceConfig_StatsdLogging value) {
50958     static constexpr uint32_t field_id = FieldMetadata_StatsdLogging::kFieldId;
50959     // Call the appropriate protozero::Message::Append(field_id, ...)
50960     // method based on the type of the field.
50961     ::protozero::internal::FieldWriter<
50962       ::protozero::proto_utils::ProtoSchemaType::kEnum>
50963         ::Append(*this, field_id, value);
50964   }
50965 
50966   using FieldMetadata_TraceUuidMsb =
50967     ::protozero::proto_utils::FieldMetadata<
50968       27,
50969       ::protozero::proto_utils::RepetitionType::kNotRepeated,
50970       ::protozero::proto_utils::ProtoSchemaType::kInt64,
50971       int64_t,
50972       TraceConfig>;
50973 
50974   // Ceci n'est pas une pipe.
50975   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
50976   // type (and users are expected to use it as such, hence kCamelCase name).
50977   // It is declared as a function to keep protozero bindings header-only as
50978   // inline constexpr variables are not available until C++17 (while inline
50979   // functions are).
50980   // TODO(altimin): Use inline variable instead after adopting C++17.
kTraceUuidMsb()50981   static constexpr FieldMetadata_TraceUuidMsb kTraceUuidMsb() { return {}; }
set_trace_uuid_msb(int64_t value)50982   void set_trace_uuid_msb(int64_t value) {
50983     static constexpr uint32_t field_id = FieldMetadata_TraceUuidMsb::kFieldId;
50984     // Call the appropriate protozero::Message::Append(field_id, ...)
50985     // method based on the type of the field.
50986     ::protozero::internal::FieldWriter<
50987       ::protozero::proto_utils::ProtoSchemaType::kInt64>
50988         ::Append(*this, field_id, value);
50989   }
50990 
50991   using FieldMetadata_TraceUuidLsb =
50992     ::protozero::proto_utils::FieldMetadata<
50993       28,
50994       ::protozero::proto_utils::RepetitionType::kNotRepeated,
50995       ::protozero::proto_utils::ProtoSchemaType::kInt64,
50996       int64_t,
50997       TraceConfig>;
50998 
50999   // Ceci n'est pas une pipe.
51000   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
51001   // type (and users are expected to use it as such, hence kCamelCase name).
51002   // It is declared as a function to keep protozero bindings header-only as
51003   // inline constexpr variables are not available until C++17 (while inline
51004   // functions are).
51005   // TODO(altimin): Use inline variable instead after adopting C++17.
kTraceUuidLsb()51006   static constexpr FieldMetadata_TraceUuidLsb kTraceUuidLsb() { return {}; }
set_trace_uuid_lsb(int64_t value)51007   void set_trace_uuid_lsb(int64_t value) {
51008     static constexpr uint32_t field_id = FieldMetadata_TraceUuidLsb::kFieldId;
51009     // Call the appropriate protozero::Message::Append(field_id, ...)
51010     // method based on the type of the field.
51011     ::protozero::internal::FieldWriter<
51012       ::protozero::proto_utils::ProtoSchemaType::kInt64>
51013         ::Append(*this, field_id, value);
51014   }
51015 
51016   using FieldMetadata_TraceFilter =
51017     ::protozero::proto_utils::FieldMetadata<
51018       33,
51019       ::protozero::proto_utils::RepetitionType::kNotRepeated,
51020       ::protozero::proto_utils::ProtoSchemaType::kMessage,
51021       TraceConfig_TraceFilter,
51022       TraceConfig>;
51023 
51024   // Ceci n'est pas une pipe.
51025   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
51026   // type (and users are expected to use it as such, hence kCamelCase name).
51027   // It is declared as a function to keep protozero bindings header-only as
51028   // inline constexpr variables are not available until C++17 (while inline
51029   // functions are).
51030   // TODO(altimin): Use inline variable instead after adopting C++17.
kTraceFilter()51031   static constexpr FieldMetadata_TraceFilter kTraceFilter() { return {}; }
set_trace_filter()51032   template <typename T = TraceConfig_TraceFilter> T* set_trace_filter() {
51033     return BeginNestedMessage<T>(33);
51034   }
51035 
51036 };
51037 
51038 class TraceConfig_TraceFilter_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
51039  public:
TraceConfig_TraceFilter_Decoder(const uint8_t * data,size_t len)51040   TraceConfig_TraceFilter_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
TraceConfig_TraceFilter_Decoder(const std::string & raw)51041   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)51042   explicit TraceConfig_TraceFilter_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
has_bytecode() const51043   bool has_bytecode() const { return at<1>().valid(); }
bytecode() const51044   ::protozero::ConstBytes bytecode() const { return at<1>().as_bytes(); }
51045 };
51046 
51047 class TraceConfig_TraceFilter : public ::protozero::Message {
51048  public:
51049   using Decoder = TraceConfig_TraceFilter_Decoder;
51050   enum : int32_t {
51051     kBytecodeFieldNumber = 1,
51052   };
51053 
51054   using FieldMetadata_Bytecode =
51055     ::protozero::proto_utils::FieldMetadata<
51056       1,
51057       ::protozero::proto_utils::RepetitionType::kNotRepeated,
51058       ::protozero::proto_utils::ProtoSchemaType::kBytes,
51059       std::string,
51060       TraceConfig_TraceFilter>;
51061 
51062   // Ceci n'est pas une pipe.
51063   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
51064   // type (and users are expected to use it as such, hence kCamelCase name).
51065   // It is declared as a function to keep protozero bindings header-only as
51066   // inline constexpr variables are not available until C++17 (while inline
51067   // functions are).
51068   // TODO(altimin): Use inline variable instead after adopting C++17.
kBytecode()51069   static constexpr FieldMetadata_Bytecode kBytecode() { return {}; }
set_bytecode(const uint8_t * data,size_t size)51070   void set_bytecode(const uint8_t* data, size_t size) {
51071     AppendBytes(FieldMetadata_Bytecode::kFieldId, data, size);
51072   }
set_bytecode(std::string value)51073   void set_bytecode(std::string value) {
51074     static constexpr uint32_t field_id = FieldMetadata_Bytecode::kFieldId;
51075     // Call the appropriate protozero::Message::Append(field_id, ...)
51076     // method based on the type of the field.
51077     ::protozero::internal::FieldWriter<
51078       ::protozero::proto_utils::ProtoSchemaType::kBytes>
51079         ::Append(*this, field_id, value);
51080   }
51081 };
51082 
51083 class TraceConfig_IncidentReportConfig_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
51084  public:
TraceConfig_IncidentReportConfig_Decoder(const uint8_t * data,size_t len)51085   TraceConfig_IncidentReportConfig_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
TraceConfig_IncidentReportConfig_Decoder(const std::string & raw)51086   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)51087   explicit TraceConfig_IncidentReportConfig_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
has_destination_package() const51088   bool has_destination_package() const { return at<1>().valid(); }
destination_package() const51089   ::protozero::ConstChars destination_package() const { return at<1>().as_string(); }
has_destination_class() const51090   bool has_destination_class() const { return at<2>().valid(); }
destination_class() const51091   ::protozero::ConstChars destination_class() const { return at<2>().as_string(); }
has_privacy_level() const51092   bool has_privacy_level() const { return at<3>().valid(); }
privacy_level() const51093   int32_t privacy_level() const { return at<3>().as_int32(); }
has_skip_incidentd() const51094   bool has_skip_incidentd() const { return at<5>().valid(); }
skip_incidentd() const51095   bool skip_incidentd() const { return at<5>().as_bool(); }
has_skip_dropbox() const51096   bool has_skip_dropbox() const { return at<4>().valid(); }
skip_dropbox() const51097   bool skip_dropbox() const { return at<4>().as_bool(); }
51098 };
51099 
51100 class TraceConfig_IncidentReportConfig : public ::protozero::Message {
51101  public:
51102   using Decoder = TraceConfig_IncidentReportConfig_Decoder;
51103   enum : int32_t {
51104     kDestinationPackageFieldNumber = 1,
51105     kDestinationClassFieldNumber = 2,
51106     kPrivacyLevelFieldNumber = 3,
51107     kSkipIncidentdFieldNumber = 5,
51108     kSkipDropboxFieldNumber = 4,
51109   };
51110 
51111   using FieldMetadata_DestinationPackage =
51112     ::protozero::proto_utils::FieldMetadata<
51113       1,
51114       ::protozero::proto_utils::RepetitionType::kNotRepeated,
51115       ::protozero::proto_utils::ProtoSchemaType::kString,
51116       std::string,
51117       TraceConfig_IncidentReportConfig>;
51118 
51119   // Ceci n'est pas une pipe.
51120   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
51121   // type (and users are expected to use it as such, hence kCamelCase name).
51122   // It is declared as a function to keep protozero bindings header-only as
51123   // inline constexpr variables are not available until C++17 (while inline
51124   // functions are).
51125   // TODO(altimin): Use inline variable instead after adopting C++17.
kDestinationPackage()51126   static constexpr FieldMetadata_DestinationPackage kDestinationPackage() { return {}; }
set_destination_package(const char * data,size_t size)51127   void set_destination_package(const char* data, size_t size) {
51128     AppendBytes(FieldMetadata_DestinationPackage::kFieldId, data, size);
51129   }
set_destination_package(std::string value)51130   void set_destination_package(std::string value) {
51131     static constexpr uint32_t field_id = FieldMetadata_DestinationPackage::kFieldId;
51132     // Call the appropriate protozero::Message::Append(field_id, ...)
51133     // method based on the type of the field.
51134     ::protozero::internal::FieldWriter<
51135       ::protozero::proto_utils::ProtoSchemaType::kString>
51136         ::Append(*this, field_id, value);
51137   }
51138 
51139   using FieldMetadata_DestinationClass =
51140     ::protozero::proto_utils::FieldMetadata<
51141       2,
51142       ::protozero::proto_utils::RepetitionType::kNotRepeated,
51143       ::protozero::proto_utils::ProtoSchemaType::kString,
51144       std::string,
51145       TraceConfig_IncidentReportConfig>;
51146 
51147   // Ceci n'est pas une pipe.
51148   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
51149   // type (and users are expected to use it as such, hence kCamelCase name).
51150   // It is declared as a function to keep protozero bindings header-only as
51151   // inline constexpr variables are not available until C++17 (while inline
51152   // functions are).
51153   // TODO(altimin): Use inline variable instead after adopting C++17.
kDestinationClass()51154   static constexpr FieldMetadata_DestinationClass kDestinationClass() { return {}; }
set_destination_class(const char * data,size_t size)51155   void set_destination_class(const char* data, size_t size) {
51156     AppendBytes(FieldMetadata_DestinationClass::kFieldId, data, size);
51157   }
set_destination_class(std::string value)51158   void set_destination_class(std::string value) {
51159     static constexpr uint32_t field_id = FieldMetadata_DestinationClass::kFieldId;
51160     // Call the appropriate protozero::Message::Append(field_id, ...)
51161     // method based on the type of the field.
51162     ::protozero::internal::FieldWriter<
51163       ::protozero::proto_utils::ProtoSchemaType::kString>
51164         ::Append(*this, field_id, value);
51165   }
51166 
51167   using FieldMetadata_PrivacyLevel =
51168     ::protozero::proto_utils::FieldMetadata<
51169       3,
51170       ::protozero::proto_utils::RepetitionType::kNotRepeated,
51171       ::protozero::proto_utils::ProtoSchemaType::kInt32,
51172       int32_t,
51173       TraceConfig_IncidentReportConfig>;
51174 
51175   // Ceci n'est pas une pipe.
51176   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
51177   // type (and users are expected to use it as such, hence kCamelCase name).
51178   // It is declared as a function to keep protozero bindings header-only as
51179   // inline constexpr variables are not available until C++17 (while inline
51180   // functions are).
51181   // TODO(altimin): Use inline variable instead after adopting C++17.
kPrivacyLevel()51182   static constexpr FieldMetadata_PrivacyLevel kPrivacyLevel() { return {}; }
set_privacy_level(int32_t value)51183   void set_privacy_level(int32_t value) {
51184     static constexpr uint32_t field_id = FieldMetadata_PrivacyLevel::kFieldId;
51185     // Call the appropriate protozero::Message::Append(field_id, ...)
51186     // method based on the type of the field.
51187     ::protozero::internal::FieldWriter<
51188       ::protozero::proto_utils::ProtoSchemaType::kInt32>
51189         ::Append(*this, field_id, value);
51190   }
51191 
51192   using FieldMetadata_SkipIncidentd =
51193     ::protozero::proto_utils::FieldMetadata<
51194       5,
51195       ::protozero::proto_utils::RepetitionType::kNotRepeated,
51196       ::protozero::proto_utils::ProtoSchemaType::kBool,
51197       bool,
51198       TraceConfig_IncidentReportConfig>;
51199 
51200   // Ceci n'est pas une pipe.
51201   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
51202   // type (and users are expected to use it as such, hence kCamelCase name).
51203   // It is declared as a function to keep protozero bindings header-only as
51204   // inline constexpr variables are not available until C++17 (while inline
51205   // functions are).
51206   // TODO(altimin): Use inline variable instead after adopting C++17.
kSkipIncidentd()51207   static constexpr FieldMetadata_SkipIncidentd kSkipIncidentd() { return {}; }
set_skip_incidentd(bool value)51208   void set_skip_incidentd(bool value) {
51209     static constexpr uint32_t field_id = FieldMetadata_SkipIncidentd::kFieldId;
51210     // Call the appropriate protozero::Message::Append(field_id, ...)
51211     // method based on the type of the field.
51212     ::protozero::internal::FieldWriter<
51213       ::protozero::proto_utils::ProtoSchemaType::kBool>
51214         ::Append(*this, field_id, value);
51215   }
51216 
51217   using FieldMetadata_SkipDropbox =
51218     ::protozero::proto_utils::FieldMetadata<
51219       4,
51220       ::protozero::proto_utils::RepetitionType::kNotRepeated,
51221       ::protozero::proto_utils::ProtoSchemaType::kBool,
51222       bool,
51223       TraceConfig_IncidentReportConfig>;
51224 
51225   // Ceci n'est pas une pipe.
51226   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
51227   // type (and users are expected to use it as such, hence kCamelCase name).
51228   // It is declared as a function to keep protozero bindings header-only as
51229   // inline constexpr variables are not available until C++17 (while inline
51230   // functions are).
51231   // TODO(altimin): Use inline variable instead after adopting C++17.
kSkipDropbox()51232   static constexpr FieldMetadata_SkipDropbox kSkipDropbox() { return {}; }
set_skip_dropbox(bool value)51233   void set_skip_dropbox(bool value) {
51234     static constexpr uint32_t field_id = FieldMetadata_SkipDropbox::kFieldId;
51235     // Call the appropriate protozero::Message::Append(field_id, ...)
51236     // method based on the type of the field.
51237     ::protozero::internal::FieldWriter<
51238       ::protozero::proto_utils::ProtoSchemaType::kBool>
51239         ::Append(*this, field_id, value);
51240   }
51241 };
51242 
51243 class TraceConfig_IncrementalStateConfig_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
51244  public:
TraceConfig_IncrementalStateConfig_Decoder(const uint8_t * data,size_t len)51245   TraceConfig_IncrementalStateConfig_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
TraceConfig_IncrementalStateConfig_Decoder(const std::string & raw)51246   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)51247   explicit TraceConfig_IncrementalStateConfig_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
has_clear_period_ms() const51248   bool has_clear_period_ms() const { return at<1>().valid(); }
clear_period_ms() const51249   uint32_t clear_period_ms() const { return at<1>().as_uint32(); }
51250 };
51251 
51252 class TraceConfig_IncrementalStateConfig : public ::protozero::Message {
51253  public:
51254   using Decoder = TraceConfig_IncrementalStateConfig_Decoder;
51255   enum : int32_t {
51256     kClearPeriodMsFieldNumber = 1,
51257   };
51258 
51259   using FieldMetadata_ClearPeriodMs =
51260     ::protozero::proto_utils::FieldMetadata<
51261       1,
51262       ::protozero::proto_utils::RepetitionType::kNotRepeated,
51263       ::protozero::proto_utils::ProtoSchemaType::kUint32,
51264       uint32_t,
51265       TraceConfig_IncrementalStateConfig>;
51266 
51267   // Ceci n'est pas une pipe.
51268   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
51269   // type (and users are expected to use it as such, hence kCamelCase name).
51270   // It is declared as a function to keep protozero bindings header-only as
51271   // inline constexpr variables are not available until C++17 (while inline
51272   // functions are).
51273   // TODO(altimin): Use inline variable instead after adopting C++17.
kClearPeriodMs()51274   static constexpr FieldMetadata_ClearPeriodMs kClearPeriodMs() { return {}; }
set_clear_period_ms(uint32_t value)51275   void set_clear_period_ms(uint32_t value) {
51276     static constexpr uint32_t field_id = FieldMetadata_ClearPeriodMs::kFieldId;
51277     // Call the appropriate protozero::Message::Append(field_id, ...)
51278     // method based on the type of the field.
51279     ::protozero::internal::FieldWriter<
51280       ::protozero::proto_utils::ProtoSchemaType::kUint32>
51281         ::Append(*this, field_id, value);
51282   }
51283 };
51284 
51285 class TraceConfig_TriggerConfig_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
51286  public:
TraceConfig_TriggerConfig_Decoder(const uint8_t * data,size_t len)51287   TraceConfig_TriggerConfig_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
TraceConfig_TriggerConfig_Decoder(const std::string & raw)51288   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)51289   explicit TraceConfig_TriggerConfig_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
has_trigger_mode() const51290   bool has_trigger_mode() const { return at<1>().valid(); }
trigger_mode() const51291   int32_t trigger_mode() const { return at<1>().as_int32(); }
has_triggers() const51292   bool has_triggers() const { return at<2>().valid(); }
triggers() const51293   ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> triggers() const { return GetRepeated<::protozero::ConstBytes>(2); }
has_trigger_timeout_ms() const51294   bool has_trigger_timeout_ms() const { return at<3>().valid(); }
trigger_timeout_ms() const51295   uint32_t trigger_timeout_ms() const { return at<3>().as_uint32(); }
51296 };
51297 
51298 class TraceConfig_TriggerConfig : public ::protozero::Message {
51299  public:
51300   using Decoder = TraceConfig_TriggerConfig_Decoder;
51301   enum : int32_t {
51302     kTriggerModeFieldNumber = 1,
51303     kTriggersFieldNumber = 2,
51304     kTriggerTimeoutMsFieldNumber = 3,
51305   };
51306   using Trigger = ::perfetto::protos::pbzero::TraceConfig_TriggerConfig_Trigger;
51307   using TriggerMode = ::perfetto::protos::pbzero::TraceConfig_TriggerConfig_TriggerMode;
51308   static const TriggerMode UNSPECIFIED = TraceConfig_TriggerConfig_TriggerMode_UNSPECIFIED;
51309   static const TriggerMode START_TRACING = TraceConfig_TriggerConfig_TriggerMode_START_TRACING;
51310   static const TriggerMode STOP_TRACING = TraceConfig_TriggerConfig_TriggerMode_STOP_TRACING;
51311 
51312   using FieldMetadata_TriggerMode =
51313     ::protozero::proto_utils::FieldMetadata<
51314       1,
51315       ::protozero::proto_utils::RepetitionType::kNotRepeated,
51316       ::protozero::proto_utils::ProtoSchemaType::kEnum,
51317       ::perfetto::protos::pbzero::TraceConfig_TriggerConfig_TriggerMode,
51318       TraceConfig_TriggerConfig>;
51319 
51320   // Ceci n'est pas une pipe.
51321   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
51322   // type (and users are expected to use it as such, hence kCamelCase name).
51323   // It is declared as a function to keep protozero bindings header-only as
51324   // inline constexpr variables are not available until C++17 (while inline
51325   // functions are).
51326   // TODO(altimin): Use inline variable instead after adopting C++17.
kTriggerMode()51327   static constexpr FieldMetadata_TriggerMode kTriggerMode() { return {}; }
set_trigger_mode(::perfetto::protos::pbzero::TraceConfig_TriggerConfig_TriggerMode value)51328   void set_trigger_mode(::perfetto::protos::pbzero::TraceConfig_TriggerConfig_TriggerMode value) {
51329     static constexpr uint32_t field_id = FieldMetadata_TriggerMode::kFieldId;
51330     // Call the appropriate protozero::Message::Append(field_id, ...)
51331     // method based on the type of the field.
51332     ::protozero::internal::FieldWriter<
51333       ::protozero::proto_utils::ProtoSchemaType::kEnum>
51334         ::Append(*this, field_id, value);
51335   }
51336 
51337   using FieldMetadata_Triggers =
51338     ::protozero::proto_utils::FieldMetadata<
51339       2,
51340       ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
51341       ::protozero::proto_utils::ProtoSchemaType::kMessage,
51342       TraceConfig_TriggerConfig_Trigger,
51343       TraceConfig_TriggerConfig>;
51344 
51345   // Ceci n'est pas une pipe.
51346   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
51347   // type (and users are expected to use it as such, hence kCamelCase name).
51348   // It is declared as a function to keep protozero bindings header-only as
51349   // inline constexpr variables are not available until C++17 (while inline
51350   // functions are).
51351   // TODO(altimin): Use inline variable instead after adopting C++17.
kTriggers()51352   static constexpr FieldMetadata_Triggers kTriggers() { return {}; }
add_triggers()51353   template <typename T = TraceConfig_TriggerConfig_Trigger> T* add_triggers() {
51354     return BeginNestedMessage<T>(2);
51355   }
51356 
51357 
51358   using FieldMetadata_TriggerTimeoutMs =
51359     ::protozero::proto_utils::FieldMetadata<
51360       3,
51361       ::protozero::proto_utils::RepetitionType::kNotRepeated,
51362       ::protozero::proto_utils::ProtoSchemaType::kUint32,
51363       uint32_t,
51364       TraceConfig_TriggerConfig>;
51365 
51366   // Ceci n'est pas une pipe.
51367   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
51368   // type (and users are expected to use it as such, hence kCamelCase name).
51369   // It is declared as a function to keep protozero bindings header-only as
51370   // inline constexpr variables are not available until C++17 (while inline
51371   // functions are).
51372   // TODO(altimin): Use inline variable instead after adopting C++17.
kTriggerTimeoutMs()51373   static constexpr FieldMetadata_TriggerTimeoutMs kTriggerTimeoutMs() { return {}; }
set_trigger_timeout_ms(uint32_t value)51374   void set_trigger_timeout_ms(uint32_t value) {
51375     static constexpr uint32_t field_id = FieldMetadata_TriggerTimeoutMs::kFieldId;
51376     // Call the appropriate protozero::Message::Append(field_id, ...)
51377     // method based on the type of the field.
51378     ::protozero::internal::FieldWriter<
51379       ::protozero::proto_utils::ProtoSchemaType::kUint32>
51380         ::Append(*this, field_id, value);
51381   }
51382 };
51383 
51384 class TraceConfig_TriggerConfig_Trigger_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
51385  public:
TraceConfig_TriggerConfig_Trigger_Decoder(const uint8_t * data,size_t len)51386   TraceConfig_TriggerConfig_Trigger_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
TraceConfig_TriggerConfig_Trigger_Decoder(const std::string & raw)51387   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)51388   explicit TraceConfig_TriggerConfig_Trigger_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
has_name() const51389   bool has_name() const { return at<1>().valid(); }
name() const51390   ::protozero::ConstChars name() const { return at<1>().as_string(); }
has_producer_name_regex() const51391   bool has_producer_name_regex() const { return at<2>().valid(); }
producer_name_regex() const51392   ::protozero::ConstChars producer_name_regex() const { return at<2>().as_string(); }
has_stop_delay_ms() const51393   bool has_stop_delay_ms() const { return at<3>().valid(); }
stop_delay_ms() const51394   uint32_t stop_delay_ms() const { return at<3>().as_uint32(); }
has_max_per_24_h() const51395   bool has_max_per_24_h() const { return at<4>().valid(); }
max_per_24_h() const51396   uint32_t max_per_24_h() const { return at<4>().as_uint32(); }
has_skip_probability() const51397   bool has_skip_probability() const { return at<5>().valid(); }
skip_probability() const51398   double skip_probability() const { return at<5>().as_double(); }
51399 };
51400 
51401 class TraceConfig_TriggerConfig_Trigger : public ::protozero::Message {
51402  public:
51403   using Decoder = TraceConfig_TriggerConfig_Trigger_Decoder;
51404   enum : int32_t {
51405     kNameFieldNumber = 1,
51406     kProducerNameRegexFieldNumber = 2,
51407     kStopDelayMsFieldNumber = 3,
51408     kMaxPer24HFieldNumber = 4,
51409     kSkipProbabilityFieldNumber = 5,
51410   };
51411 
51412   using FieldMetadata_Name =
51413     ::protozero::proto_utils::FieldMetadata<
51414       1,
51415       ::protozero::proto_utils::RepetitionType::kNotRepeated,
51416       ::protozero::proto_utils::ProtoSchemaType::kString,
51417       std::string,
51418       TraceConfig_TriggerConfig_Trigger>;
51419 
51420   // Ceci n'est pas une pipe.
51421   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
51422   // type (and users are expected to use it as such, hence kCamelCase name).
51423   // It is declared as a function to keep protozero bindings header-only as
51424   // inline constexpr variables are not available until C++17 (while inline
51425   // functions are).
51426   // TODO(altimin): Use inline variable instead after adopting C++17.
kName()51427   static constexpr FieldMetadata_Name kName() { return {}; }
set_name(const char * data,size_t size)51428   void set_name(const char* data, size_t size) {
51429     AppendBytes(FieldMetadata_Name::kFieldId, data, size);
51430   }
set_name(std::string value)51431   void set_name(std::string value) {
51432     static constexpr uint32_t field_id = FieldMetadata_Name::kFieldId;
51433     // Call the appropriate protozero::Message::Append(field_id, ...)
51434     // method based on the type of the field.
51435     ::protozero::internal::FieldWriter<
51436       ::protozero::proto_utils::ProtoSchemaType::kString>
51437         ::Append(*this, field_id, value);
51438   }
51439 
51440   using FieldMetadata_ProducerNameRegex =
51441     ::protozero::proto_utils::FieldMetadata<
51442       2,
51443       ::protozero::proto_utils::RepetitionType::kNotRepeated,
51444       ::protozero::proto_utils::ProtoSchemaType::kString,
51445       std::string,
51446       TraceConfig_TriggerConfig_Trigger>;
51447 
51448   // Ceci n'est pas une pipe.
51449   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
51450   // type (and users are expected to use it as such, hence kCamelCase name).
51451   // It is declared as a function to keep protozero bindings header-only as
51452   // inline constexpr variables are not available until C++17 (while inline
51453   // functions are).
51454   // TODO(altimin): Use inline variable instead after adopting C++17.
kProducerNameRegex()51455   static constexpr FieldMetadata_ProducerNameRegex kProducerNameRegex() { return {}; }
set_producer_name_regex(const char * data,size_t size)51456   void set_producer_name_regex(const char* data, size_t size) {
51457     AppendBytes(FieldMetadata_ProducerNameRegex::kFieldId, data, size);
51458   }
set_producer_name_regex(std::string value)51459   void set_producer_name_regex(std::string value) {
51460     static constexpr uint32_t field_id = FieldMetadata_ProducerNameRegex::kFieldId;
51461     // Call the appropriate protozero::Message::Append(field_id, ...)
51462     // method based on the type of the field.
51463     ::protozero::internal::FieldWriter<
51464       ::protozero::proto_utils::ProtoSchemaType::kString>
51465         ::Append(*this, field_id, value);
51466   }
51467 
51468   using FieldMetadata_StopDelayMs =
51469     ::protozero::proto_utils::FieldMetadata<
51470       3,
51471       ::protozero::proto_utils::RepetitionType::kNotRepeated,
51472       ::protozero::proto_utils::ProtoSchemaType::kUint32,
51473       uint32_t,
51474       TraceConfig_TriggerConfig_Trigger>;
51475 
51476   // Ceci n'est pas une pipe.
51477   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
51478   // type (and users are expected to use it as such, hence kCamelCase name).
51479   // It is declared as a function to keep protozero bindings header-only as
51480   // inline constexpr variables are not available until C++17 (while inline
51481   // functions are).
51482   // TODO(altimin): Use inline variable instead after adopting C++17.
kStopDelayMs()51483   static constexpr FieldMetadata_StopDelayMs kStopDelayMs() { return {}; }
set_stop_delay_ms(uint32_t value)51484   void set_stop_delay_ms(uint32_t value) {
51485     static constexpr uint32_t field_id = FieldMetadata_StopDelayMs::kFieldId;
51486     // Call the appropriate protozero::Message::Append(field_id, ...)
51487     // method based on the type of the field.
51488     ::protozero::internal::FieldWriter<
51489       ::protozero::proto_utils::ProtoSchemaType::kUint32>
51490         ::Append(*this, field_id, value);
51491   }
51492 
51493   using FieldMetadata_MaxPer24H =
51494     ::protozero::proto_utils::FieldMetadata<
51495       4,
51496       ::protozero::proto_utils::RepetitionType::kNotRepeated,
51497       ::protozero::proto_utils::ProtoSchemaType::kUint32,
51498       uint32_t,
51499       TraceConfig_TriggerConfig_Trigger>;
51500 
51501   // Ceci n'est pas une pipe.
51502   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
51503   // type (and users are expected to use it as such, hence kCamelCase name).
51504   // It is declared as a function to keep protozero bindings header-only as
51505   // inline constexpr variables are not available until C++17 (while inline
51506   // functions are).
51507   // TODO(altimin): Use inline variable instead after adopting C++17.
kMaxPer24H()51508   static constexpr FieldMetadata_MaxPer24H kMaxPer24H() { return {}; }
set_max_per_24_h(uint32_t value)51509   void set_max_per_24_h(uint32_t value) {
51510     static constexpr uint32_t field_id = FieldMetadata_MaxPer24H::kFieldId;
51511     // Call the appropriate protozero::Message::Append(field_id, ...)
51512     // method based on the type of the field.
51513     ::protozero::internal::FieldWriter<
51514       ::protozero::proto_utils::ProtoSchemaType::kUint32>
51515         ::Append(*this, field_id, value);
51516   }
51517 
51518   using FieldMetadata_SkipProbability =
51519     ::protozero::proto_utils::FieldMetadata<
51520       5,
51521       ::protozero::proto_utils::RepetitionType::kNotRepeated,
51522       ::protozero::proto_utils::ProtoSchemaType::kDouble,
51523       double,
51524       TraceConfig_TriggerConfig_Trigger>;
51525 
51526   // Ceci n'est pas une pipe.
51527   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
51528   // type (and users are expected to use it as such, hence kCamelCase name).
51529   // It is declared as a function to keep protozero bindings header-only as
51530   // inline constexpr variables are not available until C++17 (while inline
51531   // functions are).
51532   // TODO(altimin): Use inline variable instead after adopting C++17.
kSkipProbability()51533   static constexpr FieldMetadata_SkipProbability kSkipProbability() { return {}; }
set_skip_probability(double value)51534   void set_skip_probability(double value) {
51535     static constexpr uint32_t field_id = FieldMetadata_SkipProbability::kFieldId;
51536     // Call the appropriate protozero::Message::Append(field_id, ...)
51537     // method based on the type of the field.
51538     ::protozero::internal::FieldWriter<
51539       ::protozero::proto_utils::ProtoSchemaType::kDouble>
51540         ::Append(*this, field_id, value);
51541   }
51542 };
51543 
51544 class TraceConfig_GuardrailOverrides_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/1, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
51545  public:
TraceConfig_GuardrailOverrides_Decoder(const uint8_t * data,size_t len)51546   TraceConfig_GuardrailOverrides_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
TraceConfig_GuardrailOverrides_Decoder(const std::string & raw)51547   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)51548   explicit TraceConfig_GuardrailOverrides_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
has_max_upload_per_day_bytes() const51549   bool has_max_upload_per_day_bytes() const { return at<1>().valid(); }
max_upload_per_day_bytes() const51550   uint64_t max_upload_per_day_bytes() const { return at<1>().as_uint64(); }
51551 };
51552 
51553 class TraceConfig_GuardrailOverrides : public ::protozero::Message {
51554  public:
51555   using Decoder = TraceConfig_GuardrailOverrides_Decoder;
51556   enum : int32_t {
51557     kMaxUploadPerDayBytesFieldNumber = 1,
51558   };
51559 
51560   using FieldMetadata_MaxUploadPerDayBytes =
51561     ::protozero::proto_utils::FieldMetadata<
51562       1,
51563       ::protozero::proto_utils::RepetitionType::kNotRepeated,
51564       ::protozero::proto_utils::ProtoSchemaType::kUint64,
51565       uint64_t,
51566       TraceConfig_GuardrailOverrides>;
51567 
51568   // Ceci n'est pas une pipe.
51569   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
51570   // type (and users are expected to use it as such, hence kCamelCase name).
51571   // It is declared as a function to keep protozero bindings header-only as
51572   // inline constexpr variables are not available until C++17 (while inline
51573   // functions are).
51574   // TODO(altimin): Use inline variable instead after adopting C++17.
kMaxUploadPerDayBytes()51575   static constexpr FieldMetadata_MaxUploadPerDayBytes kMaxUploadPerDayBytes() { return {}; }
set_max_upload_per_day_bytes(uint64_t value)51576   void set_max_upload_per_day_bytes(uint64_t value) {
51577     static constexpr uint32_t field_id = FieldMetadata_MaxUploadPerDayBytes::kFieldId;
51578     // Call the appropriate protozero::Message::Append(field_id, ...)
51579     // method based on the type of the field.
51580     ::protozero::internal::FieldWriter<
51581       ::protozero::proto_utils::ProtoSchemaType::kUint64>
51582         ::Append(*this, field_id, value);
51583   }
51584 };
51585 
51586 class TraceConfig_StatsdMetadata_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
51587  public:
TraceConfig_StatsdMetadata_Decoder(const uint8_t * data,size_t len)51588   TraceConfig_StatsdMetadata_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
TraceConfig_StatsdMetadata_Decoder(const std::string & raw)51589   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)51590   explicit TraceConfig_StatsdMetadata_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
has_triggering_alert_id() const51591   bool has_triggering_alert_id() const { return at<1>().valid(); }
triggering_alert_id() const51592   int64_t triggering_alert_id() const { return at<1>().as_int64(); }
has_triggering_config_uid() const51593   bool has_triggering_config_uid() const { return at<2>().valid(); }
triggering_config_uid() const51594   int32_t triggering_config_uid() const { return at<2>().as_int32(); }
has_triggering_config_id() const51595   bool has_triggering_config_id() const { return at<3>().valid(); }
triggering_config_id() const51596   int64_t triggering_config_id() const { return at<3>().as_int64(); }
has_triggering_subscription_id() const51597   bool has_triggering_subscription_id() const { return at<4>().valid(); }
triggering_subscription_id() const51598   int64_t triggering_subscription_id() const { return at<4>().as_int64(); }
51599 };
51600 
51601 class TraceConfig_StatsdMetadata : public ::protozero::Message {
51602  public:
51603   using Decoder = TraceConfig_StatsdMetadata_Decoder;
51604   enum : int32_t {
51605     kTriggeringAlertIdFieldNumber = 1,
51606     kTriggeringConfigUidFieldNumber = 2,
51607     kTriggeringConfigIdFieldNumber = 3,
51608     kTriggeringSubscriptionIdFieldNumber = 4,
51609   };
51610 
51611   using FieldMetadata_TriggeringAlertId =
51612     ::protozero::proto_utils::FieldMetadata<
51613       1,
51614       ::protozero::proto_utils::RepetitionType::kNotRepeated,
51615       ::protozero::proto_utils::ProtoSchemaType::kInt64,
51616       int64_t,
51617       TraceConfig_StatsdMetadata>;
51618 
51619   // Ceci n'est pas une pipe.
51620   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
51621   // type (and users are expected to use it as such, hence kCamelCase name).
51622   // It is declared as a function to keep protozero bindings header-only as
51623   // inline constexpr variables are not available until C++17 (while inline
51624   // functions are).
51625   // TODO(altimin): Use inline variable instead after adopting C++17.
kTriggeringAlertId()51626   static constexpr FieldMetadata_TriggeringAlertId kTriggeringAlertId() { return {}; }
set_triggering_alert_id(int64_t value)51627   void set_triggering_alert_id(int64_t value) {
51628     static constexpr uint32_t field_id = FieldMetadata_TriggeringAlertId::kFieldId;
51629     // Call the appropriate protozero::Message::Append(field_id, ...)
51630     // method based on the type of the field.
51631     ::protozero::internal::FieldWriter<
51632       ::protozero::proto_utils::ProtoSchemaType::kInt64>
51633         ::Append(*this, field_id, value);
51634   }
51635 
51636   using FieldMetadata_TriggeringConfigUid =
51637     ::protozero::proto_utils::FieldMetadata<
51638       2,
51639       ::protozero::proto_utils::RepetitionType::kNotRepeated,
51640       ::protozero::proto_utils::ProtoSchemaType::kInt32,
51641       int32_t,
51642       TraceConfig_StatsdMetadata>;
51643 
51644   // Ceci n'est pas une pipe.
51645   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
51646   // type (and users are expected to use it as such, hence kCamelCase name).
51647   // It is declared as a function to keep protozero bindings header-only as
51648   // inline constexpr variables are not available until C++17 (while inline
51649   // functions are).
51650   // TODO(altimin): Use inline variable instead after adopting C++17.
kTriggeringConfigUid()51651   static constexpr FieldMetadata_TriggeringConfigUid kTriggeringConfigUid() { return {}; }
set_triggering_config_uid(int32_t value)51652   void set_triggering_config_uid(int32_t value) {
51653     static constexpr uint32_t field_id = FieldMetadata_TriggeringConfigUid::kFieldId;
51654     // Call the appropriate protozero::Message::Append(field_id, ...)
51655     // method based on the type of the field.
51656     ::protozero::internal::FieldWriter<
51657       ::protozero::proto_utils::ProtoSchemaType::kInt32>
51658         ::Append(*this, field_id, value);
51659   }
51660 
51661   using FieldMetadata_TriggeringConfigId =
51662     ::protozero::proto_utils::FieldMetadata<
51663       3,
51664       ::protozero::proto_utils::RepetitionType::kNotRepeated,
51665       ::protozero::proto_utils::ProtoSchemaType::kInt64,
51666       int64_t,
51667       TraceConfig_StatsdMetadata>;
51668 
51669   // Ceci n'est pas une pipe.
51670   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
51671   // type (and users are expected to use it as such, hence kCamelCase name).
51672   // It is declared as a function to keep protozero bindings header-only as
51673   // inline constexpr variables are not available until C++17 (while inline
51674   // functions are).
51675   // TODO(altimin): Use inline variable instead after adopting C++17.
kTriggeringConfigId()51676   static constexpr FieldMetadata_TriggeringConfigId kTriggeringConfigId() { return {}; }
set_triggering_config_id(int64_t value)51677   void set_triggering_config_id(int64_t value) {
51678     static constexpr uint32_t field_id = FieldMetadata_TriggeringConfigId::kFieldId;
51679     // Call the appropriate protozero::Message::Append(field_id, ...)
51680     // method based on the type of the field.
51681     ::protozero::internal::FieldWriter<
51682       ::protozero::proto_utils::ProtoSchemaType::kInt64>
51683         ::Append(*this, field_id, value);
51684   }
51685 
51686   using FieldMetadata_TriggeringSubscriptionId =
51687     ::protozero::proto_utils::FieldMetadata<
51688       4,
51689       ::protozero::proto_utils::RepetitionType::kNotRepeated,
51690       ::protozero::proto_utils::ProtoSchemaType::kInt64,
51691       int64_t,
51692       TraceConfig_StatsdMetadata>;
51693 
51694   // Ceci n'est pas une pipe.
51695   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
51696   // type (and users are expected to use it as such, hence kCamelCase name).
51697   // It is declared as a function to keep protozero bindings header-only as
51698   // inline constexpr variables are not available until C++17 (while inline
51699   // functions are).
51700   // TODO(altimin): Use inline variable instead after adopting C++17.
kTriggeringSubscriptionId()51701   static constexpr FieldMetadata_TriggeringSubscriptionId kTriggeringSubscriptionId() { return {}; }
set_triggering_subscription_id(int64_t value)51702   void set_triggering_subscription_id(int64_t value) {
51703     static constexpr uint32_t field_id = FieldMetadata_TriggeringSubscriptionId::kFieldId;
51704     // Call the appropriate protozero::Message::Append(field_id, ...)
51705     // method based on the type of the field.
51706     ::protozero::internal::FieldWriter<
51707       ::protozero::proto_utils::ProtoSchemaType::kInt64>
51708         ::Append(*this, field_id, value);
51709   }
51710 };
51711 
51712 class TraceConfig_ProducerConfig_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
51713  public:
TraceConfig_ProducerConfig_Decoder(const uint8_t * data,size_t len)51714   TraceConfig_ProducerConfig_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
TraceConfig_ProducerConfig_Decoder(const std::string & raw)51715   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)51716   explicit TraceConfig_ProducerConfig_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
has_producer_name() const51717   bool has_producer_name() const { return at<1>().valid(); }
producer_name() const51718   ::protozero::ConstChars producer_name() const { return at<1>().as_string(); }
has_shm_size_kb() const51719   bool has_shm_size_kb() const { return at<2>().valid(); }
shm_size_kb() const51720   uint32_t shm_size_kb() const { return at<2>().as_uint32(); }
has_page_size_kb() const51721   bool has_page_size_kb() const { return at<3>().valid(); }
page_size_kb() const51722   uint32_t page_size_kb() const { return at<3>().as_uint32(); }
51723 };
51724 
51725 class TraceConfig_ProducerConfig : public ::protozero::Message {
51726  public:
51727   using Decoder = TraceConfig_ProducerConfig_Decoder;
51728   enum : int32_t {
51729     kProducerNameFieldNumber = 1,
51730     kShmSizeKbFieldNumber = 2,
51731     kPageSizeKbFieldNumber = 3,
51732   };
51733 
51734   using FieldMetadata_ProducerName =
51735     ::protozero::proto_utils::FieldMetadata<
51736       1,
51737       ::protozero::proto_utils::RepetitionType::kNotRepeated,
51738       ::protozero::proto_utils::ProtoSchemaType::kString,
51739       std::string,
51740       TraceConfig_ProducerConfig>;
51741 
51742   // Ceci n'est pas une pipe.
51743   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
51744   // type (and users are expected to use it as such, hence kCamelCase name).
51745   // It is declared as a function to keep protozero bindings header-only as
51746   // inline constexpr variables are not available until C++17 (while inline
51747   // functions are).
51748   // TODO(altimin): Use inline variable instead after adopting C++17.
kProducerName()51749   static constexpr FieldMetadata_ProducerName kProducerName() { return {}; }
set_producer_name(const char * data,size_t size)51750   void set_producer_name(const char* data, size_t size) {
51751     AppendBytes(FieldMetadata_ProducerName::kFieldId, data, size);
51752   }
set_producer_name(std::string value)51753   void set_producer_name(std::string value) {
51754     static constexpr uint32_t field_id = FieldMetadata_ProducerName::kFieldId;
51755     // Call the appropriate protozero::Message::Append(field_id, ...)
51756     // method based on the type of the field.
51757     ::protozero::internal::FieldWriter<
51758       ::protozero::proto_utils::ProtoSchemaType::kString>
51759         ::Append(*this, field_id, value);
51760   }
51761 
51762   using FieldMetadata_ShmSizeKb =
51763     ::protozero::proto_utils::FieldMetadata<
51764       2,
51765       ::protozero::proto_utils::RepetitionType::kNotRepeated,
51766       ::protozero::proto_utils::ProtoSchemaType::kUint32,
51767       uint32_t,
51768       TraceConfig_ProducerConfig>;
51769 
51770   // Ceci n'est pas une pipe.
51771   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
51772   // type (and users are expected to use it as such, hence kCamelCase name).
51773   // It is declared as a function to keep protozero bindings header-only as
51774   // inline constexpr variables are not available until C++17 (while inline
51775   // functions are).
51776   // TODO(altimin): Use inline variable instead after adopting C++17.
kShmSizeKb()51777   static constexpr FieldMetadata_ShmSizeKb kShmSizeKb() { return {}; }
set_shm_size_kb(uint32_t value)51778   void set_shm_size_kb(uint32_t value) {
51779     static constexpr uint32_t field_id = FieldMetadata_ShmSizeKb::kFieldId;
51780     // Call the appropriate protozero::Message::Append(field_id, ...)
51781     // method based on the type of the field.
51782     ::protozero::internal::FieldWriter<
51783       ::protozero::proto_utils::ProtoSchemaType::kUint32>
51784         ::Append(*this, field_id, value);
51785   }
51786 
51787   using FieldMetadata_PageSizeKb =
51788     ::protozero::proto_utils::FieldMetadata<
51789       3,
51790       ::protozero::proto_utils::RepetitionType::kNotRepeated,
51791       ::protozero::proto_utils::ProtoSchemaType::kUint32,
51792       uint32_t,
51793       TraceConfig_ProducerConfig>;
51794 
51795   // Ceci n'est pas une pipe.
51796   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
51797   // type (and users are expected to use it as such, hence kCamelCase name).
51798   // It is declared as a function to keep protozero bindings header-only as
51799   // inline constexpr variables are not available until C++17 (while inline
51800   // functions are).
51801   // TODO(altimin): Use inline variable instead after adopting C++17.
kPageSizeKb()51802   static constexpr FieldMetadata_PageSizeKb kPageSizeKb() { return {}; }
set_page_size_kb(uint32_t value)51803   void set_page_size_kb(uint32_t value) {
51804     static constexpr uint32_t field_id = FieldMetadata_PageSizeKb::kFieldId;
51805     // Call the appropriate protozero::Message::Append(field_id, ...)
51806     // method based on the type of the field.
51807     ::protozero::internal::FieldWriter<
51808       ::protozero::proto_utils::ProtoSchemaType::kUint32>
51809         ::Append(*this, field_id, value);
51810   }
51811 };
51812 
51813 class TraceConfig_BuiltinDataSource_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/7, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
51814  public:
TraceConfig_BuiltinDataSource_Decoder(const uint8_t * data,size_t len)51815   TraceConfig_BuiltinDataSource_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
TraceConfig_BuiltinDataSource_Decoder(const std::string & raw)51816   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)51817   explicit TraceConfig_BuiltinDataSource_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
has_disable_clock_snapshotting() const51818   bool has_disable_clock_snapshotting() const { return at<1>().valid(); }
disable_clock_snapshotting() const51819   bool disable_clock_snapshotting() const { return at<1>().as_bool(); }
has_disable_trace_config() const51820   bool has_disable_trace_config() const { return at<2>().valid(); }
disable_trace_config() const51821   bool disable_trace_config() const { return at<2>().as_bool(); }
has_disable_system_info() const51822   bool has_disable_system_info() const { return at<3>().valid(); }
disable_system_info() const51823   bool disable_system_info() const { return at<3>().as_bool(); }
has_disable_service_events() const51824   bool has_disable_service_events() const { return at<4>().valid(); }
disable_service_events() const51825   bool disable_service_events() const { return at<4>().as_bool(); }
has_primary_trace_clock() const51826   bool has_primary_trace_clock() const { return at<5>().valid(); }
primary_trace_clock() const51827   int32_t primary_trace_clock() const { return at<5>().as_int32(); }
has_snapshot_interval_ms() const51828   bool has_snapshot_interval_ms() const { return at<6>().valid(); }
snapshot_interval_ms() const51829   uint32_t snapshot_interval_ms() const { return at<6>().as_uint32(); }
has_prefer_suspend_clock_for_snapshot() const51830   bool has_prefer_suspend_clock_for_snapshot() const { return at<7>().valid(); }
prefer_suspend_clock_for_snapshot() const51831   bool prefer_suspend_clock_for_snapshot() const { return at<7>().as_bool(); }
51832 };
51833 
51834 class TraceConfig_BuiltinDataSource : public ::protozero::Message {
51835  public:
51836   using Decoder = TraceConfig_BuiltinDataSource_Decoder;
51837   enum : int32_t {
51838     kDisableClockSnapshottingFieldNumber = 1,
51839     kDisableTraceConfigFieldNumber = 2,
51840     kDisableSystemInfoFieldNumber = 3,
51841     kDisableServiceEventsFieldNumber = 4,
51842     kPrimaryTraceClockFieldNumber = 5,
51843     kSnapshotIntervalMsFieldNumber = 6,
51844     kPreferSuspendClockForSnapshotFieldNumber = 7,
51845   };
51846 
51847   using FieldMetadata_DisableClockSnapshotting =
51848     ::protozero::proto_utils::FieldMetadata<
51849       1,
51850       ::protozero::proto_utils::RepetitionType::kNotRepeated,
51851       ::protozero::proto_utils::ProtoSchemaType::kBool,
51852       bool,
51853       TraceConfig_BuiltinDataSource>;
51854 
51855   // Ceci n'est pas une pipe.
51856   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
51857   // type (and users are expected to use it as such, hence kCamelCase name).
51858   // It is declared as a function to keep protozero bindings header-only as
51859   // inline constexpr variables are not available until C++17 (while inline
51860   // functions are).
51861   // TODO(altimin): Use inline variable instead after adopting C++17.
kDisableClockSnapshotting()51862   static constexpr FieldMetadata_DisableClockSnapshotting kDisableClockSnapshotting() { return {}; }
set_disable_clock_snapshotting(bool value)51863   void set_disable_clock_snapshotting(bool value) {
51864     static constexpr uint32_t field_id = FieldMetadata_DisableClockSnapshotting::kFieldId;
51865     // Call the appropriate protozero::Message::Append(field_id, ...)
51866     // method based on the type of the field.
51867     ::protozero::internal::FieldWriter<
51868       ::protozero::proto_utils::ProtoSchemaType::kBool>
51869         ::Append(*this, field_id, value);
51870   }
51871 
51872   using FieldMetadata_DisableTraceConfig =
51873     ::protozero::proto_utils::FieldMetadata<
51874       2,
51875       ::protozero::proto_utils::RepetitionType::kNotRepeated,
51876       ::protozero::proto_utils::ProtoSchemaType::kBool,
51877       bool,
51878       TraceConfig_BuiltinDataSource>;
51879 
51880   // Ceci n'est pas une pipe.
51881   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
51882   // type (and users are expected to use it as such, hence kCamelCase name).
51883   // It is declared as a function to keep protozero bindings header-only as
51884   // inline constexpr variables are not available until C++17 (while inline
51885   // functions are).
51886   // TODO(altimin): Use inline variable instead after adopting C++17.
kDisableTraceConfig()51887   static constexpr FieldMetadata_DisableTraceConfig kDisableTraceConfig() { return {}; }
set_disable_trace_config(bool value)51888   void set_disable_trace_config(bool value) {
51889     static constexpr uint32_t field_id = FieldMetadata_DisableTraceConfig::kFieldId;
51890     // Call the appropriate protozero::Message::Append(field_id, ...)
51891     // method based on the type of the field.
51892     ::protozero::internal::FieldWriter<
51893       ::protozero::proto_utils::ProtoSchemaType::kBool>
51894         ::Append(*this, field_id, value);
51895   }
51896 
51897   using FieldMetadata_DisableSystemInfo =
51898     ::protozero::proto_utils::FieldMetadata<
51899       3,
51900       ::protozero::proto_utils::RepetitionType::kNotRepeated,
51901       ::protozero::proto_utils::ProtoSchemaType::kBool,
51902       bool,
51903       TraceConfig_BuiltinDataSource>;
51904 
51905   // Ceci n'est pas une pipe.
51906   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
51907   // type (and users are expected to use it as such, hence kCamelCase name).
51908   // It is declared as a function to keep protozero bindings header-only as
51909   // inline constexpr variables are not available until C++17 (while inline
51910   // functions are).
51911   // TODO(altimin): Use inline variable instead after adopting C++17.
kDisableSystemInfo()51912   static constexpr FieldMetadata_DisableSystemInfo kDisableSystemInfo() { return {}; }
set_disable_system_info(bool value)51913   void set_disable_system_info(bool value) {
51914     static constexpr uint32_t field_id = FieldMetadata_DisableSystemInfo::kFieldId;
51915     // Call the appropriate protozero::Message::Append(field_id, ...)
51916     // method based on the type of the field.
51917     ::protozero::internal::FieldWriter<
51918       ::protozero::proto_utils::ProtoSchemaType::kBool>
51919         ::Append(*this, field_id, value);
51920   }
51921 
51922   using FieldMetadata_DisableServiceEvents =
51923     ::protozero::proto_utils::FieldMetadata<
51924       4,
51925       ::protozero::proto_utils::RepetitionType::kNotRepeated,
51926       ::protozero::proto_utils::ProtoSchemaType::kBool,
51927       bool,
51928       TraceConfig_BuiltinDataSource>;
51929 
51930   // Ceci n'est pas une pipe.
51931   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
51932   // type (and users are expected to use it as such, hence kCamelCase name).
51933   // It is declared as a function to keep protozero bindings header-only as
51934   // inline constexpr variables are not available until C++17 (while inline
51935   // functions are).
51936   // TODO(altimin): Use inline variable instead after adopting C++17.
kDisableServiceEvents()51937   static constexpr FieldMetadata_DisableServiceEvents kDisableServiceEvents() { return {}; }
set_disable_service_events(bool value)51938   void set_disable_service_events(bool value) {
51939     static constexpr uint32_t field_id = FieldMetadata_DisableServiceEvents::kFieldId;
51940     // Call the appropriate protozero::Message::Append(field_id, ...)
51941     // method based on the type of the field.
51942     ::protozero::internal::FieldWriter<
51943       ::protozero::proto_utils::ProtoSchemaType::kBool>
51944         ::Append(*this, field_id, value);
51945   }
51946 
51947   using FieldMetadata_PrimaryTraceClock =
51948     ::protozero::proto_utils::FieldMetadata<
51949       5,
51950       ::protozero::proto_utils::RepetitionType::kNotRepeated,
51951       ::protozero::proto_utils::ProtoSchemaType::kEnum,
51952       ::perfetto::protos::pbzero::BuiltinClock,
51953       TraceConfig_BuiltinDataSource>;
51954 
51955   // Ceci n'est pas une pipe.
51956   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
51957   // type (and users are expected to use it as such, hence kCamelCase name).
51958   // It is declared as a function to keep protozero bindings header-only as
51959   // inline constexpr variables are not available until C++17 (while inline
51960   // functions are).
51961   // TODO(altimin): Use inline variable instead after adopting C++17.
kPrimaryTraceClock()51962   static constexpr FieldMetadata_PrimaryTraceClock kPrimaryTraceClock() { return {}; }
set_primary_trace_clock(::perfetto::protos::pbzero::BuiltinClock value)51963   void set_primary_trace_clock(::perfetto::protos::pbzero::BuiltinClock value) {
51964     static constexpr uint32_t field_id = FieldMetadata_PrimaryTraceClock::kFieldId;
51965     // Call the appropriate protozero::Message::Append(field_id, ...)
51966     // method based on the type of the field.
51967     ::protozero::internal::FieldWriter<
51968       ::protozero::proto_utils::ProtoSchemaType::kEnum>
51969         ::Append(*this, field_id, value);
51970   }
51971 
51972   using FieldMetadata_SnapshotIntervalMs =
51973     ::protozero::proto_utils::FieldMetadata<
51974       6,
51975       ::protozero::proto_utils::RepetitionType::kNotRepeated,
51976       ::protozero::proto_utils::ProtoSchemaType::kUint32,
51977       uint32_t,
51978       TraceConfig_BuiltinDataSource>;
51979 
51980   // Ceci n'est pas une pipe.
51981   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
51982   // type (and users are expected to use it as such, hence kCamelCase name).
51983   // It is declared as a function to keep protozero bindings header-only as
51984   // inline constexpr variables are not available until C++17 (while inline
51985   // functions are).
51986   // TODO(altimin): Use inline variable instead after adopting C++17.
kSnapshotIntervalMs()51987   static constexpr FieldMetadata_SnapshotIntervalMs kSnapshotIntervalMs() { return {}; }
set_snapshot_interval_ms(uint32_t value)51988   void set_snapshot_interval_ms(uint32_t value) {
51989     static constexpr uint32_t field_id = FieldMetadata_SnapshotIntervalMs::kFieldId;
51990     // Call the appropriate protozero::Message::Append(field_id, ...)
51991     // method based on the type of the field.
51992     ::protozero::internal::FieldWriter<
51993       ::protozero::proto_utils::ProtoSchemaType::kUint32>
51994         ::Append(*this, field_id, value);
51995   }
51996 
51997   using FieldMetadata_PreferSuspendClockForSnapshot =
51998     ::protozero::proto_utils::FieldMetadata<
51999       7,
52000       ::protozero::proto_utils::RepetitionType::kNotRepeated,
52001       ::protozero::proto_utils::ProtoSchemaType::kBool,
52002       bool,
52003       TraceConfig_BuiltinDataSource>;
52004 
52005   // Ceci n'est pas une pipe.
52006   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
52007   // type (and users are expected to use it as such, hence kCamelCase name).
52008   // It is declared as a function to keep protozero bindings header-only as
52009   // inline constexpr variables are not available until C++17 (while inline
52010   // functions are).
52011   // TODO(altimin): Use inline variable instead after adopting C++17.
kPreferSuspendClockForSnapshot()52012   static constexpr FieldMetadata_PreferSuspendClockForSnapshot kPreferSuspendClockForSnapshot() { return {}; }
set_prefer_suspend_clock_for_snapshot(bool value)52013   void set_prefer_suspend_clock_for_snapshot(bool value) {
52014     static constexpr uint32_t field_id = FieldMetadata_PreferSuspendClockForSnapshot::kFieldId;
52015     // Call the appropriate protozero::Message::Append(field_id, ...)
52016     // method based on the type of the field.
52017     ::protozero::internal::FieldWriter<
52018       ::protozero::proto_utils::ProtoSchemaType::kBool>
52019         ::Append(*this, field_id, value);
52020   }
52021 };
52022 
52023 class TraceConfig_DataSource_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
52024  public:
TraceConfig_DataSource_Decoder(const uint8_t * data,size_t len)52025   TraceConfig_DataSource_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
TraceConfig_DataSource_Decoder(const std::string & raw)52026   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)52027   explicit TraceConfig_DataSource_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
has_config() const52028   bool has_config() const { return at<1>().valid(); }
config() const52029   ::protozero::ConstBytes config() const { return at<1>().as_bytes(); }
has_producer_name_filter() const52030   bool has_producer_name_filter() const { return at<2>().valid(); }
producer_name_filter() const52031   ::protozero::RepeatedFieldIterator<::protozero::ConstChars> producer_name_filter() const { return GetRepeated<::protozero::ConstChars>(2); }
has_producer_name_regex_filter() const52032   bool has_producer_name_regex_filter() const { return at<3>().valid(); }
producer_name_regex_filter() const52033   ::protozero::RepeatedFieldIterator<::protozero::ConstChars> producer_name_regex_filter() const { return GetRepeated<::protozero::ConstChars>(3); }
52034 };
52035 
52036 class TraceConfig_DataSource : public ::protozero::Message {
52037  public:
52038   using Decoder = TraceConfig_DataSource_Decoder;
52039   enum : int32_t {
52040     kConfigFieldNumber = 1,
52041     kProducerNameFilterFieldNumber = 2,
52042     kProducerNameRegexFilterFieldNumber = 3,
52043   };
52044 
52045   using FieldMetadata_Config =
52046     ::protozero::proto_utils::FieldMetadata<
52047       1,
52048       ::protozero::proto_utils::RepetitionType::kNotRepeated,
52049       ::protozero::proto_utils::ProtoSchemaType::kMessage,
52050       DataSourceConfig,
52051       TraceConfig_DataSource>;
52052 
52053   // Ceci n'est pas une pipe.
52054   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
52055   // type (and users are expected to use it as such, hence kCamelCase name).
52056   // It is declared as a function to keep protozero bindings header-only as
52057   // inline constexpr variables are not available until C++17 (while inline
52058   // functions are).
52059   // TODO(altimin): Use inline variable instead after adopting C++17.
kConfig()52060   static constexpr FieldMetadata_Config kConfig() { return {}; }
set_config()52061   template <typename T = DataSourceConfig> T* set_config() {
52062     return BeginNestedMessage<T>(1);
52063   }
52064 
52065 
52066   using FieldMetadata_ProducerNameFilter =
52067     ::protozero::proto_utils::FieldMetadata<
52068       2,
52069       ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
52070       ::protozero::proto_utils::ProtoSchemaType::kString,
52071       std::string,
52072       TraceConfig_DataSource>;
52073 
52074   // Ceci n'est pas une pipe.
52075   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
52076   // type (and users are expected to use it as such, hence kCamelCase name).
52077   // It is declared as a function to keep protozero bindings header-only as
52078   // inline constexpr variables are not available until C++17 (while inline
52079   // functions are).
52080   // TODO(altimin): Use inline variable instead after adopting C++17.
kProducerNameFilter()52081   static constexpr FieldMetadata_ProducerNameFilter kProducerNameFilter() { return {}; }
add_producer_name_filter(const char * data,size_t size)52082   void add_producer_name_filter(const char* data, size_t size) {
52083     AppendBytes(FieldMetadata_ProducerNameFilter::kFieldId, data, size);
52084   }
add_producer_name_filter(std::string value)52085   void add_producer_name_filter(std::string value) {
52086     static constexpr uint32_t field_id = FieldMetadata_ProducerNameFilter::kFieldId;
52087     // Call the appropriate protozero::Message::Append(field_id, ...)
52088     // method based on the type of the field.
52089     ::protozero::internal::FieldWriter<
52090       ::protozero::proto_utils::ProtoSchemaType::kString>
52091         ::Append(*this, field_id, value);
52092   }
52093 
52094   using FieldMetadata_ProducerNameRegexFilter =
52095     ::protozero::proto_utils::FieldMetadata<
52096       3,
52097       ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
52098       ::protozero::proto_utils::ProtoSchemaType::kString,
52099       std::string,
52100       TraceConfig_DataSource>;
52101 
52102   // Ceci n'est pas une pipe.
52103   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
52104   // type (and users are expected to use it as such, hence kCamelCase name).
52105   // It is declared as a function to keep protozero bindings header-only as
52106   // inline constexpr variables are not available until C++17 (while inline
52107   // functions are).
52108   // TODO(altimin): Use inline variable instead after adopting C++17.
kProducerNameRegexFilter()52109   static constexpr FieldMetadata_ProducerNameRegexFilter kProducerNameRegexFilter() { return {}; }
add_producer_name_regex_filter(const char * data,size_t size)52110   void add_producer_name_regex_filter(const char* data, size_t size) {
52111     AppendBytes(FieldMetadata_ProducerNameRegexFilter::kFieldId, data, size);
52112   }
add_producer_name_regex_filter(std::string value)52113   void add_producer_name_regex_filter(std::string value) {
52114     static constexpr uint32_t field_id = FieldMetadata_ProducerNameRegexFilter::kFieldId;
52115     // Call the appropriate protozero::Message::Append(field_id, ...)
52116     // method based on the type of the field.
52117     ::protozero::internal::FieldWriter<
52118       ::protozero::proto_utils::ProtoSchemaType::kString>
52119         ::Append(*this, field_id, value);
52120   }
52121 };
52122 
52123 class TraceConfig_BufferConfig_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
52124  public:
TraceConfig_BufferConfig_Decoder(const uint8_t * data,size_t len)52125   TraceConfig_BufferConfig_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
TraceConfig_BufferConfig_Decoder(const std::string & raw)52126   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)52127   explicit TraceConfig_BufferConfig_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
has_size_kb() const52128   bool has_size_kb() const { return at<1>().valid(); }
size_kb() const52129   uint32_t size_kb() const { return at<1>().as_uint32(); }
has_fill_policy() const52130   bool has_fill_policy() const { return at<4>().valid(); }
fill_policy() const52131   int32_t fill_policy() const { return at<4>().as_int32(); }
52132 };
52133 
52134 class TraceConfig_BufferConfig : public ::protozero::Message {
52135  public:
52136   using Decoder = TraceConfig_BufferConfig_Decoder;
52137   enum : int32_t {
52138     kSizeKbFieldNumber = 1,
52139     kFillPolicyFieldNumber = 4,
52140   };
52141   using FillPolicy = ::perfetto::protos::pbzero::TraceConfig_BufferConfig_FillPolicy;
52142   static const FillPolicy UNSPECIFIED = TraceConfig_BufferConfig_FillPolicy_UNSPECIFIED;
52143   static const FillPolicy RING_BUFFER = TraceConfig_BufferConfig_FillPolicy_RING_BUFFER;
52144   static const FillPolicy DISCARD = TraceConfig_BufferConfig_FillPolicy_DISCARD;
52145 
52146   using FieldMetadata_SizeKb =
52147     ::protozero::proto_utils::FieldMetadata<
52148       1,
52149       ::protozero::proto_utils::RepetitionType::kNotRepeated,
52150       ::protozero::proto_utils::ProtoSchemaType::kUint32,
52151       uint32_t,
52152       TraceConfig_BufferConfig>;
52153 
52154   // Ceci n'est pas une pipe.
52155   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
52156   // type (and users are expected to use it as such, hence kCamelCase name).
52157   // It is declared as a function to keep protozero bindings header-only as
52158   // inline constexpr variables are not available until C++17 (while inline
52159   // functions are).
52160   // TODO(altimin): Use inline variable instead after adopting C++17.
kSizeKb()52161   static constexpr FieldMetadata_SizeKb kSizeKb() { return {}; }
set_size_kb(uint32_t value)52162   void set_size_kb(uint32_t value) {
52163     static constexpr uint32_t field_id = FieldMetadata_SizeKb::kFieldId;
52164     // Call the appropriate protozero::Message::Append(field_id, ...)
52165     // method based on the type of the field.
52166     ::protozero::internal::FieldWriter<
52167       ::protozero::proto_utils::ProtoSchemaType::kUint32>
52168         ::Append(*this, field_id, value);
52169   }
52170 
52171   using FieldMetadata_FillPolicy =
52172     ::protozero::proto_utils::FieldMetadata<
52173       4,
52174       ::protozero::proto_utils::RepetitionType::kNotRepeated,
52175       ::protozero::proto_utils::ProtoSchemaType::kEnum,
52176       ::perfetto::protos::pbzero::TraceConfig_BufferConfig_FillPolicy,
52177       TraceConfig_BufferConfig>;
52178 
52179   // Ceci n'est pas une pipe.
52180   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
52181   // type (and users are expected to use it as such, hence kCamelCase name).
52182   // It is declared as a function to keep protozero bindings header-only as
52183   // inline constexpr variables are not available until C++17 (while inline
52184   // functions are).
52185   // TODO(altimin): Use inline variable instead after adopting C++17.
kFillPolicy()52186   static constexpr FieldMetadata_FillPolicy kFillPolicy() { return {}; }
set_fill_policy(::perfetto::protos::pbzero::TraceConfig_BufferConfig_FillPolicy value)52187   void set_fill_policy(::perfetto::protos::pbzero::TraceConfig_BufferConfig_FillPolicy value) {
52188     static constexpr uint32_t field_id = FieldMetadata_FillPolicy::kFieldId;
52189     // Call the appropriate protozero::Message::Append(field_id, ...)
52190     // method based on the type of the field.
52191     ::protozero::internal::FieldWriter<
52192       ::protozero::proto_utils::ProtoSchemaType::kEnum>
52193         ::Append(*this, field_id, value);
52194   }
52195 };
52196 
52197 } // Namespace.
52198 } // Namespace.
52199 } // Namespace.
52200 #endif  // Include guard.
52201 // gen_amalgamated begin header: gen/protos/perfetto/trace/clock_snapshot.pbzero.h
52202 // Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
52203 
52204 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_CLOCK_SNAPSHOT_PROTO_H_
52205 #define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_CLOCK_SNAPSHOT_PROTO_H_
52206 
52207 #include <stddef.h>
52208 #include <stdint.h>
52209 
52210 // gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
52211 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
52212 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
52213 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
52214 // gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
52215 
52216 namespace perfetto {
52217 namespace protos {
52218 namespace pbzero {
52219 
52220 class ClockSnapshot_Clock;
52221 enum BuiltinClock : int32_t;
52222 
52223 enum ClockSnapshot_Clock_BuiltinClocks : int32_t {
52224   ClockSnapshot_Clock_BuiltinClocks_UNKNOWN = 0,
52225   ClockSnapshot_Clock_BuiltinClocks_REALTIME = 1,
52226   ClockSnapshot_Clock_BuiltinClocks_REALTIME_COARSE = 2,
52227   ClockSnapshot_Clock_BuiltinClocks_MONOTONIC = 3,
52228   ClockSnapshot_Clock_BuiltinClocks_MONOTONIC_COARSE = 4,
52229   ClockSnapshot_Clock_BuiltinClocks_MONOTONIC_RAW = 5,
52230   ClockSnapshot_Clock_BuiltinClocks_BOOTTIME = 6,
52231   ClockSnapshot_Clock_BuiltinClocks_BUILTIN_CLOCK_MAX_ID = 63,
52232 };
52233 
52234 const ClockSnapshot_Clock_BuiltinClocks ClockSnapshot_Clock_BuiltinClocks_MIN = ClockSnapshot_Clock_BuiltinClocks_UNKNOWN;
52235 const ClockSnapshot_Clock_BuiltinClocks ClockSnapshot_Clock_BuiltinClocks_MAX = ClockSnapshot_Clock_BuiltinClocks_BUILTIN_CLOCK_MAX_ID;
52236 
52237 class ClockSnapshot_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/2, /*HAS_NONPACKED_REPEATED_FIELDS=*/true> {
52238  public:
ClockSnapshot_Decoder(const uint8_t * data,size_t len)52239   ClockSnapshot_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
ClockSnapshot_Decoder(const std::string & raw)52240   explicit ClockSnapshot_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
ClockSnapshot_Decoder(const::protozero::ConstBytes & raw)52241   explicit ClockSnapshot_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
has_clocks() const52242   bool has_clocks() const { return at<1>().valid(); }
clocks() const52243   ::protozero::RepeatedFieldIterator<::protozero::ConstBytes> clocks() const { return GetRepeated<::protozero::ConstBytes>(1); }
has_primary_trace_clock() const52244   bool has_primary_trace_clock() const { return at<2>().valid(); }
primary_trace_clock() const52245   int32_t primary_trace_clock() const { return at<2>().as_int32(); }
52246 };
52247 
52248 class ClockSnapshot : public ::protozero::Message {
52249  public:
52250   using Decoder = ClockSnapshot_Decoder;
52251   enum : int32_t {
52252     kClocksFieldNumber = 1,
52253     kPrimaryTraceClockFieldNumber = 2,
52254   };
52255   using Clock = ::perfetto::protos::pbzero::ClockSnapshot_Clock;
52256 
52257   using FieldMetadata_Clocks =
52258     ::protozero::proto_utils::FieldMetadata<
52259       1,
52260       ::protozero::proto_utils::RepetitionType::kRepeatedNotPacked,
52261       ::protozero::proto_utils::ProtoSchemaType::kMessage,
52262       ClockSnapshot_Clock,
52263       ClockSnapshot>;
52264 
52265   // Ceci n'est pas une pipe.
52266   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
52267   // type (and users are expected to use it as such, hence kCamelCase name).
52268   // It is declared as a function to keep protozero bindings header-only as
52269   // inline constexpr variables are not available until C++17 (while inline
52270   // functions are).
52271   // TODO(altimin): Use inline variable instead after adopting C++17.
kClocks()52272   static constexpr FieldMetadata_Clocks kClocks() { return {}; }
add_clocks()52273   template <typename T = ClockSnapshot_Clock> T* add_clocks() {
52274     return BeginNestedMessage<T>(1);
52275   }
52276 
52277 
52278   using FieldMetadata_PrimaryTraceClock =
52279     ::protozero::proto_utils::FieldMetadata<
52280       2,
52281       ::protozero::proto_utils::RepetitionType::kNotRepeated,
52282       ::protozero::proto_utils::ProtoSchemaType::kEnum,
52283       ::perfetto::protos::pbzero::BuiltinClock,
52284       ClockSnapshot>;
52285 
52286   // Ceci n'est pas une pipe.
52287   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
52288   // type (and users are expected to use it as such, hence kCamelCase name).
52289   // It is declared as a function to keep protozero bindings header-only as
52290   // inline constexpr variables are not available until C++17 (while inline
52291   // functions are).
52292   // TODO(altimin): Use inline variable instead after adopting C++17.
kPrimaryTraceClock()52293   static constexpr FieldMetadata_PrimaryTraceClock kPrimaryTraceClock() { return {}; }
set_primary_trace_clock(::perfetto::protos::pbzero::BuiltinClock value)52294   void set_primary_trace_clock(::perfetto::protos::pbzero::BuiltinClock value) {
52295     static constexpr uint32_t field_id = FieldMetadata_PrimaryTraceClock::kFieldId;
52296     // Call the appropriate protozero::Message::Append(field_id, ...)
52297     // method based on the type of the field.
52298     ::protozero::internal::FieldWriter<
52299       ::protozero::proto_utils::ProtoSchemaType::kEnum>
52300         ::Append(*this, field_id, value);
52301   }
52302 };
52303 
52304 class ClockSnapshot_Clock_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
52305  public:
ClockSnapshot_Clock_Decoder(const uint8_t * data,size_t len)52306   ClockSnapshot_Clock_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
ClockSnapshot_Clock_Decoder(const std::string & raw)52307   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)52308   explicit ClockSnapshot_Clock_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
has_clock_id() const52309   bool has_clock_id() const { return at<1>().valid(); }
clock_id() const52310   uint32_t clock_id() const { return at<1>().as_uint32(); }
has_timestamp() const52311   bool has_timestamp() const { return at<2>().valid(); }
timestamp() const52312   uint64_t timestamp() const { return at<2>().as_uint64(); }
has_is_incremental() const52313   bool has_is_incremental() const { return at<3>().valid(); }
is_incremental() const52314   bool is_incremental() const { return at<3>().as_bool(); }
has_unit_multiplier_ns() const52315   bool has_unit_multiplier_ns() const { return at<4>().valid(); }
unit_multiplier_ns() const52316   uint64_t unit_multiplier_ns() const { return at<4>().as_uint64(); }
52317 };
52318 
52319 class ClockSnapshot_Clock : public ::protozero::Message {
52320  public:
52321   using Decoder = ClockSnapshot_Clock_Decoder;
52322   enum : int32_t {
52323     kClockIdFieldNumber = 1,
52324     kTimestampFieldNumber = 2,
52325     kIsIncrementalFieldNumber = 3,
52326     kUnitMultiplierNsFieldNumber = 4,
52327   };
52328   using BuiltinClocks = ::perfetto::protos::pbzero::ClockSnapshot_Clock_BuiltinClocks;
52329   static const BuiltinClocks UNKNOWN = ClockSnapshot_Clock_BuiltinClocks_UNKNOWN;
52330   static const BuiltinClocks REALTIME = ClockSnapshot_Clock_BuiltinClocks_REALTIME;
52331   static const BuiltinClocks REALTIME_COARSE = ClockSnapshot_Clock_BuiltinClocks_REALTIME_COARSE;
52332   static const BuiltinClocks MONOTONIC = ClockSnapshot_Clock_BuiltinClocks_MONOTONIC;
52333   static const BuiltinClocks MONOTONIC_COARSE = ClockSnapshot_Clock_BuiltinClocks_MONOTONIC_COARSE;
52334   static const BuiltinClocks MONOTONIC_RAW = ClockSnapshot_Clock_BuiltinClocks_MONOTONIC_RAW;
52335   static const BuiltinClocks BOOTTIME = ClockSnapshot_Clock_BuiltinClocks_BOOTTIME;
52336   static const BuiltinClocks BUILTIN_CLOCK_MAX_ID = ClockSnapshot_Clock_BuiltinClocks_BUILTIN_CLOCK_MAX_ID;
52337 
52338   using FieldMetadata_ClockId =
52339     ::protozero::proto_utils::FieldMetadata<
52340       1,
52341       ::protozero::proto_utils::RepetitionType::kNotRepeated,
52342       ::protozero::proto_utils::ProtoSchemaType::kUint32,
52343       uint32_t,
52344       ClockSnapshot_Clock>;
52345 
52346   // Ceci n'est pas une pipe.
52347   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
52348   // type (and users are expected to use it as such, hence kCamelCase name).
52349   // It is declared as a function to keep protozero bindings header-only as
52350   // inline constexpr variables are not available until C++17 (while inline
52351   // functions are).
52352   // TODO(altimin): Use inline variable instead after adopting C++17.
kClockId()52353   static constexpr FieldMetadata_ClockId kClockId() { return {}; }
set_clock_id(uint32_t value)52354   void set_clock_id(uint32_t value) {
52355     static constexpr uint32_t field_id = FieldMetadata_ClockId::kFieldId;
52356     // Call the appropriate protozero::Message::Append(field_id, ...)
52357     // method based on the type of the field.
52358     ::protozero::internal::FieldWriter<
52359       ::protozero::proto_utils::ProtoSchemaType::kUint32>
52360         ::Append(*this, field_id, value);
52361   }
52362 
52363   using FieldMetadata_Timestamp =
52364     ::protozero::proto_utils::FieldMetadata<
52365       2,
52366       ::protozero::proto_utils::RepetitionType::kNotRepeated,
52367       ::protozero::proto_utils::ProtoSchemaType::kUint64,
52368       uint64_t,
52369       ClockSnapshot_Clock>;
52370 
52371   // Ceci n'est pas une pipe.
52372   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
52373   // type (and users are expected to use it as such, hence kCamelCase name).
52374   // It is declared as a function to keep protozero bindings header-only as
52375   // inline constexpr variables are not available until C++17 (while inline
52376   // functions are).
52377   // TODO(altimin): Use inline variable instead after adopting C++17.
kTimestamp()52378   static constexpr FieldMetadata_Timestamp kTimestamp() { return {}; }
set_timestamp(uint64_t value)52379   void set_timestamp(uint64_t value) {
52380     static constexpr uint32_t field_id = FieldMetadata_Timestamp::kFieldId;
52381     // Call the appropriate protozero::Message::Append(field_id, ...)
52382     // method based on the type of the field.
52383     ::protozero::internal::FieldWriter<
52384       ::protozero::proto_utils::ProtoSchemaType::kUint64>
52385         ::Append(*this, field_id, value);
52386   }
52387 
52388   using FieldMetadata_IsIncremental =
52389     ::protozero::proto_utils::FieldMetadata<
52390       3,
52391       ::protozero::proto_utils::RepetitionType::kNotRepeated,
52392       ::protozero::proto_utils::ProtoSchemaType::kBool,
52393       bool,
52394       ClockSnapshot_Clock>;
52395 
52396   // Ceci n'est pas une pipe.
52397   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
52398   // type (and users are expected to use it as such, hence kCamelCase name).
52399   // It is declared as a function to keep protozero bindings header-only as
52400   // inline constexpr variables are not available until C++17 (while inline
52401   // functions are).
52402   // TODO(altimin): Use inline variable instead after adopting C++17.
kIsIncremental()52403   static constexpr FieldMetadata_IsIncremental kIsIncremental() { return {}; }
set_is_incremental(bool value)52404   void set_is_incremental(bool value) {
52405     static constexpr uint32_t field_id = FieldMetadata_IsIncremental::kFieldId;
52406     // Call the appropriate protozero::Message::Append(field_id, ...)
52407     // method based on the type of the field.
52408     ::protozero::internal::FieldWriter<
52409       ::protozero::proto_utils::ProtoSchemaType::kBool>
52410         ::Append(*this, field_id, value);
52411   }
52412 
52413   using FieldMetadata_UnitMultiplierNs =
52414     ::protozero::proto_utils::FieldMetadata<
52415       4,
52416       ::protozero::proto_utils::RepetitionType::kNotRepeated,
52417       ::protozero::proto_utils::ProtoSchemaType::kUint64,
52418       uint64_t,
52419       ClockSnapshot_Clock>;
52420 
52421   // Ceci n'est pas une pipe.
52422   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
52423   // type (and users are expected to use it as such, hence kCamelCase name).
52424   // It is declared as a function to keep protozero bindings header-only as
52425   // inline constexpr variables are not available until C++17 (while inline
52426   // functions are).
52427   // TODO(altimin): Use inline variable instead after adopting C++17.
kUnitMultiplierNs()52428   static constexpr FieldMetadata_UnitMultiplierNs kUnitMultiplierNs() { return {}; }
set_unit_multiplier_ns(uint64_t value)52429   void set_unit_multiplier_ns(uint64_t value) {
52430     static constexpr uint32_t field_id = FieldMetadata_UnitMultiplierNs::kFieldId;
52431     // Call the appropriate protozero::Message::Append(field_id, ...)
52432     // method based on the type of the field.
52433     ::protozero::internal::FieldWriter<
52434       ::protozero::proto_utils::ProtoSchemaType::kUint64>
52435         ::Append(*this, field_id, value);
52436   }
52437 };
52438 
52439 } // Namespace.
52440 } // Namespace.
52441 } // Namespace.
52442 #endif  // Include guard.
52443 // gen_amalgamated begin header: gen/protos/perfetto/trace/perfetto/tracing_service_event.pbzero.h
52444 // Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
52445 
52446 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_PERFETTO_TRACING_SERVICE_EVENT_PROTO_H_
52447 #define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_PERFETTO_TRACING_SERVICE_EVENT_PROTO_H_
52448 
52449 #include <stddef.h>
52450 #include <stdint.h>
52451 
52452 // gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
52453 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
52454 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
52455 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
52456 // gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
52457 
52458 namespace perfetto {
52459 namespace protos {
52460 namespace pbzero {
52461 
52462 
52463 class TracingServiceEvent_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/6, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
52464  public:
TracingServiceEvent_Decoder(const uint8_t * data,size_t len)52465   TracingServiceEvent_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
TracingServiceEvent_Decoder(const std::string & raw)52466   explicit TracingServiceEvent_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
TracingServiceEvent_Decoder(const::protozero::ConstBytes & raw)52467   explicit TracingServiceEvent_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
has_tracing_started() const52468   bool has_tracing_started() const { return at<2>().valid(); }
tracing_started() const52469   bool tracing_started() const { return at<2>().as_bool(); }
has_all_data_sources_started() const52470   bool has_all_data_sources_started() const { return at<1>().valid(); }
all_data_sources_started() const52471   bool all_data_sources_started() const { return at<1>().as_bool(); }
has_all_data_sources_flushed() const52472   bool has_all_data_sources_flushed() const { return at<3>().valid(); }
all_data_sources_flushed() const52473   bool all_data_sources_flushed() const { return at<3>().as_bool(); }
has_read_tracing_buffers_completed() const52474   bool has_read_tracing_buffers_completed() const { return at<4>().valid(); }
read_tracing_buffers_completed() const52475   bool read_tracing_buffers_completed() const { return at<4>().as_bool(); }
has_tracing_disabled() const52476   bool has_tracing_disabled() const { return at<5>().valid(); }
tracing_disabled() const52477   bool tracing_disabled() const { return at<5>().as_bool(); }
has_seized_for_bugreport() const52478   bool has_seized_for_bugreport() const { return at<6>().valid(); }
seized_for_bugreport() const52479   bool seized_for_bugreport() const { return at<6>().as_bool(); }
52480 };
52481 
52482 class TracingServiceEvent : public ::protozero::Message {
52483  public:
52484   using Decoder = TracingServiceEvent_Decoder;
52485   enum : int32_t {
52486     kTracingStartedFieldNumber = 2,
52487     kAllDataSourcesStartedFieldNumber = 1,
52488     kAllDataSourcesFlushedFieldNumber = 3,
52489     kReadTracingBuffersCompletedFieldNumber = 4,
52490     kTracingDisabledFieldNumber = 5,
52491     kSeizedForBugreportFieldNumber = 6,
52492   };
52493 
52494   using FieldMetadata_TracingStarted =
52495     ::protozero::proto_utils::FieldMetadata<
52496       2,
52497       ::protozero::proto_utils::RepetitionType::kNotRepeated,
52498       ::protozero::proto_utils::ProtoSchemaType::kBool,
52499       bool,
52500       TracingServiceEvent>;
52501 
52502   // Ceci n'est pas une pipe.
52503   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
52504   // type (and users are expected to use it as such, hence kCamelCase name).
52505   // It is declared as a function to keep protozero bindings header-only as
52506   // inline constexpr variables are not available until C++17 (while inline
52507   // functions are).
52508   // TODO(altimin): Use inline variable instead after adopting C++17.
kTracingStarted()52509   static constexpr FieldMetadata_TracingStarted kTracingStarted() { return {}; }
set_tracing_started(bool value)52510   void set_tracing_started(bool value) {
52511     static constexpr uint32_t field_id = FieldMetadata_TracingStarted::kFieldId;
52512     // Call the appropriate protozero::Message::Append(field_id, ...)
52513     // method based on the type of the field.
52514     ::protozero::internal::FieldWriter<
52515       ::protozero::proto_utils::ProtoSchemaType::kBool>
52516         ::Append(*this, field_id, value);
52517   }
52518 
52519   using FieldMetadata_AllDataSourcesStarted =
52520     ::protozero::proto_utils::FieldMetadata<
52521       1,
52522       ::protozero::proto_utils::RepetitionType::kNotRepeated,
52523       ::protozero::proto_utils::ProtoSchemaType::kBool,
52524       bool,
52525       TracingServiceEvent>;
52526 
52527   // Ceci n'est pas une pipe.
52528   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
52529   // type (and users are expected to use it as such, hence kCamelCase name).
52530   // It is declared as a function to keep protozero bindings header-only as
52531   // inline constexpr variables are not available until C++17 (while inline
52532   // functions are).
52533   // TODO(altimin): Use inline variable instead after adopting C++17.
kAllDataSourcesStarted()52534   static constexpr FieldMetadata_AllDataSourcesStarted kAllDataSourcesStarted() { return {}; }
set_all_data_sources_started(bool value)52535   void set_all_data_sources_started(bool value) {
52536     static constexpr uint32_t field_id = FieldMetadata_AllDataSourcesStarted::kFieldId;
52537     // Call the appropriate protozero::Message::Append(field_id, ...)
52538     // method based on the type of the field.
52539     ::protozero::internal::FieldWriter<
52540       ::protozero::proto_utils::ProtoSchemaType::kBool>
52541         ::Append(*this, field_id, value);
52542   }
52543 
52544   using FieldMetadata_AllDataSourcesFlushed =
52545     ::protozero::proto_utils::FieldMetadata<
52546       3,
52547       ::protozero::proto_utils::RepetitionType::kNotRepeated,
52548       ::protozero::proto_utils::ProtoSchemaType::kBool,
52549       bool,
52550       TracingServiceEvent>;
52551 
52552   // Ceci n'est pas une pipe.
52553   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
52554   // type (and users are expected to use it as such, hence kCamelCase name).
52555   // It is declared as a function to keep protozero bindings header-only as
52556   // inline constexpr variables are not available until C++17 (while inline
52557   // functions are).
52558   // TODO(altimin): Use inline variable instead after adopting C++17.
kAllDataSourcesFlushed()52559   static constexpr FieldMetadata_AllDataSourcesFlushed kAllDataSourcesFlushed() { return {}; }
set_all_data_sources_flushed(bool value)52560   void set_all_data_sources_flushed(bool value) {
52561     static constexpr uint32_t field_id = FieldMetadata_AllDataSourcesFlushed::kFieldId;
52562     // Call the appropriate protozero::Message::Append(field_id, ...)
52563     // method based on the type of the field.
52564     ::protozero::internal::FieldWriter<
52565       ::protozero::proto_utils::ProtoSchemaType::kBool>
52566         ::Append(*this, field_id, value);
52567   }
52568 
52569   using FieldMetadata_ReadTracingBuffersCompleted =
52570     ::protozero::proto_utils::FieldMetadata<
52571       4,
52572       ::protozero::proto_utils::RepetitionType::kNotRepeated,
52573       ::protozero::proto_utils::ProtoSchemaType::kBool,
52574       bool,
52575       TracingServiceEvent>;
52576 
52577   // Ceci n'est pas une pipe.
52578   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
52579   // type (and users are expected to use it as such, hence kCamelCase name).
52580   // It is declared as a function to keep protozero bindings header-only as
52581   // inline constexpr variables are not available until C++17 (while inline
52582   // functions are).
52583   // TODO(altimin): Use inline variable instead after adopting C++17.
kReadTracingBuffersCompleted()52584   static constexpr FieldMetadata_ReadTracingBuffersCompleted kReadTracingBuffersCompleted() { return {}; }
set_read_tracing_buffers_completed(bool value)52585   void set_read_tracing_buffers_completed(bool value) {
52586     static constexpr uint32_t field_id = FieldMetadata_ReadTracingBuffersCompleted::kFieldId;
52587     // Call the appropriate protozero::Message::Append(field_id, ...)
52588     // method based on the type of the field.
52589     ::protozero::internal::FieldWriter<
52590       ::protozero::proto_utils::ProtoSchemaType::kBool>
52591         ::Append(*this, field_id, value);
52592   }
52593 
52594   using FieldMetadata_TracingDisabled =
52595     ::protozero::proto_utils::FieldMetadata<
52596       5,
52597       ::protozero::proto_utils::RepetitionType::kNotRepeated,
52598       ::protozero::proto_utils::ProtoSchemaType::kBool,
52599       bool,
52600       TracingServiceEvent>;
52601 
52602   // Ceci n'est pas une pipe.
52603   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
52604   // type (and users are expected to use it as such, hence kCamelCase name).
52605   // It is declared as a function to keep protozero bindings header-only as
52606   // inline constexpr variables are not available until C++17 (while inline
52607   // functions are).
52608   // TODO(altimin): Use inline variable instead after adopting C++17.
kTracingDisabled()52609   static constexpr FieldMetadata_TracingDisabled kTracingDisabled() { return {}; }
set_tracing_disabled(bool value)52610   void set_tracing_disabled(bool value) {
52611     static constexpr uint32_t field_id = FieldMetadata_TracingDisabled::kFieldId;
52612     // Call the appropriate protozero::Message::Append(field_id, ...)
52613     // method based on the type of the field.
52614     ::protozero::internal::FieldWriter<
52615       ::protozero::proto_utils::ProtoSchemaType::kBool>
52616         ::Append(*this, field_id, value);
52617   }
52618 
52619   using FieldMetadata_SeizedForBugreport =
52620     ::protozero::proto_utils::FieldMetadata<
52621       6,
52622       ::protozero::proto_utils::RepetitionType::kNotRepeated,
52623       ::protozero::proto_utils::ProtoSchemaType::kBool,
52624       bool,
52625       TracingServiceEvent>;
52626 
52627   // Ceci n'est pas une pipe.
52628   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
52629   // type (and users are expected to use it as such, hence kCamelCase name).
52630   // It is declared as a function to keep protozero bindings header-only as
52631   // inline constexpr variables are not available until C++17 (while inline
52632   // functions are).
52633   // TODO(altimin): Use inline variable instead after adopting C++17.
kSeizedForBugreport()52634   static constexpr FieldMetadata_SeizedForBugreport kSeizedForBugreport() { return {}; }
set_seized_for_bugreport(bool value)52635   void set_seized_for_bugreport(bool value) {
52636     static constexpr uint32_t field_id = FieldMetadata_SeizedForBugreport::kFieldId;
52637     // Call the appropriate protozero::Message::Append(field_id, ...)
52638     // method based on the type of the field.
52639     ::protozero::internal::FieldWriter<
52640       ::protozero::proto_utils::ProtoSchemaType::kBool>
52641         ::Append(*this, field_id, value);
52642   }
52643 };
52644 
52645 } // Namespace.
52646 } // Namespace.
52647 } // Namespace.
52648 #endif  // Include guard.
52649 // gen_amalgamated begin header: gen/protos/perfetto/trace/system_info.pbzero.h
52650 // Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
52651 
52652 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_SYSTEM_INFO_PROTO_H_
52653 #define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_SYSTEM_INFO_PROTO_H_
52654 
52655 #include <stddef.h>
52656 #include <stdint.h>
52657 
52658 // gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
52659 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
52660 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
52661 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
52662 // gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
52663 
52664 namespace perfetto {
52665 namespace protos {
52666 namespace pbzero {
52667 
52668 class Utsname;
52669 
52670 class SystemInfo_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/5, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
52671  public:
SystemInfo_Decoder(const uint8_t * data,size_t len)52672   SystemInfo_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
SystemInfo_Decoder(const std::string & raw)52673   explicit SystemInfo_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
SystemInfo_Decoder(const::protozero::ConstBytes & raw)52674   explicit SystemInfo_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
has_utsname() const52675   bool has_utsname() const { return at<1>().valid(); }
utsname() const52676   ::protozero::ConstBytes utsname() const { return at<1>().as_bytes(); }
has_android_build_fingerprint() const52677   bool has_android_build_fingerprint() const { return at<2>().valid(); }
android_build_fingerprint() const52678   ::protozero::ConstChars android_build_fingerprint() const { return at<2>().as_string(); }
has_hz() const52679   bool has_hz() const { return at<3>().valid(); }
hz() const52680   int64_t hz() const { return at<3>().as_int64(); }
has_tracing_service_version() const52681   bool has_tracing_service_version() const { return at<4>().valid(); }
tracing_service_version() const52682   ::protozero::ConstChars tracing_service_version() const { return at<4>().as_string(); }
has_android_sdk_version() const52683   bool has_android_sdk_version() const { return at<5>().valid(); }
android_sdk_version() const52684   uint64_t android_sdk_version() const { return at<5>().as_uint64(); }
52685 };
52686 
52687 class SystemInfo : public ::protozero::Message {
52688  public:
52689   using Decoder = SystemInfo_Decoder;
52690   enum : int32_t {
52691     kUtsnameFieldNumber = 1,
52692     kAndroidBuildFingerprintFieldNumber = 2,
52693     kHzFieldNumber = 3,
52694     kTracingServiceVersionFieldNumber = 4,
52695     kAndroidSdkVersionFieldNumber = 5,
52696   };
52697 
52698   using FieldMetadata_Utsname =
52699     ::protozero::proto_utils::FieldMetadata<
52700       1,
52701       ::protozero::proto_utils::RepetitionType::kNotRepeated,
52702       ::protozero::proto_utils::ProtoSchemaType::kMessage,
52703       Utsname,
52704       SystemInfo>;
52705 
52706   // Ceci n'est pas une pipe.
52707   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
52708   // type (and users are expected to use it as such, hence kCamelCase name).
52709   // It is declared as a function to keep protozero bindings header-only as
52710   // inline constexpr variables are not available until C++17 (while inline
52711   // functions are).
52712   // TODO(altimin): Use inline variable instead after adopting C++17.
kUtsname()52713   static constexpr FieldMetadata_Utsname kUtsname() { return {}; }
set_utsname()52714   template <typename T = Utsname> T* set_utsname() {
52715     return BeginNestedMessage<T>(1);
52716   }
52717 
52718 
52719   using FieldMetadata_AndroidBuildFingerprint =
52720     ::protozero::proto_utils::FieldMetadata<
52721       2,
52722       ::protozero::proto_utils::RepetitionType::kNotRepeated,
52723       ::protozero::proto_utils::ProtoSchemaType::kString,
52724       std::string,
52725       SystemInfo>;
52726 
52727   // Ceci n'est pas une pipe.
52728   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
52729   // type (and users are expected to use it as such, hence kCamelCase name).
52730   // It is declared as a function to keep protozero bindings header-only as
52731   // inline constexpr variables are not available until C++17 (while inline
52732   // functions are).
52733   // TODO(altimin): Use inline variable instead after adopting C++17.
kAndroidBuildFingerprint()52734   static constexpr FieldMetadata_AndroidBuildFingerprint kAndroidBuildFingerprint() { return {}; }
set_android_build_fingerprint(const char * data,size_t size)52735   void set_android_build_fingerprint(const char* data, size_t size) {
52736     AppendBytes(FieldMetadata_AndroidBuildFingerprint::kFieldId, data, size);
52737   }
set_android_build_fingerprint(std::string value)52738   void set_android_build_fingerprint(std::string value) {
52739     static constexpr uint32_t field_id = FieldMetadata_AndroidBuildFingerprint::kFieldId;
52740     // Call the appropriate protozero::Message::Append(field_id, ...)
52741     // method based on the type of the field.
52742     ::protozero::internal::FieldWriter<
52743       ::protozero::proto_utils::ProtoSchemaType::kString>
52744         ::Append(*this, field_id, value);
52745   }
52746 
52747   using FieldMetadata_Hz =
52748     ::protozero::proto_utils::FieldMetadata<
52749       3,
52750       ::protozero::proto_utils::RepetitionType::kNotRepeated,
52751       ::protozero::proto_utils::ProtoSchemaType::kInt64,
52752       int64_t,
52753       SystemInfo>;
52754 
52755   // Ceci n'est pas une pipe.
52756   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
52757   // type (and users are expected to use it as such, hence kCamelCase name).
52758   // It is declared as a function to keep protozero bindings header-only as
52759   // inline constexpr variables are not available until C++17 (while inline
52760   // functions are).
52761   // TODO(altimin): Use inline variable instead after adopting C++17.
kHz()52762   static constexpr FieldMetadata_Hz kHz() { return {}; }
set_hz(int64_t value)52763   void set_hz(int64_t value) {
52764     static constexpr uint32_t field_id = FieldMetadata_Hz::kFieldId;
52765     // Call the appropriate protozero::Message::Append(field_id, ...)
52766     // method based on the type of the field.
52767     ::protozero::internal::FieldWriter<
52768       ::protozero::proto_utils::ProtoSchemaType::kInt64>
52769         ::Append(*this, field_id, value);
52770   }
52771 
52772   using FieldMetadata_TracingServiceVersion =
52773     ::protozero::proto_utils::FieldMetadata<
52774       4,
52775       ::protozero::proto_utils::RepetitionType::kNotRepeated,
52776       ::protozero::proto_utils::ProtoSchemaType::kString,
52777       std::string,
52778       SystemInfo>;
52779 
52780   // Ceci n'est pas une pipe.
52781   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
52782   // type (and users are expected to use it as such, hence kCamelCase name).
52783   // It is declared as a function to keep protozero bindings header-only as
52784   // inline constexpr variables are not available until C++17 (while inline
52785   // functions are).
52786   // TODO(altimin): Use inline variable instead after adopting C++17.
kTracingServiceVersion()52787   static constexpr FieldMetadata_TracingServiceVersion kTracingServiceVersion() { return {}; }
set_tracing_service_version(const char * data,size_t size)52788   void set_tracing_service_version(const char* data, size_t size) {
52789     AppendBytes(FieldMetadata_TracingServiceVersion::kFieldId, data, size);
52790   }
set_tracing_service_version(std::string value)52791   void set_tracing_service_version(std::string value) {
52792     static constexpr uint32_t field_id = FieldMetadata_TracingServiceVersion::kFieldId;
52793     // Call the appropriate protozero::Message::Append(field_id, ...)
52794     // method based on the type of the field.
52795     ::protozero::internal::FieldWriter<
52796       ::protozero::proto_utils::ProtoSchemaType::kString>
52797         ::Append(*this, field_id, value);
52798   }
52799 
52800   using FieldMetadata_AndroidSdkVersion =
52801     ::protozero::proto_utils::FieldMetadata<
52802       5,
52803       ::protozero::proto_utils::RepetitionType::kNotRepeated,
52804       ::protozero::proto_utils::ProtoSchemaType::kUint64,
52805       uint64_t,
52806       SystemInfo>;
52807 
52808   // Ceci n'est pas une pipe.
52809   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
52810   // type (and users are expected to use it as such, hence kCamelCase name).
52811   // It is declared as a function to keep protozero bindings header-only as
52812   // inline constexpr variables are not available until C++17 (while inline
52813   // functions are).
52814   // TODO(altimin): Use inline variable instead after adopting C++17.
kAndroidSdkVersion()52815   static constexpr FieldMetadata_AndroidSdkVersion kAndroidSdkVersion() { return {}; }
set_android_sdk_version(uint64_t value)52816   void set_android_sdk_version(uint64_t value) {
52817     static constexpr uint32_t field_id = FieldMetadata_AndroidSdkVersion::kFieldId;
52818     // Call the appropriate protozero::Message::Append(field_id, ...)
52819     // method based on the type of the field.
52820     ::protozero::internal::FieldWriter<
52821       ::protozero::proto_utils::ProtoSchemaType::kUint64>
52822         ::Append(*this, field_id, value);
52823   }
52824 };
52825 
52826 class Utsname_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/4, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
52827  public:
Utsname_Decoder(const uint8_t * data,size_t len)52828   Utsname_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
Utsname_Decoder(const std::string & raw)52829   explicit Utsname_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
Utsname_Decoder(const::protozero::ConstBytes & raw)52830   explicit Utsname_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
has_sysname() const52831   bool has_sysname() const { return at<1>().valid(); }
sysname() const52832   ::protozero::ConstChars sysname() const { return at<1>().as_string(); }
has_version() const52833   bool has_version() const { return at<2>().valid(); }
version() const52834   ::protozero::ConstChars version() const { return at<2>().as_string(); }
has_release() const52835   bool has_release() const { return at<3>().valid(); }
release() const52836   ::protozero::ConstChars release() const { return at<3>().as_string(); }
has_machine() const52837   bool has_machine() const { return at<4>().valid(); }
machine() const52838   ::protozero::ConstChars machine() const { return at<4>().as_string(); }
52839 };
52840 
52841 class Utsname : public ::protozero::Message {
52842  public:
52843   using Decoder = Utsname_Decoder;
52844   enum : int32_t {
52845     kSysnameFieldNumber = 1,
52846     kVersionFieldNumber = 2,
52847     kReleaseFieldNumber = 3,
52848     kMachineFieldNumber = 4,
52849   };
52850 
52851   using FieldMetadata_Sysname =
52852     ::protozero::proto_utils::FieldMetadata<
52853       1,
52854       ::protozero::proto_utils::RepetitionType::kNotRepeated,
52855       ::protozero::proto_utils::ProtoSchemaType::kString,
52856       std::string,
52857       Utsname>;
52858 
52859   // Ceci n'est pas une pipe.
52860   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
52861   // type (and users are expected to use it as such, hence kCamelCase name).
52862   // It is declared as a function to keep protozero bindings header-only as
52863   // inline constexpr variables are not available until C++17 (while inline
52864   // functions are).
52865   // TODO(altimin): Use inline variable instead after adopting C++17.
kSysname()52866   static constexpr FieldMetadata_Sysname kSysname() { return {}; }
set_sysname(const char * data,size_t size)52867   void set_sysname(const char* data, size_t size) {
52868     AppendBytes(FieldMetadata_Sysname::kFieldId, data, size);
52869   }
set_sysname(std::string value)52870   void set_sysname(std::string value) {
52871     static constexpr uint32_t field_id = FieldMetadata_Sysname::kFieldId;
52872     // Call the appropriate protozero::Message::Append(field_id, ...)
52873     // method based on the type of the field.
52874     ::protozero::internal::FieldWriter<
52875       ::protozero::proto_utils::ProtoSchemaType::kString>
52876         ::Append(*this, field_id, value);
52877   }
52878 
52879   using FieldMetadata_Version =
52880     ::protozero::proto_utils::FieldMetadata<
52881       2,
52882       ::protozero::proto_utils::RepetitionType::kNotRepeated,
52883       ::protozero::proto_utils::ProtoSchemaType::kString,
52884       std::string,
52885       Utsname>;
52886 
52887   // Ceci n'est pas une pipe.
52888   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
52889   // type (and users are expected to use it as such, hence kCamelCase name).
52890   // It is declared as a function to keep protozero bindings header-only as
52891   // inline constexpr variables are not available until C++17 (while inline
52892   // functions are).
52893   // TODO(altimin): Use inline variable instead after adopting C++17.
kVersion()52894   static constexpr FieldMetadata_Version kVersion() { return {}; }
set_version(const char * data,size_t size)52895   void set_version(const char* data, size_t size) {
52896     AppendBytes(FieldMetadata_Version::kFieldId, data, size);
52897   }
set_version(std::string value)52898   void set_version(std::string value) {
52899     static constexpr uint32_t field_id = FieldMetadata_Version::kFieldId;
52900     // Call the appropriate protozero::Message::Append(field_id, ...)
52901     // method based on the type of the field.
52902     ::protozero::internal::FieldWriter<
52903       ::protozero::proto_utils::ProtoSchemaType::kString>
52904         ::Append(*this, field_id, value);
52905   }
52906 
52907   using FieldMetadata_Release =
52908     ::protozero::proto_utils::FieldMetadata<
52909       3,
52910       ::protozero::proto_utils::RepetitionType::kNotRepeated,
52911       ::protozero::proto_utils::ProtoSchemaType::kString,
52912       std::string,
52913       Utsname>;
52914 
52915   // Ceci n'est pas une pipe.
52916   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
52917   // type (and users are expected to use it as such, hence kCamelCase name).
52918   // It is declared as a function to keep protozero bindings header-only as
52919   // inline constexpr variables are not available until C++17 (while inline
52920   // functions are).
52921   // TODO(altimin): Use inline variable instead after adopting C++17.
kRelease()52922   static constexpr FieldMetadata_Release kRelease() { return {}; }
set_release(const char * data,size_t size)52923   void set_release(const char* data, size_t size) {
52924     AppendBytes(FieldMetadata_Release::kFieldId, data, size);
52925   }
set_release(std::string value)52926   void set_release(std::string value) {
52927     static constexpr uint32_t field_id = FieldMetadata_Release::kFieldId;
52928     // Call the appropriate protozero::Message::Append(field_id, ...)
52929     // method based on the type of the field.
52930     ::protozero::internal::FieldWriter<
52931       ::protozero::proto_utils::ProtoSchemaType::kString>
52932         ::Append(*this, field_id, value);
52933   }
52934 
52935   using FieldMetadata_Machine =
52936     ::protozero::proto_utils::FieldMetadata<
52937       4,
52938       ::protozero::proto_utils::RepetitionType::kNotRepeated,
52939       ::protozero::proto_utils::ProtoSchemaType::kString,
52940       std::string,
52941       Utsname>;
52942 
52943   // Ceci n'est pas une pipe.
52944   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
52945   // type (and users are expected to use it as such, hence kCamelCase name).
52946   // It is declared as a function to keep protozero bindings header-only as
52947   // inline constexpr variables are not available until C++17 (while inline
52948   // functions are).
52949   // TODO(altimin): Use inline variable instead after adopting C++17.
kMachine()52950   static constexpr FieldMetadata_Machine kMachine() { return {}; }
set_machine(const char * data,size_t size)52951   void set_machine(const char* data, size_t size) {
52952     AppendBytes(FieldMetadata_Machine::kFieldId, data, size);
52953   }
set_machine(std::string value)52954   void set_machine(std::string value) {
52955     static constexpr uint32_t field_id = FieldMetadata_Machine::kFieldId;
52956     // Call the appropriate protozero::Message::Append(field_id, ...)
52957     // method based on the type of the field.
52958     ::protozero::internal::FieldWriter<
52959       ::protozero::proto_utils::ProtoSchemaType::kString>
52960         ::Append(*this, field_id, value);
52961   }
52962 };
52963 
52964 } // Namespace.
52965 } // Namespace.
52966 } // Namespace.
52967 #endif  // Include guard.
52968 // gen_amalgamated begin header: gen/protos/perfetto/trace/trigger.pbzero.h
52969 // Autogenerated by the ProtoZero compiler plugin. DO NOT EDIT.
52970 
52971 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRIGGER_PROTO_H_
52972 #define PERFETTO_PROTOS_PROTOS_PERFETTO_TRACE_TRIGGER_PROTO_H_
52973 
52974 #include <stddef.h>
52975 #include <stdint.h>
52976 
52977 // gen_amalgamated expanded: #include "perfetto/protozero/field_writer.h"
52978 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
52979 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
52980 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
52981 // gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
52982 
52983 namespace perfetto {
52984 namespace protos {
52985 namespace pbzero {
52986 
52987 
52988 class Trigger_Decoder : public ::protozero::TypedProtoDecoder</*MAX_FIELD_ID=*/3, /*HAS_NONPACKED_REPEATED_FIELDS=*/false> {
52989  public:
Trigger_Decoder(const uint8_t * data,size_t len)52990   Trigger_Decoder(const uint8_t* data, size_t len) : TypedProtoDecoder(data, len) {}
Trigger_Decoder(const std::string & raw)52991   explicit Trigger_Decoder(const std::string& raw) : TypedProtoDecoder(reinterpret_cast<const uint8_t*>(raw.data()), raw.size()) {}
Trigger_Decoder(const::protozero::ConstBytes & raw)52992   explicit Trigger_Decoder(const ::protozero::ConstBytes& raw) : TypedProtoDecoder(raw.data, raw.size) {}
has_trigger_name() const52993   bool has_trigger_name() const { return at<1>().valid(); }
trigger_name() const52994   ::protozero::ConstChars trigger_name() const { return at<1>().as_string(); }
has_producer_name() const52995   bool has_producer_name() const { return at<2>().valid(); }
producer_name() const52996   ::protozero::ConstChars producer_name() const { return at<2>().as_string(); }
has_trusted_producer_uid() const52997   bool has_trusted_producer_uid() const { return at<3>().valid(); }
trusted_producer_uid() const52998   int32_t trusted_producer_uid() const { return at<3>().as_int32(); }
52999 };
53000 
53001 class Trigger : public ::protozero::Message {
53002  public:
53003   using Decoder = Trigger_Decoder;
53004   enum : int32_t {
53005     kTriggerNameFieldNumber = 1,
53006     kProducerNameFieldNumber = 2,
53007     kTrustedProducerUidFieldNumber = 3,
53008   };
53009 
53010   using FieldMetadata_TriggerName =
53011     ::protozero::proto_utils::FieldMetadata<
53012       1,
53013       ::protozero::proto_utils::RepetitionType::kNotRepeated,
53014       ::protozero::proto_utils::ProtoSchemaType::kString,
53015       std::string,
53016       Trigger>;
53017 
53018   // Ceci n'est pas une pipe.
53019   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
53020   // type (and users are expected to use it as such, hence kCamelCase name).
53021   // It is declared as a function to keep protozero bindings header-only as
53022   // inline constexpr variables are not available until C++17 (while inline
53023   // functions are).
53024   // TODO(altimin): Use inline variable instead after adopting C++17.
kTriggerName()53025   static constexpr FieldMetadata_TriggerName kTriggerName() { return {}; }
set_trigger_name(const char * data,size_t size)53026   void set_trigger_name(const char* data, size_t size) {
53027     AppendBytes(FieldMetadata_TriggerName::kFieldId, data, size);
53028   }
set_trigger_name(std::string value)53029   void set_trigger_name(std::string value) {
53030     static constexpr uint32_t field_id = FieldMetadata_TriggerName::kFieldId;
53031     // Call the appropriate protozero::Message::Append(field_id, ...)
53032     // method based on the type of the field.
53033     ::protozero::internal::FieldWriter<
53034       ::protozero::proto_utils::ProtoSchemaType::kString>
53035         ::Append(*this, field_id, value);
53036   }
53037 
53038   using FieldMetadata_ProducerName =
53039     ::protozero::proto_utils::FieldMetadata<
53040       2,
53041       ::protozero::proto_utils::RepetitionType::kNotRepeated,
53042       ::protozero::proto_utils::ProtoSchemaType::kString,
53043       std::string,
53044       Trigger>;
53045 
53046   // Ceci n'est pas une pipe.
53047   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
53048   // type (and users are expected to use it as such, hence kCamelCase name).
53049   // It is declared as a function to keep protozero bindings header-only as
53050   // inline constexpr variables are not available until C++17 (while inline
53051   // functions are).
53052   // TODO(altimin): Use inline variable instead after adopting C++17.
kProducerName()53053   static constexpr FieldMetadata_ProducerName kProducerName() { return {}; }
set_producer_name(const char * data,size_t size)53054   void set_producer_name(const char* data, size_t size) {
53055     AppendBytes(FieldMetadata_ProducerName::kFieldId, data, size);
53056   }
set_producer_name(std::string value)53057   void set_producer_name(std::string value) {
53058     static constexpr uint32_t field_id = FieldMetadata_ProducerName::kFieldId;
53059     // Call the appropriate protozero::Message::Append(field_id, ...)
53060     // method based on the type of the field.
53061     ::protozero::internal::FieldWriter<
53062       ::protozero::proto_utils::ProtoSchemaType::kString>
53063         ::Append(*this, field_id, value);
53064   }
53065 
53066   using FieldMetadata_TrustedProducerUid =
53067     ::protozero::proto_utils::FieldMetadata<
53068       3,
53069       ::protozero::proto_utils::RepetitionType::kNotRepeated,
53070       ::protozero::proto_utils::ProtoSchemaType::kInt32,
53071       int32_t,
53072       Trigger>;
53073 
53074   // Ceci n'est pas une pipe.
53075   // This is actually a variable of FieldMetadataHelper<FieldMetadata<...>>
53076   // type (and users are expected to use it as such, hence kCamelCase name).
53077   // It is declared as a function to keep protozero bindings header-only as
53078   // inline constexpr variables are not available until C++17 (while inline
53079   // functions are).
53080   // TODO(altimin): Use inline variable instead after adopting C++17.
kTrustedProducerUid()53081   static constexpr FieldMetadata_TrustedProducerUid kTrustedProducerUid() { return {}; }
set_trusted_producer_uid(int32_t value)53082   void set_trusted_producer_uid(int32_t value) {
53083     static constexpr uint32_t field_id = FieldMetadata_TrustedProducerUid::kFieldId;
53084     // Call the appropriate protozero::Message::Append(field_id, ...)
53085     // method based on the type of the field.
53086     ::protozero::internal::FieldWriter<
53087       ::protozero::proto_utils::ProtoSchemaType::kInt32>
53088         ::Append(*this, field_id, value);
53089   }
53090 };
53091 
53092 } // Namespace.
53093 } // Namespace.
53094 } // Namespace.
53095 #endif  // Include guard.
53096 /*
53097  * Copyright (C) 2017 The Android Open Source Project
53098  *
53099  * Licensed under the Apache License, Version 2.0 (the "License");
53100  * you may not use this file except in compliance with the License.
53101  * You may obtain a copy of the License at
53102  *
53103  *      http://www.apache.org/licenses/LICENSE-2.0
53104  *
53105  * Unless required by applicable law or agreed to in writing, software
53106  * distributed under the License is distributed on an "AS IS" BASIS,
53107  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
53108  * See the License for the specific language governing permissions and
53109  * limitations under the License.
53110  */
53111 
53112 // gen_amalgamated expanded: #include "src/tracing/core/tracing_service_impl.h"
53113 
53114 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
53115 // gen_amalgamated expanded: #include "perfetto/tracing/core/forward_decls.h"
53116 
53117 #include <errno.h>
53118 #include <limits.h>
53119 #include <string.h>
53120 
53121 #include <cinttypes>
53122 #include <regex>
53123 #include <unordered_set>
53124 
53125 #if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) && \
53126     !PERFETTO_BUILDFLAG(PERFETTO_OS_NACL)
53127 #include <sys/uio.h>
53128 #include <sys/utsname.h>
53129 #include <unistd.h>
53130 #endif
53131 
53132 #if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) && \
53133     PERFETTO_BUILDFLAG(PERFETTO_ANDROID_BUILD)
53134 // gen_amalgamated expanded: #include "src/android_internal/lazy_library_loader.h"    // nogncheck
53135 // gen_amalgamated expanded: #include "src/android_internal/tracing_service_proxy.h"  // nogncheck
53136 #endif
53137 
53138 #if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \
53139     PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) ||   \
53140     PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
53141 #define PERFETTO_HAS_CHMOD
53142 #include <sys/stat.h>
53143 #endif
53144 
53145 #include <algorithm>
53146 
53147 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
53148 // gen_amalgamated expanded: #include "perfetto/base/status.h"
53149 // gen_amalgamated expanded: #include "perfetto/base/task_runner.h"
53150 // gen_amalgamated expanded: #include "perfetto/ext/base/android_utils.h"
53151 // gen_amalgamated expanded: #include "perfetto/ext/base/crash_keys.h"
53152 // gen_amalgamated expanded: #include "perfetto/ext/base/file_utils.h"
53153 // gen_amalgamated expanded: #include "perfetto/ext/base/metatrace.h"
53154 // gen_amalgamated expanded: #include "perfetto/ext/base/string_utils.h"
53155 // gen_amalgamated expanded: #include "perfetto/ext/base/temp_file.h"
53156 // gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
53157 // gen_amalgamated expanded: #include "perfetto/ext/base/version.h"
53158 // gen_amalgamated expanded: #include "perfetto/ext/base/watchdog.h"
53159 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/basic_types.h"
53160 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/consumer.h"
53161 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/observable_events.h"
53162 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/producer.h"
53163 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/shared_memory.h"
53164 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/shared_memory_abi.h"
53165 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/trace_packet.h"
53166 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/trace_writer.h"
53167 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
53168 // gen_amalgamated expanded: #include "perfetto/protozero/static_buffer.h"
53169 // gen_amalgamated expanded: #include "perfetto/tracing/core/data_source_descriptor.h"
53170 // gen_amalgamated expanded: #include "perfetto/tracing/core/tracing_service_capabilities.h"
53171 // gen_amalgamated expanded: #include "perfetto/tracing/core/tracing_service_state.h"
53172 // gen_amalgamated expanded: #include "src/android_stats/statsd_logging_helper.h"
53173 // gen_amalgamated expanded: #include "src/protozero/filtering/message_filter.h"
53174 // gen_amalgamated expanded: #include "src/tracing/core/packet_stream_validator.h"
53175 // gen_amalgamated expanded: #include "src/tracing/core/shared_memory_arbiter_impl.h"
53176 // gen_amalgamated expanded: #include "src/tracing/core/trace_buffer.h"
53177 
53178 // gen_amalgamated expanded: #include "protos/perfetto/common/builtin_clock.gen.h"
53179 // gen_amalgamated expanded: #include "protos/perfetto/common/builtin_clock.pbzero.h"
53180 // gen_amalgamated expanded: #include "protos/perfetto/common/trace_stats.pbzero.h"
53181 // gen_amalgamated expanded: #include "protos/perfetto/config/trace_config.pbzero.h"
53182 // gen_amalgamated expanded: #include "protos/perfetto/trace/clock_snapshot.pbzero.h"
53183 // gen_amalgamated expanded: #include "protos/perfetto/trace/perfetto/tracing_service_event.pbzero.h"
53184 // gen_amalgamated expanded: #include "protos/perfetto/trace/system_info.pbzero.h"
53185 // gen_amalgamated expanded: #include "protos/perfetto/trace/trace_packet.pbzero.h"
53186 // gen_amalgamated expanded: #include "protos/perfetto/trace/trigger.pbzero.h"
53187 
53188 // General note: this class must assume that Producers are malicious and will
53189 // try to crash / exploit this class. We can trust pointers because they come
53190 // from the IPC layer, but we should never assume that that the producer calls
53191 // come in the right order or their arguments are sane / within bounds.
53192 
53193 // This is a macro because we want the call-site line number for the ELOG.
53194 #define PERFETTO_SVC_ERR(...) \
53195   (PERFETTO_ELOG(__VA_ARGS__), ::perfetto::base::ErrStatus(__VA_ARGS__))
53196 
53197 namespace perfetto {
53198 
53199 #if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) && \
53200     PERFETTO_BUILDFLAG(PERFETTO_ANDROID_BUILD)
53201 // These are the only SELinux approved dir for trace files that are created
53202 // directly by traced.
53203 const char* kTraceDirBasePath = "/data/misc/perfetto-traces/";
53204 const char* kAndroidProductionBugreportTracePath =
53205     "/data/misc/perfetto-traces/bugreport/systrace.pftrace";
53206 #endif
53207 
53208 namespace {
53209 constexpr int kMaxBuffersPerConsumer = 128;
53210 constexpr uint32_t kDefaultSnapshotsIntervalMs = 10 * 1000;
53211 constexpr int kDefaultWriteIntoFilePeriodMs = 5000;
53212 constexpr int kMaxConcurrentTracingSessions = 15;
53213 constexpr int kMaxConcurrentTracingSessionsPerUid = 5;
53214 constexpr int kMaxConcurrentTracingSessionsForStatsdUid = 10;
53215 constexpr int64_t kMinSecondsBetweenTracesGuardrail = 5 * 60;
53216 
53217 constexpr uint32_t kMillisPerHour = 3600000;
53218 constexpr uint32_t kMillisPerDay = kMillisPerHour * 24;
53219 constexpr uint32_t kMaxTracingDurationMillis = 7 * 24 * kMillisPerHour;
53220 
53221 // These apply only if enable_extra_guardrails is true.
53222 constexpr uint32_t kGuardrailsMaxTracingBufferSizeKb = 128 * 1024;
53223 constexpr uint32_t kGuardrailsMaxTracingDurationMillis = 24 * kMillisPerHour;
53224 
53225 // TODO(primiano): this is to investigate b/191600928. Remove in Jan 2022.
53226 base::CrashKey g_crash_key_prod_name("producer_name");
53227 base::CrashKey g_crash_key_ds_count("ds_count");
53228 base::CrashKey g_crash_key_ds_clear_count("ds_clear_count");
53229 
53230 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) || PERFETTO_BUILDFLAG(PERFETTO_OS_NACL)
53231 struct iovec {
53232   void* iov_base;  // Address
53233   size_t iov_len;  // Block size
53234 };
53235 
53236 // Simple implementation of writev. Note that this does not give the atomicity
53237 // guarantees of a real writev, but we don't depend on these (we aren't writing
53238 // to the same file from another thread).
writev(int fd,const struct iovec * iov,int iovcnt)53239 ssize_t writev(int fd, const struct iovec* iov, int iovcnt) {
53240   ssize_t total_size = 0;
53241   for (int i = 0; i < iovcnt; ++i) {
53242     ssize_t current_size = base::WriteAll(fd, iov[i].iov_base, iov[i].iov_len);
53243     if (current_size != static_cast<ssize_t>(iov[i].iov_len))
53244       return -1;
53245     total_size += current_size;
53246   }
53247   return total_size;
53248 }
53249 
53250 #define IOV_MAX 1024  // Linux compatible limit.
53251 
53252 #endif  // PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) ||
53253         // PERFETTO_BUILDFLAG(PERFETTO_OS_NACL)
53254 
53255 // Partially encodes a CommitDataRequest in an int32 for the purposes of
53256 // metatracing. Note that it encodes only the bottom 10 bits of the producer id
53257 // (which is technically 16 bits wide).
53258 //
53259 // Format (by bit range):
53260 // [   31 ][         30 ][             29:20 ][            19:10 ][        9:0]
53261 // [unused][has flush id][num chunks to patch][num chunks to move][producer id]
EncodeCommitDataRequest(ProducerID producer_id,const CommitDataRequest & req_untrusted)53262 static int32_t EncodeCommitDataRequest(ProducerID producer_id,
53263                                        const CommitDataRequest& req_untrusted) {
53264   uint32_t cmov = static_cast<uint32_t>(req_untrusted.chunks_to_move_size());
53265   uint32_t cpatch = static_cast<uint32_t>(req_untrusted.chunks_to_patch_size());
53266   uint32_t has_flush_id = req_untrusted.flush_request_id() != 0;
53267 
53268   uint32_t mask = (1 << 10) - 1;
53269   uint32_t acc = 0;
53270   acc |= has_flush_id << 30;
53271   acc |= (cpatch & mask) << 20;
53272   acc |= (cmov & mask) << 10;
53273   acc |= (producer_id & mask);
53274   return static_cast<int32_t>(acc);
53275 }
53276 
SerializeAndAppendPacket(std::vector<TracePacket> * packets,std::vector<uint8_t> packet)53277 void SerializeAndAppendPacket(std::vector<TracePacket>* packets,
53278                               std::vector<uint8_t> packet) {
53279   Slice slice = Slice::Allocate(packet.size());
53280   memcpy(slice.own_data(), packet.data(), packet.size());
53281   packets->emplace_back();
53282   packets->back().AddSlice(std::move(slice));
53283 }
53284 
EnsureValidShmSizes(size_t shm_size,size_t page_size)53285 std::tuple<size_t /*shm_size*/, size_t /*page_size*/> EnsureValidShmSizes(
53286     size_t shm_size,
53287     size_t page_size) {
53288   // Theoretically the max page size supported by the ABI is 64KB.
53289   // However, the current implementation of TraceBuffer (the non-shared
53290   // userspace buffer where the service copies data) supports at most
53291   // 32K. Setting 64K "works" from the producer<>consumer viewpoint
53292   // but then causes the data to be discarded when copying it into
53293   // TraceBuffer.
53294   constexpr size_t kMaxPageSize = 32 * 1024;
53295   static_assert(kMaxPageSize <= SharedMemoryABI::kMaxPageSize, "");
53296 
53297   if (page_size == 0)
53298     page_size = TracingServiceImpl::kDefaultShmPageSize;
53299   if (shm_size == 0)
53300     shm_size = TracingServiceImpl::kDefaultShmSize;
53301 
53302   page_size = std::min<size_t>(page_size, kMaxPageSize);
53303   shm_size = std::min<size_t>(shm_size, TracingServiceImpl::kMaxShmSize);
53304 
53305   // The tracing page size has to be multiple of 4K. On some systems (e.g. Mac
53306   // on Arm64) the system page size can be larger (e.g., 16K). That doesn't
53307   // matter here, because the tracing page size is just a logical partitioning
53308   // and does not have any dependencies on kernel mm syscalls (read: it's fine
53309   // to have trace page sizes of 4K on a system where the kernel page size is
53310   // 16K).
53311   bool page_size_is_valid = page_size >= SharedMemoryABI::kMinPageSize;
53312   page_size_is_valid &= page_size % SharedMemoryABI::kMinPageSize == 0;
53313 
53314   // Only allow power of two numbers of pages, i.e. 1, 2, 4, 8 pages.
53315   size_t num_pages = page_size / SharedMemoryABI::kMinPageSize;
53316   page_size_is_valid &= (num_pages & (num_pages - 1)) == 0;
53317 
53318   if (!page_size_is_valid || shm_size < page_size ||
53319       shm_size % page_size != 0) {
53320     return std::make_tuple(TracingServiceImpl::kDefaultShmSize,
53321                            TracingServiceImpl::kDefaultShmPageSize);
53322   }
53323   return std::make_tuple(shm_size, page_size);
53324 }
53325 
NameMatchesFilter(const std::string & name,const std::vector<std::string> & name_filter,const std::vector<std::string> & name_regex_filter)53326 bool NameMatchesFilter(const std::string& name,
53327                        const std::vector<std::string>& name_filter,
53328                        const std::vector<std::string>& name_regex_filter) {
53329   bool filter_is_set = !name_filter.empty() || !name_regex_filter.empty();
53330   if (!filter_is_set)
53331     return true;
53332   bool filter_matches = std::find(name_filter.begin(), name_filter.end(),
53333                                   name) != name_filter.end();
53334   bool filter_regex_matches =
53335       std::find_if(name_regex_filter.begin(), name_regex_filter.end(),
53336                    [&](const std::string& regex) {
53337                      return std::regex_match(
53338                          name, std::regex(regex, std::regex::extended));
53339                    }) != name_regex_filter.end();
53340   return filter_matches || filter_regex_matches;
53341 }
53342 
53343 // Used when:
53344 // 1. TraceConfig.write_into_file == true and output_path is not empty.
53345 // 2. Calling SaveTraceForBugreport(), from perfetto --save-for-bugreport.
CreateTraceFile(const std::string & path,bool overwrite)53346 base::ScopedFile CreateTraceFile(const std::string& path, bool overwrite) {
53347 #if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) && \
53348     PERFETTO_BUILDFLAG(PERFETTO_ANDROID_BUILD)
53349   // This is NOT trying to preserve any security property, SELinux does that.
53350   // It just improves the actionability of the error when people try to save the
53351   // trace in a location that is not SELinux-allowed (a generic "permission
53352   // denied" vs "don't put it here, put it there").
53353   if (!base::StartsWith(path, kTraceDirBasePath)) {
53354     PERFETTO_ELOG("Invalid output_path %s. On Android it must be within %s.",
53355                   path.c_str(), kTraceDirBasePath);
53356     return base::ScopedFile();
53357   }
53358 #endif
53359   // O_CREAT | O_EXCL will fail if the file exists already.
53360   const int flags = O_RDWR | O_CREAT | (overwrite ? O_TRUNC : O_EXCL);
53361   auto fd = base::OpenFile(path, flags, 0600);
53362   if (fd) {
53363 #if defined(PERFETTO_HAS_CHMOD)
53364     // Passing 0644 directly above won't work because of umask.
53365     PERFETTO_CHECK(fchmod(*fd, 0644) == 0);
53366 #endif
53367   } else {
53368     PERFETTO_PLOG("Failed to create %s", path.c_str());
53369   }
53370   return fd;
53371 }
53372 
GetBugreportTmpPath()53373 std::string GetBugreportTmpPath() {
53374   return GetBugreportPath() + ".tmp";
53375 }
53376 
ShouldLogEvent(const TraceConfig & cfg)53377 bool ShouldLogEvent(const TraceConfig& cfg) {
53378   switch (cfg.statsd_logging()) {
53379     case TraceConfig::STATSD_LOGGING_ENABLED:
53380       return true;
53381     case TraceConfig::STATSD_LOGGING_DISABLED:
53382       return false;
53383     case TraceConfig::STATSD_LOGGING_UNSPECIFIED:
53384       // For backward compatibility with older versions of perfetto_cmd.
53385       return cfg.enable_extra_guardrails();
53386   }
53387   PERFETTO_FATAL("For GCC");
53388 }
53389 
53390 // Appends `data` (which has `size` bytes), to `*packet`. Splits the data in
53391 // slices no larger than `max_slice_size`.
AppendOwnedSlicesToPacket(std::unique_ptr<uint8_t[]> data,size_t size,size_t max_slice_size,perfetto::TracePacket * packet)53392 void AppendOwnedSlicesToPacket(std::unique_ptr<uint8_t[]> data,
53393                                size_t size,
53394                                size_t max_slice_size,
53395                                perfetto::TracePacket* packet) {
53396   if (size <= max_slice_size) {
53397     packet->AddSlice(Slice::TakeOwnership(std::move(data), size));
53398     return;
53399   }
53400   uint8_t* src_ptr = data.get();
53401   for (size_t size_left = size; size_left > 0;) {
53402     const size_t slice_size = std::min(size_left, max_slice_size);
53403 
53404     Slice slice = Slice::Allocate(slice_size);
53405     memcpy(slice.own_data(), src_ptr, slice_size);
53406     packet->AddSlice(std::move(slice));
53407 
53408     src_ptr += slice_size;
53409     size_left -= slice_size;
53410   }
53411 }
53412 
53413 }  // namespace
53414 
53415 // These constants instead are defined in the header because are used by tests.
53416 constexpr size_t TracingServiceImpl::kDefaultShmSize;
53417 constexpr size_t TracingServiceImpl::kDefaultShmPageSize;
53418 
53419 constexpr size_t TracingServiceImpl::kMaxShmSize;
53420 constexpr uint32_t TracingServiceImpl::kDataSourceStopTimeoutMs;
53421 constexpr uint8_t TracingServiceImpl::kSyncMarker[];
53422 
GetBugreportPath()53423 std::string GetBugreportPath() {
53424 #if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) && \
53425     PERFETTO_BUILDFLAG(PERFETTO_ANDROID_BUILD)
53426   return kAndroidProductionBugreportTracePath;
53427 #else
53428   // Only for tests, SaveTraceForBugreport is not used on other OSes.
53429   return base::GetSysTempDir() + "/bugreport.pftrace";
53430 #endif
53431 }
53432 
53433 // static
CreateInstance(std::unique_ptr<SharedMemory::Factory> shm_factory,base::TaskRunner * task_runner)53434 std::unique_ptr<TracingService> TracingService::CreateInstance(
53435     std::unique_ptr<SharedMemory::Factory> shm_factory,
53436     base::TaskRunner* task_runner) {
53437   return std::unique_ptr<TracingService>(
53438       new TracingServiceImpl(std::move(shm_factory), task_runner));
53439 }
53440 
TracingServiceImpl(std::unique_ptr<SharedMemory::Factory> shm_factory,base::TaskRunner * task_runner)53441 TracingServiceImpl::TracingServiceImpl(
53442     std::unique_ptr<SharedMemory::Factory> shm_factory,
53443     base::TaskRunner* task_runner)
53444     : task_runner_(task_runner),
53445       shm_factory_(std::move(shm_factory)),
53446       uid_(base::GetCurrentUserId()),
53447       buffer_ids_(kMaxTraceBufferID),
53448       trigger_probability_rand_(
53449           static_cast<uint32_t>(base::GetWallTimeNs().count())),
53450       weak_ptr_factory_(this) {
53451   PERFETTO_DCHECK(task_runner_);
53452 }
53453 
~TracingServiceImpl()53454 TracingServiceImpl::~TracingServiceImpl() {
53455   // TODO(fmayer): handle teardown of all Producer.
53456 }
53457 
53458 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)53459 TracingServiceImpl::ConnectProducer(Producer* producer,
53460                                     uid_t uid,
53461                                     const std::string& producer_name,
53462                                     size_t shared_memory_size_hint_bytes,
53463                                     bool in_process,
53464                                     ProducerSMBScrapingMode smb_scraping_mode,
53465                                     size_t shared_memory_page_size_hint_bytes,
53466                                     std::unique_ptr<SharedMemory> shm,
53467                                     const std::string& sdk_version) {
53468   PERFETTO_DCHECK_THREAD(thread_checker_);
53469 
53470   if (lockdown_mode_ && uid != base::GetCurrentUserId()) {
53471     PERFETTO_DLOG("Lockdown mode. Rejecting producer with UID %ld",
53472                   static_cast<unsigned long>(uid));
53473     return nullptr;
53474   }
53475 
53476   if (producers_.size() >= kMaxProducerID) {
53477     PERFETTO_DFATAL("Too many producers.");
53478     return nullptr;
53479   }
53480   const ProducerID id = GetNextProducerID();
53481   PERFETTO_DLOG("Producer %" PRIu16 " connected, uid=%d", id,
53482                 static_cast<int>(uid));
53483   bool smb_scraping_enabled = smb_scraping_enabled_;
53484   switch (smb_scraping_mode) {
53485     case ProducerSMBScrapingMode::kDefault:
53486       break;
53487     case ProducerSMBScrapingMode::kEnabled:
53488       smb_scraping_enabled = true;
53489       break;
53490     case ProducerSMBScrapingMode::kDisabled:
53491       smb_scraping_enabled = false;
53492       break;
53493   }
53494 
53495   std::unique_ptr<ProducerEndpointImpl> endpoint(new ProducerEndpointImpl(
53496       id, uid, this, task_runner_, producer, producer_name, sdk_version,
53497       in_process, smb_scraping_enabled));
53498   auto it_and_inserted = producers_.emplace(id, endpoint.get());
53499   PERFETTO_DCHECK(it_and_inserted.second);
53500   endpoint->shmem_size_hint_bytes_ = shared_memory_size_hint_bytes;
53501   endpoint->shmem_page_size_hint_bytes_ = shared_memory_page_size_hint_bytes;
53502 
53503   // Producer::OnConnect() should run before Producer::OnTracingSetup(). The
53504   // latter may be posted by SetupSharedMemory() below, so post OnConnect() now.
53505   auto weak_ptr = endpoint->weak_ptr_factory_.GetWeakPtr();
53506   task_runner_->PostTask([weak_ptr] {
53507     if (weak_ptr)
53508       weak_ptr->producer_->OnConnect();
53509   });
53510 
53511   if (shm) {
53512     // The producer supplied an SMB. This is used only by Chrome; in the most
53513     // common cases the SMB is created by the service and passed via
53514     // OnTracingSetup(). Verify that it is correctly sized before we attempt to
53515     // use it. The transport layer has to verify the integrity of the SMB (e.g.
53516     // ensure that the producer can't resize if after the fact).
53517     size_t shm_size, page_size;
53518     std::tie(shm_size, page_size) =
53519         EnsureValidShmSizes(shm->size(), endpoint->shmem_page_size_hint_bytes_);
53520     if (shm_size == shm->size() &&
53521         page_size == endpoint->shmem_page_size_hint_bytes_) {
53522       PERFETTO_DLOG(
53523           "Adopting producer-provided SMB of %zu kB for producer \"%s\"",
53524           shm_size / 1024, endpoint->name_.c_str());
53525       endpoint->SetupSharedMemory(std::move(shm), page_size,
53526                                   /*provided_by_producer=*/true);
53527     } else {
53528       PERFETTO_LOG(
53529           "Discarding incorrectly sized producer-provided SMB for producer "
53530           "\"%s\", falling back to service-provided SMB. Requested sizes: %zu "
53531           "B total, %zu B page size; suggested corrected sizes: %zu B total, "
53532           "%zu B page size",
53533           endpoint->name_.c_str(), shm->size(),
53534           endpoint->shmem_page_size_hint_bytes_, shm_size, page_size);
53535       shm.reset();
53536     }
53537   }
53538 
53539   return std::unique_ptr<ProducerEndpoint>(std::move(endpoint));
53540 }
53541 
DisconnectProducer(ProducerID id)53542 void TracingServiceImpl::DisconnectProducer(ProducerID id) {
53543   PERFETTO_DCHECK_THREAD(thread_checker_);
53544   PERFETTO_DLOG("Producer %" PRIu16 " disconnected", id);
53545   PERFETTO_DCHECK(producers_.count(id));
53546 
53547   // Scrape remaining chunks for this producer to ensure we don't lose data.
53548   if (auto* producer = GetProducer(id)) {
53549     for (auto& session_id_and_session : tracing_sessions_)
53550       ScrapeSharedMemoryBuffers(&session_id_and_session.second, producer);
53551   }
53552 
53553   for (auto it = data_sources_.begin(); it != data_sources_.end();) {
53554     auto next = it;
53555     next++;
53556     if (it->second.producer_id == id)
53557       UnregisterDataSource(id, it->second.descriptor.name());
53558     it = next;
53559   }
53560 
53561   producers_.erase(id);
53562   UpdateMemoryGuardrail();
53563 }
53564 
GetProducer(ProducerID id) const53565 TracingServiceImpl::ProducerEndpointImpl* TracingServiceImpl::GetProducer(
53566     ProducerID id) const {
53567   PERFETTO_DCHECK_THREAD(thread_checker_);
53568   auto it = producers_.find(id);
53569   if (it == producers_.end())
53570     return nullptr;
53571   return it->second;
53572 }
53573 
53574 std::unique_ptr<TracingService::ConsumerEndpoint>
ConnectConsumer(Consumer * consumer,uid_t uid)53575 TracingServiceImpl::ConnectConsumer(Consumer* consumer, uid_t uid) {
53576   PERFETTO_DCHECK_THREAD(thread_checker_);
53577   PERFETTO_DLOG("Consumer %p connected from UID %" PRIu64,
53578                 reinterpret_cast<void*>(consumer), static_cast<uint64_t>(uid));
53579   std::unique_ptr<ConsumerEndpointImpl> endpoint(
53580       new ConsumerEndpointImpl(this, task_runner_, consumer, uid));
53581   auto it_and_inserted = consumers_.emplace(endpoint.get());
53582   PERFETTO_DCHECK(it_and_inserted.second);
53583   // Consumer might go away before we're able to send the connect notification,
53584   // if that is the case just bail out.
53585   auto weak_ptr = endpoint->weak_ptr_factory_.GetWeakPtr();
53586   task_runner_->PostTask([weak_ptr] {
53587     if (weak_ptr)
53588       weak_ptr->consumer_->OnConnect();
53589   });
53590   return std::unique_ptr<ConsumerEndpoint>(std::move(endpoint));
53591 }
53592 
DisconnectConsumer(ConsumerEndpointImpl * consumer)53593 void TracingServiceImpl::DisconnectConsumer(ConsumerEndpointImpl* consumer) {
53594   PERFETTO_DCHECK_THREAD(thread_checker_);
53595   PERFETTO_DLOG("Consumer %p disconnected", reinterpret_cast<void*>(consumer));
53596   PERFETTO_DCHECK(consumers_.count(consumer));
53597 
53598   // TODO(primiano) : Check that this is safe (what happens if there are
53599   // ReadBuffers() calls posted in the meantime? They need to become noop).
53600   if (consumer->tracing_session_id_)
53601     FreeBuffers(consumer->tracing_session_id_);  // Will also DisableTracing().
53602   consumers_.erase(consumer);
53603 
53604   // At this point no more pointers to |consumer| should be around.
53605   PERFETTO_DCHECK(!std::any_of(
53606       tracing_sessions_.begin(), tracing_sessions_.end(),
53607       [consumer](const std::pair<const TracingSessionID, TracingSession>& kv) {
53608         return kv.second.consumer_maybe_null == consumer;
53609       }));
53610 }
53611 
DetachConsumer(ConsumerEndpointImpl * consumer,const std::string & key)53612 bool TracingServiceImpl::DetachConsumer(ConsumerEndpointImpl* consumer,
53613                                         const std::string& key) {
53614   PERFETTO_DCHECK_THREAD(thread_checker_);
53615   PERFETTO_DLOG("Consumer %p detached", reinterpret_cast<void*>(consumer));
53616   PERFETTO_DCHECK(consumers_.count(consumer));
53617 
53618   TracingSessionID tsid = consumer->tracing_session_id_;
53619   TracingSession* tracing_session;
53620   if (!tsid || !(tracing_session = GetTracingSession(tsid)))
53621     return false;
53622 
53623   if (GetDetachedSession(consumer->uid_, key)) {
53624     PERFETTO_ELOG("Another session has been detached with the same key \"%s\"",
53625                   key.c_str());
53626     return false;
53627   }
53628 
53629   PERFETTO_DCHECK(tracing_session->consumer_maybe_null == consumer);
53630   tracing_session->consumer_maybe_null = nullptr;
53631   tracing_session->detach_key = key;
53632   consumer->tracing_session_id_ = 0;
53633   return true;
53634 }
53635 
AttachConsumer(ConsumerEndpointImpl * consumer,const std::string & key)53636 bool TracingServiceImpl::AttachConsumer(ConsumerEndpointImpl* consumer,
53637                                         const std::string& key) {
53638   PERFETTO_DCHECK_THREAD(thread_checker_);
53639   PERFETTO_DLOG("Consumer %p attaching to session %s",
53640                 reinterpret_cast<void*>(consumer), key.c_str());
53641   PERFETTO_DCHECK(consumers_.count(consumer));
53642 
53643   if (consumer->tracing_session_id_) {
53644     PERFETTO_ELOG(
53645         "Cannot reattach consumer to session %s"
53646         " while it already attached tracing session ID %" PRIu64,
53647         key.c_str(), consumer->tracing_session_id_);
53648     return false;
53649   }
53650 
53651   auto* tracing_session = GetDetachedSession(consumer->uid_, key);
53652   if (!tracing_session) {
53653     PERFETTO_ELOG(
53654         "Failed to attach consumer, session '%s' not found for uid %d",
53655         key.c_str(), static_cast<int>(consumer->uid_));
53656     return false;
53657   }
53658 
53659   consumer->tracing_session_id_ = tracing_session->id;
53660   tracing_session->consumer_maybe_null = consumer;
53661   tracing_session->detach_key.clear();
53662   return true;
53663 }
53664 
EnableTracing(ConsumerEndpointImpl * consumer,const TraceConfig & cfg,base::ScopedFile fd)53665 base::Status TracingServiceImpl::EnableTracing(ConsumerEndpointImpl* consumer,
53666                                                const TraceConfig& cfg,
53667                                                base::ScopedFile fd) {
53668   PERFETTO_DCHECK_THREAD(thread_checker_);
53669   PERFETTO_DLOG("Enabling tracing for consumer %p",
53670                 reinterpret_cast<void*>(consumer));
53671   MaybeLogUploadEvent(cfg, PerfettoStatsdAtom::kTracedEnableTracing);
53672   if (cfg.lockdown_mode() == TraceConfig::LOCKDOWN_SET)
53673     lockdown_mode_ = true;
53674   if (cfg.lockdown_mode() == TraceConfig::LOCKDOWN_CLEAR)
53675     lockdown_mode_ = false;
53676 
53677   // Scope |tracing_session| to this block to prevent accidental use of a null
53678   // pointer later in this function.
53679   {
53680     TracingSession* tracing_session =
53681         GetTracingSession(consumer->tracing_session_id_);
53682     if (tracing_session) {
53683       MaybeLogUploadEvent(
53684           cfg, PerfettoStatsdAtom::kTracedEnableTracingExistingTraceSession);
53685       return PERFETTO_SVC_ERR(
53686           "A Consumer is trying to EnableTracing() but another tracing "
53687           "session is already active (forgot a call to FreeBuffers() ?)");
53688     }
53689   }
53690 
53691   const uint32_t max_duration_ms = cfg.enable_extra_guardrails()
53692                                        ? kGuardrailsMaxTracingDurationMillis
53693                                        : kMaxTracingDurationMillis;
53694   if (cfg.duration_ms() > max_duration_ms) {
53695     MaybeLogUploadEvent(cfg,
53696                         PerfettoStatsdAtom::kTracedEnableTracingTooLongTrace);
53697     return PERFETTO_SVC_ERR("Requested too long trace (%" PRIu32
53698                             "ms  > %" PRIu32 " ms)",
53699                             cfg.duration_ms(), max_duration_ms);
53700   }
53701 
53702   const bool has_trigger_config = cfg.trigger_config().trigger_mode() !=
53703                                   TraceConfig::TriggerConfig::UNSPECIFIED;
53704   if (has_trigger_config && (cfg.trigger_config().trigger_timeout_ms() == 0 ||
53705                              cfg.trigger_config().trigger_timeout_ms() >
53706                                  kGuardrailsMaxTracingDurationMillis)) {
53707     MaybeLogUploadEvent(
53708         cfg, PerfettoStatsdAtom::kTracedEnableTracingInvalidTriggerTimeout);
53709     return PERFETTO_SVC_ERR(
53710         "Traces with START_TRACING triggers must provide a positive "
53711         "trigger_timeout_ms < 7 days (received %" PRIu32 "ms)",
53712         cfg.trigger_config().trigger_timeout_ms());
53713   }
53714 
53715   if (has_trigger_config && cfg.duration_ms() != 0) {
53716     MaybeLogUploadEvent(
53717         cfg, PerfettoStatsdAtom::kTracedEnableTracingDurationWithTrigger);
53718     return PERFETTO_SVC_ERR(
53719         "duration_ms was set, this must not be set for traces with triggers.");
53720   }
53721 
53722   if (cfg.trigger_config().trigger_mode() ==
53723           TraceConfig::TriggerConfig::STOP_TRACING &&
53724       cfg.write_into_file()) {
53725     // We don't support this usecase because there are subtle assumptions which
53726     // break around TracingServiceEvents and windowed sorting (i.e. if we don't
53727     // drain the events in ReadBuffers because we are waiting for STOP_TRACING,
53728     // we can end up queueing up a lot of TracingServiceEvents and emitting them
53729     // wildy out of order breaking windowed sorting in trace processor).
53730     MaybeLogUploadEvent(
53731         cfg, PerfettoStatsdAtom::kTracedEnableTracingStopTracingWriteIntoFile);
53732     return PERFETTO_SVC_ERR(
53733         "Specifying trigger mode STOP_TRACING and write_into_file together is "
53734         "unsupported");
53735   }
53736 
53737   std::unordered_set<std::string> triggers;
53738   for (const auto& trigger : cfg.trigger_config().triggers()) {
53739     if (!triggers.insert(trigger.name()).second) {
53740       MaybeLogUploadEvent(
53741           cfg, PerfettoStatsdAtom::kTracedEnableTracingDuplicateTriggerName);
53742       return PERFETTO_SVC_ERR("Duplicate trigger name: %s",
53743                               trigger.name().c_str());
53744     }
53745   }
53746 
53747   if (cfg.enable_extra_guardrails()) {
53748     if (cfg.deferred_start()) {
53749       MaybeLogUploadEvent(
53750           cfg, PerfettoStatsdAtom::kTracedEnableTracingInvalidDeferredStart);
53751       return PERFETTO_SVC_ERR(
53752           "deferred_start=true is not supported in unsupervised traces");
53753     }
53754     uint64_t buf_size_sum = 0;
53755     for (const auto& buf : cfg.buffers()) {
53756       if (buf.size_kb() % 4 != 0) {
53757         MaybeLogUploadEvent(
53758             cfg, PerfettoStatsdAtom::kTracedEnableTracingInvalidBufferSize);
53759         return PERFETTO_SVC_ERR(
53760             "buffers.size_kb must be a multiple of 4, got %" PRIu32,
53761             buf.size_kb());
53762       }
53763       buf_size_sum += buf.size_kb();
53764     }
53765     if (buf_size_sum > kGuardrailsMaxTracingBufferSizeKb) {
53766       MaybeLogUploadEvent(
53767           cfg, PerfettoStatsdAtom::kTracedEnableTracingBufferSizeTooLarge);
53768       return PERFETTO_SVC_ERR("Requested too large trace buffer (%" PRIu64
53769                               "kB  > %" PRIu32 " kB)",
53770                               buf_size_sum, kGuardrailsMaxTracingBufferSizeKb);
53771     }
53772   }
53773 
53774   if (cfg.buffers_size() > kMaxBuffersPerConsumer) {
53775     MaybeLogUploadEvent(cfg,
53776                         PerfettoStatsdAtom::kTracedEnableTracingTooManyBuffers);
53777     return PERFETTO_SVC_ERR("Too many buffers configured (%d)",
53778                             cfg.buffers_size());
53779   }
53780   // Check that the config specifies all buffers for its data sources. This
53781   // is also checked in SetupDataSource, but it is simpler to return a proper
53782   // error to the consumer from here (and there will be less state to undo).
53783   for (const TraceConfig::DataSource& cfg_data_source : cfg.data_sources()) {
53784     size_t num_buffers = static_cast<size_t>(cfg.buffers_size());
53785     size_t target_buffer = cfg_data_source.config().target_buffer();
53786     if (target_buffer >= num_buffers) {
53787       MaybeLogUploadEvent(
53788           cfg, PerfettoStatsdAtom::kTracedEnableTracingOobTargetBuffer);
53789       return PERFETTO_SVC_ERR(
53790           "Data source \"%s\" specified an out of bounds target_buffer (%zu >= "
53791           "%zu)",
53792           cfg_data_source.config().name().c_str(), target_buffer, num_buffers);
53793     }
53794   }
53795 
53796   if (!cfg.unique_session_name().empty()) {
53797     const std::string& name = cfg.unique_session_name();
53798     for (auto& kv : tracing_sessions_) {
53799       if (kv.second.config.unique_session_name() == name) {
53800         MaybeLogUploadEvent(
53801             cfg, PerfettoStatsdAtom::kTracedEnableTracingDuplicateSessionName);
53802         static const char fmt[] =
53803             "A trace with this unique session name (%s) already exists";
53804         // This happens frequently, don't make it an "E"LOG.
53805         PERFETTO_LOG(fmt, name.c_str());
53806         return base::ErrStatus(fmt, name.c_str());
53807       }
53808     }
53809   }
53810 
53811   if (cfg.enable_extra_guardrails()) {
53812     // unique_session_name can be empty
53813     const std::string& name = cfg.unique_session_name();
53814     int64_t now_s = base::GetBootTimeS().count();
53815 
53816     // Remove any entries where the time limit has passed so this map doesn't
53817     // grow indefinitely:
53818     std::map<std::string, int64_t>& sessions = session_to_last_trace_s_;
53819     for (auto it = sessions.cbegin(); it != sessions.cend();) {
53820       if (now_s - it->second > kMinSecondsBetweenTracesGuardrail) {
53821         it = sessions.erase(it);
53822       } else {
53823         ++it;
53824       }
53825     }
53826 
53827     int64_t& previous_s = session_to_last_trace_s_[name];
53828     if (previous_s == 0) {
53829       previous_s = now_s;
53830     } else {
53831       MaybeLogUploadEvent(
53832           cfg, PerfettoStatsdAtom::kTracedEnableTracingSessionNameTooRecent);
53833       return PERFETTO_SVC_ERR(
53834           "A trace with unique session name \"%s\" began less than %" PRId64
53835           "s ago (%" PRId64 "s)",
53836           name.c_str(), kMinSecondsBetweenTracesGuardrail, now_s - previous_s);
53837     }
53838   }
53839 
53840   const int sessions_for_uid = static_cast<int>(std::count_if(
53841       tracing_sessions_.begin(), tracing_sessions_.end(),
53842       [consumer](const decltype(tracing_sessions_)::value_type& s) {
53843         return s.second.consumer_uid == consumer->uid_;
53844       }));
53845 
53846   int per_uid_limit = kMaxConcurrentTracingSessionsPerUid;
53847   if (consumer->uid_ == 1066 /* AID_STATSD*/) {
53848     per_uid_limit = kMaxConcurrentTracingSessionsForStatsdUid;
53849   }
53850   if (sessions_for_uid >= per_uid_limit) {
53851     MaybeLogUploadEvent(
53852         cfg, PerfettoStatsdAtom::kTracedEnableTracingTooManySessionsForUid);
53853     return PERFETTO_SVC_ERR(
53854         "Too many concurrent tracing sesions (%d) for uid %d limit is %d",
53855         sessions_for_uid, static_cast<int>(consumer->uid_), per_uid_limit);
53856   }
53857 
53858   // TODO(primiano): This is a workaround to prevent that a producer gets stuck
53859   // in a state where it stalls by design by having more TraceWriterImpl
53860   // instances than free pages in the buffer. This is really a bug in
53861   // trace_probes and the way it handles stalls in the shmem buffer.
53862   if (tracing_sessions_.size() >= kMaxConcurrentTracingSessions) {
53863     MaybeLogUploadEvent(
53864         cfg, PerfettoStatsdAtom::kTracedEnableTracingTooManyConcurrentSessions);
53865     return PERFETTO_SVC_ERR("Too many concurrent tracing sesions (%zu)",
53866                             tracing_sessions_.size());
53867   }
53868 
53869   // If the trace config provides a filter bytecode, setup the filter now.
53870   // If the filter loading fails, abort the tracing session rather than running
53871   // unfiltered.
53872   std::unique_ptr<protozero::MessageFilter> trace_filter;
53873   if (cfg.has_trace_filter()) {
53874     const auto& filt = cfg.trace_filter();
53875     const std::string& bytecode = filt.bytecode();
53876     trace_filter.reset(new protozero::MessageFilter());
53877     if (!trace_filter->LoadFilterBytecode(bytecode.data(), bytecode.size())) {
53878       MaybeLogUploadEvent(
53879           cfg, PerfettoStatsdAtom::kTracedEnableTracingInvalidFilter);
53880       return PERFETTO_SVC_ERR("Trace filter bytecode invalid, aborting");
53881     }
53882     // The filter is created using perfetto.protos.Trace as root message
53883     // (because that makes it possible to play around with the `proto_filter`
53884     // tool on actual traces). Here in the service, however, we deal with
53885     // perfetto.protos.TracePacket(s), which are one level down (Trace.packet).
53886     // The IPC client (or the write_into_filte logic in here) are responsible
53887     // for pre-pending the packet preamble (See GetProtoPreamble() calls), but
53888     // the preamble is not there at ReadBuffer time. Hence we change the root of
53889     // the filtering to start at the Trace.packet level.
53890     uint32_t packet_field_id = TracePacket::kPacketFieldNumber;
53891     if (!trace_filter->SetFilterRoot(&packet_field_id, 1)) {
53892       MaybeLogUploadEvent(
53893           cfg, PerfettoStatsdAtom::kTracedEnableTracingInvalidFilter);
53894       return PERFETTO_SVC_ERR("Failed to set filter root.");
53895     }
53896   }
53897 
53898   const TracingSessionID tsid = ++last_tracing_session_id_;
53899   TracingSession* tracing_session =
53900       &tracing_sessions_
53901            .emplace(std::piecewise_construct, std::forward_as_tuple(tsid),
53902                     std::forward_as_tuple(tsid, consumer, cfg, task_runner_))
53903            .first->second;
53904 
53905   if (trace_filter)
53906     tracing_session->trace_filter = std::move(trace_filter);
53907 
53908   if (cfg.write_into_file()) {
53909     if (!fd ^ !cfg.output_path().empty()) {
53910       tracing_sessions_.erase(tsid);
53911       MaybeLogUploadEvent(
53912           tracing_session->config,
53913           PerfettoStatsdAtom::kTracedEnableTracingInvalidFdOutputFile);
53914       return PERFETTO_SVC_ERR(
53915           "When write_into_file==true either a FD needs to be passed or "
53916           "output_path must be populated (but not both)");
53917     }
53918     if (!cfg.output_path().empty()) {
53919       fd = CreateTraceFile(cfg.output_path(), /*overwrite=*/false);
53920       if (!fd) {
53921         MaybeLogUploadEvent(
53922             tracing_session->config,
53923             PerfettoStatsdAtom::kTracedEnableTracingFailedToCreateFile);
53924         tracing_sessions_.erase(tsid);
53925         return PERFETTO_SVC_ERR("Failed to create the trace file %s",
53926                                 cfg.output_path().c_str());
53927       }
53928     }
53929     tracing_session->write_into_file = std::move(fd);
53930     uint32_t write_period_ms = cfg.file_write_period_ms();
53931     if (write_period_ms == 0)
53932       write_period_ms = kDefaultWriteIntoFilePeriodMs;
53933     if (write_period_ms < min_write_period_ms_)
53934       write_period_ms = min_write_period_ms_;
53935     tracing_session->write_period_ms = write_period_ms;
53936     tracing_session->max_file_size_bytes = cfg.max_file_size_bytes();
53937     tracing_session->bytes_written_into_file = 0;
53938   }
53939 
53940   // Initialize the log buffers.
53941   bool did_allocate_all_buffers = true;
53942 
53943   // Allocate the trace buffers. Also create a map to translate a consumer
53944   // relative index (TraceConfig.DataSourceConfig.target_buffer) into the
53945   // corresponding BufferID, which is a global ID namespace for the service and
53946   // all producers.
53947   size_t total_buf_size_kb = 0;
53948   const size_t num_buffers = static_cast<size_t>(cfg.buffers_size());
53949   tracing_session->buffers_index.reserve(num_buffers);
53950   for (size_t i = 0; i < num_buffers; i++) {
53951     const TraceConfig::BufferConfig& buffer_cfg = cfg.buffers()[i];
53952     BufferID global_id = buffer_ids_.Allocate();
53953     if (!global_id) {
53954       did_allocate_all_buffers = false;  // We ran out of IDs.
53955       break;
53956     }
53957     tracing_session->buffers_index.push_back(global_id);
53958     const size_t buf_size_bytes = buffer_cfg.size_kb() * 1024u;
53959     total_buf_size_kb += buffer_cfg.size_kb();
53960     TraceBuffer::OverwritePolicy policy =
53961         buffer_cfg.fill_policy() == TraceConfig::BufferConfig::DISCARD
53962             ? TraceBuffer::kDiscard
53963             : TraceBuffer::kOverwrite;
53964     auto it_and_inserted = buffers_.emplace(
53965         global_id, TraceBuffer::Create(buf_size_bytes, policy));
53966     PERFETTO_DCHECK(it_and_inserted.second);  // buffers_.count(global_id) == 0.
53967     std::unique_ptr<TraceBuffer>& trace_buffer = it_and_inserted.first->second;
53968     if (!trace_buffer) {
53969       did_allocate_all_buffers = false;
53970       break;
53971     }
53972   }
53973 
53974   UpdateMemoryGuardrail();
53975 
53976   // This can happen if either:
53977   // - All the kMaxTraceBufferID slots are taken.
53978   // - OOM, or, more relistically, we exhausted virtual memory.
53979   // In any case, free all the previously allocated buffers and abort.
53980   // TODO(fmayer): add a test to cover this case, this is quite subtle.
53981   if (!did_allocate_all_buffers) {
53982     for (BufferID global_id : tracing_session->buffers_index) {
53983       buffer_ids_.Free(global_id);
53984       buffers_.erase(global_id);
53985     }
53986     tracing_sessions_.erase(tsid);
53987     MaybeLogUploadEvent(tracing_session->config,
53988                         PerfettoStatsdAtom::kTracedEnableTracingOom);
53989     return PERFETTO_SVC_ERR(
53990         "Failed to allocate tracing buffers: OOM or too many buffers");
53991   }
53992 
53993   consumer->tracing_session_id_ = tsid;
53994 
53995   // Setup the data sources on the producers without starting them.
53996   for (const TraceConfig::DataSource& cfg_data_source : cfg.data_sources()) {
53997     // Scan all the registered data sources with a matching name.
53998     auto range = data_sources_.equal_range(cfg_data_source.config().name());
53999     for (auto it = range.first; it != range.second; it++) {
54000       TraceConfig::ProducerConfig producer_config;
54001       for (auto& config : cfg.producers()) {
54002         if (GetProducer(it->second.producer_id)->name_ ==
54003             config.producer_name()) {
54004           producer_config = config;
54005           break;
54006         }
54007       }
54008       SetupDataSource(cfg_data_source, producer_config, it->second,
54009                       tracing_session);
54010     }
54011   }
54012 
54013   bool has_start_trigger = false;
54014   auto weak_this = weak_ptr_factory_.GetWeakPtr();
54015   switch (cfg.trigger_config().trigger_mode()) {
54016     case TraceConfig::TriggerConfig::UNSPECIFIED:
54017       // no triggers are specified so this isn't a trace that is using triggers.
54018       PERFETTO_DCHECK(!has_trigger_config);
54019       break;
54020     case TraceConfig::TriggerConfig::START_TRACING:
54021       // For traces which use START_TRACE triggers we need to ensure that the
54022       // tracing session will be cleaned up when it times out.
54023       has_start_trigger = true;
54024       task_runner_->PostDelayedTask(
54025           [weak_this, tsid]() {
54026             if (weak_this)
54027               weak_this->OnStartTriggersTimeout(tsid);
54028           },
54029           cfg.trigger_config().trigger_timeout_ms());
54030       break;
54031     case TraceConfig::TriggerConfig::STOP_TRACING:
54032       // Update the tracing_session's duration_ms to ensure that if no trigger
54033       // is received the session will end and be cleaned up equal to the
54034       // timeout.
54035       //
54036       // TODO(nuskos): Refactor this so that rather then modifying the config we
54037       // have a field we look at on the tracing_session.
54038       tracing_session->config.set_duration_ms(
54039           cfg.trigger_config().trigger_timeout_ms());
54040       break;
54041   }
54042 
54043   tracing_session->state = TracingSession::CONFIGURED;
54044   PERFETTO_LOG(
54045       "Configured tracing session %" PRIu64
54046       ", #sources:%zu, duration:%d ms, #buffers:%d, total "
54047       "buffer size:%zu KB, total sessions:%zu, uid:%d session name: \"%s\"",
54048       tsid, cfg.data_sources().size(), tracing_session->config.duration_ms(),
54049       cfg.buffers_size(), total_buf_size_kb, tracing_sessions_.size(),
54050       static_cast<unsigned int>(consumer->uid_),
54051       cfg.unique_session_name().c_str());
54052 
54053   // Start the data sources, unless this is a case of early setup + fast
54054   // triggering, either through TraceConfig.deferred_start or
54055   // TraceConfig.trigger_config(). If both are specified which ever one occurs
54056   // first will initiate the trace.
54057   if (!cfg.deferred_start() && !has_start_trigger)
54058     return StartTracing(tsid);
54059 
54060   return base::OkStatus();
54061 }
54062 
ChangeTraceConfig(ConsumerEndpointImpl * consumer,const TraceConfig & updated_cfg)54063 void TracingServiceImpl::ChangeTraceConfig(ConsumerEndpointImpl* consumer,
54064                                            const TraceConfig& updated_cfg) {
54065   PERFETTO_DCHECK_THREAD(thread_checker_);
54066   TracingSession* tracing_session =
54067       GetTracingSession(consumer->tracing_session_id_);
54068   PERFETTO_DCHECK(tracing_session);
54069 
54070   if ((tracing_session->state != TracingSession::STARTED) &&
54071       (tracing_session->state != TracingSession::CONFIGURED)) {
54072     PERFETTO_ELOG(
54073         "ChangeTraceConfig() was called for a tracing session which isn't "
54074         "running.");
54075     return;
54076   }
54077 
54078   // We only support updating producer_name_{,regex}_filter (and pass-through
54079   // configs) for now; null out any changeable fields and make sure the rest are
54080   // identical.
54081   TraceConfig new_config_copy(updated_cfg);
54082   for (auto& ds_cfg : *new_config_copy.mutable_data_sources()) {
54083     ds_cfg.clear_producer_name_filter();
54084     ds_cfg.clear_producer_name_regex_filter();
54085   }
54086 
54087   TraceConfig current_config_copy(tracing_session->config);
54088   for (auto& ds_cfg : *current_config_copy.mutable_data_sources()) {
54089     ds_cfg.clear_producer_name_filter();
54090     ds_cfg.clear_producer_name_regex_filter();
54091   }
54092 
54093   if (new_config_copy != current_config_copy) {
54094     PERFETTO_LOG(
54095         "ChangeTraceConfig() was called with a config containing unsupported "
54096         "changes; only adding to the producer_name_{,regex}_filter is "
54097         "currently supported and will have an effect.");
54098   }
54099 
54100   for (TraceConfig::DataSource& cfg_data_source :
54101        *tracing_session->config.mutable_data_sources()) {
54102     // Find the updated producer_filter in the new config.
54103     std::vector<std::string> new_producer_name_filter;
54104     std::vector<std::string> new_producer_name_regex_filter;
54105     bool found_data_source = false;
54106     for (const auto& it : updated_cfg.data_sources()) {
54107       if (cfg_data_source.config().name() == it.config().name()) {
54108         new_producer_name_filter = it.producer_name_filter();
54109         new_producer_name_regex_filter = it.producer_name_regex_filter();
54110         found_data_source = true;
54111         break;
54112       }
54113     }
54114 
54115     // Bail out if data source not present in the new config.
54116     if (!found_data_source) {
54117       PERFETTO_ELOG(
54118           "ChangeTraceConfig() called without a current data source also "
54119           "present in the new config: %s",
54120           cfg_data_source.config().name().c_str());
54121       continue;
54122     }
54123 
54124     // TODO(oysteine): Just replacing the filter means that if
54125     // there are any filter entries which were present in the original config,
54126     // but removed from the config passed to ChangeTraceConfig, any matching
54127     // producers will keep producing but newly added producers after this
54128     // point will never start.
54129     *cfg_data_source.mutable_producer_name_filter() = new_producer_name_filter;
54130     *cfg_data_source.mutable_producer_name_regex_filter() =
54131         new_producer_name_regex_filter;
54132 
54133     // Scan all the registered data sources with a matching name.
54134     auto range = data_sources_.equal_range(cfg_data_source.config().name());
54135     for (auto it = range.first; it != range.second; it++) {
54136       ProducerEndpointImpl* producer = GetProducer(it->second.producer_id);
54137       PERFETTO_DCHECK(producer);
54138 
54139       // Check if the producer name of this data source is present
54140       // in the name filters. We currently only support new filters, not
54141       // removing old ones.
54142       if (!NameMatchesFilter(producer->name_, new_producer_name_filter,
54143                              new_producer_name_regex_filter)) {
54144         continue;
54145       }
54146 
54147       bool already_setup = false;
54148       auto& ds_instances = tracing_session->data_source_instances;
54149       for (auto instance_it = ds_instances.begin();
54150            instance_it != ds_instances.end(); ++instance_it) {
54151         if (instance_it->first == it->second.producer_id &&
54152             instance_it->second.data_source_name ==
54153                 cfg_data_source.config().name()) {
54154           already_setup = true;
54155           break;
54156         }
54157       }
54158 
54159       if (already_setup)
54160         continue;
54161 
54162       // If it wasn't previously setup, set it up now.
54163       // (The per-producer config is optional).
54164       TraceConfig::ProducerConfig producer_config;
54165       for (auto& config : tracing_session->config.producers()) {
54166         if (producer->name_ == config.producer_name()) {
54167           producer_config = config;
54168           break;
54169         }
54170       }
54171 
54172       DataSourceInstance* ds_inst = SetupDataSource(
54173           cfg_data_source, producer_config, it->second, tracing_session);
54174 
54175       if (ds_inst && tracing_session->state == TracingSession::STARTED)
54176         StartDataSourceInstance(producer, tracing_session, ds_inst);
54177     }
54178   }
54179 }
54180 
StartTracing(TracingSessionID tsid)54181 base::Status TracingServiceImpl::StartTracing(TracingSessionID tsid) {
54182   PERFETTO_DCHECK_THREAD(thread_checker_);
54183 
54184   auto weak_this = weak_ptr_factory_.GetWeakPtr();
54185   TracingSession* tracing_session = GetTracingSession(tsid);
54186   if (!tracing_session) {
54187     return PERFETTO_SVC_ERR(
54188         "StartTracing() failed, invalid session ID %" PRIu64, tsid);
54189   }
54190 
54191   MaybeLogUploadEvent(tracing_session->config,
54192                       PerfettoStatsdAtom::kTracedStartTracing);
54193 
54194   if (tracing_session->state != TracingSession::CONFIGURED) {
54195     MaybeLogUploadEvent(
54196         tracing_session->config,
54197         PerfettoStatsdAtom::kTracedStartTracingInvalidSessionState);
54198     return PERFETTO_SVC_ERR("StartTracing() failed, invalid session state: %d",
54199                             tracing_session->state);
54200   }
54201 
54202   tracing_session->state = TracingSession::STARTED;
54203 
54204   // We store the start of trace snapshot separately as it's important to make
54205   // sure we can interpret all the data in the trace and storing it in the ring
54206   // buffer means it could be overwritten by a later snapshot.
54207   if (!tracing_session->config.builtin_data_sources()
54208            .disable_clock_snapshotting()) {
54209     SnapshotClocks(&tracing_session->initial_clock_snapshot);
54210   }
54211 
54212   // We don't snapshot the clocks here because we just did this above.
54213   SnapshotLifecyleEvent(
54214       tracing_session,
54215       protos::pbzero::TracingServiceEvent::kTracingStartedFieldNumber,
54216       false /* snapshot_clocks */);
54217 
54218   // Periodically snapshot clocks, stats, sync markers while the trace is
54219   // active. The snapshots are emitted on the future ReadBuffers() calls, which
54220   // means that:
54221   //  (a) If we're streaming to a file (or to a consumer) while tracing, we
54222   //      write snapshots periodically into the trace.
54223   //  (b) If ReadBuffers() is only called after tracing ends, we emit the latest
54224   //      snapshot into the trace. For clock snapshots, we keep track of the
54225   //      snapshot recorded at the beginning of the session
54226   //      (initial_clock_snapshot above), as well as the most recent sampled
54227   //      snapshots that showed significant new drift between different clocks.
54228   //      The latter clock snapshots are sampled periodically and at lifecycle
54229   //      events.
54230   base::PeriodicTask::Args snapshot_task_args;
54231   snapshot_task_args.start_first_task_immediately = true;
54232   snapshot_task_args.use_suspend_aware_timer =
54233       tracing_session->config.builtin_data_sources()
54234           .prefer_suspend_clock_for_snapshot();
54235   snapshot_task_args.task = [weak_this, tsid] {
54236     if (weak_this)
54237       weak_this->PeriodicSnapshotTask(tsid);
54238   };
54239   snapshot_task_args.period_ms =
54240       tracing_session->config.builtin_data_sources().snapshot_interval_ms();
54241   if (!snapshot_task_args.period_ms)
54242     snapshot_task_args.period_ms = kDefaultSnapshotsIntervalMs;
54243   tracing_session->snapshot_periodic_task.Start(snapshot_task_args);
54244 
54245   // Trigger delayed task if the trace is time limited.
54246   const uint32_t trace_duration_ms = tracing_session->config.duration_ms();
54247   if (trace_duration_ms > 0) {
54248     task_runner_->PostDelayedTask(
54249         [weak_this, tsid] {
54250           // Skip entirely the flush if the trace session doesn't exist anymore.
54251           // This is to prevent misleading error messages to be logged.
54252           if (!weak_this)
54253             return;
54254           auto* tracing_session_ptr = weak_this->GetTracingSession(tsid);
54255           if (!tracing_session_ptr)
54256             return;
54257           // If this trace was using STOP_TRACING triggers and we've seen
54258           // one, then the trigger overrides the normal timeout. In this
54259           // case we just return and let the other task clean up this trace.
54260           if (tracing_session_ptr->config.trigger_config().trigger_mode() ==
54261                   TraceConfig::TriggerConfig::STOP_TRACING &&
54262               !tracing_session_ptr->received_triggers.empty())
54263             return;
54264           // In all other cases (START_TRACING or no triggers) we flush
54265           // after |trace_duration_ms| unconditionally.
54266           weak_this->FlushAndDisableTracing(tsid);
54267         },
54268         trace_duration_ms);
54269   }
54270 
54271   // Start the periodic drain tasks if we should to save the trace into a file.
54272   if (tracing_session->config.write_into_file()) {
54273     task_runner_->PostDelayedTask(
54274         [weak_this, tsid] {
54275           if (weak_this)
54276             weak_this->ReadBuffersIntoFile(tsid);
54277         },
54278         tracing_session->delay_to_next_write_period_ms());
54279   }
54280 
54281   // Start the periodic flush tasks if the config specified a flush period.
54282   if (tracing_session->config.flush_period_ms())
54283     PeriodicFlushTask(tsid, /*post_next_only=*/true);
54284 
54285   // Start the periodic incremental state clear tasks if the config specified a
54286   // period.
54287   if (tracing_session->config.incremental_state_config().clear_period_ms()) {
54288     PeriodicClearIncrementalStateTask(tsid, /*post_next_only=*/true);
54289   }
54290 
54291   for (auto& kv : tracing_session->data_source_instances) {
54292     ProducerID producer_id = kv.first;
54293     DataSourceInstance& data_source = kv.second;
54294     ProducerEndpointImpl* producer = GetProducer(producer_id);
54295     if (!producer) {
54296       PERFETTO_DFATAL("Producer does not exist.");
54297       continue;
54298     }
54299     StartDataSourceInstance(producer, tracing_session, &data_source);
54300   }
54301 
54302   MaybeNotifyAllDataSourcesStarted(tracing_session);
54303   return base::OkStatus();
54304 }
54305 
StartDataSourceInstance(ProducerEndpointImpl * producer,TracingSession * tracing_session,TracingServiceImpl::DataSourceInstance * instance)54306 void TracingServiceImpl::StartDataSourceInstance(
54307     ProducerEndpointImpl* producer,
54308     TracingSession* tracing_session,
54309     TracingServiceImpl::DataSourceInstance* instance) {
54310   PERFETTO_DCHECK(instance->state == DataSourceInstance::CONFIGURED);
54311   if (instance->will_notify_on_start) {
54312     instance->state = DataSourceInstance::STARTING;
54313   } else {
54314     instance->state = DataSourceInstance::STARTED;
54315   }
54316   if (tracing_session->consumer_maybe_null) {
54317     tracing_session->consumer_maybe_null->OnDataSourceInstanceStateChange(
54318         *producer, *instance);
54319   }
54320   producer->StartDataSource(instance->instance_id, instance->config);
54321 
54322   // If all data sources are started, notify the consumer.
54323   if (instance->state == DataSourceInstance::STARTED)
54324     MaybeNotifyAllDataSourcesStarted(tracing_session);
54325 }
54326 
54327 // DisableTracing just stops the data sources but doesn't free up any buffer.
54328 // This is to allow the consumer to freeze the buffers (by stopping the trace)
54329 // and then drain the buffers. The actual teardown of the TracingSession happens
54330 // in FreeBuffers().
DisableTracing(TracingSessionID tsid,bool disable_immediately)54331 void TracingServiceImpl::DisableTracing(TracingSessionID tsid,
54332                                         bool disable_immediately) {
54333   PERFETTO_DCHECK_THREAD(thread_checker_);
54334   TracingSession* tracing_session = GetTracingSession(tsid);
54335   if (!tracing_session) {
54336     // Can happen if the consumer calls this before EnableTracing() or after
54337     // FreeBuffers().
54338     PERFETTO_DLOG("DisableTracing() failed, invalid session ID %" PRIu64, tsid);
54339     return;
54340   }
54341 
54342   MaybeLogUploadEvent(tracing_session->config,
54343                       PerfettoStatsdAtom::kTracedDisableTracing);
54344 
54345   switch (tracing_session->state) {
54346     // Spurious call to DisableTracing() while already disabled, nothing to do.
54347     case TracingSession::DISABLED:
54348       PERFETTO_DCHECK(tracing_session->AllDataSourceInstancesStopped());
54349       return;
54350 
54351     // This is either:
54352     // A) The case of a graceful DisableTracing() call followed by a call to
54353     //    FreeBuffers(), iff |disable_immediately| == true. In this case we want
54354     //    to forcefully transition in the disabled state without waiting for the
54355     //    outstanding acks because the buffers are going to be destroyed soon.
54356     // B) A spurious call, iff |disable_immediately| == false, in which case
54357     //    there is nothing to do.
54358     case TracingSession::DISABLING_WAITING_STOP_ACKS:
54359       PERFETTO_DCHECK(!tracing_session->AllDataSourceInstancesStopped());
54360       if (disable_immediately)
54361         DisableTracingNotifyConsumerAndFlushFile(tracing_session);
54362       return;
54363 
54364     // Continues below.
54365     case TracingSession::CONFIGURED:
54366       // If the session didn't even start there is no need to orchestrate a
54367       // graceful stop of data sources.
54368       disable_immediately = true;
54369       break;
54370 
54371     // This is the nominal case, continues below.
54372     case TracingSession::STARTED:
54373       break;
54374   }
54375 
54376   for (auto& data_source_inst : tracing_session->data_source_instances) {
54377     const ProducerID producer_id = data_source_inst.first;
54378     DataSourceInstance& instance = data_source_inst.second;
54379     ProducerEndpointImpl* producer = GetProducer(producer_id);
54380     PERFETTO_DCHECK(producer);
54381     PERFETTO_DCHECK(instance.state == DataSourceInstance::CONFIGURED ||
54382                     instance.state == DataSourceInstance::STARTING ||
54383                     instance.state == DataSourceInstance::STARTED);
54384     StopDataSourceInstance(producer, tracing_session, &instance,
54385                            disable_immediately);
54386   }
54387 
54388   // If the periodic task is running, we can stop the periodic snapshot timer
54389   // here instead of waiting until FreeBuffers to prevent useless snapshots
54390   // which won't be read.
54391   tracing_session->snapshot_periodic_task.Reset();
54392 
54393   // Either this request is flagged with |disable_immediately| or there are no
54394   // data sources that are requesting a final handshake. In both cases just mark
54395   // the session as disabled immediately, notify the consumer and flush the
54396   // trace file (if used).
54397   if (tracing_session->AllDataSourceInstancesStopped())
54398     return DisableTracingNotifyConsumerAndFlushFile(tracing_session);
54399 
54400   tracing_session->state = TracingSession::DISABLING_WAITING_STOP_ACKS;
54401   auto weak_this = weak_ptr_factory_.GetWeakPtr();
54402   task_runner_->PostDelayedTask(
54403       [weak_this, tsid] {
54404         if (weak_this)
54405           weak_this->OnDisableTracingTimeout(tsid);
54406       },
54407       tracing_session->data_source_stop_timeout_ms());
54408 
54409   // Deliberately NOT removing the session from |tracing_session_|, it's still
54410   // needed to call ReadBuffers(). FreeBuffers() will erase() the session.
54411 }
54412 
NotifyDataSourceStarted(ProducerID producer_id,DataSourceInstanceID instance_id)54413 void TracingServiceImpl::NotifyDataSourceStarted(
54414     ProducerID producer_id,
54415     DataSourceInstanceID instance_id) {
54416   PERFETTO_DCHECK_THREAD(thread_checker_);
54417   for (auto& kv : tracing_sessions_) {
54418     TracingSession& tracing_session = kv.second;
54419     DataSourceInstance* instance =
54420         tracing_session.GetDataSourceInstance(producer_id, instance_id);
54421 
54422     if (!instance)
54423       continue;
54424 
54425     // If the tracing session was already stopped, ignore this notification.
54426     if (tracing_session.state != TracingSession::STARTED)
54427       continue;
54428 
54429     if (instance->state != DataSourceInstance::STARTING) {
54430       PERFETTO_ELOG("Started data source instance in incorrect state: %d",
54431                     instance->state);
54432       continue;
54433     }
54434 
54435     instance->state = DataSourceInstance::STARTED;
54436 
54437     ProducerEndpointImpl* producer = GetProducer(producer_id);
54438     PERFETTO_DCHECK(producer);
54439     if (tracing_session.consumer_maybe_null) {
54440       tracing_session.consumer_maybe_null->OnDataSourceInstanceStateChange(
54441           *producer, *instance);
54442     }
54443 
54444     // If all data sources are started, notify the consumer.
54445     MaybeNotifyAllDataSourcesStarted(&tracing_session);
54446   }  // for (tracing_session)
54447 }
54448 
MaybeNotifyAllDataSourcesStarted(TracingSession * tracing_session)54449 void TracingServiceImpl::MaybeNotifyAllDataSourcesStarted(
54450     TracingSession* tracing_session) {
54451   if (!tracing_session->consumer_maybe_null)
54452     return;
54453 
54454   if (!tracing_session->AllDataSourceInstancesStarted())
54455     return;
54456 
54457   // In some rare cases, we can get in this state more than once. Consider the
54458   // following scenario: 3 data sources are registered -> trace starts ->
54459   // all 3 data sources ack -> OnAllDataSourcesStarted() is called.
54460   // Imagine now that a 4th data source registers while the trace is ongoing.
54461   // This would hit the AllDataSourceInstancesStarted() condition again.
54462   // In this case, however, we don't want to re-notify the consumer again.
54463   // That would be unexpected (even if, perhaps, technically correct) and
54464   // trigger bugs in the consumer.
54465   if (tracing_session->did_notify_all_data_source_started)
54466     return;
54467 
54468   PERFETTO_DLOG("All data sources started");
54469 
54470   SnapshotLifecyleEvent(
54471       tracing_session,
54472       protos::pbzero::TracingServiceEvent::kAllDataSourcesStartedFieldNumber,
54473       true /* snapshot_clocks */);
54474 
54475   tracing_session->did_notify_all_data_source_started = true;
54476   tracing_session->consumer_maybe_null->OnAllDataSourcesStarted();
54477 }
54478 
NotifyDataSourceStopped(ProducerID producer_id,DataSourceInstanceID instance_id)54479 void TracingServiceImpl::NotifyDataSourceStopped(
54480     ProducerID producer_id,
54481     DataSourceInstanceID instance_id) {
54482   PERFETTO_DCHECK_THREAD(thread_checker_);
54483   for (auto& kv : tracing_sessions_) {
54484     TracingSession& tracing_session = kv.second;
54485     DataSourceInstance* instance =
54486         tracing_session.GetDataSourceInstance(producer_id, instance_id);
54487 
54488     if (!instance)
54489       continue;
54490 
54491     if (instance->state != DataSourceInstance::STOPPING) {
54492       PERFETTO_ELOG("Stopped data source instance in incorrect state: %d",
54493                     instance->state);
54494       continue;
54495     }
54496 
54497     instance->state = DataSourceInstance::STOPPED;
54498 
54499     ProducerEndpointImpl* producer = GetProducer(producer_id);
54500     PERFETTO_DCHECK(producer);
54501     if (tracing_session.consumer_maybe_null) {
54502       tracing_session.consumer_maybe_null->OnDataSourceInstanceStateChange(
54503           *producer, *instance);
54504     }
54505 
54506     if (!tracing_session.AllDataSourceInstancesStopped())
54507       continue;
54508 
54509     if (tracing_session.state != TracingSession::DISABLING_WAITING_STOP_ACKS)
54510       continue;
54511 
54512     // All data sources acked the termination.
54513     DisableTracingNotifyConsumerAndFlushFile(&tracing_session);
54514   }  // for (tracing_session)
54515 }
54516 
ActivateTriggers(ProducerID producer_id,const std::vector<std::string> & triggers)54517 void TracingServiceImpl::ActivateTriggers(
54518     ProducerID producer_id,
54519     const std::vector<std::string>& triggers) {
54520   PERFETTO_DCHECK_THREAD(thread_checker_);
54521   auto* producer = GetProducer(producer_id);
54522   PERFETTO_DCHECK(producer);
54523 
54524   int64_t now_ns = base::GetBootTimeNs().count();
54525   for (const auto& trigger_name : triggers) {
54526     PERFETTO_DLOG("Received ActivateTriggers request for \"%s\"",
54527                   trigger_name.c_str());
54528     base::Hash hash;
54529     hash.Update(trigger_name.c_str(), trigger_name.size());
54530 
54531     uint64_t trigger_name_hash = hash.digest();
54532     size_t count_in_window =
54533         PurgeExpiredAndCountTriggerInWindow(now_ns, trigger_name_hash);
54534 
54535     bool trigger_applied = false;
54536     for (auto& id_and_tracing_session : tracing_sessions_) {
54537       auto& tracing_session = id_and_tracing_session.second;
54538       TracingSessionID tsid = id_and_tracing_session.first;
54539       auto iter = std::find_if(
54540           tracing_session.config.trigger_config().triggers().begin(),
54541           tracing_session.config.trigger_config().triggers().end(),
54542           [&trigger_name](const TraceConfig::TriggerConfig::Trigger& trigger) {
54543             return trigger.name() == trigger_name;
54544           });
54545       if (iter == tracing_session.config.trigger_config().triggers().end()) {
54546         continue;
54547       }
54548 
54549       // If this trigger requires a certain producer to have sent it
54550       // (non-empty producer_name()) ensure the producer who sent this trigger
54551       // matches.
54552       if (!iter->producer_name_regex().empty() &&
54553           !std::regex_match(
54554               producer->name_,
54555               std::regex(iter->producer_name_regex(), std::regex::extended))) {
54556         continue;
54557       }
54558 
54559       // Use a random number between 0 and 1 to check if we should allow this
54560       // trigger through or not.
54561       double trigger_rnd =
54562           trigger_rnd_override_for_testing_ > 0
54563               ? trigger_rnd_override_for_testing_
54564               : trigger_probability_dist_(trigger_probability_rand_);
54565       PERFETTO_DCHECK(trigger_rnd >= 0 && trigger_rnd < 1);
54566       if (trigger_rnd < iter->skip_probability()) {
54567         MaybeLogTriggerEvent(tracing_session.config,
54568                              PerfettoTriggerAtom::kTracedLimitProbability,
54569                              trigger_name);
54570         continue;
54571       }
54572 
54573       // If we already triggered more times than the limit, silently ignore
54574       // this trigger.
54575       if (iter->max_per_24_h() > 0 && count_in_window >= iter->max_per_24_h()) {
54576         MaybeLogTriggerEvent(tracing_session.config,
54577                              PerfettoTriggerAtom::kTracedLimitMaxPer24h,
54578                              trigger_name);
54579         continue;
54580       }
54581       trigger_applied = true;
54582 
54583       const bool triggers_already_received =
54584           !tracing_session.received_triggers.empty();
54585       tracing_session.received_triggers.push_back(
54586           {static_cast<uint64_t>(now_ns), iter->name(), producer->name_,
54587            producer->uid_});
54588       auto weak_this = weak_ptr_factory_.GetWeakPtr();
54589       switch (tracing_session.config.trigger_config().trigger_mode()) {
54590         case TraceConfig::TriggerConfig::START_TRACING:
54591           // If the session has already been triggered and moved past
54592           // CONFIGURED then we don't need to repeat StartTracing. This would
54593           // work fine (StartTracing would return false) but would add error
54594           // logs.
54595           if (tracing_session.state != TracingSession::CONFIGURED)
54596             break;
54597 
54598           PERFETTO_DLOG("Triggering '%s' on tracing session %" PRIu64
54599                         " with duration of %" PRIu32 "ms.",
54600                         iter->name().c_str(), tsid, iter->stop_delay_ms());
54601           MaybeLogUploadEvent(tracing_session.config,
54602                               PerfettoStatsdAtom::kTracedTriggerStartTracing,
54603                               iter->name());
54604 
54605           // We override the trace duration to be the trigger's requested
54606           // value, this ensures that the trace will end after this amount
54607           // of time has passed.
54608           tracing_session.config.set_duration_ms(iter->stop_delay_ms());
54609           StartTracing(tsid);
54610           break;
54611         case TraceConfig::TriggerConfig::STOP_TRACING:
54612           // Only stop the trace once to avoid confusing log messages. I.E.
54613           // when we've already hit the first trigger we've already Posted the
54614           // task to FlushAndDisable. So all future triggers will just break
54615           // out.
54616           if (triggers_already_received)
54617             break;
54618 
54619           PERFETTO_DLOG("Triggering '%s' on tracing session %" PRIu64
54620                         " with duration of %" PRIu32 "ms.",
54621                         iter->name().c_str(), tsid, iter->stop_delay_ms());
54622           MaybeLogUploadEvent(tracing_session.config,
54623                               PerfettoStatsdAtom::kTracedTriggerStopTracing,
54624                               iter->name());
54625 
54626           // Now that we've seen a trigger we need to stop, flush, and disable
54627           // this session after the configured |stop_delay_ms|.
54628           task_runner_->PostDelayedTask(
54629               [weak_this, tsid] {
54630                 // Skip entirely the flush if the trace session doesn't exist
54631                 // anymore. This is to prevent misleading error messages to be
54632                 // logged.
54633                 if (weak_this && weak_this->GetTracingSession(tsid))
54634                   weak_this->FlushAndDisableTracing(tsid);
54635               },
54636               // If this trigger is zero this will immediately executable and
54637               // will happen shortly.
54638               iter->stop_delay_ms());
54639           break;
54640         case TraceConfig::TriggerConfig::UNSPECIFIED:
54641           PERFETTO_ELOG("Trigger activated but trigger mode unspecified.");
54642           break;
54643       }
54644     }  // for (.. : tracing_sessions_)
54645 
54646     if (trigger_applied) {
54647       trigger_history_.emplace_back(TriggerHistory{now_ns, trigger_name_hash});
54648     }
54649   }
54650 }
54651 
54652 // Always invoked kDataSourceStopTimeoutMs after DisableTracing(). In nominal
54653 // conditions all data sources should have acked the stop and this will early
54654 // out.
OnDisableTracingTimeout(TracingSessionID tsid)54655 void TracingServiceImpl::OnDisableTracingTimeout(TracingSessionID tsid) {
54656   PERFETTO_DCHECK_THREAD(thread_checker_);
54657   TracingSession* tracing_session = GetTracingSession(tsid);
54658   if (!tracing_session ||
54659       tracing_session->state != TracingSession::DISABLING_WAITING_STOP_ACKS) {
54660     return;  // Tracing session was successfully disabled.
54661   }
54662 
54663   PERFETTO_ILOG("Timeout while waiting for ACKs for tracing session %" PRIu64,
54664                 tsid);
54665   PERFETTO_DCHECK(!tracing_session->AllDataSourceInstancesStopped());
54666   DisableTracingNotifyConsumerAndFlushFile(tracing_session);
54667 }
54668 
DisableTracingNotifyConsumerAndFlushFile(TracingSession * tracing_session)54669 void TracingServiceImpl::DisableTracingNotifyConsumerAndFlushFile(
54670     TracingSession* tracing_session) {
54671   PERFETTO_DCHECK(tracing_session->state != TracingSession::DISABLED);
54672   for (auto& inst_kv : tracing_session->data_source_instances) {
54673     if (inst_kv.second.state == DataSourceInstance::STOPPED)
54674       continue;
54675     inst_kv.second.state = DataSourceInstance::STOPPED;
54676     ProducerEndpointImpl* producer = GetProducer(inst_kv.first);
54677     PERFETTO_DCHECK(producer);
54678     if (tracing_session->consumer_maybe_null) {
54679       tracing_session->consumer_maybe_null->OnDataSourceInstanceStateChange(
54680           *producer, inst_kv.second);
54681     }
54682   }
54683   tracing_session->state = TracingSession::DISABLED;
54684 
54685   // Scrape any remaining chunks that weren't flushed by the producers.
54686   for (auto& producer_id_and_producer : producers_)
54687     ScrapeSharedMemoryBuffers(tracing_session, producer_id_and_producer.second);
54688 
54689   SnapshotLifecyleEvent(
54690       tracing_session,
54691       protos::pbzero::TracingServiceEvent::kTracingDisabledFieldNumber,
54692       true /* snapshot_clocks */);
54693 
54694   if (tracing_session->write_into_file) {
54695     tracing_session->write_period_ms = 0;
54696     ReadBuffersIntoFile(tracing_session->id);
54697   }
54698 
54699   if (tracing_session->on_disable_callback_for_bugreport) {
54700     std::move(tracing_session->on_disable_callback_for_bugreport)();
54701     tracing_session->on_disable_callback_for_bugreport = nullptr;
54702   }
54703 
54704   MaybeLogUploadEvent(tracing_session->config,
54705                       PerfettoStatsdAtom::kTracedNotifyTracingDisabled);
54706 
54707   if (tracing_session->consumer_maybe_null)
54708     tracing_session->consumer_maybe_null->NotifyOnTracingDisabled("");
54709 }
54710 
Flush(TracingSessionID tsid,uint32_t timeout_ms,ConsumerEndpoint::FlushCallback callback)54711 void TracingServiceImpl::Flush(TracingSessionID tsid,
54712                                uint32_t timeout_ms,
54713                                ConsumerEndpoint::FlushCallback callback) {
54714   PERFETTO_DCHECK_THREAD(thread_checker_);
54715   TracingSession* tracing_session = GetTracingSession(tsid);
54716   if (!tracing_session) {
54717     PERFETTO_DLOG("Flush() failed, invalid session ID %" PRIu64, tsid);
54718     return;
54719   }
54720 
54721   if (!timeout_ms)
54722     timeout_ms = tracing_session->flush_timeout_ms();
54723 
54724   if (tracing_session->pending_flushes.size() > 1000) {
54725     PERFETTO_ELOG("Too many flushes (%zu) pending for the tracing session",
54726                   tracing_session->pending_flushes.size());
54727     callback(false);
54728     return;
54729   }
54730 
54731   FlushRequestID flush_request_id = ++last_flush_request_id_;
54732   PendingFlush& pending_flush =
54733       tracing_session->pending_flushes
54734           .emplace_hint(tracing_session->pending_flushes.end(),
54735                         flush_request_id, PendingFlush(std::move(callback)))
54736           ->second;
54737 
54738   // Send a flush request to each producer involved in the tracing session. In
54739   // order to issue a flush request we have to build a map of all data source
54740   // instance ids enabled for each producer.
54741   std::map<ProducerID, std::vector<DataSourceInstanceID>> flush_map;
54742   for (const auto& data_source_inst : tracing_session->data_source_instances) {
54743     const ProducerID producer_id = data_source_inst.first;
54744     const DataSourceInstanceID ds_inst_id = data_source_inst.second.instance_id;
54745     flush_map[producer_id].push_back(ds_inst_id);
54746   }
54747 
54748   for (const auto& kv : flush_map) {
54749     ProducerID producer_id = kv.first;
54750     ProducerEndpointImpl* producer = GetProducer(producer_id);
54751     const std::vector<DataSourceInstanceID>& data_sources = kv.second;
54752     producer->Flush(flush_request_id, data_sources);
54753     pending_flush.producers.insert(producer_id);
54754   }
54755 
54756   // If there are no producers to flush (realistically this happens only in
54757   // some tests) fire OnFlushTimeout() straight away, without waiting.
54758   if (flush_map.empty())
54759     timeout_ms = 0;
54760 
54761   auto weak_this = weak_ptr_factory_.GetWeakPtr();
54762   task_runner_->PostDelayedTask(
54763       [weak_this, tsid, flush_request_id] {
54764         if (weak_this)
54765           weak_this->OnFlushTimeout(tsid, flush_request_id);
54766       },
54767       timeout_ms);
54768 }
54769 
NotifyFlushDoneForProducer(ProducerID producer_id,FlushRequestID flush_request_id)54770 void TracingServiceImpl::NotifyFlushDoneForProducer(
54771     ProducerID producer_id,
54772     FlushRequestID flush_request_id) {
54773   for (auto& kv : tracing_sessions_) {
54774     // Remove all pending flushes <= |flush_request_id| for |producer_id|.
54775     auto& pending_flushes = kv.second.pending_flushes;
54776     auto end_it = pending_flushes.upper_bound(flush_request_id);
54777     for (auto it = pending_flushes.begin(); it != end_it;) {
54778       PendingFlush& pending_flush = it->second;
54779       pending_flush.producers.erase(producer_id);
54780       if (pending_flush.producers.empty()) {
54781         auto weak_this = weak_ptr_factory_.GetWeakPtr();
54782         TracingSessionID tsid = kv.first;
54783         auto callback = std::move(pending_flush.callback);
54784         task_runner_->PostTask([weak_this, tsid, callback]() {
54785           if (weak_this) {
54786             weak_this->CompleteFlush(tsid, std::move(callback),
54787                                      /*success=*/true);
54788           }
54789         });
54790         it = pending_flushes.erase(it);
54791       } else {
54792         it++;
54793       }
54794     }  // for (pending_flushes)
54795   }    // for (tracing_session)
54796 }
54797 
OnFlushTimeout(TracingSessionID tsid,FlushRequestID flush_request_id)54798 void TracingServiceImpl::OnFlushTimeout(TracingSessionID tsid,
54799                                         FlushRequestID flush_request_id) {
54800   TracingSession* tracing_session = GetTracingSession(tsid);
54801   if (!tracing_session)
54802     return;
54803   auto it = tracing_session->pending_flushes.find(flush_request_id);
54804   if (it == tracing_session->pending_flushes.end())
54805     return;  // Nominal case: flush was completed and acked on time.
54806 
54807   // If there were no producers to flush, consider it a success.
54808   bool success = it->second.producers.empty();
54809 
54810   auto callback = std::move(it->second.callback);
54811   tracing_session->pending_flushes.erase(it);
54812   CompleteFlush(tsid, std::move(callback), success);
54813 }
54814 
CompleteFlush(TracingSessionID tsid,ConsumerEndpoint::FlushCallback callback,bool success)54815 void TracingServiceImpl::CompleteFlush(TracingSessionID tsid,
54816                                        ConsumerEndpoint::FlushCallback callback,
54817                                        bool success) {
54818   TracingSession* tracing_session = GetTracingSession(tsid);
54819   if (!tracing_session) {
54820     callback(false);
54821     return;
54822   }
54823   // Producers may not have been able to flush all their data, even if they
54824   // indicated flush completion. If possible, also collect uncommitted chunks
54825   // to make sure we have everything they wrote so far.
54826   for (auto& producer_id_and_producer : producers_) {
54827     ScrapeSharedMemoryBuffers(tracing_session, producer_id_and_producer.second);
54828   }
54829   SnapshotLifecyleEvent(
54830       tracing_session,
54831       protos::pbzero::TracingServiceEvent::kAllDataSourcesFlushedFieldNumber,
54832       true /* snapshot_clocks */);
54833   callback(success);
54834 }
54835 
ScrapeSharedMemoryBuffers(TracingSession * tracing_session,ProducerEndpointImpl * producer)54836 void TracingServiceImpl::ScrapeSharedMemoryBuffers(
54837     TracingSession* tracing_session,
54838     ProducerEndpointImpl* producer) {
54839   if (!producer->smb_scraping_enabled_)
54840     return;
54841 
54842   // Can't copy chunks if we don't know about any trace writers.
54843   if (producer->writers_.empty())
54844     return;
54845 
54846   // Performance optimization: On flush or session disconnect, this method is
54847   // called for each producer. If the producer doesn't participate in the
54848   // session, there's no need to scape its chunks right now. We can tell if a
54849   // producer participates in the session by checking if the producer is allowed
54850   // to write into the session's log buffers.
54851   const auto& session_buffers = tracing_session->buffers_index;
54852   bool producer_in_session =
54853       std::any_of(session_buffers.begin(), session_buffers.end(),
54854                   [producer](BufferID buffer_id) {
54855                     return producer->allowed_target_buffers_.count(buffer_id);
54856                   });
54857   if (!producer_in_session)
54858     return;
54859 
54860   PERFETTO_DLOG("Scraping SMB for producer %" PRIu16, producer->id_);
54861 
54862   // Find and copy any uncommitted chunks from the SMB.
54863   //
54864   // In nominal conditions, the page layout of the used SMB pages should never
54865   // change because the service is the only one who is supposed to modify used
54866   // pages (to make them free again).
54867   //
54868   // However, the code here needs to deal with the case of a malicious producer
54869   // altering the SMB in unpredictable ways. Thankfully the SMB size is
54870   // immutable, so a chunk will always point to some valid memory, even if the
54871   // producer alters the intended layout and chunk header concurrently.
54872   // Ultimately a malicious producer altering the SMB's chunk layout while we
54873   // are iterating in this function is not any different from the case of a
54874   // malicious producer asking to commit a chunk made of random data, which is
54875   // something this class has to deal with regardless.
54876   //
54877   // The only legitimate mutations that can happen from sane producers,
54878   // concurrently to this function, are:
54879   //   A. free pages being partitioned,
54880   //   B. free chunks being migrated to kChunkBeingWritten,
54881   //   C. kChunkBeingWritten chunks being migrated to kChunkCompleted.
54882 
54883   SharedMemoryABI* abi = &producer->shmem_abi_;
54884   // num_pages() is immutable after the SMB is initialized and cannot be changed
54885   // even by a producer even if malicious.
54886   for (size_t page_idx = 0; page_idx < abi->num_pages(); page_idx++) {
54887     uint32_t layout = abi->GetPageLayout(page_idx);
54888 
54889     uint32_t used_chunks = abi->GetUsedChunks(layout);  // Returns a bitmap.
54890     // Skip empty pages.
54891     if (used_chunks == 0)
54892       continue;
54893 
54894     // Scrape the chunks that are currently used. These should be either in
54895     // state kChunkBeingWritten or kChunkComplete.
54896     for (uint32_t chunk_idx = 0; used_chunks; chunk_idx++, used_chunks >>= 1) {
54897       if (!(used_chunks & 1))
54898         continue;
54899 
54900       SharedMemoryABI::ChunkState state =
54901           SharedMemoryABI::GetChunkStateFromLayout(layout, chunk_idx);
54902       PERFETTO_DCHECK(state == SharedMemoryABI::kChunkBeingWritten ||
54903                       state == SharedMemoryABI::kChunkComplete);
54904       bool chunk_complete = state == SharedMemoryABI::kChunkComplete;
54905 
54906       SharedMemoryABI::Chunk chunk =
54907           abi->GetChunkUnchecked(page_idx, layout, chunk_idx);
54908 
54909       uint16_t packet_count;
54910       uint8_t flags;
54911       // GetPacketCountAndFlags has acquire_load semantics.
54912       std::tie(packet_count, flags) = chunk.GetPacketCountAndFlags();
54913 
54914       // It only makes sense to copy an incomplete chunk if there's at least
54915       // one full packet available. (The producer may not have completed the
54916       // last packet in it yet, so we need at least 2.)
54917       if (!chunk_complete && packet_count < 2)
54918         continue;
54919 
54920       // At this point, it is safe to access the remaining header fields of
54921       // the chunk. Even if the chunk was only just transferred from
54922       // kChunkFree into kChunkBeingWritten state, the header should be
54923       // written completely once the packet count increased above 1 (it was
54924       // reset to 0 by the service when the chunk was freed).
54925 
54926       WriterID writer_id = chunk.writer_id();
54927       base::Optional<BufferID> target_buffer_id =
54928           producer->buffer_id_for_writer(writer_id);
54929 
54930       // We can only scrape this chunk if we know which log buffer to copy it
54931       // into.
54932       if (!target_buffer_id)
54933         continue;
54934 
54935       // Skip chunks that don't belong to the requested tracing session.
54936       bool target_buffer_belongs_to_session =
54937           std::find(session_buffers.begin(), session_buffers.end(),
54938                     *target_buffer_id) != session_buffers.end();
54939       if (!target_buffer_belongs_to_session)
54940         continue;
54941 
54942       uint32_t chunk_id =
54943           chunk.header()->chunk_id.load(std::memory_order_relaxed);
54944 
54945       CopyProducerPageIntoLogBuffer(
54946           producer->id_, producer->uid_, writer_id, chunk_id, *target_buffer_id,
54947           packet_count, flags, chunk_complete, chunk.payload_begin(),
54948           chunk.payload_size());
54949     }
54950   }
54951 }
54952 
FlushAndDisableTracing(TracingSessionID tsid)54953 void TracingServiceImpl::FlushAndDisableTracing(TracingSessionID tsid) {
54954   PERFETTO_DCHECK_THREAD(thread_checker_);
54955   PERFETTO_DLOG("Triggering final flush for %" PRIu64, tsid);
54956   auto weak_this = weak_ptr_factory_.GetWeakPtr();
54957   Flush(tsid, 0, [weak_this, tsid](bool success) {
54958     // This was a DLOG up to Jun 2021 (v16, Android S).
54959     PERFETTO_LOG("FlushAndDisableTracing(%" PRIu64 ") done, success=%d", tsid,
54960                  success);
54961     if (!weak_this)
54962       return;
54963     TracingSession* session = weak_this->GetTracingSession(tsid);
54964     if (session->consumer_maybe_null) {
54965       // If the consumer is still attached, just disable the session but give it
54966       // a chance to read the contents.
54967       weak_this->DisableTracing(tsid);
54968     } else {
54969       // If the consumer detached, destroy the session. If the consumer did
54970       // start the session in long-tracing mode, the service will have saved
54971       // the contents to the passed file. If not, the contents will be
54972       // destroyed.
54973       weak_this->FreeBuffers(tsid);
54974     }
54975   });
54976 }
54977 
PeriodicFlushTask(TracingSessionID tsid,bool post_next_only)54978 void TracingServiceImpl::PeriodicFlushTask(TracingSessionID tsid,
54979                                            bool post_next_only) {
54980   PERFETTO_DCHECK_THREAD(thread_checker_);
54981   TracingSession* tracing_session = GetTracingSession(tsid);
54982   if (!tracing_session || tracing_session->state != TracingSession::STARTED)
54983     return;
54984 
54985   uint32_t flush_period_ms = tracing_session->config.flush_period_ms();
54986   auto weak_this = weak_ptr_factory_.GetWeakPtr();
54987   task_runner_->PostDelayedTask(
54988       [weak_this, tsid] {
54989         if (weak_this)
54990           weak_this->PeriodicFlushTask(tsid, /*post_next_only=*/false);
54991       },
54992       flush_period_ms - static_cast<uint32_t>(base::GetWallTimeMs().count() %
54993                                               flush_period_ms));
54994 
54995   if (post_next_only)
54996     return;
54997 
54998   PERFETTO_DLOG("Triggering periodic flush for trace session %" PRIu64, tsid);
54999   Flush(tsid, 0, [](bool success) {
55000     if (!success)
55001       PERFETTO_ELOG("Periodic flush timed out");
55002   });
55003 }
55004 
PeriodicClearIncrementalStateTask(TracingSessionID tsid,bool post_next_only)55005 void TracingServiceImpl::PeriodicClearIncrementalStateTask(
55006     TracingSessionID tsid,
55007     bool post_next_only) {
55008   PERFETTO_DCHECK_THREAD(thread_checker_);
55009   TracingSession* tracing_session = GetTracingSession(tsid);
55010   if (!tracing_session || tracing_session->state != TracingSession::STARTED)
55011     return;
55012 
55013   uint32_t clear_period_ms =
55014       tracing_session->config.incremental_state_config().clear_period_ms();
55015   auto weak_this = weak_ptr_factory_.GetWeakPtr();
55016   task_runner_->PostDelayedTask(
55017       [weak_this, tsid] {
55018         if (weak_this)
55019           weak_this->PeriodicClearIncrementalStateTask(
55020               tsid, /*post_next_only=*/false);
55021       },
55022       clear_period_ms - static_cast<uint32_t>(base::GetWallTimeMs().count() %
55023                                               clear_period_ms));
55024 
55025   if (post_next_only)
55026     return;
55027 
55028   PERFETTO_DLOG(
55029       "Performing periodic incremental state clear for trace session %" PRIu64,
55030       tsid);
55031 
55032   // Queue the IPCs to producers with active data sources that opted in.
55033   std::map<ProducerID, std::vector<DataSourceInstanceID>> clear_map;
55034   int ds_clear_count = 0;
55035   for (const auto& kv : tracing_session->data_source_instances) {
55036     ProducerID producer_id = kv.first;
55037     const DataSourceInstance& data_source = kv.second;
55038     if (data_source.handles_incremental_state_clear) {
55039       clear_map[producer_id].push_back(data_source.instance_id);
55040       ++ds_clear_count;
55041     }
55042   }
55043 
55044   g_crash_key_ds_clear_count.Set(ds_clear_count);
55045 
55046   for (const auto& kv : clear_map) {
55047     ProducerID producer_id = kv.first;
55048     const std::vector<DataSourceInstanceID>& data_sources = kv.second;
55049     ProducerEndpointImpl* producer = GetProducer(producer_id);
55050     if (!producer) {
55051       PERFETTO_DFATAL("Producer does not exist.");
55052       continue;
55053     }
55054     producer->ClearIncrementalState(data_sources);
55055   }
55056 
55057   // ClearIncrementalState internally posts a task for each data source. Clear
55058   // the crash key in a task queued at the end of the tasks atove.
55059   task_runner_->PostTask([] { g_crash_key_ds_clear_count.Clear(); });
55060 }
55061 
ReadBuffersIntoConsumer(TracingSessionID tsid,ConsumerEndpointImpl * consumer)55062 bool TracingServiceImpl::ReadBuffersIntoConsumer(
55063     TracingSessionID tsid,
55064     ConsumerEndpointImpl* consumer) {
55065   PERFETTO_DCHECK(consumer);
55066   PERFETTO_DCHECK_THREAD(thread_checker_);
55067   TracingSession* tracing_session = GetTracingSession(tsid);
55068   if (!tracing_session) {
55069     PERFETTO_DLOG(
55070         "Cannot ReadBuffersIntoConsumer(): no tracing session is active");
55071     return false;
55072   }
55073 
55074   if (tracing_session->write_into_file) {
55075     // If the consumer enabled tracing and asked to save the contents into the
55076     // passed file makes little sense to also try to read the buffers over IPC,
55077     // as that would just steal data from the periodic draining task.
55078     PERFETTO_ELOG("Consumer trying to read from write_into_file session.");
55079     return false;
55080   }
55081 
55082   // If a bugreport request happened and the trace was stolen for that, give
55083   // an empty trace with a clear signal to the consumer. This deals only with
55084   // the case of readback-from-IPC. A similar code-path deals with the
55085   // write_into_file case in MaybeSaveTraceForBugreport().
55086   if (tracing_session->seized_for_bugreport) {
55087     std::vector<TracePacket> packets;
55088     if (!tracing_session->config.builtin_data_sources()
55089              .disable_service_events()) {
55090       EmitSeizedForBugreportLifecycleEvent(&packets);
55091     }
55092     EmitLifecycleEvents(tracing_session, &packets);
55093     consumer->consumer_->OnTraceData(std::move(packets), /*has_more=*/false);
55094     return true;
55095   }
55096 
55097   if (IsWaitingForTrigger(tracing_session))
55098     return false;
55099 
55100   return ReadBuffers(tsid, tracing_session, consumer);
55101 }
55102 
ReadBuffersIntoFile(TracingSessionID tsid)55103 bool TracingServiceImpl::ReadBuffersIntoFile(TracingSessionID tsid) {
55104   PERFETTO_DCHECK_THREAD(thread_checker_);
55105   TracingSession* tracing_session = GetTracingSession(tsid);
55106   if (!tracing_session) {
55107     // This will be hit systematically from the PostDelayedTask. Avoid logging,
55108     // it would be just spam.
55109     return false;
55110   }
55111 
55112   // This can happen if the file is closed by a previous task because it reaches
55113   // |max_file_size_bytes|.
55114   if (!tracing_session->write_into_file)
55115     return false;
55116 
55117   if (!tracing_session->seized_for_bugreport &&
55118       IsWaitingForTrigger(tracing_session))
55119     return false;
55120 
55121   return ReadBuffers(tsid, tracing_session, nullptr);
55122 }
55123 
IsWaitingForTrigger(TracingSession * tracing_session)55124 bool TracingServiceImpl::IsWaitingForTrigger(TracingSession* tracing_session) {
55125   // When a tracing session is waiting for a trigger, it is considered empty. If
55126   // a tracing session finishes and moves into DISABLED without ever receiving a
55127   // trigger, the trace should never return any data. This includes the
55128   // synthetic packets like TraceConfig and Clock snapshots. So we bail out
55129   // early and let the consumer know there is no data.
55130   if (!tracing_session->config.trigger_config().triggers().empty() &&
55131       tracing_session->received_triggers.empty()) {
55132     PERFETTO_DLOG(
55133         "ReadBuffers(): tracing session has not received a trigger yet.");
55134     return true;
55135   }
55136   return false;
55137 }
55138 
55139 // Note: when this is called to write into a file passed when starting tracing
55140 // |consumer| will be == nullptr (as opposite to the case of a consumer asking
55141 // to send the trace data back over IPC).
ReadBuffers(TracingSessionID tsid,TracingSession * tracing_session,ConsumerEndpointImpl * consumer)55142 bool TracingServiceImpl::ReadBuffers(TracingSessionID tsid,
55143                                      TracingSession* tracing_session,
55144                                      ConsumerEndpointImpl* consumer) {
55145   PERFETTO_DCHECK_THREAD(thread_checker_);
55146   PERFETTO_DCHECK(tracing_session);
55147 
55148   // Speculative fix for the memory watchdog crash in b/195145848. This function
55149   // uses the heap extensively and might need a M_PURGE. window.gc() is back.
55150   // TODO(primiano): if this fixes the crash we might want to coalesce the purge
55151   // and throttle it.
55152   auto on_ret = base::OnScopeExit([] { base::MaybeReleaseAllocatorMemToOS(); });
55153 
55154   std::vector<TracePacket> packets;
55155   packets.reserve(1024);  // Just an educated guess to avoid trivial expansions.
55156 
55157   if (!tracing_session->initial_clock_snapshot.empty()) {
55158     EmitClockSnapshot(tracing_session,
55159                       std::move(tracing_session->initial_clock_snapshot),
55160                       &packets);
55161   }
55162 
55163   for (auto& snapshot : tracing_session->clock_snapshot_ring_buffer) {
55164     PERFETTO_DCHECK(!snapshot.empty());
55165     EmitClockSnapshot(tracing_session, std::move(snapshot), &packets);
55166   }
55167   tracing_session->clock_snapshot_ring_buffer.clear();
55168 
55169   if (tracing_session->should_emit_sync_marker) {
55170     EmitSyncMarker(&packets);
55171     tracing_session->should_emit_sync_marker = false;
55172   }
55173 
55174   if (!tracing_session->config.builtin_data_sources().disable_trace_config()) {
55175     MaybeEmitTraceConfig(tracing_session, &packets);
55176     MaybeEmitReceivedTriggers(tracing_session, &packets);
55177   }
55178   if (!tracing_session->config.builtin_data_sources().disable_system_info())
55179     MaybeEmitSystemInfo(tracing_session, &packets);
55180 
55181   // Note that in the proto comment, we guarantee that the tracing_started
55182   // lifecycle event will be emitted before any data packets so make sure to
55183   // keep this before reading the tracing buffers.
55184   if (!tracing_session->config.builtin_data_sources().disable_service_events())
55185     EmitLifecycleEvents(tracing_session, &packets);
55186 
55187   size_t packets_bytes = 0;  // SUM(slice.size() for each slice in |packets|).
55188 
55189   // Add up size for packets added by the Maybe* calls above.
55190   for (const TracePacket& packet : packets) {
55191     packets_bytes += packet.size();
55192   }
55193 
55194   // This is a rough threshold to determine how much to read from the buffer in
55195   // each task. This is to avoid executing a single huge sending task for too
55196   // long and risk to hit the watchdog. This is *not* an upper bound: we just
55197   // stop accumulating new packets and PostTask *after* we cross this threshold.
55198   // This constant essentially balances the PostTask and IPC overhead vs the
55199   // responsiveness of the service. An extremely small value will cause one IPC
55200   // and one PostTask for each slice but will keep the service extremely
55201   // responsive. An extremely large value will batch the send for the full
55202   // buffer in one large task, will hit the blocking send() once the socket
55203   // buffers are full and hang the service for a bit (until the consumer
55204   // catches up).
55205   static constexpr size_t kApproxBytesPerTask = 32768;
55206   bool did_hit_threshold = false;
55207 
55208   // TODO(primiano): Extend the ReadBuffers API to allow reading only some
55209   // buffers, not all of them in one go.
55210   for (size_t buf_idx = 0;
55211        buf_idx < tracing_session->num_buffers() && !did_hit_threshold;
55212        buf_idx++) {
55213     auto tbuf_iter = buffers_.find(tracing_session->buffers_index[buf_idx]);
55214     if (tbuf_iter == buffers_.end()) {
55215       PERFETTO_DFATAL("Buffer not found.");
55216       continue;
55217     }
55218     TraceBuffer& tbuf = *tbuf_iter->second;
55219     tbuf.BeginRead();
55220     while (!did_hit_threshold) {
55221       TracePacket packet;
55222       TraceBuffer::PacketSequenceProperties sequence_properties{};
55223       bool previous_packet_dropped;
55224       if (!tbuf.ReadNextTracePacket(&packet, &sequence_properties,
55225                                     &previous_packet_dropped)) {
55226         break;
55227       }
55228       PERFETTO_DCHECK(sequence_properties.producer_id_trusted != 0);
55229       PERFETTO_DCHECK(sequence_properties.writer_id != 0);
55230       PERFETTO_DCHECK(sequence_properties.producer_uid_trusted != kInvalidUid);
55231       PERFETTO_DCHECK(packet.size() > 0);
55232       if (!PacketStreamValidator::Validate(packet.slices())) {
55233         tracing_session->invalid_packets++;
55234         PERFETTO_DLOG("Dropping invalid packet");
55235         continue;
55236       }
55237 
55238       // Append a slice with the trusted field data. This can't be spoofed
55239       // because above we validated that the existing slices don't contain any
55240       // trusted fields. For added safety we append instead of prepending
55241       // because according to protobuf semantics, if the same field is
55242       // encountered multiple times the last instance takes priority. Note that
55243       // truncated packets are also rejected, so the producer can't give us a
55244       // partial packet (e.g., a truncated string) which only becomes valid when
55245       // the trusted data is appended here.
55246       Slice slice = Slice::Allocate(32);
55247       protozero::StaticBuffered<protos::pbzero::TracePacket> trusted_packet(
55248           slice.own_data(), slice.size);
55249       trusted_packet->set_trusted_uid(
55250           static_cast<int32_t>(sequence_properties.producer_uid_trusted));
55251       trusted_packet->set_trusted_packet_sequence_id(
55252           tracing_session->GetPacketSequenceID(
55253               sequence_properties.producer_id_trusted,
55254               sequence_properties.writer_id));
55255       if (previous_packet_dropped)
55256         trusted_packet->set_previous_packet_dropped(previous_packet_dropped);
55257       slice.size = trusted_packet.Finalize();
55258       packet.AddSlice(std::move(slice));
55259 
55260       // Append the packet (inclusive of the trusted uid) to |packets|.
55261       packets_bytes += packet.size();
55262       did_hit_threshold = packets_bytes >= kApproxBytesPerTask &&
55263                           !tracing_session->write_into_file;
55264       packets.emplace_back(std::move(packet));
55265     }  // for(packets...)
55266   }    // for(buffers...)
55267 
55268   const bool has_more = did_hit_threshold;
55269 
55270   if (!tracing_session->config.builtin_data_sources()
55271            .disable_service_events()) {
55272     // We don't bother snapshotting clocks here because we wouldn't be able to
55273     // emit it and we shouldn't have significant drift from the last snapshot in
55274     // any case.
55275     SnapshotLifecyleEvent(tracing_session,
55276                           protos::pbzero::TracingServiceEvent::
55277                               kReadTracingBuffersCompletedFieldNumber,
55278                           false /* snapshot_clocks */);
55279     EmitLifecycleEvents(tracing_session, &packets);
55280   }
55281 
55282   // Only emit the stats when there is no more trace data is available to read.
55283   // That way, any problems that occur while reading from the buffers are
55284   // reflected in the emitted stats. This is particularly important for use
55285   // cases where ReadBuffers is only ever called after the tracing session is
55286   // stopped.
55287   if (!has_more && tracing_session->should_emit_stats) {
55288     EmitStats(tracing_session, &packets);
55289     tracing_session->should_emit_stats = false;
55290   }
55291 
55292   // +-------------------------------------------------------------------------+
55293   // | NO MORE CHANGES TO |packets| AFTER THIS POINT.                          |
55294   // +-------------------------------------------------------------------------+
55295 
55296   // If the tracing session specified a filter, run all packets through the
55297   // filter and replace them with the filter results.
55298   // The process below mantains the cardinality of input packets. Even if an
55299   // entire packet is filtered out, we emit a zero-sized TracePacket proto. That
55300   // makes debugging and reasoning about the trace stats easier.
55301   // This place swaps the contents of each |packets| entry in place.
55302   if (tracing_session->trace_filter) {
55303     auto& trace_filter = *tracing_session->trace_filter;
55304     // The filter root shoud be reset from protos.Trace to protos.TracePacket
55305     // by the earlier call to SetFilterRoot() in EnableTracing().
55306     PERFETTO_DCHECK(trace_filter.root_msg_index() != 0);
55307     std::vector<protozero::MessageFilter::InputSlice> filter_input;
55308     for (auto it = packets.begin(); it != packets.end(); ++it) {
55309       const auto& packet_slices = it->slices();
55310       filter_input.clear();
55311       filter_input.resize(packet_slices.size());
55312       ++tracing_session->filter_input_packets;
55313       tracing_session->filter_input_bytes += it->size();
55314       for (size_t i = 0; i < packet_slices.size(); ++i)
55315         filter_input[i] = {packet_slices[i].start, packet_slices[i].size};
55316       auto filtered_packet = trace_filter.FilterMessageFragments(
55317           &filter_input[0], filter_input.size());
55318 
55319       // Replace the packet in-place with the filtered one (unless failed).
55320       *it = TracePacket();
55321       if (filtered_packet.error) {
55322         ++tracing_session->filter_errors;
55323         PERFETTO_DLOG("Trace packet filtering failed @ packet %" PRIu64,
55324                       tracing_session->filter_input_packets);
55325         continue;
55326       }
55327       tracing_session->filter_output_bytes += filtered_packet.size;
55328       AppendOwnedSlicesToPacket(std::move(filtered_packet.data),
55329                                 filtered_packet.size, kMaxTracePacketSliceSize,
55330                                 &*it);
55331 
55332     }  // for (packet)
55333   }    // if (trace_filter)
55334 
55335   // If the caller asked us to write into a file by setting
55336   // |write_into_file| == true in the trace config, drain the packets read
55337   // (if any) into the given file descriptor.
55338   if (tracing_session->write_into_file) {
55339     const uint64_t max_size = tracing_session->max_file_size_bytes
55340                                   ? tracing_session->max_file_size_bytes
55341                                   : std::numeric_limits<size_t>::max();
55342 
55343     size_t total_slices = 0;
55344     for (const TracePacket& packet : packets) {
55345       total_slices += packet.slices().size();
55346     }
55347     // When writing into a file, the file should look like a root trace.proto
55348     // message. Each packet should be prepended with a proto preamble stating
55349     // its field id (within trace.proto) and size. Hence the addition below.
55350     const size_t max_iovecs = total_slices + packets.size();
55351 
55352     size_t num_iovecs = 0;
55353     bool stop_writing_into_file = false;
55354     std::unique_ptr<struct iovec[]> iovecs(new struct iovec[max_iovecs]);
55355     size_t num_iovecs_at_last_packet = 0;
55356     uint64_t bytes_about_to_be_written = 0;
55357     for (TracePacket& packet : packets) {
55358       std::tie(iovecs[num_iovecs].iov_base, iovecs[num_iovecs].iov_len) =
55359           packet.GetProtoPreamble();
55360       bytes_about_to_be_written += iovecs[num_iovecs].iov_len;
55361       num_iovecs++;
55362       for (const Slice& slice : packet.slices()) {
55363         // writev() doesn't change the passed pointer. However, struct iovec
55364         // take a non-const ptr because it's the same struct used by readv().
55365         // Hence the const_cast here.
55366         char* start = static_cast<char*>(const_cast<void*>(slice.start));
55367         bytes_about_to_be_written += slice.size;
55368         iovecs[num_iovecs++] = {start, slice.size};
55369       }
55370 
55371       if (tracing_session->bytes_written_into_file +
55372               bytes_about_to_be_written >=
55373           max_size) {
55374         stop_writing_into_file = true;
55375         num_iovecs = num_iovecs_at_last_packet;
55376         break;
55377       }
55378 
55379       num_iovecs_at_last_packet = num_iovecs;
55380     }
55381     PERFETTO_DCHECK(num_iovecs <= max_iovecs);
55382     int fd = *tracing_session->write_into_file;
55383 
55384     uint64_t total_wr_size = 0;
55385 
55386     // writev() can take at most IOV_MAX entries per call. Batch them.
55387     constexpr size_t kIOVMax = IOV_MAX;
55388     for (size_t i = 0; i < num_iovecs; i += kIOVMax) {
55389       int iov_batch_size = static_cast<int>(std::min(num_iovecs - i, kIOVMax));
55390       ssize_t wr_size = PERFETTO_EINTR(writev(fd, &iovecs[i], iov_batch_size));
55391       if (wr_size <= 0) {
55392         PERFETTO_PLOG("writev() failed");
55393         stop_writing_into_file = true;
55394         break;
55395       }
55396       total_wr_size += static_cast<size_t>(wr_size);
55397     }
55398 
55399     tracing_session->bytes_written_into_file += total_wr_size;
55400 
55401     PERFETTO_DLOG("Draining into file, written: %" PRIu64 " KB, stop: %d",
55402                   (total_wr_size + 1023) / 1024, stop_writing_into_file);
55403     if (stop_writing_into_file || tracing_session->write_period_ms == 0) {
55404       // Ensure all data was written to the file before we close it.
55405       base::FlushFile(fd);
55406       tracing_session->write_into_file.reset();
55407       tracing_session->write_period_ms = 0;
55408       if (tracing_session->state == TracingSession::STARTED)
55409         DisableTracing(tsid);
55410       return true;
55411     }
55412 
55413     auto weak_this = weak_ptr_factory_.GetWeakPtr();
55414     task_runner_->PostDelayedTask(
55415         [weak_this, tsid] {
55416           if (weak_this)
55417             weak_this->ReadBuffersIntoFile(tsid);
55418         },
55419         tracing_session->delay_to_next_write_period_ms());
55420     return true;
55421   }  // if (tracing_session->write_into_file)
55422 
55423   if (has_more) {
55424     auto weak_consumer = consumer->weak_ptr_factory_.GetWeakPtr();
55425     auto weak_this = weak_ptr_factory_.GetWeakPtr();
55426     task_runner_->PostTask([weak_this, weak_consumer, tsid] {
55427       if (!weak_this || !weak_consumer)
55428         return;
55429       weak_this->ReadBuffersIntoConsumer(tsid, weak_consumer.get());
55430     });
55431   }
55432 
55433   // Keep this as tail call, just in case the consumer re-enters.
55434   consumer->consumer_->OnTraceData(std::move(packets), has_more);
55435   return true;
55436 }
55437 
FreeBuffers(TracingSessionID tsid)55438 void TracingServiceImpl::FreeBuffers(TracingSessionID tsid) {
55439   PERFETTO_DCHECK_THREAD(thread_checker_);
55440   PERFETTO_DLOG("Freeing buffers for session %" PRIu64, tsid);
55441   TracingSession* tracing_session = GetTracingSession(tsid);
55442   if (!tracing_session) {
55443     PERFETTO_DLOG("FreeBuffers() failed, invalid session ID %" PRIu64, tsid);
55444     return;  // TODO(primiano): signal failure?
55445   }
55446   DisableTracing(tsid, /*disable_immediately=*/true);
55447 
55448   PERFETTO_DCHECK(tracing_session->AllDataSourceInstancesStopped());
55449   tracing_session->data_source_instances.clear();
55450 
55451   for (auto& producer_entry : producers_) {
55452     ProducerEndpointImpl* producer = producer_entry.second;
55453     producer->OnFreeBuffers(tracing_session->buffers_index);
55454   }
55455 
55456   for (BufferID buffer_id : tracing_session->buffers_index) {
55457     buffer_ids_.Free(buffer_id);
55458     PERFETTO_DCHECK(buffers_.count(buffer_id) == 1);
55459     buffers_.erase(buffer_id);
55460   }
55461   bool notify_traceur = tracing_session->config.notify_traceur();
55462   bool is_long_trace =
55463       (tracing_session->config.write_into_file() &&
55464        tracing_session->config.file_write_period_ms() < kMillisPerDay);
55465   bool seized_for_bugreport = tracing_session->seized_for_bugreport;
55466   tracing_sessions_.erase(tsid);
55467   tracing_session = nullptr;
55468   UpdateMemoryGuardrail();
55469 
55470   PERFETTO_LOG("Tracing session %" PRIu64 " ended, total sessions:%zu", tsid,
55471                tracing_sessions_.size());
55472 
55473 #if PERFETTO_BUILDFLAG(PERFETTO_ANDROID_BUILD) && \
55474     PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
55475   if (notify_traceur && (seized_for_bugreport || is_long_trace)) {
55476     PERFETTO_LAZY_LOAD(android_internal::NotifyTraceSessionEnded, notify_fn);
55477     if (!notify_fn || !notify_fn(seized_for_bugreport))
55478       PERFETTO_ELOG("Failed to notify Traceur long tracing has ended");
55479   }
55480 #else
55481   base::ignore_result(notify_traceur);
55482   base::ignore_result(is_long_trace);
55483   base::ignore_result(seized_for_bugreport);
55484 #endif
55485 }
55486 
RegisterDataSource(ProducerID producer_id,const DataSourceDescriptor & desc)55487 void TracingServiceImpl::RegisterDataSource(ProducerID producer_id,
55488                                             const DataSourceDescriptor& desc) {
55489   PERFETTO_DCHECK_THREAD(thread_checker_);
55490   if (desc.name().empty()) {
55491     PERFETTO_DLOG("Received RegisterDataSource() with empty name");
55492     return;
55493   }
55494 
55495   ProducerEndpointImpl* producer = GetProducer(producer_id);
55496   if (!producer) {
55497     PERFETTO_DFATAL("Producer not found.");
55498     return;
55499   }
55500 
55501   // Check that the producer doesn't register two data sources with the same ID.
55502   // Note that we tolerate |id| == 0 because until Android T / v22 the |id|
55503   // field didn't exist.
55504   for (const auto& kv : data_sources_) {
55505     if (desc.id() && kv.second.producer_id == producer_id &&
55506         kv.second.descriptor.id() == desc.id()) {
55507       PERFETTO_ELOG(
55508           "Failed to register data source \"%s\". A data source with the same "
55509           "id %" PRIu64 " (name=\"%s\") is already registered for producer %d",
55510           desc.name().c_str(), desc.id(), kv.second.descriptor.name().c_str(),
55511           producer_id);
55512       return;
55513     }
55514   }
55515 
55516   PERFETTO_DLOG("Producer %" PRIu16 " registered data source \"%s\"",
55517                 producer_id, desc.name().c_str());
55518 
55519   auto reg_ds = data_sources_.emplace(desc.name(),
55520                                       RegisteredDataSource{producer_id, desc});
55521   g_crash_key_ds_count.Set(static_cast<int64_t>(data_sources_.size()));
55522 
55523   // If there are existing tracing sessions, we need to check if the new
55524   // data source is enabled by any of them.
55525   for (auto& iter : tracing_sessions_) {
55526     TracingSession& tracing_session = iter.second;
55527     if (tracing_session.state != TracingSession::STARTED &&
55528         tracing_session.state != TracingSession::CONFIGURED) {
55529       continue;
55530     }
55531 
55532     TraceConfig::ProducerConfig producer_config;
55533     for (auto& config : tracing_session.config.producers()) {
55534       if (producer->name_ == config.producer_name()) {
55535         producer_config = config;
55536         break;
55537       }
55538     }
55539     for (const TraceConfig::DataSource& cfg_data_source :
55540          tracing_session.config.data_sources()) {
55541       if (cfg_data_source.config().name() != desc.name())
55542         continue;
55543       DataSourceInstance* ds_inst = SetupDataSource(
55544           cfg_data_source, producer_config, reg_ds->second, &tracing_session);
55545       if (ds_inst && tracing_session.state == TracingSession::STARTED)
55546         StartDataSourceInstance(producer, &tracing_session, ds_inst);
55547     }
55548   }  // for(iter : tracing_sessions_)
55549 }
55550 
UpdateDataSource(ProducerID producer_id,const DataSourceDescriptor & new_desc)55551 void TracingServiceImpl::UpdateDataSource(
55552     ProducerID producer_id,
55553     const DataSourceDescriptor& new_desc) {
55554   if (new_desc.id() == 0) {
55555     PERFETTO_ELOG("UpdateDataSource() must have a non-zero id");
55556     return;
55557   }
55558 
55559   // If this producer has already registered a matching descriptor name and id,
55560   // just update the descriptor.
55561   RegisteredDataSource* data_source = nullptr;
55562   auto range = data_sources_.equal_range(new_desc.name());
55563   for (auto it = range.first; it != range.second; ++it) {
55564     if (it->second.producer_id == producer_id &&
55565         it->second.descriptor.id() == new_desc.id()) {
55566       data_source = &it->second;
55567       break;
55568     }
55569   }
55570 
55571   if (!data_source) {
55572     PERFETTO_ELOG(
55573         "UpdateDataSource() failed, could not find an existing data source "
55574         "with name=\"%s\" id=%" PRIu64,
55575         new_desc.name().c_str(), new_desc.id());
55576     return;
55577   }
55578 
55579   data_source->descriptor = new_desc;
55580 }
55581 
StopDataSourceInstance(ProducerEndpointImpl * producer,TracingSession * tracing_session,DataSourceInstance * instance,bool disable_immediately)55582 void TracingServiceImpl::StopDataSourceInstance(ProducerEndpointImpl* producer,
55583                                                 TracingSession* tracing_session,
55584                                                 DataSourceInstance* instance,
55585                                                 bool disable_immediately) {
55586   const DataSourceInstanceID ds_inst_id = instance->instance_id;
55587   if (instance->will_notify_on_stop && !disable_immediately) {
55588     instance->state = DataSourceInstance::STOPPING;
55589   } else {
55590     instance->state = DataSourceInstance::STOPPED;
55591   }
55592   if (tracing_session->consumer_maybe_null) {
55593     tracing_session->consumer_maybe_null->OnDataSourceInstanceStateChange(
55594         *producer, *instance);
55595   }
55596   producer->StopDataSource(ds_inst_id);
55597 }
55598 
UnregisterDataSource(ProducerID producer_id,const std::string & name)55599 void TracingServiceImpl::UnregisterDataSource(ProducerID producer_id,
55600                                               const std::string& name) {
55601   PERFETTO_DCHECK_THREAD(thread_checker_);
55602   PERFETTO_DLOG("Producer %" PRIu16 " unregistered data source \"%s\"",
55603                 producer_id, name.c_str());
55604   PERFETTO_CHECK(producer_id);
55605   ProducerEndpointImpl* producer = GetProducer(producer_id);
55606   PERFETTO_DCHECK(producer);
55607   for (auto& kv : tracing_sessions_) {
55608     auto& ds_instances = kv.second.data_source_instances;
55609     bool removed = false;
55610     for (auto it = ds_instances.begin(); it != ds_instances.end();) {
55611       if (it->first == producer_id && it->second.data_source_name == name) {
55612         DataSourceInstanceID ds_inst_id = it->second.instance_id;
55613         if (it->second.state != DataSourceInstance::STOPPED) {
55614           if (it->second.state != DataSourceInstance::STOPPING) {
55615             StopDataSourceInstance(producer, &kv.second, &it->second,
55616                                    /* disable_immediately = */ false);
55617           }
55618 
55619           // Mark the instance as stopped immediately, since we are
55620           // unregistering it below.
55621           //
55622           //  The StopDataSourceInstance above might have set the state to
55623           //  STOPPING so this condition isn't an else.
55624           if (it->second.state == DataSourceInstance::STOPPING)
55625             NotifyDataSourceStopped(producer_id, ds_inst_id);
55626         }
55627         it = ds_instances.erase(it);
55628         removed = true;
55629       } else {
55630         ++it;
55631       }
55632     }  // for (data_source_instances)
55633     if (removed)
55634       MaybeNotifyAllDataSourcesStarted(&kv.second);
55635   }  // for (tracing_session)
55636 
55637   for (auto it = data_sources_.begin(); it != data_sources_.end(); ++it) {
55638     if (it->second.producer_id == producer_id &&
55639         it->second.descriptor.name() == name) {
55640       data_sources_.erase(it);
55641       g_crash_key_ds_count.Set(static_cast<int64_t>(data_sources_.size()));
55642       return;
55643     }
55644   }
55645 
55646   PERFETTO_DFATAL(
55647       "Tried to unregister a non-existent data source \"%s\" for "
55648       "producer %" PRIu16,
55649       name.c_str(), producer_id);
55650 }
55651 
SetupDataSource(const TraceConfig::DataSource & cfg_data_source,const TraceConfig::ProducerConfig & producer_config,const RegisteredDataSource & data_source,TracingSession * tracing_session)55652 TracingServiceImpl::DataSourceInstance* TracingServiceImpl::SetupDataSource(
55653     const TraceConfig::DataSource& cfg_data_source,
55654     const TraceConfig::ProducerConfig& producer_config,
55655     const RegisteredDataSource& data_source,
55656     TracingSession* tracing_session) {
55657   PERFETTO_DCHECK_THREAD(thread_checker_);
55658   ProducerEndpointImpl* producer = GetProducer(data_source.producer_id);
55659   PERFETTO_DCHECK(producer);
55660   // An existing producer that is not ftrace could have registered itself as
55661   // ftrace, we must not enable it in that case.
55662   if (lockdown_mode_ && producer->uid_ != uid_) {
55663     PERFETTO_DLOG("Lockdown mode: not enabling producer %hu", producer->id_);
55664     return nullptr;
55665   }
55666   // TODO(primiano): Add tests for registration ordering (data sources vs
55667   // consumers).
55668   if (!NameMatchesFilter(producer->name_,
55669                          cfg_data_source.producer_name_filter(),
55670                          cfg_data_source.producer_name_regex_filter())) {
55671     PERFETTO_DLOG("Data source: %s is filtered out for producer: %s",
55672                   cfg_data_source.config().name().c_str(),
55673                   producer->name_.c_str());
55674     return nullptr;
55675   }
55676 
55677   auto relative_buffer_id = cfg_data_source.config().target_buffer();
55678   if (relative_buffer_id >= tracing_session->num_buffers()) {
55679     PERFETTO_LOG(
55680         "The TraceConfig for DataSource %s specified a target_buffer out of "
55681         "bound (%d). Skipping it.",
55682         cfg_data_source.config().name().c_str(), relative_buffer_id);
55683     return nullptr;
55684   }
55685 
55686   // Create a copy of the DataSourceConfig specified in the trace config. This
55687   // will be passed to the producer after translating the |target_buffer| id.
55688   // The |target_buffer| parameter passed by the consumer in the trace config is
55689   // relative to the buffers declared in the same trace config. This has to be
55690   // translated to the global BufferID before passing it to the producers, which
55691   // don't know anything about tracing sessions and consumers.
55692 
55693   DataSourceInstanceID inst_id = ++last_data_source_instance_id_;
55694   auto insert_iter = tracing_session->data_source_instances.emplace(
55695       std::piecewise_construct,  //
55696       std::forward_as_tuple(producer->id_),
55697       std::forward_as_tuple(
55698           inst_id,
55699           cfg_data_source.config(),  //  Deliberate copy.
55700           data_source.descriptor.name(),
55701           data_source.descriptor.will_notify_on_start(),
55702           data_source.descriptor.will_notify_on_stop(),
55703           data_source.descriptor.handles_incremental_state_clear()));
55704   DataSourceInstance* ds_instance = &insert_iter->second;
55705 
55706   // New data source instance starts out in CONFIGURED state.
55707   if (tracing_session->consumer_maybe_null) {
55708     tracing_session->consumer_maybe_null->OnDataSourceInstanceStateChange(
55709         *producer, *ds_instance);
55710   }
55711 
55712   DataSourceConfig& ds_config = ds_instance->config;
55713   ds_config.set_trace_duration_ms(tracing_session->config.duration_ms());
55714   ds_config.set_stop_timeout_ms(tracing_session->data_source_stop_timeout_ms());
55715   ds_config.set_enable_extra_guardrails(
55716       tracing_session->config.enable_extra_guardrails());
55717   if (tracing_session->consumer_uid == 1066 /* AID_STATSD */ &&
55718       tracing_session->config.statsd_metadata().triggering_config_uid() !=
55719           2000 /* AID_SHELL */
55720       && tracing_session->config.statsd_metadata().triggering_config_uid() !=
55721              0 /* AID_ROOT */) {
55722     // StatsD can be triggered either by shell, root or an app that has DUMP and
55723     // USAGE_STATS permission. When triggered by shell or root, we do not want
55724     // to consider the trace a trusted system trace, as it was initiated by the
55725     // user. Otherwise, it has to come from an app with DUMP and
55726     // PACKAGE_USAGE_STATS, which has to be preinstalled and trusted by the
55727     // system.
55728     // Check for shell / root: https://bit.ly/3b7oZNi
55729     // Check for DUMP or PACKAGE_USAGE_STATS: https://bit.ly/3ep0NrR
55730     ds_config.set_session_initiator(
55731         DataSourceConfig::SESSION_INITIATOR_TRUSTED_SYSTEM);
55732   } else {
55733     // Unset in case the consumer set it.
55734     // We need to be able to trust this field.
55735     ds_config.set_session_initiator(
55736         DataSourceConfig::SESSION_INITIATOR_UNSPECIFIED);
55737   }
55738   ds_config.set_tracing_session_id(tracing_session->id);
55739   BufferID global_id = tracing_session->buffers_index[relative_buffer_id];
55740   PERFETTO_DCHECK(global_id);
55741   ds_config.set_target_buffer(global_id);
55742 
55743   PERFETTO_DLOG("Setting up data source %s with target buffer %" PRIu16,
55744                 ds_config.name().c_str(), global_id);
55745   if (!producer->shared_memory()) {
55746     // Determine the SMB page size. Must be an integer multiple of 4k.
55747     // As for the SMB size below, the decision tree is as follows:
55748     // 1. Give priority to what is defined in the trace config.
55749     // 2. If unset give priority to the hint passed by the producer.
55750     // 3. Keep within bounds and ensure it's a multiple of 4k.
55751     size_t page_size = producer_config.page_size_kb() * 1024;
55752     if (page_size == 0)
55753       page_size = producer->shmem_page_size_hint_bytes_;
55754 
55755     // Determine the SMB size. Must be an integer multiple of the SMB page size.
55756     // The decision tree is as follows:
55757     // 1. Give priority to what defined in the trace config.
55758     // 2. If unset give priority to the hint passed by the producer.
55759     // 3. Keep within bounds and ensure it's a multiple of the page size.
55760     size_t shm_size = producer_config.shm_size_kb() * 1024;
55761     if (shm_size == 0)
55762       shm_size = producer->shmem_size_hint_bytes_;
55763 
55764     auto valid_sizes = EnsureValidShmSizes(shm_size, page_size);
55765     if (valid_sizes != std::tie(shm_size, page_size)) {
55766       PERFETTO_DLOG(
55767           "Invalid configured SMB sizes: shm_size %zu page_size %zu. Falling "
55768           "back to shm_size %zu page_size %zu.",
55769           shm_size, page_size, std::get<0>(valid_sizes),
55770           std::get<1>(valid_sizes));
55771     }
55772     std::tie(shm_size, page_size) = valid_sizes;
55773 
55774     // TODO(primiano): right now Create() will suicide in case of OOM if the
55775     // mmap fails. We should instead gracefully fail the request and tell the
55776     // client to go away.
55777     PERFETTO_DLOG("Creating SMB of %zu KB for producer \"%s\"", shm_size / 1024,
55778                   producer->name_.c_str());
55779     auto shared_memory = shm_factory_->CreateSharedMemory(shm_size);
55780     producer->SetupSharedMemory(std::move(shared_memory), page_size,
55781                                 /*provided_by_producer=*/false);
55782   }
55783   producer->SetupDataSource(inst_id, ds_config);
55784   return ds_instance;
55785 }
55786 
55787 // Note: all the fields % *_trusted ones are untrusted, as in, the Producer
55788 // might be lying / returning garbage contents. |src| and |size| can be trusted
55789 // 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)55790 void TracingServiceImpl::CopyProducerPageIntoLogBuffer(
55791     ProducerID producer_id_trusted,
55792     uid_t producer_uid_trusted,
55793     WriterID writer_id,
55794     ChunkID chunk_id,
55795     BufferID buffer_id,
55796     uint16_t num_fragments,
55797     uint8_t chunk_flags,
55798     bool chunk_complete,
55799     const uint8_t* src,
55800     size_t size) {
55801   PERFETTO_DCHECK_THREAD(thread_checker_);
55802 
55803   ProducerEndpointImpl* producer = GetProducer(producer_id_trusted);
55804   if (!producer) {
55805     PERFETTO_DFATAL("Producer not found.");
55806     chunks_discarded_++;
55807     return;
55808   }
55809 
55810   TraceBuffer* buf = GetBufferByID(buffer_id);
55811   if (!buf) {
55812     PERFETTO_DLOG("Could not find target buffer %" PRIu16
55813                   " for producer %" PRIu16,
55814                   buffer_id, producer_id_trusted);
55815     chunks_discarded_++;
55816     return;
55817   }
55818 
55819   // Verify that the producer is actually allowed to write into the target
55820   // buffer specified in the request. This prevents a malicious producer from
55821   // injecting data into a log buffer that belongs to a tracing session the
55822   // producer is not part of.
55823   if (!producer->is_allowed_target_buffer(buffer_id)) {
55824     PERFETTO_ELOG("Producer %" PRIu16
55825                   " tried to write into forbidden target buffer %" PRIu16,
55826                   producer_id_trusted, buffer_id);
55827     PERFETTO_DFATAL("Forbidden target buffer");
55828     chunks_discarded_++;
55829     return;
55830   }
55831 
55832   // If the writer was registered by the producer, it should only write into the
55833   // buffer it was registered with.
55834   base::Optional<BufferID> associated_buffer =
55835       producer->buffer_id_for_writer(writer_id);
55836   if (associated_buffer && *associated_buffer != buffer_id) {
55837     PERFETTO_ELOG("Writer %" PRIu16 " of producer %" PRIu16
55838                   " was registered to write into target buffer %" PRIu16
55839                   ", but tried to write into buffer %" PRIu16,
55840                   writer_id, producer_id_trusted, *associated_buffer,
55841                   buffer_id);
55842     PERFETTO_DFATAL("Wrong target buffer");
55843     chunks_discarded_++;
55844     return;
55845   }
55846 
55847   buf->CopyChunkUntrusted(producer_id_trusted, producer_uid_trusted, writer_id,
55848                           chunk_id, num_fragments, chunk_flags, chunk_complete,
55849                           src, size);
55850 }
55851 
ApplyChunkPatches(ProducerID producer_id_trusted,const std::vector<CommitDataRequest::ChunkToPatch> & chunks_to_patch)55852 void TracingServiceImpl::ApplyChunkPatches(
55853     ProducerID producer_id_trusted,
55854     const std::vector<CommitDataRequest::ChunkToPatch>& chunks_to_patch) {
55855   PERFETTO_DCHECK_THREAD(thread_checker_);
55856 
55857   for (const auto& chunk : chunks_to_patch) {
55858     const ChunkID chunk_id = static_cast<ChunkID>(chunk.chunk_id());
55859     const WriterID writer_id = static_cast<WriterID>(chunk.writer_id());
55860     TraceBuffer* buf =
55861         GetBufferByID(static_cast<BufferID>(chunk.target_buffer()));
55862     static_assert(std::numeric_limits<ChunkID>::max() == kMaxChunkID,
55863                   "Add a '|| chunk_id > kMaxChunkID' below if this fails");
55864     if (!writer_id || writer_id > kMaxWriterID || !buf) {
55865       // This can genuinely happen when the trace is stopped. The producers
55866       // might see the stop signal with some delay and try to keep sending
55867       // patches left soon after.
55868       PERFETTO_DLOG(
55869           "Received invalid chunks_to_patch request from Producer: %" PRIu16
55870           ", BufferID: %" PRIu32 " ChunkdID: %" PRIu32 " WriterID: %" PRIu16,
55871           producer_id_trusted, chunk.target_buffer(), chunk_id, writer_id);
55872       patches_discarded_ += static_cast<uint64_t>(chunk.patches_size());
55873       continue;
55874     }
55875 
55876     // Note, there's no need to validate that the producer is allowed to write
55877     // to the specified buffer ID (or that it's the correct buffer ID for a
55878     // registered TraceWriter). That's because TraceBuffer uses the producer ID
55879     // and writer ID to look up the chunk to patch. If the producer specifies an
55880     // incorrect buffer, this lookup will fail and TraceBuffer will ignore the
55881     // patches. Because the producer ID is trusted, there's also no way for a
55882     // malicious producer to patch another producer's data.
55883 
55884     // Speculate on the fact that there are going to be a limited amount of
55885     // patches per request, so we can allocate the |patches| array on the stack.
55886     std::array<TraceBuffer::Patch, 1024> patches;  // Uninitialized.
55887     if (chunk.patches().size() > patches.size()) {
55888       PERFETTO_ELOG("Too many patches (%zu) batched in the same request",
55889                     patches.size());
55890       PERFETTO_DFATAL("Too many patches");
55891       patches_discarded_ += static_cast<uint64_t>(chunk.patches_size());
55892       continue;
55893     }
55894 
55895     size_t i = 0;
55896     for (const auto& patch : chunk.patches()) {
55897       const std::string& patch_data = patch.data();
55898       if (patch_data.size() != patches[i].data.size()) {
55899         PERFETTO_ELOG("Received patch from producer: %" PRIu16
55900                       " of unexpected size %zu",
55901                       producer_id_trusted, patch_data.size());
55902         patches_discarded_++;
55903         continue;
55904       }
55905       patches[i].offset_untrusted = patch.offset();
55906       memcpy(&patches[i].data[0], patch_data.data(), patches[i].data.size());
55907       i++;
55908     }
55909     buf->TryPatchChunkContents(producer_id_trusted, writer_id, chunk_id,
55910                                &patches[0], i, chunk.has_more_patches());
55911   }
55912 }
55913 
GetDetachedSession(uid_t uid,const std::string & key)55914 TracingServiceImpl::TracingSession* TracingServiceImpl::GetDetachedSession(
55915     uid_t uid,
55916     const std::string& key) {
55917   PERFETTO_DCHECK_THREAD(thread_checker_);
55918   for (auto& kv : tracing_sessions_) {
55919     TracingSession* session = &kv.second;
55920     if (session->consumer_uid == uid && session->detach_key == key) {
55921       PERFETTO_DCHECK(session->consumer_maybe_null == nullptr);
55922       return session;
55923     }
55924   }
55925   return nullptr;
55926 }
55927 
GetTracingSession(TracingSessionID tsid)55928 TracingServiceImpl::TracingSession* TracingServiceImpl::GetTracingSession(
55929     TracingSessionID tsid) {
55930   PERFETTO_DCHECK_THREAD(thread_checker_);
55931   auto it = tsid ? tracing_sessions_.find(tsid) : tracing_sessions_.end();
55932   if (it == tracing_sessions_.end())
55933     return nullptr;
55934   return &it->second;
55935 }
55936 
GetNextProducerID()55937 ProducerID TracingServiceImpl::GetNextProducerID() {
55938   PERFETTO_DCHECK_THREAD(thread_checker_);
55939   PERFETTO_CHECK(producers_.size() < kMaxProducerID);
55940   do {
55941     ++last_producer_id_;
55942   } while (producers_.count(last_producer_id_) || last_producer_id_ == 0);
55943   PERFETTO_DCHECK(last_producer_id_ > 0 && last_producer_id_ <= kMaxProducerID);
55944   return last_producer_id_;
55945 }
55946 
GetBufferByID(BufferID buffer_id)55947 TraceBuffer* TracingServiceImpl::GetBufferByID(BufferID buffer_id) {
55948   auto buf_iter = buffers_.find(buffer_id);
55949   if (buf_iter == buffers_.end())
55950     return nullptr;
55951   return &*buf_iter->second;
55952 }
55953 
OnStartTriggersTimeout(TracingSessionID tsid)55954 void TracingServiceImpl::OnStartTriggersTimeout(TracingSessionID tsid) {
55955   // Skip entirely the flush if the trace session doesn't exist anymore.
55956   // This is to prevent misleading error messages to be logged.
55957   //
55958   // if the trace has started from the trigger we rely on
55959   // the |stop_delay_ms| from the trigger so don't flush and
55960   // disable if we've moved beyond a CONFIGURED state
55961   auto* tracing_session_ptr = GetTracingSession(tsid);
55962   if (tracing_session_ptr &&
55963       tracing_session_ptr->state == TracingSession::CONFIGURED) {
55964     PERFETTO_DLOG("Disabling TracingSession %" PRIu64
55965                   " since no triggers activated.",
55966                   tsid);
55967     // No data should be returned from ReadBuffers() regardless of if we
55968     // call FreeBuffers() or DisableTracing(). This is because in
55969     // STOP_TRACING we need this promise in either case, and using
55970     // DisableTracing() allows a graceful shutdown. Consumers can follow
55971     // their normal path and check the buffers through ReadBuffers() and
55972     // the code won't hang because the tracing session will still be
55973     // alive just disabled.
55974     DisableTracing(tsid);
55975   }
55976 }
55977 
UpdateMemoryGuardrail()55978 void TracingServiceImpl::UpdateMemoryGuardrail() {
55979 #if PERFETTO_BUILDFLAG(PERFETTO_WATCHDOG)
55980   uint64_t total_buffer_bytes = 0;
55981 
55982   // Sum up all the shared memory buffers.
55983   for (const auto& id_to_producer : producers_) {
55984     if (id_to_producer.second->shared_memory())
55985       total_buffer_bytes += id_to_producer.second->shared_memory()->size();
55986   }
55987 
55988   // Sum up all the trace buffers.
55989   for (const auto& id_to_buffer : buffers_) {
55990     total_buffer_bytes += id_to_buffer.second->size();
55991   }
55992 
55993   // Set the guard rail to 32MB + the sum of all the buffers over a 30 second
55994   // interval.
55995   uint64_t guardrail = base::kWatchdogDefaultMemorySlack + total_buffer_bytes;
55996   base::Watchdog::GetInstance()->SetMemoryLimit(guardrail, 30 * 1000);
55997 #endif
55998 }
55999 
PeriodicSnapshotTask(TracingSessionID tsid)56000 void TracingServiceImpl::PeriodicSnapshotTask(TracingSessionID tsid) {
56001   auto* tracing_session = GetTracingSession(tsid);
56002   if (!tracing_session)
56003     return;
56004   if (tracing_session->state != TracingSession::STARTED)
56005     return;
56006   tracing_session->should_emit_sync_marker = true;
56007   tracing_session->should_emit_stats = true;
56008   MaybeSnapshotClocksIntoRingBuffer(tracing_session);
56009 }
56010 
SnapshotLifecyleEvent(TracingSession * tracing_session,uint32_t field_id,bool snapshot_clocks)56011 void TracingServiceImpl::SnapshotLifecyleEvent(TracingSession* tracing_session,
56012                                                uint32_t field_id,
56013                                                bool snapshot_clocks) {
56014   // field_id should be an id of a field in TracingServiceEvent.
56015   auto& lifecycle_events = tracing_session->lifecycle_events;
56016   auto event_it =
56017       std::find_if(lifecycle_events.begin(), lifecycle_events.end(),
56018                    [field_id](const TracingSession::LifecycleEvent& event) {
56019                      return event.field_id == field_id;
56020                    });
56021 
56022   TracingSession::LifecycleEvent* event;
56023   if (event_it == lifecycle_events.end()) {
56024     lifecycle_events.emplace_back(field_id);
56025     event = &lifecycle_events.back();
56026   } else {
56027     event = &*event_it;
56028   }
56029 
56030   // Snapshot the clocks before capturing the timestamp for the event so we can
56031   // use this snapshot to resolve the event timestamp if necessary.
56032   if (snapshot_clocks)
56033     MaybeSnapshotClocksIntoRingBuffer(tracing_session);
56034 
56035   // Erase before emplacing to prevent a unncessary doubling of memory if
56036   // not needed.
56037   if (event->timestamps.size() >= event->max_size) {
56038     event->timestamps.erase_front(1 + event->timestamps.size() -
56039                                   event->max_size);
56040   }
56041   event->timestamps.emplace_back(base::GetBootTimeNs().count());
56042 }
56043 
MaybeSnapshotClocksIntoRingBuffer(TracingSession * tracing_session)56044 void TracingServiceImpl::MaybeSnapshotClocksIntoRingBuffer(
56045     TracingSession* tracing_session) {
56046   if (tracing_session->config.builtin_data_sources()
56047           .disable_clock_snapshotting()) {
56048     return;
56049   }
56050 
56051   // We are making an explicit copy of the latest snapshot (if it exists)
56052   // because SnapshotClocks reads this data and computes the drift based on its
56053   // content. If the clock drift is high enough, it will update the contents of
56054   // |snapshot| and return true. Otherwise, it will return false.
56055   TracingSession::ClockSnapshotData snapshot =
56056       tracing_session->clock_snapshot_ring_buffer.empty()
56057           ? TracingSession::ClockSnapshotData()
56058           : tracing_session->clock_snapshot_ring_buffer.back();
56059   bool did_update = SnapshotClocks(&snapshot);
56060   if (did_update) {
56061     // This means clocks drifted enough since last snapshot. See the comment
56062     // in SnapshotClocks.
56063     auto* snapshot_buffer = &tracing_session->clock_snapshot_ring_buffer;
56064 
56065     // Erase before emplacing to prevent a unncessary doubling of memory if
56066     // not needed.
56067     static constexpr uint32_t kClockSnapshotRingBufferSize = 16;
56068     if (snapshot_buffer->size() >= kClockSnapshotRingBufferSize) {
56069       snapshot_buffer->erase_front(1 + snapshot_buffer->size() -
56070                                    kClockSnapshotRingBufferSize);
56071     }
56072     snapshot_buffer->emplace_back(std::move(snapshot));
56073   }
56074 }
56075 
56076 // Returns true when the data in |snapshot_data| is updated with the new state
56077 // of the clocks and false otherwise.
SnapshotClocks(TracingSession::ClockSnapshotData * snapshot_data)56078 bool TracingServiceImpl::SnapshotClocks(
56079     TracingSession::ClockSnapshotData* snapshot_data) {
56080   // Minimum drift that justifies replacing a prior clock snapshot that hasn't
56081   // been emitted into the trace yet (see comment below).
56082   static constexpr int64_t kSignificantDriftNs = 10 * 1000 * 1000;  // 10 ms
56083 
56084   TracingSession::ClockSnapshotData new_snapshot_data;
56085 
56086 #if !PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE) && \
56087     !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) &&   \
56088     !PERFETTO_BUILDFLAG(PERFETTO_OS_NACL)
56089   struct {
56090     clockid_t id;
56091     protos::pbzero::BuiltinClock type;
56092     struct timespec ts;
56093   } clocks[] = {
56094       {CLOCK_BOOTTIME, protos::pbzero::BUILTIN_CLOCK_BOOTTIME, {0, 0}},
56095       {CLOCK_REALTIME_COARSE,
56096        protos::pbzero::BUILTIN_CLOCK_REALTIME_COARSE,
56097        {0, 0}},
56098       {CLOCK_MONOTONIC_COARSE,
56099        protos::pbzero::BUILTIN_CLOCK_MONOTONIC_COARSE,
56100        {0, 0}},
56101       {CLOCK_REALTIME, protos::pbzero::BUILTIN_CLOCK_REALTIME, {0, 0}},
56102       {CLOCK_MONOTONIC, protos::pbzero::BUILTIN_CLOCK_MONOTONIC, {0, 0}},
56103       {CLOCK_MONOTONIC_RAW,
56104        protos::pbzero::BUILTIN_CLOCK_MONOTONIC_RAW,
56105        {0, 0}},
56106   };
56107   // First snapshot all the clocks as atomically as we can.
56108   for (auto& clock : clocks) {
56109     if (clock_gettime(clock.id, &clock.ts) == -1)
56110       PERFETTO_DLOG("clock_gettime failed for clock %d", clock.id);
56111   }
56112   for (auto& clock : clocks) {
56113     new_snapshot_data.push_back(std::make_pair(
56114         static_cast<uint32_t>(clock.type),
56115         static_cast<uint64_t>(base::FromPosixTimespec(clock.ts).count())));
56116   }
56117 #else  // OS_APPLE || OS_WIN && OS_NACL
56118   auto wall_time_ns = static_cast<uint64_t>(base::GetWallTimeNs().count());
56119   // The default trace clock is boot time, so we always need to emit a path to
56120   // it. However since we don't actually have a boot time source on these
56121   // platforms, pretend that wall time equals boot time.
56122   new_snapshot_data.push_back(
56123       std::make_pair(protos::pbzero::BUILTIN_CLOCK_BOOTTIME, wall_time_ns));
56124   new_snapshot_data.push_back(
56125       std::make_pair(protos::pbzero::BUILTIN_CLOCK_MONOTONIC, wall_time_ns));
56126 #endif
56127 
56128   // If we're about to update a session's latest clock snapshot that hasn't been
56129   // emitted into the trace yet, check whether the clocks have drifted enough to
56130   // warrant overriding the current snapshot values. The older snapshot would be
56131   // valid for a larger part of the currently buffered trace data because the
56132   // clock sync protocol in trace processor uses the latest clock <= timestamp
56133   // to translate times (see https://perfetto.dev/docs/concepts/clock-sync), so
56134   // we try to keep it if we can.
56135   if (!snapshot_data->empty()) {
56136     PERFETTO_DCHECK(snapshot_data->size() == new_snapshot_data.size());
56137     PERFETTO_DCHECK((*snapshot_data)[0].first ==
56138                     protos::gen::BUILTIN_CLOCK_BOOTTIME);
56139 
56140     bool update_snapshot = false;
56141     uint64_t old_boot_ns = (*snapshot_data)[0].second;
56142     uint64_t new_boot_ns = new_snapshot_data[0].second;
56143     int64_t boot_diff =
56144         static_cast<int64_t>(new_boot_ns) - static_cast<int64_t>(old_boot_ns);
56145 
56146     for (size_t i = 1; i < snapshot_data->size(); i++) {
56147       uint64_t old_ns = (*snapshot_data)[i].second;
56148       uint64_t new_ns = new_snapshot_data[i].second;
56149 
56150       int64_t diff =
56151           static_cast<int64_t>(new_ns) - static_cast<int64_t>(old_ns);
56152 
56153       // Compare the boottime delta against the delta of this clock.
56154       if (std::abs(boot_diff - diff) >= kSignificantDriftNs) {
56155         update_snapshot = true;
56156         break;
56157       }
56158     }
56159     if (!update_snapshot)
56160       return false;
56161     snapshot_data->clear();
56162   }
56163 
56164   *snapshot_data = std::move(new_snapshot_data);
56165   return true;
56166 }
56167 
EmitClockSnapshot(TracingSession * tracing_session,TracingSession::ClockSnapshotData snapshot_data,std::vector<TracePacket> * packets)56168 void TracingServiceImpl::EmitClockSnapshot(
56169     TracingSession* tracing_session,
56170     TracingSession::ClockSnapshotData snapshot_data,
56171     std::vector<TracePacket>* packets) {
56172   PERFETTO_DCHECK(!tracing_session->config.builtin_data_sources()
56173                        .disable_clock_snapshotting());
56174 
56175   protozero::HeapBuffered<protos::pbzero::TracePacket> packet;
56176   auto* snapshot = packet->set_clock_snapshot();
56177 
56178   protos::gen::BuiltinClock trace_clock =
56179       tracing_session->config.builtin_data_sources().primary_trace_clock();
56180   if (!trace_clock)
56181     trace_clock = protos::gen::BUILTIN_CLOCK_BOOTTIME;
56182   snapshot->set_primary_trace_clock(
56183       static_cast<protos::pbzero::BuiltinClock>(trace_clock));
56184 
56185   for (auto& clock_id_and_ts : snapshot_data) {
56186     auto* c = snapshot->add_clocks();
56187     c->set_clock_id(clock_id_and_ts.first);
56188     c->set_timestamp(clock_id_and_ts.second);
56189   }
56190 
56191   packet->set_trusted_uid(static_cast<int32_t>(uid_));
56192   packet->set_trusted_packet_sequence_id(kServicePacketSequenceID);
56193   SerializeAndAppendPacket(packets, packet.SerializeAsArray());
56194 }
56195 
EmitSyncMarker(std::vector<TracePacket> * packets)56196 void TracingServiceImpl::EmitSyncMarker(std::vector<TracePacket>* packets) {
56197   // The sync marks are used to tokenize large traces efficiently.
56198   // See description in trace_packet.proto.
56199   if (sync_marker_packet_size_ == 0) {
56200     // The marker ABI expects that the marker is written after the uid.
56201     // Protozero guarantees that fields are written in the same order of the
56202     // calls. The ResynchronizeTraceStreamUsingSyncMarker test verifies the ABI.
56203     protozero::StaticBuffered<protos::pbzero::TracePacket> packet(
56204         &sync_marker_packet_[0], sizeof(sync_marker_packet_));
56205     packet->set_trusted_uid(static_cast<int32_t>(uid_));
56206     packet->set_trusted_packet_sequence_id(kServicePacketSequenceID);
56207 
56208     // Keep this last.
56209     packet->set_synchronization_marker(kSyncMarker, sizeof(kSyncMarker));
56210     sync_marker_packet_size_ = packet.Finalize();
56211   }
56212   packets->emplace_back();
56213   packets->back().AddSlice(&sync_marker_packet_[0], sync_marker_packet_size_);
56214 }
56215 
EmitStats(TracingSession * tracing_session,std::vector<TracePacket> * packets)56216 void TracingServiceImpl::EmitStats(TracingSession* tracing_session,
56217                                    std::vector<TracePacket>* packets) {
56218   protozero::HeapBuffered<protos::pbzero::TracePacket> packet;
56219   packet->set_trusted_uid(static_cast<int32_t>(uid_));
56220   packet->set_trusted_packet_sequence_id(kServicePacketSequenceID);
56221   GetTraceStats(tracing_session).Serialize(packet->set_trace_stats());
56222   SerializeAndAppendPacket(packets, packet.SerializeAsArray());
56223 }
56224 
GetTraceStats(TracingSession * tracing_session)56225 TraceStats TracingServiceImpl::GetTraceStats(TracingSession* tracing_session) {
56226   TraceStats trace_stats;
56227   trace_stats.set_producers_connected(static_cast<uint32_t>(producers_.size()));
56228   trace_stats.set_producers_seen(last_producer_id_);
56229   trace_stats.set_data_sources_registered(
56230       static_cast<uint32_t>(data_sources_.size()));
56231   trace_stats.set_data_sources_seen(last_data_source_instance_id_);
56232   trace_stats.set_tracing_sessions(
56233       static_cast<uint32_t>(tracing_sessions_.size()));
56234   trace_stats.set_total_buffers(static_cast<uint32_t>(buffers_.size()));
56235   trace_stats.set_chunks_discarded(chunks_discarded_);
56236   trace_stats.set_patches_discarded(patches_discarded_);
56237   trace_stats.set_invalid_packets(tracing_session->invalid_packets);
56238 
56239   if (tracing_session->trace_filter) {
56240     auto* filt_stats = trace_stats.mutable_filter_stats();
56241     filt_stats->set_input_packets(tracing_session->filter_input_packets);
56242     filt_stats->set_input_bytes(tracing_session->filter_input_bytes);
56243     filt_stats->set_output_bytes(tracing_session->filter_output_bytes);
56244     filt_stats->set_errors(tracing_session->filter_errors);
56245   }
56246 
56247   for (BufferID buf_id : tracing_session->buffers_index) {
56248     TraceBuffer* buf = GetBufferByID(buf_id);
56249     if (!buf) {
56250       PERFETTO_DFATAL("Buffer not found.");
56251       continue;
56252     }
56253     *trace_stats.add_buffer_stats() = buf->stats();
56254   }  // for (buf in session).
56255   return trace_stats;
56256 }
56257 
MaybeEmitTraceConfig(TracingSession * tracing_session,std::vector<TracePacket> * packets)56258 void TracingServiceImpl::MaybeEmitTraceConfig(
56259     TracingSession* tracing_session,
56260     std::vector<TracePacket>* packets) {
56261   if (tracing_session->did_emit_config)
56262     return;
56263   tracing_session->did_emit_config = true;
56264   protozero::HeapBuffered<protos::pbzero::TracePacket> packet;
56265   packet->set_trusted_uid(static_cast<int32_t>(uid_));
56266   packet->set_trusted_packet_sequence_id(kServicePacketSequenceID);
56267   tracing_session->config.Serialize(packet->set_trace_config());
56268   SerializeAndAppendPacket(packets, packet.SerializeAsArray());
56269 }
56270 
MaybeEmitSystemInfo(TracingSession * tracing_session,std::vector<TracePacket> * packets)56271 void TracingServiceImpl::MaybeEmitSystemInfo(
56272     TracingSession* tracing_session,
56273     std::vector<TracePacket>* packets) {
56274   if (tracing_session->did_emit_system_info)
56275     return;
56276   tracing_session->did_emit_system_info = true;
56277   protozero::HeapBuffered<protos::pbzero::TracePacket> packet;
56278   auto* info = packet->set_system_info();
56279   info->set_tracing_service_version(base::GetVersionString());
56280 #if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) && \
56281     !PERFETTO_BUILDFLAG(PERFETTO_OS_NACL)
56282   struct utsname uname_info;
56283   if (uname(&uname_info) == 0) {
56284     auto* utsname_info = info->set_utsname();
56285     utsname_info->set_sysname(uname_info.sysname);
56286     utsname_info->set_version(uname_info.version);
56287     utsname_info->set_machine(uname_info.machine);
56288     utsname_info->set_release(uname_info.release);
56289   }
56290 #endif  // !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
56291 #if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
56292   std::string fingerprint_value = base::GetAndroidProp("ro.build.fingerprint");
56293   if (!fingerprint_value.empty()) {
56294     info->set_android_build_fingerprint(fingerprint_value);
56295   } else {
56296     PERFETTO_ELOG("Unable to read ro.build.fingerprint");
56297   }
56298 
56299   std::string sdk_str_value = base::GetAndroidProp("ro.build.version.sdk");
56300   base::Optional<uint64_t> sdk_value = base::StringToUInt64(sdk_str_value);
56301   if (sdk_value.has_value()) {
56302     info->set_android_sdk_version(*sdk_value);
56303   } else {
56304     PERFETTO_ELOG("Unable to read ro.build.version.sdk");
56305   }
56306   info->set_hz(sysconf(_SC_CLK_TCK));
56307 #endif  // PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
56308   packet->set_trusted_uid(static_cast<int32_t>(uid_));
56309   packet->set_trusted_packet_sequence_id(kServicePacketSequenceID);
56310   SerializeAndAppendPacket(packets, packet.SerializeAsArray());
56311 }
56312 
EmitLifecycleEvents(TracingSession * tracing_session,std::vector<TracePacket> * packets)56313 void TracingServiceImpl::EmitLifecycleEvents(
56314     TracingSession* tracing_session,
56315     std::vector<TracePacket>* packets) {
56316   using TimestampedPacket =
56317       std::pair<int64_t /* ts */, std::vector<uint8_t> /* serialized packet */>;
56318 
56319   std::vector<TimestampedPacket> timestamped_packets;
56320   for (auto& event : tracing_session->lifecycle_events) {
56321     for (int64_t ts : event.timestamps) {
56322       protozero::HeapBuffered<protos::pbzero::TracePacket> packet;
56323       packet->set_timestamp(static_cast<uint64_t>(ts));
56324       packet->set_trusted_uid(static_cast<int32_t>(uid_));
56325       packet->set_trusted_packet_sequence_id(kServicePacketSequenceID);
56326 
56327       auto* service_event = packet->set_service_event();
56328       service_event->AppendVarInt(event.field_id, 1);
56329       timestamped_packets.emplace_back(ts, packet.SerializeAsArray());
56330     }
56331     event.timestamps.clear();
56332   }
56333 
56334   // We sort by timestamp here to ensure that the "sequence" of lifecycle
56335   // packets has monotonic timestamps like other sequences in the trace.
56336   // Note that these events could still be out of order with respect to other
56337   // events on the service packet sequence (e.g. trigger received packets).
56338   std::sort(timestamped_packets.begin(), timestamped_packets.end(),
56339             [](const TimestampedPacket& a, const TimestampedPacket& b) {
56340               return a.first < b.first;
56341             });
56342 
56343   for (const auto& pair : timestamped_packets)
56344     SerializeAndAppendPacket(packets, std::move(pair.second));
56345 }
56346 
EmitSeizedForBugreportLifecycleEvent(std::vector<TracePacket> * packets)56347 void TracingServiceImpl::EmitSeizedForBugreportLifecycleEvent(
56348     std::vector<TracePacket>* packets) {
56349   protozero::HeapBuffered<protos::pbzero::TracePacket> packet;
56350   packet->set_timestamp(static_cast<uint64_t>(base::GetBootTimeNs().count()));
56351   packet->set_trusted_uid(static_cast<int32_t>(uid_));
56352   packet->set_trusted_packet_sequence_id(kServicePacketSequenceID);
56353   auto* service_event = packet->set_service_event();
56354   service_event->AppendVarInt(
56355       protos::pbzero::TracingServiceEvent::kSeizedForBugreportFieldNumber, 1);
56356   SerializeAndAppendPacket(packets, packet.SerializeAsArray());
56357 }
56358 
MaybeEmitReceivedTriggers(TracingSession * tracing_session,std::vector<TracePacket> * packets)56359 void TracingServiceImpl::MaybeEmitReceivedTriggers(
56360     TracingSession* tracing_session,
56361     std::vector<TracePacket>* packets) {
56362   PERFETTO_DCHECK(tracing_session->num_triggers_emitted_into_trace <=
56363                   tracing_session->received_triggers.size());
56364   for (size_t i = tracing_session->num_triggers_emitted_into_trace;
56365        i < tracing_session->received_triggers.size(); ++i) {
56366     const auto& info = tracing_session->received_triggers[i];
56367     protozero::HeapBuffered<protos::pbzero::TracePacket> packet;
56368     auto* trigger = packet->set_trigger();
56369     trigger->set_trigger_name(info.trigger_name);
56370     trigger->set_producer_name(info.producer_name);
56371     trigger->set_trusted_producer_uid(static_cast<int32_t>(info.producer_uid));
56372 
56373     packet->set_timestamp(info.boot_time_ns);
56374     packet->set_trusted_uid(static_cast<int32_t>(uid_));
56375     packet->set_trusted_packet_sequence_id(kServicePacketSequenceID);
56376     SerializeAndAppendPacket(packets, packet.SerializeAsArray());
56377     ++tracing_session->num_triggers_emitted_into_trace;
56378   }
56379 }
56380 
MaybeSaveTraceForBugreport(std::function<void ()> callback)56381 bool TracingServiceImpl::MaybeSaveTraceForBugreport(
56382     std::function<void()> callback) {
56383   TracingSession* max_session = nullptr;
56384   TracingSessionID max_tsid = 0;
56385   for (auto& session_id_and_session : tracing_sessions_) {
56386     auto& session = session_id_and_session.second;
56387     const int32_t score = session.config.bugreport_score();
56388     // Exclude sessions with 0 (or below) score. By default tracing sessions
56389     // should NOT be eligible to be attached to bugreports.
56390     if (score <= 0 || session.state != TracingSession::STARTED)
56391       continue;
56392 
56393     // Also don't try to steal long traces with write_into_file if their content
56394     // has been already partially written into a file, as we would get partial
56395     // traces on both sides. We can't just copy the original file into the
56396     // bugreport because the file could be too big (GBs) for bugreports.
56397     // The only case where it's legit to steal traces with write_into_file, is
56398     // when the consumer specified a very large write_period_ms (e.g. 24h),
56399     // meaning that this is effectively a ring-buffer trace. Traceur (the
56400     // Android System Tracing app), which uses --detach, does this to have a
56401     // consistent invocation path for long-traces and ring-buffer-mode traces.
56402     if (session.write_into_file && session.bytes_written_into_file > 0)
56403       continue;
56404 
56405     // If we are already in the process of finalizing another trace for
56406     // bugreport, don't even start another one, as they would try to write onto
56407     // the same file.
56408     if (session.on_disable_callback_for_bugreport)
56409       return false;
56410 
56411     if (!max_session || score > max_session->config.bugreport_score()) {
56412       max_session = &session;
56413       max_tsid = session_id_and_session.first;
56414     }
56415   }
56416 
56417   // No eligible trace found.
56418   if (!max_session)
56419     return false;
56420 
56421   PERFETTO_LOG("Seizing trace for bugreport. tsid:%" PRIu64
56422                " state:%d wf:%d score:%d name:\"%s\"",
56423                max_tsid, max_session->state, !!max_session->write_into_file,
56424                max_session->config.bugreport_score(),
56425                max_session->config.unique_session_name().c_str());
56426 
56427   auto br_fd = CreateTraceFile(GetBugreportTmpPath(), /*overwrite=*/true);
56428   if (!br_fd)
56429     return false;
56430 
56431   if (max_session->write_into_file) {
56432     auto fd = *max_session->write_into_file;
56433     // If we are stealing a write_into_file session, add a marker that explains
56434     // why the trace has been stolen rather than creating an empty file. This is
56435     // only for write_into_file traces. A similar code path deals with the case
56436     // of reading-back a seized trace from IPC in ReadBuffers().
56437     if (!max_session->config.builtin_data_sources().disable_service_events()) {
56438       std::vector<TracePacket> packets;
56439       EmitSeizedForBugreportLifecycleEvent(&packets);
56440       for (auto& packet : packets) {
56441         char* preamble;
56442         size_t preamble_size = 0;
56443         std::tie(preamble, preamble_size) = packet.GetProtoPreamble();
56444         base::WriteAll(fd, preamble, preamble_size);
56445         for (const Slice& slice : packet.slices()) {
56446           base::WriteAll(fd, slice.start, slice.size);
56447         }
56448       }  // for (packets)
56449     }    // if (!disable_service_events())
56450   }      // if (max_session->write_into_file)
56451   max_session->write_into_file = std::move(br_fd);
56452   max_session->on_disable_callback_for_bugreport = std::move(callback);
56453   max_session->seized_for_bugreport = true;
56454 
56455   // Post a task to avoid that early FlushAndDisableTracing() failures invoke
56456   // the callback before we return. That would re-enter in a weird way the
56457   // callstack of the calling ConsumerEndpointImpl::SaveTraceForBugreport().
56458   auto weak_this = weak_ptr_factory_.GetWeakPtr();
56459   task_runner_->PostTask([weak_this, max_tsid] {
56460     if (weak_this)
56461       weak_this->FlushAndDisableTracing(max_tsid);
56462   });
56463   return true;
56464 }
56465 
MaybeLogUploadEvent(const TraceConfig & cfg,PerfettoStatsdAtom atom,const std::string & trigger_name)56466 void TracingServiceImpl::MaybeLogUploadEvent(const TraceConfig& cfg,
56467                                              PerfettoStatsdAtom atom,
56468                                              const std::string& trigger_name) {
56469   if (!ShouldLogEvent(cfg))
56470     return;
56471 
56472   // If the UUID is not set for some reason, don't log anything.
56473   if (cfg.trace_uuid_lsb() == 0 && cfg.trace_uuid_msb() == 0)
56474     return;
56475 
56476   android_stats::MaybeLogUploadEvent(atom, cfg.trace_uuid_lsb(),
56477                                      cfg.trace_uuid_msb(), trigger_name);
56478 }
56479 
MaybeLogTriggerEvent(const TraceConfig & cfg,PerfettoTriggerAtom atom,const std::string & trigger_name)56480 void TracingServiceImpl::MaybeLogTriggerEvent(const TraceConfig& cfg,
56481                                               PerfettoTriggerAtom atom,
56482                                               const std::string& trigger_name) {
56483   if (!ShouldLogEvent(cfg))
56484     return;
56485   android_stats::MaybeLogTriggerEvent(atom, trigger_name);
56486 }
56487 
PurgeExpiredAndCountTriggerInWindow(int64_t now_ns,uint64_t trigger_name_hash)56488 size_t TracingServiceImpl::PurgeExpiredAndCountTriggerInWindow(
56489     int64_t now_ns,
56490     uint64_t trigger_name_hash) {
56491   PERFETTO_DCHECK(
56492       std::is_sorted(trigger_history_.begin(), trigger_history_.end()));
56493   size_t remove_count = 0;
56494   size_t trigger_count = 0;
56495   for (const TriggerHistory& h : trigger_history_) {
56496     if (h.timestamp_ns < now_ns - trigger_window_ns_) {
56497       remove_count++;
56498     } else if (h.name_hash == trigger_name_hash) {
56499       trigger_count++;
56500     }
56501   }
56502   trigger_history_.erase_front(remove_count);
56503   return trigger_count;
56504 }
56505 
56506 ////////////////////////////////////////////////////////////////////////////////
56507 // TracingServiceImpl::ConsumerEndpointImpl implementation
56508 ////////////////////////////////////////////////////////////////////////////////
56509 
ConsumerEndpointImpl(TracingServiceImpl * service,base::TaskRunner * task_runner,Consumer * consumer,uid_t uid)56510 TracingServiceImpl::ConsumerEndpointImpl::ConsumerEndpointImpl(
56511     TracingServiceImpl* service,
56512     base::TaskRunner* task_runner,
56513     Consumer* consumer,
56514     uid_t uid)
56515     : task_runner_(task_runner),
56516       service_(service),
56517       consumer_(consumer),
56518       uid_(uid),
56519       weak_ptr_factory_(this) {}
56520 
~ConsumerEndpointImpl()56521 TracingServiceImpl::ConsumerEndpointImpl::~ConsumerEndpointImpl() {
56522   service_->DisconnectConsumer(this);
56523   consumer_->OnDisconnect();
56524 }
56525 
NotifyOnTracingDisabled(const std::string & error)56526 void TracingServiceImpl::ConsumerEndpointImpl::NotifyOnTracingDisabled(
56527     const std::string& error) {
56528   PERFETTO_DCHECK_THREAD(thread_checker_);
56529   auto weak_this = weak_ptr_factory_.GetWeakPtr();
56530   task_runner_->PostTask([weak_this, error /* deliberate copy */] {
56531     if (weak_this)
56532       weak_this->consumer_->OnTracingDisabled(error);
56533   });
56534 }
56535 
EnableTracing(const TraceConfig & cfg,base::ScopedFile fd)56536 void TracingServiceImpl::ConsumerEndpointImpl::EnableTracing(
56537     const TraceConfig& cfg,
56538     base::ScopedFile fd) {
56539   PERFETTO_DCHECK_THREAD(thread_checker_);
56540   auto status = service_->EnableTracing(this, cfg, std::move(fd));
56541   if (!status.ok())
56542     NotifyOnTracingDisabled(status.message());
56543 }
56544 
ChangeTraceConfig(const TraceConfig & cfg)56545 void TracingServiceImpl::ConsumerEndpointImpl::ChangeTraceConfig(
56546     const TraceConfig& cfg) {
56547   if (!tracing_session_id_) {
56548     PERFETTO_LOG(
56549         "Consumer called ChangeTraceConfig() but tracing was "
56550         "not active");
56551     return;
56552   }
56553   service_->ChangeTraceConfig(this, cfg);
56554 }
56555 
StartTracing()56556 void TracingServiceImpl::ConsumerEndpointImpl::StartTracing() {
56557   PERFETTO_DCHECK_THREAD(thread_checker_);
56558   if (!tracing_session_id_) {
56559     PERFETTO_LOG("Consumer called StartTracing() but tracing was not active");
56560     return;
56561   }
56562   service_->StartTracing(tracing_session_id_);
56563 }
56564 
DisableTracing()56565 void TracingServiceImpl::ConsumerEndpointImpl::DisableTracing() {
56566   PERFETTO_DCHECK_THREAD(thread_checker_);
56567   if (!tracing_session_id_) {
56568     PERFETTO_LOG("Consumer called DisableTracing() but tracing was not active");
56569     return;
56570   }
56571   service_->DisableTracing(tracing_session_id_);
56572 }
56573 
ReadBuffers()56574 void TracingServiceImpl::ConsumerEndpointImpl::ReadBuffers() {
56575   PERFETTO_DCHECK_THREAD(thread_checker_);
56576   if (!tracing_session_id_) {
56577     PERFETTO_LOG("Consumer called ReadBuffers() but tracing was not active");
56578     consumer_->OnTraceData({}, /* has_more = */ false);
56579     return;
56580   }
56581   if (!service_->ReadBuffersIntoConsumer(tracing_session_id_, this)) {
56582     consumer_->OnTraceData({}, /* has_more = */ false);
56583   }
56584 }
56585 
FreeBuffers()56586 void TracingServiceImpl::ConsumerEndpointImpl::FreeBuffers() {
56587   PERFETTO_DCHECK_THREAD(thread_checker_);
56588   if (!tracing_session_id_) {
56589     PERFETTO_LOG("Consumer called FreeBuffers() but tracing was not active");
56590     return;
56591   }
56592   service_->FreeBuffers(tracing_session_id_);
56593   tracing_session_id_ = 0;
56594 }
56595 
Flush(uint32_t timeout_ms,FlushCallback callback)56596 void TracingServiceImpl::ConsumerEndpointImpl::Flush(uint32_t timeout_ms,
56597                                                      FlushCallback callback) {
56598   PERFETTO_DCHECK_THREAD(thread_checker_);
56599   if (!tracing_session_id_) {
56600     PERFETTO_LOG("Consumer called Flush() but tracing was not active");
56601     return;
56602   }
56603   service_->Flush(tracing_session_id_, timeout_ms, callback);
56604 }
56605 
Detach(const std::string & key)56606 void TracingServiceImpl::ConsumerEndpointImpl::Detach(const std::string& key) {
56607   PERFETTO_DCHECK_THREAD(thread_checker_);
56608   bool success = service_->DetachConsumer(this, key);
56609   auto weak_this = weak_ptr_factory_.GetWeakPtr();
56610   task_runner_->PostTask([weak_this, success] {
56611     if (weak_this)
56612       weak_this->consumer_->OnDetach(success);
56613   });
56614 }
56615 
Attach(const std::string & key)56616 void TracingServiceImpl::ConsumerEndpointImpl::Attach(const std::string& key) {
56617   PERFETTO_DCHECK_THREAD(thread_checker_);
56618   bool success = service_->AttachConsumer(this, key);
56619   auto weak_this = weak_ptr_factory_.GetWeakPtr();
56620   task_runner_->PostTask([weak_this, success] {
56621     if (!weak_this)
56622       return;
56623     Consumer* consumer = weak_this->consumer_;
56624     TracingSession* session =
56625         weak_this->service_->GetTracingSession(weak_this->tracing_session_id_);
56626     if (!session) {
56627       consumer->OnAttach(false, TraceConfig());
56628       return;
56629     }
56630     consumer->OnAttach(success, session->config);
56631   });
56632 }
56633 
GetTraceStats()56634 void TracingServiceImpl::ConsumerEndpointImpl::GetTraceStats() {
56635   PERFETTO_DCHECK_THREAD(thread_checker_);
56636   bool success = false;
56637   TraceStats stats;
56638   TracingSession* session = service_->GetTracingSession(tracing_session_id_);
56639   if (session) {
56640     success = true;
56641     stats = service_->GetTraceStats(session);
56642   }
56643   auto weak_this = weak_ptr_factory_.GetWeakPtr();
56644   task_runner_->PostTask([weak_this, success, stats] {
56645     if (weak_this)
56646       weak_this->consumer_->OnTraceStats(success, stats);
56647   });
56648 }
56649 
ObserveEvents(uint32_t events_mask)56650 void TracingServiceImpl::ConsumerEndpointImpl::ObserveEvents(
56651     uint32_t events_mask) {
56652   PERFETTO_DCHECK_THREAD(thread_checker_);
56653   observable_events_mask_ = events_mask;
56654   TracingSession* session = service_->GetTracingSession(tracing_session_id_);
56655   if (!session)
56656     return;
56657 
56658   if (observable_events_mask_ & ObservableEvents::TYPE_DATA_SOURCES_INSTANCES) {
56659     // Issue initial states.
56660     for (const auto& kv : session->data_source_instances) {
56661       ProducerEndpointImpl* producer = service_->GetProducer(kv.first);
56662       PERFETTO_DCHECK(producer);
56663       OnDataSourceInstanceStateChange(*producer, kv.second);
56664     }
56665   }
56666 
56667   // If the ObserveEvents() call happens after data sources have acked already
56668   // notify immediately.
56669   if (observable_events_mask_ &
56670       ObservableEvents::TYPE_ALL_DATA_SOURCES_STARTED) {
56671     service_->MaybeNotifyAllDataSourcesStarted(session);
56672   }
56673 }
56674 
OnDataSourceInstanceStateChange(const ProducerEndpointImpl & producer,const DataSourceInstance & instance)56675 void TracingServiceImpl::ConsumerEndpointImpl::OnDataSourceInstanceStateChange(
56676     const ProducerEndpointImpl& producer,
56677     const DataSourceInstance& instance) {
56678   if (!(observable_events_mask_ &
56679         ObservableEvents::TYPE_DATA_SOURCES_INSTANCES)) {
56680     return;
56681   }
56682 
56683   if (instance.state != DataSourceInstance::CONFIGURED &&
56684       instance.state != DataSourceInstance::STARTED &&
56685       instance.state != DataSourceInstance::STOPPED) {
56686     return;
56687   }
56688 
56689   auto* observable_events = AddObservableEvents();
56690   auto* change = observable_events->add_instance_state_changes();
56691   change->set_producer_name(producer.name_);
56692   change->set_data_source_name(instance.data_source_name);
56693   if (instance.state == DataSourceInstance::STARTED) {
56694     change->set_state(ObservableEvents::DATA_SOURCE_INSTANCE_STATE_STARTED);
56695   } else {
56696     change->set_state(ObservableEvents::DATA_SOURCE_INSTANCE_STATE_STOPPED);
56697   }
56698 }
56699 
OnAllDataSourcesStarted()56700 void TracingServiceImpl::ConsumerEndpointImpl::OnAllDataSourcesStarted() {
56701   if (!(observable_events_mask_ &
56702         ObservableEvents::TYPE_ALL_DATA_SOURCES_STARTED)) {
56703     return;
56704   }
56705   auto* observable_events = AddObservableEvents();
56706   observable_events->set_all_data_sources_started(true);
56707 }
56708 
56709 ObservableEvents*
AddObservableEvents()56710 TracingServiceImpl::ConsumerEndpointImpl::AddObservableEvents() {
56711   PERFETTO_DCHECK_THREAD(thread_checker_);
56712   if (!observable_events_) {
56713     observable_events_.reset(new ObservableEvents());
56714     auto weak_this = weak_ptr_factory_.GetWeakPtr();
56715     task_runner_->PostTask([weak_this] {
56716       if (!weak_this)
56717         return;
56718 
56719       // Move into a temporary to allow reentrancy in OnObservableEvents.
56720       auto observable_events = std::move(weak_this->observable_events_);
56721       weak_this->consumer_->OnObservableEvents(*observable_events);
56722     });
56723   }
56724   return observable_events_.get();
56725 }
56726 
QueryServiceState(QueryServiceStateCallback callback)56727 void TracingServiceImpl::ConsumerEndpointImpl::QueryServiceState(
56728     QueryServiceStateCallback callback) {
56729   PERFETTO_DCHECK_THREAD(thread_checker_);
56730   TracingServiceState svc_state;
56731 
56732   const auto& sessions = service_->tracing_sessions_;
56733   svc_state.set_tracing_service_version(base::GetVersionString());
56734   svc_state.set_num_sessions(static_cast<int>(sessions.size()));
56735 
56736   int num_started = 0;
56737   for (const auto& kv : sessions)
56738     num_started += kv.second.state == TracingSession::State::STARTED ? 1 : 0;
56739   svc_state.set_num_sessions_started(static_cast<int>(num_started));
56740 
56741   for (const auto& kv : service_->producers_) {
56742     auto* producer = svc_state.add_producers();
56743     producer->set_id(static_cast<int>(kv.first));
56744     producer->set_name(kv.second->name_);
56745     producer->set_sdk_version(kv.second->sdk_version_);
56746     producer->set_uid(static_cast<int32_t>(kv.second->uid()));
56747   }
56748 
56749   for (const auto& kv : service_->data_sources_) {
56750     const auto& registered_data_source = kv.second;
56751     auto* data_source = svc_state.add_data_sources();
56752     *data_source->mutable_ds_descriptor() = registered_data_source.descriptor;
56753     data_source->set_producer_id(
56754         static_cast<int>(registered_data_source.producer_id));
56755   }
56756   callback(/*success=*/true, svc_state);
56757 }
56758 
QueryCapabilities(QueryCapabilitiesCallback callback)56759 void TracingServiceImpl::ConsumerEndpointImpl::QueryCapabilities(
56760     QueryCapabilitiesCallback callback) {
56761   PERFETTO_DCHECK_THREAD(thread_checker_);
56762   TracingServiceCapabilities caps;
56763   caps.set_has_query_capabilities(true);
56764   caps.set_has_trace_config_output_path(true);
56765   caps.add_observable_events(ObservableEvents::TYPE_DATA_SOURCES_INSTANCES);
56766   caps.add_observable_events(ObservableEvents::TYPE_ALL_DATA_SOURCES_STARTED);
56767   static_assert(ObservableEvents::Type_MAX ==
56768                     ObservableEvents::TYPE_ALL_DATA_SOURCES_STARTED,
56769                 "");
56770   callback(caps);
56771 }
56772 
SaveTraceForBugreport(SaveTraceForBugreportCallback consumer_callback)56773 void TracingServiceImpl::ConsumerEndpointImpl::SaveTraceForBugreport(
56774     SaveTraceForBugreportCallback consumer_callback) {
56775   PERFETTO_DCHECK_THREAD(thread_checker_);
56776   auto on_complete_callback = [consumer_callback] {
56777     if (rename(GetBugreportTmpPath().c_str(), GetBugreportPath().c_str())) {
56778       consumer_callback(false, "rename(" + GetBugreportTmpPath() + ", " +
56779                                    GetBugreportPath() + ") failed (" +
56780                                    strerror(errno) + ")");
56781     } else {
56782       consumer_callback(true, GetBugreportPath());
56783     }
56784   };
56785   if (!service_->MaybeSaveTraceForBugreport(std::move(on_complete_callback))) {
56786     consumer_callback(false,
56787                       "No trace with TraceConfig.bugreport_score > 0 eligible "
56788                       "for bug reporting was found");
56789   }
56790 }
56791 
56792 ////////////////////////////////////////////////////////////////////////////////
56793 // TracingServiceImpl::ProducerEndpointImpl implementation
56794 ////////////////////////////////////////////////////////////////////////////////
56795 
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)56796 TracingServiceImpl::ProducerEndpointImpl::ProducerEndpointImpl(
56797     ProducerID id,
56798     uid_t uid,
56799     TracingServiceImpl* service,
56800     base::TaskRunner* task_runner,
56801     Producer* producer,
56802     const std::string& producer_name,
56803     const std::string& sdk_version,
56804     bool in_process,
56805     bool smb_scraping_enabled)
56806     : id_(id),
56807       uid_(uid),
56808       service_(service),
56809       task_runner_(task_runner),
56810       producer_(producer),
56811       name_(producer_name),
56812       sdk_version_(sdk_version),
56813       in_process_(in_process),
56814       smb_scraping_enabled_(smb_scraping_enabled),
56815       weak_ptr_factory_(this) {}
56816 
~ProducerEndpointImpl()56817 TracingServiceImpl::ProducerEndpointImpl::~ProducerEndpointImpl() {
56818   service_->DisconnectProducer(id_);
56819   producer_->OnDisconnect();
56820 }
56821 
RegisterDataSource(const DataSourceDescriptor & desc)56822 void TracingServiceImpl::ProducerEndpointImpl::RegisterDataSource(
56823     const DataSourceDescriptor& desc) {
56824   PERFETTO_DCHECK_THREAD(thread_checker_);
56825   service_->RegisterDataSource(id_, desc);
56826 }
56827 
UpdateDataSource(const DataSourceDescriptor & desc)56828 void TracingServiceImpl::ProducerEndpointImpl::UpdateDataSource(
56829     const DataSourceDescriptor& desc) {
56830   PERFETTO_DCHECK_THREAD(thread_checker_);
56831   service_->UpdateDataSource(id_, desc);
56832 }
56833 
UnregisterDataSource(const std::string & name)56834 void TracingServiceImpl::ProducerEndpointImpl::UnregisterDataSource(
56835     const std::string& name) {
56836   PERFETTO_DCHECK_THREAD(thread_checker_);
56837   service_->UnregisterDataSource(id_, name);
56838 }
56839 
RegisterTraceWriter(uint32_t writer_id,uint32_t target_buffer)56840 void TracingServiceImpl::ProducerEndpointImpl::RegisterTraceWriter(
56841     uint32_t writer_id,
56842     uint32_t target_buffer) {
56843   PERFETTO_DCHECK_THREAD(thread_checker_);
56844   writers_[static_cast<WriterID>(writer_id)] =
56845       static_cast<BufferID>(target_buffer);
56846 }
56847 
UnregisterTraceWriter(uint32_t writer_id)56848 void TracingServiceImpl::ProducerEndpointImpl::UnregisterTraceWriter(
56849     uint32_t writer_id) {
56850   PERFETTO_DCHECK_THREAD(thread_checker_);
56851   writers_.erase(static_cast<WriterID>(writer_id));
56852 }
56853 
CommitData(const CommitDataRequest & req_untrusted,CommitDataCallback callback)56854 void TracingServiceImpl::ProducerEndpointImpl::CommitData(
56855     const CommitDataRequest& req_untrusted,
56856     CommitDataCallback callback) {
56857   PERFETTO_DCHECK_THREAD(thread_checker_);
56858 
56859   if (metatrace::IsEnabled(metatrace::TAG_TRACE_SERVICE)) {
56860     PERFETTO_METATRACE_COUNTER(TAG_TRACE_SERVICE, TRACE_SERVICE_COMMIT_DATA,
56861                                EncodeCommitDataRequest(id_, req_untrusted));
56862   }
56863 
56864   if (!shared_memory_) {
56865     PERFETTO_DLOG(
56866         "Attempted to commit data before the shared memory was allocated.");
56867     return;
56868   }
56869   PERFETTO_DCHECK(shmem_abi_.is_valid());
56870   for (const auto& entry : req_untrusted.chunks_to_move()) {
56871     const uint32_t page_idx = entry.page();
56872     if (page_idx >= shmem_abi_.num_pages())
56873       continue;  // A buggy or malicious producer.
56874 
56875     SharedMemoryABI::Chunk chunk =
56876         shmem_abi_.TryAcquireChunkForReading(page_idx, entry.chunk());
56877     if (!chunk.is_valid()) {
56878       PERFETTO_DLOG("Asked to move chunk %d:%d, but it's not complete",
56879                     entry.page(), entry.chunk());
56880       continue;
56881     }
56882 
56883     // TryAcquireChunkForReading() has load-acquire semantics. Once acquired,
56884     // the ABI contract expects the producer to not touch the chunk anymore
56885     // (until the service marks that as free). This is why all the reads below
56886     // are just memory_order_relaxed. Also, the code here assumes that all this
56887     // data can be malicious and just gives up if anything is malformed.
56888     BufferID buffer_id = static_cast<BufferID>(entry.target_buffer());
56889     const SharedMemoryABI::ChunkHeader& chunk_header = *chunk.header();
56890     WriterID writer_id = chunk_header.writer_id.load(std::memory_order_relaxed);
56891     ChunkID chunk_id = chunk_header.chunk_id.load(std::memory_order_relaxed);
56892     auto packets = chunk_header.packets.load(std::memory_order_relaxed);
56893     uint16_t num_fragments = packets.count;
56894     uint8_t chunk_flags = packets.flags;
56895 
56896     service_->CopyProducerPageIntoLogBuffer(
56897         id_, uid_, writer_id, chunk_id, buffer_id, num_fragments, chunk_flags,
56898         /*chunk_complete=*/true, chunk.payload_begin(), chunk.payload_size());
56899 
56900     // This one has release-store semantics.
56901     shmem_abi_.ReleaseChunkAsFree(std::move(chunk));
56902   }  // for(chunks_to_move)
56903 
56904   service_->ApplyChunkPatches(id_, req_untrusted.chunks_to_patch());
56905 
56906   if (req_untrusted.flush_request_id()) {
56907     service_->NotifyFlushDoneForProducer(id_, req_untrusted.flush_request_id());
56908   }
56909 
56910   // Keep this invocation last. ProducerIPCService::CommitData() relies on this
56911   // callback being invoked within the same callstack and not posted. If this
56912   // changes, the code there needs to be changed accordingly.
56913   if (callback)
56914     callback();
56915 }
56916 
SetupSharedMemory(std::unique_ptr<SharedMemory> shared_memory,size_t page_size_bytes,bool provided_by_producer)56917 void TracingServiceImpl::ProducerEndpointImpl::SetupSharedMemory(
56918     std::unique_ptr<SharedMemory> shared_memory,
56919     size_t page_size_bytes,
56920     bool provided_by_producer) {
56921   PERFETTO_DCHECK(!shared_memory_ && !shmem_abi_.is_valid());
56922   PERFETTO_DCHECK(page_size_bytes % 1024 == 0);
56923 
56924   shared_memory_ = std::move(shared_memory);
56925   shared_buffer_page_size_kb_ = page_size_bytes / 1024;
56926   is_shmem_provided_by_producer_ = provided_by_producer;
56927 
56928   shmem_abi_.Initialize(reinterpret_cast<uint8_t*>(shared_memory_->start()),
56929                         shared_memory_->size(),
56930                         shared_buffer_page_size_kb() * 1024);
56931   if (in_process_) {
56932     inproc_shmem_arbiter_.reset(new SharedMemoryArbiterImpl(
56933         shared_memory_->start(), shared_memory_->size(),
56934         shared_buffer_page_size_kb_ * 1024, this, task_runner_));
56935     inproc_shmem_arbiter_->SetDirectSMBPatchingSupportedByService();
56936   }
56937 
56938   OnTracingSetup();
56939   service_->UpdateMemoryGuardrail();
56940 }
56941 
shared_memory() const56942 SharedMemory* TracingServiceImpl::ProducerEndpointImpl::shared_memory() const {
56943   PERFETTO_DCHECK_THREAD(thread_checker_);
56944   return shared_memory_.get();
56945 }
56946 
shared_buffer_page_size_kb() const56947 size_t TracingServiceImpl::ProducerEndpointImpl::shared_buffer_page_size_kb()
56948     const {
56949   return shared_buffer_page_size_kb_;
56950 }
56951 
ActivateTriggers(const std::vector<std::string> & triggers)56952 void TracingServiceImpl::ProducerEndpointImpl::ActivateTriggers(
56953     const std::vector<std::string>& triggers) {
56954   service_->ActivateTriggers(id_, triggers);
56955 }
56956 
StopDataSource(DataSourceInstanceID ds_inst_id)56957 void TracingServiceImpl::ProducerEndpointImpl::StopDataSource(
56958     DataSourceInstanceID ds_inst_id) {
56959   // TODO(primiano): When we'll support tearing down the SMB, at this point we
56960   // should send the Producer a TearDownTracing if all its data sources have
56961   // been disabled (see b/77532839 and aosp/655179 PS1).
56962   PERFETTO_DCHECK_THREAD(thread_checker_);
56963   auto weak_this = weak_ptr_factory_.GetWeakPtr();
56964   task_runner_->PostTask([weak_this, ds_inst_id] {
56965     if (weak_this)
56966       weak_this->producer_->StopDataSource(ds_inst_id);
56967   });
56968 }
56969 
56970 SharedMemoryArbiter*
MaybeSharedMemoryArbiter()56971 TracingServiceImpl::ProducerEndpointImpl::MaybeSharedMemoryArbiter() {
56972   if (!inproc_shmem_arbiter_) {
56973     PERFETTO_FATAL(
56974         "The in-process SharedMemoryArbiter can only be used when "
56975         "CreateProducer has been called with in_process=true and after tracing "
56976         "has started.");
56977   }
56978 
56979   PERFETTO_DCHECK(in_process_);
56980   return inproc_shmem_arbiter_.get();
56981 }
56982 
IsShmemProvidedByProducer() const56983 bool TracingServiceImpl::ProducerEndpointImpl::IsShmemProvidedByProducer()
56984     const {
56985   return is_shmem_provided_by_producer_;
56986 }
56987 
56988 // Can be called on any thread.
56989 std::unique_ptr<TraceWriter>
CreateTraceWriter(BufferID buf_id,BufferExhaustedPolicy buffer_exhausted_policy)56990 TracingServiceImpl::ProducerEndpointImpl::CreateTraceWriter(
56991     BufferID buf_id,
56992     BufferExhaustedPolicy buffer_exhausted_policy) {
56993   PERFETTO_DCHECK(MaybeSharedMemoryArbiter());
56994   return MaybeSharedMemoryArbiter()->CreateTraceWriter(buf_id,
56995                                                        buffer_exhausted_policy);
56996 }
56997 
NotifyFlushComplete(FlushRequestID id)56998 void TracingServiceImpl::ProducerEndpointImpl::NotifyFlushComplete(
56999     FlushRequestID id) {
57000   PERFETTO_DCHECK_THREAD(thread_checker_);
57001   PERFETTO_DCHECK(MaybeSharedMemoryArbiter());
57002   return MaybeSharedMemoryArbiter()->NotifyFlushComplete(id);
57003 }
57004 
OnTracingSetup()57005 void TracingServiceImpl::ProducerEndpointImpl::OnTracingSetup() {
57006   auto weak_this = weak_ptr_factory_.GetWeakPtr();
57007   task_runner_->PostTask([weak_this] {
57008     if (weak_this)
57009       weak_this->producer_->OnTracingSetup();
57010   });
57011 }
57012 
Flush(FlushRequestID flush_request_id,const std::vector<DataSourceInstanceID> & data_sources)57013 void TracingServiceImpl::ProducerEndpointImpl::Flush(
57014     FlushRequestID flush_request_id,
57015     const std::vector<DataSourceInstanceID>& data_sources) {
57016   PERFETTO_DCHECK_THREAD(thread_checker_);
57017   auto weak_this = weak_ptr_factory_.GetWeakPtr();
57018   task_runner_->PostTask([weak_this, flush_request_id, data_sources] {
57019     if (weak_this) {
57020       weak_this->producer_->Flush(flush_request_id, data_sources.data(),
57021                                   data_sources.size());
57022     }
57023   });
57024 }
57025 
SetupDataSource(DataSourceInstanceID ds_id,const DataSourceConfig & config)57026 void TracingServiceImpl::ProducerEndpointImpl::SetupDataSource(
57027     DataSourceInstanceID ds_id,
57028     const DataSourceConfig& config) {
57029   PERFETTO_DCHECK_THREAD(thread_checker_);
57030   allowed_target_buffers_.insert(static_cast<BufferID>(config.target_buffer()));
57031   auto weak_this = weak_ptr_factory_.GetWeakPtr();
57032   task_runner_->PostTask([weak_this, ds_id, config] {
57033     if (weak_this)
57034       weak_this->producer_->SetupDataSource(ds_id, std::move(config));
57035   });
57036 }
57037 
StartDataSource(DataSourceInstanceID ds_id,const DataSourceConfig & config)57038 void TracingServiceImpl::ProducerEndpointImpl::StartDataSource(
57039     DataSourceInstanceID ds_id,
57040     const DataSourceConfig& config) {
57041   PERFETTO_DCHECK_THREAD(thread_checker_);
57042   auto weak_this = weak_ptr_factory_.GetWeakPtr();
57043   task_runner_->PostTask([weak_this, ds_id, config] {
57044     if (weak_this)
57045       weak_this->producer_->StartDataSource(ds_id, std::move(config));
57046   });
57047 }
57048 
NotifyDataSourceStarted(DataSourceInstanceID data_source_id)57049 void TracingServiceImpl::ProducerEndpointImpl::NotifyDataSourceStarted(
57050     DataSourceInstanceID data_source_id) {
57051   PERFETTO_DCHECK_THREAD(thread_checker_);
57052   service_->NotifyDataSourceStarted(id_, data_source_id);
57053 }
57054 
NotifyDataSourceStopped(DataSourceInstanceID data_source_id)57055 void TracingServiceImpl::ProducerEndpointImpl::NotifyDataSourceStopped(
57056     DataSourceInstanceID data_source_id) {
57057   PERFETTO_DCHECK_THREAD(thread_checker_);
57058   service_->NotifyDataSourceStopped(id_, data_source_id);
57059 }
57060 
OnFreeBuffers(const std::vector<BufferID> & target_buffers)57061 void TracingServiceImpl::ProducerEndpointImpl::OnFreeBuffers(
57062     const std::vector<BufferID>& target_buffers) {
57063   if (allowed_target_buffers_.empty())
57064     return;
57065   for (BufferID buffer : target_buffers)
57066     allowed_target_buffers_.erase(buffer);
57067 }
57068 
ClearIncrementalState(const std::vector<DataSourceInstanceID> & data_sources)57069 void TracingServiceImpl::ProducerEndpointImpl::ClearIncrementalState(
57070     const std::vector<DataSourceInstanceID>& data_sources) {
57071   PERFETTO_DCHECK_THREAD(thread_checker_);
57072   auto weak_this = weak_ptr_factory_.GetWeakPtr();
57073   task_runner_->PostTask([weak_this, data_sources] {
57074     if (weak_this) {
57075       base::StringView producer_name(weak_this->name_);
57076       auto scoped_crash_key = g_crash_key_prod_name.SetScoped(producer_name);
57077       weak_this->producer_->ClearIncrementalState(data_sources.data(),
57078                                                   data_sources.size());
57079     }
57080   });
57081 }
57082 
Sync(std::function<void ()> callback)57083 void TracingServiceImpl::ProducerEndpointImpl::Sync(
57084     std::function<void()> callback) {
57085   task_runner_->PostTask(callback);
57086 }
57087 
57088 ////////////////////////////////////////////////////////////////////////////////
57089 // TracingServiceImpl::TracingSession implementation
57090 ////////////////////////////////////////////////////////////////////////////////
57091 
TracingSession(TracingSessionID session_id,ConsumerEndpointImpl * consumer,const TraceConfig & new_config,base::TaskRunner * task_runner)57092 TracingServiceImpl::TracingSession::TracingSession(
57093     TracingSessionID session_id,
57094     ConsumerEndpointImpl* consumer,
57095     const TraceConfig& new_config,
57096     base::TaskRunner* task_runner)
57097     : id(session_id),
57098       consumer_maybe_null(consumer),
57099       consumer_uid(consumer->uid_),
57100       config(new_config),
57101       snapshot_periodic_task(task_runner) {
57102   // all_data_sources_flushed is special because we store up to 64 events of
57103   // this type. Other events will go through the default case in
57104   // SnapshotLifecycleEvent() where they will be given a max history of 1.
57105   lifecycle_events.emplace_back(
57106       protos::pbzero::TracingServiceEvent::kAllDataSourcesFlushedFieldNumber,
57107       64 /* max_size */);
57108 }
57109 
57110 }  // namespace perfetto
57111 // gen_amalgamated begin source: src/tracing/internal/in_process_tracing_backend.cc
57112 /*
57113  * Copyright (C) 2019 The Android Open Source Project
57114  *
57115  * Licensed under the Apache License, Version 2.0 (the "License");
57116  * you may not use this file except in compliance with the License.
57117  * You may obtain a copy of the License at
57118  *
57119  *      http://www.apache.org/licenses/LICENSE-2.0
57120  *
57121  * Unless required by applicable law or agreed to in writing, software
57122  * distributed under the License is distributed on an "AS IS" BASIS,
57123  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
57124  * See the License for the specific language governing permissions and
57125  * limitations under the License.
57126  */
57127 
57128 // gen_amalgamated expanded: #include "perfetto/tracing/internal/in_process_tracing_backend.h"
57129 
57130 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
57131 // gen_amalgamated expanded: #include "perfetto/base/task_runner.h"
57132 // gen_amalgamated expanded: #include "perfetto/ext/base/paged_memory.h"
57133 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/shared_memory.h"
57134 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/tracing_service.h"
57135 
57136 // TODO(primiano): When the in-process backend is used, we should never end up
57137 // in a situation where the thread where the TracingService and Producer live
57138 // writes a packet and hence can get into the GetNewChunk() stall.
57139 // This would happen only if the API client code calls Trace() from one of the
57140 // callbacks it receives (e.g. OnStart(), OnStop()). We should either cause a
57141 // hard crash or ignore traces from that thread if that happens, because it
57142 // will deadlock (the Service will never free up the SMB because won't ever get
57143 // to run the task).
57144 
57145 namespace perfetto {
57146 namespace internal {
57147 
57148 namespace {
57149 
57150 class InProcessShm : public SharedMemory {
57151  public:
57152   explicit InProcessShm(size_t size);
57153   ~InProcessShm() override;
57154   void* start() const override;
57155   size_t size() const override;
57156 
57157  private:
57158   base::PagedMemory mem_;
57159 };
57160 
57161 class InProcessShmFactory : public SharedMemory::Factory {
57162  public:
57163   ~InProcessShmFactory() override;
57164   std::unique_ptr<SharedMemory> CreateSharedMemory(size_t) override;
57165 };
57166 
57167 InProcessShm::~InProcessShm() = default;
57168 
InProcessShm(size_t size)57169 InProcessShm::InProcessShm(size_t size)
57170     : mem_(base::PagedMemory::Allocate(size)) {}
57171 
start() const57172 void* InProcessShm::start() const {
57173   return mem_.Get();
57174 }
57175 
size() const57176 size_t InProcessShm::size() const {
57177   return mem_.size();
57178 }
57179 
57180 InProcessShmFactory::~InProcessShmFactory() = default;
CreateSharedMemory(size_t size)57181 std::unique_ptr<SharedMemory> InProcessShmFactory::CreateSharedMemory(
57182     size_t size) {
57183   return std::unique_ptr<SharedMemory>(new InProcessShm(size));
57184 }
57185 
57186 }  // namespace
57187 
57188 // static
GetInstance()57189 TracingBackend* InProcessTracingBackend::GetInstance() {
57190   static auto* instance = new InProcessTracingBackend();
57191   return instance;
57192 }
57193 
InProcessTracingBackend()57194 InProcessTracingBackend::InProcessTracingBackend() {}
57195 
ConnectProducer(const ConnectProducerArgs & args)57196 std::unique_ptr<ProducerEndpoint> InProcessTracingBackend::ConnectProducer(
57197     const ConnectProducerArgs& args) {
57198   PERFETTO_DCHECK(args.task_runner->RunsTasksOnCurrentThread());
57199   return GetOrCreateService(args.task_runner)
57200       ->ConnectProducer(args.producer, /*uid=*/0, args.producer_name,
57201                         args.shmem_size_hint_bytes,
57202                         /*in_process=*/true,
57203                         TracingService::ProducerSMBScrapingMode::kEnabled,
57204                         args.shmem_page_size_hint_bytes);
57205 }
57206 
ConnectConsumer(const ConnectConsumerArgs & args)57207 std::unique_ptr<ConsumerEndpoint> InProcessTracingBackend::ConnectConsumer(
57208     const ConnectConsumerArgs& args) {
57209   return GetOrCreateService(args.task_runner)
57210       ->ConnectConsumer(args.consumer, /*uid=*/0);
57211 }
57212 
GetOrCreateService(base::TaskRunner * task_runner)57213 TracingService* InProcessTracingBackend::GetOrCreateService(
57214     base::TaskRunner* task_runner) {
57215   if (!service_) {
57216     std::unique_ptr<InProcessShmFactory> shm(new InProcessShmFactory());
57217     service_ = TracingService::CreateInstance(std::move(shm), task_runner);
57218     service_->SetSMBScrapingEnabled(true);
57219   }
57220   return service_.get();
57221 }
57222 
57223 }  // namespace internal
57224 }  // namespace perfetto
57225 // gen_amalgamated begin source: gen/protos/perfetto/ipc/consumer_port.gen.cc
57226 // gen_amalgamated begin header: gen/protos/perfetto/ipc/consumer_port.gen.h
57227 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
57228 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_IPC_CONSUMER_PORT_PROTO_CPP_H_
57229 #define PERFETTO_PROTOS_PROTOS_PERFETTO_IPC_CONSUMER_PORT_PROTO_CPP_H_
57230 
57231 #include <stdint.h>
57232 #include <bitset>
57233 #include <vector>
57234 #include <string>
57235 #include <type_traits>
57236 
57237 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
57238 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
57239 // gen_amalgamated expanded: #include "perfetto/base/export.h"
57240 
57241 namespace perfetto {
57242 namespace protos {
57243 namespace gen {
57244 class SaveTraceForBugreportResponse;
57245 class SaveTraceForBugreportRequest;
57246 class QueryCapabilitiesResponse;
57247 class TracingServiceCapabilities;
57248 class QueryCapabilitiesRequest;
57249 class QueryServiceStateResponse;
57250 class TracingServiceState;
57251 class TracingServiceState_DataSource;
57252 class DataSourceDescriptor;
57253 class TracingServiceState_Producer;
57254 class QueryServiceStateRequest;
57255 class ObserveEventsResponse;
57256 class ObservableEvents;
57257 class ObservableEvents_DataSourceInstanceStateChange;
57258 class ObserveEventsRequest;
57259 class GetTraceStatsResponse;
57260 class TraceStats;
57261 class TraceStats_FilterStats;
57262 class TraceStats_BufferStats;
57263 class GetTraceStatsRequest;
57264 class AttachResponse;
57265 class TraceConfig;
57266 class TraceConfig_TraceFilter;
57267 class TraceConfig_IncidentReportConfig;
57268 class TraceConfig_IncrementalStateConfig;
57269 class TraceConfig_TriggerConfig;
57270 class TraceConfig_TriggerConfig_Trigger;
57271 class TraceConfig_GuardrailOverrides;
57272 class TraceConfig_StatsdMetadata;
57273 class TraceConfig_ProducerConfig;
57274 class TraceConfig_BuiltinDataSource;
57275 class TraceConfig_DataSource;
57276 class DataSourceConfig;
57277 class TestConfig;
57278 class TestConfig_DummyFields;
57279 class InterceptorConfig;
57280 class ChromeConfig;
57281 class TraceConfig_BufferConfig;
57282 class AttachRequest;
57283 class DetachResponse;
57284 class DetachRequest;
57285 class FlushResponse;
57286 class FlushRequest;
57287 class FreeBuffersResponse;
57288 class FreeBuffersRequest;
57289 class ReadBuffersResponse;
57290 class ReadBuffersResponse_Slice;
57291 class ReadBuffersRequest;
57292 class DisableTracingResponse;
57293 class DisableTracingRequest;
57294 class ChangeTraceConfigResponse;
57295 class ChangeTraceConfigRequest;
57296 class StartTracingResponse;
57297 class StartTracingRequest;
57298 class EnableTracingResponse;
57299 class EnableTracingRequest;
57300 enum ObservableEvents_Type : int;
57301 enum ObservableEvents_DataSourceInstanceState : int;
57302 enum TraceConfig_LockdownModeOperation : int;
57303 enum TraceConfig_CompressionType : int;
57304 enum TraceConfig_StatsdLogging : int;
57305 enum TraceConfig_TriggerConfig_TriggerMode : int;
57306 enum BuiltinClock : int;
57307 enum DataSourceConfig_SessionInitiator : int;
57308 enum ChromeConfig_ClientPriority : int;
57309 enum TraceConfig_BufferConfig_FillPolicy : int;
57310 }  // namespace perfetto
57311 }  // namespace protos
57312 }  // namespace gen
57313 
57314 namespace protozero {
57315 class Message;
57316 }  // namespace protozero
57317 
57318 namespace perfetto {
57319 namespace protos {
57320 namespace gen {
57321 
57322 class PERFETTO_EXPORT SaveTraceForBugreportResponse : public ::protozero::CppMessageObj {
57323  public:
57324   enum FieldNumbers {
57325     kSuccessFieldNumber = 1,
57326     kMsgFieldNumber = 2,
57327   };
57328 
57329   SaveTraceForBugreportResponse();
57330   ~SaveTraceForBugreportResponse() override;
57331   SaveTraceForBugreportResponse(SaveTraceForBugreportResponse&&) noexcept;
57332   SaveTraceForBugreportResponse& operator=(SaveTraceForBugreportResponse&&);
57333   SaveTraceForBugreportResponse(const SaveTraceForBugreportResponse&);
57334   SaveTraceForBugreportResponse& operator=(const SaveTraceForBugreportResponse&);
57335   bool operator==(const SaveTraceForBugreportResponse&) const;
operator !=(const SaveTraceForBugreportResponse & other) const57336   bool operator!=(const SaveTraceForBugreportResponse& other) const { return !(*this == other); }
57337 
57338   bool ParseFromArray(const void*, size_t) override;
57339   std::string SerializeAsString() const override;
57340   std::vector<uint8_t> SerializeAsArray() const override;
57341   void Serialize(::protozero::Message*) const;
57342 
has_success() const57343   bool has_success() const { return _has_field_[1]; }
success() const57344   bool success() const { return success_; }
set_success(bool value)57345   void set_success(bool value) { success_ = value; _has_field_.set(1); }
57346 
has_msg() const57347   bool has_msg() const { return _has_field_[2]; }
msg() const57348   const std::string& msg() const { return msg_; }
set_msg(const std::string & value)57349   void set_msg(const std::string& value) { msg_ = value; _has_field_.set(2); }
57350 
57351  private:
57352   bool success_{};
57353   std::string msg_{};
57354 
57355   // Allows to preserve unknown protobuf fields for compatibility
57356   // with future versions of .proto files.
57357   std::string unknown_fields_;
57358 
57359   std::bitset<3> _has_field_{};
57360 };
57361 
57362 
57363 class PERFETTO_EXPORT SaveTraceForBugreportRequest : public ::protozero::CppMessageObj {
57364  public:
57365   enum FieldNumbers {
57366   };
57367 
57368   SaveTraceForBugreportRequest();
57369   ~SaveTraceForBugreportRequest() override;
57370   SaveTraceForBugreportRequest(SaveTraceForBugreportRequest&&) noexcept;
57371   SaveTraceForBugreportRequest& operator=(SaveTraceForBugreportRequest&&);
57372   SaveTraceForBugreportRequest(const SaveTraceForBugreportRequest&);
57373   SaveTraceForBugreportRequest& operator=(const SaveTraceForBugreportRequest&);
57374   bool operator==(const SaveTraceForBugreportRequest&) const;
operator !=(const SaveTraceForBugreportRequest & other) const57375   bool operator!=(const SaveTraceForBugreportRequest& other) const { return !(*this == other); }
57376 
57377   bool ParseFromArray(const void*, size_t) override;
57378   std::string SerializeAsString() const override;
57379   std::vector<uint8_t> SerializeAsArray() const override;
57380   void Serialize(::protozero::Message*) const;
57381 
57382  private:
57383 
57384   // Allows to preserve unknown protobuf fields for compatibility
57385   // with future versions of .proto files.
57386   std::string unknown_fields_;
57387 
57388   std::bitset<2> _has_field_{};
57389 };
57390 
57391 
57392 class PERFETTO_EXPORT QueryCapabilitiesResponse : public ::protozero::CppMessageObj {
57393  public:
57394   enum FieldNumbers {
57395     kCapabilitiesFieldNumber = 1,
57396   };
57397 
57398   QueryCapabilitiesResponse();
57399   ~QueryCapabilitiesResponse() override;
57400   QueryCapabilitiesResponse(QueryCapabilitiesResponse&&) noexcept;
57401   QueryCapabilitiesResponse& operator=(QueryCapabilitiesResponse&&);
57402   QueryCapabilitiesResponse(const QueryCapabilitiesResponse&);
57403   QueryCapabilitiesResponse& operator=(const QueryCapabilitiesResponse&);
57404   bool operator==(const QueryCapabilitiesResponse&) const;
operator !=(const QueryCapabilitiesResponse & other) const57405   bool operator!=(const QueryCapabilitiesResponse& other) const { return !(*this == other); }
57406 
57407   bool ParseFromArray(const void*, size_t) override;
57408   std::string SerializeAsString() const override;
57409   std::vector<uint8_t> SerializeAsArray() const override;
57410   void Serialize(::protozero::Message*) const;
57411 
has_capabilities() const57412   bool has_capabilities() const { return _has_field_[1]; }
capabilities() const57413   const TracingServiceCapabilities& capabilities() const { return *capabilities_; }
mutable_capabilities()57414   TracingServiceCapabilities* mutable_capabilities() { _has_field_.set(1); return capabilities_.get(); }
57415 
57416  private:
57417   ::protozero::CopyablePtr<TracingServiceCapabilities> capabilities_;
57418 
57419   // Allows to preserve unknown protobuf fields for compatibility
57420   // with future versions of .proto files.
57421   std::string unknown_fields_;
57422 
57423   std::bitset<2> _has_field_{};
57424 };
57425 
57426 
57427 class PERFETTO_EXPORT QueryCapabilitiesRequest : public ::protozero::CppMessageObj {
57428  public:
57429   enum FieldNumbers {
57430   };
57431 
57432   QueryCapabilitiesRequest();
57433   ~QueryCapabilitiesRequest() override;
57434   QueryCapabilitiesRequest(QueryCapabilitiesRequest&&) noexcept;
57435   QueryCapabilitiesRequest& operator=(QueryCapabilitiesRequest&&);
57436   QueryCapabilitiesRequest(const QueryCapabilitiesRequest&);
57437   QueryCapabilitiesRequest& operator=(const QueryCapabilitiesRequest&);
57438   bool operator==(const QueryCapabilitiesRequest&) const;
operator !=(const QueryCapabilitiesRequest & other) const57439   bool operator!=(const QueryCapabilitiesRequest& other) const { return !(*this == other); }
57440 
57441   bool ParseFromArray(const void*, size_t) override;
57442   std::string SerializeAsString() const override;
57443   std::vector<uint8_t> SerializeAsArray() const override;
57444   void Serialize(::protozero::Message*) const;
57445 
57446  private:
57447 
57448   // Allows to preserve unknown protobuf fields for compatibility
57449   // with future versions of .proto files.
57450   std::string unknown_fields_;
57451 
57452   std::bitset<2> _has_field_{};
57453 };
57454 
57455 
57456 class PERFETTO_EXPORT QueryServiceStateResponse : public ::protozero::CppMessageObj {
57457  public:
57458   enum FieldNumbers {
57459     kServiceStateFieldNumber = 1,
57460   };
57461 
57462   QueryServiceStateResponse();
57463   ~QueryServiceStateResponse() override;
57464   QueryServiceStateResponse(QueryServiceStateResponse&&) noexcept;
57465   QueryServiceStateResponse& operator=(QueryServiceStateResponse&&);
57466   QueryServiceStateResponse(const QueryServiceStateResponse&);
57467   QueryServiceStateResponse& operator=(const QueryServiceStateResponse&);
57468   bool operator==(const QueryServiceStateResponse&) const;
operator !=(const QueryServiceStateResponse & other) const57469   bool operator!=(const QueryServiceStateResponse& other) const { return !(*this == other); }
57470 
57471   bool ParseFromArray(const void*, size_t) override;
57472   std::string SerializeAsString() const override;
57473   std::vector<uint8_t> SerializeAsArray() const override;
57474   void Serialize(::protozero::Message*) const;
57475 
has_service_state() const57476   bool has_service_state() const { return _has_field_[1]; }
service_state() const57477   const TracingServiceState& service_state() const { return *service_state_; }
mutable_service_state()57478   TracingServiceState* mutable_service_state() { _has_field_.set(1); return service_state_.get(); }
57479 
57480  private:
57481   ::protozero::CopyablePtr<TracingServiceState> service_state_;
57482 
57483   // Allows to preserve unknown protobuf fields for compatibility
57484   // with future versions of .proto files.
57485   std::string unknown_fields_;
57486 
57487   std::bitset<2> _has_field_{};
57488 };
57489 
57490 
57491 class PERFETTO_EXPORT QueryServiceStateRequest : public ::protozero::CppMessageObj {
57492  public:
57493   enum FieldNumbers {
57494   };
57495 
57496   QueryServiceStateRequest();
57497   ~QueryServiceStateRequest() override;
57498   QueryServiceStateRequest(QueryServiceStateRequest&&) noexcept;
57499   QueryServiceStateRequest& operator=(QueryServiceStateRequest&&);
57500   QueryServiceStateRequest(const QueryServiceStateRequest&);
57501   QueryServiceStateRequest& operator=(const QueryServiceStateRequest&);
57502   bool operator==(const QueryServiceStateRequest&) const;
operator !=(const QueryServiceStateRequest & other) const57503   bool operator!=(const QueryServiceStateRequest& other) const { return !(*this == other); }
57504 
57505   bool ParseFromArray(const void*, size_t) override;
57506   std::string SerializeAsString() const override;
57507   std::vector<uint8_t> SerializeAsArray() const override;
57508   void Serialize(::protozero::Message*) const;
57509 
57510  private:
57511 
57512   // Allows to preserve unknown protobuf fields for compatibility
57513   // with future versions of .proto files.
57514   std::string unknown_fields_;
57515 
57516   std::bitset<2> _has_field_{};
57517 };
57518 
57519 
57520 class PERFETTO_EXPORT ObserveEventsResponse : public ::protozero::CppMessageObj {
57521  public:
57522   enum FieldNumbers {
57523     kEventsFieldNumber = 1,
57524   };
57525 
57526   ObserveEventsResponse();
57527   ~ObserveEventsResponse() override;
57528   ObserveEventsResponse(ObserveEventsResponse&&) noexcept;
57529   ObserveEventsResponse& operator=(ObserveEventsResponse&&);
57530   ObserveEventsResponse(const ObserveEventsResponse&);
57531   ObserveEventsResponse& operator=(const ObserveEventsResponse&);
57532   bool operator==(const ObserveEventsResponse&) const;
operator !=(const ObserveEventsResponse & other) const57533   bool operator!=(const ObserveEventsResponse& other) const { return !(*this == other); }
57534 
57535   bool ParseFromArray(const void*, size_t) override;
57536   std::string SerializeAsString() const override;
57537   std::vector<uint8_t> SerializeAsArray() const override;
57538   void Serialize(::protozero::Message*) const;
57539 
has_events() const57540   bool has_events() const { return _has_field_[1]; }
events() const57541   const ObservableEvents& events() const { return *events_; }
mutable_events()57542   ObservableEvents* mutable_events() { _has_field_.set(1); return events_.get(); }
57543 
57544  private:
57545   ::protozero::CopyablePtr<ObservableEvents> events_;
57546 
57547   // Allows to preserve unknown protobuf fields for compatibility
57548   // with future versions of .proto files.
57549   std::string unknown_fields_;
57550 
57551   std::bitset<2> _has_field_{};
57552 };
57553 
57554 
57555 class PERFETTO_EXPORT ObserveEventsRequest : public ::protozero::CppMessageObj {
57556  public:
57557   enum FieldNumbers {
57558     kEventsToObserveFieldNumber = 1,
57559   };
57560 
57561   ObserveEventsRequest();
57562   ~ObserveEventsRequest() override;
57563   ObserveEventsRequest(ObserveEventsRequest&&) noexcept;
57564   ObserveEventsRequest& operator=(ObserveEventsRequest&&);
57565   ObserveEventsRequest(const ObserveEventsRequest&);
57566   ObserveEventsRequest& operator=(const ObserveEventsRequest&);
57567   bool operator==(const ObserveEventsRequest&) const;
operator !=(const ObserveEventsRequest & other) const57568   bool operator!=(const ObserveEventsRequest& other) const { return !(*this == other); }
57569 
57570   bool ParseFromArray(const void*, size_t) override;
57571   std::string SerializeAsString() const override;
57572   std::vector<uint8_t> SerializeAsArray() const override;
57573   void Serialize(::protozero::Message*) const;
57574 
events_to_observe() const57575   const std::vector<ObservableEvents_Type>& events_to_observe() const { return events_to_observe_; }
mutable_events_to_observe()57576   std::vector<ObservableEvents_Type>* mutable_events_to_observe() { return &events_to_observe_; }
events_to_observe_size() const57577   int events_to_observe_size() const { return static_cast<int>(events_to_observe_.size()); }
clear_events_to_observe()57578   void clear_events_to_observe() { events_to_observe_.clear(); }
add_events_to_observe(ObservableEvents_Type value)57579   void add_events_to_observe(ObservableEvents_Type value) { events_to_observe_.emplace_back(value); }
add_events_to_observe()57580   ObservableEvents_Type* add_events_to_observe() { events_to_observe_.emplace_back(); return &events_to_observe_.back(); }
57581 
57582  private:
57583   std::vector<ObservableEvents_Type> events_to_observe_;
57584 
57585   // Allows to preserve unknown protobuf fields for compatibility
57586   // with future versions of .proto files.
57587   std::string unknown_fields_;
57588 
57589   std::bitset<2> _has_field_{};
57590 };
57591 
57592 
57593 class PERFETTO_EXPORT GetTraceStatsResponse : public ::protozero::CppMessageObj {
57594  public:
57595   enum FieldNumbers {
57596     kTraceStatsFieldNumber = 1,
57597   };
57598 
57599   GetTraceStatsResponse();
57600   ~GetTraceStatsResponse() override;
57601   GetTraceStatsResponse(GetTraceStatsResponse&&) noexcept;
57602   GetTraceStatsResponse& operator=(GetTraceStatsResponse&&);
57603   GetTraceStatsResponse(const GetTraceStatsResponse&);
57604   GetTraceStatsResponse& operator=(const GetTraceStatsResponse&);
57605   bool operator==(const GetTraceStatsResponse&) const;
operator !=(const GetTraceStatsResponse & other) const57606   bool operator!=(const GetTraceStatsResponse& other) const { return !(*this == other); }
57607 
57608   bool ParseFromArray(const void*, size_t) override;
57609   std::string SerializeAsString() const override;
57610   std::vector<uint8_t> SerializeAsArray() const override;
57611   void Serialize(::protozero::Message*) const;
57612 
has_trace_stats() const57613   bool has_trace_stats() const { return _has_field_[1]; }
trace_stats() const57614   const TraceStats& trace_stats() const { return *trace_stats_; }
mutable_trace_stats()57615   TraceStats* mutable_trace_stats() { _has_field_.set(1); return trace_stats_.get(); }
57616 
57617  private:
57618   ::protozero::CopyablePtr<TraceStats> trace_stats_;
57619 
57620   // Allows to preserve unknown protobuf fields for compatibility
57621   // with future versions of .proto files.
57622   std::string unknown_fields_;
57623 
57624   std::bitset<2> _has_field_{};
57625 };
57626 
57627 
57628 class PERFETTO_EXPORT GetTraceStatsRequest : public ::protozero::CppMessageObj {
57629  public:
57630   enum FieldNumbers {
57631   };
57632 
57633   GetTraceStatsRequest();
57634   ~GetTraceStatsRequest() override;
57635   GetTraceStatsRequest(GetTraceStatsRequest&&) noexcept;
57636   GetTraceStatsRequest& operator=(GetTraceStatsRequest&&);
57637   GetTraceStatsRequest(const GetTraceStatsRequest&);
57638   GetTraceStatsRequest& operator=(const GetTraceStatsRequest&);
57639   bool operator==(const GetTraceStatsRequest&) const;
operator !=(const GetTraceStatsRequest & other) const57640   bool operator!=(const GetTraceStatsRequest& other) const { return !(*this == other); }
57641 
57642   bool ParseFromArray(const void*, size_t) override;
57643   std::string SerializeAsString() const override;
57644   std::vector<uint8_t> SerializeAsArray() const override;
57645   void Serialize(::protozero::Message*) const;
57646 
57647  private:
57648 
57649   // Allows to preserve unknown protobuf fields for compatibility
57650   // with future versions of .proto files.
57651   std::string unknown_fields_;
57652 
57653   std::bitset<2> _has_field_{};
57654 };
57655 
57656 
57657 class PERFETTO_EXPORT AttachResponse : public ::protozero::CppMessageObj {
57658  public:
57659   enum FieldNumbers {
57660     kTraceConfigFieldNumber = 1,
57661   };
57662 
57663   AttachResponse();
57664   ~AttachResponse() override;
57665   AttachResponse(AttachResponse&&) noexcept;
57666   AttachResponse& operator=(AttachResponse&&);
57667   AttachResponse(const AttachResponse&);
57668   AttachResponse& operator=(const AttachResponse&);
57669   bool operator==(const AttachResponse&) const;
operator !=(const AttachResponse & other) const57670   bool operator!=(const AttachResponse& other) const { return !(*this == other); }
57671 
57672   bool ParseFromArray(const void*, size_t) override;
57673   std::string SerializeAsString() const override;
57674   std::vector<uint8_t> SerializeAsArray() const override;
57675   void Serialize(::protozero::Message*) const;
57676 
has_trace_config() const57677   bool has_trace_config() const { return _has_field_[1]; }
trace_config() const57678   const TraceConfig& trace_config() const { return *trace_config_; }
mutable_trace_config()57679   TraceConfig* mutable_trace_config() { _has_field_.set(1); return trace_config_.get(); }
57680 
57681  private:
57682   ::protozero::CopyablePtr<TraceConfig> trace_config_;
57683 
57684   // Allows to preserve unknown protobuf fields for compatibility
57685   // with future versions of .proto files.
57686   std::string unknown_fields_;
57687 
57688   std::bitset<2> _has_field_{};
57689 };
57690 
57691 
57692 class PERFETTO_EXPORT AttachRequest : public ::protozero::CppMessageObj {
57693  public:
57694   enum FieldNumbers {
57695     kKeyFieldNumber = 1,
57696   };
57697 
57698   AttachRequest();
57699   ~AttachRequest() override;
57700   AttachRequest(AttachRequest&&) noexcept;
57701   AttachRequest& operator=(AttachRequest&&);
57702   AttachRequest(const AttachRequest&);
57703   AttachRequest& operator=(const AttachRequest&);
57704   bool operator==(const AttachRequest&) const;
operator !=(const AttachRequest & other) const57705   bool operator!=(const AttachRequest& other) const { return !(*this == other); }
57706 
57707   bool ParseFromArray(const void*, size_t) override;
57708   std::string SerializeAsString() const override;
57709   std::vector<uint8_t> SerializeAsArray() const override;
57710   void Serialize(::protozero::Message*) const;
57711 
has_key() const57712   bool has_key() const { return _has_field_[1]; }
key() const57713   const std::string& key() const { return key_; }
set_key(const std::string & value)57714   void set_key(const std::string& value) { key_ = value; _has_field_.set(1); }
57715 
57716  private:
57717   std::string key_{};
57718 
57719   // Allows to preserve unknown protobuf fields for compatibility
57720   // with future versions of .proto files.
57721   std::string unknown_fields_;
57722 
57723   std::bitset<2> _has_field_{};
57724 };
57725 
57726 
57727 class PERFETTO_EXPORT DetachResponse : public ::protozero::CppMessageObj {
57728  public:
57729   enum FieldNumbers {
57730   };
57731 
57732   DetachResponse();
57733   ~DetachResponse() override;
57734   DetachResponse(DetachResponse&&) noexcept;
57735   DetachResponse& operator=(DetachResponse&&);
57736   DetachResponse(const DetachResponse&);
57737   DetachResponse& operator=(const DetachResponse&);
57738   bool operator==(const DetachResponse&) const;
operator !=(const DetachResponse & other) const57739   bool operator!=(const DetachResponse& other) const { return !(*this == other); }
57740 
57741   bool ParseFromArray(const void*, size_t) override;
57742   std::string SerializeAsString() const override;
57743   std::vector<uint8_t> SerializeAsArray() const override;
57744   void Serialize(::protozero::Message*) const;
57745 
57746  private:
57747 
57748   // Allows to preserve unknown protobuf fields for compatibility
57749   // with future versions of .proto files.
57750   std::string unknown_fields_;
57751 
57752   std::bitset<2> _has_field_{};
57753 };
57754 
57755 
57756 class PERFETTO_EXPORT DetachRequest : public ::protozero::CppMessageObj {
57757  public:
57758   enum FieldNumbers {
57759     kKeyFieldNumber = 1,
57760   };
57761 
57762   DetachRequest();
57763   ~DetachRequest() override;
57764   DetachRequest(DetachRequest&&) noexcept;
57765   DetachRequest& operator=(DetachRequest&&);
57766   DetachRequest(const DetachRequest&);
57767   DetachRequest& operator=(const DetachRequest&);
57768   bool operator==(const DetachRequest&) const;
operator !=(const DetachRequest & other) const57769   bool operator!=(const DetachRequest& other) const { return !(*this == other); }
57770 
57771   bool ParseFromArray(const void*, size_t) override;
57772   std::string SerializeAsString() const override;
57773   std::vector<uint8_t> SerializeAsArray() const override;
57774   void Serialize(::protozero::Message*) const;
57775 
has_key() const57776   bool has_key() const { return _has_field_[1]; }
key() const57777   const std::string& key() const { return key_; }
set_key(const std::string & value)57778   void set_key(const std::string& value) { key_ = value; _has_field_.set(1); }
57779 
57780  private:
57781   std::string key_{};
57782 
57783   // Allows to preserve unknown protobuf fields for compatibility
57784   // with future versions of .proto files.
57785   std::string unknown_fields_;
57786 
57787   std::bitset<2> _has_field_{};
57788 };
57789 
57790 
57791 class PERFETTO_EXPORT FlushResponse : public ::protozero::CppMessageObj {
57792  public:
57793   enum FieldNumbers {
57794   };
57795 
57796   FlushResponse();
57797   ~FlushResponse() override;
57798   FlushResponse(FlushResponse&&) noexcept;
57799   FlushResponse& operator=(FlushResponse&&);
57800   FlushResponse(const FlushResponse&);
57801   FlushResponse& operator=(const FlushResponse&);
57802   bool operator==(const FlushResponse&) const;
operator !=(const FlushResponse & other) const57803   bool operator!=(const FlushResponse& other) const { return !(*this == other); }
57804 
57805   bool ParseFromArray(const void*, size_t) override;
57806   std::string SerializeAsString() const override;
57807   std::vector<uint8_t> SerializeAsArray() const override;
57808   void Serialize(::protozero::Message*) const;
57809 
57810  private:
57811 
57812   // Allows to preserve unknown protobuf fields for compatibility
57813   // with future versions of .proto files.
57814   std::string unknown_fields_;
57815 
57816   std::bitset<2> _has_field_{};
57817 };
57818 
57819 
57820 class PERFETTO_EXPORT FlushRequest : public ::protozero::CppMessageObj {
57821  public:
57822   enum FieldNumbers {
57823     kTimeoutMsFieldNumber = 1,
57824   };
57825 
57826   FlushRequest();
57827   ~FlushRequest() override;
57828   FlushRequest(FlushRequest&&) noexcept;
57829   FlushRequest& operator=(FlushRequest&&);
57830   FlushRequest(const FlushRequest&);
57831   FlushRequest& operator=(const FlushRequest&);
57832   bool operator==(const FlushRequest&) const;
operator !=(const FlushRequest & other) const57833   bool operator!=(const FlushRequest& other) const { return !(*this == other); }
57834 
57835   bool ParseFromArray(const void*, size_t) override;
57836   std::string SerializeAsString() const override;
57837   std::vector<uint8_t> SerializeAsArray() const override;
57838   void Serialize(::protozero::Message*) const;
57839 
has_timeout_ms() const57840   bool has_timeout_ms() const { return _has_field_[1]; }
timeout_ms() const57841   uint32_t timeout_ms() const { return timeout_ms_; }
set_timeout_ms(uint32_t value)57842   void set_timeout_ms(uint32_t value) { timeout_ms_ = value; _has_field_.set(1); }
57843 
57844  private:
57845   uint32_t timeout_ms_{};
57846 
57847   // Allows to preserve unknown protobuf fields for compatibility
57848   // with future versions of .proto files.
57849   std::string unknown_fields_;
57850 
57851   std::bitset<2> _has_field_{};
57852 };
57853 
57854 
57855 class PERFETTO_EXPORT FreeBuffersResponse : public ::protozero::CppMessageObj {
57856  public:
57857   enum FieldNumbers {
57858   };
57859 
57860   FreeBuffersResponse();
57861   ~FreeBuffersResponse() override;
57862   FreeBuffersResponse(FreeBuffersResponse&&) noexcept;
57863   FreeBuffersResponse& operator=(FreeBuffersResponse&&);
57864   FreeBuffersResponse(const FreeBuffersResponse&);
57865   FreeBuffersResponse& operator=(const FreeBuffersResponse&);
57866   bool operator==(const FreeBuffersResponse&) const;
operator !=(const FreeBuffersResponse & other) const57867   bool operator!=(const FreeBuffersResponse& other) const { return !(*this == other); }
57868 
57869   bool ParseFromArray(const void*, size_t) override;
57870   std::string SerializeAsString() const override;
57871   std::vector<uint8_t> SerializeAsArray() const override;
57872   void Serialize(::protozero::Message*) const;
57873 
57874  private:
57875 
57876   // Allows to preserve unknown protobuf fields for compatibility
57877   // with future versions of .proto files.
57878   std::string unknown_fields_;
57879 
57880   std::bitset<2> _has_field_{};
57881 };
57882 
57883 
57884 class PERFETTO_EXPORT FreeBuffersRequest : public ::protozero::CppMessageObj {
57885  public:
57886   enum FieldNumbers {
57887     kBufferIdsFieldNumber = 1,
57888   };
57889 
57890   FreeBuffersRequest();
57891   ~FreeBuffersRequest() override;
57892   FreeBuffersRequest(FreeBuffersRequest&&) noexcept;
57893   FreeBuffersRequest& operator=(FreeBuffersRequest&&);
57894   FreeBuffersRequest(const FreeBuffersRequest&);
57895   FreeBuffersRequest& operator=(const FreeBuffersRequest&);
57896   bool operator==(const FreeBuffersRequest&) const;
operator !=(const FreeBuffersRequest & other) const57897   bool operator!=(const FreeBuffersRequest& other) const { return !(*this == other); }
57898 
57899   bool ParseFromArray(const void*, size_t) override;
57900   std::string SerializeAsString() const override;
57901   std::vector<uint8_t> SerializeAsArray() const override;
57902   void Serialize(::protozero::Message*) const;
57903 
buffer_ids() const57904   const std::vector<uint32_t>& buffer_ids() const { return buffer_ids_; }
mutable_buffer_ids()57905   std::vector<uint32_t>* mutable_buffer_ids() { return &buffer_ids_; }
buffer_ids_size() const57906   int buffer_ids_size() const { return static_cast<int>(buffer_ids_.size()); }
clear_buffer_ids()57907   void clear_buffer_ids() { buffer_ids_.clear(); }
add_buffer_ids(uint32_t value)57908   void add_buffer_ids(uint32_t value) { buffer_ids_.emplace_back(value); }
add_buffer_ids()57909   uint32_t* add_buffer_ids() { buffer_ids_.emplace_back(); return &buffer_ids_.back(); }
57910 
57911  private:
57912   std::vector<uint32_t> buffer_ids_;
57913 
57914   // Allows to preserve unknown protobuf fields for compatibility
57915   // with future versions of .proto files.
57916   std::string unknown_fields_;
57917 
57918   std::bitset<2> _has_field_{};
57919 };
57920 
57921 
57922 class PERFETTO_EXPORT ReadBuffersResponse : public ::protozero::CppMessageObj {
57923  public:
57924   using Slice = ReadBuffersResponse_Slice;
57925   enum FieldNumbers {
57926     kSlicesFieldNumber = 2,
57927   };
57928 
57929   ReadBuffersResponse();
57930   ~ReadBuffersResponse() override;
57931   ReadBuffersResponse(ReadBuffersResponse&&) noexcept;
57932   ReadBuffersResponse& operator=(ReadBuffersResponse&&);
57933   ReadBuffersResponse(const ReadBuffersResponse&);
57934   ReadBuffersResponse& operator=(const ReadBuffersResponse&);
57935   bool operator==(const ReadBuffersResponse&) const;
operator !=(const ReadBuffersResponse & other) const57936   bool operator!=(const ReadBuffersResponse& other) const { return !(*this == other); }
57937 
57938   bool ParseFromArray(const void*, size_t) override;
57939   std::string SerializeAsString() const override;
57940   std::vector<uint8_t> SerializeAsArray() const override;
57941   void Serialize(::protozero::Message*) const;
57942 
slices() const57943   const std::vector<ReadBuffersResponse_Slice>& slices() const { return slices_; }
mutable_slices()57944   std::vector<ReadBuffersResponse_Slice>* mutable_slices() { return &slices_; }
57945   int slices_size() const;
57946   void clear_slices();
57947   ReadBuffersResponse_Slice* add_slices();
57948 
57949  private:
57950   std::vector<ReadBuffersResponse_Slice> slices_;
57951 
57952   // Allows to preserve unknown protobuf fields for compatibility
57953   // with future versions of .proto files.
57954   std::string unknown_fields_;
57955 
57956   std::bitset<3> _has_field_{};
57957 };
57958 
57959 
57960 class PERFETTO_EXPORT ReadBuffersResponse_Slice : public ::protozero::CppMessageObj {
57961  public:
57962   enum FieldNumbers {
57963     kDataFieldNumber = 1,
57964     kLastSliceForPacketFieldNumber = 2,
57965   };
57966 
57967   ReadBuffersResponse_Slice();
57968   ~ReadBuffersResponse_Slice() override;
57969   ReadBuffersResponse_Slice(ReadBuffersResponse_Slice&&) noexcept;
57970   ReadBuffersResponse_Slice& operator=(ReadBuffersResponse_Slice&&);
57971   ReadBuffersResponse_Slice(const ReadBuffersResponse_Slice&);
57972   ReadBuffersResponse_Slice& operator=(const ReadBuffersResponse_Slice&);
57973   bool operator==(const ReadBuffersResponse_Slice&) const;
operator !=(const ReadBuffersResponse_Slice & other) const57974   bool operator!=(const ReadBuffersResponse_Slice& other) const { return !(*this == other); }
57975 
57976   bool ParseFromArray(const void*, size_t) override;
57977   std::string SerializeAsString() const override;
57978   std::vector<uint8_t> SerializeAsArray() const override;
57979   void Serialize(::protozero::Message*) const;
57980 
has_data() const57981   bool has_data() const { return _has_field_[1]; }
data() const57982   const std::string& data() const { return data_; }
set_data(const std::string & value)57983   void set_data(const std::string& value) { data_ = value; _has_field_.set(1); }
set_data(const void * p,size_t s)57984   void set_data(const void* p, size_t s) { data_.assign(reinterpret_cast<const char*>(p), s); _has_field_.set(1); }
57985 
has_last_slice_for_packet() const57986   bool has_last_slice_for_packet() const { return _has_field_[2]; }
last_slice_for_packet() const57987   bool last_slice_for_packet() const { return last_slice_for_packet_; }
set_last_slice_for_packet(bool value)57988   void set_last_slice_for_packet(bool value) { last_slice_for_packet_ = value; _has_field_.set(2); }
57989 
57990  private:
57991   std::string data_{};
57992   bool last_slice_for_packet_{};
57993 
57994   // Allows to preserve unknown protobuf fields for compatibility
57995   // with future versions of .proto files.
57996   std::string unknown_fields_;
57997 
57998   std::bitset<3> _has_field_{};
57999 };
58000 
58001 
58002 class PERFETTO_EXPORT ReadBuffersRequest : public ::protozero::CppMessageObj {
58003  public:
58004   enum FieldNumbers {
58005   };
58006 
58007   ReadBuffersRequest();
58008   ~ReadBuffersRequest() override;
58009   ReadBuffersRequest(ReadBuffersRequest&&) noexcept;
58010   ReadBuffersRequest& operator=(ReadBuffersRequest&&);
58011   ReadBuffersRequest(const ReadBuffersRequest&);
58012   ReadBuffersRequest& operator=(const ReadBuffersRequest&);
58013   bool operator==(const ReadBuffersRequest&) const;
operator !=(const ReadBuffersRequest & other) const58014   bool operator!=(const ReadBuffersRequest& other) const { return !(*this == other); }
58015 
58016   bool ParseFromArray(const void*, size_t) override;
58017   std::string SerializeAsString() const override;
58018   std::vector<uint8_t> SerializeAsArray() const override;
58019   void Serialize(::protozero::Message*) const;
58020 
58021  private:
58022 
58023   // Allows to preserve unknown protobuf fields for compatibility
58024   // with future versions of .proto files.
58025   std::string unknown_fields_;
58026 
58027   std::bitset<2> _has_field_{};
58028 };
58029 
58030 
58031 class PERFETTO_EXPORT DisableTracingResponse : public ::protozero::CppMessageObj {
58032  public:
58033   enum FieldNumbers {
58034   };
58035 
58036   DisableTracingResponse();
58037   ~DisableTracingResponse() override;
58038   DisableTracingResponse(DisableTracingResponse&&) noexcept;
58039   DisableTracingResponse& operator=(DisableTracingResponse&&);
58040   DisableTracingResponse(const DisableTracingResponse&);
58041   DisableTracingResponse& operator=(const DisableTracingResponse&);
58042   bool operator==(const DisableTracingResponse&) const;
operator !=(const DisableTracingResponse & other) const58043   bool operator!=(const DisableTracingResponse& other) const { return !(*this == other); }
58044 
58045   bool ParseFromArray(const void*, size_t) override;
58046   std::string SerializeAsString() const override;
58047   std::vector<uint8_t> SerializeAsArray() const override;
58048   void Serialize(::protozero::Message*) const;
58049 
58050  private:
58051 
58052   // Allows to preserve unknown protobuf fields for compatibility
58053   // with future versions of .proto files.
58054   std::string unknown_fields_;
58055 
58056   std::bitset<2> _has_field_{};
58057 };
58058 
58059 
58060 class PERFETTO_EXPORT DisableTracingRequest : public ::protozero::CppMessageObj {
58061  public:
58062   enum FieldNumbers {
58063   };
58064 
58065   DisableTracingRequest();
58066   ~DisableTracingRequest() override;
58067   DisableTracingRequest(DisableTracingRequest&&) noexcept;
58068   DisableTracingRequest& operator=(DisableTracingRequest&&);
58069   DisableTracingRequest(const DisableTracingRequest&);
58070   DisableTracingRequest& operator=(const DisableTracingRequest&);
58071   bool operator==(const DisableTracingRequest&) const;
operator !=(const DisableTracingRequest & other) const58072   bool operator!=(const DisableTracingRequest& other) const { return !(*this == other); }
58073 
58074   bool ParseFromArray(const void*, size_t) override;
58075   std::string SerializeAsString() const override;
58076   std::vector<uint8_t> SerializeAsArray() const override;
58077   void Serialize(::protozero::Message*) const;
58078 
58079  private:
58080 
58081   // Allows to preserve unknown protobuf fields for compatibility
58082   // with future versions of .proto files.
58083   std::string unknown_fields_;
58084 
58085   std::bitset<2> _has_field_{};
58086 };
58087 
58088 
58089 class PERFETTO_EXPORT ChangeTraceConfigResponse : public ::protozero::CppMessageObj {
58090  public:
58091   enum FieldNumbers {
58092   };
58093 
58094   ChangeTraceConfigResponse();
58095   ~ChangeTraceConfigResponse() override;
58096   ChangeTraceConfigResponse(ChangeTraceConfigResponse&&) noexcept;
58097   ChangeTraceConfigResponse& operator=(ChangeTraceConfigResponse&&);
58098   ChangeTraceConfigResponse(const ChangeTraceConfigResponse&);
58099   ChangeTraceConfigResponse& operator=(const ChangeTraceConfigResponse&);
58100   bool operator==(const ChangeTraceConfigResponse&) const;
operator !=(const ChangeTraceConfigResponse & other) const58101   bool operator!=(const ChangeTraceConfigResponse& other) const { return !(*this == other); }
58102 
58103   bool ParseFromArray(const void*, size_t) override;
58104   std::string SerializeAsString() const override;
58105   std::vector<uint8_t> SerializeAsArray() const override;
58106   void Serialize(::protozero::Message*) const;
58107 
58108  private:
58109 
58110   // Allows to preserve unknown protobuf fields for compatibility
58111   // with future versions of .proto files.
58112   std::string unknown_fields_;
58113 
58114   std::bitset<2> _has_field_{};
58115 };
58116 
58117 
58118 class PERFETTO_EXPORT ChangeTraceConfigRequest : public ::protozero::CppMessageObj {
58119  public:
58120   enum FieldNumbers {
58121     kTraceConfigFieldNumber = 1,
58122   };
58123 
58124   ChangeTraceConfigRequest();
58125   ~ChangeTraceConfigRequest() override;
58126   ChangeTraceConfigRequest(ChangeTraceConfigRequest&&) noexcept;
58127   ChangeTraceConfigRequest& operator=(ChangeTraceConfigRequest&&);
58128   ChangeTraceConfigRequest(const ChangeTraceConfigRequest&);
58129   ChangeTraceConfigRequest& operator=(const ChangeTraceConfigRequest&);
58130   bool operator==(const ChangeTraceConfigRequest&) const;
operator !=(const ChangeTraceConfigRequest & other) const58131   bool operator!=(const ChangeTraceConfigRequest& other) const { return !(*this == other); }
58132 
58133   bool ParseFromArray(const void*, size_t) override;
58134   std::string SerializeAsString() const override;
58135   std::vector<uint8_t> SerializeAsArray() const override;
58136   void Serialize(::protozero::Message*) const;
58137 
has_trace_config() const58138   bool has_trace_config() const { return _has_field_[1]; }
trace_config() const58139   const TraceConfig& trace_config() const { return *trace_config_; }
mutable_trace_config()58140   TraceConfig* mutable_trace_config() { _has_field_.set(1); return trace_config_.get(); }
58141 
58142  private:
58143   ::protozero::CopyablePtr<TraceConfig> trace_config_;
58144 
58145   // Allows to preserve unknown protobuf fields for compatibility
58146   // with future versions of .proto files.
58147   std::string unknown_fields_;
58148 
58149   std::bitset<2> _has_field_{};
58150 };
58151 
58152 
58153 class PERFETTO_EXPORT StartTracingResponse : public ::protozero::CppMessageObj {
58154  public:
58155   enum FieldNumbers {
58156   };
58157 
58158   StartTracingResponse();
58159   ~StartTracingResponse() override;
58160   StartTracingResponse(StartTracingResponse&&) noexcept;
58161   StartTracingResponse& operator=(StartTracingResponse&&);
58162   StartTracingResponse(const StartTracingResponse&);
58163   StartTracingResponse& operator=(const StartTracingResponse&);
58164   bool operator==(const StartTracingResponse&) const;
operator !=(const StartTracingResponse & other) const58165   bool operator!=(const StartTracingResponse& other) const { return !(*this == other); }
58166 
58167   bool ParseFromArray(const void*, size_t) override;
58168   std::string SerializeAsString() const override;
58169   std::vector<uint8_t> SerializeAsArray() const override;
58170   void Serialize(::protozero::Message*) const;
58171 
58172  private:
58173 
58174   // Allows to preserve unknown protobuf fields for compatibility
58175   // with future versions of .proto files.
58176   std::string unknown_fields_;
58177 
58178   std::bitset<2> _has_field_{};
58179 };
58180 
58181 
58182 class PERFETTO_EXPORT StartTracingRequest : public ::protozero::CppMessageObj {
58183  public:
58184   enum FieldNumbers {
58185   };
58186 
58187   StartTracingRequest();
58188   ~StartTracingRequest() override;
58189   StartTracingRequest(StartTracingRequest&&) noexcept;
58190   StartTracingRequest& operator=(StartTracingRequest&&);
58191   StartTracingRequest(const StartTracingRequest&);
58192   StartTracingRequest& operator=(const StartTracingRequest&);
58193   bool operator==(const StartTracingRequest&) const;
operator !=(const StartTracingRequest & other) const58194   bool operator!=(const StartTracingRequest& other) const { return !(*this == other); }
58195 
58196   bool ParseFromArray(const void*, size_t) override;
58197   std::string SerializeAsString() const override;
58198   std::vector<uint8_t> SerializeAsArray() const override;
58199   void Serialize(::protozero::Message*) const;
58200 
58201  private:
58202 
58203   // Allows to preserve unknown protobuf fields for compatibility
58204   // with future versions of .proto files.
58205   std::string unknown_fields_;
58206 
58207   std::bitset<2> _has_field_{};
58208 };
58209 
58210 
58211 class PERFETTO_EXPORT EnableTracingResponse : public ::protozero::CppMessageObj {
58212  public:
58213   enum FieldNumbers {
58214     kDisabledFieldNumber = 1,
58215     kErrorFieldNumber = 3,
58216   };
58217 
58218   EnableTracingResponse();
58219   ~EnableTracingResponse() override;
58220   EnableTracingResponse(EnableTracingResponse&&) noexcept;
58221   EnableTracingResponse& operator=(EnableTracingResponse&&);
58222   EnableTracingResponse(const EnableTracingResponse&);
58223   EnableTracingResponse& operator=(const EnableTracingResponse&);
58224   bool operator==(const EnableTracingResponse&) const;
operator !=(const EnableTracingResponse & other) const58225   bool operator!=(const EnableTracingResponse& other) const { return !(*this == other); }
58226 
58227   bool ParseFromArray(const void*, size_t) override;
58228   std::string SerializeAsString() const override;
58229   std::vector<uint8_t> SerializeAsArray() const override;
58230   void Serialize(::protozero::Message*) const;
58231 
has_disabled() const58232   bool has_disabled() const { return _has_field_[1]; }
disabled() const58233   bool disabled() const { return disabled_; }
set_disabled(bool value)58234   void set_disabled(bool value) { disabled_ = value; _has_field_.set(1); }
58235 
has_error() const58236   bool has_error() const { return _has_field_[3]; }
error() const58237   const std::string& error() const { return error_; }
set_error(const std::string & value)58238   void set_error(const std::string& value) { error_ = value; _has_field_.set(3); }
58239 
58240  private:
58241   bool disabled_{};
58242   std::string error_{};
58243 
58244   // Allows to preserve unknown protobuf fields for compatibility
58245   // with future versions of .proto files.
58246   std::string unknown_fields_;
58247 
58248   std::bitset<4> _has_field_{};
58249 };
58250 
58251 
58252 class PERFETTO_EXPORT EnableTracingRequest : public ::protozero::CppMessageObj {
58253  public:
58254   enum FieldNumbers {
58255     kTraceConfigFieldNumber = 1,
58256     kAttachNotificationOnlyFieldNumber = 2,
58257   };
58258 
58259   EnableTracingRequest();
58260   ~EnableTracingRequest() override;
58261   EnableTracingRequest(EnableTracingRequest&&) noexcept;
58262   EnableTracingRequest& operator=(EnableTracingRequest&&);
58263   EnableTracingRequest(const EnableTracingRequest&);
58264   EnableTracingRequest& operator=(const EnableTracingRequest&);
58265   bool operator==(const EnableTracingRequest&) const;
operator !=(const EnableTracingRequest & other) const58266   bool operator!=(const EnableTracingRequest& other) const { return !(*this == other); }
58267 
58268   bool ParseFromArray(const void*, size_t) override;
58269   std::string SerializeAsString() const override;
58270   std::vector<uint8_t> SerializeAsArray() const override;
58271   void Serialize(::protozero::Message*) const;
58272 
has_trace_config() const58273   bool has_trace_config() const { return _has_field_[1]; }
trace_config() const58274   const TraceConfig& trace_config() const { return *trace_config_; }
mutable_trace_config()58275   TraceConfig* mutable_trace_config() { _has_field_.set(1); return trace_config_.get(); }
58276 
has_attach_notification_only() const58277   bool has_attach_notification_only() const { return _has_field_[2]; }
attach_notification_only() const58278   bool attach_notification_only() const { return attach_notification_only_; }
set_attach_notification_only(bool value)58279   void set_attach_notification_only(bool value) { attach_notification_only_ = value; _has_field_.set(2); }
58280 
58281  private:
58282   ::protozero::CopyablePtr<TraceConfig> trace_config_;
58283   bool attach_notification_only_{};
58284 
58285   // Allows to preserve unknown protobuf fields for compatibility
58286   // with future versions of .proto files.
58287   std::string unknown_fields_;
58288 
58289   std::bitset<3> _has_field_{};
58290 };
58291 
58292 }  // namespace perfetto
58293 }  // namespace protos
58294 }  // namespace gen
58295 
58296 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_IPC_CONSUMER_PORT_PROTO_CPP_H_
58297 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
58298 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
58299 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
58300 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
58301 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
58302 #if defined(__GNUC__) || defined(__clang__)
58303 #pragma GCC diagnostic push
58304 #pragma GCC diagnostic ignored "-Wfloat-equal"
58305 #endif
58306 // gen_amalgamated expanded: #include "protos/perfetto/ipc/consumer_port.gen.h"
58307 // gen_amalgamated expanded: #include "protos/perfetto/config/trace_config.gen.h"
58308 // gen_amalgamated expanded: #include "protos/perfetto/config/data_source_config.gen.h"
58309 // gen_amalgamated expanded: #include "protos/perfetto/config/track_event/track_event_config.gen.h"
58310 // gen_amalgamated expanded: #include "protos/perfetto/config/test_config.gen.h"
58311 // gen_amalgamated expanded: #include "protos/perfetto/config/sys_stats/sys_stats_config.gen.h"
58312 // gen_amalgamated expanded: #include "protos/perfetto/common/sys_stats_counters.gen.h"
58313 // gen_amalgamated expanded: #include "protos/perfetto/config/profiling/perf_event_config.gen.h"
58314 // gen_amalgamated expanded: #include "protos/perfetto/common/perf_events.gen.h"
58315 // gen_amalgamated expanded: #include "protos/perfetto/config/profiling/java_hprof_config.gen.h"
58316 // gen_amalgamated expanded: #include "protos/perfetto/config/profiling/heapprofd_config.gen.h"
58317 // gen_amalgamated expanded: #include "protos/perfetto/config/process_stats/process_stats_config.gen.h"
58318 // gen_amalgamated expanded: #include "protos/perfetto/config/power/android_power_config.gen.h"
58319 // gen_amalgamated expanded: #include "protos/perfetto/config/interceptor_config.gen.h"
58320 // gen_amalgamated expanded: #include "protos/perfetto/config/interceptors/console_config.gen.h"
58321 // gen_amalgamated expanded: #include "protos/perfetto/config/inode_file/inode_file_config.gen.h"
58322 // gen_amalgamated expanded: #include "protos/perfetto/config/gpu/vulkan_memory_config.gen.h"
58323 // gen_amalgamated expanded: #include "protos/perfetto/config/gpu/gpu_counter_config.gen.h"
58324 // gen_amalgamated expanded: #include "protos/perfetto/config/ftrace/ftrace_config.gen.h"
58325 // gen_amalgamated expanded: #include "protos/perfetto/config/chrome/chrome_config.gen.h"
58326 // gen_amalgamated expanded: #include "protos/perfetto/config/android/packages_list_config.gen.h"
58327 // gen_amalgamated expanded: #include "protos/perfetto/config/android/android_polled_state_config.gen.h"
58328 // gen_amalgamated expanded: #include "protos/perfetto/config/android/android_log_config.gen.h"
58329 // gen_amalgamated expanded: #include "protos/perfetto/common/android_log_constants.gen.h"
58330 // gen_amalgamated expanded: #include "protos/perfetto/common/builtin_clock.gen.h"
58331 // gen_amalgamated expanded: #include "protos/perfetto/common/trace_stats.gen.h"
58332 // gen_amalgamated expanded: #include "protos/perfetto/common/tracing_service_capabilities.gen.h"
58333 // gen_amalgamated expanded: #include "protos/perfetto/common/observable_events.gen.h"
58334 // gen_amalgamated expanded: #include "protos/perfetto/common/tracing_service_state.gen.h"
58335 // gen_amalgamated expanded: #include "protos/perfetto/common/data_source_descriptor.gen.h"
58336 // gen_amalgamated expanded: #include "protos/perfetto/common/track_event_descriptor.gen.h"
58337 // gen_amalgamated expanded: #include "protos/perfetto/common/gpu_counter_descriptor.gen.h"
58338 // gen_amalgamated expanded: #include "protos/perfetto/common/observable_events.gen.h"
58339 
58340 namespace perfetto {
58341 namespace protos {
58342 namespace gen {
58343 
58344 SaveTraceForBugreportResponse::SaveTraceForBugreportResponse() = default;
58345 SaveTraceForBugreportResponse::~SaveTraceForBugreportResponse() = default;
58346 SaveTraceForBugreportResponse::SaveTraceForBugreportResponse(const SaveTraceForBugreportResponse&) = default;
58347 SaveTraceForBugreportResponse& SaveTraceForBugreportResponse::operator=(const SaveTraceForBugreportResponse&) = default;
58348 SaveTraceForBugreportResponse::SaveTraceForBugreportResponse(SaveTraceForBugreportResponse&&) noexcept = default;
58349 SaveTraceForBugreportResponse& SaveTraceForBugreportResponse::operator=(SaveTraceForBugreportResponse&&) = default;
58350 
operator ==(const SaveTraceForBugreportResponse & other) const58351 bool SaveTraceForBugreportResponse::operator==(const SaveTraceForBugreportResponse& other) const {
58352   return unknown_fields_ == other.unknown_fields_
58353    && success_ == other.success_
58354    && msg_ == other.msg_;
58355 }
58356 
ParseFromArray(const void * raw,size_t size)58357 bool SaveTraceForBugreportResponse::ParseFromArray(const void* raw, size_t size) {
58358   unknown_fields_.clear();
58359   bool packed_error = false;
58360 
58361   ::protozero::ProtoDecoder dec(raw, size);
58362   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
58363     if (field.id() < _has_field_.size()) {
58364       _has_field_.set(field.id());
58365     }
58366     switch (field.id()) {
58367       case 1 /* success */:
58368         field.get(&success_);
58369         break;
58370       case 2 /* msg */:
58371         field.get(&msg_);
58372         break;
58373       default:
58374         field.SerializeAndAppendTo(&unknown_fields_);
58375         break;
58376     }
58377   }
58378   return !packed_error && !dec.bytes_left();
58379 }
58380 
SerializeAsString() const58381 std::string SaveTraceForBugreportResponse::SerializeAsString() const {
58382   ::protozero::HeapBuffered<::protozero::Message> msg;
58383   Serialize(msg.get());
58384   return msg.SerializeAsString();
58385 }
58386 
SerializeAsArray() const58387 std::vector<uint8_t> SaveTraceForBugreportResponse::SerializeAsArray() const {
58388   ::protozero::HeapBuffered<::protozero::Message> msg;
58389   Serialize(msg.get());
58390   return msg.SerializeAsArray();
58391 }
58392 
Serialize(::protozero::Message * msg) const58393 void SaveTraceForBugreportResponse::Serialize(::protozero::Message* msg) const {
58394   // Field 1: success
58395   if (_has_field_[1]) {
58396     msg->AppendTinyVarInt(1, success_);
58397   }
58398 
58399   // Field 2: msg
58400   if (_has_field_[2]) {
58401     msg->AppendString(2, msg_);
58402   }
58403 
58404   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
58405 }
58406 
58407 
58408 SaveTraceForBugreportRequest::SaveTraceForBugreportRequest() = default;
58409 SaveTraceForBugreportRequest::~SaveTraceForBugreportRequest() = default;
58410 SaveTraceForBugreportRequest::SaveTraceForBugreportRequest(const SaveTraceForBugreportRequest&) = default;
58411 SaveTraceForBugreportRequest& SaveTraceForBugreportRequest::operator=(const SaveTraceForBugreportRequest&) = default;
58412 SaveTraceForBugreportRequest::SaveTraceForBugreportRequest(SaveTraceForBugreportRequest&&) noexcept = default;
58413 SaveTraceForBugreportRequest& SaveTraceForBugreportRequest::operator=(SaveTraceForBugreportRequest&&) = default;
58414 
operator ==(const SaveTraceForBugreportRequest & other) const58415 bool SaveTraceForBugreportRequest::operator==(const SaveTraceForBugreportRequest& other) const {
58416   return unknown_fields_ == other.unknown_fields_;
58417 }
58418 
ParseFromArray(const void * raw,size_t size)58419 bool SaveTraceForBugreportRequest::ParseFromArray(const void* raw, size_t size) {
58420   unknown_fields_.clear();
58421   bool packed_error = false;
58422 
58423   ::protozero::ProtoDecoder dec(raw, size);
58424   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
58425     if (field.id() < _has_field_.size()) {
58426       _has_field_.set(field.id());
58427     }
58428     switch (field.id()) {
58429       default:
58430         field.SerializeAndAppendTo(&unknown_fields_);
58431         break;
58432     }
58433   }
58434   return !packed_error && !dec.bytes_left();
58435 }
58436 
SerializeAsString() const58437 std::string SaveTraceForBugreportRequest::SerializeAsString() const {
58438   ::protozero::HeapBuffered<::protozero::Message> msg;
58439   Serialize(msg.get());
58440   return msg.SerializeAsString();
58441 }
58442 
SerializeAsArray() const58443 std::vector<uint8_t> SaveTraceForBugreportRequest::SerializeAsArray() const {
58444   ::protozero::HeapBuffered<::protozero::Message> msg;
58445   Serialize(msg.get());
58446   return msg.SerializeAsArray();
58447 }
58448 
Serialize(::protozero::Message * msg) const58449 void SaveTraceForBugreportRequest::Serialize(::protozero::Message* msg) const {
58450   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
58451 }
58452 
58453 
58454 QueryCapabilitiesResponse::QueryCapabilitiesResponse() = default;
58455 QueryCapabilitiesResponse::~QueryCapabilitiesResponse() = default;
58456 QueryCapabilitiesResponse::QueryCapabilitiesResponse(const QueryCapabilitiesResponse&) = default;
58457 QueryCapabilitiesResponse& QueryCapabilitiesResponse::operator=(const QueryCapabilitiesResponse&) = default;
58458 QueryCapabilitiesResponse::QueryCapabilitiesResponse(QueryCapabilitiesResponse&&) noexcept = default;
58459 QueryCapabilitiesResponse& QueryCapabilitiesResponse::operator=(QueryCapabilitiesResponse&&) = default;
58460 
operator ==(const QueryCapabilitiesResponse & other) const58461 bool QueryCapabilitiesResponse::operator==(const QueryCapabilitiesResponse& other) const {
58462   return unknown_fields_ == other.unknown_fields_
58463    && capabilities_ == other.capabilities_;
58464 }
58465 
ParseFromArray(const void * raw,size_t size)58466 bool QueryCapabilitiesResponse::ParseFromArray(const void* raw, size_t size) {
58467   unknown_fields_.clear();
58468   bool packed_error = false;
58469 
58470   ::protozero::ProtoDecoder dec(raw, size);
58471   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
58472     if (field.id() < _has_field_.size()) {
58473       _has_field_.set(field.id());
58474     }
58475     switch (field.id()) {
58476       case 1 /* capabilities */:
58477         (*capabilities_).ParseFromArray(field.data(), field.size());
58478         break;
58479       default:
58480         field.SerializeAndAppendTo(&unknown_fields_);
58481         break;
58482     }
58483   }
58484   return !packed_error && !dec.bytes_left();
58485 }
58486 
SerializeAsString() const58487 std::string QueryCapabilitiesResponse::SerializeAsString() const {
58488   ::protozero::HeapBuffered<::protozero::Message> msg;
58489   Serialize(msg.get());
58490   return msg.SerializeAsString();
58491 }
58492 
SerializeAsArray() const58493 std::vector<uint8_t> QueryCapabilitiesResponse::SerializeAsArray() const {
58494   ::protozero::HeapBuffered<::protozero::Message> msg;
58495   Serialize(msg.get());
58496   return msg.SerializeAsArray();
58497 }
58498 
Serialize(::protozero::Message * msg) const58499 void QueryCapabilitiesResponse::Serialize(::protozero::Message* msg) const {
58500   // Field 1: capabilities
58501   if (_has_field_[1]) {
58502     (*capabilities_).Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
58503   }
58504 
58505   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
58506 }
58507 
58508 
58509 QueryCapabilitiesRequest::QueryCapabilitiesRequest() = default;
58510 QueryCapabilitiesRequest::~QueryCapabilitiesRequest() = default;
58511 QueryCapabilitiesRequest::QueryCapabilitiesRequest(const QueryCapabilitiesRequest&) = default;
58512 QueryCapabilitiesRequest& QueryCapabilitiesRequest::operator=(const QueryCapabilitiesRequest&) = default;
58513 QueryCapabilitiesRequest::QueryCapabilitiesRequest(QueryCapabilitiesRequest&&) noexcept = default;
58514 QueryCapabilitiesRequest& QueryCapabilitiesRequest::operator=(QueryCapabilitiesRequest&&) = default;
58515 
operator ==(const QueryCapabilitiesRequest & other) const58516 bool QueryCapabilitiesRequest::operator==(const QueryCapabilitiesRequest& other) const {
58517   return unknown_fields_ == other.unknown_fields_;
58518 }
58519 
ParseFromArray(const void * raw,size_t size)58520 bool QueryCapabilitiesRequest::ParseFromArray(const void* raw, size_t size) {
58521   unknown_fields_.clear();
58522   bool packed_error = false;
58523 
58524   ::protozero::ProtoDecoder dec(raw, size);
58525   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
58526     if (field.id() < _has_field_.size()) {
58527       _has_field_.set(field.id());
58528     }
58529     switch (field.id()) {
58530       default:
58531         field.SerializeAndAppendTo(&unknown_fields_);
58532         break;
58533     }
58534   }
58535   return !packed_error && !dec.bytes_left();
58536 }
58537 
SerializeAsString() const58538 std::string QueryCapabilitiesRequest::SerializeAsString() const {
58539   ::protozero::HeapBuffered<::protozero::Message> msg;
58540   Serialize(msg.get());
58541   return msg.SerializeAsString();
58542 }
58543 
SerializeAsArray() const58544 std::vector<uint8_t> QueryCapabilitiesRequest::SerializeAsArray() const {
58545   ::protozero::HeapBuffered<::protozero::Message> msg;
58546   Serialize(msg.get());
58547   return msg.SerializeAsArray();
58548 }
58549 
Serialize(::protozero::Message * msg) const58550 void QueryCapabilitiesRequest::Serialize(::protozero::Message* msg) const {
58551   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
58552 }
58553 
58554 
58555 QueryServiceStateResponse::QueryServiceStateResponse() = default;
58556 QueryServiceStateResponse::~QueryServiceStateResponse() = default;
58557 QueryServiceStateResponse::QueryServiceStateResponse(const QueryServiceStateResponse&) = default;
58558 QueryServiceStateResponse& QueryServiceStateResponse::operator=(const QueryServiceStateResponse&) = default;
58559 QueryServiceStateResponse::QueryServiceStateResponse(QueryServiceStateResponse&&) noexcept = default;
58560 QueryServiceStateResponse& QueryServiceStateResponse::operator=(QueryServiceStateResponse&&) = default;
58561 
operator ==(const QueryServiceStateResponse & other) const58562 bool QueryServiceStateResponse::operator==(const QueryServiceStateResponse& other) const {
58563   return unknown_fields_ == other.unknown_fields_
58564    && service_state_ == other.service_state_;
58565 }
58566 
ParseFromArray(const void * raw,size_t size)58567 bool QueryServiceStateResponse::ParseFromArray(const void* raw, size_t size) {
58568   unknown_fields_.clear();
58569   bool packed_error = false;
58570 
58571   ::protozero::ProtoDecoder dec(raw, size);
58572   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
58573     if (field.id() < _has_field_.size()) {
58574       _has_field_.set(field.id());
58575     }
58576     switch (field.id()) {
58577       case 1 /* service_state */:
58578         (*service_state_).ParseFromArray(field.data(), field.size());
58579         break;
58580       default:
58581         field.SerializeAndAppendTo(&unknown_fields_);
58582         break;
58583     }
58584   }
58585   return !packed_error && !dec.bytes_left();
58586 }
58587 
SerializeAsString() const58588 std::string QueryServiceStateResponse::SerializeAsString() const {
58589   ::protozero::HeapBuffered<::protozero::Message> msg;
58590   Serialize(msg.get());
58591   return msg.SerializeAsString();
58592 }
58593 
SerializeAsArray() const58594 std::vector<uint8_t> QueryServiceStateResponse::SerializeAsArray() const {
58595   ::protozero::HeapBuffered<::protozero::Message> msg;
58596   Serialize(msg.get());
58597   return msg.SerializeAsArray();
58598 }
58599 
Serialize(::protozero::Message * msg) const58600 void QueryServiceStateResponse::Serialize(::protozero::Message* msg) const {
58601   // Field 1: service_state
58602   if (_has_field_[1]) {
58603     (*service_state_).Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
58604   }
58605 
58606   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
58607 }
58608 
58609 
58610 QueryServiceStateRequest::QueryServiceStateRequest() = default;
58611 QueryServiceStateRequest::~QueryServiceStateRequest() = default;
58612 QueryServiceStateRequest::QueryServiceStateRequest(const QueryServiceStateRequest&) = default;
58613 QueryServiceStateRequest& QueryServiceStateRequest::operator=(const QueryServiceStateRequest&) = default;
58614 QueryServiceStateRequest::QueryServiceStateRequest(QueryServiceStateRequest&&) noexcept = default;
58615 QueryServiceStateRequest& QueryServiceStateRequest::operator=(QueryServiceStateRequest&&) = default;
58616 
operator ==(const QueryServiceStateRequest & other) const58617 bool QueryServiceStateRequest::operator==(const QueryServiceStateRequest& other) const {
58618   return unknown_fields_ == other.unknown_fields_;
58619 }
58620 
ParseFromArray(const void * raw,size_t size)58621 bool QueryServiceStateRequest::ParseFromArray(const void* raw, size_t size) {
58622   unknown_fields_.clear();
58623   bool packed_error = false;
58624 
58625   ::protozero::ProtoDecoder dec(raw, size);
58626   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
58627     if (field.id() < _has_field_.size()) {
58628       _has_field_.set(field.id());
58629     }
58630     switch (field.id()) {
58631       default:
58632         field.SerializeAndAppendTo(&unknown_fields_);
58633         break;
58634     }
58635   }
58636   return !packed_error && !dec.bytes_left();
58637 }
58638 
SerializeAsString() const58639 std::string QueryServiceStateRequest::SerializeAsString() const {
58640   ::protozero::HeapBuffered<::protozero::Message> msg;
58641   Serialize(msg.get());
58642   return msg.SerializeAsString();
58643 }
58644 
SerializeAsArray() const58645 std::vector<uint8_t> QueryServiceStateRequest::SerializeAsArray() const {
58646   ::protozero::HeapBuffered<::protozero::Message> msg;
58647   Serialize(msg.get());
58648   return msg.SerializeAsArray();
58649 }
58650 
Serialize(::protozero::Message * msg) const58651 void QueryServiceStateRequest::Serialize(::protozero::Message* msg) const {
58652   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
58653 }
58654 
58655 
58656 ObserveEventsResponse::ObserveEventsResponse() = default;
58657 ObserveEventsResponse::~ObserveEventsResponse() = default;
58658 ObserveEventsResponse::ObserveEventsResponse(const ObserveEventsResponse&) = default;
58659 ObserveEventsResponse& ObserveEventsResponse::operator=(const ObserveEventsResponse&) = default;
58660 ObserveEventsResponse::ObserveEventsResponse(ObserveEventsResponse&&) noexcept = default;
58661 ObserveEventsResponse& ObserveEventsResponse::operator=(ObserveEventsResponse&&) = default;
58662 
operator ==(const ObserveEventsResponse & other) const58663 bool ObserveEventsResponse::operator==(const ObserveEventsResponse& other) const {
58664   return unknown_fields_ == other.unknown_fields_
58665    && events_ == other.events_;
58666 }
58667 
ParseFromArray(const void * raw,size_t size)58668 bool ObserveEventsResponse::ParseFromArray(const void* raw, size_t size) {
58669   unknown_fields_.clear();
58670   bool packed_error = false;
58671 
58672   ::protozero::ProtoDecoder dec(raw, size);
58673   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
58674     if (field.id() < _has_field_.size()) {
58675       _has_field_.set(field.id());
58676     }
58677     switch (field.id()) {
58678       case 1 /* events */:
58679         (*events_).ParseFromArray(field.data(), field.size());
58680         break;
58681       default:
58682         field.SerializeAndAppendTo(&unknown_fields_);
58683         break;
58684     }
58685   }
58686   return !packed_error && !dec.bytes_left();
58687 }
58688 
SerializeAsString() const58689 std::string ObserveEventsResponse::SerializeAsString() const {
58690   ::protozero::HeapBuffered<::protozero::Message> msg;
58691   Serialize(msg.get());
58692   return msg.SerializeAsString();
58693 }
58694 
SerializeAsArray() const58695 std::vector<uint8_t> ObserveEventsResponse::SerializeAsArray() const {
58696   ::protozero::HeapBuffered<::protozero::Message> msg;
58697   Serialize(msg.get());
58698   return msg.SerializeAsArray();
58699 }
58700 
Serialize(::protozero::Message * msg) const58701 void ObserveEventsResponse::Serialize(::protozero::Message* msg) const {
58702   // Field 1: events
58703   if (_has_field_[1]) {
58704     (*events_).Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
58705   }
58706 
58707   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
58708 }
58709 
58710 
58711 ObserveEventsRequest::ObserveEventsRequest() = default;
58712 ObserveEventsRequest::~ObserveEventsRequest() = default;
58713 ObserveEventsRequest::ObserveEventsRequest(const ObserveEventsRequest&) = default;
58714 ObserveEventsRequest& ObserveEventsRequest::operator=(const ObserveEventsRequest&) = default;
58715 ObserveEventsRequest::ObserveEventsRequest(ObserveEventsRequest&&) noexcept = default;
58716 ObserveEventsRequest& ObserveEventsRequest::operator=(ObserveEventsRequest&&) = default;
58717 
operator ==(const ObserveEventsRequest & other) const58718 bool ObserveEventsRequest::operator==(const ObserveEventsRequest& other) const {
58719   return unknown_fields_ == other.unknown_fields_
58720    && events_to_observe_ == other.events_to_observe_;
58721 }
58722 
ParseFromArray(const void * raw,size_t size)58723 bool ObserveEventsRequest::ParseFromArray(const void* raw, size_t size) {
58724   events_to_observe_.clear();
58725   unknown_fields_.clear();
58726   bool packed_error = false;
58727 
58728   ::protozero::ProtoDecoder dec(raw, size);
58729   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
58730     if (field.id() < _has_field_.size()) {
58731       _has_field_.set(field.id());
58732     }
58733     switch (field.id()) {
58734       case 1 /* events_to_observe */:
58735         events_to_observe_.emplace_back();
58736         field.get(&events_to_observe_.back());
58737         break;
58738       default:
58739         field.SerializeAndAppendTo(&unknown_fields_);
58740         break;
58741     }
58742   }
58743   return !packed_error && !dec.bytes_left();
58744 }
58745 
SerializeAsString() const58746 std::string ObserveEventsRequest::SerializeAsString() const {
58747   ::protozero::HeapBuffered<::protozero::Message> msg;
58748   Serialize(msg.get());
58749   return msg.SerializeAsString();
58750 }
58751 
SerializeAsArray() const58752 std::vector<uint8_t> ObserveEventsRequest::SerializeAsArray() const {
58753   ::protozero::HeapBuffered<::protozero::Message> msg;
58754   Serialize(msg.get());
58755   return msg.SerializeAsArray();
58756 }
58757 
Serialize(::protozero::Message * msg) const58758 void ObserveEventsRequest::Serialize(::protozero::Message* msg) const {
58759   // Field 1: events_to_observe
58760   for (auto& it : events_to_observe_) {
58761     msg->AppendVarInt(1, it);
58762   }
58763 
58764   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
58765 }
58766 
58767 
58768 GetTraceStatsResponse::GetTraceStatsResponse() = default;
58769 GetTraceStatsResponse::~GetTraceStatsResponse() = default;
58770 GetTraceStatsResponse::GetTraceStatsResponse(const GetTraceStatsResponse&) = default;
58771 GetTraceStatsResponse& GetTraceStatsResponse::operator=(const GetTraceStatsResponse&) = default;
58772 GetTraceStatsResponse::GetTraceStatsResponse(GetTraceStatsResponse&&) noexcept = default;
58773 GetTraceStatsResponse& GetTraceStatsResponse::operator=(GetTraceStatsResponse&&) = default;
58774 
operator ==(const GetTraceStatsResponse & other) const58775 bool GetTraceStatsResponse::operator==(const GetTraceStatsResponse& other) const {
58776   return unknown_fields_ == other.unknown_fields_
58777    && trace_stats_ == other.trace_stats_;
58778 }
58779 
ParseFromArray(const void * raw,size_t size)58780 bool GetTraceStatsResponse::ParseFromArray(const void* raw, size_t size) {
58781   unknown_fields_.clear();
58782   bool packed_error = false;
58783 
58784   ::protozero::ProtoDecoder dec(raw, size);
58785   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
58786     if (field.id() < _has_field_.size()) {
58787       _has_field_.set(field.id());
58788     }
58789     switch (field.id()) {
58790       case 1 /* trace_stats */:
58791         (*trace_stats_).ParseFromArray(field.data(), field.size());
58792         break;
58793       default:
58794         field.SerializeAndAppendTo(&unknown_fields_);
58795         break;
58796     }
58797   }
58798   return !packed_error && !dec.bytes_left();
58799 }
58800 
SerializeAsString() const58801 std::string GetTraceStatsResponse::SerializeAsString() const {
58802   ::protozero::HeapBuffered<::protozero::Message> msg;
58803   Serialize(msg.get());
58804   return msg.SerializeAsString();
58805 }
58806 
SerializeAsArray() const58807 std::vector<uint8_t> GetTraceStatsResponse::SerializeAsArray() const {
58808   ::protozero::HeapBuffered<::protozero::Message> msg;
58809   Serialize(msg.get());
58810   return msg.SerializeAsArray();
58811 }
58812 
Serialize(::protozero::Message * msg) const58813 void GetTraceStatsResponse::Serialize(::protozero::Message* msg) const {
58814   // Field 1: trace_stats
58815   if (_has_field_[1]) {
58816     (*trace_stats_).Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
58817   }
58818 
58819   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
58820 }
58821 
58822 
58823 GetTraceStatsRequest::GetTraceStatsRequest() = default;
58824 GetTraceStatsRequest::~GetTraceStatsRequest() = default;
58825 GetTraceStatsRequest::GetTraceStatsRequest(const GetTraceStatsRequest&) = default;
58826 GetTraceStatsRequest& GetTraceStatsRequest::operator=(const GetTraceStatsRequest&) = default;
58827 GetTraceStatsRequest::GetTraceStatsRequest(GetTraceStatsRequest&&) noexcept = default;
58828 GetTraceStatsRequest& GetTraceStatsRequest::operator=(GetTraceStatsRequest&&) = default;
58829 
operator ==(const GetTraceStatsRequest & other) const58830 bool GetTraceStatsRequest::operator==(const GetTraceStatsRequest& other) const {
58831   return unknown_fields_ == other.unknown_fields_;
58832 }
58833 
ParseFromArray(const void * raw,size_t size)58834 bool GetTraceStatsRequest::ParseFromArray(const void* raw, size_t size) {
58835   unknown_fields_.clear();
58836   bool packed_error = false;
58837 
58838   ::protozero::ProtoDecoder dec(raw, size);
58839   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
58840     if (field.id() < _has_field_.size()) {
58841       _has_field_.set(field.id());
58842     }
58843     switch (field.id()) {
58844       default:
58845         field.SerializeAndAppendTo(&unknown_fields_);
58846         break;
58847     }
58848   }
58849   return !packed_error && !dec.bytes_left();
58850 }
58851 
SerializeAsString() const58852 std::string GetTraceStatsRequest::SerializeAsString() const {
58853   ::protozero::HeapBuffered<::protozero::Message> msg;
58854   Serialize(msg.get());
58855   return msg.SerializeAsString();
58856 }
58857 
SerializeAsArray() const58858 std::vector<uint8_t> GetTraceStatsRequest::SerializeAsArray() const {
58859   ::protozero::HeapBuffered<::protozero::Message> msg;
58860   Serialize(msg.get());
58861   return msg.SerializeAsArray();
58862 }
58863 
Serialize(::protozero::Message * msg) const58864 void GetTraceStatsRequest::Serialize(::protozero::Message* msg) const {
58865   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
58866 }
58867 
58868 
58869 AttachResponse::AttachResponse() = default;
58870 AttachResponse::~AttachResponse() = default;
58871 AttachResponse::AttachResponse(const AttachResponse&) = default;
58872 AttachResponse& AttachResponse::operator=(const AttachResponse&) = default;
58873 AttachResponse::AttachResponse(AttachResponse&&) noexcept = default;
58874 AttachResponse& AttachResponse::operator=(AttachResponse&&) = default;
58875 
operator ==(const AttachResponse & other) const58876 bool AttachResponse::operator==(const AttachResponse& other) const {
58877   return unknown_fields_ == other.unknown_fields_
58878    && trace_config_ == other.trace_config_;
58879 }
58880 
ParseFromArray(const void * raw,size_t size)58881 bool AttachResponse::ParseFromArray(const void* raw, size_t size) {
58882   unknown_fields_.clear();
58883   bool packed_error = false;
58884 
58885   ::protozero::ProtoDecoder dec(raw, size);
58886   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
58887     if (field.id() < _has_field_.size()) {
58888       _has_field_.set(field.id());
58889     }
58890     switch (field.id()) {
58891       case 1 /* trace_config */:
58892         (*trace_config_).ParseFromArray(field.data(), field.size());
58893         break;
58894       default:
58895         field.SerializeAndAppendTo(&unknown_fields_);
58896         break;
58897     }
58898   }
58899   return !packed_error && !dec.bytes_left();
58900 }
58901 
SerializeAsString() const58902 std::string AttachResponse::SerializeAsString() const {
58903   ::protozero::HeapBuffered<::protozero::Message> msg;
58904   Serialize(msg.get());
58905   return msg.SerializeAsString();
58906 }
58907 
SerializeAsArray() const58908 std::vector<uint8_t> AttachResponse::SerializeAsArray() const {
58909   ::protozero::HeapBuffered<::protozero::Message> msg;
58910   Serialize(msg.get());
58911   return msg.SerializeAsArray();
58912 }
58913 
Serialize(::protozero::Message * msg) const58914 void AttachResponse::Serialize(::protozero::Message* msg) const {
58915   // Field 1: trace_config
58916   if (_has_field_[1]) {
58917     (*trace_config_).Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
58918   }
58919 
58920   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
58921 }
58922 
58923 
58924 AttachRequest::AttachRequest() = default;
58925 AttachRequest::~AttachRequest() = default;
58926 AttachRequest::AttachRequest(const AttachRequest&) = default;
58927 AttachRequest& AttachRequest::operator=(const AttachRequest&) = default;
58928 AttachRequest::AttachRequest(AttachRequest&&) noexcept = default;
58929 AttachRequest& AttachRequest::operator=(AttachRequest&&) = default;
58930 
operator ==(const AttachRequest & other) const58931 bool AttachRequest::operator==(const AttachRequest& other) const {
58932   return unknown_fields_ == other.unknown_fields_
58933    && key_ == other.key_;
58934 }
58935 
ParseFromArray(const void * raw,size_t size)58936 bool AttachRequest::ParseFromArray(const void* raw, size_t size) {
58937   unknown_fields_.clear();
58938   bool packed_error = false;
58939 
58940   ::protozero::ProtoDecoder dec(raw, size);
58941   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
58942     if (field.id() < _has_field_.size()) {
58943       _has_field_.set(field.id());
58944     }
58945     switch (field.id()) {
58946       case 1 /* key */:
58947         field.get(&key_);
58948         break;
58949       default:
58950         field.SerializeAndAppendTo(&unknown_fields_);
58951         break;
58952     }
58953   }
58954   return !packed_error && !dec.bytes_left();
58955 }
58956 
SerializeAsString() const58957 std::string AttachRequest::SerializeAsString() const {
58958   ::protozero::HeapBuffered<::protozero::Message> msg;
58959   Serialize(msg.get());
58960   return msg.SerializeAsString();
58961 }
58962 
SerializeAsArray() const58963 std::vector<uint8_t> AttachRequest::SerializeAsArray() const {
58964   ::protozero::HeapBuffered<::protozero::Message> msg;
58965   Serialize(msg.get());
58966   return msg.SerializeAsArray();
58967 }
58968 
Serialize(::protozero::Message * msg) const58969 void AttachRequest::Serialize(::protozero::Message* msg) const {
58970   // Field 1: key
58971   if (_has_field_[1]) {
58972     msg->AppendString(1, key_);
58973   }
58974 
58975   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
58976 }
58977 
58978 
58979 DetachResponse::DetachResponse() = default;
58980 DetachResponse::~DetachResponse() = default;
58981 DetachResponse::DetachResponse(const DetachResponse&) = default;
58982 DetachResponse& DetachResponse::operator=(const DetachResponse&) = default;
58983 DetachResponse::DetachResponse(DetachResponse&&) noexcept = default;
58984 DetachResponse& DetachResponse::operator=(DetachResponse&&) = default;
58985 
operator ==(const DetachResponse & other) const58986 bool DetachResponse::operator==(const DetachResponse& other) const {
58987   return unknown_fields_ == other.unknown_fields_;
58988 }
58989 
ParseFromArray(const void * raw,size_t size)58990 bool DetachResponse::ParseFromArray(const void* raw, size_t size) {
58991   unknown_fields_.clear();
58992   bool packed_error = false;
58993 
58994   ::protozero::ProtoDecoder dec(raw, size);
58995   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
58996     if (field.id() < _has_field_.size()) {
58997       _has_field_.set(field.id());
58998     }
58999     switch (field.id()) {
59000       default:
59001         field.SerializeAndAppendTo(&unknown_fields_);
59002         break;
59003     }
59004   }
59005   return !packed_error && !dec.bytes_left();
59006 }
59007 
SerializeAsString() const59008 std::string DetachResponse::SerializeAsString() const {
59009   ::protozero::HeapBuffered<::protozero::Message> msg;
59010   Serialize(msg.get());
59011   return msg.SerializeAsString();
59012 }
59013 
SerializeAsArray() const59014 std::vector<uint8_t> DetachResponse::SerializeAsArray() const {
59015   ::protozero::HeapBuffered<::protozero::Message> msg;
59016   Serialize(msg.get());
59017   return msg.SerializeAsArray();
59018 }
59019 
Serialize(::protozero::Message * msg) const59020 void DetachResponse::Serialize(::protozero::Message* msg) const {
59021   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
59022 }
59023 
59024 
59025 DetachRequest::DetachRequest() = default;
59026 DetachRequest::~DetachRequest() = default;
59027 DetachRequest::DetachRequest(const DetachRequest&) = default;
59028 DetachRequest& DetachRequest::operator=(const DetachRequest&) = default;
59029 DetachRequest::DetachRequest(DetachRequest&&) noexcept = default;
59030 DetachRequest& DetachRequest::operator=(DetachRequest&&) = default;
59031 
operator ==(const DetachRequest & other) const59032 bool DetachRequest::operator==(const DetachRequest& other) const {
59033   return unknown_fields_ == other.unknown_fields_
59034    && key_ == other.key_;
59035 }
59036 
ParseFromArray(const void * raw,size_t size)59037 bool DetachRequest::ParseFromArray(const void* raw, size_t size) {
59038   unknown_fields_.clear();
59039   bool packed_error = false;
59040 
59041   ::protozero::ProtoDecoder dec(raw, size);
59042   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
59043     if (field.id() < _has_field_.size()) {
59044       _has_field_.set(field.id());
59045     }
59046     switch (field.id()) {
59047       case 1 /* key */:
59048         field.get(&key_);
59049         break;
59050       default:
59051         field.SerializeAndAppendTo(&unknown_fields_);
59052         break;
59053     }
59054   }
59055   return !packed_error && !dec.bytes_left();
59056 }
59057 
SerializeAsString() const59058 std::string DetachRequest::SerializeAsString() const {
59059   ::protozero::HeapBuffered<::protozero::Message> msg;
59060   Serialize(msg.get());
59061   return msg.SerializeAsString();
59062 }
59063 
SerializeAsArray() const59064 std::vector<uint8_t> DetachRequest::SerializeAsArray() const {
59065   ::protozero::HeapBuffered<::protozero::Message> msg;
59066   Serialize(msg.get());
59067   return msg.SerializeAsArray();
59068 }
59069 
Serialize(::protozero::Message * msg) const59070 void DetachRequest::Serialize(::protozero::Message* msg) const {
59071   // Field 1: key
59072   if (_has_field_[1]) {
59073     msg->AppendString(1, key_);
59074   }
59075 
59076   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
59077 }
59078 
59079 
59080 FlushResponse::FlushResponse() = default;
59081 FlushResponse::~FlushResponse() = default;
59082 FlushResponse::FlushResponse(const FlushResponse&) = default;
59083 FlushResponse& FlushResponse::operator=(const FlushResponse&) = default;
59084 FlushResponse::FlushResponse(FlushResponse&&) noexcept = default;
59085 FlushResponse& FlushResponse::operator=(FlushResponse&&) = default;
59086 
operator ==(const FlushResponse & other) const59087 bool FlushResponse::operator==(const FlushResponse& other) const {
59088   return unknown_fields_ == other.unknown_fields_;
59089 }
59090 
ParseFromArray(const void * raw,size_t size)59091 bool FlushResponse::ParseFromArray(const void* raw, size_t size) {
59092   unknown_fields_.clear();
59093   bool packed_error = false;
59094 
59095   ::protozero::ProtoDecoder dec(raw, size);
59096   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
59097     if (field.id() < _has_field_.size()) {
59098       _has_field_.set(field.id());
59099     }
59100     switch (field.id()) {
59101       default:
59102         field.SerializeAndAppendTo(&unknown_fields_);
59103         break;
59104     }
59105   }
59106   return !packed_error && !dec.bytes_left();
59107 }
59108 
SerializeAsString() const59109 std::string FlushResponse::SerializeAsString() const {
59110   ::protozero::HeapBuffered<::protozero::Message> msg;
59111   Serialize(msg.get());
59112   return msg.SerializeAsString();
59113 }
59114 
SerializeAsArray() const59115 std::vector<uint8_t> FlushResponse::SerializeAsArray() const {
59116   ::protozero::HeapBuffered<::protozero::Message> msg;
59117   Serialize(msg.get());
59118   return msg.SerializeAsArray();
59119 }
59120 
Serialize(::protozero::Message * msg) const59121 void FlushResponse::Serialize(::protozero::Message* msg) const {
59122   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
59123 }
59124 
59125 
59126 FlushRequest::FlushRequest() = default;
59127 FlushRequest::~FlushRequest() = default;
59128 FlushRequest::FlushRequest(const FlushRequest&) = default;
59129 FlushRequest& FlushRequest::operator=(const FlushRequest&) = default;
59130 FlushRequest::FlushRequest(FlushRequest&&) noexcept = default;
59131 FlushRequest& FlushRequest::operator=(FlushRequest&&) = default;
59132 
operator ==(const FlushRequest & other) const59133 bool FlushRequest::operator==(const FlushRequest& other) const {
59134   return unknown_fields_ == other.unknown_fields_
59135    && timeout_ms_ == other.timeout_ms_;
59136 }
59137 
ParseFromArray(const void * raw,size_t size)59138 bool FlushRequest::ParseFromArray(const void* raw, size_t size) {
59139   unknown_fields_.clear();
59140   bool packed_error = false;
59141 
59142   ::protozero::ProtoDecoder dec(raw, size);
59143   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
59144     if (field.id() < _has_field_.size()) {
59145       _has_field_.set(field.id());
59146     }
59147     switch (field.id()) {
59148       case 1 /* timeout_ms */:
59149         field.get(&timeout_ms_);
59150         break;
59151       default:
59152         field.SerializeAndAppendTo(&unknown_fields_);
59153         break;
59154     }
59155   }
59156   return !packed_error && !dec.bytes_left();
59157 }
59158 
SerializeAsString() const59159 std::string FlushRequest::SerializeAsString() const {
59160   ::protozero::HeapBuffered<::protozero::Message> msg;
59161   Serialize(msg.get());
59162   return msg.SerializeAsString();
59163 }
59164 
SerializeAsArray() const59165 std::vector<uint8_t> FlushRequest::SerializeAsArray() const {
59166   ::protozero::HeapBuffered<::protozero::Message> msg;
59167   Serialize(msg.get());
59168   return msg.SerializeAsArray();
59169 }
59170 
Serialize(::protozero::Message * msg) const59171 void FlushRequest::Serialize(::protozero::Message* msg) const {
59172   // Field 1: timeout_ms
59173   if (_has_field_[1]) {
59174     msg->AppendVarInt(1, timeout_ms_);
59175   }
59176 
59177   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
59178 }
59179 
59180 
59181 FreeBuffersResponse::FreeBuffersResponse() = default;
59182 FreeBuffersResponse::~FreeBuffersResponse() = default;
59183 FreeBuffersResponse::FreeBuffersResponse(const FreeBuffersResponse&) = default;
59184 FreeBuffersResponse& FreeBuffersResponse::operator=(const FreeBuffersResponse&) = default;
59185 FreeBuffersResponse::FreeBuffersResponse(FreeBuffersResponse&&) noexcept = default;
59186 FreeBuffersResponse& FreeBuffersResponse::operator=(FreeBuffersResponse&&) = default;
59187 
operator ==(const FreeBuffersResponse & other) const59188 bool FreeBuffersResponse::operator==(const FreeBuffersResponse& other) const {
59189   return unknown_fields_ == other.unknown_fields_;
59190 }
59191 
ParseFromArray(const void * raw,size_t size)59192 bool FreeBuffersResponse::ParseFromArray(const void* raw, size_t size) {
59193   unknown_fields_.clear();
59194   bool packed_error = false;
59195 
59196   ::protozero::ProtoDecoder dec(raw, size);
59197   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
59198     if (field.id() < _has_field_.size()) {
59199       _has_field_.set(field.id());
59200     }
59201     switch (field.id()) {
59202       default:
59203         field.SerializeAndAppendTo(&unknown_fields_);
59204         break;
59205     }
59206   }
59207   return !packed_error && !dec.bytes_left();
59208 }
59209 
SerializeAsString() const59210 std::string FreeBuffersResponse::SerializeAsString() const {
59211   ::protozero::HeapBuffered<::protozero::Message> msg;
59212   Serialize(msg.get());
59213   return msg.SerializeAsString();
59214 }
59215 
SerializeAsArray() const59216 std::vector<uint8_t> FreeBuffersResponse::SerializeAsArray() const {
59217   ::protozero::HeapBuffered<::protozero::Message> msg;
59218   Serialize(msg.get());
59219   return msg.SerializeAsArray();
59220 }
59221 
Serialize(::protozero::Message * msg) const59222 void FreeBuffersResponse::Serialize(::protozero::Message* msg) const {
59223   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
59224 }
59225 
59226 
59227 FreeBuffersRequest::FreeBuffersRequest() = default;
59228 FreeBuffersRequest::~FreeBuffersRequest() = default;
59229 FreeBuffersRequest::FreeBuffersRequest(const FreeBuffersRequest&) = default;
59230 FreeBuffersRequest& FreeBuffersRequest::operator=(const FreeBuffersRequest&) = default;
59231 FreeBuffersRequest::FreeBuffersRequest(FreeBuffersRequest&&) noexcept = default;
59232 FreeBuffersRequest& FreeBuffersRequest::operator=(FreeBuffersRequest&&) = default;
59233 
operator ==(const FreeBuffersRequest & other) const59234 bool FreeBuffersRequest::operator==(const FreeBuffersRequest& other) const {
59235   return unknown_fields_ == other.unknown_fields_
59236    && buffer_ids_ == other.buffer_ids_;
59237 }
59238 
ParseFromArray(const void * raw,size_t size)59239 bool FreeBuffersRequest::ParseFromArray(const void* raw, size_t size) {
59240   buffer_ids_.clear();
59241   unknown_fields_.clear();
59242   bool packed_error = false;
59243 
59244   ::protozero::ProtoDecoder dec(raw, size);
59245   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
59246     if (field.id() < _has_field_.size()) {
59247       _has_field_.set(field.id());
59248     }
59249     switch (field.id()) {
59250       case 1 /* buffer_ids */:
59251         buffer_ids_.emplace_back();
59252         field.get(&buffer_ids_.back());
59253         break;
59254       default:
59255         field.SerializeAndAppendTo(&unknown_fields_);
59256         break;
59257     }
59258   }
59259   return !packed_error && !dec.bytes_left();
59260 }
59261 
SerializeAsString() const59262 std::string FreeBuffersRequest::SerializeAsString() const {
59263   ::protozero::HeapBuffered<::protozero::Message> msg;
59264   Serialize(msg.get());
59265   return msg.SerializeAsString();
59266 }
59267 
SerializeAsArray() const59268 std::vector<uint8_t> FreeBuffersRequest::SerializeAsArray() const {
59269   ::protozero::HeapBuffered<::protozero::Message> msg;
59270   Serialize(msg.get());
59271   return msg.SerializeAsArray();
59272 }
59273 
Serialize(::protozero::Message * msg) const59274 void FreeBuffersRequest::Serialize(::protozero::Message* msg) const {
59275   // Field 1: buffer_ids
59276   for (auto& it : buffer_ids_) {
59277     msg->AppendVarInt(1, it);
59278   }
59279 
59280   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
59281 }
59282 
59283 
59284 ReadBuffersResponse::ReadBuffersResponse() = default;
59285 ReadBuffersResponse::~ReadBuffersResponse() = default;
59286 ReadBuffersResponse::ReadBuffersResponse(const ReadBuffersResponse&) = default;
59287 ReadBuffersResponse& ReadBuffersResponse::operator=(const ReadBuffersResponse&) = default;
59288 ReadBuffersResponse::ReadBuffersResponse(ReadBuffersResponse&&) noexcept = default;
59289 ReadBuffersResponse& ReadBuffersResponse::operator=(ReadBuffersResponse&&) = default;
59290 
operator ==(const ReadBuffersResponse & other) const59291 bool ReadBuffersResponse::operator==(const ReadBuffersResponse& other) const {
59292   return unknown_fields_ == other.unknown_fields_
59293    && slices_ == other.slices_;
59294 }
59295 
slices_size() const59296 int ReadBuffersResponse::slices_size() const { return static_cast<int>(slices_.size()); }
clear_slices()59297 void ReadBuffersResponse::clear_slices() { slices_.clear(); }
add_slices()59298 ReadBuffersResponse_Slice* ReadBuffersResponse::add_slices() { slices_.emplace_back(); return &slices_.back(); }
ParseFromArray(const void * raw,size_t size)59299 bool ReadBuffersResponse::ParseFromArray(const void* raw, size_t size) {
59300   slices_.clear();
59301   unknown_fields_.clear();
59302   bool packed_error = false;
59303 
59304   ::protozero::ProtoDecoder dec(raw, size);
59305   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
59306     if (field.id() < _has_field_.size()) {
59307       _has_field_.set(field.id());
59308     }
59309     switch (field.id()) {
59310       case 2 /* slices */:
59311         slices_.emplace_back();
59312         slices_.back().ParseFromArray(field.data(), field.size());
59313         break;
59314       default:
59315         field.SerializeAndAppendTo(&unknown_fields_);
59316         break;
59317     }
59318   }
59319   return !packed_error && !dec.bytes_left();
59320 }
59321 
SerializeAsString() const59322 std::string ReadBuffersResponse::SerializeAsString() const {
59323   ::protozero::HeapBuffered<::protozero::Message> msg;
59324   Serialize(msg.get());
59325   return msg.SerializeAsString();
59326 }
59327 
SerializeAsArray() const59328 std::vector<uint8_t> ReadBuffersResponse::SerializeAsArray() const {
59329   ::protozero::HeapBuffered<::protozero::Message> msg;
59330   Serialize(msg.get());
59331   return msg.SerializeAsArray();
59332 }
59333 
Serialize(::protozero::Message * msg) const59334 void ReadBuffersResponse::Serialize(::protozero::Message* msg) const {
59335   // Field 2: slices
59336   for (auto& it : slices_) {
59337     it.Serialize(msg->BeginNestedMessage<::protozero::Message>(2));
59338   }
59339 
59340   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
59341 }
59342 
59343 
59344 ReadBuffersResponse_Slice::ReadBuffersResponse_Slice() = default;
59345 ReadBuffersResponse_Slice::~ReadBuffersResponse_Slice() = default;
59346 ReadBuffersResponse_Slice::ReadBuffersResponse_Slice(const ReadBuffersResponse_Slice&) = default;
59347 ReadBuffersResponse_Slice& ReadBuffersResponse_Slice::operator=(const ReadBuffersResponse_Slice&) = default;
59348 ReadBuffersResponse_Slice::ReadBuffersResponse_Slice(ReadBuffersResponse_Slice&&) noexcept = default;
59349 ReadBuffersResponse_Slice& ReadBuffersResponse_Slice::operator=(ReadBuffersResponse_Slice&&) = default;
59350 
operator ==(const ReadBuffersResponse_Slice & other) const59351 bool ReadBuffersResponse_Slice::operator==(const ReadBuffersResponse_Slice& other) const {
59352   return unknown_fields_ == other.unknown_fields_
59353    && data_ == other.data_
59354    && last_slice_for_packet_ == other.last_slice_for_packet_;
59355 }
59356 
ParseFromArray(const void * raw,size_t size)59357 bool ReadBuffersResponse_Slice::ParseFromArray(const void* raw, size_t size) {
59358   unknown_fields_.clear();
59359   bool packed_error = false;
59360 
59361   ::protozero::ProtoDecoder dec(raw, size);
59362   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
59363     if (field.id() < _has_field_.size()) {
59364       _has_field_.set(field.id());
59365     }
59366     switch (field.id()) {
59367       case 1 /* data */:
59368         field.get(&data_);
59369         break;
59370       case 2 /* last_slice_for_packet */:
59371         field.get(&last_slice_for_packet_);
59372         break;
59373       default:
59374         field.SerializeAndAppendTo(&unknown_fields_);
59375         break;
59376     }
59377   }
59378   return !packed_error && !dec.bytes_left();
59379 }
59380 
SerializeAsString() const59381 std::string ReadBuffersResponse_Slice::SerializeAsString() const {
59382   ::protozero::HeapBuffered<::protozero::Message> msg;
59383   Serialize(msg.get());
59384   return msg.SerializeAsString();
59385 }
59386 
SerializeAsArray() const59387 std::vector<uint8_t> ReadBuffersResponse_Slice::SerializeAsArray() const {
59388   ::protozero::HeapBuffered<::protozero::Message> msg;
59389   Serialize(msg.get());
59390   return msg.SerializeAsArray();
59391 }
59392 
Serialize(::protozero::Message * msg) const59393 void ReadBuffersResponse_Slice::Serialize(::protozero::Message* msg) const {
59394   // Field 1: data
59395   if (_has_field_[1]) {
59396     msg->AppendString(1, data_);
59397   }
59398 
59399   // Field 2: last_slice_for_packet
59400   if (_has_field_[2]) {
59401     msg->AppendTinyVarInt(2, last_slice_for_packet_);
59402   }
59403 
59404   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
59405 }
59406 
59407 
59408 ReadBuffersRequest::ReadBuffersRequest() = default;
59409 ReadBuffersRequest::~ReadBuffersRequest() = default;
59410 ReadBuffersRequest::ReadBuffersRequest(const ReadBuffersRequest&) = default;
59411 ReadBuffersRequest& ReadBuffersRequest::operator=(const ReadBuffersRequest&) = default;
59412 ReadBuffersRequest::ReadBuffersRequest(ReadBuffersRequest&&) noexcept = default;
59413 ReadBuffersRequest& ReadBuffersRequest::operator=(ReadBuffersRequest&&) = default;
59414 
operator ==(const ReadBuffersRequest & other) const59415 bool ReadBuffersRequest::operator==(const ReadBuffersRequest& other) const {
59416   return unknown_fields_ == other.unknown_fields_;
59417 }
59418 
ParseFromArray(const void * raw,size_t size)59419 bool ReadBuffersRequest::ParseFromArray(const void* raw, size_t size) {
59420   unknown_fields_.clear();
59421   bool packed_error = false;
59422 
59423   ::protozero::ProtoDecoder dec(raw, size);
59424   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
59425     if (field.id() < _has_field_.size()) {
59426       _has_field_.set(field.id());
59427     }
59428     switch (field.id()) {
59429       default:
59430         field.SerializeAndAppendTo(&unknown_fields_);
59431         break;
59432     }
59433   }
59434   return !packed_error && !dec.bytes_left();
59435 }
59436 
SerializeAsString() const59437 std::string ReadBuffersRequest::SerializeAsString() const {
59438   ::protozero::HeapBuffered<::protozero::Message> msg;
59439   Serialize(msg.get());
59440   return msg.SerializeAsString();
59441 }
59442 
SerializeAsArray() const59443 std::vector<uint8_t> ReadBuffersRequest::SerializeAsArray() const {
59444   ::protozero::HeapBuffered<::protozero::Message> msg;
59445   Serialize(msg.get());
59446   return msg.SerializeAsArray();
59447 }
59448 
Serialize(::protozero::Message * msg) const59449 void ReadBuffersRequest::Serialize(::protozero::Message* msg) const {
59450   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
59451 }
59452 
59453 
59454 DisableTracingResponse::DisableTracingResponse() = default;
59455 DisableTracingResponse::~DisableTracingResponse() = default;
59456 DisableTracingResponse::DisableTracingResponse(const DisableTracingResponse&) = default;
59457 DisableTracingResponse& DisableTracingResponse::operator=(const DisableTracingResponse&) = default;
59458 DisableTracingResponse::DisableTracingResponse(DisableTracingResponse&&) noexcept = default;
59459 DisableTracingResponse& DisableTracingResponse::operator=(DisableTracingResponse&&) = default;
59460 
operator ==(const DisableTracingResponse & other) const59461 bool DisableTracingResponse::operator==(const DisableTracingResponse& other) const {
59462   return unknown_fields_ == other.unknown_fields_;
59463 }
59464 
ParseFromArray(const void * raw,size_t size)59465 bool DisableTracingResponse::ParseFromArray(const void* raw, size_t size) {
59466   unknown_fields_.clear();
59467   bool packed_error = false;
59468 
59469   ::protozero::ProtoDecoder dec(raw, size);
59470   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
59471     if (field.id() < _has_field_.size()) {
59472       _has_field_.set(field.id());
59473     }
59474     switch (field.id()) {
59475       default:
59476         field.SerializeAndAppendTo(&unknown_fields_);
59477         break;
59478     }
59479   }
59480   return !packed_error && !dec.bytes_left();
59481 }
59482 
SerializeAsString() const59483 std::string DisableTracingResponse::SerializeAsString() const {
59484   ::protozero::HeapBuffered<::protozero::Message> msg;
59485   Serialize(msg.get());
59486   return msg.SerializeAsString();
59487 }
59488 
SerializeAsArray() const59489 std::vector<uint8_t> DisableTracingResponse::SerializeAsArray() const {
59490   ::protozero::HeapBuffered<::protozero::Message> msg;
59491   Serialize(msg.get());
59492   return msg.SerializeAsArray();
59493 }
59494 
Serialize(::protozero::Message * msg) const59495 void DisableTracingResponse::Serialize(::protozero::Message* msg) const {
59496   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
59497 }
59498 
59499 
59500 DisableTracingRequest::DisableTracingRequest() = default;
59501 DisableTracingRequest::~DisableTracingRequest() = default;
59502 DisableTracingRequest::DisableTracingRequest(const DisableTracingRequest&) = default;
59503 DisableTracingRequest& DisableTracingRequest::operator=(const DisableTracingRequest&) = default;
59504 DisableTracingRequest::DisableTracingRequest(DisableTracingRequest&&) noexcept = default;
59505 DisableTracingRequest& DisableTracingRequest::operator=(DisableTracingRequest&&) = default;
59506 
operator ==(const DisableTracingRequest & other) const59507 bool DisableTracingRequest::operator==(const DisableTracingRequest& other) const {
59508   return unknown_fields_ == other.unknown_fields_;
59509 }
59510 
ParseFromArray(const void * raw,size_t size)59511 bool DisableTracingRequest::ParseFromArray(const void* raw, size_t size) {
59512   unknown_fields_.clear();
59513   bool packed_error = false;
59514 
59515   ::protozero::ProtoDecoder dec(raw, size);
59516   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
59517     if (field.id() < _has_field_.size()) {
59518       _has_field_.set(field.id());
59519     }
59520     switch (field.id()) {
59521       default:
59522         field.SerializeAndAppendTo(&unknown_fields_);
59523         break;
59524     }
59525   }
59526   return !packed_error && !dec.bytes_left();
59527 }
59528 
SerializeAsString() const59529 std::string DisableTracingRequest::SerializeAsString() const {
59530   ::protozero::HeapBuffered<::protozero::Message> msg;
59531   Serialize(msg.get());
59532   return msg.SerializeAsString();
59533 }
59534 
SerializeAsArray() const59535 std::vector<uint8_t> DisableTracingRequest::SerializeAsArray() const {
59536   ::protozero::HeapBuffered<::protozero::Message> msg;
59537   Serialize(msg.get());
59538   return msg.SerializeAsArray();
59539 }
59540 
Serialize(::protozero::Message * msg) const59541 void DisableTracingRequest::Serialize(::protozero::Message* msg) const {
59542   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
59543 }
59544 
59545 
59546 ChangeTraceConfigResponse::ChangeTraceConfigResponse() = default;
59547 ChangeTraceConfigResponse::~ChangeTraceConfigResponse() = default;
59548 ChangeTraceConfigResponse::ChangeTraceConfigResponse(const ChangeTraceConfigResponse&) = default;
59549 ChangeTraceConfigResponse& ChangeTraceConfigResponse::operator=(const ChangeTraceConfigResponse&) = default;
59550 ChangeTraceConfigResponse::ChangeTraceConfigResponse(ChangeTraceConfigResponse&&) noexcept = default;
59551 ChangeTraceConfigResponse& ChangeTraceConfigResponse::operator=(ChangeTraceConfigResponse&&) = default;
59552 
operator ==(const ChangeTraceConfigResponse & other) const59553 bool ChangeTraceConfigResponse::operator==(const ChangeTraceConfigResponse& other) const {
59554   return unknown_fields_ == other.unknown_fields_;
59555 }
59556 
ParseFromArray(const void * raw,size_t size)59557 bool ChangeTraceConfigResponse::ParseFromArray(const void* raw, size_t size) {
59558   unknown_fields_.clear();
59559   bool packed_error = false;
59560 
59561   ::protozero::ProtoDecoder dec(raw, size);
59562   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
59563     if (field.id() < _has_field_.size()) {
59564       _has_field_.set(field.id());
59565     }
59566     switch (field.id()) {
59567       default:
59568         field.SerializeAndAppendTo(&unknown_fields_);
59569         break;
59570     }
59571   }
59572   return !packed_error && !dec.bytes_left();
59573 }
59574 
SerializeAsString() const59575 std::string ChangeTraceConfigResponse::SerializeAsString() const {
59576   ::protozero::HeapBuffered<::protozero::Message> msg;
59577   Serialize(msg.get());
59578   return msg.SerializeAsString();
59579 }
59580 
SerializeAsArray() const59581 std::vector<uint8_t> ChangeTraceConfigResponse::SerializeAsArray() const {
59582   ::protozero::HeapBuffered<::protozero::Message> msg;
59583   Serialize(msg.get());
59584   return msg.SerializeAsArray();
59585 }
59586 
Serialize(::protozero::Message * msg) const59587 void ChangeTraceConfigResponse::Serialize(::protozero::Message* msg) const {
59588   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
59589 }
59590 
59591 
59592 ChangeTraceConfigRequest::ChangeTraceConfigRequest() = default;
59593 ChangeTraceConfigRequest::~ChangeTraceConfigRequest() = default;
59594 ChangeTraceConfigRequest::ChangeTraceConfigRequest(const ChangeTraceConfigRequest&) = default;
59595 ChangeTraceConfigRequest& ChangeTraceConfigRequest::operator=(const ChangeTraceConfigRequest&) = default;
59596 ChangeTraceConfigRequest::ChangeTraceConfigRequest(ChangeTraceConfigRequest&&) noexcept = default;
59597 ChangeTraceConfigRequest& ChangeTraceConfigRequest::operator=(ChangeTraceConfigRequest&&) = default;
59598 
operator ==(const ChangeTraceConfigRequest & other) const59599 bool ChangeTraceConfigRequest::operator==(const ChangeTraceConfigRequest& other) const {
59600   return unknown_fields_ == other.unknown_fields_
59601    && trace_config_ == other.trace_config_;
59602 }
59603 
ParseFromArray(const void * raw,size_t size)59604 bool ChangeTraceConfigRequest::ParseFromArray(const void* raw, size_t size) {
59605   unknown_fields_.clear();
59606   bool packed_error = false;
59607 
59608   ::protozero::ProtoDecoder dec(raw, size);
59609   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
59610     if (field.id() < _has_field_.size()) {
59611       _has_field_.set(field.id());
59612     }
59613     switch (field.id()) {
59614       case 1 /* trace_config */:
59615         (*trace_config_).ParseFromArray(field.data(), field.size());
59616         break;
59617       default:
59618         field.SerializeAndAppendTo(&unknown_fields_);
59619         break;
59620     }
59621   }
59622   return !packed_error && !dec.bytes_left();
59623 }
59624 
SerializeAsString() const59625 std::string ChangeTraceConfigRequest::SerializeAsString() const {
59626   ::protozero::HeapBuffered<::protozero::Message> msg;
59627   Serialize(msg.get());
59628   return msg.SerializeAsString();
59629 }
59630 
SerializeAsArray() const59631 std::vector<uint8_t> ChangeTraceConfigRequest::SerializeAsArray() const {
59632   ::protozero::HeapBuffered<::protozero::Message> msg;
59633   Serialize(msg.get());
59634   return msg.SerializeAsArray();
59635 }
59636 
Serialize(::protozero::Message * msg) const59637 void ChangeTraceConfigRequest::Serialize(::protozero::Message* msg) const {
59638   // Field 1: trace_config
59639   if (_has_field_[1]) {
59640     (*trace_config_).Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
59641   }
59642 
59643   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
59644 }
59645 
59646 
59647 StartTracingResponse::StartTracingResponse() = default;
59648 StartTracingResponse::~StartTracingResponse() = default;
59649 StartTracingResponse::StartTracingResponse(const StartTracingResponse&) = default;
59650 StartTracingResponse& StartTracingResponse::operator=(const StartTracingResponse&) = default;
59651 StartTracingResponse::StartTracingResponse(StartTracingResponse&&) noexcept = default;
59652 StartTracingResponse& StartTracingResponse::operator=(StartTracingResponse&&) = default;
59653 
operator ==(const StartTracingResponse & other) const59654 bool StartTracingResponse::operator==(const StartTracingResponse& other) const {
59655   return unknown_fields_ == other.unknown_fields_;
59656 }
59657 
ParseFromArray(const void * raw,size_t size)59658 bool StartTracingResponse::ParseFromArray(const void* raw, size_t size) {
59659   unknown_fields_.clear();
59660   bool packed_error = false;
59661 
59662   ::protozero::ProtoDecoder dec(raw, size);
59663   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
59664     if (field.id() < _has_field_.size()) {
59665       _has_field_.set(field.id());
59666     }
59667     switch (field.id()) {
59668       default:
59669         field.SerializeAndAppendTo(&unknown_fields_);
59670         break;
59671     }
59672   }
59673   return !packed_error && !dec.bytes_left();
59674 }
59675 
SerializeAsString() const59676 std::string StartTracingResponse::SerializeAsString() const {
59677   ::protozero::HeapBuffered<::protozero::Message> msg;
59678   Serialize(msg.get());
59679   return msg.SerializeAsString();
59680 }
59681 
SerializeAsArray() const59682 std::vector<uint8_t> StartTracingResponse::SerializeAsArray() const {
59683   ::protozero::HeapBuffered<::protozero::Message> msg;
59684   Serialize(msg.get());
59685   return msg.SerializeAsArray();
59686 }
59687 
Serialize(::protozero::Message * msg) const59688 void StartTracingResponse::Serialize(::protozero::Message* msg) const {
59689   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
59690 }
59691 
59692 
59693 StartTracingRequest::StartTracingRequest() = default;
59694 StartTracingRequest::~StartTracingRequest() = default;
59695 StartTracingRequest::StartTracingRequest(const StartTracingRequest&) = default;
59696 StartTracingRequest& StartTracingRequest::operator=(const StartTracingRequest&) = default;
59697 StartTracingRequest::StartTracingRequest(StartTracingRequest&&) noexcept = default;
59698 StartTracingRequest& StartTracingRequest::operator=(StartTracingRequest&&) = default;
59699 
operator ==(const StartTracingRequest & other) const59700 bool StartTracingRequest::operator==(const StartTracingRequest& other) const {
59701   return unknown_fields_ == other.unknown_fields_;
59702 }
59703 
ParseFromArray(const void * raw,size_t size)59704 bool StartTracingRequest::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 StartTracingRequest::SerializeAsString() const {
59723   ::protozero::HeapBuffered<::protozero::Message> msg;
59724   Serialize(msg.get());
59725   return msg.SerializeAsString();
59726 }
59727 
SerializeAsArray() const59728 std::vector<uint8_t> StartTracingRequest::SerializeAsArray() const {
59729   ::protozero::HeapBuffered<::protozero::Message> msg;
59730   Serialize(msg.get());
59731   return msg.SerializeAsArray();
59732 }
59733 
Serialize(::protozero::Message * msg) const59734 void StartTracingRequest::Serialize(::protozero::Message* msg) const {
59735   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
59736 }
59737 
59738 
59739 EnableTracingResponse::EnableTracingResponse() = default;
59740 EnableTracingResponse::~EnableTracingResponse() = default;
59741 EnableTracingResponse::EnableTracingResponse(const EnableTracingResponse&) = default;
59742 EnableTracingResponse& EnableTracingResponse::operator=(const EnableTracingResponse&) = default;
59743 EnableTracingResponse::EnableTracingResponse(EnableTracingResponse&&) noexcept = default;
59744 EnableTracingResponse& EnableTracingResponse::operator=(EnableTracingResponse&&) = default;
59745 
operator ==(const EnableTracingResponse & other) const59746 bool EnableTracingResponse::operator==(const EnableTracingResponse& other) const {
59747   return unknown_fields_ == other.unknown_fields_
59748    && disabled_ == other.disabled_
59749    && error_ == other.error_;
59750 }
59751 
ParseFromArray(const void * raw,size_t size)59752 bool EnableTracingResponse::ParseFromArray(const void* raw, size_t size) {
59753   unknown_fields_.clear();
59754   bool packed_error = false;
59755 
59756   ::protozero::ProtoDecoder dec(raw, size);
59757   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
59758     if (field.id() < _has_field_.size()) {
59759       _has_field_.set(field.id());
59760     }
59761     switch (field.id()) {
59762       case 1 /* disabled */:
59763         field.get(&disabled_);
59764         break;
59765       case 3 /* error */:
59766         field.get(&error_);
59767         break;
59768       default:
59769         field.SerializeAndAppendTo(&unknown_fields_);
59770         break;
59771     }
59772   }
59773   return !packed_error && !dec.bytes_left();
59774 }
59775 
SerializeAsString() const59776 std::string EnableTracingResponse::SerializeAsString() const {
59777   ::protozero::HeapBuffered<::protozero::Message> msg;
59778   Serialize(msg.get());
59779   return msg.SerializeAsString();
59780 }
59781 
SerializeAsArray() const59782 std::vector<uint8_t> EnableTracingResponse::SerializeAsArray() const {
59783   ::protozero::HeapBuffered<::protozero::Message> msg;
59784   Serialize(msg.get());
59785   return msg.SerializeAsArray();
59786 }
59787 
Serialize(::protozero::Message * msg) const59788 void EnableTracingResponse::Serialize(::protozero::Message* msg) const {
59789   // Field 1: disabled
59790   if (_has_field_[1]) {
59791     msg->AppendTinyVarInt(1, disabled_);
59792   }
59793 
59794   // Field 3: error
59795   if (_has_field_[3]) {
59796     msg->AppendString(3, error_);
59797   }
59798 
59799   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
59800 }
59801 
59802 
59803 EnableTracingRequest::EnableTracingRequest() = default;
59804 EnableTracingRequest::~EnableTracingRequest() = default;
59805 EnableTracingRequest::EnableTracingRequest(const EnableTracingRequest&) = default;
59806 EnableTracingRequest& EnableTracingRequest::operator=(const EnableTracingRequest&) = default;
59807 EnableTracingRequest::EnableTracingRequest(EnableTracingRequest&&) noexcept = default;
59808 EnableTracingRequest& EnableTracingRequest::operator=(EnableTracingRequest&&) = default;
59809 
operator ==(const EnableTracingRequest & other) const59810 bool EnableTracingRequest::operator==(const EnableTracingRequest& other) const {
59811   return unknown_fields_ == other.unknown_fields_
59812    && trace_config_ == other.trace_config_
59813    && attach_notification_only_ == other.attach_notification_only_;
59814 }
59815 
ParseFromArray(const void * raw,size_t size)59816 bool EnableTracingRequest::ParseFromArray(const void* raw, size_t size) {
59817   unknown_fields_.clear();
59818   bool packed_error = false;
59819 
59820   ::protozero::ProtoDecoder dec(raw, size);
59821   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
59822     if (field.id() < _has_field_.size()) {
59823       _has_field_.set(field.id());
59824     }
59825     switch (field.id()) {
59826       case 1 /* trace_config */:
59827         (*trace_config_).ParseFromArray(field.data(), field.size());
59828         break;
59829       case 2 /* attach_notification_only */:
59830         field.get(&attach_notification_only_);
59831         break;
59832       default:
59833         field.SerializeAndAppendTo(&unknown_fields_);
59834         break;
59835     }
59836   }
59837   return !packed_error && !dec.bytes_left();
59838 }
59839 
SerializeAsString() const59840 std::string EnableTracingRequest::SerializeAsString() const {
59841   ::protozero::HeapBuffered<::protozero::Message> msg;
59842   Serialize(msg.get());
59843   return msg.SerializeAsString();
59844 }
59845 
SerializeAsArray() const59846 std::vector<uint8_t> EnableTracingRequest::SerializeAsArray() const {
59847   ::protozero::HeapBuffered<::protozero::Message> msg;
59848   Serialize(msg.get());
59849   return msg.SerializeAsArray();
59850 }
59851 
Serialize(::protozero::Message * msg) const59852 void EnableTracingRequest::Serialize(::protozero::Message* msg) const {
59853   // Field 1: trace_config
59854   if (_has_field_[1]) {
59855     (*trace_config_).Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
59856   }
59857 
59858   // Field 2: attach_notification_only
59859   if (_has_field_[2]) {
59860     msg->AppendTinyVarInt(2, attach_notification_only_);
59861   }
59862 
59863   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
59864 }
59865 
59866 }  // namespace perfetto
59867 }  // namespace protos
59868 }  // namespace gen
59869 #if defined(__GNUC__) || defined(__clang__)
59870 #pragma GCC diagnostic pop
59871 #endif
59872 // gen_amalgamated begin source: gen/protos/perfetto/ipc/producer_port.gen.cc
59873 // gen_amalgamated begin header: gen/protos/perfetto/ipc/producer_port.gen.h
59874 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
59875 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_IPC_PRODUCER_PORT_PROTO_CPP_H_
59876 #define PERFETTO_PROTOS_PROTOS_PERFETTO_IPC_PRODUCER_PORT_PROTO_CPP_H_
59877 
59878 #include <stdint.h>
59879 #include <bitset>
59880 #include <vector>
59881 #include <string>
59882 #include <type_traits>
59883 
59884 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
59885 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
59886 // gen_amalgamated expanded: #include "perfetto/base/export.h"
59887 
59888 namespace perfetto {
59889 namespace protos {
59890 namespace gen {
59891 class SyncResponse;
59892 class SyncRequest;
59893 class GetAsyncCommandResponse;
59894 class GetAsyncCommandResponse_ClearIncrementalState;
59895 class GetAsyncCommandResponse_Flush;
59896 class GetAsyncCommandResponse_StopDataSource;
59897 class GetAsyncCommandResponse_StartDataSource;
59898 class DataSourceConfig;
59899 class TestConfig;
59900 class TestConfig_DummyFields;
59901 class InterceptorConfig;
59902 class ChromeConfig;
59903 class GetAsyncCommandResponse_SetupDataSource;
59904 class GetAsyncCommandResponse_SetupTracing;
59905 class GetAsyncCommandRequest;
59906 class ActivateTriggersResponse;
59907 class ActivateTriggersRequest;
59908 class NotifyDataSourceStoppedResponse;
59909 class NotifyDataSourceStoppedRequest;
59910 class NotifyDataSourceStartedResponse;
59911 class NotifyDataSourceStartedRequest;
59912 class CommitDataResponse;
59913 class UnregisterTraceWriterResponse;
59914 class UnregisterTraceWriterRequest;
59915 class RegisterTraceWriterResponse;
59916 class RegisterTraceWriterRequest;
59917 class UnregisterDataSourceResponse;
59918 class UnregisterDataSourceRequest;
59919 class UpdateDataSourceResponse;
59920 class UpdateDataSourceRequest;
59921 class DataSourceDescriptor;
59922 class RegisterDataSourceResponse;
59923 class RegisterDataSourceRequest;
59924 class InitializeConnectionResponse;
59925 class InitializeConnectionRequest;
59926 enum DataSourceConfig_SessionInitiator : int;
59927 enum ChromeConfig_ClientPriority : int;
59928 enum InitializeConnectionRequest_ProducerSMBScrapingMode : int;
59929 }  // namespace perfetto
59930 }  // namespace protos
59931 }  // namespace gen
59932 
59933 namespace protozero {
59934 class Message;
59935 }  // namespace protozero
59936 
59937 namespace perfetto {
59938 namespace protos {
59939 namespace gen {
59940 enum InitializeConnectionRequest_ProducerSMBScrapingMode : int {
59941   InitializeConnectionRequest_ProducerSMBScrapingMode_SMB_SCRAPING_UNSPECIFIED = 0,
59942   InitializeConnectionRequest_ProducerSMBScrapingMode_SMB_SCRAPING_ENABLED = 1,
59943   InitializeConnectionRequest_ProducerSMBScrapingMode_SMB_SCRAPING_DISABLED = 2,
59944 };
59945 
59946 class PERFETTO_EXPORT SyncResponse : public ::protozero::CppMessageObj {
59947  public:
59948   enum FieldNumbers {
59949   };
59950 
59951   SyncResponse();
59952   ~SyncResponse() override;
59953   SyncResponse(SyncResponse&&) noexcept;
59954   SyncResponse& operator=(SyncResponse&&);
59955   SyncResponse(const SyncResponse&);
59956   SyncResponse& operator=(const SyncResponse&);
59957   bool operator==(const SyncResponse&) const;
operator !=(const SyncResponse & other) const59958   bool operator!=(const SyncResponse& other) const { return !(*this == other); }
59959 
59960   bool ParseFromArray(const void*, size_t) override;
59961   std::string SerializeAsString() const override;
59962   std::vector<uint8_t> SerializeAsArray() const override;
59963   void Serialize(::protozero::Message*) const;
59964 
59965  private:
59966 
59967   // Allows to preserve unknown protobuf fields for compatibility
59968   // with future versions of .proto files.
59969   std::string unknown_fields_;
59970 
59971   std::bitset<2> _has_field_{};
59972 };
59973 
59974 
59975 class PERFETTO_EXPORT SyncRequest : public ::protozero::CppMessageObj {
59976  public:
59977   enum FieldNumbers {
59978   };
59979 
59980   SyncRequest();
59981   ~SyncRequest() override;
59982   SyncRequest(SyncRequest&&) noexcept;
59983   SyncRequest& operator=(SyncRequest&&);
59984   SyncRequest(const SyncRequest&);
59985   SyncRequest& operator=(const SyncRequest&);
59986   bool operator==(const SyncRequest&) const;
operator !=(const SyncRequest & other) const59987   bool operator!=(const SyncRequest& other) const { return !(*this == other); }
59988 
59989   bool ParseFromArray(const void*, size_t) override;
59990   std::string SerializeAsString() const override;
59991   std::vector<uint8_t> SerializeAsArray() const override;
59992   void Serialize(::protozero::Message*) const;
59993 
59994  private:
59995 
59996   // Allows to preserve unknown protobuf fields for compatibility
59997   // with future versions of .proto files.
59998   std::string unknown_fields_;
59999 
60000   std::bitset<2> _has_field_{};
60001 };
60002 
60003 
60004 class PERFETTO_EXPORT GetAsyncCommandResponse : public ::protozero::CppMessageObj {
60005  public:
60006   using SetupDataSource = GetAsyncCommandResponse_SetupDataSource;
60007   using StartDataSource = GetAsyncCommandResponse_StartDataSource;
60008   using StopDataSource = GetAsyncCommandResponse_StopDataSource;
60009   using SetupTracing = GetAsyncCommandResponse_SetupTracing;
60010   using Flush = GetAsyncCommandResponse_Flush;
60011   using ClearIncrementalState = GetAsyncCommandResponse_ClearIncrementalState;
60012   enum FieldNumbers {
60013     kSetupTracingFieldNumber = 3,
60014     kSetupDataSourceFieldNumber = 6,
60015     kStartDataSourceFieldNumber = 1,
60016     kStopDataSourceFieldNumber = 2,
60017     kFlushFieldNumber = 5,
60018     kClearIncrementalStateFieldNumber = 7,
60019   };
60020 
60021   GetAsyncCommandResponse();
60022   ~GetAsyncCommandResponse() override;
60023   GetAsyncCommandResponse(GetAsyncCommandResponse&&) noexcept;
60024   GetAsyncCommandResponse& operator=(GetAsyncCommandResponse&&);
60025   GetAsyncCommandResponse(const GetAsyncCommandResponse&);
60026   GetAsyncCommandResponse& operator=(const GetAsyncCommandResponse&);
60027   bool operator==(const GetAsyncCommandResponse&) const;
operator !=(const GetAsyncCommandResponse & other) const60028   bool operator!=(const GetAsyncCommandResponse& other) const { return !(*this == other); }
60029 
60030   bool ParseFromArray(const void*, size_t) override;
60031   std::string SerializeAsString() const override;
60032   std::vector<uint8_t> SerializeAsArray() const override;
60033   void Serialize(::protozero::Message*) const;
60034 
has_setup_tracing() const60035   bool has_setup_tracing() const { return _has_field_[3]; }
setup_tracing() const60036   const GetAsyncCommandResponse_SetupTracing& setup_tracing() const { return *setup_tracing_; }
mutable_setup_tracing()60037   GetAsyncCommandResponse_SetupTracing* mutable_setup_tracing() { _has_field_.set(3); return setup_tracing_.get(); }
60038 
has_setup_data_source() const60039   bool has_setup_data_source() const { return _has_field_[6]; }
setup_data_source() const60040   const GetAsyncCommandResponse_SetupDataSource& setup_data_source() const { return *setup_data_source_; }
mutable_setup_data_source()60041   GetAsyncCommandResponse_SetupDataSource* mutable_setup_data_source() { _has_field_.set(6); return setup_data_source_.get(); }
60042 
has_start_data_source() const60043   bool has_start_data_source() const { return _has_field_[1]; }
start_data_source() const60044   const GetAsyncCommandResponse_StartDataSource& start_data_source() const { return *start_data_source_; }
mutable_start_data_source()60045   GetAsyncCommandResponse_StartDataSource* mutable_start_data_source() { _has_field_.set(1); return start_data_source_.get(); }
60046 
has_stop_data_source() const60047   bool has_stop_data_source() const { return _has_field_[2]; }
stop_data_source() const60048   const GetAsyncCommandResponse_StopDataSource& stop_data_source() const { return *stop_data_source_; }
mutable_stop_data_source()60049   GetAsyncCommandResponse_StopDataSource* mutable_stop_data_source() { _has_field_.set(2); return stop_data_source_.get(); }
60050 
has_flush() const60051   bool has_flush() const { return _has_field_[5]; }
flush() const60052   const GetAsyncCommandResponse_Flush& flush() const { return *flush_; }
mutable_flush()60053   GetAsyncCommandResponse_Flush* mutable_flush() { _has_field_.set(5); return flush_.get(); }
60054 
has_clear_incremental_state() const60055   bool has_clear_incremental_state() const { return _has_field_[7]; }
clear_incremental_state() const60056   const GetAsyncCommandResponse_ClearIncrementalState& clear_incremental_state() const { return *clear_incremental_state_; }
mutable_clear_incremental_state()60057   GetAsyncCommandResponse_ClearIncrementalState* mutable_clear_incremental_state() { _has_field_.set(7); return clear_incremental_state_.get(); }
60058 
60059  private:
60060   ::protozero::CopyablePtr<GetAsyncCommandResponse_SetupTracing> setup_tracing_;
60061   ::protozero::CopyablePtr<GetAsyncCommandResponse_SetupDataSource> setup_data_source_;
60062   ::protozero::CopyablePtr<GetAsyncCommandResponse_StartDataSource> start_data_source_;
60063   ::protozero::CopyablePtr<GetAsyncCommandResponse_StopDataSource> stop_data_source_;
60064   ::protozero::CopyablePtr<GetAsyncCommandResponse_Flush> flush_;
60065   ::protozero::CopyablePtr<GetAsyncCommandResponse_ClearIncrementalState> clear_incremental_state_;
60066 
60067   // Allows to preserve unknown protobuf fields for compatibility
60068   // with future versions of .proto files.
60069   std::string unknown_fields_;
60070 
60071   std::bitset<8> _has_field_{};
60072 };
60073 
60074 
60075 class PERFETTO_EXPORT GetAsyncCommandResponse_ClearIncrementalState : public ::protozero::CppMessageObj {
60076  public:
60077   enum FieldNumbers {
60078     kDataSourceIdsFieldNumber = 1,
60079   };
60080 
60081   GetAsyncCommandResponse_ClearIncrementalState();
60082   ~GetAsyncCommandResponse_ClearIncrementalState() override;
60083   GetAsyncCommandResponse_ClearIncrementalState(GetAsyncCommandResponse_ClearIncrementalState&&) noexcept;
60084   GetAsyncCommandResponse_ClearIncrementalState& operator=(GetAsyncCommandResponse_ClearIncrementalState&&);
60085   GetAsyncCommandResponse_ClearIncrementalState(const GetAsyncCommandResponse_ClearIncrementalState&);
60086   GetAsyncCommandResponse_ClearIncrementalState& operator=(const GetAsyncCommandResponse_ClearIncrementalState&);
60087   bool operator==(const GetAsyncCommandResponse_ClearIncrementalState&) const;
operator !=(const GetAsyncCommandResponse_ClearIncrementalState & other) const60088   bool operator!=(const GetAsyncCommandResponse_ClearIncrementalState& other) const { return !(*this == other); }
60089 
60090   bool ParseFromArray(const void*, size_t) override;
60091   std::string SerializeAsString() const override;
60092   std::vector<uint8_t> SerializeAsArray() const override;
60093   void Serialize(::protozero::Message*) const;
60094 
data_source_ids() const60095   const std::vector<uint64_t>& data_source_ids() const { return data_source_ids_; }
mutable_data_source_ids()60096   std::vector<uint64_t>* mutable_data_source_ids() { return &data_source_ids_; }
data_source_ids_size() const60097   int data_source_ids_size() const { return static_cast<int>(data_source_ids_.size()); }
clear_data_source_ids()60098   void clear_data_source_ids() { data_source_ids_.clear(); }
add_data_source_ids(uint64_t value)60099   void add_data_source_ids(uint64_t value) { data_source_ids_.emplace_back(value); }
add_data_source_ids()60100   uint64_t* add_data_source_ids() { data_source_ids_.emplace_back(); return &data_source_ids_.back(); }
60101 
60102  private:
60103   std::vector<uint64_t> data_source_ids_;
60104 
60105   // Allows to preserve unknown protobuf fields for compatibility
60106   // with future versions of .proto files.
60107   std::string unknown_fields_;
60108 
60109   std::bitset<2> _has_field_{};
60110 };
60111 
60112 
60113 class PERFETTO_EXPORT GetAsyncCommandResponse_Flush : public ::protozero::CppMessageObj {
60114  public:
60115   enum FieldNumbers {
60116     kDataSourceIdsFieldNumber = 1,
60117     kRequestIdFieldNumber = 2,
60118   };
60119 
60120   GetAsyncCommandResponse_Flush();
60121   ~GetAsyncCommandResponse_Flush() override;
60122   GetAsyncCommandResponse_Flush(GetAsyncCommandResponse_Flush&&) noexcept;
60123   GetAsyncCommandResponse_Flush& operator=(GetAsyncCommandResponse_Flush&&);
60124   GetAsyncCommandResponse_Flush(const GetAsyncCommandResponse_Flush&);
60125   GetAsyncCommandResponse_Flush& operator=(const GetAsyncCommandResponse_Flush&);
60126   bool operator==(const GetAsyncCommandResponse_Flush&) const;
operator !=(const GetAsyncCommandResponse_Flush & other) const60127   bool operator!=(const GetAsyncCommandResponse_Flush& other) const { return !(*this == other); }
60128 
60129   bool ParseFromArray(const void*, size_t) override;
60130   std::string SerializeAsString() const override;
60131   std::vector<uint8_t> SerializeAsArray() const override;
60132   void Serialize(::protozero::Message*) const;
60133 
data_source_ids() const60134   const std::vector<uint64_t>& data_source_ids() const { return data_source_ids_; }
mutable_data_source_ids()60135   std::vector<uint64_t>* mutable_data_source_ids() { return &data_source_ids_; }
data_source_ids_size() const60136   int data_source_ids_size() const { return static_cast<int>(data_source_ids_.size()); }
clear_data_source_ids()60137   void clear_data_source_ids() { data_source_ids_.clear(); }
add_data_source_ids(uint64_t value)60138   void add_data_source_ids(uint64_t value) { data_source_ids_.emplace_back(value); }
add_data_source_ids()60139   uint64_t* add_data_source_ids() { data_source_ids_.emplace_back(); return &data_source_ids_.back(); }
60140 
has_request_id() const60141   bool has_request_id() const { return _has_field_[2]; }
request_id() const60142   uint64_t request_id() const { return request_id_; }
set_request_id(uint64_t value)60143   void set_request_id(uint64_t value) { request_id_ = value; _has_field_.set(2); }
60144 
60145  private:
60146   std::vector<uint64_t> data_source_ids_;
60147   uint64_t request_id_{};
60148 
60149   // Allows to preserve unknown protobuf fields for compatibility
60150   // with future versions of .proto files.
60151   std::string unknown_fields_;
60152 
60153   std::bitset<3> _has_field_{};
60154 };
60155 
60156 
60157 class PERFETTO_EXPORT GetAsyncCommandResponse_StopDataSource : public ::protozero::CppMessageObj {
60158  public:
60159   enum FieldNumbers {
60160     kInstanceIdFieldNumber = 1,
60161   };
60162 
60163   GetAsyncCommandResponse_StopDataSource();
60164   ~GetAsyncCommandResponse_StopDataSource() override;
60165   GetAsyncCommandResponse_StopDataSource(GetAsyncCommandResponse_StopDataSource&&) noexcept;
60166   GetAsyncCommandResponse_StopDataSource& operator=(GetAsyncCommandResponse_StopDataSource&&);
60167   GetAsyncCommandResponse_StopDataSource(const GetAsyncCommandResponse_StopDataSource&);
60168   GetAsyncCommandResponse_StopDataSource& operator=(const GetAsyncCommandResponse_StopDataSource&);
60169   bool operator==(const GetAsyncCommandResponse_StopDataSource&) const;
operator !=(const GetAsyncCommandResponse_StopDataSource & other) const60170   bool operator!=(const GetAsyncCommandResponse_StopDataSource& other) const { return !(*this == other); }
60171 
60172   bool ParseFromArray(const void*, size_t) override;
60173   std::string SerializeAsString() const override;
60174   std::vector<uint8_t> SerializeAsArray() const override;
60175   void Serialize(::protozero::Message*) const;
60176 
has_instance_id() const60177   bool has_instance_id() const { return _has_field_[1]; }
instance_id() const60178   uint64_t instance_id() const { return instance_id_; }
set_instance_id(uint64_t value)60179   void set_instance_id(uint64_t value) { instance_id_ = value; _has_field_.set(1); }
60180 
60181  private:
60182   uint64_t instance_id_{};
60183 
60184   // Allows to preserve unknown protobuf fields for compatibility
60185   // with future versions of .proto files.
60186   std::string unknown_fields_;
60187 
60188   std::bitset<2> _has_field_{};
60189 };
60190 
60191 
60192 class PERFETTO_EXPORT GetAsyncCommandResponse_StartDataSource : public ::protozero::CppMessageObj {
60193  public:
60194   enum FieldNumbers {
60195     kNewInstanceIdFieldNumber = 1,
60196     kConfigFieldNumber = 2,
60197   };
60198 
60199   GetAsyncCommandResponse_StartDataSource();
60200   ~GetAsyncCommandResponse_StartDataSource() override;
60201   GetAsyncCommandResponse_StartDataSource(GetAsyncCommandResponse_StartDataSource&&) noexcept;
60202   GetAsyncCommandResponse_StartDataSource& operator=(GetAsyncCommandResponse_StartDataSource&&);
60203   GetAsyncCommandResponse_StartDataSource(const GetAsyncCommandResponse_StartDataSource&);
60204   GetAsyncCommandResponse_StartDataSource& operator=(const GetAsyncCommandResponse_StartDataSource&);
60205   bool operator==(const GetAsyncCommandResponse_StartDataSource&) const;
operator !=(const GetAsyncCommandResponse_StartDataSource & other) const60206   bool operator!=(const GetAsyncCommandResponse_StartDataSource& other) const { return !(*this == other); }
60207 
60208   bool ParseFromArray(const void*, size_t) override;
60209   std::string SerializeAsString() const override;
60210   std::vector<uint8_t> SerializeAsArray() const override;
60211   void Serialize(::protozero::Message*) const;
60212 
has_new_instance_id() const60213   bool has_new_instance_id() const { return _has_field_[1]; }
new_instance_id() const60214   uint64_t new_instance_id() const { return new_instance_id_; }
set_new_instance_id(uint64_t value)60215   void set_new_instance_id(uint64_t value) { new_instance_id_ = value; _has_field_.set(1); }
60216 
has_config() const60217   bool has_config() const { return _has_field_[2]; }
config() const60218   const DataSourceConfig& config() const { return *config_; }
mutable_config()60219   DataSourceConfig* mutable_config() { _has_field_.set(2); return config_.get(); }
60220 
60221  private:
60222   uint64_t new_instance_id_{};
60223   ::protozero::CopyablePtr<DataSourceConfig> config_;
60224 
60225   // Allows to preserve unknown protobuf fields for compatibility
60226   // with future versions of .proto files.
60227   std::string unknown_fields_;
60228 
60229   std::bitset<3> _has_field_{};
60230 };
60231 
60232 
60233 class PERFETTO_EXPORT GetAsyncCommandResponse_SetupDataSource : public ::protozero::CppMessageObj {
60234  public:
60235   enum FieldNumbers {
60236     kNewInstanceIdFieldNumber = 1,
60237     kConfigFieldNumber = 2,
60238   };
60239 
60240   GetAsyncCommandResponse_SetupDataSource();
60241   ~GetAsyncCommandResponse_SetupDataSource() override;
60242   GetAsyncCommandResponse_SetupDataSource(GetAsyncCommandResponse_SetupDataSource&&) noexcept;
60243   GetAsyncCommandResponse_SetupDataSource& operator=(GetAsyncCommandResponse_SetupDataSource&&);
60244   GetAsyncCommandResponse_SetupDataSource(const GetAsyncCommandResponse_SetupDataSource&);
60245   GetAsyncCommandResponse_SetupDataSource& operator=(const GetAsyncCommandResponse_SetupDataSource&);
60246   bool operator==(const GetAsyncCommandResponse_SetupDataSource&) const;
operator !=(const GetAsyncCommandResponse_SetupDataSource & other) const60247   bool operator!=(const GetAsyncCommandResponse_SetupDataSource& other) const { return !(*this == other); }
60248 
60249   bool ParseFromArray(const void*, size_t) override;
60250   std::string SerializeAsString() const override;
60251   std::vector<uint8_t> SerializeAsArray() const override;
60252   void Serialize(::protozero::Message*) const;
60253 
has_new_instance_id() const60254   bool has_new_instance_id() const { return _has_field_[1]; }
new_instance_id() const60255   uint64_t new_instance_id() const { return new_instance_id_; }
set_new_instance_id(uint64_t value)60256   void set_new_instance_id(uint64_t value) { new_instance_id_ = value; _has_field_.set(1); }
60257 
has_config() const60258   bool has_config() const { return _has_field_[2]; }
config() const60259   const DataSourceConfig& config() const { return *config_; }
mutable_config()60260   DataSourceConfig* mutable_config() { _has_field_.set(2); return config_.get(); }
60261 
60262  private:
60263   uint64_t new_instance_id_{};
60264   ::protozero::CopyablePtr<DataSourceConfig> config_;
60265 
60266   // Allows to preserve unknown protobuf fields for compatibility
60267   // with future versions of .proto files.
60268   std::string unknown_fields_;
60269 
60270   std::bitset<3> _has_field_{};
60271 };
60272 
60273 
60274 class PERFETTO_EXPORT GetAsyncCommandResponse_SetupTracing : public ::protozero::CppMessageObj {
60275  public:
60276   enum FieldNumbers {
60277     kSharedBufferPageSizeKbFieldNumber = 1,
60278     kShmKeyWindowsFieldNumber = 2,
60279   };
60280 
60281   GetAsyncCommandResponse_SetupTracing();
60282   ~GetAsyncCommandResponse_SetupTracing() override;
60283   GetAsyncCommandResponse_SetupTracing(GetAsyncCommandResponse_SetupTracing&&) noexcept;
60284   GetAsyncCommandResponse_SetupTracing& operator=(GetAsyncCommandResponse_SetupTracing&&);
60285   GetAsyncCommandResponse_SetupTracing(const GetAsyncCommandResponse_SetupTracing&);
60286   GetAsyncCommandResponse_SetupTracing& operator=(const GetAsyncCommandResponse_SetupTracing&);
60287   bool operator==(const GetAsyncCommandResponse_SetupTracing&) const;
operator !=(const GetAsyncCommandResponse_SetupTracing & other) const60288   bool operator!=(const GetAsyncCommandResponse_SetupTracing& other) const { return !(*this == other); }
60289 
60290   bool ParseFromArray(const void*, size_t) override;
60291   std::string SerializeAsString() const override;
60292   std::vector<uint8_t> SerializeAsArray() const override;
60293   void Serialize(::protozero::Message*) const;
60294 
has_shared_buffer_page_size_kb() const60295   bool has_shared_buffer_page_size_kb() const { return _has_field_[1]; }
shared_buffer_page_size_kb() const60296   uint32_t shared_buffer_page_size_kb() const { return shared_buffer_page_size_kb_; }
set_shared_buffer_page_size_kb(uint32_t value)60297   void set_shared_buffer_page_size_kb(uint32_t value) { shared_buffer_page_size_kb_ = value; _has_field_.set(1); }
60298 
has_shm_key_windows() const60299   bool has_shm_key_windows() const { return _has_field_[2]; }
shm_key_windows() const60300   const std::string& shm_key_windows() const { return shm_key_windows_; }
set_shm_key_windows(const std::string & value)60301   void set_shm_key_windows(const std::string& value) { shm_key_windows_ = value; _has_field_.set(2); }
60302 
60303  private:
60304   uint32_t shared_buffer_page_size_kb_{};
60305   std::string shm_key_windows_{};
60306 
60307   // Allows to preserve unknown protobuf fields for compatibility
60308   // with future versions of .proto files.
60309   std::string unknown_fields_;
60310 
60311   std::bitset<3> _has_field_{};
60312 };
60313 
60314 
60315 class PERFETTO_EXPORT GetAsyncCommandRequest : public ::protozero::CppMessageObj {
60316  public:
60317   enum FieldNumbers {
60318   };
60319 
60320   GetAsyncCommandRequest();
60321   ~GetAsyncCommandRequest() override;
60322   GetAsyncCommandRequest(GetAsyncCommandRequest&&) noexcept;
60323   GetAsyncCommandRequest& operator=(GetAsyncCommandRequest&&);
60324   GetAsyncCommandRequest(const GetAsyncCommandRequest&);
60325   GetAsyncCommandRequest& operator=(const GetAsyncCommandRequest&);
60326   bool operator==(const GetAsyncCommandRequest&) const;
operator !=(const GetAsyncCommandRequest & other) const60327   bool operator!=(const GetAsyncCommandRequest& other) const { return !(*this == other); }
60328 
60329   bool ParseFromArray(const void*, size_t) override;
60330   std::string SerializeAsString() const override;
60331   std::vector<uint8_t> SerializeAsArray() const override;
60332   void Serialize(::protozero::Message*) const;
60333 
60334  private:
60335 
60336   // Allows to preserve unknown protobuf fields for compatibility
60337   // with future versions of .proto files.
60338   std::string unknown_fields_;
60339 
60340   std::bitset<2> _has_field_{};
60341 };
60342 
60343 
60344 class PERFETTO_EXPORT ActivateTriggersResponse : public ::protozero::CppMessageObj {
60345  public:
60346   enum FieldNumbers {
60347   };
60348 
60349   ActivateTriggersResponse();
60350   ~ActivateTriggersResponse() override;
60351   ActivateTriggersResponse(ActivateTriggersResponse&&) noexcept;
60352   ActivateTriggersResponse& operator=(ActivateTriggersResponse&&);
60353   ActivateTriggersResponse(const ActivateTriggersResponse&);
60354   ActivateTriggersResponse& operator=(const ActivateTriggersResponse&);
60355   bool operator==(const ActivateTriggersResponse&) const;
operator !=(const ActivateTriggersResponse & other) const60356   bool operator!=(const ActivateTriggersResponse& other) const { return !(*this == other); }
60357 
60358   bool ParseFromArray(const void*, size_t) override;
60359   std::string SerializeAsString() const override;
60360   std::vector<uint8_t> SerializeAsArray() const override;
60361   void Serialize(::protozero::Message*) const;
60362 
60363  private:
60364 
60365   // Allows to preserve unknown protobuf fields for compatibility
60366   // with future versions of .proto files.
60367   std::string unknown_fields_;
60368 
60369   std::bitset<2> _has_field_{};
60370 };
60371 
60372 
60373 class PERFETTO_EXPORT ActivateTriggersRequest : public ::protozero::CppMessageObj {
60374  public:
60375   enum FieldNumbers {
60376     kTriggerNamesFieldNumber = 1,
60377   };
60378 
60379   ActivateTriggersRequest();
60380   ~ActivateTriggersRequest() override;
60381   ActivateTriggersRequest(ActivateTriggersRequest&&) noexcept;
60382   ActivateTriggersRequest& operator=(ActivateTriggersRequest&&);
60383   ActivateTriggersRequest(const ActivateTriggersRequest&);
60384   ActivateTriggersRequest& operator=(const ActivateTriggersRequest&);
60385   bool operator==(const ActivateTriggersRequest&) const;
operator !=(const ActivateTriggersRequest & other) const60386   bool operator!=(const ActivateTriggersRequest& other) const { return !(*this == other); }
60387 
60388   bool ParseFromArray(const void*, size_t) override;
60389   std::string SerializeAsString() const override;
60390   std::vector<uint8_t> SerializeAsArray() const override;
60391   void Serialize(::protozero::Message*) const;
60392 
trigger_names() const60393   const std::vector<std::string>& trigger_names() const { return trigger_names_; }
mutable_trigger_names()60394   std::vector<std::string>* mutable_trigger_names() { return &trigger_names_; }
trigger_names_size() const60395   int trigger_names_size() const { return static_cast<int>(trigger_names_.size()); }
clear_trigger_names()60396   void clear_trigger_names() { trigger_names_.clear(); }
add_trigger_names(std::string value)60397   void add_trigger_names(std::string value) { trigger_names_.emplace_back(value); }
add_trigger_names()60398   std::string* add_trigger_names() { trigger_names_.emplace_back(); return &trigger_names_.back(); }
60399 
60400  private:
60401   std::vector<std::string> trigger_names_;
60402 
60403   // Allows to preserve unknown protobuf fields for compatibility
60404   // with future versions of .proto files.
60405   std::string unknown_fields_;
60406 
60407   std::bitset<2> _has_field_{};
60408 };
60409 
60410 
60411 class PERFETTO_EXPORT NotifyDataSourceStoppedResponse : public ::protozero::CppMessageObj {
60412  public:
60413   enum FieldNumbers {
60414   };
60415 
60416   NotifyDataSourceStoppedResponse();
60417   ~NotifyDataSourceStoppedResponse() override;
60418   NotifyDataSourceStoppedResponse(NotifyDataSourceStoppedResponse&&) noexcept;
60419   NotifyDataSourceStoppedResponse& operator=(NotifyDataSourceStoppedResponse&&);
60420   NotifyDataSourceStoppedResponse(const NotifyDataSourceStoppedResponse&);
60421   NotifyDataSourceStoppedResponse& operator=(const NotifyDataSourceStoppedResponse&);
60422   bool operator==(const NotifyDataSourceStoppedResponse&) const;
operator !=(const NotifyDataSourceStoppedResponse & other) const60423   bool operator!=(const NotifyDataSourceStoppedResponse& other) const { return !(*this == other); }
60424 
60425   bool ParseFromArray(const void*, size_t) override;
60426   std::string SerializeAsString() const override;
60427   std::vector<uint8_t> SerializeAsArray() const override;
60428   void Serialize(::protozero::Message*) const;
60429 
60430  private:
60431 
60432   // Allows to preserve unknown protobuf fields for compatibility
60433   // with future versions of .proto files.
60434   std::string unknown_fields_;
60435 
60436   std::bitset<2> _has_field_{};
60437 };
60438 
60439 
60440 class PERFETTO_EXPORT NotifyDataSourceStoppedRequest : public ::protozero::CppMessageObj {
60441  public:
60442   enum FieldNumbers {
60443     kDataSourceIdFieldNumber = 1,
60444   };
60445 
60446   NotifyDataSourceStoppedRequest();
60447   ~NotifyDataSourceStoppedRequest() override;
60448   NotifyDataSourceStoppedRequest(NotifyDataSourceStoppedRequest&&) noexcept;
60449   NotifyDataSourceStoppedRequest& operator=(NotifyDataSourceStoppedRequest&&);
60450   NotifyDataSourceStoppedRequest(const NotifyDataSourceStoppedRequest&);
60451   NotifyDataSourceStoppedRequest& operator=(const NotifyDataSourceStoppedRequest&);
60452   bool operator==(const NotifyDataSourceStoppedRequest&) const;
operator !=(const NotifyDataSourceStoppedRequest & other) const60453   bool operator!=(const NotifyDataSourceStoppedRequest& other) const { return !(*this == other); }
60454 
60455   bool ParseFromArray(const void*, size_t) override;
60456   std::string SerializeAsString() const override;
60457   std::vector<uint8_t> SerializeAsArray() const override;
60458   void Serialize(::protozero::Message*) const;
60459 
has_data_source_id() const60460   bool has_data_source_id() const { return _has_field_[1]; }
data_source_id() const60461   uint64_t data_source_id() const { return data_source_id_; }
set_data_source_id(uint64_t value)60462   void set_data_source_id(uint64_t value) { data_source_id_ = value; _has_field_.set(1); }
60463 
60464  private:
60465   uint64_t data_source_id_{};
60466 
60467   // Allows to preserve unknown protobuf fields for compatibility
60468   // with future versions of .proto files.
60469   std::string unknown_fields_;
60470 
60471   std::bitset<2> _has_field_{};
60472 };
60473 
60474 
60475 class PERFETTO_EXPORT NotifyDataSourceStartedResponse : public ::protozero::CppMessageObj {
60476  public:
60477   enum FieldNumbers {
60478   };
60479 
60480   NotifyDataSourceStartedResponse();
60481   ~NotifyDataSourceStartedResponse() override;
60482   NotifyDataSourceStartedResponse(NotifyDataSourceStartedResponse&&) noexcept;
60483   NotifyDataSourceStartedResponse& operator=(NotifyDataSourceStartedResponse&&);
60484   NotifyDataSourceStartedResponse(const NotifyDataSourceStartedResponse&);
60485   NotifyDataSourceStartedResponse& operator=(const NotifyDataSourceStartedResponse&);
60486   bool operator==(const NotifyDataSourceStartedResponse&) const;
operator !=(const NotifyDataSourceStartedResponse & other) const60487   bool operator!=(const NotifyDataSourceStartedResponse& other) const { return !(*this == other); }
60488 
60489   bool ParseFromArray(const void*, size_t) override;
60490   std::string SerializeAsString() const override;
60491   std::vector<uint8_t> SerializeAsArray() const override;
60492   void Serialize(::protozero::Message*) const;
60493 
60494  private:
60495 
60496   // Allows to preserve unknown protobuf fields for compatibility
60497   // with future versions of .proto files.
60498   std::string unknown_fields_;
60499 
60500   std::bitset<2> _has_field_{};
60501 };
60502 
60503 
60504 class PERFETTO_EXPORT NotifyDataSourceStartedRequest : public ::protozero::CppMessageObj {
60505  public:
60506   enum FieldNumbers {
60507     kDataSourceIdFieldNumber = 1,
60508   };
60509 
60510   NotifyDataSourceStartedRequest();
60511   ~NotifyDataSourceStartedRequest() override;
60512   NotifyDataSourceStartedRequest(NotifyDataSourceStartedRequest&&) noexcept;
60513   NotifyDataSourceStartedRequest& operator=(NotifyDataSourceStartedRequest&&);
60514   NotifyDataSourceStartedRequest(const NotifyDataSourceStartedRequest&);
60515   NotifyDataSourceStartedRequest& operator=(const NotifyDataSourceStartedRequest&);
60516   bool operator==(const NotifyDataSourceStartedRequest&) const;
operator !=(const NotifyDataSourceStartedRequest & other) const60517   bool operator!=(const NotifyDataSourceStartedRequest& other) const { return !(*this == other); }
60518 
60519   bool ParseFromArray(const void*, size_t) override;
60520   std::string SerializeAsString() const override;
60521   std::vector<uint8_t> SerializeAsArray() const override;
60522   void Serialize(::protozero::Message*) const;
60523 
has_data_source_id() const60524   bool has_data_source_id() const { return _has_field_[1]; }
data_source_id() const60525   uint64_t data_source_id() const { return data_source_id_; }
set_data_source_id(uint64_t value)60526   void set_data_source_id(uint64_t value) { data_source_id_ = value; _has_field_.set(1); }
60527 
60528  private:
60529   uint64_t data_source_id_{};
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<2> _has_field_{};
60536 };
60537 
60538 
60539 class PERFETTO_EXPORT CommitDataResponse : public ::protozero::CppMessageObj {
60540  public:
60541   enum FieldNumbers {
60542   };
60543 
60544   CommitDataResponse();
60545   ~CommitDataResponse() override;
60546   CommitDataResponse(CommitDataResponse&&) noexcept;
60547   CommitDataResponse& operator=(CommitDataResponse&&);
60548   CommitDataResponse(const CommitDataResponse&);
60549   CommitDataResponse& operator=(const CommitDataResponse&);
60550   bool operator==(const CommitDataResponse&) const;
operator !=(const CommitDataResponse & other) const60551   bool operator!=(const CommitDataResponse& other) const { return !(*this == other); }
60552 
60553   bool ParseFromArray(const void*, size_t) override;
60554   std::string SerializeAsString() const override;
60555   std::vector<uint8_t> SerializeAsArray() const override;
60556   void Serialize(::protozero::Message*) const;
60557 
60558  private:
60559 
60560   // Allows to preserve unknown protobuf fields for compatibility
60561   // with future versions of .proto files.
60562   std::string unknown_fields_;
60563 
60564   std::bitset<2> _has_field_{};
60565 };
60566 
60567 
60568 class PERFETTO_EXPORT UnregisterTraceWriterResponse : public ::protozero::CppMessageObj {
60569  public:
60570   enum FieldNumbers {
60571   };
60572 
60573   UnregisterTraceWriterResponse();
60574   ~UnregisterTraceWriterResponse() override;
60575   UnregisterTraceWriterResponse(UnregisterTraceWriterResponse&&) noexcept;
60576   UnregisterTraceWriterResponse& operator=(UnregisterTraceWriterResponse&&);
60577   UnregisterTraceWriterResponse(const UnregisterTraceWriterResponse&);
60578   UnregisterTraceWriterResponse& operator=(const UnregisterTraceWriterResponse&);
60579   bool operator==(const UnregisterTraceWriterResponse&) const;
operator !=(const UnregisterTraceWriterResponse & other) const60580   bool operator!=(const UnregisterTraceWriterResponse& other) const { return !(*this == other); }
60581 
60582   bool ParseFromArray(const void*, size_t) override;
60583   std::string SerializeAsString() const override;
60584   std::vector<uint8_t> SerializeAsArray() const override;
60585   void Serialize(::protozero::Message*) const;
60586 
60587  private:
60588 
60589   // Allows to preserve unknown protobuf fields for compatibility
60590   // with future versions of .proto files.
60591   std::string unknown_fields_;
60592 
60593   std::bitset<2> _has_field_{};
60594 };
60595 
60596 
60597 class PERFETTO_EXPORT UnregisterTraceWriterRequest : public ::protozero::CppMessageObj {
60598  public:
60599   enum FieldNumbers {
60600     kTraceWriterIdFieldNumber = 1,
60601   };
60602 
60603   UnregisterTraceWriterRequest();
60604   ~UnregisterTraceWriterRequest() override;
60605   UnregisterTraceWriterRequest(UnregisterTraceWriterRequest&&) noexcept;
60606   UnregisterTraceWriterRequest& operator=(UnregisterTraceWriterRequest&&);
60607   UnregisterTraceWriterRequest(const UnregisterTraceWriterRequest&);
60608   UnregisterTraceWriterRequest& operator=(const UnregisterTraceWriterRequest&);
60609   bool operator==(const UnregisterTraceWriterRequest&) const;
operator !=(const UnregisterTraceWriterRequest & other) const60610   bool operator!=(const UnregisterTraceWriterRequest& other) const { return !(*this == other); }
60611 
60612   bool ParseFromArray(const void*, size_t) override;
60613   std::string SerializeAsString() const override;
60614   std::vector<uint8_t> SerializeAsArray() const override;
60615   void Serialize(::protozero::Message*) const;
60616 
has_trace_writer_id() const60617   bool has_trace_writer_id() const { return _has_field_[1]; }
trace_writer_id() const60618   uint32_t trace_writer_id() const { return trace_writer_id_; }
set_trace_writer_id(uint32_t value)60619   void set_trace_writer_id(uint32_t value) { trace_writer_id_ = value; _has_field_.set(1); }
60620 
60621  private:
60622   uint32_t trace_writer_id_{};
60623 
60624   // Allows to preserve unknown protobuf fields for compatibility
60625   // with future versions of .proto files.
60626   std::string unknown_fields_;
60627 
60628   std::bitset<2> _has_field_{};
60629 };
60630 
60631 
60632 class PERFETTO_EXPORT RegisterTraceWriterResponse : public ::protozero::CppMessageObj {
60633  public:
60634   enum FieldNumbers {
60635   };
60636 
60637   RegisterTraceWriterResponse();
60638   ~RegisterTraceWriterResponse() override;
60639   RegisterTraceWriterResponse(RegisterTraceWriterResponse&&) noexcept;
60640   RegisterTraceWriterResponse& operator=(RegisterTraceWriterResponse&&);
60641   RegisterTraceWriterResponse(const RegisterTraceWriterResponse&);
60642   RegisterTraceWriterResponse& operator=(const RegisterTraceWriterResponse&);
60643   bool operator==(const RegisterTraceWriterResponse&) const;
operator !=(const RegisterTraceWriterResponse & other) const60644   bool operator!=(const RegisterTraceWriterResponse& other) const { return !(*this == other); }
60645 
60646   bool ParseFromArray(const void*, size_t) override;
60647   std::string SerializeAsString() const override;
60648   std::vector<uint8_t> SerializeAsArray() const override;
60649   void Serialize(::protozero::Message*) const;
60650 
60651  private:
60652 
60653   // Allows to preserve unknown protobuf fields for compatibility
60654   // with future versions of .proto files.
60655   std::string unknown_fields_;
60656 
60657   std::bitset<2> _has_field_{};
60658 };
60659 
60660 
60661 class PERFETTO_EXPORT RegisterTraceWriterRequest : public ::protozero::CppMessageObj {
60662  public:
60663   enum FieldNumbers {
60664     kTraceWriterIdFieldNumber = 1,
60665     kTargetBufferFieldNumber = 2,
60666   };
60667 
60668   RegisterTraceWriterRequest();
60669   ~RegisterTraceWriterRequest() override;
60670   RegisterTraceWriterRequest(RegisterTraceWriterRequest&&) noexcept;
60671   RegisterTraceWriterRequest& operator=(RegisterTraceWriterRequest&&);
60672   RegisterTraceWriterRequest(const RegisterTraceWriterRequest&);
60673   RegisterTraceWriterRequest& operator=(const RegisterTraceWriterRequest&);
60674   bool operator==(const RegisterTraceWriterRequest&) const;
operator !=(const RegisterTraceWriterRequest & other) const60675   bool operator!=(const RegisterTraceWriterRequest& other) const { return !(*this == other); }
60676 
60677   bool ParseFromArray(const void*, size_t) override;
60678   std::string SerializeAsString() const override;
60679   std::vector<uint8_t> SerializeAsArray() const override;
60680   void Serialize(::protozero::Message*) const;
60681 
has_trace_writer_id() const60682   bool has_trace_writer_id() const { return _has_field_[1]; }
trace_writer_id() const60683   uint32_t trace_writer_id() const { return trace_writer_id_; }
set_trace_writer_id(uint32_t value)60684   void set_trace_writer_id(uint32_t value) { trace_writer_id_ = value; _has_field_.set(1); }
60685 
has_target_buffer() const60686   bool has_target_buffer() const { return _has_field_[2]; }
target_buffer() const60687   uint32_t target_buffer() const { return target_buffer_; }
set_target_buffer(uint32_t value)60688   void set_target_buffer(uint32_t value) { target_buffer_ = value; _has_field_.set(2); }
60689 
60690  private:
60691   uint32_t trace_writer_id_{};
60692   uint32_t target_buffer_{};
60693 
60694   // Allows to preserve unknown protobuf fields for compatibility
60695   // with future versions of .proto files.
60696   std::string unknown_fields_;
60697 
60698   std::bitset<3> _has_field_{};
60699 };
60700 
60701 
60702 class PERFETTO_EXPORT UnregisterDataSourceResponse : public ::protozero::CppMessageObj {
60703  public:
60704   enum FieldNumbers {
60705   };
60706 
60707   UnregisterDataSourceResponse();
60708   ~UnregisterDataSourceResponse() override;
60709   UnregisterDataSourceResponse(UnregisterDataSourceResponse&&) noexcept;
60710   UnregisterDataSourceResponse& operator=(UnregisterDataSourceResponse&&);
60711   UnregisterDataSourceResponse(const UnregisterDataSourceResponse&);
60712   UnregisterDataSourceResponse& operator=(const UnregisterDataSourceResponse&);
60713   bool operator==(const UnregisterDataSourceResponse&) const;
operator !=(const UnregisterDataSourceResponse & other) const60714   bool operator!=(const UnregisterDataSourceResponse& other) const { return !(*this == other); }
60715 
60716   bool ParseFromArray(const void*, size_t) override;
60717   std::string SerializeAsString() const override;
60718   std::vector<uint8_t> SerializeAsArray() const override;
60719   void Serialize(::protozero::Message*) const;
60720 
60721  private:
60722 
60723   // Allows to preserve unknown protobuf fields for compatibility
60724   // with future versions of .proto files.
60725   std::string unknown_fields_;
60726 
60727   std::bitset<2> _has_field_{};
60728 };
60729 
60730 
60731 class PERFETTO_EXPORT UnregisterDataSourceRequest : public ::protozero::CppMessageObj {
60732  public:
60733   enum FieldNumbers {
60734     kDataSourceNameFieldNumber = 1,
60735   };
60736 
60737   UnregisterDataSourceRequest();
60738   ~UnregisterDataSourceRequest() override;
60739   UnregisterDataSourceRequest(UnregisterDataSourceRequest&&) noexcept;
60740   UnregisterDataSourceRequest& operator=(UnregisterDataSourceRequest&&);
60741   UnregisterDataSourceRequest(const UnregisterDataSourceRequest&);
60742   UnregisterDataSourceRequest& operator=(const UnregisterDataSourceRequest&);
60743   bool operator==(const UnregisterDataSourceRequest&) const;
operator !=(const UnregisterDataSourceRequest & other) const60744   bool operator!=(const UnregisterDataSourceRequest& other) const { return !(*this == other); }
60745 
60746   bool ParseFromArray(const void*, size_t) override;
60747   std::string SerializeAsString() const override;
60748   std::vector<uint8_t> SerializeAsArray() const override;
60749   void Serialize(::protozero::Message*) const;
60750 
has_data_source_name() const60751   bool has_data_source_name() const { return _has_field_[1]; }
data_source_name() const60752   const std::string& data_source_name() const { return data_source_name_; }
set_data_source_name(const std::string & value)60753   void set_data_source_name(const std::string& value) { data_source_name_ = value; _has_field_.set(1); }
60754 
60755  private:
60756   std::string data_source_name_{};
60757 
60758   // Allows to preserve unknown protobuf fields for compatibility
60759   // with future versions of .proto files.
60760   std::string unknown_fields_;
60761 
60762   std::bitset<2> _has_field_{};
60763 };
60764 
60765 
60766 class PERFETTO_EXPORT UpdateDataSourceResponse : public ::protozero::CppMessageObj {
60767  public:
60768   enum FieldNumbers {
60769   };
60770 
60771   UpdateDataSourceResponse();
60772   ~UpdateDataSourceResponse() override;
60773   UpdateDataSourceResponse(UpdateDataSourceResponse&&) noexcept;
60774   UpdateDataSourceResponse& operator=(UpdateDataSourceResponse&&);
60775   UpdateDataSourceResponse(const UpdateDataSourceResponse&);
60776   UpdateDataSourceResponse& operator=(const UpdateDataSourceResponse&);
60777   bool operator==(const UpdateDataSourceResponse&) const;
operator !=(const UpdateDataSourceResponse & other) const60778   bool operator!=(const UpdateDataSourceResponse& other) const { return !(*this == other); }
60779 
60780   bool ParseFromArray(const void*, size_t) override;
60781   std::string SerializeAsString() const override;
60782   std::vector<uint8_t> SerializeAsArray() const override;
60783   void Serialize(::protozero::Message*) const;
60784 
60785  private:
60786 
60787   // Allows to preserve unknown protobuf fields for compatibility
60788   // with future versions of .proto files.
60789   std::string unknown_fields_;
60790 
60791   std::bitset<2> _has_field_{};
60792 };
60793 
60794 
60795 class PERFETTO_EXPORT UpdateDataSourceRequest : public ::protozero::CppMessageObj {
60796  public:
60797   enum FieldNumbers {
60798     kDataSourceDescriptorFieldNumber = 1,
60799   };
60800 
60801   UpdateDataSourceRequest();
60802   ~UpdateDataSourceRequest() override;
60803   UpdateDataSourceRequest(UpdateDataSourceRequest&&) noexcept;
60804   UpdateDataSourceRequest& operator=(UpdateDataSourceRequest&&);
60805   UpdateDataSourceRequest(const UpdateDataSourceRequest&);
60806   UpdateDataSourceRequest& operator=(const UpdateDataSourceRequest&);
60807   bool operator==(const UpdateDataSourceRequest&) const;
operator !=(const UpdateDataSourceRequest & other) const60808   bool operator!=(const UpdateDataSourceRequest& other) const { return !(*this == other); }
60809 
60810   bool ParseFromArray(const void*, size_t) override;
60811   std::string SerializeAsString() const override;
60812   std::vector<uint8_t> SerializeAsArray() const override;
60813   void Serialize(::protozero::Message*) const;
60814 
has_data_source_descriptor() const60815   bool has_data_source_descriptor() const { return _has_field_[1]; }
data_source_descriptor() const60816   const DataSourceDescriptor& data_source_descriptor() const { return *data_source_descriptor_; }
mutable_data_source_descriptor()60817   DataSourceDescriptor* mutable_data_source_descriptor() { _has_field_.set(1); return data_source_descriptor_.get(); }
60818 
60819  private:
60820   ::protozero::CopyablePtr<DataSourceDescriptor> data_source_descriptor_;
60821 
60822   // Allows to preserve unknown protobuf fields for compatibility
60823   // with future versions of .proto files.
60824   std::string unknown_fields_;
60825 
60826   std::bitset<2> _has_field_{};
60827 };
60828 
60829 
60830 class PERFETTO_EXPORT RegisterDataSourceResponse : public ::protozero::CppMessageObj {
60831  public:
60832   enum FieldNumbers {
60833     kErrorFieldNumber = 1,
60834   };
60835 
60836   RegisterDataSourceResponse();
60837   ~RegisterDataSourceResponse() override;
60838   RegisterDataSourceResponse(RegisterDataSourceResponse&&) noexcept;
60839   RegisterDataSourceResponse& operator=(RegisterDataSourceResponse&&);
60840   RegisterDataSourceResponse(const RegisterDataSourceResponse&);
60841   RegisterDataSourceResponse& operator=(const RegisterDataSourceResponse&);
60842   bool operator==(const RegisterDataSourceResponse&) const;
operator !=(const RegisterDataSourceResponse & other) const60843   bool operator!=(const RegisterDataSourceResponse& other) const { return !(*this == other); }
60844 
60845   bool ParseFromArray(const void*, size_t) override;
60846   std::string SerializeAsString() const override;
60847   std::vector<uint8_t> SerializeAsArray() const override;
60848   void Serialize(::protozero::Message*) const;
60849 
has_error() const60850   bool has_error() const { return _has_field_[1]; }
error() const60851   const std::string& error() const { return error_; }
set_error(const std::string & value)60852   void set_error(const std::string& value) { error_ = value; _has_field_.set(1); }
60853 
60854  private:
60855   std::string error_{};
60856 
60857   // Allows to preserve unknown protobuf fields for compatibility
60858   // with future versions of .proto files.
60859   std::string unknown_fields_;
60860 
60861   std::bitset<2> _has_field_{};
60862 };
60863 
60864 
60865 class PERFETTO_EXPORT RegisterDataSourceRequest : public ::protozero::CppMessageObj {
60866  public:
60867   enum FieldNumbers {
60868     kDataSourceDescriptorFieldNumber = 1,
60869   };
60870 
60871   RegisterDataSourceRequest();
60872   ~RegisterDataSourceRequest() override;
60873   RegisterDataSourceRequest(RegisterDataSourceRequest&&) noexcept;
60874   RegisterDataSourceRequest& operator=(RegisterDataSourceRequest&&);
60875   RegisterDataSourceRequest(const RegisterDataSourceRequest&);
60876   RegisterDataSourceRequest& operator=(const RegisterDataSourceRequest&);
60877   bool operator==(const RegisterDataSourceRequest&) const;
operator !=(const RegisterDataSourceRequest & other) const60878   bool operator!=(const RegisterDataSourceRequest& other) const { return !(*this == other); }
60879 
60880   bool ParseFromArray(const void*, size_t) override;
60881   std::string SerializeAsString() const override;
60882   std::vector<uint8_t> SerializeAsArray() const override;
60883   void Serialize(::protozero::Message*) const;
60884 
has_data_source_descriptor() const60885   bool has_data_source_descriptor() const { return _has_field_[1]; }
data_source_descriptor() const60886   const DataSourceDescriptor& data_source_descriptor() const { return *data_source_descriptor_; }
mutable_data_source_descriptor()60887   DataSourceDescriptor* mutable_data_source_descriptor() { _has_field_.set(1); return data_source_descriptor_.get(); }
60888 
60889  private:
60890   ::protozero::CopyablePtr<DataSourceDescriptor> data_source_descriptor_;
60891 
60892   // Allows to preserve unknown protobuf fields for compatibility
60893   // with future versions of .proto files.
60894   std::string unknown_fields_;
60895 
60896   std::bitset<2> _has_field_{};
60897 };
60898 
60899 
60900 class PERFETTO_EXPORT InitializeConnectionResponse : public ::protozero::CppMessageObj {
60901  public:
60902   enum FieldNumbers {
60903     kUsingShmemProvidedByProducerFieldNumber = 1,
60904     kDirectSmbPatchingSupportedFieldNumber = 2,
60905   };
60906 
60907   InitializeConnectionResponse();
60908   ~InitializeConnectionResponse() override;
60909   InitializeConnectionResponse(InitializeConnectionResponse&&) noexcept;
60910   InitializeConnectionResponse& operator=(InitializeConnectionResponse&&);
60911   InitializeConnectionResponse(const InitializeConnectionResponse&);
60912   InitializeConnectionResponse& operator=(const InitializeConnectionResponse&);
60913   bool operator==(const InitializeConnectionResponse&) const;
operator !=(const InitializeConnectionResponse & other) const60914   bool operator!=(const InitializeConnectionResponse& other) const { return !(*this == other); }
60915 
60916   bool ParseFromArray(const void*, size_t) override;
60917   std::string SerializeAsString() const override;
60918   std::vector<uint8_t> SerializeAsArray() const override;
60919   void Serialize(::protozero::Message*) const;
60920 
has_using_shmem_provided_by_producer() const60921   bool has_using_shmem_provided_by_producer() const { return _has_field_[1]; }
using_shmem_provided_by_producer() const60922   bool using_shmem_provided_by_producer() const { return using_shmem_provided_by_producer_; }
set_using_shmem_provided_by_producer(bool value)60923   void set_using_shmem_provided_by_producer(bool value) { using_shmem_provided_by_producer_ = value; _has_field_.set(1); }
60924 
has_direct_smb_patching_supported() const60925   bool has_direct_smb_patching_supported() const { return _has_field_[2]; }
direct_smb_patching_supported() const60926   bool direct_smb_patching_supported() const { return direct_smb_patching_supported_; }
set_direct_smb_patching_supported(bool value)60927   void set_direct_smb_patching_supported(bool value) { direct_smb_patching_supported_ = value; _has_field_.set(2); }
60928 
60929  private:
60930   bool using_shmem_provided_by_producer_{};
60931   bool direct_smb_patching_supported_{};
60932 
60933   // Allows to preserve unknown protobuf fields for compatibility
60934   // with future versions of .proto files.
60935   std::string unknown_fields_;
60936 
60937   std::bitset<3> _has_field_{};
60938 };
60939 
60940 
60941 class PERFETTO_EXPORT InitializeConnectionRequest : public ::protozero::CppMessageObj {
60942  public:
60943   using ProducerSMBScrapingMode = InitializeConnectionRequest_ProducerSMBScrapingMode;
60944   static constexpr auto SMB_SCRAPING_UNSPECIFIED = InitializeConnectionRequest_ProducerSMBScrapingMode_SMB_SCRAPING_UNSPECIFIED;
60945   static constexpr auto SMB_SCRAPING_ENABLED = InitializeConnectionRequest_ProducerSMBScrapingMode_SMB_SCRAPING_ENABLED;
60946   static constexpr auto SMB_SCRAPING_DISABLED = InitializeConnectionRequest_ProducerSMBScrapingMode_SMB_SCRAPING_DISABLED;
60947   static constexpr auto ProducerSMBScrapingMode_MIN = InitializeConnectionRequest_ProducerSMBScrapingMode_SMB_SCRAPING_UNSPECIFIED;
60948   static constexpr auto ProducerSMBScrapingMode_MAX = InitializeConnectionRequest_ProducerSMBScrapingMode_SMB_SCRAPING_DISABLED;
60949   enum FieldNumbers {
60950     kSharedMemoryPageSizeHintBytesFieldNumber = 1,
60951     kSharedMemorySizeHintBytesFieldNumber = 2,
60952     kProducerNameFieldNumber = 3,
60953     kSmbScrapingModeFieldNumber = 4,
60954     kProducerProvidedShmemFieldNumber = 6,
60955     kSdkVersionFieldNumber = 8,
60956     kShmKeyWindowsFieldNumber = 7,
60957   };
60958 
60959   InitializeConnectionRequest();
60960   ~InitializeConnectionRequest() override;
60961   InitializeConnectionRequest(InitializeConnectionRequest&&) noexcept;
60962   InitializeConnectionRequest& operator=(InitializeConnectionRequest&&);
60963   InitializeConnectionRequest(const InitializeConnectionRequest&);
60964   InitializeConnectionRequest& operator=(const InitializeConnectionRequest&);
60965   bool operator==(const InitializeConnectionRequest&) const;
operator !=(const InitializeConnectionRequest & other) const60966   bool operator!=(const InitializeConnectionRequest& other) const { return !(*this == other); }
60967 
60968   bool ParseFromArray(const void*, size_t) override;
60969   std::string SerializeAsString() const override;
60970   std::vector<uint8_t> SerializeAsArray() const override;
60971   void Serialize(::protozero::Message*) const;
60972 
has_shared_memory_page_size_hint_bytes() const60973   bool has_shared_memory_page_size_hint_bytes() const { return _has_field_[1]; }
shared_memory_page_size_hint_bytes() const60974   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)60975   void set_shared_memory_page_size_hint_bytes(uint32_t value) { shared_memory_page_size_hint_bytes_ = value; _has_field_.set(1); }
60976 
has_shared_memory_size_hint_bytes() const60977   bool has_shared_memory_size_hint_bytes() const { return _has_field_[2]; }
shared_memory_size_hint_bytes() const60978   uint32_t shared_memory_size_hint_bytes() const { return shared_memory_size_hint_bytes_; }
set_shared_memory_size_hint_bytes(uint32_t value)60979   void set_shared_memory_size_hint_bytes(uint32_t value) { shared_memory_size_hint_bytes_ = value; _has_field_.set(2); }
60980 
has_producer_name() const60981   bool has_producer_name() const { return _has_field_[3]; }
producer_name() const60982   const std::string& producer_name() const { return producer_name_; }
set_producer_name(const std::string & value)60983   void set_producer_name(const std::string& value) { producer_name_ = value; _has_field_.set(3); }
60984 
has_smb_scraping_mode() const60985   bool has_smb_scraping_mode() const { return _has_field_[4]; }
smb_scraping_mode() const60986   InitializeConnectionRequest_ProducerSMBScrapingMode smb_scraping_mode() const { return smb_scraping_mode_; }
set_smb_scraping_mode(InitializeConnectionRequest_ProducerSMBScrapingMode value)60987   void set_smb_scraping_mode(InitializeConnectionRequest_ProducerSMBScrapingMode value) { smb_scraping_mode_ = value; _has_field_.set(4); }
60988 
has_producer_provided_shmem() const60989   bool has_producer_provided_shmem() const { return _has_field_[6]; }
producer_provided_shmem() const60990   bool producer_provided_shmem() const { return producer_provided_shmem_; }
set_producer_provided_shmem(bool value)60991   void set_producer_provided_shmem(bool value) { producer_provided_shmem_ = value; _has_field_.set(6); }
60992 
has_sdk_version() const60993   bool has_sdk_version() const { return _has_field_[8]; }
sdk_version() const60994   const std::string& sdk_version() const { return sdk_version_; }
set_sdk_version(const std::string & value)60995   void set_sdk_version(const std::string& value) { sdk_version_ = value; _has_field_.set(8); }
60996 
has_shm_key_windows() const60997   bool has_shm_key_windows() const { return _has_field_[7]; }
shm_key_windows() const60998   const std::string& shm_key_windows() const { return shm_key_windows_; }
set_shm_key_windows(const std::string & value)60999   void set_shm_key_windows(const std::string& value) { shm_key_windows_ = value; _has_field_.set(7); }
61000 
61001  private:
61002   uint32_t shared_memory_page_size_hint_bytes_{};
61003   uint32_t shared_memory_size_hint_bytes_{};
61004   std::string producer_name_{};
61005   InitializeConnectionRequest_ProducerSMBScrapingMode smb_scraping_mode_{};
61006   bool producer_provided_shmem_{};
61007   std::string sdk_version_{};
61008   std::string shm_key_windows_{};
61009 
61010   // Allows to preserve unknown protobuf fields for compatibility
61011   // with future versions of .proto files.
61012   std::string unknown_fields_;
61013 
61014   std::bitset<9> _has_field_{};
61015 };
61016 
61017 }  // namespace perfetto
61018 }  // namespace protos
61019 }  // namespace gen
61020 
61021 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_IPC_PRODUCER_PORT_PROTO_CPP_H_
61022 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
61023 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
61024 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
61025 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
61026 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
61027 #if defined(__GNUC__) || defined(__clang__)
61028 #pragma GCC diagnostic push
61029 #pragma GCC diagnostic ignored "-Wfloat-equal"
61030 #endif
61031 // gen_amalgamated expanded: #include "protos/perfetto/ipc/producer_port.gen.h"
61032 // gen_amalgamated expanded: #include "protos/perfetto/common/data_source_descriptor.gen.h"
61033 // gen_amalgamated expanded: #include "protos/perfetto/common/track_event_descriptor.gen.h"
61034 // gen_amalgamated expanded: #include "protos/perfetto/common/gpu_counter_descriptor.gen.h"
61035 // gen_amalgamated expanded: #include "protos/perfetto/config/data_source_config.gen.h"
61036 // gen_amalgamated expanded: #include "protos/perfetto/config/track_event/track_event_config.gen.h"
61037 // gen_amalgamated expanded: #include "protos/perfetto/config/test_config.gen.h"
61038 // gen_amalgamated expanded: #include "protos/perfetto/config/sys_stats/sys_stats_config.gen.h"
61039 // gen_amalgamated expanded: #include "protos/perfetto/common/sys_stats_counters.gen.h"
61040 // gen_amalgamated expanded: #include "protos/perfetto/config/profiling/perf_event_config.gen.h"
61041 // gen_amalgamated expanded: #include "protos/perfetto/common/perf_events.gen.h"
61042 // gen_amalgamated expanded: #include "protos/perfetto/config/profiling/java_hprof_config.gen.h"
61043 // gen_amalgamated expanded: #include "protos/perfetto/config/profiling/heapprofd_config.gen.h"
61044 // gen_amalgamated expanded: #include "protos/perfetto/config/process_stats/process_stats_config.gen.h"
61045 // gen_amalgamated expanded: #include "protos/perfetto/config/power/android_power_config.gen.h"
61046 // gen_amalgamated expanded: #include "protos/perfetto/config/interceptor_config.gen.h"
61047 // gen_amalgamated expanded: #include "protos/perfetto/config/interceptors/console_config.gen.h"
61048 // gen_amalgamated expanded: #include "protos/perfetto/config/inode_file/inode_file_config.gen.h"
61049 // gen_amalgamated expanded: #include "protos/perfetto/config/gpu/vulkan_memory_config.gen.h"
61050 // gen_amalgamated expanded: #include "protos/perfetto/config/gpu/gpu_counter_config.gen.h"
61051 // gen_amalgamated expanded: #include "protos/perfetto/config/ftrace/ftrace_config.gen.h"
61052 // gen_amalgamated expanded: #include "protos/perfetto/config/chrome/chrome_config.gen.h"
61053 // gen_amalgamated expanded: #include "protos/perfetto/config/android/packages_list_config.gen.h"
61054 // gen_amalgamated expanded: #include "protos/perfetto/config/android/android_polled_state_config.gen.h"
61055 // gen_amalgamated expanded: #include "protos/perfetto/config/android/android_log_config.gen.h"
61056 // gen_amalgamated expanded: #include "protos/perfetto/common/android_log_constants.gen.h"
61057 // gen_amalgamated expanded: #include "protos/perfetto/common/commit_data_request.gen.h"
61058 
61059 namespace perfetto {
61060 namespace protos {
61061 namespace gen {
61062 
61063 SyncResponse::SyncResponse() = default;
61064 SyncResponse::~SyncResponse() = default;
61065 SyncResponse::SyncResponse(const SyncResponse&) = default;
61066 SyncResponse& SyncResponse::operator=(const SyncResponse&) = default;
61067 SyncResponse::SyncResponse(SyncResponse&&) noexcept = default;
61068 SyncResponse& SyncResponse::operator=(SyncResponse&&) = default;
61069 
operator ==(const SyncResponse & other) const61070 bool SyncResponse::operator==(const SyncResponse& other) const {
61071   return unknown_fields_ == other.unknown_fields_;
61072 }
61073 
ParseFromArray(const void * raw,size_t size)61074 bool SyncResponse::ParseFromArray(const void* raw, size_t size) {
61075   unknown_fields_.clear();
61076   bool packed_error = false;
61077 
61078   ::protozero::ProtoDecoder dec(raw, size);
61079   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
61080     if (field.id() < _has_field_.size()) {
61081       _has_field_.set(field.id());
61082     }
61083     switch (field.id()) {
61084       default:
61085         field.SerializeAndAppendTo(&unknown_fields_);
61086         break;
61087     }
61088   }
61089   return !packed_error && !dec.bytes_left();
61090 }
61091 
SerializeAsString() const61092 std::string SyncResponse::SerializeAsString() const {
61093   ::protozero::HeapBuffered<::protozero::Message> msg;
61094   Serialize(msg.get());
61095   return msg.SerializeAsString();
61096 }
61097 
SerializeAsArray() const61098 std::vector<uint8_t> SyncResponse::SerializeAsArray() const {
61099   ::protozero::HeapBuffered<::protozero::Message> msg;
61100   Serialize(msg.get());
61101   return msg.SerializeAsArray();
61102 }
61103 
Serialize(::protozero::Message * msg) const61104 void SyncResponse::Serialize(::protozero::Message* msg) const {
61105   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
61106 }
61107 
61108 
61109 SyncRequest::SyncRequest() = default;
61110 SyncRequest::~SyncRequest() = default;
61111 SyncRequest::SyncRequest(const SyncRequest&) = default;
61112 SyncRequest& SyncRequest::operator=(const SyncRequest&) = default;
61113 SyncRequest::SyncRequest(SyncRequest&&) noexcept = default;
61114 SyncRequest& SyncRequest::operator=(SyncRequest&&) = default;
61115 
operator ==(const SyncRequest & other) const61116 bool SyncRequest::operator==(const SyncRequest& other) const {
61117   return unknown_fields_ == other.unknown_fields_;
61118 }
61119 
ParseFromArray(const void * raw,size_t size)61120 bool SyncRequest::ParseFromArray(const void* raw, size_t size) {
61121   unknown_fields_.clear();
61122   bool packed_error = false;
61123 
61124   ::protozero::ProtoDecoder dec(raw, size);
61125   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
61126     if (field.id() < _has_field_.size()) {
61127       _has_field_.set(field.id());
61128     }
61129     switch (field.id()) {
61130       default:
61131         field.SerializeAndAppendTo(&unknown_fields_);
61132         break;
61133     }
61134   }
61135   return !packed_error && !dec.bytes_left();
61136 }
61137 
SerializeAsString() const61138 std::string SyncRequest::SerializeAsString() const {
61139   ::protozero::HeapBuffered<::protozero::Message> msg;
61140   Serialize(msg.get());
61141   return msg.SerializeAsString();
61142 }
61143 
SerializeAsArray() const61144 std::vector<uint8_t> SyncRequest::SerializeAsArray() const {
61145   ::protozero::HeapBuffered<::protozero::Message> msg;
61146   Serialize(msg.get());
61147   return msg.SerializeAsArray();
61148 }
61149 
Serialize(::protozero::Message * msg) const61150 void SyncRequest::Serialize(::protozero::Message* msg) const {
61151   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
61152 }
61153 
61154 
61155 GetAsyncCommandResponse::GetAsyncCommandResponse() = default;
61156 GetAsyncCommandResponse::~GetAsyncCommandResponse() = default;
61157 GetAsyncCommandResponse::GetAsyncCommandResponse(const GetAsyncCommandResponse&) = default;
61158 GetAsyncCommandResponse& GetAsyncCommandResponse::operator=(const GetAsyncCommandResponse&) = default;
61159 GetAsyncCommandResponse::GetAsyncCommandResponse(GetAsyncCommandResponse&&) noexcept = default;
61160 GetAsyncCommandResponse& GetAsyncCommandResponse::operator=(GetAsyncCommandResponse&&) = default;
61161 
operator ==(const GetAsyncCommandResponse & other) const61162 bool GetAsyncCommandResponse::operator==(const GetAsyncCommandResponse& other) const {
61163   return unknown_fields_ == other.unknown_fields_
61164    && setup_tracing_ == other.setup_tracing_
61165    && setup_data_source_ == other.setup_data_source_
61166    && start_data_source_ == other.start_data_source_
61167    && stop_data_source_ == other.stop_data_source_
61168    && flush_ == other.flush_
61169    && clear_incremental_state_ == other.clear_incremental_state_;
61170 }
61171 
ParseFromArray(const void * raw,size_t size)61172 bool GetAsyncCommandResponse::ParseFromArray(const void* raw, size_t size) {
61173   unknown_fields_.clear();
61174   bool packed_error = false;
61175 
61176   ::protozero::ProtoDecoder dec(raw, size);
61177   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
61178     if (field.id() < _has_field_.size()) {
61179       _has_field_.set(field.id());
61180     }
61181     switch (field.id()) {
61182       case 3 /* setup_tracing */:
61183         (*setup_tracing_).ParseFromArray(field.data(), field.size());
61184         break;
61185       case 6 /* setup_data_source */:
61186         (*setup_data_source_).ParseFromArray(field.data(), field.size());
61187         break;
61188       case 1 /* start_data_source */:
61189         (*start_data_source_).ParseFromArray(field.data(), field.size());
61190         break;
61191       case 2 /* stop_data_source */:
61192         (*stop_data_source_).ParseFromArray(field.data(), field.size());
61193         break;
61194       case 5 /* flush */:
61195         (*flush_).ParseFromArray(field.data(), field.size());
61196         break;
61197       case 7 /* clear_incremental_state */:
61198         (*clear_incremental_state_).ParseFromArray(field.data(), field.size());
61199         break;
61200       default:
61201         field.SerializeAndAppendTo(&unknown_fields_);
61202         break;
61203     }
61204   }
61205   return !packed_error && !dec.bytes_left();
61206 }
61207 
SerializeAsString() const61208 std::string GetAsyncCommandResponse::SerializeAsString() const {
61209   ::protozero::HeapBuffered<::protozero::Message> msg;
61210   Serialize(msg.get());
61211   return msg.SerializeAsString();
61212 }
61213 
SerializeAsArray() const61214 std::vector<uint8_t> GetAsyncCommandResponse::SerializeAsArray() const {
61215   ::protozero::HeapBuffered<::protozero::Message> msg;
61216   Serialize(msg.get());
61217   return msg.SerializeAsArray();
61218 }
61219 
Serialize(::protozero::Message * msg) const61220 void GetAsyncCommandResponse::Serialize(::protozero::Message* msg) const {
61221   // Field 3: setup_tracing
61222   if (_has_field_[3]) {
61223     (*setup_tracing_).Serialize(msg->BeginNestedMessage<::protozero::Message>(3));
61224   }
61225 
61226   // Field 6: setup_data_source
61227   if (_has_field_[6]) {
61228     (*setup_data_source_).Serialize(msg->BeginNestedMessage<::protozero::Message>(6));
61229   }
61230 
61231   // Field 1: start_data_source
61232   if (_has_field_[1]) {
61233     (*start_data_source_).Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
61234   }
61235 
61236   // Field 2: stop_data_source
61237   if (_has_field_[2]) {
61238     (*stop_data_source_).Serialize(msg->BeginNestedMessage<::protozero::Message>(2));
61239   }
61240 
61241   // Field 5: flush
61242   if (_has_field_[5]) {
61243     (*flush_).Serialize(msg->BeginNestedMessage<::protozero::Message>(5));
61244   }
61245 
61246   // Field 7: clear_incremental_state
61247   if (_has_field_[7]) {
61248     (*clear_incremental_state_).Serialize(msg->BeginNestedMessage<::protozero::Message>(7));
61249   }
61250 
61251   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
61252 }
61253 
61254 
61255 GetAsyncCommandResponse_ClearIncrementalState::GetAsyncCommandResponse_ClearIncrementalState() = default;
61256 GetAsyncCommandResponse_ClearIncrementalState::~GetAsyncCommandResponse_ClearIncrementalState() = default;
61257 GetAsyncCommandResponse_ClearIncrementalState::GetAsyncCommandResponse_ClearIncrementalState(const GetAsyncCommandResponse_ClearIncrementalState&) = default;
61258 GetAsyncCommandResponse_ClearIncrementalState& GetAsyncCommandResponse_ClearIncrementalState::operator=(const GetAsyncCommandResponse_ClearIncrementalState&) = default;
61259 GetAsyncCommandResponse_ClearIncrementalState::GetAsyncCommandResponse_ClearIncrementalState(GetAsyncCommandResponse_ClearIncrementalState&&) noexcept = default;
61260 GetAsyncCommandResponse_ClearIncrementalState& GetAsyncCommandResponse_ClearIncrementalState::operator=(GetAsyncCommandResponse_ClearIncrementalState&&) = default;
61261 
operator ==(const GetAsyncCommandResponse_ClearIncrementalState & other) const61262 bool GetAsyncCommandResponse_ClearIncrementalState::operator==(const GetAsyncCommandResponse_ClearIncrementalState& other) const {
61263   return unknown_fields_ == other.unknown_fields_
61264    && data_source_ids_ == other.data_source_ids_;
61265 }
61266 
ParseFromArray(const void * raw,size_t size)61267 bool GetAsyncCommandResponse_ClearIncrementalState::ParseFromArray(const void* raw, size_t size) {
61268   data_source_ids_.clear();
61269   unknown_fields_.clear();
61270   bool packed_error = false;
61271 
61272   ::protozero::ProtoDecoder dec(raw, size);
61273   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
61274     if (field.id() < _has_field_.size()) {
61275       _has_field_.set(field.id());
61276     }
61277     switch (field.id()) {
61278       case 1 /* data_source_ids */:
61279         data_source_ids_.emplace_back();
61280         field.get(&data_source_ids_.back());
61281         break;
61282       default:
61283         field.SerializeAndAppendTo(&unknown_fields_);
61284         break;
61285     }
61286   }
61287   return !packed_error && !dec.bytes_left();
61288 }
61289 
SerializeAsString() const61290 std::string GetAsyncCommandResponse_ClearIncrementalState::SerializeAsString() const {
61291   ::protozero::HeapBuffered<::protozero::Message> msg;
61292   Serialize(msg.get());
61293   return msg.SerializeAsString();
61294 }
61295 
SerializeAsArray() const61296 std::vector<uint8_t> GetAsyncCommandResponse_ClearIncrementalState::SerializeAsArray() const {
61297   ::protozero::HeapBuffered<::protozero::Message> msg;
61298   Serialize(msg.get());
61299   return msg.SerializeAsArray();
61300 }
61301 
Serialize(::protozero::Message * msg) const61302 void GetAsyncCommandResponse_ClearIncrementalState::Serialize(::protozero::Message* msg) const {
61303   // Field 1: data_source_ids
61304   for (auto& it : data_source_ids_) {
61305     msg->AppendVarInt(1, it);
61306   }
61307 
61308   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
61309 }
61310 
61311 
61312 GetAsyncCommandResponse_Flush::GetAsyncCommandResponse_Flush() = default;
61313 GetAsyncCommandResponse_Flush::~GetAsyncCommandResponse_Flush() = default;
61314 GetAsyncCommandResponse_Flush::GetAsyncCommandResponse_Flush(const GetAsyncCommandResponse_Flush&) = default;
61315 GetAsyncCommandResponse_Flush& GetAsyncCommandResponse_Flush::operator=(const GetAsyncCommandResponse_Flush&) = default;
61316 GetAsyncCommandResponse_Flush::GetAsyncCommandResponse_Flush(GetAsyncCommandResponse_Flush&&) noexcept = default;
61317 GetAsyncCommandResponse_Flush& GetAsyncCommandResponse_Flush::operator=(GetAsyncCommandResponse_Flush&&) = default;
61318 
operator ==(const GetAsyncCommandResponse_Flush & other) const61319 bool GetAsyncCommandResponse_Flush::operator==(const GetAsyncCommandResponse_Flush& other) const {
61320   return unknown_fields_ == other.unknown_fields_
61321    && data_source_ids_ == other.data_source_ids_
61322    && request_id_ == other.request_id_;
61323 }
61324 
ParseFromArray(const void * raw,size_t size)61325 bool GetAsyncCommandResponse_Flush::ParseFromArray(const void* raw, size_t size) {
61326   data_source_ids_.clear();
61327   unknown_fields_.clear();
61328   bool packed_error = false;
61329 
61330   ::protozero::ProtoDecoder dec(raw, size);
61331   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
61332     if (field.id() < _has_field_.size()) {
61333       _has_field_.set(field.id());
61334     }
61335     switch (field.id()) {
61336       case 1 /* data_source_ids */:
61337         data_source_ids_.emplace_back();
61338         field.get(&data_source_ids_.back());
61339         break;
61340       case 2 /* request_id */:
61341         field.get(&request_id_);
61342         break;
61343       default:
61344         field.SerializeAndAppendTo(&unknown_fields_);
61345         break;
61346     }
61347   }
61348   return !packed_error && !dec.bytes_left();
61349 }
61350 
SerializeAsString() const61351 std::string GetAsyncCommandResponse_Flush::SerializeAsString() const {
61352   ::protozero::HeapBuffered<::protozero::Message> msg;
61353   Serialize(msg.get());
61354   return msg.SerializeAsString();
61355 }
61356 
SerializeAsArray() const61357 std::vector<uint8_t> GetAsyncCommandResponse_Flush::SerializeAsArray() const {
61358   ::protozero::HeapBuffered<::protozero::Message> msg;
61359   Serialize(msg.get());
61360   return msg.SerializeAsArray();
61361 }
61362 
Serialize(::protozero::Message * msg) const61363 void GetAsyncCommandResponse_Flush::Serialize(::protozero::Message* msg) const {
61364   // Field 1: data_source_ids
61365   for (auto& it : data_source_ids_) {
61366     msg->AppendVarInt(1, it);
61367   }
61368 
61369   // Field 2: request_id
61370   if (_has_field_[2]) {
61371     msg->AppendVarInt(2, request_id_);
61372   }
61373 
61374   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
61375 }
61376 
61377 
61378 GetAsyncCommandResponse_StopDataSource::GetAsyncCommandResponse_StopDataSource() = default;
61379 GetAsyncCommandResponse_StopDataSource::~GetAsyncCommandResponse_StopDataSource() = default;
61380 GetAsyncCommandResponse_StopDataSource::GetAsyncCommandResponse_StopDataSource(const GetAsyncCommandResponse_StopDataSource&) = default;
61381 GetAsyncCommandResponse_StopDataSource& GetAsyncCommandResponse_StopDataSource::operator=(const GetAsyncCommandResponse_StopDataSource&) = default;
61382 GetAsyncCommandResponse_StopDataSource::GetAsyncCommandResponse_StopDataSource(GetAsyncCommandResponse_StopDataSource&&) noexcept = default;
61383 GetAsyncCommandResponse_StopDataSource& GetAsyncCommandResponse_StopDataSource::operator=(GetAsyncCommandResponse_StopDataSource&&) = default;
61384 
operator ==(const GetAsyncCommandResponse_StopDataSource & other) const61385 bool GetAsyncCommandResponse_StopDataSource::operator==(const GetAsyncCommandResponse_StopDataSource& other) const {
61386   return unknown_fields_ == other.unknown_fields_
61387    && instance_id_ == other.instance_id_;
61388 }
61389 
ParseFromArray(const void * raw,size_t size)61390 bool GetAsyncCommandResponse_StopDataSource::ParseFromArray(const void* raw, size_t size) {
61391   unknown_fields_.clear();
61392   bool packed_error = false;
61393 
61394   ::protozero::ProtoDecoder dec(raw, size);
61395   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
61396     if (field.id() < _has_field_.size()) {
61397       _has_field_.set(field.id());
61398     }
61399     switch (field.id()) {
61400       case 1 /* instance_id */:
61401         field.get(&instance_id_);
61402         break;
61403       default:
61404         field.SerializeAndAppendTo(&unknown_fields_);
61405         break;
61406     }
61407   }
61408   return !packed_error && !dec.bytes_left();
61409 }
61410 
SerializeAsString() const61411 std::string GetAsyncCommandResponse_StopDataSource::SerializeAsString() const {
61412   ::protozero::HeapBuffered<::protozero::Message> msg;
61413   Serialize(msg.get());
61414   return msg.SerializeAsString();
61415 }
61416 
SerializeAsArray() const61417 std::vector<uint8_t> GetAsyncCommandResponse_StopDataSource::SerializeAsArray() const {
61418   ::protozero::HeapBuffered<::protozero::Message> msg;
61419   Serialize(msg.get());
61420   return msg.SerializeAsArray();
61421 }
61422 
Serialize(::protozero::Message * msg) const61423 void GetAsyncCommandResponse_StopDataSource::Serialize(::protozero::Message* msg) const {
61424   // Field 1: instance_id
61425   if (_has_field_[1]) {
61426     msg->AppendVarInt(1, instance_id_);
61427   }
61428 
61429   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
61430 }
61431 
61432 
61433 GetAsyncCommandResponse_StartDataSource::GetAsyncCommandResponse_StartDataSource() = default;
61434 GetAsyncCommandResponse_StartDataSource::~GetAsyncCommandResponse_StartDataSource() = default;
61435 GetAsyncCommandResponse_StartDataSource::GetAsyncCommandResponse_StartDataSource(const GetAsyncCommandResponse_StartDataSource&) = default;
61436 GetAsyncCommandResponse_StartDataSource& GetAsyncCommandResponse_StartDataSource::operator=(const GetAsyncCommandResponse_StartDataSource&) = default;
61437 GetAsyncCommandResponse_StartDataSource::GetAsyncCommandResponse_StartDataSource(GetAsyncCommandResponse_StartDataSource&&) noexcept = default;
61438 GetAsyncCommandResponse_StartDataSource& GetAsyncCommandResponse_StartDataSource::operator=(GetAsyncCommandResponse_StartDataSource&&) = default;
61439 
operator ==(const GetAsyncCommandResponse_StartDataSource & other) const61440 bool GetAsyncCommandResponse_StartDataSource::operator==(const GetAsyncCommandResponse_StartDataSource& other) const {
61441   return unknown_fields_ == other.unknown_fields_
61442    && new_instance_id_ == other.new_instance_id_
61443    && config_ == other.config_;
61444 }
61445 
ParseFromArray(const void * raw,size_t size)61446 bool GetAsyncCommandResponse_StartDataSource::ParseFromArray(const void* raw, size_t size) {
61447   unknown_fields_.clear();
61448   bool packed_error = false;
61449 
61450   ::protozero::ProtoDecoder dec(raw, size);
61451   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
61452     if (field.id() < _has_field_.size()) {
61453       _has_field_.set(field.id());
61454     }
61455     switch (field.id()) {
61456       case 1 /* new_instance_id */:
61457         field.get(&new_instance_id_);
61458         break;
61459       case 2 /* config */:
61460         (*config_).ParseFromArray(field.data(), field.size());
61461         break;
61462       default:
61463         field.SerializeAndAppendTo(&unknown_fields_);
61464         break;
61465     }
61466   }
61467   return !packed_error && !dec.bytes_left();
61468 }
61469 
SerializeAsString() const61470 std::string GetAsyncCommandResponse_StartDataSource::SerializeAsString() const {
61471   ::protozero::HeapBuffered<::protozero::Message> msg;
61472   Serialize(msg.get());
61473   return msg.SerializeAsString();
61474 }
61475 
SerializeAsArray() const61476 std::vector<uint8_t> GetAsyncCommandResponse_StartDataSource::SerializeAsArray() const {
61477   ::protozero::HeapBuffered<::protozero::Message> msg;
61478   Serialize(msg.get());
61479   return msg.SerializeAsArray();
61480 }
61481 
Serialize(::protozero::Message * msg) const61482 void GetAsyncCommandResponse_StartDataSource::Serialize(::protozero::Message* msg) const {
61483   // Field 1: new_instance_id
61484   if (_has_field_[1]) {
61485     msg->AppendVarInt(1, new_instance_id_);
61486   }
61487 
61488   // Field 2: config
61489   if (_has_field_[2]) {
61490     (*config_).Serialize(msg->BeginNestedMessage<::protozero::Message>(2));
61491   }
61492 
61493   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
61494 }
61495 
61496 
61497 GetAsyncCommandResponse_SetupDataSource::GetAsyncCommandResponse_SetupDataSource() = default;
61498 GetAsyncCommandResponse_SetupDataSource::~GetAsyncCommandResponse_SetupDataSource() = default;
61499 GetAsyncCommandResponse_SetupDataSource::GetAsyncCommandResponse_SetupDataSource(const GetAsyncCommandResponse_SetupDataSource&) = default;
61500 GetAsyncCommandResponse_SetupDataSource& GetAsyncCommandResponse_SetupDataSource::operator=(const GetAsyncCommandResponse_SetupDataSource&) = default;
61501 GetAsyncCommandResponse_SetupDataSource::GetAsyncCommandResponse_SetupDataSource(GetAsyncCommandResponse_SetupDataSource&&) noexcept = default;
61502 GetAsyncCommandResponse_SetupDataSource& GetAsyncCommandResponse_SetupDataSource::operator=(GetAsyncCommandResponse_SetupDataSource&&) = default;
61503 
operator ==(const GetAsyncCommandResponse_SetupDataSource & other) const61504 bool GetAsyncCommandResponse_SetupDataSource::operator==(const GetAsyncCommandResponse_SetupDataSource& other) const {
61505   return unknown_fields_ == other.unknown_fields_
61506    && new_instance_id_ == other.new_instance_id_
61507    && config_ == other.config_;
61508 }
61509 
ParseFromArray(const void * raw,size_t size)61510 bool GetAsyncCommandResponse_SetupDataSource::ParseFromArray(const void* raw, size_t size) {
61511   unknown_fields_.clear();
61512   bool packed_error = false;
61513 
61514   ::protozero::ProtoDecoder dec(raw, size);
61515   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
61516     if (field.id() < _has_field_.size()) {
61517       _has_field_.set(field.id());
61518     }
61519     switch (field.id()) {
61520       case 1 /* new_instance_id */:
61521         field.get(&new_instance_id_);
61522         break;
61523       case 2 /* config */:
61524         (*config_).ParseFromArray(field.data(), field.size());
61525         break;
61526       default:
61527         field.SerializeAndAppendTo(&unknown_fields_);
61528         break;
61529     }
61530   }
61531   return !packed_error && !dec.bytes_left();
61532 }
61533 
SerializeAsString() const61534 std::string GetAsyncCommandResponse_SetupDataSource::SerializeAsString() const {
61535   ::protozero::HeapBuffered<::protozero::Message> msg;
61536   Serialize(msg.get());
61537   return msg.SerializeAsString();
61538 }
61539 
SerializeAsArray() const61540 std::vector<uint8_t> GetAsyncCommandResponse_SetupDataSource::SerializeAsArray() const {
61541   ::protozero::HeapBuffered<::protozero::Message> msg;
61542   Serialize(msg.get());
61543   return msg.SerializeAsArray();
61544 }
61545 
Serialize(::protozero::Message * msg) const61546 void GetAsyncCommandResponse_SetupDataSource::Serialize(::protozero::Message* msg) const {
61547   // Field 1: new_instance_id
61548   if (_has_field_[1]) {
61549     msg->AppendVarInt(1, new_instance_id_);
61550   }
61551 
61552   // Field 2: config
61553   if (_has_field_[2]) {
61554     (*config_).Serialize(msg->BeginNestedMessage<::protozero::Message>(2));
61555   }
61556 
61557   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
61558 }
61559 
61560 
61561 GetAsyncCommandResponse_SetupTracing::GetAsyncCommandResponse_SetupTracing() = default;
61562 GetAsyncCommandResponse_SetupTracing::~GetAsyncCommandResponse_SetupTracing() = default;
61563 GetAsyncCommandResponse_SetupTracing::GetAsyncCommandResponse_SetupTracing(const GetAsyncCommandResponse_SetupTracing&) = default;
61564 GetAsyncCommandResponse_SetupTracing& GetAsyncCommandResponse_SetupTracing::operator=(const GetAsyncCommandResponse_SetupTracing&) = default;
61565 GetAsyncCommandResponse_SetupTracing::GetAsyncCommandResponse_SetupTracing(GetAsyncCommandResponse_SetupTracing&&) noexcept = default;
61566 GetAsyncCommandResponse_SetupTracing& GetAsyncCommandResponse_SetupTracing::operator=(GetAsyncCommandResponse_SetupTracing&&) = default;
61567 
operator ==(const GetAsyncCommandResponse_SetupTracing & other) const61568 bool GetAsyncCommandResponse_SetupTracing::operator==(const GetAsyncCommandResponse_SetupTracing& other) const {
61569   return unknown_fields_ == other.unknown_fields_
61570    && shared_buffer_page_size_kb_ == other.shared_buffer_page_size_kb_
61571    && shm_key_windows_ == other.shm_key_windows_;
61572 }
61573 
ParseFromArray(const void * raw,size_t size)61574 bool GetAsyncCommandResponse_SetupTracing::ParseFromArray(const void* raw, size_t size) {
61575   unknown_fields_.clear();
61576   bool packed_error = false;
61577 
61578   ::protozero::ProtoDecoder dec(raw, size);
61579   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
61580     if (field.id() < _has_field_.size()) {
61581       _has_field_.set(field.id());
61582     }
61583     switch (field.id()) {
61584       case 1 /* shared_buffer_page_size_kb */:
61585         field.get(&shared_buffer_page_size_kb_);
61586         break;
61587       case 2 /* shm_key_windows */:
61588         field.get(&shm_key_windows_);
61589         break;
61590       default:
61591         field.SerializeAndAppendTo(&unknown_fields_);
61592         break;
61593     }
61594   }
61595   return !packed_error && !dec.bytes_left();
61596 }
61597 
SerializeAsString() const61598 std::string GetAsyncCommandResponse_SetupTracing::SerializeAsString() const {
61599   ::protozero::HeapBuffered<::protozero::Message> msg;
61600   Serialize(msg.get());
61601   return msg.SerializeAsString();
61602 }
61603 
SerializeAsArray() const61604 std::vector<uint8_t> GetAsyncCommandResponse_SetupTracing::SerializeAsArray() const {
61605   ::protozero::HeapBuffered<::protozero::Message> msg;
61606   Serialize(msg.get());
61607   return msg.SerializeAsArray();
61608 }
61609 
Serialize(::protozero::Message * msg) const61610 void GetAsyncCommandResponse_SetupTracing::Serialize(::protozero::Message* msg) const {
61611   // Field 1: shared_buffer_page_size_kb
61612   if (_has_field_[1]) {
61613     msg->AppendVarInt(1, shared_buffer_page_size_kb_);
61614   }
61615 
61616   // Field 2: shm_key_windows
61617   if (_has_field_[2]) {
61618     msg->AppendString(2, shm_key_windows_);
61619   }
61620 
61621   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
61622 }
61623 
61624 
61625 GetAsyncCommandRequest::GetAsyncCommandRequest() = default;
61626 GetAsyncCommandRequest::~GetAsyncCommandRequest() = default;
61627 GetAsyncCommandRequest::GetAsyncCommandRequest(const GetAsyncCommandRequest&) = default;
61628 GetAsyncCommandRequest& GetAsyncCommandRequest::operator=(const GetAsyncCommandRequest&) = default;
61629 GetAsyncCommandRequest::GetAsyncCommandRequest(GetAsyncCommandRequest&&) noexcept = default;
61630 GetAsyncCommandRequest& GetAsyncCommandRequest::operator=(GetAsyncCommandRequest&&) = default;
61631 
operator ==(const GetAsyncCommandRequest & other) const61632 bool GetAsyncCommandRequest::operator==(const GetAsyncCommandRequest& other) const {
61633   return unknown_fields_ == other.unknown_fields_;
61634 }
61635 
ParseFromArray(const void * raw,size_t size)61636 bool GetAsyncCommandRequest::ParseFromArray(const void* raw, size_t size) {
61637   unknown_fields_.clear();
61638   bool packed_error = false;
61639 
61640   ::protozero::ProtoDecoder dec(raw, size);
61641   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
61642     if (field.id() < _has_field_.size()) {
61643       _has_field_.set(field.id());
61644     }
61645     switch (field.id()) {
61646       default:
61647         field.SerializeAndAppendTo(&unknown_fields_);
61648         break;
61649     }
61650   }
61651   return !packed_error && !dec.bytes_left();
61652 }
61653 
SerializeAsString() const61654 std::string GetAsyncCommandRequest::SerializeAsString() const {
61655   ::protozero::HeapBuffered<::protozero::Message> msg;
61656   Serialize(msg.get());
61657   return msg.SerializeAsString();
61658 }
61659 
SerializeAsArray() const61660 std::vector<uint8_t> GetAsyncCommandRequest::SerializeAsArray() const {
61661   ::protozero::HeapBuffered<::protozero::Message> msg;
61662   Serialize(msg.get());
61663   return msg.SerializeAsArray();
61664 }
61665 
Serialize(::protozero::Message * msg) const61666 void GetAsyncCommandRequest::Serialize(::protozero::Message* msg) const {
61667   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
61668 }
61669 
61670 
61671 ActivateTriggersResponse::ActivateTriggersResponse() = default;
61672 ActivateTriggersResponse::~ActivateTriggersResponse() = default;
61673 ActivateTriggersResponse::ActivateTriggersResponse(const ActivateTriggersResponse&) = default;
61674 ActivateTriggersResponse& ActivateTriggersResponse::operator=(const ActivateTriggersResponse&) = default;
61675 ActivateTriggersResponse::ActivateTriggersResponse(ActivateTriggersResponse&&) noexcept = default;
61676 ActivateTriggersResponse& ActivateTriggersResponse::operator=(ActivateTriggersResponse&&) = default;
61677 
operator ==(const ActivateTriggersResponse & other) const61678 bool ActivateTriggersResponse::operator==(const ActivateTriggersResponse& other) const {
61679   return unknown_fields_ == other.unknown_fields_;
61680 }
61681 
ParseFromArray(const void * raw,size_t size)61682 bool ActivateTriggersResponse::ParseFromArray(const void* raw, size_t size) {
61683   unknown_fields_.clear();
61684   bool packed_error = false;
61685 
61686   ::protozero::ProtoDecoder dec(raw, size);
61687   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
61688     if (field.id() < _has_field_.size()) {
61689       _has_field_.set(field.id());
61690     }
61691     switch (field.id()) {
61692       default:
61693         field.SerializeAndAppendTo(&unknown_fields_);
61694         break;
61695     }
61696   }
61697   return !packed_error && !dec.bytes_left();
61698 }
61699 
SerializeAsString() const61700 std::string ActivateTriggersResponse::SerializeAsString() const {
61701   ::protozero::HeapBuffered<::protozero::Message> msg;
61702   Serialize(msg.get());
61703   return msg.SerializeAsString();
61704 }
61705 
SerializeAsArray() const61706 std::vector<uint8_t> ActivateTriggersResponse::SerializeAsArray() const {
61707   ::protozero::HeapBuffered<::protozero::Message> msg;
61708   Serialize(msg.get());
61709   return msg.SerializeAsArray();
61710 }
61711 
Serialize(::protozero::Message * msg) const61712 void ActivateTriggersResponse::Serialize(::protozero::Message* msg) const {
61713   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
61714 }
61715 
61716 
61717 ActivateTriggersRequest::ActivateTriggersRequest() = default;
61718 ActivateTriggersRequest::~ActivateTriggersRequest() = default;
61719 ActivateTriggersRequest::ActivateTriggersRequest(const ActivateTriggersRequest&) = default;
61720 ActivateTriggersRequest& ActivateTriggersRequest::operator=(const ActivateTriggersRequest&) = default;
61721 ActivateTriggersRequest::ActivateTriggersRequest(ActivateTriggersRequest&&) noexcept = default;
61722 ActivateTriggersRequest& ActivateTriggersRequest::operator=(ActivateTriggersRequest&&) = default;
61723 
operator ==(const ActivateTriggersRequest & other) const61724 bool ActivateTriggersRequest::operator==(const ActivateTriggersRequest& other) const {
61725   return unknown_fields_ == other.unknown_fields_
61726    && trigger_names_ == other.trigger_names_;
61727 }
61728 
ParseFromArray(const void * raw,size_t size)61729 bool ActivateTriggersRequest::ParseFromArray(const void* raw, size_t size) {
61730   trigger_names_.clear();
61731   unknown_fields_.clear();
61732   bool packed_error = false;
61733 
61734   ::protozero::ProtoDecoder dec(raw, size);
61735   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
61736     if (field.id() < _has_field_.size()) {
61737       _has_field_.set(field.id());
61738     }
61739     switch (field.id()) {
61740       case 1 /* trigger_names */:
61741         trigger_names_.emplace_back();
61742         field.get(&trigger_names_.back());
61743         break;
61744       default:
61745         field.SerializeAndAppendTo(&unknown_fields_);
61746         break;
61747     }
61748   }
61749   return !packed_error && !dec.bytes_left();
61750 }
61751 
SerializeAsString() const61752 std::string ActivateTriggersRequest::SerializeAsString() const {
61753   ::protozero::HeapBuffered<::protozero::Message> msg;
61754   Serialize(msg.get());
61755   return msg.SerializeAsString();
61756 }
61757 
SerializeAsArray() const61758 std::vector<uint8_t> ActivateTriggersRequest::SerializeAsArray() const {
61759   ::protozero::HeapBuffered<::protozero::Message> msg;
61760   Serialize(msg.get());
61761   return msg.SerializeAsArray();
61762 }
61763 
Serialize(::protozero::Message * msg) const61764 void ActivateTriggersRequest::Serialize(::protozero::Message* msg) const {
61765   // Field 1: trigger_names
61766   for (auto& it : trigger_names_) {
61767     msg->AppendString(1, it);
61768   }
61769 
61770   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
61771 }
61772 
61773 
61774 NotifyDataSourceStoppedResponse::NotifyDataSourceStoppedResponse() = default;
61775 NotifyDataSourceStoppedResponse::~NotifyDataSourceStoppedResponse() = default;
61776 NotifyDataSourceStoppedResponse::NotifyDataSourceStoppedResponse(const NotifyDataSourceStoppedResponse&) = default;
61777 NotifyDataSourceStoppedResponse& NotifyDataSourceStoppedResponse::operator=(const NotifyDataSourceStoppedResponse&) = default;
61778 NotifyDataSourceStoppedResponse::NotifyDataSourceStoppedResponse(NotifyDataSourceStoppedResponse&&) noexcept = default;
61779 NotifyDataSourceStoppedResponse& NotifyDataSourceStoppedResponse::operator=(NotifyDataSourceStoppedResponse&&) = default;
61780 
operator ==(const NotifyDataSourceStoppedResponse & other) const61781 bool NotifyDataSourceStoppedResponse::operator==(const NotifyDataSourceStoppedResponse& other) const {
61782   return unknown_fields_ == other.unknown_fields_;
61783 }
61784 
ParseFromArray(const void * raw,size_t size)61785 bool NotifyDataSourceStoppedResponse::ParseFromArray(const void* raw, size_t size) {
61786   unknown_fields_.clear();
61787   bool packed_error = false;
61788 
61789   ::protozero::ProtoDecoder dec(raw, size);
61790   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
61791     if (field.id() < _has_field_.size()) {
61792       _has_field_.set(field.id());
61793     }
61794     switch (field.id()) {
61795       default:
61796         field.SerializeAndAppendTo(&unknown_fields_);
61797         break;
61798     }
61799   }
61800   return !packed_error && !dec.bytes_left();
61801 }
61802 
SerializeAsString() const61803 std::string NotifyDataSourceStoppedResponse::SerializeAsString() const {
61804   ::protozero::HeapBuffered<::protozero::Message> msg;
61805   Serialize(msg.get());
61806   return msg.SerializeAsString();
61807 }
61808 
SerializeAsArray() const61809 std::vector<uint8_t> NotifyDataSourceStoppedResponse::SerializeAsArray() const {
61810   ::protozero::HeapBuffered<::protozero::Message> msg;
61811   Serialize(msg.get());
61812   return msg.SerializeAsArray();
61813 }
61814 
Serialize(::protozero::Message * msg) const61815 void NotifyDataSourceStoppedResponse::Serialize(::protozero::Message* msg) const {
61816   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
61817 }
61818 
61819 
61820 NotifyDataSourceStoppedRequest::NotifyDataSourceStoppedRequest() = default;
61821 NotifyDataSourceStoppedRequest::~NotifyDataSourceStoppedRequest() = default;
61822 NotifyDataSourceStoppedRequest::NotifyDataSourceStoppedRequest(const NotifyDataSourceStoppedRequest&) = default;
61823 NotifyDataSourceStoppedRequest& NotifyDataSourceStoppedRequest::operator=(const NotifyDataSourceStoppedRequest&) = default;
61824 NotifyDataSourceStoppedRequest::NotifyDataSourceStoppedRequest(NotifyDataSourceStoppedRequest&&) noexcept = default;
61825 NotifyDataSourceStoppedRequest& NotifyDataSourceStoppedRequest::operator=(NotifyDataSourceStoppedRequest&&) = default;
61826 
operator ==(const NotifyDataSourceStoppedRequest & other) const61827 bool NotifyDataSourceStoppedRequest::operator==(const NotifyDataSourceStoppedRequest& other) const {
61828   return unknown_fields_ == other.unknown_fields_
61829    && data_source_id_ == other.data_source_id_;
61830 }
61831 
ParseFromArray(const void * raw,size_t size)61832 bool NotifyDataSourceStoppedRequest::ParseFromArray(const void* raw, size_t size) {
61833   unknown_fields_.clear();
61834   bool packed_error = false;
61835 
61836   ::protozero::ProtoDecoder dec(raw, size);
61837   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
61838     if (field.id() < _has_field_.size()) {
61839       _has_field_.set(field.id());
61840     }
61841     switch (field.id()) {
61842       case 1 /* data_source_id */:
61843         field.get(&data_source_id_);
61844         break;
61845       default:
61846         field.SerializeAndAppendTo(&unknown_fields_);
61847         break;
61848     }
61849   }
61850   return !packed_error && !dec.bytes_left();
61851 }
61852 
SerializeAsString() const61853 std::string NotifyDataSourceStoppedRequest::SerializeAsString() const {
61854   ::protozero::HeapBuffered<::protozero::Message> msg;
61855   Serialize(msg.get());
61856   return msg.SerializeAsString();
61857 }
61858 
SerializeAsArray() const61859 std::vector<uint8_t> NotifyDataSourceStoppedRequest::SerializeAsArray() const {
61860   ::protozero::HeapBuffered<::protozero::Message> msg;
61861   Serialize(msg.get());
61862   return msg.SerializeAsArray();
61863 }
61864 
Serialize(::protozero::Message * msg) const61865 void NotifyDataSourceStoppedRequest::Serialize(::protozero::Message* msg) const {
61866   // Field 1: data_source_id
61867   if (_has_field_[1]) {
61868     msg->AppendVarInt(1, data_source_id_);
61869   }
61870 
61871   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
61872 }
61873 
61874 
61875 NotifyDataSourceStartedResponse::NotifyDataSourceStartedResponse() = default;
61876 NotifyDataSourceStartedResponse::~NotifyDataSourceStartedResponse() = default;
61877 NotifyDataSourceStartedResponse::NotifyDataSourceStartedResponse(const NotifyDataSourceStartedResponse&) = default;
61878 NotifyDataSourceStartedResponse& NotifyDataSourceStartedResponse::operator=(const NotifyDataSourceStartedResponse&) = default;
61879 NotifyDataSourceStartedResponse::NotifyDataSourceStartedResponse(NotifyDataSourceStartedResponse&&) noexcept = default;
61880 NotifyDataSourceStartedResponse& NotifyDataSourceStartedResponse::operator=(NotifyDataSourceStartedResponse&&) = default;
61881 
operator ==(const NotifyDataSourceStartedResponse & other) const61882 bool NotifyDataSourceStartedResponse::operator==(const NotifyDataSourceStartedResponse& other) const {
61883   return unknown_fields_ == other.unknown_fields_;
61884 }
61885 
ParseFromArray(const void * raw,size_t size)61886 bool NotifyDataSourceStartedResponse::ParseFromArray(const void* raw, size_t size) {
61887   unknown_fields_.clear();
61888   bool packed_error = false;
61889 
61890   ::protozero::ProtoDecoder dec(raw, size);
61891   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
61892     if (field.id() < _has_field_.size()) {
61893       _has_field_.set(field.id());
61894     }
61895     switch (field.id()) {
61896       default:
61897         field.SerializeAndAppendTo(&unknown_fields_);
61898         break;
61899     }
61900   }
61901   return !packed_error && !dec.bytes_left();
61902 }
61903 
SerializeAsString() const61904 std::string NotifyDataSourceStartedResponse::SerializeAsString() const {
61905   ::protozero::HeapBuffered<::protozero::Message> msg;
61906   Serialize(msg.get());
61907   return msg.SerializeAsString();
61908 }
61909 
SerializeAsArray() const61910 std::vector<uint8_t> NotifyDataSourceStartedResponse::SerializeAsArray() const {
61911   ::protozero::HeapBuffered<::protozero::Message> msg;
61912   Serialize(msg.get());
61913   return msg.SerializeAsArray();
61914 }
61915 
Serialize(::protozero::Message * msg) const61916 void NotifyDataSourceStartedResponse::Serialize(::protozero::Message* msg) const {
61917   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
61918 }
61919 
61920 
61921 NotifyDataSourceStartedRequest::NotifyDataSourceStartedRequest() = default;
61922 NotifyDataSourceStartedRequest::~NotifyDataSourceStartedRequest() = default;
61923 NotifyDataSourceStartedRequest::NotifyDataSourceStartedRequest(const NotifyDataSourceStartedRequest&) = default;
61924 NotifyDataSourceStartedRequest& NotifyDataSourceStartedRequest::operator=(const NotifyDataSourceStartedRequest&) = default;
61925 NotifyDataSourceStartedRequest::NotifyDataSourceStartedRequest(NotifyDataSourceStartedRequest&&) noexcept = default;
61926 NotifyDataSourceStartedRequest& NotifyDataSourceStartedRequest::operator=(NotifyDataSourceStartedRequest&&) = default;
61927 
operator ==(const NotifyDataSourceStartedRequest & other) const61928 bool NotifyDataSourceStartedRequest::operator==(const NotifyDataSourceStartedRequest& other) const {
61929   return unknown_fields_ == other.unknown_fields_
61930    && data_source_id_ == other.data_source_id_;
61931 }
61932 
ParseFromArray(const void * raw,size_t size)61933 bool NotifyDataSourceStartedRequest::ParseFromArray(const void* raw, size_t size) {
61934   unknown_fields_.clear();
61935   bool packed_error = false;
61936 
61937   ::protozero::ProtoDecoder dec(raw, size);
61938   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
61939     if (field.id() < _has_field_.size()) {
61940       _has_field_.set(field.id());
61941     }
61942     switch (field.id()) {
61943       case 1 /* data_source_id */:
61944         field.get(&data_source_id_);
61945         break;
61946       default:
61947         field.SerializeAndAppendTo(&unknown_fields_);
61948         break;
61949     }
61950   }
61951   return !packed_error && !dec.bytes_left();
61952 }
61953 
SerializeAsString() const61954 std::string NotifyDataSourceStartedRequest::SerializeAsString() const {
61955   ::protozero::HeapBuffered<::protozero::Message> msg;
61956   Serialize(msg.get());
61957   return msg.SerializeAsString();
61958 }
61959 
SerializeAsArray() const61960 std::vector<uint8_t> NotifyDataSourceStartedRequest::SerializeAsArray() const {
61961   ::protozero::HeapBuffered<::protozero::Message> msg;
61962   Serialize(msg.get());
61963   return msg.SerializeAsArray();
61964 }
61965 
Serialize(::protozero::Message * msg) const61966 void NotifyDataSourceStartedRequest::Serialize(::protozero::Message* msg) const {
61967   // Field 1: data_source_id
61968   if (_has_field_[1]) {
61969     msg->AppendVarInt(1, data_source_id_);
61970   }
61971 
61972   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
61973 }
61974 
61975 
61976 CommitDataResponse::CommitDataResponse() = default;
61977 CommitDataResponse::~CommitDataResponse() = default;
61978 CommitDataResponse::CommitDataResponse(const CommitDataResponse&) = default;
61979 CommitDataResponse& CommitDataResponse::operator=(const CommitDataResponse&) = default;
61980 CommitDataResponse::CommitDataResponse(CommitDataResponse&&) noexcept = default;
61981 CommitDataResponse& CommitDataResponse::operator=(CommitDataResponse&&) = default;
61982 
operator ==(const CommitDataResponse & other) const61983 bool CommitDataResponse::operator==(const CommitDataResponse& other) const {
61984   return unknown_fields_ == other.unknown_fields_;
61985 }
61986 
ParseFromArray(const void * raw,size_t size)61987 bool CommitDataResponse::ParseFromArray(const void* raw, size_t size) {
61988   unknown_fields_.clear();
61989   bool packed_error = false;
61990 
61991   ::protozero::ProtoDecoder dec(raw, size);
61992   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
61993     if (field.id() < _has_field_.size()) {
61994       _has_field_.set(field.id());
61995     }
61996     switch (field.id()) {
61997       default:
61998         field.SerializeAndAppendTo(&unknown_fields_);
61999         break;
62000     }
62001   }
62002   return !packed_error && !dec.bytes_left();
62003 }
62004 
SerializeAsString() const62005 std::string CommitDataResponse::SerializeAsString() const {
62006   ::protozero::HeapBuffered<::protozero::Message> msg;
62007   Serialize(msg.get());
62008   return msg.SerializeAsString();
62009 }
62010 
SerializeAsArray() const62011 std::vector<uint8_t> CommitDataResponse::SerializeAsArray() const {
62012   ::protozero::HeapBuffered<::protozero::Message> msg;
62013   Serialize(msg.get());
62014   return msg.SerializeAsArray();
62015 }
62016 
Serialize(::protozero::Message * msg) const62017 void CommitDataResponse::Serialize(::protozero::Message* msg) const {
62018   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
62019 }
62020 
62021 
62022 UnregisterTraceWriterResponse::UnregisterTraceWriterResponse() = default;
62023 UnregisterTraceWriterResponse::~UnregisterTraceWriterResponse() = default;
62024 UnregisterTraceWriterResponse::UnregisterTraceWriterResponse(const UnregisterTraceWriterResponse&) = default;
62025 UnregisterTraceWriterResponse& UnregisterTraceWriterResponse::operator=(const UnregisterTraceWriterResponse&) = default;
62026 UnregisterTraceWriterResponse::UnregisterTraceWriterResponse(UnregisterTraceWriterResponse&&) noexcept = default;
62027 UnregisterTraceWriterResponse& UnregisterTraceWriterResponse::operator=(UnregisterTraceWriterResponse&&) = default;
62028 
operator ==(const UnregisterTraceWriterResponse & other) const62029 bool UnregisterTraceWriterResponse::operator==(const UnregisterTraceWriterResponse& other) const {
62030   return unknown_fields_ == other.unknown_fields_;
62031 }
62032 
ParseFromArray(const void * raw,size_t size)62033 bool UnregisterTraceWriterResponse::ParseFromArray(const void* raw, size_t size) {
62034   unknown_fields_.clear();
62035   bool packed_error = false;
62036 
62037   ::protozero::ProtoDecoder dec(raw, size);
62038   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
62039     if (field.id() < _has_field_.size()) {
62040       _has_field_.set(field.id());
62041     }
62042     switch (field.id()) {
62043       default:
62044         field.SerializeAndAppendTo(&unknown_fields_);
62045         break;
62046     }
62047   }
62048   return !packed_error && !dec.bytes_left();
62049 }
62050 
SerializeAsString() const62051 std::string UnregisterTraceWriterResponse::SerializeAsString() const {
62052   ::protozero::HeapBuffered<::protozero::Message> msg;
62053   Serialize(msg.get());
62054   return msg.SerializeAsString();
62055 }
62056 
SerializeAsArray() const62057 std::vector<uint8_t> UnregisterTraceWriterResponse::SerializeAsArray() const {
62058   ::protozero::HeapBuffered<::protozero::Message> msg;
62059   Serialize(msg.get());
62060   return msg.SerializeAsArray();
62061 }
62062 
Serialize(::protozero::Message * msg) const62063 void UnregisterTraceWriterResponse::Serialize(::protozero::Message* msg) const {
62064   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
62065 }
62066 
62067 
62068 UnregisterTraceWriterRequest::UnregisterTraceWriterRequest() = default;
62069 UnregisterTraceWriterRequest::~UnregisterTraceWriterRequest() = default;
62070 UnregisterTraceWriterRequest::UnregisterTraceWriterRequest(const UnregisterTraceWriterRequest&) = default;
62071 UnregisterTraceWriterRequest& UnregisterTraceWriterRequest::operator=(const UnregisterTraceWriterRequest&) = default;
62072 UnregisterTraceWriterRequest::UnregisterTraceWriterRequest(UnregisterTraceWriterRequest&&) noexcept = default;
62073 UnregisterTraceWriterRequest& UnregisterTraceWriterRequest::operator=(UnregisterTraceWriterRequest&&) = default;
62074 
operator ==(const UnregisterTraceWriterRequest & other) const62075 bool UnregisterTraceWriterRequest::operator==(const UnregisterTraceWriterRequest& other) const {
62076   return unknown_fields_ == other.unknown_fields_
62077    && trace_writer_id_ == other.trace_writer_id_;
62078 }
62079 
ParseFromArray(const void * raw,size_t size)62080 bool UnregisterTraceWriterRequest::ParseFromArray(const void* raw, size_t size) {
62081   unknown_fields_.clear();
62082   bool packed_error = false;
62083 
62084   ::protozero::ProtoDecoder dec(raw, size);
62085   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
62086     if (field.id() < _has_field_.size()) {
62087       _has_field_.set(field.id());
62088     }
62089     switch (field.id()) {
62090       case 1 /* trace_writer_id */:
62091         field.get(&trace_writer_id_);
62092         break;
62093       default:
62094         field.SerializeAndAppendTo(&unknown_fields_);
62095         break;
62096     }
62097   }
62098   return !packed_error && !dec.bytes_left();
62099 }
62100 
SerializeAsString() const62101 std::string UnregisterTraceWriterRequest::SerializeAsString() const {
62102   ::protozero::HeapBuffered<::protozero::Message> msg;
62103   Serialize(msg.get());
62104   return msg.SerializeAsString();
62105 }
62106 
SerializeAsArray() const62107 std::vector<uint8_t> UnregisterTraceWriterRequest::SerializeAsArray() const {
62108   ::protozero::HeapBuffered<::protozero::Message> msg;
62109   Serialize(msg.get());
62110   return msg.SerializeAsArray();
62111 }
62112 
Serialize(::protozero::Message * msg) const62113 void UnregisterTraceWriterRequest::Serialize(::protozero::Message* msg) const {
62114   // Field 1: trace_writer_id
62115   if (_has_field_[1]) {
62116     msg->AppendVarInt(1, trace_writer_id_);
62117   }
62118 
62119   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
62120 }
62121 
62122 
62123 RegisterTraceWriterResponse::RegisterTraceWriterResponse() = default;
62124 RegisterTraceWriterResponse::~RegisterTraceWriterResponse() = default;
62125 RegisterTraceWriterResponse::RegisterTraceWriterResponse(const RegisterTraceWriterResponse&) = default;
62126 RegisterTraceWriterResponse& RegisterTraceWriterResponse::operator=(const RegisterTraceWriterResponse&) = default;
62127 RegisterTraceWriterResponse::RegisterTraceWriterResponse(RegisterTraceWriterResponse&&) noexcept = default;
62128 RegisterTraceWriterResponse& RegisterTraceWriterResponse::operator=(RegisterTraceWriterResponse&&) = default;
62129 
operator ==(const RegisterTraceWriterResponse & other) const62130 bool RegisterTraceWriterResponse::operator==(const RegisterTraceWriterResponse& other) const {
62131   return unknown_fields_ == other.unknown_fields_;
62132 }
62133 
ParseFromArray(const void * raw,size_t size)62134 bool RegisterTraceWriterResponse::ParseFromArray(const void* raw, size_t size) {
62135   unknown_fields_.clear();
62136   bool packed_error = false;
62137 
62138   ::protozero::ProtoDecoder dec(raw, size);
62139   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
62140     if (field.id() < _has_field_.size()) {
62141       _has_field_.set(field.id());
62142     }
62143     switch (field.id()) {
62144       default:
62145         field.SerializeAndAppendTo(&unknown_fields_);
62146         break;
62147     }
62148   }
62149   return !packed_error && !dec.bytes_left();
62150 }
62151 
SerializeAsString() const62152 std::string RegisterTraceWriterResponse::SerializeAsString() const {
62153   ::protozero::HeapBuffered<::protozero::Message> msg;
62154   Serialize(msg.get());
62155   return msg.SerializeAsString();
62156 }
62157 
SerializeAsArray() const62158 std::vector<uint8_t> RegisterTraceWriterResponse::SerializeAsArray() const {
62159   ::protozero::HeapBuffered<::protozero::Message> msg;
62160   Serialize(msg.get());
62161   return msg.SerializeAsArray();
62162 }
62163 
Serialize(::protozero::Message * msg) const62164 void RegisterTraceWriterResponse::Serialize(::protozero::Message* msg) const {
62165   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
62166 }
62167 
62168 
62169 RegisterTraceWriterRequest::RegisterTraceWriterRequest() = default;
62170 RegisterTraceWriterRequest::~RegisterTraceWriterRequest() = default;
62171 RegisterTraceWriterRequest::RegisterTraceWriterRequest(const RegisterTraceWriterRequest&) = default;
62172 RegisterTraceWriterRequest& RegisterTraceWriterRequest::operator=(const RegisterTraceWriterRequest&) = default;
62173 RegisterTraceWriterRequest::RegisterTraceWriterRequest(RegisterTraceWriterRequest&&) noexcept = default;
62174 RegisterTraceWriterRequest& RegisterTraceWriterRequest::operator=(RegisterTraceWriterRequest&&) = default;
62175 
operator ==(const RegisterTraceWriterRequest & other) const62176 bool RegisterTraceWriterRequest::operator==(const RegisterTraceWriterRequest& other) const {
62177   return unknown_fields_ == other.unknown_fields_
62178    && trace_writer_id_ == other.trace_writer_id_
62179    && target_buffer_ == other.target_buffer_;
62180 }
62181 
ParseFromArray(const void * raw,size_t size)62182 bool RegisterTraceWriterRequest::ParseFromArray(const void* raw, size_t size) {
62183   unknown_fields_.clear();
62184   bool packed_error = false;
62185 
62186   ::protozero::ProtoDecoder dec(raw, size);
62187   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
62188     if (field.id() < _has_field_.size()) {
62189       _has_field_.set(field.id());
62190     }
62191     switch (field.id()) {
62192       case 1 /* trace_writer_id */:
62193         field.get(&trace_writer_id_);
62194         break;
62195       case 2 /* target_buffer */:
62196         field.get(&target_buffer_);
62197         break;
62198       default:
62199         field.SerializeAndAppendTo(&unknown_fields_);
62200         break;
62201     }
62202   }
62203   return !packed_error && !dec.bytes_left();
62204 }
62205 
SerializeAsString() const62206 std::string RegisterTraceWriterRequest::SerializeAsString() const {
62207   ::protozero::HeapBuffered<::protozero::Message> msg;
62208   Serialize(msg.get());
62209   return msg.SerializeAsString();
62210 }
62211 
SerializeAsArray() const62212 std::vector<uint8_t> RegisterTraceWriterRequest::SerializeAsArray() const {
62213   ::protozero::HeapBuffered<::protozero::Message> msg;
62214   Serialize(msg.get());
62215   return msg.SerializeAsArray();
62216 }
62217 
Serialize(::protozero::Message * msg) const62218 void RegisterTraceWriterRequest::Serialize(::protozero::Message* msg) const {
62219   // Field 1: trace_writer_id
62220   if (_has_field_[1]) {
62221     msg->AppendVarInt(1, trace_writer_id_);
62222   }
62223 
62224   // Field 2: target_buffer
62225   if (_has_field_[2]) {
62226     msg->AppendVarInt(2, target_buffer_);
62227   }
62228 
62229   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
62230 }
62231 
62232 
62233 UnregisterDataSourceResponse::UnregisterDataSourceResponse() = default;
62234 UnregisterDataSourceResponse::~UnregisterDataSourceResponse() = default;
62235 UnregisterDataSourceResponse::UnregisterDataSourceResponse(const UnregisterDataSourceResponse&) = default;
62236 UnregisterDataSourceResponse& UnregisterDataSourceResponse::operator=(const UnregisterDataSourceResponse&) = default;
62237 UnregisterDataSourceResponse::UnregisterDataSourceResponse(UnregisterDataSourceResponse&&) noexcept = default;
62238 UnregisterDataSourceResponse& UnregisterDataSourceResponse::operator=(UnregisterDataSourceResponse&&) = default;
62239 
operator ==(const UnregisterDataSourceResponse & other) const62240 bool UnregisterDataSourceResponse::operator==(const UnregisterDataSourceResponse& other) const {
62241   return unknown_fields_ == other.unknown_fields_;
62242 }
62243 
ParseFromArray(const void * raw,size_t size)62244 bool UnregisterDataSourceResponse::ParseFromArray(const void* raw, size_t size) {
62245   unknown_fields_.clear();
62246   bool packed_error = false;
62247 
62248   ::protozero::ProtoDecoder dec(raw, size);
62249   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
62250     if (field.id() < _has_field_.size()) {
62251       _has_field_.set(field.id());
62252     }
62253     switch (field.id()) {
62254       default:
62255         field.SerializeAndAppendTo(&unknown_fields_);
62256         break;
62257     }
62258   }
62259   return !packed_error && !dec.bytes_left();
62260 }
62261 
SerializeAsString() const62262 std::string UnregisterDataSourceResponse::SerializeAsString() const {
62263   ::protozero::HeapBuffered<::protozero::Message> msg;
62264   Serialize(msg.get());
62265   return msg.SerializeAsString();
62266 }
62267 
SerializeAsArray() const62268 std::vector<uint8_t> UnregisterDataSourceResponse::SerializeAsArray() const {
62269   ::protozero::HeapBuffered<::protozero::Message> msg;
62270   Serialize(msg.get());
62271   return msg.SerializeAsArray();
62272 }
62273 
Serialize(::protozero::Message * msg) const62274 void UnregisterDataSourceResponse::Serialize(::protozero::Message* msg) const {
62275   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
62276 }
62277 
62278 
62279 UnregisterDataSourceRequest::UnregisterDataSourceRequest() = default;
62280 UnregisterDataSourceRequest::~UnregisterDataSourceRequest() = default;
62281 UnregisterDataSourceRequest::UnregisterDataSourceRequest(const UnregisterDataSourceRequest&) = default;
62282 UnregisterDataSourceRequest& UnregisterDataSourceRequest::operator=(const UnregisterDataSourceRequest&) = default;
62283 UnregisterDataSourceRequest::UnregisterDataSourceRequest(UnregisterDataSourceRequest&&) noexcept = default;
62284 UnregisterDataSourceRequest& UnregisterDataSourceRequest::operator=(UnregisterDataSourceRequest&&) = default;
62285 
operator ==(const UnregisterDataSourceRequest & other) const62286 bool UnregisterDataSourceRequest::operator==(const UnregisterDataSourceRequest& other) const {
62287   return unknown_fields_ == other.unknown_fields_
62288    && data_source_name_ == other.data_source_name_;
62289 }
62290 
ParseFromArray(const void * raw,size_t size)62291 bool UnregisterDataSourceRequest::ParseFromArray(const void* raw, size_t size) {
62292   unknown_fields_.clear();
62293   bool packed_error = false;
62294 
62295   ::protozero::ProtoDecoder dec(raw, size);
62296   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
62297     if (field.id() < _has_field_.size()) {
62298       _has_field_.set(field.id());
62299     }
62300     switch (field.id()) {
62301       case 1 /* data_source_name */:
62302         field.get(&data_source_name_);
62303         break;
62304       default:
62305         field.SerializeAndAppendTo(&unknown_fields_);
62306         break;
62307     }
62308   }
62309   return !packed_error && !dec.bytes_left();
62310 }
62311 
SerializeAsString() const62312 std::string UnregisterDataSourceRequest::SerializeAsString() const {
62313   ::protozero::HeapBuffered<::protozero::Message> msg;
62314   Serialize(msg.get());
62315   return msg.SerializeAsString();
62316 }
62317 
SerializeAsArray() const62318 std::vector<uint8_t> UnregisterDataSourceRequest::SerializeAsArray() const {
62319   ::protozero::HeapBuffered<::protozero::Message> msg;
62320   Serialize(msg.get());
62321   return msg.SerializeAsArray();
62322 }
62323 
Serialize(::protozero::Message * msg) const62324 void UnregisterDataSourceRequest::Serialize(::protozero::Message* msg) const {
62325   // Field 1: data_source_name
62326   if (_has_field_[1]) {
62327     msg->AppendString(1, data_source_name_);
62328   }
62329 
62330   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
62331 }
62332 
62333 
62334 UpdateDataSourceResponse::UpdateDataSourceResponse() = default;
62335 UpdateDataSourceResponse::~UpdateDataSourceResponse() = default;
62336 UpdateDataSourceResponse::UpdateDataSourceResponse(const UpdateDataSourceResponse&) = default;
62337 UpdateDataSourceResponse& UpdateDataSourceResponse::operator=(const UpdateDataSourceResponse&) = default;
62338 UpdateDataSourceResponse::UpdateDataSourceResponse(UpdateDataSourceResponse&&) noexcept = default;
62339 UpdateDataSourceResponse& UpdateDataSourceResponse::operator=(UpdateDataSourceResponse&&) = default;
62340 
operator ==(const UpdateDataSourceResponse & other) const62341 bool UpdateDataSourceResponse::operator==(const UpdateDataSourceResponse& other) const {
62342   return unknown_fields_ == other.unknown_fields_;
62343 }
62344 
ParseFromArray(const void * raw,size_t size)62345 bool UpdateDataSourceResponse::ParseFromArray(const void* raw, size_t size) {
62346   unknown_fields_.clear();
62347   bool packed_error = false;
62348 
62349   ::protozero::ProtoDecoder dec(raw, size);
62350   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
62351     if (field.id() < _has_field_.size()) {
62352       _has_field_.set(field.id());
62353     }
62354     switch (field.id()) {
62355       default:
62356         field.SerializeAndAppendTo(&unknown_fields_);
62357         break;
62358     }
62359   }
62360   return !packed_error && !dec.bytes_left();
62361 }
62362 
SerializeAsString() const62363 std::string UpdateDataSourceResponse::SerializeAsString() const {
62364   ::protozero::HeapBuffered<::protozero::Message> msg;
62365   Serialize(msg.get());
62366   return msg.SerializeAsString();
62367 }
62368 
SerializeAsArray() const62369 std::vector<uint8_t> UpdateDataSourceResponse::SerializeAsArray() const {
62370   ::protozero::HeapBuffered<::protozero::Message> msg;
62371   Serialize(msg.get());
62372   return msg.SerializeAsArray();
62373 }
62374 
Serialize(::protozero::Message * msg) const62375 void UpdateDataSourceResponse::Serialize(::protozero::Message* msg) const {
62376   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
62377 }
62378 
62379 
62380 UpdateDataSourceRequest::UpdateDataSourceRequest() = default;
62381 UpdateDataSourceRequest::~UpdateDataSourceRequest() = default;
62382 UpdateDataSourceRequest::UpdateDataSourceRequest(const UpdateDataSourceRequest&) = default;
62383 UpdateDataSourceRequest& UpdateDataSourceRequest::operator=(const UpdateDataSourceRequest&) = default;
62384 UpdateDataSourceRequest::UpdateDataSourceRequest(UpdateDataSourceRequest&&) noexcept = default;
62385 UpdateDataSourceRequest& UpdateDataSourceRequest::operator=(UpdateDataSourceRequest&&) = default;
62386 
operator ==(const UpdateDataSourceRequest & other) const62387 bool UpdateDataSourceRequest::operator==(const UpdateDataSourceRequest& other) const {
62388   return unknown_fields_ == other.unknown_fields_
62389    && data_source_descriptor_ == other.data_source_descriptor_;
62390 }
62391 
ParseFromArray(const void * raw,size_t size)62392 bool UpdateDataSourceRequest::ParseFromArray(const void* raw, size_t size) {
62393   unknown_fields_.clear();
62394   bool packed_error = false;
62395 
62396   ::protozero::ProtoDecoder dec(raw, size);
62397   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
62398     if (field.id() < _has_field_.size()) {
62399       _has_field_.set(field.id());
62400     }
62401     switch (field.id()) {
62402       case 1 /* data_source_descriptor */:
62403         (*data_source_descriptor_).ParseFromArray(field.data(), field.size());
62404         break;
62405       default:
62406         field.SerializeAndAppendTo(&unknown_fields_);
62407         break;
62408     }
62409   }
62410   return !packed_error && !dec.bytes_left();
62411 }
62412 
SerializeAsString() const62413 std::string UpdateDataSourceRequest::SerializeAsString() const {
62414   ::protozero::HeapBuffered<::protozero::Message> msg;
62415   Serialize(msg.get());
62416   return msg.SerializeAsString();
62417 }
62418 
SerializeAsArray() const62419 std::vector<uint8_t> UpdateDataSourceRequest::SerializeAsArray() const {
62420   ::protozero::HeapBuffered<::protozero::Message> msg;
62421   Serialize(msg.get());
62422   return msg.SerializeAsArray();
62423 }
62424 
Serialize(::protozero::Message * msg) const62425 void UpdateDataSourceRequest::Serialize(::protozero::Message* msg) const {
62426   // Field 1: data_source_descriptor
62427   if (_has_field_[1]) {
62428     (*data_source_descriptor_).Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
62429   }
62430 
62431   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
62432 }
62433 
62434 
62435 RegisterDataSourceResponse::RegisterDataSourceResponse() = default;
62436 RegisterDataSourceResponse::~RegisterDataSourceResponse() = default;
62437 RegisterDataSourceResponse::RegisterDataSourceResponse(const RegisterDataSourceResponse&) = default;
62438 RegisterDataSourceResponse& RegisterDataSourceResponse::operator=(const RegisterDataSourceResponse&) = default;
62439 RegisterDataSourceResponse::RegisterDataSourceResponse(RegisterDataSourceResponse&&) noexcept = default;
62440 RegisterDataSourceResponse& RegisterDataSourceResponse::operator=(RegisterDataSourceResponse&&) = default;
62441 
operator ==(const RegisterDataSourceResponse & other) const62442 bool RegisterDataSourceResponse::operator==(const RegisterDataSourceResponse& other) const {
62443   return unknown_fields_ == other.unknown_fields_
62444    && error_ == other.error_;
62445 }
62446 
ParseFromArray(const void * raw,size_t size)62447 bool RegisterDataSourceResponse::ParseFromArray(const void* raw, size_t size) {
62448   unknown_fields_.clear();
62449   bool packed_error = false;
62450 
62451   ::protozero::ProtoDecoder dec(raw, size);
62452   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
62453     if (field.id() < _has_field_.size()) {
62454       _has_field_.set(field.id());
62455     }
62456     switch (field.id()) {
62457       case 1 /* error */:
62458         field.get(&error_);
62459         break;
62460       default:
62461         field.SerializeAndAppendTo(&unknown_fields_);
62462         break;
62463     }
62464   }
62465   return !packed_error && !dec.bytes_left();
62466 }
62467 
SerializeAsString() const62468 std::string RegisterDataSourceResponse::SerializeAsString() const {
62469   ::protozero::HeapBuffered<::protozero::Message> msg;
62470   Serialize(msg.get());
62471   return msg.SerializeAsString();
62472 }
62473 
SerializeAsArray() const62474 std::vector<uint8_t> RegisterDataSourceResponse::SerializeAsArray() const {
62475   ::protozero::HeapBuffered<::protozero::Message> msg;
62476   Serialize(msg.get());
62477   return msg.SerializeAsArray();
62478 }
62479 
Serialize(::protozero::Message * msg) const62480 void RegisterDataSourceResponse::Serialize(::protozero::Message* msg) const {
62481   // Field 1: error
62482   if (_has_field_[1]) {
62483     msg->AppendString(1, error_);
62484   }
62485 
62486   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
62487 }
62488 
62489 
62490 RegisterDataSourceRequest::RegisterDataSourceRequest() = default;
62491 RegisterDataSourceRequest::~RegisterDataSourceRequest() = default;
62492 RegisterDataSourceRequest::RegisterDataSourceRequest(const RegisterDataSourceRequest&) = default;
62493 RegisterDataSourceRequest& RegisterDataSourceRequest::operator=(const RegisterDataSourceRequest&) = default;
62494 RegisterDataSourceRequest::RegisterDataSourceRequest(RegisterDataSourceRequest&&) noexcept = default;
62495 RegisterDataSourceRequest& RegisterDataSourceRequest::operator=(RegisterDataSourceRequest&&) = default;
62496 
operator ==(const RegisterDataSourceRequest & other) const62497 bool RegisterDataSourceRequest::operator==(const RegisterDataSourceRequest& other) const {
62498   return unknown_fields_ == other.unknown_fields_
62499    && data_source_descriptor_ == other.data_source_descriptor_;
62500 }
62501 
ParseFromArray(const void * raw,size_t size)62502 bool RegisterDataSourceRequest::ParseFromArray(const void* raw, size_t size) {
62503   unknown_fields_.clear();
62504   bool packed_error = false;
62505 
62506   ::protozero::ProtoDecoder dec(raw, size);
62507   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
62508     if (field.id() < _has_field_.size()) {
62509       _has_field_.set(field.id());
62510     }
62511     switch (field.id()) {
62512       case 1 /* data_source_descriptor */:
62513         (*data_source_descriptor_).ParseFromArray(field.data(), field.size());
62514         break;
62515       default:
62516         field.SerializeAndAppendTo(&unknown_fields_);
62517         break;
62518     }
62519   }
62520   return !packed_error && !dec.bytes_left();
62521 }
62522 
SerializeAsString() const62523 std::string RegisterDataSourceRequest::SerializeAsString() const {
62524   ::protozero::HeapBuffered<::protozero::Message> msg;
62525   Serialize(msg.get());
62526   return msg.SerializeAsString();
62527 }
62528 
SerializeAsArray() const62529 std::vector<uint8_t> RegisterDataSourceRequest::SerializeAsArray() const {
62530   ::protozero::HeapBuffered<::protozero::Message> msg;
62531   Serialize(msg.get());
62532   return msg.SerializeAsArray();
62533 }
62534 
Serialize(::protozero::Message * msg) const62535 void RegisterDataSourceRequest::Serialize(::protozero::Message* msg) const {
62536   // Field 1: data_source_descriptor
62537   if (_has_field_[1]) {
62538     (*data_source_descriptor_).Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
62539   }
62540 
62541   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
62542 }
62543 
62544 
62545 InitializeConnectionResponse::InitializeConnectionResponse() = default;
62546 InitializeConnectionResponse::~InitializeConnectionResponse() = default;
62547 InitializeConnectionResponse::InitializeConnectionResponse(const InitializeConnectionResponse&) = default;
62548 InitializeConnectionResponse& InitializeConnectionResponse::operator=(const InitializeConnectionResponse&) = default;
62549 InitializeConnectionResponse::InitializeConnectionResponse(InitializeConnectionResponse&&) noexcept = default;
62550 InitializeConnectionResponse& InitializeConnectionResponse::operator=(InitializeConnectionResponse&&) = default;
62551 
operator ==(const InitializeConnectionResponse & other) const62552 bool InitializeConnectionResponse::operator==(const InitializeConnectionResponse& other) const {
62553   return unknown_fields_ == other.unknown_fields_
62554    && using_shmem_provided_by_producer_ == other.using_shmem_provided_by_producer_
62555    && direct_smb_patching_supported_ == other.direct_smb_patching_supported_;
62556 }
62557 
ParseFromArray(const void * raw,size_t size)62558 bool InitializeConnectionResponse::ParseFromArray(const void* raw, size_t size) {
62559   unknown_fields_.clear();
62560   bool packed_error = false;
62561 
62562   ::protozero::ProtoDecoder dec(raw, size);
62563   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
62564     if (field.id() < _has_field_.size()) {
62565       _has_field_.set(field.id());
62566     }
62567     switch (field.id()) {
62568       case 1 /* using_shmem_provided_by_producer */:
62569         field.get(&using_shmem_provided_by_producer_);
62570         break;
62571       case 2 /* direct_smb_patching_supported */:
62572         field.get(&direct_smb_patching_supported_);
62573         break;
62574       default:
62575         field.SerializeAndAppendTo(&unknown_fields_);
62576         break;
62577     }
62578   }
62579   return !packed_error && !dec.bytes_left();
62580 }
62581 
SerializeAsString() const62582 std::string InitializeConnectionResponse::SerializeAsString() const {
62583   ::protozero::HeapBuffered<::protozero::Message> msg;
62584   Serialize(msg.get());
62585   return msg.SerializeAsString();
62586 }
62587 
SerializeAsArray() const62588 std::vector<uint8_t> InitializeConnectionResponse::SerializeAsArray() const {
62589   ::protozero::HeapBuffered<::protozero::Message> msg;
62590   Serialize(msg.get());
62591   return msg.SerializeAsArray();
62592 }
62593 
Serialize(::protozero::Message * msg) const62594 void InitializeConnectionResponse::Serialize(::protozero::Message* msg) const {
62595   // Field 1: using_shmem_provided_by_producer
62596   if (_has_field_[1]) {
62597     msg->AppendTinyVarInt(1, using_shmem_provided_by_producer_);
62598   }
62599 
62600   // Field 2: direct_smb_patching_supported
62601   if (_has_field_[2]) {
62602     msg->AppendTinyVarInt(2, direct_smb_patching_supported_);
62603   }
62604 
62605   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
62606 }
62607 
62608 
62609 InitializeConnectionRequest::InitializeConnectionRequest() = default;
62610 InitializeConnectionRequest::~InitializeConnectionRequest() = default;
62611 InitializeConnectionRequest::InitializeConnectionRequest(const InitializeConnectionRequest&) = default;
62612 InitializeConnectionRequest& InitializeConnectionRequest::operator=(const InitializeConnectionRequest&) = default;
62613 InitializeConnectionRequest::InitializeConnectionRequest(InitializeConnectionRequest&&) noexcept = default;
62614 InitializeConnectionRequest& InitializeConnectionRequest::operator=(InitializeConnectionRequest&&) = default;
62615 
operator ==(const InitializeConnectionRequest & other) const62616 bool InitializeConnectionRequest::operator==(const InitializeConnectionRequest& other) const {
62617   return unknown_fields_ == other.unknown_fields_
62618    && shared_memory_page_size_hint_bytes_ == other.shared_memory_page_size_hint_bytes_
62619    && shared_memory_size_hint_bytes_ == other.shared_memory_size_hint_bytes_
62620    && producer_name_ == other.producer_name_
62621    && smb_scraping_mode_ == other.smb_scraping_mode_
62622    && producer_provided_shmem_ == other.producer_provided_shmem_
62623    && sdk_version_ == other.sdk_version_
62624    && shm_key_windows_ == other.shm_key_windows_;
62625 }
62626 
ParseFromArray(const void * raw,size_t size)62627 bool InitializeConnectionRequest::ParseFromArray(const void* raw, size_t size) {
62628   unknown_fields_.clear();
62629   bool packed_error = false;
62630 
62631   ::protozero::ProtoDecoder dec(raw, size);
62632   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
62633     if (field.id() < _has_field_.size()) {
62634       _has_field_.set(field.id());
62635     }
62636     switch (field.id()) {
62637       case 1 /* shared_memory_page_size_hint_bytes */:
62638         field.get(&shared_memory_page_size_hint_bytes_);
62639         break;
62640       case 2 /* shared_memory_size_hint_bytes */:
62641         field.get(&shared_memory_size_hint_bytes_);
62642         break;
62643       case 3 /* producer_name */:
62644         field.get(&producer_name_);
62645         break;
62646       case 4 /* smb_scraping_mode */:
62647         field.get(&smb_scraping_mode_);
62648         break;
62649       case 6 /* producer_provided_shmem */:
62650         field.get(&producer_provided_shmem_);
62651         break;
62652       case 8 /* sdk_version */:
62653         field.get(&sdk_version_);
62654         break;
62655       case 7 /* shm_key_windows */:
62656         field.get(&shm_key_windows_);
62657         break;
62658       default:
62659         field.SerializeAndAppendTo(&unknown_fields_);
62660         break;
62661     }
62662   }
62663   return !packed_error && !dec.bytes_left();
62664 }
62665 
SerializeAsString() const62666 std::string InitializeConnectionRequest::SerializeAsString() const {
62667   ::protozero::HeapBuffered<::protozero::Message> msg;
62668   Serialize(msg.get());
62669   return msg.SerializeAsString();
62670 }
62671 
SerializeAsArray() const62672 std::vector<uint8_t> InitializeConnectionRequest::SerializeAsArray() const {
62673   ::protozero::HeapBuffered<::protozero::Message> msg;
62674   Serialize(msg.get());
62675   return msg.SerializeAsArray();
62676 }
62677 
Serialize(::protozero::Message * msg) const62678 void InitializeConnectionRequest::Serialize(::protozero::Message* msg) const {
62679   // Field 1: shared_memory_page_size_hint_bytes
62680   if (_has_field_[1]) {
62681     msg->AppendVarInt(1, shared_memory_page_size_hint_bytes_);
62682   }
62683 
62684   // Field 2: shared_memory_size_hint_bytes
62685   if (_has_field_[2]) {
62686     msg->AppendVarInt(2, shared_memory_size_hint_bytes_);
62687   }
62688 
62689   // Field 3: producer_name
62690   if (_has_field_[3]) {
62691     msg->AppendString(3, producer_name_);
62692   }
62693 
62694   // Field 4: smb_scraping_mode
62695   if (_has_field_[4]) {
62696     msg->AppendVarInt(4, smb_scraping_mode_);
62697   }
62698 
62699   // Field 6: producer_provided_shmem
62700   if (_has_field_[6]) {
62701     msg->AppendTinyVarInt(6, producer_provided_shmem_);
62702   }
62703 
62704   // Field 8: sdk_version
62705   if (_has_field_[8]) {
62706     msg->AppendString(8, sdk_version_);
62707   }
62708 
62709   // Field 7: shm_key_windows
62710   if (_has_field_[7]) {
62711     msg->AppendString(7, shm_key_windows_);
62712   }
62713 
62714   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
62715 }
62716 
62717 }  // namespace perfetto
62718 }  // namespace protos
62719 }  // namespace gen
62720 #if defined(__GNUC__) || defined(__clang__)
62721 #pragma GCC diagnostic pop
62722 #endif
62723 // gen_amalgamated begin source: gen/protos/perfetto/ipc/wire_protocol.gen.cc
62724 // gen_amalgamated begin header: gen/protos/perfetto/ipc/wire_protocol.gen.h
62725 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
62726 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_IPC_WIRE_PROTOCOL_PROTO_CPP_H_
62727 #define PERFETTO_PROTOS_PROTOS_PERFETTO_IPC_WIRE_PROTOCOL_PROTO_CPP_H_
62728 
62729 #include <stdint.h>
62730 #include <bitset>
62731 #include <vector>
62732 #include <string>
62733 #include <type_traits>
62734 
62735 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
62736 // gen_amalgamated expanded: #include "perfetto/protozero/copyable_ptr.h"
62737 // gen_amalgamated expanded: #include "perfetto/base/export.h"
62738 
62739 namespace perfetto {
62740 namespace protos {
62741 namespace gen {
62742 class IPCFrame;
62743 class IPCFrame_RequestError;
62744 class IPCFrame_InvokeMethodReply;
62745 class IPCFrame_InvokeMethod;
62746 class IPCFrame_BindServiceReply;
62747 class IPCFrame_BindServiceReply_MethodInfo;
62748 class IPCFrame_BindService;
62749 }  // namespace perfetto
62750 }  // namespace protos
62751 }  // namespace gen
62752 
62753 namespace protozero {
62754 class Message;
62755 }  // namespace protozero
62756 
62757 namespace perfetto {
62758 namespace protos {
62759 namespace gen {
62760 
62761 class PERFETTO_EXPORT IPCFrame : public ::protozero::CppMessageObj {
62762  public:
62763   using BindService = IPCFrame_BindService;
62764   using BindServiceReply = IPCFrame_BindServiceReply;
62765   using InvokeMethod = IPCFrame_InvokeMethod;
62766   using InvokeMethodReply = IPCFrame_InvokeMethodReply;
62767   using RequestError = IPCFrame_RequestError;
62768   enum FieldNumbers {
62769     kRequestIdFieldNumber = 2,
62770     kMsgBindServiceFieldNumber = 3,
62771     kMsgBindServiceReplyFieldNumber = 4,
62772     kMsgInvokeMethodFieldNumber = 5,
62773     kMsgInvokeMethodReplyFieldNumber = 6,
62774     kMsgRequestErrorFieldNumber = 7,
62775     kDataForTestingFieldNumber = 1,
62776   };
62777 
62778   IPCFrame();
62779   ~IPCFrame() override;
62780   IPCFrame(IPCFrame&&) noexcept;
62781   IPCFrame& operator=(IPCFrame&&);
62782   IPCFrame(const IPCFrame&);
62783   IPCFrame& operator=(const IPCFrame&);
62784   bool operator==(const IPCFrame&) const;
operator !=(const IPCFrame & other) const62785   bool operator!=(const IPCFrame& other) const { return !(*this == other); }
62786 
62787   bool ParseFromArray(const void*, size_t) override;
62788   std::string SerializeAsString() const override;
62789   std::vector<uint8_t> SerializeAsArray() const override;
62790   void Serialize(::protozero::Message*) const;
62791 
has_request_id() const62792   bool has_request_id() const { return _has_field_[2]; }
request_id() const62793   uint64_t request_id() const { return request_id_; }
set_request_id(uint64_t value)62794   void set_request_id(uint64_t value) { request_id_ = value; _has_field_.set(2); }
62795 
has_msg_bind_service() const62796   bool has_msg_bind_service() const { return _has_field_[3]; }
msg_bind_service() const62797   const IPCFrame_BindService& msg_bind_service() const { return *msg_bind_service_; }
mutable_msg_bind_service()62798   IPCFrame_BindService* mutable_msg_bind_service() { _has_field_.set(3); return msg_bind_service_.get(); }
62799 
has_msg_bind_service_reply() const62800   bool has_msg_bind_service_reply() const { return _has_field_[4]; }
msg_bind_service_reply() const62801   const IPCFrame_BindServiceReply& msg_bind_service_reply() const { return *msg_bind_service_reply_; }
mutable_msg_bind_service_reply()62802   IPCFrame_BindServiceReply* mutable_msg_bind_service_reply() { _has_field_.set(4); return msg_bind_service_reply_.get(); }
62803 
has_msg_invoke_method() const62804   bool has_msg_invoke_method() const { return _has_field_[5]; }
msg_invoke_method() const62805   const IPCFrame_InvokeMethod& msg_invoke_method() const { return *msg_invoke_method_; }
mutable_msg_invoke_method()62806   IPCFrame_InvokeMethod* mutable_msg_invoke_method() { _has_field_.set(5); return msg_invoke_method_.get(); }
62807 
has_msg_invoke_method_reply() const62808   bool has_msg_invoke_method_reply() const { return _has_field_[6]; }
msg_invoke_method_reply() const62809   const IPCFrame_InvokeMethodReply& msg_invoke_method_reply() const { return *msg_invoke_method_reply_; }
mutable_msg_invoke_method_reply()62810   IPCFrame_InvokeMethodReply* mutable_msg_invoke_method_reply() { _has_field_.set(6); return msg_invoke_method_reply_.get(); }
62811 
has_msg_request_error() const62812   bool has_msg_request_error() const { return _has_field_[7]; }
msg_request_error() const62813   const IPCFrame_RequestError& msg_request_error() const { return *msg_request_error_; }
mutable_msg_request_error()62814   IPCFrame_RequestError* mutable_msg_request_error() { _has_field_.set(7); return msg_request_error_.get(); }
62815 
data_for_testing() const62816   const std::vector<std::string>& data_for_testing() const { return data_for_testing_; }
mutable_data_for_testing()62817   std::vector<std::string>* mutable_data_for_testing() { return &data_for_testing_; }
data_for_testing_size() const62818   int data_for_testing_size() const { return static_cast<int>(data_for_testing_.size()); }
clear_data_for_testing()62819   void clear_data_for_testing() { data_for_testing_.clear(); }
add_data_for_testing(std::string value)62820   void add_data_for_testing(std::string value) { data_for_testing_.emplace_back(value); }
add_data_for_testing()62821   std::string* add_data_for_testing() { data_for_testing_.emplace_back(); return &data_for_testing_.back(); }
62822 
62823  private:
62824   uint64_t request_id_{};
62825   ::protozero::CopyablePtr<IPCFrame_BindService> msg_bind_service_;
62826   ::protozero::CopyablePtr<IPCFrame_BindServiceReply> msg_bind_service_reply_;
62827   ::protozero::CopyablePtr<IPCFrame_InvokeMethod> msg_invoke_method_;
62828   ::protozero::CopyablePtr<IPCFrame_InvokeMethodReply> msg_invoke_method_reply_;
62829   ::protozero::CopyablePtr<IPCFrame_RequestError> msg_request_error_;
62830   std::vector<std::string> data_for_testing_;
62831 
62832   // Allows to preserve unknown protobuf fields for compatibility
62833   // with future versions of .proto files.
62834   std::string unknown_fields_;
62835 
62836   std::bitset<8> _has_field_{};
62837 };
62838 
62839 
62840 class PERFETTO_EXPORT IPCFrame_RequestError : public ::protozero::CppMessageObj {
62841  public:
62842   enum FieldNumbers {
62843     kErrorFieldNumber = 1,
62844   };
62845 
62846   IPCFrame_RequestError();
62847   ~IPCFrame_RequestError() override;
62848   IPCFrame_RequestError(IPCFrame_RequestError&&) noexcept;
62849   IPCFrame_RequestError& operator=(IPCFrame_RequestError&&);
62850   IPCFrame_RequestError(const IPCFrame_RequestError&);
62851   IPCFrame_RequestError& operator=(const IPCFrame_RequestError&);
62852   bool operator==(const IPCFrame_RequestError&) const;
operator !=(const IPCFrame_RequestError & other) const62853   bool operator!=(const IPCFrame_RequestError& other) const { return !(*this == other); }
62854 
62855   bool ParseFromArray(const void*, size_t) override;
62856   std::string SerializeAsString() const override;
62857   std::vector<uint8_t> SerializeAsArray() const override;
62858   void Serialize(::protozero::Message*) const;
62859 
has_error() const62860   bool has_error() const { return _has_field_[1]; }
error() const62861   const std::string& error() const { return error_; }
set_error(const std::string & value)62862   void set_error(const std::string& value) { error_ = value; _has_field_.set(1); }
62863 
62864  private:
62865   std::string error_{};
62866 
62867   // Allows to preserve unknown protobuf fields for compatibility
62868   // with future versions of .proto files.
62869   std::string unknown_fields_;
62870 
62871   std::bitset<2> _has_field_{};
62872 };
62873 
62874 
62875 class PERFETTO_EXPORT IPCFrame_InvokeMethodReply : public ::protozero::CppMessageObj {
62876  public:
62877   enum FieldNumbers {
62878     kSuccessFieldNumber = 1,
62879     kHasMoreFieldNumber = 2,
62880     kReplyProtoFieldNumber = 3,
62881   };
62882 
62883   IPCFrame_InvokeMethodReply();
62884   ~IPCFrame_InvokeMethodReply() override;
62885   IPCFrame_InvokeMethodReply(IPCFrame_InvokeMethodReply&&) noexcept;
62886   IPCFrame_InvokeMethodReply& operator=(IPCFrame_InvokeMethodReply&&);
62887   IPCFrame_InvokeMethodReply(const IPCFrame_InvokeMethodReply&);
62888   IPCFrame_InvokeMethodReply& operator=(const IPCFrame_InvokeMethodReply&);
62889   bool operator==(const IPCFrame_InvokeMethodReply&) const;
operator !=(const IPCFrame_InvokeMethodReply & other) const62890   bool operator!=(const IPCFrame_InvokeMethodReply& other) const { return !(*this == other); }
62891 
62892   bool ParseFromArray(const void*, size_t) override;
62893   std::string SerializeAsString() const override;
62894   std::vector<uint8_t> SerializeAsArray() const override;
62895   void Serialize(::protozero::Message*) const;
62896 
has_success() const62897   bool has_success() const { return _has_field_[1]; }
success() const62898   bool success() const { return success_; }
set_success(bool value)62899   void set_success(bool value) { success_ = value; _has_field_.set(1); }
62900 
has_has_more() const62901   bool has_has_more() const { return _has_field_[2]; }
has_more() const62902   bool has_more() const { return has_more_; }
set_has_more(bool value)62903   void set_has_more(bool value) { has_more_ = value; _has_field_.set(2); }
62904 
has_reply_proto() const62905   bool has_reply_proto() const { return _has_field_[3]; }
reply_proto() const62906   const std::string& reply_proto() const { return reply_proto_; }
set_reply_proto(const std::string & value)62907   void set_reply_proto(const std::string& value) { reply_proto_ = value; _has_field_.set(3); }
set_reply_proto(const void * p,size_t s)62908   void set_reply_proto(const void* p, size_t s) { reply_proto_.assign(reinterpret_cast<const char*>(p), s); _has_field_.set(3); }
62909 
62910  private:
62911   bool success_{};
62912   bool has_more_{};
62913   std::string reply_proto_{};
62914 
62915   // Allows to preserve unknown protobuf fields for compatibility
62916   // with future versions of .proto files.
62917   std::string unknown_fields_;
62918 
62919   std::bitset<4> _has_field_{};
62920 };
62921 
62922 
62923 class PERFETTO_EXPORT IPCFrame_InvokeMethod : public ::protozero::CppMessageObj {
62924  public:
62925   enum FieldNumbers {
62926     kServiceIdFieldNumber = 1,
62927     kMethodIdFieldNumber = 2,
62928     kArgsProtoFieldNumber = 3,
62929     kDropReplyFieldNumber = 4,
62930   };
62931 
62932   IPCFrame_InvokeMethod();
62933   ~IPCFrame_InvokeMethod() override;
62934   IPCFrame_InvokeMethod(IPCFrame_InvokeMethod&&) noexcept;
62935   IPCFrame_InvokeMethod& operator=(IPCFrame_InvokeMethod&&);
62936   IPCFrame_InvokeMethod(const IPCFrame_InvokeMethod&);
62937   IPCFrame_InvokeMethod& operator=(const IPCFrame_InvokeMethod&);
62938   bool operator==(const IPCFrame_InvokeMethod&) const;
operator !=(const IPCFrame_InvokeMethod & other) const62939   bool operator!=(const IPCFrame_InvokeMethod& other) const { return !(*this == other); }
62940 
62941   bool ParseFromArray(const void*, size_t) override;
62942   std::string SerializeAsString() const override;
62943   std::vector<uint8_t> SerializeAsArray() const override;
62944   void Serialize(::protozero::Message*) const;
62945 
has_service_id() const62946   bool has_service_id() const { return _has_field_[1]; }
service_id() const62947   uint32_t service_id() const { return service_id_; }
set_service_id(uint32_t value)62948   void set_service_id(uint32_t value) { service_id_ = value; _has_field_.set(1); }
62949 
has_method_id() const62950   bool has_method_id() const { return _has_field_[2]; }
method_id() const62951   uint32_t method_id() const { return method_id_; }
set_method_id(uint32_t value)62952   void set_method_id(uint32_t value) { method_id_ = value; _has_field_.set(2); }
62953 
has_args_proto() const62954   bool has_args_proto() const { return _has_field_[3]; }
args_proto() const62955   const std::string& args_proto() const { return args_proto_; }
set_args_proto(const std::string & value)62956   void set_args_proto(const std::string& value) { args_proto_ = value; _has_field_.set(3); }
set_args_proto(const void * p,size_t s)62957   void set_args_proto(const void* p, size_t s) { args_proto_.assign(reinterpret_cast<const char*>(p), s); _has_field_.set(3); }
62958 
has_drop_reply() const62959   bool has_drop_reply() const { return _has_field_[4]; }
drop_reply() const62960   bool drop_reply() const { return drop_reply_; }
set_drop_reply(bool value)62961   void set_drop_reply(bool value) { drop_reply_ = value; _has_field_.set(4); }
62962 
62963  private:
62964   uint32_t service_id_{};
62965   uint32_t method_id_{};
62966   std::string args_proto_{};
62967   bool drop_reply_{};
62968 
62969   // Allows to preserve unknown protobuf fields for compatibility
62970   // with future versions of .proto files.
62971   std::string unknown_fields_;
62972 
62973   std::bitset<5> _has_field_{};
62974 };
62975 
62976 
62977 class PERFETTO_EXPORT IPCFrame_BindServiceReply : public ::protozero::CppMessageObj {
62978  public:
62979   using MethodInfo = IPCFrame_BindServiceReply_MethodInfo;
62980   enum FieldNumbers {
62981     kSuccessFieldNumber = 1,
62982     kServiceIdFieldNumber = 2,
62983     kMethodsFieldNumber = 3,
62984   };
62985 
62986   IPCFrame_BindServiceReply();
62987   ~IPCFrame_BindServiceReply() override;
62988   IPCFrame_BindServiceReply(IPCFrame_BindServiceReply&&) noexcept;
62989   IPCFrame_BindServiceReply& operator=(IPCFrame_BindServiceReply&&);
62990   IPCFrame_BindServiceReply(const IPCFrame_BindServiceReply&);
62991   IPCFrame_BindServiceReply& operator=(const IPCFrame_BindServiceReply&);
62992   bool operator==(const IPCFrame_BindServiceReply&) const;
operator !=(const IPCFrame_BindServiceReply & other) const62993   bool operator!=(const IPCFrame_BindServiceReply& other) const { return !(*this == other); }
62994 
62995   bool ParseFromArray(const void*, size_t) override;
62996   std::string SerializeAsString() const override;
62997   std::vector<uint8_t> SerializeAsArray() const override;
62998   void Serialize(::protozero::Message*) const;
62999 
has_success() const63000   bool has_success() const { return _has_field_[1]; }
success() const63001   bool success() const { return success_; }
set_success(bool value)63002   void set_success(bool value) { success_ = value; _has_field_.set(1); }
63003 
has_service_id() const63004   bool has_service_id() const { return _has_field_[2]; }
service_id() const63005   uint32_t service_id() const { return service_id_; }
set_service_id(uint32_t value)63006   void set_service_id(uint32_t value) { service_id_ = value; _has_field_.set(2); }
63007 
methods() const63008   const std::vector<IPCFrame_BindServiceReply_MethodInfo>& methods() const { return methods_; }
mutable_methods()63009   std::vector<IPCFrame_BindServiceReply_MethodInfo>* mutable_methods() { return &methods_; }
63010   int methods_size() const;
63011   void clear_methods();
63012   IPCFrame_BindServiceReply_MethodInfo* add_methods();
63013 
63014  private:
63015   bool success_{};
63016   uint32_t service_id_{};
63017   std::vector<IPCFrame_BindServiceReply_MethodInfo> methods_;
63018 
63019   // Allows to preserve unknown protobuf fields for compatibility
63020   // with future versions of .proto files.
63021   std::string unknown_fields_;
63022 
63023   std::bitset<4> _has_field_{};
63024 };
63025 
63026 
63027 class PERFETTO_EXPORT IPCFrame_BindServiceReply_MethodInfo : public ::protozero::CppMessageObj {
63028  public:
63029   enum FieldNumbers {
63030     kIdFieldNumber = 1,
63031     kNameFieldNumber = 2,
63032   };
63033 
63034   IPCFrame_BindServiceReply_MethodInfo();
63035   ~IPCFrame_BindServiceReply_MethodInfo() override;
63036   IPCFrame_BindServiceReply_MethodInfo(IPCFrame_BindServiceReply_MethodInfo&&) noexcept;
63037   IPCFrame_BindServiceReply_MethodInfo& operator=(IPCFrame_BindServiceReply_MethodInfo&&);
63038   IPCFrame_BindServiceReply_MethodInfo(const IPCFrame_BindServiceReply_MethodInfo&);
63039   IPCFrame_BindServiceReply_MethodInfo& operator=(const IPCFrame_BindServiceReply_MethodInfo&);
63040   bool operator==(const IPCFrame_BindServiceReply_MethodInfo&) const;
operator !=(const IPCFrame_BindServiceReply_MethodInfo & other) const63041   bool operator!=(const IPCFrame_BindServiceReply_MethodInfo& other) const { return !(*this == other); }
63042 
63043   bool ParseFromArray(const void*, size_t) override;
63044   std::string SerializeAsString() const override;
63045   std::vector<uint8_t> SerializeAsArray() const override;
63046   void Serialize(::protozero::Message*) const;
63047 
has_id() const63048   bool has_id() const { return _has_field_[1]; }
id() const63049   uint32_t id() const { return id_; }
set_id(uint32_t value)63050   void set_id(uint32_t value) { id_ = value; _has_field_.set(1); }
63051 
has_name() const63052   bool has_name() const { return _has_field_[2]; }
name() const63053   const std::string& name() const { return name_; }
set_name(const std::string & value)63054   void set_name(const std::string& value) { name_ = value; _has_field_.set(2); }
63055 
63056  private:
63057   uint32_t id_{};
63058   std::string name_{};
63059 
63060   // Allows to preserve unknown protobuf fields for compatibility
63061   // with future versions of .proto files.
63062   std::string unknown_fields_;
63063 
63064   std::bitset<3> _has_field_{};
63065 };
63066 
63067 
63068 class PERFETTO_EXPORT IPCFrame_BindService : public ::protozero::CppMessageObj {
63069  public:
63070   enum FieldNumbers {
63071     kServiceNameFieldNumber = 1,
63072   };
63073 
63074   IPCFrame_BindService();
63075   ~IPCFrame_BindService() override;
63076   IPCFrame_BindService(IPCFrame_BindService&&) noexcept;
63077   IPCFrame_BindService& operator=(IPCFrame_BindService&&);
63078   IPCFrame_BindService(const IPCFrame_BindService&);
63079   IPCFrame_BindService& operator=(const IPCFrame_BindService&);
63080   bool operator==(const IPCFrame_BindService&) const;
operator !=(const IPCFrame_BindService & other) const63081   bool operator!=(const IPCFrame_BindService& other) const { return !(*this == other); }
63082 
63083   bool ParseFromArray(const void*, size_t) override;
63084   std::string SerializeAsString() const override;
63085   std::vector<uint8_t> SerializeAsArray() const override;
63086   void Serialize(::protozero::Message*) const;
63087 
has_service_name() const63088   bool has_service_name() const { return _has_field_[1]; }
service_name() const63089   const std::string& service_name() const { return service_name_; }
set_service_name(const std::string & value)63090   void set_service_name(const std::string& value) { service_name_ = value; _has_field_.set(1); }
63091 
63092  private:
63093   std::string service_name_{};
63094 
63095   // Allows to preserve unknown protobuf fields for compatibility
63096   // with future versions of .proto files.
63097   std::string unknown_fields_;
63098 
63099   std::bitset<2> _has_field_{};
63100 };
63101 
63102 }  // namespace perfetto
63103 }  // namespace protos
63104 }  // namespace gen
63105 
63106 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_IPC_WIRE_PROTOCOL_PROTO_CPP_H_
63107 // gen_amalgamated expanded: #include "perfetto/protozero/message.h"
63108 // gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
63109 // gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
63110 // gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
63111 // DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
63112 #if defined(__GNUC__) || defined(__clang__)
63113 #pragma GCC diagnostic push
63114 #pragma GCC diagnostic ignored "-Wfloat-equal"
63115 #endif
63116 // gen_amalgamated expanded: #include "protos/perfetto/ipc/wire_protocol.gen.h"
63117 
63118 namespace perfetto {
63119 namespace protos {
63120 namespace gen {
63121 
63122 IPCFrame::IPCFrame() = default;
63123 IPCFrame::~IPCFrame() = default;
63124 IPCFrame::IPCFrame(const IPCFrame&) = default;
63125 IPCFrame& IPCFrame::operator=(const IPCFrame&) = default;
63126 IPCFrame::IPCFrame(IPCFrame&&) noexcept = default;
63127 IPCFrame& IPCFrame::operator=(IPCFrame&&) = default;
63128 
operator ==(const IPCFrame & other) const63129 bool IPCFrame::operator==(const IPCFrame& other) const {
63130   return unknown_fields_ == other.unknown_fields_
63131    && request_id_ == other.request_id_
63132    && msg_bind_service_ == other.msg_bind_service_
63133    && msg_bind_service_reply_ == other.msg_bind_service_reply_
63134    && msg_invoke_method_ == other.msg_invoke_method_
63135    && msg_invoke_method_reply_ == other.msg_invoke_method_reply_
63136    && msg_request_error_ == other.msg_request_error_
63137    && data_for_testing_ == other.data_for_testing_;
63138 }
63139 
ParseFromArray(const void * raw,size_t size)63140 bool IPCFrame::ParseFromArray(const void* raw, size_t size) {
63141   data_for_testing_.clear();
63142   unknown_fields_.clear();
63143   bool packed_error = false;
63144 
63145   ::protozero::ProtoDecoder dec(raw, size);
63146   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
63147     if (field.id() < _has_field_.size()) {
63148       _has_field_.set(field.id());
63149     }
63150     switch (field.id()) {
63151       case 2 /* request_id */:
63152         field.get(&request_id_);
63153         break;
63154       case 3 /* msg_bind_service */:
63155         (*msg_bind_service_).ParseFromArray(field.data(), field.size());
63156         break;
63157       case 4 /* msg_bind_service_reply */:
63158         (*msg_bind_service_reply_).ParseFromArray(field.data(), field.size());
63159         break;
63160       case 5 /* msg_invoke_method */:
63161         (*msg_invoke_method_).ParseFromArray(field.data(), field.size());
63162         break;
63163       case 6 /* msg_invoke_method_reply */:
63164         (*msg_invoke_method_reply_).ParseFromArray(field.data(), field.size());
63165         break;
63166       case 7 /* msg_request_error */:
63167         (*msg_request_error_).ParseFromArray(field.data(), field.size());
63168         break;
63169       case 1 /* data_for_testing */:
63170         data_for_testing_.emplace_back();
63171         field.get(&data_for_testing_.back());
63172         break;
63173       default:
63174         field.SerializeAndAppendTo(&unknown_fields_);
63175         break;
63176     }
63177   }
63178   return !packed_error && !dec.bytes_left();
63179 }
63180 
SerializeAsString() const63181 std::string IPCFrame::SerializeAsString() const {
63182   ::protozero::HeapBuffered<::protozero::Message> msg;
63183   Serialize(msg.get());
63184   return msg.SerializeAsString();
63185 }
63186 
SerializeAsArray() const63187 std::vector<uint8_t> IPCFrame::SerializeAsArray() const {
63188   ::protozero::HeapBuffered<::protozero::Message> msg;
63189   Serialize(msg.get());
63190   return msg.SerializeAsArray();
63191 }
63192 
Serialize(::protozero::Message * msg) const63193 void IPCFrame::Serialize(::protozero::Message* msg) const {
63194   // Field 2: request_id
63195   if (_has_field_[2]) {
63196     msg->AppendVarInt(2, request_id_);
63197   }
63198 
63199   // Field 3: msg_bind_service
63200   if (_has_field_[3]) {
63201     (*msg_bind_service_).Serialize(msg->BeginNestedMessage<::protozero::Message>(3));
63202   }
63203 
63204   // Field 4: msg_bind_service_reply
63205   if (_has_field_[4]) {
63206     (*msg_bind_service_reply_).Serialize(msg->BeginNestedMessage<::protozero::Message>(4));
63207   }
63208 
63209   // Field 5: msg_invoke_method
63210   if (_has_field_[5]) {
63211     (*msg_invoke_method_).Serialize(msg->BeginNestedMessage<::protozero::Message>(5));
63212   }
63213 
63214   // Field 6: msg_invoke_method_reply
63215   if (_has_field_[6]) {
63216     (*msg_invoke_method_reply_).Serialize(msg->BeginNestedMessage<::protozero::Message>(6));
63217   }
63218 
63219   // Field 7: msg_request_error
63220   if (_has_field_[7]) {
63221     (*msg_request_error_).Serialize(msg->BeginNestedMessage<::protozero::Message>(7));
63222   }
63223 
63224   // Field 1: data_for_testing
63225   for (auto& it : data_for_testing_) {
63226     msg->AppendString(1, it);
63227   }
63228 
63229   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
63230 }
63231 
63232 
63233 IPCFrame_RequestError::IPCFrame_RequestError() = default;
63234 IPCFrame_RequestError::~IPCFrame_RequestError() = default;
63235 IPCFrame_RequestError::IPCFrame_RequestError(const IPCFrame_RequestError&) = default;
63236 IPCFrame_RequestError& IPCFrame_RequestError::operator=(const IPCFrame_RequestError&) = default;
63237 IPCFrame_RequestError::IPCFrame_RequestError(IPCFrame_RequestError&&) noexcept = default;
63238 IPCFrame_RequestError& IPCFrame_RequestError::operator=(IPCFrame_RequestError&&) = default;
63239 
operator ==(const IPCFrame_RequestError & other) const63240 bool IPCFrame_RequestError::operator==(const IPCFrame_RequestError& other) const {
63241   return unknown_fields_ == other.unknown_fields_
63242    && error_ == other.error_;
63243 }
63244 
ParseFromArray(const void * raw,size_t size)63245 bool IPCFrame_RequestError::ParseFromArray(const void* raw, size_t size) {
63246   unknown_fields_.clear();
63247   bool packed_error = false;
63248 
63249   ::protozero::ProtoDecoder dec(raw, size);
63250   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
63251     if (field.id() < _has_field_.size()) {
63252       _has_field_.set(field.id());
63253     }
63254     switch (field.id()) {
63255       case 1 /* error */:
63256         field.get(&error_);
63257         break;
63258       default:
63259         field.SerializeAndAppendTo(&unknown_fields_);
63260         break;
63261     }
63262   }
63263   return !packed_error && !dec.bytes_left();
63264 }
63265 
SerializeAsString() const63266 std::string IPCFrame_RequestError::SerializeAsString() const {
63267   ::protozero::HeapBuffered<::protozero::Message> msg;
63268   Serialize(msg.get());
63269   return msg.SerializeAsString();
63270 }
63271 
SerializeAsArray() const63272 std::vector<uint8_t> IPCFrame_RequestError::SerializeAsArray() const {
63273   ::protozero::HeapBuffered<::protozero::Message> msg;
63274   Serialize(msg.get());
63275   return msg.SerializeAsArray();
63276 }
63277 
Serialize(::protozero::Message * msg) const63278 void IPCFrame_RequestError::Serialize(::protozero::Message* msg) const {
63279   // Field 1: error
63280   if (_has_field_[1]) {
63281     msg->AppendString(1, error_);
63282   }
63283 
63284   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
63285 }
63286 
63287 
63288 IPCFrame_InvokeMethodReply::IPCFrame_InvokeMethodReply() = default;
63289 IPCFrame_InvokeMethodReply::~IPCFrame_InvokeMethodReply() = default;
63290 IPCFrame_InvokeMethodReply::IPCFrame_InvokeMethodReply(const IPCFrame_InvokeMethodReply&) = default;
63291 IPCFrame_InvokeMethodReply& IPCFrame_InvokeMethodReply::operator=(const IPCFrame_InvokeMethodReply&) = default;
63292 IPCFrame_InvokeMethodReply::IPCFrame_InvokeMethodReply(IPCFrame_InvokeMethodReply&&) noexcept = default;
63293 IPCFrame_InvokeMethodReply& IPCFrame_InvokeMethodReply::operator=(IPCFrame_InvokeMethodReply&&) = default;
63294 
operator ==(const IPCFrame_InvokeMethodReply & other) const63295 bool IPCFrame_InvokeMethodReply::operator==(const IPCFrame_InvokeMethodReply& other) const {
63296   return unknown_fields_ == other.unknown_fields_
63297    && success_ == other.success_
63298    && has_more_ == other.has_more_
63299    && reply_proto_ == other.reply_proto_;
63300 }
63301 
ParseFromArray(const void * raw,size_t size)63302 bool IPCFrame_InvokeMethodReply::ParseFromArray(const void* raw, size_t size) {
63303   unknown_fields_.clear();
63304   bool packed_error = false;
63305 
63306   ::protozero::ProtoDecoder dec(raw, size);
63307   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
63308     if (field.id() < _has_field_.size()) {
63309       _has_field_.set(field.id());
63310     }
63311     switch (field.id()) {
63312       case 1 /* success */:
63313         field.get(&success_);
63314         break;
63315       case 2 /* has_more */:
63316         field.get(&has_more_);
63317         break;
63318       case 3 /* reply_proto */:
63319         field.get(&reply_proto_);
63320         break;
63321       default:
63322         field.SerializeAndAppendTo(&unknown_fields_);
63323         break;
63324     }
63325   }
63326   return !packed_error && !dec.bytes_left();
63327 }
63328 
SerializeAsString() const63329 std::string IPCFrame_InvokeMethodReply::SerializeAsString() const {
63330   ::protozero::HeapBuffered<::protozero::Message> msg;
63331   Serialize(msg.get());
63332   return msg.SerializeAsString();
63333 }
63334 
SerializeAsArray() const63335 std::vector<uint8_t> IPCFrame_InvokeMethodReply::SerializeAsArray() const {
63336   ::protozero::HeapBuffered<::protozero::Message> msg;
63337   Serialize(msg.get());
63338   return msg.SerializeAsArray();
63339 }
63340 
Serialize(::protozero::Message * msg) const63341 void IPCFrame_InvokeMethodReply::Serialize(::protozero::Message* msg) const {
63342   // Field 1: success
63343   if (_has_field_[1]) {
63344     msg->AppendTinyVarInt(1, success_);
63345   }
63346 
63347   // Field 2: has_more
63348   if (_has_field_[2]) {
63349     msg->AppendTinyVarInt(2, has_more_);
63350   }
63351 
63352   // Field 3: reply_proto
63353   if (_has_field_[3]) {
63354     msg->AppendString(3, reply_proto_);
63355   }
63356 
63357   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
63358 }
63359 
63360 
63361 IPCFrame_InvokeMethod::IPCFrame_InvokeMethod() = default;
63362 IPCFrame_InvokeMethod::~IPCFrame_InvokeMethod() = default;
63363 IPCFrame_InvokeMethod::IPCFrame_InvokeMethod(const IPCFrame_InvokeMethod&) = default;
63364 IPCFrame_InvokeMethod& IPCFrame_InvokeMethod::operator=(const IPCFrame_InvokeMethod&) = default;
63365 IPCFrame_InvokeMethod::IPCFrame_InvokeMethod(IPCFrame_InvokeMethod&&) noexcept = default;
63366 IPCFrame_InvokeMethod& IPCFrame_InvokeMethod::operator=(IPCFrame_InvokeMethod&&) = default;
63367 
operator ==(const IPCFrame_InvokeMethod & other) const63368 bool IPCFrame_InvokeMethod::operator==(const IPCFrame_InvokeMethod& other) const {
63369   return unknown_fields_ == other.unknown_fields_
63370    && service_id_ == other.service_id_
63371    && method_id_ == other.method_id_
63372    && args_proto_ == other.args_proto_
63373    && drop_reply_ == other.drop_reply_;
63374 }
63375 
ParseFromArray(const void * raw,size_t size)63376 bool IPCFrame_InvokeMethod::ParseFromArray(const void* raw, size_t size) {
63377   unknown_fields_.clear();
63378   bool packed_error = false;
63379 
63380   ::protozero::ProtoDecoder dec(raw, size);
63381   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
63382     if (field.id() < _has_field_.size()) {
63383       _has_field_.set(field.id());
63384     }
63385     switch (field.id()) {
63386       case 1 /* service_id */:
63387         field.get(&service_id_);
63388         break;
63389       case 2 /* method_id */:
63390         field.get(&method_id_);
63391         break;
63392       case 3 /* args_proto */:
63393         field.get(&args_proto_);
63394         break;
63395       case 4 /* drop_reply */:
63396         field.get(&drop_reply_);
63397         break;
63398       default:
63399         field.SerializeAndAppendTo(&unknown_fields_);
63400         break;
63401     }
63402   }
63403   return !packed_error && !dec.bytes_left();
63404 }
63405 
SerializeAsString() const63406 std::string IPCFrame_InvokeMethod::SerializeAsString() const {
63407   ::protozero::HeapBuffered<::protozero::Message> msg;
63408   Serialize(msg.get());
63409   return msg.SerializeAsString();
63410 }
63411 
SerializeAsArray() const63412 std::vector<uint8_t> IPCFrame_InvokeMethod::SerializeAsArray() const {
63413   ::protozero::HeapBuffered<::protozero::Message> msg;
63414   Serialize(msg.get());
63415   return msg.SerializeAsArray();
63416 }
63417 
Serialize(::protozero::Message * msg) const63418 void IPCFrame_InvokeMethod::Serialize(::protozero::Message* msg) const {
63419   // Field 1: service_id
63420   if (_has_field_[1]) {
63421     msg->AppendVarInt(1, service_id_);
63422   }
63423 
63424   // Field 2: method_id
63425   if (_has_field_[2]) {
63426     msg->AppendVarInt(2, method_id_);
63427   }
63428 
63429   // Field 3: args_proto
63430   if (_has_field_[3]) {
63431     msg->AppendString(3, args_proto_);
63432   }
63433 
63434   // Field 4: drop_reply
63435   if (_has_field_[4]) {
63436     msg->AppendTinyVarInt(4, drop_reply_);
63437   }
63438 
63439   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
63440 }
63441 
63442 
63443 IPCFrame_BindServiceReply::IPCFrame_BindServiceReply() = default;
63444 IPCFrame_BindServiceReply::~IPCFrame_BindServiceReply() = default;
63445 IPCFrame_BindServiceReply::IPCFrame_BindServiceReply(const IPCFrame_BindServiceReply&) = default;
63446 IPCFrame_BindServiceReply& IPCFrame_BindServiceReply::operator=(const IPCFrame_BindServiceReply&) = default;
63447 IPCFrame_BindServiceReply::IPCFrame_BindServiceReply(IPCFrame_BindServiceReply&&) noexcept = default;
63448 IPCFrame_BindServiceReply& IPCFrame_BindServiceReply::operator=(IPCFrame_BindServiceReply&&) = default;
63449 
operator ==(const IPCFrame_BindServiceReply & other) const63450 bool IPCFrame_BindServiceReply::operator==(const IPCFrame_BindServiceReply& other) const {
63451   return unknown_fields_ == other.unknown_fields_
63452    && success_ == other.success_
63453    && service_id_ == other.service_id_
63454    && methods_ == other.methods_;
63455 }
63456 
methods_size() const63457 int IPCFrame_BindServiceReply::methods_size() const { return static_cast<int>(methods_.size()); }
clear_methods()63458 void IPCFrame_BindServiceReply::clear_methods() { methods_.clear(); }
add_methods()63459 IPCFrame_BindServiceReply_MethodInfo* IPCFrame_BindServiceReply::add_methods() { methods_.emplace_back(); return &methods_.back(); }
ParseFromArray(const void * raw,size_t size)63460 bool IPCFrame_BindServiceReply::ParseFromArray(const void* raw, size_t size) {
63461   methods_.clear();
63462   unknown_fields_.clear();
63463   bool packed_error = false;
63464 
63465   ::protozero::ProtoDecoder dec(raw, size);
63466   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
63467     if (field.id() < _has_field_.size()) {
63468       _has_field_.set(field.id());
63469     }
63470     switch (field.id()) {
63471       case 1 /* success */:
63472         field.get(&success_);
63473         break;
63474       case 2 /* service_id */:
63475         field.get(&service_id_);
63476         break;
63477       case 3 /* methods */:
63478         methods_.emplace_back();
63479         methods_.back().ParseFromArray(field.data(), field.size());
63480         break;
63481       default:
63482         field.SerializeAndAppendTo(&unknown_fields_);
63483         break;
63484     }
63485   }
63486   return !packed_error && !dec.bytes_left();
63487 }
63488 
SerializeAsString() const63489 std::string IPCFrame_BindServiceReply::SerializeAsString() const {
63490   ::protozero::HeapBuffered<::protozero::Message> msg;
63491   Serialize(msg.get());
63492   return msg.SerializeAsString();
63493 }
63494 
SerializeAsArray() const63495 std::vector<uint8_t> IPCFrame_BindServiceReply::SerializeAsArray() const {
63496   ::protozero::HeapBuffered<::protozero::Message> msg;
63497   Serialize(msg.get());
63498   return msg.SerializeAsArray();
63499 }
63500 
Serialize(::protozero::Message * msg) const63501 void IPCFrame_BindServiceReply::Serialize(::protozero::Message* msg) const {
63502   // Field 1: success
63503   if (_has_field_[1]) {
63504     msg->AppendTinyVarInt(1, success_);
63505   }
63506 
63507   // Field 2: service_id
63508   if (_has_field_[2]) {
63509     msg->AppendVarInt(2, service_id_);
63510   }
63511 
63512   // Field 3: methods
63513   for (auto& it : methods_) {
63514     it.Serialize(msg->BeginNestedMessage<::protozero::Message>(3));
63515   }
63516 
63517   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
63518 }
63519 
63520 
63521 IPCFrame_BindServiceReply_MethodInfo::IPCFrame_BindServiceReply_MethodInfo() = default;
63522 IPCFrame_BindServiceReply_MethodInfo::~IPCFrame_BindServiceReply_MethodInfo() = default;
63523 IPCFrame_BindServiceReply_MethodInfo::IPCFrame_BindServiceReply_MethodInfo(const IPCFrame_BindServiceReply_MethodInfo&) = default;
63524 IPCFrame_BindServiceReply_MethodInfo& IPCFrame_BindServiceReply_MethodInfo::operator=(const IPCFrame_BindServiceReply_MethodInfo&) = default;
63525 IPCFrame_BindServiceReply_MethodInfo::IPCFrame_BindServiceReply_MethodInfo(IPCFrame_BindServiceReply_MethodInfo&&) noexcept = default;
63526 IPCFrame_BindServiceReply_MethodInfo& IPCFrame_BindServiceReply_MethodInfo::operator=(IPCFrame_BindServiceReply_MethodInfo&&) = default;
63527 
operator ==(const IPCFrame_BindServiceReply_MethodInfo & other) const63528 bool IPCFrame_BindServiceReply_MethodInfo::operator==(const IPCFrame_BindServiceReply_MethodInfo& other) const {
63529   return unknown_fields_ == other.unknown_fields_
63530    && id_ == other.id_
63531    && name_ == other.name_;
63532 }
63533 
ParseFromArray(const void * raw,size_t size)63534 bool IPCFrame_BindServiceReply_MethodInfo::ParseFromArray(const void* raw, size_t size) {
63535   unknown_fields_.clear();
63536   bool packed_error = false;
63537 
63538   ::protozero::ProtoDecoder dec(raw, size);
63539   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
63540     if (field.id() < _has_field_.size()) {
63541       _has_field_.set(field.id());
63542     }
63543     switch (field.id()) {
63544       case 1 /* id */:
63545         field.get(&id_);
63546         break;
63547       case 2 /* name */:
63548         field.get(&name_);
63549         break;
63550       default:
63551         field.SerializeAndAppendTo(&unknown_fields_);
63552         break;
63553     }
63554   }
63555   return !packed_error && !dec.bytes_left();
63556 }
63557 
SerializeAsString() const63558 std::string IPCFrame_BindServiceReply_MethodInfo::SerializeAsString() const {
63559   ::protozero::HeapBuffered<::protozero::Message> msg;
63560   Serialize(msg.get());
63561   return msg.SerializeAsString();
63562 }
63563 
SerializeAsArray() const63564 std::vector<uint8_t> IPCFrame_BindServiceReply_MethodInfo::SerializeAsArray() const {
63565   ::protozero::HeapBuffered<::protozero::Message> msg;
63566   Serialize(msg.get());
63567   return msg.SerializeAsArray();
63568 }
63569 
Serialize(::protozero::Message * msg) const63570 void IPCFrame_BindServiceReply_MethodInfo::Serialize(::protozero::Message* msg) const {
63571   // Field 1: id
63572   if (_has_field_[1]) {
63573     msg->AppendVarInt(1, id_);
63574   }
63575 
63576   // Field 2: name
63577   if (_has_field_[2]) {
63578     msg->AppendString(2, name_);
63579   }
63580 
63581   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
63582 }
63583 
63584 
63585 IPCFrame_BindService::IPCFrame_BindService() = default;
63586 IPCFrame_BindService::~IPCFrame_BindService() = default;
63587 IPCFrame_BindService::IPCFrame_BindService(const IPCFrame_BindService&) = default;
63588 IPCFrame_BindService& IPCFrame_BindService::operator=(const IPCFrame_BindService&) = default;
63589 IPCFrame_BindService::IPCFrame_BindService(IPCFrame_BindService&&) noexcept = default;
63590 IPCFrame_BindService& IPCFrame_BindService::operator=(IPCFrame_BindService&&) = default;
63591 
operator ==(const IPCFrame_BindService & other) const63592 bool IPCFrame_BindService::operator==(const IPCFrame_BindService& other) const {
63593   return unknown_fields_ == other.unknown_fields_
63594    && service_name_ == other.service_name_;
63595 }
63596 
ParseFromArray(const void * raw,size_t size)63597 bool IPCFrame_BindService::ParseFromArray(const void* raw, size_t size) {
63598   unknown_fields_.clear();
63599   bool packed_error = false;
63600 
63601   ::protozero::ProtoDecoder dec(raw, size);
63602   for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
63603     if (field.id() < _has_field_.size()) {
63604       _has_field_.set(field.id());
63605     }
63606     switch (field.id()) {
63607       case 1 /* service_name */:
63608         field.get(&service_name_);
63609         break;
63610       default:
63611         field.SerializeAndAppendTo(&unknown_fields_);
63612         break;
63613     }
63614   }
63615   return !packed_error && !dec.bytes_left();
63616 }
63617 
SerializeAsString() const63618 std::string IPCFrame_BindService::SerializeAsString() const {
63619   ::protozero::HeapBuffered<::protozero::Message> msg;
63620   Serialize(msg.get());
63621   return msg.SerializeAsString();
63622 }
63623 
SerializeAsArray() const63624 std::vector<uint8_t> IPCFrame_BindService::SerializeAsArray() const {
63625   ::protozero::HeapBuffered<::protozero::Message> msg;
63626   Serialize(msg.get());
63627   return msg.SerializeAsArray();
63628 }
63629 
Serialize(::protozero::Message * msg) const63630 void IPCFrame_BindService::Serialize(::protozero::Message* msg) const {
63631   // Field 1: service_name
63632   if (_has_field_[1]) {
63633     msg->AppendString(1, service_name_);
63634   }
63635 
63636   msg->AppendRawProtoBytes(unknown_fields_.data(), unknown_fields_.size());
63637 }
63638 
63639 }  // namespace perfetto
63640 }  // namespace protos
63641 }  // namespace gen
63642 #if defined(__GNUC__) || defined(__clang__)
63643 #pragma GCC diagnostic pop
63644 #endif
63645 // gen_amalgamated begin source: src/base/unix_socket.cc
63646 // gen_amalgamated begin header: include/perfetto/ext/base/unix_socket.h
63647 /*
63648  * Copyright (C) 2017 The Android Open Source Project
63649  *
63650  * Licensed under the Apache License, Version 2.0 (the "License");
63651  * you may not use this file except in compliance with the License.
63652  * You may obtain a copy of the License at
63653  *
63654  *      http://www.apache.org/licenses/LICENSE-2.0
63655  *
63656  * Unless required by applicable law or agreed to in writing, software
63657  * distributed under the License is distributed on an "AS IS" BASIS,
63658  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
63659  * See the License for the specific language governing permissions and
63660  * limitations under the License.
63661  */
63662 
63663 #ifndef INCLUDE_PERFETTO_EXT_BASE_UNIX_SOCKET_H_
63664 #define INCLUDE_PERFETTO_EXT_BASE_UNIX_SOCKET_H_
63665 
63666 #include <stdint.h>
63667 #include <sys/types.h>
63668 
63669 #include <memory>
63670 #include <string>
63671 
63672 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
63673 // gen_amalgamated expanded: #include "perfetto/base/export.h"
63674 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
63675 // gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"
63676 // gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
63677 // gen_amalgamated expanded: #include "perfetto/ext/base/weak_ptr.h"
63678 
63679 struct msghdr;
63680 
63681 namespace perfetto {
63682 namespace base {
63683 
63684 // Define the SocketHandle and ScopedSocketHandle types.
63685 // On POSIX OSes, a SocketHandle is really just an int (a file descriptor).
63686 // On Windows, sockets are have their own type (SOCKET) which is neither a
63687 // HANDLE nor an int. However Windows SOCKET(s) can have a event HANDLE attached
63688 // to them (which in Perfetto is a PlatformHandle), and that can be used in
63689 // WaitForMultipleObjects, hence in base::TaskRunner.AddFileDescriptorWatch().
63690 
63691 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
63692 // uintptr_t really reads as SOCKET here (Windows headers typedef to that).
63693 // As usual we don't just use SOCKET here to avoid leaking Windows.h includes
63694 // in our headers.
63695 using SocketHandle = uintptr_t;  // SOCKET
63696 int CloseSocket(SocketHandle);   // A wrapper around ::closesocket().
63697 using ScopedSocketHandle =
63698     ScopedResource<SocketHandle, CloseSocket, static_cast<SocketHandle>(-1)>;
63699 #else
63700 using SocketHandle = int;
63701 using ScopedSocketHandle = ScopedFile;
63702 #endif
63703 
63704 class TaskRunner;
63705 
63706 // Use arbitrarily high values to avoid that some code accidentally ends up
63707 // assuming that these enum values match the sysroot's SOCK_xxx defines rather
63708 // than using GetSockType() / GetSockFamily().
63709 enum class SockType { kStream = 100, kDgram, kSeqPacket };
63710 enum class SockFamily { kUnix = 200, kInet, kInet6 };
63711 
63712 // Controls the getsockopt(SO_PEERCRED) behavior, which allows to obtain the
63713 // peer credentials.
63714 enum class SockPeerCredMode {
63715   // Obtain the peer credentials immediatley after connection and cache them.
63716   kReadOnConnect = 0,
63717 
63718   // Don't read peer credentials at all. Calls to peer_uid()/peer_pid() will
63719   // hit a DCHECK and return kInvalidUid/Pid in release builds.
63720   kIgnore = 1,
63721 
63722 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
63723   kDefault = kIgnore,
63724 #else
63725   kDefault = kReadOnConnect,
63726 #endif
63727 };
63728 
63729 // UnixSocketRaw is a basic wrapper around sockets. It exposes wrapper
63730 // methods that take care of most common pitfalls (e.g., marking fd as
63731 // O_CLOEXEC, avoiding SIGPIPE, properly handling partial writes). It is used as
63732 // a building block for the more sophisticated UnixSocket class which depends
63733 // on base::TaskRunner.
63734 class UnixSocketRaw {
63735  public:
63736   // Creates a new unconnected unix socket.
63737   static UnixSocketRaw CreateMayFail(SockFamily family, SockType type);
63738 
63739 #if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
63740   // Crates a pair of connected sockets.
63741   static std::pair<UnixSocketRaw, UnixSocketRaw> CreatePairPosix(SockFamily,
63742                                                                  SockType);
63743 #endif
63744 
63745   // Creates an uninitialized unix socket.
63746   UnixSocketRaw();
63747 
63748   // Creates a unix socket adopting an existing file descriptor. This is
63749   // typically used to inherit fds from init via environment variables.
63750   UnixSocketRaw(ScopedSocketHandle, SockFamily, SockType);
63751 
63752   ~UnixSocketRaw() = default;
63753   UnixSocketRaw(UnixSocketRaw&&) noexcept = default;
63754   UnixSocketRaw& operator=(UnixSocketRaw&&) = default;
63755 
63756   bool Bind(const std::string& socket_name);
63757   bool Listen();
63758   bool Connect(const std::string& socket_name);
63759   bool SetTxTimeout(uint32_t timeout_ms);
63760   bool SetRxTimeout(uint32_t timeout_ms);
63761   void Shutdown();
63762   void SetBlocking(bool);
63763   void DcheckIsBlocking(bool expected) const;  // No-op on release and Win.
63764   void RetainOnExec();
type() const63765   SockType type() const { return type_; }
family() const63766   SockFamily family() const { return family_; }
fd() const63767   SocketHandle fd() const { return *fd_; }
operator bool() const63768   explicit operator bool() const { return !!fd_; }
63769 
63770   // This is the handle that passed to TaskRunner.AddFileDescriptorWatch().
63771   // On UNIX this is just the socket FD. On Windows, we need to create a
63772   // dedicated event object.
watch_handle() const63773   PlatformHandle watch_handle() const {
63774 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
63775     return *event_handle_;
63776 #else
63777     return *fd_;
63778 #endif
63779   }
63780 
ReleaseFd()63781   ScopedSocketHandle ReleaseFd() { return std::move(fd_); }
63782 
63783   // |send_fds| and |num_fds| are ignored on Windows.
63784   ssize_t Send(const void* msg,
63785                size_t len,
63786                const int* send_fds = nullptr,
63787                size_t num_fds = 0);
63788 
SendStr(const std::string & str)63789   ssize_t SendStr(const std::string& str) {
63790     return Send(str.data(), str.size());
63791   }
63792 
63793   // |fd_vec| and |max_files| are ignored on Windows.
63794   ssize_t Receive(void* msg,
63795                   size_t len,
63796                   ScopedFile* fd_vec = nullptr,
63797                   size_t max_files = 0);
63798 
63799 #if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
63800   // UNIX-specific helpers to deal with SCM_RIGHTS.
63801 
63802   // Re-enter sendmsg until all the data has been sent or an error occurs.
63803   // TODO(fmayer): Figure out how to do timeouts here for heapprofd.
63804   ssize_t SendMsgAllPosix(struct msghdr* msg);
63805 
63806   // Exposed for testing only.
63807   // Update msghdr so subsequent sendmsg will send data that remains after n
63808   // bytes have already been sent.
63809   static void ShiftMsgHdrPosix(size_t n, struct msghdr* msg);
63810 #endif
63811 
63812  private:
63813   UnixSocketRaw(SockFamily, SockType);
63814 
63815   UnixSocketRaw(const UnixSocketRaw&) = delete;
63816   UnixSocketRaw& operator=(const UnixSocketRaw&) = delete;
63817 
63818   ScopedSocketHandle fd_;
63819 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
63820   ScopedPlatformHandle event_handle_;
63821 #endif
63822   SockFamily family_ = SockFamily::kUnix;
63823   SockType type_ = SockType::kStream;
63824   uint32_t tx_timeout_ms_ = 0;
63825 };
63826 
63827 // A non-blocking UNIX domain socket. Allows also to transfer file descriptors.
63828 // None of the methods in this class are blocking.
63829 // The main design goal is making strong guarantees on the EventListener
63830 // callbacks, in order to avoid ending in some undefined state.
63831 // In case of any error it will aggressively just shut down the socket and
63832 // notify the failure with OnConnect(false) or OnDisconnect() depending on the
63833 // state of the socket (see below).
63834 // EventListener callbacks stop happening as soon as the instance is destroyed.
63835 //
63836 // Lifecycle of a client socket:
63837 //
63838 //                           Connect()
63839 //                               |
63840 //            +------------------+------------------+
63841 //            | (success)                           | (failure or Shutdown())
63842 //            V                                     V
63843 //     OnConnect(true)                         OnConnect(false)
63844 //            |
63845 //            V
63846 //    OnDataAvailable()
63847 //            |
63848 //            V
63849 //     OnDisconnect()  (failure or shutdown)
63850 //
63851 //
63852 // Lifecycle of a server socket:
63853 //
63854 //                          Listen()  --> returns false in case of errors.
63855 //                             |
63856 //                             V
63857 //              OnNewIncomingConnection(new_socket)
63858 //
63859 //          (|new_socket| inherits the same EventListener)
63860 //                             |
63861 //                             V
63862 //                     OnDataAvailable()
63863 //                             | (failure or Shutdown())
63864 //                             V
63865 //                       OnDisconnect()
63866 class PERFETTO_EXPORT UnixSocket {
63867  public:
63868   class EventListener {
63869    public:
63870     virtual ~EventListener();
63871 
63872     // After Listen().
63873     virtual void OnNewIncomingConnection(
63874         UnixSocket* self,
63875         std::unique_ptr<UnixSocket> new_connection);
63876 
63877     // After Connect(), whether successful or not.
63878     virtual void OnConnect(UnixSocket* self, bool connected);
63879 
63880     // After a successful Connect() or OnNewIncomingConnection(). Either the
63881     // other endpoint did disconnect or some other error happened.
63882     virtual void OnDisconnect(UnixSocket* self);
63883 
63884     // Whenever there is data available to Receive(). Note that spurious FD
63885     // watch events are possible, so it is possible that Receive() soon after
63886     // OnDataAvailable() returns 0 (just ignore those).
63887     virtual void OnDataAvailable(UnixSocket* self);
63888   };
63889 
63890   enum class State {
63891     kDisconnected = 0,  // Failed connection, peer disconnection or Shutdown().
63892     kConnecting,  // Soon after Connect(), before it either succeeds or fails.
63893     kConnected,   // After a successful Connect().
63894     kListening    // After Listen(), until Shutdown().
63895   };
63896 
63897   // Creates a socket and starts listening. If SockFamily::kUnix and
63898   // |socket_name| starts with a '@', an abstract UNIX dmoain socket will be
63899   // created instead of a filesystem-linked UNIX socket (Linux/Android only).
63900   // If SockFamily::kInet, |socket_name| is host:port (e.g., "1.2.3.4:8000").
63901   // If SockFamily::kInet6, |socket_name| is [host]:port (e.g., "[::1]:8000").
63902   // Returns nullptr if the socket creation or bind fails. If listening fails,
63903   // (e.g. if another socket with the same name is already listening) the
63904   // returned socket will have is_listening() == false.
63905   static std::unique_ptr<UnixSocket> Listen(const std::string& socket_name,
63906                                             EventListener*,
63907                                             TaskRunner*,
63908                                             SockFamily,
63909                                             SockType);
63910 
63911   // Attaches to a pre-existing socket. The socket must have been created in
63912   // SOCK_STREAM mode and the caller must have called bind() on it.
63913   static std::unique_ptr<UnixSocket> Listen(ScopedSocketHandle,
63914                                             EventListener*,
63915                                             TaskRunner*,
63916                                             SockFamily,
63917                                             SockType);
63918 
63919   // Creates a Unix domain socket and connects to the listening endpoint.
63920   // Returns always an instance. EventListener::OnConnect(bool success) will
63921   // be called always, whether the connection succeeded or not.
63922   static std::unique_ptr<UnixSocket> Connect(
63923       const std::string& socket_name,
63924       EventListener*,
63925       TaskRunner*,
63926       SockFamily,
63927       SockType,
63928       SockPeerCredMode = SockPeerCredMode::kDefault);
63929 
63930   // Constructs a UnixSocket using the given connected socket.
63931   static std::unique_ptr<UnixSocket> AdoptConnected(
63932       ScopedSocketHandle,
63933       EventListener*,
63934       TaskRunner*,
63935       SockFamily,
63936       SockType,
63937       SockPeerCredMode = SockPeerCredMode::kDefault);
63938 
63939   UnixSocket(const UnixSocket&) = delete;
63940   UnixSocket& operator=(const UnixSocket&) = delete;
63941   // Cannot be easily moved because of tasks from the FileDescriptorWatch.
63942   UnixSocket(UnixSocket&&) = delete;
63943   UnixSocket& operator=(UnixSocket&&) = delete;
63944 
63945   // This class gives the hard guarantee that no callback is called on the
63946   // passed EventListener immediately after the object has been destroyed.
63947   // Any queued callback will be silently dropped.
63948   ~UnixSocket();
63949 
63950   // Shuts down the current connection, if any. If the socket was Listen()-ing,
63951   // stops listening. The socket goes back to kNotInitialized state, so it can
63952   // be reused with Listen() or Connect().
63953   void Shutdown(bool notify);
63954 
SetTxTimeout(uint32_t timeout_ms)63955   void SetTxTimeout(uint32_t timeout_ms) {
63956     PERFETTO_CHECK(sock_raw_.SetTxTimeout(timeout_ms));
63957   }
SetRxTimeout(uint32_t timeout_ms)63958   void SetRxTimeout(uint32_t timeout_ms) {
63959     PERFETTO_CHECK(sock_raw_.SetRxTimeout(timeout_ms));
63960   }
63961   // Returns true is the message was queued, false if there was no space in the
63962   // output buffer, in which case the client should retry or give up.
63963   // If any other error happens the socket will be shutdown and
63964   // EventListener::OnDisconnect() will be called.
63965   // If the socket is not connected, Send() will just return false.
63966   // Does not append a null string terminator to msg in any case.
63967   bool Send(const void* msg, size_t len, const int* send_fds, size_t num_fds);
63968 
Send(const void * msg,size_t len,int send_fd=-1)63969   inline bool Send(const void* msg, size_t len, int send_fd = -1) {
63970     if (send_fd != -1)
63971       return Send(msg, len, &send_fd, 1);
63972     return Send(msg, len, nullptr, 0);
63973   }
63974 
SendStr(const std::string & msg)63975   inline bool SendStr(const std::string& msg) {
63976     return Send(msg.data(), msg.size(), -1);
63977   }
63978 
63979   // Returns the number of bytes (<= |len|) written in |msg| or 0 if there
63980   // is no data in the buffer to read or an error occurs (in which case a
63981   // EventListener::OnDisconnect() will follow).
63982   // If the ScopedFile pointer is not null and a FD is received, it moves the
63983   // received FD into that. If a FD is received but the ScopedFile pointer is
63984   // null, the FD will be automatically closed.
63985   size_t Receive(void* msg, size_t len, ScopedFile*, size_t max_files = 1);
63986 
Receive(void * msg,size_t len)63987   inline size_t Receive(void* msg, size_t len) {
63988     return Receive(msg, len, nullptr, 0);
63989   }
63990 
63991   // Only for tests. This is slower than Receive() as it requires a heap
63992   // allocation and a copy for the std::string. Guarantees that the returned
63993   // string is null terminated even if the underlying message sent by the peer
63994   // is not.
63995   std::string ReceiveString(size_t max_length = 1024);
63996 
is_connected() const63997   bool is_connected() const { return state_ == State::kConnected; }
is_listening() const63998   bool is_listening() const { return state_ == State::kListening; }
fd() const63999   SocketHandle fd() const { return sock_raw_.fd(); }
64000 
64001   // User ID of the peer, as returned by the kernel. If the client disconnects
64002   // and the socket goes into the kDisconnected state, it retains the uid of
64003   // the last peer.
64004 #if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
peer_uid_posix(bool skip_check_for_testing=false) const64005   uid_t peer_uid_posix(bool skip_check_for_testing = false) const {
64006     PERFETTO_DCHECK((!is_listening() && peer_uid_ != kInvalidUid) ||
64007                     skip_check_for_testing);
64008 
64009     return peer_uid_;
64010   }
64011 #endif
64012 
64013 #if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
64014     PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
64015   // Process ID of the peer, as returned by the kernel. If the client
64016   // disconnects and the socket goes into the kDisconnected state, it
64017   // retains the pid of the last peer.
64018   //
64019   // This is only available on Linux / Android.
peer_pid_linux(bool skip_check_for_testing=false) const64020   pid_t peer_pid_linux(bool skip_check_for_testing = false) const {
64021     PERFETTO_DCHECK((!is_listening() && peer_pid_ != kInvalidPid) ||
64022                     skip_check_for_testing);
64023     return peer_pid_;
64024   }
64025 #endif
64026 
64027   // This makes the UnixSocket unusable.
64028   UnixSocketRaw ReleaseSocket();
64029 
64030  private:
64031   UnixSocket(EventListener*,
64032              TaskRunner*,
64033              SockFamily,
64034              SockType,
64035              SockPeerCredMode);
64036   UnixSocket(EventListener*,
64037              TaskRunner*,
64038              ScopedSocketHandle,
64039              State,
64040              SockFamily,
64041              SockType,
64042              SockPeerCredMode);
64043 
64044   // Called once by the corresponding public static factory methods.
64045   void DoConnect(const std::string& socket_name);
64046 
64047 #if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
64048   void ReadPeerCredentialsPosix();
64049 #endif
64050 
64051   void OnEvent();
64052   void NotifyConnectionState(bool success);
64053 
64054   UnixSocketRaw sock_raw_;
64055   State state_ = State::kDisconnected;
64056   SockPeerCredMode peer_cred_mode_ = SockPeerCredMode::kDefault;
64057 
64058 #if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
64059   uid_t peer_uid_ = kInvalidUid;
64060 #endif
64061 #if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
64062     PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
64063   pid_t peer_pid_ = kInvalidPid;
64064 #endif
64065   EventListener* const event_listener_;
64066   TaskRunner* const task_runner_;
64067   WeakPtrFactory<UnixSocket> weak_ptr_factory_;  // Keep last.
64068 };
64069 
64070 }  // namespace base
64071 }  // namespace perfetto
64072 
64073 #endif  // INCLUDE_PERFETTO_EXT_BASE_UNIX_SOCKET_H_
64074 /*
64075  * Copyright (C) 2017 The Android Open Source Project
64076  *
64077  * Licensed under the Apache License, Version 2.0 (the "License");
64078  * you may not use this file except in compliance with the License.
64079  * You may obtain a copy of the License at
64080  *
64081  *      http://www.apache.org/licenses/LICENSE-2.0
64082  *
64083  * Unless required by applicable law or agreed to in writing, software
64084  * distributed under the License is distributed on an "AS IS" BASIS,
64085  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
64086  * See the License for the specific language governing permissions and
64087  * limitations under the License.
64088  */
64089 
64090 // gen_amalgamated expanded: #include "perfetto/ext/base/unix_socket.h"
64091 
64092 #include <errno.h>
64093 #include <fcntl.h>
64094 #include <stdlib.h>
64095 #include <string.h>
64096 #include <sys/stat.h>
64097 #include <sys/types.h>
64098 // gen_amalgamated expanded: #include "perfetto/base/compiler.h"
64099 
64100 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
64101 // The include order matters on these three Windows header groups.
64102 #include <Windows.h>
64103 
64104 #include <WS2tcpip.h>
64105 #include <WinSock2.h>
64106 
64107 #include <afunix.h>
64108 #else
64109 #include <netdb.h>
64110 #include <netinet/in.h>
64111 #include <netinet/tcp.h>
64112 #include <poll.h>
64113 #include <sys/socket.h>
64114 #include <sys/un.h>
64115 #include <unistd.h>
64116 #endif
64117 
64118 #if PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
64119 #include <sys/ucred.h>
64120 #endif
64121 
64122 #include <algorithm>
64123 #include <memory>
64124 
64125 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
64126 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
64127 // gen_amalgamated expanded: #include "perfetto/base/task_runner.h"
64128 // gen_amalgamated expanded: #include "perfetto/base/time.h"
64129 // gen_amalgamated expanded: #include "perfetto/ext/base/string_utils.h"
64130 // gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
64131 
64132 namespace perfetto {
64133 namespace base {
64134 
64135 // The CMSG_* macros use NULL instead of nullptr.
64136 // Note: MSVC doesn't have #pragma GCC diagnostic, hence the if __GNUC__.
64137 #if defined(__GNUC__) && !PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
64138 #pragma GCC diagnostic push
64139 #pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant"
64140 #endif
64141 
64142 namespace {
64143 
64144 // Android takes an int instead of socklen_t for the control buffer size.
64145 #if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
64146 using CBufLenType = size_t;
64147 #else
64148 using CBufLenType = socklen_t;
64149 #endif
64150 
64151 // A wrapper around variable-size sockaddr structs.
64152 // This is solving the following problem: when calling connect() or bind(), the
64153 // caller needs to take care to allocate the right struct (sockaddr_un for
64154 // AF_UNIX, sockaddr_in for AF_INET).   Those structs have different sizes and,
64155 // more importantly, are bigger than the base struct sockaddr.
64156 struct SockaddrAny {
SockaddrAnyperfetto::base::__anon3c415f21cf11::SockaddrAny64157   SockaddrAny() : size() {}
SockaddrAnyperfetto::base::__anon3c415f21cf11::SockaddrAny64158   SockaddrAny(const void* addr, socklen_t sz)
64159       : data(new char[static_cast<size_t>(sz)]), size(sz) {
64160     memcpy(data.get(), addr, static_cast<size_t>(size));
64161   }
64162 
addrperfetto::base::__anon3c415f21cf11::SockaddrAny64163   const struct sockaddr* addr() const {
64164     return reinterpret_cast<const struct sockaddr*>(data.get());
64165   }
64166 
64167   std::unique_ptr<char[]> data;
64168   socklen_t size;
64169 };
64170 
GetSockFamily(SockFamily family)64171 inline int GetSockFamily(SockFamily family) {
64172   switch (family) {
64173     case SockFamily::kUnix:
64174       return AF_UNIX;
64175     case SockFamily::kInet:
64176       return AF_INET;
64177     case SockFamily::kInet6:
64178       return AF_INET6;
64179   }
64180   PERFETTO_CHECK(false);  // For GCC.
64181 }
64182 
GetSockType(SockType type)64183 inline int GetSockType(SockType type) {
64184 #ifdef SOCK_CLOEXEC
64185   constexpr int kSockCloExec = SOCK_CLOEXEC;
64186 #else
64187   constexpr int kSockCloExec = 0;
64188 #endif
64189   switch (type) {
64190     case SockType::kStream:
64191       return SOCK_STREAM | kSockCloExec;
64192     case SockType::kDgram:
64193       return SOCK_DGRAM | kSockCloExec;
64194     case SockType::kSeqPacket:
64195       return SOCK_SEQPACKET | kSockCloExec;
64196   }
64197   PERFETTO_CHECK(false);  // For GCC.
64198 }
64199 
MakeSockAddr(SockFamily family,const std::string & socket_name)64200 SockaddrAny MakeSockAddr(SockFamily family, const std::string& socket_name) {
64201   switch (family) {
64202     case SockFamily::kUnix: {
64203       struct sockaddr_un saddr {};
64204       const size_t name_len = socket_name.size();
64205       if (name_len >= sizeof(saddr.sun_path)) {
64206         errno = ENAMETOOLONG;
64207         return SockaddrAny();
64208       }
64209       memcpy(saddr.sun_path, socket_name.data(), name_len);
64210       if (saddr.sun_path[0] == '@') {
64211         saddr.sun_path[0] = '\0';
64212 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
64213         // The MSDN blog claims that abstract (non-filesystem based) AF_UNIX
64214         // socket are supported, but that doesn't seem true.
64215         PERFETTO_ELOG(
64216             "Abstract AF_UNIX sockets are not supported on Windows, see "
64217             "https://github.com/microsoft/WSL/issues/4240");
64218         return SockaddrAny{};
64219 #endif
64220       }
64221       saddr.sun_family = AF_UNIX;
64222       auto size = static_cast<socklen_t>(
64223           __builtin_offsetof(sockaddr_un, sun_path) + name_len + 1);
64224       PERFETTO_CHECK(static_cast<size_t>(size) <= sizeof(saddr));
64225       return SockaddrAny(&saddr, size);
64226     }
64227     case SockFamily::kInet: {
64228       auto parts = SplitString(socket_name, ":");
64229       PERFETTO_CHECK(parts.size() == 2);
64230       struct addrinfo* addr_info = nullptr;
64231       struct addrinfo hints {};
64232       hints.ai_family = AF_INET;
64233       PERFETTO_CHECK(getaddrinfo(parts[0].c_str(), parts[1].c_str(), &hints,
64234                                  &addr_info) == 0);
64235       PERFETTO_CHECK(addr_info->ai_family == AF_INET);
64236       SockaddrAny res(addr_info->ai_addr,
64237                       static_cast<socklen_t>(addr_info->ai_addrlen));
64238       freeaddrinfo(addr_info);
64239       return res;
64240     }
64241     case SockFamily::kInet6: {
64242       auto parts = SplitString(socket_name, "]");
64243       PERFETTO_CHECK(parts.size() == 2);
64244       auto address = SplitString(parts[0], "[");
64245       PERFETTO_CHECK(address.size() == 1);
64246       auto port = SplitString(parts[1], ":");
64247       PERFETTO_CHECK(port.size() == 1);
64248       struct addrinfo* addr_info = nullptr;
64249       struct addrinfo hints {};
64250       hints.ai_family = AF_INET6;
64251       PERFETTO_CHECK(getaddrinfo(address[0].c_str(), port[0].c_str(), &hints,
64252                                  &addr_info) == 0);
64253       PERFETTO_CHECK(addr_info->ai_family == AF_INET6);
64254       SockaddrAny res(addr_info->ai_addr,
64255                       static_cast<socklen_t>(addr_info->ai_addrlen));
64256       freeaddrinfo(addr_info);
64257       return res;
64258     }
64259   }
64260   PERFETTO_CHECK(false);  // For GCC.
64261 }
64262 
CreateSocketHandle(SockFamily family,SockType type)64263 ScopedSocketHandle CreateSocketHandle(SockFamily family, SockType type) {
64264 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
64265   static bool init_winsock_once = [] {
64266     WSADATA ignored{};
64267     return WSAStartup(MAKEWORD(2, 2), &ignored) == 0;
64268   }();
64269   PERFETTO_CHECK(init_winsock_once);
64270 #endif
64271   return ScopedSocketHandle(
64272       socket(GetSockFamily(family), GetSockType(type), 0));
64273 }
64274 
64275 }  // namespace
64276 
64277 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
CloseSocket(SocketHandle s)64278 int CloseSocket(SocketHandle s) {
64279   return ::closesocket(s);
64280 }
64281 #endif
64282 
64283 // +-----------------------+
64284 // | UnixSocketRaw methods |
64285 // +-----------------------+
64286 
64287 #if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
64288 // static
ShiftMsgHdrPosix(size_t n,struct msghdr * msg)64289 void UnixSocketRaw::ShiftMsgHdrPosix(size_t n, struct msghdr* msg) {
64290   using LenType = decltype(msg->msg_iovlen);  // Mac and Linux don't agree.
64291   for (LenType i = 0; i < msg->msg_iovlen; ++i) {
64292     struct iovec* vec = &msg->msg_iov[i];
64293     if (n < vec->iov_len) {
64294       // We sent a part of this iovec.
64295       vec->iov_base = reinterpret_cast<char*>(vec->iov_base) + n;
64296       vec->iov_len -= n;
64297       msg->msg_iov = vec;
64298       msg->msg_iovlen -= i;
64299       return;
64300     }
64301     // We sent the whole iovec.
64302     n -= vec->iov_len;
64303   }
64304   // We sent all the iovecs.
64305   PERFETTO_CHECK(n == 0);
64306   msg->msg_iovlen = 0;
64307   msg->msg_iov = nullptr;
64308 }
64309 
64310 // static
CreatePairPosix(SockFamily family,SockType type)64311 std::pair<UnixSocketRaw, UnixSocketRaw> UnixSocketRaw::CreatePairPosix(
64312     SockFamily family,
64313     SockType type) {
64314   int fds[2];
64315   if (socketpair(GetSockFamily(family), GetSockType(type), 0, fds) != 0)
64316     return std::make_pair(UnixSocketRaw(), UnixSocketRaw());
64317 
64318   return std::make_pair(UnixSocketRaw(ScopedFile(fds[0]), family, type),
64319                         UnixSocketRaw(ScopedFile(fds[1]), family, type));
64320 }
64321 #endif
64322 
64323 // static
CreateMayFail(SockFamily family,SockType type)64324 UnixSocketRaw UnixSocketRaw::CreateMayFail(SockFamily family, SockType type) {
64325   auto fd = CreateSocketHandle(family, type);
64326   if (!fd)
64327     return UnixSocketRaw();
64328   return UnixSocketRaw(std::move(fd), family, type);
64329 }
64330 
64331 UnixSocketRaw::UnixSocketRaw() = default;
64332 
UnixSocketRaw(SockFamily family,SockType type)64333 UnixSocketRaw::UnixSocketRaw(SockFamily family, SockType type)
64334     : UnixSocketRaw(CreateSocketHandle(family, type), family, type) {}
64335 
UnixSocketRaw(ScopedSocketHandle fd,SockFamily family,SockType type)64336 UnixSocketRaw::UnixSocketRaw(ScopedSocketHandle fd,
64337                              SockFamily family,
64338                              SockType type)
64339     : fd_(std::move(fd)), family_(family), type_(type) {
64340   PERFETTO_CHECK(fd_);
64341 #if PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
64342   const int no_sigpipe = 1;
64343   setsockopt(*fd_, SOL_SOCKET, SO_NOSIGPIPE, &no_sigpipe, sizeof(no_sigpipe));
64344 #endif
64345 
64346   if (family == SockFamily::kInet || family == SockFamily::kInet6) {
64347     int flag = 1;
64348     // The reinterpret_cast<const char*> is needed for Windows, where the 4th
64349     // arg is a const char* (on other POSIX system is a const void*).
64350     PERFETTO_CHECK(!setsockopt(*fd_, SOL_SOCKET, SO_REUSEADDR,
64351                                reinterpret_cast<const char*>(&flag),
64352                                sizeof(flag)));
64353     flag = 1;
64354     // Disable Nagle's algorithm, optimize for low-latency.
64355     // See https://github.com/google/perfetto/issues/70.
64356     setsockopt(*fd_, IPPROTO_TCP, TCP_NODELAY,
64357                reinterpret_cast<const char*>(&flag), sizeof(flag));
64358   }
64359 
64360 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
64361   // We use one event handle for all socket events, to stay consistent to what
64362   // we do on UNIX with the base::TaskRunner's poll().
64363   event_handle_.reset(WSACreateEvent());
64364   PERFETTO_CHECK(event_handle_);
64365 #else
64366   // There is no reason why a socket should outlive the process in case of
64367   // exec() by default, this is just working around a broken unix design.
64368   int fcntl_res = fcntl(*fd_, F_SETFD, FD_CLOEXEC);
64369   PERFETTO_CHECK(fcntl_res == 0);
64370 #endif
64371 }
64372 
SetBlocking(bool is_blocking)64373 void UnixSocketRaw::SetBlocking(bool is_blocking) {
64374   PERFETTO_DCHECK(fd_);
64375 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
64376   unsigned long flag = is_blocking ? 0 : 1;  // FIONBIO has reverse logic.
64377   if (is_blocking) {
64378     // When switching between non-blocking -> blocking mode, we need to reset
64379     // the event handle registration, otherwise the call will fail.
64380     PERFETTO_CHECK(WSAEventSelect(*fd_, *event_handle_, 0) == 0);
64381   }
64382   PERFETTO_CHECK(ioctlsocket(*fd_, static_cast<long>(FIONBIO), &flag) == 0);
64383   if (!is_blocking) {
64384     PERFETTO_CHECK(
64385         WSAEventSelect(*fd_, *event_handle_,
64386                        FD_ACCEPT | FD_CONNECT | FD_READ | FD_CLOSE) == 0);
64387   }
64388 #else
64389   int flags = fcntl(*fd_, F_GETFL, 0);
64390   if (!is_blocking) {
64391     flags |= O_NONBLOCK;
64392   } else {
64393     flags &= ~static_cast<int>(O_NONBLOCK);
64394   }
64395   int fcntl_res = fcntl(*fd_, F_SETFL, flags);
64396   PERFETTO_CHECK(fcntl_res == 0);
64397 #endif
64398 }
64399 
RetainOnExec()64400 void UnixSocketRaw::RetainOnExec() {
64401 #if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
64402   PERFETTO_DCHECK(fd_);
64403   int flags = fcntl(*fd_, F_GETFD, 0);
64404   flags &= ~static_cast<int>(FD_CLOEXEC);
64405   int fcntl_res = fcntl(*fd_, F_SETFD, flags);
64406   PERFETTO_CHECK(fcntl_res == 0);
64407 #endif
64408 }
64409 
DcheckIsBlocking(bool expected) const64410 void UnixSocketRaw::DcheckIsBlocking(bool expected) const {
64411 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
64412   ignore_result(expected);
64413 #else
64414   PERFETTO_DCHECK(fd_);
64415   bool is_blocking = (fcntl(*fd_, F_GETFL, 0) & O_NONBLOCK) == 0;
64416   PERFETTO_DCHECK(is_blocking == expected);
64417 #endif
64418 }
64419 
Bind(const std::string & socket_name)64420 bool UnixSocketRaw::Bind(const std::string& socket_name) {
64421   PERFETTO_DCHECK(fd_);
64422   SockaddrAny addr = MakeSockAddr(family_, socket_name);
64423   if (addr.size == 0)
64424     return false;
64425 
64426   if (bind(*fd_, addr.addr(), addr.size)) {
64427     PERFETTO_DPLOG("bind(%s)", socket_name.c_str());
64428     return false;
64429   }
64430 
64431   return true;
64432 }
64433 
Listen()64434 bool UnixSocketRaw::Listen() {
64435   PERFETTO_DCHECK(fd_);
64436   PERFETTO_DCHECK(type_ == SockType::kStream || type_ == SockType::kSeqPacket);
64437   return listen(*fd_, SOMAXCONN) == 0;
64438 }
64439 
Connect(const std::string & socket_name)64440 bool UnixSocketRaw::Connect(const std::string& socket_name) {
64441   PERFETTO_DCHECK(fd_);
64442   SockaddrAny addr = MakeSockAddr(family_, socket_name);
64443   if (addr.size == 0)
64444     return false;
64445 
64446   int res = PERFETTO_EINTR(connect(*fd_, addr.addr(), addr.size));
64447 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
64448   bool continue_async = WSAGetLastError() == WSAEWOULDBLOCK;
64449 #else
64450   bool continue_async = errno == EINPROGRESS;
64451 #endif
64452   if (res && !continue_async)
64453     return false;
64454 
64455   return true;
64456 }
64457 
Shutdown()64458 void UnixSocketRaw::Shutdown() {
64459 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
64460   // Somebody felt very strongly about the naming of this constant.
64461   shutdown(*fd_, SD_BOTH);
64462 #else
64463   shutdown(*fd_, SHUT_RDWR);
64464 #endif
64465   fd_.reset();
64466 }
64467 
64468 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
64469 
Send(const void * msg,size_t len,const int *,size_t num_fds)64470 ssize_t UnixSocketRaw::Send(const void* msg,
64471                             size_t len,
64472                             const int* /*send_fds*/,
64473                             size_t num_fds) {
64474   PERFETTO_DCHECK(num_fds == 0);
64475   return sendto(*fd_, static_cast<const char*>(msg), static_cast<int>(len), 0,
64476                 nullptr, 0);
64477 }
64478 
Receive(void * msg,size_t len,ScopedFile *,size_t)64479 ssize_t UnixSocketRaw::Receive(void* msg,
64480                                size_t len,
64481                                ScopedFile* /*fd_vec*/,
64482                                size_t /*max_files*/) {
64483   return recv(*fd_, static_cast<char*>(msg), static_cast<int>(len), 0);
64484 }
64485 
64486 #else
64487 // For the interested reader, Linux kernel dive to verify this is not only a
64488 // theoretical possibility: sock_stream_sendmsg, if sock_alloc_send_pskb returns
64489 // NULL [1] (which it does when it gets interrupted [2]), returns early with the
64490 // amount of bytes already sent.
64491 //
64492 // [1]:
64493 // https://elixir.bootlin.com/linux/v4.18.10/source/net/unix/af_unix.c#L1872
64494 // [2]: https://elixir.bootlin.com/linux/v4.18.10/source/net/core/sock.c#L2101
SendMsgAllPosix(struct msghdr * msg)64495 ssize_t UnixSocketRaw::SendMsgAllPosix(struct msghdr* msg) {
64496   // This does not make sense on non-blocking sockets.
64497   PERFETTO_DCHECK(fd_);
64498 
64499   const bool is_blocking_with_timeout =
64500       tx_timeout_ms_ > 0 && ((fcntl(*fd_, F_GETFL, 0) & O_NONBLOCK) == 0);
64501   const int64_t start_ms = GetWallTimeMs().count();
64502 
64503   // Waits until some space is available in the tx buffer.
64504   // Returns true if some buffer space is available, false if times out.
64505   auto poll_or_timeout = [&] {
64506     PERFETTO_DCHECK(is_blocking_with_timeout);
64507     const int64_t deadline = start_ms + tx_timeout_ms_;
64508     const int64_t now_ms = GetWallTimeMs().count();
64509     if (now_ms >= deadline)
64510       return false;  // Timed out
64511     const int timeout_ms = static_cast<int>(deadline - now_ms);
64512     pollfd pfd{*fd_, POLLOUT, 0};
64513     return PERFETTO_EINTR(poll(&pfd, 1, timeout_ms)) > 0;
64514   };
64515 
64516 // We implement blocking sends that require a timeout as non-blocking + poll.
64517 // This is because SO_SNDTIMEO doesn't work as expected (b/193234818). On linux
64518 // we can just pass MSG_DONTWAIT to force the send to be non-blocking. On Mac,
64519 // instead we need to flip the O_NONBLOCK flag back and forth.
64520 #if PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
64521   // MSG_NOSIGNAL is not supported on Mac OS X, but in that case the socket is
64522   // created with SO_NOSIGPIPE (See InitializeSocket()).
64523   int send_flags = 0;
64524 
64525   if (is_blocking_with_timeout)
64526     SetBlocking(false);
64527 
64528   auto reset_nonblock_on_exit = OnScopeExit([&] {
64529     if (is_blocking_with_timeout)
64530       SetBlocking(true);
64531   });
64532 #else
64533   int send_flags = MSG_NOSIGNAL | (is_blocking_with_timeout ? MSG_DONTWAIT : 0);
64534 #endif
64535 
64536   ssize_t total_sent = 0;
64537   while (msg->msg_iov) {
64538     ssize_t send_res = PERFETTO_EINTR(sendmsg(*fd_, msg, send_flags));
64539     if (send_res == -1 && IsAgain(errno)) {
64540       if (is_blocking_with_timeout && poll_or_timeout()) {
64541         continue;  // Tx buffer unblocked, repeat the loop.
64542       }
64543       return total_sent;
64544     } else if (send_res <= 0) {
64545       return send_res;  // An error occurred.
64546     } else {
64547       total_sent += send_res;
64548       ShiftMsgHdrPosix(static_cast<size_t>(send_res), msg);
64549       // Only send the ancillary data with the first sendmsg call.
64550       msg->msg_control = nullptr;
64551       msg->msg_controllen = 0;
64552     }
64553   }
64554   return total_sent;
64555 }
64556 
Send(const void * msg,size_t len,const int * send_fds,size_t num_fds)64557 ssize_t UnixSocketRaw::Send(const void* msg,
64558                             size_t len,
64559                             const int* send_fds,
64560                             size_t num_fds) {
64561   PERFETTO_DCHECK(fd_);
64562   msghdr msg_hdr = {};
64563   iovec iov = {const_cast<void*>(msg), len};
64564   msg_hdr.msg_iov = &iov;
64565   msg_hdr.msg_iovlen = 1;
64566   alignas(cmsghdr) char control_buf[256];
64567 
64568   if (num_fds > 0) {
64569     const auto raw_ctl_data_sz = num_fds * sizeof(int);
64570     const CBufLenType control_buf_len =
64571         static_cast<CBufLenType>(CMSG_SPACE(raw_ctl_data_sz));
64572     PERFETTO_CHECK(control_buf_len <= sizeof(control_buf));
64573     memset(control_buf, 0, sizeof(control_buf));
64574     msg_hdr.msg_control = control_buf;
64575     msg_hdr.msg_controllen = control_buf_len;  // used by CMSG_FIRSTHDR
64576     struct cmsghdr* cmsg = CMSG_FIRSTHDR(&msg_hdr);
64577     cmsg->cmsg_level = SOL_SOCKET;
64578     cmsg->cmsg_type = SCM_RIGHTS;
64579     cmsg->cmsg_len = static_cast<CBufLenType>(CMSG_LEN(raw_ctl_data_sz));
64580     memcpy(CMSG_DATA(cmsg), send_fds, num_fds * sizeof(int));
64581     // note: if we were to send multiple cmsghdr structures, then
64582     // msg_hdr.msg_controllen would need to be adjusted, see "man 3 cmsg".
64583   }
64584 
64585   return SendMsgAllPosix(&msg_hdr);
64586 }
64587 
Receive(void * msg,size_t len,ScopedFile * fd_vec,size_t max_files)64588 ssize_t UnixSocketRaw::Receive(void* msg,
64589                                size_t len,
64590                                ScopedFile* fd_vec,
64591                                size_t max_files) {
64592   PERFETTO_DCHECK(fd_);
64593   msghdr msg_hdr = {};
64594   iovec iov = {msg, len};
64595   msg_hdr.msg_iov = &iov;
64596   msg_hdr.msg_iovlen = 1;
64597   alignas(cmsghdr) char control_buf[256];
64598 
64599   if (max_files > 0) {
64600     msg_hdr.msg_control = control_buf;
64601     msg_hdr.msg_controllen =
64602         static_cast<CBufLenType>(CMSG_SPACE(max_files * sizeof(int)));
64603     PERFETTO_CHECK(msg_hdr.msg_controllen <= sizeof(control_buf));
64604   }
64605   const ssize_t sz = PERFETTO_EINTR(recvmsg(*fd_, &msg_hdr, 0));
64606   if (sz <= 0) {
64607     return sz;
64608   }
64609   PERFETTO_CHECK(static_cast<size_t>(sz) <= len);
64610 
64611   int* fds = nullptr;
64612   uint32_t fds_len = 0;
64613 
64614   if (max_files > 0) {
64615     for (cmsghdr* cmsg = CMSG_FIRSTHDR(&msg_hdr); cmsg;
64616          cmsg = CMSG_NXTHDR(&msg_hdr, cmsg)) {
64617       const size_t payload_len = cmsg->cmsg_len - CMSG_LEN(0);
64618       if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_RIGHTS) {
64619         PERFETTO_DCHECK(payload_len % sizeof(int) == 0u);
64620         PERFETTO_CHECK(fds == nullptr);
64621         fds = reinterpret_cast<int*>(CMSG_DATA(cmsg));
64622         fds_len = static_cast<uint32_t>(payload_len / sizeof(int));
64623       }
64624     }
64625   }
64626 
64627   if (msg_hdr.msg_flags & MSG_TRUNC || msg_hdr.msg_flags & MSG_CTRUNC) {
64628     for (size_t i = 0; fds && i < fds_len; ++i)
64629       close(fds[i]);
64630     PERFETTO_ELOG(
64631         "Socket message truncated. This might be due to a SELinux denial on "
64632         "fd:use.");
64633     errno = EMSGSIZE;
64634     return -1;
64635   }
64636 
64637   for (size_t i = 0; fds && i < fds_len; ++i) {
64638     if (i < max_files)
64639       fd_vec[i].reset(fds[i]);
64640     else
64641       close(fds[i]);
64642   }
64643 
64644   return sz;
64645 }
64646 #endif  // OS_WIN
64647 
SetTxTimeout(uint32_t timeout_ms)64648 bool UnixSocketRaw::SetTxTimeout(uint32_t timeout_ms) {
64649   PERFETTO_DCHECK(fd_);
64650   // On Unix-based systems, SO_SNDTIMEO isn't used for Send() because it's
64651   // unreliable (b/193234818). Instead we use non-blocking sendmsg() + poll().
64652   // See SendMsgAllPosix(). We still make the setsockopt call because
64653   // SO_SNDTIMEO also affects connect().
64654   tx_timeout_ms_ = timeout_ms;
64655 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
64656   DWORD timeout = timeout_ms;
64657   ignore_result(tx_timeout_ms_);
64658 #else
64659   struct timeval timeout {};
64660   uint32_t timeout_sec = timeout_ms / 1000;
64661   timeout.tv_sec = static_cast<decltype(timeout.tv_sec)>(timeout_sec);
64662   timeout.tv_usec = static_cast<decltype(timeout.tv_usec)>(
64663       (timeout_ms - (timeout_sec * 1000)) * 1000);
64664 #endif
64665   return setsockopt(*fd_, SOL_SOCKET, SO_SNDTIMEO,
64666                     reinterpret_cast<const char*>(&timeout),
64667                     sizeof(timeout)) == 0;
64668 }
64669 
SetRxTimeout(uint32_t timeout_ms)64670 bool UnixSocketRaw::SetRxTimeout(uint32_t timeout_ms) {
64671   PERFETTO_DCHECK(fd_);
64672 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
64673   DWORD timeout = timeout_ms;
64674 #else
64675   struct timeval timeout {};
64676   uint32_t timeout_sec = timeout_ms / 1000;
64677   timeout.tv_sec = static_cast<decltype(timeout.tv_sec)>(timeout_sec);
64678   timeout.tv_usec = static_cast<decltype(timeout.tv_usec)>(
64679       (timeout_ms - (timeout_sec * 1000)) * 1000);
64680 #endif
64681   return setsockopt(*fd_, SOL_SOCKET, SO_RCVTIMEO,
64682                     reinterpret_cast<const char*>(&timeout),
64683                     sizeof(timeout)) == 0;
64684 }
64685 
64686 #if defined(__GNUC__) && !PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
64687 #pragma GCC diagnostic pop
64688 #endif
64689 
64690 // +--------------------+
64691 // | UnixSocket methods |
64692 // +--------------------+
64693 
64694 // TODO(primiano): Add ThreadChecker to methods of this class.
64695 
64696 // static
Listen(const std::string & socket_name,EventListener * event_listener,TaskRunner * task_runner,SockFamily sock_family,SockType sock_type)64697 std::unique_ptr<UnixSocket> UnixSocket::Listen(const std::string& socket_name,
64698                                                EventListener* event_listener,
64699                                                TaskRunner* task_runner,
64700                                                SockFamily sock_family,
64701                                                SockType sock_type) {
64702   auto sock_raw = UnixSocketRaw::CreateMayFail(sock_family, sock_type);
64703   if (!sock_raw || !sock_raw.Bind(socket_name))
64704     return nullptr;
64705 
64706   // Forward the call to the Listen() overload below.
64707   return Listen(sock_raw.ReleaseFd(), event_listener, task_runner, sock_family,
64708                 sock_type);
64709 }
64710 
64711 // static
Listen(ScopedSocketHandle fd,EventListener * event_listener,TaskRunner * task_runner,SockFamily sock_family,SockType sock_type)64712 std::unique_ptr<UnixSocket> UnixSocket::Listen(ScopedSocketHandle fd,
64713                                                EventListener* event_listener,
64714                                                TaskRunner* task_runner,
64715                                                SockFamily sock_family,
64716                                                SockType sock_type) {
64717   return std::unique_ptr<UnixSocket>(new UnixSocket(
64718       event_listener, task_runner, std::move(fd), State::kListening,
64719       sock_family, sock_type, SockPeerCredMode::kDefault));
64720 }
64721 
64722 // static
Connect(const std::string & socket_name,EventListener * event_listener,TaskRunner * task_runner,SockFamily sock_family,SockType sock_type,SockPeerCredMode peer_cred_mode)64723 std::unique_ptr<UnixSocket> UnixSocket::Connect(
64724     const std::string& socket_name,
64725     EventListener* event_listener,
64726     TaskRunner* task_runner,
64727     SockFamily sock_family,
64728     SockType sock_type,
64729     SockPeerCredMode peer_cred_mode) {
64730   std::unique_ptr<UnixSocket> sock(new UnixSocket(
64731       event_listener, task_runner, sock_family, sock_type, peer_cred_mode));
64732   sock->DoConnect(socket_name);
64733   return sock;
64734 }
64735 
64736 // static
AdoptConnected(ScopedSocketHandle fd,EventListener * event_listener,TaskRunner * task_runner,SockFamily sock_family,SockType sock_type,SockPeerCredMode peer_cred_mode)64737 std::unique_ptr<UnixSocket> UnixSocket::AdoptConnected(
64738     ScopedSocketHandle fd,
64739     EventListener* event_listener,
64740     TaskRunner* task_runner,
64741     SockFamily sock_family,
64742     SockType sock_type,
64743     SockPeerCredMode peer_cred_mode) {
64744   return std::unique_ptr<UnixSocket>(new UnixSocket(
64745       event_listener, task_runner, std::move(fd), State::kConnected,
64746       sock_family, sock_type, peer_cred_mode));
64747 }
64748 
UnixSocket(EventListener * event_listener,TaskRunner * task_runner,SockFamily sock_family,SockType sock_type,SockPeerCredMode peer_cred_mode)64749 UnixSocket::UnixSocket(EventListener* event_listener,
64750                        TaskRunner* task_runner,
64751                        SockFamily sock_family,
64752                        SockType sock_type,
64753                        SockPeerCredMode peer_cred_mode)
64754     : UnixSocket(event_listener,
64755                  task_runner,
64756                  ScopedSocketHandle(),
64757                  State::kDisconnected,
64758                  sock_family,
64759                  sock_type,
64760                  peer_cred_mode) {}
64761 
UnixSocket(EventListener * event_listener,TaskRunner * task_runner,ScopedSocketHandle adopt_fd,State adopt_state,SockFamily sock_family,SockType sock_type,SockPeerCredMode peer_cred_mode)64762 UnixSocket::UnixSocket(EventListener* event_listener,
64763                        TaskRunner* task_runner,
64764                        ScopedSocketHandle adopt_fd,
64765                        State adopt_state,
64766                        SockFamily sock_family,
64767                        SockType sock_type,
64768                        SockPeerCredMode peer_cred_mode)
64769     : peer_cred_mode_(peer_cred_mode),
64770       event_listener_(event_listener),
64771       task_runner_(task_runner),
64772       weak_ptr_factory_(this) {
64773   state_ = State::kDisconnected;
64774   if (adopt_state == State::kDisconnected) {
64775     PERFETTO_DCHECK(!adopt_fd);
64776     sock_raw_ = UnixSocketRaw::CreateMayFail(sock_family, sock_type);
64777     if (!sock_raw_)
64778       return;
64779   } else if (adopt_state == State::kConnected) {
64780     PERFETTO_DCHECK(adopt_fd);
64781     sock_raw_ = UnixSocketRaw(std::move(adopt_fd), sock_family, sock_type);
64782     state_ = State::kConnected;
64783 #if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
64784     if (peer_cred_mode_ == SockPeerCredMode::kReadOnConnect)
64785       ReadPeerCredentialsPosix();
64786 #endif
64787   } else if (adopt_state == State::kListening) {
64788     // We get here from Listen().
64789 
64790     // |adopt_fd| might genuinely be invalid if the bind() failed.
64791     if (!adopt_fd)
64792       return;
64793 
64794     sock_raw_ = UnixSocketRaw(std::move(adopt_fd), sock_family, sock_type);
64795     if (!sock_raw_.Listen()) {
64796       PERFETTO_DPLOG("listen() failed");
64797       return;
64798     }
64799     state_ = State::kListening;
64800   } else {
64801     PERFETTO_FATAL("Unexpected adopt_state");  // Unfeasible.
64802   }
64803 
64804   PERFETTO_CHECK(sock_raw_);
64805 
64806   sock_raw_.SetBlocking(false);
64807 
64808   WeakPtr<UnixSocket> weak_ptr = weak_ptr_factory_.GetWeakPtr();
64809 
64810   task_runner_->AddFileDescriptorWatch(sock_raw_.watch_handle(), [weak_ptr] {
64811     if (weak_ptr)
64812       weak_ptr->OnEvent();
64813   });
64814 }
64815 
~UnixSocket()64816 UnixSocket::~UnixSocket() {
64817   // The implicit dtor of |weak_ptr_factory_| will no-op pending callbacks.
64818   Shutdown(true);
64819 }
64820 
ReleaseSocket()64821 UnixSocketRaw UnixSocket::ReleaseSocket() {
64822   // This will invalidate any pending calls to OnEvent.
64823   state_ = State::kDisconnected;
64824   if (sock_raw_)
64825     task_runner_->RemoveFileDescriptorWatch(sock_raw_.watch_handle());
64826 
64827   return std::move(sock_raw_);
64828 }
64829 
64830 // Called only by the Connect() static constructor.
DoConnect(const std::string & socket_name)64831 void UnixSocket::DoConnect(const std::string& socket_name) {
64832   PERFETTO_DCHECK(state_ == State::kDisconnected);
64833 
64834   // This is the only thing that can gracefully fail in the ctor.
64835   if (!sock_raw_)
64836     return NotifyConnectionState(false);
64837 
64838   if (!sock_raw_.Connect(socket_name))
64839     return NotifyConnectionState(false);
64840 
64841   // At this point either connect() succeeded or started asynchronously
64842   // (errno = EINPROGRESS).
64843   state_ = State::kConnecting;
64844 
64845   // Even if the socket is non-blocking, connecting to a UNIX socket can be
64846   // acknowledged straight away rather than returning EINPROGRESS.
64847   // The decision here is to deal with the two cases uniformly, at the cost of
64848   // delaying the straight-away-connect() case by one task, to avoid depending
64849   // on implementation details of UNIX socket on the various OSes.
64850   // Posting the OnEvent() below emulates a wakeup of the FD watch. OnEvent(),
64851   // which knows how to deal with spurious wakeups, will poll the SO_ERROR and
64852   // evolve, if necessary, the state into either kConnected or kDisconnected.
64853   WeakPtr<UnixSocket> weak_ptr = weak_ptr_factory_.GetWeakPtr();
64854   task_runner_->PostTask([weak_ptr] {
64855     if (weak_ptr)
64856       weak_ptr->OnEvent();
64857   });
64858 }
64859 
64860 #if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
ReadPeerCredentialsPosix()64861 void UnixSocket::ReadPeerCredentialsPosix() {
64862   // Peer credentials are supported only on AF_UNIX sockets.
64863   if (sock_raw_.family() != SockFamily::kUnix)
64864     return;
64865   PERFETTO_CHECK(peer_cred_mode_ != SockPeerCredMode::kIgnore);
64866 
64867 #if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
64868     PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
64869   struct ucred user_cred;
64870   socklen_t len = sizeof(user_cred);
64871   int fd = sock_raw_.fd();
64872   int res = getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &user_cred, &len);
64873   PERFETTO_CHECK(res == 0);
64874   peer_uid_ = user_cred.uid;
64875   peer_pid_ = user_cred.pid;
64876 #elif PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
64877   struct xucred user_cred;
64878   socklen_t len = sizeof(user_cred);
64879   int res = getsockopt(sock_raw_.fd(), 0, LOCAL_PEERCRED, &user_cred, &len);
64880   PERFETTO_CHECK(res == 0 && user_cred.cr_version == XUCRED_VERSION);
64881   peer_uid_ = static_cast<uid_t>(user_cred.cr_uid);
64882   // There is no pid in the LOCAL_PEERCREDS for MacOS / FreeBSD.
64883 #endif
64884 }
64885 #endif  // !OS_WIN
64886 
64887 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
OnEvent()64888 void UnixSocket::OnEvent() {
64889   WSANETWORKEVENTS evts{};
64890   PERFETTO_CHECK(WSAEnumNetworkEvents(sock_raw_.fd(), sock_raw_.watch_handle(),
64891                                       &evts) == 0);
64892   if (state_ == State::kDisconnected)
64893     return;  // Some spurious event, typically queued just before Shutdown().
64894 
64895   if (state_ == State::kConnecting && (evts.lNetworkEvents & FD_CONNECT)) {
64896     PERFETTO_DCHECK(sock_raw_);
64897     int err = evts.iErrorCode[FD_CONNECT_BIT];
64898     if (err) {
64899       PERFETTO_DPLOG("Connection error: %d", err);
64900       Shutdown(false);
64901       event_listener_->OnConnect(this, false /* connected */);
64902       return;
64903     }
64904 
64905     // kReadOnConnect is not supported on Windows.
64906     PERFETTO_DCHECK(peer_cred_mode_ != SockPeerCredMode::kReadOnConnect);
64907     state_ = State::kConnected;
64908     event_listener_->OnConnect(this, true /* connected */);
64909   }
64910 
64911   // This is deliberately NOT an else-if. When a client socket connects and
64912   // there is already data queued, the following will happen within the same
64913   // OnEvent() call:
64914   // 1. The block above will transition kConnecting -> kConnected.
64915   // 2. This block will cause an OnDataAvailable() call.
64916   // Unlike UNIX, where poll() keeps signalling the event until the client
64917   // does a recv(), Windows is more picky and stops signalling the event until
64918   // the next call to recv() is made. In other words, in Windows we cannot
64919   // miss an OnDataAvailable() call or the event pump will stop.
64920   if (state_ == State::kConnected) {
64921     if (evts.lNetworkEvents & FD_READ) {
64922       event_listener_->OnDataAvailable(this);
64923       // TODO(primiano): I am very conflicted here. Because of the behavior
64924       // described above, if the event listener doesn't do a Recv() call in
64925       // the OnDataAvailable() callback, WinSock won't notify the event ever
64926       // again. On one side, I don't see any reason why a client should decide
64927       // to not do a Recv() in OnDataAvailable. On the other side, the
64928       // behavior here diverges from UNIX, where OnDataAvailable() would be
64929       // re-posted immediately. In both cases, not doing a Recv() in
64930       // OnDataAvailable, leads to something bad (getting stuck on Windows,
64931       // getting in a hot loop on Linux), so doesn't feel we should worry too
64932       // much about this. If we wanted to keep the behavrior consistent, here
64933       // we should do something like: `if (sock_raw_)
64934       // sock_raw_.SetBlocking(false)` (Note that the socket might be closed
64935       // by the time we come back here, hence the if part).
64936       return;
64937     }
64938     // Could read EOF and disconnect here.
64939     if (evts.lNetworkEvents & FD_CLOSE) {
64940       Shutdown(true);
64941       return;
64942     }
64943   }
64944 
64945   // New incoming connection.
64946   if (state_ == State::kListening && (evts.lNetworkEvents & FD_ACCEPT)) {
64947     // There could be more than one incoming connection behind each FD watch
64948     // notification. Drain'em all.
64949     for (;;) {
64950       // Note: right now we don't need the remote endpoint, hence we pass
64951       // nullptr to |addr| and |addrlen|. If we ever need to do so, be
64952       // extremely careful. Windows' WinSock API will happily write more than
64953       // |addrlen| (hence corrupt the stack) if the |addr| argument passed is
64954       // not big enough (e.g. passing a struct sockaddr_in to a AF_UNIX
64955       // socket, where sizeof(sockaddr_un) is >> sizef(sockaddr_in)). It seems
64956       // a Windows / CRT bug in the AF_UNIX implementation.
64957       ScopedSocketHandle new_fd(accept(sock_raw_.fd(), nullptr, nullptr));
64958       if (!new_fd)
64959         return;
64960       std::unique_ptr<UnixSocket> new_sock(new UnixSocket(
64961           event_listener_, task_runner_, std::move(new_fd), State::kConnected,
64962           sock_raw_.family(), sock_raw_.type(), peer_cred_mode_));
64963       event_listener_->OnNewIncomingConnection(this, std::move(new_sock));
64964     }
64965   }
64966 }
64967 #else
OnEvent()64968 void UnixSocket::OnEvent() {
64969   if (state_ == State::kDisconnected)
64970     return;  // Some spurious event, typically queued just before Shutdown().
64971 
64972   if (state_ == State::kConnected)
64973     return event_listener_->OnDataAvailable(this);
64974 
64975   if (state_ == State::kConnecting) {
64976     PERFETTO_DCHECK(sock_raw_);
64977     int sock_err = EINVAL;
64978     socklen_t err_len = sizeof(sock_err);
64979     int res =
64980         getsockopt(sock_raw_.fd(), SOL_SOCKET, SO_ERROR, &sock_err, &err_len);
64981 
64982     if (res == 0 && sock_err == EINPROGRESS)
64983       return;  // Not connected yet, just a spurious FD watch wakeup.
64984     if (res == 0 && sock_err == 0) {
64985       if (peer_cred_mode_ == SockPeerCredMode::kReadOnConnect)
64986         ReadPeerCredentialsPosix();
64987       state_ = State::kConnected;
64988       return event_listener_->OnConnect(this, true /* connected */);
64989     }
64990     PERFETTO_DLOG("Connection error: %s", strerror(sock_err));
64991     Shutdown(false);
64992     return event_listener_->OnConnect(this, false /* connected */);
64993   }
64994 
64995   // New incoming connection.
64996   if (state_ == State::kListening) {
64997     // There could be more than one incoming connection behind each FD watch
64998     // notification. Drain'em all.
64999     for (;;) {
65000       ScopedFile new_fd(
65001           PERFETTO_EINTR(accept(sock_raw_.fd(), nullptr, nullptr)));
65002       if (!new_fd)
65003         return;
65004       std::unique_ptr<UnixSocket> new_sock(new UnixSocket(
65005           event_listener_, task_runner_, std::move(new_fd), State::kConnected,
65006           sock_raw_.family(), sock_raw_.type(), peer_cred_mode_));
65007       event_listener_->OnNewIncomingConnection(this, std::move(new_sock));
65008     }
65009   }
65010 }
65011 #endif
65012 
Send(const void * msg,size_t len,const int * send_fds,size_t num_fds)65013 bool UnixSocket::Send(const void* msg,
65014                       size_t len,
65015                       const int* send_fds,
65016                       size_t num_fds) {
65017   if (state_ != State::kConnected) {
65018     errno = ENOTCONN;
65019     return false;
65020   }
65021 
65022   sock_raw_.SetBlocking(true);
65023   const ssize_t sz = sock_raw_.Send(msg, len, send_fds, num_fds);
65024   sock_raw_.SetBlocking(false);
65025 
65026   if (sz == static_cast<ssize_t>(len)) {
65027     return true;
65028   }
65029 
65030   // If we ever decide to support non-blocking sends again, here we should
65031   // watch for both EAGAIN and EWOULDBLOCK (see base::IsAgain()).
65032 
65033   // If sendmsg() succeeds but the returned size is >= 0 and < |len| it means
65034   // that the endpoint disconnected in the middle of the read, and we managed
65035   // to send only a portion of the buffer.
65036   // If sz < 0, either the other endpoint disconnected (ECONNRESET) or some
65037   // other error happened. In both cases we should just give up.
65038   PERFETTO_DPLOG("sendmsg() failed");
65039   Shutdown(true);
65040   return false;
65041 }
65042 
Shutdown(bool notify)65043 void UnixSocket::Shutdown(bool notify) {
65044   WeakPtr<UnixSocket> weak_ptr = weak_ptr_factory_.GetWeakPtr();
65045   if (notify) {
65046     if (state_ == State::kConnected) {
65047       task_runner_->PostTask([weak_ptr] {
65048         if (weak_ptr)
65049           weak_ptr->event_listener_->OnDisconnect(weak_ptr.get());
65050       });
65051     } else if (state_ == State::kConnecting) {
65052       task_runner_->PostTask([weak_ptr] {
65053         if (weak_ptr)
65054           weak_ptr->event_listener_->OnConnect(weak_ptr.get(), false);
65055       });
65056     }
65057   }
65058 
65059   if (sock_raw_) {
65060     task_runner_->RemoveFileDescriptorWatch(sock_raw_.watch_handle());
65061     sock_raw_.Shutdown();
65062   }
65063   state_ = State::kDisconnected;
65064 }
65065 
Receive(void * msg,size_t len,ScopedFile * fd_vec,size_t max_files)65066 size_t UnixSocket::Receive(void* msg,
65067                            size_t len,
65068                            ScopedFile* fd_vec,
65069                            size_t max_files) {
65070   if (state_ != State::kConnected)
65071     return 0;
65072 
65073   const ssize_t sz = sock_raw_.Receive(msg, len, fd_vec, max_files);
65074 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
65075   bool async_would_block = WSAGetLastError() == WSAEWOULDBLOCK;
65076 #else
65077   bool async_would_block = IsAgain(errno);
65078 #endif
65079   if (sz < 0 && async_would_block)
65080     return 0;
65081 
65082   if (sz <= 0) {
65083     Shutdown(true);
65084     return 0;
65085   }
65086   PERFETTO_CHECK(static_cast<size_t>(sz) <= len);
65087   return static_cast<size_t>(sz);
65088 }
65089 
ReceiveString(size_t max_length)65090 std::string UnixSocket::ReceiveString(size_t max_length) {
65091   std::unique_ptr<char[]> buf(new char[max_length + 1]);
65092   size_t rsize = Receive(buf.get(), max_length);
65093   PERFETTO_CHECK(rsize <= max_length);
65094   buf[rsize] = '\0';
65095   return std::string(buf.get());
65096 }
65097 
NotifyConnectionState(bool success)65098 void UnixSocket::NotifyConnectionState(bool success) {
65099   if (!success)
65100     Shutdown(false);
65101 
65102   WeakPtr<UnixSocket> weak_ptr = weak_ptr_factory_.GetWeakPtr();
65103   task_runner_->PostTask([weak_ptr, success] {
65104     if (weak_ptr)
65105       weak_ptr->event_listener_->OnConnect(weak_ptr.get(), success);
65106   });
65107 }
65108 
~EventListener()65109 UnixSocket::EventListener::~EventListener() {}
OnNewIncomingConnection(UnixSocket *,std::unique_ptr<UnixSocket>)65110 void UnixSocket::EventListener::OnNewIncomingConnection(
65111     UnixSocket*,
65112     std::unique_ptr<UnixSocket>) {}
OnConnect(UnixSocket *,bool)65113 void UnixSocket::EventListener::OnConnect(UnixSocket*, bool) {}
OnDisconnect(UnixSocket *)65114 void UnixSocket::EventListener::OnDisconnect(UnixSocket*) {}
OnDataAvailable(UnixSocket *)65115 void UnixSocket::EventListener::OnDataAvailable(UnixSocket*) {}
65116 
65117 }  // namespace base
65118 }  // namespace perfetto
65119 // gen_amalgamated begin source: src/ipc/buffered_frame_deserializer.cc
65120 // gen_amalgamated begin header: src/ipc/buffered_frame_deserializer.h
65121 // gen_amalgamated begin header: include/perfetto/ext/ipc/basic_types.h
65122 /*
65123  * Copyright (C) 2017 The Android Open Source Project
65124  *
65125  * Licensed under the Apache License, Version 2.0 (the "License");
65126  * you may not use this file except in compliance with the License.
65127  * You may obtain a copy of the License at
65128  *
65129  *      http://www.apache.org/licenses/LICENSE-2.0
65130  *
65131  * Unless required by applicable law or agreed to in writing, software
65132  * distributed under the License is distributed on an "AS IS" BASIS,
65133  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
65134  * See the License for the specific language governing permissions and
65135  * limitations under the License.
65136  */
65137 
65138 #ifndef INCLUDE_PERFETTO_EXT_IPC_BASIC_TYPES_H_
65139 #define INCLUDE_PERFETTO_EXT_IPC_BASIC_TYPES_H_
65140 
65141 #include <stddef.h>
65142 #include <stdint.h>
65143 #include <sys/types.h>
65144 
65145 // gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
65146 // gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
65147 
65148 namespace perfetto {
65149 namespace ipc {
65150 
65151 using ProtoMessage = ::protozero::CppMessageObj;
65152 using ServiceID = uint32_t;
65153 using MethodID = uint32_t;
65154 using ClientID = uint64_t;
65155 using RequestID = uint64_t;
65156 
65157 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
65158 // AF_UNIX on Windows is supported only on Windows 10 from build 17063.
65159 // Also it doesn't bring major advantages compared to a TCP socket.
65160 // See go/perfetto-win .
65161 constexpr bool kUseTCPSocket = true;
65162 #else
65163 // On Android, Linux, Mac use a AF_UNIX socket.
65164 constexpr bool kUseTCPSocket = false;
65165 #endif
65166 
65167 // This determines the maximum size allowed for an IPC message. Trying to send
65168 // or receive a larger message will hit DCHECK(s) and auto-disconnect.
65169 constexpr size_t kIPCBufferSize = 128 * 1024;
65170 
65171 constexpr uid_t kInvalidUid = static_cast<uid_t>(-1);
65172 
65173 }  // namespace ipc
65174 }  // namespace perfetto
65175 
65176 #endif  // INCLUDE_PERFETTO_EXT_IPC_BASIC_TYPES_H_
65177 /*
65178  * Copyright (C) 2017 The Android Open Source Project
65179  *
65180  * Licensed under the Apache License, Version 2.0 (the "License");
65181  * you may not use this file except in compliance with the License.
65182  * You may obtain a copy of the License at
65183  *
65184  *      http://www.apache.org/licenses/LICENSE-2.0
65185  *
65186  * Unless required by applicable law or agreed to in writing, software
65187  * distributed under the License is distributed on an "AS IS" BASIS,
65188  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
65189  * See the License for the specific language governing permissions and
65190  * limitations under the License.
65191  */
65192 
65193 #ifndef SRC_IPC_BUFFERED_FRAME_DESERIALIZER_H_
65194 #define SRC_IPC_BUFFERED_FRAME_DESERIALIZER_H_
65195 
65196 #include <stddef.h>
65197 
65198 #include <list>
65199 #include <memory>
65200 
65201 // gen_amalgamated expanded: #include "perfetto/ext/base/paged_memory.h"
65202 // gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
65203 // gen_amalgamated expanded: #include "perfetto/ext/ipc/basic_types.h"
65204 
65205 namespace perfetto {
65206 
65207 namespace protos {
65208 namespace gen {
65209 class IPCFrame;
65210 }  // namespace gen
65211 }  // namespace protos
65212 
65213 namespace ipc {
65214 
65215 using Frame = ::perfetto::protos::gen::IPCFrame;
65216 
65217 // Deserializes incoming frames, taking care of buffering and tokenization.
65218 // Used by both host and client to decode incoming frames.
65219 //
65220 // Which problem does it solve?
65221 // ----------------------------
65222 // The wire protocol is as follows:
65223 // [32-bit frame size][proto-encoded Frame], e.g:
65224 // [06 00 00 00][00 11 22 33 44 55 66]
65225 // [02 00 00 00][AA BB]
65226 // [04 00 00 00][CC DD EE FF]
65227 // However, given that the socket works in SOCK_STREAM mode, the recv() calls
65228 // might see the following:
65229 // 06 00 00
65230 // 00 00 11 22 33 44 55
65231 // 66 02 00 00 00 ...
65232 // This class takes care of buffering efficiently the data received, without
65233 // making any assumption on how the incoming data will be chunked by the socket.
65234 // For instance, it is possible that a recv() doesn't produce any frame (because
65235 // it received only a part of the frame) or produces more than one frame.
65236 //
65237 // Usage
65238 // -----
65239 // Both host and client use this as follows:
65240 //
65241 // auto buf = rpc_frame_decoder.BeginReceive();
65242 // size_t rsize = socket.recv(buf.first, buf.second);
65243 // rpc_frame_decoder.EndReceive(rsize);
65244 // while (Frame frame = rpc_frame_decoder.PopNextFrame()) {
65245 //   ... process |frame|
65246 // }
65247 //
65248 // Design goals:
65249 // -------------
65250 // - Optimize for the realistic case of each recv() receiving one or more
65251 //   whole frames. In this case no memmove is performed.
65252 // - Guarantee that frames lay in a virtually contiguous memory area.
65253 //   This allows to use the protobuf-lite deserialization API (scattered
65254 //   deserialization is supported only by libprotobuf-full).
65255 // - Put a hard boundary to the size of the incoming buffer. This is to prevent
65256 //   that a malicious sends an abnormally large frame and OOMs us.
65257 // - Simplicity: just use a linear mmap region. No reallocations or scattering.
65258 //   Takes care of madvise()-ing unused memory.
65259 
65260 class BufferedFrameDeserializer {
65261  public:
65262   struct ReceiveBuffer {
65263     char* data;
65264     size_t size;
65265   };
65266 
65267   // |max_capacity| is overridable only for tests.
65268   explicit BufferedFrameDeserializer(size_t max_capacity = kIPCBufferSize);
65269   ~BufferedFrameDeserializer();
65270 
65271   // This function doesn't really belong here as it does Serialization, unlike
65272   // the rest of this class. However it is so small and has so many dependencies
65273   // in common that doesn't justify having its own class.
65274   static std::string Serialize(const Frame&);
65275 
65276   // Returns a buffer that can be passed to recv(). The buffer is deliberately
65277   // not initialized.
65278   ReceiveBuffer BeginReceive();
65279 
65280   // Must be called soon after BeginReceive().
65281   // |recv_size| is the number of valid bytes that have been written into the
65282   // buffer previously returned by BeginReceive() (the return value of recv()).
65283   // Returns false if a header > |max_capacity| is received, in which case the
65284   // caller is expected to shutdown the socket and terminate the ipc.
65285   bool EndReceive(size_t recv_size) PERFETTO_WARN_UNUSED_RESULT;
65286 
65287   // Decodes and returns the next decoded frame in the buffer if any, nullptr
65288   // if no further frames have been decoded.
65289   std::unique_ptr<Frame> PopNextFrame();
65290 
capacity() const65291   size_t capacity() const { return capacity_; }
size() const65292   size_t size() const { return size_; }
65293 
65294  private:
65295   BufferedFrameDeserializer(const BufferedFrameDeserializer&) = delete;
65296   BufferedFrameDeserializer& operator=(const BufferedFrameDeserializer&) =
65297       delete;
65298 
65299   // If a valid frame is decoded it is added to |decoded_frames_|.
65300   void DecodeFrame(const char*, size_t);
65301 
buf()65302   char* buf() { return reinterpret_cast<char*>(buf_.Get()); }
65303 
65304   base::PagedMemory buf_;
65305   const size_t capacity_ = 0;  // sizeof(|buf_|).
65306 
65307   // THe number of bytes in |buf_| that contain valid data (as a result of
65308   // EndReceive()). This is always <= |capacity_|.
65309   size_t size_ = 0;
65310 
65311   std::list<std::unique_ptr<Frame>> decoded_frames_;
65312 };
65313 
65314 }  // namespace ipc
65315 }  // namespace perfetto
65316 
65317 #endif  // SRC_IPC_BUFFERED_FRAME_DESERIALIZER_H_
65318 /*
65319  * Copyright (C) 2017 The Android Open Source Project
65320  *
65321  * Licensed under the Apache License, Version 2.0 (the "License");
65322  * you may not use this file except in compliance with the License.
65323  * You may obtain a copy of the License at
65324  *
65325  *      http://www.apache.org/licenses/LICENSE-2.0
65326  *
65327  * Unless required by applicable law or agreed to in writing, software
65328  * distributed under the License is distributed on an "AS IS" BASIS,
65329  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
65330  * See the License for the specific language governing permissions and
65331  * limitations under the License.
65332  */
65333 
65334 // gen_amalgamated expanded: #include "src/ipc/buffered_frame_deserializer.h"
65335 
65336 #include <algorithm>
65337 #include <cinttypes>
65338 #include <type_traits>
65339 #include <utility>
65340 
65341 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
65342 // gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
65343 
65344 // gen_amalgamated expanded: #include "protos/perfetto/ipc/wire_protocol.gen.h"
65345 
65346 namespace perfetto {
65347 namespace ipc {
65348 
65349 namespace {
65350 
65351 // The header is just the number of bytes of the Frame protobuf message.
65352 constexpr size_t kHeaderSize = sizeof(uint32_t);
65353 }  // namespace
65354 
BufferedFrameDeserializer(size_t max_capacity)65355 BufferedFrameDeserializer::BufferedFrameDeserializer(size_t max_capacity)
65356     : capacity_(max_capacity) {
65357   PERFETTO_CHECK(max_capacity % base::GetSysPageSize() == 0);
65358   PERFETTO_CHECK(max_capacity >= base::GetSysPageSize());
65359 }
65360 
65361 BufferedFrameDeserializer::~BufferedFrameDeserializer() = default;
65362 
65363 BufferedFrameDeserializer::ReceiveBuffer
BeginReceive()65364 BufferedFrameDeserializer::BeginReceive() {
65365   // Upon the first recv initialize the buffer to the max message size but
65366   // release the physical memory for all but the first page. The kernel will
65367   // automatically give us physical pages back as soon as we page-fault on them.
65368   if (!buf_.IsValid()) {
65369     PERFETTO_DCHECK(size_ == 0);
65370     // TODO(eseckler): Don't commit all of the buffer at once on Windows.
65371     buf_ = base::PagedMemory::Allocate(capacity_);
65372 
65373     // Surely we are going to use at least the first page, but we may not need
65374     // the rest for a bit.
65375     const auto page_size = base::GetSysPageSize();
65376     buf_.AdviseDontNeed(buf() + page_size, capacity_ - page_size);
65377   }
65378 
65379   PERFETTO_CHECK(capacity_ > size_);
65380   return ReceiveBuffer{buf() + size_, capacity_ - size_};
65381 }
65382 
EndReceive(size_t recv_size)65383 bool BufferedFrameDeserializer::EndReceive(size_t recv_size) {
65384   const auto page_size = base::GetSysPageSize();
65385   PERFETTO_CHECK(recv_size + size_ <= capacity_);
65386   size_ += recv_size;
65387 
65388   // At this point the contents buf_ can contain:
65389   // A) Only a fragment of the header (the size of the frame). E.g.,
65390   //    03 00 00 (the header is 4 bytes, one is missing).
65391   //
65392   // B) A header and a part of the frame. E.g.,
65393   //     05 00 00 00         11 22 33
65394   //    [ header, size=5 ]  [ Partial frame ]
65395   //
65396   // C) One or more complete header+frame. E.g.,
65397   //     05 00 00 00         11 22 33 44 55   03 00 00 00        AA BB CC
65398   //    [ header, size=5 ]  [ Whole frame ]  [ header, size=3 ] [ Whole frame ]
65399   //
65400   // D) Some complete header+frame(s) and a partial header or frame (C + A/B).
65401   //
65402   // C Is the more likely case and the one we are optimizing for. A, B, D can
65403   // happen because of the streaming nature of the socket.
65404   // The invariant of this function is that, when it returns, buf_ is either
65405   // empty (we drained all the complete frames) or starts with the header of the
65406   // next, still incomplete, frame.
65407 
65408   size_t consumed_size = 0;
65409   for (;;) {
65410     if (size_ < consumed_size + kHeaderSize)
65411       break;  // Case A, not enough data to read even the header.
65412 
65413     // Read the header into |payload_size|.
65414     uint32_t payload_size = 0;
65415     const char* rd_ptr = buf() + consumed_size;
65416     memcpy(base::AssumeLittleEndian(&payload_size), rd_ptr, kHeaderSize);
65417 
65418     // Saturate the |payload_size| to prevent overflows. The > capacity_ check
65419     // below will abort the parsing.
65420     size_t next_frame_size =
65421         std::min(static_cast<size_t>(payload_size), capacity_);
65422     next_frame_size += kHeaderSize;
65423     rd_ptr += kHeaderSize;
65424 
65425     if (size_ < consumed_size + next_frame_size) {
65426       // Case B. We got the header but not the whole frame.
65427       if (next_frame_size > capacity_) {
65428         // The caller is expected to shut down the socket and give up at this
65429         // point. If it doesn't do that and insists going on at some point it
65430         // will hit the capacity check in BeginReceive().
65431         PERFETTO_LOG("IPC Frame too large (size %zu)", next_frame_size);
65432         return false;
65433       }
65434       break;
65435     }
65436 
65437     // Case C. We got at least one header and whole frame.
65438     DecodeFrame(rd_ptr, payload_size);
65439     consumed_size += next_frame_size;
65440   }
65441 
65442   PERFETTO_DCHECK(consumed_size <= size_);
65443   if (consumed_size > 0) {
65444     // Shift out the consumed data from the buffer. In the typical case (C)
65445     // there is nothing to shift really, just setting size_ = 0 is enough.
65446     // Shifting is only for the (unlikely) case D.
65447     size_ -= consumed_size;
65448     if (size_ > 0) {
65449       // Case D. We consumed some frames but there is a leftover at the end of
65450       // the buffer. Shift out the consumed bytes, so that on the next round
65451       // |buf_| starts with the header of the next unconsumed frame.
65452       const char* move_begin = buf() + consumed_size;
65453       PERFETTO_CHECK(move_begin > buf());
65454       PERFETTO_CHECK(move_begin + size_ <= buf() + capacity_);
65455       memmove(buf(), move_begin, size_);
65456     }
65457     // If we just finished decoding a large frame that used more than one page,
65458     // release the extra memory in the buffer. Large frames should be quite
65459     // rare.
65460     if (consumed_size > page_size) {
65461       size_t size_rounded_up = (size_ / page_size + 1) * page_size;
65462       if (size_rounded_up < capacity_) {
65463         char* madvise_begin = buf() + size_rounded_up;
65464         const size_t madvise_size = capacity_ - size_rounded_up;
65465         PERFETTO_CHECK(madvise_begin > buf() + size_);
65466         PERFETTO_CHECK(madvise_begin + madvise_size <= buf() + capacity_);
65467         buf_.AdviseDontNeed(madvise_begin, madvise_size);
65468       }
65469     }
65470   }
65471   // At this point |size_| == 0 for case C, > 0 for cases A, B, D.
65472   return true;
65473 }
65474 
PopNextFrame()65475 std::unique_ptr<Frame> BufferedFrameDeserializer::PopNextFrame() {
65476   if (decoded_frames_.empty())
65477     return nullptr;
65478   std::unique_ptr<Frame> frame = std::move(decoded_frames_.front());
65479   decoded_frames_.pop_front();
65480   return frame;
65481 }
65482 
DecodeFrame(const char * data,size_t size)65483 void BufferedFrameDeserializer::DecodeFrame(const char* data, size_t size) {
65484   if (size == 0)
65485     return;
65486   std::unique_ptr<Frame> frame(new Frame);
65487   if (frame->ParseFromArray(data, size))
65488     decoded_frames_.push_back(std::move(frame));
65489 }
65490 
65491 // static
Serialize(const Frame & frame)65492 std::string BufferedFrameDeserializer::Serialize(const Frame& frame) {
65493   std::vector<uint8_t> payload = frame.SerializeAsArray();
65494   const uint32_t payload_size = static_cast<uint32_t>(payload.size());
65495   std::string buf;
65496   buf.resize(kHeaderSize + payload_size);
65497   memcpy(&buf[0], base::AssumeLittleEndian(&payload_size), kHeaderSize);
65498   memcpy(&buf[kHeaderSize], payload.data(), payload.size());
65499   return buf;
65500 }
65501 
65502 }  // namespace ipc
65503 }  // namespace perfetto
65504 // gen_amalgamated begin source: src/ipc/deferred.cc
65505 // gen_amalgamated begin header: include/perfetto/ext/ipc/deferred.h
65506 // gen_amalgamated begin header: include/perfetto/ext/ipc/async_result.h
65507 /*
65508  * Copyright (C) 2017 The Android Open Source Project
65509  *
65510  * Licensed under the Apache License, Version 2.0 (the "License");
65511  * you may not use this file except in compliance with the License.
65512  * You may obtain a copy of the License at
65513  *
65514  *      http://www.apache.org/licenses/LICENSE-2.0
65515  *
65516  * Unless required by applicable law or agreed to in writing, software
65517  * distributed under the License is distributed on an "AS IS" BASIS,
65518  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
65519  * See the License for the specific language governing permissions and
65520  * limitations under the License.
65521  */
65522 
65523 #ifndef INCLUDE_PERFETTO_EXT_IPC_ASYNC_RESULT_H_
65524 #define INCLUDE_PERFETTO_EXT_IPC_ASYNC_RESULT_H_
65525 
65526 #include <memory>
65527 #include <type_traits>
65528 #include <utility>
65529 
65530 // gen_amalgamated expanded: #include "perfetto/ext/ipc/basic_types.h"
65531 
65532 namespace perfetto {
65533 namespace ipc {
65534 
65535 // Wraps the result of an asynchronous invocation. This is the equivalent of a
65536 // std::pair<unique_ptr<T>, bool> with syntactic sugar. It is used as callback
65537 // argument by Deferred<T>. T is a ProtoMessage subclass (i.e. generated .pb.h).
65538 template <typename T>
65539 class AsyncResult {
65540  public:
Create()65541   static AsyncResult Create() {
65542     return AsyncResult(std::unique_ptr<T>(new T()));
65543   }
65544 
AsyncResult(std::unique_ptr<T> msg=nullptr,bool has_more=false,int fd=-1)65545   AsyncResult(std::unique_ptr<T> msg = nullptr,
65546               bool has_more = false,
65547               int fd = -1)
65548       : msg_(std::move(msg)), has_more_(has_more), fd_(fd) {
65549     static_assert(std::is_base_of<ProtoMessage, T>::value, "T->ProtoMessage");
65550   }
65551   AsyncResult(AsyncResult&&) noexcept = default;
65552   AsyncResult& operator=(AsyncResult&&) = default;
65553 
success() const65554   bool success() const { return !!msg_; }
operator bool() const65555   explicit operator bool() const { return success(); }
65556 
has_more() const65557   bool has_more() const { return has_more_; }
set_has_more(bool has_more)65558   void set_has_more(bool has_more) { has_more_ = has_more; }
65559 
set_msg(std::unique_ptr<T> msg)65560   void set_msg(std::unique_ptr<T> msg) { msg_ = std::move(msg); }
release_msg()65561   T* release_msg() { return msg_.release(); }
operator ->()65562   T* operator->() { return msg_.get(); }
operator *()65563   T& operator*() { return *msg_; }
65564 
set_fd(int fd)65565   void set_fd(int fd) { fd_ = fd; }
fd() const65566   int fd() const { return fd_; }
65567 
65568  private:
65569   std::unique_ptr<T> msg_;
65570   bool has_more_ = false;
65571 
65572   // Optional. Only for messages that convey a file descriptor, for sharing
65573   // memory across processes.
65574   int fd_ = -1;
65575 };
65576 
65577 }  // namespace ipc
65578 }  // namespace perfetto
65579 
65580 #endif  // INCLUDE_PERFETTO_EXT_IPC_ASYNC_RESULT_H_
65581 /*
65582  * Copyright (C) 2017 The Android Open Source Project
65583  *
65584  * Licensed under the Apache License, Version 2.0 (the "License");
65585  * you may not use this file except in compliance with the License.
65586  * You may obtain a copy of the License at
65587  *
65588  *      http://www.apache.org/licenses/LICENSE-2.0
65589  *
65590  * Unless required by applicable law or agreed to in writing, software
65591  * distributed under the License is distributed on an "AS IS" BASIS,
65592  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
65593  * See the License for the specific language governing permissions and
65594  * limitations under the License.
65595  */
65596 
65597 #ifndef INCLUDE_PERFETTO_EXT_IPC_DEFERRED_H_
65598 #define INCLUDE_PERFETTO_EXT_IPC_DEFERRED_H_
65599 
65600 #include <functional>
65601 #include <memory>
65602 #include <utility>
65603 
65604 // gen_amalgamated expanded: #include "perfetto/ext/ipc/async_result.h"
65605 // gen_amalgamated expanded: #include "perfetto/ext/ipc/basic_types.h"
65606 
65607 namespace perfetto {
65608 namespace ipc {
65609 
65610 // This class is a wrapper for a callback handling async results.
65611 // The problem this is solving is the following: For each result argument of the
65612 // methods generated from the .proto file:
65613 // - The client wants to see something on which it can Bind() a callback, which
65614 //   is invoked asynchronously once reply is received from the host.
65615 // - The host wants to expose something to user code that implements the IPC
65616 //   methods to allow them to provide an asynchronous reply back to the client.
65617 //   Eventually even more than once, for the case streaming replies.
65618 //
65619 // In both cases we want to make sure that callbacks don't get lost along the
65620 // way. To address this, this class will automatically reject the callbacks
65621 // if they are not resolved at destructor time (or the object is std::move()'d).
65622 //
65623 // The client is supposed to use this class as follows:
65624 //   class GreeterProxy {
65625 //      void SayHello(const HelloRequest&, Deferred<HelloReply> reply)
65626 //   }
65627 //  ...
65628 //  Deferred<HelloReply> reply;
65629 //  reply.Bind([] (AsyncResult<HelloReply> reply) {
65630 //    std::cout << reply.success() ? reply->message : "failure";
65631 //  });
65632 //  host_proxy_instance.SayHello(req, std::move(reply));
65633 //
65634 // The host instead is supposed to use this as follows:
65635 //   class GreeterImpl : public Greeter {
65636 //     void SayHello(const HelloRequest& req, Deferred<HelloReply> reply) {
65637 //        AsyncResult<HelloReply> reply = AsyncResult<HelloReply>::Create();
65638 //        reply->set_greeting("Hello " + req.name)
65639 //        reply.Resolve(std::move(reply));
65640 //     }
65641 //   }
65642 // Or for more complex cases, the deferred object can be std::move()'d outside
65643 // and the reply can continue asynchronously later.
65644 
65645 template <typename T>
65646 class Deferred;
65647 
65648 class DeferredBase {
65649  public:
65650   explicit DeferredBase(
65651       std::function<void(AsyncResult<ProtoMessage>)> callback = nullptr);
65652 
65653   template <typename T>
DeferredBase(Deferred<T> other)65654   explicit DeferredBase(Deferred<T> other)
65655       : callback_(std::move(other.callback_)) {}
65656 
65657   ~DeferredBase();
65658   DeferredBase(DeferredBase&&) noexcept;
65659   DeferredBase& operator=(DeferredBase&&);
65660   void Bind(std::function<void(AsyncResult<ProtoMessage>)> callback);
65661   bool IsBound() const;
65662   void Resolve(AsyncResult<ProtoMessage>);
65663   void Reject();
65664 
65665  protected:
65666   template <typename T>
65667   friend class Deferred;
65668   void Move(DeferredBase&);
65669 
65670   std::function<void(AsyncResult<ProtoMessage>)> callback_;
65671 };
65672 
65673 template <typename T>  // T : ProtoMessage subclass
65674 class Deferred : public DeferredBase {
65675  public:
Deferred(std::function<void (AsyncResult<T>)> callback=nullptr)65676   explicit Deferred(std::function<void(AsyncResult<T>)> callback = nullptr) {
65677     Bind(std::move(callback));
65678   }
65679 
65680   // This move constructor (and the similar one in DeferredBase) is meant to be
65681   // called only by the autogenerated code. The caller has to guarantee that the
65682   // moved-from and moved-to types match. The behavior is otherwise undefined.
Deferred(DeferredBase && other)65683   explicit Deferred(DeferredBase&& other) {
65684     callback_ = std::move(other.callback_);
65685     other.callback_ = nullptr;
65686   }
65687 
Bind(std::function<void (AsyncResult<T>)> callback)65688   void Bind(std::function<void(AsyncResult<T>)> callback) {
65689     if (!callback)
65690       return;
65691 
65692     // Here we need a callback adapter to downcast the callback to a generic
65693     // callback that takes an AsyncResult<ProtoMessage>, so that it can be
65694     // stored in the base class |callback_|.
65695     auto callback_adapter = [callback](
65696                                 AsyncResult<ProtoMessage> async_result_base) {
65697       // Upcast the async_result from <ProtoMessage> -> <T : ProtoMessage>.
65698       static_assert(std::is_base_of<ProtoMessage, T>::value, "T:ProtoMessage");
65699       AsyncResult<T> async_result(
65700           std::unique_ptr<T>(static_cast<T*>(async_result_base.release_msg())),
65701           async_result_base.has_more(), async_result_base.fd());
65702       callback(std::move(async_result));
65703     };
65704     DeferredBase::Bind(callback_adapter);
65705   }
65706 
65707   // If no more messages are expected, |callback_| is released.
Resolve(AsyncResult<T> async_result)65708   void Resolve(AsyncResult<T> async_result) {
65709     // Convert the |async_result| to the generic base one (T -> ProtoMessage).
65710     AsyncResult<ProtoMessage> async_result_base(
65711         std::unique_ptr<ProtoMessage>(async_result.release_msg()),
65712         async_result.has_more(), async_result.fd());
65713     DeferredBase::Resolve(std::move(async_result_base));
65714   }
65715 };
65716 
65717 }  // namespace ipc
65718 }  // namespace perfetto
65719 
65720 #endif  // INCLUDE_PERFETTO_EXT_IPC_DEFERRED_H_
65721 /*
65722  * Copyright (C) 2017 The Android Open Source Project
65723  *
65724  * Licensed under the Apache License, Version 2.0 (the "License");
65725  * you may not use this file except in compliance with the License.
65726  * You may obtain a copy of the License at
65727  *
65728  *      http://www.apache.org/licenses/LICENSE-2.0
65729  *
65730  * Unless required by applicable law or agreed to in writing, software
65731  * distributed under the License is distributed on an "AS IS" BASIS,
65732  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
65733  * See the License for the specific language governing permissions and
65734  * limitations under the License.
65735  */
65736 
65737 // gen_amalgamated expanded: #include "perfetto/ext/ipc/deferred.h"
65738 
65739 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
65740 // gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
65741 
65742 namespace perfetto {
65743 namespace ipc {
65744 
DeferredBase(std::function<void (AsyncResult<ProtoMessage>)> callback)65745 DeferredBase::DeferredBase(
65746     std::function<void(AsyncResult<ProtoMessage>)> callback)
65747     : callback_(std::move(callback)) {}
65748 
~DeferredBase()65749 DeferredBase::~DeferredBase() {
65750   if (callback_)
65751     Reject();
65752 }
65753 
65754 // Can't just use "= default" here because the default move operator for
65755 // std::function doesn't necessarily swap and hence can leave a copy of the
65756 // bind state around, which is undesirable.
DeferredBase(DeferredBase && other)65757 DeferredBase::DeferredBase(DeferredBase&& other) noexcept {
65758   Move(other);
65759 }
65760 
operator =(DeferredBase && other)65761 DeferredBase& DeferredBase::operator=(DeferredBase&& other) {
65762   if (callback_)
65763     Reject();
65764   Move(other);
65765   return *this;
65766 }
65767 
Move(DeferredBase & other)65768 void DeferredBase::Move(DeferredBase& other) {
65769   callback_ = std::move(other.callback_);
65770   other.callback_ = nullptr;
65771 }
65772 
Bind(std::function<void (AsyncResult<ProtoMessage>)> callback)65773 void DeferredBase::Bind(
65774     std::function<void(AsyncResult<ProtoMessage>)> callback) {
65775   callback_ = std::move(callback);
65776 }
65777 
IsBound() const65778 bool DeferredBase::IsBound() const {
65779   return !!callback_;
65780 }
65781 
Resolve(AsyncResult<ProtoMessage> async_result)65782 void DeferredBase::Resolve(AsyncResult<ProtoMessage> async_result) {
65783   if (!callback_) {
65784     PERFETTO_DFATAL("No callback set.");
65785     return;
65786   }
65787   bool has_more = async_result.has_more();
65788   callback_(std::move(async_result));
65789   if (!has_more)
65790     callback_ = nullptr;
65791 }
65792 
65793 // Resolves with a nullptr |msg_|, signalling failure to |callback_|.
Reject()65794 void DeferredBase::Reject() {
65795   Resolve(AsyncResult<ProtoMessage>());
65796 }
65797 
65798 }  // namespace ipc
65799 }  // namespace perfetto
65800 // gen_amalgamated begin source: src/ipc/virtual_destructors.cc
65801 // gen_amalgamated begin header: include/perfetto/ext/ipc/client.h
65802 /*
65803  * Copyright (C) 2017 The Android Open Source Project
65804  *
65805  * Licensed under the Apache License, Version 2.0 (the "License");
65806  * you may not use this file except in compliance with the License.
65807  * You may obtain a copy of the License at
65808  *
65809  *      http://www.apache.org/licenses/LICENSE-2.0
65810  *
65811  * Unless required by applicable law or agreed to in writing, software
65812  * distributed under the License is distributed on an "AS IS" BASIS,
65813  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
65814  * See the License for the specific language governing permissions and
65815  * limitations under the License.
65816  */
65817 
65818 #ifndef INCLUDE_PERFETTO_EXT_IPC_CLIENT_H_
65819 #define INCLUDE_PERFETTO_EXT_IPC_CLIENT_H_
65820 
65821 #include <functional>
65822 #include <memory>
65823 
65824 // gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"
65825 // gen_amalgamated expanded: #include "perfetto/ext/base/unix_socket.h"
65826 // gen_amalgamated expanded: #include "perfetto/ext/base/weak_ptr.h"
65827 // gen_amalgamated expanded: #include "perfetto/ext/ipc/basic_types.h"
65828 
65829 namespace perfetto {
65830 
65831 namespace base {
65832 class TaskRunner;
65833 }  // namespace base
65834 
65835 namespace ipc {
65836 class ServiceProxy;
65837 
65838 // The client-side class that talks to the host over the socket and multiplexes
65839 // requests coming from the various autogenerated ServiceProxy stubs.
65840 // This is meant to be used by the user code as follows:
65841 // auto client = Client::CreateInstance("socket_name", task_runner);
65842 // std::unique_ptr<GreeterService> svc(new GreeterService());
65843 // client.BindService(svc);
65844 // svc.OnConnect([] () {
65845 //    svc.SayHello(..., ...);
65846 // });
65847 class Client {
65848  public:
65849   // struct ConnArgs is used for creating a client in 2 connection modes:
65850   // 1. Connect using a socket name with the option to retry the connection on
65851   //    connection failure.
65852   // 2. Adopt a connected socket.
65853   struct ConnArgs {
ConnArgsperfetto::ipc::Client::ConnArgs65854     ConnArgs(const char* sock_name, bool sock_retry)
65855         : socket_name(sock_name), retry(sock_retry) {}
ConnArgsperfetto::ipc::Client::ConnArgs65856     explicit ConnArgs(base::ScopedSocketHandle sock_fd)
65857         : socket_fd(std::move(sock_fd)) {}
65858 
65859     // Disallow copy. Only supports move.
65860     ConnArgs(const ConnArgs& other) = delete;
65861     ConnArgs(ConnArgs&& other) = default;
65862 
65863     base::ScopedSocketHandle socket_fd;
65864     const char* socket_name = nullptr;
65865     bool retry = false;  // Only for connecting with |socket_name|.
65866   };
65867 
65868   static std::unique_ptr<Client> CreateInstance(ConnArgs, base::TaskRunner*);
65869   virtual ~Client();
65870 
65871   virtual void BindService(base::WeakPtr<ServiceProxy>) = 0;
65872 
65873   // There is no need to call this method explicitly. Destroying the
65874   // ServiceProxy instance is sufficient and will automatically unbind it. This
65875   // method is exposed only for the ServiceProxy destructor.
65876   virtual void UnbindService(ServiceID) = 0;
65877 
65878   // Returns (with move semantics) the last file descriptor received on the IPC
65879   // channel. No buffering is performed: if a service sends two file descriptors
65880   // and the caller doesn't read them immediately, the first one will be
65881   // automatically closed when the second is received (and will hit a DCHECK in
65882   // debug builds).
65883   virtual base::ScopedFile TakeReceivedFD() = 0;
65884 };
65885 
65886 }  // namespace ipc
65887 }  // namespace perfetto
65888 
65889 #endif  // INCLUDE_PERFETTO_EXT_IPC_CLIENT_H_
65890 // gen_amalgamated begin header: include/perfetto/ext/ipc/host.h
65891 /*
65892  * Copyright (C) 2017 The Android Open Source Project
65893  *
65894  * Licensed under the Apache License, Version 2.0 (the "License");
65895  * you may not use this file except in compliance with the License.
65896  * You may obtain a copy of the License at
65897  *
65898  *      http://www.apache.org/licenses/LICENSE-2.0
65899  *
65900  * Unless required by applicable law or agreed to in writing, software
65901  * distributed under the License is distributed on an "AS IS" BASIS,
65902  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
65903  * See the License for the specific language governing permissions and
65904  * limitations under the License.
65905  */
65906 
65907 #ifndef INCLUDE_PERFETTO_EXT_IPC_HOST_H_
65908 #define INCLUDE_PERFETTO_EXT_IPC_HOST_H_
65909 
65910 #include <memory>
65911 
65912 // gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"
65913 // gen_amalgamated expanded: #include "perfetto/ext/base/unix_socket.h"
65914 // gen_amalgamated expanded: #include "perfetto/ext/ipc/basic_types.h"
65915 
65916 namespace perfetto {
65917 
65918 namespace base {
65919 class TaskRunner;
65920 }  // namespace base
65921 
65922 namespace ipc {
65923 
65924 class Service;
65925 
65926 // The host-side of the IPC layer. This class acts as a registry and request
65927 // dispatcher. It listen on the UnixSocket |socket_name| for incoming requests
65928 // (coming Client instances) and dispatches their requests to the various
65929 // Services exposed.
65930 class Host {
65931  public:
65932   // Creates an instance and starts listening on the given |socket_name|.
65933   // Returns nullptr if listening on the socket fails.
65934   static std::unique_ptr<Host> CreateInstance(const char* socket_name,
65935                                               base::TaskRunner*);
65936 
65937   // Like the above but takes a file descriptor to a pre-bound unix socket.
65938   // Returns nullptr if listening on the socket fails.
65939   static std::unique_ptr<Host> CreateInstance(base::ScopedSocketHandle,
65940                                               base::TaskRunner*);
65941 
65942   virtual ~Host();
65943 
65944   // Registers a new service and makes it available to remote IPC peers.
65945   // All the exposed Service instances will be destroyed when destroying the
65946   // Host instance if ExposeService succeeds and returns true, or immediately
65947   // after the call in case of failure.
65948   // Returns true if the register has been successfully registered, false in
65949   // case of errors (e.g., another service with the same name is already
65950   // registered).
65951   virtual bool ExposeService(std::unique_ptr<Service>) = 0;
65952 };
65953 
65954 }  // namespace ipc
65955 }  // namespace perfetto
65956 
65957 #endif  // INCLUDE_PERFETTO_EXT_IPC_HOST_H_
65958 // gen_amalgamated begin header: include/perfetto/ext/ipc/service.h
65959 // gen_amalgamated begin header: include/perfetto/ext/ipc/client_info.h
65960 /*
65961  * Copyright (C) 2017 The Android Open Source Project
65962  *
65963  * Licensed under the Apache License, Version 2.0 (the "License");
65964  * you may not use this file except in compliance with the License.
65965  * You may obtain a copy of the License at
65966  *
65967  *      http://www.apache.org/licenses/LICENSE-2.0
65968  *
65969  * Unless required by applicable law or agreed to in writing, software
65970  * distributed under the License is distributed on an "AS IS" BASIS,
65971  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
65972  * See the License for the specific language governing permissions and
65973  * limitations under the License.
65974  */
65975 
65976 #ifndef INCLUDE_PERFETTO_EXT_IPC_CLIENT_INFO_H_
65977 #define INCLUDE_PERFETTO_EXT_IPC_CLIENT_INFO_H_
65978 
65979 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
65980 // gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
65981 // gen_amalgamated expanded: #include "perfetto/ext/ipc/basic_types.h"
65982 
65983 namespace perfetto {
65984 namespace ipc {
65985 
65986 // Passed to Service(s) to identify remote clients.
65987 class ClientInfo {
65988  public:
65989   ClientInfo() = default;
ClientInfo(ClientID client_id,uid_t uid)65990   ClientInfo(ClientID client_id, uid_t uid)
65991       : client_id_(client_id), uid_(uid) {}
65992 
operator ==(const ClientInfo & other) const65993   bool operator==(const ClientInfo& other) const {
65994     return (client_id_ == other.client_id_ && uid_ == other.uid_);
65995   }
operator !=(const ClientInfo & other) const65996   bool operator!=(const ClientInfo& other) const { return !(*this == other); }
65997 
65998   // For map<> and other sorted containers.
operator <(const ClientInfo & other) const65999   bool operator<(const ClientInfo& other) const {
66000     PERFETTO_DCHECK(client_id_ != other.client_id_ || *this == other);
66001     return client_id_ < other.client_id_;
66002   }
66003 
is_valid() const66004   bool is_valid() const { return client_id_ != 0; }
66005 
66006   // A monotonic counter.
client_id() const66007   ClientID client_id() const { return client_id_; }
66008 
66009   // Posix User ID. Comes from the kernel, can be trusted.
uid() const66010   uid_t uid() const { return uid_; }
66011 
66012  private:
66013   ClientID client_id_ = 0;
66014   uid_t uid_ = kInvalidUid;
66015 };
66016 
66017 }  // namespace ipc
66018 }  // namespace perfetto
66019 
66020 #endif  // INCLUDE_PERFETTO_EXT_IPC_CLIENT_INFO_H_
66021 /*
66022  * Copyright (C) 2017 The Android Open Source Project
66023  *
66024  * Licensed under the Apache License, Version 2.0 (the "License");
66025  * you may not use this file except in compliance with the License.
66026  * You may obtain a copy of the License at
66027  *
66028  *      http://www.apache.org/licenses/LICENSE-2.0
66029  *
66030  * Unless required by applicable law or agreed to in writing, software
66031  * distributed under the License is distributed on an "AS IS" BASIS,
66032  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
66033  * See the License for the specific language governing permissions and
66034  * limitations under the License.
66035  */
66036 
66037 #ifndef INCLUDE_PERFETTO_EXT_IPC_SERVICE_H_
66038 #define INCLUDE_PERFETTO_EXT_IPC_SERVICE_H_
66039 
66040 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
66041 // gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"
66042 // gen_amalgamated expanded: #include "perfetto/ext/ipc/client_info.h"
66043 
66044 namespace perfetto {
66045 namespace ipc {
66046 
66047 class ServiceDescriptor;
66048 
66049 // The base class for all the autogenerated host-side service interfaces.
66050 class Service {
66051  public:
66052   virtual ~Service();
66053 
66054   // Overridden by the auto-generated class. Provides the list of methods and
66055   // the protobuf (de)serialization functions for their arguments.
66056   virtual const ServiceDescriptor& GetDescriptor() = 0;
66057 
66058   // Invoked when a remote client disconnects. Use client_info() to obtain
66059   // details about the client that disconnected.
OnClientDisconnected()66060   virtual void OnClientDisconnected() {}
66061 
66062   // Returns the ClientInfo for the current IPC request. Returns an invalid
66063   // ClientInfo if called outside the scope of an IPC method.
client_info()66064   const ClientInfo& client_info() {
66065     PERFETTO_DCHECK(client_info_.is_valid());
66066     return client_info_;
66067   }
66068 
TakeReceivedFD()66069   base::ScopedFile TakeReceivedFD() {
66070     if (received_fd_)
66071       return std::move(*received_fd_);
66072     return base::ScopedFile();
66073   }
66074 
66075  private:
66076   friend class HostImpl;
66077   ClientInfo client_info_;
66078   // This is a pointer because the received fd needs to remain owned by the
66079   // ClientConnection, as we will provide it to all method invocations
66080   // for that client until one of them calls Service::TakeReceivedFD.
66081   //
66082   // Different clients might have sent different FDs so this cannot be owned
66083   // here.
66084   //
66085   // Note that this means that there can always only be one outstanding
66086   // invocation per client that supplies an FD and the client needs to
66087   // wait for this one to return before calling another one.
66088   base::ScopedFile* received_fd_;
66089 };
66090 
66091 }  // namespace ipc
66092 }  // namespace perfetto
66093 
66094 #endif  // INCLUDE_PERFETTO_EXT_IPC_SERVICE_H_
66095 // gen_amalgamated begin header: include/perfetto/ext/ipc/service_proxy.h
66096 /*
66097  * Copyright (C) 2017 The Android Open Source Project
66098  *
66099  * Licensed under the Apache License, Version 2.0 (the "License");
66100  * you may not use this file except in compliance with the License.
66101  * You may obtain a copy of the License at
66102  *
66103  *      http://www.apache.org/licenses/LICENSE-2.0
66104  *
66105  * Unless required by applicable law or agreed to in writing, software
66106  * distributed under the License is distributed on an "AS IS" BASIS,
66107  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
66108  * See the License for the specific language governing permissions and
66109  * limitations under the License.
66110  */
66111 
66112 #ifndef INCLUDE_PERFETTO_EXT_IPC_SERVICE_PROXY_H_
66113 #define INCLUDE_PERFETTO_EXT_IPC_SERVICE_PROXY_H_
66114 
66115 // gen_amalgamated expanded: #include "perfetto/ext/ipc/basic_types.h"
66116 
66117 #include <assert.h>
66118 
66119 #include <functional>
66120 #include <map>
66121 #include <memory>
66122 #include <string>
66123 
66124 // gen_amalgamated expanded: #include "perfetto/base/export.h"
66125 // gen_amalgamated expanded: #include "perfetto/ext/base/weak_ptr.h"
66126 // gen_amalgamated expanded: #include "perfetto/ext/ipc/deferred.h"
66127 
66128 namespace perfetto {
66129 namespace ipc {
66130 
66131 class Client;
66132 class ServiceDescriptor;
66133 
66134 // The base class for the client-side autogenerated stubs that forward method
66135 // invocations to the host. All the methods of this class are meant to be called
66136 // only by the autogenerated code.
66137 class PERFETTO_EXPORT ServiceProxy {
66138  public:
66139   class EventListener {
66140    public:
66141     virtual ~EventListener();
66142 
66143     // Called once after Client::BindService() if the ServiceProxy has been
66144     // successfully bound to the host. It is possible to start sending IPC
66145     // requests soon after this.
OnConnect()66146     virtual void OnConnect() {}
66147 
66148     // Called if the connection fails to be established or drops after having
66149     // been established.
OnDisconnect()66150     virtual void OnDisconnect() {}
66151   };
66152 
66153   // Guarantees that no callback will happen after this object has been
66154   // destroyed. The caller has to guarantee that the |event_listener| stays
66155   // alive at least as long as the ServiceProxy instance.
66156   explicit ServiceProxy(EventListener*);
66157   virtual ~ServiceProxy();
66158 
66159   void InitializeBinding(base::WeakPtr<Client>,
66160                          ServiceID,
66161                          std::map<std::string, MethodID>);
66162 
66163   // Called by the IPC methods in the autogenerated classes.
66164   void BeginInvoke(const std::string& method_name,
66165                    const ProtoMessage& request,
66166                    DeferredBase reply,
66167                    int fd = -1);
66168 
66169   // Called by ClientImpl.
66170   // |reply_args| == nullptr means request failure.
66171   void EndInvoke(RequestID,
66172                  std::unique_ptr<ProtoMessage> reply_arg,
66173                  bool has_more);
66174 
66175   // Called by ClientImpl.
66176   void OnConnect(bool success);
66177   void OnDisconnect();
connected() const66178   bool connected() const { return service_id_ != 0; }
66179 
66180   base::WeakPtr<ServiceProxy> GetWeakPtr() const;
66181 
66182   // Implemented by the autogenerated class.
66183   virtual const ServiceDescriptor& GetDescriptor() = 0;
66184 
66185  private:
66186   base::WeakPtr<Client> client_;
66187   ServiceID service_id_ = 0;
66188   std::map<std::string, MethodID> remote_method_ids_;
66189   std::map<RequestID, DeferredBase> pending_callbacks_;
66190   EventListener* const event_listener_;
66191   base::WeakPtrFactory<ServiceProxy> weak_ptr_factory_;  // Keep last.
66192 };
66193 
66194 }  // namespace ipc
66195 }  // namespace perfetto
66196 
66197 #endif  // INCLUDE_PERFETTO_EXT_IPC_SERVICE_PROXY_H_
66198 /*
66199  * Copyright (C) 2018 The Android Open Source Project
66200  *
66201  * Licensed under the Apache License, Version 2.0 (the "License");
66202  * you may not use this file except in compliance with the License.
66203  * You may obtain a copy of the License at
66204  *
66205  *      http://www.apache.org/licenses/LICENSE-2.0
66206  *
66207  * Unless required by applicable law or agreed to in writing, software
66208  * distributed under the License is distributed on an "AS IS" BASIS,
66209  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
66210  * See the License for the specific language governing permissions and
66211  * limitations under the License.
66212  */
66213 
66214 // gen_amalgamated expanded: #include "perfetto/ext/ipc/client.h"
66215 // gen_amalgamated expanded: #include "perfetto/ext/ipc/host.h"
66216 // gen_amalgamated expanded: #include "perfetto/ext/ipc/service.h"
66217 // gen_amalgamated expanded: #include "perfetto/ext/ipc/service_proxy.h"
66218 
66219 // This translation unit contains the definitions for the destructor of pure
66220 // virtual interfaces for the current build target. The alternative would be
66221 // introducing a one-liner .cc file for each pure virtual interface, which is
66222 // overkill. This is for compliance with -Wweak-vtables.
66223 
66224 namespace perfetto {
66225 namespace ipc {
66226 
66227 Client::~Client() = default;
66228 Host::~Host() = default;
66229 Service::~Service() = default;
66230 ServiceProxy::EventListener::~EventListener() = default;
66231 
66232 }  // namespace ipc
66233 }  // namespace perfetto
66234 // gen_amalgamated begin source: src/ipc/client_impl.cc
66235 // gen_amalgamated begin header: src/ipc/client_impl.h
66236 /*
66237  * Copyright (C) 2017 The Android Open Source Project
66238  *
66239  * Licensed under the Apache License, Version 2.0 (the "License");
66240  * you may not use this file except in compliance with the License.
66241  * You may obtain a copy of the License at
66242  *
66243  *      http://www.apache.org/licenses/LICENSE-2.0
66244  *
66245  * Unless required by applicable law or agreed to in writing, software
66246  * distributed under the License is distributed on an "AS IS" BASIS,
66247  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
66248  * See the License for the specific language governing permissions and
66249  * limitations under the License.
66250  */
66251 
66252 #ifndef SRC_IPC_CLIENT_IMPL_H_
66253 #define SRC_IPC_CLIENT_IMPL_H_
66254 
66255 #include <list>
66256 #include <map>
66257 #include <memory>
66258 
66259 // gen_amalgamated expanded: #include "perfetto/base/task_runner.h"
66260 // gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"
66261 // gen_amalgamated expanded: #include "perfetto/ext/base/unix_socket.h"
66262 // gen_amalgamated expanded: #include "perfetto/ext/ipc/client.h"
66263 // gen_amalgamated expanded: #include "src/ipc/buffered_frame_deserializer.h"
66264 
66265 namespace perfetto {
66266 
66267 namespace protos {
66268 namespace gen {
66269 class IPCFrame_BindServiceReply;
66270 class IPCFrame_InvokeMethodReply;
66271 }  // namespace gen
66272 }  // namespace protos
66273 
66274 namespace base {
66275 class TaskRunner;
66276 }  // namespace base
66277 
66278 namespace ipc {
66279 
66280 class ServiceDescriptor;
66281 
66282 class ClientImpl : public Client, public base::UnixSocket::EventListener {
66283  public:
66284   ClientImpl(ConnArgs, base::TaskRunner*);
66285   ~ClientImpl() override;
66286 
66287   // Client implementation.
66288   void BindService(base::WeakPtr<ServiceProxy>) override;
66289   void UnbindService(ServiceID) override;
66290   base::ScopedFile TakeReceivedFD() override;
66291 
66292   // base::UnixSocket::EventListener implementation.
66293   void OnConnect(base::UnixSocket*, bool connected) override;
66294   void OnDisconnect(base::UnixSocket*) override;
66295   void OnDataAvailable(base::UnixSocket*) override;
66296 
66297   RequestID BeginInvoke(ServiceID,
66298                         const std::string& method_name,
66299                         MethodID remote_method_id,
66300                         const ProtoMessage& method_args,
66301                         bool drop_reply,
66302                         base::WeakPtr<ServiceProxy>,
66303                         int fd = -1);
66304 
GetUnixSocketForTesting()66305   base::UnixSocket* GetUnixSocketForTesting() { return sock_.get(); }
66306 
66307  private:
66308   struct QueuedRequest {
66309     QueuedRequest();
66310     int type = 0;  // From Frame::msg_case(), see wire_protocol.proto.
66311     RequestID request_id = 0;
66312     base::WeakPtr<ServiceProxy> service_proxy;
66313 
66314     // Only for type == kMsgInvokeMethod.
66315     std::string method_name;
66316   };
66317 
66318   ClientImpl(const ClientImpl&) = delete;
66319   ClientImpl& operator=(const ClientImpl&) = delete;
66320 
66321   void TryConnect();
66322   bool SendFrame(const Frame&, int fd = -1);
66323   void OnFrameReceived(const Frame&);
66324   void OnBindServiceReply(QueuedRequest,
66325                           const protos::gen::IPCFrame_BindServiceReply&);
66326   void OnInvokeMethodReply(QueuedRequest,
66327                            const protos::gen::IPCFrame_InvokeMethodReply&);
66328 
66329   bool invoking_method_reply_ = false;
66330   const char* socket_name_ = nullptr;
66331   bool socket_retry_ = false;
66332   uint32_t socket_backoff_ms_ = 0;
66333   std::unique_ptr<base::UnixSocket> sock_;
66334   base::TaskRunner* const task_runner_;
66335   RequestID last_request_id_ = 0;
66336   BufferedFrameDeserializer frame_deserializer_;
66337   base::ScopedFile received_fd_;
66338   std::map<RequestID, QueuedRequest> queued_requests_;
66339   std::map<ServiceID, base::WeakPtr<ServiceProxy>> service_bindings_;
66340 
66341   // Queue of calls to BindService() that happened before the socket connected.
66342   std::list<base::WeakPtr<ServiceProxy>> queued_bindings_;
66343 
66344   base::WeakPtrFactory<Client> weak_ptr_factory_;  // Keep last.
66345 };
66346 
66347 }  // namespace ipc
66348 }  // namespace perfetto
66349 
66350 #endif  // SRC_IPC_CLIENT_IMPL_H_
66351 // gen_amalgamated begin header: include/perfetto/ext/ipc/service_descriptor.h
66352 /*
66353  * Copyright (C) 2017 The Android Open Source Project
66354  *
66355  * Licensed under the Apache License, Version 2.0 (the "License");
66356  * you may not use this file except in compliance with the License.
66357  * You may obtain a copy of the License at
66358  *
66359  *      http://www.apache.org/licenses/LICENSE-2.0
66360  *
66361  * Unless required by applicable law or agreed to in writing, software
66362  * distributed under the License is distributed on an "AS IS" BASIS,
66363  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
66364  * See the License for the specific language governing permissions and
66365  * limitations under the License.
66366  */
66367 
66368 #ifndef INCLUDE_PERFETTO_EXT_IPC_SERVICE_DESCRIPTOR_H_
66369 #define INCLUDE_PERFETTO_EXT_IPC_SERVICE_DESCRIPTOR_H_
66370 
66371 #include <functional>
66372 #include <string>
66373 #include <utility>
66374 #include <vector>
66375 
66376 // gen_amalgamated expanded: #include "perfetto/ext/ipc/basic_types.h"
66377 // gen_amalgamated expanded: #include "perfetto/ext/ipc/deferred.h"
66378 
66379 namespace perfetto {
66380 namespace ipc {
66381 
66382 class Service;
66383 
66384 // This is a pure data structure which holds factory methods and strings for the
66385 // services and their methods that get generated in the .h/.cc files.
66386 // Each autogenerated class has a GetDescriptor() method that returns one
66387 // instance of these and allows both client and hosts to map service and method
66388 // names to IDs and provide function pointers to the protobuf decoder fuctions.
66389 class ServiceDescriptor {
66390  public:
66391   struct Method {
66392     const char* name;
66393 
66394     // DecoderFunc is pointer to a function that takes a string in input
66395     // containing protobuf encoded data and returns a decoded protobuf message.
66396     using DecoderFunc = std::unique_ptr<ProtoMessage> (*)(const std::string&);
66397 
66398     // Function pointer to decode the request argument of the method.
66399     DecoderFunc request_proto_decoder;
66400 
66401     // Function pointer to decoded the reply argument of the method.
66402     DecoderFunc reply_proto_decoder;
66403 
66404     // Function pointer that dispatches the generic request to the corresponding
66405     // method implementation.
66406     using InvokerFunc = void (*)(Service*,
66407                                  const ProtoMessage& /* request_args */,
66408                                  DeferredBase /* deferred_reply */);
66409     InvokerFunc invoker;
66410   };
66411 
66412   const char* service_name = nullptr;
66413 
66414   // Note that methods order is not stable. Client and Host might have different
66415   // method indexes, depending on their versions. The Client can't just rely
66416   // on the indexes and has to keep a [string -> remote index] translation map.
66417   std::vector<Method> methods;
66418 };
66419 
66420 }  // namespace ipc
66421 }  // namespace perfetto
66422 
66423 #endif  // INCLUDE_PERFETTO_EXT_IPC_SERVICE_DESCRIPTOR_H_
66424 /*
66425  * Copyright (C) 2017 The Android Open Source Project
66426  *
66427  * Licensed under the Apache License, Version 2.0 (the "License");
66428  * you may not use this file except in compliance with the License.
66429  * You may obtain a copy of the License at
66430  *
66431  *      http://www.apache.org/licenses/LICENSE-2.0
66432  *
66433  * Unless required by applicable law or agreed to in writing, software
66434  * distributed under the License is distributed on an "AS IS" BASIS,
66435  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
66436  * See the License for the specific language governing permissions and
66437  * limitations under the License.
66438  */
66439 
66440 // gen_amalgamated expanded: #include "src/ipc/client_impl.h"
66441 
66442 #include <fcntl.h>
66443 
66444 #include <cinttypes>
66445 #include <utility>
66446 
66447 // gen_amalgamated expanded: #include "perfetto/base/task_runner.h"
66448 // gen_amalgamated expanded: #include "perfetto/ext/base/unix_socket.h"
66449 // gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
66450 // gen_amalgamated expanded: #include "perfetto/ext/ipc/service_descriptor.h"
66451 // gen_amalgamated expanded: #include "perfetto/ext/ipc/service_proxy.h"
66452 
66453 // gen_amalgamated expanded: #include "protos/perfetto/ipc/wire_protocol.gen.h"
66454 
66455 // TODO(primiano): Add ThreadChecker everywhere.
66456 
66457 // TODO(primiano): Add timeouts.
66458 
66459 namespace perfetto {
66460 namespace ipc {
66461 
66462 namespace {
66463 constexpr base::SockFamily kClientSockFamily =
66464     kUseTCPSocket ? base::SockFamily::kInet : base::SockFamily::kUnix;
66465 }  // namespace
66466 
66467 // static
CreateInstance(ConnArgs conn_args,base::TaskRunner * task_runner)66468 std::unique_ptr<Client> Client::CreateInstance(ConnArgs conn_args,
66469                                                base::TaskRunner* task_runner) {
66470   std::unique_ptr<Client> client(
66471       new ClientImpl(std::move(conn_args), task_runner));
66472   return client;
66473 }
66474 
ClientImpl(ConnArgs conn_args,base::TaskRunner * task_runner)66475 ClientImpl::ClientImpl(ConnArgs conn_args, base::TaskRunner* task_runner)
66476     : socket_name_(conn_args.socket_name),
66477       socket_retry_(conn_args.retry),
66478       task_runner_(task_runner),
66479       weak_ptr_factory_(this) {
66480   if (conn_args.socket_fd) {
66481     // Create the client using a connected socket. This code path will never hit
66482     // OnConnect().
66483     sock_ = base::UnixSocket::AdoptConnected(
66484         std::move(conn_args.socket_fd), this, task_runner_, kClientSockFamily,
66485         base::SockType::kStream, base::SockPeerCredMode::kIgnore);
66486   } else {
66487     // Connect using the socket name.
66488     TryConnect();
66489   }
66490 }
66491 
~ClientImpl()66492 ClientImpl::~ClientImpl() {
66493   // Ensure we are not destroyed in the middle of invoking a reply.
66494   PERFETTO_DCHECK(!invoking_method_reply_);
66495   OnDisconnect(
66496       nullptr);  // The base::UnixSocket* ptr is not used in OnDisconnect().
66497 }
66498 
TryConnect()66499 void ClientImpl::TryConnect() {
66500   PERFETTO_DCHECK(socket_name_);
66501   sock_ = base::UnixSocket::Connect(socket_name_, this, task_runner_,
66502                                     kClientSockFamily, base::SockType::kStream,
66503                                     base::SockPeerCredMode::kIgnore);
66504 }
66505 
BindService(base::WeakPtr<ServiceProxy> service_proxy)66506 void ClientImpl::BindService(base::WeakPtr<ServiceProxy> service_proxy) {
66507   if (!service_proxy)
66508     return;
66509   if (!sock_->is_connected()) {
66510     queued_bindings_.emplace_back(service_proxy);
66511     return;
66512   }
66513   RequestID request_id = ++last_request_id_;
66514   Frame frame;
66515   frame.set_request_id(request_id);
66516   Frame::BindService* req = frame.mutable_msg_bind_service();
66517   const char* const service_name = service_proxy->GetDescriptor().service_name;
66518   req->set_service_name(service_name);
66519   if (!SendFrame(frame)) {
66520     PERFETTO_DLOG("BindService(%s) failed", service_name);
66521     return service_proxy->OnConnect(false /* success */);
66522   }
66523   QueuedRequest qr;
66524   qr.type = Frame::kMsgBindServiceFieldNumber;
66525   qr.request_id = request_id;
66526   qr.service_proxy = service_proxy;
66527   queued_requests_.emplace(request_id, std::move(qr));
66528 }
66529 
UnbindService(ServiceID service_id)66530 void ClientImpl::UnbindService(ServiceID service_id) {
66531   service_bindings_.erase(service_id);
66532 }
66533 
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)66534 RequestID ClientImpl::BeginInvoke(ServiceID service_id,
66535                                   const std::string& method_name,
66536                                   MethodID remote_method_id,
66537                                   const ProtoMessage& method_args,
66538                                   bool drop_reply,
66539                                   base::WeakPtr<ServiceProxy> service_proxy,
66540                                   int fd) {
66541   RequestID request_id = ++last_request_id_;
66542   Frame frame;
66543   frame.set_request_id(request_id);
66544   Frame::InvokeMethod* req = frame.mutable_msg_invoke_method();
66545   req->set_service_id(service_id);
66546   req->set_method_id(remote_method_id);
66547   req->set_drop_reply(drop_reply);
66548   req->set_args_proto(method_args.SerializeAsString());
66549   if (!SendFrame(frame, fd)) {
66550     PERFETTO_DLOG("BeginInvoke() failed while sending the frame");
66551     return 0;
66552   }
66553   if (drop_reply)
66554     return 0;
66555   QueuedRequest qr;
66556   qr.type = Frame::kMsgInvokeMethodFieldNumber;
66557   qr.request_id = request_id;
66558   qr.method_name = method_name;
66559   qr.service_proxy = std::move(service_proxy);
66560   queued_requests_.emplace(request_id, std::move(qr));
66561   return request_id;
66562 }
66563 
SendFrame(const Frame & frame,int fd)66564 bool ClientImpl::SendFrame(const Frame& frame, int fd) {
66565   // Serialize the frame into protobuf, add the size header, and send it.
66566   std::string buf = BufferedFrameDeserializer::Serialize(frame);
66567 
66568   // TODO(primiano): this should do non-blocking I/O. But then what if the
66569   // socket buffer is full? We might want to either drop the request or throttle
66570   // the send and PostTask the reply later? Right now we are making Send()
66571   // blocking as a workaround. Propagate bakpressure to the caller instead.
66572   bool res = sock_->Send(buf.data(), buf.size(), fd);
66573   PERFETTO_CHECK(res || !sock_->is_connected());
66574   return res;
66575 }
66576 
OnConnect(base::UnixSocket *,bool connected)66577 void ClientImpl::OnConnect(base::UnixSocket*, bool connected) {
66578   if (!connected && socket_retry_) {
66579     socket_backoff_ms_ =
66580         (socket_backoff_ms_ < 10000) ? socket_backoff_ms_ + 1000 : 30000;
66581     PERFETTO_DLOG(
66582         "Connection to traced's UNIX socket failed, retrying in %u seconds",
66583         socket_backoff_ms_ / 1000);
66584     auto weak_this = weak_ptr_factory_.GetWeakPtr();
66585     task_runner_->PostDelayedTask(
66586         [weak_this] {
66587           if (weak_this)
66588             static_cast<ClientImpl&>(*weak_this).TryConnect();
66589         },
66590         socket_backoff_ms_);
66591     return;
66592   }
66593 
66594   // Drain the BindService() calls that were queued before establishing the
66595   // connection with the host. Note that if we got disconnected, the call to
66596   // OnConnect below might delete |this|, so move everything on the stack first.
66597   auto queued_bindings = std::move(queued_bindings_);
66598   queued_bindings_.clear();
66599   for (base::WeakPtr<ServiceProxy>& service_proxy : queued_bindings) {
66600     if (connected) {
66601       BindService(service_proxy);
66602     } else if (service_proxy) {
66603       service_proxy->OnConnect(false /* success */);
66604     }
66605   }
66606   // Don't access |this| below here.
66607 }
66608 
OnDisconnect(base::UnixSocket *)66609 void ClientImpl::OnDisconnect(base::UnixSocket*) {
66610   for (const auto& it : service_bindings_) {
66611     base::WeakPtr<ServiceProxy> service_proxy = it.second;
66612     task_runner_->PostTask([service_proxy] {
66613       if (service_proxy)
66614         service_proxy->OnDisconnect();
66615     });
66616   }
66617   service_bindings_.clear();
66618   queued_bindings_.clear();
66619 }
66620 
OnDataAvailable(base::UnixSocket *)66621 void ClientImpl::OnDataAvailable(base::UnixSocket*) {
66622   size_t rsize;
66623   do {
66624     auto buf = frame_deserializer_.BeginReceive();
66625     base::ScopedFile fd;
66626     rsize = sock_->Receive(buf.data, buf.size, &fd);
66627 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
66628     PERFETTO_DCHECK(!fd);
66629 #else
66630     if (fd) {
66631       PERFETTO_DCHECK(!received_fd_);
66632       int res = fcntl(*fd, F_SETFD, FD_CLOEXEC);
66633       PERFETTO_DCHECK(res == 0);
66634       received_fd_ = std::move(fd);
66635     }
66636 #endif
66637     if (!frame_deserializer_.EndReceive(rsize)) {
66638       // The endpoint tried to send a frame that is way too large.
66639       return sock_->Shutdown(true);  // In turn will trigger an OnDisconnect().
66640       // TODO(fmayer): check this.
66641     }
66642   } while (rsize > 0);
66643 
66644   while (std::unique_ptr<Frame> frame = frame_deserializer_.PopNextFrame())
66645     OnFrameReceived(*frame);
66646 }
66647 
OnFrameReceived(const Frame & frame)66648 void ClientImpl::OnFrameReceived(const Frame& frame) {
66649   auto queued_requests_it = queued_requests_.find(frame.request_id());
66650   if (queued_requests_it == queued_requests_.end()) {
66651     PERFETTO_DLOG("OnFrameReceived(): got invalid request_id=%" PRIu64,
66652                   static_cast<uint64_t>(frame.request_id()));
66653     return;
66654   }
66655   QueuedRequest req = std::move(queued_requests_it->second);
66656   queued_requests_.erase(queued_requests_it);
66657 
66658   if (req.type == Frame::kMsgBindServiceFieldNumber &&
66659       frame.has_msg_bind_service_reply()) {
66660     return OnBindServiceReply(std::move(req), frame.msg_bind_service_reply());
66661   }
66662   if (req.type == Frame::kMsgInvokeMethodFieldNumber &&
66663       frame.has_msg_invoke_method_reply()) {
66664     return OnInvokeMethodReply(std::move(req), frame.msg_invoke_method_reply());
66665   }
66666   if (frame.has_msg_request_error()) {
66667     PERFETTO_DLOG("Host error: %s", frame.msg_request_error().error().c_str());
66668     return;
66669   }
66670 
66671   PERFETTO_DLOG(
66672       "OnFrameReceived() request type=%d, received unknown frame in reply to "
66673       "request_id=%" PRIu64,
66674       req.type, static_cast<uint64_t>(frame.request_id()));
66675 }
66676 
OnBindServiceReply(QueuedRequest req,const Frame::BindServiceReply & reply)66677 void ClientImpl::OnBindServiceReply(QueuedRequest req,
66678                                     const Frame::BindServiceReply& reply) {
66679   base::WeakPtr<ServiceProxy>& service_proxy = req.service_proxy;
66680   if (!service_proxy)
66681     return;
66682   const char* svc_name = service_proxy->GetDescriptor().service_name;
66683   if (!reply.success()) {
66684     PERFETTO_DLOG("BindService(): unknown service_name=\"%s\"", svc_name);
66685     return service_proxy->OnConnect(false /* success */);
66686   }
66687 
66688   auto prev_service = service_bindings_.find(reply.service_id());
66689   if (prev_service != service_bindings_.end() && prev_service->second.get()) {
66690     PERFETTO_DLOG(
66691         "BindService(): Trying to bind service \"%s\" but another service "
66692         "named \"%s\" is already bound with the same ID.",
66693         svc_name, prev_service->second->GetDescriptor().service_name);
66694     return service_proxy->OnConnect(false /* success */);
66695   }
66696 
66697   // Build the method [name] -> [remote_id] map.
66698   std::map<std::string, MethodID> methods;
66699   for (const auto& method : reply.methods()) {
66700     if (method.name().empty() || method.id() <= 0) {
66701       PERFETTO_DLOG("OnBindServiceReply(): invalid method \"%s\" -> %" PRIu64,
66702                     method.name().c_str(), static_cast<uint64_t>(method.id()));
66703       continue;
66704     }
66705     methods[method.name()] = method.id();
66706   }
66707   service_proxy->InitializeBinding(weak_ptr_factory_.GetWeakPtr(),
66708                                    reply.service_id(), std::move(methods));
66709   service_bindings_[reply.service_id()] = service_proxy;
66710   service_proxy->OnConnect(true /* success */);
66711 }
66712 
OnInvokeMethodReply(QueuedRequest req,const Frame::InvokeMethodReply & reply)66713 void ClientImpl::OnInvokeMethodReply(QueuedRequest req,
66714                                      const Frame::InvokeMethodReply& reply) {
66715   base::WeakPtr<ServiceProxy> service_proxy = req.service_proxy;
66716   if (!service_proxy)
66717     return;
66718   std::unique_ptr<ProtoMessage> decoded_reply;
66719   if (reply.success()) {
66720     // If this becomes a hotspot, optimize by maintaining a dedicated hashtable.
66721     for (const auto& method : service_proxy->GetDescriptor().methods) {
66722       if (req.method_name == method.name) {
66723         decoded_reply = method.reply_proto_decoder(reply.reply_proto());
66724         break;
66725       }
66726     }
66727   }
66728   const RequestID request_id = req.request_id;
66729   invoking_method_reply_ = true;
66730   service_proxy->EndInvoke(request_id, std::move(decoded_reply),
66731                            reply.has_more());
66732   invoking_method_reply_ = false;
66733 
66734   // If this is a streaming method and future replies will be resolved, put back
66735   // the |req| with the callback into the set of active requests.
66736   if (reply.has_more())
66737     queued_requests_.emplace(request_id, std::move(req));
66738 }
66739 
66740 ClientImpl::QueuedRequest::QueuedRequest() = default;
66741 
TakeReceivedFD()66742 base::ScopedFile ClientImpl::TakeReceivedFD() {
66743   return std::move(received_fd_);
66744 }
66745 
66746 }  // namespace ipc
66747 }  // namespace perfetto
66748 // gen_amalgamated begin source: src/ipc/service_proxy.cc
66749 /*
66750  * Copyright (C) 2017 The Android Open Source Project
66751  *
66752  * Licensed under the Apache License, Version 2.0 (the "License");
66753  * you may not use this file except in compliance with the License.
66754  * You may obtain a copy of the License at
66755  *
66756  *      http://www.apache.org/licenses/LICENSE-2.0
66757  *
66758  * Unless required by applicable law or agreed to in writing, software
66759  * distributed under the License is distributed on an "AS IS" BASIS,
66760  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
66761  * See the License for the specific language governing permissions and
66762  * limitations under the License.
66763  */
66764 
66765 // gen_amalgamated expanded: #include "perfetto/ext/ipc/service_proxy.h"
66766 
66767 #include <utility>
66768 
66769 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
66770 // gen_amalgamated expanded: #include "perfetto/ext/base/weak_ptr.h"
66771 // gen_amalgamated expanded: #include "perfetto/ext/ipc/service_descriptor.h"
66772 // gen_amalgamated expanded: #include "src/ipc/client_impl.h"
66773 
66774 // gen_amalgamated expanded: #include "protos/perfetto/ipc/wire_protocol.gen.h"
66775 
66776 namespace perfetto {
66777 namespace ipc {
66778 
ServiceProxy(EventListener * event_listener)66779 ServiceProxy::ServiceProxy(EventListener* event_listener)
66780     : event_listener_(event_listener), weak_ptr_factory_(this) {}
66781 
~ServiceProxy()66782 ServiceProxy::~ServiceProxy() {
66783   if (client_ && connected())
66784     client_->UnbindService(service_id_);
66785 }
66786 
InitializeBinding(base::WeakPtr<Client> client,ServiceID service_id,std::map<std::string,MethodID> remote_method_ids)66787 void ServiceProxy::InitializeBinding(
66788     base::WeakPtr<Client> client,
66789     ServiceID service_id,
66790     std::map<std::string, MethodID> remote_method_ids) {
66791   client_ = std::move(client);
66792   service_id_ = service_id;
66793   remote_method_ids_ = std::move(remote_method_ids);
66794 }
66795 
BeginInvoke(const std::string & method_name,const ProtoMessage & request,DeferredBase reply,int fd)66796 void ServiceProxy::BeginInvoke(const std::string& method_name,
66797                                const ProtoMessage& request,
66798                                DeferredBase reply,
66799                                int fd) {
66800   // |reply| will auto-resolve if it gets out of scope early.
66801   if (!connected()) {
66802     PERFETTO_DFATAL("Not connected.");
66803     return;
66804   }
66805   if (!client_)
66806     return;  // The Client object has been destroyed in the meantime.
66807 
66808   auto remote_method_it = remote_method_ids_.find(method_name);
66809   RequestID request_id = 0;
66810   const bool drop_reply = !reply.IsBound();
66811   if (remote_method_it != remote_method_ids_.end()) {
66812     request_id =
66813         static_cast<ClientImpl*>(client_.get())
66814             ->BeginInvoke(service_id_, method_name, remote_method_it->second,
66815                           request, drop_reply, weak_ptr_factory_.GetWeakPtr(),
66816                           fd);
66817   } else {
66818     PERFETTO_DLOG("Cannot find method \"%s\" on the host", method_name.c_str());
66819   }
66820 
66821   // When passing |drop_reply| == true, the returned |request_id| should be 0.
66822   PERFETTO_DCHECK(!drop_reply || !request_id);
66823 
66824   if (!request_id)
66825     return;
66826   PERFETTO_DCHECK(pending_callbacks_.count(request_id) == 0);
66827   pending_callbacks_.emplace(request_id, std::move(reply));
66828 }
66829 
EndInvoke(RequestID request_id,std::unique_ptr<ProtoMessage> result,bool has_more)66830 void ServiceProxy::EndInvoke(RequestID request_id,
66831                              std::unique_ptr<ProtoMessage> result,
66832                              bool has_more) {
66833   auto callback_it = pending_callbacks_.find(request_id);
66834   if (callback_it == pending_callbacks_.end()) {
66835     // Either we are getting a reply for a method we never invoked, or we are
66836     // getting a reply to a method marked drop_reply (that has been invoked
66837     // without binding any callback in the Defererd response object).
66838     PERFETTO_DFATAL("Unexpected reply received.");
66839     return;
66840   }
66841   DeferredBase& reply_callback = callback_it->second;
66842   AsyncResult<ProtoMessage> reply(std::move(result), has_more);
66843   reply_callback.Resolve(std::move(reply));
66844   if (!has_more)
66845     pending_callbacks_.erase(callback_it);
66846 }
66847 
OnConnect(bool success)66848 void ServiceProxy::OnConnect(bool success) {
66849   if (success) {
66850     PERFETTO_DCHECK(service_id_);
66851     return event_listener_->OnConnect();
66852   }
66853   return event_listener_->OnDisconnect();
66854 }
66855 
OnDisconnect()66856 void ServiceProxy::OnDisconnect() {
66857   pending_callbacks_.clear();  // Will Reject() all the pending callbacks.
66858   event_listener_->OnDisconnect();
66859 }
66860 
GetWeakPtr() const66861 base::WeakPtr<ServiceProxy> ServiceProxy::GetWeakPtr() const {
66862   return weak_ptr_factory_.GetWeakPtr();
66863 }
66864 
66865 }  // namespace ipc
66866 }  // namespace perfetto
66867 // gen_amalgamated begin source: src/ipc/host_impl.cc
66868 // gen_amalgamated begin header: src/ipc/host_impl.h
66869 /*
66870  * Copyright (C) 2017 The Android Open Source Project
66871  *
66872  * Licensed under the Apache License, Version 2.0 (the "License");
66873  * you may not use this file except in compliance with the License.
66874  * You may obtain a copy of the License at
66875  *
66876  *      http://www.apache.org/licenses/LICENSE-2.0
66877  *
66878  * Unless required by applicable law or agreed to in writing, software
66879  * distributed under the License is distributed on an "AS IS" BASIS,
66880  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
66881  * See the License for the specific language governing permissions and
66882  * limitations under the License.
66883  */
66884 
66885 #ifndef SRC_IPC_HOST_IMPL_H_
66886 #define SRC_IPC_HOST_IMPL_H_
66887 
66888 #include <map>
66889 #include <set>
66890 #include <string>
66891 #include <vector>
66892 
66893 // gen_amalgamated expanded: #include "perfetto/base/task_runner.h"
66894 // gen_amalgamated expanded: #include "perfetto/ext/base/thread_checker.h"
66895 // gen_amalgamated expanded: #include "perfetto/ext/base/unix_socket.h"
66896 // gen_amalgamated expanded: #include "perfetto/ext/ipc/deferred.h"
66897 // gen_amalgamated expanded: #include "perfetto/ext/ipc/host.h"
66898 // gen_amalgamated expanded: #include "src/ipc/buffered_frame_deserializer.h"
66899 
66900 namespace perfetto {
66901 namespace ipc {
66902 
66903 class HostImpl : public Host, public base::UnixSocket::EventListener {
66904  public:
66905   HostImpl(const char* socket_name, base::TaskRunner*);
66906   HostImpl(base::ScopedSocketHandle, base::TaskRunner*);
66907   ~HostImpl() override;
66908 
66909   // Host implementation.
66910   bool ExposeService(std::unique_ptr<Service>) override;
66911 
66912   // base::UnixSocket::EventListener implementation.
66913   void OnNewIncomingConnection(base::UnixSocket*,
66914                                std::unique_ptr<base::UnixSocket>) override;
66915   void OnDisconnect(base::UnixSocket*) override;
66916   void OnDataAvailable(base::UnixSocket*) override;
66917 
sock() const66918   const base::UnixSocket* sock() const { return sock_.get(); }
66919 
66920  private:
66921   // Owns the per-client receive buffer (BufferedFrameDeserializer).
66922   struct ClientConnection {
66923     ~ClientConnection();
66924     ClientID id;
66925     std::unique_ptr<base::UnixSocket> sock;
66926     BufferedFrameDeserializer frame_deserializer;
66927     base::ScopedFile received_fd;
66928   };
66929   struct ExposedService {
66930     ExposedService(ServiceID, const std::string&, std::unique_ptr<Service>);
66931     ~ExposedService();
66932     ExposedService(ExposedService&&) noexcept;
66933     ExposedService& operator=(ExposedService&&);
66934 
66935     ServiceID id;
66936     std::string name;
66937     std::unique_ptr<Service> instance;
66938   };
66939 
66940   HostImpl(const HostImpl&) = delete;
66941   HostImpl& operator=(const HostImpl&) = delete;
66942 
66943   bool Initialize(const char* socket_name);
66944   void OnReceivedFrame(ClientConnection*, const Frame&);
66945   void OnBindService(ClientConnection*, const Frame&);
66946   void OnInvokeMethod(ClientConnection*, const Frame&);
66947   void ReplyToMethodInvocation(ClientID, RequestID, AsyncResult<ProtoMessage>);
66948   const ExposedService* GetServiceByName(const std::string&);
66949 
66950   static void SendFrame(ClientConnection*, const Frame&, int fd = -1);
66951 
66952   base::TaskRunner* const task_runner_;
66953   std::map<ServiceID, ExposedService> services_;
66954   std::unique_ptr<base::UnixSocket> sock_;  // The listening socket.
66955   std::map<ClientID, std::unique_ptr<ClientConnection>> clients_;
66956   std::map<base::UnixSocket*, ClientConnection*> clients_by_socket_;
66957   ServiceID last_service_id_ = 0;
66958   ClientID last_client_id_ = 0;
66959   PERFETTO_THREAD_CHECKER(thread_checker_)
66960   base::WeakPtrFactory<HostImpl> weak_ptr_factory_;  // Keep last.
66961 };
66962 
66963 }  // namespace ipc
66964 }  // namespace perfetto
66965 
66966 #endif  // SRC_IPC_HOST_IMPL_H_
66967 /*
66968  * Copyright (C) 2017 The Android Open Source Project
66969  *
66970  * Licensed under the Apache License, Version 2.0 (the "License");
66971  * you may not use this file except in compliance with the License.
66972  * You may obtain a copy of the License at
66973  *
66974  *      http://www.apache.org/licenses/LICENSE-2.0
66975  *
66976  * Unless required by applicable law or agreed to in writing, software
66977  * distributed under the License is distributed on an "AS IS" BASIS,
66978  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
66979  * See the License for the specific language governing permissions and
66980  * limitations under the License.
66981  */
66982 
66983 // gen_amalgamated expanded: #include "src/ipc/host_impl.h"
66984 
66985 #include <algorithm>
66986 #include <cinttypes>
66987 #include <utility>
66988 
66989 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
66990 // gen_amalgamated expanded: #include "perfetto/base/task_runner.h"
66991 // gen_amalgamated expanded: #include "perfetto/base/time.h"
66992 // gen_amalgamated expanded: #include "perfetto/ext/base/crash_keys.h"
66993 // gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
66994 // gen_amalgamated expanded: #include "perfetto/ext/ipc/service.h"
66995 // gen_amalgamated expanded: #include "perfetto/ext/ipc/service_descriptor.h"
66996 
66997 // gen_amalgamated expanded: #include "protos/perfetto/ipc/wire_protocol.gen.h"
66998 
66999 #if (PERFETTO_BUILDFLAG(PERFETTO_STANDALONE_BUILD) || \
67000      PERFETTO_BUILDFLAG(PERFETTO_ANDROID_BUILD)) &&   \
67001     (PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) ||         \
67002      PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID))
67003 #define PERFETTO_LOG_TXBUF_FOR_B_191600928
67004 // TODO(primiano): temporary for investigating b/191600928. Remove in Jan 2022
67005 #include <sys/ioctl.h>
67006 #endif
67007 
67008 // TODO(primiano): put limits on #connections/uid and req. queue (b/69093705).
67009 
67010 namespace perfetto {
67011 namespace ipc {
67012 
67013 namespace {
67014 
67015 constexpr base::SockFamily kHostSockFamily =
67016     kUseTCPSocket ? base::SockFamily::kInet : base::SockFamily::kUnix;
67017 
67018 // TODO(primiano): temporary for investigating b/191600928. Remove in Jan 2022.
67019 base::CrashKey g_crash_key_uid("ipc_uid");
67020 base::CrashKey g_crash_key_tx_b("ipc_tx_boot");
67021 base::CrashKey g_crash_key_tx_m("ipc_tx_mono");
67022 base::CrashKey g_crash_key_tx_qlen("ipc_tx_qlen");
67023 
GetPosixPeerUid(base::UnixSocket * sock)67024 uid_t GetPosixPeerUid(base::UnixSocket* sock) {
67025 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
67026   base::ignore_result(sock);
67027   // Unsupported. Must be != kInvalidUid or the PacketValidator will fail.
67028   return 0;
67029 #else
67030   return sock->peer_uid_posix();
67031 #endif
67032 }
67033 
67034 }  // namespace
67035 
67036 // static
CreateInstance(const char * socket_name,base::TaskRunner * task_runner)67037 std::unique_ptr<Host> Host::CreateInstance(const char* socket_name,
67038                                            base::TaskRunner* task_runner) {
67039   std::unique_ptr<HostImpl> host(new HostImpl(socket_name, task_runner));
67040   if (!host->sock() || !host->sock()->is_listening())
67041     return nullptr;
67042   return std::unique_ptr<Host>(std::move(host));
67043 }
67044 
67045 // static
CreateInstance(base::ScopedSocketHandle socket_fd,base::TaskRunner * task_runner)67046 std::unique_ptr<Host> Host::CreateInstance(base::ScopedSocketHandle socket_fd,
67047                                            base::TaskRunner* task_runner) {
67048   std::unique_ptr<HostImpl> host(
67049       new HostImpl(std::move(socket_fd), task_runner));
67050   if (!host->sock() || !host->sock()->is_listening())
67051     return nullptr;
67052   return std::unique_ptr<Host>(std::move(host));
67053 }
67054 
HostImpl(base::ScopedSocketHandle socket_fd,base::TaskRunner * task_runner)67055 HostImpl::HostImpl(base::ScopedSocketHandle socket_fd,
67056                    base::TaskRunner* task_runner)
67057     : task_runner_(task_runner), weak_ptr_factory_(this) {
67058   PERFETTO_DCHECK_THREAD(thread_checker_);
67059   sock_ = base::UnixSocket::Listen(std::move(socket_fd), this, task_runner_,
67060                                    kHostSockFamily, base::SockType::kStream);
67061 }
67062 
HostImpl(const char * socket_name,base::TaskRunner * task_runner)67063 HostImpl::HostImpl(const char* socket_name, base::TaskRunner* task_runner)
67064     : task_runner_(task_runner), weak_ptr_factory_(this) {
67065   PERFETTO_DCHECK_THREAD(thread_checker_);
67066   sock_ = base::UnixSocket::Listen(socket_name, this, task_runner_,
67067                                    kHostSockFamily, base::SockType::kStream);
67068   if (!sock_) {
67069     PERFETTO_PLOG("Failed to create %s", socket_name);
67070   }
67071 }
67072 
67073 HostImpl::~HostImpl() = default;
67074 
ExposeService(std::unique_ptr<Service> service)67075 bool HostImpl::ExposeService(std::unique_ptr<Service> service) {
67076   PERFETTO_DCHECK_THREAD(thread_checker_);
67077   const std::string& service_name = service->GetDescriptor().service_name;
67078   if (GetServiceByName(service_name)) {
67079     PERFETTO_DLOG("Duplicate ExposeService(): %s", service_name.c_str());
67080     return false;
67081   }
67082   ServiceID sid = ++last_service_id_;
67083   ExposedService exposed_service(sid, service_name, std::move(service));
67084   services_.emplace(sid, std::move(exposed_service));
67085   return true;
67086 }
67087 
OnNewIncomingConnection(base::UnixSocket *,std::unique_ptr<base::UnixSocket> new_conn)67088 void HostImpl::OnNewIncomingConnection(
67089     base::UnixSocket*,
67090     std::unique_ptr<base::UnixSocket> new_conn) {
67091   PERFETTO_DCHECK_THREAD(thread_checker_);
67092   std::unique_ptr<ClientConnection> client(new ClientConnection());
67093   ClientID client_id = ++last_client_id_;
67094   clients_by_socket_[new_conn.get()] = client.get();
67095   client->id = client_id;
67096   client->sock = std::move(new_conn);
67097   // Watchdog is 30 seconds, so set the socket timeout to 10 seconds.
67098   client->sock->SetTxTimeout(10000);
67099   clients_[client_id] = std::move(client);
67100 }
67101 
OnDataAvailable(base::UnixSocket * sock)67102 void HostImpl::OnDataAvailable(base::UnixSocket* sock) {
67103   PERFETTO_DCHECK_THREAD(thread_checker_);
67104   auto it = clients_by_socket_.find(sock);
67105   if (it == clients_by_socket_.end())
67106     return;
67107   ClientConnection* client = it->second;
67108   BufferedFrameDeserializer& frame_deserializer = client->frame_deserializer;
67109 
67110   auto peer_uid = GetPosixPeerUid(client->sock.get());
67111   auto scoped_key = g_crash_key_uid.SetScoped(static_cast<int64_t>(peer_uid));
67112 
67113   size_t rsize;
67114   do {
67115     auto buf = frame_deserializer.BeginReceive();
67116     base::ScopedFile fd;
67117     rsize = client->sock->Receive(buf.data, buf.size, &fd);
67118     if (fd) {
67119       PERFETTO_DCHECK(!client->received_fd);
67120       client->received_fd = std::move(fd);
67121     }
67122     if (!frame_deserializer.EndReceive(rsize))
67123       return OnDisconnect(client->sock.get());
67124   } while (rsize > 0);
67125 
67126   for (;;) {
67127     std::unique_ptr<Frame> frame = frame_deserializer.PopNextFrame();
67128     if (!frame)
67129       break;
67130     OnReceivedFrame(client, *frame);
67131   }
67132 }
67133 
OnReceivedFrame(ClientConnection * client,const Frame & req_frame)67134 void HostImpl::OnReceivedFrame(ClientConnection* client,
67135                                const Frame& req_frame) {
67136   if (req_frame.has_msg_bind_service())
67137     return OnBindService(client, req_frame);
67138   if (req_frame.has_msg_invoke_method())
67139     return OnInvokeMethod(client, req_frame);
67140 
67141   PERFETTO_DLOG("Received invalid RPC frame from client %" PRIu64, client->id);
67142   Frame reply_frame;
67143   reply_frame.set_request_id(req_frame.request_id());
67144   reply_frame.mutable_msg_request_error()->set_error("unknown request");
67145   SendFrame(client, reply_frame);
67146 }
67147 
OnBindService(ClientConnection * client,const Frame & req_frame)67148 void HostImpl::OnBindService(ClientConnection* client, const Frame& req_frame) {
67149   // Binding a service doesn't do anything major. It just returns back the
67150   // service id and its method map.
67151   const Frame::BindService& req = req_frame.msg_bind_service();
67152   Frame reply_frame;
67153   reply_frame.set_request_id(req_frame.request_id());
67154   auto* reply = reply_frame.mutable_msg_bind_service_reply();
67155   const ExposedService* service = GetServiceByName(req.service_name());
67156   if (service) {
67157     reply->set_success(true);
67158     reply->set_service_id(service->id);
67159     uint32_t method_id = 1;  // method ids start at index 1.
67160     for (const auto& desc_method : service->instance->GetDescriptor().methods) {
67161       Frame::BindServiceReply::MethodInfo* method_info = reply->add_methods();
67162       method_info->set_name(desc_method.name);
67163       method_info->set_id(method_id++);
67164     }
67165   }
67166   SendFrame(client, reply_frame);
67167 }
67168 
OnInvokeMethod(ClientConnection * client,const Frame & req_frame)67169 void HostImpl::OnInvokeMethod(ClientConnection* client,
67170                               const Frame& req_frame) {
67171   const Frame::InvokeMethod& req = req_frame.msg_invoke_method();
67172   Frame reply_frame;
67173   RequestID request_id = req_frame.request_id();
67174   reply_frame.set_request_id(request_id);
67175   reply_frame.mutable_msg_invoke_method_reply()->set_success(false);
67176   auto svc_it = services_.find(req.service_id());
67177   if (svc_it == services_.end())
67178     return SendFrame(client, reply_frame);  // |success| == false by default.
67179 
67180   Service* service = svc_it->second.instance.get();
67181   const ServiceDescriptor& svc = service->GetDescriptor();
67182   const auto& methods = svc.methods;
67183   const uint32_t method_id = req.method_id();
67184   if (method_id == 0 || method_id > methods.size())
67185     return SendFrame(client, reply_frame);
67186 
67187   const ServiceDescriptor::Method& method = methods[method_id - 1];
67188   std::unique_ptr<ProtoMessage> decoded_req_args(
67189       method.request_proto_decoder(req.args_proto()));
67190   if (!decoded_req_args)
67191     return SendFrame(client, reply_frame);
67192 
67193   Deferred<ProtoMessage> deferred_reply;
67194   base::WeakPtr<HostImpl> host_weak_ptr = weak_ptr_factory_.GetWeakPtr();
67195   ClientID client_id = client->id;
67196 
67197   if (!req.drop_reply()) {
67198     deferred_reply.Bind([host_weak_ptr, client_id,
67199                          request_id](AsyncResult<ProtoMessage> reply) {
67200       if (!host_weak_ptr)
67201         return;  // The reply came too late, the HostImpl has gone.
67202       host_weak_ptr->ReplyToMethodInvocation(client_id, request_id,
67203                                              std::move(reply));
67204     });
67205   }
67206 
67207   auto peer_uid = GetPosixPeerUid(client->sock.get());
67208   auto scoped_key = g_crash_key_uid.SetScoped(static_cast<int64_t>(peer_uid));
67209   service->client_info_ = ClientInfo(client->id, peer_uid);
67210   service->received_fd_ = &client->received_fd;
67211   method.invoker(service, *decoded_req_args, std::move(deferred_reply));
67212   service->received_fd_ = nullptr;
67213   service->client_info_ = ClientInfo();
67214 }
67215 
ReplyToMethodInvocation(ClientID client_id,RequestID request_id,AsyncResult<ProtoMessage> reply)67216 void HostImpl::ReplyToMethodInvocation(ClientID client_id,
67217                                        RequestID request_id,
67218                                        AsyncResult<ProtoMessage> reply) {
67219   auto client_iter = clients_.find(client_id);
67220   if (client_iter == clients_.end())
67221     return;  // client has disconnected by the time we got the async reply.
67222 
67223   ClientConnection* client = client_iter->second.get();
67224   Frame reply_frame;
67225   reply_frame.set_request_id(request_id);
67226 
67227   // TODO(fmayer): add a test to guarantee that the reply is consumed within the
67228   // same call stack and not kept around. ConsumerIPCService::OnTraceData()
67229   // relies on this behavior.
67230   auto* reply_frame_data = reply_frame.mutable_msg_invoke_method_reply();
67231   reply_frame_data->set_has_more(reply.has_more());
67232   if (reply.success()) {
67233     std::string reply_proto = reply->SerializeAsString();
67234     reply_frame_data->set_reply_proto(reply_proto);
67235     reply_frame_data->set_success(true);
67236   }
67237   SendFrame(client, reply_frame, reply.fd());
67238 }
67239 
67240 // static
SendFrame(ClientConnection * client,const Frame & frame,int fd)67241 void HostImpl::SendFrame(ClientConnection* client, const Frame& frame, int fd) {
67242   auto peer_uid = GetPosixPeerUid(client->sock.get());
67243   auto scoped_key = g_crash_key_uid.SetScoped(static_cast<int64_t>(peer_uid));
67244 
67245   std::string buf = BufferedFrameDeserializer::Serialize(frame);
67246 
67247   auto crash_key_b = g_crash_key_tx_b.SetScoped(base::GetBootTimeS().count());
67248   auto crash_key_w = g_crash_key_tx_m.SetScoped(base::GetWallTimeS().count());
67249 
67250 #if defined(PERFETTO_LOG_TXBUF_FOR_B_191600928)
67251   int32_t tx_queue_len = 0;
67252   ioctl(client->sock->fd(), TIOCOUTQ, &tx_queue_len);
67253   auto crash_key_qlen = g_crash_key_tx_qlen.SetScoped(tx_queue_len);
67254 #else
67255   base::ignore_result(g_crash_key_tx_qlen);
67256 #endif
67257 
67258   // When a new Client connects in OnNewClientConnection we set a timeout on
67259   // Send (see call to SetTxTimeout).
67260   //
67261   // The old behaviour was to do a blocking I/O call, which caused crashes from
67262   // misbehaving producers (see b/169051440).
67263   bool res = client->sock->Send(buf.data(), buf.size(), fd);
67264   // If we timeout |res| will be false, but the UnixSocket will have called
67265   // UnixSocket::ShutDown() and thus |is_connected()| is false.
67266   PERFETTO_CHECK(res || !client->sock->is_connected());
67267 }
67268 
OnDisconnect(base::UnixSocket * sock)67269 void HostImpl::OnDisconnect(base::UnixSocket* sock) {
67270   PERFETTO_DCHECK_THREAD(thread_checker_);
67271   auto it = clients_by_socket_.find(sock);
67272   if (it == clients_by_socket_.end())
67273     return;
67274   ClientID client_id = it->second->id;
67275 
67276   ClientInfo client_info(client_id, GetPosixPeerUid(sock));
67277   clients_by_socket_.erase(it);
67278   PERFETTO_DCHECK(clients_.count(client_id));
67279   clients_.erase(client_id);
67280 
67281   for (const auto& service_it : services_) {
67282     Service& service = *service_it.second.instance;
67283     service.client_info_ = client_info;
67284     service.OnClientDisconnected();
67285     service.client_info_ = ClientInfo();
67286   }
67287 }
67288 
GetServiceByName(const std::string & name)67289 const HostImpl::ExposedService* HostImpl::GetServiceByName(
67290     const std::string& name) {
67291   // This could be optimized by using another map<name,ServiceID>. However this
67292   // is used only by Bind/ExposeService that are quite rare (once per client
67293   // connection and once per service instance), not worth it.
67294   for (const auto& it : services_) {
67295     if (it.second.name == name)
67296       return &it.second;
67297   }
67298   return nullptr;
67299 }
67300 
ExposedService(ServiceID id_,const std::string & name_,std::unique_ptr<Service> instance_)67301 HostImpl::ExposedService::ExposedService(ServiceID id_,
67302                                          const std::string& name_,
67303                                          std::unique_ptr<Service> instance_)
67304     : id(id_), name(name_), instance(std::move(instance_)) {}
67305 
67306 HostImpl::ExposedService::ExposedService(ExposedService&&) noexcept = default;
67307 HostImpl::ExposedService& HostImpl::ExposedService::operator=(
67308     HostImpl::ExposedService&&) = default;
67309 HostImpl::ExposedService::~ExposedService() = default;
67310 
67311 HostImpl::ClientConnection::~ClientConnection() = default;
67312 
67313 }  // namespace ipc
67314 }  // namespace perfetto
67315 // gen_amalgamated begin source: gen/protos/perfetto/ipc/consumer_port.ipc.cc
67316 // gen_amalgamated begin header: gen/protos/perfetto/ipc/consumer_port.ipc.h
67317 // DO NOT EDIT. Autogenerated by Perfetto IPC
67318 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_IPC_CONSUMER_PORT_PROTO_H_
67319 #define PERFETTO_PROTOS_PROTOS_PERFETTO_IPC_CONSUMER_PORT_PROTO_H_
67320 
67321 // gen_amalgamated expanded: #include "perfetto/ext/ipc/deferred.h"
67322 // gen_amalgamated expanded: #include "perfetto/ext/ipc/service.h"
67323 // gen_amalgamated expanded: #include "perfetto/ext/ipc/service_descriptor.h"
67324 // gen_amalgamated expanded: #include "perfetto/ext/ipc/service_proxy.h"
67325 
67326 // gen_amalgamated expanded: #include "protos/perfetto/ipc/consumer_port.gen.h"
67327 // gen_amalgamated expanded: #include "protos/perfetto/common/observable_events.gen.h"
67328 // gen_amalgamated expanded: #include "protos/perfetto/common/tracing_service_state.gen.h"
67329 // gen_amalgamated expanded: #include "protos/perfetto/common/tracing_service_capabilities.gen.h"
67330 // gen_amalgamated expanded: #include "protos/perfetto/common/trace_stats.gen.h"
67331 // gen_amalgamated expanded: #include "protos/perfetto/config/trace_config.gen.h"
67332 
67333 namespace perfetto {
67334 namespace protos {
67335 namespace gen {
67336 
67337 class ConsumerPort : public ::perfetto::ipc::Service {
67338  private:
67339   static ::perfetto::ipc::ServiceDescriptor* NewDescriptor();
67340 
67341  public:
67342   ~ConsumerPort() override;
67343 
67344   static const ::perfetto::ipc::ServiceDescriptor& GetDescriptorStatic();
67345 
67346   // Service implementation.
67347   const ::perfetto::ipc::ServiceDescriptor& GetDescriptor() override;
67348 
67349   // Methods from the .proto file
67350   using DeferredEnableTracingResponse = ::perfetto::ipc::Deferred<EnableTracingResponse>;
67351   virtual void EnableTracing(const EnableTracingRequest&, DeferredEnableTracingResponse) = 0;
67352 
67353   using DeferredDisableTracingResponse = ::perfetto::ipc::Deferred<DisableTracingResponse>;
67354   virtual void DisableTracing(const DisableTracingRequest&, DeferredDisableTracingResponse) = 0;
67355 
67356   using DeferredReadBuffersResponse = ::perfetto::ipc::Deferred<ReadBuffersResponse>;
67357   virtual void ReadBuffers(const ReadBuffersRequest&, DeferredReadBuffersResponse) = 0;
67358 
67359   using DeferredFreeBuffersResponse = ::perfetto::ipc::Deferred<FreeBuffersResponse>;
67360   virtual void FreeBuffers(const FreeBuffersRequest&, DeferredFreeBuffersResponse) = 0;
67361 
67362   using DeferredFlushResponse = ::perfetto::ipc::Deferred<FlushResponse>;
67363   virtual void Flush(const FlushRequest&, DeferredFlushResponse) = 0;
67364 
67365   using DeferredStartTracingResponse = ::perfetto::ipc::Deferred<StartTracingResponse>;
67366   virtual void StartTracing(const StartTracingRequest&, DeferredStartTracingResponse) = 0;
67367 
67368   using DeferredChangeTraceConfigResponse = ::perfetto::ipc::Deferred<ChangeTraceConfigResponse>;
67369   virtual void ChangeTraceConfig(const ChangeTraceConfigRequest&, DeferredChangeTraceConfigResponse) = 0;
67370 
67371   using DeferredDetachResponse = ::perfetto::ipc::Deferred<DetachResponse>;
67372   virtual void Detach(const DetachRequest&, DeferredDetachResponse) = 0;
67373 
67374   using DeferredAttachResponse = ::perfetto::ipc::Deferred<AttachResponse>;
67375   virtual void Attach(const AttachRequest&, DeferredAttachResponse) = 0;
67376 
67377   using DeferredGetTraceStatsResponse = ::perfetto::ipc::Deferred<GetTraceStatsResponse>;
67378   virtual void GetTraceStats(const GetTraceStatsRequest&, DeferredGetTraceStatsResponse) = 0;
67379 
67380   using DeferredObserveEventsResponse = ::perfetto::ipc::Deferred<ObserveEventsResponse>;
67381   virtual void ObserveEvents(const ObserveEventsRequest&, DeferredObserveEventsResponse) = 0;
67382 
67383   using DeferredQueryServiceStateResponse = ::perfetto::ipc::Deferred<QueryServiceStateResponse>;
67384   virtual void QueryServiceState(const QueryServiceStateRequest&, DeferredQueryServiceStateResponse) = 0;
67385 
67386   using DeferredQueryCapabilitiesResponse = ::perfetto::ipc::Deferred<QueryCapabilitiesResponse>;
67387   virtual void QueryCapabilities(const QueryCapabilitiesRequest&, DeferredQueryCapabilitiesResponse) = 0;
67388 
67389   using DeferredSaveTraceForBugreportResponse = ::perfetto::ipc::Deferred<SaveTraceForBugreportResponse>;
67390   virtual void SaveTraceForBugreport(const SaveTraceForBugreportRequest&, DeferredSaveTraceForBugreportResponse) = 0;
67391 
67392 };
67393 
67394 
67395 class ConsumerPortProxy : public ::perfetto::ipc::ServiceProxy {
67396  public:
67397    explicit ConsumerPortProxy(::perfetto::ipc::ServiceProxy::EventListener*);
67398    ~ConsumerPortProxy() override;
67399 
67400   // ServiceProxy implementation.
67401   const ::perfetto::ipc::ServiceDescriptor& GetDescriptor() override;
67402 
67403   // Methods from the .proto file
67404   using DeferredEnableTracingResponse = ::perfetto::ipc::Deferred<EnableTracingResponse>;
67405   void EnableTracing(const EnableTracingRequest&, DeferredEnableTracingResponse, int fd = -1);
67406 
67407   using DeferredDisableTracingResponse = ::perfetto::ipc::Deferred<DisableTracingResponse>;
67408   void DisableTracing(const DisableTracingRequest&, DeferredDisableTracingResponse, int fd = -1);
67409 
67410   using DeferredReadBuffersResponse = ::perfetto::ipc::Deferred<ReadBuffersResponse>;
67411   void ReadBuffers(const ReadBuffersRequest&, DeferredReadBuffersResponse, int fd = -1);
67412 
67413   using DeferredFreeBuffersResponse = ::perfetto::ipc::Deferred<FreeBuffersResponse>;
67414   void FreeBuffers(const FreeBuffersRequest&, DeferredFreeBuffersResponse, int fd = -1);
67415 
67416   using DeferredFlushResponse = ::perfetto::ipc::Deferred<FlushResponse>;
67417   void Flush(const FlushRequest&, DeferredFlushResponse, int fd = -1);
67418 
67419   using DeferredStartTracingResponse = ::perfetto::ipc::Deferred<StartTracingResponse>;
67420   void StartTracing(const StartTracingRequest&, DeferredStartTracingResponse, int fd = -1);
67421 
67422   using DeferredChangeTraceConfigResponse = ::perfetto::ipc::Deferred<ChangeTraceConfigResponse>;
67423   void ChangeTraceConfig(const ChangeTraceConfigRequest&, DeferredChangeTraceConfigResponse, int fd = -1);
67424 
67425   using DeferredDetachResponse = ::perfetto::ipc::Deferred<DetachResponse>;
67426   void Detach(const DetachRequest&, DeferredDetachResponse, int fd = -1);
67427 
67428   using DeferredAttachResponse = ::perfetto::ipc::Deferred<AttachResponse>;
67429   void Attach(const AttachRequest&, DeferredAttachResponse, int fd = -1);
67430 
67431   using DeferredGetTraceStatsResponse = ::perfetto::ipc::Deferred<GetTraceStatsResponse>;
67432   void GetTraceStats(const GetTraceStatsRequest&, DeferredGetTraceStatsResponse, int fd = -1);
67433 
67434   using DeferredObserveEventsResponse = ::perfetto::ipc::Deferred<ObserveEventsResponse>;
67435   void ObserveEvents(const ObserveEventsRequest&, DeferredObserveEventsResponse, int fd = -1);
67436 
67437   using DeferredQueryServiceStateResponse = ::perfetto::ipc::Deferred<QueryServiceStateResponse>;
67438   void QueryServiceState(const QueryServiceStateRequest&, DeferredQueryServiceStateResponse, int fd = -1);
67439 
67440   using DeferredQueryCapabilitiesResponse = ::perfetto::ipc::Deferred<QueryCapabilitiesResponse>;
67441   void QueryCapabilities(const QueryCapabilitiesRequest&, DeferredQueryCapabilitiesResponse, int fd = -1);
67442 
67443   using DeferredSaveTraceForBugreportResponse = ::perfetto::ipc::Deferred<SaveTraceForBugreportResponse>;
67444   void SaveTraceForBugreport(const SaveTraceForBugreportRequest&, DeferredSaveTraceForBugreportResponse, int fd = -1);
67445 
67446 };
67447 
67448 }  // namespace perfetto
67449 }  // namespace protos
67450 }  // namespace gen
67451 
67452 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_IPC_CONSUMER_PORT_PROTO_H_
67453 // gen_amalgamated begin header: include/perfetto/ext/ipc/codegen_helpers.h
67454 /*
67455  * Copyright (C) 2017 The Android Open Source Project
67456  *
67457  * Licensed under the Apache License, Version 2.0 (the "License");
67458  * you may not use this file except in compliance with the License.
67459  * You may obtain a copy of the License at
67460  *
67461  *      http://www.apache.org/licenses/LICENSE-2.0
67462  *
67463  * Unless required by applicable law or agreed to in writing, software
67464  * distributed under the License is distributed on an "AS IS" BASIS,
67465  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
67466  * See the License for the specific language governing permissions and
67467  * limitations under the License.
67468  */
67469 
67470 // This file is only meant to be included in autogenerated .cc files.
67471 
67472 #ifndef INCLUDE_PERFETTO_EXT_IPC_CODEGEN_HELPERS_H_
67473 #define INCLUDE_PERFETTO_EXT_IPC_CODEGEN_HELPERS_H_
67474 
67475 #include <memory>
67476 
67477 // gen_amalgamated expanded: #include "perfetto/ext/ipc/basic_types.h"
67478 // gen_amalgamated expanded: #include "perfetto/ext/ipc/deferred.h"
67479 // gen_amalgamated expanded: #include "perfetto/ext/ipc/service.h"
67480 
67481 // A templated protobuf message decoder. Returns nullptr in case of failure.
67482 template <typename T>
_IPC_Decoder(const std::string & proto_data)67483 ::std::unique_ptr<::perfetto::ipc::ProtoMessage> _IPC_Decoder(
67484     const std::string& proto_data) {
67485   ::std::unique_ptr<::perfetto::ipc::ProtoMessage> msg(new T());
67486   if (msg->ParseFromString(proto_data))
67487     return msg;
67488   return nullptr;
67489 }
67490 
67491 // Templated method dispatcher. Used to obtain a function pointer to a given
67492 // IPC method (Method) of a given service (TSvc) that can be invoked by the
67493 // host-side machinery starting from a generic Service pointer and a generic
67494 // ProtoMessage request argument.
67495 template <typename TSvc,    // Type of the actual Service subclass.
67496           typename TReq,    // Type of the request argument.
67497           typename TReply,  // Type of the reply argument.
67498           void (TSvc::*Method)(const TReq&, ::perfetto::ipc::Deferred<TReply>)>
_IPC_Invoker(::perfetto::ipc::Service * s,const::perfetto::ipc::ProtoMessage & req,::perfetto::ipc::DeferredBase reply)67499 void _IPC_Invoker(::perfetto::ipc::Service* s,
67500                   const ::perfetto::ipc::ProtoMessage& req,
67501                   ::perfetto::ipc::DeferredBase reply) {
67502   (*static_cast<TSvc*>(s).*Method)(
67503       static_cast<const TReq&>(req),
67504       ::perfetto::ipc::Deferred<TReply>(::std::move(reply)));
67505 }
67506 
67507 #endif  // INCLUDE_PERFETTO_EXT_IPC_CODEGEN_HELPERS_H_
67508 // DO NOT EDIT. Autogenerated by Perfetto IPC
67509 // gen_amalgamated expanded: #include "protos/perfetto/ipc/consumer_port.ipc.h"
67510 // gen_amalgamated expanded: #include "perfetto/ext/ipc/codegen_helpers.h"
67511 
67512 #include <memory>
67513 
67514 namespace perfetto {
67515 namespace protos {
67516 namespace gen {
NewDescriptor()67517 ::perfetto::ipc::ServiceDescriptor* ConsumerPort::NewDescriptor() {
67518   auto* desc = new ::perfetto::ipc::ServiceDescriptor();
67519   desc->service_name = "ConsumerPort";
67520 
67521   desc->methods.emplace_back(::perfetto::ipc::ServiceDescriptor::Method{
67522      "EnableTracing",
67523      &_IPC_Decoder<EnableTracingRequest>,
67524      &_IPC_Decoder<EnableTracingResponse>,
67525      &_IPC_Invoker<ConsumerPort, EnableTracingRequest, EnableTracingResponse, &ConsumerPort::EnableTracing>});
67526 
67527   desc->methods.emplace_back(::perfetto::ipc::ServiceDescriptor::Method{
67528      "DisableTracing",
67529      &_IPC_Decoder<DisableTracingRequest>,
67530      &_IPC_Decoder<DisableTracingResponse>,
67531      &_IPC_Invoker<ConsumerPort, DisableTracingRequest, DisableTracingResponse, &ConsumerPort::DisableTracing>});
67532 
67533   desc->methods.emplace_back(::perfetto::ipc::ServiceDescriptor::Method{
67534      "ReadBuffers",
67535      &_IPC_Decoder<ReadBuffersRequest>,
67536      &_IPC_Decoder<ReadBuffersResponse>,
67537      &_IPC_Invoker<ConsumerPort, ReadBuffersRequest, ReadBuffersResponse, &ConsumerPort::ReadBuffers>});
67538 
67539   desc->methods.emplace_back(::perfetto::ipc::ServiceDescriptor::Method{
67540      "FreeBuffers",
67541      &_IPC_Decoder<FreeBuffersRequest>,
67542      &_IPC_Decoder<FreeBuffersResponse>,
67543      &_IPC_Invoker<ConsumerPort, FreeBuffersRequest, FreeBuffersResponse, &ConsumerPort::FreeBuffers>});
67544 
67545   desc->methods.emplace_back(::perfetto::ipc::ServiceDescriptor::Method{
67546      "Flush",
67547      &_IPC_Decoder<FlushRequest>,
67548      &_IPC_Decoder<FlushResponse>,
67549      &_IPC_Invoker<ConsumerPort, FlushRequest, FlushResponse, &ConsumerPort::Flush>});
67550 
67551   desc->methods.emplace_back(::perfetto::ipc::ServiceDescriptor::Method{
67552      "StartTracing",
67553      &_IPC_Decoder<StartTracingRequest>,
67554      &_IPC_Decoder<StartTracingResponse>,
67555      &_IPC_Invoker<ConsumerPort, StartTracingRequest, StartTracingResponse, &ConsumerPort::StartTracing>});
67556 
67557   desc->methods.emplace_back(::perfetto::ipc::ServiceDescriptor::Method{
67558      "ChangeTraceConfig",
67559      &_IPC_Decoder<ChangeTraceConfigRequest>,
67560      &_IPC_Decoder<ChangeTraceConfigResponse>,
67561      &_IPC_Invoker<ConsumerPort, ChangeTraceConfigRequest, ChangeTraceConfigResponse, &ConsumerPort::ChangeTraceConfig>});
67562 
67563   desc->methods.emplace_back(::perfetto::ipc::ServiceDescriptor::Method{
67564      "Detach",
67565      &_IPC_Decoder<DetachRequest>,
67566      &_IPC_Decoder<DetachResponse>,
67567      &_IPC_Invoker<ConsumerPort, DetachRequest, DetachResponse, &ConsumerPort::Detach>});
67568 
67569   desc->methods.emplace_back(::perfetto::ipc::ServiceDescriptor::Method{
67570      "Attach",
67571      &_IPC_Decoder<AttachRequest>,
67572      &_IPC_Decoder<AttachResponse>,
67573      &_IPC_Invoker<ConsumerPort, AttachRequest, AttachResponse, &ConsumerPort::Attach>});
67574 
67575   desc->methods.emplace_back(::perfetto::ipc::ServiceDescriptor::Method{
67576      "GetTraceStats",
67577      &_IPC_Decoder<GetTraceStatsRequest>,
67578      &_IPC_Decoder<GetTraceStatsResponse>,
67579      &_IPC_Invoker<ConsumerPort, GetTraceStatsRequest, GetTraceStatsResponse, &ConsumerPort::GetTraceStats>});
67580 
67581   desc->methods.emplace_back(::perfetto::ipc::ServiceDescriptor::Method{
67582      "ObserveEvents",
67583      &_IPC_Decoder<ObserveEventsRequest>,
67584      &_IPC_Decoder<ObserveEventsResponse>,
67585      &_IPC_Invoker<ConsumerPort, ObserveEventsRequest, ObserveEventsResponse, &ConsumerPort::ObserveEvents>});
67586 
67587   desc->methods.emplace_back(::perfetto::ipc::ServiceDescriptor::Method{
67588      "QueryServiceState",
67589      &_IPC_Decoder<QueryServiceStateRequest>,
67590      &_IPC_Decoder<QueryServiceStateResponse>,
67591      &_IPC_Invoker<ConsumerPort, QueryServiceStateRequest, QueryServiceStateResponse, &ConsumerPort::QueryServiceState>});
67592 
67593   desc->methods.emplace_back(::perfetto::ipc::ServiceDescriptor::Method{
67594      "QueryCapabilities",
67595      &_IPC_Decoder<QueryCapabilitiesRequest>,
67596      &_IPC_Decoder<QueryCapabilitiesResponse>,
67597      &_IPC_Invoker<ConsumerPort, QueryCapabilitiesRequest, QueryCapabilitiesResponse, &ConsumerPort::QueryCapabilities>});
67598 
67599   desc->methods.emplace_back(::perfetto::ipc::ServiceDescriptor::Method{
67600      "SaveTraceForBugreport",
67601      &_IPC_Decoder<SaveTraceForBugreportRequest>,
67602      &_IPC_Decoder<SaveTraceForBugreportResponse>,
67603      &_IPC_Invoker<ConsumerPort, SaveTraceForBugreportRequest, SaveTraceForBugreportResponse, &ConsumerPort::SaveTraceForBugreport>});
67604   desc->methods.shrink_to_fit();
67605   return desc;
67606 }
67607 
67608 
GetDescriptorStatic()67609 const ::perfetto::ipc::ServiceDescriptor& ConsumerPort::GetDescriptorStatic() {
67610   static auto* instance = NewDescriptor();
67611   return *instance;
67612 }
67613 
67614 // Host-side definitions.
67615 ConsumerPort::~ConsumerPort() = default;
67616 
GetDescriptor()67617 const ::perfetto::ipc::ServiceDescriptor& ConsumerPort::GetDescriptor() {
67618   return GetDescriptorStatic();
67619 }
67620 
67621 // Client-side definitions.
ConsumerPortProxy(::perfetto::ipc::ServiceProxy::EventListener * event_listener)67622 ConsumerPortProxy::ConsumerPortProxy(::perfetto::ipc::ServiceProxy::EventListener* event_listener)
67623     : ::perfetto::ipc::ServiceProxy(event_listener) {}
67624 
67625 ConsumerPortProxy::~ConsumerPortProxy() = default;
67626 
GetDescriptor()67627 const ::perfetto::ipc::ServiceDescriptor& ConsumerPortProxy::GetDescriptor() {
67628   return ConsumerPort::GetDescriptorStatic();
67629 }
67630 
EnableTracing(const EnableTracingRequest & request,DeferredEnableTracingResponse reply,int fd)67631 void ConsumerPortProxy::EnableTracing(const EnableTracingRequest& request, DeferredEnableTracingResponse reply, int fd) {
67632   BeginInvoke("EnableTracing", request, ::perfetto::ipc::DeferredBase(std::move(reply)),
67633               fd);
67634 }
67635 
DisableTracing(const DisableTracingRequest & request,DeferredDisableTracingResponse reply,int fd)67636 void ConsumerPortProxy::DisableTracing(const DisableTracingRequest& request, DeferredDisableTracingResponse reply, int fd) {
67637   BeginInvoke("DisableTracing", request, ::perfetto::ipc::DeferredBase(std::move(reply)),
67638               fd);
67639 }
67640 
ReadBuffers(const ReadBuffersRequest & request,DeferredReadBuffersResponse reply,int fd)67641 void ConsumerPortProxy::ReadBuffers(const ReadBuffersRequest& request, DeferredReadBuffersResponse reply, int fd) {
67642   BeginInvoke("ReadBuffers", request, ::perfetto::ipc::DeferredBase(std::move(reply)),
67643               fd);
67644 }
67645 
FreeBuffers(const FreeBuffersRequest & request,DeferredFreeBuffersResponse reply,int fd)67646 void ConsumerPortProxy::FreeBuffers(const FreeBuffersRequest& request, DeferredFreeBuffersResponse reply, int fd) {
67647   BeginInvoke("FreeBuffers", request, ::perfetto::ipc::DeferredBase(std::move(reply)),
67648               fd);
67649 }
67650 
Flush(const FlushRequest & request,DeferredFlushResponse reply,int fd)67651 void ConsumerPortProxy::Flush(const FlushRequest& request, DeferredFlushResponse reply, int fd) {
67652   BeginInvoke("Flush", request, ::perfetto::ipc::DeferredBase(std::move(reply)),
67653               fd);
67654 }
67655 
StartTracing(const StartTracingRequest & request,DeferredStartTracingResponse reply,int fd)67656 void ConsumerPortProxy::StartTracing(const StartTracingRequest& request, DeferredStartTracingResponse reply, int fd) {
67657   BeginInvoke("StartTracing", request, ::perfetto::ipc::DeferredBase(std::move(reply)),
67658               fd);
67659 }
67660 
ChangeTraceConfig(const ChangeTraceConfigRequest & request,DeferredChangeTraceConfigResponse reply,int fd)67661 void ConsumerPortProxy::ChangeTraceConfig(const ChangeTraceConfigRequest& request, DeferredChangeTraceConfigResponse reply, int fd) {
67662   BeginInvoke("ChangeTraceConfig", request, ::perfetto::ipc::DeferredBase(std::move(reply)),
67663               fd);
67664 }
67665 
Detach(const DetachRequest & request,DeferredDetachResponse reply,int fd)67666 void ConsumerPortProxy::Detach(const DetachRequest& request, DeferredDetachResponse reply, int fd) {
67667   BeginInvoke("Detach", request, ::perfetto::ipc::DeferredBase(std::move(reply)),
67668               fd);
67669 }
67670 
Attach(const AttachRequest & request,DeferredAttachResponse reply,int fd)67671 void ConsumerPortProxy::Attach(const AttachRequest& request, DeferredAttachResponse reply, int fd) {
67672   BeginInvoke("Attach", request, ::perfetto::ipc::DeferredBase(std::move(reply)),
67673               fd);
67674 }
67675 
GetTraceStats(const GetTraceStatsRequest & request,DeferredGetTraceStatsResponse reply,int fd)67676 void ConsumerPortProxy::GetTraceStats(const GetTraceStatsRequest& request, DeferredGetTraceStatsResponse reply, int fd) {
67677   BeginInvoke("GetTraceStats", request, ::perfetto::ipc::DeferredBase(std::move(reply)),
67678               fd);
67679 }
67680 
ObserveEvents(const ObserveEventsRequest & request,DeferredObserveEventsResponse reply,int fd)67681 void ConsumerPortProxy::ObserveEvents(const ObserveEventsRequest& request, DeferredObserveEventsResponse reply, int fd) {
67682   BeginInvoke("ObserveEvents", request, ::perfetto::ipc::DeferredBase(std::move(reply)),
67683               fd);
67684 }
67685 
QueryServiceState(const QueryServiceStateRequest & request,DeferredQueryServiceStateResponse reply,int fd)67686 void ConsumerPortProxy::QueryServiceState(const QueryServiceStateRequest& request, DeferredQueryServiceStateResponse reply, int fd) {
67687   BeginInvoke("QueryServiceState", request, ::perfetto::ipc::DeferredBase(std::move(reply)),
67688               fd);
67689 }
67690 
QueryCapabilities(const QueryCapabilitiesRequest & request,DeferredQueryCapabilitiesResponse reply,int fd)67691 void ConsumerPortProxy::QueryCapabilities(const QueryCapabilitiesRequest& request, DeferredQueryCapabilitiesResponse reply, int fd) {
67692   BeginInvoke("QueryCapabilities", request, ::perfetto::ipc::DeferredBase(std::move(reply)),
67693               fd);
67694 }
67695 
SaveTraceForBugreport(const SaveTraceForBugreportRequest & request,DeferredSaveTraceForBugreportResponse reply,int fd)67696 void ConsumerPortProxy::SaveTraceForBugreport(const SaveTraceForBugreportRequest& request, DeferredSaveTraceForBugreportResponse reply, int fd) {
67697   BeginInvoke("SaveTraceForBugreport", request, ::perfetto::ipc::DeferredBase(std::move(reply)),
67698               fd);
67699 }
67700 }  // namespace perfetto
67701 }  // namespace protos
67702 }  // namespace gen
67703 // gen_amalgamated begin source: gen/protos/perfetto/ipc/producer_port.ipc.cc
67704 // gen_amalgamated begin header: gen/protos/perfetto/ipc/producer_port.ipc.h
67705 // DO NOT EDIT. Autogenerated by Perfetto IPC
67706 #ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_IPC_PRODUCER_PORT_PROTO_H_
67707 #define PERFETTO_PROTOS_PROTOS_PERFETTO_IPC_PRODUCER_PORT_PROTO_H_
67708 
67709 // gen_amalgamated expanded: #include "perfetto/ext/ipc/deferred.h"
67710 // gen_amalgamated expanded: #include "perfetto/ext/ipc/service.h"
67711 // gen_amalgamated expanded: #include "perfetto/ext/ipc/service_descriptor.h"
67712 // gen_amalgamated expanded: #include "perfetto/ext/ipc/service_proxy.h"
67713 
67714 // gen_amalgamated expanded: #include "protos/perfetto/ipc/producer_port.gen.h"
67715 // gen_amalgamated expanded: #include "protos/perfetto/common/commit_data_request.gen.h"
67716 // gen_amalgamated expanded: #include "protos/perfetto/config/data_source_config.gen.h"
67717 // gen_amalgamated expanded: #include "protos/perfetto/common/data_source_descriptor.gen.h"
67718 
67719 namespace perfetto {
67720 namespace protos {
67721 namespace gen {
67722 
67723 class ProducerPort : public ::perfetto::ipc::Service {
67724  private:
67725   static ::perfetto::ipc::ServiceDescriptor* NewDescriptor();
67726 
67727  public:
67728   ~ProducerPort() override;
67729 
67730   static const ::perfetto::ipc::ServiceDescriptor& GetDescriptorStatic();
67731 
67732   // Service implementation.
67733   const ::perfetto::ipc::ServiceDescriptor& GetDescriptor() override;
67734 
67735   // Methods from the .proto file
67736   using DeferredInitializeConnectionResponse = ::perfetto::ipc::Deferred<InitializeConnectionResponse>;
67737   virtual void InitializeConnection(const InitializeConnectionRequest&, DeferredInitializeConnectionResponse) = 0;
67738 
67739   using DeferredRegisterDataSourceResponse = ::perfetto::ipc::Deferred<RegisterDataSourceResponse>;
67740   virtual void RegisterDataSource(const RegisterDataSourceRequest&, DeferredRegisterDataSourceResponse) = 0;
67741 
67742   using DeferredUnregisterDataSourceResponse = ::perfetto::ipc::Deferred<UnregisterDataSourceResponse>;
67743   virtual void UnregisterDataSource(const UnregisterDataSourceRequest&, DeferredUnregisterDataSourceResponse) = 0;
67744 
67745   using DeferredCommitDataResponse = ::perfetto::ipc::Deferred<CommitDataResponse>;
67746   virtual void CommitData(const CommitDataRequest&, DeferredCommitDataResponse) = 0;
67747 
67748   using DeferredGetAsyncCommandResponse = ::perfetto::ipc::Deferred<GetAsyncCommandResponse>;
67749   virtual void GetAsyncCommand(const GetAsyncCommandRequest&, DeferredGetAsyncCommandResponse) = 0;
67750 
67751   using DeferredRegisterTraceWriterResponse = ::perfetto::ipc::Deferred<RegisterTraceWriterResponse>;
67752   virtual void RegisterTraceWriter(const RegisterTraceWriterRequest&, DeferredRegisterTraceWriterResponse) = 0;
67753 
67754   using DeferredUnregisterTraceWriterResponse = ::perfetto::ipc::Deferred<UnregisterTraceWriterResponse>;
67755   virtual void UnregisterTraceWriter(const UnregisterTraceWriterRequest&, DeferredUnregisterTraceWriterResponse) = 0;
67756 
67757   using DeferredNotifyDataSourceStartedResponse = ::perfetto::ipc::Deferred<NotifyDataSourceStartedResponse>;
67758   virtual void NotifyDataSourceStarted(const NotifyDataSourceStartedRequest&, DeferredNotifyDataSourceStartedResponse) = 0;
67759 
67760   using DeferredNotifyDataSourceStoppedResponse = ::perfetto::ipc::Deferred<NotifyDataSourceStoppedResponse>;
67761   virtual void NotifyDataSourceStopped(const NotifyDataSourceStoppedRequest&, DeferredNotifyDataSourceStoppedResponse) = 0;
67762 
67763   using DeferredActivateTriggersResponse = ::perfetto::ipc::Deferred<ActivateTriggersResponse>;
67764   virtual void ActivateTriggers(const ActivateTriggersRequest&, DeferredActivateTriggersResponse) = 0;
67765 
67766   using DeferredSyncResponse = ::perfetto::ipc::Deferred<SyncResponse>;
67767   virtual void Sync(const SyncRequest&, DeferredSyncResponse) = 0;
67768 
67769   using DeferredUpdateDataSourceResponse = ::perfetto::ipc::Deferred<UpdateDataSourceResponse>;
67770   virtual void UpdateDataSource(const UpdateDataSourceRequest&, DeferredUpdateDataSourceResponse) = 0;
67771 
67772 };
67773 
67774 
67775 class ProducerPortProxy : public ::perfetto::ipc::ServiceProxy {
67776  public:
67777    explicit ProducerPortProxy(::perfetto::ipc::ServiceProxy::EventListener*);
67778    ~ProducerPortProxy() override;
67779 
67780   // ServiceProxy implementation.
67781   const ::perfetto::ipc::ServiceDescriptor& GetDescriptor() override;
67782 
67783   // Methods from the .proto file
67784   using DeferredInitializeConnectionResponse = ::perfetto::ipc::Deferred<InitializeConnectionResponse>;
67785   void InitializeConnection(const InitializeConnectionRequest&, DeferredInitializeConnectionResponse, int fd = -1);
67786 
67787   using DeferredRegisterDataSourceResponse = ::perfetto::ipc::Deferred<RegisterDataSourceResponse>;
67788   void RegisterDataSource(const RegisterDataSourceRequest&, DeferredRegisterDataSourceResponse, int fd = -1);
67789 
67790   using DeferredUnregisterDataSourceResponse = ::perfetto::ipc::Deferred<UnregisterDataSourceResponse>;
67791   void UnregisterDataSource(const UnregisterDataSourceRequest&, DeferredUnregisterDataSourceResponse, int fd = -1);
67792 
67793   using DeferredCommitDataResponse = ::perfetto::ipc::Deferred<CommitDataResponse>;
67794   void CommitData(const CommitDataRequest&, DeferredCommitDataResponse, int fd = -1);
67795 
67796   using DeferredGetAsyncCommandResponse = ::perfetto::ipc::Deferred<GetAsyncCommandResponse>;
67797   void GetAsyncCommand(const GetAsyncCommandRequest&, DeferredGetAsyncCommandResponse, int fd = -1);
67798 
67799   using DeferredRegisterTraceWriterResponse = ::perfetto::ipc::Deferred<RegisterTraceWriterResponse>;
67800   void RegisterTraceWriter(const RegisterTraceWriterRequest&, DeferredRegisterTraceWriterResponse, int fd = -1);
67801 
67802   using DeferredUnregisterTraceWriterResponse = ::perfetto::ipc::Deferred<UnregisterTraceWriterResponse>;
67803   void UnregisterTraceWriter(const UnregisterTraceWriterRequest&, DeferredUnregisterTraceWriterResponse, int fd = -1);
67804 
67805   using DeferredNotifyDataSourceStartedResponse = ::perfetto::ipc::Deferred<NotifyDataSourceStartedResponse>;
67806   void NotifyDataSourceStarted(const NotifyDataSourceStartedRequest&, DeferredNotifyDataSourceStartedResponse, int fd = -1);
67807 
67808   using DeferredNotifyDataSourceStoppedResponse = ::perfetto::ipc::Deferred<NotifyDataSourceStoppedResponse>;
67809   void NotifyDataSourceStopped(const NotifyDataSourceStoppedRequest&, DeferredNotifyDataSourceStoppedResponse, int fd = -1);
67810 
67811   using DeferredActivateTriggersResponse = ::perfetto::ipc::Deferred<ActivateTriggersResponse>;
67812   void ActivateTriggers(const ActivateTriggersRequest&, DeferredActivateTriggersResponse, int fd = -1);
67813 
67814   using DeferredSyncResponse = ::perfetto::ipc::Deferred<SyncResponse>;
67815   void Sync(const SyncRequest&, DeferredSyncResponse, int fd = -1);
67816 
67817   using DeferredUpdateDataSourceResponse = ::perfetto::ipc::Deferred<UpdateDataSourceResponse>;
67818   void UpdateDataSource(const UpdateDataSourceRequest&, DeferredUpdateDataSourceResponse, int fd = -1);
67819 
67820 };
67821 
67822 }  // namespace perfetto
67823 }  // namespace protos
67824 }  // namespace gen
67825 
67826 #endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_IPC_PRODUCER_PORT_PROTO_H_
67827 // DO NOT EDIT. Autogenerated by Perfetto IPC
67828 // gen_amalgamated expanded: #include "protos/perfetto/ipc/producer_port.ipc.h"
67829 // gen_amalgamated expanded: #include "perfetto/ext/ipc/codegen_helpers.h"
67830 
67831 #include <memory>
67832 
67833 namespace perfetto {
67834 namespace protos {
67835 namespace gen {
NewDescriptor()67836 ::perfetto::ipc::ServiceDescriptor* ProducerPort::NewDescriptor() {
67837   auto* desc = new ::perfetto::ipc::ServiceDescriptor();
67838   desc->service_name = "ProducerPort";
67839 
67840   desc->methods.emplace_back(::perfetto::ipc::ServiceDescriptor::Method{
67841      "InitializeConnection",
67842      &_IPC_Decoder<InitializeConnectionRequest>,
67843      &_IPC_Decoder<InitializeConnectionResponse>,
67844      &_IPC_Invoker<ProducerPort, InitializeConnectionRequest, InitializeConnectionResponse, &ProducerPort::InitializeConnection>});
67845 
67846   desc->methods.emplace_back(::perfetto::ipc::ServiceDescriptor::Method{
67847      "RegisterDataSource",
67848      &_IPC_Decoder<RegisterDataSourceRequest>,
67849      &_IPC_Decoder<RegisterDataSourceResponse>,
67850      &_IPC_Invoker<ProducerPort, RegisterDataSourceRequest, RegisterDataSourceResponse, &ProducerPort::RegisterDataSource>});
67851 
67852   desc->methods.emplace_back(::perfetto::ipc::ServiceDescriptor::Method{
67853      "UnregisterDataSource",
67854      &_IPC_Decoder<UnregisterDataSourceRequest>,
67855      &_IPC_Decoder<UnregisterDataSourceResponse>,
67856      &_IPC_Invoker<ProducerPort, UnregisterDataSourceRequest, UnregisterDataSourceResponse, &ProducerPort::UnregisterDataSource>});
67857 
67858   desc->methods.emplace_back(::perfetto::ipc::ServiceDescriptor::Method{
67859      "CommitData",
67860      &_IPC_Decoder<CommitDataRequest>,
67861      &_IPC_Decoder<CommitDataResponse>,
67862      &_IPC_Invoker<ProducerPort, CommitDataRequest, CommitDataResponse, &ProducerPort::CommitData>});
67863 
67864   desc->methods.emplace_back(::perfetto::ipc::ServiceDescriptor::Method{
67865      "GetAsyncCommand",
67866      &_IPC_Decoder<GetAsyncCommandRequest>,
67867      &_IPC_Decoder<GetAsyncCommandResponse>,
67868      &_IPC_Invoker<ProducerPort, GetAsyncCommandRequest, GetAsyncCommandResponse, &ProducerPort::GetAsyncCommand>});
67869 
67870   desc->methods.emplace_back(::perfetto::ipc::ServiceDescriptor::Method{
67871      "RegisterTraceWriter",
67872      &_IPC_Decoder<RegisterTraceWriterRequest>,
67873      &_IPC_Decoder<RegisterTraceWriterResponse>,
67874      &_IPC_Invoker<ProducerPort, RegisterTraceWriterRequest, RegisterTraceWriterResponse, &ProducerPort::RegisterTraceWriter>});
67875 
67876   desc->methods.emplace_back(::perfetto::ipc::ServiceDescriptor::Method{
67877      "UnregisterTraceWriter",
67878      &_IPC_Decoder<UnregisterTraceWriterRequest>,
67879      &_IPC_Decoder<UnregisterTraceWriterResponse>,
67880      &_IPC_Invoker<ProducerPort, UnregisterTraceWriterRequest, UnregisterTraceWriterResponse, &ProducerPort::UnregisterTraceWriter>});
67881 
67882   desc->methods.emplace_back(::perfetto::ipc::ServiceDescriptor::Method{
67883      "NotifyDataSourceStarted",
67884      &_IPC_Decoder<NotifyDataSourceStartedRequest>,
67885      &_IPC_Decoder<NotifyDataSourceStartedResponse>,
67886      &_IPC_Invoker<ProducerPort, NotifyDataSourceStartedRequest, NotifyDataSourceStartedResponse, &ProducerPort::NotifyDataSourceStarted>});
67887 
67888   desc->methods.emplace_back(::perfetto::ipc::ServiceDescriptor::Method{
67889      "NotifyDataSourceStopped",
67890      &_IPC_Decoder<NotifyDataSourceStoppedRequest>,
67891      &_IPC_Decoder<NotifyDataSourceStoppedResponse>,
67892      &_IPC_Invoker<ProducerPort, NotifyDataSourceStoppedRequest, NotifyDataSourceStoppedResponse, &ProducerPort::NotifyDataSourceStopped>});
67893 
67894   desc->methods.emplace_back(::perfetto::ipc::ServiceDescriptor::Method{
67895      "ActivateTriggers",
67896      &_IPC_Decoder<ActivateTriggersRequest>,
67897      &_IPC_Decoder<ActivateTriggersResponse>,
67898      &_IPC_Invoker<ProducerPort, ActivateTriggersRequest, ActivateTriggersResponse, &ProducerPort::ActivateTriggers>});
67899 
67900   desc->methods.emplace_back(::perfetto::ipc::ServiceDescriptor::Method{
67901      "Sync",
67902      &_IPC_Decoder<SyncRequest>,
67903      &_IPC_Decoder<SyncResponse>,
67904      &_IPC_Invoker<ProducerPort, SyncRequest, SyncResponse, &ProducerPort::Sync>});
67905 
67906   desc->methods.emplace_back(::perfetto::ipc::ServiceDescriptor::Method{
67907      "UpdateDataSource",
67908      &_IPC_Decoder<UpdateDataSourceRequest>,
67909      &_IPC_Decoder<UpdateDataSourceResponse>,
67910      &_IPC_Invoker<ProducerPort, UpdateDataSourceRequest, UpdateDataSourceResponse, &ProducerPort::UpdateDataSource>});
67911   desc->methods.shrink_to_fit();
67912   return desc;
67913 }
67914 
67915 
GetDescriptorStatic()67916 const ::perfetto::ipc::ServiceDescriptor& ProducerPort::GetDescriptorStatic() {
67917   static auto* instance = NewDescriptor();
67918   return *instance;
67919 }
67920 
67921 // Host-side definitions.
67922 ProducerPort::~ProducerPort() = default;
67923 
GetDescriptor()67924 const ::perfetto::ipc::ServiceDescriptor& ProducerPort::GetDescriptor() {
67925   return GetDescriptorStatic();
67926 }
67927 
67928 // Client-side definitions.
ProducerPortProxy(::perfetto::ipc::ServiceProxy::EventListener * event_listener)67929 ProducerPortProxy::ProducerPortProxy(::perfetto::ipc::ServiceProxy::EventListener* event_listener)
67930     : ::perfetto::ipc::ServiceProxy(event_listener) {}
67931 
67932 ProducerPortProxy::~ProducerPortProxy() = default;
67933 
GetDescriptor()67934 const ::perfetto::ipc::ServiceDescriptor& ProducerPortProxy::GetDescriptor() {
67935   return ProducerPort::GetDescriptorStatic();
67936 }
67937 
InitializeConnection(const InitializeConnectionRequest & request,DeferredInitializeConnectionResponse reply,int fd)67938 void ProducerPortProxy::InitializeConnection(const InitializeConnectionRequest& request, DeferredInitializeConnectionResponse reply, int fd) {
67939   BeginInvoke("InitializeConnection", request, ::perfetto::ipc::DeferredBase(std::move(reply)),
67940               fd);
67941 }
67942 
RegisterDataSource(const RegisterDataSourceRequest & request,DeferredRegisterDataSourceResponse reply,int fd)67943 void ProducerPortProxy::RegisterDataSource(const RegisterDataSourceRequest& request, DeferredRegisterDataSourceResponse reply, int fd) {
67944   BeginInvoke("RegisterDataSource", request, ::perfetto::ipc::DeferredBase(std::move(reply)),
67945               fd);
67946 }
67947 
UnregisterDataSource(const UnregisterDataSourceRequest & request,DeferredUnregisterDataSourceResponse reply,int fd)67948 void ProducerPortProxy::UnregisterDataSource(const UnregisterDataSourceRequest& request, DeferredUnregisterDataSourceResponse reply, int fd) {
67949   BeginInvoke("UnregisterDataSource", request, ::perfetto::ipc::DeferredBase(std::move(reply)),
67950               fd);
67951 }
67952 
CommitData(const CommitDataRequest & request,DeferredCommitDataResponse reply,int fd)67953 void ProducerPortProxy::CommitData(const CommitDataRequest& request, DeferredCommitDataResponse reply, int fd) {
67954   BeginInvoke("CommitData", request, ::perfetto::ipc::DeferredBase(std::move(reply)),
67955               fd);
67956 }
67957 
GetAsyncCommand(const GetAsyncCommandRequest & request,DeferredGetAsyncCommandResponse reply,int fd)67958 void ProducerPortProxy::GetAsyncCommand(const GetAsyncCommandRequest& request, DeferredGetAsyncCommandResponse reply, int fd) {
67959   BeginInvoke("GetAsyncCommand", request, ::perfetto::ipc::DeferredBase(std::move(reply)),
67960               fd);
67961 }
67962 
RegisterTraceWriter(const RegisterTraceWriterRequest & request,DeferredRegisterTraceWriterResponse reply,int fd)67963 void ProducerPortProxy::RegisterTraceWriter(const RegisterTraceWriterRequest& request, DeferredRegisterTraceWriterResponse reply, int fd) {
67964   BeginInvoke("RegisterTraceWriter", request, ::perfetto::ipc::DeferredBase(std::move(reply)),
67965               fd);
67966 }
67967 
UnregisterTraceWriter(const UnregisterTraceWriterRequest & request,DeferredUnregisterTraceWriterResponse reply,int fd)67968 void ProducerPortProxy::UnregisterTraceWriter(const UnregisterTraceWriterRequest& request, DeferredUnregisterTraceWriterResponse reply, int fd) {
67969   BeginInvoke("UnregisterTraceWriter", request, ::perfetto::ipc::DeferredBase(std::move(reply)),
67970               fd);
67971 }
67972 
NotifyDataSourceStarted(const NotifyDataSourceStartedRequest & request,DeferredNotifyDataSourceStartedResponse reply,int fd)67973 void ProducerPortProxy::NotifyDataSourceStarted(const NotifyDataSourceStartedRequest& request, DeferredNotifyDataSourceStartedResponse reply, int fd) {
67974   BeginInvoke("NotifyDataSourceStarted", request, ::perfetto::ipc::DeferredBase(std::move(reply)),
67975               fd);
67976 }
67977 
NotifyDataSourceStopped(const NotifyDataSourceStoppedRequest & request,DeferredNotifyDataSourceStoppedResponse reply,int fd)67978 void ProducerPortProxy::NotifyDataSourceStopped(const NotifyDataSourceStoppedRequest& request, DeferredNotifyDataSourceStoppedResponse reply, int fd) {
67979   BeginInvoke("NotifyDataSourceStopped", request, ::perfetto::ipc::DeferredBase(std::move(reply)),
67980               fd);
67981 }
67982 
ActivateTriggers(const ActivateTriggersRequest & request,DeferredActivateTriggersResponse reply,int fd)67983 void ProducerPortProxy::ActivateTriggers(const ActivateTriggersRequest& request, DeferredActivateTriggersResponse reply, int fd) {
67984   BeginInvoke("ActivateTriggers", request, ::perfetto::ipc::DeferredBase(std::move(reply)),
67985               fd);
67986 }
67987 
Sync(const SyncRequest & request,DeferredSyncResponse reply,int fd)67988 void ProducerPortProxy::Sync(const SyncRequest& request, DeferredSyncResponse reply, int fd) {
67989   BeginInvoke("Sync", request, ::perfetto::ipc::DeferredBase(std::move(reply)),
67990               fd);
67991 }
67992 
UpdateDataSource(const UpdateDataSourceRequest & request,DeferredUpdateDataSourceResponse reply,int fd)67993 void ProducerPortProxy::UpdateDataSource(const UpdateDataSourceRequest& request, DeferredUpdateDataSourceResponse reply, int fd) {
67994   BeginInvoke("UpdateDataSource", request, ::perfetto::ipc::DeferredBase(std::move(reply)),
67995               fd);
67996 }
67997 }  // namespace perfetto
67998 }  // namespace protos
67999 }  // namespace gen
68000 // gen_amalgamated begin source: src/tracing/ipc/default_socket.cc
68001 // gen_amalgamated begin header: include/perfetto/ext/tracing/ipc/default_socket.h
68002 /*
68003  * Copyright (C) 2018 The Android Open Source Project
68004  *
68005  * Licensed under the Apache License, Version 2.0 (the "License");
68006  * you may not use this file except in compliance with the License.
68007  * You may obtain a copy of the License at
68008  *
68009  *      http://www.apache.org/licenses/LICENSE-2.0
68010  *
68011  * Unless required by applicable law or agreed to in writing, software
68012  * distributed under the License is distributed on an "AS IS" BASIS,
68013  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
68014  * See the License for the specific language governing permissions and
68015  * limitations under the License.
68016  */
68017 
68018 #ifndef INCLUDE_PERFETTO_EXT_TRACING_IPC_DEFAULT_SOCKET_H_
68019 #define INCLUDE_PERFETTO_EXT_TRACING_IPC_DEFAULT_SOCKET_H_
68020 
68021 // gen_amalgamated expanded: #include "perfetto/base/export.h"
68022 
68023 namespace perfetto {
68024 
68025 PERFETTO_EXPORT const char* GetConsumerSocket();
68026 PERFETTO_EXPORT const char* GetProducerSocket();
68027 
68028 }  // namespace perfetto
68029 
68030 #endif  // INCLUDE_PERFETTO_EXT_TRACING_IPC_DEFAULT_SOCKET_H_
68031 /*
68032  * Copyright (C) 2018 The Android Open Source Project
68033  *
68034  * Licensed under the Apache License, Version 2.0 (the "License");
68035  * you may not use this file except in compliance with the License.
68036  * You may obtain a copy of the License at
68037  *
68038  *      http://www.apache.org/licenses/LICENSE-2.0
68039  *
68040  * Unless required by applicable law or agreed to in writing, software
68041  * distributed under the License is distributed on an "AS IS" BASIS,
68042  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
68043  * See the License for the specific language governing permissions and
68044  * limitations under the License.
68045  */
68046 
68047 // gen_amalgamated expanded: #include "perfetto/ext/tracing/ipc/default_socket.h"
68048 
68049 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
68050 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
68051 // gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
68052 // gen_amalgamated expanded: #include "perfetto/ext/ipc/basic_types.h"
68053 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/basic_types.h"
68054 
68055 #include <stdlib.h>
68056 
68057 #if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) ||   \
68058     PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \
68059     PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
68060 #include <unistd.h>
68061 #endif
68062 
68063 namespace perfetto {
68064 namespace {
68065 
68066 const char* kRunPerfettoBaseDir = "/run/perfetto/";
68067 
68068 // On Linux and CrOS, check /run/perfetto/ before using /tmp/ as the socket
68069 // base directory.
UseRunPerfettoBaseDir()68070 bool UseRunPerfettoBaseDir() {
68071 #if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX)
68072   // Note that the trailing / in |kRunPerfettoBaseDir| ensures we are checking
68073   // against a directory, not a file.
68074   int res = PERFETTO_EINTR(access(kRunPerfettoBaseDir, X_OK));
68075   if (!res)
68076     return true;
68077 
68078   // If the path doesn't exist (ENOENT), fail silently to the caller. Otherwise,
68079   // fail with an explicit error message.
68080   if (errno != ENOENT
68081 #if PERFETTO_BUILDFLAG(PERFETTO_CHROMIUM_BUILD)
68082       // access(2) won't return EPERM, but Chromium sandbox returns EPERM if the
68083       // sandbox doesn't allow the call (e.g. in the child processes).
68084       && errno != EPERM
68085 #endif
68086   ) {
68087     PERFETTO_PLOG("%s exists but cannot be accessed. Falling back on /tmp/ ",
68088                   kRunPerfettoBaseDir);
68089   }
68090   return false;
68091 #else
68092   base::ignore_result(kRunPerfettoBaseDir);
68093   return false;
68094 #endif
68095 }
68096 
68097 }  // anonymous namespace
68098 
68099 static_assert(kInvalidUid == ipc::kInvalidUid, "kInvalidUid mismatching");
68100 
GetProducerSocket()68101 const char* GetProducerSocket() {
68102   const char* name = getenv("PERFETTO_PRODUCER_SOCK_NAME");
68103   if (name == nullptr) {
68104 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
68105     name = "127.0.0.1:32278";
68106 #elif PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
68107     name = "/dev/socket/traced_producer";
68108 #else
68109     // Use /run/perfetto if it exists. Then fallback to /tmp.
68110     static const char* producer_socket =
68111         UseRunPerfettoBaseDir() ? "/run/perfetto/traced-producer.sock"
68112                                 : "/tmp/perfetto-producer";
68113     name = producer_socket;
68114 #endif
68115   }
68116   base::ignore_result(UseRunPerfettoBaseDir);  // Silence unused func warnings.
68117   return name;
68118 }
68119 
GetConsumerSocket()68120 const char* GetConsumerSocket() {
68121   const char* name = getenv("PERFETTO_CONSUMER_SOCK_NAME");
68122   if (name == nullptr) {
68123 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
68124     name = "127.0.0.1:32279";
68125 #elif PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
68126     name = "/dev/socket/traced_consumer";
68127 #else
68128     // Use /run/perfetto if it exists. Then fallback to /tmp.
68129     static const char* consumer_socket =
68130         UseRunPerfettoBaseDir() ? "/run/perfetto/traced-consumer.sock"
68131                                 : "/tmp/perfetto-consumer";
68132     name = consumer_socket;
68133 #endif
68134   }
68135   return name;
68136 }
68137 
68138 }  // namespace perfetto
68139 // gen_amalgamated begin source: src/tracing/ipc/memfd.cc
68140 // gen_amalgamated begin header: src/tracing/ipc/memfd.h
68141 /*
68142  * Copyright (C) 2020 The Android Open Source Project
68143  *
68144  * Licensed under the Apache License, Version 2.0 (the "License");
68145  * you may not use this file except in compliance with the License.
68146  * You may obtain a copy of the License at
68147  *
68148  *      http://www.apache.org/licenses/LICENSE-2.0
68149  *
68150  * Unless required by applicable law or agreed to in writing, software
68151  * distributed under the License is distributed on an "AS IS" BASIS,
68152  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
68153  * See the License for the specific language governing permissions and
68154  * limitations under the License.
68155  */
68156 
68157 #ifndef SRC_TRACING_IPC_MEMFD_H_
68158 #define SRC_TRACING_IPC_MEMFD_H_
68159 
68160 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
68161 
68162 // gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"
68163 
68164 // Some android build bots use a sysroot that doesn't support memfd when
68165 // compiling for the host, so we define the flags we need ourselves.
68166 
68167 // from memfd.h
68168 #ifndef MFD_CLOEXEC
68169 #define MFD_CLOEXEC 0x0001U
68170 #define MFD_ALLOW_SEALING 0x0002U
68171 #endif
68172 
68173 // from fcntl.h
68174 #ifndef F_ADD_SEALS
68175 #define F_ADD_SEALS 1033
68176 #define F_GET_SEALS 1034
68177 #define F_SEAL_SEAL 0x0001
68178 #define F_SEAL_SHRINK 0x0002
68179 #define F_SEAL_GROW 0x0004
68180 #define F_SEAL_WRITE 0x0008
68181 #endif
68182 
68183 namespace perfetto {
68184 
68185 // Whether the operating system supports memfd.
68186 bool HasMemfdSupport();
68187 
68188 // Call memfd(2) if available on platform and return the fd as result. This call
68189 // also makes a kernel version check for safety on older kernels (b/116769556).
68190 // Returns an invalid ScopedFile on failure.
68191 base::ScopedFile CreateMemfd(const char* name, unsigned int flags);
68192 
68193 }  // namespace perfetto
68194 
68195 #endif  // SRC_TRACING_IPC_MEMFD_H_
68196 /*
68197  * Copyright (C) 2020 The Android Open Source Project
68198  *
68199  * Licensed under the Apache License, Version 2.0 (the "License");
68200  * you may not use this file except in compliance with the License.
68201  * You may obtain a copy of the License at
68202  *
68203  *      http://www.apache.org/licenses/LICENSE-2.0
68204  *
68205  * Unless required by applicable law or agreed to in writing, software
68206  * distributed under the License is distributed on an "AS IS" BASIS,
68207  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
68208  * See the License for the specific language governing permissions and
68209  * limitations under the License.
68210  */
68211 
68212 // gen_amalgamated expanded: #include "src/tracing/ipc/memfd.h"
68213 
68214 #include <errno.h>
68215 
68216 #define PERFETTO_MEMFD_ENABLED()             \
68217   PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \
68218       PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX)
68219 
68220 #if PERFETTO_MEMFD_ENABLED()
68221 
68222 #include <stdio.h>
68223 #include <string.h>
68224 #include <sys/syscall.h>
68225 #include <sys/utsname.h>
68226 #include <unistd.h>
68227 
68228 // Some android build bots use a sysroot that doesn't support memfd when
68229 // compiling for the host, so we redefine it if necessary.
68230 #if !defined(__NR_memfd_create)
68231 #if defined(__x86_64__)
68232 #define __NR_memfd_create 319
68233 #elif defined(__i386__)
68234 #define __NR_memfd_create 356
68235 #elif defined(__aarch64__)
68236 #define __NR_memfd_create 279
68237 #elif defined(__arm__)
68238 #define __NR_memfd_create 385
68239 #else
68240 #error "unsupported sysroot without memfd support"
68241 #endif
68242 #endif  // !defined(__NR_memfd_create)
68243 
68244 namespace perfetto {
HasMemfdSupport()68245 bool HasMemfdSupport() {
68246   static bool kSupportsMemfd = [] {
68247     // Check kernel version supports memfd_create(). Some older kernels segfault
68248     // executing memfd_create() rather than returning ENOSYS (b/116769556).
68249     static constexpr int kRequiredMajor = 3;
68250     static constexpr int kRequiredMinor = 17;
68251     struct utsname uts;
68252     int major, minor;
68253     if (uname(&uts) == 0 && strcmp(uts.sysname, "Linux") == 0 &&
68254         sscanf(uts.release, "%d.%d", &major, &minor) == 2 &&
68255         ((major < kRequiredMajor ||
68256           (major == kRequiredMajor && minor < kRequiredMinor)))) {
68257       return false;
68258     }
68259 
68260     base::ScopedFile fd;
68261     fd.reset(static_cast<int>(syscall(__NR_memfd_create, "perfetto_shmem",
68262                                       MFD_CLOEXEC | MFD_ALLOW_SEALING)));
68263     return !!fd;
68264   }();
68265   return kSupportsMemfd;
68266 }
68267 
CreateMemfd(const char * name,unsigned int flags)68268 base::ScopedFile CreateMemfd(const char* name, unsigned int flags) {
68269   if (!HasMemfdSupport()) {
68270     errno = ENOSYS;
68271     return base::ScopedFile();
68272   }
68273   return base::ScopedFile(
68274       static_cast<int>(syscall(__NR_memfd_create, name, flags)));
68275 }
68276 }  // namespace perfetto
68277 
68278 #else  // PERFETTO_MEMFD_ENABLED()
68279 
68280 namespace perfetto {
HasMemfdSupport()68281 bool HasMemfdSupport() {
68282   return false;
68283 }
CreateMemfd(const char *,unsigned int)68284 base::ScopedFile CreateMemfd(const char*, unsigned int) {
68285   errno = ENOSYS;
68286   return base::ScopedFile();
68287 }
68288 }  // namespace perfetto
68289 
68290 #endif  // PERFETTO_MEMFD_ENABLED()
68291 // gen_amalgamated begin source: src/tracing/ipc/posix_shared_memory.cc
68292 // gen_amalgamated begin header: src/tracing/ipc/posix_shared_memory.h
68293 /*
68294  * Copyright (C) 2017 The Android Open Source Project
68295  *
68296  * Licensed under the Apache License, Version 2.0 (the "License");
68297  * you may not use this file except in compliance with the License.
68298  * You may obtain a copy of the License at
68299  *
68300  *      http://www.apache.org/licenses/LICENSE-2.0
68301  *
68302  * Unless required by applicable law or agreed to in writing, software
68303  * distributed under the License is distributed on an "AS IS" BASIS,
68304  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
68305  * See the License for the specific language governing permissions and
68306  * limitations under the License.
68307  */
68308 
68309 #ifndef SRC_TRACING_IPC_POSIX_SHARED_MEMORY_H_
68310 #define SRC_TRACING_IPC_POSIX_SHARED_MEMORY_H_
68311 
68312 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
68313 
68314 #if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) ||   \
68315     PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \
68316     PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
68317 
68318 #include <stddef.h>
68319 
68320 #include <memory>
68321 
68322 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
68323 // gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"
68324 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/shared_memory.h"
68325 
68326 namespace perfetto {
68327 
68328 // Implements the SharedMemory and its factory for the posix-based transport.
68329 class PosixSharedMemory : public SharedMemory {
68330  public:
68331   class Factory : public SharedMemory::Factory {
68332    public:
68333     ~Factory() override;
68334     std::unique_ptr<SharedMemory> CreateSharedMemory(size_t) override;
68335   };
68336 
68337   // Create a brand new SHM region.
68338   static std::unique_ptr<PosixSharedMemory> Create(size_t size);
68339 
68340   // Mmaps a file descriptor to an existing SHM region. If
68341   // |require_seals_if_supported| is true and the system supports
68342   // memfd_create(), the FD is required to be a sealed memfd with F_SEAL_SEAL,
68343   // F_SEAL_GROW, and F_SEAL_SHRINK seals set (otherwise, nullptr is returned).
68344   // May also return nullptr if mapping fails for another reason (e.g. OOM).
68345   static std::unique_ptr<PosixSharedMemory> AttachToFd(
68346       base::ScopedFile,
68347       bool require_seals_if_supported = true);
68348 
68349   ~PosixSharedMemory() override;
68350 
fd() const68351   int fd() const { return fd_.get(); }
68352 
68353   // SharedMemory implementation.
start() const68354   void* start() const override { return start_; }
size() const68355   size_t size() const override { return size_; }
68356 
68357  private:
68358   static std::unique_ptr<PosixSharedMemory> MapFD(base::ScopedFile, size_t);
68359 
68360   PosixSharedMemory(void* start, size_t size, base::ScopedFile);
68361   PosixSharedMemory(const PosixSharedMemory&) = delete;
68362   PosixSharedMemory& operator=(const PosixSharedMemory&) = delete;
68363 
68364   void* const start_;
68365   const size_t size_;
68366   base::ScopedFile fd_;
68367 };
68368 
68369 }  // namespace perfetto
68370 
68371 #endif  // OS_LINUX || OS_ANDROID || OS_APPLE
68372 #endif  // SRC_TRACING_IPC_POSIX_SHARED_MEMORY_H_
68373 /*
68374  * Copyright (C) 2017 The Android Open Source Project
68375  *
68376  * Licensed under the Apache License, Version 2.0 (the "License");
68377  * you may not use this file except in compliance with the License.
68378  * You may obtain a copy of the License at
68379  *
68380  *      http://www.apache.org/licenses/LICENSE-2.0
68381  *
68382  * Unless required by applicable law or agreed to in writing, software
68383  * distributed under the License is distributed on an "AS IS" BASIS,
68384  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
68385  * See the License for the specific language governing permissions and
68386  * limitations under the License.
68387  */
68388 
68389 // gen_amalgamated expanded: #include "src/tracing/ipc/posix_shared_memory.h"
68390 
68391 #if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) ||   \
68392     PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \
68393     PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
68394 
68395 #include <fcntl.h>
68396 #include <stdint.h>
68397 #include <stdio.h>
68398 #include <stdlib.h>
68399 #include <sys/mman.h>
68400 #include <sys/stat.h>
68401 #include <unistd.h>
68402 
68403 #include <memory>
68404 #include <utility>
68405 
68406 // gen_amalgamated expanded: #include "perfetto/base/compiler.h"
68407 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
68408 // gen_amalgamated expanded: #include "perfetto/ext/base/temp_file.h"
68409 // gen_amalgamated expanded: #include "src/tracing/ipc/memfd.h"
68410 
68411 namespace perfetto {
68412 
68413 namespace {
68414 int kFileSeals = F_SEAL_SHRINK | F_SEAL_GROW | F_SEAL_SEAL;
68415 }  // namespace
68416 
68417 // static
Create(size_t size)68418 std::unique_ptr<PosixSharedMemory> PosixSharedMemory::Create(size_t size) {
68419   base::ScopedFile fd =
68420       CreateMemfd("perfetto_shmem", MFD_CLOEXEC | MFD_ALLOW_SEALING);
68421   bool is_memfd = !!fd;
68422 
68423   // In-tree builds only allow mem_fd, so we can inspect the seals to verify the
68424   // fd is appropriately sealed. We'll crash in the PERFETTO_CHECK(fd) below if
68425   // memfd_create failed.
68426 #if !PERFETTO_BUILDFLAG(PERFETTO_ANDROID_BUILD)
68427   if (!fd) {
68428     // TODO: if this fails on Android we should fall back on ashmem.
68429     PERFETTO_DPLOG("memfd_create() failed");
68430     fd = base::TempFile::CreateUnlinked().ReleaseFD();
68431   }
68432 #endif
68433 
68434   PERFETTO_CHECK(fd);
68435   int res = ftruncate(fd.get(), static_cast<off_t>(size));
68436   PERFETTO_CHECK(res == 0);
68437 
68438   if (is_memfd) {
68439     // When memfd is supported, file seals should be, too.
68440     res = fcntl(*fd, F_ADD_SEALS, kFileSeals);
68441     PERFETTO_DCHECK(res == 0);
68442   }
68443 
68444   return MapFD(std::move(fd), size);
68445 }
68446 
68447 // static
AttachToFd(base::ScopedFile fd,bool require_seals_if_supported)68448 std::unique_ptr<PosixSharedMemory> PosixSharedMemory::AttachToFd(
68449     base::ScopedFile fd,
68450     bool require_seals_if_supported) {
68451   bool requires_seals = require_seals_if_supported;
68452 
68453 #if PERFETTO_BUILDFLAG(PERFETTO_ANDROID_BUILD)
68454   // In-tree kernels all support memfd.
68455   PERFETTO_CHECK(HasMemfdSupport());
68456 #else
68457   // In out-of-tree builds, we only require seals if the kernel supports memfd.
68458   if (requires_seals)
68459     requires_seals = HasMemfdSupport();
68460 #endif
68461 
68462   if (requires_seals) {
68463     // If the system supports memfd, we require a sealed memfd.
68464     int res = fcntl(*fd, F_GET_SEALS);
68465     if (res == -1 || (res & kFileSeals) != kFileSeals) {
68466       PERFETTO_PLOG("Couldn't verify file seals on shmem FD");
68467       return nullptr;
68468     }
68469   }
68470 
68471   struct stat stat_buf = {};
68472   int res = fstat(fd.get(), &stat_buf);
68473   PERFETTO_CHECK(res == 0 && stat_buf.st_size > 0);
68474   return MapFD(std::move(fd), static_cast<size_t>(stat_buf.st_size));
68475 }
68476 
68477 // static
MapFD(base::ScopedFile fd,size_t size)68478 std::unique_ptr<PosixSharedMemory> PosixSharedMemory::MapFD(base::ScopedFile fd,
68479                                                             size_t size) {
68480   PERFETTO_DCHECK(fd);
68481   PERFETTO_DCHECK(size > 0);
68482   void* start =
68483       mmap(nullptr, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd.get(), 0);
68484   PERFETTO_CHECK(start != MAP_FAILED);
68485   return std::unique_ptr<PosixSharedMemory>(
68486       new PosixSharedMemory(start, size, std::move(fd)));
68487 }
68488 
PosixSharedMemory(void * start,size_t size,base::ScopedFile fd)68489 PosixSharedMemory::PosixSharedMemory(void* start,
68490                                      size_t size,
68491                                      base::ScopedFile fd)
68492     : start_(start), size_(size), fd_(std::move(fd)) {}
68493 
~PosixSharedMemory()68494 PosixSharedMemory::~PosixSharedMemory() {
68495   munmap(start(), size());
68496 }
68497 
~Factory()68498 PosixSharedMemory::Factory::~Factory() {}
68499 
CreateSharedMemory(size_t size)68500 std::unique_ptr<SharedMemory> PosixSharedMemory::Factory::CreateSharedMemory(
68501     size_t size) {
68502   return PosixSharedMemory::Create(size);
68503 }
68504 
68505 }  // namespace perfetto
68506 
68507 #endif  // OS_LINUX || OS_ANDROID || OS_APPLE
68508 // gen_amalgamated begin source: src/tracing/ipc/shared_memory_windows.cc
68509 // gen_amalgamated begin header: src/tracing/ipc/shared_memory_windows.h
68510 /*
68511  * Copyright (C) 2021 The Android Open Source Project
68512  *
68513  * Licensed under the Apache License, Version 2.0 (the "License");
68514  * you may not use this file except in compliance with the License.
68515  * You may obtain a copy of the License at
68516  *
68517  *      http://www.apache.org/licenses/LICENSE-2.0
68518  *
68519  * Unless required by applicable law or agreed to in writing, software
68520  * distributed under the License is distributed on an "AS IS" BASIS,
68521  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
68522  * See the License for the specific language governing permissions and
68523  * limitations under the License.
68524  */
68525 
68526 #ifndef SRC_TRACING_IPC_SHARED_MEMORY_WINDOWS_H_
68527 #define SRC_TRACING_IPC_SHARED_MEMORY_WINDOWS_H_
68528 
68529 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
68530 
68531 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
68532 
68533 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
68534 // gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"
68535 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/shared_memory.h"
68536 
68537 namespace perfetto {
68538 
68539 // Implements the SharedMemory and its factory for the Windows IPC transport.
68540 // This used only for standalone builds and NOT in chromium, which instead uses
68541 // a custom Mojo wrapper (MojoSharedMemory in chromium's //services/tracing/).
68542 class SharedMemoryWindows : public SharedMemory {
68543  public:
68544   class Factory : public SharedMemory::Factory {
68545    public:
68546     ~Factory() override;
68547     std::unique_ptr<SharedMemory> CreateSharedMemory(size_t) override;
68548   };
68549 
68550   // Create a brand new SHM region.
68551   static std::unique_ptr<SharedMemoryWindows> Create(size_t size);
68552   static std::unique_ptr<SharedMemoryWindows> Attach(const std::string& key);
68553   ~SharedMemoryWindows() override;
key() const68554   const std::string& key() const { return key_; }
68555 
68556   // SharedMemory implementation.
start() const68557   void* start() const override { return start_; }
size() const68558   size_t size() const override { return size_; }
68559 
68560  private:
68561   SharedMemoryWindows(void* start,
68562                       size_t size,
68563                       std::string,
68564                       base::ScopedPlatformHandle);
68565   SharedMemoryWindows(const SharedMemoryWindows&) = delete;
68566   SharedMemoryWindows& operator=(const SharedMemoryWindows&) = delete;
68567 
68568   void* const start_;
68569   const size_t size_;
68570   std::string key_;
68571   base::ScopedPlatformHandle handle_;
68572 };
68573 
68574 }  // namespace perfetto
68575 
68576 #endif  // OS_WIN
68577 
68578 #endif  // SRC_TRACING_IPC_SHARED_MEMORY_WINDOWS_H_
68579 /*
68580  * Copyright (C) 2021 The Android Open Source Project
68581  *
68582  * Licensed under the Apache License, Version 2.0 (the "License");
68583  * you may not use this file except in compliance with the License.
68584  * You may obtain a copy of the License at
68585  *
68586  *      http://www.apache.org/licenses/LICENSE-2.0
68587  *
68588  * Unless required by applicable law or agreed to in writing, software
68589  * distributed under the License is distributed on an "AS IS" BASIS,
68590  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
68591  * See the License for the specific language governing permissions and
68592  * limitations under the License.
68593  */
68594 
68595 // gen_amalgamated expanded: #include "src/tracing/ipc/shared_memory_windows.h"
68596 
68597 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
68598 
68599 #include <memory>
68600 #include <random>
68601 
68602 #include <Windows.h>
68603 
68604 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
68605 // gen_amalgamated expanded: #include "perfetto/ext/base/string_utils.h"
68606 
68607 namespace perfetto {
68608 
68609 // static
Create(size_t size)68610 std::unique_ptr<SharedMemoryWindows> SharedMemoryWindows::Create(size_t size) {
68611   base::ScopedPlatformHandle shmem_handle;
68612   std::random_device rnd_dev;
68613   uint64_t rnd_key = (static_cast<uint64_t>(rnd_dev()) << 32) | rnd_dev();
68614   std::string key = "perfetto_shm_" + base::Uint64ToHexStringNoPrefix(rnd_key);
68615   shmem_handle.reset(CreateFileMappingA(
68616       INVALID_HANDLE_VALUE,  // Use paging file.
68617       nullptr,               // Default security.
68618       PAGE_READWRITE,
68619       static_cast<DWORD>(size >> 32),  // maximum object size (high-order DWORD)
68620       static_cast<DWORD>(size),        // maximum object size (low-order DWORD)
68621       key.c_str()));
68622 
68623   if (!shmem_handle) {
68624     PERFETTO_PLOG("CreateFileMapping() call failed");
68625     return nullptr;
68626   }
68627   void* start =
68628       MapViewOfFile(*shmem_handle, FILE_MAP_ALL_ACCESS, /*offsetHigh=*/0,
68629                     /*offsetLow=*/0, size);
68630   if (!start) {
68631     PERFETTO_PLOG("MapViewOfFile() failed");
68632     return nullptr;
68633   }
68634 
68635   return std::unique_ptr<SharedMemoryWindows>(new SharedMemoryWindows(
68636       start, size, std::move(key), std::move(shmem_handle)));
68637 }
68638 
68639 // static
Attach(const std::string & key)68640 std::unique_ptr<SharedMemoryWindows> SharedMemoryWindows::Attach(
68641     const std::string& key) {
68642   base::ScopedPlatformHandle shmem_handle;
68643   shmem_handle.reset(
68644       OpenFileMappingA(FILE_MAP_ALL_ACCESS, /*inherit=*/false, key.c_str()));
68645   if (!shmem_handle) {
68646     PERFETTO_PLOG("Failed to OpenFileMapping()");
68647     return nullptr;
68648   }
68649 
68650   void* start =
68651       MapViewOfFile(*shmem_handle, FILE_MAP_ALL_ACCESS, /*offsetHigh=*/0,
68652                     /*offsetLow=*/0, /*dwNumberOfBytesToMap=*/0);
68653   if (!start) {
68654     PERFETTO_PLOG("MapViewOfFile() failed");
68655     return nullptr;
68656   }
68657 
68658   MEMORY_BASIC_INFORMATION info{};
68659   if (!VirtualQuery(start, &info, sizeof(info))) {
68660     PERFETTO_PLOG("VirtualQuery() failed");
68661     return nullptr;
68662   }
68663   size_t size = info.RegionSize;
68664   return std::unique_ptr<SharedMemoryWindows>(
68665       new SharedMemoryWindows(start, size, key, std::move(shmem_handle)));
68666 }
68667 
SharedMemoryWindows(void * start,size_t size,std::string key,base::ScopedPlatformHandle handle)68668 SharedMemoryWindows::SharedMemoryWindows(void* start,
68669                                          size_t size,
68670                                          std::string key,
68671                                          base::ScopedPlatformHandle handle)
68672     : start_(start),
68673       size_(size),
68674       key_(std::move(key)),
68675       handle_(std::move(handle)) {}
68676 
~SharedMemoryWindows()68677 SharedMemoryWindows::~SharedMemoryWindows() {
68678   if (start_)
68679     UnmapViewOfFile(start_);
68680 }
68681 
68682 SharedMemoryWindows::Factory::~Factory() = default;
68683 
CreateSharedMemory(size_t size)68684 std::unique_ptr<SharedMemory> SharedMemoryWindows::Factory::CreateSharedMemory(
68685     size_t size) {
68686   return SharedMemoryWindows::Create(size);
68687 }
68688 
68689 }  // namespace perfetto
68690 
68691 #endif  // !OS_WIN
68692 // gen_amalgamated begin source: src/tracing/ipc/consumer/consumer_ipc_client_impl.cc
68693 // gen_amalgamated begin header: src/tracing/ipc/consumer/consumer_ipc_client_impl.h
68694 // gen_amalgamated begin header: include/perfetto/ext/tracing/ipc/consumer_ipc_client.h
68695 /*
68696  * Copyright (C) 2017 The Android Open Source Project
68697  *
68698  * Licensed under the Apache License, Version 2.0 (the "License");
68699  * you may not use this file except in compliance with the License.
68700  * You may obtain a copy of the License at
68701  *
68702  *      http://www.apache.org/licenses/LICENSE-2.0
68703  *
68704  * Unless required by applicable law or agreed to in writing, software
68705  * distributed under the License is distributed on an "AS IS" BASIS,
68706  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
68707  * See the License for the specific language governing permissions and
68708  * limitations under the License.
68709  */
68710 
68711 #ifndef INCLUDE_PERFETTO_EXT_TRACING_IPC_CONSUMER_IPC_CLIENT_H_
68712 #define INCLUDE_PERFETTO_EXT_TRACING_IPC_CONSUMER_IPC_CLIENT_H_
68713 
68714 #include <memory>
68715 #include <string>
68716 
68717 // gen_amalgamated expanded: #include "perfetto/base/export.h"
68718 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/tracing_service.h"
68719 
68720 namespace perfetto {
68721 
68722 class Consumer;
68723 
68724 // Allows to connect to a remote Service through a UNIX domain socket.
68725 // Exposed to:
68726 //   Consumer(s) of the tracing library.
68727 // Implemented in:
68728 //   src/tracing/ipc/consumer/consumer_ipc_client_impl.cc
68729 class PERFETTO_EXPORT ConsumerIPCClient {
68730  public:
68731   // Connects to the producer port of the Service listening on the given
68732   // |service_sock_name|. If the connection is successful, the OnConnect()
68733   // method will be invoked asynchronously on the passed Consumer interface.
68734   // If the connection fails, OnDisconnect() will be invoked instead.
68735   // The returned ConsumerEndpoint serves also to delimit the scope of the
68736   // callbacks invoked on the Consumer interface: no more Consumer callbacks are
68737   // invoked immediately after its destruction and any pending callback will be
68738   // dropped.
68739   static std::unique_ptr<TracingService::ConsumerEndpoint>
68740   Connect(const char* service_sock_name, Consumer*, base::TaskRunner*);
68741 
68742  protected:
68743   ConsumerIPCClient() = delete;
68744 };
68745 
68746 }  // namespace perfetto
68747 
68748 #endif  // INCLUDE_PERFETTO_EXT_TRACING_IPC_CONSUMER_IPC_CLIENT_H_
68749 /*
68750  * Copyright (C) 2017 The Android Open Source Project
68751  *
68752  * Licensed under the Apache License, Version 2.0 (the "License");
68753  * you may not use this file except in compliance with the License.
68754  * You may obtain a copy of the License at
68755  *
68756  *      http://www.apache.org/licenses/LICENSE-2.0
68757  *
68758  * Unless required by applicable law or agreed to in writing, software
68759  * distributed under the License is distributed on an "AS IS" BASIS,
68760  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
68761  * See the License for the specific language governing permissions and
68762  * limitations under the License.
68763  */
68764 
68765 #ifndef SRC_TRACING_IPC_CONSUMER_CONSUMER_IPC_CLIENT_IMPL_H_
68766 #define SRC_TRACING_IPC_CONSUMER_CONSUMER_IPC_CLIENT_IMPL_H_
68767 
68768 #include <stdint.h>
68769 
68770 #include <list>
68771 #include <vector>
68772 
68773 // gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"
68774 // gen_amalgamated expanded: #include "perfetto/ext/base/weak_ptr.h"
68775 // gen_amalgamated expanded: #include "perfetto/ext/ipc/service_proxy.h"
68776 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/basic_types.h"
68777 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/trace_packet.h"
68778 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/tracing_service.h"
68779 // gen_amalgamated expanded: #include "perfetto/ext/tracing/ipc/consumer_ipc_client.h"
68780 // gen_amalgamated expanded: #include "perfetto/tracing/core/forward_decls.h"
68781 
68782 // gen_amalgamated expanded: #include "protos/perfetto/ipc/consumer_port.ipc.h"
68783 
68784 namespace perfetto {
68785 
68786 namespace base {
68787 class TaskRunner;
68788 }  // namespace base
68789 
68790 namespace ipc {
68791 class Client;
68792 }  // namespace ipc
68793 
68794 class Consumer;
68795 
68796 // Exposes a Service endpoint to Consumer(s), proxying all requests through a
68797 // IPC channel to the remote Service. This class is the glue layer between the
68798 // generic Service interface exposed to the clients of the library and the
68799 // actual IPC transport.
68800 class ConsumerIPCClientImpl : public TracingService::ConsumerEndpoint,
68801                               public ipc::ServiceProxy::EventListener {
68802  public:
68803   ConsumerIPCClientImpl(const char* service_sock_name,
68804                         Consumer*,
68805                         base::TaskRunner*);
68806   ~ConsumerIPCClientImpl() override;
68807 
68808   // TracingService::ConsumerEndpoint implementation.
68809   // These methods are invoked by the actual Consumer(s) code by clients of the
68810   // tracing library, which know nothing about the IPC transport.
68811   void EnableTracing(const TraceConfig&, base::ScopedFile) override;
68812   void StartTracing() override;
68813   void ChangeTraceConfig(const TraceConfig&) override;
68814   void DisableTracing() override;
68815   void ReadBuffers() override;
68816   void FreeBuffers() override;
68817   void Flush(uint32_t timeout_ms, FlushCallback) override;
68818   void Detach(const std::string& key) override;
68819   void Attach(const std::string& key) override;
68820   void GetTraceStats() override;
68821   void ObserveEvents(uint32_t enabled_event_types) override;
68822   void QueryServiceState(QueryServiceStateCallback) override;
68823   void QueryCapabilities(QueryCapabilitiesCallback) override;
68824   void SaveTraceForBugreport(SaveTraceForBugreportCallback) override;
68825 
68826   // ipc::ServiceProxy::EventListener implementation.
68827   // These methods are invoked by the IPC layer, which knows nothing about
68828   // tracing, consumers and consumers.
68829   void OnConnect() override;
68830   void OnDisconnect() override;
68831 
68832  private:
68833   struct PendingQueryServiceRequest {
68834     QueryServiceStateCallback callback;
68835 
68836     // All the replies will be appended here until |has_more| == false.
68837     std::vector<uint8_t> merged_resp;
68838   };
68839 
68840   // List because we need stable iterators.
68841   using PendingQueryServiceRequests = std::list<PendingQueryServiceRequest>;
68842 
68843   void OnReadBuffersResponse(
68844       ipc::AsyncResult<protos::gen::ReadBuffersResponse>);
68845   void OnEnableTracingResponse(
68846       ipc::AsyncResult<protos::gen::EnableTracingResponse>);
68847   void OnQueryServiceStateResponse(
68848       ipc::AsyncResult<protos::gen::QueryServiceStateResponse>,
68849       PendingQueryServiceRequests::iterator);
68850 
68851   // TODO(primiano): think to dtor order, do we rely on any specific sequence?
68852   Consumer* const consumer_;
68853 
68854   // The object that owns the client socket and takes care of IPC traffic.
68855   std::unique_ptr<ipc::Client> ipc_channel_;
68856 
68857   // The proxy interface for the consumer port of the service. It is bound
68858   // to |ipc_channel_| and (de)serializes method invocations over the wire.
68859   protos::gen::ConsumerPortProxy consumer_port_;
68860 
68861   bool connected_ = false;
68862 
68863   PendingQueryServiceRequests pending_query_svc_reqs_;
68864 
68865   // When a packet is too big to fit into a ReadBuffersResponse IPC, the service
68866   // will chunk it into several IPCs, each containing few slices of the packet
68867   // (a packet's slice is always guaranteed to be << kIPCBufferSize). When
68868   // chunking happens this field accumulates the slices received until the
68869   // one with |last_slice_for_packet| == true is received.
68870   TracePacket partial_packet_;
68871 
68872   // Keep last.
68873   base::WeakPtrFactory<ConsumerIPCClientImpl> weak_ptr_factory_;
68874 };
68875 
68876 }  // namespace perfetto
68877 
68878 #endif  // SRC_TRACING_IPC_CONSUMER_CONSUMER_IPC_CLIENT_IMPL_H_
68879 /*
68880  * Copyright (C) 2017 The Android Open Source Project
68881  *
68882  * Licensed under the Apache License, Version 2.0 (the "License");
68883  * you may not use this file except in compliance with the License.
68884  * You may obtain a copy of the License at
68885  *
68886  *      http://www.apache.org/licenses/LICENSE-2.0
68887  *
68888  * Unless required by applicable law or agreed to in writing, software
68889  * distributed under the License is distributed on an "AS IS" BASIS,
68890  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
68891  * See the License for the specific language governing permissions and
68892  * limitations under the License.
68893  */
68894 
68895 // gen_amalgamated expanded: #include "src/tracing/ipc/consumer/consumer_ipc_client_impl.h"
68896 
68897 #include <string.h>
68898 
68899 #include <cinttypes>
68900 
68901 // gen_amalgamated expanded: #include "perfetto/base/task_runner.h"
68902 // gen_amalgamated expanded: #include "perfetto/ext/ipc/client.h"
68903 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/consumer.h"
68904 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/observable_events.h"
68905 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/trace_stats.h"
68906 // gen_amalgamated expanded: #include "perfetto/tracing/core/trace_config.h"
68907 // gen_amalgamated expanded: #include "perfetto/tracing/core/tracing_service_state.h"
68908 
68909 // TODO(fmayer): Add a test to check to what happens when ConsumerIPCClientImpl
68910 // gets destroyed w.r.t. the Consumer pointer. Also think to lifetime of the
68911 // Consumer* during the callbacks.
68912 
68913 namespace perfetto {
68914 
68915 // static. (Declared in include/tracing/ipc/consumer_ipc_client.h).
Connect(const char * service_sock_name,Consumer * consumer,base::TaskRunner * task_runner)68916 std::unique_ptr<TracingService::ConsumerEndpoint> ConsumerIPCClient::Connect(
68917     const char* service_sock_name,
68918     Consumer* consumer,
68919     base::TaskRunner* task_runner) {
68920   return std::unique_ptr<TracingService::ConsumerEndpoint>(
68921       new ConsumerIPCClientImpl(service_sock_name, consumer, task_runner));
68922 }
68923 
ConsumerIPCClientImpl(const char * service_sock_name,Consumer * consumer,base::TaskRunner * task_runner)68924 ConsumerIPCClientImpl::ConsumerIPCClientImpl(const char* service_sock_name,
68925                                              Consumer* consumer,
68926                                              base::TaskRunner* task_runner)
68927     : consumer_(consumer),
68928       ipc_channel_(
68929           ipc::Client::CreateInstance({service_sock_name, /*sock_retry=*/false},
68930                                       task_runner)),
68931       consumer_port_(this /* event_listener */),
68932       weak_ptr_factory_(this) {
68933   ipc_channel_->BindService(consumer_port_.GetWeakPtr());
68934 }
68935 
68936 ConsumerIPCClientImpl::~ConsumerIPCClientImpl() = default;
68937 
68938 // Called by the IPC layer if the BindService() succeeds.
OnConnect()68939 void ConsumerIPCClientImpl::OnConnect() {
68940   connected_ = true;
68941   consumer_->OnConnect();
68942 }
68943 
OnDisconnect()68944 void ConsumerIPCClientImpl::OnDisconnect() {
68945   PERFETTO_DLOG("Tracing service connection failure");
68946   connected_ = false;
68947   consumer_->OnDisconnect();  // Note: may delete |this|.
68948 }
68949 
EnableTracing(const TraceConfig & trace_config,base::ScopedFile fd)68950 void ConsumerIPCClientImpl::EnableTracing(const TraceConfig& trace_config,
68951                                           base::ScopedFile fd) {
68952   if (!connected_) {
68953     PERFETTO_DLOG("Cannot EnableTracing(), not connected to tracing service");
68954     return;
68955   }
68956 
68957 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
68958   if (fd) {
68959     consumer_->OnTracingDisabled(
68960         "Passing FDs for write_into_file is not supported on Windows");
68961     return;
68962   }
68963 #endif
68964 
68965   protos::gen::EnableTracingRequest req;
68966   *req.mutable_trace_config() = trace_config;
68967   ipc::Deferred<protos::gen::EnableTracingResponse> async_response;
68968   auto weak_this = weak_ptr_factory_.GetWeakPtr();
68969   async_response.Bind(
68970       [weak_this](
68971           ipc::AsyncResult<protos::gen::EnableTracingResponse> response) {
68972         if (weak_this)
68973           weak_this->OnEnableTracingResponse(std::move(response));
68974       });
68975 
68976   // |fd| will be closed when this function returns, but it's fine because the
68977   // IPC layer dup()'s it when sending the IPC.
68978   consumer_port_.EnableTracing(req, std::move(async_response), *fd);
68979 }
68980 
ChangeTraceConfig(const TraceConfig & trace_config)68981 void ConsumerIPCClientImpl::ChangeTraceConfig(const TraceConfig& trace_config) {
68982   if (!connected_) {
68983     PERFETTO_DLOG(
68984         "Cannot ChangeTraceConfig(), not connected to tracing service");
68985     return;
68986   }
68987 
68988   ipc::Deferred<protos::gen::ChangeTraceConfigResponse> async_response;
68989   async_response.Bind(
68990       [](ipc::AsyncResult<protos::gen::ChangeTraceConfigResponse> response) {
68991         if (!response)
68992           PERFETTO_DLOG("ChangeTraceConfig() failed");
68993       });
68994   protos::gen::ChangeTraceConfigRequest req;
68995   *req.mutable_trace_config() = trace_config;
68996   consumer_port_.ChangeTraceConfig(req, std::move(async_response));
68997 }
68998 
StartTracing()68999 void ConsumerIPCClientImpl::StartTracing() {
69000   if (!connected_) {
69001     PERFETTO_DLOG("Cannot StartTracing(), not connected to tracing service");
69002     return;
69003   }
69004 
69005   ipc::Deferred<protos::gen::StartTracingResponse> async_response;
69006   async_response.Bind(
69007       [](ipc::AsyncResult<protos::gen::StartTracingResponse> response) {
69008         if (!response)
69009           PERFETTO_DLOG("StartTracing() failed");
69010       });
69011   protos::gen::StartTracingRequest req;
69012   consumer_port_.StartTracing(req, std::move(async_response));
69013 }
69014 
DisableTracing()69015 void ConsumerIPCClientImpl::DisableTracing() {
69016   if (!connected_) {
69017     PERFETTO_DLOG("Cannot DisableTracing(), not connected to tracing service");
69018     return;
69019   }
69020 
69021   ipc::Deferred<protos::gen::DisableTracingResponse> async_response;
69022   async_response.Bind(
69023       [](ipc::AsyncResult<protos::gen::DisableTracingResponse> response) {
69024         if (!response)
69025           PERFETTO_DLOG("DisableTracing() failed");
69026       });
69027   consumer_port_.DisableTracing(protos::gen::DisableTracingRequest(),
69028                                 std::move(async_response));
69029 }
69030 
ReadBuffers()69031 void ConsumerIPCClientImpl::ReadBuffers() {
69032   if (!connected_) {
69033     PERFETTO_DLOG("Cannot ReadBuffers(), not connected to tracing service");
69034     return;
69035   }
69036 
69037   ipc::Deferred<protos::gen::ReadBuffersResponse> async_response;
69038 
69039   // The IPC layer guarantees that callbacks are destroyed after this object
69040   // is destroyed (by virtue of destroying the |consumer_port_|). In turn the
69041   // contract of this class expects the caller to not destroy the Consumer class
69042   // before having destroyed this class. Hence binding |this| here is safe.
69043   async_response.Bind(
69044       [this](ipc::AsyncResult<protos::gen::ReadBuffersResponse> response) {
69045         OnReadBuffersResponse(std::move(response));
69046       });
69047   consumer_port_.ReadBuffers(protos::gen::ReadBuffersRequest(),
69048                              std::move(async_response));
69049 }
69050 
OnReadBuffersResponse(ipc::AsyncResult<protos::gen::ReadBuffersResponse> response)69051 void ConsumerIPCClientImpl::OnReadBuffersResponse(
69052     ipc::AsyncResult<protos::gen::ReadBuffersResponse> response) {
69053   if (!response) {
69054     PERFETTO_DLOG("ReadBuffers() failed");
69055     return;
69056   }
69057   std::vector<TracePacket> trace_packets;
69058   for (auto& resp_slice : response->slices()) {
69059     const std::string& slice_data = resp_slice.data();
69060     Slice slice = Slice::Allocate(slice_data.size());
69061     memcpy(slice.own_data(), slice_data.data(), slice.size);
69062     partial_packet_.AddSlice(std::move(slice));
69063     if (resp_slice.last_slice_for_packet())
69064       trace_packets.emplace_back(std::move(partial_packet_));
69065   }
69066   if (!trace_packets.empty() || !response.has_more())
69067     consumer_->OnTraceData(std::move(trace_packets), response.has_more());
69068 }
69069 
OnEnableTracingResponse(ipc::AsyncResult<protos::gen::EnableTracingResponse> response)69070 void ConsumerIPCClientImpl::OnEnableTracingResponse(
69071     ipc::AsyncResult<protos::gen::EnableTracingResponse> response) {
69072   std::string error;
69073   // |response| might be empty when the request gets rejected (if the connection
69074   // with the service is dropped all outstanding requests are auto-rejected).
69075   if (!response) {
69076     error =
69077         "EnableTracing IPC request rejected. This is likely due to a loss of "
69078         "the traced connection";
69079   } else {
69080     error = response->error();
69081   }
69082   if (!response || response->disabled())
69083     consumer_->OnTracingDisabled(error);
69084 }
69085 
FreeBuffers()69086 void ConsumerIPCClientImpl::FreeBuffers() {
69087   if (!connected_) {
69088     PERFETTO_DLOG("Cannot FreeBuffers(), not connected to tracing service");
69089     return;
69090   }
69091 
69092   protos::gen::FreeBuffersRequest req;
69093   ipc::Deferred<protos::gen::FreeBuffersResponse> async_response;
69094   async_response.Bind(
69095       [](ipc::AsyncResult<protos::gen::FreeBuffersResponse> response) {
69096         if (!response)
69097           PERFETTO_DLOG("FreeBuffers() failed");
69098       });
69099   consumer_port_.FreeBuffers(req, std::move(async_response));
69100 }
69101 
Flush(uint32_t timeout_ms,FlushCallback callback)69102 void ConsumerIPCClientImpl::Flush(uint32_t timeout_ms, FlushCallback callback) {
69103   if (!connected_) {
69104     PERFETTO_DLOG("Cannot Flush(), not connected to tracing service");
69105     return callback(/*success=*/false);
69106   }
69107 
69108   protos::gen::FlushRequest req;
69109   req.set_timeout_ms(static_cast<uint32_t>(timeout_ms));
69110   ipc::Deferred<protos::gen::FlushResponse> async_response;
69111   async_response.Bind(
69112       [callback](ipc::AsyncResult<protos::gen::FlushResponse> response) {
69113         callback(!!response);
69114       });
69115   consumer_port_.Flush(req, std::move(async_response));
69116 }
69117 
Detach(const std::string & key)69118 void ConsumerIPCClientImpl::Detach(const std::string& key) {
69119   if (!connected_) {
69120     PERFETTO_DLOG("Cannot Detach(), not connected to tracing service");
69121     return;
69122   }
69123 
69124   protos::gen::DetachRequest req;
69125   req.set_key(key);
69126   ipc::Deferred<protos::gen::DetachResponse> async_response;
69127   auto weak_this = weak_ptr_factory_.GetWeakPtr();
69128 
69129   async_response.Bind(
69130       [weak_this](ipc::AsyncResult<protos::gen::DetachResponse> response) {
69131         if (weak_this)
69132           weak_this->consumer_->OnDetach(!!response);
69133       });
69134   consumer_port_.Detach(req, std::move(async_response));
69135 }
69136 
Attach(const std::string & key)69137 void ConsumerIPCClientImpl::Attach(const std::string& key) {
69138   if (!connected_) {
69139     PERFETTO_DLOG("Cannot Attach(), not connected to tracing service");
69140     return;
69141   }
69142 
69143   {
69144     protos::gen::AttachRequest req;
69145     req.set_key(key);
69146     ipc::Deferred<protos::gen::AttachResponse> async_response;
69147     auto weak_this = weak_ptr_factory_.GetWeakPtr();
69148 
69149     async_response.Bind(
69150         [weak_this](ipc::AsyncResult<protos::gen::AttachResponse> response) {
69151           if (!weak_this)
69152             return;
69153           if (!response) {
69154             weak_this->consumer_->OnAttach(/*success=*/false, TraceConfig());
69155             return;
69156           }
69157           const TraceConfig& trace_config = response->trace_config();
69158 
69159           // If attached succesfully, also attach to the end-of-trace
69160           // notificaton callback, via EnableTracing(attach_notification_only).
69161           protos::gen::EnableTracingRequest enable_req;
69162           enable_req.set_attach_notification_only(true);
69163           ipc::Deferred<protos::gen::EnableTracingResponse> enable_resp;
69164           enable_resp.Bind(
69165               [weak_this](
69166                   ipc::AsyncResult<protos::gen::EnableTracingResponse> resp) {
69167                 if (weak_this)
69168                   weak_this->OnEnableTracingResponse(std::move(resp));
69169               });
69170           weak_this->consumer_port_.EnableTracing(enable_req,
69171                                                   std::move(enable_resp));
69172 
69173           weak_this->consumer_->OnAttach(/*success=*/true, trace_config);
69174         });
69175     consumer_port_.Attach(req, std::move(async_response));
69176   }
69177 }
69178 
GetTraceStats()69179 void ConsumerIPCClientImpl::GetTraceStats() {
69180   if (!connected_) {
69181     PERFETTO_DLOG("Cannot GetTraceStats(), not connected to tracing service");
69182     return;
69183   }
69184 
69185   protos::gen::GetTraceStatsRequest req;
69186   ipc::Deferred<protos::gen::GetTraceStatsResponse> async_response;
69187 
69188   // The IPC layer guarantees that callbacks are destroyed after this object
69189   // is destroyed (by virtue of destroying the |consumer_port_|). In turn the
69190   // contract of this class expects the caller to not destroy the Consumer class
69191   // before having destroyed this class. Hence binding |this| here is safe.
69192   async_response.Bind(
69193       [this](ipc::AsyncResult<protos::gen::GetTraceStatsResponse> response) {
69194         if (!response) {
69195           consumer_->OnTraceStats(/*success=*/false, TraceStats());
69196           return;
69197         }
69198         consumer_->OnTraceStats(/*success=*/true, response->trace_stats());
69199       });
69200   consumer_port_.GetTraceStats(req, std::move(async_response));
69201 }
69202 
ObserveEvents(uint32_t enabled_event_types)69203 void ConsumerIPCClientImpl::ObserveEvents(uint32_t enabled_event_types) {
69204   if (!connected_) {
69205     PERFETTO_DLOG("Cannot ObserveEvents(), not connected to tracing service");
69206     return;
69207   }
69208 
69209   protos::gen::ObserveEventsRequest req;
69210   for (uint32_t i = 0; i < 32; i++) {
69211     const uint32_t event_id = 1u << i;
69212     if (enabled_event_types & event_id)
69213       req.add_events_to_observe(static_cast<ObservableEvents::Type>(event_id));
69214   }
69215 
69216   ipc::Deferred<protos::gen::ObserveEventsResponse> async_response;
69217   // The IPC layer guarantees that callbacks are destroyed after this object
69218   // is destroyed (by virtue of destroying the |consumer_port_|). In turn the
69219   // contract of this class expects the caller to not destroy the Consumer class
69220   // before having destroyed this class. Hence binding |this| here is safe.
69221   async_response.Bind(
69222       [this](ipc::AsyncResult<protos::gen::ObserveEventsResponse> response) {
69223         // Skip empty response, which the service sends to close the stream.
69224         if (!response.has_more()) {
69225           PERFETTO_DCHECK(!response.success());
69226           return;
69227         }
69228         consumer_->OnObservableEvents(response->events());
69229       });
69230   consumer_port_.ObserveEvents(req, std::move(async_response));
69231 }
69232 
QueryServiceState(QueryServiceStateCallback callback)69233 void ConsumerIPCClientImpl::QueryServiceState(
69234     QueryServiceStateCallback callback) {
69235   if (!connected_) {
69236     PERFETTO_DLOG(
69237         "Cannot QueryServiceState(), not connected to tracing service");
69238     return;
69239   }
69240 
69241   auto it = pending_query_svc_reqs_.insert(pending_query_svc_reqs_.end(),
69242                                            {std::move(callback), {}});
69243   protos::gen::QueryServiceStateRequest req;
69244   ipc::Deferred<protos::gen::QueryServiceStateResponse> async_response;
69245   auto weak_this = weak_ptr_factory_.GetWeakPtr();
69246   async_response.Bind(
69247       [weak_this,
69248        it](ipc::AsyncResult<protos::gen::QueryServiceStateResponse> response) {
69249         if (weak_this)
69250           weak_this->OnQueryServiceStateResponse(std::move(response), it);
69251       });
69252   consumer_port_.QueryServiceState(req, std::move(async_response));
69253 }
69254 
OnQueryServiceStateResponse(ipc::AsyncResult<protos::gen::QueryServiceStateResponse> response,PendingQueryServiceRequests::iterator req_it)69255 void ConsumerIPCClientImpl::OnQueryServiceStateResponse(
69256     ipc::AsyncResult<protos::gen::QueryServiceStateResponse> response,
69257     PendingQueryServiceRequests::iterator req_it) {
69258   PERFETTO_DCHECK(req_it->callback);
69259 
69260   if (!response) {
69261     auto callback = std::move(req_it->callback);
69262     pending_query_svc_reqs_.erase(req_it);
69263     callback(false, TracingServiceState());
69264     return;
69265   }
69266 
69267   // The QueryServiceState response can be split in several chunks if the
69268   // service has several data sources. The client is supposed to merge all the
69269   // replies. The easiest way to achieve this is to re-serialize the partial
69270   // response and then re-decode the merged result in one shot.
69271   std::vector<uint8_t>& merged_resp = req_it->merged_resp;
69272   std::vector<uint8_t> part = response->service_state().SerializeAsArray();
69273   merged_resp.insert(merged_resp.end(), part.begin(), part.end());
69274 
69275   if (response.has_more())
69276     return;
69277 
69278   // All replies have been received. Decode the merged result and reply to the
69279   // callback.
69280   protos::gen::TracingServiceState svc_state;
69281   bool ok = svc_state.ParseFromArray(merged_resp.data(), merged_resp.size());
69282   if (!ok)
69283     PERFETTO_ELOG("Failed to decode merged QueryServiceStateResponse");
69284   auto callback = std::move(req_it->callback);
69285   pending_query_svc_reqs_.erase(req_it);
69286   callback(ok, std::move(svc_state));
69287 }
69288 
QueryCapabilities(QueryCapabilitiesCallback callback)69289 void ConsumerIPCClientImpl::QueryCapabilities(
69290     QueryCapabilitiesCallback callback) {
69291   if (!connected_) {
69292     PERFETTO_DLOG(
69293         "Cannot QueryCapabilities(), not connected to tracing service");
69294     return;
69295   }
69296 
69297   protos::gen::QueryCapabilitiesRequest req;
69298   ipc::Deferred<protos::gen::QueryCapabilitiesResponse> async_response;
69299   async_response.Bind(
69300       [callback](
69301           ipc::AsyncResult<protos::gen::QueryCapabilitiesResponse> response) {
69302         if (!response) {
69303           // If the IPC fails, we are talking to an older version of the service
69304           // that didn't support QueryCapabilities at all. In this case return
69305           // an empty capabilities message.
69306           callback(TracingServiceCapabilities());
69307         } else {
69308           callback(response->capabilities());
69309         }
69310       });
69311   consumer_port_.QueryCapabilities(req, std::move(async_response));
69312 }
69313 
SaveTraceForBugreport(SaveTraceForBugreportCallback callback)69314 void ConsumerIPCClientImpl::SaveTraceForBugreport(
69315     SaveTraceForBugreportCallback callback) {
69316   if (!connected_) {
69317     PERFETTO_DLOG(
69318         "Cannot SaveTraceForBugreport(), not connected to tracing service");
69319     return;
69320   }
69321 
69322   protos::gen::SaveTraceForBugreportRequest req;
69323   ipc::Deferred<protos::gen::SaveTraceForBugreportResponse> async_response;
69324   async_response.Bind(
69325       [callback](ipc::AsyncResult<protos::gen::SaveTraceForBugreportResponse>
69326                      response) {
69327         if (!response) {
69328           // If the IPC fails, we are talking to an older version of the service
69329           // that didn't support SaveTraceForBugreport at all.
69330           callback(
69331               false,
69332               "The tracing service doesn't support SaveTraceForBugreport()");
69333         } else {
69334           callback(response->success(), response->msg());
69335         }
69336       });
69337   consumer_port_.SaveTraceForBugreport(req, std::move(async_response));
69338 }
69339 
69340 }  // namespace perfetto
69341 // gen_amalgamated begin source: src/tracing/ipc/producer/producer_ipc_client_impl.cc
69342 // gen_amalgamated begin header: src/tracing/ipc/producer/producer_ipc_client_impl.h
69343 // gen_amalgamated begin header: include/perfetto/ext/tracing/ipc/producer_ipc_client.h
69344 /*
69345  * Copyright (C) 2017 The Android Open Source Project
69346  *
69347  * Licensed under the Apache License, Version 2.0 (the "License");
69348  * you may not use this file except in compliance with the License.
69349  * You may obtain a copy of the License at
69350  *
69351  *      http://www.apache.org/licenses/LICENSE-2.0
69352  *
69353  * Unless required by applicable law or agreed to in writing, software
69354  * distributed under the License is distributed on an "AS IS" BASIS,
69355  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
69356  * See the License for the specific language governing permissions and
69357  * limitations under the License.
69358  */
69359 
69360 #ifndef INCLUDE_PERFETTO_EXT_TRACING_IPC_PRODUCER_IPC_CLIENT_H_
69361 #define INCLUDE_PERFETTO_EXT_TRACING_IPC_PRODUCER_IPC_CLIENT_H_
69362 
69363 #include <memory>
69364 #include <string>
69365 
69366 // gen_amalgamated expanded: #include "perfetto/base/export.h"
69367 // gen_amalgamated expanded: #include "perfetto/ext/ipc/client.h"
69368 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/shared_memory.h"
69369 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/shared_memory_arbiter.h"
69370 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/tracing_service.h"
69371 
69372 namespace perfetto {
69373 
69374 class Producer;
69375 
69376 // Allows to connect to a remote Service through a UNIX domain socket.
69377 // Exposed to:
69378 //   Producer(s) of the tracing library.
69379 // Implemented in:
69380 //   src/tracing/ipc/producer/producer_ipc_client_impl.cc
69381 class PERFETTO_EXPORT ProducerIPCClient {
69382  public:
69383   enum class ConnectionFlags {
69384     // Fails immediately with OnConnect(false) if the service connection cannot
69385     // be established.
69386     kDefault = 0,
69387 
69388     // Keeps retrying with exponential backoff indefinitely. The caller will
69389     // never see an OnConnect(false).
69390     kRetryIfUnreachable = 1,
69391   };
69392 
69393   // Connects to the producer port of the Service listening on the given
69394   // |service_sock_name|. If the connection is successful, the OnConnect()
69395   // method will be invoked asynchronously on the passed Producer interface. If
69396   // the connection fails, OnDisconnect() will be invoked instead. The returned
69397   // ProducerEndpoint serves also to delimit the scope of the callbacks invoked
69398   // on the Producer interface: no more Producer callbacks are invoked
69399   // immediately after its destruction and any pending callback will be dropped.
69400   // To provide a producer-allocated shared memory buffer, both |shm| and
69401   // |shm_arbiter| should be set. |shm_arbiter| should be an unbound
69402   // SharedMemoryArbiter instance. When |shm| and |shm_arbiter| are provided,
69403   // the service will attempt to adopt the provided SMB. If this fails, the
69404   // ProducerEndpoint will disconnect, but the SMB and arbiter will remain valid
69405   // until the client is destroyed.
69406   //
69407   // TODO(eseckler): Support adoption failure more gracefully.
69408   // TODO(primiano): move all the existing use cases to the Connect(ConnArgs)
69409   // below. Also move the functionality of ConnectionFlags into ConnArgs.
69410   static std::unique_ptr<TracingService::ProducerEndpoint> Connect(
69411       const char* service_sock_name,
69412       Producer*,
69413       const std::string& producer_name,
69414       base::TaskRunner*,
69415       TracingService::ProducerSMBScrapingMode smb_scraping_mode =
69416           TracingService::ProducerSMBScrapingMode::kDefault,
69417       size_t shared_memory_size_hint_bytes = 0,
69418       size_t shared_memory_page_size_hint_bytes = 0,
69419       std::unique_ptr<SharedMemory> shm = nullptr,
69420       std::unique_ptr<SharedMemoryArbiter> shm_arbiter = nullptr,
69421       ConnectionFlags = ConnectionFlags::kDefault);
69422 
69423   // Overload of Connect() to support adopting a connected socket using
69424   // ipc::Client::ConnArgs.
69425   static std::unique_ptr<TracingService::ProducerEndpoint> Connect(
69426       ipc::Client::ConnArgs,
69427       Producer*,
69428       const std::string& producer_name,
69429       base::TaskRunner*,
69430       TracingService::ProducerSMBScrapingMode smb_scraping_mode =
69431           TracingService::ProducerSMBScrapingMode::kDefault,
69432       size_t shared_memory_size_hint_bytes = 0,
69433       size_t shared_memory_page_size_hint_bytes = 0,
69434       std::unique_ptr<SharedMemory> shm = nullptr,
69435       std::unique_ptr<SharedMemoryArbiter> shm_arbiter = nullptr);
69436 
69437  protected:
69438   ProducerIPCClient() = delete;
69439 };
69440 
69441 }  // namespace perfetto
69442 
69443 #endif  // INCLUDE_PERFETTO_EXT_TRACING_IPC_PRODUCER_IPC_CLIENT_H_
69444 /*
69445  * Copyright (C) 2017 The Android Open Source Project
69446  *
69447  * Licensed under the Apache License, Version 2.0 (the "License");
69448  * you may not use this file except in compliance with the License.
69449  * You may obtain a copy of the License at
69450  *
69451  *      http://www.apache.org/licenses/LICENSE-2.0
69452  *
69453  * Unless required by applicable law or agreed to in writing, software
69454  * distributed under the License is distributed on an "AS IS" BASIS,
69455  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
69456  * See the License for the specific language governing permissions and
69457  * limitations under the License.
69458  */
69459 
69460 #ifndef SRC_TRACING_IPC_PRODUCER_PRODUCER_IPC_CLIENT_IMPL_H_
69461 #define SRC_TRACING_IPC_PRODUCER_PRODUCER_IPC_CLIENT_IMPL_H_
69462 
69463 #include <stdint.h>
69464 
69465 #include <set>
69466 #include <vector>
69467 
69468 // gen_amalgamated expanded: #include "perfetto/ext/base/thread_checker.h"
69469 // gen_amalgamated expanded: #include "perfetto/ext/ipc/client.h"
69470 // gen_amalgamated expanded: #include "perfetto/ext/ipc/service_proxy.h"
69471 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/basic_types.h"
69472 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/shared_memory.h"
69473 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/tracing_service.h"
69474 // gen_amalgamated expanded: #include "perfetto/ext/tracing/ipc/producer_ipc_client.h"
69475 
69476 // gen_amalgamated expanded: #include "protos/perfetto/ipc/producer_port.ipc.h"
69477 
69478 namespace perfetto {
69479 
69480 namespace base {
69481 class TaskRunner;
69482 }  // namespace base
69483 
69484 class Producer;
69485 class SharedMemoryArbiter;
69486 
69487 // Exposes a Service endpoint to Producer(s), proxying all requests through a
69488 // IPC channel to the remote Service. This class is the glue layer between the
69489 // generic Service interface exposed to the clients of the library and the
69490 // actual IPC transport.
69491 class ProducerIPCClientImpl : public TracingService::ProducerEndpoint,
69492                               public ipc::ServiceProxy::EventListener {
69493  public:
69494   ProducerIPCClientImpl(ipc::Client::ConnArgs,
69495                         Producer*,
69496                         const std::string& producer_name,
69497                         base::TaskRunner*,
69498                         TracingService::ProducerSMBScrapingMode,
69499                         size_t shared_memory_size_hint_bytes,
69500                         size_t shared_memory_page_size_hint_bytes,
69501                         std::unique_ptr<SharedMemory> shm,
69502                         std::unique_ptr<SharedMemoryArbiter> shm_arbiter);
69503   ~ProducerIPCClientImpl() override;
69504 
69505   // TracingService::ProducerEndpoint implementation.
69506   // These methods are invoked by the actual Producer(s) code by clients of the
69507   // tracing library, which know nothing about the IPC transport.
69508   void RegisterDataSource(const DataSourceDescriptor&) override;
69509   void UpdateDataSource(const DataSourceDescriptor&) override;
69510   void UnregisterDataSource(const std::string& name) override;
69511   void RegisterTraceWriter(uint32_t writer_id, uint32_t target_buffer) override;
69512   void UnregisterTraceWriter(uint32_t writer_id) override;
69513   void CommitData(const CommitDataRequest&, CommitDataCallback) override;
69514   void NotifyDataSourceStarted(DataSourceInstanceID) override;
69515   void NotifyDataSourceStopped(DataSourceInstanceID) override;
69516   void ActivateTriggers(const std::vector<std::string>&) override;
69517   void Sync(std::function<void()> callback) override;
69518 
69519   std::unique_ptr<TraceWriter> CreateTraceWriter(
69520       BufferID target_buffer,
69521       BufferExhaustedPolicy) override;
69522   SharedMemoryArbiter* MaybeSharedMemoryArbiter() override;
69523   bool IsShmemProvidedByProducer() const override;
69524   void NotifyFlushComplete(FlushRequestID) override;
69525   SharedMemory* shared_memory() const override;
69526   size_t shared_buffer_page_size_kb() const override;
69527 
69528   // ipc::ServiceProxy::EventListener implementation.
69529   // These methods are invoked by the IPC layer, which knows nothing about
69530   // tracing, producers and consumers.
69531   void OnConnect() override;
69532   void OnDisconnect() override;
69533 
GetClientForTesting()69534   ipc::Client* GetClientForTesting() { return ipc_channel_.get(); }
69535 
69536  private:
69537   // Invoked soon after having established the connection with the service.
69538   void OnConnectionInitialized(bool connection_succeeded,
69539                                bool using_shmem_provided_by_producer,
69540                                bool direct_smb_patching_supported);
69541 
69542   // Invoked when the remote Service sends an IPC to tell us to do something
69543   // (e.g. start/stop a data source).
69544   void OnServiceRequest(const protos::gen::GetAsyncCommandResponse&);
69545 
69546   // TODO think to destruction order, do we rely on any specific dtor sequence?
69547   Producer* const producer_;
69548   base::TaskRunner* const task_runner_;
69549 
69550   // The object that owns the client socket and takes care of IPC traffic.
69551   std::unique_ptr<ipc::Client> ipc_channel_;
69552 
69553   // The proxy interface for the producer port of the service. It is bound
69554   // to |ipc_channel_| and (de)serializes method invocations over the wire.
69555   protos::gen::ProducerPortProxy producer_port_;
69556 
69557   std::unique_ptr<SharedMemory> shared_memory_;
69558   std::unique_ptr<SharedMemoryArbiter> shared_memory_arbiter_;
69559   size_t shared_buffer_page_size_kb_ = 0;
69560   std::set<DataSourceInstanceID> data_sources_setup_;
69561   bool connected_ = false;
69562   std::string const name_;
69563   size_t shared_memory_page_size_hint_bytes_ = 0;
69564   size_t shared_memory_size_hint_bytes_ = 0;
69565   TracingService::ProducerSMBScrapingMode const smb_scraping_mode_;
69566   bool is_shmem_provided_by_producer_ = false;
69567   bool direct_smb_patching_supported_ = false;
69568   std::vector<std::function<void()>> pending_sync_reqs_;
69569   PERFETTO_THREAD_CHECKER(thread_checker_)
69570 };
69571 
69572 }  // namespace perfetto
69573 
69574 #endif  // SRC_TRACING_IPC_PRODUCER_PRODUCER_IPC_CLIENT_IMPL_H_
69575 /*
69576  * Copyright (C) 2017 The Android Open Source Project
69577  *
69578  * Licensed under the Apache License, Version 2.0 (the "License");
69579  * you may not use this file except in compliance with the License.
69580  * You may obtain a copy of the License at
69581  *
69582  *      http://www.apache.org/licenses/LICENSE-2.0
69583  *
69584  * Unless required by applicable law or agreed to in writing, software
69585  * distributed under the License is distributed on an "AS IS" BASIS,
69586  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
69587  * See the License for the specific language governing permissions and
69588  * limitations under the License.
69589  */
69590 
69591 // gen_amalgamated expanded: #include "src/tracing/ipc/producer/producer_ipc_client_impl.h"
69592 
69593 #include <cinttypes>
69594 
69595 #include <string.h>
69596 
69597 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
69598 // gen_amalgamated expanded: #include "perfetto/base/task_runner.h"
69599 // gen_amalgamated expanded: #include "perfetto/ext/base/version.h"
69600 // gen_amalgamated expanded: #include "perfetto/ext/ipc/client.h"
69601 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/commit_data_request.h"
69602 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/producer.h"
69603 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/shared_memory_arbiter.h"
69604 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/trace_writer.h"
69605 // gen_amalgamated expanded: #include "perfetto/tracing/core/data_source_config.h"
69606 // gen_amalgamated expanded: #include "perfetto/tracing/core/data_source_descriptor.h"
69607 // gen_amalgamated expanded: #include "perfetto/tracing/core/trace_config.h"
69608 
69609 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
69610 // gen_amalgamated expanded: #include "src/tracing/ipc/shared_memory_windows.h"
69611 #else
69612 // gen_amalgamated expanded: #include "src/tracing/ipc/posix_shared_memory.h"
69613 #endif
69614 
69615 // TODO(fmayer): think to what happens when ProducerIPCClientImpl gets destroyed
69616 // w.r.t. the Producer pointer. Also think to lifetime of the Producer* during
69617 // the callbacks.
69618 
69619 namespace perfetto {
69620 
69621 // 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)69622 std::unique_ptr<TracingService::ProducerEndpoint> ProducerIPCClient::Connect(
69623     const char* service_sock_name,
69624     Producer* producer,
69625     const std::string& producer_name,
69626     base::TaskRunner* task_runner,
69627     TracingService::ProducerSMBScrapingMode smb_scraping_mode,
69628     size_t shared_memory_size_hint_bytes,
69629     size_t shared_memory_page_size_hint_bytes,
69630     std::unique_ptr<SharedMemory> shm,
69631     std::unique_ptr<SharedMemoryArbiter> shm_arbiter,
69632     ConnectionFlags conn_flags) {
69633   return std::unique_ptr<TracingService::ProducerEndpoint>(
69634       new ProducerIPCClientImpl(
69635           {service_sock_name,
69636            conn_flags ==
69637                ProducerIPCClient::ConnectionFlags::kRetryIfUnreachable},
69638           producer, producer_name, task_runner, smb_scraping_mode,
69639           shared_memory_size_hint_bytes, shared_memory_page_size_hint_bytes,
69640           std::move(shm), std::move(shm_arbiter)));
69641 }
69642 
69643 // 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)69644 std::unique_ptr<TracingService::ProducerEndpoint> ProducerIPCClient::Connect(
69645     ipc::Client::ConnArgs conn_args,
69646     Producer* producer,
69647     const std::string& producer_name,
69648     base::TaskRunner* task_runner,
69649     TracingService::ProducerSMBScrapingMode smb_scraping_mode,
69650     size_t shared_memory_size_hint_bytes,
69651     size_t shared_memory_page_size_hint_bytes,
69652     std::unique_ptr<SharedMemory> shm,
69653     std::unique_ptr<SharedMemoryArbiter> shm_arbiter) {
69654   return std::unique_ptr<TracingService::ProducerEndpoint>(
69655       new ProducerIPCClientImpl(std::move(conn_args), producer, producer_name,
69656                                 task_runner, smb_scraping_mode,
69657                                 shared_memory_size_hint_bytes,
69658                                 shared_memory_page_size_hint_bytes,
69659                                 std::move(shm), std::move(shm_arbiter)));
69660 }
69661 
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)69662 ProducerIPCClientImpl::ProducerIPCClientImpl(
69663     ipc::Client::ConnArgs conn_args,
69664     Producer* producer,
69665     const std::string& producer_name,
69666     base::TaskRunner* task_runner,
69667     TracingService::ProducerSMBScrapingMode smb_scraping_mode,
69668     size_t shared_memory_size_hint_bytes,
69669     size_t shared_memory_page_size_hint_bytes,
69670     std::unique_ptr<SharedMemory> shm,
69671     std::unique_ptr<SharedMemoryArbiter> shm_arbiter)
69672     : producer_(producer),
69673       task_runner_(task_runner),
69674       ipc_channel_(
69675           ipc::Client::CreateInstance(std::move(conn_args), task_runner)),
69676       producer_port_(this /* event_listener */),
69677       shared_memory_(std::move(shm)),
69678       shared_memory_arbiter_(std::move(shm_arbiter)),
69679       name_(producer_name),
69680       shared_memory_page_size_hint_bytes_(shared_memory_page_size_hint_bytes),
69681       shared_memory_size_hint_bytes_(shared_memory_size_hint_bytes),
69682       smb_scraping_mode_(smb_scraping_mode) {
69683   // Check for producer-provided SMB (used by Chrome for startup tracing).
69684   if (shared_memory_) {
69685     // We also expect a valid (unbound) arbiter. Bind it to this endpoint now.
69686     PERFETTO_CHECK(shared_memory_arbiter_);
69687     shared_memory_arbiter_->BindToProducerEndpoint(this, task_runner_);
69688 
69689     // If the service accepts our SMB, then it must match our requested page
69690     // layout. The protocol doesn't allow the service to change the size and
69691     // layout when the SMB is provided by the producer.
69692     shared_buffer_page_size_kb_ = shared_memory_page_size_hint_bytes_ / 1024;
69693   }
69694 
69695   ipc_channel_->BindService(producer_port_.GetWeakPtr());
69696   PERFETTO_DCHECK_THREAD(thread_checker_);
69697 }
69698 
~ProducerIPCClientImpl()69699 ProducerIPCClientImpl::~ProducerIPCClientImpl() {
69700   PERFETTO_DCHECK_THREAD(thread_checker_);
69701 }
69702 
69703 // Called by the IPC layer if the BindService() succeeds.
OnConnect()69704 void ProducerIPCClientImpl::OnConnect() {
69705   PERFETTO_DCHECK_THREAD(thread_checker_);
69706   connected_ = true;
69707 
69708   // The IPC layer guarantees that any outstanding callback will be dropped on
69709   // the floor if producer_port_ is destroyed between the request and the reply.
69710   // Binding |this| is hence safe.
69711   ipc::Deferred<protos::gen::InitializeConnectionResponse> on_init;
69712   on_init.Bind(
69713       [this](ipc::AsyncResult<protos::gen::InitializeConnectionResponse> resp) {
69714         OnConnectionInitialized(
69715             resp.success(),
69716             resp.success() ? resp->using_shmem_provided_by_producer() : false,
69717             resp.success() ? resp->direct_smb_patching_supported() : false);
69718       });
69719   protos::gen::InitializeConnectionRequest req;
69720   req.set_producer_name(name_);
69721   req.set_shared_memory_size_hint_bytes(
69722       static_cast<uint32_t>(shared_memory_size_hint_bytes_));
69723   req.set_shared_memory_page_size_hint_bytes(
69724       static_cast<uint32_t>(shared_memory_page_size_hint_bytes_));
69725   switch (smb_scraping_mode_) {
69726     case TracingService::ProducerSMBScrapingMode::kDefault:
69727       // No need to set the mode, it defaults to use the service default if
69728       // unspecified.
69729       break;
69730     case TracingService::ProducerSMBScrapingMode::kEnabled:
69731       req.set_smb_scraping_mode(
69732           protos::gen::InitializeConnectionRequest::SMB_SCRAPING_ENABLED);
69733       break;
69734     case TracingService::ProducerSMBScrapingMode::kDisabled:
69735       req.set_smb_scraping_mode(
69736           protos::gen::InitializeConnectionRequest::SMB_SCRAPING_DISABLED);
69737       break;
69738   }
69739 
69740   int shm_fd = -1;
69741   if (shared_memory_) {
69742     req.set_producer_provided_shmem(true);
69743 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
69744     auto key = static_cast<SharedMemoryWindows*>(shared_memory_.get())->key();
69745     req.set_shm_key_windows(key);
69746 #else
69747     shm_fd = static_cast<PosixSharedMemory*>(shared_memory_.get())->fd();
69748 #endif
69749   }
69750 
69751   req.set_sdk_version(base::GetVersionString());
69752   producer_port_.InitializeConnection(req, std::move(on_init), shm_fd);
69753 
69754   // Create the back channel to receive commands from the Service.
69755   ipc::Deferred<protos::gen::GetAsyncCommandResponse> on_cmd;
69756   on_cmd.Bind(
69757       [this](ipc::AsyncResult<protos::gen::GetAsyncCommandResponse> resp) {
69758         if (!resp)
69759           return;  // The IPC channel was closed and |resp| was auto-rejected.
69760         OnServiceRequest(*resp);
69761       });
69762   producer_port_.GetAsyncCommand(protos::gen::GetAsyncCommandRequest(),
69763                                  std::move(on_cmd));
69764 
69765   // If there are pending Sync() requests, send them now.
69766   for (const auto& pending_sync : pending_sync_reqs_)
69767     Sync(std::move(pending_sync));
69768   pending_sync_reqs_.clear();
69769 }
69770 
OnDisconnect()69771 void ProducerIPCClientImpl::OnDisconnect() {
69772   PERFETTO_DCHECK_THREAD(thread_checker_);
69773   PERFETTO_DLOG("Tracing service connection failure");
69774   connected_ = false;
69775   data_sources_setup_.clear();
69776   producer_->OnDisconnect();  // Note: may delete |this|.
69777 }
69778 
OnConnectionInitialized(bool connection_succeeded,bool using_shmem_provided_by_producer,bool direct_smb_patching_supported)69779 void ProducerIPCClientImpl::OnConnectionInitialized(
69780     bool connection_succeeded,
69781     bool using_shmem_provided_by_producer,
69782     bool direct_smb_patching_supported) {
69783   PERFETTO_DCHECK_THREAD(thread_checker_);
69784   // If connection_succeeded == false, the OnDisconnect() call will follow next
69785   // and there we'll notify the |producer_|. TODO: add a test for this.
69786   if (!connection_succeeded)
69787     return;
69788   is_shmem_provided_by_producer_ = using_shmem_provided_by_producer;
69789   direct_smb_patching_supported_ = direct_smb_patching_supported;
69790   producer_->OnConnect();
69791 
69792   // Bail out if the service failed to adopt our producer-allocated SMB.
69793   // TODO(eseckler): Handle adoption failure more gracefully.
69794   if (shared_memory_ && !is_shmem_provided_by_producer_) {
69795     PERFETTO_DLOG("Service failed adopt producer-provided SMB, disconnecting.");
69796     ipc_channel_.reset();
69797     return;
69798   }
69799 }
69800 
OnServiceRequest(const protos::gen::GetAsyncCommandResponse & cmd)69801 void ProducerIPCClientImpl::OnServiceRequest(
69802     const protos::gen::GetAsyncCommandResponse& cmd) {
69803   PERFETTO_DCHECK_THREAD(thread_checker_);
69804 
69805   // This message is sent only when connecting to a service running Android Q+.
69806   // See comment below in kStartDataSource.
69807   if (cmd.has_setup_data_source()) {
69808     const auto& req = cmd.setup_data_source();
69809     const DataSourceInstanceID dsid = req.new_instance_id();
69810     data_sources_setup_.insert(dsid);
69811     producer_->SetupDataSource(dsid, req.config());
69812     return;
69813   }
69814 
69815   if (cmd.has_start_data_source()) {
69816     const auto& req = cmd.start_data_source();
69817     const DataSourceInstanceID dsid = req.new_instance_id();
69818     const DataSourceConfig& cfg = req.config();
69819     if (!data_sources_setup_.count(dsid)) {
69820       // When connecting with an older (Android P) service, the service will not
69821       // send a SetupDataSource message. We synthesize it here in that case.
69822       producer_->SetupDataSource(dsid, cfg);
69823     }
69824     producer_->StartDataSource(dsid, cfg);
69825     return;
69826   }
69827 
69828   if (cmd.has_stop_data_source()) {
69829     const DataSourceInstanceID dsid = cmd.stop_data_source().instance_id();
69830     producer_->StopDataSource(dsid);
69831     data_sources_setup_.erase(dsid);
69832     return;
69833   }
69834 
69835   if (cmd.has_setup_tracing()) {
69836     std::unique_ptr<SharedMemory> ipc_shared_memory;
69837 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
69838     const std::string& shm_key = cmd.setup_tracing().shm_key_windows();
69839     if (!shm_key.empty())
69840       ipc_shared_memory = SharedMemoryWindows::Attach(shm_key);
69841 #else
69842     base::ScopedFile shmem_fd = ipc_channel_->TakeReceivedFD();
69843     if (shmem_fd) {
69844       // TODO(primiano): handle mmap failure in case of OOM.
69845       ipc_shared_memory =
69846           PosixSharedMemory::AttachToFd(std::move(shmem_fd),
69847                                         /*require_seals_if_supported=*/false);
69848     }
69849 #endif
69850     if (ipc_shared_memory) {
69851       // This is the nominal case used in most configurations, where the service
69852       // provides the SMB.
69853       PERFETTO_CHECK(!is_shmem_provided_by_producer_ && !shared_memory_);
69854       shared_memory_ = std::move(ipc_shared_memory);
69855       shared_buffer_page_size_kb_ =
69856           cmd.setup_tracing().shared_buffer_page_size_kb();
69857       shared_memory_arbiter_ = SharedMemoryArbiter::CreateInstance(
69858           shared_memory_.get(), shared_buffer_page_size_kb_ * 1024, this,
69859           task_runner_);
69860       if (direct_smb_patching_supported_)
69861         shared_memory_arbiter_->SetDirectSMBPatchingSupportedByService();
69862     } else {
69863       // Producer-provided SMB (used by Chrome for startup tracing).
69864       PERFETTO_CHECK(is_shmem_provided_by_producer_ && shared_memory_ &&
69865                      shared_memory_arbiter_);
69866     }
69867     producer_->OnTracingSetup();
69868     return;
69869   }
69870 
69871   if (cmd.has_flush()) {
69872     // This cast boilerplate is required only because protobuf uses its own
69873     // uint64 and not stdint's uint64_t. On some 64 bit archs they differ on the
69874     // type (long vs long long) even though they have the same size.
69875     const auto* data_source_ids = cmd.flush().data_source_ids().data();
69876     static_assert(sizeof(data_source_ids[0]) == sizeof(DataSourceInstanceID),
69877                   "data_source_ids should be 64-bit");
69878     producer_->Flush(
69879         cmd.flush().request_id(),
69880         reinterpret_cast<const DataSourceInstanceID*>(data_source_ids),
69881         static_cast<size_t>(cmd.flush().data_source_ids().size()));
69882     return;
69883   }
69884 
69885   if (cmd.has_clear_incremental_state()) {
69886     const auto* data_source_ids =
69887         cmd.clear_incremental_state().data_source_ids().data();
69888     static_assert(sizeof(data_source_ids[0]) == sizeof(DataSourceInstanceID),
69889                   "data_source_ids should be 64-bit");
69890     producer_->ClearIncrementalState(
69891         reinterpret_cast<const DataSourceInstanceID*>(data_source_ids),
69892         static_cast<size_t>(
69893             cmd.clear_incremental_state().data_source_ids().size()));
69894     return;
69895   }
69896 
69897   PERFETTO_DFATAL("Unknown async request received from tracing service");
69898 }
69899 
RegisterDataSource(const DataSourceDescriptor & descriptor)69900 void ProducerIPCClientImpl::RegisterDataSource(
69901     const DataSourceDescriptor& descriptor) {
69902   PERFETTO_DCHECK_THREAD(thread_checker_);
69903   if (!connected_) {
69904     PERFETTO_DLOG(
69905         "Cannot RegisterDataSource(), not connected to tracing service");
69906   }
69907   protos::gen::RegisterDataSourceRequest req;
69908   *req.mutable_data_source_descriptor() = descriptor;
69909   ipc::Deferred<protos::gen::RegisterDataSourceResponse> async_response;
69910   async_response.Bind(
69911       [](ipc::AsyncResult<protos::gen::RegisterDataSourceResponse> response) {
69912         if (!response)
69913           PERFETTO_DLOG("RegisterDataSource() failed: connection reset");
69914       });
69915   producer_port_.RegisterDataSource(req, std::move(async_response));
69916 }
69917 
UpdateDataSource(const DataSourceDescriptor & descriptor)69918 void ProducerIPCClientImpl::UpdateDataSource(
69919     const DataSourceDescriptor& descriptor) {
69920   PERFETTO_DCHECK_THREAD(thread_checker_);
69921   if (!connected_) {
69922     PERFETTO_DLOG(
69923         "Cannot UpdateDataSource(), not connected to tracing service");
69924   }
69925   protos::gen::UpdateDataSourceRequest req;
69926   *req.mutable_data_source_descriptor() = descriptor;
69927   ipc::Deferred<protos::gen::UpdateDataSourceResponse> async_response;
69928   async_response.Bind(
69929       [](ipc::AsyncResult<protos::gen::UpdateDataSourceResponse> response) {
69930         if (!response)
69931           PERFETTO_DLOG("UpdateDataSource() failed: connection reset");
69932       });
69933   producer_port_.UpdateDataSource(req, std::move(async_response));
69934 }
69935 
UnregisterDataSource(const std::string & name)69936 void ProducerIPCClientImpl::UnregisterDataSource(const std::string& name) {
69937   PERFETTO_DCHECK_THREAD(thread_checker_);
69938   if (!connected_) {
69939     PERFETTO_DLOG(
69940         "Cannot UnregisterDataSource(), not connected to tracing service");
69941     return;
69942   }
69943   protos::gen::UnregisterDataSourceRequest req;
69944   req.set_data_source_name(name);
69945   producer_port_.UnregisterDataSource(
69946       req, ipc::Deferred<protos::gen::UnregisterDataSourceResponse>());
69947 }
69948 
RegisterTraceWriter(uint32_t writer_id,uint32_t target_buffer)69949 void ProducerIPCClientImpl::RegisterTraceWriter(uint32_t writer_id,
69950                                                 uint32_t target_buffer) {
69951   PERFETTO_DCHECK_THREAD(thread_checker_);
69952   if (!connected_) {
69953     PERFETTO_DLOG(
69954         "Cannot RegisterTraceWriter(), not connected to tracing service");
69955     return;
69956   }
69957   protos::gen::RegisterTraceWriterRequest req;
69958   req.set_trace_writer_id(writer_id);
69959   req.set_target_buffer(target_buffer);
69960   producer_port_.RegisterTraceWriter(
69961       req, ipc::Deferred<protos::gen::RegisterTraceWriterResponse>());
69962 }
69963 
UnregisterTraceWriter(uint32_t writer_id)69964 void ProducerIPCClientImpl::UnregisterTraceWriter(uint32_t writer_id) {
69965   PERFETTO_DCHECK_THREAD(thread_checker_);
69966   if (!connected_) {
69967     PERFETTO_DLOG(
69968         "Cannot UnregisterTraceWriter(), not connected to tracing service");
69969     return;
69970   }
69971   protos::gen::UnregisterTraceWriterRequest req;
69972   req.set_trace_writer_id(writer_id);
69973   producer_port_.UnregisterTraceWriter(
69974       req, ipc::Deferred<protos::gen::UnregisterTraceWriterResponse>());
69975 }
69976 
CommitData(const CommitDataRequest & req,CommitDataCallback callback)69977 void ProducerIPCClientImpl::CommitData(const CommitDataRequest& req,
69978                                        CommitDataCallback callback) {
69979   PERFETTO_DCHECK_THREAD(thread_checker_);
69980   if (!connected_) {
69981     PERFETTO_DLOG("Cannot CommitData(), not connected to tracing service");
69982     return;
69983   }
69984   ipc::Deferred<protos::gen::CommitDataResponse> async_response;
69985   // TODO(primiano): add a test that destroys ProducerIPCClientImpl soon after
69986   // this call and checks that the callback is dropped.
69987   if (callback) {
69988     async_response.Bind(
69989         [callback](ipc::AsyncResult<protos::gen::CommitDataResponse> response) {
69990           if (!response) {
69991             PERFETTO_DLOG("CommitData() failed: connection reset");
69992             return;
69993           }
69994           callback();
69995         });
69996   }
69997   producer_port_.CommitData(req, std::move(async_response));
69998 }
69999 
NotifyDataSourceStarted(DataSourceInstanceID id)70000 void ProducerIPCClientImpl::NotifyDataSourceStarted(DataSourceInstanceID id) {
70001   PERFETTO_DCHECK_THREAD(thread_checker_);
70002   if (!connected_) {
70003     PERFETTO_DLOG(
70004         "Cannot NotifyDataSourceStarted(), not connected to tracing service");
70005     return;
70006   }
70007   protos::gen::NotifyDataSourceStartedRequest req;
70008   req.set_data_source_id(id);
70009   producer_port_.NotifyDataSourceStarted(
70010       req, ipc::Deferred<protos::gen::NotifyDataSourceStartedResponse>());
70011 }
70012 
NotifyDataSourceStopped(DataSourceInstanceID id)70013 void ProducerIPCClientImpl::NotifyDataSourceStopped(DataSourceInstanceID id) {
70014   PERFETTO_DCHECK_THREAD(thread_checker_);
70015   if (!connected_) {
70016     PERFETTO_DLOG(
70017         "Cannot NotifyDataSourceStopped(), not connected to tracing service");
70018     return;
70019   }
70020   protos::gen::NotifyDataSourceStoppedRequest req;
70021   req.set_data_source_id(id);
70022   producer_port_.NotifyDataSourceStopped(
70023       req, ipc::Deferred<protos::gen::NotifyDataSourceStoppedResponse>());
70024 }
70025 
ActivateTriggers(const std::vector<std::string> & triggers)70026 void ProducerIPCClientImpl::ActivateTriggers(
70027     const std::vector<std::string>& triggers) {
70028   PERFETTO_DCHECK_THREAD(thread_checker_);
70029   if (!connected_) {
70030     PERFETTO_DLOG(
70031         "Cannot ActivateTriggers(), not connected to tracing service");
70032     return;
70033   }
70034   protos::gen::ActivateTriggersRequest proto_req;
70035   for (const auto& name : triggers) {
70036     *proto_req.add_trigger_names() = name;
70037   }
70038   producer_port_.ActivateTriggers(
70039       proto_req, ipc::Deferred<protos::gen::ActivateTriggersResponse>());
70040 }
70041 
Sync(std::function<void ()> callback)70042 void ProducerIPCClientImpl::Sync(std::function<void()> callback) {
70043   PERFETTO_DCHECK_THREAD(thread_checker_);
70044   if (!connected_) {
70045     pending_sync_reqs_.emplace_back(std::move(callback));
70046     return;
70047   }
70048   ipc::Deferred<protos::gen::SyncResponse> resp;
70049   resp.Bind([callback](ipc::AsyncResult<protos::gen::SyncResponse>) {
70050     // Here we ACK the callback even if the service replies with a failure
70051     // (i.e. the service is too old and doesn't understand Sync()). In that
70052     // case the service has still seen the request, the IPC roundtrip is
70053     // still a (weaker) linearization fence.
70054     callback();
70055   });
70056   producer_port_.Sync(protos::gen::SyncRequest(), std::move(resp));
70057 }
70058 
CreateTraceWriter(BufferID target_buffer,BufferExhaustedPolicy buffer_exhausted_policy)70059 std::unique_ptr<TraceWriter> ProducerIPCClientImpl::CreateTraceWriter(
70060     BufferID target_buffer,
70061     BufferExhaustedPolicy buffer_exhausted_policy) {
70062   // This method can be called by different threads. |shared_memory_arbiter_| is
70063   // thread-safe but be aware of accessing any other state in this function.
70064   return shared_memory_arbiter_->CreateTraceWriter(target_buffer,
70065                                                    buffer_exhausted_policy);
70066 }
70067 
MaybeSharedMemoryArbiter()70068 SharedMemoryArbiter* ProducerIPCClientImpl::MaybeSharedMemoryArbiter() {
70069   return shared_memory_arbiter_.get();
70070 }
70071 
IsShmemProvidedByProducer() const70072 bool ProducerIPCClientImpl::IsShmemProvidedByProducer() const {
70073   return is_shmem_provided_by_producer_;
70074 }
70075 
NotifyFlushComplete(FlushRequestID req_id)70076 void ProducerIPCClientImpl::NotifyFlushComplete(FlushRequestID req_id) {
70077   return shared_memory_arbiter_->NotifyFlushComplete(req_id);
70078 }
70079 
shared_memory() const70080 SharedMemory* ProducerIPCClientImpl::shared_memory() const {
70081   return shared_memory_.get();
70082 }
70083 
shared_buffer_page_size_kb() const70084 size_t ProducerIPCClientImpl::shared_buffer_page_size_kb() const {
70085   return shared_buffer_page_size_kb_;
70086 }
70087 
70088 }  // namespace perfetto
70089 // gen_amalgamated begin source: src/tracing/ipc/service/consumer_ipc_service.cc
70090 // gen_amalgamated begin header: src/tracing/ipc/service/consumer_ipc_service.h
70091 /*
70092  * Copyright (C) 2017 The Android Open Source Project
70093  *
70094  * Licensed under the Apache License, Version 2.0 (the "License");
70095  * you may not use this file except in compliance with the License.
70096  * You may obtain a copy of the License at
70097  *
70098  *      http://www.apache.org/licenses/LICENSE-2.0
70099  *
70100  * Unless required by applicable law or agreed to in writing, software
70101  * distributed under the License is distributed on an "AS IS" BASIS,
70102  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
70103  * See the License for the specific language governing permissions and
70104  * limitations under the License.
70105  */
70106 
70107 #ifndef SRC_TRACING_IPC_SERVICE_CONSUMER_IPC_SERVICE_H_
70108 #define SRC_TRACING_IPC_SERVICE_CONSUMER_IPC_SERVICE_H_
70109 
70110 #include <list>
70111 #include <map>
70112 #include <memory>
70113 #include <string>
70114 
70115 // gen_amalgamated expanded: #include "perfetto/ext/base/weak_ptr.h"
70116 // gen_amalgamated expanded: #include "perfetto/ext/ipc/basic_types.h"
70117 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/consumer.h"
70118 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/tracing_service.h"
70119 // gen_amalgamated expanded: #include "perfetto/tracing/core/forward_decls.h"
70120 // gen_amalgamated expanded: #include "protos/perfetto/ipc/consumer_port.ipc.h"
70121 
70122 namespace perfetto {
70123 
70124 namespace ipc {
70125 class Host;
70126 }  // namespace ipc
70127 
70128 // Implements the Consumer port of the IPC service. This class proxies requests
70129 // and responses between the core service logic (|svc_|) and remote Consumer(s)
70130 // on the IPC socket, through the methods overriddden from ConsumerPort.
70131 class ConsumerIPCService : public protos::gen::ConsumerPort {
70132  public:
70133   explicit ConsumerIPCService(TracingService* core_service);
70134   ~ConsumerIPCService() override;
70135 
70136   // ConsumerPort implementation (from .proto IPC definition).
70137   void EnableTracing(const protos::gen::EnableTracingRequest&,
70138                      DeferredEnableTracingResponse) override;
70139   void StartTracing(const protos::gen::StartTracingRequest&,
70140                     DeferredStartTracingResponse) override;
70141   void ChangeTraceConfig(const protos::gen::ChangeTraceConfigRequest&,
70142                          DeferredChangeTraceConfigResponse) override;
70143   void DisableTracing(const protos::gen::DisableTracingRequest&,
70144                       DeferredDisableTracingResponse) override;
70145   void ReadBuffers(const protos::gen::ReadBuffersRequest&,
70146                    DeferredReadBuffersResponse) override;
70147   void FreeBuffers(const protos::gen::FreeBuffersRequest&,
70148                    DeferredFreeBuffersResponse) override;
70149   void Flush(const protos::gen::FlushRequest&, DeferredFlushResponse) override;
70150   void Detach(const protos::gen::DetachRequest&,
70151               DeferredDetachResponse) override;
70152   void Attach(const protos::gen::AttachRequest&,
70153               DeferredAttachResponse) override;
70154   void GetTraceStats(const protos::gen::GetTraceStatsRequest&,
70155                      DeferredGetTraceStatsResponse) override;
70156   void ObserveEvents(const protos::gen::ObserveEventsRequest&,
70157                      DeferredObserveEventsResponse) override;
70158   void QueryServiceState(const protos::gen::QueryServiceStateRequest&,
70159                          DeferredQueryServiceStateResponse) override;
70160   void QueryCapabilities(const protos::gen::QueryCapabilitiesRequest&,
70161                          DeferredQueryCapabilitiesResponse) override;
70162   void SaveTraceForBugreport(const protos::gen::SaveTraceForBugreportRequest&,
70163                              DeferredSaveTraceForBugreportResponse) override;
70164   void OnClientDisconnected() override;
70165 
70166  private:
70167   // Acts like a Consumer with the core Service business logic (which doesn't
70168   // know anything about the remote transport), but all it does is proxying
70169   // methods to the remote Consumer on the other side of the IPC channel.
70170   class RemoteConsumer : public Consumer {
70171    public:
70172     RemoteConsumer();
70173     ~RemoteConsumer() override;
70174 
70175     // These methods are called by the |core_service_| business logic. There is
70176     // no connection here, these methods are posted straight away.
70177     void OnConnect() override;
70178     void OnDisconnect() override;
70179     void OnTracingDisabled(const std::string& error) override;
70180     void OnTraceData(std::vector<TracePacket>, bool has_more) override;
70181     void OnDetach(bool) override;
70182     void OnAttach(bool, const TraceConfig&) override;
70183     void OnTraceStats(bool, const TraceStats&) override;
70184     void OnObservableEvents(const ObservableEvents&) override;
70185 
70186     void CloseObserveEventsResponseStream();
70187 
70188     // The interface obtained from the core service business logic through
70189     // TracingService::ConnectConsumer(this). This allows to invoke methods for
70190     // a specific Consumer on the Service business logic.
70191     std::unique_ptr<TracingService::ConsumerEndpoint> service_endpoint;
70192 
70193     // After ReadBuffers() is invoked, this binds the async callback that
70194     // allows to stream trace packets back to the client.
70195     DeferredReadBuffersResponse read_buffers_response;
70196 
70197     // After EnableTracing() is invoked, this binds the async callback that
70198     // allows to send the OnTracingDisabled notification.
70199     DeferredEnableTracingResponse enable_tracing_response;
70200 
70201     // After Detach() is invoked, this binds the async callback that allows to
70202     // send the session id to the consumer.
70203     DeferredDetachResponse detach_response;
70204 
70205     // As above, but for the Attach() case.
70206     DeferredAttachResponse attach_response;
70207 
70208     // As above, but for GetTraceStats().
70209     DeferredGetTraceStatsResponse get_trace_stats_response;
70210 
70211     // After ObserveEvents() is invoked, this binds the async callback that
70212     // allows to stream ObservableEvents back to the client.
70213     DeferredObserveEventsResponse observe_events_response;
70214   };
70215 
70216   // This has to be a container that doesn't invalidate iterators.
70217   using PendingFlushResponses = std::list<DeferredFlushResponse>;
70218   using PendingQuerySvcResponses = std::list<DeferredQueryServiceStateResponse>;
70219   using PendingQueryCapabilitiesResponses =
70220       std::list<DeferredQueryCapabilitiesResponse>;
70221   using PendingSaveTraceForBugreportResponses =
70222       std::list<DeferredSaveTraceForBugreportResponse>;
70223 
70224   ConsumerIPCService(const ConsumerIPCService&) = delete;
70225   ConsumerIPCService& operator=(const ConsumerIPCService&) = delete;
70226 
70227   // Returns the ConsumerEndpoint in the core business logic that corresponds to
70228   // the current IPC request.
70229   RemoteConsumer* GetConsumerForCurrentRequest();
70230 
70231   void OnFlushCallback(bool success, PendingFlushResponses::iterator);
70232   void OnQueryServiceCallback(bool success,
70233                               const TracingServiceState&,
70234                               PendingQuerySvcResponses::iterator);
70235   void OnQueryCapabilitiesCallback(const TracingServiceCapabilities&,
70236                                    PendingQueryCapabilitiesResponses::iterator);
70237   void OnSaveTraceForBugreportCallback(
70238       bool success,
70239       const std::string& msg,
70240       PendingSaveTraceForBugreportResponses::iterator);
70241 
70242   TracingService* const core_service_;
70243 
70244   // Maps IPC clients to ConsumerEndpoint instances registered on the
70245   // |core_service_| business logic.
70246   std::map<ipc::ClientID, std::unique_ptr<RemoteConsumer>> consumers_;
70247 
70248   PendingFlushResponses pending_flush_responses_;
70249   PendingQuerySvcResponses pending_query_service_responses_;
70250   PendingQueryCapabilitiesResponses pending_query_capabilities_responses_;
70251   PendingSaveTraceForBugreportResponses pending_bugreport_responses_;
70252 
70253   base::WeakPtrFactory<ConsumerIPCService> weak_ptr_factory_;  // Keep last.
70254 };
70255 
70256 }  // namespace perfetto
70257 
70258 #endif  // SRC_TRACING_IPC_SERVICE_CONSUMER_IPC_SERVICE_H_
70259 /*
70260  * Copyright (C) 2017 The Android Open Source Project
70261  *
70262  * Licensed under the Apache License, Version 2.0 (the "License");
70263  * you may not use this file except in compliance with the License.
70264  * You may obtain a copy of the License at
70265  *
70266  *      http://www.apache.org/licenses/LICENSE-2.0
70267  *
70268  * Unless required by applicable law or agreed to in writing, software
70269  * distributed under the License is distributed on an "AS IS" BASIS,
70270  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
70271  * See the License for the specific language governing permissions and
70272  * limitations under the License.
70273  */
70274 
70275 // gen_amalgamated expanded: #include "src/tracing/ipc/service/consumer_ipc_service.h"
70276 
70277 #include <cinttypes>
70278 
70279 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
70280 // gen_amalgamated expanded: #include "perfetto/base/task_runner.h"
70281 // gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"
70282 // gen_amalgamated expanded: #include "perfetto/ext/ipc/basic_types.h"
70283 // gen_amalgamated expanded: #include "perfetto/ext/ipc/host.h"
70284 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/shared_memory_abi.h"
70285 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/slice.h"
70286 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/trace_packet.h"
70287 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/trace_stats.h"
70288 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/tracing_service.h"
70289 // gen_amalgamated expanded: #include "perfetto/tracing/core/trace_config.h"
70290 // gen_amalgamated expanded: #include "perfetto/tracing/core/tracing_service_capabilities.h"
70291 // gen_amalgamated expanded: #include "perfetto/tracing/core/tracing_service_state.h"
70292 
70293 namespace perfetto {
70294 
ConsumerIPCService(TracingService * core_service)70295 ConsumerIPCService::ConsumerIPCService(TracingService* core_service)
70296     : core_service_(core_service), weak_ptr_factory_(this) {}
70297 
70298 ConsumerIPCService::~ConsumerIPCService() = default;
70299 
70300 ConsumerIPCService::RemoteConsumer*
GetConsumerForCurrentRequest()70301 ConsumerIPCService::GetConsumerForCurrentRequest() {
70302   const ipc::ClientID ipc_client_id = ipc::Service::client_info().client_id();
70303   const uid_t uid = ipc::Service::client_info().uid();
70304   PERFETTO_CHECK(ipc_client_id);
70305   auto it = consumers_.find(ipc_client_id);
70306   if (it == consumers_.end()) {
70307     auto* remote_consumer = new RemoteConsumer();
70308     consumers_[ipc_client_id].reset(remote_consumer);
70309     remote_consumer->service_endpoint =
70310         core_service_->ConnectConsumer(remote_consumer, uid);
70311     return remote_consumer;
70312   }
70313   return it->second.get();
70314 }
70315 
70316 // Called by the IPC layer.
OnClientDisconnected()70317 void ConsumerIPCService::OnClientDisconnected() {
70318   ipc::ClientID client_id = ipc::Service::client_info().client_id();
70319   consumers_.erase(client_id);
70320 }
70321 
70322 // Called by the IPC layer.
EnableTracing(const protos::gen::EnableTracingRequest & req,DeferredEnableTracingResponse resp)70323 void ConsumerIPCService::EnableTracing(
70324     const protos::gen::EnableTracingRequest& req,
70325     DeferredEnableTracingResponse resp) {
70326   RemoteConsumer* remote_consumer = GetConsumerForCurrentRequest();
70327   if (req.attach_notification_only()) {
70328     remote_consumer->enable_tracing_response = std::move(resp);
70329     return;
70330   }
70331   const TraceConfig& trace_config = req.trace_config();
70332   base::ScopedFile fd;
70333   if (trace_config.write_into_file() && trace_config.output_path().empty())
70334     fd = ipc::Service::TakeReceivedFD();
70335   remote_consumer->service_endpoint->EnableTracing(trace_config, std::move(fd));
70336   remote_consumer->enable_tracing_response = std::move(resp);
70337 }
70338 
70339 // Called by the IPC layer.
StartTracing(const protos::gen::StartTracingRequest &,DeferredStartTracingResponse resp)70340 void ConsumerIPCService::StartTracing(const protos::gen::StartTracingRequest&,
70341                                       DeferredStartTracingResponse resp) {
70342   RemoteConsumer* remote_consumer = GetConsumerForCurrentRequest();
70343   remote_consumer->service_endpoint->StartTracing();
70344   resp.Resolve(ipc::AsyncResult<protos::gen::StartTracingResponse>::Create());
70345 }
70346 
70347 // Called by the IPC layer.
ChangeTraceConfig(const protos::gen::ChangeTraceConfigRequest & req,DeferredChangeTraceConfigResponse resp)70348 void ConsumerIPCService::ChangeTraceConfig(
70349     const protos::gen::ChangeTraceConfigRequest& req,
70350     DeferredChangeTraceConfigResponse resp) {
70351   RemoteConsumer* remote_consumer = GetConsumerForCurrentRequest();
70352   remote_consumer->service_endpoint->ChangeTraceConfig(req.trace_config());
70353   resp.Resolve(
70354       ipc::AsyncResult<protos::gen::ChangeTraceConfigResponse>::Create());
70355 }
70356 
70357 // Called by the IPC layer.
DisableTracing(const protos::gen::DisableTracingRequest &,DeferredDisableTracingResponse resp)70358 void ConsumerIPCService::DisableTracing(
70359     const protos::gen::DisableTracingRequest&,
70360     DeferredDisableTracingResponse resp) {
70361   GetConsumerForCurrentRequest()->service_endpoint->DisableTracing();
70362   resp.Resolve(ipc::AsyncResult<protos::gen::DisableTracingResponse>::Create());
70363 }
70364 
70365 // Called by the IPC layer.
ReadBuffers(const protos::gen::ReadBuffersRequest &,DeferredReadBuffersResponse resp)70366 void ConsumerIPCService::ReadBuffers(const protos::gen::ReadBuffersRequest&,
70367                                      DeferredReadBuffersResponse resp) {
70368   RemoteConsumer* remote_consumer = GetConsumerForCurrentRequest();
70369   remote_consumer->read_buffers_response = std::move(resp);
70370   remote_consumer->service_endpoint->ReadBuffers();
70371 }
70372 
70373 // Called by the IPC layer.
FreeBuffers(const protos::gen::FreeBuffersRequest &,DeferredFreeBuffersResponse resp)70374 void ConsumerIPCService::FreeBuffers(const protos::gen::FreeBuffersRequest&,
70375                                      DeferredFreeBuffersResponse resp) {
70376   GetConsumerForCurrentRequest()->service_endpoint->FreeBuffers();
70377   resp.Resolve(ipc::AsyncResult<protos::gen::FreeBuffersResponse>::Create());
70378 }
70379 
70380 // Called by the IPC layer.
Flush(const protos::gen::FlushRequest & req,DeferredFlushResponse resp)70381 void ConsumerIPCService::Flush(const protos::gen::FlushRequest& req,
70382                                DeferredFlushResponse resp) {
70383   auto it = pending_flush_responses_.insert(pending_flush_responses_.end(),
70384                                             std::move(resp));
70385   auto weak_this = weak_ptr_factory_.GetWeakPtr();
70386   auto callback = [weak_this, it](bool success) {
70387     if (weak_this)
70388       weak_this->OnFlushCallback(success, std::move(it));
70389   };
70390   GetConsumerForCurrentRequest()->service_endpoint->Flush(req.timeout_ms(),
70391                                                           std::move(callback));
70392 }
70393 
70394 // Called by the IPC layer.
Detach(const protos::gen::DetachRequest & req,DeferredDetachResponse resp)70395 void ConsumerIPCService::Detach(const protos::gen::DetachRequest& req,
70396                                 DeferredDetachResponse resp) {
70397   // OnDetach() will resolve the |detach_response|.
70398   RemoteConsumer* remote_consumer = GetConsumerForCurrentRequest();
70399   remote_consumer->detach_response = std::move(resp);
70400   remote_consumer->service_endpoint->Detach(req.key());
70401 }
70402 
70403 // Called by the IPC layer.
Attach(const protos::gen::AttachRequest & req,DeferredAttachResponse resp)70404 void ConsumerIPCService::Attach(const protos::gen::AttachRequest& req,
70405                                 DeferredAttachResponse resp) {
70406   // OnAttach() will resolve the |attach_response|.
70407   RemoteConsumer* remote_consumer = GetConsumerForCurrentRequest();
70408   remote_consumer->attach_response = std::move(resp);
70409   remote_consumer->service_endpoint->Attach(req.key());
70410 }
70411 
70412 // Called by the IPC layer.
GetTraceStats(const protos::gen::GetTraceStatsRequest &,DeferredGetTraceStatsResponse resp)70413 void ConsumerIPCService::GetTraceStats(const protos::gen::GetTraceStatsRequest&,
70414                                        DeferredGetTraceStatsResponse resp) {
70415   // OnTraceStats() will resolve the |get_trace_stats_response|.
70416   RemoteConsumer* remote_consumer = GetConsumerForCurrentRequest();
70417   remote_consumer->get_trace_stats_response = std::move(resp);
70418   remote_consumer->service_endpoint->GetTraceStats();
70419 }
70420 
70421 // Called by the IPC layer.
ObserveEvents(const protos::gen::ObserveEventsRequest & req,DeferredObserveEventsResponse resp)70422 void ConsumerIPCService::ObserveEvents(
70423     const protos::gen::ObserveEventsRequest& req,
70424     DeferredObserveEventsResponse resp) {
70425   RemoteConsumer* remote_consumer = GetConsumerForCurrentRequest();
70426 
70427   // If there's a prior stream, close it so that client can clean it up.
70428   remote_consumer->CloseObserveEventsResponseStream();
70429 
70430   remote_consumer->observe_events_response = std::move(resp);
70431 
70432   uint32_t events_mask = 0;
70433   for (const auto& type : req.events_to_observe()) {
70434     events_mask |= static_cast<uint32_t>(type);
70435   }
70436   remote_consumer->service_endpoint->ObserveEvents(events_mask);
70437 
70438   // If no events are to be observed, close the stream immediately so that the
70439   // client can clean up.
70440   if (events_mask == 0)
70441     remote_consumer->CloseObserveEventsResponseStream();
70442 }
70443 
70444 // Called by the IPC layer.
QueryServiceState(const protos::gen::QueryServiceStateRequest &,DeferredQueryServiceStateResponse resp)70445 void ConsumerIPCService::QueryServiceState(
70446     const protos::gen::QueryServiceStateRequest&,
70447     DeferredQueryServiceStateResponse resp) {
70448   RemoteConsumer* remote_consumer = GetConsumerForCurrentRequest();
70449   auto it = pending_query_service_responses_.insert(
70450       pending_query_service_responses_.end(), std::move(resp));
70451   auto weak_this = weak_ptr_factory_.GetWeakPtr();
70452   auto callback = [weak_this, it](bool success,
70453                                   const TracingServiceState& svc_state) {
70454     if (weak_this)
70455       weak_this->OnQueryServiceCallback(success, svc_state, std::move(it));
70456   };
70457   remote_consumer->service_endpoint->QueryServiceState(callback);
70458 }
70459 
70460 // Called by the service in response to service_endpoint->QueryServiceState().
OnQueryServiceCallback(bool success,const TracingServiceState & svc_state,PendingQuerySvcResponses::iterator pending_response_it)70461 void ConsumerIPCService::OnQueryServiceCallback(
70462     bool success,
70463     const TracingServiceState& svc_state,
70464     PendingQuerySvcResponses::iterator pending_response_it) {
70465   DeferredQueryServiceStateResponse response(std::move(*pending_response_it));
70466   pending_query_service_responses_.erase(pending_response_it);
70467   if (!success) {
70468     response.Reject();
70469     return;
70470   }
70471 
70472   // The TracingServiceState object might be too big to fit into a single IPC
70473   // message because it contains the DataSourceDescriptor of each data source.
70474   // Here we split it in chunks to fit in the IPC limit, observing the
70475   // following rule: each chunk must be invididually a valid TracingServiceState
70476   // message; all the chunks concatenated together must form the original
70477   // message. This is to deal with the legacy API that was just sending one
70478   // whole message (failing in presence of too many data sources, b/153142114).
70479   // The message is split as follows: we take the whole TracingServiceState,
70480   // take out the data sources section (which is a top-level repeated field)
70481   // and re-add them one-by-one. If, in the process of appending, the IPC msg
70482   // size is reached, a new chunk is created. This assumes that the rest of
70483   // TracingServiceState fits in one IPC message and each DataSourceDescriptor
70484   // fits in the worst case in a dedicated message (which is true, because
70485   // otherwise the RegisterDataSource() which passes the descriptor in the first
70486   // place would fail).
70487 
70488   std::vector<uint8_t> chunked_reply;
70489 
70490   // Transmits the current chunk and starts a new one.
70491   bool sent_eof = false;
70492   auto send_chunked_reply = [&chunked_reply, &response,
70493                              &sent_eof](bool has_more) {
70494     PERFETTO_CHECK(!sent_eof);
70495     sent_eof = !has_more;
70496     auto resp =
70497         ipc::AsyncResult<protos::gen::QueryServiceStateResponse>::Create();
70498     resp.set_has_more(has_more);
70499     PERFETTO_CHECK(resp->mutable_service_state()->ParseFromArray(
70500         chunked_reply.data(), chunked_reply.size()));
70501     chunked_reply.clear();
70502     response.Resolve(std::move(resp));
70503   };
70504 
70505   // Create a copy of the whole response and cut away the data_sources section.
70506   protos::gen::TracingServiceState svc_state_copy = svc_state;
70507   auto data_sources = std::move(*svc_state_copy.mutable_data_sources());
70508   chunked_reply = svc_state_copy.SerializeAsArray();
70509 
70510   // Now re-add them fitting within the IPC message limits (- some margin for
70511   // the outer IPC frame).
70512   constexpr size_t kMaxMsgSize = ipc::kIPCBufferSize - 128;
70513   for (const auto& data_source : data_sources) {
70514     protos::gen::TracingServiceState tmp;
70515     tmp.mutable_data_sources()->emplace_back(std::move(data_source));
70516     std::vector<uint8_t> chunk = tmp.SerializeAsArray();
70517     if (chunked_reply.size() + chunk.size() < kMaxMsgSize) {
70518       chunked_reply.insert(chunked_reply.end(), chunk.begin(), chunk.end());
70519     } else {
70520       send_chunked_reply(/*has_more=*/true);
70521       chunked_reply = std::move(chunk);
70522     }
70523   }
70524 
70525   PERFETTO_DCHECK(!chunked_reply.empty());
70526   send_chunked_reply(/*has_more=*/false);
70527   PERFETTO_CHECK(sent_eof);
70528 }
70529 
70530 // Called by the service in response to a service_endpoint->Flush() request.
OnFlushCallback(bool success,PendingFlushResponses::iterator pending_response_it)70531 void ConsumerIPCService::OnFlushCallback(
70532     bool success,
70533     PendingFlushResponses::iterator pending_response_it) {
70534   DeferredFlushResponse response(std::move(*pending_response_it));
70535   pending_flush_responses_.erase(pending_response_it);
70536   if (success) {
70537     response.Resolve(ipc::AsyncResult<protos::gen::FlushResponse>::Create());
70538   } else {
70539     response.Reject();
70540   }
70541 }
70542 
QueryCapabilities(const protos::gen::QueryCapabilitiesRequest &,DeferredQueryCapabilitiesResponse resp)70543 void ConsumerIPCService::QueryCapabilities(
70544     const protos::gen::QueryCapabilitiesRequest&,
70545     DeferredQueryCapabilitiesResponse resp) {
70546   RemoteConsumer* remote_consumer = GetConsumerForCurrentRequest();
70547   auto it = pending_query_capabilities_responses_.insert(
70548       pending_query_capabilities_responses_.end(), std::move(resp));
70549   auto weak_this = weak_ptr_factory_.GetWeakPtr();
70550   auto callback = [weak_this, it](const TracingServiceCapabilities& caps) {
70551     if (weak_this)
70552       weak_this->OnQueryCapabilitiesCallback(caps, std::move(it));
70553   };
70554   remote_consumer->service_endpoint->QueryCapabilities(callback);
70555 }
70556 
70557 // Called by the service in response to service_endpoint->QueryCapabilities().
OnQueryCapabilitiesCallback(const TracingServiceCapabilities & caps,PendingQueryCapabilitiesResponses::iterator pending_response_it)70558 void ConsumerIPCService::OnQueryCapabilitiesCallback(
70559     const TracingServiceCapabilities& caps,
70560     PendingQueryCapabilitiesResponses::iterator pending_response_it) {
70561   DeferredQueryCapabilitiesResponse response(std::move(*pending_response_it));
70562   pending_query_capabilities_responses_.erase(pending_response_it);
70563   auto resp =
70564       ipc::AsyncResult<protos::gen::QueryCapabilitiesResponse>::Create();
70565   *resp->mutable_capabilities() = caps;
70566   response.Resolve(std::move(resp));
70567 }
70568 
SaveTraceForBugreport(const protos::gen::SaveTraceForBugreportRequest &,DeferredSaveTraceForBugreportResponse resp)70569 void ConsumerIPCService::SaveTraceForBugreport(
70570     const protos::gen::SaveTraceForBugreportRequest&,
70571     DeferredSaveTraceForBugreportResponse resp) {
70572   RemoteConsumer* remote_consumer = GetConsumerForCurrentRequest();
70573   auto it = pending_bugreport_responses_.insert(
70574       pending_bugreport_responses_.end(), std::move(resp));
70575   auto weak_this = weak_ptr_factory_.GetWeakPtr();
70576   auto callback = [weak_this, it](bool success, const std::string& msg) {
70577     if (weak_this)
70578       weak_this->OnSaveTraceForBugreportCallback(success, msg, std::move(it));
70579   };
70580   remote_consumer->service_endpoint->SaveTraceForBugreport(callback);
70581 }
70582 
70583 // Called by the service in response to
70584 // service_endpoint->SaveTraceForBugreport().
OnSaveTraceForBugreportCallback(bool success,const std::string & msg,PendingSaveTraceForBugreportResponses::iterator pending_response_it)70585 void ConsumerIPCService::OnSaveTraceForBugreportCallback(
70586     bool success,
70587     const std::string& msg,
70588     PendingSaveTraceForBugreportResponses::iterator pending_response_it) {
70589   DeferredSaveTraceForBugreportResponse response(
70590       std::move(*pending_response_it));
70591   pending_bugreport_responses_.erase(pending_response_it);
70592   auto resp =
70593       ipc::AsyncResult<protos::gen::SaveTraceForBugreportResponse>::Create();
70594   resp->set_success(success);
70595   resp->set_msg(msg);
70596   response.Resolve(std::move(resp));
70597 }
70598 
70599 ////////////////////////////////////////////////////////////////////////////////
70600 // RemoteConsumer methods
70601 ////////////////////////////////////////////////////////////////////////////////
70602 
70603 ConsumerIPCService::RemoteConsumer::RemoteConsumer() = default;
70604 ConsumerIPCService::RemoteConsumer::~RemoteConsumer() = default;
70605 
70606 // Invoked by the |core_service_| business logic after the ConnectConsumer()
70607 // call. There is nothing to do here, we really expected the ConnectConsumer()
70608 // to just work in the local case.
OnConnect()70609 void ConsumerIPCService::RemoteConsumer::OnConnect() {}
70610 
70611 // Invoked by the |core_service_| business logic after we destroy the
70612 // |service_endpoint| (in the RemoteConsumer dtor).
OnDisconnect()70613 void ConsumerIPCService::RemoteConsumer::OnDisconnect() {}
70614 
OnTracingDisabled(const std::string & error)70615 void ConsumerIPCService::RemoteConsumer::OnTracingDisabled(
70616     const std::string& error) {
70617   if (enable_tracing_response.IsBound()) {
70618     auto result =
70619         ipc::AsyncResult<protos::gen::EnableTracingResponse>::Create();
70620     result->set_disabled(true);
70621     if (!error.empty())
70622       result->set_error(error);
70623     enable_tracing_response.Resolve(std::move(result));
70624   }
70625 }
70626 
OnTraceData(std::vector<TracePacket> trace_packets,bool has_more)70627 void ConsumerIPCService::RemoteConsumer::OnTraceData(
70628     std::vector<TracePacket> trace_packets,
70629     bool has_more) {
70630   if (!read_buffers_response.IsBound())
70631     return;
70632 
70633   auto result = ipc::AsyncResult<protos::gen::ReadBuffersResponse>::Create();
70634 
70635   // A TracePacket might be too big to fit into a single IPC message (max
70636   // kIPCBufferSize). However a TracePacket is made of slices and each slice
70637   // is way smaller than kIPCBufferSize (a slice size is effectively bounded by
70638   // the max chunk size of the SharedMemoryABI). When sending a TracePacket,
70639   // if its slices don't fit within one IPC, chunk them over several contiguous
70640   // IPCs using the |last_slice_for_packet| for glueing on the other side.
70641   static_assert(ipc::kIPCBufferSize >= SharedMemoryABI::kMaxPageSize * 2,
70642                 "kIPCBufferSize too small given the max possible slice size");
70643 
70644   auto send_ipc_reply = [this, &result](bool more) {
70645     result.set_has_more(more);
70646     read_buffers_response.Resolve(std::move(result));
70647     result = ipc::AsyncResult<protos::gen::ReadBuffersResponse>::Create();
70648   };
70649 
70650   size_t approx_reply_size = 0;
70651   for (const TracePacket& trace_packet : trace_packets) {
70652     size_t num_slices_left_for_packet = trace_packet.slices().size();
70653     for (const Slice& slice : trace_packet.slices()) {
70654       // Check if this slice would cause the IPC to overflow its max size and,
70655       // if that is the case, split the IPCs. The "16" and "64" below are
70656       // over-estimations of, respectively:
70657       // 16: the preamble that prefixes each slice (there are 2 x size fields
70658       //     in the proto + the |last_slice_for_packet| bool).
70659       // 64: the overhead of the IPC InvokeMethodReply + wire_protocol's frame.
70660       // If these estimations are wrong, BufferedFrameDeserializer::Serialize()
70661       // will hit a DCHECK anyways.
70662       const size_t approx_slice_size = slice.size + 16;
70663       if (approx_reply_size + approx_slice_size > ipc::kIPCBufferSize - 64) {
70664         // If we hit this CHECK we got a single slice that is > kIPCBufferSize.
70665         PERFETTO_CHECK(result->slices_size() > 0);
70666         send_ipc_reply(/*has_more=*/true);
70667         approx_reply_size = 0;
70668       }
70669       approx_reply_size += approx_slice_size;
70670 
70671       auto* res_slice = result->add_slices();
70672       res_slice->set_last_slice_for_packet(--num_slices_left_for_packet == 0);
70673       res_slice->set_data(slice.start, slice.size);
70674     }
70675   }
70676   send_ipc_reply(has_more);
70677 }
70678 
OnDetach(bool success)70679 void ConsumerIPCService::RemoteConsumer::OnDetach(bool success) {
70680   if (!success) {
70681     std::move(detach_response).Reject();
70682     return;
70683   }
70684   auto resp = ipc::AsyncResult<protos::gen::DetachResponse>::Create();
70685   std::move(detach_response).Resolve(std::move(resp));
70686 }
70687 
OnAttach(bool success,const TraceConfig & trace_config)70688 void ConsumerIPCService::RemoteConsumer::OnAttach(
70689     bool success,
70690     const TraceConfig& trace_config) {
70691   if (!success) {
70692     std::move(attach_response).Reject();
70693     return;
70694   }
70695   auto response = ipc::AsyncResult<protos::gen::AttachResponse>::Create();
70696   *response->mutable_trace_config() = trace_config;
70697   std::move(attach_response).Resolve(std::move(response));
70698 }
70699 
OnTraceStats(bool success,const TraceStats & stats)70700 void ConsumerIPCService::RemoteConsumer::OnTraceStats(bool success,
70701                                                       const TraceStats& stats) {
70702   if (!success) {
70703     std::move(get_trace_stats_response).Reject();
70704     return;
70705   }
70706   auto response =
70707       ipc::AsyncResult<protos::gen::GetTraceStatsResponse>::Create();
70708   *response->mutable_trace_stats() = stats;
70709   std::move(get_trace_stats_response).Resolve(std::move(response));
70710 }
70711 
OnObservableEvents(const ObservableEvents & events)70712 void ConsumerIPCService::RemoteConsumer::OnObservableEvents(
70713     const ObservableEvents& events) {
70714   if (!observe_events_response.IsBound())
70715     return;
70716 
70717   auto result = ipc::AsyncResult<protos::gen::ObserveEventsResponse>::Create();
70718   result.set_has_more(true);
70719   *result->mutable_events() = events;
70720   observe_events_response.Resolve(std::move(result));
70721 }
70722 
CloseObserveEventsResponseStream()70723 void ConsumerIPCService::RemoteConsumer::CloseObserveEventsResponseStream() {
70724   if (!observe_events_response.IsBound())
70725     return;
70726 
70727   auto result = ipc::AsyncResult<protos::gen::ObserveEventsResponse>::Create();
70728   result.set_has_more(false);
70729   observe_events_response.Resolve(std::move(result));
70730 }
70731 
70732 }  // namespace perfetto
70733 // gen_amalgamated begin source: src/tracing/ipc/service/producer_ipc_service.cc
70734 // gen_amalgamated begin header: src/tracing/ipc/service/producer_ipc_service.h
70735 /*
70736  * Copyright (C) 2017 The Android Open Source Project
70737  *
70738  * Licensed under the Apache License, Version 2.0 (the "License");
70739  * you may not use this file except in compliance with the License.
70740  * You may obtain a copy of the License at
70741  *
70742  *      http://www.apache.org/licenses/LICENSE-2.0
70743  *
70744  * Unless required by applicable law or agreed to in writing, software
70745  * distributed under the License is distributed on an "AS IS" BASIS,
70746  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
70747  * See the License for the specific language governing permissions and
70748  * limitations under the License.
70749  */
70750 
70751 #ifndef SRC_TRACING_IPC_SERVICE_PRODUCER_IPC_SERVICE_H_
70752 #define SRC_TRACING_IPC_SERVICE_PRODUCER_IPC_SERVICE_H_
70753 
70754 #include <list>
70755 #include <map>
70756 #include <memory>
70757 #include <string>
70758 
70759 // gen_amalgamated expanded: #include "perfetto/ext/base/weak_ptr.h"
70760 // gen_amalgamated expanded: #include "perfetto/ext/ipc/basic_types.h"
70761 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/producer.h"
70762 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/tracing_service.h"
70763 
70764 // gen_amalgamated expanded: #include "protos/perfetto/ipc/producer_port.ipc.h"
70765 
70766 namespace perfetto {
70767 
70768 namespace ipc {
70769 class Host;
70770 }  // namespace ipc
70771 
70772 // Implements the Producer port of the IPC service. This class proxies requests
70773 // and responses between the core service logic (|svc_|) and remote Producer(s)
70774 // on the IPC socket, through the methods overriddden from ProducerPort.
70775 class ProducerIPCService : public protos::gen::ProducerPort {
70776  public:
70777   explicit ProducerIPCService(TracingService* core_service);
70778   ~ProducerIPCService() override;
70779 
70780   // ProducerPort implementation (from .proto IPC definition).
70781   void InitializeConnection(const protos::gen::InitializeConnectionRequest&,
70782                             DeferredInitializeConnectionResponse) override;
70783   void RegisterDataSource(const protos::gen::RegisterDataSourceRequest&,
70784                           DeferredRegisterDataSourceResponse) override;
70785   void UpdateDataSource(const protos::gen::UpdateDataSourceRequest&,
70786                         DeferredUpdateDataSourceResponse) override;
70787   void UnregisterDataSource(const protos::gen::UnregisterDataSourceRequest&,
70788                             DeferredUnregisterDataSourceResponse) override;
70789   void RegisterTraceWriter(const protos::gen::RegisterTraceWriterRequest&,
70790                            DeferredRegisterTraceWriterResponse) override;
70791   void UnregisterTraceWriter(const protos::gen::UnregisterTraceWriterRequest&,
70792                              DeferredUnregisterTraceWriterResponse) override;
70793   void CommitData(const protos::gen::CommitDataRequest&,
70794                   DeferredCommitDataResponse) override;
70795   void NotifyDataSourceStarted(
70796       const protos::gen::NotifyDataSourceStartedRequest&,
70797       DeferredNotifyDataSourceStartedResponse) override;
70798   void NotifyDataSourceStopped(
70799       const protos::gen::NotifyDataSourceStoppedRequest&,
70800       DeferredNotifyDataSourceStoppedResponse) override;
70801   void ActivateTriggers(const protos::gen::ActivateTriggersRequest&,
70802                         DeferredActivateTriggersResponse) override;
70803 
70804   void GetAsyncCommand(const protos::gen::GetAsyncCommandRequest&,
70805                        DeferredGetAsyncCommandResponse) override;
70806   void Sync(const protos::gen::SyncRequest&, DeferredSyncResponse) override;
70807   void OnClientDisconnected() override;
70808 
70809  private:
70810   // Acts like a Producer with the core Service business logic (which doesn't
70811   // know anything about the remote transport), but all it does is proxying
70812   // methods to the remote Producer on the other side of the IPC channel.
70813   class RemoteProducer : public Producer {
70814    public:
70815     RemoteProducer();
70816     ~RemoteProducer() override;
70817 
70818     // These methods are called by the |core_service_| business logic. There is
70819     // no connection here, these methods are posted straight away.
70820     void OnConnect() override;
70821     void OnDisconnect() override;
70822     void SetupDataSource(DataSourceInstanceID,
70823                          const DataSourceConfig&) override;
70824     void StartDataSource(DataSourceInstanceID,
70825                          const DataSourceConfig&) override;
70826     void StopDataSource(DataSourceInstanceID) override;
70827     void OnTracingSetup() override;
70828     void Flush(FlushRequestID,
70829                const DataSourceInstanceID* data_source_ids,
70830                size_t num_data_sources) override;
70831 
70832     void ClearIncrementalState(const DataSourceInstanceID* data_source_ids,
70833                                size_t num_data_sources) override;
70834 
70835     void SendSetupTracing();
70836 
70837     // The interface obtained from the core service business logic through
70838     // Service::ConnectProducer(this). This allows to invoke methods for a
70839     // specific Producer on the Service business logic.
70840     std::unique_ptr<TracingService::ProducerEndpoint> service_endpoint;
70841 
70842     // The back-channel (based on a never ending stream request) that allows us
70843     // to send asynchronous commands to the remote Producer (e.g. start/stop a
70844     // data source).
70845     DeferredGetAsyncCommandResponse async_producer_commands;
70846 
70847     // Set if the service calls OnTracingSetup() before the
70848     // |async_producer_commands| was bound by the service. In this case, we
70849     // forward the SetupTracing command when it is bound later.
70850     bool send_setup_tracing_on_async_commands_bound = false;
70851   };
70852 
70853   ProducerIPCService(const ProducerIPCService&) = delete;
70854   ProducerIPCService& operator=(const ProducerIPCService&) = delete;
70855 
70856   // Returns the ProducerEndpoint in the core business logic that corresponds to
70857   // the current IPC request.
70858   RemoteProducer* GetProducerForCurrentRequest();
70859 
70860   TracingService* const core_service_;
70861 
70862   // Maps IPC clients to ProducerEndpoint instances registered on the
70863   // |core_service_| business logic.
70864   std::map<ipc::ClientID, std::unique_ptr<RemoteProducer>> producers_;
70865 
70866   // List because pointers need to be stable.
70867   std::list<DeferredSyncResponse> pending_syncs_;
70868 
70869   base::WeakPtrFactory<ProducerIPCService> weak_ptr_factory_;  // Keep last.
70870 };
70871 
70872 }  // namespace perfetto
70873 
70874 #endif  // SRC_TRACING_IPC_SERVICE_PRODUCER_IPC_SERVICE_H_
70875 /*
70876  * Copyright (C) 2017 The Android Open Source Project
70877  *
70878  * Licensed under the Apache License, Version 2.0 (the "License");
70879  * you may not use this file except in compliance with the License.
70880  * You may obtain a copy of the License at
70881  *
70882  *      http://www.apache.org/licenses/LICENSE-2.0
70883  *
70884  * Unless required by applicable law or agreed to in writing, software
70885  * distributed under the License is distributed on an "AS IS" BASIS,
70886  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
70887  * See the License for the specific language governing permissions and
70888  * limitations under the License.
70889  */
70890 
70891 // gen_amalgamated expanded: #include "src/tracing/ipc/service/producer_ipc_service.h"
70892 
70893 #include <cinttypes>
70894 
70895 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
70896 // gen_amalgamated expanded: #include "perfetto/base/task_runner.h"
70897 // gen_amalgamated expanded: #include "perfetto/ext/ipc/host.h"
70898 // gen_amalgamated expanded: #include "perfetto/ext/ipc/service.h"
70899 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/commit_data_request.h"
70900 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/tracing_service.h"
70901 // gen_amalgamated expanded: #include "perfetto/tracing/core/data_source_config.h"
70902 // gen_amalgamated expanded: #include "perfetto/tracing/core/data_source_descriptor.h"
70903 
70904 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
70905 // gen_amalgamated expanded: #include "src/tracing/ipc/shared_memory_windows.h"
70906 #else
70907 // gen_amalgamated expanded: #include "src/tracing/ipc/posix_shared_memory.h"
70908 #endif
70909 
70910 // The remote Producer(s) are not trusted. All the methods from the ProducerPort
70911 // IPC layer (e.g. RegisterDataSource()) must assume that the remote Producer is
70912 // compromised.
70913 
70914 namespace perfetto {
70915 
ProducerIPCService(TracingService * core_service)70916 ProducerIPCService::ProducerIPCService(TracingService* core_service)
70917     : core_service_(core_service), weak_ptr_factory_(this) {}
70918 
70919 ProducerIPCService::~ProducerIPCService() = default;
70920 
70921 ProducerIPCService::RemoteProducer*
GetProducerForCurrentRequest()70922 ProducerIPCService::GetProducerForCurrentRequest() {
70923   const ipc::ClientID ipc_client_id = ipc::Service::client_info().client_id();
70924   PERFETTO_CHECK(ipc_client_id);
70925   auto it = producers_.find(ipc_client_id);
70926   if (it == producers_.end())
70927     return nullptr;
70928   return it->second.get();
70929 }
70930 
70931 // Called by the remote Producer through the IPC channel soon after connecting.
InitializeConnection(const protos::gen::InitializeConnectionRequest & req,DeferredInitializeConnectionResponse response)70932 void ProducerIPCService::InitializeConnection(
70933     const protos::gen::InitializeConnectionRequest& req,
70934     DeferredInitializeConnectionResponse response) {
70935   const auto& client_info = ipc::Service::client_info();
70936   const ipc::ClientID ipc_client_id = client_info.client_id();
70937   PERFETTO_CHECK(ipc_client_id);
70938 
70939   if (producers_.count(ipc_client_id) > 0) {
70940     PERFETTO_DLOG(
70941         "The remote Producer is trying to re-initialize the connection");
70942     return response.Reject();
70943   }
70944 
70945   // Create a new entry.
70946   std::unique_ptr<RemoteProducer> producer(new RemoteProducer());
70947 
70948   TracingService::ProducerSMBScrapingMode smb_scraping_mode =
70949       TracingService::ProducerSMBScrapingMode::kDefault;
70950   switch (req.smb_scraping_mode()) {
70951     case protos::gen::InitializeConnectionRequest::SMB_SCRAPING_UNSPECIFIED:
70952       break;
70953     case protos::gen::InitializeConnectionRequest::SMB_SCRAPING_DISABLED:
70954       smb_scraping_mode = TracingService::ProducerSMBScrapingMode::kDisabled;
70955       break;
70956     case protos::gen::InitializeConnectionRequest::SMB_SCRAPING_ENABLED:
70957       smb_scraping_mode = TracingService::ProducerSMBScrapingMode::kEnabled;
70958       break;
70959   }
70960 
70961   // If the producer provided an SMB, tell the service to attempt to adopt it.
70962   std::unique_ptr<SharedMemory> shmem;
70963   if (req.producer_provided_shmem()) {
70964 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
70965     if (!req.has_shm_key_windows() || req.shm_key_windows().empty()) {
70966       PERFETTO_ELOG(
70967           "shm_key_windows must be non-empty when "
70968           "producer_provided_shmem = true");
70969     } else {
70970       shmem = SharedMemoryWindows::Attach(req.shm_key_windows());
70971       // Attach() does error logging if something fails, no need to extra ELOGs.
70972     }
70973 #else
70974     base::ScopedFile shmem_fd = ipc::Service::TakeReceivedFD();
70975 
70976     if (shmem_fd) {
70977       shmem = PosixSharedMemory::AttachToFd(
70978           std::move(shmem_fd), /*require_seals_if_supported=*/true);
70979       if (!shmem) {
70980         PERFETTO_ELOG(
70981             "Couldn't map producer-provided SMB, falling back to "
70982             "service-provided SMB");
70983       }
70984     } else {
70985       PERFETTO_DLOG(
70986           "InitializeConnectionRequest's producer_provided_shmem flag is set "
70987           "but the producer didn't provide an FD");
70988     }
70989 #endif
70990   }
70991 
70992   // ConnectProducer will call OnConnect() on the next task.
70993   producer->service_endpoint = core_service_->ConnectProducer(
70994       producer.get(), client_info.uid(), req.producer_name(),
70995       req.shared_memory_size_hint_bytes(),
70996       /*in_process=*/false, smb_scraping_mode,
70997       req.shared_memory_page_size_hint_bytes(), std::move(shmem),
70998       req.sdk_version());
70999 
71000   // Could happen if the service has too many producers connected.
71001   if (!producer->service_endpoint) {
71002     response.Reject();
71003     return;
71004   }
71005 
71006   bool using_producer_shmem =
71007       producer->service_endpoint->IsShmemProvidedByProducer();
71008 
71009   producers_.emplace(ipc_client_id, std::move(producer));
71010   // Because of the std::move() |producer| is invalid after this point.
71011 
71012   auto async_res =
71013       ipc::AsyncResult<protos::gen::InitializeConnectionResponse>::Create();
71014   async_res->set_using_shmem_provided_by_producer(using_producer_shmem);
71015   async_res->set_direct_smb_patching_supported(true);
71016   response.Resolve(std::move(async_res));
71017 }
71018 
71019 // Called by the remote Producer through the IPC channel.
RegisterDataSource(const protos::gen::RegisterDataSourceRequest & req,DeferredRegisterDataSourceResponse response)71020 void ProducerIPCService::RegisterDataSource(
71021     const protos::gen::RegisterDataSourceRequest& req,
71022     DeferredRegisterDataSourceResponse response) {
71023   RemoteProducer* producer = GetProducerForCurrentRequest();
71024   if (!producer) {
71025     PERFETTO_DLOG(
71026         "Producer invoked RegisterDataSource() before InitializeConnection()");
71027     if (response.IsBound())
71028       response.Reject();
71029     return;
71030   }
71031 
71032   const DataSourceDescriptor& dsd = req.data_source_descriptor();
71033   GetProducerForCurrentRequest()->service_endpoint->RegisterDataSource(dsd);
71034 
71035   // RegisterDataSource doesn't expect any meaningful response.
71036   if (response.IsBound()) {
71037     response.Resolve(
71038         ipc::AsyncResult<protos::gen::RegisterDataSourceResponse>::Create());
71039   }
71040 }
71041 
71042 // Called by the remote Producer through the IPC channel.
UpdateDataSource(const protos::gen::UpdateDataSourceRequest & req,DeferredUpdateDataSourceResponse response)71043 void ProducerIPCService::UpdateDataSource(
71044     const protos::gen::UpdateDataSourceRequest& req,
71045     DeferredUpdateDataSourceResponse response) {
71046   RemoteProducer* producer = GetProducerForCurrentRequest();
71047   if (!producer) {
71048     PERFETTO_DLOG(
71049         "Producer invoked UpdateDataSource() before InitializeConnection()");
71050     if (response.IsBound())
71051       response.Reject();
71052     return;
71053   }
71054 
71055   const DataSourceDescriptor& dsd = req.data_source_descriptor();
71056   GetProducerForCurrentRequest()->service_endpoint->UpdateDataSource(dsd);
71057 
71058   // UpdateDataSource doesn't expect any meaningful response.
71059   if (response.IsBound()) {
71060     response.Resolve(
71061         ipc::AsyncResult<protos::gen::UpdateDataSourceResponse>::Create());
71062   }
71063 }
71064 
71065 // Called by the IPC layer.
OnClientDisconnected()71066 void ProducerIPCService::OnClientDisconnected() {
71067   ipc::ClientID client_id = ipc::Service::client_info().client_id();
71068   PERFETTO_DLOG("Client %" PRIu64 " disconnected", client_id);
71069   producers_.erase(client_id);
71070 }
71071 
71072 // TODO(fmayer): test what happens if we receive the following tasks, in order:
71073 // RegisterDataSource, UnregisterDataSource, OnDataSourceRegistered.
71074 // which essentially means that the client posted back to back a
71075 // ReqisterDataSource and UnregisterDataSource speculating on the next id.
71076 // Called by the remote Service through the IPC channel.
UnregisterDataSource(const protos::gen::UnregisterDataSourceRequest & req,DeferredUnregisterDataSourceResponse response)71077 void ProducerIPCService::UnregisterDataSource(
71078     const protos::gen::UnregisterDataSourceRequest& req,
71079     DeferredUnregisterDataSourceResponse response) {
71080   RemoteProducer* producer = GetProducerForCurrentRequest();
71081   if (!producer) {
71082     PERFETTO_DLOG(
71083         "Producer invoked UnregisterDataSource() before "
71084         "InitializeConnection()");
71085     if (response.IsBound())
71086       response.Reject();
71087     return;
71088   }
71089   producer->service_endpoint->UnregisterDataSource(req.data_source_name());
71090 
71091   // UnregisterDataSource doesn't expect any meaningful response.
71092   if (response.IsBound()) {
71093     response.Resolve(
71094         ipc::AsyncResult<protos::gen::UnregisterDataSourceResponse>::Create());
71095   }
71096 }
71097 
RegisterTraceWriter(const protos::gen::RegisterTraceWriterRequest & req,DeferredRegisterTraceWriterResponse response)71098 void ProducerIPCService::RegisterTraceWriter(
71099     const protos::gen::RegisterTraceWriterRequest& req,
71100     DeferredRegisterTraceWriterResponse response) {
71101   RemoteProducer* producer = GetProducerForCurrentRequest();
71102   if (!producer) {
71103     PERFETTO_DLOG(
71104         "Producer invoked RegisterTraceWriter() before "
71105         "InitializeConnection()");
71106     if (response.IsBound())
71107       response.Reject();
71108     return;
71109   }
71110   producer->service_endpoint->RegisterTraceWriter(req.trace_writer_id(),
71111                                                   req.target_buffer());
71112 
71113   // RegisterTraceWriter doesn't expect any meaningful response.
71114   if (response.IsBound()) {
71115     response.Resolve(
71116         ipc::AsyncResult<protos::gen::RegisterTraceWriterResponse>::Create());
71117   }
71118 }
71119 
UnregisterTraceWriter(const protos::gen::UnregisterTraceWriterRequest & req,DeferredUnregisterTraceWriterResponse response)71120 void ProducerIPCService::UnregisterTraceWriter(
71121     const protos::gen::UnregisterTraceWriterRequest& req,
71122     DeferredUnregisterTraceWriterResponse response) {
71123   RemoteProducer* producer = GetProducerForCurrentRequest();
71124   if (!producer) {
71125     PERFETTO_DLOG(
71126         "Producer invoked UnregisterTraceWriter() before "
71127         "InitializeConnection()");
71128     if (response.IsBound())
71129       response.Reject();
71130     return;
71131   }
71132   producer->service_endpoint->UnregisterTraceWriter(req.trace_writer_id());
71133 
71134   // UnregisterTraceWriter doesn't expect any meaningful response.
71135   if (response.IsBound()) {
71136     response.Resolve(
71137         ipc::AsyncResult<protos::gen::UnregisterTraceWriterResponse>::Create());
71138   }
71139 }
71140 
CommitData(const protos::gen::CommitDataRequest & req,DeferredCommitDataResponse resp)71141 void ProducerIPCService::CommitData(const protos::gen::CommitDataRequest& req,
71142                                     DeferredCommitDataResponse resp) {
71143   RemoteProducer* producer = GetProducerForCurrentRequest();
71144   if (!producer) {
71145     PERFETTO_DLOG(
71146         "Producer invoked CommitData() before InitializeConnection()");
71147     if (resp.IsBound())
71148       resp.Reject();
71149     return;
71150   }
71151 
71152   // We don't want to send a response if the client didn't attach a callback to
71153   // the original request. Doing so would generate unnecessary wakeups and
71154   // context switches.
71155   std::function<void()> callback;
71156   if (resp.IsBound()) {
71157     // Capturing |resp| by reference here speculates on the fact that
71158     // CommitData() in tracing_service_impl.cc invokes the passed callback
71159     // inline, without posting it. If that assumption changes this code needs to
71160     // wrap the response in a shared_ptr (C+11 lambdas don't support move) and
71161     // use a weak ptr in the caller.
71162     callback = [&resp] {
71163       resp.Resolve(ipc::AsyncResult<protos::gen::CommitDataResponse>::Create());
71164     };
71165   }
71166   producer->service_endpoint->CommitData(req, callback);
71167 }
71168 
NotifyDataSourceStarted(const protos::gen::NotifyDataSourceStartedRequest & request,DeferredNotifyDataSourceStartedResponse response)71169 void ProducerIPCService::NotifyDataSourceStarted(
71170     const protos::gen::NotifyDataSourceStartedRequest& request,
71171     DeferredNotifyDataSourceStartedResponse response) {
71172   RemoteProducer* producer = GetProducerForCurrentRequest();
71173   if (!producer) {
71174     PERFETTO_DLOG(
71175         "Producer invoked NotifyDataSourceStarted() before "
71176         "InitializeConnection()");
71177     if (response.IsBound())
71178       response.Reject();
71179     return;
71180   }
71181   producer->service_endpoint->NotifyDataSourceStarted(request.data_source_id());
71182 
71183   // NotifyDataSourceStopped shouldn't expect any meaningful response, avoid
71184   // a useless IPC in that case.
71185   if (response.IsBound()) {
71186     response.Resolve(ipc::AsyncResult<
71187                      protos::gen::NotifyDataSourceStartedResponse>::Create());
71188   }
71189 }
71190 
NotifyDataSourceStopped(const protos::gen::NotifyDataSourceStoppedRequest & request,DeferredNotifyDataSourceStoppedResponse response)71191 void ProducerIPCService::NotifyDataSourceStopped(
71192     const protos::gen::NotifyDataSourceStoppedRequest& request,
71193     DeferredNotifyDataSourceStoppedResponse response) {
71194   RemoteProducer* producer = GetProducerForCurrentRequest();
71195   if (!producer) {
71196     PERFETTO_DLOG(
71197         "Producer invoked NotifyDataSourceStopped() before "
71198         "InitializeConnection()");
71199     if (response.IsBound())
71200       response.Reject();
71201     return;
71202   }
71203   producer->service_endpoint->NotifyDataSourceStopped(request.data_source_id());
71204 
71205   // NotifyDataSourceStopped shouldn't expect any meaningful response, avoid
71206   // a useless IPC in that case.
71207   if (response.IsBound()) {
71208     response.Resolve(ipc::AsyncResult<
71209                      protos::gen::NotifyDataSourceStoppedResponse>::Create());
71210   }
71211 }
71212 
ActivateTriggers(const protos::gen::ActivateTriggersRequest & proto_req,DeferredActivateTriggersResponse resp)71213 void ProducerIPCService::ActivateTriggers(
71214     const protos::gen::ActivateTriggersRequest& proto_req,
71215     DeferredActivateTriggersResponse resp) {
71216   RemoteProducer* producer = GetProducerForCurrentRequest();
71217   if (!producer) {
71218     PERFETTO_DLOG(
71219         "Producer invoked ActivateTriggers() before InitializeConnection()");
71220     if (resp.IsBound())
71221       resp.Reject();
71222     return;
71223   }
71224   std::vector<std::string> triggers;
71225   for (const auto& name : proto_req.trigger_names()) {
71226     triggers.push_back(name);
71227   }
71228   producer->service_endpoint->ActivateTriggers(triggers);
71229   // ActivateTriggers shouldn't expect any meaningful response, avoid
71230   // a useless IPC in that case.
71231   if (resp.IsBound()) {
71232     resp.Resolve(
71233         ipc::AsyncResult<protos::gen::ActivateTriggersResponse>::Create());
71234   }
71235 }
71236 
GetAsyncCommand(const protos::gen::GetAsyncCommandRequest &,DeferredGetAsyncCommandResponse response)71237 void ProducerIPCService::GetAsyncCommand(
71238     const protos::gen::GetAsyncCommandRequest&,
71239     DeferredGetAsyncCommandResponse response) {
71240   RemoteProducer* producer = GetProducerForCurrentRequest();
71241   if (!producer) {
71242     PERFETTO_DLOG(
71243         "Producer invoked GetAsyncCommand() before "
71244         "InitializeConnection()");
71245     return response.Reject();
71246   }
71247   // Keep the back channel open, without ever resolving the ipc::Deferred fully,
71248   // to send async commands to the RemoteProducer (e.g., starting/stopping a
71249   // data source).
71250   producer->async_producer_commands = std::move(response);
71251 
71252   // Service may already have issued the OnTracingSetup() event, in which case
71253   // we should forward it to the producer now.
71254   if (producer->send_setup_tracing_on_async_commands_bound)
71255     producer->SendSetupTracing();
71256 }
71257 
Sync(const protos::gen::SyncRequest &,DeferredSyncResponse resp)71258 void ProducerIPCService::Sync(const protos::gen::SyncRequest&,
71259                               DeferredSyncResponse resp) {
71260   RemoteProducer* producer = GetProducerForCurrentRequest();
71261   if (!producer) {
71262     PERFETTO_DLOG("Producer invoked Sync() before InitializeConnection()");
71263     return resp.Reject();
71264   }
71265   auto weak_this = weak_ptr_factory_.GetWeakPtr();
71266   auto resp_it = pending_syncs_.insert(pending_syncs_.end(), std::move(resp));
71267   auto callback = [weak_this, resp_it]() {
71268     if (!weak_this)
71269       return;
71270     auto pending_resp = std::move(*resp_it);
71271     weak_this->pending_syncs_.erase(resp_it);
71272     pending_resp.Resolve(ipc::AsyncResult<protos::gen::SyncResponse>::Create());
71273   };
71274   producer->service_endpoint->Sync(callback);
71275 }
71276 
71277 ////////////////////////////////////////////////////////////////////////////////
71278 // RemoteProducer methods
71279 ////////////////////////////////////////////////////////////////////////////////
71280 
71281 ProducerIPCService::RemoteProducer::RemoteProducer() = default;
71282 ProducerIPCService::RemoteProducer::~RemoteProducer() = default;
71283 
71284 // Invoked by the |core_service_| business logic after the ConnectProducer()
71285 // call. There is nothing to do here, we really expected the ConnectProducer()
71286 // to just work in the local case.
OnConnect()71287 void ProducerIPCService::RemoteProducer::OnConnect() {}
71288 
71289 // Invoked by the |core_service_| business logic after we destroy the
71290 // |service_endpoint| (in the RemoteProducer dtor).
OnDisconnect()71291 void ProducerIPCService::RemoteProducer::OnDisconnect() {}
71292 
71293 // Invoked by the |core_service_| business logic when it wants to create a new
71294 // data source.
SetupDataSource(DataSourceInstanceID dsid,const DataSourceConfig & cfg)71295 void ProducerIPCService::RemoteProducer::SetupDataSource(
71296     DataSourceInstanceID dsid,
71297     const DataSourceConfig& cfg) {
71298   if (!async_producer_commands.IsBound()) {
71299     PERFETTO_DLOG(
71300         "The Service tried to create a new data source but the remote Producer "
71301         "has not yet initialized the connection");
71302     return;
71303   }
71304   auto cmd = ipc::AsyncResult<protos::gen::GetAsyncCommandResponse>::Create();
71305   cmd.set_has_more(true);
71306   cmd->mutable_setup_data_source()->set_new_instance_id(dsid);
71307   *cmd->mutable_setup_data_source()->mutable_config() = cfg;
71308   async_producer_commands.Resolve(std::move(cmd));
71309 }
71310 
71311 // Invoked by the |core_service_| business logic when it wants to start a new
71312 // data source.
StartDataSource(DataSourceInstanceID dsid,const DataSourceConfig & cfg)71313 void ProducerIPCService::RemoteProducer::StartDataSource(
71314     DataSourceInstanceID dsid,
71315     const DataSourceConfig& cfg) {
71316   if (!async_producer_commands.IsBound()) {
71317     PERFETTO_DLOG(
71318         "The Service tried to start a new data source but the remote Producer "
71319         "has not yet initialized the connection");
71320     return;
71321   }
71322   auto cmd = ipc::AsyncResult<protos::gen::GetAsyncCommandResponse>::Create();
71323   cmd.set_has_more(true);
71324   cmd->mutable_start_data_source()->set_new_instance_id(dsid);
71325   *cmd->mutable_start_data_source()->mutable_config() = cfg;
71326   async_producer_commands.Resolve(std::move(cmd));
71327 }
71328 
StopDataSource(DataSourceInstanceID dsid)71329 void ProducerIPCService::RemoteProducer::StopDataSource(
71330     DataSourceInstanceID dsid) {
71331   if (!async_producer_commands.IsBound()) {
71332     PERFETTO_DLOG(
71333         "The Service tried to stop a data source but the remote Producer "
71334         "has not yet initialized the connection");
71335     return;
71336   }
71337   auto cmd = ipc::AsyncResult<protos::gen::GetAsyncCommandResponse>::Create();
71338   cmd.set_has_more(true);
71339   cmd->mutable_stop_data_source()->set_instance_id(dsid);
71340   async_producer_commands.Resolve(std::move(cmd));
71341 }
71342 
OnTracingSetup()71343 void ProducerIPCService::RemoteProducer::OnTracingSetup() {
71344   if (!async_producer_commands.IsBound()) {
71345     // Service may call this before the producer issued GetAsyncCommand.
71346     send_setup_tracing_on_async_commands_bound = true;
71347     return;
71348   }
71349   SendSetupTracing();
71350 }
71351 
SendSetupTracing()71352 void ProducerIPCService::RemoteProducer::SendSetupTracing() {
71353   PERFETTO_CHECK(async_producer_commands.IsBound());
71354   PERFETTO_CHECK(service_endpoint->shared_memory());
71355   auto cmd = ipc::AsyncResult<protos::gen::GetAsyncCommandResponse>::Create();
71356   cmd.set_has_more(true);
71357   auto setup_tracing = cmd->mutable_setup_tracing();
71358   if (!service_endpoint->IsShmemProvidedByProducer()) {
71359     // Nominal case (% Chrome): service provides SMB.
71360     setup_tracing->set_shared_buffer_page_size_kb(
71361         static_cast<uint32_t>(service_endpoint->shared_buffer_page_size_kb()));
71362 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
71363     const std::string& shm_key =
71364         static_cast<SharedMemoryWindows*>(service_endpoint->shared_memory())
71365             ->key();
71366     setup_tracing->set_shm_key_windows(shm_key);
71367 #else
71368     const int shm_fd =
71369         static_cast<PosixSharedMemory*>(service_endpoint->shared_memory())
71370             ->fd();
71371     cmd.set_fd(shm_fd);
71372 #endif
71373   }
71374   async_producer_commands.Resolve(std::move(cmd));
71375 }
71376 
Flush(FlushRequestID flush_request_id,const DataSourceInstanceID * data_source_ids,size_t num_data_sources)71377 void ProducerIPCService::RemoteProducer::Flush(
71378     FlushRequestID flush_request_id,
71379     const DataSourceInstanceID* data_source_ids,
71380     size_t num_data_sources) {
71381   if (!async_producer_commands.IsBound()) {
71382     PERFETTO_DLOG(
71383         "The Service tried to request a flush but the remote Producer has not "
71384         "yet initialized the connection");
71385     return;
71386   }
71387   auto cmd = ipc::AsyncResult<protos::gen::GetAsyncCommandResponse>::Create();
71388   cmd.set_has_more(true);
71389   for (size_t i = 0; i < num_data_sources; i++)
71390     cmd->mutable_flush()->add_data_source_ids(data_source_ids[i]);
71391   cmd->mutable_flush()->set_request_id(flush_request_id);
71392   async_producer_commands.Resolve(std::move(cmd));
71393 }
71394 
ClearIncrementalState(const DataSourceInstanceID * data_source_ids,size_t num_data_sources)71395 void ProducerIPCService::RemoteProducer::ClearIncrementalState(
71396     const DataSourceInstanceID* data_source_ids,
71397     size_t num_data_sources) {
71398   if (!async_producer_commands.IsBound()) {
71399     PERFETTO_DLOG(
71400         "The Service tried to request an incremental state invalidation, but "
71401         "the remote Producer has not yet initialized the connection");
71402     return;
71403   }
71404   auto cmd = ipc::AsyncResult<protos::gen::GetAsyncCommandResponse>::Create();
71405   cmd.set_has_more(true);
71406   for (size_t i = 0; i < num_data_sources; i++)
71407     cmd->mutable_clear_incremental_state()->add_data_source_ids(
71408         data_source_ids[i]);
71409   async_producer_commands.Resolve(std::move(cmd));
71410 }
71411 
71412 }  // namespace perfetto
71413 // gen_amalgamated begin source: src/tracing/ipc/service/service_ipc_host_impl.cc
71414 // gen_amalgamated begin header: src/tracing/ipc/service/service_ipc_host_impl.h
71415 // gen_amalgamated begin header: include/perfetto/ext/tracing/ipc/service_ipc_host.h
71416 /*
71417  * Copyright (C) 2017 The Android Open Source Project
71418  *
71419  * Licensed under the Apache License, Version 2.0 (the "License");
71420  * you may not use this file except in compliance with the License.
71421  * You may obtain a copy of the License at
71422  *
71423  *      http://www.apache.org/licenses/LICENSE-2.0
71424  *
71425  * Unless required by applicable law or agreed to in writing, software
71426  * distributed under the License is distributed on an "AS IS" BASIS,
71427  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
71428  * See the License for the specific language governing permissions and
71429  * limitations under the License.
71430  */
71431 
71432 #ifndef INCLUDE_PERFETTO_EXT_TRACING_IPC_SERVICE_IPC_HOST_H_
71433 #define INCLUDE_PERFETTO_EXT_TRACING_IPC_SERVICE_IPC_HOST_H_
71434 
71435 #include <memory>
71436 
71437 // gen_amalgamated expanded: #include "perfetto/base/export.h"
71438 // gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"
71439 // gen_amalgamated expanded: #include "perfetto/ext/base/unix_socket.h"
71440 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/basic_types.h"
71441 
71442 namespace perfetto {
71443 namespace base {
71444 class TaskRunner;
71445 }  // namespace base.
71446 
71447 class TracingService;
71448 
71449 // Creates an instance of the service (business logic + UNIX socket transport).
71450 // Exposed to:
71451 //   The code in the tracing client that will host the service e.g., traced.
71452 // Implemented in:
71453 //   src/tracing/ipc/service/service_ipc_host_impl.cc
71454 class PERFETTO_EXPORT ServiceIPCHost {
71455  public:
71456   static std::unique_ptr<ServiceIPCHost> CreateInstance(base::TaskRunner*);
71457   virtual ~ServiceIPCHost();
71458 
71459   // Start listening on the Producer & Consumer ports. Returns false in case of
71460   // failure (e.g., something else is listening on |socket_name|).
71461   virtual bool Start(const char* producer_socket_name,
71462                      const char* consumer_socket_name) = 0;
71463 
71464   // Like the above, but takes two file descriptors to already bound sockets.
71465   // This is used when building as part of the Android tree, where init opens
71466   // and binds the socket beore exec()-ing us.
71467   virtual bool Start(base::ScopedSocketHandle producer_socket_fd,
71468                      base::ScopedSocketHandle consumer_socket_fd) = 0;
71469 
71470   virtual TracingService* service() const = 0;
71471 
71472  protected:
71473   ServiceIPCHost();
71474 
71475  private:
71476   ServiceIPCHost(const ServiceIPCHost&) = delete;
71477   ServiceIPCHost& operator=(const ServiceIPCHost&) = delete;
71478 };
71479 
71480 }  // namespace perfetto
71481 
71482 #endif  // INCLUDE_PERFETTO_EXT_TRACING_IPC_SERVICE_IPC_HOST_H_
71483 /*
71484  * Copyright (C) 2017 The Android Open Source Project
71485  *
71486  * Licensed under the Apache License, Version 2.0 (the "License");
71487  * you may not use this file except in compliance with the License.
71488  * You may obtain a copy of the License at
71489  *
71490  *      http://www.apache.org/licenses/LICENSE-2.0
71491  *
71492  * Unless required by applicable law or agreed to in writing, software
71493  * distributed under the License is distributed on an "AS IS" BASIS,
71494  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
71495  * See the License for the specific language governing permissions and
71496  * limitations under the License.
71497  */
71498 
71499 #ifndef SRC_TRACING_IPC_SERVICE_SERVICE_IPC_HOST_IMPL_H_
71500 #define SRC_TRACING_IPC_SERVICE_SERVICE_IPC_HOST_IMPL_H_
71501 
71502 #include <memory>
71503 
71504 // gen_amalgamated expanded: #include "perfetto/ext/tracing/ipc/service_ipc_host.h"
71505 
71506 namespace perfetto {
71507 
71508 namespace ipc {
71509 class Host;
71510 }
71511 
71512 // The implementation of the IPC host for the tracing service. This class does
71513 // very few things: it mostly initializes the IPC transport. The actual
71514 // implementation of the IPC <> Service business logic glue lives in
71515 // producer_ipc_service.cc and consumer_ipc_service.cc.
71516 class ServiceIPCHostImpl : public ServiceIPCHost {
71517  public:
71518   ServiceIPCHostImpl(base::TaskRunner*);
71519   ~ServiceIPCHostImpl() override;
71520 
71521   // ServiceIPCHost implementation.
71522   bool Start(const char* producer_socket_name,
71523              const char* consumer_socket_name) override;
71524   bool Start(base::ScopedSocketHandle producer_socket_fd,
71525              base::ScopedSocketHandle consumer_socket_fd) override;
71526 
71527   TracingService* service() const override;
71528 
71529  private:
71530   bool DoStart();
71531   void Shutdown();
71532 
71533   base::TaskRunner* const task_runner_;
71534   std::unique_ptr<TracingService> svc_;  // The service business logic.
71535 
71536   // The IPC host that listens on the Producer socket. It owns the
71537   // PosixServiceProducerPort instance which deals with all producers' IPC(s).
71538   std::unique_ptr<ipc::Host> producer_ipc_port_;
71539 
71540   // As above, but for the Consumer port.
71541   std::unique_ptr<ipc::Host> consumer_ipc_port_;
71542 };
71543 
71544 }  // namespace perfetto
71545 
71546 #endif  // SRC_TRACING_IPC_SERVICE_SERVICE_IPC_HOST_IMPL_H_
71547 /*
71548  * Copyright (C) 2017 The Android Open Source Project
71549  *
71550  * Licensed under the Apache License, Version 2.0 (the "License");
71551  * you may not use this file except in compliance with the License.
71552  * You may obtain a copy of the License at
71553  *
71554  *      http://www.apache.org/licenses/LICENSE-2.0
71555  *
71556  * Unless required by applicable law or agreed to in writing, software
71557  * distributed under the License is distributed on an "AS IS" BASIS,
71558  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
71559  * See the License for the specific language governing permissions and
71560  * limitations under the License.
71561  */
71562 
71563 // gen_amalgamated expanded: #include "src/tracing/ipc/service/service_ipc_host_impl.h"
71564 
71565 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
71566 // gen_amalgamated expanded: #include "perfetto/base/task_runner.h"
71567 // gen_amalgamated expanded: #include "perfetto/ext/ipc/host.h"
71568 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/tracing_service.h"
71569 // gen_amalgamated expanded: #include "src/tracing/ipc/service/consumer_ipc_service.h"
71570 // gen_amalgamated expanded: #include "src/tracing/ipc/service/producer_ipc_service.h"
71571 
71572 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
71573 // gen_amalgamated expanded: #include "src/tracing/ipc/shared_memory_windows.h"
71574 #else
71575 // gen_amalgamated expanded: #include "src/tracing/ipc/posix_shared_memory.h"
71576 #endif
71577 
71578 namespace perfetto {
71579 
71580 // TODO(fmayer): implement per-uid connection limit (b/69093705).
71581 
71582 // Implements the publicly exposed factory method declared in
71583 // include/tracing/posix_ipc/posix_service_host.h.
CreateInstance(base::TaskRunner * task_runner)71584 std::unique_ptr<ServiceIPCHost> ServiceIPCHost::CreateInstance(
71585     base::TaskRunner* task_runner) {
71586   return std::unique_ptr<ServiceIPCHost>(new ServiceIPCHostImpl(task_runner));
71587 }
71588 
ServiceIPCHostImpl(base::TaskRunner * task_runner)71589 ServiceIPCHostImpl::ServiceIPCHostImpl(base::TaskRunner* task_runner)
71590     : task_runner_(task_runner) {}
71591 
~ServiceIPCHostImpl()71592 ServiceIPCHostImpl::~ServiceIPCHostImpl() {}
71593 
Start(const char * producer_socket_name,const char * consumer_socket_name)71594 bool ServiceIPCHostImpl::Start(const char* producer_socket_name,
71595                                const char* consumer_socket_name) {
71596   PERFETTO_CHECK(!svc_);  // Check if already started.
71597 
71598   // Initialize the IPC transport.
71599   producer_ipc_port_ =
71600       ipc::Host::CreateInstance(producer_socket_name, task_runner_);
71601   consumer_ipc_port_ =
71602       ipc::Host::CreateInstance(consumer_socket_name, task_runner_);
71603   return DoStart();
71604 }
71605 
Start(base::ScopedSocketHandle producer_socket_fd,base::ScopedSocketHandle consumer_socket_fd)71606 bool ServiceIPCHostImpl::Start(base::ScopedSocketHandle producer_socket_fd,
71607                                base::ScopedSocketHandle consumer_socket_fd) {
71608   PERFETTO_CHECK(!svc_);  // Check if already started.
71609 
71610   // Initialize the IPC transport.
71611   producer_ipc_port_ =
71612       ipc::Host::CreateInstance(std::move(producer_socket_fd), task_runner_);
71613   consumer_ipc_port_ =
71614       ipc::Host::CreateInstance(std::move(consumer_socket_fd), task_runner_);
71615   return DoStart();
71616 }
71617 
DoStart()71618 bool ServiceIPCHostImpl::DoStart() {
71619   // Create and initialize the platform-independent tracing business logic.
71620 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
71621   std::unique_ptr<SharedMemory::Factory> shm_factory(
71622       new SharedMemoryWindows::Factory());
71623 #else
71624   std::unique_ptr<SharedMemory::Factory> shm_factory(
71625       new PosixSharedMemory::Factory());
71626 #endif
71627   svc_ = TracingService::CreateInstance(std::move(shm_factory), task_runner_);
71628 
71629   if (!producer_ipc_port_ || !consumer_ipc_port_) {
71630     Shutdown();
71631     return false;
71632   }
71633 
71634   // TODO(fmayer): add a test that destroyes the ServiceIPCHostImpl soon after
71635   // Start() and checks that no spurious callbacks are issued.
71636   bool producer_service_exposed = producer_ipc_port_->ExposeService(
71637       std::unique_ptr<ipc::Service>(new ProducerIPCService(svc_.get())));
71638   PERFETTO_CHECK(producer_service_exposed);
71639 
71640   bool consumer_service_exposed = consumer_ipc_port_->ExposeService(
71641       std::unique_ptr<ipc::Service>(new ConsumerIPCService(svc_.get())));
71642   PERFETTO_CHECK(consumer_service_exposed);
71643 
71644   return true;
71645 }
71646 
service() const71647 TracingService* ServiceIPCHostImpl::service() const {
71648   return svc_.get();
71649 }
71650 
Shutdown()71651 void ServiceIPCHostImpl::Shutdown() {
71652   // TODO(primiano): add a test that causes the Shutdown() and checks that no
71653   // spurious callbacks are issued.
71654   producer_ipc_port_.reset();
71655   consumer_ipc_port_.reset();
71656   svc_.reset();
71657 }
71658 
71659 // Definitions for the base class ctor/dtor.
71660 ServiceIPCHost::ServiceIPCHost() = default;
71661 ServiceIPCHost::~ServiceIPCHost() = default;
71662 
71663 }  // namespace perfetto
71664 // gen_amalgamated begin source: src/tracing/internal/system_tracing_backend.cc
71665 /*
71666  * Copyright (C) 2019 The Android Open Source Project
71667  *
71668  * Licensed under the Apache License, Version 2.0 (the "License");
71669  * you may not use this file except in compliance with the License.
71670  * You may obtain a copy of the License at
71671  *
71672  *      http://www.apache.org/licenses/LICENSE-2.0
71673  *
71674  * Unless required by applicable law or agreed to in writing, software
71675  * distributed under the License is distributed on an "AS IS" BASIS,
71676  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
71677  * See the License for the specific language governing permissions and
71678  * limitations under the License.
71679  */
71680 
71681 // gen_amalgamated expanded: #include "perfetto/tracing/internal/system_tracing_backend.h"
71682 
71683 // gen_amalgamated expanded: #include "perfetto/base/logging.h"
71684 // gen_amalgamated expanded: #include "perfetto/base/task_runner.h"
71685 // gen_amalgamated expanded: #include "perfetto/ext/tracing/core/tracing_service.h"
71686 // gen_amalgamated expanded: #include "perfetto/ext/tracing/ipc/consumer_ipc_client.h"
71687 // gen_amalgamated expanded: #include "perfetto/ext/tracing/ipc/default_socket.h"
71688 // gen_amalgamated expanded: #include "perfetto/ext/tracing/ipc/producer_ipc_client.h"
71689 
71690 namespace perfetto {
71691 namespace internal {
71692 
71693 // static
GetInstance()71694 TracingBackend* SystemTracingBackend::GetInstance() {
71695   static auto* instance = new SystemTracingBackend();
71696   return instance;
71697 }
71698 
SystemTracingBackend()71699 SystemTracingBackend::SystemTracingBackend() {}
71700 
ConnectProducer(const ConnectProducerArgs & args)71701 std::unique_ptr<ProducerEndpoint> SystemTracingBackend::ConnectProducer(
71702     const ConnectProducerArgs& args) {
71703   PERFETTO_DCHECK(args.task_runner->RunsTasksOnCurrentThread());
71704 
71705   auto endpoint = ProducerIPCClient::Connect(
71706       GetProducerSocket(), args.producer, args.producer_name, args.task_runner,
71707       TracingService::ProducerSMBScrapingMode::kEnabled,
71708       args.shmem_size_hint_bytes, args.shmem_page_size_hint_bytes, nullptr,
71709       nullptr, ProducerIPCClient::ConnectionFlags::kRetryIfUnreachable);
71710   PERFETTO_CHECK(endpoint);
71711   return endpoint;
71712 }
71713 
ConnectConsumer(const ConnectConsumerArgs & args)71714 std::unique_ptr<ConsumerEndpoint> SystemTracingBackend::ConnectConsumer(
71715     const ConnectConsumerArgs& args) {
71716   auto endpoint = ConsumerIPCClient::Connect(GetConsumerSocket(), args.consumer,
71717                                              args.task_runner);
71718   PERFETTO_CHECK(endpoint);
71719   return endpoint;
71720 }
71721 
71722 }  // namespace internal
71723 }  // namespace perfetto
71724 // gen_amalgamated begin source: src/tracing/platform_posix.cc
71725 /*
71726  * Copyright (C) 2019 The Android Open Source Project
71727  *
71728  * Licensed under the Apache License, Version 2.0 (the "License");
71729  * you may not use this file except in compliance with the License.
71730  * You may obtain a copy of the License at
71731  *
71732  *      http://www.apache.org/licenses/LICENSE-2.0
71733  *
71734  * Unless required by applicable law or agreed to in writing, software
71735  * distributed under the License is distributed on an "AS IS" BASIS,
71736  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
71737  * See the License for the specific language governing permissions and
71738  * limitations under the License.
71739  */
71740 
71741 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
71742 
71743 #if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) ||   \
71744     PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \
71745     PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
71746 
71747 // gen_amalgamated expanded: #include "perfetto/ext/base/file_utils.h"
71748 // gen_amalgamated expanded: #include "perfetto/ext/base/thread_task_runner.h"
71749 // gen_amalgamated expanded: #include "perfetto/tracing/internal/tracing_tls.h"
71750 // gen_amalgamated expanded: #include "perfetto/tracing/platform.h"
71751 // gen_amalgamated expanded: #include "perfetto/tracing/trace_writer_base.h"
71752 
71753 #include <pthread.h>
71754 #include <stdlib.h>
71755 
71756 namespace perfetto {
71757 
71758 namespace {
71759 
71760 class PlatformPosix : public Platform {
71761  public:
71762   PlatformPosix();
71763   ~PlatformPosix() override;
71764 
71765   ThreadLocalObject* GetOrCreateThreadLocalObject() override;
71766 
71767   std::unique_ptr<base::TaskRunner> CreateTaskRunner(
71768       const CreateTaskRunnerArgs&) override;
71769   std::string GetCurrentProcessName() override;
71770 
71771  private:
71772   pthread_key_t tls_key_{};
71773 };
71774 
71775 PlatformPosix* g_instance = nullptr;
71776 
71777 using ThreadLocalObject = Platform::ThreadLocalObject;
71778 
PlatformPosix()71779 PlatformPosix::PlatformPosix() {
71780   PERFETTO_CHECK(!g_instance);
71781   g_instance = this;
71782   auto tls_dtor = [](void* obj) {
71783     // The Posix TLS implementation resets the key before calling this dtor.
71784     // Here we re-reset it to the object we are about to delete. This is to
71785     // handle re-entrant usages of tracing in the PostTask done during the dtor
71786     // (see comments in TracingTLS::~TracingTLS()). Chromium's platform
71787     // implementation (which does NOT use this platform impl) has a similar
71788     // workaround (https://crrev.com/c/2748300).
71789     pthread_setspecific(g_instance->tls_key_, obj);
71790     delete static_cast<ThreadLocalObject*>(obj);
71791     pthread_setspecific(g_instance->tls_key_, nullptr);
71792   };
71793   PERFETTO_CHECK(pthread_key_create(&tls_key_, tls_dtor) == 0);
71794 }
71795 
~PlatformPosix()71796 PlatformPosix::~PlatformPosix() {
71797   pthread_key_delete(tls_key_);
71798   g_instance = nullptr;
71799 }
71800 
GetOrCreateThreadLocalObject()71801 ThreadLocalObject* PlatformPosix::GetOrCreateThreadLocalObject() {
71802   // In chromium this should be implemented using base::ThreadLocalStorage.
71803   void* tls_ptr = pthread_getspecific(tls_key_);
71804 
71805   // This is needed to handle re-entrant calls during TLS dtor.
71806   // See comments in platform.cc and aosp/1712371 .
71807   ThreadLocalObject* tls = static_cast<ThreadLocalObject*>(tls_ptr);
71808   if (!tls) {
71809     tls = ThreadLocalObject::CreateInstance().release();
71810     pthread_setspecific(tls_key_, tls);
71811   }
71812   return tls;
71813 }
71814 
CreateTaskRunner(const CreateTaskRunnerArgs & args)71815 std::unique_ptr<base::TaskRunner> PlatformPosix::CreateTaskRunner(
71816     const CreateTaskRunnerArgs& args) {
71817   return std::unique_ptr<base::TaskRunner>(new base::ThreadTaskRunner(
71818       base::ThreadTaskRunner::CreateAndStart(args.name_for_debugging)));
71819 }
71820 
GetCurrentProcessName()71821 std::string PlatformPosix::GetCurrentProcessName() {
71822 #if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
71823     PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
71824   std::string cmdline;
71825   base::ReadFile("/proc/self/cmdline", &cmdline);
71826   return cmdline.substr(0, cmdline.find('\0'));
71827 #elif PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
71828   return std::string(getprogname());
71829 #else
71830   return "unknown_producer";
71831 #endif
71832 }
71833 
71834 }  // namespace
71835 
71836 // static
GetDefaultPlatform()71837 Platform* Platform::GetDefaultPlatform() {
71838   static PlatformPosix* instance = new PlatformPosix();
71839   return instance;
71840 }
71841 
71842 }  // namespace perfetto
71843 #endif  // OS_LINUX || OS_ANDROID || OS_APPLE
71844 // gen_amalgamated begin source: src/tracing/platform_windows.cc
71845 /*
71846  * Copyright (C) 2021 The Android Open Source Project
71847  *
71848  * Licensed under the Apache License, Version 2.0 (the "License");
71849  * you may not use this file except in compliance with the License.
71850  * You may obtain a copy of the License at
71851  *
71852  *      http://www.apache.org/licenses/LICENSE-2.0
71853  *
71854  * Unless required by applicable law or agreed to in writing, software
71855  * distributed under the License is distributed on an "AS IS" BASIS,
71856  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
71857  * See the License for the specific language governing permissions and
71858  * limitations under the License.
71859  */
71860 
71861 // gen_amalgamated expanded: #include "perfetto/base/build_config.h"
71862 
71863 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
71864 
71865 #include <Windows.h>
71866 
71867 // gen_amalgamated expanded: #include "perfetto/ext/base/thread_task_runner.h"
71868 // gen_amalgamated expanded: #include "perfetto/tracing/internal/tracing_tls.h"
71869 // gen_amalgamated expanded: #include "perfetto/tracing/platform.h"
71870 
71871 // Thread Termination Callbacks.
71872 // Windows doesn't support a per-thread destructor with its
71873 // TLS primitives. So, we build it manually by inserting a
71874 // function to be called on each thread's exit.
71875 // This magic is from chromium's base/threading/thread_local_storage_win.cc
71876 // which in turn is from http://www.codeproject.com/threads/tls.asp.
71877 
71878 #ifdef _WIN64
71879 #pragma comment(linker, "/INCLUDE:_tls_used")
71880 #pragma comment(linker, "/INCLUDE:perfetto_thread_callback_base")
71881 #else
71882 #pragma comment(linker, "/INCLUDE:__tls_used")
71883 #pragma comment(linker, "/INCLUDE:_perfetto_thread_callback_base")
71884 #endif
71885 
71886 namespace perfetto {
71887 
71888 namespace {
71889 
71890 class PlatformWindows : public Platform {
71891  public:
71892   static PlatformWindows* instance;
71893   PlatformWindows();
71894   ~PlatformWindows() override;
71895 
71896   ThreadLocalObject* GetOrCreateThreadLocalObject() override;
71897   std::unique_ptr<base::TaskRunner> CreateTaskRunner(
71898       const CreateTaskRunnerArgs&) override;
71899   std::string GetCurrentProcessName() override;
71900   void OnThreadExit();
71901 
71902  private:
71903   DWORD tls_key_{};
71904 };
71905 
71906 using ThreadLocalObject = Platform::ThreadLocalObject;
71907 
71908 // static
71909 PlatformWindows* PlatformWindows::instance = nullptr;
71910 
PlatformWindows()71911 PlatformWindows::PlatformWindows() {
71912   instance = this;
71913   tls_key_ = ::TlsAlloc();
71914   PERFETTO_CHECK(tls_key_ != TLS_OUT_OF_INDEXES);
71915 }
71916 
~PlatformWindows()71917 PlatformWindows::~PlatformWindows() {
71918   ::TlsFree(tls_key_);
71919   instance = nullptr;
71920 }
71921 
OnThreadExit()71922 void PlatformWindows::OnThreadExit() {
71923   auto tls = static_cast<ThreadLocalObject*>(::TlsGetValue(tls_key_));
71924   if (tls) {
71925     // At this point we rely on the TLS object to be still set to the TracingTLS
71926     // we are deleting. See comments in TracingTLS::~TracingTLS().
71927     delete tls;
71928   }
71929 }
71930 
GetOrCreateThreadLocalObject()71931 ThreadLocalObject* PlatformWindows::GetOrCreateThreadLocalObject() {
71932   void* tls_ptr = ::TlsGetValue(tls_key_);
71933 
71934   auto* tls = static_cast<ThreadLocalObject*>(tls_ptr);
71935   if (!tls) {
71936     tls = ThreadLocalObject::CreateInstance().release();
71937     ::TlsSetValue(tls_key_, tls);
71938   }
71939   return tls;
71940 }
71941 
CreateTaskRunner(const CreateTaskRunnerArgs & args)71942 std::unique_ptr<base::TaskRunner> PlatformWindows::CreateTaskRunner(
71943     const CreateTaskRunnerArgs& args) {
71944   return std::unique_ptr<base::TaskRunner>(new base::ThreadTaskRunner(
71945       base::ThreadTaskRunner::CreateAndStart(args.name_for_debugging)));
71946 }
71947 
GetCurrentProcessName()71948 std::string PlatformWindows::GetCurrentProcessName() {
71949   char buf[MAX_PATH];
71950   auto len = ::GetModuleFileNameA(nullptr /*current*/, buf, sizeof(buf));
71951   std::string name(buf, static_cast<size_t>(len));
71952   size_t sep = name.find_last_of('\\');
71953   if (sep != std::string::npos)
71954     name = name.substr(sep + 1);
71955   return name;
71956 }
71957 
71958 }  // namespace
71959 
71960 // static
GetDefaultPlatform()71961 Platform* Platform::GetDefaultPlatform() {
71962   static PlatformWindows* thread_safe_init_instance = new PlatformWindows();
71963   return thread_safe_init_instance;
71964 }
71965 
71966 }  // namespace perfetto
71967 
71968 // -----------------------
71969 // Thread-local destructor
71970 // -----------------------
71971 
71972 // .CRT$XLA to .CRT$XLZ is an array of PIMAGE_TLS_CALLBACK pointers that are
71973 // called automatically by the OS loader code (not the CRT) when the module is
71974 // loaded and on thread creation. They are NOT called if the module has been
71975 // loaded by a LoadLibrary() call. It must have implicitly been loaded at
71976 // process startup.
71977 // See VC\crt\src\tlssup.c for reference.
71978 
71979 // extern "C" suppresses C++ name mangling so we know the symbol name for the
71980 // linker /INCLUDE:symbol pragma above.
71981 extern "C" {
71982 // The linker must not discard perfetto_thread_callback_base. (We force a
71983 // reference to this variable with a linker /INCLUDE:symbol pragma to ensure
71984 // that.) If this variable is discarded, the OnThreadExit function will never be
71985 // called.
71986 
71987 void NTAPI PerfettoOnThreadExit(PVOID, DWORD, PVOID);
PerfettoOnThreadExit(PVOID module,DWORD reason,PVOID reserved)71988 void NTAPI PerfettoOnThreadExit(PVOID module, DWORD reason, PVOID reserved) {
71989   if (reason == DLL_THREAD_DETACH || reason == DLL_PROCESS_DETACH) {
71990     if (perfetto::PlatformWindows::instance)
71991       perfetto::PlatformWindows::instance->OnThreadExit();
71992   }
71993 }
71994 
71995 #ifdef _WIN64
71996 
71997 // .CRT section is merged with .rdata on x64 so it must be constant data.
71998 #pragma const_seg(".CRT$XLP")
71999 
72000 // When defining a const variable, it must have external linkage to be sure the
72001 // linker doesn't discard it.
72002 extern const PIMAGE_TLS_CALLBACK perfetto_thread_callback_base;
72003 const PIMAGE_TLS_CALLBACK perfetto_thread_callback_base = PerfettoOnThreadExit;
72004 
72005 // Reset the default section.
72006 #pragma const_seg()
72007 
72008 #else  // _WIN64
72009 
72010 #pragma data_seg(".CRT$XLP")
72011 PIMAGE_TLS_CALLBACK perfetto_thread_callback_base = PerfettoOnThreadExit;
72012 // Reset the default section.
72013 #pragma data_seg()
72014 
72015 #endif  // _WIN64
72016 
72017 }  // extern "C"
72018 
72019 #endif  // OS_WIN
72020 
72021