// Copyright (C) 2019 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// This file is automatically generated by gen_amalgamated. Do not edit.

// gen_amalgamated: predefined macros
#if !defined(PERFETTO_IMPLEMENTATION)
#define PERFETTO_IMPLEMENTATION
#endif
#include "perfetto.h"
// gen_amalgamated begin source: src/base/default_platform.cc
// gen_amalgamated begin header: include/perfetto/ext/base/platform.h
/*
 * Copyright (C) 2023 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef INCLUDE_PERFETTO_EXT_BASE_PLATFORM_H_
#define INCLUDE_PERFETTO_EXT_BASE_PLATFORM_H_

namespace perfetto {
namespace base {
namespace platform {

// Executed before entering a syscall (e.g. poll, read, write etc) which might
// block.
// This is overridden in Google internal builds for dealing with userspace
// scheduling.
void BeforeMaybeBlockingSyscall();

// Executed after entering a syscall (e.g. poll, read, write etc) which might
// block.
// This is overridden in Google internal builds for dealing with userspace
// scheduling.
void AfterMaybeBlockingSyscall();

}  // namespace platform
}  // namespace base
}  // namespace perfetto

#endif  // INCLUDE_PERFETTO_EXT_BASE_PLATFORM_H_
/*
 * Copyright (C) 2023 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// gen_amalgamated expanded: #include "perfetto/ext/base/platform.h"

namespace perfetto {
namespace base {
namespace platform {

// This is a no-op outside of Google3 where we have some custom logic to deal
// with the userspace scheduler.
void BeforeMaybeBlockingSyscall() {}

// This is a no-op outside of Google3 where we have some custom logic to deal
// with the userspace scheduler.
void AfterMaybeBlockingSyscall() {}

}  // namespace platform
}  // namespace base
}  // namespace perfetto
// gen_amalgamated begin source: src/base/android_utils.cc
// gen_amalgamated begin header: include/perfetto/ext/base/android_utils.h
/*
 * Copyright (C) 2021 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef INCLUDE_PERFETTO_EXT_BASE_ANDROID_UTILS_H_
#define INCLUDE_PERFETTO_EXT_BASE_ANDROID_UTILS_H_

#include <string>

// gen_amalgamated expanded: #include "perfetto/base/build_config.h"

namespace perfetto {
namespace base {

#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)

// Returns the value of the Android system property named `name`. If the
// property does not exist, returns an empty string (a non-existing property is
// the same as a property with an empty value for this API).
std::string GetAndroidProp(const char* name);

#endif  // PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)

}  // namespace base
}  // namespace perfetto

#endif  // INCLUDE_PERFETTO_EXT_BASE_ANDROID_UTILS_H_
/*
 * Copyright (C) 2021 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// gen_amalgamated expanded: #include "perfetto/ext/base/android_utils.h"

// gen_amalgamated expanded: #include "perfetto/base/build_config.h"

#include <string>

#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
#include <sys/system_properties.h>
#endif

// gen_amalgamated expanded: #include "perfetto/base/compiler.h"
// gen_amalgamated expanded: #include "perfetto/base/logging.h"

namespace perfetto {
namespace base {

#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)

std::string GetAndroidProp(const char* name) {
  std::string ret;
#if __ANDROID_API__ >= 26
  const prop_info* pi = __system_property_find(name);
  if (!pi) {
    return ret;
  }
  __system_property_read_callback(
      pi,
      [](void* dst_void, const char*, const char* value, uint32_t) {
        std::string& dst = *static_cast<std::string*>(dst_void);
        dst = value;
      },
      &ret);
#else  // __ANDROID_API__ < 26
  char value_buf[PROP_VALUE_MAX];
  int len = __system_property_get(name, value_buf);
  if (len > 0 && static_cast<size_t>(len) < sizeof(value_buf)) {
    ret = std::string(value_buf, static_cast<size_t>(len));
  }
#endif
  return ret;
}

#endif  // PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)

}  // namespace base
}  // namespace perfetto
// gen_amalgamated begin source: src/base/base64.cc
// gen_amalgamated begin header: include/perfetto/ext/base/base64.h
// gen_amalgamated begin header: include/perfetto/ext/base/string_view.h
// gen_amalgamated begin header: include/perfetto/ext/base/hash.h
/*
 * Copyright (C) 2019 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef INCLUDE_PERFETTO_EXT_BASE_HASH_H_
#define INCLUDE_PERFETTO_EXT_BASE_HASH_H_

#include <stddef.h>
#include <stdint.h>
#include <string>
#include <type_traits>
#include <utility>

namespace perfetto {
namespace base {

// A helper class which computes a 64-bit hash of the input data.
// The algorithm used is FNV-1a as it is fast and easy to implement and has
// relatively few collisions.
// WARNING: This hash function should not be used for any cryptographic purpose.
class Hasher {
 public:
  // Creates an empty hash object
  Hasher() {}

  // Hashes a numeric value.
  template <
      typename T,
      typename std::enable_if<std::is_arithmetic<T>::value, bool>::type = true>
  void Update(T data) {
    Update(reinterpret_cast<const char*>(&data), sizeof(data));
  }

  // Using the loop instead of "Update(str, strlen(str))" to avoid looping twice
  void Update(const char* str) {
    for (const auto* p = str; *p; ++p)
      Update(*p);
  }

  // Hashes a byte array.
  void Update(const char* data, size_t size) {
    for (size_t i = 0; i < size; i++) {
      result_ ^= static_cast<uint8_t>(data[i]);
      // Note: Arithmetic overflow of unsigned integers is well defined in C++
      // standard unlike signed integers.
      // https://stackoverflow.com/a/41280273
      result_ *= kFnv1a64Prime;
    }
  }

  // Allow hashing anything that has a |data| field, a |size| field,
  // and has the kHashable trait (e.g., base::StringView).
  template <typename T, typename = std::enable_if_t<T::kHashable>>
  void Update(const T& t) {
    Update(t.data(), t.size());
  }

  void Update(const std::string& s) { Update(s.data(), s.size()); }

  uint64_t digest() const { return result_; }

  // Usage:
  // uint64_t hashed_value = Hash::Combine(33, false, "ABC", 458L, 3u, 'x');
  template <typename... Ts>
  static uint64_t Combine(Ts&&... args) {
    Hasher hasher;
    hasher.UpdateAll(std::forward<Ts>(args)...);
    return hasher.digest();
  }

  // `hasher.UpdateAll(33, false, "ABC")` is shorthand for:
  // `hasher.Update(33); hasher.Update(false); hasher.Update("ABC");`
  void UpdateAll() {}

  template <typename T, typename... Ts>
  void UpdateAll(T&& arg, Ts&&... args) {
    Update(arg);
    UpdateAll(std::forward<Ts>(args)...);
  }

 private:
  static constexpr uint64_t kFnv1a64OffsetBasis = 0xcbf29ce484222325;
  static constexpr uint64_t kFnv1a64Prime = 0x100000001b3;

  uint64_t result_ = kFnv1a64OffsetBasis;
};

// This is for using already-hashed key into std::unordered_map and avoid the
// cost of re-hashing. Example:
// unordered_map<uint64_t, Value, AlreadyHashed> my_map.
template <typename T>
struct AlreadyHashed {
  size_t operator()(const T& x) const { return static_cast<size_t>(x); }
};

// base::Hash uses base::Hasher for integer values and falls base to std::hash
// for other types. This is needed as std::hash for integers is just the
// identity function and Perfetto uses open-addressing hash table, which are
// very sensitive to hash quality and are known to degrade in performance
// when using std::hash.
template <typename T>
struct Hash {
  // Version for ints, using base::Hasher.
  template <typename U = T>
  auto operator()(const U& x) ->
      typename std::enable_if<std::is_arithmetic<U>::value, size_t>::type
      const {
    Hasher hash;
    hash.Update(x);
    return static_cast<size_t>(hash.digest());
  }

  // Version for non-ints, falling back to std::hash.
  template <typename U = T>
  auto operator()(const U& x) ->
      typename std::enable_if<!std::is_arithmetic<U>::value, size_t>::type
      const {
    return std::hash<U>()(x);
  }
};

}  // namespace base
}  // namespace perfetto

#endif  // INCLUDE_PERFETTO_EXT_BASE_HASH_H_
/*
 * Copyright (C) 2018 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef INCLUDE_PERFETTO_EXT_BASE_STRING_VIEW_H_
#define INCLUDE_PERFETTO_EXT_BASE_STRING_VIEW_H_

#include <string.h>

#include <algorithm>
#include <string>

// gen_amalgamated expanded: #include "perfetto/base/build_config.h"
// gen_amalgamated expanded: #include "perfetto/base/logging.h"
// gen_amalgamated expanded: #include "perfetto/ext/base/hash.h"

namespace perfetto {
namespace base {

// A string-like object that refers to a non-owned piece of memory.
// Strings are internally NOT null terminated.
class StringView {
 public:
  // Allow hashing with base::Hash.
  static constexpr bool kHashable = true;
  static constexpr size_t npos = static_cast<size_t>(-1);

  StringView() : data_(nullptr), size_(0) {}
  StringView(const StringView&) = default;
  StringView& operator=(const StringView&) = default;
  StringView(const char* data, size_t size) : data_(data), size_(size) {
    PERFETTO_DCHECK(size == 0 || data != nullptr);
  }

  // Allow implicit conversion from any class that has a |data| and |size| field
  // and has the kConvertibleToStringView trait (e.g., protozero::ConstChars).
  template <typename T, typename = std::enable_if<T::kConvertibleToStringView>>
  StringView(const T& x) : StringView(x.data, x.size) {
    PERFETTO_DCHECK(x.size == 0 || x.data != nullptr);
  }

  // Creates a StringView from a null-terminated C string.
  // Deliberately not "explicit".
  StringView(const char* cstr) : data_(cstr), size_(strlen(cstr)) {
    PERFETTO_DCHECK(cstr != nullptr);
  }

  // This instead has to be explicit, as creating a StringView out of a
  // std::string can be subtle.
  explicit StringView(const std::string& str)
      : data_(str.data()), size_(str.size()) {}

  bool empty() const { return size_ == 0; }
  size_t size() const { return size_; }
  const char* data() const { return data_; }
  const char* begin() const { return data_; }
  const char* end() const { return data_ + size_; }

  char at(size_t pos) const {
    PERFETTO_DCHECK(pos < size_);
    return data_[pos];
  }

  size_t find(char c, size_t start_pos = 0) const {
    for (size_t i = start_pos; i < size_; ++i) {
      if (data_[i] == c)
        return i;
    }
    return npos;
  }

  size_t find(const StringView& str, size_t start_pos = 0) const {
    if (start_pos > size())
      return npos;
    auto it = std::search(begin() + start_pos, end(), str.begin(), str.end());
    size_t pos = static_cast<size_t>(it - begin());
    return pos + str.size() <= size() ? pos : npos;
  }

  size_t find(const char* str, size_t start_pos = 0) const {
    return find(StringView(str), start_pos);
  }

  size_t rfind(char c) const {
    for (size_t i = size_; i > 0; --i) {
      if (data_[i - 1] == c)
        return i - 1;
    }
    return npos;
  }

  StringView substr(size_t pos, size_t count = npos) const {
    if (pos >= size_)
      return StringView("", 0);
    size_t rcount = std::min(count, size_ - pos);
    return StringView(data_ + pos, rcount);
  }

  bool CaseInsensitiveEq(const StringView& other) const {
    if (size() != other.size())
      return false;
    if (size() == 0)
      return true;
#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
    return _strnicmp(data(), other.data(), size()) == 0;
#else
    return strncasecmp(data(), other.data(), size()) == 0;
#endif
  }

  bool StartsWith(const StringView& other) const {
    if (other.size() == 0)
      return true;
    if (size() == 0)
      return false;
    if (other.size() > size())
      return false;
    return memcmp(data(), other.data(), other.size()) == 0;
  }

  bool EndsWith(const StringView& other) const {
    if (other.size() == 0)
      return true;
    if (size() == 0)
      return false;
    if (other.size() > size())
      return false;
    size_t off = size() - other.size();
    return memcmp(data() + off, other.data(), other.size()) == 0;
  }

  std::string ToStdString() const {
    return size_ == 0 ? "" : std::string(data_, size_);
  }

  uint64_t Hash() const {
    base::Hasher hasher;
    hasher.Update(data_, size_);
    return hasher.digest();
  }

 private:
  const char* data_ = nullptr;
  size_t size_ = 0;
};

inline bool operator==(const StringView& x, const StringView& y) {
  if (x.size() != y.size())
    return false;
  if (x.size() == 0)
    return true;
  return memcmp(x.data(), y.data(), x.size()) == 0;
}

inline bool operator!=(const StringView& x, const StringView& y) {
  return !(x == y);
}

inline bool operator<(const StringView& x, const StringView& y) {
  auto size = std::min(x.size(), y.size());
  if (size == 0)
    return x.size() < y.size();
  int result = memcmp(x.data(), y.data(), size);
  return result < 0 || (result == 0 && x.size() < y.size());
}

inline bool operator>=(const StringView& x, const StringView& y) {
  return !(x < y);
}

inline bool operator>(const StringView& x, const StringView& y) {
  return y < x;
}

inline bool operator<=(const StringView& x, const StringView& y) {
  return !(y < x);
}

}  // namespace base
}  // namespace perfetto

template <>
struct std::hash<::perfetto::base::StringView> {
  size_t operator()(const ::perfetto::base::StringView& sv) const {
    return static_cast<size_t>(sv.Hash());
  }
};

#endif  // INCLUDE_PERFETTO_EXT_BASE_STRING_VIEW_H_
// gen_amalgamated begin header: include/perfetto/ext/base/utils.h
// gen_amalgamated begin header: include/perfetto/ext/base/sys_types.h
/*
 * Copyright (C) 2022 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef INCLUDE_PERFETTO_EXT_BASE_SYS_TYPES_H_
#define INCLUDE_PERFETTO_EXT_BASE_SYS_TYPES_H_

// This headers deals with sys types commonly used in the codebase that are
// missing on Windows.

#include <sys/types.h>
#include <cstdint>

// gen_amalgamated expanded: #include "perfetto/base/build_config.h"

#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)

#if !PERFETTO_BUILDFLAG(PERFETTO_COMPILER_GCC)
// MinGW has these. clang-cl and MSVC, which use just the Windows SDK, don't.
using uid_t = int;
using pid_t = int;
#endif  // !GCC

#if defined(_WIN64)
using ssize_t = int64_t;
#else
using ssize_t = long;
#endif  // _WIN64

#endif  // OS_WIN

#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) && !defined(AID_SHELL)
// From libcutils' android_filesystem_config.h .
#define AID_SHELL 2000
#endif

namespace perfetto {
namespace base {

// The machine ID used in the tracing core.
using MachineID = uint32_t;
// The default value reserved for the host trace.
constexpr MachineID kDefaultMachineID = 0;

constexpr uid_t kInvalidUid = static_cast<uid_t>(-1);
constexpr pid_t kInvalidPid = static_cast<pid_t>(-1);

}  // namespace base
}  // namespace perfetto

#endif  // INCLUDE_PERFETTO_EXT_BASE_SYS_TYPES_H_
/*
 * Copyright (C) 2017 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef INCLUDE_PERFETTO_EXT_BASE_UTILS_H_
#define INCLUDE_PERFETTO_EXT_BASE_UTILS_H_

#include <errno.h>
#include <stddef.h>
#include <stdint.h>
#include <stdlib.h>

#include <atomic>
#include <functional>
#include <memory>
#include <string>

// gen_amalgamated expanded: #include "perfetto/base/build_config.h"
// gen_amalgamated expanded: #include "perfetto/base/compiler.h"
// gen_amalgamated expanded: #include "perfetto/ext/base/sys_types.h"

#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
// Even if Windows has errno.h, the all syscall-restart behavior does not apply.
// Trying to handle EINTR can cause more harm than good if errno is left stale.
// Chromium does the same.
#define PERFETTO_EINTR(x) (x)
#else
#define PERFETTO_EINTR(x)                                   \
  ([&] {                                                    \
    decltype(x) eintr_wrapper_result;                       \
    do {                                                    \
      eintr_wrapper_result = (x);                           \
    } while (eintr_wrapper_result == -1 && errno == EINTR); \
    return eintr_wrapper_result;                            \
  }())
#endif

namespace perfetto {
namespace base {

namespace internal {
extern std::atomic<uint32_t> g_cached_page_size;
uint32_t GetSysPageSizeSlowpath();
}  // namespace internal

// Returns the system's page size. Use this when dealing with mmap, madvise and
// similar mm-related syscalls.
// This function might be called in hot paths. Avoid calling getpagesize() all
// the times, in many implementations getpagesize() calls sysconf() which is
// not cheap.
inline uint32_t GetSysPageSize() {
  const uint32_t page_size =
      internal::g_cached_page_size.load(std::memory_order_relaxed);
  return page_size != 0 ? page_size : internal::GetSysPageSizeSlowpath();
}

template <typename T, size_t TSize>
constexpr size_t ArraySize(const T (&)[TSize]) {
  return TSize;
}

// Function object which invokes 'free' on its parameter, which must be
// a pointer. Can be used to store malloc-allocated pointers in std::unique_ptr:
//
// std::unique_ptr<int, base::FreeDeleter> foo_ptr(
//     static_cast<int*>(malloc(sizeof(int))));
struct FreeDeleter {
  inline void operator()(void* ptr) const { free(ptr); }
};

template <typename T>
constexpr T AssumeLittleEndian(T value) {
#if !PERFETTO_IS_LITTLE_ENDIAN()
  static_assert(false, "Unimplemented on big-endian archs");
#endif
  return value;
}

// Round up |size| to a multiple of |alignment| (must be a power of two).
inline constexpr size_t AlignUp(size_t size, size_t alignment) {
  return (size + alignment - 1) & ~(alignment - 1);
}

// TODO(primiano): clean this up and move all existing usages to the constexpr
// version above.
template <size_t alignment>
constexpr size_t AlignUp(size_t size) {
  static_assert((alignment & (alignment - 1)) == 0, "alignment must be a pow2");
  return AlignUp(size, alignment);
}

inline bool IsAgain(int err) {
  return err == EAGAIN || err == EWOULDBLOCK;
}

// setenv(2)-equivalent. Deals with Windows vs Posix discrepancies.
void SetEnv(const std::string& key, const std::string& value);

// unsetenv(2)-equivalent. Deals with Windows vs Posix discrepancies.
void UnsetEnv(const std::string& key);

// Calls mallopt(M_PURGE, 0) on Android. Does nothing on other platforms.
// This forces the allocator to release freed memory. This is used to work
// around various Scudo inefficiencies. See b/170217718.
void MaybeReleaseAllocatorMemToOS();

// geteuid() on POSIX OSes, returns 0 on Windows (See comment in utils.cc).
uid_t GetCurrentUserId();

// Forks the process.
// Parent: prints the PID of the child, calls |parent_cb| and exits from the
//         process with its return value.
// Child: redirects stdio onto /dev/null, chdirs into / and returns.
void Daemonize(std::function<int()> parent_cb);

// Returns the path of the current executable, e.g. /foo/bar/exe.
std::string GetCurExecutablePath();

// Returns the directory where the current executable lives in, e.g. /foo/bar.
// This is independent of cwd().
std::string GetCurExecutableDir();

// Memory returned by AlignedAlloc() must be freed via AlignedFree() not just
// free. It makes a difference on Windows where _aligned_malloc() and
// _aligned_free() must be paired.
// Prefer using the AlignedAllocTyped() below which takes care of the pairing.
void* AlignedAlloc(size_t alignment, size_t size);
void AlignedFree(void*);

// A RAII version of the above, which takes care of pairing Aligned{Alloc,Free}.
template <typename T>
struct AlignedDeleter {
  inline void operator()(T* ptr) const { AlignedFree(ptr); }
};

// The remove_extent<T> here and below is to allow defining unique_ptr<T[]>.
// As per https://en.cppreference.com/w/cpp/memory/unique_ptr the Deleter takes
// always a T*, not a T[]*.
template <typename T>
using AlignedUniquePtr =
    std::unique_ptr<T, AlignedDeleter<typename std::remove_extent<T>::type>>;

template <typename T>
AlignedUniquePtr<T> AlignedAllocTyped(size_t n_membs) {
  using TU = typename std::remove_extent<T>::type;
  return AlignedUniquePtr<T>(
      static_cast<TU*>(AlignedAlloc(alignof(TU), sizeof(TU) * n_membs)));
}

// A RAII wrapper to invoke a function when leaving a function/scope.
template <typename Func>
class OnScopeExitWrapper {
 public:
  explicit OnScopeExitWrapper(Func f) : f_(std::move(f)), active_(true) {}
  OnScopeExitWrapper(OnScopeExitWrapper&& other) noexcept
      : f_(std::move(other.f_)), active_(other.active_) {
    other.active_ = false;
  }
  ~OnScopeExitWrapper() {
    if (active_)
      f_();
  }

 private:
  Func f_;
  bool active_;
};

template <typename Func>
PERFETTO_WARN_UNUSED_RESULT OnScopeExitWrapper<Func> OnScopeExit(Func f) {
  return OnScopeExitWrapper<Func>(std::move(f));
}

// Returns a xxd-style hex dump (hex + ascii chars) of the input data.
std::string HexDump(const void* data, size_t len, size_t bytes_per_line = 16);
inline std::string HexDump(const std::string& data,
                           size_t bytes_per_line = 16) {
  return HexDump(data.data(), data.size(), bytes_per_line);
}

}  // namespace base
}  // namespace perfetto

#endif  // INCLUDE_PERFETTO_EXT_BASE_UTILS_H_
/*
 * Copyright (C) 2021 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef INCLUDE_PERFETTO_EXT_BASE_BASE64_H_
#define INCLUDE_PERFETTO_EXT_BASE_BASE64_H_

#include <optional>
#include <string>

// gen_amalgamated expanded: #include "perfetto/ext/base/string_view.h"
// gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"  // For ssize_t.

namespace perfetto {
namespace base {

// Returns the length of the destination string (included '=' padding).
// Does NOT include the size of the string null terminator.
inline size_t Base64EncSize(size_t src_size) {
  return (src_size + 2) / 3 * 4;
}

// Returns the upper bound on the length of the destination buffer.
// The actual decoded length might be <= the number returned here.
inline size_t Base64DecSize(size_t src_size) {
  return (src_size + 3) / 4 * 3;
}

// Does NOT null-terminate |dst|.
ssize_t Base64Encode(const void* src,
                     size_t src_size,
                     char* dst,
                     size_t dst_size);

std::string Base64Encode(const void* src, size_t src_size);

inline std::string Base64Encode(StringView sv) {
  return Base64Encode(sv.data(), sv.size());
}

// Returns -1 in case of failure.
ssize_t Base64Decode(const char* src,
                     size_t src_size,
                     uint8_t* dst,
                     size_t dst_size);

std::optional<std::string> Base64Decode(const char* src, size_t src_size);

inline std::optional<std::string> Base64Decode(StringView sv) {
  return Base64Decode(sv.data(), sv.size());
}

}  // namespace base
}  // namespace perfetto

#endif  // INCLUDE_PERFETTO_EXT_BASE_BASE64_H_
/*
 * Copyright (C) 2021 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// gen_amalgamated expanded: #include "perfetto/ext/base/base64.h"

namespace perfetto {
namespace base {

namespace {

constexpr char kPadding = '=';

constexpr char kEncTable[] =
    "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
static_assert(sizeof(kEncTable) == (1u << 6) + sizeof('\0'), "Bad table size");

// Maps an ASCII character to its 6-bit value. It only contains translations
// from '+' to 'z'. Supports the standard (+/) and URL-safe (-_) alphabets.
constexpr uint8_t kX = 0xff;  // Value used for invalid characters
constexpr uint8_t kDecTable[] = {
    62, kX, 62, kX, 63, 52, 53, 54, 55, 56,  // 00 - 09
    57, 58, 59, 60, 61, kX, kX, kX, 0,  kX,  // 10 - 19
    kX, kX, 0,  1,  2,  3,  4,  5,  6,  7,   // 20 - 29
    8,  9,  10, 11, 12, 13, 14, 15, 16, 17,  // 30 - 39
    18, 19, 20, 21, 22, 23, 24, 25, kX, kX,  // 40 - 49
    kX, kX, 63, kX, 26, 27, 28, 29, 30, 31,  // 50 - 59
    32, 33, 34, 35, 36, 37, 38, 39, 40, 41,  // 60 - 69
    42, 43, 44, 45, 46, 47, 48, 49, 50, 51,  // 70 - 79
};
constexpr char kMinDecChar = '+';
constexpr char kMaxDecChar = 'z';
static_assert(kMaxDecChar - kMinDecChar <= sizeof(kDecTable), "Bad table size");

inline uint8_t DecodeChar(char c) {
  if (c < kMinDecChar || c > kMaxDecChar)
    return kX;
  return kDecTable[c - kMinDecChar];
}

}  // namespace

ssize_t Base64Encode(const void* src,
                     size_t src_size,
                     char* dst,
                     size_t dst_size) {
  const size_t padded_dst_size = Base64EncSize(src_size);
  if (dst_size < padded_dst_size)
    return -1;  // Not enough space in output.

  const uint8_t* rd = static_cast<const uint8_t*>(src);
  const uint8_t* const end = rd + src_size;
  size_t wr_size = 0;
  while (rd < end) {
    uint8_t s[3]{};
    s[0] = *(rd++);
    dst[wr_size++] = kEncTable[s[0] >> 2];

    uint8_t carry0 = static_cast<uint8_t>((s[0] & 0x03) << 4);
    if (PERFETTO_LIKELY(rd < end)) {
      s[1] = *(rd++);
      dst[wr_size++] = kEncTable[carry0 | (s[1] >> 4)];
    } else {
      dst[wr_size++] = kEncTable[carry0];
      dst[wr_size++] = kPadding;
      dst[wr_size++] = kPadding;
      break;
    }

    uint8_t carry1 = static_cast<uint8_t>((s[1] & 0x0f) << 2);
    if (PERFETTO_LIKELY(rd < end)) {
      s[2] = *(rd++);
      dst[wr_size++] = kEncTable[carry1 | (s[2] >> 6)];
    } else {
      dst[wr_size++] = kEncTable[carry1];
      dst[wr_size++] = kPadding;
      break;
    }

    dst[wr_size++] = kEncTable[s[2] & 0x3f];
  }
  PERFETTO_DCHECK(wr_size == padded_dst_size);
  return static_cast<ssize_t>(padded_dst_size);
}

std::string Base64Encode(const void* src, size_t src_size) {
  std::string dst;
  dst.resize(Base64EncSize(src_size));
  auto res = Base64Encode(src, src_size, &dst[0], dst.size());
  PERFETTO_CHECK(res == static_cast<ssize_t>(dst.size()));
  return dst;
}

ssize_t Base64Decode(const char* src,
                     size_t src_size,
                     uint8_t* dst,
                     size_t dst_size) {
  const size_t min_dst_size = Base64DecSize(src_size);
  if (dst_size < min_dst_size)
    return -1;

  const char* rd = src;
  const char* const end = src + src_size;
  size_t wr_size = 0;

  char s[4]{};
  while (rd < end) {
    uint8_t d[4];
    for (uint32_t j = 0; j < 4; j++) {
      // Padding is only feasible for the last 2 chars of each group of 4.
      s[j] = rd < end ? *(rd++) : (j < 2 ? '\0' : kPadding);
      d[j] = DecodeChar(s[j]);
      if (d[j] == kX)
        return -1;  // Invalid input char.
    }
    dst[wr_size] = static_cast<uint8_t>((d[0] << 2) | (d[1] >> 4));
    dst[wr_size + 1] = static_cast<uint8_t>((d[1] << 4) | (d[2] >> 2));
    dst[wr_size + 2] = static_cast<uint8_t>((d[2] << 6) | (d[3]));
    wr_size += 3;
  }

  PERFETTO_CHECK(wr_size <= dst_size);
  wr_size -= (s[3] == kPadding ? 1 : 0) + (s[2] == kPadding ? 1 : 0);
  return static_cast<ssize_t>(wr_size);
}

std::optional<std::string> Base64Decode(const char* src, size_t src_size) {
  std::string dst;
  dst.resize(Base64DecSize(src_size));
  auto res = Base64Decode(src, src_size, reinterpret_cast<uint8_t*>(&dst[0]),
                          dst.size());
  if (res < 0)
    return std::nullopt;  // Decoding error.

  PERFETTO_CHECK(res <= static_cast<ssize_t>(dst.size()));
  dst.resize(static_cast<size_t>(res));
  return std::make_optional(dst);
}

}  // namespace base
}  // namespace perfetto
// gen_amalgamated begin source: src/base/crash_keys.cc
// gen_amalgamated begin header: include/perfetto/ext/base/crash_keys.h
/*
 * Copyright (C) 2021 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef INCLUDE_PERFETTO_EXT_BASE_CRASH_KEYS_H_
#define INCLUDE_PERFETTO_EXT_BASE_CRASH_KEYS_H_

#include <algorithm>
#include <atomic>

#include <stdint.h>
#include <string.h>

// gen_amalgamated expanded: #include "perfetto/base/compiler.h"
// gen_amalgamated expanded: #include "perfetto/ext/base/string_view.h"

// Crash keys are very simple global variables with static-storage that
// are reported on crash time for managed crashes (CHECK/FATAL/Watchdog).
// - Translation units can define a CrashKey and register it at some point
//   during initialization.
// - CrashKey instances must be long-lived. They should really be just global
//   static variable in the anonymous namespace.
// Example:
// subsystem_1.cc
//   CrashKey g_client_id("ipc_client_id");
//   ...
//   OnIpcReceived(client_id) {
//      g_client_id.Set(client_id);
//      ... // Process the IPC
//      g_client_id.Clear();
//   }
//   Or equivalently:
//   OnIpcReceived(client_id) {
//      auto scoped_key = g_client_id.SetScoped(client_id);
//      ... // Process the IPC
//   }
//
// If a crash happens while processing the IPC, the crash report will
// have a line "ipc_client_id: 42".
//
// Thread safety considerations:
// CrashKeys can be registered and set/cleared from any thread.
// There is no compelling use-case to have full acquire/release consistency when
// setting a key. This means that if a thread crashes immediately after a
// crash key has been set on another thread, the value printed on the crash
// report could be incomplete. The code guarantees defined behavior and does
// not rely on null-terminated string (in the worst case 32 bytes of random
// garbage will be printed out).

// The tests live in logging_unittest.cc.

namespace perfetto {
namespace base {

constexpr size_t kCrashKeyMaxStrSize = 32;

// CrashKey instances must be long lived
class CrashKey {
 public:
  class ScopedClear {
   public:
    explicit ScopedClear(CrashKey* k) : key_(k) {}
    ~ScopedClear() {
      if (key_)
        key_->Clear();
    }
    ScopedClear(const ScopedClear&) = delete;
    ScopedClear& operator=(const ScopedClear&) = delete;
    ScopedClear& operator=(ScopedClear&&) = delete;
    ScopedClear(ScopedClear&& other) noexcept : key_(other.key_) {
      other.key_ = nullptr;
    }

   private:
    CrashKey* key_;
  };

  // constexpr so it can be used in the anon namespace without requiring a
  // global constructor.
  // |name| must be a long-lived string.
  constexpr explicit CrashKey(const char* name)
      : registered_{}, type_(Type::kUnset), name_(name), str_value_{} {}
  CrashKey(const CrashKey&) = delete;
  CrashKey& operator=(const CrashKey&) = delete;
  CrashKey(CrashKey&&) = delete;
  CrashKey& operator=(CrashKey&&) = delete;

  enum class Type : uint8_t { kUnset = 0, kInt, kStr };

  void Clear() {
    int_value_.store(0, std::memory_order_relaxed);
    type_.store(Type::kUnset, std::memory_order_relaxed);
  }

  void Set(int64_t value) {
    int_value_.store(value, std::memory_order_relaxed);
    type_.store(Type::kInt, std::memory_order_relaxed);
    if (PERFETTO_UNLIKELY(!registered_.load(std::memory_order_relaxed)))
      Register();
  }

  void Set(StringView sv) {
    size_t len = std::min(sv.size(), sizeof(str_value_) - 1);
    for (size_t i = 0; i < len; ++i)
      str_value_[i].store(sv.data()[i], std::memory_order_relaxed);
    str_value_[len].store('\0', std::memory_order_relaxed);
    type_.store(Type::kStr, std::memory_order_relaxed);
    if (PERFETTO_UNLIKELY(!registered_.load(std::memory_order_relaxed)))
      Register();
  }

  ScopedClear SetScoped(int64_t value) PERFETTO_WARN_UNUSED_RESULT {
    Set(value);
    return ScopedClear(this);
  }

  ScopedClear SetScoped(StringView sv) PERFETTO_WARN_UNUSED_RESULT {
    Set(sv);
    return ScopedClear(this);
  }

  void Register();

  int64_t int_value() const {
    return int_value_.load(std::memory_order_relaxed);
  }
  size_t ToString(char* dst, size_t len);

 private:
  std::atomic<bool> registered_;
  std::atomic<Type> type_;
  const char* const name_;
  union {
    std::atomic<char> str_value_[kCrashKeyMaxStrSize];
    std::atomic<int64_t> int_value_;
  };
};

// Fills |dst| with a string containing one line for each crash key
// (excluding the unset ones).
// Returns number of chars written, without counting the NUL terminator.
// This is used in logging.cc when emitting the crash report abort message.
size_t SerializeCrashKeys(char* dst, size_t len);

void UnregisterAllCrashKeysForTesting();

}  // namespace base
}  // namespace perfetto

#endif  // INCLUDE_PERFETTO_EXT_BASE_CRASH_KEYS_H_
// gen_amalgamated begin header: include/perfetto/ext/base/string_utils.h
/*
 * Copyright (C) 2018 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef INCLUDE_PERFETTO_EXT_BASE_STRING_UTILS_H_
#define INCLUDE_PERFETTO_EXT_BASE_STRING_UTILS_H_

#include <stdarg.h>
#include <stdlib.h>
#include <string.h>

#include <cinttypes>
#include <optional>
#include <string>
#include <vector>

// gen_amalgamated expanded: #include "perfetto/ext/base/string_view.h"

namespace perfetto {
namespace base {

inline char Lowercase(char c) {
  return ('A' <= c && c <= 'Z') ? static_cast<char>(c - ('A' - 'a')) : c;
}

inline char Uppercase(char c) {
  return ('a' <= c && c <= 'z') ? static_cast<char>(c + ('A' - 'a')) : c;
}

inline std::optional<uint32_t> CStringToUInt32(const char* s, int base = 10) {
  char* endptr = nullptr;
  auto value = static_cast<uint32_t>(strtoul(s, &endptr, base));
  return (*s && !*endptr) ? std::make_optional(value) : std::nullopt;
}

inline std::optional<int32_t> CStringToInt32(const char* s, int base = 10) {
  char* endptr = nullptr;
  auto value = static_cast<int32_t>(strtol(s, &endptr, base));
  return (*s && !*endptr) ? std::make_optional(value) : std::nullopt;
}

// Note: it saturates to 7fffffffffffffff if parsing a hex number >= 0x8000...
inline std::optional<int64_t> CStringToInt64(const char* s, int base = 10) {
  char* endptr = nullptr;
  auto value = static_cast<int64_t>(strtoll(s, &endptr, base));
  return (*s && !*endptr) ? std::make_optional(value) : std::nullopt;
}

inline std::optional<uint64_t> CStringToUInt64(const char* s, int base = 10) {
  char* endptr = nullptr;
  auto value = static_cast<uint64_t>(strtoull(s, &endptr, base));
  return (*s && !*endptr) ? std::make_optional(value) : std::nullopt;
}

double StrToD(const char* nptr, char** endptr);

inline std::optional<double> CStringToDouble(const char* s) {
  char* endptr = nullptr;
  double value = StrToD(s, &endptr);
  std::optional<double> result(std::nullopt);
  if (*s != '\0' && *endptr == '\0')
    result = value;
  return result;
}

inline std::optional<uint32_t> StringToUInt32(const std::string& s,
                                              int base = 10) {
  return CStringToUInt32(s.c_str(), base);
}

inline std::optional<int32_t> StringToInt32(const std::string& s,
                                            int base = 10) {
  return CStringToInt32(s.c_str(), base);
}

inline std::optional<uint64_t> StringToUInt64(const std::string& s,
                                              int base = 10) {
  return CStringToUInt64(s.c_str(), base);
}

inline std::optional<int64_t> StringToInt64(const std::string& s,
                                            int base = 10) {
  return CStringToInt64(s.c_str(), base);
}

inline std::optional<double> StringToDouble(const std::string& s) {
  return CStringToDouble(s.c_str());
}

bool StartsWith(const std::string& str, const std::string& prefix);
bool EndsWith(const std::string& str, const std::string& suffix);
bool StartsWithAny(const std::string& str,
                   const std::vector<std::string>& prefixes);
bool Contains(const std::string& haystack, const std::string& needle);
bool Contains(const std::string& haystack, char needle);
size_t Find(const StringView& needle, const StringView& haystack);
bool CaseInsensitiveEqual(const std::string& first, const std::string& second);
std::string Join(const std::vector<std::string>& parts,
                 const std::string& delim);
std::vector<std::string> SplitString(const std::string& text,
                                     const std::string& delimiter);
std::string StripPrefix(const std::string& str, const std::string& prefix);
std::string StripSuffix(const std::string& str, const std::string& suffix);
std::string TrimWhitespace(const std::string& str);
std::string ToLower(const std::string& str);
std::string ToUpper(const std::string& str);
std::string StripChars(const std::string& str,
                       const std::string& chars,
                       char replacement);
std::string ToHex(const char* data, size_t size);
inline std::string ToHex(const std::string& s) {
  return ToHex(s.c_str(), s.size());
}
std::string IntToHexString(uint32_t number);
std::string Uint64ToHexString(uint64_t number);
std::string Uint64ToHexStringNoPrefix(uint64_t number);
std::string ReplaceAll(std::string str,
                       const std::string& to_replace,
                       const std::string& replacement);

#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
bool WideToUTF8(const std::wstring& source, std::string& output);
bool UTF8ToWide(const std::string& source, std::wstring& output);
#endif // PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)

// A BSD-style strlcpy without the return value.
// Copies at most |dst_size|-1 characters. Unlike strncpy, it always \0
// terminates |dst|, as long as |dst_size| is not 0.
// Unlike strncpy and like strlcpy it does not zero-pad the rest of |dst|.
// Returns nothing. The BSD strlcpy returns the size of |src|, which might
// be > |dst_size|. Anecdotal experience suggests people assume the return value
// is the number of bytes written in |dst|. That assumption can lead to
// dangerous bugs.
// In order to avoid being subtly uncompliant with strlcpy AND avoid misuse,
// the choice here is to return nothing.
inline void StringCopy(char* dst, const char* src, size_t dst_size) {
  for (size_t i = 0; i < dst_size; ++i) {
    if ((dst[i] = src[i]) == '\0') {
      return;  // We hit and copied the null terminator.
    }
  }

  // We were left off at dst_size. We over copied 1 byte. Null terminate.
  if (PERFETTO_LIKELY(dst_size > 0))
    dst[dst_size - 1] = 0;
}

// Like snprintf() but returns the number of chars *actually* written (without
// counting the null terminator) NOT "the number of chars which would have been
// written to the final string if enough  space had been available".
// This should be used in almost all cases when the caller uses the return value
// of snprintf(). If the return value is not used, there is no benefit in using
// this wrapper, as this just calls snprintf() and mangles the return value.
// It always null-terminates |dst| (even in case of errors), unless
// |dst_size| == 0.
// Examples:
//   SprintfTrunc(x, 4, "123whatever"): returns 3 and writes "123\0".
//   SprintfTrunc(x, 4, "123"): returns 3 and writes "123\0".
//   SprintfTrunc(x, 3, "123"): returns 2 and writes "12\0".
//   SprintfTrunc(x, 2, "123"): returns 1 and writes "1\0".
//   SprintfTrunc(x, 1, "123"): returns 0 and writes "\0".
//   SprintfTrunc(x, 0, "123"): returns 0 and writes nothing.
// NOTE: This means that the caller has no way to tell when truncation happens
//   vs the edge case of *just* fitting in the buffer.
size_t SprintfTrunc(char* dst, size_t dst_size, const char* fmt, ...)
    PERFETTO_PRINTF_FORMAT(3, 4);

// Line number starts from 1
struct LineWithOffset {
  base::StringView line;
  uint32_t line_offset;
  uint32_t line_num;
};

// For given string and offset Pfinds a line with character for
// which offset points, what number is this line (starts from 1), and the offset
// inside this line. returns std::nullopt if the offset points to
// line break character or exceeds string length.
std::optional<LineWithOffset> FindLineWithOffset(base::StringView str,
                                                 uint32_t offset);

// A helper class to facilitate construction and usage of write-once stack
// strings.
// Example usage:
//   StackString<32> x("format %d %s", 42, string_arg);
//   TakeString(x.c_str() | x.string_view() | x.ToStdString());
// Rather than char x[32] + sprintf.
// Advantages:
// - Avoids useless zero-fills caused by people doing `char buf[32] {}` (mainly
//   by fearing unknown snprintf failure modes).
// - Makes the code more robust in case of snprintf truncations (len() and
//  string_view() will return the truncated length, unlike snprintf).
template <size_t N>
class StackString {
 public:
  explicit PERFETTO_PRINTF_FORMAT(/* 1=this */ 2, 3)
      StackString(const char* fmt, ...) {
    buf_[0] = '\0';
    va_list args;
    va_start(args, fmt);
    int res = vsnprintf(buf_, sizeof(buf_), fmt, args);
    va_end(args);
    buf_[sizeof(buf_) - 1] = '\0';
    len_ = res < 0 ? 0 : std::min(static_cast<size_t>(res), sizeof(buf_) - 1);
  }

  StringView string_view() const { return StringView(buf_, len_); }
  std::string ToStdString() const { return std::string(buf_, len_); }
  const char* c_str() const { return buf_; }
  size_t len() const { return len_; }
  char* mutable_data() { return buf_; }

 private:
  char buf_[N];
  size_t len_ = 0;  // Does not include the \0.
};

}  // namespace base
}  // namespace perfetto

#endif  // INCLUDE_PERFETTO_EXT_BASE_STRING_UTILS_H_
/*
 * Copyright (C) 2021 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// gen_amalgamated expanded: #include "perfetto/ext/base/crash_keys.h"

#include <string.h>

#include <atomic>
#include <cinttypes>

// gen_amalgamated expanded: #include "perfetto/ext/base/string_utils.h"

namespace perfetto {
namespace base {

namespace {

constexpr size_t kMaxKeys = 32;

std::atomic<CrashKey*> g_keys[kMaxKeys]{};
std::atomic<uint32_t> g_num_keys{};
}  // namespace

void CrashKey::Register() {
  // If doesn't matter if we fail below. If there are no slots left, don't
  // keep trying re-registering on every Set(), the outcome won't change.

  // If two threads raced on the Register(), avoid registering the key twice.
  if (registered_.exchange(true))
    return;

  uint32_t slot = g_num_keys.fetch_add(1);
  if (slot >= kMaxKeys) {
    PERFETTO_LOG("Too many crash keys registered");
    return;
  }
  g_keys[slot].store(this);
}

// Returns the number of chars written, without counting the \0.
size_t CrashKey::ToString(char* dst, size_t len) {
  if (len > 0)
    *dst = '\0';
  switch (type_.load(std::memory_order_relaxed)) {
    case Type::kUnset:
      break;
    case Type::kInt:
      return SprintfTrunc(dst, len, "%s: %" PRId64 "\n", name_,
                          int_value_.load(std::memory_order_relaxed));
    case Type::kStr:
      char buf[sizeof(str_value_)];
      for (size_t i = 0; i < sizeof(str_value_); i++)
        buf[i] = str_value_[i].load(std::memory_order_relaxed);

      // Don't assume |str_value_| is properly null-terminated.
      return SprintfTrunc(dst, len, "%s: %.*s\n", name_, int(sizeof(buf)), buf);
  }
  return 0;
}

void UnregisterAllCrashKeysForTesting() {
  g_num_keys.store(0);
  for (auto& key : g_keys)
    key.store(nullptr);
}

size_t SerializeCrashKeys(char* dst, size_t len) {
  size_t written = 0;
  uint32_t num_keys = g_num_keys.load();
  if (len > 0)
    *dst = '\0';
  for (uint32_t i = 0; i < num_keys && written < len; i++) {
    CrashKey* key = g_keys[i].load();
    if (!key)
      continue;  // Can happen if we hit this between the add and the store.
    written += key->ToString(dst + written, len - written);
  }
  PERFETTO_DCHECK(written <= len);
  PERFETTO_DCHECK(len == 0 || dst[written] == '\0');
  return written;
}

}  // namespace base
}  // namespace perfetto
// gen_amalgamated begin source: src/base/ctrl_c_handler.cc
// gen_amalgamated begin header: include/perfetto/ext/base/ctrl_c_handler.h
/*
 * Copyright (C) 2021 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef INCLUDE_PERFETTO_EXT_BASE_CTRL_C_HANDLER_H_
#define INCLUDE_PERFETTO_EXT_BASE_CTRL_C_HANDLER_H_

namespace perfetto {
namespace base {

// On Linux/Android/Mac: installs SIGINT + SIGTERM signal handlers.
// On Windows: installs a SetConsoleCtrlHandler() handler.
// The passed handler must be async safe.
using CtrlCHandlerFunction = void (*)();
void InstallCtrlCHandler(CtrlCHandlerFunction);

}  // namespace base
}  // namespace perfetto

#endif  // INCLUDE_PERFETTO_EXT_BASE_CTRL_C_HANDLER_H_
/*
 * Copyright (C) 2021 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// gen_amalgamated expanded: #include "perfetto/ext/base/ctrl_c_handler.h"

// gen_amalgamated expanded: #include "perfetto/base/build_config.h"
// gen_amalgamated expanded: #include "perfetto/base/compiler.h"
// gen_amalgamated expanded: #include "perfetto/base/logging.h"

#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
#include <Windows.h>
#include <io.h>
#else
#include <signal.h>
#include <unistd.h>
#endif

namespace perfetto {
namespace base {

namespace {
CtrlCHandlerFunction g_handler = nullptr;
}

void InstallCtrlCHandler(CtrlCHandlerFunction handler) {
  PERFETTO_CHECK(g_handler == nullptr);
  g_handler = handler;

#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
  auto trampoline = [](DWORD type) -> int {
    if (type == CTRL_C_EVENT) {
      g_handler();
      return true;
    }
    return false;
  };
  ::SetConsoleCtrlHandler(trampoline, true);
#elif PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
    PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \
    PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
  // Setup signal handler.
  struct sigaction sa {};

// Glibc headers for sa_sigaction trigger this.
#pragma GCC diagnostic push
#if defined(__clang__)
#pragma GCC diagnostic ignored "-Wdisabled-macro-expansion"
#endif
  sa.sa_handler = [](int) { g_handler(); };
  sa.sa_flags = static_cast<decltype(sa.sa_flags)>(SA_RESETHAND | SA_RESTART);
#pragma GCC diagnostic pop
  sigaction(SIGINT, &sa, nullptr);
  sigaction(SIGTERM, &sa, nullptr);
#else
  // Do nothing on NaCL and Fuchsia.
  ignore_result(handler);
#endif
}

}  // namespace base
}  // namespace perfetto
// gen_amalgamated begin source: src/base/event_fd.cc
// gen_amalgamated begin header: include/perfetto/ext/base/event_fd.h
// gen_amalgamated begin header: include/perfetto/ext/base/scoped_file.h
/*
 * Copyright (C) 2017 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef INCLUDE_PERFETTO_EXT_BASE_SCOPED_FILE_H_
#define INCLUDE_PERFETTO_EXT_BASE_SCOPED_FILE_H_

// gen_amalgamated expanded: #include "perfetto/base/build_config.h"

#include <stdio.h>

#if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
#include <dirent.h>  // For DIR* / opendir().
#endif

#include <string>

// gen_amalgamated expanded: #include "perfetto/base/export.h"
// gen_amalgamated expanded: #include "perfetto/base/logging.h"
// gen_amalgamated expanded: #include "perfetto/base/platform_handle.h"

namespace perfetto {
namespace base {

namespace internal {
// Used for the most common cases of ScopedResource where there is only one
// invalid value.
template <typename T, T InvalidValue>
struct DefaultValidityChecker {
  static bool IsValid(T t) { return t != InvalidValue; }
};
}  // namespace internal

// RAII classes for auto-releasing fds and dirs.
// if T is a pointer type, InvalidValue must be nullptr. Doing otherwise
// causes weird unexpected behaviors (See https://godbolt.org/z/5nGMW4).
template <typename T,
          int (*CloseFunction)(T),
          T InvalidValue,
          bool CheckClose = true,
          class Checker = internal::DefaultValidityChecker<T, InvalidValue>>
class ScopedResource {
 public:
  using ValidityChecker = Checker;
  static constexpr T kInvalid = InvalidValue;

  explicit ScopedResource(T t = InvalidValue) : t_(t) {}
  ScopedResource(ScopedResource&& other) noexcept {
    t_ = other.t_;
    other.t_ = InvalidValue;
  }
  ScopedResource& operator=(ScopedResource&& other) {
    reset(other.t_);
    other.t_ = InvalidValue;
    return *this;
  }
  T get() const { return t_; }
  T operator*() const { return t_; }
  explicit operator bool() const { return Checker::IsValid(t_); }
  void reset(T r = InvalidValue) {
    if (Checker::IsValid(t_)) {
      int res = CloseFunction(t_);
      if (CheckClose)
        PERFETTO_CHECK(res == 0);
    }
    t_ = r;
  }
  T release() {
    T t = t_;
    t_ = InvalidValue;
    return t;
  }
  ~ScopedResource() { reset(InvalidValue); }

 private:
  ScopedResource(const ScopedResource&) = delete;
  ScopedResource& operator=(const ScopedResource&) = delete;
  T t_;
};

// Declared in file_utils.h. Forward declared to avoid #include cycles.
int PERFETTO_EXPORT_COMPONENT CloseFile(int fd);

// Use this for file resources obtained via open() and similar APIs.
using ScopedFile = ScopedResource<int, CloseFile, -1>;
using ScopedFstream = ScopedResource<FILE*, fclose, nullptr>;

// Use this for resources that are HANDLE on Windows. See comments in
// platform_handle.h
#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
using ScopedPlatformHandle = ScopedResource<PlatformHandle,
                                            ClosePlatformHandle,
                                            /*InvalidValue=*/nullptr,
                                            /*CheckClose=*/true,
                                            PlatformHandleChecker>;
#else
// On non-windows systems we alias ScopedPlatformHandle to ScopedFile because
// they are really the same. This is to allow assignments between the two in
// Linux-specific code paths that predate ScopedPlatformHandle.
static_assert(std::is_same<int, PlatformHandle>::value, "");
using ScopedPlatformHandle = ScopedFile;

// DIR* does not exist on Windows.
using ScopedDir = ScopedResource<DIR*, closedir, nullptr>;
#endif

}  // namespace base
}  // namespace perfetto

#endif  // INCLUDE_PERFETTO_EXT_BASE_SCOPED_FILE_H_
/*
 * Copyright (C) 2018 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef INCLUDE_PERFETTO_EXT_BASE_EVENT_FD_H_
#define INCLUDE_PERFETTO_EXT_BASE_EVENT_FD_H_

// gen_amalgamated expanded: #include "perfetto/base/build_config.h"
// gen_amalgamated expanded: #include "perfetto/base/platform_handle.h"
// gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"

namespace perfetto {
namespace base {

// A waitable event that can be used with poll/select.
// This is really a wrapper around eventfd_create with a pipe-based fallback
// for other platforms where eventfd is not supported.
class EventFd {
 public:
  EventFd();
  ~EventFd();
  EventFd(EventFd&&) noexcept = default;
  EventFd& operator=(EventFd&&) = default;

  // The non-blocking file descriptor that can be polled to wait for the event.
  PlatformHandle fd() const { return event_handle_.get(); }

  // Can be called from any thread.
  void Notify();

  // Can be called from any thread. If more Notify() are queued a Clear() call
  // can clear all of them (up to 16 per call).
  void Clear();

 private:
  // The eventfd, when eventfd is supported, otherwise this is the read end of
  // the pipe for fallback mode.
  ScopedPlatformHandle event_handle_;

#if !PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) &&   \
    !PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) && \
    !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
  // On Mac and other non-Linux UNIX platforms a pipe-based fallback is used.
  // The write end of the wakeup pipe.
  ScopedFile write_fd_;
#endif
};

}  // namespace base
}  // namespace perfetto

#endif  // INCLUDE_PERFETTO_EXT_BASE_EVENT_FD_H_
// gen_amalgamated begin header: include/perfetto/ext/base/pipe.h
/*
 * Copyright (C) 2018 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef INCLUDE_PERFETTO_EXT_BASE_PIPE_H_
#define INCLUDE_PERFETTO_EXT_BASE_PIPE_H_

// gen_amalgamated expanded: #include "perfetto/base/platform_handle.h"
// gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"

namespace perfetto {
namespace base {

class Pipe {
 public:
  enum Flags {
    kBothBlock = 0,
#if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
    kBothNonBlock,
    kRdNonBlock,
    kWrNonBlock,
#endif
  };

  static Pipe Create(Flags = kBothBlock);

  Pipe();
  Pipe(Pipe&&) noexcept;
  Pipe& operator=(Pipe&&);

  ScopedPlatformHandle rd;
  ScopedPlatformHandle wr;
};

}  // namespace base
}  // namespace perfetto

#endif  // INCLUDE_PERFETTO_EXT_BASE_PIPE_H_
/*
 * Copyright (C) 2018 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// gen_amalgamated expanded: #include "perfetto/base/build_config.h"

#include <errno.h>
#include <stdint.h>

#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
#include <Windows.h>
#include <synchapi.h>
#elif PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
    PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
#include <sys/eventfd.h>
#include <unistd.h>
#else  // Mac, Fuchsia and other non-Linux UNIXes
#include <unistd.h>
#endif

// gen_amalgamated expanded: #include "perfetto/base/logging.h"
// gen_amalgamated expanded: #include "perfetto/ext/base/event_fd.h"
// gen_amalgamated expanded: #include "perfetto/ext/base/pipe.h"
// gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"

namespace perfetto {
namespace base {

EventFd::~EventFd() = default;

#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
EventFd::EventFd() {
  event_handle_.reset(
      CreateEventA(/*lpEventAttributes=*/nullptr, /*bManualReset=*/true,
                   /*bInitialState=*/false, /*bInitialState=*/nullptr));
}

void EventFd::Notify() {
  if (!SetEvent(event_handle_.get()))  // 0: fail, !0: success, unlike UNIX.
    PERFETTO_DFATAL("EventFd::Notify()");
}

void EventFd::Clear() {
  if (!ResetEvent(event_handle_.get()))  // 0: fail, !0: success, unlike UNIX.
    PERFETTO_DFATAL("EventFd::Clear()");
}

#elif PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
    PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)

EventFd::EventFd() {
  event_handle_.reset(eventfd(/*initval=*/0, EFD_CLOEXEC | EFD_NONBLOCK));
  PERFETTO_CHECK(event_handle_);
}

void EventFd::Notify() {
  const uint64_t value = 1;
  ssize_t ret = write(event_handle_.get(), &value, sizeof(value));
  if (ret <= 0 && errno != EAGAIN)
    PERFETTO_DFATAL("EventFd::Notify()");
}

void EventFd::Clear() {
  uint64_t value;
  ssize_t ret =
      PERFETTO_EINTR(read(event_handle_.get(), &value, sizeof(value)));
  if (ret <= 0 && errno != EAGAIN)
    PERFETTO_DFATAL("EventFd::Clear()");
}

#else

EventFd::EventFd() {
  // Make the pipe non-blocking so that we never block the waking thread (either
  // the main thread or another one) when scheduling a wake-up.
  Pipe pipe = Pipe::Create(Pipe::kBothNonBlock);
  event_handle_ = ScopedPlatformHandle(std::move(pipe.rd).release());
  write_fd_ = std::move(pipe.wr);
}

void EventFd::Notify() {
  const uint64_t value = 1;
  ssize_t ret = write(write_fd_.get(), &value, sizeof(uint8_t));
  if (ret <= 0 && errno != EAGAIN)
    PERFETTO_DFATAL("EventFd::Notify()");
}

void EventFd::Clear() {
  // Drain the byte(s) written to the wake-up pipe. We can potentially read
  // more than one byte if several wake-ups have been scheduled.
  char buffer[16];
  ssize_t ret =
      PERFETTO_EINTR(read(event_handle_.get(), &buffer[0], sizeof(buffer)));
  if (ret <= 0 && errno != EAGAIN)
    PERFETTO_DFATAL("EventFd::Clear()");
}
#endif

}  // namespace base
}  // namespace perfetto
// gen_amalgamated begin source: src/base/file_utils.cc
// gen_amalgamated begin header: include/perfetto/ext/base/file_utils.h
// gen_amalgamated begin header: include/perfetto/base/status.h
/*
 * Copyright (C) 2019 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef INCLUDE_PERFETTO_BASE_STATUS_H_
#define INCLUDE_PERFETTO_BASE_STATUS_H_

#include <optional>
#include <string>
#include <string_view>
#include <vector>

// gen_amalgamated expanded: #include "perfetto/base/compiler.h"
// gen_amalgamated expanded: #include "perfetto/base/export.h"
// gen_amalgamated expanded: #include "perfetto/base/logging.h"

namespace perfetto {
namespace base {

// Represents either the success or the failure message of a function.
// This can used as the return type of functions which would usually return an
// bool for success or int for errno but also wants to add some string context
// (ususally for logging).
//
// Similar to absl::Status, an optional "payload" can also be included with more
// context about the error. This allows passing additional metadata about the
// error (e.g. location of errors, potential mitigations etc).
class PERFETTO_EXPORT_COMPONENT Status {
 public:
  Status() : ok_(true) {}
  explicit Status(std::string msg) : ok_(false), message_(std::move(msg)) {
    PERFETTO_CHECK(!message_.empty());
  }

  // Copy operations.
  Status(const Status&) = default;
  Status& operator=(const Status&) = default;

  // Move operations. The moved-from state is valid but unspecified.
  Status(Status&&) noexcept = default;
  Status& operator=(Status&&) = default;

  bool ok() const { return ok_; }

  // When ok() is false this returns the error message. Returns the empty string
  // otherwise.
  const std::string& message() const { return message_; }
  const char* c_message() const { return message_.c_str(); }

  //////////////////////////////////////////////////////////////////////////////
  // Payload Management APIs
  //////////////////////////////////////////////////////////////////////////////

  // Payloads can be attached to error statuses to provide additional context.
  //
  // Payloads are (key, value) pairs, where the key is a string acting as a
  // unique "type URL" and the value is an opaque string. The "type URL" should
  // be unique, follow the format of a URL and, ideally, documentation on how to
  // interpret its associated data should be available.
  //
  // To attach a payload to a status object, call `Status::SetPayload()`.
  // Similarly, to extract the payload from a status, call
  // `Status::GetPayload()`.
  //
  // Note: the payload APIs are only meaningful to call when the status is an
  // error. Otherwise, all methods are noops.

  // Gets the payload for the given |type_url| if one exists.
  //
  // Will always return std::nullopt if |ok()|.
  std::optional<std::string_view> GetPayload(std::string_view type_url) const;

  // Sets the payload for the given key. The key should
  //
  // Will always do nothing if |ok()|.
  void SetPayload(std::string_view type_url, std::string value);

  // Erases the payload for the given string and returns true if the payload
  // existed and was erased.
  //
  // Will always do nothing if |ok()|.
  bool ErasePayload(std::string_view type_url);

 private:
  struct Payload {
    std::string type_url;
    std::string payload;
  };

  bool ok_ = false;
  std::string message_;
  std::vector<Payload> payloads_;
};

// Returns a status object which represents the Ok status.
inline Status OkStatus() {
  return Status();
}

PERFETTO_PRINTF_FORMAT(1, 2) Status ErrStatus(const char* format, ...);

}  // namespace base
}  // namespace perfetto

#endif  // INCLUDE_PERFETTO_BASE_STATUS_H_
/*
 * Copyright (C) 2018 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef INCLUDE_PERFETTO_EXT_BASE_FILE_UTILS_H_
#define INCLUDE_PERFETTO_EXT_BASE_FILE_UTILS_H_

#include <fcntl.h>  // For mode_t & O_RDONLY/RDWR. Exists also on Windows.
#include <stddef.h>

#include <optional>
#include <string>
#include <vector>

// gen_amalgamated expanded: #include "perfetto/base/build_config.h"
// gen_amalgamated expanded: #include "perfetto/base/export.h"
// gen_amalgamated expanded: #include "perfetto/base/status.h"
// gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"
// gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"

namespace perfetto {
namespace base {

#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
using FileOpenMode = int;
inline constexpr char kDevNull[] = "NUL";
#else
using FileOpenMode = mode_t;
inline constexpr char kDevNull[] = "/dev/null";
#endif

constexpr FileOpenMode kFileModeInvalid = static_cast<FileOpenMode>(-1);

bool ReadPlatformHandle(PlatformHandle, std::string* out);
bool ReadFileDescriptor(int fd, std::string* out);
bool ReadFileStream(FILE* f, std::string* out);
bool ReadFile(const std::string& path, std::string* out);

// A wrapper around read(2). It deals with Linux vs Windows includes. It also
// deals with handling EINTR. Has the same semantics of UNIX's read(2).
ssize_t Read(int fd, void* dst, size_t dst_size);

// Call write until all data is written or an error is detected.
//
// man 2 write:
//   If a write() is interrupted by a signal handler before any bytes are
//   written, then the call fails with the error EINTR; if it is
//   interrupted after at least one byte has been written, the call
//   succeeds, and returns the number of bytes written.
ssize_t WriteAll(int fd, const void* buf, size_t count);

ssize_t WriteAllHandle(PlatformHandle, const void* buf, size_t count);

ScopedFile OpenFile(const std::string& path,
                    int flags,
                    FileOpenMode = kFileModeInvalid);
ScopedFstream OpenFstream(const char* path, const char* mode);

// This is an alias for close(). It's to avoid leaking Windows.h in headers.
// Exported because ScopedFile is used in the /include/ext API by Chromium
// component builds.
int PERFETTO_EXPORT_COMPONENT CloseFile(int fd);

bool FlushFile(int fd);

// Returns true if mkdir succeeds, false if it fails (see errno in that case).
bool Mkdir(const std::string& path);

// Calls rmdir() on UNIX, _rmdir() on Windows.
bool Rmdir(const std::string& path);

// Wrapper around access(path, F_OK).
bool FileExists(const std::string& path);

// Gets the extension for a filename. If the file has two extensions, returns
// only the last one (foo.pb.gz => .gz). Returns empty string if there is no
// extension.
std::string GetFileExtension(const std::string& filename);

// Puts the path to all files under |dir_path| in |output|, recursively walking
// subdirectories. File paths are relative to |dir_path|. Only files are
// included, not directories. Path separator is always '/', even on windows (not
// '\').
base::Status ListFilesRecursive(const std::string& dir_path,
                                std::vector<std::string>& output);

// Sets |path|'s owner group to |group_name| and permission mode bits to
// |mode_bits|.
base::Status SetFilePermissions(const std::string& path,
                                const std::string& group_name,
                                const std::string& mode_bits);

// Returns the size of the file located at |path|, or nullopt in case of error.
std::optional<uint64_t> GetFileSize(const std::string& path);

// Returns the size of the open file |fd|, or nullopt in case of error.
std::optional<uint64_t> GetFileSize(PlatformHandle fd);

}  // namespace base
}  // namespace perfetto

#endif  // INCLUDE_PERFETTO_EXT_BASE_FILE_UTILS_H_
/*
 * Copyright (C) 2018 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// gen_amalgamated expanded: #include "perfetto/ext/base/file_utils.h"

#include <sys/stat.h>
#include <sys/types.h>

#include <algorithm>
#include <deque>
#include <optional>
#include <string>
#include <vector>

// gen_amalgamated expanded: #include "perfetto/base/build_config.h"
// gen_amalgamated expanded: #include "perfetto/base/compiler.h"
// gen_amalgamated expanded: #include "perfetto/base/logging.h"
// gen_amalgamated expanded: #include "perfetto/base/platform_handle.h"
// gen_amalgamated expanded: #include "perfetto/base/status.h"
// gen_amalgamated expanded: #include "perfetto/ext/base/platform.h"
// gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"
// gen_amalgamated expanded: #include "perfetto/ext/base/string_utils.h"
// gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"

#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
#include <Windows.h>
#include <direct.h>
#include <io.h>
#include <stringapiset.h>
#else
#include <dirent.h>
#include <unistd.h>
#endif

#if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) ||   \
    PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \
    PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
#define PERFETTO_SET_FILE_PERMISSIONS
#include <fcntl.h>
#include <grp.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#endif

namespace perfetto {
namespace base {
namespace {
constexpr size_t kBufSize = 2048;

#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
// Wrap FindClose to: (1) make the return unix-style; (2) deal with stdcall.
int CloseFindHandle(HANDLE h) {
  return FindClose(h) ? 0 : -1;
}

std::optional<std::wstring> ToUtf16(const std::string str) {
  int len = MultiByteToWideChar(CP_UTF8, 0, str.data(),
                                static_cast<int>(str.size()), nullptr, 0);
  if (len < 0) {
    return std::nullopt;
  }
  std::vector<wchar_t> tmp;
  tmp.resize(static_cast<std::vector<wchar_t>::size_type>(len));
  len =
      MultiByteToWideChar(CP_UTF8, 0, str.data(), static_cast<int>(str.size()),
                          tmp.data(), static_cast<int>(tmp.size()));
  if (len < 0) {
    return std::nullopt;
  }
  PERFETTO_CHECK(static_cast<std::vector<wchar_t>::size_type>(len) ==
                 tmp.size());
  return std::wstring(tmp.data(), tmp.size());
}

#endif

}  // namespace

ssize_t Read(int fd, void* dst, size_t dst_size) {
  ssize_t ret;
  platform::BeforeMaybeBlockingSyscall();
#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
  ret = _read(fd, dst, static_cast<unsigned>(dst_size));
#else
  ret = PERFETTO_EINTR(read(fd, dst, dst_size));
#endif
  platform::AfterMaybeBlockingSyscall();
  return ret;
}

bool ReadFileDescriptor(int fd, std::string* out) {
  // Do not override existing data in string.
  size_t i = out->size();

  struct stat buf {};
  if (fstat(fd, &buf) != -1) {
    if (buf.st_size > 0)
      out->resize(i + static_cast<size_t>(buf.st_size));
  }

  ssize_t bytes_read;
  for (;;) {
    if (out->size() < i + kBufSize)
      out->resize(out->size() + kBufSize);

    bytes_read = Read(fd, &((*out)[i]), kBufSize);
    if (bytes_read > 0) {
      i += static_cast<size_t>(bytes_read);
    } else {
      out->resize(i);
      return bytes_read == 0;
    }
  }
}

bool ReadPlatformHandle(PlatformHandle h, std::string* out) {
#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
  // Do not override existing data in string.
  size_t i = out->size();

  for (;;) {
    if (out->size() < i + kBufSize)
      out->resize(out->size() + kBufSize);
    DWORD bytes_read = 0;
    auto res = ::ReadFile(h, &((*out)[i]), kBufSize, &bytes_read, nullptr);
    if (res && bytes_read > 0) {
      i += static_cast<size_t>(bytes_read);
    } else {
      out->resize(i);
      const bool is_eof = res && bytes_read == 0;
      auto err = res ? 0 : GetLastError();
      // The "Broken pipe" error on Windows is slighly different than Unix:
      // On Unix: a "broken pipe" error can happen only on the writer side. On
      // the reader there is no broken pipe, just a EOF.
      // On windows: the reader also sees a broken pipe error.
      // Here we normalize on the Unix behavior, treating broken pipe as EOF.
      return is_eof || err == ERROR_BROKEN_PIPE;
    }
  }
#else
  return ReadFileDescriptor(h, out);
#endif
}

bool ReadFileStream(FILE* f, std::string* out) {
  return ReadFileDescriptor(fileno(f), out);
}

bool ReadFile(const std::string& path, std::string* out) {
  base::ScopedFile fd = base::OpenFile(path, O_RDONLY);
  if (!fd)
    return false;

  return ReadFileDescriptor(*fd, out);
}

ssize_t WriteAll(int fd, const void* buf, size_t count) {
  size_t written = 0;
  while (written < count) {
    // write() on windows takes an unsigned int size.
    uint32_t bytes_left = static_cast<uint32_t>(
        std::min(count - written, static_cast<size_t>(UINT32_MAX)));
    platform::BeforeMaybeBlockingSyscall();
    ssize_t wr = PERFETTO_EINTR(
        write(fd, static_cast<const char*>(buf) + written, bytes_left));
    platform::AfterMaybeBlockingSyscall();
    if (wr == 0)
      break;
    if (wr < 0)
      return wr;
    written += static_cast<size_t>(wr);
  }
  return static_cast<ssize_t>(written);
}

ssize_t WriteAllHandle(PlatformHandle h, const void* buf, size_t count) {
#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
  DWORD wsize = 0;
  if (::WriteFile(h, buf, static_cast<DWORD>(count), &wsize, nullptr)) {
    return wsize;
  } else {
    return -1;
  }
#else
  return WriteAll(h, buf, count);
#endif
}

bool FlushFile(int fd) {
  PERFETTO_DCHECK(fd != 0);
#if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
    PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
  return !PERFETTO_EINTR(fdatasync(fd));
#elif PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
  return !PERFETTO_EINTR(_commit(fd));
#else
  return !PERFETTO_EINTR(fsync(fd));
#endif
}

bool Mkdir(const std::string& path) {
#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
  return _mkdir(path.c_str()) == 0;
#else
  return mkdir(path.c_str(), 0755) == 0;
#endif
}

bool Rmdir(const std::string& path) {
#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
  return _rmdir(path.c_str()) == 0;
#else
  return rmdir(path.c_str()) == 0;
#endif
}

int CloseFile(int fd) {
  return close(fd);
}

ScopedFile OpenFile(const std::string& path, int flags, FileOpenMode mode) {
  // If a new file might be created, ensure that the permissions for the new
  // file are explicitly specified.
  PERFETTO_CHECK((flags & O_CREAT) == 0 || mode != kFileModeInvalid);
#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
  // Always use O_BINARY on Windows, to avoid silly EOL translations.
  ScopedFile fd(_open(path.c_str(), flags | O_BINARY, mode));
#else
  // Always open a ScopedFile with O_CLOEXEC so we can safely fork and exec.
  ScopedFile fd(open(path.c_str(), flags | O_CLOEXEC, mode));
#endif
  return fd;
}

ScopedFstream OpenFstream(const char* path, const char* mode) {
  ScopedFstream file;
// On Windows fopen interprets filename using the ANSI or OEM codepage but
// sqlite3_value_text returns a UTF-8 string. To make sure we interpret the
// filename correctly we use _wfopen and a UTF-16 string on windows.
#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
  auto w_path = ToUtf16(path);
  auto w_mode = ToUtf16(mode);
  if (w_path && w_mode) {
    file.reset(_wfopen(w_path->c_str(), w_mode->c_str()));
  }
#else
  file.reset(fopen(path, mode));
#endif
  return file;
}

bool FileExists(const std::string& path) {
#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
  return _access(path.c_str(), 0) == 0;
#else
  return access(path.c_str(), F_OK) == 0;
#endif
}

// Declared in base/platform_handle.h.
int ClosePlatformHandle(PlatformHandle handle) {
#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
  // Make the return value UNIX-style.
  return CloseHandle(handle) ? 0 : -1;
#else
  return close(handle);
#endif
}

base::Status ListFilesRecursive(const std::string& dir_path,
                                std::vector<std::string>& output) {
  std::string root_dir_path = dir_path;
  if (root_dir_path.back() == '\\') {
    root_dir_path.back() = '/';
  } else if (root_dir_path.back() != '/') {
    root_dir_path.push_back('/');
  }

  // dir_queue contains full paths to the directories. The paths include the
  // root_dir_path at the beginning and the trailing slash at the end.
  std::deque<std::string> dir_queue;
  dir_queue.push_back(root_dir_path);

  while (!dir_queue.empty()) {
    const std::string cur_dir = std::move(dir_queue.front());
    dir_queue.pop_front();
#if PERFETTO_BUILDFLAG(PERFETTO_OS_NACL)
    return base::ErrStatus("ListFilesRecursive not supported yet");
#elif PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
    std::string glob_path = cur_dir + "*";
    // + 1 because we also have to count the NULL terminator.
    if (glob_path.length() + 1 > MAX_PATH)
      return base::ErrStatus("Directory path %s is too long", dir_path.c_str());
    WIN32_FIND_DATAA ffd;

    base::ScopedResource<HANDLE, CloseFindHandle, nullptr, false,
                         base::PlatformHandleChecker>
        hFind(FindFirstFileA(glob_path.c_str(), &ffd));
    if (!hFind) {
      // For empty directories, there should be at least one entry '.'.
      // If FindFirstFileA returns INVALID_HANDLE_VALUE, this means directory
      // couldn't be accessed.
      return base::ErrStatus("Failed to open directory %s", cur_dir.c_str());
    }
    do {
      if (strcmp(ffd.cFileName, ".") == 0 || strcmp(ffd.cFileName, "..") == 0)
        continue;
      if (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
        std::string subdir_path = cur_dir + ffd.cFileName + '/';
        dir_queue.push_back(subdir_path);
      } else {
        const std::string full_path = cur_dir + ffd.cFileName;
        PERFETTO_CHECK(full_path.length() > root_dir_path.length());
        output.push_back(full_path.substr(root_dir_path.length()));
      }
    } while (FindNextFileA(*hFind, &ffd));
#else
    ScopedDir dir = ScopedDir(opendir(cur_dir.c_str()));
    if (!dir) {
      return base::ErrStatus("Failed to open directory %s", cur_dir.c_str());
    }
    for (auto* dirent = readdir(dir.get()); dirent != nullptr;
         dirent = readdir(dir.get())) {
      if (strcmp(dirent->d_name, ".") == 0 ||
          strcmp(dirent->d_name, "..") == 0) {
        continue;
      }
      if (dirent->d_type == DT_DIR) {
        dir_queue.push_back(cur_dir + dirent->d_name + '/');
      } else if (dirent->d_type == DT_REG) {
        const std::string full_path = cur_dir + dirent->d_name;
        PERFETTO_CHECK(full_path.length() > root_dir_path.length());
        output.push_back(full_path.substr(root_dir_path.length()));
      }
    }
#endif
  }
  return base::OkStatus();
}

std::string GetFileExtension(const std::string& filename) {
  auto ext_idx = filename.rfind('.');
  if (ext_idx == std::string::npos)
    return std::string();
  return filename.substr(ext_idx);
}

base::Status SetFilePermissions(const std::string& file_path,
                                const std::string& group_name_or_id,
                                const std::string& mode_bits) {
#ifdef PERFETTO_SET_FILE_PERMISSIONS
  PERFETTO_CHECK(!file_path.empty());
  PERFETTO_CHECK(!group_name_or_id.empty());

  // Default |group_id| to -1 for not changing the group ownership.
  gid_t group_id = static_cast<gid_t>(-1);
  auto maybe_group_id = base::StringToUInt32(group_name_or_id);
  if (maybe_group_id) {  // A numerical group ID.
    group_id = *maybe_group_id;
  } else {  // A group name.
    struct group* file_group = nullptr;
    // Query the group ID of |group|.
    do {
      file_group = getgrnam(group_name_or_id.c_str());
    } while (file_group == nullptr && errno == EINTR);
    if (file_group == nullptr) {
      return base::ErrStatus("Failed to get group information of %s ",
                             group_name_or_id.c_str());
    }
    group_id = file_group->gr_gid;
  }

  if (PERFETTO_EINTR(chown(file_path.c_str(), geteuid(), group_id))) {
    return base::ErrStatus("Failed to chown %s ", file_path.c_str());
  }

  // |mode| accepts values like "0660" as "rw-rw----" mode bits.
  auto mode_value = base::StringToInt32(mode_bits, 8);
  if (!(mode_bits.size() == 4 && mode_value.has_value())) {
    return base::ErrStatus(
        "The chmod mode bits must be a 4-digit octal number, e.g. 0660");
  }
  if (PERFETTO_EINTR(
          chmod(file_path.c_str(), static_cast<mode_t>(mode_value.value())))) {
    return base::ErrStatus("Failed to chmod %s", file_path.c_str());
  }
  return base::OkStatus();
#else
  base::ignore_result(file_path);
  base::ignore_result(group_name_or_id);
  base::ignore_result(mode_bits);
  return base::ErrStatus(
      "Setting file permissions is not supported on this platform");
#endif
}

std::optional<uint64_t> GetFileSize(const std::string& file_path) {
#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
  // This does not use base::OpenFile to avoid getting an exclusive lock.
  base::ScopedPlatformHandle fd(
      CreateFileA(file_path.c_str(), GENERIC_READ, FILE_SHARE_READ, nullptr,
                  OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr));
#else
  base::ScopedFile fd(base::OpenFile(file_path, O_RDONLY | O_CLOEXEC));
#endif
  if (!fd) {
    return std::nullopt;
  }
  return GetFileSize(*fd);
}

std::optional<uint64_t> GetFileSize(PlatformHandle fd) {
#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
  LARGE_INTEGER file_size;
  file_size.QuadPart = 0;
  if (!GetFileSizeEx(fd, &file_size)) {
    return std::nullopt;
  }
  static_assert(sizeof(decltype(file_size.QuadPart)) <= sizeof(uint64_t));
  return static_cast<uint64_t>(file_size.QuadPart);
#else
  struct stat buf {};
  if (fstat(fd, &buf) == -1) {
    return std::nullopt;
  }
  static_assert(sizeof(decltype(buf.st_size)) <= sizeof(uint64_t));
  return static_cast<uint64_t>(buf.st_size);
#endif
}

}  // namespace base
}  // namespace perfetto
// gen_amalgamated begin source: src/base/getopt_compat.cc
// gen_amalgamated begin header: include/perfetto/ext/base/getopt_compat.h
/*
 * Copyright (C) 2021 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef INCLUDE_PERFETTO_EXT_BASE_GETOPT_COMPAT_H_
#define INCLUDE_PERFETTO_EXT_BASE_GETOPT_COMPAT_H_

#include <cstddef>  // For std::nullptr_t

// No translation units other than base/getopt.h and getopt_compat_unittest.cc
// should directly include this file. Use base/getopt.h instead.

namespace perfetto {
namespace base {
namespace getopt_compat {

// A tiny getopt() replacement for Windows, which doesn't have <getopt.h>.
// This implementation is based on the subset of features that we use in the
// Perfetto codebase. It doesn't even try to deal with the full surface of GNU's
// getopt().
// Limitations:
// - getopt_long_only() is not supported.
// - optional_argument is not supported. That is extremely subtle and caused us
//   problems in the past with GNU's getopt.
// - It does not reorder non-option arguments. It behaves like MacOS getopt, or
//   GNU's when POSIXLY_CORRECT=1.
// - Doesn't expose optopt or opterr.
// - option.flag and longindex are not supported and must be nullptr.

enum {
  no_argument = 0,
  required_argument = 1,
};

struct option {
  const char* name;
  int has_arg;
  std::nullptr_t flag;  // Only nullptr is supported.
  int val;
};

extern char* optarg;
extern int optind;
extern int optopt;
extern int opterr;

int getopt_long(int argc,
                char** argv,
                const char* shortopts,
                const option* longopts,
                std::nullptr_t /*longindex is not supported*/);

int getopt(int argc, char** argv, const char* shortopts);

}  // namespace getopt_compat
}  // namespace base
}  // namespace perfetto

#endif  // INCLUDE_PERFETTO_EXT_BASE_GETOPT_COMPAT_H_
/*
 * Copyright (C) 2021 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// gen_amalgamated expanded: #include "perfetto/ext/base/getopt_compat.h"

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <vector>

// gen_amalgamated expanded: #include "perfetto/base/logging.h"

namespace perfetto {
namespace base {
namespace getopt_compat {

char* optarg = nullptr;
int optind = 0;
int optopt = 0;
int opterr = 1;

namespace {

char* nextchar = nullptr;

const option* LookupLongOpt(const std::vector<option>& opts,
                            const char* name,
                            size_t len) {
  for (const option& opt : opts) {
    if (strncmp(opt.name, name, len) == 0 && strlen(opt.name) == len)
      return &opt;
  }
  return nullptr;
}

const option* LookupShortOpt(const std::vector<option>& opts, char c) {
  for (const option& opt : opts) {
    if (!*opt.name && opt.val == c)
      return &opt;
  }
  return nullptr;
}

bool ParseOpts(const char* shortopts,
               const option* longopts,
               std::vector<option>* res) {
  // Parse long options first.
  for (const option* lopt = longopts; lopt && lopt->name; lopt++) {
    PERFETTO_CHECK(lopt->flag == nullptr);
    PERFETTO_CHECK(lopt->has_arg == no_argument ||
                   lopt->has_arg == required_argument);
    res->emplace_back(*lopt);
  }

  // Merge short options.
  for (const char* sopt = shortopts; sopt && *sopt;) {
    const size_t idx = static_cast<size_t>(sopt - shortopts);
    char c = *sopt++;
    bool valid = (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') ||
                 (c >= '0' && c <= '9');
    if (!valid) {
      fprintf(stderr,
              "Error parsing shortopts. Unexpected char '%c' at offset %zu\n",
              c, idx);
      return false;
    }
    res->emplace_back();
    option& opt = res->back();
    opt.name = "";
    opt.val = c;
    opt.has_arg = no_argument;
    if (*sopt == ':') {
      opt.has_arg = required_argument;
      ++sopt;
    }
  }
  return true;
}

}  // namespace

int getopt_long(int argc,
                char** argv,
                const char* shortopts,
                const option* longopts,
                std::nullptr_t /*longind*/) {
  std::vector<option> opts;
  optarg = nullptr;

  if (optind == 0)
    optind = 1;

  if (optind >= argc)
    return -1;

  if (!ParseOpts(shortopts, longopts, &opts))
    return '?';

  char* arg = argv[optind];
  optopt = 0;

  if (!nextchar) {
    // If |nextchar| is null we are NOT in the middle of a short option and we
    // should parse the next argv.
    if (strncmp(arg, "--", 2) == 0 && strlen(arg) > 2) {
      // A --long option.
      arg += 2;
      char* sep = strchr(arg, '=');
      optind++;

      size_t len = sep ? static_cast<size_t>(sep - arg) : strlen(arg);
      const option* opt = LookupLongOpt(opts, arg, len);

      if (!opt) {
        if (opterr)
          fprintf(stderr, "unrecognized option '--%s'\n", arg);
        return '?';
      }

      optopt = opt->val;
      if (opt->has_arg == no_argument) {
        if (sep) {
          fprintf(stderr, "option '--%s' doesn't allow an argument\n", arg);
          return '?';
        } else {
          return opt->val;
        }
      } else if (opt->has_arg == required_argument) {
        if (sep) {
          optarg = sep + 1;
          return opt->val;
        } else if (optind >= argc) {
          if (opterr)
            fprintf(stderr, "option '--%s' requires an argument\n", arg);
          return '?';
        } else {
          optarg = argv[optind++];
          return opt->val;
        }
      }
      // has_arg must be either |no_argument| or |required_argument|. We
      // shoulnd't get here unless the check in ParseOpts() has a bug.
      PERFETTO_CHECK(false);
    }  // if (arg ~= "--*").

    if (strlen(arg) > 1 && arg[0] == '-' && arg[1] != '-') {
      // A sequence of short options. Parsing logic continues below.
      nextchar = &arg[1];
    }
  }  // if(!nextchar)

  if (nextchar) {
    // At this point either:
    // 1. This is the first char of a sequence of short options, and we fell
    //    through here from the lines above.
    // 2. This is the N (>1) char of a sequence of short options, and we got
    //    here from a new getopt() call to getopt().
    const char cur_char = *nextchar;
    PERFETTO_CHECK(cur_char != '\0');

    // Advance the option char in any case, before we start reasoning on them.
    // if we got to the end of the "-abc" sequence, increment optind so the next
    // getopt() call resumes from the next argv argument.
    if (*(++nextchar) == '\0') {
      nextchar = nullptr;
      ++optind;
    }

    const option* opt = LookupShortOpt(opts, cur_char);
    optopt = cur_char;
    if (!opt) {
      if (opterr)
        fprintf(stderr, "invalid option -- '%c'\n", cur_char);
      return '?';
    }
    if (opt->has_arg == no_argument) {
      return cur_char;
    } else if (opt->has_arg == required_argument) {
      // This is a subtle getopt behavior. Say you call `tar -fx`, there are
      // two cases:
      // 1. If 'f' is no_argument then 'x' (and anything else after) is
      //    interpreted as an independent argument (like `tar -f -x`).
      // 2. If 'f' is required_argument, than everything else after the 'f'
      //    is interpreted as the option argument (like `tar -f x`)
      if (!nextchar) {
        // Case 1.
        if (optind >= argc) {
          if (opterr)
            fprintf(stderr, "option requires an argument -- '%c'\n", cur_char);
          return '?';
        } else {
          optarg = argv[optind++];
          return cur_char;
        }
      } else {
        // Case 2.
        optarg = nextchar;
        nextchar = nullptr;
        optind++;
        return cur_char;
      }
    }
    PERFETTO_CHECK(false);
  }  // if (nextchar)

  // If we get here, we found the first non-option argument. Stop here.

  if (strcmp(arg, "--") == 0)
    optind++;

  return -1;
}

int getopt(int argc, char** argv, const char* shortopts) {
  return getopt_long(argc, argv, shortopts, nullptr, nullptr);
}

}  // namespace getopt_compat
}  // namespace base
}  // namespace perfetto
// gen_amalgamated begin source: src/base/logging.cc
// gen_amalgamated begin header: src/base/log_ring_buffer.h
// gen_amalgamated begin header: include/perfetto/ext/base/thread_annotations.h
/*
 * Copyright (C) 2019 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef INCLUDE_PERFETTO_EXT_BASE_THREAD_ANNOTATIONS_H_
#define INCLUDE_PERFETTO_EXT_BASE_THREAD_ANNOTATIONS_H_

// gen_amalgamated expanded: #include "perfetto/base/build_config.h"

// Windows TSAN doesn't currently support these annotations.
#if defined(THREAD_SANITIZER) && !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
extern "C" {
void AnnotateBenignRaceSized(const char* file,
                             int line,
                             const volatile void* address,
                             size_t size,
                             const char* description);
}

#define PERFETTO_ANNOTATE_BENIGN_RACE_SIZED(pointer, size, description) \
  AnnotateBenignRaceSized(__FILE__, __LINE__, pointer, size, description);
#else  // defined(ADDRESS_SANITIZER)
#define PERFETTO_ANNOTATE_BENIGN_RACE_SIZED(pointer, size, description)
#endif  // defined(ADDRESS_SANITIZER)

#endif  // INCLUDE_PERFETTO_EXT_BASE_THREAD_ANNOTATIONS_H_
/*
 * Copyright (C) 2021 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef SRC_BASE_LOG_RING_BUFFER_H_
#define SRC_BASE_LOG_RING_BUFFER_H_

#include <stddef.h>
#include <stdio.h>

#include <array>
#include <atomic>

// gen_amalgamated expanded: #include "perfetto/ext/base/string_view.h"
// gen_amalgamated expanded: #include "perfetto/ext/base/thread_annotations.h"

namespace perfetto {
namespace base {

// Defined out of line because a static constexpr requires static storage if
// ODR-used, not worth adding a .cc file just for tests.
constexpr size_t kLogRingBufEntries = 8;
constexpr size_t kLogRingBufMsgLen = 256;

// A static non-allocating ring-buffer to hold the most recent log events.
// This class is really an implementation detail of logging.cc. The only reason
// why is fully defined in a dedicated header is for allowing unittesting,
// without leaking extra headers into logging.h (which is a high-fanout header).
// This is used to report the last logs in a crash report when a CHECK/FATAL
// is encountered.
// This class has just an Append() method to insert events into the buffer and
// a Read() to read the events in FIFO order. Read() is non-destructive.
//
// Thread safety considerations:
// - The Append() method can be called concurrently by several threads, unless
//   there are > kLogRingBufEntries concurrent threads. Even if that happens,
//   case some events will contain a mix of strings but the behavior of
//   futher Append() and Read() is still defined.
// - The Read() method is not thread safe but it's fine in practice. Even if
//   it's called concurrently with other Append(), it only causes some partial
//   events to be emitted in output.
// In both cases, we never rely purely on \0, all operations are size-bound.
//
// See logging_unittest.cc for tests.
class LogRingBuffer {
 public:
  LogRingBuffer() = default;
  LogRingBuffer(const LogRingBuffer&) = delete;
  LogRingBuffer& operator=(const LogRingBuffer&) = delete;
  LogRingBuffer(LogRingBuffer&&) = delete;
  LogRingBuffer& operator=(LogRingBuffer&&) = delete;

  // This takes three arguments because it fits its only caller (logging.cc).
  // The args are just concatenated together (plus one space before the msg).
  void Append(StringView tstamp, StringView source, StringView log_msg) {
    // Reserve atomically a slot in the ring buffer, so any concurrent Append()
    // won't overlap (unless too many concurrent Append() happen together).
    // There is no strict synchronization here, |event_slot_| is atomic only for
    // the sake of avoiding colliding on the same slot but does NOT guarantee
    // full consistency and integrity of the log messages written in each slot.
    // A release-store (or acq+rel) won't be enough for full consistency. Two
    // threads that race on Append() and take the N+1 and N+2 slots could finish
    // the write in reverse order. So Read() would need to synchronize with
    // something else (either a per-slot atomic flag or with a second atomic
    // counter which is incremented after the snprintf). Both options increase
    // the cost of Append() with no huge benefits (90% of the perfetto services
    // where we use it is single thread, and the log ring buffer is disabled
    // on non-standalone builds like the SDK).
    uint32_t slot = event_slot_.fetch_add(1, std::memory_order_relaxed);
    slot = slot % kLogRingBufEntries;

    char* const msg = events_[slot];
    PERFETTO_ANNOTATE_BENIGN_RACE_SIZED(msg, kLogRingBufMsgLen,
                                        "see comments in log_ring_buffer.h")
    snprintf(msg, kLogRingBufMsgLen, "%.*s%.*s %.*s",
             static_cast<int>(tstamp.size()), tstamp.data(),
             static_cast<int>(source.size()), source.data(),
             static_cast<int>(log_msg.size()), log_msg.data());
  }

  // Reads back the buffer in FIFO order, up to |len - 1| characters at most
  // (the -1 is because a NUL terminator is always appended, unless |len| == 0).
  // The string written in |dst| is guaranteed to be NUL-terminated, even if
  // |len| < buffer contents length.
  // Returns the number of bytes written in output, excluding the \0 terminator.
  size_t Read(char* dst, size_t len) {
    if (len == 0)
      return 0;
    // This is a relaxed-load because we don't need to fully synchronize on the
    // writing path for the reasons described in the fetch_add() above.
    const uint32_t event_slot = event_slot_.load(std::memory_order_relaxed);
    size_t dst_written = 0;
    for (uint32_t pos = 0; pos < kLogRingBufEntries; ++pos) {
      const uint32_t slot = (event_slot + pos) % kLogRingBufEntries;
      const char* src = events_[slot];
      if (*src == '\0')
        continue;  // Empty slot. Skip.
      char* const wptr = dst + dst_written;
      // |src| might not be null terminated. This can happen if some
      // thread-race happened. Limit the copy length.
      const size_t limit = std::min(len - dst_written, kLogRingBufMsgLen);
      for (size_t i = 0; i < limit; ++i) {
        const char c = src[i];
        ++dst_written;
        if (c == '\0' || i == limit - 1) {
          wptr[i] = '\n';
          break;
        }
        // Skip non-printable ASCII characters to avoid confusing crash reports.
        // Note that this deliberately mangles \n. Log messages should not have
        // a \n in the middle and are NOT \n terminated. The trailing \n between
        // each line is appended by the if () branch above.
        const bool is_printable = c >= ' ' && c <= '~';
        wptr[i] = is_printable ? c : '?';
      }
    }
    // Ensure that the output string is null-terminated.
    PERFETTO_DCHECK(dst_written <= len);
    if (dst_written == len) {
      // In case of truncation we replace the last char with \0. But the return
      // value is the number of chars without \0, hence the --.
      dst[--dst_written] = '\0';
    } else {
      dst[dst_written] = '\0';
    }
    return dst_written;
  }

 private:
  using EventBuf = char[kLogRingBufMsgLen];
  EventBuf events_[kLogRingBufEntries]{};

  static_assert((kLogRingBufEntries & (kLogRingBufEntries - 1)) == 0,
                "kLogRingBufEntries must be a power of two");

  // A monotonically increasing counter incremented on each event written.
  // It determines which of the kLogRingBufEntries indexes in |events_| should
  // be used next.
  // It grows >> kLogRingBufEntries, it's supposed to be always used
  // mod(kLogRingBufEntries). A static_assert in the .cc file ensures that
  // kLogRingBufEntries is a power of two so wraps are aligned.
  std::atomic<uint32_t> event_slot_{};
};

}  // namespace base
}  // namespace perfetto

#endif  // SRC_BASE_LOG_RING_BUFFER_H_
/*
 * Copyright (C) 2019 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// gen_amalgamated expanded: #include "perfetto/base/logging.h"

#include <stdarg.h>
#include <stdio.h>

#if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
#include <unistd.h>  // For isatty()
#endif

#include <atomic>
#include <memory>

// gen_amalgamated expanded: #include "perfetto/base/build_config.h"
// gen_amalgamated expanded: #include "perfetto/base/time.h"
// gen_amalgamated expanded: #include "perfetto/ext/base/crash_keys.h"
// gen_amalgamated expanded: #include "perfetto/ext/base/string_utils.h"
// gen_amalgamated expanded: #include "perfetto/ext/base/string_view.h"
// gen_amalgamated expanded: #include "src/base/log_ring_buffer.h"

#if PERFETTO_ENABLE_LOG_RING_BUFFER() && PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
#include <android/set_abort_message.h>
#endif

namespace perfetto {
namespace base {

namespace {
const char kReset[] = "\x1b[0m";
const char kDefault[] = "\x1b[39m";
const char kDim[] = "\x1b[2m";
const char kRed[] = "\x1b[31m";
const char kBoldGreen[] = "\x1b[1m\x1b[32m";
const char kLightGray[] = "\x1b[90m";

std::atomic<LogMessageCallback> g_log_callback{};

#if PERFETTO_BUILDFLAG(PERFETTO_STDERR_CRASH_DUMP)
// __attribute__((constructor)) causes a static initializer that automagically
// early runs this function before the main().
void PERFETTO_EXPORT_COMPONENT __attribute__((constructor))
InitDebugCrashReporter() {
  // This function is defined in debug_crash_stack_trace.cc.
  // The dynamic initializer is in logging.cc because logging.cc is included
  // in virtually any target that depends on base. Having it in
  // debug_crash_stack_trace.cc would require figuring out -Wl,whole-archive
  // which is not worth it.
  EnableStacktraceOnCrashForDebug();
}
#endif

#if PERFETTO_ENABLE_LOG_RING_BUFFER()
LogRingBuffer g_log_ring_buffer{};

// This is global to avoid allocating memory or growing too much the stack
// in MaybeSerializeLastLogsForCrashReporting(), which is called from
// arbitrary code paths hitting PERFETTO_CHECK()/FATAL().
char g_crash_buf[kLogRingBufEntries * kLogRingBufMsgLen];
#endif

}  // namespace

void SetLogMessageCallback(LogMessageCallback callback) {
  g_log_callback.store(callback, std::memory_order_relaxed);
}

void LogMessage(LogLev level,
                const char* fname,
                int line,
                const char* fmt,
                ...) {
  char stack_buf[512];
  std::unique_ptr<char[]> large_buf;
  char* log_msg = &stack_buf[0];
  size_t log_msg_len = 0;

  // By default use a stack allocated buffer because most log messages are quite
  // short. In rare cases they can be larger (e.g. --help). In those cases we
  // pay the cost of allocating the buffer on the heap.
  for (size_t max_len = sizeof(stack_buf);;) {
    va_list args;
    va_start(args, fmt);
    int res = vsnprintf(log_msg, max_len, fmt, args);
    va_end(args);

    // If for any reason the print fails, overwrite the message but still print
    // it. The code below will attach the filename and line, which is still
    // useful.
    if (res < 0) {
      snprintf(log_msg, max_len, "%s", "[printf format error]");
      break;
    }

    // if res == max_len, vsnprintf saturated the input buffer. Retry with a
    // larger buffer in that case (within reasonable limits).
    if (res < static_cast<int>(max_len) || max_len >= 128 * 1024) {
      // In case of truncation vsnprintf returns the len that "would have been
      // written if the string was longer", not the actual chars written.
      log_msg_len = std::min(static_cast<size_t>(res), max_len - 1);
      break;
    }
    max_len *= 4;
    large_buf.reset(new char[max_len]);
    log_msg = &large_buf[0];
  }

  LogMessageCallback cb = g_log_callback.load(std::memory_order_relaxed);
  if (cb) {
    cb({level, line, fname, log_msg});
    return;
  }

  const char* color = kDefault;
  switch (level) {
    case kLogDebug:
      color = kDim;
      break;
    case kLogInfo:
      color = kDefault;
      break;
    case kLogImportant:
      color = kBoldGreen;
      break;
    case kLogError:
      color = kRed;
      break;
  }

#if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) &&  \
    !PERFETTO_BUILDFLAG(PERFETTO_OS_WASM) && \
    !PERFETTO_BUILDFLAG(PERFETTO_CHROMIUM_BUILD)
  static const bool use_colors = isatty(STDERR_FILENO);
#else
  static const bool use_colors = false;
#endif

  // Formats file.cc:line as a space-padded fixed width string. If the file name
  // |fname| is too long, truncate it on the left-hand side.
  StackString<10> line_str("%d", line);

  // 24 will be the width of the file.cc:line column in the log event.
  static constexpr size_t kMaxNameAndLine = 24;
  size_t fname_len = strlen(fname);
  size_t fname_max = kMaxNameAndLine - line_str.len() - 2;  // 2 = ':' + '\0'.
  size_t fname_offset = fname_len <= fname_max ? 0 : fname_len - fname_max;
  StackString<kMaxNameAndLine> file_and_line(
      "%*s:%s", static_cast<int>(fname_max), &fname[fname_offset],
      line_str.c_str());

#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
  // Logcat has already timestamping, don't re-emit it.
  __android_log_print(int{ANDROID_LOG_DEBUG} + level, "perfetto", "%s %s",
                      file_and_line.c_str(), log_msg);
#endif

  // When printing on stderr, print also the timestamp. We don't really care
  // about the actual time. We just need some reference clock that can be used
  // to correlated events across differrent processses (e.g. traced and
  // traced_probes). The wall time % 1000 is good enough.
  uint32_t t_ms = static_cast<uint32_t>(GetWallTimeMs().count());
  uint32_t t_sec = t_ms / 1000;
  t_ms -= t_sec * 1000;
  t_sec = t_sec % 1000;
  StackString<32> timestamp("[%03u.%03u] ", t_sec, t_ms);

  if (use_colors) {
    fprintf(stderr, "%s%s%s%s %s%s%s\n", kLightGray, timestamp.c_str(),
            file_and_line.c_str(), kReset, color, log_msg, kReset);
  } else {
    fprintf(stderr, "%s%s %s\n", timestamp.c_str(), file_and_line.c_str(),
            log_msg);
  }

#if PERFETTO_ENABLE_LOG_RING_BUFFER()
  // Append the message to the ring buffer for crash reporting postmortems.
  StringView timestamp_sv = timestamp.string_view();
  StringView file_and_line_sv = file_and_line.string_view();
  StringView log_msg_sv(log_msg, static_cast<size_t>(log_msg_len));
  g_log_ring_buffer.Append(timestamp_sv, file_and_line_sv, log_msg_sv);
#else
  ignore_result(log_msg_len);
#endif
}

#if PERFETTO_ENABLE_LOG_RING_BUFFER()
void MaybeSerializeLastLogsForCrashReporting() {
  // Keep this function minimal. This is called from the watchdog thread, often
  // when the system is thrashing.

  // This is racy because two threads could hit a CHECK/FATAL at the same time.
  // But if that happens we have bigger problems, not worth designing around it.
  // The behaviour is still defined in the race case (the string attached to
  // the crash report will contain a mixture of log strings).
  size_t wr = 0;
  wr += SerializeCrashKeys(&g_crash_buf[wr], sizeof(g_crash_buf) - wr);
  wr += g_log_ring_buffer.Read(&g_crash_buf[wr], sizeof(g_crash_buf) - wr);

  // Read() null-terminates the string properly. This is just to avoid UB when
  // two threads race on each other (T1 writes a shorter string, T2
  // overwrites the \0 writing a longer string. T1 continues here before T2
  // finishes writing the longer string with the \0 -> boom.
  g_crash_buf[sizeof(g_crash_buf) - 1] = '\0';

#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
  // android_set_abort_message() will cause debuggerd to report the message
  // in the tombstone and in the crash log in logcat.
  // NOTE: android_set_abort_message() can be called only once. This should
  // be called only when we are sure we are about to crash.
  android_set_abort_message(g_crash_buf);
#else
  // Print out the message on stderr on Linux/Mac/Win.
  fputs("\n-----BEGIN PERFETTO PRE-CRASH LOG-----\n", stderr);
  fputs(g_crash_buf, stderr);
  fputs("\n-----END PERFETTO PRE-CRASH LOG-----\n", stderr);
#endif
}
#endif  // PERFETTO_ENABLE_LOG_RING_BUFFER

}  // namespace base
}  // namespace perfetto
// gen_amalgamated begin source: src/base/metatrace.cc
// gen_amalgamated begin header: include/perfetto/ext/base/metatrace.h
// gen_amalgamated begin header: include/perfetto/ext/base/metatrace_events.h
/*
 * Copyright (C) 2019 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef INCLUDE_PERFETTO_EXT_BASE_METATRACE_EVENTS_H_
#define INCLUDE_PERFETTO_EXT_BASE_METATRACE_EVENTS_H_

#include <stdint.h>

namespace perfetto {
namespace metatrace {

enum Tags : uint32_t {
  TAG_NONE = 0,
  TAG_ANY = uint32_t(-1),
  TAG_FTRACE = 1 << 0,
  TAG_PROC_POLLERS = 1 << 1,
  TAG_TRACE_WRITER = 1 << 2,
  TAG_TRACE_SERVICE = 1 << 3,
  TAG_PRODUCER = 1 << 4,
};

// The macros below generate matching enums and arrays of string literals.
// This is to avoid maintaining string maps manually.

// clang-format off

// DO NOT remove or reshuffle items in this list, only append. The ID of these
// events are an ABI, the trace processor relies on these to open old traces.
#define PERFETTO_METATRACE_EVENTS(F) \
  F(EVENT_ZERO_UNUSED), \
  F(FTRACE_CPU_READER_READ), /*unused*/ \
  F(FTRACE_DRAIN_CPUS), /*unused*/ \
  F(FTRACE_UNBLOCK_READERS), /*unused*/ \
  F(FTRACE_CPU_READ_NONBLOCK), /*unused*/ \
  F(FTRACE_CPU_READ_BLOCK), /*unused*/ \
  F(FTRACE_CPU_SPLICE_NONBLOCK), /*unused*/ \
  F(FTRACE_CPU_SPLICE_BLOCK), /*unused*/ \
  F(FTRACE_CPU_WAIT_CMD), /*unused*/ \
  F(FTRACE_CPU_RUN_CYCLE), /*unused*/ \
  F(FTRACE_CPU_FLUSH), \
  F(FTRACE_CPU_BUFFER_WATERMARK), \
  F(READ_SYS_STATS), \
  F(PS_WRITE_ALL_PROCESSES), \
  F(PS_ON_PIDS), \
  F(PS_ON_RENAME_PIDS), \
  F(PS_WRITE_ALL_PROCESS_STATS), \
  F(TRACE_WRITER_COMMIT_STARTUP_WRITER_BATCH), \
  F(FTRACE_READ_TICK), \
  F(FTRACE_CPU_READ_CYCLE), \
  F(FTRACE_CPU_READ_BATCH), \
  F(KALLSYMS_PARSE), \
  F(PROFILER_READ_TICK), \
  F(PROFILER_READ_CPU), \
  F(PROFILER_UNWIND_TICK), \
  F(PROFILER_UNWIND_SAMPLE), \
  F(PROFILER_UNWIND_INITIAL_ATTEMPT), \
  F(PROFILER_UNWIND_ATTEMPT), \
  F(PROFILER_MAPS_PARSE), \
  F(PROFILER_MAPS_REPARSE), \
  F(PROFILER_UNWIND_CACHE_CLEAR)

// Append only, see above.
//
// Values that aren't used as counters:
// * FTRACE_SERVICE_COMMIT_DATA is a bit-packed representation of an event, see
//   tracing_service_impl.cc for the format.
// * PROFILER_UNWIND_CURRENT_PID represents the PID that is being unwound.
//
#define PERFETTO_METATRACE_COUNTERS(F) \
  F(COUNTER_ZERO_UNUSED),\
  F(FTRACE_PAGES_DRAINED), \
  F(PS_PIDS_SCANNED), \
  F(TRACE_SERVICE_COMMIT_DATA), \
  F(PROFILER_UNWIND_QUEUE_SZ), \
  F(PROFILER_UNWIND_CURRENT_PID)

// clang-format on

#define PERFETTO_METATRACE_IDENTITY(name) name
#define PERFETTO_METATRACE_TOSTRING(name) #name

enum Events : uint16_t {
  PERFETTO_METATRACE_EVENTS(PERFETTO_METATRACE_IDENTITY),
  EVENTS_MAX
};
constexpr char const* kEventNames[] = {
    PERFETTO_METATRACE_EVENTS(PERFETTO_METATRACE_TOSTRING)};

enum Counters : uint16_t {
  PERFETTO_METATRACE_COUNTERS(PERFETTO_METATRACE_IDENTITY),
  COUNTERS_MAX
};
constexpr char const* kCounterNames[] = {
    PERFETTO_METATRACE_COUNTERS(PERFETTO_METATRACE_TOSTRING)};

inline void SuppressUnusedVarsInAmalgamatedBuild() {
  (void)kCounterNames;
  (void)kEventNames;
}

}  // namespace metatrace
}  // namespace perfetto

#endif  // INCLUDE_PERFETTO_EXT_BASE_METATRACE_EVENTS_H_
/*
 * Copyright (C) 2019 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef INCLUDE_PERFETTO_EXT_BASE_METATRACE_H_
#define INCLUDE_PERFETTO_EXT_BASE_METATRACE_H_

#include <array>
#include <atomic>
#include <functional>
#include <string>

// gen_amalgamated expanded: #include "perfetto/base/logging.h"
// gen_amalgamated expanded: #include "perfetto/base/thread_utils.h"
// gen_amalgamated expanded: #include "perfetto/base/time.h"
// gen_amalgamated expanded: #include "perfetto/ext/base/metatrace_events.h"
// gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"

// A facility to trace execution of the perfetto codebase itself.
// The meta-tracing framework is organized into three layers:
//
// 1. A static ring-buffer in base/ (this file) that supports concurrent writes
//    and a single reader.
//    The responsibility of this layer is to store events and counters as
//    efficiently as possible without re-entering any tracing code.
//    This is really a static-storage-based ring-buffer based on a POD array.
//    This layer does NOT deal with serializing the meta-trace buffer.
//    It posts a task when it's half full and expects something outside of
//    base/ to drain the ring-buffer and serialize it, eventually writing it
//    into the trace itself, before it gets 100% full.
//
// 2. A class in tracing/core which takes care of serializing the meta-trace
//    buffer into the trace using a TraceWriter. See metatrace_writer.h .
//
// 3. A data source in traced_probes that, when be enabled via the trace config,
//    injects metatrace events into the trace. See metatrace_data_source.h .
//
// The available events and tags are defined in metatrace_events.h .

namespace perfetto {

namespace base {
class TaskRunner;
}  // namespace base

namespace metatrace {

// Meta-tracing is organized in "tags" that can be selectively enabled. This is
// to enable meta-tracing only of one sub-system. This word has one "enabled"
// bit for each tag. 0 -> meta-tracing off.
extern std::atomic<uint32_t> g_enabled_tags;

// Time of the Enable() call. Used as a reference for keeping delta timestmaps
// in Record.
extern std::atomic<uint64_t> g_enabled_timestamp;

// Enables meta-tracing for one or more tags. Once enabled it will discard any
// further Enable() calls and return false until disabled,
// |read_task| is a closure that will be called enqueued |task_runner| when the
// meta-tracing ring buffer is half full. The task is expected to read the ring
// buffer using RingBuffer::GetReadIterator() and serialize the contents onto a
// file or into the trace itself.
// Must be called on the |task_runner| passed.
// |task_runner| must have static lifetime.
bool Enable(std::function<void()> read_task, base::TaskRunner*, uint32_t tags);

// Disables meta-tracing.
// Must be called on the same |task_runner| as Enable().
void Disable();

inline uint64_t TraceTimeNowNs() {
  return static_cast<uint64_t>(base::GetBootTimeNs().count());
}

// Returns a relaxed view of whether metatracing is enabled for the given tag.
// Useful for skipping unnecessary argument computation if metatracing is off.
inline bool IsEnabled(uint32_t tag) {
  auto enabled_tags = g_enabled_tags.load(std::memory_order_relaxed);
  return PERFETTO_UNLIKELY((enabled_tags & tag) != 0);
}

// Holds the data for a metatrace event or counter.
struct Record {
  static constexpr uint16_t kTypeMask = 0x8000;
  static constexpr uint16_t kTypeCounter = 0x8000;
  static constexpr uint16_t kTypeEvent = 0;

  uint64_t timestamp_ns() const {
    auto base_ns = g_enabled_timestamp.load(std::memory_order_relaxed);
    PERFETTO_DCHECK(base_ns);
    return base_ns + ((static_cast<uint64_t>(timestamp_ns_high) << 32) |
                      timestamp_ns_low);
  }

  void set_timestamp(uint64_t ts) {
    auto t_start = g_enabled_timestamp.load(std::memory_order_relaxed);
    uint64_t diff = ts - t_start;
    PERFETTO_DCHECK(diff < (1ull << 48));
    timestamp_ns_low = static_cast<uint32_t>(diff);
    timestamp_ns_high = static_cast<uint16_t>(diff >> 32);
  }

  // We can't just memset() this class because on MSVC std::atomic<> is not
  // trivially constructible anymore. Also std::atomic<> has a deleted copy
  // constructor so we cant just do "*this = Record()" either.
  // See http://bit.ly/339Jlzd .
  void clear() {
    this->~Record();
    new (this) Record();
  }

  // This field holds the type (counter vs event) in the MSB and event ID (as
  // defined in metatrace_events.h) in the lowest 15 bits. It is also used also
  // as a linearization point: this is always written after all the other
  // fields with a release-store. This is so the reader can determine whether it
  // can safely process the other event fields after a load-acquire.
  std::atomic<uint16_t> type_and_id{};

  // Timestamp is stored as a 48-bits value diffed against g_enabled_timestamp.
  // This gives us 78 hours from Enabled().
  uint16_t timestamp_ns_high = 0;
  uint32_t timestamp_ns_low = 0;

  uint32_t thread_id = 0;

  union {
    // Only one of the two elements can be zero initialized, clang complains
    // about "initializing multiple members of union" otherwise.
    uint32_t duration_ns = 0;  // If type == event.
    int32_t counter_value;     // If type == counter.
  };
};

// Hold the meta-tracing data into a statically allocated array.
// This class uses static storage (as opposite to being a singleton) to:
// - Have the guarantee of always valid storage, so that meta-tracing can be
//   safely used in any part of the codebase, including base/ itself.
// - Avoid barriers that thread-safe static locals would require.
class RingBuffer {
 public:
  static constexpr size_t kCapacity = 4096;  // 4096 * 16 bytes = 64K.

  // This iterator is not idempotent and will bump the read index in the buffer
  // at the end of the reads. There can be only one reader at any time.
  // Usage: for (auto it = RingBuffer::GetReadIterator(); it; ++it) { it->... }
  class ReadIterator {
   public:
    ReadIterator(ReadIterator&& other) {
      PERFETTO_DCHECK(other.valid_);
      cur_ = other.cur_;
      end_ = other.end_;
      valid_ = other.valid_;
      other.valid_ = false;
    }

    ~ReadIterator() {
      if (!valid_)
        return;
      PERFETTO_DCHECK(cur_ >= RingBuffer::rd_index_);
      PERFETTO_DCHECK(cur_ <= RingBuffer::wr_index_);
      RingBuffer::rd_index_.store(cur_, std::memory_order_release);
    }

    explicit operator bool() const { return cur_ < end_; }
    const Record* operator->() const { return RingBuffer::At(cur_); }
    const Record& operator*() const { return *operator->(); }

    // This is for ++it. it++ is deliberately not supported.
    ReadIterator& operator++() {
      PERFETTO_DCHECK(cur_ < end_);
      // Once a record has been read, mark it as free clearing its type_and_id,
      // so if we encounter it in another read iteration while being written
      // we know it's not fully written yet.
      // The memory_order_relaxed below is enough because:
      // - The reader is single-threaded and doesn't re-read the same records.
      // - Before starting a read batch, the reader has an acquire barrier on
      //   |rd_index_|.
      // - After terminating a read batch, the ~ReadIterator dtor updates the
      //   |rd_index_| with a release-store.
      // - Reader and writer are typically kCapacity/2 apart. So unless an
      //   overrun happens a writer won't reuse a newly released record any time
      //   soon. If an overrun happens, everything is busted regardless.
      At(cur_)->type_and_id.store(0, std::memory_order_relaxed);
      ++cur_;
      return *this;
    }

   private:
    friend class RingBuffer;
    ReadIterator(uint64_t begin, uint64_t end)
        : cur_(begin), end_(end), valid_(true) {}
    ReadIterator& operator=(const ReadIterator&) = delete;
    ReadIterator(const ReadIterator&) = delete;

    uint64_t cur_;
    uint64_t end_;
    bool valid_;
  };

  static Record* At(uint64_t index) {
    // Doesn't really have to be pow2, but if not the compiler will emit
    // arithmetic operations to compute the modulo instead of a bitwise AND.
    static_assert(!(kCapacity & (kCapacity - 1)), "kCapacity must be pow2");
    PERFETTO_DCHECK(index >= rd_index_);
    PERFETTO_DCHECK(index <= wr_index_);
    return &records_[index % kCapacity];
  }

  // Must be called on the same task runner passed to Enable()
  static ReadIterator GetReadIterator() {
    PERFETTO_DCHECK(RingBuffer::IsOnValidTaskRunner());
    return ReadIterator(rd_index_.load(std::memory_order_acquire),
                        wr_index_.load(std::memory_order_acquire));
  }

  static Record* AppendNewRecord();
  static void Reset();

  static bool has_overruns() {
    return has_overruns_.load(std::memory_order_acquire);
  }

  // Can temporarily return a value >= kCapacity but is eventually consistent.
  // This would happen in case of overruns until threads hit the --wr_index_
  // in AppendNewRecord().
  static uint64_t GetSizeForTesting() {
    auto wr_index = wr_index_.load(std::memory_order_relaxed);
    auto rd_index = rd_index_.load(std::memory_order_relaxed);
    PERFETTO_DCHECK(wr_index >= rd_index);
    return wr_index - rd_index;
  }

 private:
  friend class ReadIterator;

  // Returns true if the caller is on the task runner passed to Enable().
  // Used only for DCHECKs.
  static bool IsOnValidTaskRunner();

  static std::array<Record, kCapacity> records_;
  static std::atomic<bool> read_task_queued_;
  static std::atomic<uint64_t> wr_index_;
  static std::atomic<uint64_t> rd_index_;
  static std::atomic<bool> has_overruns_;
  static Record bankruptcy_record_;  // Used in case of overruns.
};

inline void TraceCounter(uint32_t tag, uint16_t id, int32_t value) {
  // memory_order_relaxed is okay because the storage has static lifetime.
  // It is safe to accidentally log an event soon after disabling.
  auto enabled_tags = g_enabled_tags.load(std::memory_order_relaxed);
  if (PERFETTO_LIKELY((enabled_tags & tag) == 0))
    return;
  Record* record = RingBuffer::AppendNewRecord();
  record->thread_id = static_cast<uint32_t>(base::GetThreadId());
  record->set_timestamp(TraceTimeNowNs());
  record->counter_value = value;
  record->type_and_id.store(Record::kTypeCounter | id,
                            std::memory_order_release);
}

class ScopedEvent {
 public:
  ScopedEvent(uint32_t tag, uint16_t event_id) {
    auto enabled_tags = g_enabled_tags.load(std::memory_order_relaxed);
    if (PERFETTO_LIKELY((enabled_tags & tag) == 0))
      return;
    event_id_ = event_id;
    record_ = RingBuffer::AppendNewRecord();
    record_->thread_id = static_cast<uint32_t>(base::GetThreadId());
    record_->set_timestamp(TraceTimeNowNs());
  }

  ~ScopedEvent() {
    if (PERFETTO_LIKELY(!record_))
      return;
    auto now = TraceTimeNowNs();
    record_->duration_ns = static_cast<uint32_t>(now - record_->timestamp_ns());
    record_->type_and_id.store(Record::kTypeEvent | event_id_,
                               std::memory_order_release);
  }

 private:
  Record* record_ = nullptr;
  uint16_t event_id_ = 0;
  ScopedEvent(const ScopedEvent&) = delete;
  ScopedEvent& operator=(const ScopedEvent&) = delete;
};

// Boilerplate to derive a unique variable name for the event.
#define PERFETTO_METATRACE_UID2(a, b) a##b
#define PERFETTO_METATRACE_UID(x) PERFETTO_METATRACE_UID2(metatrace_, x)

#define PERFETTO_METATRACE_SCOPED(TAG, ID)                                \
  ::perfetto::metatrace::ScopedEvent PERFETTO_METATRACE_UID(__COUNTER__)( \
      ::perfetto::metatrace::TAG, ::perfetto::metatrace::ID)

#define PERFETTO_METATRACE_COUNTER(TAG, ID, VALUE)                \
  ::perfetto::metatrace::TraceCounter(::perfetto::metatrace::TAG, \
                                      ::perfetto::metatrace::ID,  \
                                      static_cast<int32_t>(VALUE))

}  // namespace metatrace
}  // namespace perfetto

#endif  // INCLUDE_PERFETTO_EXT_BASE_METATRACE_H_
// gen_amalgamated begin header: include/perfetto/base/task_runner.h
/*
 * Copyright (C) 2017 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef INCLUDE_PERFETTO_BASE_TASK_RUNNER_H_
#define INCLUDE_PERFETTO_BASE_TASK_RUNNER_H_

#include <stdint.h>

#include <functional>

// gen_amalgamated expanded: #include "perfetto/base/export.h"
// gen_amalgamated expanded: #include "perfetto/base/platform_handle.h"

namespace perfetto {
namespace base {

// A generic interface to allow the library clients to interleave the execution
// of the tracing internals in their runtime environment.
// The expectation is that all tasks, which are queued either via PostTask() or
// AddFileDescriptorWatch(), are executed on the same sequence (either on the
// same thread, or on a thread pool that gives sequencing guarantees).
//
// Tasks are never executed synchronously inside PostTask and there is a full
// memory barrier between tasks.
//
// All methods of this interface can be called from any thread.
class PERFETTO_EXPORT_COMPONENT TaskRunner {
 public:
  virtual ~TaskRunner();

  // Schedule a task for immediate execution. Immediate tasks are always
  // executed in the order they are posted. Can be called from any thread.
  virtual void PostTask(std::function<void()>) = 0;

  // Schedule a task for execution after |delay_ms|. Note that there is no
  // strict ordering guarantee between immediate and delayed tasks. Can be
  // called from any thread.
  virtual void PostDelayedTask(std::function<void()>, uint32_t delay_ms) = 0;

  // Schedule a task to run when the handle becomes readable. The same handle
  // can only be monitored by one function. Note that this function only needs
  // to be implemented on platforms where the built-in ipc framework is used.
  // Can be called from any thread.
  // TODO(skyostil): Refactor this out of the shared interface.
  virtual void AddFileDescriptorWatch(PlatformHandle,
                                      std::function<void()>) = 0;

  // Remove a previously scheduled watch for the handle. If this is run on the
  // target thread of this TaskRunner, guarantees that the task registered to
  // this handle will not be executed after this function call.
  // Can be called from any thread.
  virtual void RemoveFileDescriptorWatch(PlatformHandle) = 0;

  // Checks if the current thread is the same thread where the TaskRunner's task
  // run. This allows single threaded task runners (like the ones used in
  // perfetto) to inform the caller that anything posted will run on the same
  // thread/sequence. This can allow some callers to skip PostTask and instead
  // directly execute the code. Can be called from any thread.
  virtual bool RunsTasksOnCurrentThread() const = 0;
};

}  // namespace base
}  // namespace perfetto

#endif  // INCLUDE_PERFETTO_BASE_TASK_RUNNER_H_
/*
 * Copyright (C) 2018 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// gen_amalgamated expanded: #include "perfetto/ext/base/metatrace.h"

// gen_amalgamated expanded: #include "perfetto/base/compiler.h"
// gen_amalgamated expanded: #include "perfetto/base/task_runner.h"
// gen_amalgamated expanded: #include "perfetto/base/time.h"
// gen_amalgamated expanded: #include "perfetto/ext/base/file_utils.h"
// gen_amalgamated expanded: #include "perfetto/ext/base/thread_annotations.h"

namespace perfetto {
namespace metatrace {

std::atomic<uint32_t> g_enabled_tags{0};
std::atomic<uint64_t> g_enabled_timestamp{0};

// static members
std::array<Record, RingBuffer::kCapacity> RingBuffer::records_;
std::atomic<bool> RingBuffer::read_task_queued_;
std::atomic<uint64_t> RingBuffer::wr_index_;
std::atomic<uint64_t> RingBuffer::rd_index_;
std::atomic<bool> RingBuffer::has_overruns_;
Record RingBuffer::bankruptcy_record_;

namespace {

// std::function<> is not trivially de/constructible. This struct wraps it in a
// heap-allocated struct to avoid static initializers.
struct Delegate {
  static Delegate* GetInstance() {
    static Delegate* instance = new Delegate();
    return instance;
  }

  base::TaskRunner* task_runner = nullptr;
  std::function<void()> read_task;
};

}  // namespace

bool Enable(std::function<void()> read_task,
            base::TaskRunner* task_runner,
            uint32_t tags) {
  PERFETTO_DCHECK(read_task);
  PERFETTO_DCHECK(task_runner->RunsTasksOnCurrentThread());
  if (g_enabled_tags.load(std::memory_order_acquire))
    return false;

  Delegate* dg = Delegate::GetInstance();
  dg->task_runner = task_runner;
  dg->read_task = std::move(read_task);
  RingBuffer::Reset();
  g_enabled_timestamp.store(TraceTimeNowNs(), std::memory_order_relaxed);
  g_enabled_tags.store(tags, std::memory_order_release);
  return true;
}

void Disable() {
  g_enabled_tags.store(0, std::memory_order_release);
  Delegate* dg = Delegate::GetInstance();
  PERFETTO_DCHECK(!dg->task_runner ||
                  dg->task_runner->RunsTasksOnCurrentThread());
  dg->task_runner = nullptr;
  dg->read_task = nullptr;
}

// static
void RingBuffer::Reset() {
  bankruptcy_record_.clear();
  for (Record& record : records_)
    record.clear();
  wr_index_ = 0;
  rd_index_ = 0;
  has_overruns_ = false;
  read_task_queued_ = false;
}

// static
Record* RingBuffer::AppendNewRecord() {
  auto wr_index = wr_index_.fetch_add(1, std::memory_order_acq_rel);

  // rd_index can only monotonically increase, we don't care if we read an
  // older value, we'll just hit the slow-path a bit earlier if it happens.
  auto rd_index = rd_index_.load(std::memory_order_relaxed);

  PERFETTO_DCHECK(wr_index >= rd_index);
  auto size = wr_index - rd_index;
  if (PERFETTO_LIKELY(size < kCapacity / 2))
    return At(wr_index);

  // Slow-path: Enqueue the read task and handle overruns.
  bool expected = false;
  if (RingBuffer::read_task_queued_.compare_exchange_strong(expected, true)) {
    Delegate* dg = Delegate::GetInstance();
    if (dg->task_runner) {
      dg->task_runner->PostTask([] {
        // Meta-tracing might have been disabled in the meantime.
        auto read_task = Delegate::GetInstance()->read_task;
        if (read_task)
          read_task();
        RingBuffer::read_task_queued_ = false;
      });
    }
  }

  if (PERFETTO_LIKELY(size < kCapacity))
    return At(wr_index);

  has_overruns_.store(true, std::memory_order_release);
  wr_index_.fetch_sub(1, std::memory_order_acq_rel);

  // In the case of overflows, threads will race writing on the same memory
  // location and TSan will rightly complain. This is fine though because nobody
  // will read the bankruptcy record and it's designed to contain garbage.
  PERFETTO_ANNOTATE_BENIGN_RACE_SIZED(&bankruptcy_record_, sizeof(Record),
                                      "nothing reads bankruptcy_record_")
  return &bankruptcy_record_;
}

// static
bool RingBuffer::IsOnValidTaskRunner() {
  auto* task_runner = Delegate::GetInstance()->task_runner;
  return task_runner && task_runner->RunsTasksOnCurrentThread();
}

}  // namespace metatrace
}  // namespace perfetto
// gen_amalgamated begin source: src/base/paged_memory.cc
// gen_amalgamated begin header: include/perfetto/ext/base/paged_memory.h
// gen_amalgamated begin header: include/perfetto/ext/base/container_annotations.h
/*
 * Copyright (C) 2018 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef INCLUDE_PERFETTO_EXT_BASE_CONTAINER_ANNOTATIONS_H_
#define INCLUDE_PERFETTO_EXT_BASE_CONTAINER_ANNOTATIONS_H_

// gen_amalgamated expanded: #include "perfetto/base/build_config.h"

// Windows ASAN doesn't currently support these annotations.
#if defined(ADDRESS_SANITIZER) && !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) && \
    !defined(ADDRESS_SANITIZER_WITHOUT_INSTRUMENTATION)

#include <sanitizer/common_interface_defs.h>

#define ANNOTATE_NEW_BUFFER(buffer, capacity, new_size)                      \
  if (buffer) {                                                              \
    __sanitizer_annotate_contiguous_container(buffer, (buffer) + (capacity), \
                                              (buffer) + (capacity),         \
                                              (buffer) + (new_size));        \
  }
#define ANNOTATE_DELETE_BUFFER(buffer, capacity, old_size)                   \
  if (buffer) {                                                              \
    __sanitizer_annotate_contiguous_container(buffer, (buffer) + (capacity), \
                                              (buffer) + (old_size),         \
                                              (buffer) + (capacity));        \
  }
#define ANNOTATE_CHANGE_SIZE(buffer, capacity, old_size, new_size)           \
  if (buffer) {                                                              \
    __sanitizer_annotate_contiguous_container(buffer, (buffer) + (capacity), \
                                              (buffer) + (old_size),         \
                                              (buffer) + (new_size));        \
  }
#define ANNOTATE_CHANGE_CAPACITY(buffer, old_capacity, buffer_size, \
                                 new_capacity)                      \
  ANNOTATE_DELETE_BUFFER(buffer, old_capacity, buffer_size);        \
  ANNOTATE_NEW_BUFFER(buffer, new_capacity, buffer_size);
// Annotations require buffers to begin on an 8-byte boundary.
#else  // defined(ADDRESS_SANITIZER)
#define ANNOTATE_NEW_BUFFER(buffer, capacity, new_size)
#define ANNOTATE_DELETE_BUFFER(buffer, capacity, old_size)
#define ANNOTATE_CHANGE_SIZE(buffer, capacity, old_size, new_size)
#define ANNOTATE_CHANGE_CAPACITY(buffer, old_capacity, buffer_size, \
                                 new_capacity)
#endif  // defined(ADDRESS_SANITIZER)

#endif  // INCLUDE_PERFETTO_EXT_BASE_CONTAINER_ANNOTATIONS_H_
/*
 * Copyright (C) 2017 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef INCLUDE_PERFETTO_EXT_BASE_PAGED_MEMORY_H_
#define INCLUDE_PERFETTO_EXT_BASE_PAGED_MEMORY_H_

#include <cstddef>
#include <memory>

// gen_amalgamated expanded: #include "perfetto/base/build_config.h"
// gen_amalgamated expanded: #include "perfetto/ext/base/container_annotations.h"

// We need to track the committed size on windows and when ASAN is enabled.
#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) || defined(ADDRESS_SANITIZER)
#define TRACK_COMMITTED_SIZE() 1
#else
#define TRACK_COMMITTED_SIZE() 0
#endif

namespace perfetto {
namespace base {

class PagedMemory {
 public:
  // Initializes an invalid PagedMemory pointing to nullptr.
  PagedMemory();

  ~PagedMemory();

  PagedMemory(PagedMemory&& other) noexcept;
  PagedMemory& operator=(PagedMemory&& other);

  enum AllocationFlags {
    // By default, Allocate() crashes if the underlying mmap fails (e.g., if out
    // of virtual address space). When this flag is provided, an invalid
    // PagedMemory pointing to nullptr is returned in this case instead.
    kMayFail = 1 << 0,

    // By default, Allocate() commits the allocated memory immediately. When
    // this flag is provided, the memory virtual address space may only be
    // reserved and the user should call EnsureCommitted() before writing to
    // memory addresses.
    kDontCommit = 1 << 1,
  };

  // Allocates |size| bytes using mmap(MAP_ANONYMOUS). The returned memory is
  // guaranteed to be page-aligned and guaranteed to be zeroed.
  // For |flags|, see the AllocationFlags enum above.
  static PagedMemory Allocate(size_t size, int flags = 0);

  // Hint to the OS that the memory range is not needed and can be discarded.
  // The memory remains accessible and its contents may be retained, or they
  // may be zeroed. This function may be a NOP on some platforms. Returns true
  // if implemented.
  bool AdviseDontNeed(void* p, size_t size);

  // Ensures that at least the first |committed_size| bytes of the allocated
  // memory region are committed. The implementation may commit memory in larger
  // chunks above |committed_size|. Crashes if the memory couldn't be committed.
#if TRACK_COMMITTED_SIZE()
  void EnsureCommitted(size_t committed_size);
#else   // TRACK_COMMITTED_SIZE()
  void EnsureCommitted(size_t /*committed_size*/) {}
#endif  // TRACK_COMMITTED_SIZE()

  inline void* Get() const noexcept { return p_; }
  inline bool IsValid() const noexcept { return !!p_; }
  inline size_t size() const noexcept { return size_; }

 private:
  PagedMemory(char* p, size_t size);

  PagedMemory(const PagedMemory&) = delete;
  // Defaulted for implementation of move constructor + assignment.
  PagedMemory& operator=(const PagedMemory&) = default;

  char* p_ = nullptr;

  // The size originally passed to Allocate(). The actual virtual memory
  // reservation will be larger due to: (i) guard pages; (ii) rounding up to
  // the system page size.
  size_t size_ = 0;

#if TRACK_COMMITTED_SIZE()
  size_t committed_size_ = 0u;
#endif  // TRACK_COMMITTED_SIZE()
};

}  // namespace base
}  // namespace perfetto

#endif  // INCLUDE_PERFETTO_EXT_BASE_PAGED_MEMORY_H_
/*
 * Copyright (C) 2017 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// gen_amalgamated expanded: #include "perfetto/ext/base/paged_memory.h"

#include <algorithm>
#include <cmath>
#include <cstddef>

#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
#include <Windows.h>
#else  // PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
#include <sys/mman.h>
#endif  // PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)

// gen_amalgamated expanded: #include "perfetto/base/logging.h"
// gen_amalgamated expanded: #include "perfetto/ext/base/container_annotations.h"
// gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"

namespace perfetto {
namespace base {

namespace {

#if TRACK_COMMITTED_SIZE()
constexpr size_t kCommitChunkSize = 4 * 1024 * 1024;  // 4MB
#endif

size_t RoundUpToSysPageSize(size_t req_size) {
  const size_t page_size = GetSysPageSize();
  return (req_size + page_size - 1) & ~(page_size - 1);
}

size_t GuardSize() {
  return GetSysPageSize();
}

}  // namespace

// static
PagedMemory PagedMemory::Allocate(size_t req_size, int flags) {
  size_t rounded_up_size = RoundUpToSysPageSize(req_size);
  PERFETTO_CHECK(rounded_up_size >= req_size);
  size_t outer_size = rounded_up_size + GuardSize() * 2;
#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
  void* ptr = VirtualAlloc(nullptr, outer_size, MEM_RESERVE, PAGE_NOACCESS);
  if (!ptr && (flags & kMayFail))
    return PagedMemory();
  PERFETTO_CHECK(ptr);
  char* usable_region = reinterpret_cast<char*>(ptr) + GuardSize();
#else   // PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
  void* ptr = mmap(nullptr, outer_size, PROT_READ | PROT_WRITE,
                   MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
  if (ptr == MAP_FAILED && (flags & kMayFail))
    return PagedMemory();
  PERFETTO_CHECK(ptr && ptr != MAP_FAILED);
  char* usable_region = reinterpret_cast<char*>(ptr) + GuardSize();
  int res = mprotect(ptr, GuardSize(), PROT_NONE);
  res |= mprotect(usable_region + rounded_up_size, GuardSize(), PROT_NONE);
  PERFETTO_CHECK(res == 0);
#endif  // PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)

  auto memory = PagedMemory(usable_region, req_size);
#if TRACK_COMMITTED_SIZE()
  size_t initial_commit = req_size;
  if (flags & kDontCommit)
    initial_commit = std::min(initial_commit, kCommitChunkSize);
  memory.EnsureCommitted(initial_commit);
#endif  // TRACK_COMMITTED_SIZE()
  return memory;
}

PagedMemory::PagedMemory() {}

// clang-format off
PagedMemory::PagedMemory(char* p, size_t size) : p_(p), size_(size) {
  ANNOTATE_NEW_BUFFER(p_, size_, committed_size_)
}

PagedMemory::PagedMemory(PagedMemory&& other) noexcept {
  *this = other;
  other.p_ = nullptr;
}
// clang-format on

PagedMemory& PagedMemory::operator=(PagedMemory&& other) {
  this->~PagedMemory();
  new (this) PagedMemory(std::move(other));
  return *this;
}

PagedMemory::~PagedMemory() {
  if (!p_)
    return;
  PERFETTO_CHECK(size_);
  char* start = p_ - GuardSize();
#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
  BOOL res = VirtualFree(start, 0, MEM_RELEASE);
  PERFETTO_CHECK(res != 0);
#else   // PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
  const size_t outer_size = RoundUpToSysPageSize(size_) + GuardSize() * 2;
  int res = munmap(start, outer_size);
  PERFETTO_CHECK(res == 0);
#endif  // PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
  ANNOTATE_DELETE_BUFFER(p_, size_, committed_size_)
}

bool PagedMemory::AdviseDontNeed(void* p, size_t size) {
  PERFETTO_DCHECK(p_);
  PERFETTO_DCHECK(p >= p_);
  PERFETTO_DCHECK(static_cast<char*>(p) + size <= p_ + size_);
#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) || PERFETTO_BUILDFLAG(PERFETTO_OS_NACL)
  // Discarding pages on Windows has more CPU cost than is justified for the
  // possible memory savings.
  return false;
#else   // PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) ||
        // PERFETTO_BUILDFLAG(PERFETTO_OS_NACL)
  // http://man7.org/linux/man-pages/man2/madvise.2.html
  int res = madvise(p, size, MADV_DONTNEED);
  PERFETTO_DCHECK(res == 0);
  return true;
#endif  // PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) ||
        // PERFETTO_BUILDFLAG(PERFETTO_OS_NACL)
}

#if TRACK_COMMITTED_SIZE()
void PagedMemory::EnsureCommitted(size_t committed_size) {
  PERFETTO_DCHECK(committed_size <= size_);
#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
  if (committed_size_ >= committed_size)
    return;
  // Rounding up.
  size_t delta = committed_size - committed_size_;
  size_t num_additional_chunks =
      (delta + kCommitChunkSize - 1) / kCommitChunkSize;
  PERFETTO_DCHECK(num_additional_chunks * kCommitChunkSize >= delta);
  // Don't commit more than the total size.
  size_t commit_size = std::min(num_additional_chunks * kCommitChunkSize,
                                size_ - committed_size_);
  void* res = VirtualAlloc(p_ + committed_size_, commit_size, MEM_COMMIT,
                           PAGE_READWRITE);
  PERFETTO_CHECK(res);
  ANNOTATE_CHANGE_SIZE(p_, size_, committed_size_,
                       committed_size_ + commit_size)
  committed_size_ += commit_size;
#else   // PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
  // mmap commits automatically as needed, so we only track here for ASAN.
  committed_size = std::max(committed_size_, committed_size);
  ANNOTATE_CHANGE_SIZE(p_, size_, committed_size_, committed_size)
  committed_size_ = committed_size;
#endif  // PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
}
#endif  // TRACK_COMMITTED_SIZE()

}  // namespace base
}  // namespace perfetto
// gen_amalgamated begin source: src/base/periodic_task.cc
// gen_amalgamated begin header: include/perfetto/ext/base/periodic_task.h
// gen_amalgamated begin header: include/perfetto/ext/base/thread_checker.h
/*
 * Copyright (C) 2017 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef INCLUDE_PERFETTO_EXT_BASE_THREAD_CHECKER_H_
#define INCLUDE_PERFETTO_EXT_BASE_THREAD_CHECKER_H_

// gen_amalgamated expanded: #include "perfetto/base/build_config.h"

#if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
#include <pthread.h>
#endif
#include <atomic>

// gen_amalgamated expanded: #include "perfetto/base/export.h"
// gen_amalgamated expanded: #include "perfetto/base/logging.h"
// gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"

namespace perfetto {
namespace base {

#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
using ThreadID = unsigned long;
#else
using ThreadID = pthread_t;
#endif

class PERFETTO_EXPORT_COMPONENT ThreadChecker {
 public:
  ThreadChecker();
  ~ThreadChecker();
  ThreadChecker(const ThreadChecker&);
  ThreadChecker& operator=(const ThreadChecker&);
  bool CalledOnValidThread() const PERFETTO_WARN_UNUSED_RESULT;
  void DetachFromThread();

 private:
  mutable std::atomic<ThreadID> thread_id_;
};

#if PERFETTO_DCHECK_IS_ON() && !PERFETTO_BUILDFLAG(PERFETTO_CHROMIUM_BUILD)
// TODO(primiano) Use Chromium's thread checker in Chromium.
#define PERFETTO_THREAD_CHECKER(name) base::ThreadChecker name;
#define PERFETTO_DCHECK_THREAD(name) \
  PERFETTO_DCHECK((name).CalledOnValidThread())
#define PERFETTO_DETACH_FROM_THREAD(name) (name).DetachFromThread()
#else
#define PERFETTO_THREAD_CHECKER(name)
#define PERFETTO_DCHECK_THREAD(name)
#define PERFETTO_DETACH_FROM_THREAD(name)
#endif  // PERFETTO_DCHECK_IS_ON()

}  // namespace base
}  // namespace perfetto

#endif  // INCLUDE_PERFETTO_EXT_BASE_THREAD_CHECKER_H_
// gen_amalgamated begin header: include/perfetto/ext/base/weak_ptr.h
/*
 * Copyright (C) 2017 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef INCLUDE_PERFETTO_EXT_BASE_WEAK_PTR_H_
#define INCLUDE_PERFETTO_EXT_BASE_WEAK_PTR_H_

// gen_amalgamated expanded: #include "perfetto/ext/base/thread_checker.h"

#include <memory>

namespace perfetto {
namespace base {

// A simple WeakPtr for single-threaded cases.
// Generally keep the WeakPtrFactory as last fields in classes: it makes the
// WeakPtr(s) invalidate as first thing in the class dtor.
// Usage:
// class MyClass {
//  MyClass() : weak_factory_(this) {}
//  WeakPtr<MyClass> GetWeakPtr() { return weak_factory_.GetWeakPtr(); }
//
// private:
//  WeakPtrFactory<MyClass> weak_factory_;
// }
//
// int main() {
//  std::unique_ptr<MyClass> foo(new MyClass);
//  auto wptr = foo.GetWeakPtr();
//  ASSERT_TRUE(wptr);
//  ASSERT_EQ(foo.get(), wptr->get());
//  foo.reset();
//  ASSERT_FALSE(wptr);
//  ASSERT_EQ(nullptr, wptr->get());
// }

template <typename T>
class WeakPtrFactory;  // Forward declaration, defined below.

template <typename T>
class WeakPtr {
 public:
  WeakPtr() {}
  WeakPtr(const WeakPtr&) = default;
  WeakPtr& operator=(const WeakPtr&) = default;
  WeakPtr(WeakPtr&&) = default;
  WeakPtr& operator=(WeakPtr&&) = default;

  T* get() const {
    PERFETTO_DCHECK_THREAD(thread_checker);
    return handle_ ? *handle_.get() : nullptr;
  }
  T* operator->() const { return get(); }
  T& operator*() const { return *get(); }

  explicit operator bool() const { return !!get(); }

 private:
  friend class WeakPtrFactory<T>;
  explicit WeakPtr(const std::shared_ptr<T*>& handle) : handle_(handle) {}

  std::shared_ptr<T*> handle_;
  PERFETTO_THREAD_CHECKER(thread_checker)
};

template <typename T>
class WeakPtrFactory {
 public:
  explicit WeakPtrFactory(T* owner) : weak_ptr_(std::make_shared<T*>(owner)) {
    PERFETTO_DCHECK_THREAD(thread_checker);
  }

  ~WeakPtrFactory() {
    PERFETTO_DCHECK_THREAD(thread_checker);
    *(weak_ptr_.handle_.get()) = nullptr;
  }

  // Can be safely called on any thread, since it simply copies |weak_ptr_|.
  // Note that any accesses to the returned pointer need to be made on the
  // thread that created/reset the factory.
  WeakPtr<T> GetWeakPtr() const { return weak_ptr_; }

  // Reset the factory to a new owner & thread. May only be called before any
  // weak pointers were passed out. Future weak pointers will be valid on the
  // calling thread.
  void Reset(T* owner) {
    // Reset thread checker to current thread.
    PERFETTO_DETACH_FROM_THREAD(thread_checker);
    PERFETTO_DCHECK_THREAD(thread_checker);

    // We should not have passed out any weak pointers yet at this point.
    PERFETTO_DCHECK(weak_ptr_.handle_.use_count() == 1);

    weak_ptr_ = WeakPtr<T>(std::make_shared<T*>(owner));
  }

 private:
  WeakPtrFactory(const WeakPtrFactory&) = delete;
  WeakPtrFactory& operator=(const WeakPtrFactory&) = delete;

  WeakPtr<T> weak_ptr_;
  PERFETTO_THREAD_CHECKER(thread_checker)
};

}  // namespace base
}  // namespace perfetto

#endif  // INCLUDE_PERFETTO_EXT_BASE_WEAK_PTR_H_
/*
 * Copyright (C) 2021 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef INCLUDE_PERFETTO_EXT_BASE_PERIODIC_TASK_H_
#define INCLUDE_PERFETTO_EXT_BASE_PERIODIC_TASK_H_

#include <functional>

// gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"
// gen_amalgamated expanded: #include "perfetto/ext/base/thread_checker.h"
// gen_amalgamated expanded: #include "perfetto/ext/base/weak_ptr.h"

namespace perfetto {
namespace base {

class TaskRunner;

// A periodic task utility class. It wraps the logic necessary to do periodic
// tasks using a TaskRunner, taking care of subtleties like ensuring that
// outstanding tasks are cancelled after reset/dtor.
// Tasks are aligned on wall time (unless they are |one_shot|). This is to
// ensure that when using multiple periodic tasks, they happen at the same time,
// minimizing context switches.
// On Linux/Android it also supports suspend-aware mode (via timerfd). On other
// operating systems it falls back to PostDelayedTask, which is not
// suspend-aware.
// TODO(primiano): this should probably become a periodic timer scheduler, so we
// can use one FD for everything rather than one FD per task. For now we take
// the hit of a FD-per-task to keep this low-risk.
// TODO(primiano): consider renaming this class to TimerTask. When |one_shot|
// is set, the "Periodic" part of the class name becomes a lie.
class PeriodicTask {
 public:
  explicit PeriodicTask(base::TaskRunner*);
  ~PeriodicTask();  // Calls Reset().

  struct Args {
    uint32_t period_ms = 0;
    std::function<void()> task = nullptr;
    bool start_first_task_immediately = false;
    bool use_suspend_aware_timer = false;
    bool one_shot = false;
  };

  void Start(Args);

  // Safe to be called multiple times, even without calling Start():
  void Reset();

  // No copy or move. WeakPtr-wrapped pointers to |this| are posted on the
  // task runner, this class is not easily movable.
  PeriodicTask(const PeriodicTask&) = delete;
  PeriodicTask& operator=(const PeriodicTask&) = delete;
  PeriodicTask(PeriodicTask&&) = delete;
  PeriodicTask& operator=(PeriodicTask&&) = delete;

  base::PlatformHandle timer_fd_for_testing() { return *timer_fd_; }

 private:
  static void RunTaskAndPostNext(base::WeakPtr<PeriodicTask>,
                                 uint32_t generation);
  void PostNextTask();
  void ResetTimerFd();

  base::TaskRunner* const task_runner_;
  Args args_;
  uint32_t generation_ = 0;
  base::ScopedPlatformHandle timer_fd_;

  PERFETTO_THREAD_CHECKER(thread_checker_)
  base::WeakPtrFactory<PeriodicTask> weak_ptr_factory_;  // Keep last.
};

}  // namespace base
}  // namespace perfetto

#endif  // INCLUDE_PERFETTO_EXT_BASE_PERIODIC_TASK_H_
/*
 * Copyright (C) 2021 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// gen_amalgamated expanded: #include "perfetto/ext/base/periodic_task.h"

#include <limits>

// gen_amalgamated expanded: #include "perfetto/base/build_config.h"
// gen_amalgamated expanded: #include "perfetto/base/logging.h"
// gen_amalgamated expanded: #include "perfetto/base/task_runner.h"
// gen_amalgamated expanded: #include "perfetto/base/time.h"
// gen_amalgamated expanded: #include "perfetto/ext/base/file_utils.h"

#if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
    (PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) && __ANDROID_API__ >= 19)
#include <sys/timerfd.h>
#endif

namespace perfetto {
namespace base {

namespace {

uint32_t GetNextDelayMs(const TimeMillis& now_ms,
                        const PeriodicTask::Args& args) {
  if (args.one_shot)
    return args.period_ms;

  return args.period_ms -
         static_cast<uint32_t>(now_ms.count() % args.period_ms);
}

ScopedPlatformHandle CreateTimerFd(const PeriodicTask::Args& args) {
#if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
    (PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) && __ANDROID_API__ >= 19)
  ScopedPlatformHandle tfd(
      timerfd_create(CLOCK_BOOTTIME, TFD_CLOEXEC | TFD_NONBLOCK));
  uint32_t phase_ms = GetNextDelayMs(GetBootTimeMs(), args);

  struct itimerspec its {};
  // The "1 +" is to make sure that we never pass a zero it_value in the
  // unlikely case of phase_ms being 0. That would cause the timer to be
  // considered disarmed by timerfd_settime.
  its.it_value.tv_sec = static_cast<time_t>(phase_ms / 1000u);
  its.it_value.tv_nsec = 1 + static_cast<long>((phase_ms % 1000u) * 1000000u);
  if (args.one_shot) {
    its.it_interval.tv_sec = 0;
    its.it_interval.tv_nsec = 0;
  } else {
    const uint32_t period_ms = args.period_ms;
    its.it_interval.tv_sec = static_cast<time_t>(period_ms / 1000u);
    its.it_interval.tv_nsec = static_cast<long>((period_ms % 1000u) * 1000000u);
  }
  if (timerfd_settime(*tfd, 0, &its, nullptr) < 0)
    return ScopedPlatformHandle();
  return tfd;
#else
  ignore_result(args);
  return ScopedPlatformHandle();
#endif
}

}  // namespace

PeriodicTask::PeriodicTask(TaskRunner* task_runner)
    : task_runner_(task_runner), weak_ptr_factory_(this) {}

PeriodicTask::~PeriodicTask() {
  Reset();
}

void PeriodicTask::Start(Args args) {
  PERFETTO_DCHECK_THREAD(thread_checker_);
  Reset();
  if (args.period_ms == 0 || !args.task) {
    PERFETTO_DCHECK(args.period_ms > 0);
    PERFETTO_DCHECK(args.task);
    return;
  }
  args_ = std::move(args);
  if (args_.use_suspend_aware_timer) {
    timer_fd_ = CreateTimerFd(args_);
    if (timer_fd_) {
      auto weak_this = weak_ptr_factory_.GetWeakPtr();
      task_runner_->AddFileDescriptorWatch(
          *timer_fd_,
          std::bind(PeriodicTask::RunTaskAndPostNext, weak_this, generation_));
    } else {
      PERFETTO_DPLOG("timerfd not supported, falling back on PostDelayedTask");
    }
  }  // if (use_suspend_aware_timer).

  if (!timer_fd_)
    PostNextTask();

  if (args_.start_first_task_immediately)
    args_.task();
}

void PeriodicTask::PostNextTask() {
  PERFETTO_DCHECK_THREAD(thread_checker_);
  PERFETTO_DCHECK(args_.period_ms > 0);
  PERFETTO_DCHECK(!timer_fd_);
  uint32_t delay_ms = GetNextDelayMs(GetWallTimeMs(), args_);
  auto weak_this = weak_ptr_factory_.GetWeakPtr();
  task_runner_->PostDelayedTask(
      std::bind(PeriodicTask::RunTaskAndPostNext, weak_this, generation_),
      delay_ms);
}

// static
// This function can be called in two ways (both from the TaskRunner):
// 1. When using a timerfd, this task is registered as a FD watch.
// 2. When using PostDelayedTask, this is the task posted on the TaskRunner.
void PeriodicTask::RunTaskAndPostNext(WeakPtr<PeriodicTask> thiz,
                                      uint32_t generation) {
  if (!thiz || !thiz->args_.task || generation != thiz->generation_)
    return;  // Destroyed or Reset() in the meanwhile.
  PERFETTO_DCHECK_THREAD(thiz->thread_checker_);
  if (thiz->timer_fd_) {
#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
    PERFETTO_FATAL("timerfd for periodic tasks unsupported on Windows");
#else
    // If we are using a timerfd there is no need to repeatedly call
    // PostDelayedTask(). The kernel will wakeup the timer fd periodically. We
    // just need to read() it.
    uint64_t ignored = 0;
    errno = 0;
    auto rsize = Read(*thiz->timer_fd_, &ignored, sizeof(&ignored));
    if (rsize != sizeof(uint64_t)) {
      if (errno == EAGAIN)
        return;  // A spurious wakeup. Rare, but can happen, just ignore.
      PERFETTO_PLOG("read(timerfd) failed, falling back on PostDelayedTask");
      thiz->ResetTimerFd();
    }
#endif
  }

  // Create a copy of the task to deal with either:
  // 1. one_shot causing a Reset().
  // 2. task() invoking internally Reset().
  // That would cause a reset of the args_.task itself, which would invalidate
  // the task bind state while we are invoking it.
  auto task = thiz->args_.task;

  // The repetition of the if() is to deal with the ResetTimerFd() case above.
  if (thiz->args_.one_shot) {
    thiz->Reset();
  } else if (!thiz->timer_fd_) {
    thiz->PostNextTask();
  }

  task();
}

void PeriodicTask::Reset() {
  PERFETTO_DCHECK_THREAD(thread_checker_);
  ++generation_;
  args_ = Args();
  PERFETTO_DCHECK(!args_.task);
  ResetTimerFd();
}

void PeriodicTask::ResetTimerFd() {
  if (!timer_fd_)
    return;
  task_runner_->RemoveFileDescriptorWatch(*timer_fd_);
  timer_fd_.reset();
}

}  // namespace base
}  // namespace perfetto
// gen_amalgamated begin source: src/base/pipe.cc
/*
 * Copyright (C) 2018 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// gen_amalgamated expanded: #include "perfetto/ext/base/pipe.h"

// gen_amalgamated expanded: #include "perfetto/base/build_config.h"

#include <fcntl.h>  // For O_BINARY (Windows) and F_SETxx (UNIX)

#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
#include <Windows.h>
#include <namedpipeapi.h>
#else
#include <sys/types.h>
#include <unistd.h>
#endif

// gen_amalgamated expanded: #include "perfetto/base/logging.h"

namespace perfetto {
namespace base {

Pipe::Pipe() = default;
Pipe::Pipe(Pipe&&) noexcept = default;
Pipe& Pipe::operator=(Pipe&&) = default;

Pipe Pipe::Create(Flags flags) {
  PlatformHandle fds[2];
#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
  PERFETTO_CHECK(::CreatePipe(&fds[0], &fds[1], /*lpPipeAttributes=*/nullptr,
                              0 /*default size*/));
#else
  PERFETTO_CHECK(pipe(fds) == 0);
  PERFETTO_CHECK(fcntl(fds[0], F_SETFD, FD_CLOEXEC) == 0);
  PERFETTO_CHECK(fcntl(fds[1], F_SETFD, FD_CLOEXEC) == 0);
#endif
  Pipe p;
  p.rd.reset(fds[0]);
  p.wr.reset(fds[1]);

#if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
  if (flags == kBothNonBlock || flags == kRdNonBlock) {
    int cur_flags = fcntl(*p.rd, F_GETFL, 0);
    PERFETTO_CHECK(cur_flags >= 0);
    PERFETTO_CHECK(fcntl(*p.rd, F_SETFL, cur_flags | O_NONBLOCK) == 0);
  }

  if (flags == kBothNonBlock || flags == kWrNonBlock) {
    int cur_flags = fcntl(*p.wr, F_GETFL, 0);
    PERFETTO_CHECK(cur_flags >= 0);
    PERFETTO_CHECK(fcntl(*p.wr, F_SETFL, cur_flags | O_NONBLOCK) == 0);
  }
#else
  PERFETTO_CHECK(flags == kBothBlock);
#endif
  return p;
}

}  // namespace base
}  // namespace perfetto
// gen_amalgamated begin source: src/base/scoped_mmap.cc
// gen_amalgamated begin header: include/perfetto/ext/base/scoped_mmap.h
/*
 * Copyright (C) 2024 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef INCLUDE_PERFETTO_EXT_BASE_SCOPED_MMAP_H_
#define INCLUDE_PERFETTO_EXT_BASE_SCOPED_MMAP_H_

#include <cstddef>

// gen_amalgamated expanded: #include "perfetto/base/build_config.h"
// gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"

#if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) ||   \
    PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE) ||   \
    PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \
    PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
#define PERFETTO_HAS_MMAP() 1
#else
#define PERFETTO_HAS_MMAP() 0
#endif

namespace perfetto::base {

// RAII wrapper that holds ownership of an mmap()d area and of a file. Calls
// unmap() and close() on destruction.
class ScopedMmap {
 public:
  // Creates a memory mapping for the first `length` bytes of `file`.
  static ScopedMmap FromHandle(base::ScopedPlatformHandle file, size_t length);

  ScopedMmap() {}
  ~ScopedMmap();
  ScopedMmap(ScopedMmap&& other) noexcept;

  ScopedMmap& operator=(ScopedMmap&& other) noexcept;

  // Returns a pointer to the mapped memory area. Only valid if `IsValid()` is
  // true.
  void* data() const { return ptr_; }

  // Returns true if this object contains a successfully mapped area.
  bool IsValid() const { return ptr_ != nullptr; }

  // Returns the length of the mapped area.
  size_t length() const { return length_; }

  // Unmaps the area and closes the file. Returns false if this held a mmap()d
  // area and unmapping failed. In any case, after this method, `IsValid()` will
  // return false.
  bool reset() noexcept;

#if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) ||   \
    PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \
    PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
  // Takes ownership of an mmap()d area that starts at `data`, `size` bytes
  // long. `data` should not be MAP_FAILED.
  static ScopedMmap InheritMmappedRange(void* data, size_t size);
#endif

 private:
  ScopedMmap(const ScopedMmap&) = delete;
  ScopedMmap& operator=(const ScopedMmap&) = delete;

  size_t length_ = 0;
  void* ptr_ = nullptr;
  ScopedPlatformHandle file_;
#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
  ScopedPlatformHandle map_;
#endif
};

// Tries to open `fname` and maps its first `length` bytes in memory.
ScopedMmap ReadMmapFilePart(const char* fname, size_t length);

// Tries to open `fname` and maps the whole file into memory.
ScopedMmap ReadMmapWholeFile(const char* fname);

}  // namespace perfetto::base

#endif  // INCLUDE_PERFETTO_EXT_BASE_SCOPED_MMAP_H_
/*
 * Copyright (C) 2024 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// gen_amalgamated expanded: #include "perfetto/ext/base/scoped_mmap.h"

#include <utility>

// gen_amalgamated expanded: #include "perfetto/ext/base/file_utils.h"
// gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"

#if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) ||   \
    PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \
    PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
#include <sys/mman.h>
#include <unistd.h>
#elif PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
#include <Windows.h>
#endif

namespace perfetto::base {
namespace {

ScopedPlatformHandle OpenFileForMmap(const char* fname) {
#if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) ||   \
    PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \
    PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
  return OpenFile(fname, O_RDONLY);
#elif PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
  // This does not use base::OpenFile to avoid getting an exclusive lock.
  return ScopedPlatformHandle(CreateFileA(fname, GENERIC_READ, FILE_SHARE_READ,
                                          nullptr, OPEN_EXISTING,
                                          FILE_ATTRIBUTE_NORMAL, nullptr));
#else
  // mmap is not supported. Do not even open the file.
  base::ignore_result(fname);
  return ScopedPlatformHandle();
#endif
}

}  // namespace

ScopedMmap::ScopedMmap(ScopedMmap&& other) noexcept {
  *this = std::move(other);
}

ScopedMmap& ScopedMmap::operator=(ScopedMmap&& other) noexcept {
  if (this == &other) {
    return *this;
  }
  reset();
  std::swap(ptr_, other.ptr_);
  std::swap(length_, other.length_);
  std::swap(file_, other.file_);
#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
  std::swap(map_, other.map_);
#endif
  return *this;
}

ScopedMmap::~ScopedMmap() {
  reset();
}

// static
ScopedMmap ScopedMmap::FromHandle(base::ScopedPlatformHandle file,
                                  size_t length) {
  ScopedMmap ret;
  if (!file) {
    return ret;
  }
#if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) ||   \
    PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \
    PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
  void* ptr = mmap(nullptr, length, PROT_READ, MAP_PRIVATE, *file, 0);
  if (ptr != MAP_FAILED) {
    ret.ptr_ = ptr;
    ret.length_ = length;
    ret.file_ = std::move(file);
  }
#elif PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
  ScopedPlatformHandle map(
      CreateFileMapping(*file, nullptr, PAGE_READONLY, 0, 0, nullptr));
  if (!map) {
    return ret;
  }
  void* ptr = MapViewOfFile(*map, FILE_MAP_READ, 0, 0, length);
  if (ptr != nullptr) {
    ret.ptr_ = ptr;
    ret.length_ = length;
    ret.file_ = std::move(file);
    ret.map_ = std::move(map);
  }
#else
  base::ignore_result(length);
#endif
  return ret;
}

bool ScopedMmap::reset() noexcept {
  bool ret = true;
#if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) ||   \
    PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \
    PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
  if (ptr_ != nullptr) {
    ret = munmap(ptr_, length_) == 0;
  }
#elif PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
  if (ptr_ != nullptr) {
    ret = UnmapViewOfFile(ptr_);
  }
  map_.reset();
#endif
  ptr_ = nullptr;
  length_ = 0;
  file_.reset();
  return ret;
}

#if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) ||   \
    PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \
    PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
// static
ScopedMmap ScopedMmap::InheritMmappedRange(void* data, size_t size) {
  ScopedMmap ret;
  ret.ptr_ = data;
  ret.length_ = size;
  return ret;
}
#endif

ScopedMmap ReadMmapFilePart(const char* fname, size_t length) {
  return ScopedMmap::FromHandle(OpenFileForMmap(fname), length);
}

ScopedMmap ReadMmapWholeFile(const char* fname) {
  ScopedPlatformHandle file = OpenFileForMmap(fname);
  if (!file) {
    return ScopedMmap();
  }
  std::optional<uint64_t> file_size = GetFileSize(file.get());
  if (!file_size.has_value()) {
    return ScopedMmap();
  }
  size_t size = static_cast<size_t>(*file_size);
  if (static_cast<uint64_t>(size) != *file_size) {
    return ScopedMmap();
  }
  return ScopedMmap::FromHandle(std::move(file), size);
}

}  // namespace perfetto::base
// gen_amalgamated begin source: src/base/status.cc
/*
 * Copyright (C) 2020 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// gen_amalgamated expanded: #include "perfetto/base/status.h"

#include <stdarg.h>
#include <algorithm>

namespace perfetto {
namespace base {

Status ErrStatus(const char* format, ...) {
  char buffer[1024];
  va_list ap;
  va_start(ap, format);
  vsnprintf(buffer, sizeof(buffer), format, ap);
  va_end(ap);
  Status status(buffer);
  return status;
}

std::optional<std::string_view> Status::GetPayload(
    std::string_view type_url) const {
  if (ok()) {
    return std::nullopt;
  }
  for (const auto& kv : payloads_) {
    if (kv.type_url == type_url) {
      return kv.payload;
    }
  }
  return std::nullopt;
}

void Status::SetPayload(std::string_view type_url, std::string value) {
  if (ok()) {
    return;
  }
  for (auto& kv : payloads_) {
    if (kv.type_url == type_url) {
      kv.payload = value;
      return;
    }
  }
  payloads_.push_back(Payload{std::string(type_url), std::move(value)});
}

bool Status::ErasePayload(std::string_view type_url) {
  if (ok()) {
    return false;
  }
  auto it = std::remove_if(
      payloads_.begin(), payloads_.end(),
      [type_url](const Payload& p) { return p.type_url == type_url; });
  bool erased = it != payloads_.end();
  payloads_.erase(it, payloads_.end());
  return erased;
}

}  // namespace base
}  // namespace perfetto
// gen_amalgamated begin source: src/base/string_splitter.cc
// gen_amalgamated begin header: include/perfetto/ext/base/string_splitter.h
/*
 * Copyright (C) 2018 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef INCLUDE_PERFETTO_EXT_BASE_STRING_SPLITTER_H_
#define INCLUDE_PERFETTO_EXT_BASE_STRING_SPLITTER_H_

#include <string>

namespace perfetto {
namespace base {

// C++ version of strtok(). Splits a string without making copies or any heap
// allocations. Destructs the original string passed in input.
// Supports the special case of using \0 as a delimiter.
// The token returned in output are valid as long as the input string is valid.
class StringSplitter {
 public:
  // Whether an empty string (two delimiters side-to-side) is a valid token.
  enum class EmptyTokenMode {
    DISALLOW_EMPTY_TOKENS,
    ALLOW_EMPTY_TOKENS,

    DEFAULT = DISALLOW_EMPTY_TOKENS,
  };

  // Can take ownership of the string if passed via std::move(), e.g.:
  // StringSplitter(std::move(str), '\n');
  StringSplitter(std::string,
                 char delimiter,
                 EmptyTokenMode empty_token_mode = EmptyTokenMode::DEFAULT);

  // Splits a C-string. The input string will be forcefully null-terminated (so
  // str[size - 1] should be == '\0' or the last char will be truncated).
  StringSplitter(char* str,
                 size_t size,
                 char delimiter,
                 EmptyTokenMode empty_token_mode = EmptyTokenMode::DEFAULT);

  // Splits the current token from an outer StringSplitter instance. This is to
  // chain splitters as follows:
  // for (base::StringSplitter lines(x, '\n'); ss.Next();)
  //   for (base::StringSplitter words(&lines, ' '); words.Next();)
  StringSplitter(StringSplitter*,
                 char delimiter,
                 EmptyTokenMode empty_token_mode = EmptyTokenMode::DEFAULT);

  // Returns true if a token is found (in which case it will be stored in
  // cur_token()), false if no more tokens are found.
  bool Next();

  // Returns the current token iff last call to Next() returned true. In this
  // case it guarantees that the returned string is always null terminated.
  // In all other cases (before the 1st call to Next() and after Next() returns
  // false) returns nullptr.
  char* cur_token() { return cur_; }

  // Returns the length of the current token (excluding the null terminator).
  size_t cur_token_size() const { return cur_size_; }

 private:
  StringSplitter(const StringSplitter&) = delete;
  StringSplitter& operator=(const StringSplitter&) = delete;
  void Initialize(char* str, size_t size);

  std::string str_;
  char* cur_;
  size_t cur_size_;
  char* next_;
  char* end_;  // STL-style, points one past the last char.
  const char delimiter_;
  const EmptyTokenMode empty_token_mode_;
};

}  // namespace base
}  // namespace perfetto

#endif  // INCLUDE_PERFETTO_EXT_BASE_STRING_SPLITTER_H_
/*
 * Copyright (C) 2018 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// gen_amalgamated expanded: #include "perfetto/ext/base/string_splitter.h"

#include <utility>

// gen_amalgamated expanded: #include "perfetto/base/logging.h"

namespace perfetto {
namespace base {

StringSplitter::StringSplitter(std::string str,
                               char delimiter,
                               EmptyTokenMode empty_token_mode)
    : str_(std::move(str)),
      delimiter_(delimiter),
      empty_token_mode_(empty_token_mode) {
  // It's legal to access str[str.size()] in C++11 (it always returns \0),
  // hence the +1 (which becomes just size() after the -1 in Initialize()).
  Initialize(&str_[0], str_.size() + 1);
}

StringSplitter::StringSplitter(char* str,
                               size_t size,
                               char delimiter,
                               EmptyTokenMode empty_token_mode)
    : delimiter_(delimiter), empty_token_mode_(empty_token_mode) {
  Initialize(str, size);
}

StringSplitter::StringSplitter(StringSplitter* outer,
                               char delimiter,
                               EmptyTokenMode empty_token_mode)
    : delimiter_(delimiter), empty_token_mode_(empty_token_mode) {
  Initialize(outer->cur_token(), outer->cur_token_size() + 1);
}

void StringSplitter::Initialize(char* str, size_t size) {
  PERFETTO_DCHECK(!size || str);
  next_ = str;
  end_ = str + size;
  cur_ = nullptr;
  cur_size_ = 0;
  if (size)
    next_[size - 1] = '\0';
}

bool StringSplitter::Next() {
  for (; next_ < end_; next_++) {
    if (*next_ == delimiter_ &&
        empty_token_mode_ == EmptyTokenMode::DISALLOW_EMPTY_TOKENS) {
      // If empty tokens are disallowed, find fist non-delimiter character.
      continue;
    }
    cur_ = next_;
    for (;; next_++) {
      if (*next_ == delimiter_) {
        cur_size_ = static_cast<size_t>(next_ - cur_);
        *(next_++) = '\0';
        break;
      }
      if (*next_ == '\0') {
        cur_size_ = static_cast<size_t>(next_ - cur_);
        next_ = end_;
        break;
      }
    }
    if (*cur_ || empty_token_mode_ == EmptyTokenMode::ALLOW_EMPTY_TOKENS)
      return true;
    break;
  }
  cur_ = nullptr;
  cur_size_ = 0;
  return false;
}

}  // namespace base
}  // namespace perfetto
// gen_amalgamated begin source: src/base/string_utils.cc
/*
 * Copyright (C) 2018 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// gen_amalgamated expanded: #include "perfetto/ext/base/string_utils.h"

#include <locale.h>
#include <stdarg.h>
#include <string.h>

#include <algorithm>

#if PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
#include <xlocale.h>
#elif PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
#include <Windows.h>
#endif

#include <cinttypes>

// gen_amalgamated expanded: #include "perfetto/base/compiler.h"
// gen_amalgamated expanded: #include "perfetto/base/logging.h"

namespace perfetto {
namespace base {

// Locale-independant as possible version of strtod.
double StrToD(const char* nptr, char** endptr) {
#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \
    PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) ||   \
    PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
  static auto c_locale = newlocale(LC_ALL, "C", nullptr);
  return strtod_l(nptr, endptr, c_locale);
#else
  return strtod(nptr, endptr);
#endif
}

bool StartsWith(const std::string& str, const std::string& prefix) {
  return str.compare(0, prefix.length(), prefix) == 0;
}

bool StartsWithAny(const std::string& str,
                   const std::vector<std::string>& prefixes) {
  return std::any_of(
      prefixes.begin(), prefixes.end(),
      [&str](const std::string& prefix) { return StartsWith(str, prefix); });
}

bool EndsWith(const std::string& str, const std::string& suffix) {
  if (suffix.size() > str.size())
    return false;
  return str.compare(str.size() - suffix.size(), suffix.size(), suffix) == 0;
}

bool Contains(const std::string& haystack, const std::string& needle) {
  return haystack.find(needle) != std::string::npos;
}

bool Contains(const std::string& haystack, const char needle) {
  return haystack.find(needle) != std::string::npos;
}

size_t Find(const StringView& needle, const StringView& haystack) {
  if (needle.empty())
    return 0;
  if (needle.size() > haystack.size())
    return std::string::npos;
  for (size_t i = 0; i < haystack.size() - (needle.size() - 1); ++i) {
    if (strncmp(haystack.data() + i, needle.data(), needle.size()) == 0)
      return i;
  }
  return std::string::npos;
}

bool CaseInsensitiveEqual(const std::string& first, const std::string& second) {
  return first.size() == second.size() &&
         std::equal(
             first.begin(), first.end(), second.begin(),
             [](char a, char b) { return Lowercase(a) == Lowercase(b); });
}

std::string Join(const std::vector<std::string>& parts,
                 const std::string& delim) {
  std::string acc;
  for (size_t i = 0; i < parts.size(); ++i) {
    acc += parts[i];
    if (i + 1 != parts.size()) {
      acc += delim;
    }
  }
  return acc;
}

std::vector<std::string> SplitString(const std::string& text,
                                     const std::string& delimiter) {
  PERFETTO_CHECK(!delimiter.empty());

  std::vector<std::string> output;
  size_t start = 0;
  size_t next;
  for (;;) {
    next = std::min(text.find(delimiter, start), text.size());
    if (next > start)
      output.emplace_back(&text[start], next - start);
    start = next + delimiter.size();
    if (start >= text.size())
      break;
  }
  return output;
}

std::string TrimWhitespace(const std::string& str) {
  std::string whitespaces = "\t\n ";

  size_t front_idx = str.find_first_not_of(whitespaces);
  std::string front_trimmed =
      front_idx == std::string::npos ? "" : str.substr(front_idx);

  size_t end_idx = front_trimmed.find_last_not_of(whitespaces);
  return end_idx == std::string::npos ? ""
                                      : front_trimmed.substr(0, end_idx + 1);
}

std::string StripPrefix(const std::string& str, const std::string& prefix) {
  return StartsWith(str, prefix) ? str.substr(prefix.size()) : str;
}

std::string StripSuffix(const std::string& str, const std::string& suffix) {
  return EndsWith(str, suffix) ? str.substr(0, str.size() - suffix.size())
                               : str;
}

std::string ToUpper(const std::string& str) {
  // Don't use toupper(), it depends on the locale.
  std::string res(str);
  auto end = res.end();
  for (auto c = res.begin(); c != end; ++c)
    *c = Uppercase(*c);
  return res;
}

std::string ToLower(const std::string& str) {
  // Don't use tolower(), it depends on the locale.
  std::string res(str);
  auto end = res.end();
  for (auto c = res.begin(); c != end; ++c)
    *c = Lowercase(*c);
  return res;
}

std::string ToHex(const char* data, size_t size) {
  std::string hex(2 * size + 1, 'x');
  for (size_t i = 0; i < size; ++i) {
    // snprintf prints 3 characters, the two hex digits and a null byte. As we
    // write left to right, we keep overwriting the nullbytes, except for the
    // last call to snprintf.
    snprintf(&(hex[2 * i]), 3, "%02hhx", data[i]);
  }
  // Remove the trailing nullbyte produced by the last snprintf.
  hex.resize(2 * size);
  return hex;
}

std::string IntToHexString(uint32_t number) {
  size_t max_size = 11;  // Max uint32 is 0xFFFFFFFF + 1 for null byte.
  std::string buf;
  buf.resize(max_size);
  size_t final_len = SprintfTrunc(&buf[0], max_size, "0x%02x", number);
  buf.resize(static_cast<size_t>(final_len));  // Cuts off the final null byte.
  return buf;
}

std::string Uint64ToHexString(uint64_t number) {
  return "0x" + Uint64ToHexStringNoPrefix(number);
}

std::string Uint64ToHexStringNoPrefix(uint64_t number) {
  size_t max_size = 17;  // Max uint64 is FFFFFFFFFFFFFFFF + 1 for null byte.
  std::string buf;
  buf.resize(max_size);
  size_t final_len = SprintfTrunc(&buf[0], max_size, "%" PRIx64 "", number);
  buf.resize(static_cast<size_t>(final_len));  // Cuts off the final null byte.
  return buf;
}

std::string StripChars(const std::string& str,
                       const std::string& chars,
                       char replacement) {
  std::string res(str);
  const char* start = res.c_str();
  const char* remove = chars.c_str();
  for (const char* c = strpbrk(start, remove); c; c = strpbrk(c + 1, remove))
    res[static_cast<uintptr_t>(c - start)] = replacement;
  return res;
}

std::string ReplaceAll(std::string str,
                       const std::string& to_replace,
                       const std::string& replacement) {
  PERFETTO_CHECK(!to_replace.empty());
  size_t pos = 0;
  while ((pos = str.find(to_replace, pos)) != std::string::npos) {
    str.replace(pos, to_replace.length(), replacement);
    pos += replacement.length();
  }
  return str;
}

#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
bool WideToUTF8(const std::wstring& source, std::string& output) {
  if (source.empty() ||
      source.size() > static_cast<size_t>(std::numeric_limits<int>::max())) {
    return false;
  }
  int size = ::WideCharToMultiByte(CP_UTF8, 0, &source[0],
                                   static_cast<int>(source.size()), nullptr, 0,
                                   nullptr, nullptr);
  output.assign(static_cast<size_t>(size), '\0');
  if (::WideCharToMultiByte(CP_UTF8, 0, &source[0],
                            static_cast<int>(source.size()), &output[0], size,
                            nullptr, nullptr) != size) {
    return false;
  }
  return true;
}
#endif // PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)

#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
bool UTF8ToWide(const std::string& source, std::wstring& output) {
  if (source.empty() ||
      source.size() > static_cast<size_t>(std::numeric_limits<int>::max())) {
    return false;
  }
  int size = ::MultiByteToWideChar(CP_UTF8, 0, &source[0],
                                   static_cast<int>(source.size()), nullptr, 0);
  output.assign(static_cast<size_t>(size), L'\0');
  if (::MultiByteToWideChar(CP_UTF8, 0, &source[0],
                            static_cast<int>(source.size()), &output[0],
                            size) != size) {
    return false;
  }
  return true;
}
#endif // PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)

size_t SprintfTrunc(char* dst, size_t dst_size, const char* fmt, ...) {
  if (PERFETTO_UNLIKELY(dst_size) == 0)
    return 0;

  va_list args;
  va_start(args, fmt);
  int src_size = vsnprintf(dst, dst_size, fmt, args);
  va_end(args);

  if (PERFETTO_UNLIKELY(src_size) <= 0) {
    dst[0] = '\0';
    return 0;
  }

  size_t res;
  if (PERFETTO_LIKELY(src_size < static_cast<int>(dst_size))) {
    // Most common case.
    res = static_cast<size_t>(src_size);
  } else {
    // Truncation case.
    res = dst_size - 1;
  }

  PERFETTO_DCHECK(res < dst_size);
  PERFETTO_DCHECK(dst[res] == '\0');
  return res;
}

std::optional<LineWithOffset> FindLineWithOffset(base::StringView str,
                                                 uint32_t offset) {
  static constexpr char kNewLine = '\n';
  uint32_t line_offset = 0;
  uint32_t line_count = 1;
  for (uint32_t i = 0; i < str.size(); ++i) {
    if (str.at(i) == kNewLine) {
      line_offset = i + 1;
      line_count++;
      continue;
    }
    if (i == offset) {
      size_t end_offset = str.find(kNewLine, i);
      if (end_offset == std::string::npos) {
        end_offset = str.size();
      }
      base::StringView line = str.substr(line_offset, end_offset - line_offset);
      return LineWithOffset{line, offset - line_offset, line_count};
    }
  }
  return std::nullopt;
}

}  // namespace base
}  // namespace perfetto
// gen_amalgamated begin source: src/base/string_view.cc
/*
 * Copyright (C) 2019 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// gen_amalgamated expanded: #include "perfetto/ext/base/string_view.h"

namespace perfetto {
namespace base {

// Without ignoring this warning we get the message:
//   error: out-of-line definition of constexpr static data member is redundant
//   in C++17 and is deprecated
// when using clang-cl in Windows.
#if defined(__GNUC__)  // GCC & clang
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated"
#endif  // __GNUC__

// static
constexpr size_t StringView::npos;

#if defined(__GNUC__)
#pragma GCC diagnostic pop
#endif

}  // namespace base
}  // namespace perfetto
// gen_amalgamated begin source: src/base/temp_file.cc
// gen_amalgamated begin header: include/perfetto/ext/base/temp_file.h
/*
 * Copyright (C) 2018 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef INCLUDE_PERFETTO_EXT_BASE_TEMP_FILE_H_
#define INCLUDE_PERFETTO_EXT_BASE_TEMP_FILE_H_

#include <string>

// gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"

namespace perfetto {
namespace base {

std::string GetSysTempDir();

class TempFile {
 public:
  static TempFile CreateUnlinked();
  static TempFile Create();

  TempFile(TempFile&&) noexcept;
  TempFile& operator=(TempFile&&);
  ~TempFile();

  const std::string& path() const { return path_; }
  int fd() const { return *fd_; }
  int operator*() const { return *fd_; }

  // Unlinks the file from the filesystem but keeps the fd() open.
  // It is safe to call this multiple times.
  void Unlink();

  // Releases the underlying file descriptor. Will unlink the file from the
  // filesystem if it was created via CreateUnlinked().
  ScopedFile ReleaseFD();

 private:
  TempFile();
  TempFile(const TempFile&) = delete;
  TempFile& operator=(const TempFile&) = delete;

  ScopedFile fd_;
  std::string path_;
};

class TempDir {
 public:
  static TempDir Create();

  TempDir(TempDir&&) noexcept;
  TempDir& operator=(TempDir&&);
  ~TempDir();

  const std::string& path() const { return path_; }

 private:
  TempDir();
  TempDir(const TempDir&) = delete;
  TempDir& operator=(const TempDir&) = delete;

  std::string path_;
};

}  // namespace base
}  // namespace perfetto

#endif  // INCLUDE_PERFETTO_EXT_BASE_TEMP_FILE_H_
/*
 * Copyright (C) 2018 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// gen_amalgamated expanded: #include "perfetto/ext/base/temp_file.h"

// gen_amalgamated expanded: #include "perfetto/base/build_config.h"

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
#include <Windows.h>
#include <direct.h>
#include <fileapi.h>
#include <io.h>
#else
#include <unistd.h>
#endif

// gen_amalgamated expanded: #include "perfetto/base/logging.h"
// gen_amalgamated expanded: #include "perfetto/ext/base/file_utils.h"
// gen_amalgamated expanded: #include "perfetto/ext/base/string_utils.h"

namespace perfetto {
namespace base {

#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
namespace {
std::string GetTempFilePathWin() {
  std::string tmplt = GetSysTempDir() + "\\perfetto-XXXXXX";
  StackString<255> name("%s\\perfetto-XXXXXX", GetSysTempDir().c_str());
  PERFETTO_CHECK(_mktemp_s(name.mutable_data(), name.len() + 1) == 0);
  return name.ToStdString();
}
}  // namespace
#endif

std::string GetSysTempDir() {
  const char* tmpdir = nullptr;
#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
  if ((tmpdir = getenv("TMP")))
    return tmpdir;
  if ((tmpdir = getenv("TEMP")))
    return tmpdir;
  return "C:\\TEMP";
#else
  if ((tmpdir = getenv("TMPDIR")))
    return base::StripSuffix(tmpdir, "/");
#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
  return "/data/local/tmp";
#else
  return "/tmp";
#endif  // !OS_ANDROID
#endif  // !OS_WIN
}

// static
TempFile TempFile::Create() {
  TempFile temp_file;
#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
  temp_file.path_ = GetTempFilePathWin();
  // Several tests want to read-back the temp file while still open. On Windows,
  // that requires FILE_SHARE_READ. FILE_SHARE_READ is NOT settable when using
  // the POSIX-compat equivalent function _open(). Hence the CreateFileA +
  // _open_osfhandle dance here.
  HANDLE h =
      ::CreateFileA(temp_file.path_.c_str(), GENERIC_READ | GENERIC_WRITE,
                    FILE_SHARE_DELETE | FILE_SHARE_READ, nullptr, CREATE_ALWAYS,
                    FILE_ATTRIBUTE_TEMPORARY, nullptr);
  PERFETTO_CHECK(PlatformHandleChecker::IsValid(h));
  // According to MSDN, when using _open_osfhandle the caller must not call
  // CloseHandle(). Ownership is moved to the file descriptor, which then needs
  // to be closed with just with _close().
  temp_file.fd_.reset(_open_osfhandle(reinterpret_cast<intptr_t>(h), 0));
#else
  temp_file.path_ = GetSysTempDir() + "/perfetto-XXXXXXXX";
  temp_file.fd_.reset(mkstemp(&temp_file.path_[0]));
#endif
  if (PERFETTO_UNLIKELY(!temp_file.fd_)) {
    PERFETTO_FATAL("Could not create temp file %s", temp_file.path_.c_str());
  }
  return temp_file;
}

// static
TempFile TempFile::CreateUnlinked() {
  TempFile temp_file = TempFile::Create();
  temp_file.Unlink();
  return temp_file;
}

TempFile::TempFile() = default;

TempFile::~TempFile() {
  Unlink();
}

ScopedFile TempFile::ReleaseFD() {
  Unlink();
  return std::move(fd_);
}

void TempFile::Unlink() {
  if (path_.empty())
    return;
#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
  // If the FD is still open DeleteFile will mark the file as pending deletion
  // and delete it only when the process exists.
  PERFETTO_CHECK(DeleteFileA(path_.c_str()));
#else
  PERFETTO_CHECK(unlink(path_.c_str()) == 0);
#endif
  path_.clear();
}

TempFile::TempFile(TempFile&&) noexcept = default;
TempFile& TempFile::operator=(TempFile&&) = default;

// static
TempDir TempDir::Create() {
  TempDir temp_dir;
#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
  temp_dir.path_ = GetTempFilePathWin();
  PERFETTO_CHECK(_mkdir(temp_dir.path_.c_str()) == 0);
#else
  temp_dir.path_ = GetSysTempDir() + "/perfetto-XXXXXXXX";
  PERFETTO_CHECK(mkdtemp(&temp_dir.path_[0]));
#endif
  return temp_dir;
}

TempDir::TempDir() = default;
TempDir::TempDir(TempDir&&) noexcept = default;
TempDir& TempDir::operator=(TempDir&&) = default;

TempDir::~TempDir() {
  if (path_.empty())
    return;  // For objects that get std::move()d.
  PERFETTO_CHECK(Rmdir(path_));
}

}  // namespace base
}  // namespace perfetto
// gen_amalgamated begin source: src/base/thread_checker.cc
/*
 * Copyright (C) 2017 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// gen_amalgamated expanded: #include "perfetto/ext/base/thread_checker.h"

#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
#include <Windows.h>
#endif

namespace perfetto {
namespace base {

namespace {
constexpr ThreadID kDetached{};

ThreadID CurrentThreadId() {
#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
  return ::GetCurrentThreadId();
#else
  return pthread_self();
#endif
}
}  // namespace

ThreadChecker::ThreadChecker() {
  thread_id_.store(CurrentThreadId());
}

ThreadChecker::~ThreadChecker() = default;

ThreadChecker::ThreadChecker(const ThreadChecker& other) {
  thread_id_ = other.thread_id_.load();
}

ThreadChecker& ThreadChecker::operator=(const ThreadChecker& other) {
  thread_id_ = other.thread_id_.load();
  return *this;
}

bool ThreadChecker::CalledOnValidThread() const {
  auto self = CurrentThreadId();

  // Will re-attach if previously detached using DetachFromThread().
  auto prev_value = kDetached;
  if (thread_id_.compare_exchange_strong(prev_value, self))
    return true;
  return prev_value == self;
}

void ThreadChecker::DetachFromThread() {
  thread_id_.store(kDetached);
}

}  // namespace base
}  // namespace perfetto
// gen_amalgamated begin source: src/base/thread_utils.cc
// gen_amalgamated begin header: include/perfetto/ext/base/thread_utils.h
/*
 * Copyright (C) 2020 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef INCLUDE_PERFETTO_EXT_BASE_THREAD_UTILS_H_
#define INCLUDE_PERFETTO_EXT_BASE_THREAD_UTILS_H_

#include <string>

// gen_amalgamated expanded: #include "perfetto/base/build_config.h"
// gen_amalgamated expanded: #include "perfetto/ext/base/string_utils.h"
// gen_amalgamated expanded: #include "perfetto/base/export.h"

#if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) ||   \
    PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \
    PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
#include <pthread.h>
#include <string.h>
#include <algorithm>
#endif

#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
#include <sys/prctl.h>
#endif

// Internal implementation utils that aren't as widely useful/supported as
// base/thread_utils.h.

namespace perfetto {
namespace base {

#if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) ||   \
    PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \
    PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
// Sets the "comm" of the calling thread to the first 15 chars of the given
// string.
inline bool MaybeSetThreadName(const std::string& name) {
  char buf[16] = {};
  StringCopy(buf, name.c_str(), sizeof(buf));

#if PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
  return pthread_setname_np(buf) == 0;
#else
  return pthread_setname_np(pthread_self(), buf) == 0;
#endif
}

inline bool GetThreadName(std::string& out_result) {
  char buf[16] = {};
#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
  if (prctl(PR_GET_NAME, buf) != 0)
    return false;
#else
  if (pthread_getname_np(pthread_self(), buf, sizeof(buf)) != 0)
    return false;
#endif
  out_result = std::string(buf);
  return true;
}

#elif PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)

PERFETTO_EXPORT_COMPONENT bool MaybeSetThreadName(const std::string& name);
PERFETTO_EXPORT_COMPONENT bool GetThreadName(std::string& out_result);

#else
inline bool MaybeSetThreadName(const std::string&) {
  return false;
}
inline bool GetThreadName(std::string&) {
  return false;
}
#endif

}  // namespace base
}  // namespace perfetto

#endif  // INCLUDE_PERFETTO_EXT_BASE_THREAD_UTILS_H_
/*
 * Copyright (C) 2022 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// gen_amalgamated expanded: #include "perfetto/base/thread_utils.h"
// gen_amalgamated expanded: #include "perfetto/ext/base/thread_utils.h"

// gen_amalgamated expanded: #include "perfetto/base/build_config.h"

#if PERFETTO_BUILDFLAG(PERFETTO_OS_FUCHSIA)
#include <zircon/process.h>
#include <zircon/syscalls.h>
#include <zircon/types.h>
#elif PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
#include <Windows.h>
#endif

namespace perfetto {
namespace base {

#if PERFETTO_BUILDFLAG(PERFETTO_OS_FUCHSIA)
static PlatformThreadId ResolveThreadId() {
  zx_info_handle_basic_t basic;
  return (zx_object_get_info(zx_thread_self(), ZX_INFO_HANDLE_BASIC, &basic,
                             sizeof(basic), nullptr, nullptr) == ZX_OK)
             ? basic.koid
             : ZX_KOID_INVALID;
}
PlatformThreadId GetThreadId() {
  thread_local static PlatformThreadId thread_id = ResolveThreadId();
  return thread_id;
}

#elif PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)

// The SetThreadDescription API was brought in version 1607 of Windows 10.
typedef HRESULT(WINAPI* SetThreadDescription)(HANDLE hThread,
                                              PCWSTR lpThreadDescription);

// The SetThreadDescription API was brought in version 1607 of Windows 10.
typedef HRESULT(WINAPI* GetThreadDescription)(HANDLE hThread,
                                              PWSTR* ppszThreadDescription);

bool MaybeSetThreadName(const std::string& name) {
  // The SetThreadDescription API works even if no debugger is attached.
  static auto set_thread_description_func =
      reinterpret_cast<SetThreadDescription>(
          reinterpret_cast<void*>(::GetProcAddress(
              ::GetModuleHandleA("Kernel32.dll"), "SetThreadDescription")));
  if (!set_thread_description_func) {
    return false;
  }
  std::wstring wide_thread_name;
  if (!UTF8ToWide(name, wide_thread_name)) {
    return false;
  }
  HRESULT result = set_thread_description_func(::GetCurrentThread(),
                                               wide_thread_name.c_str());
  return !FAILED(result);
}

bool GetThreadName(std::string& out_result) {
  static auto get_thread_description_func =
      reinterpret_cast<GetThreadDescription>(
          reinterpret_cast<void*>(::GetProcAddress(
              ::GetModuleHandleA("Kernel32.dll"), "GetThreadDescription")));
  if (!get_thread_description_func) {
    return false;
  }
  wchar_t* wide_thread_name;
  HRESULT result =
      get_thread_description_func(::GetCurrentThread(), &wide_thread_name);
  if (SUCCEEDED(result)) {
    bool success = WideToUTF8(std::wstring(wide_thread_name), out_result);
    LocalFree(wide_thread_name);
    return success;
  }
  return false;
}

#endif  // PERFETTO_BUILDFLAG(PERFETTO_OS_FUCHSIA)

}  // namespace base
}  // namespace perfetto
// gen_amalgamated begin source: src/base/time.cc
/*
 * Copyright (C) 2018 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <atomic>

// gen_amalgamated expanded: #include "perfetto/base/time.h"

// gen_amalgamated expanded: #include "perfetto/base/build_config.h"
// gen_amalgamated expanded: #include "perfetto/base/logging.h"
// gen_amalgamated expanded: #include "perfetto/ext/base/string_utils.h"

#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
#include <Windows.h>
#else
#include <unistd.h>
#endif

namespace perfetto {
namespace base {

#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
#if !PERFETTO_BUILDFLAG(PERFETTO_ARCH_CPU_ARM64)
namespace {

// Returns the current value of the performance counter.
int64_t QPCNowRaw() {
  LARGE_INTEGER perf_counter_now = {};
  // According to the MSDN documentation for QueryPerformanceCounter(), this
  // will never fail on systems that run XP or later.
  // https://msdn.microsoft.com/library/windows/desktop/ms644904.aspx
  ::QueryPerformanceCounter(&perf_counter_now);
  return perf_counter_now.QuadPart;
}

double TSCTicksPerSecond() {
  // The value returned by QueryPerformanceFrequency() cannot be used as the TSC
  // frequency, because there is no guarantee that the TSC frequency is equal to
  // the performance counter frequency.
  // The TSC frequency is cached in a static variable because it takes some time
  // to compute it.
  static std::atomic<double> tsc_ticks_per_second = 0;
  double value = tsc_ticks_per_second.load(std::memory_order_relaxed);
  if (value != 0)
    return value;

  // Increase the thread priority to reduces the chances of having a context
  // switch during a reading of the TSC and the performance counter.
  const int previous_priority = ::GetThreadPriority(::GetCurrentThread());
  ::SetThreadPriority(::GetCurrentThread(), THREAD_PRIORITY_HIGHEST);

  // The first time that this function is called, make an initial reading of the
  // TSC and the performance counter. Initialization of static variable is
  // thread-safe. Threads can race initializing tsc_initial vs
  // perf_counter_initial, although they should be storing very similar values.

  static const uint64_t tsc_initial = __rdtsc();
  static const int64_t perf_counter_initial = QPCNowRaw();

  // Make a another reading of the TSC and the performance counter every time
  // that this function is called.
  const uint64_t tsc_now = __rdtsc();
  const int64_t perf_counter_now = QPCNowRaw();

  // Reset the thread priority.
  ::SetThreadPriority(::GetCurrentThread(), previous_priority);

  // Make sure that at least 50 ms elapsed between the 2 readings. The first
  // time that this function is called, we don't expect this to be the case.
  // Note: The longer the elapsed time between the 2 readings is, the more
  //   accurate the computed TSC frequency will be. The 50 ms value was
  //   chosen because local benchmarks show that it allows us to get a
  //   stddev of less than 1 tick/us between multiple runs.
  // Note: According to the MSDN documentation for QueryPerformanceFrequency(),
  //   this will never fail on systems that run XP or later.
  //   https://msdn.microsoft.com/library/windows/desktop/ms644905.aspx
  LARGE_INTEGER perf_counter_frequency = {};
  ::QueryPerformanceFrequency(&perf_counter_frequency);
  PERFETTO_CHECK(perf_counter_now >= perf_counter_initial);
  const int64_t perf_counter_ticks = perf_counter_now - perf_counter_initial;
  const double elapsed_time_seconds =
      static_cast<double>(perf_counter_ticks) /
      static_cast<double>(perf_counter_frequency.QuadPart);

  constexpr double kMinimumEvaluationPeriodSeconds = 0.05;
  if (elapsed_time_seconds < kMinimumEvaluationPeriodSeconds)
    return 0;

  // Compute the frequency of the TSC.
  PERFETTO_CHECK(tsc_now >= tsc_initial);
  const uint64_t tsc_ticks = tsc_now - tsc_initial;
  // Racing with another thread to write |tsc_ticks_per_second| is benign
  // because both threads will write a valid result.
  tsc_ticks_per_second.store(
      static_cast<double>(tsc_ticks) / elapsed_time_seconds,
      std::memory_order_relaxed);

  return tsc_ticks_per_second.load(std::memory_order_relaxed);
}

}  // namespace
#endif  // !PERFETTO_BUILDFLAG(PERFETTO_ARCH_CPU_ARM64)

TimeNanos GetWallTimeNs() {
  LARGE_INTEGER freq;
  ::QueryPerformanceFrequency(&freq);
  LARGE_INTEGER counter;
  ::QueryPerformanceCounter(&counter);
  double elapsed_nanoseconds = (1e9 * static_cast<double>(counter.QuadPart)) /
                               static_cast<double>(freq.QuadPart);
  return TimeNanos(static_cast<uint64_t>(elapsed_nanoseconds));
}

TimeNanos GetThreadCPUTimeNs() {
#if PERFETTO_BUILDFLAG(PERFETTO_ARCH_CPU_ARM64)
  // QueryThreadCycleTime versus TSCTicksPerSecond doesn't have much relation to
  // actual elapsed time on Windows on Arm, because QueryThreadCycleTime is
  // backed by the actual number of CPU cycles executed, rather than a
  // constant-rate timer like Intel. To work around this, use GetThreadTimes
  // (which isn't as accurate but is meaningful as a measure of elapsed
  // per-thread time).
  FILETIME dummy, kernel_ftime, user_ftime;
  ::GetThreadTimes(GetCurrentThread(), &dummy, &dummy, &kernel_ftime,
                   &user_ftime);
  uint64_t kernel_time =
      kernel_ftime.dwHighDateTime * 0x100000000 + kernel_ftime.dwLowDateTime;
  uint64_t user_time =
      user_ftime.dwHighDateTime * 0x100000000 + user_ftime.dwLowDateTime;

  return TimeNanos((kernel_time + user_time) * 100);
#else   // !PERFETTO_BUILDFLAG(PERFETTO_ARCH_CPU_ARM64)
  // Get the number of TSC ticks used by the current thread.
  ULONG64 thread_cycle_time = 0;
  ::QueryThreadCycleTime(GetCurrentThread(), &thread_cycle_time);

  // Get the frequency of the TSC.
  const double tsc_ticks_per_second = TSCTicksPerSecond();
  if (tsc_ticks_per_second == 0)
    return TimeNanos();

  // Return the CPU time of the current thread.
  const double thread_time_seconds =
      static_cast<double>(thread_cycle_time) / tsc_ticks_per_second;
  constexpr int64_t kNanosecondsPerSecond = 1000 * 1000 * 1000;
  return TimeNanos(
      static_cast<int64_t>(thread_time_seconds * kNanosecondsPerSecond));
#endif  // !PERFETTO_BUILDFLAG(PERFETTO_ARCH_CPU_ARM64)
}

void SleepMicroseconds(unsigned interval_us) {
  // The Windows Sleep function takes a millisecond count. Round up so that
  // short sleeps don't turn into a busy wait. Note that the sleep granularity
  // on Windows can dynamically vary from 1 ms to ~16 ms, so don't count on this
  // being a short sleep.
  ::Sleep(static_cast<DWORD>((interval_us + 999) / 1000));
}

void InitializeTime() {
#if !PERFETTO_BUILDFLAG(PERFETTO_ARCH_CPU_ARM64)
  // Make an early first call to TSCTicksPerSecond() to start 50 ms elapsed time
  // (see comment in TSCTicksPerSecond()).
  TSCTicksPerSecond();
#endif  // !PERFETTO_BUILDFLAG(PERFETTO_ARCH_CPU_ARM64)
}

#else  // PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)

void SleepMicroseconds(unsigned interval_us) {
  ::usleep(static_cast<useconds_t>(interval_us));
}

void InitializeTime() {}

#endif  // PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)

std::string GetTimeFmt(const std::string& fmt) {
  time_t raw_time;
  time(&raw_time);
  struct tm* local_tm;
  local_tm = localtime(&raw_time);
  char buf[128];
  PERFETTO_CHECK(strftime(buf, 80, fmt.c_str(), local_tm) > 0);
  return buf;
}

std::optional<int32_t> GetTimezoneOffsetMins() {
  std::string tz = GetTimeFmt("%z");
  if (tz.size() != 5 || (tz[0] != '+' && tz[0] != '-'))
    return std::nullopt;
  char sign = '\0';
  int32_t hh = 0;
  int32_t mm = 0;
  if (sscanf(tz.c_str(), "%c%2d%2d", &sign, &hh, &mm) != 3)
    return std::nullopt;
  return (hh * 60 + mm) * (sign == '-' ? -1 : 1);
}

}  // namespace base
}  // namespace perfetto
// gen_amalgamated begin source: src/base/utils.cc
/*
 * Copyright (C) 2020 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"

#include <string>

// gen_amalgamated expanded: #include "perfetto/base/build_config.h"
// gen_amalgamated expanded: #include "perfetto/base/logging.h"
// gen_amalgamated expanded: #include "perfetto/ext/base/file_utils.h"
// gen_amalgamated expanded: #include "perfetto/ext/base/pipe.h"
// gen_amalgamated expanded: #include "perfetto/ext/base/string_utils.h"

#if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) ||   \
    PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \
    PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE) ||   \
    PERFETTO_BUILDFLAG(PERFETTO_OS_FUCHSIA)
#include <limits.h>
#include <stdlib.h>  // For _exit()
#include <unistd.h>  // For getpagesize() and geteuid() & fork()
#endif

#if PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
#include <mach-o/dyld.h>
#include <mach/vm_page_size.h>
#endif

#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
#include <Windows.h>
#include <io.h>
#include <malloc.h>  // For _aligned_malloc().
#endif

#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
#include <dlfcn.h>
#include <malloc.h>

#ifdef M_PURGE
#define PERFETTO_M_PURGE M_PURGE
#else
// Only available in in-tree builds and on newer SDKs.
#define PERFETTO_M_PURGE -101
#endif  // M_PURGE

#ifdef M_PURGE_ALL
#define PERFETTO_M_PURGE_ALL M_PURGE_ALL
#else
// Only available in in-tree builds and on newer SDKs.
#define PERFETTO_M_PURGE_ALL -104
#endif  // M_PURGE

namespace {
extern "C" {
using MalloptType = int (*)(int, int);
}
}  // namespace
#endif  // OS_ANDROID

namespace {

#if PERFETTO_BUILDFLAG(PERFETTO_X64_CPU_OPT)

// Preserve the %rbx register via %rdi to work around a clang bug
// https://bugs.llvm.org/show_bug.cgi?id=17907 (%rbx in an output constraint
// is not considered a clobbered register).
#define PERFETTO_GETCPUID(a, b, c, d, a_inp, c_inp) \
  asm("mov %%rbx, %%rdi\n"                          \
      "cpuid\n"                                     \
      "xchg %%rdi, %%rbx\n"                         \
      : "=a"(a), "=D"(b), "=c"(c), "=d"(d)          \
      : "a"(a_inp), "2"(c_inp))

uint32_t GetXCR0EAX() {
  uint32_t eax = 0, edx = 0;
  asm("xgetbv" : "=a"(eax), "=d"(edx) : "c"(0));
  return eax;
}

// If we are building with -msse4 check that the CPU actually supports it.
// This file must be kept in sync with gn/standalone/BUILD.gn.
void PERFETTO_EXPORT_COMPONENT __attribute__((constructor))
CheckCpuOptimizations() {
  uint32_t eax = 0, ebx = 0, ecx = 0, edx = 0;
  PERFETTO_GETCPUID(eax, ebx, ecx, edx, 1, 0);

  static constexpr uint64_t xcr0_xmm_mask = 0x2;
  static constexpr uint64_t xcr0_ymm_mask = 0x4;
  static constexpr uint64_t xcr0_avx_mask = xcr0_xmm_mask | xcr0_ymm_mask;

  const bool have_popcnt = ecx & (1u << 23);
  const bool have_sse4_2 = ecx & (1u << 20);
  const bool have_avx =
      // Does the OS save/restore XMM and YMM state?
      (ecx & (1u << 27)) &&  // OS support XGETBV.
      (ecx & (1u << 28)) &&  // AVX supported in hardware
      ((GetXCR0EAX() & xcr0_avx_mask) == xcr0_avx_mask);

  // Get level 7 features (eax = 7 and ecx= 0), to check for AVX2 support.
  // (See Intel 64 and IA-32 Architectures Software Developer's Manual
  //  Volume 2A: Instruction Set Reference, A-M CPUID).
  PERFETTO_GETCPUID(eax, ebx, ecx, edx, 7, 0);
  const bool have_avx2 = have_avx && ((ebx >> 5) & 0x1);
  const bool have_bmi = (ebx >> 3) & 0x1;
  const bool have_bmi2 = (ebx >> 8) & 0x1;

  if (!have_sse4_2 || !have_popcnt || !have_avx2 || !have_bmi || !have_bmi2) {
    fprintf(
        stderr,
        "This executable requires a x86_64 cpu that supports SSE4.2, BMI2 and "
        "AVX2.\n"
#if PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
        "On MacOS, this might be caused by running x86_64 binaries on arm64.\n"
        "See https://github.com/google/perfetto/issues/294 for more.\n"
#endif
        "Rebuild with enable_perfetto_x64_cpu_opt=false.\n");
    _exit(126);
  }
}
#endif

}  // namespace

namespace perfetto {
namespace base {

namespace internal {

std::atomic<uint32_t> g_cached_page_size{0};

uint32_t GetSysPageSizeSlowpath() {
  uint32_t page_size = 0;
#if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
    PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
  const int page_size_int = getpagesize();
  // If sysconf() fails for obscure reasons (e.g. SELinux denial) assume the
  // page size is 4KB. This is to avoid regressing subtle SDK usages, as old
  // versions of this code had a static constant baked in.
  page_size = static_cast<uint32_t>(page_size_int > 0 ? page_size_int : 4096);
#elif PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
  page_size = static_cast<uint32_t>(vm_page_size);
#else
  page_size = 4096;
#endif

  PERFETTO_CHECK(page_size > 0 && page_size % 4096 == 0);

  // Races here are fine because any thread will write the same value.
  g_cached_page_size.store(page_size, std::memory_order_relaxed);
  return page_size;
}

}  // namespace internal

void MaybeReleaseAllocatorMemToOS() {
#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
  // mallopt() on Android requires SDK level 26. Many targets and embedders
  // still depend on a lower SDK level. Given mallopt() is a quite simple API,
  // use reflection to do this rather than bumping the SDK level for all
  // embedders. This keeps the behavior of standalone builds aligned with
  // in-tree builds.
  static MalloptType mallopt_fn =
      reinterpret_cast<MalloptType>(dlsym(RTLD_DEFAULT, "mallopt"));
  if (!mallopt_fn)
    return;
  if (mallopt_fn(PERFETTO_M_PURGE_ALL, 0) == 0) {
    mallopt_fn(PERFETTO_M_PURGE, 0);
  }
#endif
}

uid_t GetCurrentUserId() {
#if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) ||   \
    PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \
    PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
  return geteuid();
#else
  // TODO(primiano): On Windows we could hash the current user SID and derive a
  // numeric user id [1]. It is not clear whether we need that. Right now that
  // would not bring any benefit. Returning 0 unil we can prove we need it.
  // [1]:https://android-review.googlesource.com/c/platform/external/perfetto/+/1513879/25/src/base/utils.cc
  return 0;
#endif
}

void SetEnv(const std::string& key, const std::string& value) {
#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
  PERFETTO_CHECK(::_putenv_s(key.c_str(), value.c_str()) == 0);
#else
  PERFETTO_CHECK(::setenv(key.c_str(), value.c_str(), /*overwrite=*/true) == 0);
#endif
}

void UnsetEnv(const std::string& key) {
#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
  PERFETTO_CHECK(::_putenv_s(key.c_str(), "") == 0);
#else
  PERFETTO_CHECK(::unsetenv(key.c_str()) == 0);
#endif
}

void Daemonize(std::function<int()> parent_cb) {
#if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) ||   \
    PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \
    PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
  Pipe pipe = Pipe::Create(Pipe::kBothBlock);
  pid_t pid;
  switch (pid = fork()) {
    case -1:
      PERFETTO_FATAL("fork");
    case 0: {
      PERFETTO_CHECK(setsid() != -1);
      base::ignore_result(chdir("/"));
      base::ScopedFile null = base::OpenFile("/dev/null", O_RDONLY);
      PERFETTO_CHECK(null);
      PERFETTO_CHECK(dup2(*null, STDIN_FILENO) != -1);
      PERFETTO_CHECK(dup2(*null, STDOUT_FILENO) != -1);
      PERFETTO_CHECK(dup2(*null, STDERR_FILENO) != -1);
      // Do not accidentally close stdin/stdout/stderr.
      if (*null <= 2)
        null.release();
      WriteAll(*pipe.wr, "1", 1);
      break;
    }
    default: {
      // Wait for the child process to have reached the setsid() call. This is
      // to avoid that 'adb shell perfetto -D' destroys the terminal (hence
      // sending a SIGHUP to the child) before the child has detached from the
      // terminal (see b/238644870).

      // This is to unblock the read() below (with EOF, which will fail the
      // CHECK) in the unlikely case of the child crashing before WriteAll("1").
      pipe.wr.reset();
      char one = '\0';
      PERFETTO_CHECK(Read(*pipe.rd, &one, sizeof(one)) == 1 && one == '1');
      printf("%d\n", pid);
      int err = parent_cb();
      exit(err);
    }
  }
#else
  // Avoid -Wunreachable warnings.
  if (reinterpret_cast<intptr_t>(&Daemonize) != 16)
    PERFETTO_FATAL("--background is only supported on Linux/Android/Mac");
  ignore_result(parent_cb);
#endif  // OS_WIN
}

std::string GetCurExecutablePath() {
  std::string self_path;
#if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) ||   \
    PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \
    PERFETTO_BUILDFLAG(PERFETTO_OS_FUCHSIA)
  char buf[PATH_MAX];
  ssize_t size = readlink("/proc/self/exe", buf, sizeof(buf));
  PERFETTO_CHECK(size != -1);
  // readlink does not null terminate.
  self_path = std::string(buf, static_cast<size_t>(size));
#elif PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
  uint32_t size = 0;
  PERFETTO_CHECK(_NSGetExecutablePath(nullptr, &size));
  self_path.resize(size);
  PERFETTO_CHECK(_NSGetExecutablePath(&self_path[0], &size) == 0);
#elif PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
  char buf[MAX_PATH];
  auto len = ::GetModuleFileNameA(nullptr /*current*/, buf, sizeof(buf));
  self_path = std::string(buf, len);
#else
  PERFETTO_FATAL(
      "GetCurExecutableDir() not implemented on the current platform");
#endif
  return self_path;
}

std::string GetCurExecutableDir() {
  auto path = GetCurExecutablePath();
#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
  // Paths in Windows can have both kinds of slashes (mingw vs msvc).
  path = path.substr(0, path.find_last_of('\\'));
#endif
  path = path.substr(0, path.find_last_of('/'));
  return path;
}

void* AlignedAlloc(size_t alignment, size_t size) {
  void* res = nullptr;
  alignment = AlignUp<sizeof(void*)>(alignment);  // At least pointer size.
#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
  // Window's _aligned_malloc() has a nearly identically signature to Unix's
  // aligned_alloc() but its arguments are obviously swapped.
  res = _aligned_malloc(size, alignment);
#else
  // aligned_alloc() has been introduced in Android only in API 28.
  // Also NaCl and Fuchsia seems to have only posix_memalign().
  ignore_result(posix_memalign(&res, alignment, size));
#endif
  PERFETTO_CHECK(res);
  return res;
}

void AlignedFree(void* ptr) {
#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
  _aligned_free(ptr);  // MSDN says it is fine to pass nullptr.
#else
  free(ptr);
#endif
}

std::string HexDump(const void* data_void, size_t len, size_t bytes_per_line) {
  const char* data = reinterpret_cast<const char*>(data_void);
  std::string res;
  static const size_t kPadding = bytes_per_line * 3 + 12;
  std::unique_ptr<char[]> line(new char[bytes_per_line * 4 + 128]);
  for (size_t i = 0; i < len; i += bytes_per_line) {
    char* wptr = line.get();
    wptr += base::SprintfTrunc(wptr, 19, "%08zX: ", i);
    for (size_t j = i; j < i + bytes_per_line && j < len; j++) {
      wptr += base::SprintfTrunc(wptr, 4, "%02X ",
                                 static_cast<unsigned>(data[j]) & 0xFF);
    }
    for (size_t j = static_cast<size_t>(wptr - line.get()); j < kPadding; ++j)
      *(wptr++) = ' ';
    for (size_t j = i; j < i + bytes_per_line && j < len; j++) {
      char c = data[j];
      *(wptr++) = (c >= 32 && c < 127) ? c : '.';
    }
    *(wptr++) = '\n';
    *(wptr++) = '\0';
    res.append(line.get());
  }
  return res;
}

}  // namespace base
}  // namespace perfetto
// gen_amalgamated begin source: src/base/uuid.cc
// gen_amalgamated begin header: include/perfetto/ext/base/uuid.h
/*
 * Copyright (C) 2019 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef INCLUDE_PERFETTO_EXT_BASE_UUID_H_
#define INCLUDE_PERFETTO_EXT_BASE_UUID_H_

#include <string.h>
#include <array>
#include <cstdint>
#include <optional>
#include <string>

namespace perfetto {
namespace base {

class Uuid {
 public:
  explicit Uuid(const std::string& s);
  explicit Uuid(int64_t lsb, int64_t msb);
  Uuid();

  std::array<uint8_t, 16>* data() { return &data_; }
  const std::array<uint8_t, 16>* data() const { return &data_; }

  bool operator==(const Uuid& other) const { return data_ == other.data_; }

  bool operator!=(const Uuid& other) const { return !(*this == other); }

  explicit operator bool() const { return *this != Uuid(); }

  int64_t msb() const {
    int64_t result;
    memcpy(&result, data_.data() + 8, 8);
    return result;
  }

  int64_t lsb() const {
    int64_t result;
    memcpy(&result, data_.data(), 8);
    return result;
  }

  void set_lsb_msb(int64_t lsb, int64_t msb) {
    set_lsb(lsb);
    set_msb(msb);
  }
  void set_msb(int64_t msb) { memcpy(data_.data() + 8, &msb, 8); }
  void set_lsb(int64_t lsb) { memcpy(data_.data(), &lsb, 8); }

  std::string ToString() const;
  std::string ToPrettyString() const;

 private:
  std::array<uint8_t, 16> data_{};
};

Uuid Uuidv4();

}  // namespace base
}  // namespace perfetto

#endif  // INCLUDE_PERFETTO_EXT_BASE_UUID_H_
// gen_amalgamated begin header: include/perfetto/ext/base/no_destructor.h
/*
 * Copyright (C) 2019 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef INCLUDE_PERFETTO_EXT_BASE_NO_DESTRUCTOR_H_
#define INCLUDE_PERFETTO_EXT_BASE_NO_DESTRUCTOR_H_

#include <new>
#include <utility>

namespace perfetto {
namespace base {

// Wrapper that can hold an object of type T, without invoking the contained
// object's destructor when being destroyed. Useful for creating statics while
// avoiding static destructors.
//
// Stores the object inline, and therefore doesn't incur memory allocation and
// pointer indirection overheads.
//
// Example of use:
//
//   const std::string& GetStr() {
//     static base::NoDestructor<std::string> s("hello");
//     return s.ref();
//   }
//
template <typename T>
class NoDestructor {
 public:
  // Forward arguments to T's constructor. Note that this doesn't cover
  // construction from initializer lists.
  template <typename... Args>
  explicit NoDestructor(Args&&... args) {
    new (storage_) T(std::forward<Args>(args)...);
  }

  NoDestructor(const NoDestructor&) = delete;
  NoDestructor& operator=(const NoDestructor&) = delete;
  NoDestructor(NoDestructor&&) = delete;
  NoDestructor& operator=(NoDestructor&&) = delete;

  ~NoDestructor() = default;

  /* To avoid type-punned pointer strict aliasing warnings on GCC6 and below
   * these need to be split over two lines. If they are collapsed onto one line.
   *   return reinterpret_cast<const T*>(storage_);
   * The error fires.
   */
  const T& ref() const {
    auto* const cast = reinterpret_cast<const T*>(storage_);
    return *cast;
  }
  T& ref() {
    auto* const cast = reinterpret_cast<T*>(storage_);
    return *cast;
  }

 private:
  alignas(T) char storage_[sizeof(T)];
};

}  // namespace base
}  // namespace perfetto

#endif  // INCLUDE_PERFETTO_EXT_BASE_NO_DESTRUCTOR_H_
/*
 * Copyright (C) 2019 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// gen_amalgamated expanded: #include "perfetto/ext/base/uuid.h"

#include <mutex>
#include <random>

// gen_amalgamated expanded: #include "perfetto/base/time.h"
// gen_amalgamated expanded: #include "perfetto/ext/base/no_destructor.h"

namespace perfetto {
namespace base {
namespace {

constexpr char kHexmap[] = {'0', '1', '2', '3', '4', '5', '6', '7',
                            '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
}  // namespace

// A globally unique 128-bit number.
// In the early days of perfetto we were (sorta) respecting rfc4122. Later we
// started replacing the LSB of the UUID with the statsd subscription ID in
// other parts of the codebase (see perfetto_cmd.cc) for the convenience of
// trace lookups, so rfc4122 made no sense as it just reduced entropy.
Uuid Uuidv4() {
  // Mix different sources of entropy to reduce the chances of collisions.
  // Only using boot time is not enough. Under the assumption that most traces
  // are started around the same time at boot, within a 1s window, the birthday
  // paradox gives a chance of 90% collisions with 70k traces over a 1e9 space
  // (Number of ns in a 1s window).
  // &kHexmap >> 14 is used to feed use indirectly ASLR as a source of entropy.
  // We deliberately don't use /dev/urandom as that might block for
  // unpredictable time if the system is idle.
  // The UUID does NOT need to be cryptographically secure, but random enough
  // to avoid collisions across a large number of devices.
  static std::minstd_rand rng(
      static_cast<uint32_t>(static_cast<uint64_t>(GetBootTimeNs().count()) ^
                            static_cast<uint64_t>(GetWallTimeNs().count()) ^
                            (reinterpret_cast<uintptr_t>(&kHexmap) >> 14)));
  Uuid uuid;
  auto& data = *uuid.data();

  // std::random is not thread safe and users of this class might mistakenly
  // assume Uuidv4() is thread_safe because from the outside looks like a
  // local object.
  static base::NoDestructor<std::mutex> rand_mutex;
  std::unique_lock<std::mutex> rand_lock(rand_mutex.ref());

  for (size_t i = 0; i < sizeof(data);) {
    // Note: the 32-th bit of rng() is always 0 as minstd_rand operates modulo
    // 2**31. Fill in blocks of 16b rather than 32b to not lose 1b of entropy.
    const auto rnd_data = static_cast<uint16_t>(rng());
    memcpy(&data[i], &rnd_data, sizeof(rnd_data));
    i += sizeof(rnd_data);
  }

  return uuid;
}

Uuid::Uuid() {}

Uuid::Uuid(const std::string& s) {
  PERFETTO_CHECK(s.size() == data_.size());
  memcpy(data_.data(), s.data(), s.size());
}

Uuid::Uuid(int64_t lsb, int64_t msb) {
  set_lsb_msb(lsb, msb);
}

std::string Uuid::ToString() const {
  return std::string(reinterpret_cast<const char*>(data_.data()), data_.size());
}

std::string Uuid::ToPrettyString() const {
  std::string s(data_.size() * 2 + 4, '-');
  // Format is 123e4567-e89b-12d3-a456-426655443322.
  size_t j = 0;
  for (size_t i = 0; i < data_.size(); ++i) {
    if (i == 4 || i == 6 || i == 8 || i == 10)
      j++;
    s[2 * i + j] = kHexmap[(data_[data_.size() - i - 1] & 0xf0) >> 4];
    s[2 * i + 1 + j] = kHexmap[(data_[data_.size() - i - 1] & 0x0f)];
  }
  return s;
}

}  // namespace base
}  // namespace perfetto
// gen_amalgamated begin source: src/base/virtual_destructors.cc
/*
 * Copyright (C) 2017 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// gen_amalgamated expanded: #include "perfetto/base/task_runner.h"

// This translation unit contains the definitions for the destructor of pure
// virtual interfaces for the current build target. The alternative would be
// introducing a one-liner .cc file for each pure virtual interface, which is
// overkill. This is for compliance with -Wweak-vtables.

namespace perfetto {
namespace base {

TaskRunner::~TaskRunner() = default;

}  // namespace base
}  // namespace perfetto
// gen_amalgamated begin source: src/base/waitable_event.cc
// gen_amalgamated begin header: include/perfetto/ext/base/waitable_event.h
/*
 * Copyright (C) 2019 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef INCLUDE_PERFETTO_EXT_BASE_WAITABLE_EVENT_H_
#define INCLUDE_PERFETTO_EXT_BASE_WAITABLE_EVENT_H_

#include <condition_variable>
#include <mutex>

namespace perfetto {
namespace base {

// A waitable event for cross-thread synchronization.
// All methods on this class can be called from any thread.
class WaitableEvent {
 public:
  WaitableEvent();
  ~WaitableEvent();
  WaitableEvent(const WaitableEvent&) = delete;
  WaitableEvent operator=(const WaitableEvent&) = delete;

  // Synchronously block until the event is notified `notification` times.
  void Wait(uint64_t notifications = 1);

  // Signal the event, waking up blocked waiters.
  void Notify();

 private:
  std::mutex mutex_;
  std::condition_variable event_;
  uint64_t notifications_ = 0;
};

}  // namespace base
}  // namespace perfetto

#endif  // INCLUDE_PERFETTO_EXT_BASE_WAITABLE_EVENT_H_
/*
 * Copyright (C) 2019 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// gen_amalgamated expanded: #include "perfetto/ext/base/waitable_event.h"

namespace perfetto {
namespace base {

WaitableEvent::WaitableEvent() = default;
WaitableEvent::~WaitableEvent() = default;

void WaitableEvent::Wait(uint64_t notifications) {
  std::unique_lock<std::mutex> lock(mutex_);
  return event_.wait(lock, [&] { return notifications_ >= notifications; });
}

void WaitableEvent::Notify() {
  std::unique_lock<std::mutex> lock(mutex_);
  notifications_++;
  event_.notify_all();
}

}  // namespace base
}  // namespace perfetto
// gen_amalgamated begin source: src/base/watchdog_posix.cc
// gen_amalgamated begin header: include/perfetto/ext/base/watchdog.h
// gen_amalgamated begin header: include/perfetto/ext/base/watchdog_noop.h
/*
 * Copyright (C) 2018 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef INCLUDE_PERFETTO_EXT_BASE_WATCHDOG_NOOP_H_
#define INCLUDE_PERFETTO_EXT_BASE_WATCHDOG_NOOP_H_

#include <stdint.h>

namespace perfetto {
namespace base {

enum class WatchdogCrashReason;  // Defined in watchdog.h.

class Watchdog {
 public:
  class Timer {
   public:
    // Define an empty dtor to avoid "unused variable" errors on the call site.
    Timer() {}
    Timer(const Timer&) {}
    ~Timer() {}
  };
  static Watchdog* GetInstance() {
    static Watchdog* watchdog = new Watchdog();
    return watchdog;
  }
  Timer CreateFatalTimer(uint32_t /*ms*/, WatchdogCrashReason) {
    return Timer();
  }
  void Start() {}
  void SetMemoryLimit(uint64_t /*bytes*/, uint32_t /*window_ms*/) {}
  void SetCpuLimit(uint32_t /*percentage*/, uint32_t /*window_ms*/) {}
};

}  // namespace base
}  // namespace perfetto

#endif  // INCLUDE_PERFETTO_EXT_BASE_WATCHDOG_NOOP_H_
/*
 * Copyright (C) 2018 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef INCLUDE_PERFETTO_EXT_BASE_WATCHDOG_H_
#define INCLUDE_PERFETTO_EXT_BASE_WATCHDOG_H_

#include <functional>

// gen_amalgamated expanded: #include "perfetto/base/build_config.h"

// The POSIX watchdog is only supported on Linux and Android in non-embedder
// builds.
#if PERFETTO_BUILDFLAG(PERFETTO_WATCHDOG)
// gen_amalgamated expanded: #include "perfetto/ext/base/watchdog_posix.h"
#else
// gen_amalgamated expanded: #include "perfetto/ext/base/watchdog_noop.h"
#endif

namespace perfetto {
namespace base {

// Used only to add more details to crash reporting.
enum class WatchdogCrashReason {
  kUnspecified = 0,
  kCpuGuardrail = 1,
  kMemGuardrail = 2,
  kTaskRunnerHung = 3,
  kTraceDidntStop = 4,
};

// Make the limits more relaxed on desktop, where multi-GB traces are likely.
// Multi-GB traces can take bursts of cpu time to write into disk at the end of
// the trace.
#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
constexpr uint32_t kWatchdogDefaultCpuLimit = 75;
constexpr uint32_t kWatchdogDefaultCpuWindow = 5 * 60 * 1000;  // 5 minutes.
#else
constexpr uint32_t kWatchdogDefaultCpuLimit = 90;
constexpr uint32_t kWatchdogDefaultCpuWindow = 10 * 60 * 1000;  // 10 minutes.
#endif

// The default memory margin we give to our processes. This is used as as a
// constant to put on top of the trace buffers.
constexpr uint64_t kWatchdogDefaultMemorySlack = 32 * 1024 * 1024;  // 32 MiB.
constexpr uint32_t kWatchdogDefaultMemoryWindow = 30 * 1000;  // 30 seconds.

inline void RunTaskWithWatchdogGuard(const std::function<void()>& task) {
  // Maximum time a single task can take in a TaskRunner before the
  // program suicides.
  constexpr int64_t kWatchdogMillis = 30000;  // 30s

  Watchdog::Timer handle = base::Watchdog::GetInstance()->CreateFatalTimer(
      kWatchdogMillis, WatchdogCrashReason::kTaskRunnerHung);
  task();

  // Suppress unused variable warnings in the client library amalgamated build.
  (void)kWatchdogDefaultCpuLimit;
  (void)kWatchdogDefaultCpuWindow;
  (void)kWatchdogDefaultMemorySlack;
  (void)kWatchdogDefaultMemoryWindow;
}

}  // namespace base
}  // namespace perfetto

#endif  // INCLUDE_PERFETTO_EXT_BASE_WATCHDOG_H_
/*
 * Copyright (C) 2018 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// gen_amalgamated expanded: #include "perfetto/ext/base/platform.h"
// gen_amalgamated expanded: #include "perfetto/ext/base/watchdog.h"

#if PERFETTO_BUILDFLAG(PERFETTO_WATCHDOG)

#include <fcntl.h>
#include <poll.h>
#include <signal.h>
#include <stdint.h>
#include <stdlib.h>
#include <sys/syscall.h>
#include <sys/timerfd.h>
#include <unistd.h>

#include <algorithm>
#include <cinttypes>
#include <fstream>
#include <thread>

// gen_amalgamated expanded: #include "perfetto/base/build_config.h"
// gen_amalgamated expanded: #include "perfetto/base/logging.h"
// gen_amalgamated expanded: #include "perfetto/base/thread_utils.h"
// gen_amalgamated expanded: #include "perfetto/base/time.h"
// gen_amalgamated expanded: #include "perfetto/ext/base/crash_keys.h"
// gen_amalgamated expanded: #include "perfetto/ext/base/file_utils.h"
// gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"
// gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"

namespace perfetto {
namespace base {

namespace {

constexpr uint32_t kDefaultPollingInterval = 30 * 1000;

base::CrashKey g_crash_key_reason("wdog_reason");

bool IsMultipleOf(uint32_t number, uint32_t divisor) {
  return number >= divisor && number % divisor == 0;
}

double MeanForArray(const uint64_t array[], size_t size) {
  uint64_t total = 0;
  for (size_t i = 0; i < size; i++) {
    total += array[i];
  }
  return static_cast<double>(total / size);
}

}  //  namespace

bool ReadProcStat(int fd, ProcStat* out) {
  char c[512];
  size_t c_pos = 0;
  while (c_pos < sizeof(c) - 1) {
    ssize_t rd = PERFETTO_EINTR(read(fd, c + c_pos, sizeof(c) - c_pos));
    if (rd < 0) {
      PERFETTO_ELOG("Failed to read stat file to enforce resource limits.");
      return false;
    }
    if (rd == 0)
      break;
    c_pos += static_cast<size_t>(rd);
  }
  PERFETTO_CHECK(c_pos < sizeof(c));
  c[c_pos] = '\0';

  if (sscanf(c,
             "%*d %*s %*c %*d %*d %*d %*d %*d %*u %*u %*u %*u %*u %lu "
             "%lu %*d %*d %*d %*d %*d %*d %*u %*u %ld",
             &out->utime, &out->stime, &out->rss_pages) != 3) {
    PERFETTO_ELOG("Invalid stat format: %s", c);
    return false;
  }
  return true;
}

Watchdog::Watchdog(uint32_t polling_interval_ms)
    : polling_interval_ms_(polling_interval_ms) {}

Watchdog::~Watchdog() {
  if (!thread_.joinable()) {
    PERFETTO_DCHECK(!enabled_);
    return;
  }
  PERFETTO_DCHECK(enabled_);
  enabled_ = false;

  // Rearm the timer to 1ns from now. This will cause the watchdog thread to
  // wakeup from the poll() and see |enabled_| == false.
  // This code path is used only in tests. In production code the watchdog is
  // a singleton and is never destroyed.
  struct itimerspec ts {};
  ts.it_value.tv_sec = 0;
  ts.it_value.tv_nsec = 1;
  timerfd_settime(*timer_fd_, /*flags=*/0, &ts, nullptr);

  thread_.join();
}

Watchdog* Watchdog::GetInstance() {
  static Watchdog* watchdog = new Watchdog(kDefaultPollingInterval);
  return watchdog;
}

// Can be called from any thread.
Watchdog::Timer Watchdog::CreateFatalTimer(uint32_t ms,
                                           WatchdogCrashReason crash_reason) {
  if (!enabled_.load(std::memory_order_relaxed))
    return Watchdog::Timer(this, 0, crash_reason);

  return Watchdog::Timer(this, ms, crash_reason);
}

// Can be called from any thread.
void Watchdog::AddFatalTimer(TimerData timer) {
  std::lock_guard<std::mutex> guard(mutex_);
  timers_.emplace_back(std::move(timer));
  RearmTimerFd_Locked();
}

// Can be called from any thread.
void Watchdog::RemoveFatalTimer(TimerData timer) {
  std::lock_guard<std::mutex> guard(mutex_);
  for (auto it = timers_.begin(); it != timers_.end(); it++) {
    if (*it == timer) {
      timers_.erase(it);
      break;  // Remove only one. Doesn't matter which one.
    }
  }
  RearmTimerFd_Locked();
}

void Watchdog::RearmTimerFd_Locked() {
  if (!enabled_)
    return;
  auto it = std::min_element(timers_.begin(), timers_.end());

  // We use one timerfd to handle all the oustanding |timers_|. Keep it armed
  // to the task expiring soonest.
  struct itimerspec ts {};
  if (it != timers_.end()) {
    ts.it_value = ToPosixTimespec(it->deadline);
  }
  // If |timers_| is empty (it == end()) |ts.it_value| will remain
  // zero-initialized and that will disarm the timer in the call below.
  int res = timerfd_settime(*timer_fd_, TFD_TIMER_ABSTIME, &ts, nullptr);
  PERFETTO_DCHECK(res == 0);
}

void Watchdog::Start() {
  std::lock_guard<std::mutex> guard(mutex_);
  if (thread_.joinable()) {
    PERFETTO_DCHECK(enabled_);
  } else {
    PERFETTO_DCHECK(!enabled_);

#if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
    PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
    // Kick the thread to start running but only on Android or Linux.
    timer_fd_.reset(
        timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC | TFD_NONBLOCK));
    if (!timer_fd_) {
      PERFETTO_PLOG(
          "timerfd_create failed, the Perfetto watchdog is not available");
      return;
    }
    enabled_ = true;
    RearmTimerFd_Locked();  // Deal with timers created before Start().
    thread_ = std::thread(&Watchdog::ThreadMain, this);
#endif
  }
}

void Watchdog::SetMemoryLimit(uint64_t bytes, uint32_t window_ms) {
  // Update the fields under the lock.
  std::lock_guard<std::mutex> guard(mutex_);

  PERFETTO_CHECK(IsMultipleOf(window_ms, polling_interval_ms_) || bytes == 0);

  size_t size = bytes == 0 ? 0 : window_ms / polling_interval_ms_ + 1;
  memory_window_bytes_.Reset(size);
  memory_limit_bytes_ = bytes;
}

void Watchdog::SetCpuLimit(uint32_t percentage, uint32_t window_ms) {
  std::lock_guard<std::mutex> guard(mutex_);

  PERFETTO_CHECK(percentage <= 100);
  PERFETTO_CHECK(IsMultipleOf(window_ms, polling_interval_ms_) ||
                 percentage == 0);

  size_t size = percentage == 0 ? 0 : window_ms / polling_interval_ms_ + 1;
  cpu_window_time_ticks_.Reset(size);
  cpu_limit_percentage_ = percentage;
}

void Watchdog::ThreadMain() {
  // Register crash keys explicitly to avoid running out of slots at crash time.
  g_crash_key_reason.Register();

  base::ScopedFile stat_fd(base::OpenFile("/proc/self/stat", O_RDONLY));
  if (!stat_fd) {
    PERFETTO_ELOG("Failed to open stat file to enforce resource limits.");
    return;
  }

  PERFETTO_DCHECK(timer_fd_);

  constexpr uint8_t kFdCount = 1;
  struct pollfd fds[kFdCount]{};
  fds[0].fd = *timer_fd_;
  fds[0].events = POLLIN;

  for (;;) {
    // We use the poll() timeout to drive the periodic ticks for the cpu/memory
    // checks. The only other case when the poll() unblocks is when we crash
    // (or have to quit via enabled_ == false, but that happens only in tests).
    platform::BeforeMaybeBlockingSyscall();
    auto ret = poll(fds, kFdCount, static_cast<int>(polling_interval_ms_));
    platform::AfterMaybeBlockingSyscall();
    if (!enabled_)
      return;
    if (ret < 0) {
      if (errno == ENOMEM || errno == EINTR) {
        // Should happen extremely rarely.
        std::this_thread::sleep_for(std::chrono::milliseconds(100));
        continue;
      }
      PERFETTO_FATAL("watchdog poll() failed");
    }

    // If we get here either:
    // 1. poll() timed out, in which case we should process cpu/mem guardrails.
    // 2. A timer expired, in which case we shall crash.

    uint64_t expired = 0;  // Must be exactly 8 bytes.
    auto res = PERFETTO_EINTR(read(*timer_fd_, &expired, sizeof(expired)));
    PERFETTO_DCHECK((res < 0 && (errno == EAGAIN)) ||
                    (res == sizeof(expired) && expired > 0));
    const auto now = GetWallTimeMs();

    // Check if any of the timers expired.
    int tid_to_kill = 0;
    WatchdogCrashReason crash_reason{};
    std::unique_lock<std::mutex> guard(mutex_);
    for (const auto& timer : timers_) {
      if (now >= timer.deadline) {
        tid_to_kill = timer.thread_id;
        crash_reason = timer.crash_reason;
        break;
      }
    }
    guard.unlock();

    if (tid_to_kill)
      SerializeLogsAndKillThread(tid_to_kill, crash_reason);

    // Check CPU and memory guardrails (if enabled).
    lseek(stat_fd.get(), 0, SEEK_SET);
    ProcStat stat;
    if (!ReadProcStat(stat_fd.get(), &stat))
      continue;
    uint64_t cpu_time = stat.utime + stat.stime;
    uint64_t rss_bytes =
        static_cast<uint64_t>(stat.rss_pages) * base::GetSysPageSize();

    bool threshold_exceeded = false;
    guard.lock();
    if (CheckMemory_Locked(rss_bytes)) {
      threshold_exceeded = true;
      crash_reason = WatchdogCrashReason::kMemGuardrail;
    } else if (CheckCpu_Locked(cpu_time)) {
      threshold_exceeded = true;
      crash_reason = WatchdogCrashReason::kCpuGuardrail;
    }
    guard.unlock();

    if (threshold_exceeded)
      SerializeLogsAndKillThread(getpid(), crash_reason);
  }
}

void Watchdog::SerializeLogsAndKillThread(int tid,
                                          WatchdogCrashReason crash_reason) {
  g_crash_key_reason.Set(static_cast<int>(crash_reason));

  // We are about to die. Serialize the logs into the crash buffer so the
  // debuggerd crash handler picks them up and attaches to the bugreport.
  // In the case of a PERFETTO_CHECK/PERFETTO_FATAL this is done in logging.h.
  // But in the watchdog case, we don't hit that codepath and must do ourselves.
  MaybeSerializeLastLogsForCrashReporting();

  // Send a SIGABRT to the thread that armed the timer. This is to see the
  // callstack of the thread that is stuck in a long task rather than the
  // watchdog thread.
  if (syscall(__NR_tgkill, getpid(), tid, SIGABRT) < 0) {
    // At this point the process must die. If for any reason the tgkill doesn't
    // work (e.g. the thread has disappeared), force a crash from here.
    abort();
  }

  if (disable_kill_failsafe_for_testing_)
    return;

  // The tgkill() above will take some milliseconds to cause a crash, as it
  // involves the kernel to queue the SIGABRT on the target thread (often the
  // main thread, which is != watchdog thread) and do a scheduling round.
  // If something goes wrong though (the target thread has signals masked or
  // is stuck in an uninterruptible+wakekill syscall) force quit from this
  // thread.
  std::this_thread::sleep_for(std::chrono::seconds(10));
  abort();
}

bool Watchdog::CheckMemory_Locked(uint64_t rss_bytes) {
  if (memory_limit_bytes_ == 0)
    return false;

  // Add the current stat value to the ring buffer and check that the mean
  // remains under our threshold.
  if (memory_window_bytes_.Push(rss_bytes)) {
    if (memory_window_bytes_.Mean() >
        static_cast<double>(memory_limit_bytes_)) {
      PERFETTO_ELOG(
          "Memory watchdog trigger. Memory window of %f bytes is above the "
          "%" PRIu64 " bytes limit.",
          memory_window_bytes_.Mean(), memory_limit_bytes_);
      return true;
    }
  }
  return false;
}

bool Watchdog::CheckCpu_Locked(uint64_t cpu_time) {
  if (cpu_limit_percentage_ == 0)
    return false;

  // Add the cpu time to the ring buffer.
  if (cpu_window_time_ticks_.Push(cpu_time)) {
    // Compute the percentage over the whole window and check that it remains
    // under the threshold.
    uint64_t difference_ticks = cpu_window_time_ticks_.NewestWhenFull() -
                                cpu_window_time_ticks_.OldestWhenFull();
    double window_interval_ticks =
        (static_cast<double>(WindowTimeForRingBuffer(cpu_window_time_ticks_)) /
         1000.0) *
        static_cast<double>(sysconf(_SC_CLK_TCK));
    double percentage = static_cast<double>(difference_ticks) /
                        static_cast<double>(window_interval_ticks) * 100;
    if (percentage > cpu_limit_percentage_) {
      PERFETTO_ELOG("CPU watchdog trigger. %f%% CPU use is above the %" PRIu32
                    "%% CPU limit.",
                    percentage, cpu_limit_percentage_);
      return true;
    }
  }
  return false;
}

uint32_t Watchdog::WindowTimeForRingBuffer(const WindowedInterval& window) {
  return static_cast<uint32_t>(window.size() - 1) * polling_interval_ms_;
}

bool Watchdog::WindowedInterval::Push(uint64_t sample) {
  // Add the sample to the current position in the ring buffer.
  buffer_[position_] = sample;

  // Update the position with next one circularily.
  position_ = (position_ + 1) % size_;

  // Set the filled flag the first time we wrap.
  filled_ = filled_ || position_ == 0;
  return filled_;
}

double Watchdog::WindowedInterval::Mean() const {
  return MeanForArray(buffer_.get(), size_);
}

void Watchdog::WindowedInterval::Clear() {
  position_ = 0;
  buffer_.reset(new uint64_t[size_]());
}

void Watchdog::WindowedInterval::Reset(size_t new_size) {
  position_ = 0;
  size_ = new_size;
  buffer_.reset(new_size == 0 ? nullptr : new uint64_t[new_size]());
}

Watchdog::Timer::Timer(Watchdog* watchdog,
                       uint32_t ms,
                       WatchdogCrashReason crash_reason)
    : watchdog_(watchdog) {
  if (!ms)
    return;  // No-op timer created when the watchdog is disabled.
  timer_data_.deadline = GetWallTimeMs() + std::chrono::milliseconds(ms);
  timer_data_.thread_id = GetThreadId();
  timer_data_.crash_reason = crash_reason;
  PERFETTO_DCHECK(watchdog_);
  watchdog_->AddFatalTimer(timer_data_);
}

Watchdog::Timer::~Timer() {
  if (timer_data_.deadline.count())
    watchdog_->RemoveFatalTimer(timer_data_);
}

Watchdog::Timer::Timer(Timer&& other) noexcept {
  watchdog_ = std::move(other.watchdog_);
  other.watchdog_ = nullptr;
  timer_data_ = std::move(other.timer_data_);
  other.timer_data_ = TimerData();
}

}  // namespace base
}  // namespace perfetto

#endif  // PERFETTO_BUILDFLAG(PERFETTO_WATCHDOG)
// gen_amalgamated begin source: src/base/thread_task_runner.cc
// gen_amalgamated begin header: include/perfetto/ext/base/thread_task_runner.h
// gen_amalgamated begin header: include/perfetto/ext/base/unix_task_runner.h
/*
 * Copyright (C) 2017 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef INCLUDE_PERFETTO_EXT_BASE_UNIX_TASK_RUNNER_H_
#define INCLUDE_PERFETTO_EXT_BASE_UNIX_TASK_RUNNER_H_

// gen_amalgamated expanded: #include "perfetto/base/build_config.h"
// gen_amalgamated expanded: #include "perfetto/base/task_runner.h"
// gen_amalgamated expanded: #include "perfetto/base/thread_utils.h"
// gen_amalgamated expanded: #include "perfetto/base/time.h"
// gen_amalgamated expanded: #include "perfetto/ext/base/event_fd.h"
// gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"
// gen_amalgamated expanded: #include "perfetto/ext/base/thread_checker.h"

#include <chrono>
#include <deque>
#include <map>
#include <mutex>
#include <vector>

#if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
#include <poll.h>
#endif

namespace perfetto {
namespace base {

// Runs a task runner on the current thread.
//
// Implementation note: we currently assume (and enforce in debug builds) that
// Run() is called from the thread that constructed the UnixTaskRunner. This is
// not strictly necessary, and we could instead track the thread that invokes
// Run(). However, a related property that *might* be important to enforce is
// that the destructor runs on the task-running thread. Otherwise, if there are
// still-pending tasks at the time of destruction, we would destroy those
// outside of the task thread (which might be unexpected to the caller). On the
// other hand, the std::function task interface discourages use of any
// resource-owning tasks (as the callable needs to be copyable), so this might
// not be important in practice.
//
// TODO(rsavitski): consider adding a thread-check in the destructor, after
// auditing existing usages.
// TODO(primiano): rename this to TaskRunnerImpl. The "Unix" part is misleading
// now as it supports also Windows.
class UnixTaskRunner : public TaskRunner {
 public:
  UnixTaskRunner();
  ~UnixTaskRunner() override;

  // Start executing tasks. Doesn't return until Quit() is called. Run() may be
  // called multiple times on the same task runner.
  void Run();
  void Quit();

  // Checks whether there are any pending immediate tasks to run. Note that
  // delayed tasks don't count even if they are due to run.
  bool IsIdleForTesting();

  // TaskRunner implementation:
  void PostTask(std::function<void()>) override;
  void PostDelayedTask(std::function<void()>, uint32_t delay_ms) override;
  void AddFileDescriptorWatch(PlatformHandle, std::function<void()>) override;
  void RemoveFileDescriptorWatch(PlatformHandle) override;
  bool RunsTasksOnCurrentThread() const override;

  // Returns true if the task runner is quitting, or has quit and hasn't been
  // restarted since. Exposed primarily for ThreadTaskRunner, not necessary for
  // normal use of this class.
  bool QuitCalled();

 private:
  void WakeUp();
  void UpdateWatchTasksLocked();
  int GetDelayMsToNextTaskLocked() const;
  void RunImmediateAndDelayedTask();
  void PostFileDescriptorWatches(uint64_t windows_wait_result);
  void RunFileDescriptorWatch(PlatformHandle);

  ThreadChecker thread_checker_;
  PlatformThreadId created_thread_id_ = GetThreadId();

  EventFd event_;

// The array of fds/handles passed to poll(2) / WaitForMultipleObjects().
#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
  std::vector<PlatformHandle> poll_fds_;
#else
  std::vector<struct pollfd> poll_fds_;
#endif

  // --- Begin lock-protected members ---

  std::mutex lock_;

  std::deque<std::function<void()>> immediate_tasks_;
  std::multimap<TimeMillis, std::function<void()>> delayed_tasks_;
  bool quit_ = false;

  struct WatchTask {
    std::function<void()> callback;
#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
    // On UNIX systems we make the FD number negative in |poll_fds_| to avoid
    // polling it again until the queued task runs. On Windows we can't do that.
    // Instead we keep track of its state here.
    bool pending = false;
#else
    size_t poll_fd_index;  // Index into |poll_fds_|.
#endif
  };

  std::map<PlatformHandle, WatchTask> watch_tasks_;
  bool watch_tasks_changed_ = false;

  // --- End lock-protected members ---
};

}  // namespace base
}  // namespace perfetto

#endif  // INCLUDE_PERFETTO_EXT_BASE_UNIX_TASK_RUNNER_H_
/*
 * Copyright (C) 2019 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef INCLUDE_PERFETTO_EXT_BASE_THREAD_TASK_RUNNER_H_
#define INCLUDE_PERFETTO_EXT_BASE_THREAD_TASK_RUNNER_H_

#include <functional>
#include <thread>

// gen_amalgamated expanded: #include "perfetto/ext/base/unix_task_runner.h"

namespace perfetto {
namespace base {

// A UnixTaskRunner backed by a dedicated task thread. Shuts down the runner and
// joins the thread upon destruction. Can be moved to transfer ownership.
//
// Guarantees that:
// * the UnixTaskRunner will be constructed and destructed on the task thread.
// * the task thread will live for the lifetime of the UnixTaskRunner.
//
class PERFETTO_EXPORT_COMPONENT ThreadTaskRunner : public TaskRunner {
 public:
  static ThreadTaskRunner CreateAndStart(const std::string& name = "") {
    return ThreadTaskRunner(name);
  }

  ThreadTaskRunner(const ThreadTaskRunner&) = delete;
  ThreadTaskRunner& operator=(const ThreadTaskRunner&) = delete;

  ThreadTaskRunner(ThreadTaskRunner&&) noexcept;
  ThreadTaskRunner& operator=(ThreadTaskRunner&&);
  ~ThreadTaskRunner() override;

  // Executes the given function on the task runner thread and blocks the caller
  // thread until the function has run.
  void PostTaskAndWaitForTesting(std::function<void()>);

  // Can be called from another thread to get the CPU time of the thread the
  // task-runner is executing on.
  uint64_t GetThreadCPUTimeNsForTesting();

  // Returns a pointer to the UnixTaskRunner, which is valid for the lifetime of
  // this ThreadTaskRunner object (unless this object is moved-from, in which
  // case the pointer remains valid for the lifetime of the new owning
  // ThreadTaskRunner).
  //
  // Warning: do not call Quit() on the returned runner pointer, the termination
  // should be handled exclusively by this class' destructor.
  UnixTaskRunner* get() const { return task_runner_; }

  // TaskRunner implementation.
  // These methods just proxy to the underlying task_runner_.
  void PostTask(std::function<void()>) override;
  void PostDelayedTask(std::function<void()>, uint32_t delay_ms) override;
  void AddFileDescriptorWatch(PlatformHandle, std::function<void()>) override;
  void RemoveFileDescriptorWatch(PlatformHandle) override;
  bool RunsTasksOnCurrentThread() const override;

 private:
  explicit ThreadTaskRunner(const std::string& name);
  void RunTaskThread(std::function<void(UnixTaskRunner*)> initializer);

  std::thread thread_;
  std::string name_;
  UnixTaskRunner* task_runner_ = nullptr;
};

}  // namespace base
}  // namespace perfetto

#endif  // INCLUDE_PERFETTO_EXT_BASE_THREAD_TASK_RUNNER_H_
/*
 * Copyright (C) 2019 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// gen_amalgamated expanded: #include "perfetto/base/build_config.h"

// gen_amalgamated expanded: #include "perfetto/ext/base/thread_task_runner.h"

#include <condition_variable>
#include <functional>
#include <mutex>
#include <thread>

// gen_amalgamated expanded: #include "perfetto/base/logging.h"
// gen_amalgamated expanded: #include "perfetto/ext/base/thread_utils.h"
// gen_amalgamated expanded: #include "perfetto/ext/base/unix_task_runner.h"

#if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
    PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
#include <sys/prctl.h>
#endif

namespace perfetto {
namespace base {

ThreadTaskRunner::ThreadTaskRunner(ThreadTaskRunner&& other) noexcept
    : thread_(std::move(other.thread_)), task_runner_(other.task_runner_) {
  other.task_runner_ = nullptr;
}

ThreadTaskRunner& ThreadTaskRunner::operator=(ThreadTaskRunner&& other) {
  this->~ThreadTaskRunner();
  new (this) ThreadTaskRunner(std::move(other));
  return *this;
}

ThreadTaskRunner::~ThreadTaskRunner() {
  if (task_runner_) {
    PERFETTO_CHECK(!task_runner_->QuitCalled());
    task_runner_->Quit();

    PERFETTO_DCHECK(thread_.joinable());
  }
  if (thread_.joinable())
    thread_.join();
}

ThreadTaskRunner::ThreadTaskRunner(const std::string& name) : name_(name) {
  std::mutex init_lock;
  std::condition_variable init_cv;

  std::function<void(UnixTaskRunner*)> initializer =
      [this, &init_lock, &init_cv](UnixTaskRunner* task_runner) {
        std::lock_guard<std::mutex> lock(init_lock);
        task_runner_ = task_runner;
        // Notify while still holding the lock, as init_cv ceases to exist as
        // soon as the main thread observes a non-null task_runner_, and it can
        // wake up spuriously (i.e. before the notify if we had unlocked before
        // notifying).
        init_cv.notify_one();
      };

  thread_ = std::thread(&ThreadTaskRunner::RunTaskThread, this,
                        std::move(initializer));

  std::unique_lock<std::mutex> lock(init_lock);
  init_cv.wait(lock, [this] { return !!task_runner_; });
}

void ThreadTaskRunner::RunTaskThread(
    std::function<void(UnixTaskRunner*)> initializer) {
  if (!name_.empty()) {
    base::MaybeSetThreadName(name_);
  }

  UnixTaskRunner task_runner;
  task_runner.PostTask(std::bind(std::move(initializer), &task_runner));
  task_runner.Run();
}

void ThreadTaskRunner::PostTaskAndWaitForTesting(std::function<void()> fn) {
  std::mutex mutex;
  std::condition_variable cv;

  std::unique_lock<std::mutex> lock(mutex);
  bool done = false;
  task_runner_->PostTask([&mutex, &cv, &done, &fn] {
    fn();

    std::lock_guard<std::mutex> inner_lock(mutex);
    done = true;
    cv.notify_one();
  });
  cv.wait(lock, [&done] { return done; });
}

uint64_t ThreadTaskRunner::GetThreadCPUTimeNsForTesting() {
  uint64_t thread_time_ns = 0;
  PostTaskAndWaitForTesting([&thread_time_ns] {
    thread_time_ns = static_cast<uint64_t>(base::GetThreadCPUTimeNs().count());
  });
  return thread_time_ns;
}

void ThreadTaskRunner::PostTask(std::function<void()> task) {
  task_runner_->PostTask(std::move(task));
}

void ThreadTaskRunner::PostDelayedTask(std::function<void()> task,
                                       uint32_t delay_ms) {
  task_runner_->PostDelayedTask(std::move(task), delay_ms);
}

void ThreadTaskRunner::AddFileDescriptorWatch(
    PlatformHandle handle,
    std::function<void()> watch_task) {
  task_runner_->AddFileDescriptorWatch(handle, std::move(watch_task));
}

void ThreadTaskRunner::RemoveFileDescriptorWatch(PlatformHandle handle) {
  task_runner_->RemoveFileDescriptorWatch(handle);
}

bool ThreadTaskRunner::RunsTasksOnCurrentThread() const {
  return task_runner_->RunsTasksOnCurrentThread();
}

}  // namespace base
}  // namespace perfetto
// gen_amalgamated begin source: src/base/unix_task_runner.cc
/*
 * Copyright (C) 2017 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// gen_amalgamated expanded: #include "perfetto/base/build_config.h"

// gen_amalgamated expanded: #include "perfetto/ext/base/platform.h"
// gen_amalgamated expanded: #include "perfetto/ext/base/unix_task_runner.h"

#include <errno.h>
#include <stdlib.h>

#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
#include <Windows.h>
#include <synchapi.h>
#else
#include <unistd.h>
#endif

#include <algorithm>
#include <limits>

// gen_amalgamated expanded: #include "perfetto/ext/base/watchdog.h"

namespace perfetto {
namespace base {

UnixTaskRunner::UnixTaskRunner() {
  AddFileDescriptorWatch(event_.fd(), [] {
    // Not reached -- see PostFileDescriptorWatches().
    PERFETTO_DFATAL("Should be unreachable.");
  });
}

UnixTaskRunner::~UnixTaskRunner() = default;

void UnixTaskRunner::WakeUp() {
  event_.Notify();
}

void UnixTaskRunner::Run() {
  PERFETTO_DCHECK_THREAD(thread_checker_);
  created_thread_id_ = GetThreadId();
  quit_ = false;
  for (;;) {
    int poll_timeout_ms;
    {
      std::lock_guard<std::mutex> lock(lock_);
      if (quit_)
        return;
      poll_timeout_ms = GetDelayMsToNextTaskLocked();
      UpdateWatchTasksLocked();
    }

#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
    DWORD timeout =
        poll_timeout_ms >= 0 ? static_cast<DWORD>(poll_timeout_ms) : INFINITE;
    DWORD ret =
        WaitForMultipleObjects(static_cast<DWORD>(poll_fds_.size()),
                               &poll_fds_[0], /*bWaitAll=*/false, timeout);
    // Unlike poll(2), WaitForMultipleObjects() returns only *one* handle in the
    // set, even when >1 is signalled. In order to avoid starvation,
    // PostFileDescriptorWatches() will WaitForSingleObject() each other handle
    // to ensure fairness. |ret| here is passed just to avoid an extra
    // WaitForSingleObject() for the one handle that WaitForMultipleObject()
    // returned.
    PostFileDescriptorWatches(ret);
#else
    platform::BeforeMaybeBlockingSyscall();
    int ret = PERFETTO_EINTR(poll(
        &poll_fds_[0], static_cast<nfds_t>(poll_fds_.size()), poll_timeout_ms));
    platform::AfterMaybeBlockingSyscall();
    PERFETTO_CHECK(ret >= 0);
    PostFileDescriptorWatches(0 /*ignored*/);
#endif

    // To avoid starvation we always interleave all types of tasks -- immediate,
    // delayed and file descriptor watches.
    RunImmediateAndDelayedTask();
  }
}

void UnixTaskRunner::Quit() {
  std::lock_guard<std::mutex> lock(lock_);
  quit_ = true;
  WakeUp();
}

bool UnixTaskRunner::QuitCalled() {
  std::lock_guard<std::mutex> lock(lock_);
  return quit_;
}

bool UnixTaskRunner::IsIdleForTesting() {
  std::lock_guard<std::mutex> lock(lock_);
  return immediate_tasks_.empty();
}

void UnixTaskRunner::UpdateWatchTasksLocked() {
  PERFETTO_DCHECK_THREAD(thread_checker_);
#if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
  if (!watch_tasks_changed_)
    return;
  watch_tasks_changed_ = false;
#endif
  poll_fds_.clear();
  for (auto& it : watch_tasks_) {
    PlatformHandle handle = it.first;
    WatchTask& watch_task = it.second;
#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
    if (!watch_task.pending)
      poll_fds_.push_back(handle);
#else
    watch_task.poll_fd_index = poll_fds_.size();
    poll_fds_.push_back({handle, POLLIN | POLLHUP, 0});
#endif
  }
}

void UnixTaskRunner::RunImmediateAndDelayedTask() {
  // If locking overhead becomes an issue, add a separate work queue.
  std::function<void()> immediate_task;
  std::function<void()> delayed_task;
  TimeMillis now = GetWallTimeMs();
  {
    std::lock_guard<std::mutex> lock(lock_);
    if (!immediate_tasks_.empty()) {
      immediate_task = std::move(immediate_tasks_.front());
      immediate_tasks_.pop_front();
    }
    if (!delayed_tasks_.empty()) {
      auto it = delayed_tasks_.begin();
      if (now >= it->first) {
        delayed_task = std::move(it->second);
        delayed_tasks_.erase(it);
      }
    }
  }

  errno = 0;
  if (immediate_task)
    RunTaskWithWatchdogGuard(immediate_task);
  errno = 0;
  if (delayed_task)
    RunTaskWithWatchdogGuard(delayed_task);
}

void UnixTaskRunner::PostFileDescriptorWatches(uint64_t windows_wait_result) {
  PERFETTO_DCHECK_THREAD(thread_checker_);
  for (size_t i = 0; i < poll_fds_.size(); i++) {
#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
    const PlatformHandle handle = poll_fds_[i];
    // |windows_wait_result| is the result of WaitForMultipleObjects() call. If
    // one of the objects was signalled, it will have a value between
    // [0, poll_fds_.size()].
    if (i != windows_wait_result &&
        WaitForSingleObject(handle, 0) != WAIT_OBJECT_0) {
      continue;
    }
#else
    base::ignore_result(windows_wait_result);
    const PlatformHandle handle = poll_fds_[i].fd;
    if (!(poll_fds_[i].revents & (POLLIN | POLLHUP)))
      continue;
    poll_fds_[i].revents = 0;
#endif

    // The wake-up event is handled inline to avoid an infinite recursion of
    // posted tasks.
    if (handle == event_.fd()) {
      event_.Clear();
      continue;
    }

    // Binding to |this| is safe since we are the only object executing the
    // task.
    PostTask(std::bind(&UnixTaskRunner::RunFileDescriptorWatch, this, handle));

    // Flag the task as pending.
#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
    // On Windows this is done by marking the WatchTask entry as pending. This
    // is more expensive than Linux as requires rebuilding the |poll_fds_|
    // vector on each call. There doesn't seem to be a good alternative though.
    auto it = watch_tasks_.find(handle);
    PERFETTO_CHECK(it != watch_tasks_.end());
    PERFETTO_DCHECK(!it->second.pending);
    it->second.pending = true;
#else
    // On UNIX systems instead, we just make the fd negative while its task is
    // pending. This makes poll(2) ignore the fd.
    PERFETTO_DCHECK(poll_fds_[i].fd >= 0);
    poll_fds_[i].fd = -poll_fds_[i].fd;
#endif
  }
}

void UnixTaskRunner::RunFileDescriptorWatch(PlatformHandle fd) {
  std::function<void()> task;
  {
    std::lock_guard<std::mutex> lock(lock_);
    auto it = watch_tasks_.find(fd);
    if (it == watch_tasks_.end())
      return;
    WatchTask& watch_task = it->second;

    // Make poll(2) pay attention to the fd again. Since another thread may have
    // updated this watch we need to refresh the set first.
    UpdateWatchTasksLocked();

#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
    // On Windows we manually track the presence of outstanding tasks for the
    // watch. The UpdateWatchTasksLocked() in the Run() loop will re-add the
    // task to the |poll_fds_| vector.
    PERFETTO_DCHECK(watch_task.pending);
    watch_task.pending = false;
#else
    size_t fd_index = watch_task.poll_fd_index;
    PERFETTO_DCHECK(fd_index < poll_fds_.size());
    PERFETTO_DCHECK(::abs(poll_fds_[fd_index].fd) == fd);
    poll_fds_[fd_index].fd = fd;
#endif
    task = watch_task.callback;
  }
  errno = 0;
  RunTaskWithWatchdogGuard(task);
}

int UnixTaskRunner::GetDelayMsToNextTaskLocked() const {
  PERFETTO_DCHECK_THREAD(thread_checker_);
  if (!immediate_tasks_.empty())
    return 0;
  if (!delayed_tasks_.empty()) {
    TimeMillis diff = delayed_tasks_.begin()->first - GetWallTimeMs();
    return std::max(0, static_cast<int>(diff.count()));
  }
  return -1;
}

void UnixTaskRunner::PostTask(std::function<void()> task) {
  bool was_empty;
  {
    std::lock_guard<std::mutex> lock(lock_);
    was_empty = immediate_tasks_.empty();
    immediate_tasks_.push_back(std::move(task));
  }
  if (was_empty)
    WakeUp();
}

void UnixTaskRunner::PostDelayedTask(std::function<void()> task,
                                     uint32_t delay_ms) {
  TimeMillis runtime = GetWallTimeMs() + TimeMillis(delay_ms);
  {
    std::lock_guard<std::mutex> lock(lock_);
    delayed_tasks_.insert(std::make_pair(runtime, std::move(task)));
  }
  WakeUp();
}

void UnixTaskRunner::AddFileDescriptorWatch(PlatformHandle fd,
                                            std::function<void()> task) {
  PERFETTO_DCHECK(PlatformHandleChecker::IsValid(fd));
  {
    std::lock_guard<std::mutex> lock(lock_);
    PERFETTO_DCHECK(!watch_tasks_.count(fd));
    WatchTask& watch_task = watch_tasks_[fd];
    watch_task.callback = std::move(task);
#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
    watch_task.pending = false;
#else
    watch_task.poll_fd_index = SIZE_MAX;
#endif
    watch_tasks_changed_ = true;
  }
  WakeUp();
}

void UnixTaskRunner::RemoveFileDescriptorWatch(PlatformHandle fd) {
  PERFETTO_DCHECK(PlatformHandleChecker::IsValid(fd));
  {
    std::lock_guard<std::mutex> lock(lock_);
    PERFETTO_DCHECK(watch_tasks_.count(fd));
    watch_tasks_.erase(fd);
    watch_tasks_changed_ = true;
  }
  // No need to schedule a wake-up for this.
}

bool UnixTaskRunner::RunsTasksOnCurrentThread() const {
  return GetThreadId() == created_thread_id_;
}

}  // namespace base
}  // namespace perfetto
// gen_amalgamated begin source: src/base/subprocess.cc
// gen_amalgamated begin header: include/perfetto/ext/base/subprocess.h
/*
 * Copyright (C) 2020 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef INCLUDE_PERFETTO_EXT_BASE_SUBPROCESS_H_
#define INCLUDE_PERFETTO_EXT_BASE_SUBPROCESS_H_

#include <condition_variable>
#include <functional>
#include <initializer_list>
#include <mutex>
#include <optional>
#include <string>
#include <thread>
#include <vector>

// gen_amalgamated expanded: #include "perfetto/base/build_config.h"
// gen_amalgamated expanded: #include "perfetto/base/logging.h"
// gen_amalgamated expanded: #include "perfetto/base/platform_handle.h"
// gen_amalgamated expanded: #include "perfetto/base/proc_utils.h"
// gen_amalgamated expanded: #include "perfetto/ext/base/event_fd.h"
// gen_amalgamated expanded: #include "perfetto/ext/base/pipe.h"
// gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"

namespace perfetto {
namespace base {

// Handles creation and lifecycle management of subprocesses, taking care of
// all subtleties involved in handling processes on UNIX.
// This class allows to deal with macro two use-cases:
// 1) fork() + exec() equivalent: for spawning a brand new process image.
//    This happens when |args.exec_cmd| is not empty.
//    This is safe to use even in a multi-threaded environment.
// 2) fork(): for spawning a process and running a function.
//    This happens when |args.posix_entrypoint_for_testing| is not empty.
//    This is intended only for tests as it is extremely subtle.
//    This mode must be used with extreme care. Before the entrypoint is
//    invoked all file descriptors other than stdin/out/err and the ones
//    specified in |args.preserve_fds| will be closed, to avoid each process
//    retaining a dupe of other subprocesses pipes. This however means that
//    any non trivial calls (including logging) must be avoided as they might
//    refer to FDs that are now closed. The entrypoint should really be used
//    just to signal a pipe or similar for synchronizing sequencing in tests.

//
// This class allows to control stdin/out/err pipe redirection and takes care
// of keeping all the pipes pumped (stdin) / drained (stdout/err), in a similar
// fashion of python's subprocess.Communicate()
// stdin: is always piped and closed once the |args.input| buffer is written.
// stdout/err can be either:
//   - dup()ed onto the parent process stdout/err.
//   - redirected onto /dev/null.
//   - piped onto a buffer (see output() method). There is only one output
//     buffer in total. If both stdout and stderr are set to kBuffer mode, they
//     will be merged onto the same. There doesn't seem any use case where they
//     are needed distinctly.
//
// Some caveats worth mentioning:
// - It always waitpid()s, to avoid leaving zombies around. If the process is
//   not terminated by the time the destructor is reached, the dtor will
//   send a SIGKILL and wait for the termination.
// - After fork()-ing it will close all file descriptors, preserving only
//   stdin/out/err and the fds listed in |args.preserve_fds|.
// - On Linux/Android, the child process will be SIGKILL-ed if the calling
//   thread exists, even if the Subprocess is std::move()-d onto another thread.
//   This happens by virtue PR_SET_PDEATHSIG, which is used to avoid that
//   child processes are leaked in the case of a crash of the parent (frequent
//   in tests). However, the child process might still be leaked if execing
//   a setuid/setgid binary (see man 2 prctl).
//
// Usage:
// base::Subprocess p({"/bin/cat", "-"});
// (or equivalently:
//     base::Subprocess p;
//     p.args.exec_cmd.push_back("/bin/cat");
//     p.args.exec_cmd.push_back("-");
//  )
// p.args.stdout_mode = base::Subprocess::kBuffer;
// p.args.stderr_mode = base::Subprocess::kInherit;
// p.args.input = "stdin contents";
// p.Call();
// (or equivalently:
//     p.Start();
//     p.Wait();
// )
// EXPECT_EQ(p.status(), base::Subprocess::kTerminated);
// EXPECT_EQ(p.returncode(), 0);
class Subprocess {
 public:
  enum Status {
    kNotStarted = 0,  // Before calling Start() or Call().
    kRunning,         // After calling Start(), before Wait().
    kTerminated,      // The subprocess terminated, either successfully or not.
                      // This includes crashes or other signals on UNIX.
  };

  enum class OutputMode {
    kInherit = 0,  // Inherit's the caller process stdout/stderr.
    kDevNull,      // dup() onto /dev/null.
    kBuffer,       // dup() onto a pipe and move it into the output() buffer.
    kFd,           // dup() onto the passed args.fd.
  };

  enum class InputMode {
    kBuffer = 0,  // dup() onto a pipe and write args.input on it.
    kDevNull,     // dup() onto /dev/null.
  };

  // Input arguments for configuring the subprocess behavior.
  struct Args {
    Args(std::initializer_list<std::string> _cmd = {}) : exec_cmd(_cmd) {}
    Args(Args&&) noexcept;
    Args& operator=(Args&&);
    // If non-empty this will cause an exec() when Start()/Call() are called.
    std::vector<std::string> exec_cmd;

#if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
    // If non-empty, it changes the argv[0] argument passed to exec. If
    // unset, argv[0] == exec_cmd[0]. This is to handle cases like:
    // exec_cmd = {"/proc/self/exec"}, argv0: "my_custom_test_override".
    std::string posix_argv0_override_for_testing;

    // If non-empty this will be invoked on the fork()-ed child process, after
    // stdin/out/err has been redirected and all other file descriptor are
    // closed. It is valid to specify both |exec_cmd| AND
    // |posix_entrypoint_for_testing|. In this case the latter will be invoked
    // just before the exec() call, but after having closed all fds % stdin/o/e.
    // This is for synchronization barriers in tests.
    std::function<void()> posix_entrypoint_for_testing;

    // When set, will will move the process to the given process group. If set
    // and zero, it will create a new process group. Effectively this calls
    // setpgid(0 /*self_pid*/, posix_proc_group_id).
    // This can be used to avoid that subprocesses receive CTRL-C from the
    // terminal, while still living in the same session.
    std::optional<pid_t> posix_proc_group_id{};
#endif

    // If non-empty, replaces the environment passed to exec().
    std::vector<std::string> env;

    // The file descriptors in this list will not be closed.
    std::vector<int> preserve_fds;

    // The data to push in the child process stdin, if input_mode ==
    // InputMode::kBuffer.
    std::string input;

    InputMode stdin_mode = InputMode::kBuffer;
    OutputMode stdout_mode = OutputMode::kInherit;
    OutputMode stderr_mode = OutputMode::kInherit;

    base::ScopedPlatformHandle out_fd;

    // Returns " ".join(exec_cmd), quoting arguments.
    std::string GetCmdString() const;
  };

  struct ResourceUsage {
    uint32_t cpu_utime_ms = 0;
    uint32_t cpu_stime_ms = 0;
    uint32_t max_rss_kb = 0;
    uint32_t min_page_faults = 0;
    uint32_t maj_page_faults = 0;
    uint32_t vol_ctx_switch = 0;
    uint32_t invol_ctx_switch = 0;

    uint32_t cpu_time_ms() const { return cpu_utime_ms + cpu_stime_ms; }
  };

  explicit Subprocess(std::initializer_list<std::string> exec_cmd = {});
  Subprocess(Subprocess&&) noexcept;
  Subprocess& operator=(Subprocess&&);
  ~Subprocess();  // It will KillAndWaitForTermination() if still alive.

  // Starts the subprocess but doesn't wait for its termination. The caller
  // is expected to either call Wait() or Poll() after this call.
  void Start();

  // Wait for process termination. Can be called more than once.
  // Args:
  //   |timeout_ms| = 0: wait indefinitely.
  //   |timeout_ms| > 0: wait for at most |timeout_ms|.
  // Returns:
  //  True: The process terminated. See status() and returncode().
  //  False: Timeout reached, the process is still running. In this case the
  //         process will be left in the kRunning state.
  bool Wait(int timeout_ms = 0);

  // Equivalent of Start() + Wait();
  // Returns true if the process exited cleanly with return code 0. False in
  // any othe case.
  bool Call(int timeout_ms = 0);

  Status Poll();

  // Sends a signal (SIGKILL if not specified) and wait for process termination.
  void KillAndWaitForTermination(int sig_num = 0);

  PlatformProcessId pid() const { return s_->pid; }

  // The accessors below are updated only after a call to Poll(), Wait() or
  // KillAndWaitForTermination().
  // In most cases you want to call Poll() rather than these accessors.

  Status status() const { return s_->status; }
  int returncode() const { return s_->returncode; }
  bool timed_out() const { return s_->timed_out; }

  // This contains both stdout and stderr (if the corresponding _mode ==
  // OutputMode::kBuffer). It's non-const so the caller can std::move() it.
  std::string& output() { return s_->output; }
  const std::string& output() const { return s_->output; }

  const ResourceUsage& posix_rusage() const { return *s_->rusage; }

  Args args;

 private:
  // The signal/exit code used when killing the process in case of a timeout.
  static const int kTimeoutSignal;

  Subprocess(const Subprocess&) = delete;
  Subprocess& operator=(const Subprocess&) = delete;

  // This is to deal robustly with the move operators, without having to
  // manually maintain member-wise move instructions.
  struct MovableState {
    base::Pipe stdin_pipe;
    base::Pipe stdouterr_pipe;
    PlatformProcessId pid;
    Status status = kNotStarted;
    int returncode = -1;
    std::string output;  // Stdin+stderr. Only when OutputMode::kBuffer.
    std::unique_ptr<ResourceUsage> rusage{new ResourceUsage()};
    bool timed_out = false;
#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
    std::thread stdouterr_thread;
    std::thread stdin_thread;
    ScopedPlatformHandle win_proc_handle;
    ScopedPlatformHandle win_thread_handle;

    base::EventFd stdouterr_done_event;
    std::mutex mutex;  // Protects locked_outerr_buf and the two pipes.
    std::string locked_outerr_buf;
#else
    base::Pipe exit_status_pipe;
    size_t input_written = 0;
    std::thread waitpid_thread;
#endif
  };

#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
  static void StdinThread(MovableState*, std::string input);
  static void StdoutErrThread(MovableState*);
#else
  void TryPushStdin();
  void TryReadStdoutAndErr();
  void TryReadExitStatus();
  bool PollInternal(int poll_timeout_ms);
#endif

  std::unique_ptr<MovableState> s_;
};

}  // namespace base
}  // namespace perfetto

#endif  // INCLUDE_PERFETTO_EXT_BASE_SUBPROCESS_H_
/*
 * Copyright (C) 2020 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// gen_amalgamated expanded: #include "perfetto/ext/base/subprocess.h"

#include <tuple>

// This file contains only the common bits (ctors / dtors / move operators).
// The rest lives in subprocess_posix.cc and subprocess_windows.cc.

namespace perfetto {
namespace base {

Subprocess::Args::Args(Args&&) noexcept = default;
Subprocess::Args& Subprocess::Args::operator=(Args&&) = default;

Subprocess::Subprocess(std::initializer_list<std::string> a)
    : args(a), s_(new MovableState()) {}

Subprocess::Subprocess(Subprocess&& other) noexcept {
  static_assert(sizeof(Subprocess) ==
                    sizeof(std::tuple<std::unique_ptr<MovableState>, Args>),
                "base::Subprocess' move ctor needs updating");
  s_ = std::move(other.s_);
  args = std::move(other.args);

  // Reset the state of the moved-from object.
  other.s_.reset(new MovableState());
  other.~Subprocess();
  new (&other) Subprocess();
}

Subprocess& Subprocess::operator=(Subprocess&& other) {
  this->~Subprocess();
  new (this) Subprocess(std::move(other));
  return *this;
}

Subprocess::~Subprocess() {
  if (s_->status == kRunning)
    KillAndWaitForTermination();
}

bool Subprocess::Call(int timeout_ms) {
  PERFETTO_CHECK(s_->status == kNotStarted);
  Start();

  if (!Wait(timeout_ms)) {
    s_->timed_out = true;
    KillAndWaitForTermination(kTimeoutSignal);
  }
  PERFETTO_DCHECK(s_->status != kRunning);
  return s_->status == kTerminated && s_->returncode == 0;
}

std::string Subprocess::Args::GetCmdString() const {
  std::string str;
  for (size_t i = 0; i < exec_cmd.size(); i++) {
    str += i > 0 ? " \"" : "";
    str += exec_cmd[i];
    str += i > 0 ? "\"" : "";
  }
  return str;
}

}  // namespace base
}  // namespace perfetto
// gen_amalgamated begin source: src/base/subprocess_posix.cc
/*
 * Copyright (C) 2020 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// gen_amalgamated expanded: #include "perfetto/ext/base/subprocess.h"

// gen_amalgamated expanded: #include "perfetto/base/build_config.h"

#if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) ||   \
    PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \
    PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)

#include <fcntl.h>
#include <poll.h>
#include <signal.h>
#include <stdio.h>
#include <sys/resource.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>

#include <algorithm>
#include <thread>
#include <tuple>

#if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
    PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
#include <sys/prctl.h>
#endif

// gen_amalgamated expanded: #include "perfetto/base/logging.h"
// gen_amalgamated expanded: #include "perfetto/base/time.h"
// gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"

// In MacOS this is not defined in any header.
extern "C" char** environ;

namespace perfetto {
namespace base {

namespace {

struct ChildProcessArgs {
  Subprocess::Args* create_args;
  const char* exec_cmd = nullptr;
  std::vector<char*> argv;
  std::vector<char*> env;
  int stdin_pipe_rd = -1;
  int stdouterr_pipe_wr = -1;
};

// Don't add any dynamic allocation in this function. This will be invoked
// under a fork(), potentially in a state where the allocator lock is held.
void __attribute__((noreturn)) ChildProcess(ChildProcessArgs* args) {
#if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
    PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
  // In no case we want a child process to outlive its parent process. This is
  // relevant for tests, so that a test failure/crash doesn't leave child
  // processes around that get reparented to init.
  prctl(PR_SET_PDEATHSIG, SIGKILL);
#endif

  auto die = [args](const char* err) __attribute__((noreturn)) {
    base::ignore_result(write(args->stdouterr_pipe_wr, err, strlen(err)));
    base::ignore_result(write(args->stdouterr_pipe_wr, "\n", 1));
    // From https://www.gnu.org/software/libc/manual/html_node/Exit-Status.html
    // "In particular, the value 128 is used to indicate failure to execute
    // another program in a subprocess. This convention is not universally
    // obeyed, but it is a good idea to follow it in your programs."
    _exit(128);
  };

  if (args->create_args->posix_proc_group_id.has_value()) {
    if (setpgid(0 /*self*/, args->create_args->posix_proc_group_id.value())) {
      die("setpgid() failed");
    }
  }

  auto set_fd_close_on_exec = [&die](int fd, bool close_on_exec) {
    int flags = fcntl(fd, F_GETFD, 0);
    if (flags < 0)
      die("fcntl(F_GETFD) failed");
    flags = close_on_exec ? (flags | FD_CLOEXEC) : (flags & ~FD_CLOEXEC);
    if (fcntl(fd, F_SETFD, flags) < 0)
      die("fcntl(F_SETFD) failed");
  };

  if (getppid() == 1)
    die("terminating because parent process died");

  switch (args->create_args->stdin_mode) {
    case Subprocess::InputMode::kBuffer:
      if (dup2(args->stdin_pipe_rd, STDIN_FILENO) == -1)
        die("Failed to dup2(STDIN)");
      close(args->stdin_pipe_rd);
      break;
    case Subprocess::InputMode::kDevNull:
      if (dup2(open("/dev/null", O_RDONLY), STDIN_FILENO) == -1)
        die("Failed to dup2(STDOUT)");
      break;
  }

  switch (args->create_args->stdout_mode) {
    case Subprocess::OutputMode::kInherit:
      break;
    case Subprocess::OutputMode::kDevNull: {
      if (dup2(open("/dev/null", O_RDWR), STDOUT_FILENO) == -1)
        die("Failed to dup2(STDOUT)");
      break;
    }
    case Subprocess::OutputMode::kBuffer:
      if (dup2(args->stdouterr_pipe_wr, STDOUT_FILENO) == -1)
        die("Failed to dup2(STDOUT)");
      break;
    case Subprocess::OutputMode::kFd:
      if (dup2(*args->create_args->out_fd, STDOUT_FILENO) == -1)
        die("Failed to dup2(STDOUT)");
      break;
  }

  switch (args->create_args->stderr_mode) {
    case Subprocess::OutputMode::kInherit:
      break;
    case Subprocess::OutputMode::kDevNull: {
      if (dup2(open("/dev/null", O_RDWR), STDERR_FILENO) == -1)
        die("Failed to dup2(STDERR)");
      break;
    }
    case Subprocess::OutputMode::kBuffer:
      if (dup2(args->stdouterr_pipe_wr, STDERR_FILENO) == -1)
        die("Failed to dup2(STDERR)");
      break;
    case Subprocess::OutputMode::kFd:
      if (dup2(*args->create_args->out_fd, STDERR_FILENO) == -1)
        die("Failed to dup2(STDERR)");
      break;
  }

  // Close all FDs % stdin/out/err and the ones that the client explicitly
  // asked to retain. The reason for this is twofold:
  // 1. For exec-only (i.e. entrypoint == empty) cases: it avoids leaking FDs
  //    that didn't get marked as O_CLOEXEC by accident.
  // 2. In fork() mode (entrypoint not empty) avoids retaining a dup of eventfds
  //    that would prevent the parent process to receive EOFs (tests usually use
  //    pipes as a synchronization mechanism between subprocesses).
  const auto& preserve_fds = args->create_args->preserve_fds;
  for (int i = 0; i < 512; i++) {
    if (i != STDIN_FILENO && i != STDERR_FILENO && i != STDOUT_FILENO &&
        i != args->stdouterr_pipe_wr &&
        !std::count(preserve_fds.begin(), preserve_fds.end(), i)) {
      close(i);
    }
  }

  // Clears O_CLOEXEC from stdin/out/err and the |preserve_fds| list. These are
  // the only FDs that we want to be preserved after the exec().
  set_fd_close_on_exec(STDIN_FILENO, false);
  set_fd_close_on_exec(STDOUT_FILENO, false);
  set_fd_close_on_exec(STDERR_FILENO, false);

  for (auto fd : preserve_fds)
    set_fd_close_on_exec(fd, false);

  // If the caller specified a std::function entrypoint, run that first.
  if (args->create_args->posix_entrypoint_for_testing)
    args->create_args->posix_entrypoint_for_testing();

  // If the caller specified only an entrypoint, without any args, exit now.
  // Otherwise proceed with the exec() below.
  if (!args->exec_cmd)
    _exit(0);

  // If |args[0]| is a path use execv() (which takes a path), othewise use
  // exevp(), which uses the shell and follows PATH.
  if (strchr(args->exec_cmd, '/')) {
    char** env = args->env.empty() ? environ : args->env.data();
    execve(args->exec_cmd, args->argv.data(), env);
  } else {
    // There is no execvpe() on Mac.
    if (!args->env.empty())
      die("A full path is required for |exec_cmd| when setting |env|");
    execvp(args->exec_cmd, args->argv.data());
  }

  // Reached only if execv fails.
  die("execve() failed");
}

}  // namespace

// static
const int Subprocess::kTimeoutSignal = SIGKILL;

void Subprocess::Start() {
  ChildProcessArgs proc_args;
  proc_args.create_args = &args;

  // Setup argv.
  if (!args.exec_cmd.empty()) {
    proc_args.exec_cmd = args.exec_cmd[0].c_str();
    for (const std::string& arg : args.exec_cmd)
      proc_args.argv.push_back(const_cast<char*>(arg.c_str()));
    proc_args.argv.push_back(nullptr);

    if (!args.posix_argv0_override_for_testing.empty()) {
      proc_args.argv[0] =
          const_cast<char*>(args.posix_argv0_override_for_testing.c_str());
    }
  }

  // Setup env.
  if (!args.env.empty()) {
    for (const std::string& str : args.env)
      proc_args.env.push_back(const_cast<char*>(str.c_str()));
    proc_args.env.push_back(nullptr);
  }

  // Setup the pipes for stdin/err redirection.
  if (args.stdin_mode == InputMode::kBuffer) {
    s_->stdin_pipe = base::Pipe::Create(base::Pipe::kWrNonBlock);
    proc_args.stdin_pipe_rd = *s_->stdin_pipe.rd;
  }
  s_->stdouterr_pipe = base::Pipe::Create(base::Pipe::kRdNonBlock);
  proc_args.stdouterr_pipe_wr = *s_->stdouterr_pipe.wr;

  // Spawn the child process that will exec().
  s_->pid = fork();
  PERFETTO_CHECK(s_->pid >= 0);
  if (s_->pid == 0) {
    // Close the parent-ends of the pipes.
    s_->stdin_pipe.wr.reset();
    s_->stdouterr_pipe.rd.reset();
    ChildProcess(&proc_args);
    // ChildProcess() doesn't return, not even in case of failures.
    PERFETTO_FATAL("not reached");
  }

  s_->status = kRunning;

  // Close the child-end of the pipes.
  // Deliberately NOT closing the s_->stdin_pipe.rd. This is to avoid crashing
  // with a SIGPIPE if the process exits without consuming its stdin, while
  // the parent tries to write() on the other end of the stdin pipe.
  s_->stdouterr_pipe.wr.reset();
  proc_args.create_args->out_fd.reset();

  // Spawn a thread that is blocked on waitpid() and writes the termination
  // status onto a pipe. The problem here is that waipid() doesn't have a
  // timeout option and can't be passed to poll(). The alternative would be
  // using a SIGCHLD handler, but anecdotally signal handlers introduce more
  // problems than what they solve.
  s_->exit_status_pipe = base::Pipe::Create(base::Pipe::kRdNonBlock);

  // Both ends of the pipe are closed after the thread.join().
  int pid = s_->pid;
  int exit_status_pipe_wr = s_->exit_status_pipe.wr.release();
  auto* rusage = s_->rusage.get();
  s_->waitpid_thread = std::thread([pid, exit_status_pipe_wr, rusage] {
    int pid_stat = -1;
    struct rusage usg {};
    int wait_res = PERFETTO_EINTR(wait4(pid, &pid_stat, 0, &usg));
    PERFETTO_CHECK(wait_res == pid);

    auto tv_to_ms = [](const struct timeval& tv) {
      return static_cast<uint32_t>(tv.tv_sec * 1000 + tv.tv_usec / 1000);
    };
    rusage->cpu_utime_ms = tv_to_ms(usg.ru_utime);
    rusage->cpu_stime_ms = tv_to_ms(usg.ru_stime);
    rusage->max_rss_kb = static_cast<uint32_t>(usg.ru_maxrss) / 1000;
    rusage->min_page_faults = static_cast<uint32_t>(usg.ru_minflt);
    rusage->maj_page_faults = static_cast<uint32_t>(usg.ru_majflt);
    rusage->vol_ctx_switch = static_cast<uint32_t>(usg.ru_nvcsw);
    rusage->invol_ctx_switch = static_cast<uint32_t>(usg.ru_nivcsw);

    base::ignore_result(PERFETTO_EINTR(
        write(exit_status_pipe_wr, &pid_stat, sizeof(pid_stat))));
    PERFETTO_CHECK(close(exit_status_pipe_wr) == 0 || errno == EINTR);
  });
}

Subprocess::Status Subprocess::Poll() {
  if (s_->status != kRunning)
    return s_->status;  // Nothing to poll.
  while (PollInternal(0 /* don't block*/)) {
  }
  return s_->status;
}

// |timeout_ms| semantic:
//   -1: Block indefinitely.
//    0: Don't block, return immediately.
//   >0: Block for at most X ms.
// Returns:
//  True: Read at least one fd (so there might be more queued).
//  False: if all fds reached quiescent (no data to read/write).
bool Subprocess::PollInternal(int poll_timeout_ms) {
  struct pollfd fds[3]{};
  size_t num_fds = 0;
  if (s_->exit_status_pipe.rd) {
    fds[num_fds].fd = *s_->exit_status_pipe.rd;
    fds[num_fds].events = POLLIN;
    num_fds++;
  }
  if (s_->stdouterr_pipe.rd) {
    fds[num_fds].fd = *s_->stdouterr_pipe.rd;
    fds[num_fds].events = POLLIN;
    num_fds++;
  }
  if (s_->stdin_pipe.wr) {
    fds[num_fds].fd = *s_->stdin_pipe.wr;
    fds[num_fds].events = POLLOUT;
    num_fds++;
  }

  if (num_fds == 0)
    return false;

  auto nfds = static_cast<nfds_t>(num_fds);
  int poll_res = PERFETTO_EINTR(poll(fds, nfds, poll_timeout_ms));
  PERFETTO_CHECK(poll_res >= 0);

  TryReadStdoutAndErr();
  TryPushStdin();
  TryReadExitStatus();

  return poll_res > 0;
}

bool Subprocess::Wait(int timeout_ms) {
  PERFETTO_CHECK(s_->status != kNotStarted);

  // Break out of the loop only after both conditions are satisfied:
  // - All stdout/stderr data has been read (if kBuffer).
  // - The process exited.
  // Note that the two events can happen arbitrary order. After the process
  // exits, there might be still data in the pipe buffer, which we want to
  // read fully.
  //
  // Instead, don't wait on the stdin to be fully written. The child process
  // might exit prematurely (or crash). If that happens, we can end up in a
  // state where the write(stdin_pipe_.wr) will never unblock.

  const int64_t t_start = base::GetWallTimeMs().count();
  while (s_->exit_status_pipe.rd || s_->stdouterr_pipe.rd) {
    int poll_timeout_ms = -1;  // Block until a FD is ready.
    if (timeout_ms > 0) {
      const int64_t now = GetWallTimeMs().count();
      poll_timeout_ms = timeout_ms - static_cast<int>(now - t_start);
      if (poll_timeout_ms <= 0)
        return false;
    }
    PollInternal(poll_timeout_ms);
  }  // while(...)
  return true;
}

void Subprocess::TryReadExitStatus() {
  if (!s_->exit_status_pipe.rd)
    return;

  int pid_stat = -1;
  int64_t rsize = PERFETTO_EINTR(
      read(*s_->exit_status_pipe.rd, &pid_stat, sizeof(pid_stat)));
  if (rsize < 0 && errno == EAGAIN)
    return;

  if (rsize > 0) {
    PERFETTO_CHECK(rsize == sizeof(pid_stat));
  } else if (rsize < 0) {
    PERFETTO_PLOG("Subprocess read(s_->exit_status_pipe) failed");
  }
  s_->waitpid_thread.join();
  s_->exit_status_pipe.rd.reset();

  s_->status = kTerminated;
  if (WIFEXITED(pid_stat)) {
    s_->returncode = WEXITSTATUS(pid_stat);
  } else if (WIFSIGNALED(pid_stat)) {
    s_->returncode = 128 + WTERMSIG(pid_stat);  // Follow bash convention.
  } else {
    PERFETTO_FATAL("waitpid() returned an unexpected value (0x%x)", pid_stat);
  }
}

// If the stidn pipe is still open, push input data and close it at the end.
void Subprocess::TryPushStdin() {
  if (!s_->stdin_pipe.wr)
    return;

  PERFETTO_DCHECK(args.input.empty() || s_->input_written < args.input.size());
  if (!args.input.empty()) {
    int64_t wsize =
        PERFETTO_EINTR(write(*s_->stdin_pipe.wr, &args.input[s_->input_written],
                             args.input.size() - s_->input_written));
    if (wsize < 0 && errno == EAGAIN)
      return;

    if (wsize >= 0) {
      // Whether write() can return 0 is one of the greatest mysteries of UNIX.
      // Just ignore it.
      s_->input_written += static_cast<size_t>(wsize);
    } else {
      PERFETTO_PLOG("Subprocess write(stdin) failed");
      s_->stdin_pipe.wr.reset();
    }
  }
  PERFETTO_DCHECK(s_->input_written <= args.input.size());
  if (s_->input_written == args.input.size())
    s_->stdin_pipe.wr.reset();  // Close stdin.
}

void Subprocess::TryReadStdoutAndErr() {
  if (!s_->stdouterr_pipe.rd)
    return;
  char buf[4096];
  int64_t rsize =
      PERFETTO_EINTR(read(*s_->stdouterr_pipe.rd, buf, sizeof(buf)));
  if (rsize < 0 && errno == EAGAIN)
    return;

  if (rsize > 0) {
    s_->output.append(buf, static_cast<size_t>(rsize));
  } else if (rsize == 0 /* EOF */) {
    s_->stdouterr_pipe.rd.reset();
  } else {
    PERFETTO_PLOG("Subprocess read(stdout/err) failed");
    s_->stdouterr_pipe.rd.reset();
  }
}

void Subprocess::KillAndWaitForTermination(int sig_num) {
  kill(s_->pid, sig_num ? sig_num : SIGKILL);
  Wait();
  // TryReadExitStatus must have joined the thread.
  PERFETTO_DCHECK(!s_->waitpid_thread.joinable());
}

}  // namespace base
}  // namespace perfetto

#endif  // PERFETTO_OS_LINUX || PERFETTO_OS_ANDROID || PERFETTO_OS_APPLE
// gen_amalgamated begin source: src/base/subprocess_windows.cc
/*
 * Copyright (C) 2020 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// gen_amalgamated expanded: #include "perfetto/ext/base/subprocess.h"

// gen_amalgamated expanded: #include "perfetto/base/build_config.h"

#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)

#include <stdio.h>

#include <algorithm>
#include <mutex>
#include <tuple>

#include <Windows.h>

// gen_amalgamated expanded: #include "perfetto/base/logging.h"
// gen_amalgamated expanded: #include "perfetto/base/time.h"
// gen_amalgamated expanded: #include "perfetto/ext/base/pipe.h"
// gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"

namespace perfetto {
namespace base {

// static
const int Subprocess::kTimeoutSignal = static_cast<int>(STATUS_TIMEOUT);

void Subprocess::Start() {
  if (args.exec_cmd.empty()) {
    PERFETTO_ELOG("Subprocess.exec_cmd cannot be empty on Windows");
    return;
  }

  // Quote arguments but only when ambiguous. When quoting, CreateProcess()
  // assumes that the command is an absolute path and does not search in the
  // %PATH%. If non quoted, instead, CreateProcess() tries both. This is to
  // allow Subprocess("cmd.exe", "/c", "shell command").
  std::string cmd;
  for (const auto& part : args.exec_cmd) {
    if (part.find(" ") != std::string::npos) {
      cmd += "\"" + part + "\" ";
    } else {
      cmd += part + " ";
    }
  }
  // Remove trailing space.
  if (!cmd.empty())
    cmd.resize(cmd.size() - 1);

  if (args.stdin_mode == InputMode::kBuffer) {
    s_->stdin_pipe = Pipe::Create();
    // Allow the child process to inherit the other end of the pipe.
    PERFETTO_CHECK(
        ::SetHandleInformation(*s_->stdin_pipe.rd, HANDLE_FLAG_INHERIT, 1));
  }

  if (args.stderr_mode == OutputMode::kBuffer ||
      args.stdout_mode == OutputMode::kBuffer) {
    s_->stdouterr_pipe = Pipe::Create();
    PERFETTO_CHECK(
        ::SetHandleInformation(*s_->stdouterr_pipe.wr, HANDLE_FLAG_INHERIT, 1));
  }

  ScopedPlatformHandle nul_handle;
  if (args.stderr_mode == OutputMode::kDevNull ||
      args.stdout_mode == OutputMode::kDevNull) {
    nul_handle.reset(::CreateFileA(
        "NUL", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE,
        nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr));
    PERFETTO_CHECK(::SetHandleInformation(*nul_handle, HANDLE_FLAG_INHERIT, 1));
  }

  PROCESS_INFORMATION proc_info{};
  STARTUPINFOA start_info{};
  start_info.cb = sizeof(STARTUPINFOA);

  if (args.stderr_mode == OutputMode::kInherit) {
    start_info.hStdError = ::GetStdHandle(STD_ERROR_HANDLE);
  } else if (args.stderr_mode == OutputMode::kBuffer) {
    start_info.hStdError = *s_->stdouterr_pipe.wr;
  } else if (args.stderr_mode == OutputMode::kDevNull) {
    start_info.hStdError = *nul_handle;
  } else if (args.stderr_mode == OutputMode::kFd) {
    PERFETTO_CHECK(
        ::SetHandleInformation(*args.out_fd, HANDLE_FLAG_INHERIT, 1));
    start_info.hStdError = *args.out_fd;
  } else {
    PERFETTO_CHECK(false);
  }

  if (args.stdout_mode == OutputMode::kInherit) {
    start_info.hStdOutput = ::GetStdHandle(STD_OUTPUT_HANDLE);
  } else if (args.stdout_mode == OutputMode::kBuffer) {
    start_info.hStdOutput = *s_->stdouterr_pipe.wr;
  } else if (args.stdout_mode == OutputMode::kDevNull) {
    start_info.hStdOutput = *nul_handle;
  } else if (args.stdout_mode == OutputMode::kFd) {
    PERFETTO_CHECK(
        ::SetHandleInformation(*args.out_fd, HANDLE_FLAG_INHERIT, 1));
    start_info.hStdOutput = *args.out_fd;
  } else {
    PERFETTO_CHECK(false);
  }

  if (args.stdin_mode == InputMode::kBuffer) {
    start_info.hStdInput = *s_->stdin_pipe.rd;
  } else if (args.stdin_mode == InputMode::kDevNull) {
    start_info.hStdInput = *nul_handle;
  }

  start_info.dwFlags |= STARTF_USESTDHANDLES;

  // Create the child process.
  bool success =
      ::CreateProcessA(nullptr,      // App name. Needs to be null to use PATH.
                       &cmd[0],      // Command line.
                       nullptr,      // Process security attributes.
                       nullptr,      // Primary thread security attributes.
                       true,         // Handles are inherited.
                       0,            // Flags.
                       nullptr,      // Use parent's environment.
                       nullptr,      // Use parent's current directory.
                       &start_info,  // STARTUPINFO pointer.
                       &proc_info);  // Receives PROCESS_INFORMATION.

  // Close on our side the pipe ends that we passed to the child process.
  s_->stdin_pipe.rd.reset();
  s_->stdouterr_pipe.wr.reset();
  args.out_fd.reset();

  if (!success) {
    s_->returncode = ERROR_FILE_NOT_FOUND;
    s_->status = kTerminated;
    s_->stdin_pipe.wr.reset();
    s_->stdouterr_pipe.rd.reset();
    PERFETTO_ELOG("CreateProcess failed: %lx, cmd: %s", GetLastError(),
                  &cmd[0]);
    return;
  }

  s_->pid = proc_info.dwProcessId;
  s_->win_proc_handle = ScopedPlatformHandle(proc_info.hProcess);
  s_->win_thread_handle = ScopedPlatformHandle(proc_info.hThread);
  s_->status = kRunning;

  MovableState* s = s_.get();
  if (args.stdin_mode == InputMode::kBuffer) {
    s_->stdin_thread = std::thread(&Subprocess::StdinThread, s, args.input);
  }

  if (args.stderr_mode == OutputMode::kBuffer ||
      args.stdout_mode == OutputMode::kBuffer) {
    PERFETTO_DCHECK(s_->stdouterr_pipe.rd);
    s_->stdouterr_thread = std::thread(&Subprocess::StdoutErrThread, s);
  }
}

// static
void Subprocess::StdinThread(MovableState* s, std::string input) {
  size_t input_written = 0;
  while (input_written < input.size()) {
    DWORD wsize = 0;
    if (::WriteFile(*s->stdin_pipe.wr, input.data() + input_written,
                    static_cast<DWORD>(input.size() - input_written), &wsize,
                    nullptr)) {
      input_written += wsize;
    } else {
      // ERROR_BROKEN_PIPE is WAI when the child just closes stdin and stops
      // accepting input.
      auto err = ::GetLastError();
      if (err != ERROR_BROKEN_PIPE)
        PERFETTO_PLOG("Subprocess WriteFile(stdin) failed %lx", err);
      break;
    }
  }  // while(...)
  std::unique_lock<std::mutex> lock(s->mutex);
  s->stdin_pipe.wr.reset();
}

// static
void Subprocess::StdoutErrThread(MovableState* s) {
  char buf[4096];
  for (;;) {
    DWORD rsize = 0;
    bool res =
        ::ReadFile(*s->stdouterr_pipe.rd, buf, sizeof(buf), &rsize, nullptr);
    if (!res) {
      auto err = GetLastError();
      if (err != ERROR_BROKEN_PIPE)
        PERFETTO_PLOG("Subprocess ReadFile(stdouterr) failed %ld", err);
    }

    if (rsize > 0) {
      std::unique_lock<std::mutex> lock(s->mutex);
      s->locked_outerr_buf.append(buf, static_cast<size_t>(rsize));
    } else {  // EOF or some error.
      break;
    }
  }  // For(..)

  // Close the stdouterr_pipe. The main loop looks at the pipe closure to
  // determine whether the stdout/err thread has completed.
  {
    std::unique_lock<std::mutex> lock(s->mutex);
    s->stdouterr_pipe.rd.reset();
  }
  s->stdouterr_done_event.Notify();
}

Subprocess::Status Subprocess::Poll() {
  if (s_->status != kRunning)
    return s_->status;  // Nothing to poll.
  Wait(1 /*ms*/);
  return s_->status;
}

bool Subprocess::Wait(int timeout_ms) {
  PERFETTO_CHECK(s_->status != kNotStarted);
  const bool wait_forever = timeout_ms == 0;
  const int64_t wait_start_ms = base::GetWallTimeMs().count();

  // Break out of the loop only after both conditions are satisfied:
  // - All stdout/stderr data has been read (if OutputMode::kBuffer).
  // - The process exited.
  // Note that the two events can happen arbitrary order. After the process
  // exits, there might be still data in the pipe buffer, which we want to
  // read fully.
  // Note also that stdout/err might be "complete" before starting, if neither
  // is operating in OutputMode::kBuffer mode. In that case we just want to wait
  // for the process termination.
  //
  // Instead, don't wait on the stdin to be fully written. The child process
  // might exit prematurely (or crash). If that happens, we can end up in a
  // state where the write(stdin_pipe_.wr) will never unblock.
  bool stdouterr_complete = false;
  for (;;) {
    HANDLE wait_handles[2]{};
    DWORD num_handles = 0;

    // Check if the process exited.
    bool process_exited = !s_->win_proc_handle;
    if (!process_exited) {
      DWORD exit_code = STILL_ACTIVE;
      PERFETTO_CHECK(::GetExitCodeProcess(*s_->win_proc_handle, &exit_code));
      if (exit_code != STILL_ACTIVE) {
        s_->returncode = static_cast<int>(exit_code);
        s_->status = kTerminated;
        s_->win_proc_handle.reset();
        s_->win_thread_handle.reset();
        process_exited = true;
      }
    } else {
      PERFETTO_DCHECK(s_->status != kRunning);
    }
    if (!process_exited) {
      wait_handles[num_handles++] = *s_->win_proc_handle;
    }

    // Check if there is more output and if the stdout/err pipe has been closed.
    {
      std::unique_lock<std::mutex> lock(s_->mutex);
      // Move the output from the internal buffer shared with the
      // stdouterr_thread to the final buffer exposed to the client.
      if (!s_->locked_outerr_buf.empty()) {
        s_->output.append(std::move(s_->locked_outerr_buf));
        s_->locked_outerr_buf.clear();
      }
      stdouterr_complete = !s_->stdouterr_pipe.rd;
      if (!stdouterr_complete) {
        wait_handles[num_handles++] = s_->stdouterr_done_event.fd();
      }
    }  // lock(s_->mutex)

    if (num_handles == 0) {
      PERFETTO_DCHECK(process_exited && stdouterr_complete);
      break;
    }

    DWORD wait_ms;  // Note: DWORD is unsigned.
    if (wait_forever) {
      wait_ms = INFINITE;
    } else {
      const int64_t now = GetWallTimeMs().count();
      const int64_t wait_left_ms = timeout_ms - (now - wait_start_ms);
      if (wait_left_ms <= 0)
        return false;  // Timed out
      wait_ms = static_cast<DWORD>(wait_left_ms);
    }

    auto wait_res =
        ::WaitForMultipleObjects(num_handles, wait_handles, false, wait_ms);
    PERFETTO_CHECK(wait_res != WAIT_FAILED);
  }

  PERFETTO_DCHECK(!s_->win_proc_handle);
  PERFETTO_DCHECK(!s_->win_thread_handle);

  if (s_->stdin_thread.joinable())  // Might not exist if CreateProcess failed.
    s_->stdin_thread.join();
  if (s_->stdouterr_thread.joinable())
    s_->stdouterr_thread.join();

  // The stdin pipe is closed by the dedicated stdin thread. However if that is
  // not started (e.g. because of no redirection) force close it now. Needs to
  // happen after the join() to be thread safe.
  s_->stdin_pipe.wr.reset();
  s_->stdouterr_pipe.rd.reset();

  return true;
}

void Subprocess::KillAndWaitForTermination(int exit_code) {
  auto code = exit_code ? static_cast<DWORD>(exit_code) : STATUS_CONTROL_C_EXIT;
  ::TerminateProcess(*s_->win_proc_handle, code);
  Wait();
  // TryReadExitStatus must have joined the threads.
  PERFETTO_DCHECK(!s_->stdin_thread.joinable());
  PERFETTO_DCHECK(!s_->stdouterr_thread.joinable());
}

}  // namespace base
}  // namespace perfetto

#endif  // PERFETTO_OS_WIN
// gen_amalgamated begin source: src/protozero/field.cc
/*
 * Copyright (C) 2019 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// gen_amalgamated expanded: #include "perfetto/protozero/field.h"

// gen_amalgamated expanded: #include "perfetto/base/compiler.h"
// gen_amalgamated expanded: #include "perfetto/base/logging.h"

#if !PERFETTO_IS_LITTLE_ENDIAN()
// The memcpy() for fixed32/64 below needs to be adjusted if we want to
// support big endian CPUs. There doesn't seem to be a compelling need today.
#error Unimplemented for big endian archs.
#endif

namespace protozero {

template <typename Container>
void Field::SerializeAndAppendToInternal(Container* dst) const {
  namespace pu = proto_utils;
  size_t initial_size = dst->size();
  dst->resize(initial_size + pu::kMaxSimpleFieldEncodedSize + size_);
  uint8_t* start = reinterpret_cast<uint8_t*>(&(*dst)[initial_size]);
  uint8_t* wptr = start;
  switch (type_) {
    case static_cast<int>(pu::ProtoWireType::kVarInt): {
      wptr = pu::WriteVarInt(pu::MakeTagVarInt(id_), wptr);
      wptr = pu::WriteVarInt(int_value_, wptr);
      break;
    }
    case static_cast<int>(pu::ProtoWireType::kFixed32): {
      wptr = pu::WriteVarInt(pu::MakeTagFixed<uint32_t>(id_), wptr);
      uint32_t value32 = static_cast<uint32_t>(int_value_);
      memcpy(wptr, &value32, sizeof(value32));
      wptr += sizeof(uint32_t);
      break;
    }
    case static_cast<int>(pu::ProtoWireType::kFixed64): {
      wptr = pu::WriteVarInt(pu::MakeTagFixed<uint64_t>(id_), wptr);
      memcpy(wptr, &int_value_, sizeof(int_value_));
      wptr += sizeof(uint64_t);
      break;
    }
    case static_cast<int>(pu::ProtoWireType::kLengthDelimited): {
      ConstBytes payload = as_bytes();
      wptr = pu::WriteVarInt(pu::MakeTagLengthDelimited(id_), wptr);
      wptr = pu::WriteVarInt(payload.size, wptr);
      memcpy(wptr, payload.data, payload.size);
      wptr += payload.size;
      break;
    }
    default:
      PERFETTO_FATAL("Unknown field type %u", type_);
  }
  size_t written_size = static_cast<size_t>(wptr - start);
  PERFETTO_DCHECK(written_size > 0 && written_size < pu::kMaxMessageLength);
  PERFETTO_DCHECK(initial_size + written_size <= dst->size());
  dst->resize(initial_size + written_size);
}

void Field::SerializeAndAppendTo(std::string* dst) const {
  SerializeAndAppendToInternal(dst);
}

void Field::SerializeAndAppendTo(std::vector<uint8_t>* dst) const {
  SerializeAndAppendToInternal(dst);
}

}  // namespace protozero
// gen_amalgamated begin source: src/protozero/gen_field_helpers.cc
/*
 * Copyright (C) 2023 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"

namespace protozero {
namespace internal {
namespace gen_helpers {

void DeserializeString(const protozero::Field& field, std::string* dst) {
  field.get(dst);
}

template bool DeserializePackedRepeated<proto_utils::ProtoWireType::kVarInt,
                                        uint64_t>(const protozero::Field& field,
                                                  std::vector<uint64_t>* dst);

template bool DeserializePackedRepeated<proto_utils::ProtoWireType::kVarInt,
                                        int64_t>(const protozero::Field& field,
                                                 std::vector<int64_t>* dst);

template bool DeserializePackedRepeated<proto_utils::ProtoWireType::kVarInt,
                                        uint32_t>(const protozero::Field& field,
                                                  std::vector<uint32_t>* dst);

template bool DeserializePackedRepeated<proto_utils::ProtoWireType::kVarInt,
                                        int32_t>(const protozero::Field& field,
                                                 std::vector<int32_t>* dst);

void SerializeTinyVarInt(uint32_t field_id, bool value, Message* msg) {
  msg->AppendTinyVarInt(field_id, value);
}

template void SerializeExtendedVarInt<uint64_t>(uint32_t field_id,
                                                uint64_t value,
                                                Message* msg);

template void SerializeExtendedVarInt<uint32_t>(uint32_t field_id,
                                                uint32_t value,
                                                Message* msg);

template void SerializeFixed<double>(uint32_t field_id,
                                     double value,
                                     Message* msg);

template void SerializeFixed<float>(uint32_t field_id,
                                    float value,
                                    Message* msg);

template void SerializeFixed<uint64_t>(uint32_t field_id,
                                       uint64_t value,
                                       Message* msg);

template void SerializeFixed<int64_t>(uint32_t field_id,
                                      int64_t value,
                                      Message* msg);

template void SerializeFixed<uint32_t>(uint32_t field_id,
                                       uint32_t value,
                                       Message* msg);

template void SerializeFixed<int32_t>(uint32_t field_id,
                                      int32_t value,
                                      Message* msg);

void SerializeString(uint32_t field_id,
                     const std::string& value,
                     Message* msg) {
  msg->AppendString(field_id, value);
}

void SerializeUnknownFields(const std::string& unknown_fields, Message* msg) {
  msg->AppendRawProtoBytes(unknown_fields.data(), unknown_fields.size());
}

MessageSerializer::MessageSerializer() = default;

MessageSerializer::~MessageSerializer() = default;

std::vector<uint8_t> MessageSerializer::SerializeAsArray() {
  return msg_.SerializeAsArray();
}

std::string MessageSerializer::SerializeAsString() {
  return msg_.SerializeAsString();
}

template bool EqualsField<std::string>(const std::string&, const std::string&);

}  // namespace gen_helpers
}  // namespace internal
}  // namespace protozero
// gen_amalgamated begin source: src/protozero/message.cc
/*
 * Copyright (C) 2017 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// gen_amalgamated expanded: #include "perfetto/protozero/message.h"

#include <atomic>
#include <type_traits>

// gen_amalgamated expanded: #include "perfetto/base/compiler.h"
// gen_amalgamated expanded: #include "perfetto/base/logging.h"
// gen_amalgamated expanded: #include "perfetto/protozero/message_arena.h"
// gen_amalgamated expanded: #include "perfetto/protozero/message_handle.h"

#if !PERFETTO_IS_LITTLE_ENDIAN()
// The memcpy() for float and double below needs to be adjusted if we want to
// support big endian CPUs. There doesn't seem to be a compelling need today.
#error Unimplemented for big endian archs.
#endif

namespace protozero {

namespace {

constexpr int kBytesToCompact = proto_utils::kMessageLengthFieldSize - 1u;

#if PERFETTO_DCHECK_IS_ON()
std::atomic<uint32_t> g_generation;
#endif

}  // namespace

// Do NOT put any code in the constructor or use default initialization.
// Use the Reset() method below instead.

// This method is called to initialize both root and nested messages.
void Message::Reset(ScatteredStreamWriter* stream_writer, MessageArena* arena) {
// Older versions of libstdcxx don't have is_trivially_constructible.
#if !defined(__GLIBCXX__) || __GLIBCXX__ >= 20170516
  static_assert(std::is_trivially_constructible<Message>::value,
                "Message must be trivially constructible");
#endif

  static_assert(std::is_trivially_destructible<Message>::value,
                "Message must be trivially destructible");
  stream_writer_ = stream_writer;
  arena_ = arena;
  size_ = 0;
  size_field_ = nullptr;
  nested_message_ = nullptr;
  message_state_ = MessageState::kNotFinalized;
#if PERFETTO_DCHECK_IS_ON()
  handle_ = nullptr;
  generation_ = g_generation.fetch_add(1, std::memory_order_relaxed);
#endif
}

void Message::AppendString(uint32_t field_id, const char* str) {
  AppendBytes(field_id, str, strlen(str));
}

void Message::AppendBytes(uint32_t field_id, const void* src, size_t size) {
  PERFETTO_DCHECK(field_id);
  if (nested_message_)
    EndNestedMessage();

  PERFETTO_DCHECK(size < proto_utils::kMaxMessageLength);
  // Write the proto preamble (field id, type and length of the field).
  uint8_t buffer[proto_utils::kMaxSimpleFieldEncodedSize];
  uint8_t* pos = buffer;
  pos = proto_utils::WriteVarInt(proto_utils::MakeTagLengthDelimited(field_id),
                                 pos);
  pos = proto_utils::WriteVarInt(static_cast<uint32_t>(size), pos);
  WriteToStream(buffer, pos);

  const uint8_t* src_u8 = reinterpret_cast<const uint8_t*>(src);
  WriteToStream(src_u8, src_u8 + size);
}

size_t Message::AppendScatteredBytes(uint32_t field_id,
                                     ContiguousMemoryRange* ranges,
                                     size_t num_ranges) {
  PERFETTO_DCHECK(field_id);
  if (nested_message_)
    EndNestedMessage();

  size_t size = 0;
  for (size_t i = 0; i < num_ranges; ++i) {
    size += ranges[i].size();
  }

  PERFETTO_DCHECK(size < proto_utils::kMaxMessageLength);

  uint8_t buffer[proto_utils::kMaxSimpleFieldEncodedSize];
  uint8_t* pos = buffer;
  pos = proto_utils::WriteVarInt(proto_utils::MakeTagLengthDelimited(field_id),
                                 pos);
  pos = proto_utils::WriteVarInt(static_cast<uint32_t>(size), pos);
  WriteToStream(buffer, pos);

  for (size_t i = 0; i < num_ranges; ++i) {
    auto& range = ranges[i];
    WriteToStream(range.begin, range.end);
  }

  return size;
}

uint32_t Message::Finalize() {
  if (is_finalized())
    return size_;

  if (nested_message_)
    EndNestedMessage();

  // Write the length of the nested message a posteriori, using a leading-zero
  // redundant varint encoding. This can be nullptr for the root message, among
  // many reasons, because the TraceWriterImpl delegate is keeping track of the
  // root fragment size independently.
  if (size_field_) {
    PERFETTO_DCHECK(!is_finalized());
    PERFETTO_DCHECK(size_ < proto_utils::kMaxMessageLength);
    //
    // Normally the size of a protozero message is written with 4 bytes just
    // before the contents of the message itself:
    //
    //    size          message data
    //   [aa bb cc dd] [01 23 45 67 ...]
    //
    // We always reserve 4 bytes for the size, because the real size of the
    // message isn't known until the call to Finalize(). This is possible
    // because we can use leading zero redundant varint coding to expand any
    // size smaller than 256 MiB to 4 bytes.
    //
    // However this is wasteful for short, frequently written messages, so the
    // code below uses a 1 byte size field when possible. This is done by
    // shifting the already-written data (which should still be in the cache)
    // back by 3 bytes, resulting in this layout:
    //
    //   size  message data
    //   [aa] [01 23 45 67 ...]
    //
    // We can only do this optimization if the message is contained in a single
    // chunk (since we can't modify previously committed chunks). We can check
    // this by verifying that the size field is immediately before the message
    // in memory and is fully contained by the current chunk.
    //
    if (PERFETTO_LIKELY(size_ <= proto_utils::kMaxOneByteMessageLength &&
                        size_field_ ==
                            stream_writer_->write_ptr() - size_ -
                                proto_utils::kMessageLengthFieldSize &&
                        size_field_ >= stream_writer_->cur_range().begin)) {
      stream_writer_->Rewind(size_, kBytesToCompact);
      PERFETTO_DCHECK(size_field_ == stream_writer_->write_ptr() - size_ - 1u);
      *size_field_ = static_cast<uint8_t>(size_);
      message_state_ = MessageState::kFinalizedWithCompaction;
    } else {
      proto_utils::WriteRedundantVarInt(size_, size_field_);
      message_state_ = MessageState::kFinalized;
    }
    size_field_ = nullptr;
  } else {
    message_state_ = MessageState::kFinalized;
  }

#if PERFETTO_DCHECK_IS_ON()
  if (handle_)
    handle_->reset_message();
#endif

  return size_;
}

Message* Message::BeginNestedMessageInternal(uint32_t field_id) {
  PERFETTO_DCHECK(field_id);
  if (nested_message_)
    EndNestedMessage();

  // Write the proto preamble for the nested message.
  uint8_t data[proto_utils::kMaxTagEncodedSize];
  uint8_t* data_end = proto_utils::WriteVarInt(
      proto_utils::MakeTagLengthDelimited(field_id), data);
  WriteToStream(data, data_end);

  Message* message = arena_->NewMessage();
  message->Reset(stream_writer_, arena_);

  // The length of the nested message cannot be known upfront. So right now
  // just reserve the bytes to encode the size after the nested message is done.
  message->set_size_field(
      stream_writer_->ReserveBytes(proto_utils::kMessageLengthFieldSize));
  size_ += proto_utils::kMessageLengthFieldSize;

  nested_message_ = message;
  return message;
}

void Message::EndNestedMessage() {
  size_ += nested_message_->Finalize();
  if (nested_message_->message_state_ ==
      MessageState::kFinalizedWithCompaction) {
    size_ -= kBytesToCompact;
  }
  arena_->DeleteLastMessage(nested_message_);
  nested_message_ = nullptr;
}

}  // namespace protozero
// gen_amalgamated begin source: src/protozero/message_arena.cc
/*
 * Copyright (C) 2020 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// gen_amalgamated expanded: #include "perfetto/protozero/message_arena.h"

#include <atomic>
#include <type_traits>

// gen_amalgamated expanded: #include "perfetto/base/logging.h"
// gen_amalgamated expanded: #include "perfetto/protozero/message_handle.h"

namespace protozero {

MessageArena::MessageArena() {
  // The code below assumes that there is always at least one block.
  blocks_.emplace_front();
  static_assert(
      std::alignment_of<decltype(blocks_.front().storage[0])>::value >=
          alignof(Message),
      "MessageArea's storage is not properly aligned");
}

MessageArena::~MessageArena() = default;

Message* MessageArena::NewMessage() {
  PERFETTO_DCHECK(!blocks_.empty());  // Should never become empty.

  Block* block = &blocks_.front();
  if (PERFETTO_UNLIKELY(block->entries >= Block::kCapacity)) {
    blocks_.emplace_front();
    block = &blocks_.front();
  }
  const auto idx = block->entries++;
  void* storage = &block->storage[idx];
  PERFETTO_ASAN_UNPOISON(storage, sizeof(Message));
  return new (storage) Message();
}

void MessageArena::DeleteLastMessageInternal() {
  PERFETTO_DCHECK(!blocks_.empty());  // Should never be empty, see below.
  Block* block = &blocks_.front();
  PERFETTO_DCHECK(block->entries > 0);

  // This is the reason why there is no ~Message() call here.
  // MessageArea::Reset() (see header) also relies on dtor being trivial.
  static_assert(std::is_trivially_destructible<Message>::value,
                "Message must be trivially destructible");

  --block->entries;
  PERFETTO_ASAN_POISON(&block->storage[block->entries], sizeof(Message));

  // Don't remove the first block to avoid malloc/free calls when the root
  // message is reset. Hitting the allocator all the times is a waste of time.
  if (block->entries == 0 && std::next(blocks_.cbegin()) != blocks_.cend()) {
    blocks_.pop_front();
  }
}

}  // namespace protozero
// gen_amalgamated begin source: src/protozero/packed_repeated_fields.cc
/*
 * Copyright (C) 2017 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"

// gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"

namespace protozero {

void PackedBufferBase::GrowSlowpath() {
  size_t write_off = static_cast<size_t>(write_ptr_ - storage_begin_);
  size_t old_size = static_cast<size_t>(storage_end_ - storage_begin_);
  size_t new_size = old_size < 65536 ? (old_size * 2) : (old_size * 3 / 2);
  new_size = perfetto::base::AlignUp<4096>(new_size);
  std::unique_ptr<uint8_t[]> new_buf(new uint8_t[new_size]);
  memcpy(new_buf.get(), storage_begin_, old_size);
  heap_buf_ = std::move(new_buf);
  storage_begin_ = heap_buf_.get();
  storage_end_ = storage_begin_ + new_size;
  write_ptr_ = storage_begin_ + write_off;
}

void PackedBufferBase::Reset() {
  heap_buf_.reset();
  storage_begin_ = reinterpret_cast<uint8_t*>(&stack_buf_[0]);
  storage_end_ = reinterpret_cast<uint8_t*>(&stack_buf_[kOnStackStorageSize]);
  write_ptr_ = storage_begin_;
}

}  // namespace protozero
// gen_amalgamated begin source: src/protozero/proto_decoder.cc
/*
 * Copyright (C) 2018 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"

#include <string.h>

#include <cinttypes>
#include <limits>
#include <memory>

// gen_amalgamated expanded: #include "perfetto/base/compiler.h"
// gen_amalgamated expanded: #include "perfetto/base/logging.h"
// gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"

namespace protozero {

using namespace proto_utils;

#if !PERFETTO_IS_LITTLE_ENDIAN()
#error Unimplemented for big endian archs.
#endif

namespace {

struct ParseFieldResult {
  enum ParseResult { kAbort, kSkip, kOk };
  ParseResult parse_res;
  const uint8_t* next;
  Field field;
};

// Parses one field and returns the field itself and a pointer to the next
// field to parse. If parsing fails, the returned |next| == |buffer|.
ParseFieldResult ParseOneField(const uint8_t* const buffer,
                               const uint8_t* const end) {
  ParseFieldResult res{ParseFieldResult::kAbort, buffer, Field{}};

  // The first byte of a proto field is structured as follows:
  // The least 3 significant bits determine the field type.
  // The most 5 significant bits determine the field id. If MSB == 1, the
  // field id continues on the next bytes following the VarInt encoding.
  const uint8_t kFieldTypeNumBits = 3;
  const uint64_t kFieldTypeMask = (1 << kFieldTypeNumBits) - 1;  // 0000 0111;
  const uint8_t* pos = buffer;

  // If we've already hit the end, just return an invalid field.
  if (PERFETTO_UNLIKELY(pos >= end))
    return res;

  uint64_t preamble = 0;
  if (PERFETTO_LIKELY(*pos < 0x80)) {  // Fastpath for fields with ID < 16.
    preamble = *(pos++);
  } else {
    const uint8_t* next = ParseVarInt(pos, end, &preamble);
    if (PERFETTO_UNLIKELY(pos == next))
      return res;
    pos = next;
  }

  uint32_t field_id = static_cast<uint32_t>(preamble >> kFieldTypeNumBits);
  if (field_id == 0 || pos >= end)
    return res;

  auto field_type = static_cast<uint8_t>(preamble & kFieldTypeMask);
  const uint8_t* new_pos = pos;
  uint64_t int_value = 0;
  uint64_t size = 0;

  switch (field_type) {
    case static_cast<uint8_t>(ProtoWireType::kVarInt): {
      new_pos = ParseVarInt(pos, end, &int_value);

      // new_pos not being greater than pos means ParseVarInt could not fully
      // parse the number. This is because we are out of space in the buffer.
      // Set the id to zero and return but don't update the offset so a future
      // read can read this field.
      if (PERFETTO_UNLIKELY(new_pos == pos))
        return res;

      break;
    }

    case static_cast<uint8_t>(ProtoWireType::kLengthDelimited): {
      uint64_t payload_length;
      new_pos = ParseVarInt(pos, end, &payload_length);
      if (PERFETTO_UNLIKELY(new_pos == pos))
        return res;

      // ParseVarInt guarantees that |new_pos| <= |end| when it succeeds;
      if (payload_length > static_cast<uint64_t>(end - new_pos))
        return res;

      const uintptr_t payload_start = reinterpret_cast<uintptr_t>(new_pos);
      int_value = payload_start;
      size = payload_length;
      new_pos += payload_length;
      break;
    }

    case static_cast<uint8_t>(ProtoWireType::kFixed64): {
      new_pos = pos + sizeof(uint64_t);
      if (PERFETTO_UNLIKELY(new_pos > end))
        return res;
      memcpy(&int_value, pos, sizeof(uint64_t));
      break;
    }

    case static_cast<uint8_t>(ProtoWireType::kFixed32): {
      new_pos = pos + sizeof(uint32_t);
      if (PERFETTO_UNLIKELY(new_pos > end))
        return res;
      memcpy(&int_value, pos, sizeof(uint32_t));
      break;
    }

    default:
      PERFETTO_DLOG("Invalid proto field type: %u", field_type);
      return res;
  }

  res.next = new_pos;

  if (PERFETTO_UNLIKELY(field_id > Field::kMaxId)) {
    PERFETTO_DLOG("Skipping field %" PRIu32 " because its id > %" PRIu32,
                  field_id, Field::kMaxId);
    res.parse_res = ParseFieldResult::kSkip;
    return res;
  }

  if (PERFETTO_UNLIKELY(size > proto_utils::kMaxMessageLength)) {
    PERFETTO_DLOG("Skipping field %" PRIu32 " because it's too big (%" PRIu64
                  " KB)",
                  field_id, size / 1024);
    res.parse_res = ParseFieldResult::kSkip;
    return res;
  }

  res.parse_res = ParseFieldResult::kOk;
  res.field.initialize(field_id, field_type, int_value,
                       static_cast<uint32_t>(size));
  return res;
}

}  // namespace

Field ProtoDecoder::FindField(uint32_t field_id) {
  Field res{};
  auto old_position = read_ptr_;
  read_ptr_ = begin_;
  for (auto f = ReadField(); f.valid(); f = ReadField()) {
    if (f.id() == field_id) {
      res = f;
      break;
    }
  }
  read_ptr_ = old_position;
  return res;
}

Field ProtoDecoder::ReadField() {
  ParseFieldResult res;
  do {
    res = ParseOneField(read_ptr_, end_);
    read_ptr_ = res.next;
  } while (PERFETTO_UNLIKELY(res.parse_res == ParseFieldResult::kSkip));
  return res.field;
}

void TypedProtoDecoderBase::ParseAllFields() {
  const uint8_t* cur = begin_;
  ParseFieldResult res;
  for (;;) {
    res = ParseOneField(cur, end_);
    PERFETTO_DCHECK(res.parse_res != ParseFieldResult::kOk || res.next != cur);
    cur = res.next;
    if (PERFETTO_UNLIKELY(res.parse_res == ParseFieldResult::kSkip))
      continue;
    if (PERFETTO_UNLIKELY(res.parse_res == ParseFieldResult::kAbort))
      break;

    PERFETTO_DCHECK(res.parse_res == ParseFieldResult::kOk);
    PERFETTO_DCHECK(res.field.valid());
    auto field_id = res.field.id();
    if (PERFETTO_UNLIKELY(field_id >= num_fields_))
      continue;

    // There are two reasons why we might want to expand the heap capacity:
    // 1. We are writing a non-repeated field, which has an id >
    //    INITIAL_STACK_CAPACITY. In this case ExpandHeapStorage() ensures to
    //    allocate at least (num_fields_ + 1) slots.
    // 2. We are writing a repeated field but ran out of capacity.
    if (PERFETTO_UNLIKELY(field_id >= size_ || size_ >= capacity_))
      ExpandHeapStorage();

    PERFETTO_DCHECK(field_id < size_);
    Field* fld = &fields_[field_id];
    if (PERFETTO_LIKELY(!fld->valid())) {
      // This is the first time we see this field.
      *fld = std::move(res.field);
    } else {
      // Repeated field case.
      // In this case we need to:
      // 1. Append the last value of the field to end of the repeated field
      //    storage.
      // 2. Replace the default instance at offset |field_id| with the current
      //    value. This is because in case of repeated field a call to Get(X) is
      //    supposed to return the last value of X, not the first one.
      // This is so that the RepeatedFieldIterator will iterate in the right
      // order, see comments on RepeatedFieldIterator.
      if (num_fields_ > size_) {
        ExpandHeapStorage();
        fld = &fields_[field_id];
      }

      PERFETTO_DCHECK(size_ < capacity_);
      fields_[size_++] = *fld;
      *fld = std::move(res.field);
    }
  }
  read_ptr_ = res.next;
}

void TypedProtoDecoderBase::ExpandHeapStorage() {
  // When we expand the heap we must ensure that we have at very last capacity
  // to deal with all known fields plus at least one repeated field. We go +2048
  // here based on observations on a large 4GB android trace. This is to avoid
  // trivial re-allocations when dealing with repeated fields of a message that
  // has > INITIAL_STACK_CAPACITY fields.
  const uint32_t min_capacity = num_fields_ + 2048;  // Any num >= +1 will do.
  const uint32_t new_capacity = std::max(capacity_ * 2, min_capacity);
  PERFETTO_CHECK(new_capacity > size_ && new_capacity > num_fields_);
  std::unique_ptr<Field[]> new_storage(new Field[new_capacity]);

  static_assert(std::is_trivially_constructible<Field>::value,
                "Field must be trivially constructible");
  static_assert(std::is_trivially_copyable<Field>::value,
                "Field must be trivially copyable");

  // Zero-initialize the slots for known field IDs slots, as they can be
  // randomly accessed. Instead, there is no need to initialize the repeated
  // slots, because they are written linearly with no gaps and are always
  // initialized before incrementing |size_|.
  const uint32_t new_size = std::max(size_, num_fields_);
  memset(&new_storage[size_], 0, sizeof(Field) * (new_size - size_));

  memcpy(&new_storage[0], fields_, sizeof(Field) * size_);

  heap_storage_ = std::move(new_storage);
  fields_ = &heap_storage_[0];
  capacity_ = new_capacity;
  size_ = new_size;
}

}  // namespace protozero
// gen_amalgamated begin source: src/protozero/scattered_heap_buffer.cc
/*
 * Copyright (C) 2017 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"

#include <algorithm>

namespace protozero {

ScatteredHeapBuffer::Slice::Slice()
    : buffer_(nullptr), size_(0u), unused_bytes_(0u) {}

ScatteredHeapBuffer::Slice::Slice(size_t size)
    : buffer_(std::unique_ptr<uint8_t[]>(new uint8_t[size])),
      size_(size),
      unused_bytes_(size) {
  PERFETTO_DCHECK(size);
  Clear();
}

ScatteredHeapBuffer::Slice::Slice(Slice&& slice) noexcept = default;

ScatteredHeapBuffer::Slice::~Slice() = default;

ScatteredHeapBuffer::Slice& ScatteredHeapBuffer::Slice::operator=(Slice&&) =
    default;

void ScatteredHeapBuffer::Slice::Clear() {
  unused_bytes_ = size_;
#if PERFETTO_DCHECK_IS_ON()
  memset(start(), 0xff, size_);
#endif  // PERFETTO_DCHECK_IS_ON()
}

ScatteredHeapBuffer::ScatteredHeapBuffer(size_t initial_slice_size_bytes,
                                         size_t maximum_slice_size_bytes)
    : next_slice_size_(initial_slice_size_bytes),
      maximum_slice_size_(maximum_slice_size_bytes) {
  PERFETTO_DCHECK(next_slice_size_ && maximum_slice_size_);
  PERFETTO_DCHECK(maximum_slice_size_ >= initial_slice_size_bytes);
}

ScatteredHeapBuffer::~ScatteredHeapBuffer() = default;

protozero::ContiguousMemoryRange ScatteredHeapBuffer::GetNewBuffer() {
  PERFETTO_CHECK(writer_);
  AdjustUsedSizeOfCurrentSlice();

  if (cached_slice_.start()) {
    slices_.push_back(std::move(cached_slice_));
    PERFETTO_DCHECK(!cached_slice_.start());
  } else {
    slices_.emplace_back(next_slice_size_);
  }
  next_slice_size_ = std::min(maximum_slice_size_, next_slice_size_ * 2);
  return slices_.back().GetTotalRange();
}

const std::vector<ScatteredHeapBuffer::Slice>&
ScatteredHeapBuffer::GetSlices() {
  AdjustUsedSizeOfCurrentSlice();
  return slices_;
}

std::vector<uint8_t> ScatteredHeapBuffer::StitchSlices() {
  size_t stitched_size = 0u;
  const auto& slices = GetSlices();
  for (const auto& slice : slices)
    stitched_size += slice.size() - slice.unused_bytes();

  std::vector<uint8_t> buffer;
  buffer.reserve(stitched_size);
  for (const auto& slice : slices) {
    auto used_range = slice.GetUsedRange();
    buffer.insert(buffer.end(), used_range.begin, used_range.end);
  }
  return buffer;
}

std::vector<protozero::ContiguousMemoryRange> ScatteredHeapBuffer::GetRanges() {
  std::vector<protozero::ContiguousMemoryRange> ranges;
  for (const auto& slice : GetSlices())
    ranges.push_back(slice.GetUsedRange());
  return ranges;
}

void ScatteredHeapBuffer::AdjustUsedSizeOfCurrentSlice() {
  if (!slices_.empty())
    slices_.back().set_unused_bytes(writer_->bytes_available());
}

size_t ScatteredHeapBuffer::GetTotalSize() {
  size_t total_size = 0;
  for (auto& slice : slices_) {
    total_size += slice.size();
  }
  return total_size;
}

void ScatteredHeapBuffer::Reset() {
  if (slices_.empty())
    return;
  cached_slice_ = std::move(slices_.front());
  cached_slice_.Clear();
  slices_.clear();
}

}  // namespace protozero
// gen_amalgamated begin source: src/protozero/scattered_stream_null_delegate.cc
/*
 * Copyright (C) 2018 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// gen_amalgamated expanded: #include "perfetto/protozero/scattered_stream_null_delegate.h"

namespace protozero {

// An implementation of ScatteredStreamWriter::Delegate which always returns
// the same piece of memory.
// This is used when we need to no-op the writers (e.g. during teardown or in
// case of resource exhaustion), avoiding that the clients have to deal with
// nullptr checks.
ScatteredStreamWriterNullDelegate::ScatteredStreamWriterNullDelegate(
    size_t chunk_size)
    : chunk_size_(chunk_size),
      chunk_(std::unique_ptr<uint8_t[]>(new uint8_t[chunk_size_])) {}

ScatteredStreamWriterNullDelegate::~ScatteredStreamWriterNullDelegate() {}

ContiguousMemoryRange ScatteredStreamWriterNullDelegate::GetNewBuffer() {
  return {chunk_.get(), chunk_.get() + chunk_size_};
}

}  // namespace protozero
// gen_amalgamated begin source: src/protozero/scattered_stream_writer.cc
/*
 * Copyright (C) 2017 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// gen_amalgamated expanded: #include "perfetto/protozero/scattered_stream_writer.h"

#include <algorithm>

// gen_amalgamated expanded: #include "perfetto/base/logging.h"

namespace protozero {

ScatteredStreamWriter::Delegate::~Delegate() {}

uint8_t* ScatteredStreamWriter::Delegate::AnnotatePatch(uint8_t* patch_addr) {
  // In most cases, a patch is transparent. The caller can write directly into
  // `to_patch`, because its memory is not going away. TraceWriterImpl, however,
  // requires a more complicated logic, because the chunks might be copied
  // earlier.
  return patch_addr;
}

ScatteredStreamWriter::ScatteredStreamWriter(Delegate* delegate)
    : delegate_(delegate),
      cur_range_({nullptr, nullptr}),
      write_ptr_(nullptr) {}

ScatteredStreamWriter::~ScatteredStreamWriter() {}

void ScatteredStreamWriter::Reset(ContiguousMemoryRange range) {
  written_previously_ += static_cast<uint64_t>(write_ptr_ - cur_range_.begin);
  cur_range_ = range;
  write_ptr_ = range.begin;
  PERFETTO_DCHECK(!write_ptr_ || write_ptr_ < cur_range_.end);
}

void ScatteredStreamWriter::Extend() {
  Reset(delegate_->GetNewBuffer());
}

void ScatteredStreamWriter::WriteBytesSlowPath(const uint8_t* src,
                                               size_t size) {
  size_t bytes_left = size;
  while (bytes_left > 0) {
    if (write_ptr_ >= cur_range_.end)
      Extend();
    const size_t burst_size = std::min(bytes_available(), bytes_left);
    WriteBytesUnsafe(src, burst_size);
    bytes_left -= burst_size;
    src += burst_size;
  }
}

// TODO(primiano): perf optimization: I suspect that at the end this will always
// be called with |size| == 4, in which case we might just hardcode it.
uint8_t* ScatteredStreamWriter::ReserveBytes(size_t size) {
  if (write_ptr_ + size > cur_range_.end) {
    // Assume the reservations are always < Delegate::GetNewBuffer().size(),
    // so that one single call to Extend() will definitely give enough headroom.
    Extend();
    PERFETTO_DCHECK(write_ptr_ + size <= cur_range_.end);
  }
  uint8_t* begin = write_ptr_;
  write_ptr_ += size;
#if PERFETTO_DCHECK_IS_ON()
  // In the past, the service had a matching DCHECK in
  // TraceBuffer::TryPatchChunkContents, which was assuming that service and all
  // producers are built with matching DCHECK levels. This turned out to be a
  // source of problems and was removed in b/197340286. This memset is useless
  // these days and is here only to maintain ABI compatibility between producers
  // that use a v20+ SDK and older versions of the service that were built in
  // debug mode. At some point around 2023 it should be safe to remove it.
  // (running a debug version of traced in production seems a bad idea
  // regardless).
  memset(begin, 0, size);
#endif
  return begin;
}

}  // namespace protozero
// gen_amalgamated begin source: src/protozero/static_buffer.cc
/*
 * Copyright (C) 2019 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// gen_amalgamated expanded: #include "perfetto/protozero/static_buffer.h"

// gen_amalgamated expanded: #include "perfetto/base/logging.h"

namespace protozero {

StaticBufferDelegate::~StaticBufferDelegate() = default;

ContiguousMemoryRange StaticBufferDelegate::GetNewBuffer() {
  if (get_new_buffer_called_once_) {
    // This is the 2nd time GetNewBuffer is called. The estimate is wrong. We
    // shouldn't try to grow the buffer after the initial call.
    PERFETTO_FATAL("Static buffer too small");
  }
  get_new_buffer_called_once_ = true;
  return range_;
}

}  // namespace protozero
// gen_amalgamated begin source: src/protozero/virtual_destructors.cc
/*
 * Copyright (C) 2019 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"
// gen_amalgamated expanded: #include "perfetto/protozero/message_handle.h"

namespace protozero {

CppMessageObj::~CppMessageObj() = default;
MessageFinalizationListener::~MessageFinalizationListener() = default;

}  // namespace protozero
// gen_amalgamated begin source: gen/protos/perfetto/common/android_energy_consumer_descriptor.gen.cc
// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wfloat-equal"
#endif
// gen_amalgamated expanded: #include "protos/perfetto/common/android_energy_consumer_descriptor.gen.h"

namespace perfetto {
namespace protos {
namespace gen {

AndroidEnergyConsumerDescriptor::AndroidEnergyConsumerDescriptor() = default;
AndroidEnergyConsumerDescriptor::~AndroidEnergyConsumerDescriptor() = default;
AndroidEnergyConsumerDescriptor::AndroidEnergyConsumerDescriptor(const AndroidEnergyConsumerDescriptor&) = default;
AndroidEnergyConsumerDescriptor& AndroidEnergyConsumerDescriptor::operator=(const AndroidEnergyConsumerDescriptor&) = default;
AndroidEnergyConsumerDescriptor::AndroidEnergyConsumerDescriptor(AndroidEnergyConsumerDescriptor&&) noexcept = default;
AndroidEnergyConsumerDescriptor& AndroidEnergyConsumerDescriptor::operator=(AndroidEnergyConsumerDescriptor&&) = default;

bool AndroidEnergyConsumerDescriptor::operator==(const AndroidEnergyConsumerDescriptor& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(energy_consumers_, other.energy_consumers_);
}

int AndroidEnergyConsumerDescriptor::energy_consumers_size() const { return static_cast<int>(energy_consumers_.size()); }
void AndroidEnergyConsumerDescriptor::clear_energy_consumers() { energy_consumers_.clear(); }
AndroidEnergyConsumer* AndroidEnergyConsumerDescriptor::add_energy_consumers() { energy_consumers_.emplace_back(); return &energy_consumers_.back(); }
bool AndroidEnergyConsumerDescriptor::ParseFromArray(const void* raw, size_t size) {
  energy_consumers_.clear();
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* energy_consumers */:
        energy_consumers_.emplace_back();
        energy_consumers_.back().ParseFromArray(field.data(), field.size());
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string AndroidEnergyConsumerDescriptor::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> AndroidEnergyConsumerDescriptor::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void AndroidEnergyConsumerDescriptor::Serialize(::protozero::Message* msg) const {
  // Field 1: energy_consumers
  for (auto& it : energy_consumers_) {
    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}


AndroidEnergyConsumer::AndroidEnergyConsumer() = default;
AndroidEnergyConsumer::~AndroidEnergyConsumer() = default;
AndroidEnergyConsumer::AndroidEnergyConsumer(const AndroidEnergyConsumer&) = default;
AndroidEnergyConsumer& AndroidEnergyConsumer::operator=(const AndroidEnergyConsumer&) = default;
AndroidEnergyConsumer::AndroidEnergyConsumer(AndroidEnergyConsumer&&) noexcept = default;
AndroidEnergyConsumer& AndroidEnergyConsumer::operator=(AndroidEnergyConsumer&&) = default;

bool AndroidEnergyConsumer::operator==(const AndroidEnergyConsumer& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(energy_consumer_id_, other.energy_consumer_id_)
   && ::protozero::internal::gen_helpers::EqualsField(ordinal_, other.ordinal_)
   && ::protozero::internal::gen_helpers::EqualsField(type_, other.type_)
   && ::protozero::internal::gen_helpers::EqualsField(name_, other.name_);
}

bool AndroidEnergyConsumer::ParseFromArray(const void* raw, size_t size) {
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* energy_consumer_id */:
        field.get(&energy_consumer_id_);
        break;
      case 2 /* ordinal */:
        field.get(&ordinal_);
        break;
      case 3 /* type */:
        ::protozero::internal::gen_helpers::DeserializeString(field, &type_);
        break;
      case 4 /* name */:
        ::protozero::internal::gen_helpers::DeserializeString(field, &name_);
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string AndroidEnergyConsumer::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> AndroidEnergyConsumer::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void AndroidEnergyConsumer::Serialize(::protozero::Message* msg) const {
  // Field 1: energy_consumer_id
  if (_has_field_[1]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(1, energy_consumer_id_, msg);
  }

  // Field 2: ordinal
  if (_has_field_[2]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(2, ordinal_, msg);
  }

  // Field 3: type
  if (_has_field_[3]) {
    ::protozero::internal::gen_helpers::SerializeString(3, type_, msg);
  }

  // Field 4: name
  if (_has_field_[4]) {
    ::protozero::internal::gen_helpers::SerializeString(4, name_, msg);
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}

}  // namespace perfetto
}  // namespace protos
}  // namespace gen
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic pop
#endif
// gen_amalgamated begin source: gen/protos/perfetto/common/android_log_constants.gen.cc
// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wfloat-equal"
#endif
// gen_amalgamated expanded: #include "protos/perfetto/common/android_log_constants.gen.h"

namespace perfetto {
namespace protos {
namespace gen {
}  // namespace perfetto
}  // namespace protos
}  // namespace gen
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic pop
#endif
// gen_amalgamated begin source: gen/protos/perfetto/common/builtin_clock.gen.cc
// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wfloat-equal"
#endif
// gen_amalgamated expanded: #include "protos/perfetto/common/builtin_clock.gen.h"

namespace perfetto {
namespace protos {
namespace gen {
}  // namespace perfetto
}  // namespace protos
}  // namespace gen
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic pop
#endif
// gen_amalgamated begin source: gen/protos/perfetto/common/commit_data_request.gen.cc
// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wfloat-equal"
#endif
// gen_amalgamated expanded: #include "protos/perfetto/common/commit_data_request.gen.h"

namespace perfetto {
namespace protos {
namespace gen {

CommitDataRequest::CommitDataRequest() = default;
CommitDataRequest::~CommitDataRequest() = default;
CommitDataRequest::CommitDataRequest(const CommitDataRequest&) = default;
CommitDataRequest& CommitDataRequest::operator=(const CommitDataRequest&) = default;
CommitDataRequest::CommitDataRequest(CommitDataRequest&&) noexcept = default;
CommitDataRequest& CommitDataRequest::operator=(CommitDataRequest&&) = default;

bool CommitDataRequest::operator==(const CommitDataRequest& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(chunks_to_move_, other.chunks_to_move_)
   && ::protozero::internal::gen_helpers::EqualsField(chunks_to_patch_, other.chunks_to_patch_)
   && ::protozero::internal::gen_helpers::EqualsField(flush_request_id_, other.flush_request_id_);
}

int CommitDataRequest::chunks_to_move_size() const { return static_cast<int>(chunks_to_move_.size()); }
void CommitDataRequest::clear_chunks_to_move() { chunks_to_move_.clear(); }
CommitDataRequest_ChunksToMove* CommitDataRequest::add_chunks_to_move() { chunks_to_move_.emplace_back(); return &chunks_to_move_.back(); }
int CommitDataRequest::chunks_to_patch_size() const { return static_cast<int>(chunks_to_patch_.size()); }
void CommitDataRequest::clear_chunks_to_patch() { chunks_to_patch_.clear(); }
CommitDataRequest_ChunkToPatch* CommitDataRequest::add_chunks_to_patch() { chunks_to_patch_.emplace_back(); return &chunks_to_patch_.back(); }
bool CommitDataRequest::ParseFromArray(const void* raw, size_t size) {
  chunks_to_move_.clear();
  chunks_to_patch_.clear();
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* chunks_to_move */:
        chunks_to_move_.emplace_back();
        chunks_to_move_.back().ParseFromArray(field.data(), field.size());
        break;
      case 2 /* chunks_to_patch */:
        chunks_to_patch_.emplace_back();
        chunks_to_patch_.back().ParseFromArray(field.data(), field.size());
        break;
      case 3 /* flush_request_id */:
        field.get(&flush_request_id_);
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string CommitDataRequest::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> CommitDataRequest::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void CommitDataRequest::Serialize(::protozero::Message* msg) const {
  // Field 1: chunks_to_move
  for (auto& it : chunks_to_move_) {
    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
  }

  // Field 2: chunks_to_patch
  for (auto& it : chunks_to_patch_) {
    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(2));
  }

  // Field 3: flush_request_id
  if (_has_field_[3]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(3, flush_request_id_, msg);
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}


CommitDataRequest_ChunkToPatch::CommitDataRequest_ChunkToPatch() = default;
CommitDataRequest_ChunkToPatch::~CommitDataRequest_ChunkToPatch() = default;
CommitDataRequest_ChunkToPatch::CommitDataRequest_ChunkToPatch(const CommitDataRequest_ChunkToPatch&) = default;
CommitDataRequest_ChunkToPatch& CommitDataRequest_ChunkToPatch::operator=(const CommitDataRequest_ChunkToPatch&) = default;
CommitDataRequest_ChunkToPatch::CommitDataRequest_ChunkToPatch(CommitDataRequest_ChunkToPatch&&) noexcept = default;
CommitDataRequest_ChunkToPatch& CommitDataRequest_ChunkToPatch::operator=(CommitDataRequest_ChunkToPatch&&) = default;

bool CommitDataRequest_ChunkToPatch::operator==(const CommitDataRequest_ChunkToPatch& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(target_buffer_, other.target_buffer_)
   && ::protozero::internal::gen_helpers::EqualsField(writer_id_, other.writer_id_)
   && ::protozero::internal::gen_helpers::EqualsField(chunk_id_, other.chunk_id_)
   && ::protozero::internal::gen_helpers::EqualsField(patches_, other.patches_)
   && ::protozero::internal::gen_helpers::EqualsField(has_more_patches_, other.has_more_patches_);
}

int CommitDataRequest_ChunkToPatch::patches_size() const { return static_cast<int>(patches_.size()); }
void CommitDataRequest_ChunkToPatch::clear_patches() { patches_.clear(); }
CommitDataRequest_ChunkToPatch_Patch* CommitDataRequest_ChunkToPatch::add_patches() { patches_.emplace_back(); return &patches_.back(); }
bool CommitDataRequest_ChunkToPatch::ParseFromArray(const void* raw, size_t size) {
  patches_.clear();
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* target_buffer */:
        field.get(&target_buffer_);
        break;
      case 2 /* writer_id */:
        field.get(&writer_id_);
        break;
      case 3 /* chunk_id */:
        field.get(&chunk_id_);
        break;
      case 4 /* patches */:
        patches_.emplace_back();
        patches_.back().ParseFromArray(field.data(), field.size());
        break;
      case 5 /* has_more_patches */:
        field.get(&has_more_patches_);
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string CommitDataRequest_ChunkToPatch::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> CommitDataRequest_ChunkToPatch::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void CommitDataRequest_ChunkToPatch::Serialize(::protozero::Message* msg) const {
  // Field 1: target_buffer
  if (_has_field_[1]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(1, target_buffer_, msg);
  }

  // Field 2: writer_id
  if (_has_field_[2]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(2, writer_id_, msg);
  }

  // Field 3: chunk_id
  if (_has_field_[3]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(3, chunk_id_, msg);
  }

  // Field 4: patches
  for (auto& it : patches_) {
    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(4));
  }

  // Field 5: has_more_patches
  if (_has_field_[5]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(5, has_more_patches_, msg);
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}


CommitDataRequest_ChunkToPatch_Patch::CommitDataRequest_ChunkToPatch_Patch() = default;
CommitDataRequest_ChunkToPatch_Patch::~CommitDataRequest_ChunkToPatch_Patch() = default;
CommitDataRequest_ChunkToPatch_Patch::CommitDataRequest_ChunkToPatch_Patch(const CommitDataRequest_ChunkToPatch_Patch&) = default;
CommitDataRequest_ChunkToPatch_Patch& CommitDataRequest_ChunkToPatch_Patch::operator=(const CommitDataRequest_ChunkToPatch_Patch&) = default;
CommitDataRequest_ChunkToPatch_Patch::CommitDataRequest_ChunkToPatch_Patch(CommitDataRequest_ChunkToPatch_Patch&&) noexcept = default;
CommitDataRequest_ChunkToPatch_Patch& CommitDataRequest_ChunkToPatch_Patch::operator=(CommitDataRequest_ChunkToPatch_Patch&&) = default;

bool CommitDataRequest_ChunkToPatch_Patch::operator==(const CommitDataRequest_ChunkToPatch_Patch& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(offset_, other.offset_)
   && ::protozero::internal::gen_helpers::EqualsField(data_, other.data_);
}

bool CommitDataRequest_ChunkToPatch_Patch::ParseFromArray(const void* raw, size_t size) {
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* offset */:
        field.get(&offset_);
        break;
      case 2 /* data */:
        field.get(&data_);
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string CommitDataRequest_ChunkToPatch_Patch::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> CommitDataRequest_ChunkToPatch_Patch::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void CommitDataRequest_ChunkToPatch_Patch::Serialize(::protozero::Message* msg) const {
  // Field 1: offset
  if (_has_field_[1]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(1, offset_, msg);
  }

  // Field 2: data
  if (_has_field_[2]) {
    ::protozero::internal::gen_helpers::SerializeString(2, data_, msg);
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}


CommitDataRequest_ChunksToMove::CommitDataRequest_ChunksToMove() = default;
CommitDataRequest_ChunksToMove::~CommitDataRequest_ChunksToMove() = default;
CommitDataRequest_ChunksToMove::CommitDataRequest_ChunksToMove(const CommitDataRequest_ChunksToMove&) = default;
CommitDataRequest_ChunksToMove& CommitDataRequest_ChunksToMove::operator=(const CommitDataRequest_ChunksToMove&) = default;
CommitDataRequest_ChunksToMove::CommitDataRequest_ChunksToMove(CommitDataRequest_ChunksToMove&&) noexcept = default;
CommitDataRequest_ChunksToMove& CommitDataRequest_ChunksToMove::operator=(CommitDataRequest_ChunksToMove&&) = default;

bool CommitDataRequest_ChunksToMove::operator==(const CommitDataRequest_ChunksToMove& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(page_, other.page_)
   && ::protozero::internal::gen_helpers::EqualsField(chunk_, other.chunk_)
   && ::protozero::internal::gen_helpers::EqualsField(target_buffer_, other.target_buffer_)
   && ::protozero::internal::gen_helpers::EqualsField(data_, other.data_);
}

bool CommitDataRequest_ChunksToMove::ParseFromArray(const void* raw, size_t size) {
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* page */:
        field.get(&page_);
        break;
      case 2 /* chunk */:
        field.get(&chunk_);
        break;
      case 3 /* target_buffer */:
        field.get(&target_buffer_);
        break;
      case 4 /* data */:
        field.get(&data_);
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string CommitDataRequest_ChunksToMove::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> CommitDataRequest_ChunksToMove::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void CommitDataRequest_ChunksToMove::Serialize(::protozero::Message* msg) const {
  // Field 1: page
  if (_has_field_[1]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(1, page_, msg);
  }

  // Field 2: chunk
  if (_has_field_[2]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(2, chunk_, msg);
  }

  // Field 3: target_buffer
  if (_has_field_[3]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(3, target_buffer_, msg);
  }

  // Field 4: data
  if (_has_field_[4]) {
    ::protozero::internal::gen_helpers::SerializeString(4, data_, msg);
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}

}  // namespace perfetto
}  // namespace protos
}  // namespace gen
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic pop
#endif
// gen_amalgamated begin source: gen/protos/perfetto/common/data_source_descriptor.gen.cc
// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wfloat-equal"
#endif
// gen_amalgamated expanded: #include "protos/perfetto/common/data_source_descriptor.gen.h"

namespace perfetto {
namespace protos {
namespace gen {

DataSourceDescriptor::DataSourceDescriptor() = default;
DataSourceDescriptor::~DataSourceDescriptor() = default;
DataSourceDescriptor::DataSourceDescriptor(const DataSourceDescriptor&) = default;
DataSourceDescriptor& DataSourceDescriptor::operator=(const DataSourceDescriptor&) = default;
DataSourceDescriptor::DataSourceDescriptor(DataSourceDescriptor&&) noexcept = default;
DataSourceDescriptor& DataSourceDescriptor::operator=(DataSourceDescriptor&&) = default;

bool DataSourceDescriptor::operator==(const DataSourceDescriptor& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(name_, other.name_)
   && ::protozero::internal::gen_helpers::EqualsField(id_, other.id_)
   && ::protozero::internal::gen_helpers::EqualsField(will_notify_on_stop_, other.will_notify_on_stop_)
   && ::protozero::internal::gen_helpers::EqualsField(will_notify_on_start_, other.will_notify_on_start_)
   && ::protozero::internal::gen_helpers::EqualsField(handles_incremental_state_clear_, other.handles_incremental_state_clear_)
   && ::protozero::internal::gen_helpers::EqualsField(no_flush_, other.no_flush_)
   && ::protozero::internal::gen_helpers::EqualsField(gpu_counter_descriptor_, other.gpu_counter_descriptor_)
   && ::protozero::internal::gen_helpers::EqualsField(track_event_descriptor_, other.track_event_descriptor_)
   && ::protozero::internal::gen_helpers::EqualsField(ftrace_descriptor_, other.ftrace_descriptor_);
}

bool DataSourceDescriptor::ParseFromArray(const void* raw, size_t size) {
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* name */:
        ::protozero::internal::gen_helpers::DeserializeString(field, &name_);
        break;
      case 7 /* id */:
        field.get(&id_);
        break;
      case 2 /* will_notify_on_stop */:
        field.get(&will_notify_on_stop_);
        break;
      case 3 /* will_notify_on_start */:
        field.get(&will_notify_on_start_);
        break;
      case 4 /* handles_incremental_state_clear */:
        field.get(&handles_incremental_state_clear_);
        break;
      case 9 /* no_flush */:
        field.get(&no_flush_);
        break;
      case 5 /* gpu_counter_descriptor */:
        ::protozero::internal::gen_helpers::DeserializeString(field, &gpu_counter_descriptor_);
        break;
      case 6 /* track_event_descriptor */:
        ::protozero::internal::gen_helpers::DeserializeString(field, &track_event_descriptor_);
        break;
      case 8 /* ftrace_descriptor */:
        ::protozero::internal::gen_helpers::DeserializeString(field, &ftrace_descriptor_);
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string DataSourceDescriptor::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> DataSourceDescriptor::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void DataSourceDescriptor::Serialize(::protozero::Message* msg) const {
  // Field 1: name
  if (_has_field_[1]) {
    ::protozero::internal::gen_helpers::SerializeString(1, name_, msg);
  }

  // Field 7: id
  if (_has_field_[7]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(7, id_, msg);
  }

  // Field 2: will_notify_on_stop
  if (_has_field_[2]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(2, will_notify_on_stop_, msg);
  }

  // Field 3: will_notify_on_start
  if (_has_field_[3]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(3, will_notify_on_start_, msg);
  }

  // Field 4: handles_incremental_state_clear
  if (_has_field_[4]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(4, handles_incremental_state_clear_, msg);
  }

  // Field 9: no_flush
  if (_has_field_[9]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(9, no_flush_, msg);
  }

  // Field 5: gpu_counter_descriptor
  if (_has_field_[5]) {
    msg->AppendString(5, gpu_counter_descriptor_);
  }

  // Field 6: track_event_descriptor
  if (_has_field_[6]) {
    msg->AppendString(6, track_event_descriptor_);
  }

  // Field 8: ftrace_descriptor
  if (_has_field_[8]) {
    msg->AppendString(8, ftrace_descriptor_);
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}

}  // namespace perfetto
}  // namespace protos
}  // namespace gen
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic pop
#endif
// gen_amalgamated begin source: gen/protos/perfetto/common/descriptor.gen.cc
// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wfloat-equal"
#endif
// gen_amalgamated expanded: #include "protos/perfetto/common/descriptor.gen.h"

namespace perfetto {
namespace protos {
namespace gen {

OneofOptions::OneofOptions() = default;
OneofOptions::~OneofOptions() = default;
OneofOptions::OneofOptions(const OneofOptions&) = default;
OneofOptions& OneofOptions::operator=(const OneofOptions&) = default;
OneofOptions::OneofOptions(OneofOptions&&) noexcept = default;
OneofOptions& OneofOptions::operator=(OneofOptions&&) = default;

bool OneofOptions::operator==(const OneofOptions& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_);
}

bool OneofOptions::ParseFromArray(const void* raw, size_t size) {
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string OneofOptions::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> OneofOptions::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void OneofOptions::Serialize(::protozero::Message* msg) const {
  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}


EnumValueDescriptorProto::EnumValueDescriptorProto() = default;
EnumValueDescriptorProto::~EnumValueDescriptorProto() = default;
EnumValueDescriptorProto::EnumValueDescriptorProto(const EnumValueDescriptorProto&) = default;
EnumValueDescriptorProto& EnumValueDescriptorProto::operator=(const EnumValueDescriptorProto&) = default;
EnumValueDescriptorProto::EnumValueDescriptorProto(EnumValueDescriptorProto&&) noexcept = default;
EnumValueDescriptorProto& EnumValueDescriptorProto::operator=(EnumValueDescriptorProto&&) = default;

bool EnumValueDescriptorProto::operator==(const EnumValueDescriptorProto& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(name_, other.name_)
   && ::protozero::internal::gen_helpers::EqualsField(number_, other.number_);
}

bool EnumValueDescriptorProto::ParseFromArray(const void* raw, size_t size) {
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* name */:
        ::protozero::internal::gen_helpers::DeserializeString(field, &name_);
        break;
      case 2 /* number */:
        field.get(&number_);
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string EnumValueDescriptorProto::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> EnumValueDescriptorProto::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void EnumValueDescriptorProto::Serialize(::protozero::Message* msg) const {
  // Field 1: name
  if (_has_field_[1]) {
    ::protozero::internal::gen_helpers::SerializeString(1, name_, msg);
  }

  // Field 2: number
  if (_has_field_[2]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(2, number_, msg);
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}


EnumDescriptorProto::EnumDescriptorProto() = default;
EnumDescriptorProto::~EnumDescriptorProto() = default;
EnumDescriptorProto::EnumDescriptorProto(const EnumDescriptorProto&) = default;
EnumDescriptorProto& EnumDescriptorProto::operator=(const EnumDescriptorProto&) = default;
EnumDescriptorProto::EnumDescriptorProto(EnumDescriptorProto&&) noexcept = default;
EnumDescriptorProto& EnumDescriptorProto::operator=(EnumDescriptorProto&&) = default;

bool EnumDescriptorProto::operator==(const EnumDescriptorProto& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(name_, other.name_)
   && ::protozero::internal::gen_helpers::EqualsField(value_, other.value_)
   && ::protozero::internal::gen_helpers::EqualsField(reserved_name_, other.reserved_name_);
}

int EnumDescriptorProto::value_size() const { return static_cast<int>(value_.size()); }
void EnumDescriptorProto::clear_value() { value_.clear(); }
EnumValueDescriptorProto* EnumDescriptorProto::add_value() { value_.emplace_back(); return &value_.back(); }
bool EnumDescriptorProto::ParseFromArray(const void* raw, size_t size) {
  value_.clear();
  reserved_name_.clear();
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* name */:
        ::protozero::internal::gen_helpers::DeserializeString(field, &name_);
        break;
      case 2 /* value */:
        value_.emplace_back();
        value_.back().ParseFromArray(field.data(), field.size());
        break;
      case 5 /* reserved_name */:
        reserved_name_.emplace_back();
        ::protozero::internal::gen_helpers::DeserializeString(field, &reserved_name_.back());
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string EnumDescriptorProto::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> EnumDescriptorProto::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void EnumDescriptorProto::Serialize(::protozero::Message* msg) const {
  // Field 1: name
  if (_has_field_[1]) {
    ::protozero::internal::gen_helpers::SerializeString(1, name_, msg);
  }

  // Field 2: value
  for (auto& it : value_) {
    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(2));
  }

  // Field 5: reserved_name
  for (auto& it : reserved_name_) {
    ::protozero::internal::gen_helpers::SerializeString(5, it, msg);
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}


OneofDescriptorProto::OneofDescriptorProto() = default;
OneofDescriptorProto::~OneofDescriptorProto() = default;
OneofDescriptorProto::OneofDescriptorProto(const OneofDescriptorProto&) = default;
OneofDescriptorProto& OneofDescriptorProto::operator=(const OneofDescriptorProto&) = default;
OneofDescriptorProto::OneofDescriptorProto(OneofDescriptorProto&&) noexcept = default;
OneofDescriptorProto& OneofDescriptorProto::operator=(OneofDescriptorProto&&) = default;

bool OneofDescriptorProto::operator==(const OneofDescriptorProto& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(name_, other.name_)
   && ::protozero::internal::gen_helpers::EqualsField(options_, other.options_);
}

bool OneofDescriptorProto::ParseFromArray(const void* raw, size_t size) {
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* name */:
        ::protozero::internal::gen_helpers::DeserializeString(field, &name_);
        break;
      case 2 /* options */:
        (*options_).ParseFromArray(field.data(), field.size());
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string OneofDescriptorProto::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> OneofDescriptorProto::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void OneofDescriptorProto::Serialize(::protozero::Message* msg) const {
  // Field 1: name
  if (_has_field_[1]) {
    ::protozero::internal::gen_helpers::SerializeString(1, name_, msg);
  }

  // Field 2: options
  if (_has_field_[2]) {
    (*options_).Serialize(msg->BeginNestedMessage<::protozero::Message>(2));
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}


FieldDescriptorProto::FieldDescriptorProto() = default;
FieldDescriptorProto::~FieldDescriptorProto() = default;
FieldDescriptorProto::FieldDescriptorProto(const FieldDescriptorProto&) = default;
FieldDescriptorProto& FieldDescriptorProto::operator=(const FieldDescriptorProto&) = default;
FieldDescriptorProto::FieldDescriptorProto(FieldDescriptorProto&&) noexcept = default;
FieldDescriptorProto& FieldDescriptorProto::operator=(FieldDescriptorProto&&) = default;

bool FieldDescriptorProto::operator==(const FieldDescriptorProto& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(name_, other.name_)
   && ::protozero::internal::gen_helpers::EqualsField(number_, other.number_)
   && ::protozero::internal::gen_helpers::EqualsField(label_, other.label_)
   && ::protozero::internal::gen_helpers::EqualsField(type_, other.type_)
   && ::protozero::internal::gen_helpers::EqualsField(type_name_, other.type_name_)
   && ::protozero::internal::gen_helpers::EqualsField(extendee_, other.extendee_)
   && ::protozero::internal::gen_helpers::EqualsField(default_value_, other.default_value_)
   && ::protozero::internal::gen_helpers::EqualsField(options_, other.options_)
   && ::protozero::internal::gen_helpers::EqualsField(oneof_index_, other.oneof_index_);
}

bool FieldDescriptorProto::ParseFromArray(const void* raw, size_t size) {
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* name */:
        ::protozero::internal::gen_helpers::DeserializeString(field, &name_);
        break;
      case 3 /* number */:
        field.get(&number_);
        break;
      case 4 /* label */:
        field.get(&label_);
        break;
      case 5 /* type */:
        field.get(&type_);
        break;
      case 6 /* type_name */:
        ::protozero::internal::gen_helpers::DeserializeString(field, &type_name_);
        break;
      case 2 /* extendee */:
        ::protozero::internal::gen_helpers::DeserializeString(field, &extendee_);
        break;
      case 7 /* default_value */:
        ::protozero::internal::gen_helpers::DeserializeString(field, &default_value_);
        break;
      case 8 /* options */:
        (*options_).ParseFromArray(field.data(), field.size());
        break;
      case 9 /* oneof_index */:
        field.get(&oneof_index_);
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string FieldDescriptorProto::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> FieldDescriptorProto::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void FieldDescriptorProto::Serialize(::protozero::Message* msg) const {
  // Field 1: name
  if (_has_field_[1]) {
    ::protozero::internal::gen_helpers::SerializeString(1, name_, msg);
  }

  // Field 3: number
  if (_has_field_[3]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(3, number_, msg);
  }

  // Field 4: label
  if (_has_field_[4]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(4, label_, msg);
  }

  // Field 5: type
  if (_has_field_[5]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(5, type_, msg);
  }

  // Field 6: type_name
  if (_has_field_[6]) {
    ::protozero::internal::gen_helpers::SerializeString(6, type_name_, msg);
  }

  // Field 2: extendee
  if (_has_field_[2]) {
    ::protozero::internal::gen_helpers::SerializeString(2, extendee_, msg);
  }

  // Field 7: default_value
  if (_has_field_[7]) {
    ::protozero::internal::gen_helpers::SerializeString(7, default_value_, msg);
  }

  // Field 8: options
  if (_has_field_[8]) {
    (*options_).Serialize(msg->BeginNestedMessage<::protozero::Message>(8));
  }

  // Field 9: oneof_index
  if (_has_field_[9]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(9, oneof_index_, msg);
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}


FieldOptions::FieldOptions() = default;
FieldOptions::~FieldOptions() = default;
FieldOptions::FieldOptions(const FieldOptions&) = default;
FieldOptions& FieldOptions::operator=(const FieldOptions&) = default;
FieldOptions::FieldOptions(FieldOptions&&) noexcept = default;
FieldOptions& FieldOptions::operator=(FieldOptions&&) = default;

bool FieldOptions::operator==(const FieldOptions& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(packed_, other.packed_)
   && ::protozero::internal::gen_helpers::EqualsField(uninterpreted_option_, other.uninterpreted_option_);
}

int FieldOptions::uninterpreted_option_size() const { return static_cast<int>(uninterpreted_option_.size()); }
void FieldOptions::clear_uninterpreted_option() { uninterpreted_option_.clear(); }
UninterpretedOption* FieldOptions::add_uninterpreted_option() { uninterpreted_option_.emplace_back(); return &uninterpreted_option_.back(); }
bool FieldOptions::ParseFromArray(const void* raw, size_t size) {
  uninterpreted_option_.clear();
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 2 /* packed */:
        field.get(&packed_);
        break;
      case 999 /* uninterpreted_option */:
        uninterpreted_option_.emplace_back();
        uninterpreted_option_.back().ParseFromArray(field.data(), field.size());
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string FieldOptions::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> FieldOptions::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void FieldOptions::Serialize(::protozero::Message* msg) const {
  // Field 2: packed
  if (_has_field_[2]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(2, packed_, msg);
  }

  // Field 999: uninterpreted_option
  for (auto& it : uninterpreted_option_) {
    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(999));
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}


UninterpretedOption::UninterpretedOption() = default;
UninterpretedOption::~UninterpretedOption() = default;
UninterpretedOption::UninterpretedOption(const UninterpretedOption&) = default;
UninterpretedOption& UninterpretedOption::operator=(const UninterpretedOption&) = default;
UninterpretedOption::UninterpretedOption(UninterpretedOption&&) noexcept = default;
UninterpretedOption& UninterpretedOption::operator=(UninterpretedOption&&) = default;

bool UninterpretedOption::operator==(const UninterpretedOption& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(name_, other.name_)
   && ::protozero::internal::gen_helpers::EqualsField(identifier_value_, other.identifier_value_)
   && ::protozero::internal::gen_helpers::EqualsField(positive_int_value_, other.positive_int_value_)
   && ::protozero::internal::gen_helpers::EqualsField(negative_int_value_, other.negative_int_value_)
   && ::protozero::internal::gen_helpers::EqualsField(double_value_, other.double_value_)
   && ::protozero::internal::gen_helpers::EqualsField(string_value_, other.string_value_)
   && ::protozero::internal::gen_helpers::EqualsField(aggregate_value_, other.aggregate_value_);
}

int UninterpretedOption::name_size() const { return static_cast<int>(name_.size()); }
void UninterpretedOption::clear_name() { name_.clear(); }
UninterpretedOption_NamePart* UninterpretedOption::add_name() { name_.emplace_back(); return &name_.back(); }
bool UninterpretedOption::ParseFromArray(const void* raw, size_t size) {
  name_.clear();
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 2 /* name */:
        name_.emplace_back();
        name_.back().ParseFromArray(field.data(), field.size());
        break;
      case 3 /* identifier_value */:
        ::protozero::internal::gen_helpers::DeserializeString(field, &identifier_value_);
        break;
      case 4 /* positive_int_value */:
        field.get(&positive_int_value_);
        break;
      case 5 /* negative_int_value */:
        field.get(&negative_int_value_);
        break;
      case 6 /* double_value */:
        field.get(&double_value_);
        break;
      case 7 /* string_value */:
        field.get(&string_value_);
        break;
      case 8 /* aggregate_value */:
        ::protozero::internal::gen_helpers::DeserializeString(field, &aggregate_value_);
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string UninterpretedOption::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> UninterpretedOption::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void UninterpretedOption::Serialize(::protozero::Message* msg) const {
  // Field 2: name
  for (auto& it : name_) {
    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(2));
  }

  // Field 3: identifier_value
  if (_has_field_[3]) {
    ::protozero::internal::gen_helpers::SerializeString(3, identifier_value_, msg);
  }

  // Field 4: positive_int_value
  if (_has_field_[4]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(4, positive_int_value_, msg);
  }

  // Field 5: negative_int_value
  if (_has_field_[5]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(5, negative_int_value_, msg);
  }

  // Field 6: double_value
  if (_has_field_[6]) {
    ::protozero::internal::gen_helpers::SerializeFixed(6, double_value_, msg);
  }

  // Field 7: string_value
  if (_has_field_[7]) {
    ::protozero::internal::gen_helpers::SerializeString(7, string_value_, msg);
  }

  // Field 8: aggregate_value
  if (_has_field_[8]) {
    ::protozero::internal::gen_helpers::SerializeString(8, aggregate_value_, msg);
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}


UninterpretedOption_NamePart::UninterpretedOption_NamePart() = default;
UninterpretedOption_NamePart::~UninterpretedOption_NamePart() = default;
UninterpretedOption_NamePart::UninterpretedOption_NamePart(const UninterpretedOption_NamePart&) = default;
UninterpretedOption_NamePart& UninterpretedOption_NamePart::operator=(const UninterpretedOption_NamePart&) = default;
UninterpretedOption_NamePart::UninterpretedOption_NamePart(UninterpretedOption_NamePart&&) noexcept = default;
UninterpretedOption_NamePart& UninterpretedOption_NamePart::operator=(UninterpretedOption_NamePart&&) = default;

bool UninterpretedOption_NamePart::operator==(const UninterpretedOption_NamePart& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(name_part_, other.name_part_)
   && ::protozero::internal::gen_helpers::EqualsField(is_extension_, other.is_extension_);
}

bool UninterpretedOption_NamePart::ParseFromArray(const void* raw, size_t size) {
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* name_part */:
        ::protozero::internal::gen_helpers::DeserializeString(field, &name_part_);
        break;
      case 2 /* is_extension */:
        field.get(&is_extension_);
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string UninterpretedOption_NamePart::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> UninterpretedOption_NamePart::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void UninterpretedOption_NamePart::Serialize(::protozero::Message* msg) const {
  // Field 1: name_part
  if (_has_field_[1]) {
    ::protozero::internal::gen_helpers::SerializeString(1, name_part_, msg);
  }

  // Field 2: is_extension
  if (_has_field_[2]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(2, is_extension_, msg);
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}


DescriptorProto::DescriptorProto() = default;
DescriptorProto::~DescriptorProto() = default;
DescriptorProto::DescriptorProto(const DescriptorProto&) = default;
DescriptorProto& DescriptorProto::operator=(const DescriptorProto&) = default;
DescriptorProto::DescriptorProto(DescriptorProto&&) noexcept = default;
DescriptorProto& DescriptorProto::operator=(DescriptorProto&&) = default;

bool DescriptorProto::operator==(const DescriptorProto& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(name_, other.name_)
   && ::protozero::internal::gen_helpers::EqualsField(field_, other.field_)
   && ::protozero::internal::gen_helpers::EqualsField(extension_, other.extension_)
   && ::protozero::internal::gen_helpers::EqualsField(nested_type_, other.nested_type_)
   && ::protozero::internal::gen_helpers::EqualsField(enum_type_, other.enum_type_)
   && ::protozero::internal::gen_helpers::EqualsField(oneof_decl_, other.oneof_decl_)
   && ::protozero::internal::gen_helpers::EqualsField(reserved_range_, other.reserved_range_)
   && ::protozero::internal::gen_helpers::EqualsField(reserved_name_, other.reserved_name_);
}

int DescriptorProto::field_size() const { return static_cast<int>(field_.size()); }
void DescriptorProto::clear_field() { field_.clear(); }
FieldDescriptorProto* DescriptorProto::add_field() { field_.emplace_back(); return &field_.back(); }
int DescriptorProto::extension_size() const { return static_cast<int>(extension_.size()); }
void DescriptorProto::clear_extension() { extension_.clear(); }
FieldDescriptorProto* DescriptorProto::add_extension() { extension_.emplace_back(); return &extension_.back(); }
int DescriptorProto::nested_type_size() const { return static_cast<int>(nested_type_.size()); }
void DescriptorProto::clear_nested_type() { nested_type_.clear(); }
DescriptorProto* DescriptorProto::add_nested_type() { nested_type_.emplace_back(); return &nested_type_.back(); }
int DescriptorProto::enum_type_size() const { return static_cast<int>(enum_type_.size()); }
void DescriptorProto::clear_enum_type() { enum_type_.clear(); }
EnumDescriptorProto* DescriptorProto::add_enum_type() { enum_type_.emplace_back(); return &enum_type_.back(); }
int DescriptorProto::oneof_decl_size() const { return static_cast<int>(oneof_decl_.size()); }
void DescriptorProto::clear_oneof_decl() { oneof_decl_.clear(); }
OneofDescriptorProto* DescriptorProto::add_oneof_decl() { oneof_decl_.emplace_back(); return &oneof_decl_.back(); }
int DescriptorProto::reserved_range_size() const { return static_cast<int>(reserved_range_.size()); }
void DescriptorProto::clear_reserved_range() { reserved_range_.clear(); }
DescriptorProto_ReservedRange* DescriptorProto::add_reserved_range() { reserved_range_.emplace_back(); return &reserved_range_.back(); }
bool DescriptorProto::ParseFromArray(const void* raw, size_t size) {
  field_.clear();
  extension_.clear();
  nested_type_.clear();
  enum_type_.clear();
  oneof_decl_.clear();
  reserved_range_.clear();
  reserved_name_.clear();
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* name */:
        ::protozero::internal::gen_helpers::DeserializeString(field, &name_);
        break;
      case 2 /* field */:
        field_.emplace_back();
        field_.back().ParseFromArray(field.data(), field.size());
        break;
      case 6 /* extension */:
        extension_.emplace_back();
        extension_.back().ParseFromArray(field.data(), field.size());
        break;
      case 3 /* nested_type */:
        nested_type_.emplace_back();
        nested_type_.back().ParseFromArray(field.data(), field.size());
        break;
      case 4 /* enum_type */:
        enum_type_.emplace_back();
        enum_type_.back().ParseFromArray(field.data(), field.size());
        break;
      case 8 /* oneof_decl */:
        oneof_decl_.emplace_back();
        oneof_decl_.back().ParseFromArray(field.data(), field.size());
        break;
      case 9 /* reserved_range */:
        reserved_range_.emplace_back();
        reserved_range_.back().ParseFromArray(field.data(), field.size());
        break;
      case 10 /* reserved_name */:
        reserved_name_.emplace_back();
        ::protozero::internal::gen_helpers::DeserializeString(field, &reserved_name_.back());
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string DescriptorProto::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> DescriptorProto::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void DescriptorProto::Serialize(::protozero::Message* msg) const {
  // Field 1: name
  if (_has_field_[1]) {
    ::protozero::internal::gen_helpers::SerializeString(1, name_, msg);
  }

  // Field 2: field
  for (auto& it : field_) {
    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(2));
  }

  // Field 6: extension
  for (auto& it : extension_) {
    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(6));
  }

  // Field 3: nested_type
  for (auto& it : nested_type_) {
    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(3));
  }

  // Field 4: enum_type
  for (auto& it : enum_type_) {
    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(4));
  }

  // Field 8: oneof_decl
  for (auto& it : oneof_decl_) {
    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(8));
  }

  // Field 9: reserved_range
  for (auto& it : reserved_range_) {
    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(9));
  }

  // Field 10: reserved_name
  for (auto& it : reserved_name_) {
    ::protozero::internal::gen_helpers::SerializeString(10, it, msg);
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}


DescriptorProto_ReservedRange::DescriptorProto_ReservedRange() = default;
DescriptorProto_ReservedRange::~DescriptorProto_ReservedRange() = default;
DescriptorProto_ReservedRange::DescriptorProto_ReservedRange(const DescriptorProto_ReservedRange&) = default;
DescriptorProto_ReservedRange& DescriptorProto_ReservedRange::operator=(const DescriptorProto_ReservedRange&) = default;
DescriptorProto_ReservedRange::DescriptorProto_ReservedRange(DescriptorProto_ReservedRange&&) noexcept = default;
DescriptorProto_ReservedRange& DescriptorProto_ReservedRange::operator=(DescriptorProto_ReservedRange&&) = default;

bool DescriptorProto_ReservedRange::operator==(const DescriptorProto_ReservedRange& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(start_, other.start_)
   && ::protozero::internal::gen_helpers::EqualsField(end_, other.end_);
}

bool DescriptorProto_ReservedRange::ParseFromArray(const void* raw, size_t size) {
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* start */:
        field.get(&start_);
        break;
      case 2 /* end */:
        field.get(&end_);
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string DescriptorProto_ReservedRange::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> DescriptorProto_ReservedRange::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void DescriptorProto_ReservedRange::Serialize(::protozero::Message* msg) const {
  // Field 1: start
  if (_has_field_[1]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(1, start_, msg);
  }

  // Field 2: end
  if (_has_field_[2]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(2, end_, msg);
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}


FileDescriptorProto::FileDescriptorProto() = default;
FileDescriptorProto::~FileDescriptorProto() = default;
FileDescriptorProto::FileDescriptorProto(const FileDescriptorProto&) = default;
FileDescriptorProto& FileDescriptorProto::operator=(const FileDescriptorProto&) = default;
FileDescriptorProto::FileDescriptorProto(FileDescriptorProto&&) noexcept = default;
FileDescriptorProto& FileDescriptorProto::operator=(FileDescriptorProto&&) = default;

bool FileDescriptorProto::operator==(const FileDescriptorProto& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(name_, other.name_)
   && ::protozero::internal::gen_helpers::EqualsField(package_, other.package_)
   && ::protozero::internal::gen_helpers::EqualsField(dependency_, other.dependency_)
   && ::protozero::internal::gen_helpers::EqualsField(public_dependency_, other.public_dependency_)
   && ::protozero::internal::gen_helpers::EqualsField(weak_dependency_, other.weak_dependency_)
   && ::protozero::internal::gen_helpers::EqualsField(message_type_, other.message_type_)
   && ::protozero::internal::gen_helpers::EqualsField(enum_type_, other.enum_type_)
   && ::protozero::internal::gen_helpers::EqualsField(extension_, other.extension_);
}

int FileDescriptorProto::message_type_size() const { return static_cast<int>(message_type_.size()); }
void FileDescriptorProto::clear_message_type() { message_type_.clear(); }
DescriptorProto* FileDescriptorProto::add_message_type() { message_type_.emplace_back(); return &message_type_.back(); }
int FileDescriptorProto::enum_type_size() const { return static_cast<int>(enum_type_.size()); }
void FileDescriptorProto::clear_enum_type() { enum_type_.clear(); }
EnumDescriptorProto* FileDescriptorProto::add_enum_type() { enum_type_.emplace_back(); return &enum_type_.back(); }
int FileDescriptorProto::extension_size() const { return static_cast<int>(extension_.size()); }
void FileDescriptorProto::clear_extension() { extension_.clear(); }
FieldDescriptorProto* FileDescriptorProto::add_extension() { extension_.emplace_back(); return &extension_.back(); }
bool FileDescriptorProto::ParseFromArray(const void* raw, size_t size) {
  dependency_.clear();
  public_dependency_.clear();
  weak_dependency_.clear();
  message_type_.clear();
  enum_type_.clear();
  extension_.clear();
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* name */:
        ::protozero::internal::gen_helpers::DeserializeString(field, &name_);
        break;
      case 2 /* package */:
        ::protozero::internal::gen_helpers::DeserializeString(field, &package_);
        break;
      case 3 /* dependency */:
        dependency_.emplace_back();
        ::protozero::internal::gen_helpers::DeserializeString(field, &dependency_.back());
        break;
      case 10 /* public_dependency */:
        public_dependency_.emplace_back();
        field.get(&public_dependency_.back());
        break;
      case 11 /* weak_dependency */:
        weak_dependency_.emplace_back();
        field.get(&weak_dependency_.back());
        break;
      case 4 /* message_type */:
        message_type_.emplace_back();
        message_type_.back().ParseFromArray(field.data(), field.size());
        break;
      case 5 /* enum_type */:
        enum_type_.emplace_back();
        enum_type_.back().ParseFromArray(field.data(), field.size());
        break;
      case 7 /* extension */:
        extension_.emplace_back();
        extension_.back().ParseFromArray(field.data(), field.size());
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string FileDescriptorProto::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> FileDescriptorProto::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void FileDescriptorProto::Serialize(::protozero::Message* msg) const {
  // Field 1: name
  if (_has_field_[1]) {
    ::protozero::internal::gen_helpers::SerializeString(1, name_, msg);
  }

  // Field 2: package
  if (_has_field_[2]) {
    ::protozero::internal::gen_helpers::SerializeString(2, package_, msg);
  }

  // Field 3: dependency
  for (auto& it : dependency_) {
    ::protozero::internal::gen_helpers::SerializeString(3, it, msg);
  }

  // Field 10: public_dependency
  for (auto& it : public_dependency_) {
    ::protozero::internal::gen_helpers::SerializeVarInt(10, it, msg);
  }

  // Field 11: weak_dependency
  for (auto& it : weak_dependency_) {
    ::protozero::internal::gen_helpers::SerializeVarInt(11, it, msg);
  }

  // Field 4: message_type
  for (auto& it : message_type_) {
    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(4));
  }

  // Field 5: enum_type
  for (auto& it : enum_type_) {
    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(5));
  }

  // Field 7: extension
  for (auto& it : extension_) {
    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(7));
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}


FileDescriptorSet::FileDescriptorSet() = default;
FileDescriptorSet::~FileDescriptorSet() = default;
FileDescriptorSet::FileDescriptorSet(const FileDescriptorSet&) = default;
FileDescriptorSet& FileDescriptorSet::operator=(const FileDescriptorSet&) = default;
FileDescriptorSet::FileDescriptorSet(FileDescriptorSet&&) noexcept = default;
FileDescriptorSet& FileDescriptorSet::operator=(FileDescriptorSet&&) = default;

bool FileDescriptorSet::operator==(const FileDescriptorSet& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(file_, other.file_);
}

int FileDescriptorSet::file_size() const { return static_cast<int>(file_.size()); }
void FileDescriptorSet::clear_file() { file_.clear(); }
FileDescriptorProto* FileDescriptorSet::add_file() { file_.emplace_back(); return &file_.back(); }
bool FileDescriptorSet::ParseFromArray(const void* raw, size_t size) {
  file_.clear();
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* file */:
        file_.emplace_back();
        file_.back().ParseFromArray(field.data(), field.size());
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string FileDescriptorSet::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> FileDescriptorSet::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void FileDescriptorSet::Serialize(::protozero::Message* msg) const {
  // Field 1: file
  for (auto& it : file_) {
    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}

}  // namespace perfetto
}  // namespace protos
}  // namespace gen
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic pop
#endif
// gen_amalgamated begin source: gen/protos/perfetto/common/ftrace_descriptor.gen.cc
// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wfloat-equal"
#endif
// gen_amalgamated expanded: #include "protos/perfetto/common/ftrace_descriptor.gen.h"

namespace perfetto {
namespace protos {
namespace gen {

FtraceDescriptor::FtraceDescriptor() = default;
FtraceDescriptor::~FtraceDescriptor() = default;
FtraceDescriptor::FtraceDescriptor(const FtraceDescriptor&) = default;
FtraceDescriptor& FtraceDescriptor::operator=(const FtraceDescriptor&) = default;
FtraceDescriptor::FtraceDescriptor(FtraceDescriptor&&) noexcept = default;
FtraceDescriptor& FtraceDescriptor::operator=(FtraceDescriptor&&) = default;

bool FtraceDescriptor::operator==(const FtraceDescriptor& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(atrace_categories_, other.atrace_categories_);
}

int FtraceDescriptor::atrace_categories_size() const { return static_cast<int>(atrace_categories_.size()); }
void FtraceDescriptor::clear_atrace_categories() { atrace_categories_.clear(); }
FtraceDescriptor_AtraceCategory* FtraceDescriptor::add_atrace_categories() { atrace_categories_.emplace_back(); return &atrace_categories_.back(); }
bool FtraceDescriptor::ParseFromArray(const void* raw, size_t size) {
  atrace_categories_.clear();
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* atrace_categories */:
        atrace_categories_.emplace_back();
        atrace_categories_.back().ParseFromArray(field.data(), field.size());
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string FtraceDescriptor::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> FtraceDescriptor::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void FtraceDescriptor::Serialize(::protozero::Message* msg) const {
  // Field 1: atrace_categories
  for (auto& it : atrace_categories_) {
    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}


FtraceDescriptor_AtraceCategory::FtraceDescriptor_AtraceCategory() = default;
FtraceDescriptor_AtraceCategory::~FtraceDescriptor_AtraceCategory() = default;
FtraceDescriptor_AtraceCategory::FtraceDescriptor_AtraceCategory(const FtraceDescriptor_AtraceCategory&) = default;
FtraceDescriptor_AtraceCategory& FtraceDescriptor_AtraceCategory::operator=(const FtraceDescriptor_AtraceCategory&) = default;
FtraceDescriptor_AtraceCategory::FtraceDescriptor_AtraceCategory(FtraceDescriptor_AtraceCategory&&) noexcept = default;
FtraceDescriptor_AtraceCategory& FtraceDescriptor_AtraceCategory::operator=(FtraceDescriptor_AtraceCategory&&) = default;

bool FtraceDescriptor_AtraceCategory::operator==(const FtraceDescriptor_AtraceCategory& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(name_, other.name_)
   && ::protozero::internal::gen_helpers::EqualsField(description_, other.description_);
}

bool FtraceDescriptor_AtraceCategory::ParseFromArray(const void* raw, size_t size) {
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* name */:
        ::protozero::internal::gen_helpers::DeserializeString(field, &name_);
        break;
      case 2 /* description */:
        ::protozero::internal::gen_helpers::DeserializeString(field, &description_);
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string FtraceDescriptor_AtraceCategory::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> FtraceDescriptor_AtraceCategory::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void FtraceDescriptor_AtraceCategory::Serialize(::protozero::Message* msg) const {
  // Field 1: name
  if (_has_field_[1]) {
    ::protozero::internal::gen_helpers::SerializeString(1, name_, msg);
  }

  // Field 2: description
  if (_has_field_[2]) {
    ::protozero::internal::gen_helpers::SerializeString(2, description_, msg);
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}

}  // namespace perfetto
}  // namespace protos
}  // namespace gen
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic pop
#endif
// gen_amalgamated begin source: gen/protos/perfetto/common/gpu_counter_descriptor.gen.cc
// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wfloat-equal"
#endif
// gen_amalgamated expanded: #include "protos/perfetto/common/gpu_counter_descriptor.gen.h"

namespace perfetto {
namespace protos {
namespace gen {

GpuCounterDescriptor::GpuCounterDescriptor() = default;
GpuCounterDescriptor::~GpuCounterDescriptor() = default;
GpuCounterDescriptor::GpuCounterDescriptor(const GpuCounterDescriptor&) = default;
GpuCounterDescriptor& GpuCounterDescriptor::operator=(const GpuCounterDescriptor&) = default;
GpuCounterDescriptor::GpuCounterDescriptor(GpuCounterDescriptor&&) noexcept = default;
GpuCounterDescriptor& GpuCounterDescriptor::operator=(GpuCounterDescriptor&&) = default;

bool GpuCounterDescriptor::operator==(const GpuCounterDescriptor& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(specs_, other.specs_)
   && ::protozero::internal::gen_helpers::EqualsField(blocks_, other.blocks_)
   && ::protozero::internal::gen_helpers::EqualsField(min_sampling_period_ns_, other.min_sampling_period_ns_)
   && ::protozero::internal::gen_helpers::EqualsField(max_sampling_period_ns_, other.max_sampling_period_ns_)
   && ::protozero::internal::gen_helpers::EqualsField(supports_instrumented_sampling_, other.supports_instrumented_sampling_);
}

int GpuCounterDescriptor::specs_size() const { return static_cast<int>(specs_.size()); }
void GpuCounterDescriptor::clear_specs() { specs_.clear(); }
GpuCounterDescriptor_GpuCounterSpec* GpuCounterDescriptor::add_specs() { specs_.emplace_back(); return &specs_.back(); }
int GpuCounterDescriptor::blocks_size() const { return static_cast<int>(blocks_.size()); }
void GpuCounterDescriptor::clear_blocks() { blocks_.clear(); }
GpuCounterDescriptor_GpuCounterBlock* GpuCounterDescriptor::add_blocks() { blocks_.emplace_back(); return &blocks_.back(); }
bool GpuCounterDescriptor::ParseFromArray(const void* raw, size_t size) {
  specs_.clear();
  blocks_.clear();
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* specs */:
        specs_.emplace_back();
        specs_.back().ParseFromArray(field.data(), field.size());
        break;
      case 2 /* blocks */:
        blocks_.emplace_back();
        blocks_.back().ParseFromArray(field.data(), field.size());
        break;
      case 3 /* min_sampling_period_ns */:
        field.get(&min_sampling_period_ns_);
        break;
      case 4 /* max_sampling_period_ns */:
        field.get(&max_sampling_period_ns_);
        break;
      case 5 /* supports_instrumented_sampling */:
        field.get(&supports_instrumented_sampling_);
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string GpuCounterDescriptor::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> GpuCounterDescriptor::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void GpuCounterDescriptor::Serialize(::protozero::Message* msg) const {
  // Field 1: specs
  for (auto& it : specs_) {
    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
  }

  // Field 2: blocks
  for (auto& it : blocks_) {
    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(2));
  }

  // Field 3: min_sampling_period_ns
  if (_has_field_[3]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(3, min_sampling_period_ns_, msg);
  }

  // Field 4: max_sampling_period_ns
  if (_has_field_[4]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(4, max_sampling_period_ns_, msg);
  }

  // Field 5: supports_instrumented_sampling
  if (_has_field_[5]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(5, supports_instrumented_sampling_, msg);
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}


GpuCounterDescriptor_GpuCounterBlock::GpuCounterDescriptor_GpuCounterBlock() = default;
GpuCounterDescriptor_GpuCounterBlock::~GpuCounterDescriptor_GpuCounterBlock() = default;
GpuCounterDescriptor_GpuCounterBlock::GpuCounterDescriptor_GpuCounterBlock(const GpuCounterDescriptor_GpuCounterBlock&) = default;
GpuCounterDescriptor_GpuCounterBlock& GpuCounterDescriptor_GpuCounterBlock::operator=(const GpuCounterDescriptor_GpuCounterBlock&) = default;
GpuCounterDescriptor_GpuCounterBlock::GpuCounterDescriptor_GpuCounterBlock(GpuCounterDescriptor_GpuCounterBlock&&) noexcept = default;
GpuCounterDescriptor_GpuCounterBlock& GpuCounterDescriptor_GpuCounterBlock::operator=(GpuCounterDescriptor_GpuCounterBlock&&) = default;

bool GpuCounterDescriptor_GpuCounterBlock::operator==(const GpuCounterDescriptor_GpuCounterBlock& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(block_id_, other.block_id_)
   && ::protozero::internal::gen_helpers::EqualsField(block_capacity_, other.block_capacity_)
   && ::protozero::internal::gen_helpers::EqualsField(name_, other.name_)
   && ::protozero::internal::gen_helpers::EqualsField(description_, other.description_)
   && ::protozero::internal::gen_helpers::EqualsField(counter_ids_, other.counter_ids_);
}

bool GpuCounterDescriptor_GpuCounterBlock::ParseFromArray(const void* raw, size_t size) {
  counter_ids_.clear();
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* block_id */:
        field.get(&block_id_);
        break;
      case 2 /* block_capacity */:
        field.get(&block_capacity_);
        break;
      case 3 /* name */:
        ::protozero::internal::gen_helpers::DeserializeString(field, &name_);
        break;
      case 4 /* description */:
        ::protozero::internal::gen_helpers::DeserializeString(field, &description_);
        break;
      case 5 /* counter_ids */:
        counter_ids_.emplace_back();
        field.get(&counter_ids_.back());
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string GpuCounterDescriptor_GpuCounterBlock::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> GpuCounterDescriptor_GpuCounterBlock::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void GpuCounterDescriptor_GpuCounterBlock::Serialize(::protozero::Message* msg) const {
  // Field 1: block_id
  if (_has_field_[1]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(1, block_id_, msg);
  }

  // Field 2: block_capacity
  if (_has_field_[2]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(2, block_capacity_, msg);
  }

  // Field 3: name
  if (_has_field_[3]) {
    ::protozero::internal::gen_helpers::SerializeString(3, name_, msg);
  }

  // Field 4: description
  if (_has_field_[4]) {
    ::protozero::internal::gen_helpers::SerializeString(4, description_, msg);
  }

  // Field 5: counter_ids
  for (auto& it : counter_ids_) {
    ::protozero::internal::gen_helpers::SerializeVarInt(5, it, msg);
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}


GpuCounterDescriptor_GpuCounterSpec::GpuCounterDescriptor_GpuCounterSpec() = default;
GpuCounterDescriptor_GpuCounterSpec::~GpuCounterDescriptor_GpuCounterSpec() = default;
GpuCounterDescriptor_GpuCounterSpec::GpuCounterDescriptor_GpuCounterSpec(const GpuCounterDescriptor_GpuCounterSpec&) = default;
GpuCounterDescriptor_GpuCounterSpec& GpuCounterDescriptor_GpuCounterSpec::operator=(const GpuCounterDescriptor_GpuCounterSpec&) = default;
GpuCounterDescriptor_GpuCounterSpec::GpuCounterDescriptor_GpuCounterSpec(GpuCounterDescriptor_GpuCounterSpec&&) noexcept = default;
GpuCounterDescriptor_GpuCounterSpec& GpuCounterDescriptor_GpuCounterSpec::operator=(GpuCounterDescriptor_GpuCounterSpec&&) = default;

bool GpuCounterDescriptor_GpuCounterSpec::operator==(const GpuCounterDescriptor_GpuCounterSpec& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(counter_id_, other.counter_id_)
   && ::protozero::internal::gen_helpers::EqualsField(name_, other.name_)
   && ::protozero::internal::gen_helpers::EqualsField(description_, other.description_)
   && ::protozero::internal::gen_helpers::EqualsField(int_peak_value_, other.int_peak_value_)
   && ::protozero::internal::gen_helpers::EqualsField(double_peak_value_, other.double_peak_value_)
   && ::protozero::internal::gen_helpers::EqualsField(numerator_units_, other.numerator_units_)
   && ::protozero::internal::gen_helpers::EqualsField(denominator_units_, other.denominator_units_)
   && ::protozero::internal::gen_helpers::EqualsField(select_by_default_, other.select_by_default_)
   && ::protozero::internal::gen_helpers::EqualsField(groups_, other.groups_);
}

bool GpuCounterDescriptor_GpuCounterSpec::ParseFromArray(const void* raw, size_t size) {
  numerator_units_.clear();
  denominator_units_.clear();
  groups_.clear();
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* counter_id */:
        field.get(&counter_id_);
        break;
      case 2 /* name */:
        ::protozero::internal::gen_helpers::DeserializeString(field, &name_);
        break;
      case 3 /* description */:
        ::protozero::internal::gen_helpers::DeserializeString(field, &description_);
        break;
      case 5 /* int_peak_value */:
        field.get(&int_peak_value_);
        break;
      case 6 /* double_peak_value */:
        field.get(&double_peak_value_);
        break;
      case 7 /* numerator_units */:
        numerator_units_.emplace_back();
        field.get(&numerator_units_.back());
        break;
      case 8 /* denominator_units */:
        denominator_units_.emplace_back();
        field.get(&denominator_units_.back());
        break;
      case 9 /* select_by_default */:
        field.get(&select_by_default_);
        break;
      case 10 /* groups */:
        groups_.emplace_back();
        field.get(&groups_.back());
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string GpuCounterDescriptor_GpuCounterSpec::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> GpuCounterDescriptor_GpuCounterSpec::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void GpuCounterDescriptor_GpuCounterSpec::Serialize(::protozero::Message* msg) const {
  // Field 1: counter_id
  if (_has_field_[1]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(1, counter_id_, msg);
  }

  // Field 2: name
  if (_has_field_[2]) {
    ::protozero::internal::gen_helpers::SerializeString(2, name_, msg);
  }

  // Field 3: description
  if (_has_field_[3]) {
    ::protozero::internal::gen_helpers::SerializeString(3, description_, msg);
  }

  // Field 5: int_peak_value
  if (_has_field_[5]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(5, int_peak_value_, msg);
  }

  // Field 6: double_peak_value
  if (_has_field_[6]) {
    ::protozero::internal::gen_helpers::SerializeFixed(6, double_peak_value_, msg);
  }

  // Field 7: numerator_units
  for (auto& it : numerator_units_) {
    ::protozero::internal::gen_helpers::SerializeVarInt(7, it, msg);
  }

  // Field 8: denominator_units
  for (auto& it : denominator_units_) {
    ::protozero::internal::gen_helpers::SerializeVarInt(8, it, msg);
  }

  // Field 9: select_by_default
  if (_has_field_[9]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(9, select_by_default_, msg);
  }

  // Field 10: groups
  for (auto& it : groups_) {
    ::protozero::internal::gen_helpers::SerializeVarInt(10, it, msg);
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}

}  // namespace perfetto
}  // namespace protos
}  // namespace gen
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic pop
#endif
// gen_amalgamated begin source: gen/protos/perfetto/common/interceptor_descriptor.gen.cc
// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wfloat-equal"
#endif
// gen_amalgamated expanded: #include "protos/perfetto/common/interceptor_descriptor.gen.h"

namespace perfetto {
namespace protos {
namespace gen {

InterceptorDescriptor::InterceptorDescriptor() = default;
InterceptorDescriptor::~InterceptorDescriptor() = default;
InterceptorDescriptor::InterceptorDescriptor(const InterceptorDescriptor&) = default;
InterceptorDescriptor& InterceptorDescriptor::operator=(const InterceptorDescriptor&) = default;
InterceptorDescriptor::InterceptorDescriptor(InterceptorDescriptor&&) noexcept = default;
InterceptorDescriptor& InterceptorDescriptor::operator=(InterceptorDescriptor&&) = default;

bool InterceptorDescriptor::operator==(const InterceptorDescriptor& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(name_, other.name_);
}

bool InterceptorDescriptor::ParseFromArray(const void* raw, size_t size) {
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* name */:
        ::protozero::internal::gen_helpers::DeserializeString(field, &name_);
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string InterceptorDescriptor::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> InterceptorDescriptor::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void InterceptorDescriptor::Serialize(::protozero::Message* msg) const {
  // Field 1: name
  if (_has_field_[1]) {
    ::protozero::internal::gen_helpers::SerializeString(1, name_, msg);
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}

}  // namespace perfetto
}  // namespace protos
}  // namespace gen
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic pop
#endif
// gen_amalgamated begin source: gen/protos/perfetto/common/observable_events.gen.cc
// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wfloat-equal"
#endif
// gen_amalgamated expanded: #include "protos/perfetto/common/observable_events.gen.h"

namespace perfetto {
namespace protos {
namespace gen {

ObservableEvents::ObservableEvents() = default;
ObservableEvents::~ObservableEvents() = default;
ObservableEvents::ObservableEvents(const ObservableEvents&) = default;
ObservableEvents& ObservableEvents::operator=(const ObservableEvents&) = default;
ObservableEvents::ObservableEvents(ObservableEvents&&) noexcept = default;
ObservableEvents& ObservableEvents::operator=(ObservableEvents&&) = default;

bool ObservableEvents::operator==(const ObservableEvents& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(instance_state_changes_, other.instance_state_changes_)
   && ::protozero::internal::gen_helpers::EqualsField(all_data_sources_started_, other.all_data_sources_started_)
   && ::protozero::internal::gen_helpers::EqualsField(clone_trigger_hit_, other.clone_trigger_hit_);
}

int ObservableEvents::instance_state_changes_size() const { return static_cast<int>(instance_state_changes_.size()); }
void ObservableEvents::clear_instance_state_changes() { instance_state_changes_.clear(); }
ObservableEvents_DataSourceInstanceStateChange* ObservableEvents::add_instance_state_changes() { instance_state_changes_.emplace_back(); return &instance_state_changes_.back(); }
bool ObservableEvents::ParseFromArray(const void* raw, size_t size) {
  instance_state_changes_.clear();
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* instance_state_changes */:
        instance_state_changes_.emplace_back();
        instance_state_changes_.back().ParseFromArray(field.data(), field.size());
        break;
      case 2 /* all_data_sources_started */:
        field.get(&all_data_sources_started_);
        break;
      case 3 /* clone_trigger_hit */:
        (*clone_trigger_hit_).ParseFromArray(field.data(), field.size());
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string ObservableEvents::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> ObservableEvents::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void ObservableEvents::Serialize(::protozero::Message* msg) const {
  // Field 1: instance_state_changes
  for (auto& it : instance_state_changes_) {
    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
  }

  // Field 2: all_data_sources_started
  if (_has_field_[2]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(2, all_data_sources_started_, msg);
  }

  // Field 3: clone_trigger_hit
  if (_has_field_[3]) {
    (*clone_trigger_hit_).Serialize(msg->BeginNestedMessage<::protozero::Message>(3));
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}


ObservableEvents_CloneTriggerHit::ObservableEvents_CloneTriggerHit() = default;
ObservableEvents_CloneTriggerHit::~ObservableEvents_CloneTriggerHit() = default;
ObservableEvents_CloneTriggerHit::ObservableEvents_CloneTriggerHit(const ObservableEvents_CloneTriggerHit&) = default;
ObservableEvents_CloneTriggerHit& ObservableEvents_CloneTriggerHit::operator=(const ObservableEvents_CloneTriggerHit&) = default;
ObservableEvents_CloneTriggerHit::ObservableEvents_CloneTriggerHit(ObservableEvents_CloneTriggerHit&&) noexcept = default;
ObservableEvents_CloneTriggerHit& ObservableEvents_CloneTriggerHit::operator=(ObservableEvents_CloneTriggerHit&&) = default;

bool ObservableEvents_CloneTriggerHit::operator==(const ObservableEvents_CloneTriggerHit& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(tracing_session_id_, other.tracing_session_id_);
}

bool ObservableEvents_CloneTriggerHit::ParseFromArray(const void* raw, size_t size) {
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* tracing_session_id */:
        field.get(&tracing_session_id_);
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string ObservableEvents_CloneTriggerHit::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> ObservableEvents_CloneTriggerHit::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void ObservableEvents_CloneTriggerHit::Serialize(::protozero::Message* msg) const {
  // Field 1: tracing_session_id
  if (_has_field_[1]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(1, tracing_session_id_, msg);
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}


ObservableEvents_DataSourceInstanceStateChange::ObservableEvents_DataSourceInstanceStateChange() = default;
ObservableEvents_DataSourceInstanceStateChange::~ObservableEvents_DataSourceInstanceStateChange() = default;
ObservableEvents_DataSourceInstanceStateChange::ObservableEvents_DataSourceInstanceStateChange(const ObservableEvents_DataSourceInstanceStateChange&) = default;
ObservableEvents_DataSourceInstanceStateChange& ObservableEvents_DataSourceInstanceStateChange::operator=(const ObservableEvents_DataSourceInstanceStateChange&) = default;
ObservableEvents_DataSourceInstanceStateChange::ObservableEvents_DataSourceInstanceStateChange(ObservableEvents_DataSourceInstanceStateChange&&) noexcept = default;
ObservableEvents_DataSourceInstanceStateChange& ObservableEvents_DataSourceInstanceStateChange::operator=(ObservableEvents_DataSourceInstanceStateChange&&) = default;

bool ObservableEvents_DataSourceInstanceStateChange::operator==(const ObservableEvents_DataSourceInstanceStateChange& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(producer_name_, other.producer_name_)
   && ::protozero::internal::gen_helpers::EqualsField(data_source_name_, other.data_source_name_)
   && ::protozero::internal::gen_helpers::EqualsField(state_, other.state_);
}

bool ObservableEvents_DataSourceInstanceStateChange::ParseFromArray(const void* raw, size_t size) {
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* producer_name */:
        ::protozero::internal::gen_helpers::DeserializeString(field, &producer_name_);
        break;
      case 2 /* data_source_name */:
        ::protozero::internal::gen_helpers::DeserializeString(field, &data_source_name_);
        break;
      case 3 /* state */:
        field.get(&state_);
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string ObservableEvents_DataSourceInstanceStateChange::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> ObservableEvents_DataSourceInstanceStateChange::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void ObservableEvents_DataSourceInstanceStateChange::Serialize(::protozero::Message* msg) const {
  // Field 1: producer_name
  if (_has_field_[1]) {
    ::protozero::internal::gen_helpers::SerializeString(1, producer_name_, msg);
  }

  // Field 2: data_source_name
  if (_has_field_[2]) {
    ::protozero::internal::gen_helpers::SerializeString(2, data_source_name_, msg);
  }

  // Field 3: state
  if (_has_field_[3]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(3, state_, msg);
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}

}  // namespace perfetto
}  // namespace protos
}  // namespace gen
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic pop
#endif
// gen_amalgamated begin source: gen/protos/perfetto/common/perf_events.gen.cc
// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wfloat-equal"
#endif
// gen_amalgamated expanded: #include "protos/perfetto/common/perf_events.gen.h"

namespace perfetto {
namespace protos {
namespace gen {

PerfEvents::PerfEvents() = default;
PerfEvents::~PerfEvents() = default;
PerfEvents::PerfEvents(const PerfEvents&) = default;
PerfEvents& PerfEvents::operator=(const PerfEvents&) = default;
PerfEvents::PerfEvents(PerfEvents&&) noexcept = default;
PerfEvents& PerfEvents::operator=(PerfEvents&&) = default;

bool PerfEvents::operator==(const PerfEvents& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_);
}

bool PerfEvents::ParseFromArray(const void* raw, size_t size) {
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string PerfEvents::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> PerfEvents::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void PerfEvents::Serialize(::protozero::Message* msg) const {
  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}


PerfEvents_RawEvent::PerfEvents_RawEvent() = default;
PerfEvents_RawEvent::~PerfEvents_RawEvent() = default;
PerfEvents_RawEvent::PerfEvents_RawEvent(const PerfEvents_RawEvent&) = default;
PerfEvents_RawEvent& PerfEvents_RawEvent::operator=(const PerfEvents_RawEvent&) = default;
PerfEvents_RawEvent::PerfEvents_RawEvent(PerfEvents_RawEvent&&) noexcept = default;
PerfEvents_RawEvent& PerfEvents_RawEvent::operator=(PerfEvents_RawEvent&&) = default;

bool PerfEvents_RawEvent::operator==(const PerfEvents_RawEvent& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(type_, other.type_)
   && ::protozero::internal::gen_helpers::EqualsField(config_, other.config_)
   && ::protozero::internal::gen_helpers::EqualsField(config1_, other.config1_)
   && ::protozero::internal::gen_helpers::EqualsField(config2_, other.config2_);
}

bool PerfEvents_RawEvent::ParseFromArray(const void* raw, size_t size) {
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* type */:
        field.get(&type_);
        break;
      case 2 /* config */:
        field.get(&config_);
        break;
      case 3 /* config1 */:
        field.get(&config1_);
        break;
      case 4 /* config2 */:
        field.get(&config2_);
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string PerfEvents_RawEvent::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> PerfEvents_RawEvent::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void PerfEvents_RawEvent::Serialize(::protozero::Message* msg) const {
  // Field 1: type
  if (_has_field_[1]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(1, type_, msg);
  }

  // Field 2: config
  if (_has_field_[2]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(2, config_, msg);
  }

  // Field 3: config1
  if (_has_field_[3]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(3, config1_, msg);
  }

  // Field 4: config2
  if (_has_field_[4]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(4, config2_, msg);
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}


PerfEvents_Tracepoint::PerfEvents_Tracepoint() = default;
PerfEvents_Tracepoint::~PerfEvents_Tracepoint() = default;
PerfEvents_Tracepoint::PerfEvents_Tracepoint(const PerfEvents_Tracepoint&) = default;
PerfEvents_Tracepoint& PerfEvents_Tracepoint::operator=(const PerfEvents_Tracepoint&) = default;
PerfEvents_Tracepoint::PerfEvents_Tracepoint(PerfEvents_Tracepoint&&) noexcept = default;
PerfEvents_Tracepoint& PerfEvents_Tracepoint::operator=(PerfEvents_Tracepoint&&) = default;

bool PerfEvents_Tracepoint::operator==(const PerfEvents_Tracepoint& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(name_, other.name_)
   && ::protozero::internal::gen_helpers::EqualsField(filter_, other.filter_);
}

bool PerfEvents_Tracepoint::ParseFromArray(const void* raw, size_t size) {
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* name */:
        ::protozero::internal::gen_helpers::DeserializeString(field, &name_);
        break;
      case 2 /* filter */:
        ::protozero::internal::gen_helpers::DeserializeString(field, &filter_);
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string PerfEvents_Tracepoint::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> PerfEvents_Tracepoint::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void PerfEvents_Tracepoint::Serialize(::protozero::Message* msg) const {
  // Field 1: name
  if (_has_field_[1]) {
    ::protozero::internal::gen_helpers::SerializeString(1, name_, msg);
  }

  // Field 2: filter
  if (_has_field_[2]) {
    ::protozero::internal::gen_helpers::SerializeString(2, filter_, msg);
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}


PerfEvents_Timebase::PerfEvents_Timebase() = default;
PerfEvents_Timebase::~PerfEvents_Timebase() = default;
PerfEvents_Timebase::PerfEvents_Timebase(const PerfEvents_Timebase&) = default;
PerfEvents_Timebase& PerfEvents_Timebase::operator=(const PerfEvents_Timebase&) = default;
PerfEvents_Timebase::PerfEvents_Timebase(PerfEvents_Timebase&&) noexcept = default;
PerfEvents_Timebase& PerfEvents_Timebase::operator=(PerfEvents_Timebase&&) = default;

bool PerfEvents_Timebase::operator==(const PerfEvents_Timebase& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(frequency_, other.frequency_)
   && ::protozero::internal::gen_helpers::EqualsField(period_, other.period_)
   && ::protozero::internal::gen_helpers::EqualsField(counter_, other.counter_)
   && ::protozero::internal::gen_helpers::EqualsField(tracepoint_, other.tracepoint_)
   && ::protozero::internal::gen_helpers::EqualsField(raw_event_, other.raw_event_)
   && ::protozero::internal::gen_helpers::EqualsField(timestamp_clock_, other.timestamp_clock_)
   && ::protozero::internal::gen_helpers::EqualsField(name_, other.name_);
}

bool PerfEvents_Timebase::ParseFromArray(const void* raw, size_t size) {
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 2 /* frequency */:
        field.get(&frequency_);
        break;
      case 1 /* period */:
        field.get(&period_);
        break;
      case 4 /* counter */:
        field.get(&counter_);
        break;
      case 3 /* tracepoint */:
        (*tracepoint_).ParseFromArray(field.data(), field.size());
        break;
      case 5 /* raw_event */:
        (*raw_event_).ParseFromArray(field.data(), field.size());
        break;
      case 11 /* timestamp_clock */:
        field.get(&timestamp_clock_);
        break;
      case 10 /* name */:
        ::protozero::internal::gen_helpers::DeserializeString(field, &name_);
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string PerfEvents_Timebase::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> PerfEvents_Timebase::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void PerfEvents_Timebase::Serialize(::protozero::Message* msg) const {
  // Field 2: frequency
  if (_has_field_[2]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(2, frequency_, msg);
  }

  // Field 1: period
  if (_has_field_[1]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(1, period_, msg);
  }

  // Field 4: counter
  if (_has_field_[4]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(4, counter_, msg);
  }

  // Field 3: tracepoint
  if (_has_field_[3]) {
    (*tracepoint_).Serialize(msg->BeginNestedMessage<::protozero::Message>(3));
  }

  // Field 5: raw_event
  if (_has_field_[5]) {
    (*raw_event_).Serialize(msg->BeginNestedMessage<::protozero::Message>(5));
  }

  // Field 11: timestamp_clock
  if (_has_field_[11]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(11, timestamp_clock_, msg);
  }

  // Field 10: name
  if (_has_field_[10]) {
    ::protozero::internal::gen_helpers::SerializeString(10, name_, msg);
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}

}  // namespace perfetto
}  // namespace protos
}  // namespace gen
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic pop
#endif
// gen_amalgamated begin source: gen/protos/perfetto/common/protolog_common.gen.cc
// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wfloat-equal"
#endif
// gen_amalgamated expanded: #include "protos/perfetto/common/protolog_common.gen.h"

namespace perfetto {
namespace protos {
namespace gen {
}  // namespace perfetto
}  // namespace protos
}  // namespace gen
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic pop
#endif
// gen_amalgamated begin source: gen/protos/perfetto/common/sys_stats_counters.gen.cc
// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wfloat-equal"
#endif
// gen_amalgamated expanded: #include "protos/perfetto/common/sys_stats_counters.gen.h"

namespace perfetto {
namespace protos {
namespace gen {
}  // namespace perfetto
}  // namespace protos
}  // namespace gen
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic pop
#endif
// gen_amalgamated begin source: gen/protos/perfetto/common/trace_stats.gen.cc
// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wfloat-equal"
#endif
// gen_amalgamated expanded: #include "protos/perfetto/common/trace_stats.gen.h"

namespace perfetto {
namespace protos {
namespace gen {

TraceStats::TraceStats() = default;
TraceStats::~TraceStats() = default;
TraceStats::TraceStats(const TraceStats&) = default;
TraceStats& TraceStats::operator=(const TraceStats&) = default;
TraceStats::TraceStats(TraceStats&&) noexcept = default;
TraceStats& TraceStats::operator=(TraceStats&&) = default;

bool TraceStats::operator==(const TraceStats& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(buffer_stats_, other.buffer_stats_)
   && ::protozero::internal::gen_helpers::EqualsField(chunk_payload_histogram_def_, other.chunk_payload_histogram_def_)
   && ::protozero::internal::gen_helpers::EqualsField(writer_stats_, other.writer_stats_)
   && ::protozero::internal::gen_helpers::EqualsField(producers_connected_, other.producers_connected_)
   && ::protozero::internal::gen_helpers::EqualsField(producers_seen_, other.producers_seen_)
   && ::protozero::internal::gen_helpers::EqualsField(data_sources_registered_, other.data_sources_registered_)
   && ::protozero::internal::gen_helpers::EqualsField(data_sources_seen_, other.data_sources_seen_)
   && ::protozero::internal::gen_helpers::EqualsField(tracing_sessions_, other.tracing_sessions_)
   && ::protozero::internal::gen_helpers::EqualsField(total_buffers_, other.total_buffers_)
   && ::protozero::internal::gen_helpers::EqualsField(chunks_discarded_, other.chunks_discarded_)
   && ::protozero::internal::gen_helpers::EqualsField(patches_discarded_, other.patches_discarded_)
   && ::protozero::internal::gen_helpers::EqualsField(invalid_packets_, other.invalid_packets_)
   && ::protozero::internal::gen_helpers::EqualsField(filter_stats_, other.filter_stats_)
   && ::protozero::internal::gen_helpers::EqualsField(flushes_requested_, other.flushes_requested_)
   && ::protozero::internal::gen_helpers::EqualsField(flushes_succeeded_, other.flushes_succeeded_)
   && ::protozero::internal::gen_helpers::EqualsField(flushes_failed_, other.flushes_failed_)
   && ::protozero::internal::gen_helpers::EqualsField(final_flush_outcome_, other.final_flush_outcome_);
}

int TraceStats::buffer_stats_size() const { return static_cast<int>(buffer_stats_.size()); }
void TraceStats::clear_buffer_stats() { buffer_stats_.clear(); }
TraceStats_BufferStats* TraceStats::add_buffer_stats() { buffer_stats_.emplace_back(); return &buffer_stats_.back(); }
int TraceStats::writer_stats_size() const { return static_cast<int>(writer_stats_.size()); }
void TraceStats::clear_writer_stats() { writer_stats_.clear(); }
TraceStats_WriterStats* TraceStats::add_writer_stats() { writer_stats_.emplace_back(); return &writer_stats_.back(); }
bool TraceStats::ParseFromArray(const void* raw, size_t size) {
  buffer_stats_.clear();
  chunk_payload_histogram_def_.clear();
  writer_stats_.clear();
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* buffer_stats */:
        buffer_stats_.emplace_back();
        buffer_stats_.back().ParseFromArray(field.data(), field.size());
        break;
      case 17 /* chunk_payload_histogram_def */:
        chunk_payload_histogram_def_.emplace_back();
        field.get(&chunk_payload_histogram_def_.back());
        break;
      case 18 /* writer_stats */:
        writer_stats_.emplace_back();
        writer_stats_.back().ParseFromArray(field.data(), field.size());
        break;
      case 2 /* producers_connected */:
        field.get(&producers_connected_);
        break;
      case 3 /* producers_seen */:
        field.get(&producers_seen_);
        break;
      case 4 /* data_sources_registered */:
        field.get(&data_sources_registered_);
        break;
      case 5 /* data_sources_seen */:
        field.get(&data_sources_seen_);
        break;
      case 6 /* tracing_sessions */:
        field.get(&tracing_sessions_);
        break;
      case 7 /* total_buffers */:
        field.get(&total_buffers_);
        break;
      case 8 /* chunks_discarded */:
        field.get(&chunks_discarded_);
        break;
      case 9 /* patches_discarded */:
        field.get(&patches_discarded_);
        break;
      case 10 /* invalid_packets */:
        field.get(&invalid_packets_);
        break;
      case 11 /* filter_stats */:
        (*filter_stats_).ParseFromArray(field.data(), field.size());
        break;
      case 12 /* flushes_requested */:
        field.get(&flushes_requested_);
        break;
      case 13 /* flushes_succeeded */:
        field.get(&flushes_succeeded_);
        break;
      case 14 /* flushes_failed */:
        field.get(&flushes_failed_);
        break;
      case 15 /* final_flush_outcome */:
        field.get(&final_flush_outcome_);
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string TraceStats::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> TraceStats::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void TraceStats::Serialize(::protozero::Message* msg) const {
  // Field 1: buffer_stats
  for (auto& it : buffer_stats_) {
    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
  }

  // Field 17: chunk_payload_histogram_def
  for (auto& it : chunk_payload_histogram_def_) {
    ::protozero::internal::gen_helpers::SerializeVarInt(17, it, msg);
  }

  // Field 18: writer_stats
  for (auto& it : writer_stats_) {
    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(18));
  }

  // Field 2: producers_connected
  if (_has_field_[2]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(2, producers_connected_, msg);
  }

  // Field 3: producers_seen
  if (_has_field_[3]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(3, producers_seen_, msg);
  }

  // Field 4: data_sources_registered
  if (_has_field_[4]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(4, data_sources_registered_, msg);
  }

  // Field 5: data_sources_seen
  if (_has_field_[5]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(5, data_sources_seen_, msg);
  }

  // Field 6: tracing_sessions
  if (_has_field_[6]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(6, tracing_sessions_, msg);
  }

  // Field 7: total_buffers
  if (_has_field_[7]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(7, total_buffers_, msg);
  }

  // Field 8: chunks_discarded
  if (_has_field_[8]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(8, chunks_discarded_, msg);
  }

  // Field 9: patches_discarded
  if (_has_field_[9]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(9, patches_discarded_, msg);
  }

  // Field 10: invalid_packets
  if (_has_field_[10]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(10, invalid_packets_, msg);
  }

  // Field 11: filter_stats
  if (_has_field_[11]) {
    (*filter_stats_).Serialize(msg->BeginNestedMessage<::protozero::Message>(11));
  }

  // Field 12: flushes_requested
  if (_has_field_[12]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(12, flushes_requested_, msg);
  }

  // Field 13: flushes_succeeded
  if (_has_field_[13]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(13, flushes_succeeded_, msg);
  }

  // Field 14: flushes_failed
  if (_has_field_[14]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(14, flushes_failed_, msg);
  }

  // Field 15: final_flush_outcome
  if (_has_field_[15]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(15, final_flush_outcome_, msg);
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}


TraceStats_FilterStats::TraceStats_FilterStats() = default;
TraceStats_FilterStats::~TraceStats_FilterStats() = default;
TraceStats_FilterStats::TraceStats_FilterStats(const TraceStats_FilterStats&) = default;
TraceStats_FilterStats& TraceStats_FilterStats::operator=(const TraceStats_FilterStats&) = default;
TraceStats_FilterStats::TraceStats_FilterStats(TraceStats_FilterStats&&) noexcept = default;
TraceStats_FilterStats& TraceStats_FilterStats::operator=(TraceStats_FilterStats&&) = default;

bool TraceStats_FilterStats::operator==(const TraceStats_FilterStats& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(input_packets_, other.input_packets_)
   && ::protozero::internal::gen_helpers::EqualsField(input_bytes_, other.input_bytes_)
   && ::protozero::internal::gen_helpers::EqualsField(output_bytes_, other.output_bytes_)
   && ::protozero::internal::gen_helpers::EqualsField(errors_, other.errors_)
   && ::protozero::internal::gen_helpers::EqualsField(time_taken_ns_, other.time_taken_ns_)
   && ::protozero::internal::gen_helpers::EqualsField(bytes_discarded_per_buffer_, other.bytes_discarded_per_buffer_);
}

bool TraceStats_FilterStats::ParseFromArray(const void* raw, size_t size) {
  bytes_discarded_per_buffer_.clear();
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* input_packets */:
        field.get(&input_packets_);
        break;
      case 2 /* input_bytes */:
        field.get(&input_bytes_);
        break;
      case 3 /* output_bytes */:
        field.get(&output_bytes_);
        break;
      case 4 /* errors */:
        field.get(&errors_);
        break;
      case 5 /* time_taken_ns */:
        field.get(&time_taken_ns_);
        break;
      case 20 /* bytes_discarded_per_buffer */:
        bytes_discarded_per_buffer_.emplace_back();
        field.get(&bytes_discarded_per_buffer_.back());
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string TraceStats_FilterStats::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> TraceStats_FilterStats::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void TraceStats_FilterStats::Serialize(::protozero::Message* msg) const {
  // Field 1: input_packets
  if (_has_field_[1]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(1, input_packets_, msg);
  }

  // Field 2: input_bytes
  if (_has_field_[2]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(2, input_bytes_, msg);
  }

  // Field 3: output_bytes
  if (_has_field_[3]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(3, output_bytes_, msg);
  }

  // Field 4: errors
  if (_has_field_[4]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(4, errors_, msg);
  }

  // Field 5: time_taken_ns
  if (_has_field_[5]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(5, time_taken_ns_, msg);
  }

  // Field 20: bytes_discarded_per_buffer
  for (auto& it : bytes_discarded_per_buffer_) {
    ::protozero::internal::gen_helpers::SerializeVarInt(20, it, msg);
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}


TraceStats_WriterStats::TraceStats_WriterStats() = default;
TraceStats_WriterStats::~TraceStats_WriterStats() = default;
TraceStats_WriterStats::TraceStats_WriterStats(const TraceStats_WriterStats&) = default;
TraceStats_WriterStats& TraceStats_WriterStats::operator=(const TraceStats_WriterStats&) = default;
TraceStats_WriterStats::TraceStats_WriterStats(TraceStats_WriterStats&&) noexcept = default;
TraceStats_WriterStats& TraceStats_WriterStats::operator=(TraceStats_WriterStats&&) = default;

bool TraceStats_WriterStats::operator==(const TraceStats_WriterStats& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(sequence_id_, other.sequence_id_)
   && ::protozero::internal::gen_helpers::EqualsField(buffer_, other.buffer_)
   && ::protozero::internal::gen_helpers::EqualsField(chunk_payload_histogram_counts_, other.chunk_payload_histogram_counts_)
   && ::protozero::internal::gen_helpers::EqualsField(chunk_payload_histogram_sum_, other.chunk_payload_histogram_sum_);
}

bool TraceStats_WriterStats::ParseFromArray(const void* raw, size_t size) {
  chunk_payload_histogram_counts_.clear();
  chunk_payload_histogram_sum_.clear();
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* sequence_id */:
        field.get(&sequence_id_);
        break;
      case 4 /* buffer */:
        field.get(&buffer_);
        break;
      case 2 /* chunk_payload_histogram_counts */:
        if (!::protozero::internal::gen_helpers::DeserializePackedRepeated<::protozero::proto_utils::ProtoWireType::kVarInt, uint64_t>(field, &chunk_payload_histogram_counts_)) {
          packed_error = true;}
        break;
      case 3 /* chunk_payload_histogram_sum */:
        if (!::protozero::internal::gen_helpers::DeserializePackedRepeated<::protozero::proto_utils::ProtoWireType::kVarInt, int64_t>(field, &chunk_payload_histogram_sum_)) {
          packed_error = true;}
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string TraceStats_WriterStats::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> TraceStats_WriterStats::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void TraceStats_WriterStats::Serialize(::protozero::Message* msg) const {
  // Field 1: sequence_id
  if (_has_field_[1]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(1, sequence_id_, msg);
  }

  // Field 4: buffer
  if (_has_field_[4]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(4, buffer_, msg);
  }

  // Field 2: chunk_payload_histogram_counts
  {
    ::protozero::PackedVarInt pack;
    for (auto& it : chunk_payload_histogram_counts_)
      pack.Append(it);
    msg->AppendBytes(2, pack.data(), pack.size());
  }

  // Field 3: chunk_payload_histogram_sum
  {
    ::protozero::PackedVarInt pack;
    for (auto& it : chunk_payload_histogram_sum_)
      pack.Append(it);
    msg->AppendBytes(3, pack.data(), pack.size());
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}


TraceStats_BufferStats::TraceStats_BufferStats() = default;
TraceStats_BufferStats::~TraceStats_BufferStats() = default;
TraceStats_BufferStats::TraceStats_BufferStats(const TraceStats_BufferStats&) = default;
TraceStats_BufferStats& TraceStats_BufferStats::operator=(const TraceStats_BufferStats&) = default;
TraceStats_BufferStats::TraceStats_BufferStats(TraceStats_BufferStats&&) noexcept = default;
TraceStats_BufferStats& TraceStats_BufferStats::operator=(TraceStats_BufferStats&&) = default;

bool TraceStats_BufferStats::operator==(const TraceStats_BufferStats& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(buffer_size_, other.buffer_size_)
   && ::protozero::internal::gen_helpers::EqualsField(bytes_written_, other.bytes_written_)
   && ::protozero::internal::gen_helpers::EqualsField(bytes_overwritten_, other.bytes_overwritten_)
   && ::protozero::internal::gen_helpers::EqualsField(bytes_read_, other.bytes_read_)
   && ::protozero::internal::gen_helpers::EqualsField(padding_bytes_written_, other.padding_bytes_written_)
   && ::protozero::internal::gen_helpers::EqualsField(padding_bytes_cleared_, other.padding_bytes_cleared_)
   && ::protozero::internal::gen_helpers::EqualsField(chunks_written_, other.chunks_written_)
   && ::protozero::internal::gen_helpers::EqualsField(chunks_rewritten_, other.chunks_rewritten_)
   && ::protozero::internal::gen_helpers::EqualsField(chunks_overwritten_, other.chunks_overwritten_)
   && ::protozero::internal::gen_helpers::EqualsField(chunks_discarded_, other.chunks_discarded_)
   && ::protozero::internal::gen_helpers::EqualsField(chunks_read_, other.chunks_read_)
   && ::protozero::internal::gen_helpers::EqualsField(chunks_committed_out_of_order_, other.chunks_committed_out_of_order_)
   && ::protozero::internal::gen_helpers::EqualsField(write_wrap_count_, other.write_wrap_count_)
   && ::protozero::internal::gen_helpers::EqualsField(patches_succeeded_, other.patches_succeeded_)
   && ::protozero::internal::gen_helpers::EqualsField(patches_failed_, other.patches_failed_)
   && ::protozero::internal::gen_helpers::EqualsField(readaheads_succeeded_, other.readaheads_succeeded_)
   && ::protozero::internal::gen_helpers::EqualsField(readaheads_failed_, other.readaheads_failed_)
   && ::protozero::internal::gen_helpers::EqualsField(abi_violations_, other.abi_violations_)
   && ::protozero::internal::gen_helpers::EqualsField(trace_writer_packet_loss_, other.trace_writer_packet_loss_);
}

bool TraceStats_BufferStats::ParseFromArray(const void* raw, size_t size) {
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 12 /* buffer_size */:
        field.get(&buffer_size_);
        break;
      case 1 /* bytes_written */:
        field.get(&bytes_written_);
        break;
      case 13 /* bytes_overwritten */:
        field.get(&bytes_overwritten_);
        break;
      case 14 /* bytes_read */:
        field.get(&bytes_read_);
        break;
      case 15 /* padding_bytes_written */:
        field.get(&padding_bytes_written_);
        break;
      case 16 /* padding_bytes_cleared */:
        field.get(&padding_bytes_cleared_);
        break;
      case 2 /* chunks_written */:
        field.get(&chunks_written_);
        break;
      case 10 /* chunks_rewritten */:
        field.get(&chunks_rewritten_);
        break;
      case 3 /* chunks_overwritten */:
        field.get(&chunks_overwritten_);
        break;
      case 18 /* chunks_discarded */:
        field.get(&chunks_discarded_);
        break;
      case 17 /* chunks_read */:
        field.get(&chunks_read_);
        break;
      case 11 /* chunks_committed_out_of_order */:
        field.get(&chunks_committed_out_of_order_);
        break;
      case 4 /* write_wrap_count */:
        field.get(&write_wrap_count_);
        break;
      case 5 /* patches_succeeded */:
        field.get(&patches_succeeded_);
        break;
      case 6 /* patches_failed */:
        field.get(&patches_failed_);
        break;
      case 7 /* readaheads_succeeded */:
        field.get(&readaheads_succeeded_);
        break;
      case 8 /* readaheads_failed */:
        field.get(&readaheads_failed_);
        break;
      case 9 /* abi_violations */:
        field.get(&abi_violations_);
        break;
      case 19 /* trace_writer_packet_loss */:
        field.get(&trace_writer_packet_loss_);
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string TraceStats_BufferStats::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> TraceStats_BufferStats::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void TraceStats_BufferStats::Serialize(::protozero::Message* msg) const {
  // Field 12: buffer_size
  if (_has_field_[12]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(12, buffer_size_, msg);
  }

  // Field 1: bytes_written
  if (_has_field_[1]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(1, bytes_written_, msg);
  }

  // Field 13: bytes_overwritten
  if (_has_field_[13]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(13, bytes_overwritten_, msg);
  }

  // Field 14: bytes_read
  if (_has_field_[14]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(14, bytes_read_, msg);
  }

  // Field 15: padding_bytes_written
  if (_has_field_[15]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(15, padding_bytes_written_, msg);
  }

  // Field 16: padding_bytes_cleared
  if (_has_field_[16]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(16, padding_bytes_cleared_, msg);
  }

  // Field 2: chunks_written
  if (_has_field_[2]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(2, chunks_written_, msg);
  }

  // Field 10: chunks_rewritten
  if (_has_field_[10]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(10, chunks_rewritten_, msg);
  }

  // Field 3: chunks_overwritten
  if (_has_field_[3]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(3, chunks_overwritten_, msg);
  }

  // Field 18: chunks_discarded
  if (_has_field_[18]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(18, chunks_discarded_, msg);
  }

  // Field 17: chunks_read
  if (_has_field_[17]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(17, chunks_read_, msg);
  }

  // Field 11: chunks_committed_out_of_order
  if (_has_field_[11]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(11, chunks_committed_out_of_order_, msg);
  }

  // Field 4: write_wrap_count
  if (_has_field_[4]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(4, write_wrap_count_, msg);
  }

  // Field 5: patches_succeeded
  if (_has_field_[5]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(5, patches_succeeded_, msg);
  }

  // Field 6: patches_failed
  if (_has_field_[6]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(6, patches_failed_, msg);
  }

  // Field 7: readaheads_succeeded
  if (_has_field_[7]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(7, readaheads_succeeded_, msg);
  }

  // Field 8: readaheads_failed
  if (_has_field_[8]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(8, readaheads_failed_, msg);
  }

  // Field 9: abi_violations
  if (_has_field_[9]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(9, abi_violations_, msg);
  }

  // Field 19: trace_writer_packet_loss
  if (_has_field_[19]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(19, trace_writer_packet_loss_, msg);
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}

}  // namespace perfetto
}  // namespace protos
}  // namespace gen
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic pop
#endif
// gen_amalgamated begin source: gen/protos/perfetto/common/tracing_service_capabilities.gen.cc
// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wfloat-equal"
#endif
// gen_amalgamated expanded: #include "protos/perfetto/common/tracing_service_capabilities.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/common/observable_events.gen.h"

namespace perfetto {
namespace protos {
namespace gen {

TracingServiceCapabilities::TracingServiceCapabilities() = default;
TracingServiceCapabilities::~TracingServiceCapabilities() = default;
TracingServiceCapabilities::TracingServiceCapabilities(const TracingServiceCapabilities&) = default;
TracingServiceCapabilities& TracingServiceCapabilities::operator=(const TracingServiceCapabilities&) = default;
TracingServiceCapabilities::TracingServiceCapabilities(TracingServiceCapabilities&&) noexcept = default;
TracingServiceCapabilities& TracingServiceCapabilities::operator=(TracingServiceCapabilities&&) = default;

bool TracingServiceCapabilities::operator==(const TracingServiceCapabilities& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(has_query_capabilities_, other.has_query_capabilities_)
   && ::protozero::internal::gen_helpers::EqualsField(observable_events_, other.observable_events_)
   && ::protozero::internal::gen_helpers::EqualsField(has_trace_config_output_path_, other.has_trace_config_output_path_)
   && ::protozero::internal::gen_helpers::EqualsField(has_clone_session_, other.has_clone_session_);
}

bool TracingServiceCapabilities::ParseFromArray(const void* raw, size_t size) {
  observable_events_.clear();
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* has_query_capabilities */:
        field.get(&has_query_capabilities_);
        break;
      case 2 /* observable_events */:
        observable_events_.emplace_back();
        field.get(&observable_events_.back());
        break;
      case 3 /* has_trace_config_output_path */:
        field.get(&has_trace_config_output_path_);
        break;
      case 4 /* has_clone_session */:
        field.get(&has_clone_session_);
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string TracingServiceCapabilities::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> TracingServiceCapabilities::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void TracingServiceCapabilities::Serialize(::protozero::Message* msg) const {
  // Field 1: has_query_capabilities
  if (_has_field_[1]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(1, has_query_capabilities_, msg);
  }

  // Field 2: observable_events
  for (auto& it : observable_events_) {
    ::protozero::internal::gen_helpers::SerializeVarInt(2, it, msg);
  }

  // Field 3: has_trace_config_output_path
  if (_has_field_[3]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(3, has_trace_config_output_path_, msg);
  }

  // Field 4: has_clone_session
  if (_has_field_[4]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(4, has_clone_session_, msg);
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}

}  // namespace perfetto
}  // namespace protos
}  // namespace gen
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic pop
#endif
// gen_amalgamated begin source: gen/protos/perfetto/common/tracing_service_state.gen.cc
// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wfloat-equal"
#endif
// gen_amalgamated expanded: #include "protos/perfetto/common/tracing_service_state.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/common/data_source_descriptor.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/common/track_event_descriptor.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/common/gpu_counter_descriptor.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/common/ftrace_descriptor.gen.h"

namespace perfetto {
namespace protos {
namespace gen {

TracingServiceState::TracingServiceState() = default;
TracingServiceState::~TracingServiceState() = default;
TracingServiceState::TracingServiceState(const TracingServiceState&) = default;
TracingServiceState& TracingServiceState::operator=(const TracingServiceState&) = default;
TracingServiceState::TracingServiceState(TracingServiceState&&) noexcept = default;
TracingServiceState& TracingServiceState::operator=(TracingServiceState&&) = default;

bool TracingServiceState::operator==(const TracingServiceState& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(producers_, other.producers_)
   && ::protozero::internal::gen_helpers::EqualsField(data_sources_, other.data_sources_)
   && ::protozero::internal::gen_helpers::EqualsField(tracing_sessions_, other.tracing_sessions_)
   && ::protozero::internal::gen_helpers::EqualsField(supports_tracing_sessions_, other.supports_tracing_sessions_)
   && ::protozero::internal::gen_helpers::EqualsField(num_sessions_, other.num_sessions_)
   && ::protozero::internal::gen_helpers::EqualsField(num_sessions_started_, other.num_sessions_started_)
   && ::protozero::internal::gen_helpers::EqualsField(tracing_service_version_, other.tracing_service_version_);
}

int TracingServiceState::producers_size() const { return static_cast<int>(producers_.size()); }
void TracingServiceState::clear_producers() { producers_.clear(); }
TracingServiceState_Producer* TracingServiceState::add_producers() { producers_.emplace_back(); return &producers_.back(); }
int TracingServiceState::data_sources_size() const { return static_cast<int>(data_sources_.size()); }
void TracingServiceState::clear_data_sources() { data_sources_.clear(); }
TracingServiceState_DataSource* TracingServiceState::add_data_sources() { data_sources_.emplace_back(); return &data_sources_.back(); }
int TracingServiceState::tracing_sessions_size() const { return static_cast<int>(tracing_sessions_.size()); }
void TracingServiceState::clear_tracing_sessions() { tracing_sessions_.clear(); }
TracingServiceState_TracingSession* TracingServiceState::add_tracing_sessions() { tracing_sessions_.emplace_back(); return &tracing_sessions_.back(); }
bool TracingServiceState::ParseFromArray(const void* raw, size_t size) {
  producers_.clear();
  data_sources_.clear();
  tracing_sessions_.clear();
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* producers */:
        producers_.emplace_back();
        producers_.back().ParseFromArray(field.data(), field.size());
        break;
      case 2 /* data_sources */:
        data_sources_.emplace_back();
        data_sources_.back().ParseFromArray(field.data(), field.size());
        break;
      case 6 /* tracing_sessions */:
        tracing_sessions_.emplace_back();
        tracing_sessions_.back().ParseFromArray(field.data(), field.size());
        break;
      case 7 /* supports_tracing_sessions */:
        field.get(&supports_tracing_sessions_);
        break;
      case 3 /* num_sessions */:
        field.get(&num_sessions_);
        break;
      case 4 /* num_sessions_started */:
        field.get(&num_sessions_started_);
        break;
      case 5 /* tracing_service_version */:
        ::protozero::internal::gen_helpers::DeserializeString(field, &tracing_service_version_);
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string TracingServiceState::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> TracingServiceState::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void TracingServiceState::Serialize(::protozero::Message* msg) const {
  // Field 1: producers
  for (auto& it : producers_) {
    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
  }

  // Field 2: data_sources
  for (auto& it : data_sources_) {
    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(2));
  }

  // Field 6: tracing_sessions
  for (auto& it : tracing_sessions_) {
    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(6));
  }

  // Field 7: supports_tracing_sessions
  if (_has_field_[7]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(7, supports_tracing_sessions_, msg);
  }

  // Field 3: num_sessions
  if (_has_field_[3]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(3, num_sessions_, msg);
  }

  // Field 4: num_sessions_started
  if (_has_field_[4]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(4, num_sessions_started_, msg);
  }

  // Field 5: tracing_service_version
  if (_has_field_[5]) {
    ::protozero::internal::gen_helpers::SerializeString(5, tracing_service_version_, msg);
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}


TracingServiceState_TracingSession::TracingServiceState_TracingSession() = default;
TracingServiceState_TracingSession::~TracingServiceState_TracingSession() = default;
TracingServiceState_TracingSession::TracingServiceState_TracingSession(const TracingServiceState_TracingSession&) = default;
TracingServiceState_TracingSession& TracingServiceState_TracingSession::operator=(const TracingServiceState_TracingSession&) = default;
TracingServiceState_TracingSession::TracingServiceState_TracingSession(TracingServiceState_TracingSession&&) noexcept = default;
TracingServiceState_TracingSession& TracingServiceState_TracingSession::operator=(TracingServiceState_TracingSession&&) = default;

bool TracingServiceState_TracingSession::operator==(const TracingServiceState_TracingSession& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(id_, other.id_)
   && ::protozero::internal::gen_helpers::EqualsField(consumer_uid_, other.consumer_uid_)
   && ::protozero::internal::gen_helpers::EqualsField(state_, other.state_)
   && ::protozero::internal::gen_helpers::EqualsField(unique_session_name_, other.unique_session_name_)
   && ::protozero::internal::gen_helpers::EqualsField(buffer_size_kb_, other.buffer_size_kb_)
   && ::protozero::internal::gen_helpers::EqualsField(duration_ms_, other.duration_ms_)
   && ::protozero::internal::gen_helpers::EqualsField(num_data_sources_, other.num_data_sources_)
   && ::protozero::internal::gen_helpers::EqualsField(start_realtime_ns_, other.start_realtime_ns_)
   && ::protozero::internal::gen_helpers::EqualsField(bugreport_score_, other.bugreport_score_)
   && ::protozero::internal::gen_helpers::EqualsField(bugreport_filename_, other.bugreport_filename_)
   && ::protozero::internal::gen_helpers::EqualsField(is_started_, other.is_started_);
}

bool TracingServiceState_TracingSession::ParseFromArray(const void* raw, size_t size) {
  buffer_size_kb_.clear();
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* id */:
        field.get(&id_);
        break;
      case 2 /* consumer_uid */:
        field.get(&consumer_uid_);
        break;
      case 3 /* state */:
        ::protozero::internal::gen_helpers::DeserializeString(field, &state_);
        break;
      case 4 /* unique_session_name */:
        ::protozero::internal::gen_helpers::DeserializeString(field, &unique_session_name_);
        break;
      case 5 /* buffer_size_kb */:
        buffer_size_kb_.emplace_back();
        field.get(&buffer_size_kb_.back());
        break;
      case 6 /* duration_ms */:
        field.get(&duration_ms_);
        break;
      case 7 /* num_data_sources */:
        field.get(&num_data_sources_);
        break;
      case 8 /* start_realtime_ns */:
        field.get(&start_realtime_ns_);
        break;
      case 9 /* bugreport_score */:
        field.get(&bugreport_score_);
        break;
      case 10 /* bugreport_filename */:
        ::protozero::internal::gen_helpers::DeserializeString(field, &bugreport_filename_);
        break;
      case 11 /* is_started */:
        field.get(&is_started_);
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string TracingServiceState_TracingSession::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> TracingServiceState_TracingSession::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void TracingServiceState_TracingSession::Serialize(::protozero::Message* msg) const {
  // Field 1: id
  if (_has_field_[1]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(1, id_, msg);
  }

  // Field 2: consumer_uid
  if (_has_field_[2]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(2, consumer_uid_, msg);
  }

  // Field 3: state
  if (_has_field_[3]) {
    ::protozero::internal::gen_helpers::SerializeString(3, state_, msg);
  }

  // Field 4: unique_session_name
  if (_has_field_[4]) {
    ::protozero::internal::gen_helpers::SerializeString(4, unique_session_name_, msg);
  }

  // Field 5: buffer_size_kb
  for (auto& it : buffer_size_kb_) {
    ::protozero::internal::gen_helpers::SerializeVarInt(5, it, msg);
  }

  // Field 6: duration_ms
  if (_has_field_[6]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(6, duration_ms_, msg);
  }

  // Field 7: num_data_sources
  if (_has_field_[7]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(7, num_data_sources_, msg);
  }

  // Field 8: start_realtime_ns
  if (_has_field_[8]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(8, start_realtime_ns_, msg);
  }

  // Field 9: bugreport_score
  if (_has_field_[9]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(9, bugreport_score_, msg);
  }

  // Field 10: bugreport_filename
  if (_has_field_[10]) {
    ::protozero::internal::gen_helpers::SerializeString(10, bugreport_filename_, msg);
  }

  // Field 11: is_started
  if (_has_field_[11]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(11, is_started_, msg);
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}


TracingServiceState_DataSource::TracingServiceState_DataSource() = default;
TracingServiceState_DataSource::~TracingServiceState_DataSource() = default;
TracingServiceState_DataSource::TracingServiceState_DataSource(const TracingServiceState_DataSource&) = default;
TracingServiceState_DataSource& TracingServiceState_DataSource::operator=(const TracingServiceState_DataSource&) = default;
TracingServiceState_DataSource::TracingServiceState_DataSource(TracingServiceState_DataSource&&) noexcept = default;
TracingServiceState_DataSource& TracingServiceState_DataSource::operator=(TracingServiceState_DataSource&&) = default;

bool TracingServiceState_DataSource::operator==(const TracingServiceState_DataSource& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(ds_descriptor_, other.ds_descriptor_)
   && ::protozero::internal::gen_helpers::EqualsField(producer_id_, other.producer_id_);
}

bool TracingServiceState_DataSource::ParseFromArray(const void* raw, size_t size) {
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* ds_descriptor */:
        (*ds_descriptor_).ParseFromArray(field.data(), field.size());
        break;
      case 2 /* producer_id */:
        field.get(&producer_id_);
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string TracingServiceState_DataSource::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> TracingServiceState_DataSource::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void TracingServiceState_DataSource::Serialize(::protozero::Message* msg) const {
  // Field 1: ds_descriptor
  if (_has_field_[1]) {
    (*ds_descriptor_).Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
  }

  // Field 2: producer_id
  if (_has_field_[2]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(2, producer_id_, msg);
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}


TracingServiceState_Producer::TracingServiceState_Producer() = default;
TracingServiceState_Producer::~TracingServiceState_Producer() = default;
TracingServiceState_Producer::TracingServiceState_Producer(const TracingServiceState_Producer&) = default;
TracingServiceState_Producer& TracingServiceState_Producer::operator=(const TracingServiceState_Producer&) = default;
TracingServiceState_Producer::TracingServiceState_Producer(TracingServiceState_Producer&&) noexcept = default;
TracingServiceState_Producer& TracingServiceState_Producer::operator=(TracingServiceState_Producer&&) = default;

bool TracingServiceState_Producer::operator==(const TracingServiceState_Producer& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(id_, other.id_)
   && ::protozero::internal::gen_helpers::EqualsField(name_, other.name_)
   && ::protozero::internal::gen_helpers::EqualsField(pid_, other.pid_)
   && ::protozero::internal::gen_helpers::EqualsField(uid_, other.uid_)
   && ::protozero::internal::gen_helpers::EqualsField(sdk_version_, other.sdk_version_);
}

bool TracingServiceState_Producer::ParseFromArray(const void* raw, size_t size) {
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* id */:
        field.get(&id_);
        break;
      case 2 /* name */:
        ::protozero::internal::gen_helpers::DeserializeString(field, &name_);
        break;
      case 5 /* pid */:
        field.get(&pid_);
        break;
      case 3 /* uid */:
        field.get(&uid_);
        break;
      case 4 /* sdk_version */:
        ::protozero::internal::gen_helpers::DeserializeString(field, &sdk_version_);
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string TracingServiceState_Producer::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> TracingServiceState_Producer::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void TracingServiceState_Producer::Serialize(::protozero::Message* msg) const {
  // Field 1: id
  if (_has_field_[1]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(1, id_, msg);
  }

  // Field 2: name
  if (_has_field_[2]) {
    ::protozero::internal::gen_helpers::SerializeString(2, name_, msg);
  }

  // Field 5: pid
  if (_has_field_[5]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(5, pid_, msg);
  }

  // Field 3: uid
  if (_has_field_[3]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(3, uid_, msg);
  }

  // Field 4: sdk_version
  if (_has_field_[4]) {
    ::protozero::internal::gen_helpers::SerializeString(4, sdk_version_, msg);
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}

}  // namespace perfetto
}  // namespace protos
}  // namespace gen
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic pop
#endif
// gen_amalgamated begin source: gen/protos/perfetto/common/track_event_descriptor.gen.cc
// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wfloat-equal"
#endif
// gen_amalgamated expanded: #include "protos/perfetto/common/track_event_descriptor.gen.h"

namespace perfetto {
namespace protos {
namespace gen {

TrackEventDescriptor::TrackEventDescriptor() = default;
TrackEventDescriptor::~TrackEventDescriptor() = default;
TrackEventDescriptor::TrackEventDescriptor(const TrackEventDescriptor&) = default;
TrackEventDescriptor& TrackEventDescriptor::operator=(const TrackEventDescriptor&) = default;
TrackEventDescriptor::TrackEventDescriptor(TrackEventDescriptor&&) noexcept = default;
TrackEventDescriptor& TrackEventDescriptor::operator=(TrackEventDescriptor&&) = default;

bool TrackEventDescriptor::operator==(const TrackEventDescriptor& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(available_categories_, other.available_categories_);
}

int TrackEventDescriptor::available_categories_size() const { return static_cast<int>(available_categories_.size()); }
void TrackEventDescriptor::clear_available_categories() { available_categories_.clear(); }
TrackEventCategory* TrackEventDescriptor::add_available_categories() { available_categories_.emplace_back(); return &available_categories_.back(); }
bool TrackEventDescriptor::ParseFromArray(const void* raw, size_t size) {
  available_categories_.clear();
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* available_categories */:
        available_categories_.emplace_back();
        available_categories_.back().ParseFromArray(field.data(), field.size());
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string TrackEventDescriptor::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> TrackEventDescriptor::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void TrackEventDescriptor::Serialize(::protozero::Message* msg) const {
  // Field 1: available_categories
  for (auto& it : available_categories_) {
    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}


TrackEventCategory::TrackEventCategory() = default;
TrackEventCategory::~TrackEventCategory() = default;
TrackEventCategory::TrackEventCategory(const TrackEventCategory&) = default;
TrackEventCategory& TrackEventCategory::operator=(const TrackEventCategory&) = default;
TrackEventCategory::TrackEventCategory(TrackEventCategory&&) noexcept = default;
TrackEventCategory& TrackEventCategory::operator=(TrackEventCategory&&) = default;

bool TrackEventCategory::operator==(const TrackEventCategory& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(name_, other.name_)
   && ::protozero::internal::gen_helpers::EqualsField(description_, other.description_)
   && ::protozero::internal::gen_helpers::EqualsField(tags_, other.tags_);
}

bool TrackEventCategory::ParseFromArray(const void* raw, size_t size) {
  tags_.clear();
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* name */:
        ::protozero::internal::gen_helpers::DeserializeString(field, &name_);
        break;
      case 2 /* description */:
        ::protozero::internal::gen_helpers::DeserializeString(field, &description_);
        break;
      case 3 /* tags */:
        tags_.emplace_back();
        ::protozero::internal::gen_helpers::DeserializeString(field, &tags_.back());
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string TrackEventCategory::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> TrackEventCategory::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void TrackEventCategory::Serialize(::protozero::Message* msg) const {
  // Field 1: name
  if (_has_field_[1]) {
    ::protozero::internal::gen_helpers::SerializeString(1, name_, msg);
  }

  // Field 2: description
  if (_has_field_[2]) {
    ::protozero::internal::gen_helpers::SerializeString(2, description_, msg);
  }

  // Field 3: tags
  for (auto& it : tags_) {
    ::protozero::internal::gen_helpers::SerializeString(3, it, msg);
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}

}  // namespace perfetto
}  // namespace protos
}  // namespace gen
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic pop
#endif
// gen_amalgamated begin source: gen/protos/perfetto/config/android/android_game_intervention_list_config.gen.cc
// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wfloat-equal"
#endif
// gen_amalgamated expanded: #include "protos/perfetto/config/android/android_game_intervention_list_config.gen.h"

namespace perfetto {
namespace protos {
namespace gen {

AndroidGameInterventionListConfig::AndroidGameInterventionListConfig() = default;
AndroidGameInterventionListConfig::~AndroidGameInterventionListConfig() = default;
AndroidGameInterventionListConfig::AndroidGameInterventionListConfig(const AndroidGameInterventionListConfig&) = default;
AndroidGameInterventionListConfig& AndroidGameInterventionListConfig::operator=(const AndroidGameInterventionListConfig&) = default;
AndroidGameInterventionListConfig::AndroidGameInterventionListConfig(AndroidGameInterventionListConfig&&) noexcept = default;
AndroidGameInterventionListConfig& AndroidGameInterventionListConfig::operator=(AndroidGameInterventionListConfig&&) = default;

bool AndroidGameInterventionListConfig::operator==(const AndroidGameInterventionListConfig& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(package_name_filter_, other.package_name_filter_);
}

bool AndroidGameInterventionListConfig::ParseFromArray(const void* raw, size_t size) {
  package_name_filter_.clear();
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* package_name_filter */:
        package_name_filter_.emplace_back();
        ::protozero::internal::gen_helpers::DeserializeString(field, &package_name_filter_.back());
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string AndroidGameInterventionListConfig::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> AndroidGameInterventionListConfig::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void AndroidGameInterventionListConfig::Serialize(::protozero::Message* msg) const {
  // Field 1: package_name_filter
  for (auto& it : package_name_filter_) {
    ::protozero::internal::gen_helpers::SerializeString(1, it, msg);
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}

}  // namespace perfetto
}  // namespace protos
}  // namespace gen
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic pop
#endif
// gen_amalgamated begin source: gen/protos/perfetto/config/android/android_input_event_config.gen.cc
// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wfloat-equal"
#endif
// gen_amalgamated expanded: #include "protos/perfetto/config/android/android_input_event_config.gen.h"

namespace perfetto {
namespace protos {
namespace gen {

AndroidInputEventConfig::AndroidInputEventConfig() = default;
AndroidInputEventConfig::~AndroidInputEventConfig() = default;
AndroidInputEventConfig::AndroidInputEventConfig(const AndroidInputEventConfig&) = default;
AndroidInputEventConfig& AndroidInputEventConfig::operator=(const AndroidInputEventConfig&) = default;
AndroidInputEventConfig::AndroidInputEventConfig(AndroidInputEventConfig&&) noexcept = default;
AndroidInputEventConfig& AndroidInputEventConfig::operator=(AndroidInputEventConfig&&) = default;

bool AndroidInputEventConfig::operator==(const AndroidInputEventConfig& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(mode_, other.mode_)
   && ::protozero::internal::gen_helpers::EqualsField(rules_, other.rules_)
   && ::protozero::internal::gen_helpers::EqualsField(trace_dispatcher_input_events_, other.trace_dispatcher_input_events_)
   && ::protozero::internal::gen_helpers::EqualsField(trace_dispatcher_window_dispatch_, other.trace_dispatcher_window_dispatch_);
}

int AndroidInputEventConfig::rules_size() const { return static_cast<int>(rules_.size()); }
void AndroidInputEventConfig::clear_rules() { rules_.clear(); }
AndroidInputEventConfig_TraceRule* AndroidInputEventConfig::add_rules() { rules_.emplace_back(); return &rules_.back(); }
bool AndroidInputEventConfig::ParseFromArray(const void* raw, size_t size) {
  rules_.clear();
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* mode */:
        field.get(&mode_);
        break;
      case 2 /* rules */:
        rules_.emplace_back();
        rules_.back().ParseFromArray(field.data(), field.size());
        break;
      case 3 /* trace_dispatcher_input_events */:
        field.get(&trace_dispatcher_input_events_);
        break;
      case 4 /* trace_dispatcher_window_dispatch */:
        field.get(&trace_dispatcher_window_dispatch_);
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string AndroidInputEventConfig::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> AndroidInputEventConfig::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void AndroidInputEventConfig::Serialize(::protozero::Message* msg) const {
  // Field 1: mode
  if (_has_field_[1]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(1, mode_, msg);
  }

  // Field 2: rules
  for (auto& it : rules_) {
    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(2));
  }

  // Field 3: trace_dispatcher_input_events
  if (_has_field_[3]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(3, trace_dispatcher_input_events_, msg);
  }

  // Field 4: trace_dispatcher_window_dispatch
  if (_has_field_[4]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(4, trace_dispatcher_window_dispatch_, msg);
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}


AndroidInputEventConfig_TraceRule::AndroidInputEventConfig_TraceRule() = default;
AndroidInputEventConfig_TraceRule::~AndroidInputEventConfig_TraceRule() = default;
AndroidInputEventConfig_TraceRule::AndroidInputEventConfig_TraceRule(const AndroidInputEventConfig_TraceRule&) = default;
AndroidInputEventConfig_TraceRule& AndroidInputEventConfig_TraceRule::operator=(const AndroidInputEventConfig_TraceRule&) = default;
AndroidInputEventConfig_TraceRule::AndroidInputEventConfig_TraceRule(AndroidInputEventConfig_TraceRule&&) noexcept = default;
AndroidInputEventConfig_TraceRule& AndroidInputEventConfig_TraceRule::operator=(AndroidInputEventConfig_TraceRule&&) = default;

bool AndroidInputEventConfig_TraceRule::operator==(const AndroidInputEventConfig_TraceRule& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(trace_level_, other.trace_level_)
   && ::protozero::internal::gen_helpers::EqualsField(match_all_packages_, other.match_all_packages_)
   && ::protozero::internal::gen_helpers::EqualsField(match_any_packages_, other.match_any_packages_)
   && ::protozero::internal::gen_helpers::EqualsField(match_secure_, other.match_secure_)
   && ::protozero::internal::gen_helpers::EqualsField(match_ime_connection_active_, other.match_ime_connection_active_);
}

bool AndroidInputEventConfig_TraceRule::ParseFromArray(const void* raw, size_t size) {
  match_all_packages_.clear();
  match_any_packages_.clear();
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* trace_level */:
        field.get(&trace_level_);
        break;
      case 2 /* match_all_packages */:
        match_all_packages_.emplace_back();
        ::protozero::internal::gen_helpers::DeserializeString(field, &match_all_packages_.back());
        break;
      case 3 /* match_any_packages */:
        match_any_packages_.emplace_back();
        ::protozero::internal::gen_helpers::DeserializeString(field, &match_any_packages_.back());
        break;
      case 4 /* match_secure */:
        field.get(&match_secure_);
        break;
      case 5 /* match_ime_connection_active */:
        field.get(&match_ime_connection_active_);
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string AndroidInputEventConfig_TraceRule::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> AndroidInputEventConfig_TraceRule::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void AndroidInputEventConfig_TraceRule::Serialize(::protozero::Message* msg) const {
  // Field 1: trace_level
  if (_has_field_[1]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(1, trace_level_, msg);
  }

  // Field 2: match_all_packages
  for (auto& it : match_all_packages_) {
    ::protozero::internal::gen_helpers::SerializeString(2, it, msg);
  }

  // Field 3: match_any_packages
  for (auto& it : match_any_packages_) {
    ::protozero::internal::gen_helpers::SerializeString(3, it, msg);
  }

  // Field 4: match_secure
  if (_has_field_[4]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(4, match_secure_, msg);
  }

  // Field 5: match_ime_connection_active
  if (_has_field_[5]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(5, match_ime_connection_active_, msg);
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}

}  // namespace perfetto
}  // namespace protos
}  // namespace gen
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic pop
#endif
// gen_amalgamated begin source: gen/protos/perfetto/config/android/android_log_config.gen.cc
// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wfloat-equal"
#endif
// gen_amalgamated expanded: #include "protos/perfetto/config/android/android_log_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/common/android_log_constants.gen.h"

namespace perfetto {
namespace protos {
namespace gen {

AndroidLogConfig::AndroidLogConfig() = default;
AndroidLogConfig::~AndroidLogConfig() = default;
AndroidLogConfig::AndroidLogConfig(const AndroidLogConfig&) = default;
AndroidLogConfig& AndroidLogConfig::operator=(const AndroidLogConfig&) = default;
AndroidLogConfig::AndroidLogConfig(AndroidLogConfig&&) noexcept = default;
AndroidLogConfig& AndroidLogConfig::operator=(AndroidLogConfig&&) = default;

bool AndroidLogConfig::operator==(const AndroidLogConfig& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(log_ids_, other.log_ids_)
   && ::protozero::internal::gen_helpers::EqualsField(min_prio_, other.min_prio_)
   && ::protozero::internal::gen_helpers::EqualsField(filter_tags_, other.filter_tags_);
}

bool AndroidLogConfig::ParseFromArray(const void* raw, size_t size) {
  log_ids_.clear();
  filter_tags_.clear();
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* log_ids */:
        log_ids_.emplace_back();
        field.get(&log_ids_.back());
        break;
      case 3 /* min_prio */:
        field.get(&min_prio_);
        break;
      case 4 /* filter_tags */:
        filter_tags_.emplace_back();
        ::protozero::internal::gen_helpers::DeserializeString(field, &filter_tags_.back());
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string AndroidLogConfig::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> AndroidLogConfig::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void AndroidLogConfig::Serialize(::protozero::Message* msg) const {
  // Field 1: log_ids
  for (auto& it : log_ids_) {
    ::protozero::internal::gen_helpers::SerializeVarInt(1, it, msg);
  }

  // Field 3: min_prio
  if (_has_field_[3]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(3, min_prio_, msg);
  }

  // Field 4: filter_tags
  for (auto& it : filter_tags_) {
    ::protozero::internal::gen_helpers::SerializeString(4, it, msg);
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}

}  // namespace perfetto
}  // namespace protos
}  // namespace gen
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic pop
#endif
// gen_amalgamated begin source: gen/protos/perfetto/config/android/android_polled_state_config.gen.cc
// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wfloat-equal"
#endif
// gen_amalgamated expanded: #include "protos/perfetto/config/android/android_polled_state_config.gen.h"

namespace perfetto {
namespace protos {
namespace gen {

AndroidPolledStateConfig::AndroidPolledStateConfig() = default;
AndroidPolledStateConfig::~AndroidPolledStateConfig() = default;
AndroidPolledStateConfig::AndroidPolledStateConfig(const AndroidPolledStateConfig&) = default;
AndroidPolledStateConfig& AndroidPolledStateConfig::operator=(const AndroidPolledStateConfig&) = default;
AndroidPolledStateConfig::AndroidPolledStateConfig(AndroidPolledStateConfig&&) noexcept = default;
AndroidPolledStateConfig& AndroidPolledStateConfig::operator=(AndroidPolledStateConfig&&) = default;

bool AndroidPolledStateConfig::operator==(const AndroidPolledStateConfig& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(poll_ms_, other.poll_ms_);
}

bool AndroidPolledStateConfig::ParseFromArray(const void* raw, size_t size) {
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* poll_ms */:
        field.get(&poll_ms_);
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string AndroidPolledStateConfig::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> AndroidPolledStateConfig::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void AndroidPolledStateConfig::Serialize(::protozero::Message* msg) const {
  // Field 1: poll_ms
  if (_has_field_[1]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(1, poll_ms_, msg);
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}

}  // namespace perfetto
}  // namespace protos
}  // namespace gen
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic pop
#endif
// gen_amalgamated begin source: gen/protos/perfetto/config/android/android_sdk_sysprop_guard_config.gen.cc
// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wfloat-equal"
#endif
// gen_amalgamated expanded: #include "protos/perfetto/config/android/android_sdk_sysprop_guard_config.gen.h"

namespace perfetto {
namespace protos {
namespace gen {

AndroidSdkSyspropGuardConfig::AndroidSdkSyspropGuardConfig() = default;
AndroidSdkSyspropGuardConfig::~AndroidSdkSyspropGuardConfig() = default;
AndroidSdkSyspropGuardConfig::AndroidSdkSyspropGuardConfig(const AndroidSdkSyspropGuardConfig&) = default;
AndroidSdkSyspropGuardConfig& AndroidSdkSyspropGuardConfig::operator=(const AndroidSdkSyspropGuardConfig&) = default;
AndroidSdkSyspropGuardConfig::AndroidSdkSyspropGuardConfig(AndroidSdkSyspropGuardConfig&&) noexcept = default;
AndroidSdkSyspropGuardConfig& AndroidSdkSyspropGuardConfig::operator=(AndroidSdkSyspropGuardConfig&&) = default;

bool AndroidSdkSyspropGuardConfig::operator==(const AndroidSdkSyspropGuardConfig& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(surfaceflinger_skia_track_events_, other.surfaceflinger_skia_track_events_)
   && ::protozero::internal::gen_helpers::EqualsField(hwui_skia_track_events_, other.hwui_skia_track_events_)
   && ::protozero::internal::gen_helpers::EqualsField(hwui_package_name_filter_, other.hwui_package_name_filter_);
}

bool AndroidSdkSyspropGuardConfig::ParseFromArray(const void* raw, size_t size) {
  hwui_package_name_filter_.clear();
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* surfaceflinger_skia_track_events */:
        field.get(&surfaceflinger_skia_track_events_);
        break;
      case 2 /* hwui_skia_track_events */:
        field.get(&hwui_skia_track_events_);
        break;
      case 3 /* hwui_package_name_filter */:
        hwui_package_name_filter_.emplace_back();
        ::protozero::internal::gen_helpers::DeserializeString(field, &hwui_package_name_filter_.back());
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string AndroidSdkSyspropGuardConfig::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> AndroidSdkSyspropGuardConfig::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void AndroidSdkSyspropGuardConfig::Serialize(::protozero::Message* msg) const {
  // Field 1: surfaceflinger_skia_track_events
  if (_has_field_[1]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(1, surfaceflinger_skia_track_events_, msg);
  }

  // Field 2: hwui_skia_track_events
  if (_has_field_[2]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(2, hwui_skia_track_events_, msg);
  }

  // Field 3: hwui_package_name_filter
  for (auto& it : hwui_package_name_filter_) {
    ::protozero::internal::gen_helpers::SerializeString(3, it, msg);
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}

}  // namespace perfetto
}  // namespace protos
}  // namespace gen
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic pop
#endif
// gen_amalgamated begin source: gen/protos/perfetto/config/android/android_system_property_config.gen.cc
// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wfloat-equal"
#endif
// gen_amalgamated expanded: #include "protos/perfetto/config/android/android_system_property_config.gen.h"

namespace perfetto {
namespace protos {
namespace gen {

AndroidSystemPropertyConfig::AndroidSystemPropertyConfig() = default;
AndroidSystemPropertyConfig::~AndroidSystemPropertyConfig() = default;
AndroidSystemPropertyConfig::AndroidSystemPropertyConfig(const AndroidSystemPropertyConfig&) = default;
AndroidSystemPropertyConfig& AndroidSystemPropertyConfig::operator=(const AndroidSystemPropertyConfig&) = default;
AndroidSystemPropertyConfig::AndroidSystemPropertyConfig(AndroidSystemPropertyConfig&&) noexcept = default;
AndroidSystemPropertyConfig& AndroidSystemPropertyConfig::operator=(AndroidSystemPropertyConfig&&) = default;

bool AndroidSystemPropertyConfig::operator==(const AndroidSystemPropertyConfig& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(poll_ms_, other.poll_ms_)
   && ::protozero::internal::gen_helpers::EqualsField(property_name_, other.property_name_);
}

bool AndroidSystemPropertyConfig::ParseFromArray(const void* raw, size_t size) {
  property_name_.clear();
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* poll_ms */:
        field.get(&poll_ms_);
        break;
      case 2 /* property_name */:
        property_name_.emplace_back();
        ::protozero::internal::gen_helpers::DeserializeString(field, &property_name_.back());
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string AndroidSystemPropertyConfig::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> AndroidSystemPropertyConfig::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void AndroidSystemPropertyConfig::Serialize(::protozero::Message* msg) const {
  // Field 1: poll_ms
  if (_has_field_[1]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(1, poll_ms_, msg);
  }

  // Field 2: property_name
  for (auto& it : property_name_) {
    ::protozero::internal::gen_helpers::SerializeString(2, it, msg);
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}

}  // namespace perfetto
}  // namespace protos
}  // namespace gen
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic pop
#endif
// gen_amalgamated begin source: gen/protos/perfetto/config/android/network_trace_config.gen.cc
// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wfloat-equal"
#endif
// gen_amalgamated expanded: #include "protos/perfetto/config/android/network_trace_config.gen.h"

namespace perfetto {
namespace protos {
namespace gen {

NetworkPacketTraceConfig::NetworkPacketTraceConfig() = default;
NetworkPacketTraceConfig::~NetworkPacketTraceConfig() = default;
NetworkPacketTraceConfig::NetworkPacketTraceConfig(const NetworkPacketTraceConfig&) = default;
NetworkPacketTraceConfig& NetworkPacketTraceConfig::operator=(const NetworkPacketTraceConfig&) = default;
NetworkPacketTraceConfig::NetworkPacketTraceConfig(NetworkPacketTraceConfig&&) noexcept = default;
NetworkPacketTraceConfig& NetworkPacketTraceConfig::operator=(NetworkPacketTraceConfig&&) = default;

bool NetworkPacketTraceConfig::operator==(const NetworkPacketTraceConfig& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(poll_ms_, other.poll_ms_)
   && ::protozero::internal::gen_helpers::EqualsField(aggregation_threshold_, other.aggregation_threshold_)
   && ::protozero::internal::gen_helpers::EqualsField(intern_limit_, other.intern_limit_)
   && ::protozero::internal::gen_helpers::EqualsField(drop_local_port_, other.drop_local_port_)
   && ::protozero::internal::gen_helpers::EqualsField(drop_remote_port_, other.drop_remote_port_)
   && ::protozero::internal::gen_helpers::EqualsField(drop_tcp_flags_, other.drop_tcp_flags_);
}

bool NetworkPacketTraceConfig::ParseFromArray(const void* raw, size_t size) {
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* poll_ms */:
        field.get(&poll_ms_);
        break;
      case 2 /* aggregation_threshold */:
        field.get(&aggregation_threshold_);
        break;
      case 3 /* intern_limit */:
        field.get(&intern_limit_);
        break;
      case 4 /* drop_local_port */:
        field.get(&drop_local_port_);
        break;
      case 5 /* drop_remote_port */:
        field.get(&drop_remote_port_);
        break;
      case 6 /* drop_tcp_flags */:
        field.get(&drop_tcp_flags_);
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string NetworkPacketTraceConfig::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> NetworkPacketTraceConfig::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void NetworkPacketTraceConfig::Serialize(::protozero::Message* msg) const {
  // Field 1: poll_ms
  if (_has_field_[1]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(1, poll_ms_, msg);
  }

  // Field 2: aggregation_threshold
  if (_has_field_[2]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(2, aggregation_threshold_, msg);
  }

  // Field 3: intern_limit
  if (_has_field_[3]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(3, intern_limit_, msg);
  }

  // Field 4: drop_local_port
  if (_has_field_[4]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(4, drop_local_port_, msg);
  }

  // Field 5: drop_remote_port
  if (_has_field_[5]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(5, drop_remote_port_, msg);
  }

  // Field 6: drop_tcp_flags
  if (_has_field_[6]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(6, drop_tcp_flags_, msg);
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}

}  // namespace perfetto
}  // namespace protos
}  // namespace gen
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic pop
#endif
// gen_amalgamated begin source: gen/protos/perfetto/config/android/packages_list_config.gen.cc
// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wfloat-equal"
#endif
// gen_amalgamated expanded: #include "protos/perfetto/config/android/packages_list_config.gen.h"

namespace perfetto {
namespace protos {
namespace gen {

PackagesListConfig::PackagesListConfig() = default;
PackagesListConfig::~PackagesListConfig() = default;
PackagesListConfig::PackagesListConfig(const PackagesListConfig&) = default;
PackagesListConfig& PackagesListConfig::operator=(const PackagesListConfig&) = default;
PackagesListConfig::PackagesListConfig(PackagesListConfig&&) noexcept = default;
PackagesListConfig& PackagesListConfig::operator=(PackagesListConfig&&) = default;

bool PackagesListConfig::operator==(const PackagesListConfig& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(package_name_filter_, other.package_name_filter_);
}

bool PackagesListConfig::ParseFromArray(const void* raw, size_t size) {
  package_name_filter_.clear();
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* package_name_filter */:
        package_name_filter_.emplace_back();
        ::protozero::internal::gen_helpers::DeserializeString(field, &package_name_filter_.back());
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string PackagesListConfig::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> PackagesListConfig::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void PackagesListConfig::Serialize(::protozero::Message* msg) const {
  // Field 1: package_name_filter
  for (auto& it : package_name_filter_) {
    ::protozero::internal::gen_helpers::SerializeString(1, it, msg);
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}

}  // namespace perfetto
}  // namespace protos
}  // namespace gen
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic pop
#endif
// gen_amalgamated begin source: gen/protos/perfetto/config/android/pixel_modem_config.gen.cc
// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wfloat-equal"
#endif
// gen_amalgamated expanded: #include "protos/perfetto/config/android/pixel_modem_config.gen.h"

namespace perfetto {
namespace protos {
namespace gen {

PixelModemConfig::PixelModemConfig() = default;
PixelModemConfig::~PixelModemConfig() = default;
PixelModemConfig::PixelModemConfig(const PixelModemConfig&) = default;
PixelModemConfig& PixelModemConfig::operator=(const PixelModemConfig&) = default;
PixelModemConfig::PixelModemConfig(PixelModemConfig&&) noexcept = default;
PixelModemConfig& PixelModemConfig::operator=(PixelModemConfig&&) = default;

bool PixelModemConfig::operator==(const PixelModemConfig& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(event_group_, other.event_group_)
   && ::protozero::internal::gen_helpers::EqualsField(pigweed_hash_allow_list_, other.pigweed_hash_allow_list_)
   && ::protozero::internal::gen_helpers::EqualsField(pigweed_hash_deny_list_, other.pigweed_hash_deny_list_);
}

bool PixelModemConfig::ParseFromArray(const void* raw, size_t size) {
  pigweed_hash_allow_list_.clear();
  pigweed_hash_deny_list_.clear();
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* event_group */:
        field.get(&event_group_);
        break;
      case 2 /* pigweed_hash_allow_list */:
        pigweed_hash_allow_list_.emplace_back();
        field.get(&pigweed_hash_allow_list_.back());
        break;
      case 3 /* pigweed_hash_deny_list */:
        pigweed_hash_deny_list_.emplace_back();
        field.get(&pigweed_hash_deny_list_.back());
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string PixelModemConfig::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> PixelModemConfig::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void PixelModemConfig::Serialize(::protozero::Message* msg) const {
  // Field 1: event_group
  if (_has_field_[1]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(1, event_group_, msg);
  }

  // Field 2: pigweed_hash_allow_list
  for (auto& it : pigweed_hash_allow_list_) {
    ::protozero::internal::gen_helpers::SerializeVarInt(2, it, msg);
  }

  // Field 3: pigweed_hash_deny_list
  for (auto& it : pigweed_hash_deny_list_) {
    ::protozero::internal::gen_helpers::SerializeVarInt(3, it, msg);
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}

}  // namespace perfetto
}  // namespace protos
}  // namespace gen
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic pop
#endif
// gen_amalgamated begin source: gen/protos/perfetto/config/android/protolog_config.gen.cc
// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wfloat-equal"
#endif
// gen_amalgamated expanded: #include "protos/perfetto/config/android/protolog_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/common/protolog_common.gen.h"

namespace perfetto {
namespace protos {
namespace gen {

ProtoLogGroup::ProtoLogGroup() = default;
ProtoLogGroup::~ProtoLogGroup() = default;
ProtoLogGroup::ProtoLogGroup(const ProtoLogGroup&) = default;
ProtoLogGroup& ProtoLogGroup::operator=(const ProtoLogGroup&) = default;
ProtoLogGroup::ProtoLogGroup(ProtoLogGroup&&) noexcept = default;
ProtoLogGroup& ProtoLogGroup::operator=(ProtoLogGroup&&) = default;

bool ProtoLogGroup::operator==(const ProtoLogGroup& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(group_name_, other.group_name_)
   && ::protozero::internal::gen_helpers::EqualsField(log_from_, other.log_from_)
   && ::protozero::internal::gen_helpers::EqualsField(collect_stacktrace_, other.collect_stacktrace_);
}

bool ProtoLogGroup::ParseFromArray(const void* raw, size_t size) {
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* group_name */:
        ::protozero::internal::gen_helpers::DeserializeString(field, &group_name_);
        break;
      case 2 /* log_from */:
        field.get(&log_from_);
        break;
      case 3 /* collect_stacktrace */:
        field.get(&collect_stacktrace_);
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string ProtoLogGroup::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> ProtoLogGroup::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void ProtoLogGroup::Serialize(::protozero::Message* msg) const {
  // Field 1: group_name
  if (_has_field_[1]) {
    ::protozero::internal::gen_helpers::SerializeString(1, group_name_, msg);
  }

  // Field 2: log_from
  if (_has_field_[2]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(2, log_from_, msg);
  }

  // Field 3: collect_stacktrace
  if (_has_field_[3]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(3, collect_stacktrace_, msg);
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}


ProtoLogConfig::ProtoLogConfig() = default;
ProtoLogConfig::~ProtoLogConfig() = default;
ProtoLogConfig::ProtoLogConfig(const ProtoLogConfig&) = default;
ProtoLogConfig& ProtoLogConfig::operator=(const ProtoLogConfig&) = default;
ProtoLogConfig::ProtoLogConfig(ProtoLogConfig&&) noexcept = default;
ProtoLogConfig& ProtoLogConfig::operator=(ProtoLogConfig&&) = default;

bool ProtoLogConfig::operator==(const ProtoLogConfig& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(group_overrides_, other.group_overrides_)
   && ::protozero::internal::gen_helpers::EqualsField(tracing_mode_, other.tracing_mode_);
}

int ProtoLogConfig::group_overrides_size() const { return static_cast<int>(group_overrides_.size()); }
void ProtoLogConfig::clear_group_overrides() { group_overrides_.clear(); }
ProtoLogGroup* ProtoLogConfig::add_group_overrides() { group_overrides_.emplace_back(); return &group_overrides_.back(); }
bool ProtoLogConfig::ParseFromArray(const void* raw, size_t size) {
  group_overrides_.clear();
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* group_overrides */:
        group_overrides_.emplace_back();
        group_overrides_.back().ParseFromArray(field.data(), field.size());
        break;
      case 2 /* tracing_mode */:
        field.get(&tracing_mode_);
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string ProtoLogConfig::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> ProtoLogConfig::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void ProtoLogConfig::Serialize(::protozero::Message* msg) const {
  // Field 1: group_overrides
  for (auto& it : group_overrides_) {
    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
  }

  // Field 2: tracing_mode
  if (_has_field_[2]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(2, tracing_mode_, msg);
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}

}  // namespace perfetto
}  // namespace protos
}  // namespace gen
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic pop
#endif
// gen_amalgamated begin source: gen/protos/perfetto/config/android/surfaceflinger_layers_config.gen.cc
// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wfloat-equal"
#endif
// gen_amalgamated expanded: #include "protos/perfetto/config/android/surfaceflinger_layers_config.gen.h"

namespace perfetto {
namespace protos {
namespace gen {

SurfaceFlingerLayersConfig::SurfaceFlingerLayersConfig() = default;
SurfaceFlingerLayersConfig::~SurfaceFlingerLayersConfig() = default;
SurfaceFlingerLayersConfig::SurfaceFlingerLayersConfig(const SurfaceFlingerLayersConfig&) = default;
SurfaceFlingerLayersConfig& SurfaceFlingerLayersConfig::operator=(const SurfaceFlingerLayersConfig&) = default;
SurfaceFlingerLayersConfig::SurfaceFlingerLayersConfig(SurfaceFlingerLayersConfig&&) noexcept = default;
SurfaceFlingerLayersConfig& SurfaceFlingerLayersConfig::operator=(SurfaceFlingerLayersConfig&&) = default;

bool SurfaceFlingerLayersConfig::operator==(const SurfaceFlingerLayersConfig& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(mode_, other.mode_)
   && ::protozero::internal::gen_helpers::EqualsField(trace_flags_, other.trace_flags_);
}

bool SurfaceFlingerLayersConfig::ParseFromArray(const void* raw, size_t size) {
  trace_flags_.clear();
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* mode */:
        field.get(&mode_);
        break;
      case 2 /* trace_flags */:
        trace_flags_.emplace_back();
        field.get(&trace_flags_.back());
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string SurfaceFlingerLayersConfig::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> SurfaceFlingerLayersConfig::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void SurfaceFlingerLayersConfig::Serialize(::protozero::Message* msg) const {
  // Field 1: mode
  if (_has_field_[1]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(1, mode_, msg);
  }

  // Field 2: trace_flags
  for (auto& it : trace_flags_) {
    ::protozero::internal::gen_helpers::SerializeVarInt(2, it, msg);
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}

}  // namespace perfetto
}  // namespace protos
}  // namespace gen
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic pop
#endif
// gen_amalgamated begin source: gen/protos/perfetto/config/android/surfaceflinger_transactions_config.gen.cc
// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wfloat-equal"
#endif
// gen_amalgamated expanded: #include "protos/perfetto/config/android/surfaceflinger_transactions_config.gen.h"

namespace perfetto {
namespace protos {
namespace gen {

SurfaceFlingerTransactionsConfig::SurfaceFlingerTransactionsConfig() = default;
SurfaceFlingerTransactionsConfig::~SurfaceFlingerTransactionsConfig() = default;
SurfaceFlingerTransactionsConfig::SurfaceFlingerTransactionsConfig(const SurfaceFlingerTransactionsConfig&) = default;
SurfaceFlingerTransactionsConfig& SurfaceFlingerTransactionsConfig::operator=(const SurfaceFlingerTransactionsConfig&) = default;
SurfaceFlingerTransactionsConfig::SurfaceFlingerTransactionsConfig(SurfaceFlingerTransactionsConfig&&) noexcept = default;
SurfaceFlingerTransactionsConfig& SurfaceFlingerTransactionsConfig::operator=(SurfaceFlingerTransactionsConfig&&) = default;

bool SurfaceFlingerTransactionsConfig::operator==(const SurfaceFlingerTransactionsConfig& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(mode_, other.mode_);
}

bool SurfaceFlingerTransactionsConfig::ParseFromArray(const void* raw, size_t size) {
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* mode */:
        field.get(&mode_);
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string SurfaceFlingerTransactionsConfig::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> SurfaceFlingerTransactionsConfig::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void SurfaceFlingerTransactionsConfig::Serialize(::protozero::Message* msg) const {
  // Field 1: mode
  if (_has_field_[1]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(1, mode_, msg);
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}

}  // namespace perfetto
}  // namespace protos
}  // namespace gen
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic pop
#endif
// gen_amalgamated begin source: gen/protos/perfetto/config/ftrace/ftrace_config.gen.cc
// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wfloat-equal"
#endif
// gen_amalgamated expanded: #include "protos/perfetto/config/ftrace/ftrace_config.gen.h"

namespace perfetto {
namespace protos {
namespace gen {

FtraceConfig::FtraceConfig() = default;
FtraceConfig::~FtraceConfig() = default;
FtraceConfig::FtraceConfig(const FtraceConfig&) = default;
FtraceConfig& FtraceConfig::operator=(const FtraceConfig&) = default;
FtraceConfig::FtraceConfig(FtraceConfig&&) noexcept = default;
FtraceConfig& FtraceConfig::operator=(FtraceConfig&&) = default;

bool FtraceConfig::operator==(const FtraceConfig& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(ftrace_events_, other.ftrace_events_)
   && ::protozero::internal::gen_helpers::EqualsField(atrace_categories_, other.atrace_categories_)
   && ::protozero::internal::gen_helpers::EqualsField(atrace_apps_, other.atrace_apps_)
   && ::protozero::internal::gen_helpers::EqualsField(buffer_size_kb_, other.buffer_size_kb_)
   && ::protozero::internal::gen_helpers::EqualsField(drain_period_ms_, other.drain_period_ms_)
   && ::protozero::internal::gen_helpers::EqualsField(drain_buffer_percent_, other.drain_buffer_percent_)
   && ::protozero::internal::gen_helpers::EqualsField(compact_sched_, other.compact_sched_)
   && ::protozero::internal::gen_helpers::EqualsField(print_filter_, other.print_filter_)
   && ::protozero::internal::gen_helpers::EqualsField(symbolize_ksyms_, other.symbolize_ksyms_)
   && ::protozero::internal::gen_helpers::EqualsField(ksyms_mem_policy_, other.ksyms_mem_policy_)
   && ::protozero::internal::gen_helpers::EqualsField(initialize_ksyms_synchronously_for_testing_, other.initialize_ksyms_synchronously_for_testing_)
   && ::protozero::internal::gen_helpers::EqualsField(throttle_rss_stat_, other.throttle_rss_stat_)
   && ::protozero::internal::gen_helpers::EqualsField(disable_generic_events_, other.disable_generic_events_)
   && ::protozero::internal::gen_helpers::EqualsField(syscall_events_, other.syscall_events_)
   && ::protozero::internal::gen_helpers::EqualsField(enable_function_graph_, other.enable_function_graph_)
   && ::protozero::internal::gen_helpers::EqualsField(function_filters_, other.function_filters_)
   && ::protozero::internal::gen_helpers::EqualsField(function_graph_roots_, other.function_graph_roots_)
   && ::protozero::internal::gen_helpers::EqualsField(preserve_ftrace_buffer_, other.preserve_ftrace_buffer_)
   && ::protozero::internal::gen_helpers::EqualsField(use_monotonic_raw_clock_, other.use_monotonic_raw_clock_)
   && ::protozero::internal::gen_helpers::EqualsField(instance_name_, other.instance_name_)
   && ::protozero::internal::gen_helpers::EqualsField(buffer_size_lower_bound_, other.buffer_size_lower_bound_);
}

bool FtraceConfig::ParseFromArray(const void* raw, size_t size) {
  ftrace_events_.clear();
  atrace_categories_.clear();
  atrace_apps_.clear();
  syscall_events_.clear();
  function_filters_.clear();
  function_graph_roots_.clear();
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* ftrace_events */:
        ftrace_events_.emplace_back();
        ::protozero::internal::gen_helpers::DeserializeString(field, &ftrace_events_.back());
        break;
      case 2 /* atrace_categories */:
        atrace_categories_.emplace_back();
        ::protozero::internal::gen_helpers::DeserializeString(field, &atrace_categories_.back());
        break;
      case 3 /* atrace_apps */:
        atrace_apps_.emplace_back();
        ::protozero::internal::gen_helpers::DeserializeString(field, &atrace_apps_.back());
        break;
      case 10 /* buffer_size_kb */:
        field.get(&buffer_size_kb_);
        break;
      case 11 /* drain_period_ms */:
        field.get(&drain_period_ms_);
        break;
      case 26 /* drain_buffer_percent */:
        field.get(&drain_buffer_percent_);
        break;
      case 12 /* compact_sched */:
        (*compact_sched_).ParseFromArray(field.data(), field.size());
        break;
      case 22 /* print_filter */:
        (*print_filter_).ParseFromArray(field.data(), field.size());
        break;
      case 13 /* symbolize_ksyms */:
        field.get(&symbolize_ksyms_);
        break;
      case 17 /* ksyms_mem_policy */:
        field.get(&ksyms_mem_policy_);
        break;
      case 14 /* initialize_ksyms_synchronously_for_testing */:
        field.get(&initialize_ksyms_synchronously_for_testing_);
        break;
      case 15 /* throttle_rss_stat */:
        field.get(&throttle_rss_stat_);
        break;
      case 16 /* disable_generic_events */:
        field.get(&disable_generic_events_);
        break;
      case 18 /* syscall_events */:
        syscall_events_.emplace_back();
        ::protozero::internal::gen_helpers::DeserializeString(field, &syscall_events_.back());
        break;
      case 19 /* enable_function_graph */:
        field.get(&enable_function_graph_);
        break;
      case 20 /* function_filters */:
        function_filters_.emplace_back();
        ::protozero::internal::gen_helpers::DeserializeString(field, &function_filters_.back());
        break;
      case 21 /* function_graph_roots */:
        function_graph_roots_.emplace_back();
        ::protozero::internal::gen_helpers::DeserializeString(field, &function_graph_roots_.back());
        break;
      case 23 /* preserve_ftrace_buffer */:
        field.get(&preserve_ftrace_buffer_);
        break;
      case 24 /* use_monotonic_raw_clock */:
        field.get(&use_monotonic_raw_clock_);
        break;
      case 25 /* instance_name */:
        ::protozero::internal::gen_helpers::DeserializeString(field, &instance_name_);
        break;
      case 27 /* buffer_size_lower_bound */:
        field.get(&buffer_size_lower_bound_);
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string FtraceConfig::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> FtraceConfig::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void FtraceConfig::Serialize(::protozero::Message* msg) const {
  // Field 1: ftrace_events
  for (auto& it : ftrace_events_) {
    ::protozero::internal::gen_helpers::SerializeString(1, it, msg);
  }

  // Field 2: atrace_categories
  for (auto& it : atrace_categories_) {
    ::protozero::internal::gen_helpers::SerializeString(2, it, msg);
  }

  // Field 3: atrace_apps
  for (auto& it : atrace_apps_) {
    ::protozero::internal::gen_helpers::SerializeString(3, it, msg);
  }

  // Field 10: buffer_size_kb
  if (_has_field_[10]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(10, buffer_size_kb_, msg);
  }

  // Field 11: drain_period_ms
  if (_has_field_[11]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(11, drain_period_ms_, msg);
  }

  // Field 26: drain_buffer_percent
  if (_has_field_[26]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(26, drain_buffer_percent_, msg);
  }

  // Field 12: compact_sched
  if (_has_field_[12]) {
    (*compact_sched_).Serialize(msg->BeginNestedMessage<::protozero::Message>(12));
  }

  // Field 22: print_filter
  if (_has_field_[22]) {
    (*print_filter_).Serialize(msg->BeginNestedMessage<::protozero::Message>(22));
  }

  // Field 13: symbolize_ksyms
  if (_has_field_[13]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(13, symbolize_ksyms_, msg);
  }

  // Field 17: ksyms_mem_policy
  if (_has_field_[17]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(17, ksyms_mem_policy_, msg);
  }

  // Field 14: initialize_ksyms_synchronously_for_testing
  if (_has_field_[14]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(14, initialize_ksyms_synchronously_for_testing_, msg);
  }

  // Field 15: throttle_rss_stat
  if (_has_field_[15]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(15, throttle_rss_stat_, msg);
  }

  // Field 16: disable_generic_events
  if (_has_field_[16]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(16, disable_generic_events_, msg);
  }

  // Field 18: syscall_events
  for (auto& it : syscall_events_) {
    ::protozero::internal::gen_helpers::SerializeString(18, it, msg);
  }

  // Field 19: enable_function_graph
  if (_has_field_[19]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(19, enable_function_graph_, msg);
  }

  // Field 20: function_filters
  for (auto& it : function_filters_) {
    ::protozero::internal::gen_helpers::SerializeString(20, it, msg);
  }

  // Field 21: function_graph_roots
  for (auto& it : function_graph_roots_) {
    ::protozero::internal::gen_helpers::SerializeString(21, it, msg);
  }

  // Field 23: preserve_ftrace_buffer
  if (_has_field_[23]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(23, preserve_ftrace_buffer_, msg);
  }

  // Field 24: use_monotonic_raw_clock
  if (_has_field_[24]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(24, use_monotonic_raw_clock_, msg);
  }

  // Field 25: instance_name
  if (_has_field_[25]) {
    ::protozero::internal::gen_helpers::SerializeString(25, instance_name_, msg);
  }

  // Field 27: buffer_size_lower_bound
  if (_has_field_[27]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(27, buffer_size_lower_bound_, msg);
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}


FtraceConfig_PrintFilter::FtraceConfig_PrintFilter() = default;
FtraceConfig_PrintFilter::~FtraceConfig_PrintFilter() = default;
FtraceConfig_PrintFilter::FtraceConfig_PrintFilter(const FtraceConfig_PrintFilter&) = default;
FtraceConfig_PrintFilter& FtraceConfig_PrintFilter::operator=(const FtraceConfig_PrintFilter&) = default;
FtraceConfig_PrintFilter::FtraceConfig_PrintFilter(FtraceConfig_PrintFilter&&) noexcept = default;
FtraceConfig_PrintFilter& FtraceConfig_PrintFilter::operator=(FtraceConfig_PrintFilter&&) = default;

bool FtraceConfig_PrintFilter::operator==(const FtraceConfig_PrintFilter& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(rules_, other.rules_);
}

int FtraceConfig_PrintFilter::rules_size() const { return static_cast<int>(rules_.size()); }
void FtraceConfig_PrintFilter::clear_rules() { rules_.clear(); }
FtraceConfig_PrintFilter_Rule* FtraceConfig_PrintFilter::add_rules() { rules_.emplace_back(); return &rules_.back(); }
bool FtraceConfig_PrintFilter::ParseFromArray(const void* raw, size_t size) {
  rules_.clear();
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* rules */:
        rules_.emplace_back();
        rules_.back().ParseFromArray(field.data(), field.size());
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string FtraceConfig_PrintFilter::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> FtraceConfig_PrintFilter::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void FtraceConfig_PrintFilter::Serialize(::protozero::Message* msg) const {
  // Field 1: rules
  for (auto& it : rules_) {
    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}


FtraceConfig_PrintFilter_Rule::FtraceConfig_PrintFilter_Rule() = default;
FtraceConfig_PrintFilter_Rule::~FtraceConfig_PrintFilter_Rule() = default;
FtraceConfig_PrintFilter_Rule::FtraceConfig_PrintFilter_Rule(const FtraceConfig_PrintFilter_Rule&) = default;
FtraceConfig_PrintFilter_Rule& FtraceConfig_PrintFilter_Rule::operator=(const FtraceConfig_PrintFilter_Rule&) = default;
FtraceConfig_PrintFilter_Rule::FtraceConfig_PrintFilter_Rule(FtraceConfig_PrintFilter_Rule&&) noexcept = default;
FtraceConfig_PrintFilter_Rule& FtraceConfig_PrintFilter_Rule::operator=(FtraceConfig_PrintFilter_Rule&&) = default;

bool FtraceConfig_PrintFilter_Rule::operator==(const FtraceConfig_PrintFilter_Rule& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(prefix_, other.prefix_)
   && ::protozero::internal::gen_helpers::EqualsField(atrace_msg_, other.atrace_msg_)
   && ::protozero::internal::gen_helpers::EqualsField(allow_, other.allow_);
}

bool FtraceConfig_PrintFilter_Rule::ParseFromArray(const void* raw, size_t size) {
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* prefix */:
        ::protozero::internal::gen_helpers::DeserializeString(field, &prefix_);
        break;
      case 3 /* atrace_msg */:
        (*atrace_msg_).ParseFromArray(field.data(), field.size());
        break;
      case 2 /* allow */:
        field.get(&allow_);
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string FtraceConfig_PrintFilter_Rule::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> FtraceConfig_PrintFilter_Rule::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void FtraceConfig_PrintFilter_Rule::Serialize(::protozero::Message* msg) const {
  // Field 1: prefix
  if (_has_field_[1]) {
    ::protozero::internal::gen_helpers::SerializeString(1, prefix_, msg);
  }

  // Field 3: atrace_msg
  if (_has_field_[3]) {
    (*atrace_msg_).Serialize(msg->BeginNestedMessage<::protozero::Message>(3));
  }

  // Field 2: allow
  if (_has_field_[2]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(2, allow_, msg);
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}


FtraceConfig_PrintFilter_Rule_AtraceMessage::FtraceConfig_PrintFilter_Rule_AtraceMessage() = default;
FtraceConfig_PrintFilter_Rule_AtraceMessage::~FtraceConfig_PrintFilter_Rule_AtraceMessage() = default;
FtraceConfig_PrintFilter_Rule_AtraceMessage::FtraceConfig_PrintFilter_Rule_AtraceMessage(const FtraceConfig_PrintFilter_Rule_AtraceMessage&) = default;
FtraceConfig_PrintFilter_Rule_AtraceMessage& FtraceConfig_PrintFilter_Rule_AtraceMessage::operator=(const FtraceConfig_PrintFilter_Rule_AtraceMessage&) = default;
FtraceConfig_PrintFilter_Rule_AtraceMessage::FtraceConfig_PrintFilter_Rule_AtraceMessage(FtraceConfig_PrintFilter_Rule_AtraceMessage&&) noexcept = default;
FtraceConfig_PrintFilter_Rule_AtraceMessage& FtraceConfig_PrintFilter_Rule_AtraceMessage::operator=(FtraceConfig_PrintFilter_Rule_AtraceMessage&&) = default;

bool FtraceConfig_PrintFilter_Rule_AtraceMessage::operator==(const FtraceConfig_PrintFilter_Rule_AtraceMessage& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(type_, other.type_)
   && ::protozero::internal::gen_helpers::EqualsField(prefix_, other.prefix_);
}

bool FtraceConfig_PrintFilter_Rule_AtraceMessage::ParseFromArray(const void* raw, size_t size) {
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* type */:
        ::protozero::internal::gen_helpers::DeserializeString(field, &type_);
        break;
      case 2 /* prefix */:
        ::protozero::internal::gen_helpers::DeserializeString(field, &prefix_);
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string FtraceConfig_PrintFilter_Rule_AtraceMessage::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> FtraceConfig_PrintFilter_Rule_AtraceMessage::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void FtraceConfig_PrintFilter_Rule_AtraceMessage::Serialize(::protozero::Message* msg) const {
  // Field 1: type
  if (_has_field_[1]) {
    ::protozero::internal::gen_helpers::SerializeString(1, type_, msg);
  }

  // Field 2: prefix
  if (_has_field_[2]) {
    ::protozero::internal::gen_helpers::SerializeString(2, prefix_, msg);
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}


FtraceConfig_CompactSchedConfig::FtraceConfig_CompactSchedConfig() = default;
FtraceConfig_CompactSchedConfig::~FtraceConfig_CompactSchedConfig() = default;
FtraceConfig_CompactSchedConfig::FtraceConfig_CompactSchedConfig(const FtraceConfig_CompactSchedConfig&) = default;
FtraceConfig_CompactSchedConfig& FtraceConfig_CompactSchedConfig::operator=(const FtraceConfig_CompactSchedConfig&) = default;
FtraceConfig_CompactSchedConfig::FtraceConfig_CompactSchedConfig(FtraceConfig_CompactSchedConfig&&) noexcept = default;
FtraceConfig_CompactSchedConfig& FtraceConfig_CompactSchedConfig::operator=(FtraceConfig_CompactSchedConfig&&) = default;

bool FtraceConfig_CompactSchedConfig::operator==(const FtraceConfig_CompactSchedConfig& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(enabled_, other.enabled_);
}

bool FtraceConfig_CompactSchedConfig::ParseFromArray(const void* raw, size_t size) {
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* enabled */:
        field.get(&enabled_);
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string FtraceConfig_CompactSchedConfig::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> FtraceConfig_CompactSchedConfig::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void FtraceConfig_CompactSchedConfig::Serialize(::protozero::Message* msg) const {
  // Field 1: enabled
  if (_has_field_[1]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(1, enabled_, msg);
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}

}  // namespace perfetto
}  // namespace protos
}  // namespace gen
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic pop
#endif
// gen_amalgamated begin source: gen/protos/perfetto/config/gpu/gpu_counter_config.gen.cc
// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wfloat-equal"
#endif
// gen_amalgamated expanded: #include "protos/perfetto/config/gpu/gpu_counter_config.gen.h"

namespace perfetto {
namespace protos {
namespace gen {

GpuCounterConfig::GpuCounterConfig() = default;
GpuCounterConfig::~GpuCounterConfig() = default;
GpuCounterConfig::GpuCounterConfig(const GpuCounterConfig&) = default;
GpuCounterConfig& GpuCounterConfig::operator=(const GpuCounterConfig&) = default;
GpuCounterConfig::GpuCounterConfig(GpuCounterConfig&&) noexcept = default;
GpuCounterConfig& GpuCounterConfig::operator=(GpuCounterConfig&&) = default;

bool GpuCounterConfig::operator==(const GpuCounterConfig& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(counter_period_ns_, other.counter_period_ns_)
   && ::protozero::internal::gen_helpers::EqualsField(counter_ids_, other.counter_ids_)
   && ::protozero::internal::gen_helpers::EqualsField(instrumented_sampling_, other.instrumented_sampling_)
   && ::protozero::internal::gen_helpers::EqualsField(fix_gpu_clock_, other.fix_gpu_clock_);
}

bool GpuCounterConfig::ParseFromArray(const void* raw, size_t size) {
  counter_ids_.clear();
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* counter_period_ns */:
        field.get(&counter_period_ns_);
        break;
      case 2 /* counter_ids */:
        counter_ids_.emplace_back();
        field.get(&counter_ids_.back());
        break;
      case 3 /* instrumented_sampling */:
        field.get(&instrumented_sampling_);
        break;
      case 4 /* fix_gpu_clock */:
        field.get(&fix_gpu_clock_);
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string GpuCounterConfig::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> GpuCounterConfig::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void GpuCounterConfig::Serialize(::protozero::Message* msg) const {
  // Field 1: counter_period_ns
  if (_has_field_[1]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(1, counter_period_ns_, msg);
  }

  // Field 2: counter_ids
  for (auto& it : counter_ids_) {
    ::protozero::internal::gen_helpers::SerializeVarInt(2, it, msg);
  }

  // Field 3: instrumented_sampling
  if (_has_field_[3]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(3, instrumented_sampling_, msg);
  }

  // Field 4: fix_gpu_clock
  if (_has_field_[4]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(4, fix_gpu_clock_, msg);
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}

}  // namespace perfetto
}  // namespace protos
}  // namespace gen
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic pop
#endif
// gen_amalgamated begin source: gen/protos/perfetto/config/gpu/vulkan_memory_config.gen.cc
// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wfloat-equal"
#endif
// gen_amalgamated expanded: #include "protos/perfetto/config/gpu/vulkan_memory_config.gen.h"

namespace perfetto {
namespace protos {
namespace gen {

VulkanMemoryConfig::VulkanMemoryConfig() = default;
VulkanMemoryConfig::~VulkanMemoryConfig() = default;
VulkanMemoryConfig::VulkanMemoryConfig(const VulkanMemoryConfig&) = default;
VulkanMemoryConfig& VulkanMemoryConfig::operator=(const VulkanMemoryConfig&) = default;
VulkanMemoryConfig::VulkanMemoryConfig(VulkanMemoryConfig&&) noexcept = default;
VulkanMemoryConfig& VulkanMemoryConfig::operator=(VulkanMemoryConfig&&) = default;

bool VulkanMemoryConfig::operator==(const VulkanMemoryConfig& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(track_driver_memory_usage_, other.track_driver_memory_usage_)
   && ::protozero::internal::gen_helpers::EqualsField(track_device_memory_usage_, other.track_device_memory_usage_);
}

bool VulkanMemoryConfig::ParseFromArray(const void* raw, size_t size) {
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* track_driver_memory_usage */:
        field.get(&track_driver_memory_usage_);
        break;
      case 2 /* track_device_memory_usage */:
        field.get(&track_device_memory_usage_);
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string VulkanMemoryConfig::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> VulkanMemoryConfig::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void VulkanMemoryConfig::Serialize(::protozero::Message* msg) const {
  // Field 1: track_driver_memory_usage
  if (_has_field_[1]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(1, track_driver_memory_usage_, msg);
  }

  // Field 2: track_device_memory_usage
  if (_has_field_[2]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(2, track_device_memory_usage_, msg);
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}

}  // namespace perfetto
}  // namespace protos
}  // namespace gen
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic pop
#endif
// gen_amalgamated begin source: gen/protos/perfetto/config/inode_file/inode_file_config.gen.cc
// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wfloat-equal"
#endif
// gen_amalgamated expanded: #include "protos/perfetto/config/inode_file/inode_file_config.gen.h"

namespace perfetto {
namespace protos {
namespace gen {

InodeFileConfig::InodeFileConfig() = default;
InodeFileConfig::~InodeFileConfig() = default;
InodeFileConfig::InodeFileConfig(const InodeFileConfig&) = default;
InodeFileConfig& InodeFileConfig::operator=(const InodeFileConfig&) = default;
InodeFileConfig::InodeFileConfig(InodeFileConfig&&) noexcept = default;
InodeFileConfig& InodeFileConfig::operator=(InodeFileConfig&&) = default;

bool InodeFileConfig::operator==(const InodeFileConfig& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(scan_interval_ms_, other.scan_interval_ms_)
   && ::protozero::internal::gen_helpers::EqualsField(scan_delay_ms_, other.scan_delay_ms_)
   && ::protozero::internal::gen_helpers::EqualsField(scan_batch_size_, other.scan_batch_size_)
   && ::protozero::internal::gen_helpers::EqualsField(do_not_scan_, other.do_not_scan_)
   && ::protozero::internal::gen_helpers::EqualsField(scan_mount_points_, other.scan_mount_points_)
   && ::protozero::internal::gen_helpers::EqualsField(mount_point_mapping_, other.mount_point_mapping_);
}

int InodeFileConfig::mount_point_mapping_size() const { return static_cast<int>(mount_point_mapping_.size()); }
void InodeFileConfig::clear_mount_point_mapping() { mount_point_mapping_.clear(); }
InodeFileConfig_MountPointMappingEntry* InodeFileConfig::add_mount_point_mapping() { mount_point_mapping_.emplace_back(); return &mount_point_mapping_.back(); }
bool InodeFileConfig::ParseFromArray(const void* raw, size_t size) {
  scan_mount_points_.clear();
  mount_point_mapping_.clear();
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* scan_interval_ms */:
        field.get(&scan_interval_ms_);
        break;
      case 2 /* scan_delay_ms */:
        field.get(&scan_delay_ms_);
        break;
      case 3 /* scan_batch_size */:
        field.get(&scan_batch_size_);
        break;
      case 4 /* do_not_scan */:
        field.get(&do_not_scan_);
        break;
      case 5 /* scan_mount_points */:
        scan_mount_points_.emplace_back();
        ::protozero::internal::gen_helpers::DeserializeString(field, &scan_mount_points_.back());
        break;
      case 6 /* mount_point_mapping */:
        mount_point_mapping_.emplace_back();
        mount_point_mapping_.back().ParseFromArray(field.data(), field.size());
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string InodeFileConfig::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> InodeFileConfig::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void InodeFileConfig::Serialize(::protozero::Message* msg) const {
  // Field 1: scan_interval_ms
  if (_has_field_[1]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(1, scan_interval_ms_, msg);
  }

  // Field 2: scan_delay_ms
  if (_has_field_[2]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(2, scan_delay_ms_, msg);
  }

  // Field 3: scan_batch_size
  if (_has_field_[3]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(3, scan_batch_size_, msg);
  }

  // Field 4: do_not_scan
  if (_has_field_[4]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(4, do_not_scan_, msg);
  }

  // Field 5: scan_mount_points
  for (auto& it : scan_mount_points_) {
    ::protozero::internal::gen_helpers::SerializeString(5, it, msg);
  }

  // Field 6: mount_point_mapping
  for (auto& it : mount_point_mapping_) {
    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(6));
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}


InodeFileConfig_MountPointMappingEntry::InodeFileConfig_MountPointMappingEntry() = default;
InodeFileConfig_MountPointMappingEntry::~InodeFileConfig_MountPointMappingEntry() = default;
InodeFileConfig_MountPointMappingEntry::InodeFileConfig_MountPointMappingEntry(const InodeFileConfig_MountPointMappingEntry&) = default;
InodeFileConfig_MountPointMappingEntry& InodeFileConfig_MountPointMappingEntry::operator=(const InodeFileConfig_MountPointMappingEntry&) = default;
InodeFileConfig_MountPointMappingEntry::InodeFileConfig_MountPointMappingEntry(InodeFileConfig_MountPointMappingEntry&&) noexcept = default;
InodeFileConfig_MountPointMappingEntry& InodeFileConfig_MountPointMappingEntry::operator=(InodeFileConfig_MountPointMappingEntry&&) = default;

bool InodeFileConfig_MountPointMappingEntry::operator==(const InodeFileConfig_MountPointMappingEntry& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(mountpoint_, other.mountpoint_)
   && ::protozero::internal::gen_helpers::EqualsField(scan_roots_, other.scan_roots_);
}

bool InodeFileConfig_MountPointMappingEntry::ParseFromArray(const void* raw, size_t size) {
  scan_roots_.clear();
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* mountpoint */:
        ::protozero::internal::gen_helpers::DeserializeString(field, &mountpoint_);
        break;
      case 2 /* scan_roots */:
        scan_roots_.emplace_back();
        ::protozero::internal::gen_helpers::DeserializeString(field, &scan_roots_.back());
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string InodeFileConfig_MountPointMappingEntry::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> InodeFileConfig_MountPointMappingEntry::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void InodeFileConfig_MountPointMappingEntry::Serialize(::protozero::Message* msg) const {
  // Field 1: mountpoint
  if (_has_field_[1]) {
    ::protozero::internal::gen_helpers::SerializeString(1, mountpoint_, msg);
  }

  // Field 2: scan_roots
  for (auto& it : scan_roots_) {
    ::protozero::internal::gen_helpers::SerializeString(2, it, msg);
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}

}  // namespace perfetto
}  // namespace protos
}  // namespace gen
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic pop
#endif
// gen_amalgamated begin source: gen/protos/perfetto/config/interceptors/console_config.gen.cc
// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wfloat-equal"
#endif
// gen_amalgamated expanded: #include "protos/perfetto/config/interceptors/console_config.gen.h"

namespace perfetto {
namespace protos {
namespace gen {

ConsoleConfig::ConsoleConfig() = default;
ConsoleConfig::~ConsoleConfig() = default;
ConsoleConfig::ConsoleConfig(const ConsoleConfig&) = default;
ConsoleConfig& ConsoleConfig::operator=(const ConsoleConfig&) = default;
ConsoleConfig::ConsoleConfig(ConsoleConfig&&) noexcept = default;
ConsoleConfig& ConsoleConfig::operator=(ConsoleConfig&&) = default;

bool ConsoleConfig::operator==(const ConsoleConfig& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(output_, other.output_)
   && ::protozero::internal::gen_helpers::EqualsField(enable_colors_, other.enable_colors_);
}

bool ConsoleConfig::ParseFromArray(const void* raw, size_t size) {
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* output */:
        field.get(&output_);
        break;
      case 2 /* enable_colors */:
        field.get(&enable_colors_);
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string ConsoleConfig::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> ConsoleConfig::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void ConsoleConfig::Serialize(::protozero::Message* msg) const {
  // Field 1: output
  if (_has_field_[1]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(1, output_, msg);
  }

  // Field 2: enable_colors
  if (_has_field_[2]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(2, enable_colors_, msg);
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}

}  // namespace perfetto
}  // namespace protos
}  // namespace gen
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic pop
#endif
// gen_amalgamated begin source: gen/protos/perfetto/config/power/android_power_config.gen.cc
// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wfloat-equal"
#endif
// gen_amalgamated expanded: #include "protos/perfetto/config/power/android_power_config.gen.h"

namespace perfetto {
namespace protos {
namespace gen {

AndroidPowerConfig::AndroidPowerConfig() = default;
AndroidPowerConfig::~AndroidPowerConfig() = default;
AndroidPowerConfig::AndroidPowerConfig(const AndroidPowerConfig&) = default;
AndroidPowerConfig& AndroidPowerConfig::operator=(const AndroidPowerConfig&) = default;
AndroidPowerConfig::AndroidPowerConfig(AndroidPowerConfig&&) noexcept = default;
AndroidPowerConfig& AndroidPowerConfig::operator=(AndroidPowerConfig&&) = default;

bool AndroidPowerConfig::operator==(const AndroidPowerConfig& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(battery_poll_ms_, other.battery_poll_ms_)
   && ::protozero::internal::gen_helpers::EqualsField(battery_counters_, other.battery_counters_)
   && ::protozero::internal::gen_helpers::EqualsField(collect_power_rails_, other.collect_power_rails_)
   && ::protozero::internal::gen_helpers::EqualsField(collect_energy_estimation_breakdown_, other.collect_energy_estimation_breakdown_)
   && ::protozero::internal::gen_helpers::EqualsField(collect_entity_state_residency_, other.collect_entity_state_residency_);
}

bool AndroidPowerConfig::ParseFromArray(const void* raw, size_t size) {
  battery_counters_.clear();
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* battery_poll_ms */:
        field.get(&battery_poll_ms_);
        break;
      case 2 /* battery_counters */:
        battery_counters_.emplace_back();
        field.get(&battery_counters_.back());
        break;
      case 3 /* collect_power_rails */:
        field.get(&collect_power_rails_);
        break;
      case 4 /* collect_energy_estimation_breakdown */:
        field.get(&collect_energy_estimation_breakdown_);
        break;
      case 5 /* collect_entity_state_residency */:
        field.get(&collect_entity_state_residency_);
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string AndroidPowerConfig::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> AndroidPowerConfig::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void AndroidPowerConfig::Serialize(::protozero::Message* msg) const {
  // Field 1: battery_poll_ms
  if (_has_field_[1]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(1, battery_poll_ms_, msg);
  }

  // Field 2: battery_counters
  for (auto& it : battery_counters_) {
    ::protozero::internal::gen_helpers::SerializeVarInt(2, it, msg);
  }

  // Field 3: collect_power_rails
  if (_has_field_[3]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(3, collect_power_rails_, msg);
  }

  // Field 4: collect_energy_estimation_breakdown
  if (_has_field_[4]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(4, collect_energy_estimation_breakdown_, msg);
  }

  // Field 5: collect_entity_state_residency
  if (_has_field_[5]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(5, collect_entity_state_residency_, msg);
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}

}  // namespace perfetto
}  // namespace protos
}  // namespace gen
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic pop
#endif
// gen_amalgamated begin source: gen/protos/perfetto/config/process_stats/process_stats_config.gen.cc
// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wfloat-equal"
#endif
// gen_amalgamated expanded: #include "protos/perfetto/config/process_stats/process_stats_config.gen.h"

namespace perfetto {
namespace protos {
namespace gen {

ProcessStatsConfig::ProcessStatsConfig() = default;
ProcessStatsConfig::~ProcessStatsConfig() = default;
ProcessStatsConfig::ProcessStatsConfig(const ProcessStatsConfig&) = default;
ProcessStatsConfig& ProcessStatsConfig::operator=(const ProcessStatsConfig&) = default;
ProcessStatsConfig::ProcessStatsConfig(ProcessStatsConfig&&) noexcept = default;
ProcessStatsConfig& ProcessStatsConfig::operator=(ProcessStatsConfig&&) = default;

bool ProcessStatsConfig::operator==(const ProcessStatsConfig& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(quirks_, other.quirks_)
   && ::protozero::internal::gen_helpers::EqualsField(scan_all_processes_on_start_, other.scan_all_processes_on_start_)
   && ::protozero::internal::gen_helpers::EqualsField(record_thread_names_, other.record_thread_names_)
   && ::protozero::internal::gen_helpers::EqualsField(proc_stats_poll_ms_, other.proc_stats_poll_ms_)
   && ::protozero::internal::gen_helpers::EqualsField(proc_stats_cache_ttl_ms_, other.proc_stats_cache_ttl_ms_)
   && ::protozero::internal::gen_helpers::EqualsField(resolve_process_fds_, other.resolve_process_fds_)
   && ::protozero::internal::gen_helpers::EqualsField(scan_smaps_rollup_, other.scan_smaps_rollup_)
   && ::protozero::internal::gen_helpers::EqualsField(record_process_age_, other.record_process_age_)
   && ::protozero::internal::gen_helpers::EqualsField(record_process_runtime_, other.record_process_runtime_);
}

bool ProcessStatsConfig::ParseFromArray(const void* raw, size_t size) {
  quirks_.clear();
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* quirks */:
        quirks_.emplace_back();
        field.get(&quirks_.back());
        break;
      case 2 /* scan_all_processes_on_start */:
        field.get(&scan_all_processes_on_start_);
        break;
      case 3 /* record_thread_names */:
        field.get(&record_thread_names_);
        break;
      case 4 /* proc_stats_poll_ms */:
        field.get(&proc_stats_poll_ms_);
        break;
      case 6 /* proc_stats_cache_ttl_ms */:
        field.get(&proc_stats_cache_ttl_ms_);
        break;
      case 9 /* resolve_process_fds */:
        field.get(&resolve_process_fds_);
        break;
      case 10 /* scan_smaps_rollup */:
        field.get(&scan_smaps_rollup_);
        break;
      case 11 /* record_process_age */:
        field.get(&record_process_age_);
        break;
      case 12 /* record_process_runtime */:
        field.get(&record_process_runtime_);
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string ProcessStatsConfig::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> ProcessStatsConfig::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void ProcessStatsConfig::Serialize(::protozero::Message* msg) const {
  // Field 1: quirks
  for (auto& it : quirks_) {
    ::protozero::internal::gen_helpers::SerializeVarInt(1, it, msg);
  }

  // Field 2: scan_all_processes_on_start
  if (_has_field_[2]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(2, scan_all_processes_on_start_, msg);
  }

  // Field 3: record_thread_names
  if (_has_field_[3]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(3, record_thread_names_, msg);
  }

  // Field 4: proc_stats_poll_ms
  if (_has_field_[4]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(4, proc_stats_poll_ms_, msg);
  }

  // Field 6: proc_stats_cache_ttl_ms
  if (_has_field_[6]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(6, proc_stats_cache_ttl_ms_, msg);
  }

  // Field 9: resolve_process_fds
  if (_has_field_[9]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(9, resolve_process_fds_, msg);
  }

  // Field 10: scan_smaps_rollup
  if (_has_field_[10]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(10, scan_smaps_rollup_, msg);
  }

  // Field 11: record_process_age
  if (_has_field_[11]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(11, record_process_age_, msg);
  }

  // Field 12: record_process_runtime
  if (_has_field_[12]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(12, record_process_runtime_, msg);
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}

}  // namespace perfetto
}  // namespace protos
}  // namespace gen
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic pop
#endif
// gen_amalgamated begin source: gen/protos/perfetto/config/profiling/heapprofd_config.gen.cc
// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wfloat-equal"
#endif
// gen_amalgamated expanded: #include "protos/perfetto/config/profiling/heapprofd_config.gen.h"

namespace perfetto {
namespace protos {
namespace gen {

HeapprofdConfig::HeapprofdConfig() = default;
HeapprofdConfig::~HeapprofdConfig() = default;
HeapprofdConfig::HeapprofdConfig(const HeapprofdConfig&) = default;
HeapprofdConfig& HeapprofdConfig::operator=(const HeapprofdConfig&) = default;
HeapprofdConfig::HeapprofdConfig(HeapprofdConfig&&) noexcept = default;
HeapprofdConfig& HeapprofdConfig::operator=(HeapprofdConfig&&) = default;

bool HeapprofdConfig::operator==(const HeapprofdConfig& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(sampling_interval_bytes_, other.sampling_interval_bytes_)
   && ::protozero::internal::gen_helpers::EqualsField(adaptive_sampling_shmem_threshold_, other.adaptive_sampling_shmem_threshold_)
   && ::protozero::internal::gen_helpers::EqualsField(adaptive_sampling_max_sampling_interval_bytes_, other.adaptive_sampling_max_sampling_interval_bytes_)
   && ::protozero::internal::gen_helpers::EqualsField(process_cmdline_, other.process_cmdline_)
   && ::protozero::internal::gen_helpers::EqualsField(pid_, other.pid_)
   && ::protozero::internal::gen_helpers::EqualsField(target_installed_by_, other.target_installed_by_)
   && ::protozero::internal::gen_helpers::EqualsField(heaps_, other.heaps_)
   && ::protozero::internal::gen_helpers::EqualsField(exclude_heaps_, other.exclude_heaps_)
   && ::protozero::internal::gen_helpers::EqualsField(stream_allocations_, other.stream_allocations_)
   && ::protozero::internal::gen_helpers::EqualsField(heap_sampling_intervals_, other.heap_sampling_intervals_)
   && ::protozero::internal::gen_helpers::EqualsField(all_heaps_, other.all_heaps_)
   && ::protozero::internal::gen_helpers::EqualsField(all_, other.all_)
   && ::protozero::internal::gen_helpers::EqualsField(min_anonymous_memory_kb_, other.min_anonymous_memory_kb_)
   && ::protozero::internal::gen_helpers::EqualsField(max_heapprofd_memory_kb_, other.max_heapprofd_memory_kb_)
   && ::protozero::internal::gen_helpers::EqualsField(max_heapprofd_cpu_secs_, other.max_heapprofd_cpu_secs_)
   && ::protozero::internal::gen_helpers::EqualsField(skip_symbol_prefix_, other.skip_symbol_prefix_)
   && ::protozero::internal::gen_helpers::EqualsField(continuous_dump_config_, other.continuous_dump_config_)
   && ::protozero::internal::gen_helpers::EqualsField(shmem_size_bytes_, other.shmem_size_bytes_)
   && ::protozero::internal::gen_helpers::EqualsField(block_client_, other.block_client_)
   && ::protozero::internal::gen_helpers::EqualsField(block_client_timeout_us_, other.block_client_timeout_us_)
   && ::protozero::internal::gen_helpers::EqualsField(no_startup_, other.no_startup_)
   && ::protozero::internal::gen_helpers::EqualsField(no_running_, other.no_running_)
   && ::protozero::internal::gen_helpers::EqualsField(dump_at_max_, other.dump_at_max_)
   && ::protozero::internal::gen_helpers::EqualsField(disable_fork_teardown_, other.disable_fork_teardown_)
   && ::protozero::internal::gen_helpers::EqualsField(disable_vfork_detection_, other.disable_vfork_detection_);
}

bool HeapprofdConfig::ParseFromArray(const void* raw, size_t size) {
  process_cmdline_.clear();
  pid_.clear();
  target_installed_by_.clear();
  heaps_.clear();
  exclude_heaps_.clear();
  heap_sampling_intervals_.clear();
  skip_symbol_prefix_.clear();
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* sampling_interval_bytes */:
        field.get(&sampling_interval_bytes_);
        break;
      case 24 /* adaptive_sampling_shmem_threshold */:
        field.get(&adaptive_sampling_shmem_threshold_);
        break;
      case 25 /* adaptive_sampling_max_sampling_interval_bytes */:
        field.get(&adaptive_sampling_max_sampling_interval_bytes_);
        break;
      case 2 /* process_cmdline */:
        process_cmdline_.emplace_back();
        ::protozero::internal::gen_helpers::DeserializeString(field, &process_cmdline_.back());
        break;
      case 4 /* pid */:
        pid_.emplace_back();
        field.get(&pid_.back());
        break;
      case 26 /* target_installed_by */:
        target_installed_by_.emplace_back();
        ::protozero::internal::gen_helpers::DeserializeString(field, &target_installed_by_.back());
        break;
      case 20 /* heaps */:
        heaps_.emplace_back();
        ::protozero::internal::gen_helpers::DeserializeString(field, &heaps_.back());
        break;
      case 27 /* exclude_heaps */:
        exclude_heaps_.emplace_back();
        ::protozero::internal::gen_helpers::DeserializeString(field, &exclude_heaps_.back());
        break;
      case 23 /* stream_allocations */:
        field.get(&stream_allocations_);
        break;
      case 22 /* heap_sampling_intervals */:
        heap_sampling_intervals_.emplace_back();
        field.get(&heap_sampling_intervals_.back());
        break;
      case 21 /* all_heaps */:
        field.get(&all_heaps_);
        break;
      case 5 /* all */:
        field.get(&all_);
        break;
      case 15 /* min_anonymous_memory_kb */:
        field.get(&min_anonymous_memory_kb_);
        break;
      case 16 /* max_heapprofd_memory_kb */:
        field.get(&max_heapprofd_memory_kb_);
        break;
      case 17 /* max_heapprofd_cpu_secs */:
        field.get(&max_heapprofd_cpu_secs_);
        break;
      case 7 /* skip_symbol_prefix */:
        skip_symbol_prefix_.emplace_back();
        ::protozero::internal::gen_helpers::DeserializeString(field, &skip_symbol_prefix_.back());
        break;
      case 6 /* continuous_dump_config */:
        (*continuous_dump_config_).ParseFromArray(field.data(), field.size());
        break;
      case 8 /* shmem_size_bytes */:
        field.get(&shmem_size_bytes_);
        break;
      case 9 /* block_client */:
        field.get(&block_client_);
        break;
      case 14 /* block_client_timeout_us */:
        field.get(&block_client_timeout_us_);
        break;
      case 10 /* no_startup */:
        field.get(&no_startup_);
        break;
      case 11 /* no_running */:
        field.get(&no_running_);
        break;
      case 13 /* dump_at_max */:
        field.get(&dump_at_max_);
        break;
      case 18 /* disable_fork_teardown */:
        field.get(&disable_fork_teardown_);
        break;
      case 19 /* disable_vfork_detection */:
        field.get(&disable_vfork_detection_);
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string HeapprofdConfig::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> HeapprofdConfig::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void HeapprofdConfig::Serialize(::protozero::Message* msg) const {
  // Field 1: sampling_interval_bytes
  if (_has_field_[1]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(1, sampling_interval_bytes_, msg);
  }

  // Field 24: adaptive_sampling_shmem_threshold
  if (_has_field_[24]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(24, adaptive_sampling_shmem_threshold_, msg);
  }

  // Field 25: adaptive_sampling_max_sampling_interval_bytes
  if (_has_field_[25]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(25, adaptive_sampling_max_sampling_interval_bytes_, msg);
  }

  // Field 2: process_cmdline
  for (auto& it : process_cmdline_) {
    ::protozero::internal::gen_helpers::SerializeString(2, it, msg);
  }

  // Field 4: pid
  for (auto& it : pid_) {
    ::protozero::internal::gen_helpers::SerializeVarInt(4, it, msg);
  }

  // Field 26: target_installed_by
  for (auto& it : target_installed_by_) {
    ::protozero::internal::gen_helpers::SerializeString(26, it, msg);
  }

  // Field 20: heaps
  for (auto& it : heaps_) {
    ::protozero::internal::gen_helpers::SerializeString(20, it, msg);
  }

  // Field 27: exclude_heaps
  for (auto& it : exclude_heaps_) {
    ::protozero::internal::gen_helpers::SerializeString(27, it, msg);
  }

  // Field 23: stream_allocations
  if (_has_field_[23]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(23, stream_allocations_, msg);
  }

  // Field 22: heap_sampling_intervals
  for (auto& it : heap_sampling_intervals_) {
    ::protozero::internal::gen_helpers::SerializeVarInt(22, it, msg);
  }

  // Field 21: all_heaps
  if (_has_field_[21]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(21, all_heaps_, msg);
  }

  // Field 5: all
  if (_has_field_[5]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(5, all_, msg);
  }

  // Field 15: min_anonymous_memory_kb
  if (_has_field_[15]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(15, min_anonymous_memory_kb_, msg);
  }

  // Field 16: max_heapprofd_memory_kb
  if (_has_field_[16]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(16, max_heapprofd_memory_kb_, msg);
  }

  // Field 17: max_heapprofd_cpu_secs
  if (_has_field_[17]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(17, max_heapprofd_cpu_secs_, msg);
  }

  // Field 7: skip_symbol_prefix
  for (auto& it : skip_symbol_prefix_) {
    ::protozero::internal::gen_helpers::SerializeString(7, it, msg);
  }

  // Field 6: continuous_dump_config
  if (_has_field_[6]) {
    (*continuous_dump_config_).Serialize(msg->BeginNestedMessage<::protozero::Message>(6));
  }

  // Field 8: shmem_size_bytes
  if (_has_field_[8]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(8, shmem_size_bytes_, msg);
  }

  // Field 9: block_client
  if (_has_field_[9]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(9, block_client_, msg);
  }

  // Field 14: block_client_timeout_us
  if (_has_field_[14]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(14, block_client_timeout_us_, msg);
  }

  // Field 10: no_startup
  if (_has_field_[10]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(10, no_startup_, msg);
  }

  // Field 11: no_running
  if (_has_field_[11]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(11, no_running_, msg);
  }

  // Field 13: dump_at_max
  if (_has_field_[13]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(13, dump_at_max_, msg);
  }

  // Field 18: disable_fork_teardown
  if (_has_field_[18]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(18, disable_fork_teardown_, msg);
  }

  // Field 19: disable_vfork_detection
  if (_has_field_[19]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(19, disable_vfork_detection_, msg);
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}


HeapprofdConfig_ContinuousDumpConfig::HeapprofdConfig_ContinuousDumpConfig() = default;
HeapprofdConfig_ContinuousDumpConfig::~HeapprofdConfig_ContinuousDumpConfig() = default;
HeapprofdConfig_ContinuousDumpConfig::HeapprofdConfig_ContinuousDumpConfig(const HeapprofdConfig_ContinuousDumpConfig&) = default;
HeapprofdConfig_ContinuousDumpConfig& HeapprofdConfig_ContinuousDumpConfig::operator=(const HeapprofdConfig_ContinuousDumpConfig&) = default;
HeapprofdConfig_ContinuousDumpConfig::HeapprofdConfig_ContinuousDumpConfig(HeapprofdConfig_ContinuousDumpConfig&&) noexcept = default;
HeapprofdConfig_ContinuousDumpConfig& HeapprofdConfig_ContinuousDumpConfig::operator=(HeapprofdConfig_ContinuousDumpConfig&&) = default;

bool HeapprofdConfig_ContinuousDumpConfig::operator==(const HeapprofdConfig_ContinuousDumpConfig& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(dump_phase_ms_, other.dump_phase_ms_)
   && ::protozero::internal::gen_helpers::EqualsField(dump_interval_ms_, other.dump_interval_ms_);
}

bool HeapprofdConfig_ContinuousDumpConfig::ParseFromArray(const void* raw, size_t size) {
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 5 /* dump_phase_ms */:
        field.get(&dump_phase_ms_);
        break;
      case 6 /* dump_interval_ms */:
        field.get(&dump_interval_ms_);
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string HeapprofdConfig_ContinuousDumpConfig::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> HeapprofdConfig_ContinuousDumpConfig::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void HeapprofdConfig_ContinuousDumpConfig::Serialize(::protozero::Message* msg) const {
  // Field 5: dump_phase_ms
  if (_has_field_[5]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(5, dump_phase_ms_, msg);
  }

  // Field 6: dump_interval_ms
  if (_has_field_[6]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(6, dump_interval_ms_, msg);
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}

}  // namespace perfetto
}  // namespace protos
}  // namespace gen
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic pop
#endif
// gen_amalgamated begin source: gen/protos/perfetto/config/profiling/java_hprof_config.gen.cc
// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wfloat-equal"
#endif
// gen_amalgamated expanded: #include "protos/perfetto/config/profiling/java_hprof_config.gen.h"

namespace perfetto {
namespace protos {
namespace gen {

JavaHprofConfig::JavaHprofConfig() = default;
JavaHprofConfig::~JavaHprofConfig() = default;
JavaHprofConfig::JavaHprofConfig(const JavaHprofConfig&) = default;
JavaHprofConfig& JavaHprofConfig::operator=(const JavaHprofConfig&) = default;
JavaHprofConfig::JavaHprofConfig(JavaHprofConfig&&) noexcept = default;
JavaHprofConfig& JavaHprofConfig::operator=(JavaHprofConfig&&) = default;

bool JavaHprofConfig::operator==(const JavaHprofConfig& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(process_cmdline_, other.process_cmdline_)
   && ::protozero::internal::gen_helpers::EqualsField(pid_, other.pid_)
   && ::protozero::internal::gen_helpers::EqualsField(target_installed_by_, other.target_installed_by_)
   && ::protozero::internal::gen_helpers::EqualsField(continuous_dump_config_, other.continuous_dump_config_)
   && ::protozero::internal::gen_helpers::EqualsField(min_anonymous_memory_kb_, other.min_anonymous_memory_kb_)
   && ::protozero::internal::gen_helpers::EqualsField(dump_smaps_, other.dump_smaps_)
   && ::protozero::internal::gen_helpers::EqualsField(ignored_types_, other.ignored_types_);
}

bool JavaHprofConfig::ParseFromArray(const void* raw, size_t size) {
  process_cmdline_.clear();
  pid_.clear();
  target_installed_by_.clear();
  ignored_types_.clear();
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* process_cmdline */:
        process_cmdline_.emplace_back();
        ::protozero::internal::gen_helpers::DeserializeString(field, &process_cmdline_.back());
        break;
      case 2 /* pid */:
        pid_.emplace_back();
        field.get(&pid_.back());
        break;
      case 7 /* target_installed_by */:
        target_installed_by_.emplace_back();
        ::protozero::internal::gen_helpers::DeserializeString(field, &target_installed_by_.back());
        break;
      case 3 /* continuous_dump_config */:
        (*continuous_dump_config_).ParseFromArray(field.data(), field.size());
        break;
      case 4 /* min_anonymous_memory_kb */:
        field.get(&min_anonymous_memory_kb_);
        break;
      case 5 /* dump_smaps */:
        field.get(&dump_smaps_);
        break;
      case 6 /* ignored_types */:
        ignored_types_.emplace_back();
        ::protozero::internal::gen_helpers::DeserializeString(field, &ignored_types_.back());
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string JavaHprofConfig::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> JavaHprofConfig::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void JavaHprofConfig::Serialize(::protozero::Message* msg) const {
  // Field 1: process_cmdline
  for (auto& it : process_cmdline_) {
    ::protozero::internal::gen_helpers::SerializeString(1, it, msg);
  }

  // Field 2: pid
  for (auto& it : pid_) {
    ::protozero::internal::gen_helpers::SerializeVarInt(2, it, msg);
  }

  // Field 7: target_installed_by
  for (auto& it : target_installed_by_) {
    ::protozero::internal::gen_helpers::SerializeString(7, it, msg);
  }

  // Field 3: continuous_dump_config
  if (_has_field_[3]) {
    (*continuous_dump_config_).Serialize(msg->BeginNestedMessage<::protozero::Message>(3));
  }

  // Field 4: min_anonymous_memory_kb
  if (_has_field_[4]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(4, min_anonymous_memory_kb_, msg);
  }

  // Field 5: dump_smaps
  if (_has_field_[5]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(5, dump_smaps_, msg);
  }

  // Field 6: ignored_types
  for (auto& it : ignored_types_) {
    ::protozero::internal::gen_helpers::SerializeString(6, it, msg);
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}


JavaHprofConfig_ContinuousDumpConfig::JavaHprofConfig_ContinuousDumpConfig() = default;
JavaHprofConfig_ContinuousDumpConfig::~JavaHprofConfig_ContinuousDumpConfig() = default;
JavaHprofConfig_ContinuousDumpConfig::JavaHprofConfig_ContinuousDumpConfig(const JavaHprofConfig_ContinuousDumpConfig&) = default;
JavaHprofConfig_ContinuousDumpConfig& JavaHprofConfig_ContinuousDumpConfig::operator=(const JavaHprofConfig_ContinuousDumpConfig&) = default;
JavaHprofConfig_ContinuousDumpConfig::JavaHprofConfig_ContinuousDumpConfig(JavaHprofConfig_ContinuousDumpConfig&&) noexcept = default;
JavaHprofConfig_ContinuousDumpConfig& JavaHprofConfig_ContinuousDumpConfig::operator=(JavaHprofConfig_ContinuousDumpConfig&&) = default;

bool JavaHprofConfig_ContinuousDumpConfig::operator==(const JavaHprofConfig_ContinuousDumpConfig& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(dump_phase_ms_, other.dump_phase_ms_)
   && ::protozero::internal::gen_helpers::EqualsField(dump_interval_ms_, other.dump_interval_ms_)
   && ::protozero::internal::gen_helpers::EqualsField(scan_pids_only_on_start_, other.scan_pids_only_on_start_);
}

bool JavaHprofConfig_ContinuousDumpConfig::ParseFromArray(const void* raw, size_t size) {
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* dump_phase_ms */:
        field.get(&dump_phase_ms_);
        break;
      case 2 /* dump_interval_ms */:
        field.get(&dump_interval_ms_);
        break;
      case 3 /* scan_pids_only_on_start */:
        field.get(&scan_pids_only_on_start_);
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string JavaHprofConfig_ContinuousDumpConfig::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> JavaHprofConfig_ContinuousDumpConfig::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void JavaHprofConfig_ContinuousDumpConfig::Serialize(::protozero::Message* msg) const {
  // Field 1: dump_phase_ms
  if (_has_field_[1]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(1, dump_phase_ms_, msg);
  }

  // Field 2: dump_interval_ms
  if (_has_field_[2]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(2, dump_interval_ms_, msg);
  }

  // Field 3: scan_pids_only_on_start
  if (_has_field_[3]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(3, scan_pids_only_on_start_, msg);
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}

}  // namespace perfetto
}  // namespace protos
}  // namespace gen
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic pop
#endif
// gen_amalgamated begin source: gen/protos/perfetto/config/profiling/perf_event_config.gen.cc
// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wfloat-equal"
#endif
// gen_amalgamated expanded: #include "protos/perfetto/config/profiling/perf_event_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/common/perf_events.gen.h"

namespace perfetto {
namespace protos {
namespace gen {

PerfEventConfig::PerfEventConfig() = default;
PerfEventConfig::~PerfEventConfig() = default;
PerfEventConfig::PerfEventConfig(const PerfEventConfig&) = default;
PerfEventConfig& PerfEventConfig::operator=(const PerfEventConfig&) = default;
PerfEventConfig::PerfEventConfig(PerfEventConfig&&) noexcept = default;
PerfEventConfig& PerfEventConfig::operator=(PerfEventConfig&&) = default;

bool PerfEventConfig::operator==(const PerfEventConfig& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(timebase_, other.timebase_)
   && ::protozero::internal::gen_helpers::EqualsField(callstack_sampling_, other.callstack_sampling_)
   && ::protozero::internal::gen_helpers::EqualsField(ring_buffer_read_period_ms_, other.ring_buffer_read_period_ms_)
   && ::protozero::internal::gen_helpers::EqualsField(ring_buffer_pages_, other.ring_buffer_pages_)
   && ::protozero::internal::gen_helpers::EqualsField(max_enqueued_footprint_kb_, other.max_enqueued_footprint_kb_)
   && ::protozero::internal::gen_helpers::EqualsField(max_daemon_memory_kb_, other.max_daemon_memory_kb_)
   && ::protozero::internal::gen_helpers::EqualsField(remote_descriptor_timeout_ms_, other.remote_descriptor_timeout_ms_)
   && ::protozero::internal::gen_helpers::EqualsField(unwind_state_clear_period_ms_, other.unwind_state_clear_period_ms_)
   && ::protozero::internal::gen_helpers::EqualsField(target_installed_by_, other.target_installed_by_)
   && ::protozero::internal::gen_helpers::EqualsField(all_cpus_, other.all_cpus_)
   && ::protozero::internal::gen_helpers::EqualsField(sampling_frequency_, other.sampling_frequency_)
   && ::protozero::internal::gen_helpers::EqualsField(kernel_frames_, other.kernel_frames_)
   && ::protozero::internal::gen_helpers::EqualsField(target_pid_, other.target_pid_)
   && ::protozero::internal::gen_helpers::EqualsField(target_cmdline_, other.target_cmdline_)
   && ::protozero::internal::gen_helpers::EqualsField(exclude_pid_, other.exclude_pid_)
   && ::protozero::internal::gen_helpers::EqualsField(exclude_cmdline_, other.exclude_cmdline_)
   && ::protozero::internal::gen_helpers::EqualsField(additional_cmdline_count_, other.additional_cmdline_count_);
}

bool PerfEventConfig::ParseFromArray(const void* raw, size_t size) {
  target_installed_by_.clear();
  target_pid_.clear();
  target_cmdline_.clear();
  exclude_pid_.clear();
  exclude_cmdline_.clear();
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 15 /* timebase */:
        (*timebase_).ParseFromArray(field.data(), field.size());
        break;
      case 16 /* callstack_sampling */:
        (*callstack_sampling_).ParseFromArray(field.data(), field.size());
        break;
      case 8 /* ring_buffer_read_period_ms */:
        field.get(&ring_buffer_read_period_ms_);
        break;
      case 3 /* ring_buffer_pages */:
        field.get(&ring_buffer_pages_);
        break;
      case 17 /* max_enqueued_footprint_kb */:
        field.get(&max_enqueued_footprint_kb_);
        break;
      case 13 /* max_daemon_memory_kb */:
        field.get(&max_daemon_memory_kb_);
        break;
      case 9 /* remote_descriptor_timeout_ms */:
        field.get(&remote_descriptor_timeout_ms_);
        break;
      case 10 /* unwind_state_clear_period_ms */:
        field.get(&unwind_state_clear_period_ms_);
        break;
      case 18 /* target_installed_by */:
        target_installed_by_.emplace_back();
        ::protozero::internal::gen_helpers::DeserializeString(field, &target_installed_by_.back());
        break;
      case 1 /* all_cpus */:
        field.get(&all_cpus_);
        break;
      case 2 /* sampling_frequency */:
        field.get(&sampling_frequency_);
        break;
      case 12 /* kernel_frames */:
        field.get(&kernel_frames_);
        break;
      case 4 /* target_pid */:
        target_pid_.emplace_back();
        field.get(&target_pid_.back());
        break;
      case 5 /* target_cmdline */:
        target_cmdline_.emplace_back();
        ::protozero::internal::gen_helpers::DeserializeString(field, &target_cmdline_.back());
        break;
      case 6 /* exclude_pid */:
        exclude_pid_.emplace_back();
        field.get(&exclude_pid_.back());
        break;
      case 7 /* exclude_cmdline */:
        exclude_cmdline_.emplace_back();
        ::protozero::internal::gen_helpers::DeserializeString(field, &exclude_cmdline_.back());
        break;
      case 11 /* additional_cmdline_count */:
        field.get(&additional_cmdline_count_);
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string PerfEventConfig::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> PerfEventConfig::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void PerfEventConfig::Serialize(::protozero::Message* msg) const {
  // Field 15: timebase
  if (_has_field_[15]) {
    (*timebase_).Serialize(msg->BeginNestedMessage<::protozero::Message>(15));
  }

  // Field 16: callstack_sampling
  if (_has_field_[16]) {
    (*callstack_sampling_).Serialize(msg->BeginNestedMessage<::protozero::Message>(16));
  }

  // Field 8: ring_buffer_read_period_ms
  if (_has_field_[8]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(8, ring_buffer_read_period_ms_, msg);
  }

  // Field 3: ring_buffer_pages
  if (_has_field_[3]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(3, ring_buffer_pages_, msg);
  }

  // Field 17: max_enqueued_footprint_kb
  if (_has_field_[17]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(17, max_enqueued_footprint_kb_, msg);
  }

  // Field 13: max_daemon_memory_kb
  if (_has_field_[13]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(13, max_daemon_memory_kb_, msg);
  }

  // Field 9: remote_descriptor_timeout_ms
  if (_has_field_[9]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(9, remote_descriptor_timeout_ms_, msg);
  }

  // Field 10: unwind_state_clear_period_ms
  if (_has_field_[10]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(10, unwind_state_clear_period_ms_, msg);
  }

  // Field 18: target_installed_by
  for (auto& it : target_installed_by_) {
    ::protozero::internal::gen_helpers::SerializeString(18, it, msg);
  }

  // Field 1: all_cpus
  if (_has_field_[1]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(1, all_cpus_, msg);
  }

  // Field 2: sampling_frequency
  if (_has_field_[2]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(2, sampling_frequency_, msg);
  }

  // Field 12: kernel_frames
  if (_has_field_[12]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(12, kernel_frames_, msg);
  }

  // Field 4: target_pid
  for (auto& it : target_pid_) {
    ::protozero::internal::gen_helpers::SerializeVarInt(4, it, msg);
  }

  // Field 5: target_cmdline
  for (auto& it : target_cmdline_) {
    ::protozero::internal::gen_helpers::SerializeString(5, it, msg);
  }

  // Field 6: exclude_pid
  for (auto& it : exclude_pid_) {
    ::protozero::internal::gen_helpers::SerializeVarInt(6, it, msg);
  }

  // Field 7: exclude_cmdline
  for (auto& it : exclude_cmdline_) {
    ::protozero::internal::gen_helpers::SerializeString(7, it, msg);
  }

  // Field 11: additional_cmdline_count
  if (_has_field_[11]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(11, additional_cmdline_count_, msg);
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}


PerfEventConfig_CallstackSampling::PerfEventConfig_CallstackSampling() = default;
PerfEventConfig_CallstackSampling::~PerfEventConfig_CallstackSampling() = default;
PerfEventConfig_CallstackSampling::PerfEventConfig_CallstackSampling(const PerfEventConfig_CallstackSampling&) = default;
PerfEventConfig_CallstackSampling& PerfEventConfig_CallstackSampling::operator=(const PerfEventConfig_CallstackSampling&) = default;
PerfEventConfig_CallstackSampling::PerfEventConfig_CallstackSampling(PerfEventConfig_CallstackSampling&&) noexcept = default;
PerfEventConfig_CallstackSampling& PerfEventConfig_CallstackSampling::operator=(PerfEventConfig_CallstackSampling&&) = default;

bool PerfEventConfig_CallstackSampling::operator==(const PerfEventConfig_CallstackSampling& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(scope_, other.scope_)
   && ::protozero::internal::gen_helpers::EqualsField(kernel_frames_, other.kernel_frames_)
   && ::protozero::internal::gen_helpers::EqualsField(user_frames_, other.user_frames_);
}

bool PerfEventConfig_CallstackSampling::ParseFromArray(const void* raw, size_t size) {
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* scope */:
        (*scope_).ParseFromArray(field.data(), field.size());
        break;
      case 2 /* kernel_frames */:
        field.get(&kernel_frames_);
        break;
      case 3 /* user_frames */:
        field.get(&user_frames_);
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string PerfEventConfig_CallstackSampling::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> PerfEventConfig_CallstackSampling::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void PerfEventConfig_CallstackSampling::Serialize(::protozero::Message* msg) const {
  // Field 1: scope
  if (_has_field_[1]) {
    (*scope_).Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
  }

  // Field 2: kernel_frames
  if (_has_field_[2]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(2, kernel_frames_, msg);
  }

  // Field 3: user_frames
  if (_has_field_[3]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(3, user_frames_, msg);
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}


PerfEventConfig_Scope::PerfEventConfig_Scope() = default;
PerfEventConfig_Scope::~PerfEventConfig_Scope() = default;
PerfEventConfig_Scope::PerfEventConfig_Scope(const PerfEventConfig_Scope&) = default;
PerfEventConfig_Scope& PerfEventConfig_Scope::operator=(const PerfEventConfig_Scope&) = default;
PerfEventConfig_Scope::PerfEventConfig_Scope(PerfEventConfig_Scope&&) noexcept = default;
PerfEventConfig_Scope& PerfEventConfig_Scope::operator=(PerfEventConfig_Scope&&) = default;

bool PerfEventConfig_Scope::operator==(const PerfEventConfig_Scope& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(target_pid_, other.target_pid_)
   && ::protozero::internal::gen_helpers::EqualsField(target_cmdline_, other.target_cmdline_)
   && ::protozero::internal::gen_helpers::EqualsField(exclude_pid_, other.exclude_pid_)
   && ::protozero::internal::gen_helpers::EqualsField(exclude_cmdline_, other.exclude_cmdline_)
   && ::protozero::internal::gen_helpers::EqualsField(additional_cmdline_count_, other.additional_cmdline_count_)
   && ::protozero::internal::gen_helpers::EqualsField(process_shard_count_, other.process_shard_count_);
}

bool PerfEventConfig_Scope::ParseFromArray(const void* raw, size_t size) {
  target_pid_.clear();
  target_cmdline_.clear();
  exclude_pid_.clear();
  exclude_cmdline_.clear();
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* target_pid */:
        target_pid_.emplace_back();
        field.get(&target_pid_.back());
        break;
      case 2 /* target_cmdline */:
        target_cmdline_.emplace_back();
        ::protozero::internal::gen_helpers::DeserializeString(field, &target_cmdline_.back());
        break;
      case 3 /* exclude_pid */:
        exclude_pid_.emplace_back();
        field.get(&exclude_pid_.back());
        break;
      case 4 /* exclude_cmdline */:
        exclude_cmdline_.emplace_back();
        ::protozero::internal::gen_helpers::DeserializeString(field, &exclude_cmdline_.back());
        break;
      case 5 /* additional_cmdline_count */:
        field.get(&additional_cmdline_count_);
        break;
      case 6 /* process_shard_count */:
        field.get(&process_shard_count_);
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string PerfEventConfig_Scope::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> PerfEventConfig_Scope::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void PerfEventConfig_Scope::Serialize(::protozero::Message* msg) const {
  // Field 1: target_pid
  for (auto& it : target_pid_) {
    ::protozero::internal::gen_helpers::SerializeVarInt(1, it, msg);
  }

  // Field 2: target_cmdline
  for (auto& it : target_cmdline_) {
    ::protozero::internal::gen_helpers::SerializeString(2, it, msg);
  }

  // Field 3: exclude_pid
  for (auto& it : exclude_pid_) {
    ::protozero::internal::gen_helpers::SerializeVarInt(3, it, msg);
  }

  // Field 4: exclude_cmdline
  for (auto& it : exclude_cmdline_) {
    ::protozero::internal::gen_helpers::SerializeString(4, it, msg);
  }

  // Field 5: additional_cmdline_count
  if (_has_field_[5]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(5, additional_cmdline_count_, msg);
  }

  // Field 6: process_shard_count
  if (_has_field_[6]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(6, process_shard_count_, msg);
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}

}  // namespace perfetto
}  // namespace protos
}  // namespace gen
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic pop
#endif
// gen_amalgamated begin source: gen/protos/perfetto/config/statsd/atom_ids.gen.cc
// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wfloat-equal"
#endif
// gen_amalgamated expanded: #include "protos/perfetto/config/statsd/atom_ids.gen.h"

namespace perfetto {
namespace protos {
namespace gen {
}  // namespace perfetto
}  // namespace protos
}  // namespace gen
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic pop
#endif
// gen_amalgamated begin source: gen/protos/perfetto/config/statsd/statsd_tracing_config.gen.cc
// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wfloat-equal"
#endif
// gen_amalgamated expanded: #include "protos/perfetto/config/statsd/statsd_tracing_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/statsd/atom_ids.gen.h"

namespace perfetto {
namespace protos {
namespace gen {

StatsdPullAtomConfig::StatsdPullAtomConfig() = default;
StatsdPullAtomConfig::~StatsdPullAtomConfig() = default;
StatsdPullAtomConfig::StatsdPullAtomConfig(const StatsdPullAtomConfig&) = default;
StatsdPullAtomConfig& StatsdPullAtomConfig::operator=(const StatsdPullAtomConfig&) = default;
StatsdPullAtomConfig::StatsdPullAtomConfig(StatsdPullAtomConfig&&) noexcept = default;
StatsdPullAtomConfig& StatsdPullAtomConfig::operator=(StatsdPullAtomConfig&&) = default;

bool StatsdPullAtomConfig::operator==(const StatsdPullAtomConfig& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(pull_atom_id_, other.pull_atom_id_)
   && ::protozero::internal::gen_helpers::EqualsField(raw_pull_atom_id_, other.raw_pull_atom_id_)
   && ::protozero::internal::gen_helpers::EqualsField(pull_frequency_ms_, other.pull_frequency_ms_)
   && ::protozero::internal::gen_helpers::EqualsField(packages_, other.packages_);
}

bool StatsdPullAtomConfig::ParseFromArray(const void* raw, size_t size) {
  pull_atom_id_.clear();
  raw_pull_atom_id_.clear();
  packages_.clear();
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* pull_atom_id */:
        pull_atom_id_.emplace_back();
        field.get(&pull_atom_id_.back());
        break;
      case 2 /* raw_pull_atom_id */:
        raw_pull_atom_id_.emplace_back();
        field.get(&raw_pull_atom_id_.back());
        break;
      case 3 /* pull_frequency_ms */:
        field.get(&pull_frequency_ms_);
        break;
      case 4 /* packages */:
        packages_.emplace_back();
        ::protozero::internal::gen_helpers::DeserializeString(field, &packages_.back());
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string StatsdPullAtomConfig::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> StatsdPullAtomConfig::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void StatsdPullAtomConfig::Serialize(::protozero::Message* msg) const {
  // Field 1: pull_atom_id
  for (auto& it : pull_atom_id_) {
    ::protozero::internal::gen_helpers::SerializeVarInt(1, it, msg);
  }

  // Field 2: raw_pull_atom_id
  for (auto& it : raw_pull_atom_id_) {
    ::protozero::internal::gen_helpers::SerializeVarInt(2, it, msg);
  }

  // Field 3: pull_frequency_ms
  if (_has_field_[3]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(3, pull_frequency_ms_, msg);
  }

  // Field 4: packages
  for (auto& it : packages_) {
    ::protozero::internal::gen_helpers::SerializeString(4, it, msg);
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}


StatsdTracingConfig::StatsdTracingConfig() = default;
StatsdTracingConfig::~StatsdTracingConfig() = default;
StatsdTracingConfig::StatsdTracingConfig(const StatsdTracingConfig&) = default;
StatsdTracingConfig& StatsdTracingConfig::operator=(const StatsdTracingConfig&) = default;
StatsdTracingConfig::StatsdTracingConfig(StatsdTracingConfig&&) noexcept = default;
StatsdTracingConfig& StatsdTracingConfig::operator=(StatsdTracingConfig&&) = default;

bool StatsdTracingConfig::operator==(const StatsdTracingConfig& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(push_atom_id_, other.push_atom_id_)
   && ::protozero::internal::gen_helpers::EqualsField(raw_push_atom_id_, other.raw_push_atom_id_)
   && ::protozero::internal::gen_helpers::EqualsField(pull_config_, other.pull_config_);
}

int StatsdTracingConfig::pull_config_size() const { return static_cast<int>(pull_config_.size()); }
void StatsdTracingConfig::clear_pull_config() { pull_config_.clear(); }
StatsdPullAtomConfig* StatsdTracingConfig::add_pull_config() { pull_config_.emplace_back(); return &pull_config_.back(); }
bool StatsdTracingConfig::ParseFromArray(const void* raw, size_t size) {
  push_atom_id_.clear();
  raw_push_atom_id_.clear();
  pull_config_.clear();
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* push_atom_id */:
        push_atom_id_.emplace_back();
        field.get(&push_atom_id_.back());
        break;
      case 2 /* raw_push_atom_id */:
        raw_push_atom_id_.emplace_back();
        field.get(&raw_push_atom_id_.back());
        break;
      case 3 /* pull_config */:
        pull_config_.emplace_back();
        pull_config_.back().ParseFromArray(field.data(), field.size());
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string StatsdTracingConfig::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> StatsdTracingConfig::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void StatsdTracingConfig::Serialize(::protozero::Message* msg) const {
  // Field 1: push_atom_id
  for (auto& it : push_atom_id_) {
    ::protozero::internal::gen_helpers::SerializeVarInt(1, it, msg);
  }

  // Field 2: raw_push_atom_id
  for (auto& it : raw_push_atom_id_) {
    ::protozero::internal::gen_helpers::SerializeVarInt(2, it, msg);
  }

  // Field 3: pull_config
  for (auto& it : pull_config_) {
    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(3));
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}

}  // namespace perfetto
}  // namespace protos
}  // namespace gen
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic pop
#endif
// gen_amalgamated begin source: gen/protos/perfetto/config/sys_stats/sys_stats_config.gen.cc
// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wfloat-equal"
#endif
// gen_amalgamated expanded: #include "protos/perfetto/config/sys_stats/sys_stats_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/common/sys_stats_counters.gen.h"

namespace perfetto {
namespace protos {
namespace gen {

SysStatsConfig::SysStatsConfig() = default;
SysStatsConfig::~SysStatsConfig() = default;
SysStatsConfig::SysStatsConfig(const SysStatsConfig&) = default;
SysStatsConfig& SysStatsConfig::operator=(const SysStatsConfig&) = default;
SysStatsConfig::SysStatsConfig(SysStatsConfig&&) noexcept = default;
SysStatsConfig& SysStatsConfig::operator=(SysStatsConfig&&) = default;

bool SysStatsConfig::operator==(const SysStatsConfig& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(meminfo_period_ms_, other.meminfo_period_ms_)
   && ::protozero::internal::gen_helpers::EqualsField(meminfo_counters_, other.meminfo_counters_)
   && ::protozero::internal::gen_helpers::EqualsField(vmstat_period_ms_, other.vmstat_period_ms_)
   && ::protozero::internal::gen_helpers::EqualsField(vmstat_counters_, other.vmstat_counters_)
   && ::protozero::internal::gen_helpers::EqualsField(stat_period_ms_, other.stat_period_ms_)
   && ::protozero::internal::gen_helpers::EqualsField(stat_counters_, other.stat_counters_)
   && ::protozero::internal::gen_helpers::EqualsField(devfreq_period_ms_, other.devfreq_period_ms_)
   && ::protozero::internal::gen_helpers::EqualsField(cpufreq_period_ms_, other.cpufreq_period_ms_)
   && ::protozero::internal::gen_helpers::EqualsField(buddyinfo_period_ms_, other.buddyinfo_period_ms_)
   && ::protozero::internal::gen_helpers::EqualsField(diskstat_period_ms_, other.diskstat_period_ms_)
   && ::protozero::internal::gen_helpers::EqualsField(psi_period_ms_, other.psi_period_ms_);
}

bool SysStatsConfig::ParseFromArray(const void* raw, size_t size) {
  meminfo_counters_.clear();
  vmstat_counters_.clear();
  stat_counters_.clear();
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* meminfo_period_ms */:
        field.get(&meminfo_period_ms_);
        break;
      case 2 /* meminfo_counters */:
        meminfo_counters_.emplace_back();
        field.get(&meminfo_counters_.back());
        break;
      case 3 /* vmstat_period_ms */:
        field.get(&vmstat_period_ms_);
        break;
      case 4 /* vmstat_counters */:
        vmstat_counters_.emplace_back();
        field.get(&vmstat_counters_.back());
        break;
      case 5 /* stat_period_ms */:
        field.get(&stat_period_ms_);
        break;
      case 6 /* stat_counters */:
        stat_counters_.emplace_back();
        field.get(&stat_counters_.back());
        break;
      case 7 /* devfreq_period_ms */:
        field.get(&devfreq_period_ms_);
        break;
      case 8 /* cpufreq_period_ms */:
        field.get(&cpufreq_period_ms_);
        break;
      case 9 /* buddyinfo_period_ms */:
        field.get(&buddyinfo_period_ms_);
        break;
      case 10 /* diskstat_period_ms */:
        field.get(&diskstat_period_ms_);
        break;
      case 11 /* psi_period_ms */:
        field.get(&psi_period_ms_);
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string SysStatsConfig::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> SysStatsConfig::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void SysStatsConfig::Serialize(::protozero::Message* msg) const {
  // Field 1: meminfo_period_ms
  if (_has_field_[1]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(1, meminfo_period_ms_, msg);
  }

  // Field 2: meminfo_counters
  for (auto& it : meminfo_counters_) {
    ::protozero::internal::gen_helpers::SerializeVarInt(2, it, msg);
  }

  // Field 3: vmstat_period_ms
  if (_has_field_[3]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(3, vmstat_period_ms_, msg);
  }

  // Field 4: vmstat_counters
  for (auto& it : vmstat_counters_) {
    ::protozero::internal::gen_helpers::SerializeVarInt(4, it, msg);
  }

  // Field 5: stat_period_ms
  if (_has_field_[5]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(5, stat_period_ms_, msg);
  }

  // Field 6: stat_counters
  for (auto& it : stat_counters_) {
    ::protozero::internal::gen_helpers::SerializeVarInt(6, it, msg);
  }

  // Field 7: devfreq_period_ms
  if (_has_field_[7]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(7, devfreq_period_ms_, msg);
  }

  // Field 8: cpufreq_period_ms
  if (_has_field_[8]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(8, cpufreq_period_ms_, msg);
  }

  // Field 9: buddyinfo_period_ms
  if (_has_field_[9]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(9, buddyinfo_period_ms_, msg);
  }

  // Field 10: diskstat_period_ms
  if (_has_field_[10]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(10, diskstat_period_ms_, msg);
  }

  // Field 11: psi_period_ms
  if (_has_field_[11]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(11, psi_period_ms_, msg);
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}

}  // namespace perfetto
}  // namespace protos
}  // namespace gen
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic pop
#endif
// gen_amalgamated begin source: gen/protos/perfetto/config/system_info/system_info.gen.cc
// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wfloat-equal"
#endif
// gen_amalgamated expanded: #include "protos/perfetto/config/system_info/system_info.gen.h"

namespace perfetto {
namespace protos {
namespace gen {

SystemInfoConfig::SystemInfoConfig() = default;
SystemInfoConfig::~SystemInfoConfig() = default;
SystemInfoConfig::SystemInfoConfig(const SystemInfoConfig&) = default;
SystemInfoConfig& SystemInfoConfig::operator=(const SystemInfoConfig&) = default;
SystemInfoConfig::SystemInfoConfig(SystemInfoConfig&&) noexcept = default;
SystemInfoConfig& SystemInfoConfig::operator=(SystemInfoConfig&&) = default;

bool SystemInfoConfig::operator==(const SystemInfoConfig& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_);
}

bool SystemInfoConfig::ParseFromArray(const void* raw, size_t size) {
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string SystemInfoConfig::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> SystemInfoConfig::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void SystemInfoConfig::Serialize(::protozero::Message* msg) const {
  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}

}  // namespace perfetto
}  // namespace protos
}  // namespace gen
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic pop
#endif
// gen_amalgamated begin source: gen/protos/perfetto/config/track_event/track_event_config.gen.cc
// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wfloat-equal"
#endif
// gen_amalgamated expanded: #include "protos/perfetto/config/track_event/track_event_config.gen.h"

namespace perfetto {
namespace protos {
namespace gen {

TrackEventConfig::TrackEventConfig() = default;
TrackEventConfig::~TrackEventConfig() = default;
TrackEventConfig::TrackEventConfig(const TrackEventConfig&) = default;
TrackEventConfig& TrackEventConfig::operator=(const TrackEventConfig&) = default;
TrackEventConfig::TrackEventConfig(TrackEventConfig&&) noexcept = default;
TrackEventConfig& TrackEventConfig::operator=(TrackEventConfig&&) = default;

bool TrackEventConfig::operator==(const TrackEventConfig& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(disabled_categories_, other.disabled_categories_)
   && ::protozero::internal::gen_helpers::EqualsField(enabled_categories_, other.enabled_categories_)
   && ::protozero::internal::gen_helpers::EqualsField(disabled_tags_, other.disabled_tags_)
   && ::protozero::internal::gen_helpers::EqualsField(enabled_tags_, other.enabled_tags_)
   && ::protozero::internal::gen_helpers::EqualsField(disable_incremental_timestamps_, other.disable_incremental_timestamps_)
   && ::protozero::internal::gen_helpers::EqualsField(timestamp_unit_multiplier_, other.timestamp_unit_multiplier_)
   && ::protozero::internal::gen_helpers::EqualsField(filter_debug_annotations_, other.filter_debug_annotations_)
   && ::protozero::internal::gen_helpers::EqualsField(enable_thread_time_sampling_, other.enable_thread_time_sampling_)
   && ::protozero::internal::gen_helpers::EqualsField(filter_dynamic_event_names_, other.filter_dynamic_event_names_);
}

bool TrackEventConfig::ParseFromArray(const void* raw, size_t size) {
  disabled_categories_.clear();
  enabled_categories_.clear();
  disabled_tags_.clear();
  enabled_tags_.clear();
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* disabled_categories */:
        disabled_categories_.emplace_back();
        ::protozero::internal::gen_helpers::DeserializeString(field, &disabled_categories_.back());
        break;
      case 2 /* enabled_categories */:
        enabled_categories_.emplace_back();
        ::protozero::internal::gen_helpers::DeserializeString(field, &enabled_categories_.back());
        break;
      case 3 /* disabled_tags */:
        disabled_tags_.emplace_back();
        ::protozero::internal::gen_helpers::DeserializeString(field, &disabled_tags_.back());
        break;
      case 4 /* enabled_tags */:
        enabled_tags_.emplace_back();
        ::protozero::internal::gen_helpers::DeserializeString(field, &enabled_tags_.back());
        break;
      case 5 /* disable_incremental_timestamps */:
        field.get(&disable_incremental_timestamps_);
        break;
      case 6 /* timestamp_unit_multiplier */:
        field.get(&timestamp_unit_multiplier_);
        break;
      case 7 /* filter_debug_annotations */:
        field.get(&filter_debug_annotations_);
        break;
      case 8 /* enable_thread_time_sampling */:
        field.get(&enable_thread_time_sampling_);
        break;
      case 9 /* filter_dynamic_event_names */:
        field.get(&filter_dynamic_event_names_);
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string TrackEventConfig::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> TrackEventConfig::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void TrackEventConfig::Serialize(::protozero::Message* msg) const {
  // Field 1: disabled_categories
  for (auto& it : disabled_categories_) {
    ::protozero::internal::gen_helpers::SerializeString(1, it, msg);
  }

  // Field 2: enabled_categories
  for (auto& it : enabled_categories_) {
    ::protozero::internal::gen_helpers::SerializeString(2, it, msg);
  }

  // Field 3: disabled_tags
  for (auto& it : disabled_tags_) {
    ::protozero::internal::gen_helpers::SerializeString(3, it, msg);
  }

  // Field 4: enabled_tags
  for (auto& it : enabled_tags_) {
    ::protozero::internal::gen_helpers::SerializeString(4, it, msg);
  }

  // Field 5: disable_incremental_timestamps
  if (_has_field_[5]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(5, disable_incremental_timestamps_, msg);
  }

  // Field 6: timestamp_unit_multiplier
  if (_has_field_[6]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(6, timestamp_unit_multiplier_, msg);
  }

  // Field 7: filter_debug_annotations
  if (_has_field_[7]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(7, filter_debug_annotations_, msg);
  }

  // Field 8: enable_thread_time_sampling
  if (_has_field_[8]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(8, enable_thread_time_sampling_, msg);
  }

  // Field 9: filter_dynamic_event_names
  if (_has_field_[9]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(9, filter_dynamic_event_names_, msg);
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}

}  // namespace perfetto
}  // namespace protos
}  // namespace gen
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic pop
#endif
// gen_amalgamated begin source: gen/protos/perfetto/config/chrome/chrome_config.gen.cc
// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wfloat-equal"
#endif
// gen_amalgamated expanded: #include "protos/perfetto/config/chrome/chrome_config.gen.h"

namespace perfetto {
namespace protos {
namespace gen {

ChromeConfig::ChromeConfig() = default;
ChromeConfig::~ChromeConfig() = default;
ChromeConfig::ChromeConfig(const ChromeConfig&) = default;
ChromeConfig& ChromeConfig::operator=(const ChromeConfig&) = default;
ChromeConfig::ChromeConfig(ChromeConfig&&) noexcept = default;
ChromeConfig& ChromeConfig::operator=(ChromeConfig&&) = default;

bool ChromeConfig::operator==(const ChromeConfig& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(trace_config_, other.trace_config_)
   && ::protozero::internal::gen_helpers::EqualsField(privacy_filtering_enabled_, other.privacy_filtering_enabled_)
   && ::protozero::internal::gen_helpers::EqualsField(convert_to_legacy_json_, other.convert_to_legacy_json_)
   && ::protozero::internal::gen_helpers::EqualsField(client_priority_, other.client_priority_)
   && ::protozero::internal::gen_helpers::EqualsField(json_agent_label_filter_, other.json_agent_label_filter_);
}

bool ChromeConfig::ParseFromArray(const void* raw, size_t size) {
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* trace_config */:
        ::protozero::internal::gen_helpers::DeserializeString(field, &trace_config_);
        break;
      case 2 /* privacy_filtering_enabled */:
        field.get(&privacy_filtering_enabled_);
        break;
      case 3 /* convert_to_legacy_json */:
        field.get(&convert_to_legacy_json_);
        break;
      case 4 /* client_priority */:
        field.get(&client_priority_);
        break;
      case 5 /* json_agent_label_filter */:
        ::protozero::internal::gen_helpers::DeserializeString(field, &json_agent_label_filter_);
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string ChromeConfig::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> ChromeConfig::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void ChromeConfig::Serialize(::protozero::Message* msg) const {
  // Field 1: trace_config
  if (_has_field_[1]) {
    ::protozero::internal::gen_helpers::SerializeString(1, trace_config_, msg);
  }

  // Field 2: privacy_filtering_enabled
  if (_has_field_[2]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(2, privacy_filtering_enabled_, msg);
  }

  // Field 3: convert_to_legacy_json
  if (_has_field_[3]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(3, convert_to_legacy_json_, msg);
  }

  // Field 4: client_priority
  if (_has_field_[4]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(4, client_priority_, msg);
  }

  // Field 5: json_agent_label_filter
  if (_has_field_[5]) {
    ::protozero::internal::gen_helpers::SerializeString(5, json_agent_label_filter_, msg);
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}

}  // namespace perfetto
}  // namespace protos
}  // namespace gen
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic pop
#endif
// gen_amalgamated begin source: gen/protos/perfetto/config/chrome/scenario_config.gen.cc
// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wfloat-equal"
#endif
// gen_amalgamated expanded: #include "protos/perfetto/config/chrome/scenario_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/trace_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/data_source_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/system_info/system_info.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/track_event/track_event_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/test_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/sys_stats/sys_stats_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/common/sys_stats_counters.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/profiling/perf_event_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/common/perf_events.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/profiling/java_hprof_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/profiling/heapprofd_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/process_stats/process_stats_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/statsd/statsd_tracing_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/statsd/atom_ids.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/power/android_power_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/interceptor_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/interceptors/console_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/inode_file/inode_file_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/gpu/vulkan_memory_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/gpu/gpu_counter_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/ftrace/ftrace_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/etw/etw_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/chrome/v8_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/chrome/chrome_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/android/surfaceflinger_transactions_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/android/surfaceflinger_layers_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/android/protolog_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/common/protolog_common.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/android/pixel_modem_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/android/packages_list_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/android/network_trace_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/android/android_sdk_sysprop_guard_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/android/android_system_property_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/android/android_polled_state_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/android/android_log_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/common/android_log_constants.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/android/android_input_event_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/android/android_game_intervention_list_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/common/builtin_clock.gen.h"

namespace perfetto {
namespace protos {
namespace gen {

TracingTriggerRulesConfig::TracingTriggerRulesConfig() = default;
TracingTriggerRulesConfig::~TracingTriggerRulesConfig() = default;
TracingTriggerRulesConfig::TracingTriggerRulesConfig(const TracingTriggerRulesConfig&) = default;
TracingTriggerRulesConfig& TracingTriggerRulesConfig::operator=(const TracingTriggerRulesConfig&) = default;
TracingTriggerRulesConfig::TracingTriggerRulesConfig(TracingTriggerRulesConfig&&) noexcept = default;
TracingTriggerRulesConfig& TracingTriggerRulesConfig::operator=(TracingTriggerRulesConfig&&) = default;

bool TracingTriggerRulesConfig::operator==(const TracingTriggerRulesConfig& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(rules_, other.rules_);
}

int TracingTriggerRulesConfig::rules_size() const { return static_cast<int>(rules_.size()); }
void TracingTriggerRulesConfig::clear_rules() { rules_.clear(); }
TriggerRule* TracingTriggerRulesConfig::add_rules() { rules_.emplace_back(); return &rules_.back(); }
bool TracingTriggerRulesConfig::ParseFromArray(const void* raw, size_t size) {
  rules_.clear();
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* rules */:
        rules_.emplace_back();
        rules_.back().ParseFromArray(field.data(), field.size());
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string TracingTriggerRulesConfig::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> TracingTriggerRulesConfig::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void TracingTriggerRulesConfig::Serialize(::protozero::Message* msg) const {
  // Field 1: rules
  for (auto& it : rules_) {
    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}


TriggerRule::TriggerRule() = default;
TriggerRule::~TriggerRule() = default;
TriggerRule::TriggerRule(const TriggerRule&) = default;
TriggerRule& TriggerRule::operator=(const TriggerRule&) = default;
TriggerRule::TriggerRule(TriggerRule&&) noexcept = default;
TriggerRule& TriggerRule::operator=(TriggerRule&&) = default;

bool TriggerRule::operator==(const TriggerRule& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(name_, other.name_)
   && ::protozero::internal::gen_helpers::EqualsField(trigger_chance_, other.trigger_chance_)
   && ::protozero::internal::gen_helpers::EqualsField(delay_ms_, other.delay_ms_)
   && ::protozero::internal::gen_helpers::EqualsField(activation_delay_ms_, other.activation_delay_ms_)
   && ::protozero::internal::gen_helpers::EqualsField(manual_trigger_name_, other.manual_trigger_name_)
   && ::protozero::internal::gen_helpers::EqualsField(histogram_, other.histogram_)
   && ::protozero::internal::gen_helpers::EqualsField(repeating_interval_, other.repeating_interval_);
}

bool TriggerRule::ParseFromArray(const void* raw, size_t size) {
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* name */:
        ::protozero::internal::gen_helpers::DeserializeString(field, &name_);
        break;
      case 2 /* trigger_chance */:
        field.get(&trigger_chance_);
        break;
      case 3 /* delay_ms */:
        field.get(&delay_ms_);
        break;
      case 8 /* activation_delay_ms */:
        field.get(&activation_delay_ms_);
        break;
      case 4 /* manual_trigger_name */:
        ::protozero::internal::gen_helpers::DeserializeString(field, &manual_trigger_name_);
        break;
      case 5 /* histogram */:
        (*histogram_).ParseFromArray(field.data(), field.size());
        break;
      case 6 /* repeating_interval */:
        (*repeating_interval_).ParseFromArray(field.data(), field.size());
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string TriggerRule::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> TriggerRule::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void TriggerRule::Serialize(::protozero::Message* msg) const {
  // Field 1: name
  if (_has_field_[1]) {
    ::protozero::internal::gen_helpers::SerializeString(1, name_, msg);
  }

  // Field 2: trigger_chance
  if (_has_field_[2]) {
    ::protozero::internal::gen_helpers::SerializeFixed(2, trigger_chance_, msg);
  }

  // Field 3: delay_ms
  if (_has_field_[3]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(3, delay_ms_, msg);
  }

  // Field 8: activation_delay_ms
  if (_has_field_[8]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(8, activation_delay_ms_, msg);
  }

  // Field 4: manual_trigger_name
  if (_has_field_[4]) {
    ::protozero::internal::gen_helpers::SerializeString(4, manual_trigger_name_, msg);
  }

  // Field 5: histogram
  if (_has_field_[5]) {
    (*histogram_).Serialize(msg->BeginNestedMessage<::protozero::Message>(5));
  }

  // Field 6: repeating_interval
  if (_has_field_[6]) {
    (*repeating_interval_).Serialize(msg->BeginNestedMessage<::protozero::Message>(6));
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}


TriggerRule_RepeatingInterval::TriggerRule_RepeatingInterval() = default;
TriggerRule_RepeatingInterval::~TriggerRule_RepeatingInterval() = default;
TriggerRule_RepeatingInterval::TriggerRule_RepeatingInterval(const TriggerRule_RepeatingInterval&) = default;
TriggerRule_RepeatingInterval& TriggerRule_RepeatingInterval::operator=(const TriggerRule_RepeatingInterval&) = default;
TriggerRule_RepeatingInterval::TriggerRule_RepeatingInterval(TriggerRule_RepeatingInterval&&) noexcept = default;
TriggerRule_RepeatingInterval& TriggerRule_RepeatingInterval::operator=(TriggerRule_RepeatingInterval&&) = default;

bool TriggerRule_RepeatingInterval::operator==(const TriggerRule_RepeatingInterval& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(period_ms_, other.period_ms_)
   && ::protozero::internal::gen_helpers::EqualsField(randomized_, other.randomized_);
}

bool TriggerRule_RepeatingInterval::ParseFromArray(const void* raw, size_t size) {
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* period_ms */:
        field.get(&period_ms_);
        break;
      case 2 /* randomized */:
        field.get(&randomized_);
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string TriggerRule_RepeatingInterval::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> TriggerRule_RepeatingInterval::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void TriggerRule_RepeatingInterval::Serialize(::protozero::Message* msg) const {
  // Field 1: period_ms
  if (_has_field_[1]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(1, period_ms_, msg);
  }

  // Field 2: randomized
  if (_has_field_[2]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(2, randomized_, msg);
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}


TriggerRule_HistogramTrigger::TriggerRule_HistogramTrigger() = default;
TriggerRule_HistogramTrigger::~TriggerRule_HistogramTrigger() = default;
TriggerRule_HistogramTrigger::TriggerRule_HistogramTrigger(const TriggerRule_HistogramTrigger&) = default;
TriggerRule_HistogramTrigger& TriggerRule_HistogramTrigger::operator=(const TriggerRule_HistogramTrigger&) = default;
TriggerRule_HistogramTrigger::TriggerRule_HistogramTrigger(TriggerRule_HistogramTrigger&&) noexcept = default;
TriggerRule_HistogramTrigger& TriggerRule_HistogramTrigger::operator=(TriggerRule_HistogramTrigger&&) = default;

bool TriggerRule_HistogramTrigger::operator==(const TriggerRule_HistogramTrigger& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(histogram_name_, other.histogram_name_)
   && ::protozero::internal::gen_helpers::EqualsField(min_value_, other.min_value_)
   && ::protozero::internal::gen_helpers::EqualsField(max_value_, other.max_value_);
}

bool TriggerRule_HistogramTrigger::ParseFromArray(const void* raw, size_t size) {
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* histogram_name */:
        ::protozero::internal::gen_helpers::DeserializeString(field, &histogram_name_);
        break;
      case 2 /* min_value */:
        field.get(&min_value_);
        break;
      case 3 /* max_value */:
        field.get(&max_value_);
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string TriggerRule_HistogramTrigger::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> TriggerRule_HistogramTrigger::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void TriggerRule_HistogramTrigger::Serialize(::protozero::Message* msg) const {
  // Field 1: histogram_name
  if (_has_field_[1]) {
    ::protozero::internal::gen_helpers::SerializeString(1, histogram_name_, msg);
  }

  // Field 2: min_value
  if (_has_field_[2]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(2, min_value_, msg);
  }

  // Field 3: max_value
  if (_has_field_[3]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(3, max_value_, msg);
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}


ChromeFieldTracingConfig::ChromeFieldTracingConfig() = default;
ChromeFieldTracingConfig::~ChromeFieldTracingConfig() = default;
ChromeFieldTracingConfig::ChromeFieldTracingConfig(const ChromeFieldTracingConfig&) = default;
ChromeFieldTracingConfig& ChromeFieldTracingConfig::operator=(const ChromeFieldTracingConfig&) = default;
ChromeFieldTracingConfig::ChromeFieldTracingConfig(ChromeFieldTracingConfig&&) noexcept = default;
ChromeFieldTracingConfig& ChromeFieldTracingConfig::operator=(ChromeFieldTracingConfig&&) = default;

bool ChromeFieldTracingConfig::operator==(const ChromeFieldTracingConfig& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(scenarios_, other.scenarios_);
}

int ChromeFieldTracingConfig::scenarios_size() const { return static_cast<int>(scenarios_.size()); }
void ChromeFieldTracingConfig::clear_scenarios() { scenarios_.clear(); }
ScenarioConfig* ChromeFieldTracingConfig::add_scenarios() { scenarios_.emplace_back(); return &scenarios_.back(); }
bool ChromeFieldTracingConfig::ParseFromArray(const void* raw, size_t size) {
  scenarios_.clear();
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* scenarios */:
        scenarios_.emplace_back();
        scenarios_.back().ParseFromArray(field.data(), field.size());
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string ChromeFieldTracingConfig::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> ChromeFieldTracingConfig::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void ChromeFieldTracingConfig::Serialize(::protozero::Message* msg) const {
  // Field 1: scenarios
  for (auto& it : scenarios_) {
    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}


ScenarioConfig::ScenarioConfig() = default;
ScenarioConfig::~ScenarioConfig() = default;
ScenarioConfig::ScenarioConfig(const ScenarioConfig&) = default;
ScenarioConfig& ScenarioConfig::operator=(const ScenarioConfig&) = default;
ScenarioConfig::ScenarioConfig(ScenarioConfig&&) noexcept = default;
ScenarioConfig& ScenarioConfig::operator=(ScenarioConfig&&) = default;

bool ScenarioConfig::operator==(const ScenarioConfig& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(scenario_name_, other.scenario_name_)
   && ::protozero::internal::gen_helpers::EqualsField(start_rules_, other.start_rules_)
   && ::protozero::internal::gen_helpers::EqualsField(stop_rules_, other.stop_rules_)
   && ::protozero::internal::gen_helpers::EqualsField(upload_rules_, other.upload_rules_)
   && ::protozero::internal::gen_helpers::EqualsField(setup_rules_, other.setup_rules_)
   && ::protozero::internal::gen_helpers::EqualsField(trace_config_, other.trace_config_)
   && ::protozero::internal::gen_helpers::EqualsField(nested_scenarios_, other.nested_scenarios_);
}

int ScenarioConfig::start_rules_size() const { return static_cast<int>(start_rules_.size()); }
void ScenarioConfig::clear_start_rules() { start_rules_.clear(); }
TriggerRule* ScenarioConfig::add_start_rules() { start_rules_.emplace_back(); return &start_rules_.back(); }
int ScenarioConfig::stop_rules_size() const { return static_cast<int>(stop_rules_.size()); }
void ScenarioConfig::clear_stop_rules() { stop_rules_.clear(); }
TriggerRule* ScenarioConfig::add_stop_rules() { stop_rules_.emplace_back(); return &stop_rules_.back(); }
int ScenarioConfig::upload_rules_size() const { return static_cast<int>(upload_rules_.size()); }
void ScenarioConfig::clear_upload_rules() { upload_rules_.clear(); }
TriggerRule* ScenarioConfig::add_upload_rules() { upload_rules_.emplace_back(); return &upload_rules_.back(); }
int ScenarioConfig::setup_rules_size() const { return static_cast<int>(setup_rules_.size()); }
void ScenarioConfig::clear_setup_rules() { setup_rules_.clear(); }
TriggerRule* ScenarioConfig::add_setup_rules() { setup_rules_.emplace_back(); return &setup_rules_.back(); }
int ScenarioConfig::nested_scenarios_size() const { return static_cast<int>(nested_scenarios_.size()); }
void ScenarioConfig::clear_nested_scenarios() { nested_scenarios_.clear(); }
NestedScenarioConfig* ScenarioConfig::add_nested_scenarios() { nested_scenarios_.emplace_back(); return &nested_scenarios_.back(); }
bool ScenarioConfig::ParseFromArray(const void* raw, size_t size) {
  start_rules_.clear();
  stop_rules_.clear();
  upload_rules_.clear();
  setup_rules_.clear();
  nested_scenarios_.clear();
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* scenario_name */:
        ::protozero::internal::gen_helpers::DeserializeString(field, &scenario_name_);
        break;
      case 2 /* start_rules */:
        start_rules_.emplace_back();
        start_rules_.back().ParseFromArray(field.data(), field.size());
        break;
      case 3 /* stop_rules */:
        stop_rules_.emplace_back();
        stop_rules_.back().ParseFromArray(field.data(), field.size());
        break;
      case 4 /* upload_rules */:
        upload_rules_.emplace_back();
        upload_rules_.back().ParseFromArray(field.data(), field.size());
        break;
      case 5 /* setup_rules */:
        setup_rules_.emplace_back();
        setup_rules_.back().ParseFromArray(field.data(), field.size());
        break;
      case 6 /* trace_config */:
        (*trace_config_).ParseFromArray(field.data(), field.size());
        break;
      case 7 /* nested_scenarios */:
        nested_scenarios_.emplace_back();
        nested_scenarios_.back().ParseFromArray(field.data(), field.size());
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string ScenarioConfig::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> ScenarioConfig::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void ScenarioConfig::Serialize(::protozero::Message* msg) const {
  // Field 1: scenario_name
  if (_has_field_[1]) {
    ::protozero::internal::gen_helpers::SerializeString(1, scenario_name_, msg);
  }

  // Field 2: start_rules
  for (auto& it : start_rules_) {
    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(2));
  }

  // Field 3: stop_rules
  for (auto& it : stop_rules_) {
    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(3));
  }

  // Field 4: upload_rules
  for (auto& it : upload_rules_) {
    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(4));
  }

  // Field 5: setup_rules
  for (auto& it : setup_rules_) {
    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(5));
  }

  // Field 6: trace_config
  if (_has_field_[6]) {
    (*trace_config_).Serialize(msg->BeginNestedMessage<::protozero::Message>(6));
  }

  // Field 7: nested_scenarios
  for (auto& it : nested_scenarios_) {
    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(7));
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}


NestedScenarioConfig::NestedScenarioConfig() = default;
NestedScenarioConfig::~NestedScenarioConfig() = default;
NestedScenarioConfig::NestedScenarioConfig(const NestedScenarioConfig&) = default;
NestedScenarioConfig& NestedScenarioConfig::operator=(const NestedScenarioConfig&) = default;
NestedScenarioConfig::NestedScenarioConfig(NestedScenarioConfig&&) noexcept = default;
NestedScenarioConfig& NestedScenarioConfig::operator=(NestedScenarioConfig&&) = default;

bool NestedScenarioConfig::operator==(const NestedScenarioConfig& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(scenario_name_, other.scenario_name_)
   && ::protozero::internal::gen_helpers::EqualsField(start_rules_, other.start_rules_)
   && ::protozero::internal::gen_helpers::EqualsField(stop_rules_, other.stop_rules_)
   && ::protozero::internal::gen_helpers::EqualsField(upload_rules_, other.upload_rules_);
}

int NestedScenarioConfig::start_rules_size() const { return static_cast<int>(start_rules_.size()); }
void NestedScenarioConfig::clear_start_rules() { start_rules_.clear(); }
TriggerRule* NestedScenarioConfig::add_start_rules() { start_rules_.emplace_back(); return &start_rules_.back(); }
int NestedScenarioConfig::stop_rules_size() const { return static_cast<int>(stop_rules_.size()); }
void NestedScenarioConfig::clear_stop_rules() { stop_rules_.clear(); }
TriggerRule* NestedScenarioConfig::add_stop_rules() { stop_rules_.emplace_back(); return &stop_rules_.back(); }
int NestedScenarioConfig::upload_rules_size() const { return static_cast<int>(upload_rules_.size()); }
void NestedScenarioConfig::clear_upload_rules() { upload_rules_.clear(); }
TriggerRule* NestedScenarioConfig::add_upload_rules() { upload_rules_.emplace_back(); return &upload_rules_.back(); }
bool NestedScenarioConfig::ParseFromArray(const void* raw, size_t size) {
  start_rules_.clear();
  stop_rules_.clear();
  upload_rules_.clear();
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* scenario_name */:
        ::protozero::internal::gen_helpers::DeserializeString(field, &scenario_name_);
        break;
      case 2 /* start_rules */:
        start_rules_.emplace_back();
        start_rules_.back().ParseFromArray(field.data(), field.size());
        break;
      case 3 /* stop_rules */:
        stop_rules_.emplace_back();
        stop_rules_.back().ParseFromArray(field.data(), field.size());
        break;
      case 4 /* upload_rules */:
        upload_rules_.emplace_back();
        upload_rules_.back().ParseFromArray(field.data(), field.size());
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string NestedScenarioConfig::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> NestedScenarioConfig::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void NestedScenarioConfig::Serialize(::protozero::Message* msg) const {
  // Field 1: scenario_name
  if (_has_field_[1]) {
    ::protozero::internal::gen_helpers::SerializeString(1, scenario_name_, msg);
  }

  // Field 2: start_rules
  for (auto& it : start_rules_) {
    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(2));
  }

  // Field 3: stop_rules
  for (auto& it : stop_rules_) {
    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(3));
  }

  // Field 4: upload_rules
  for (auto& it : upload_rules_) {
    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(4));
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}

}  // namespace perfetto
}  // namespace protos
}  // namespace gen
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic pop
#endif
// gen_amalgamated begin source: gen/protos/perfetto/config/chrome/v8_config.gen.cc
// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wfloat-equal"
#endif
// gen_amalgamated expanded: #include "protos/perfetto/config/chrome/v8_config.gen.h"

namespace perfetto {
namespace protos {
namespace gen {

V8Config::V8Config() = default;
V8Config::~V8Config() = default;
V8Config::V8Config(const V8Config&) = default;
V8Config& V8Config::operator=(const V8Config&) = default;
V8Config::V8Config(V8Config&&) noexcept = default;
V8Config& V8Config::operator=(V8Config&&) = default;

bool V8Config::operator==(const V8Config& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(log_script_sources_, other.log_script_sources_)
   && ::protozero::internal::gen_helpers::EqualsField(log_instructions_, other.log_instructions_);
}

bool V8Config::ParseFromArray(const void* raw, size_t size) {
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* log_script_sources */:
        field.get(&log_script_sources_);
        break;
      case 2 /* log_instructions */:
        field.get(&log_instructions_);
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string V8Config::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> V8Config::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void V8Config::Serialize(::protozero::Message* msg) const {
  // Field 1: log_script_sources
  if (_has_field_[1]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(1, log_script_sources_, msg);
  }

  // Field 2: log_instructions
  if (_has_field_[2]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(2, log_instructions_, msg);
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}

}  // namespace perfetto
}  // namespace protos
}  // namespace gen
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic pop
#endif
// gen_amalgamated begin source: gen/protos/perfetto/config/data_source_config.gen.cc
// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wfloat-equal"
#endif
// gen_amalgamated expanded: #include "protos/perfetto/config/data_source_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/system_info/system_info.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/test_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/interceptor_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/interceptors/console_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/chrome/chrome_config.gen.h"

namespace perfetto {
namespace protos {
namespace gen {

DataSourceConfig::DataSourceConfig() = default;
DataSourceConfig::~DataSourceConfig() = default;
DataSourceConfig::DataSourceConfig(const DataSourceConfig&) = default;
DataSourceConfig& DataSourceConfig::operator=(const DataSourceConfig&) = default;
DataSourceConfig::DataSourceConfig(DataSourceConfig&&) noexcept = default;
DataSourceConfig& DataSourceConfig::operator=(DataSourceConfig&&) = default;

bool DataSourceConfig::operator==(const DataSourceConfig& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(name_, other.name_)
   && ::protozero::internal::gen_helpers::EqualsField(target_buffer_, other.target_buffer_)
   && ::protozero::internal::gen_helpers::EqualsField(trace_duration_ms_, other.trace_duration_ms_)
   && ::protozero::internal::gen_helpers::EqualsField(prefer_suspend_clock_for_duration_, other.prefer_suspend_clock_for_duration_)
   && ::protozero::internal::gen_helpers::EqualsField(stop_timeout_ms_, other.stop_timeout_ms_)
   && ::protozero::internal::gen_helpers::EqualsField(enable_extra_guardrails_, other.enable_extra_guardrails_)
   && ::protozero::internal::gen_helpers::EqualsField(session_initiator_, other.session_initiator_)
   && ::protozero::internal::gen_helpers::EqualsField(tracing_session_id_, other.tracing_session_id_)
   && ::protozero::internal::gen_helpers::EqualsField(ftrace_config_, other.ftrace_config_)
   && ::protozero::internal::gen_helpers::EqualsField(inode_file_config_, other.inode_file_config_)
   && ::protozero::internal::gen_helpers::EqualsField(process_stats_config_, other.process_stats_config_)
   && ::protozero::internal::gen_helpers::EqualsField(sys_stats_config_, other.sys_stats_config_)
   && ::protozero::internal::gen_helpers::EqualsField(heapprofd_config_, other.heapprofd_config_)
   && ::protozero::internal::gen_helpers::EqualsField(java_hprof_config_, other.java_hprof_config_)
   && ::protozero::internal::gen_helpers::EqualsField(android_power_config_, other.android_power_config_)
   && ::protozero::internal::gen_helpers::EqualsField(android_log_config_, other.android_log_config_)
   && ::protozero::internal::gen_helpers::EqualsField(gpu_counter_config_, other.gpu_counter_config_)
   && ::protozero::internal::gen_helpers::EqualsField(android_game_intervention_list_config_, other.android_game_intervention_list_config_)
   && ::protozero::internal::gen_helpers::EqualsField(packages_list_config_, other.packages_list_config_)
   && ::protozero::internal::gen_helpers::EqualsField(perf_event_config_, other.perf_event_config_)
   && ::protozero::internal::gen_helpers::EqualsField(vulkan_memory_config_, other.vulkan_memory_config_)
   && ::protozero::internal::gen_helpers::EqualsField(track_event_config_, other.track_event_config_)
   && ::protozero::internal::gen_helpers::EqualsField(android_polled_state_config_, other.android_polled_state_config_)
   && ::protozero::internal::gen_helpers::EqualsField(android_system_property_config_, other.android_system_property_config_)
   && ::protozero::internal::gen_helpers::EqualsField(statsd_tracing_config_, other.statsd_tracing_config_)
   && ::protozero::internal::gen_helpers::EqualsField(system_info_config_, other.system_info_config_)
   && ::protozero::internal::gen_helpers::EqualsField(chrome_config_, other.chrome_config_)
   && ::protozero::internal::gen_helpers::EqualsField(v8_config_, other.v8_config_)
   && ::protozero::internal::gen_helpers::EqualsField(interceptor_config_, other.interceptor_config_)
   && ::protozero::internal::gen_helpers::EqualsField(network_packet_trace_config_, other.network_packet_trace_config_)
   && ::protozero::internal::gen_helpers::EqualsField(surfaceflinger_layers_config_, other.surfaceflinger_layers_config_)
   && ::protozero::internal::gen_helpers::EqualsField(surfaceflinger_transactions_config_, other.surfaceflinger_transactions_config_)
   && ::protozero::internal::gen_helpers::EqualsField(android_sdk_sysprop_guard_config_, other.android_sdk_sysprop_guard_config_)
   && ::protozero::internal::gen_helpers::EqualsField(etw_config_, other.etw_config_)
   && ::protozero::internal::gen_helpers::EqualsField(protolog_config_, other.protolog_config_)
   && ::protozero::internal::gen_helpers::EqualsField(android_input_event_config_, other.android_input_event_config_)
   && ::protozero::internal::gen_helpers::EqualsField(pixel_modem_config_, other.pixel_modem_config_)
   && ::protozero::internal::gen_helpers::EqualsField(legacy_config_, other.legacy_config_)
   && ::protozero::internal::gen_helpers::EqualsField(for_testing_, other.for_testing_);
}

bool DataSourceConfig::ParseFromArray(const void* raw, size_t size) {
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* name */:
        ::protozero::internal::gen_helpers::DeserializeString(field, &name_);
        break;
      case 2 /* target_buffer */:
        field.get(&target_buffer_);
        break;
      case 3 /* trace_duration_ms */:
        field.get(&trace_duration_ms_);
        break;
      case 122 /* prefer_suspend_clock_for_duration */:
        field.get(&prefer_suspend_clock_for_duration_);
        break;
      case 7 /* stop_timeout_ms */:
        field.get(&stop_timeout_ms_);
        break;
      case 6 /* enable_extra_guardrails */:
        field.get(&enable_extra_guardrails_);
        break;
      case 8 /* session_initiator */:
        field.get(&session_initiator_);
        break;
      case 4 /* tracing_session_id */:
        field.get(&tracing_session_id_);
        break;
      case 100 /* ftrace_config */:
        ::protozero::internal::gen_helpers::DeserializeString(field, &ftrace_config_);
        break;
      case 102 /* inode_file_config */:
        ::protozero::internal::gen_helpers::DeserializeString(field, &inode_file_config_);
        break;
      case 103 /* process_stats_config */:
        ::protozero::internal::gen_helpers::DeserializeString(field, &process_stats_config_);
        break;
      case 104 /* sys_stats_config */:
        ::protozero::internal::gen_helpers::DeserializeString(field, &sys_stats_config_);
        break;
      case 105 /* heapprofd_config */:
        ::protozero::internal::gen_helpers::DeserializeString(field, &heapprofd_config_);
        break;
      case 110 /* java_hprof_config */:
        ::protozero::internal::gen_helpers::DeserializeString(field, &java_hprof_config_);
        break;
      case 106 /* android_power_config */:
        ::protozero::internal::gen_helpers::DeserializeString(field, &android_power_config_);
        break;
      case 107 /* android_log_config */:
        ::protozero::internal::gen_helpers::DeserializeString(field, &android_log_config_);
        break;
      case 108 /* gpu_counter_config */:
        ::protozero::internal::gen_helpers::DeserializeString(field, &gpu_counter_config_);
        break;
      case 116 /* android_game_intervention_list_config */:
        ::protozero::internal::gen_helpers::DeserializeString(field, &android_game_intervention_list_config_);
        break;
      case 109 /* packages_list_config */:
        ::protozero::internal::gen_helpers::DeserializeString(field, &packages_list_config_);
        break;
      case 111 /* perf_event_config */:
        ::protozero::internal::gen_helpers::DeserializeString(field, &perf_event_config_);
        break;
      case 112 /* vulkan_memory_config */:
        ::protozero::internal::gen_helpers::DeserializeString(field, &vulkan_memory_config_);
        break;
      case 113 /* track_event_config */:
        ::protozero::internal::gen_helpers::DeserializeString(field, &track_event_config_);
        break;
      case 114 /* android_polled_state_config */:
        ::protozero::internal::gen_helpers::DeserializeString(field, &android_polled_state_config_);
        break;
      case 118 /* android_system_property_config */:
        ::protozero::internal::gen_helpers::DeserializeString(field, &android_system_property_config_);
        break;
      case 117 /* statsd_tracing_config */:
        ::protozero::internal::gen_helpers::DeserializeString(field, &statsd_tracing_config_);
        break;
      case 119 /* system_info_config */:
        (*system_info_config_).ParseFromArray(field.data(), field.size());
        break;
      case 101 /* chrome_config */:
        (*chrome_config_).ParseFromArray(field.data(), field.size());
        break;
      case 127 /* v8_config */:
        ::protozero::internal::gen_helpers::DeserializeString(field, &v8_config_);
        break;
      case 115 /* interceptor_config */:
        (*interceptor_config_).ParseFromArray(field.data(), field.size());
        break;
      case 120 /* network_packet_trace_config */:
        ::protozero::internal::gen_helpers::DeserializeString(field, &network_packet_trace_config_);
        break;
      case 121 /* surfaceflinger_layers_config */:
        ::protozero::internal::gen_helpers::DeserializeString(field, &surfaceflinger_layers_config_);
        break;
      case 123 /* surfaceflinger_transactions_config */:
        ::protozero::internal::gen_helpers::DeserializeString(field, &surfaceflinger_transactions_config_);
        break;
      case 124 /* android_sdk_sysprop_guard_config */:
        ::protozero::internal::gen_helpers::DeserializeString(field, &android_sdk_sysprop_guard_config_);
        break;
      case 125 /* etw_config */:
        ::protozero::internal::gen_helpers::DeserializeString(field, &etw_config_);
        break;
      case 126 /* protolog_config */:
        ::protozero::internal::gen_helpers::DeserializeString(field, &protolog_config_);
        break;
      case 128 /* android_input_event_config */:
        ::protozero::internal::gen_helpers::DeserializeString(field, &android_input_event_config_);
        break;
      case 129 /* pixel_modem_config */:
        ::protozero::internal::gen_helpers::DeserializeString(field, &pixel_modem_config_);
        break;
      case 1000 /* legacy_config */:
        ::protozero::internal::gen_helpers::DeserializeString(field, &legacy_config_);
        break;
      case 1001 /* for_testing */:
        (*for_testing_).ParseFromArray(field.data(), field.size());
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string DataSourceConfig::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> DataSourceConfig::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void DataSourceConfig::Serialize(::protozero::Message* msg) const {
  // Field 1: name
  if (_has_field_[1]) {
    ::protozero::internal::gen_helpers::SerializeString(1, name_, msg);
  }

  // Field 2: target_buffer
  if (_has_field_[2]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(2, target_buffer_, msg);
  }

  // Field 3: trace_duration_ms
  if (_has_field_[3]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(3, trace_duration_ms_, msg);
  }

  // Field 122: prefer_suspend_clock_for_duration
  if (_has_field_[122]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(122, prefer_suspend_clock_for_duration_, msg);
  }

  // Field 7: stop_timeout_ms
  if (_has_field_[7]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(7, stop_timeout_ms_, msg);
  }

  // Field 6: enable_extra_guardrails
  if (_has_field_[6]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(6, enable_extra_guardrails_, msg);
  }

  // Field 8: session_initiator
  if (_has_field_[8]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(8, session_initiator_, msg);
  }

  // Field 4: tracing_session_id
  if (_has_field_[4]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(4, tracing_session_id_, msg);
  }

  // Field 100: ftrace_config
  if (_has_field_[100]) {
    msg->AppendString(100, ftrace_config_);
  }

  // Field 102: inode_file_config
  if (_has_field_[102]) {
    msg->AppendString(102, inode_file_config_);
  }

  // Field 103: process_stats_config
  if (_has_field_[103]) {
    msg->AppendString(103, process_stats_config_);
  }

  // Field 104: sys_stats_config
  if (_has_field_[104]) {
    msg->AppendString(104, sys_stats_config_);
  }

  // Field 105: heapprofd_config
  if (_has_field_[105]) {
    msg->AppendString(105, heapprofd_config_);
  }

  // Field 110: java_hprof_config
  if (_has_field_[110]) {
    msg->AppendString(110, java_hprof_config_);
  }

  // Field 106: android_power_config
  if (_has_field_[106]) {
    msg->AppendString(106, android_power_config_);
  }

  // Field 107: android_log_config
  if (_has_field_[107]) {
    msg->AppendString(107, android_log_config_);
  }

  // Field 108: gpu_counter_config
  if (_has_field_[108]) {
    msg->AppendString(108, gpu_counter_config_);
  }

  // Field 116: android_game_intervention_list_config
  if (_has_field_[116]) {
    msg->AppendString(116, android_game_intervention_list_config_);
  }

  // Field 109: packages_list_config
  if (_has_field_[109]) {
    msg->AppendString(109, packages_list_config_);
  }

  // Field 111: perf_event_config
  if (_has_field_[111]) {
    msg->AppendString(111, perf_event_config_);
  }

  // Field 112: vulkan_memory_config
  if (_has_field_[112]) {
    msg->AppendString(112, vulkan_memory_config_);
  }

  // Field 113: track_event_config
  if (_has_field_[113]) {
    msg->AppendString(113, track_event_config_);
  }

  // Field 114: android_polled_state_config
  if (_has_field_[114]) {
    msg->AppendString(114, android_polled_state_config_);
  }

  // Field 118: android_system_property_config
  if (_has_field_[118]) {
    msg->AppendString(118, android_system_property_config_);
  }

  // Field 117: statsd_tracing_config
  if (_has_field_[117]) {
    msg->AppendString(117, statsd_tracing_config_);
  }

  // Field 119: system_info_config
  if (_has_field_[119]) {
    (*system_info_config_).Serialize(msg->BeginNestedMessage<::protozero::Message>(119));
  }

  // Field 101: chrome_config
  if (_has_field_[101]) {
    (*chrome_config_).Serialize(msg->BeginNestedMessage<::protozero::Message>(101));
  }

  // Field 127: v8_config
  if (_has_field_[127]) {
    msg->AppendString(127, v8_config_);
  }

  // Field 115: interceptor_config
  if (_has_field_[115]) {
    (*interceptor_config_).Serialize(msg->BeginNestedMessage<::protozero::Message>(115));
  }

  // Field 120: network_packet_trace_config
  if (_has_field_[120]) {
    msg->AppendString(120, network_packet_trace_config_);
  }

  // Field 121: surfaceflinger_layers_config
  if (_has_field_[121]) {
    msg->AppendString(121, surfaceflinger_layers_config_);
  }

  // Field 123: surfaceflinger_transactions_config
  if (_has_field_[123]) {
    msg->AppendString(123, surfaceflinger_transactions_config_);
  }

  // Field 124: android_sdk_sysprop_guard_config
  if (_has_field_[124]) {
    msg->AppendString(124, android_sdk_sysprop_guard_config_);
  }

  // Field 125: etw_config
  if (_has_field_[125]) {
    msg->AppendString(125, etw_config_);
  }

  // Field 126: protolog_config
  if (_has_field_[126]) {
    msg->AppendString(126, protolog_config_);
  }

  // Field 128: android_input_event_config
  if (_has_field_[128]) {
    msg->AppendString(128, android_input_event_config_);
  }

  // Field 129: pixel_modem_config
  if (_has_field_[129]) {
    msg->AppendString(129, pixel_modem_config_);
  }

  // Field 1000: legacy_config
  if (_has_field_[1000]) {
    ::protozero::internal::gen_helpers::SerializeString(1000, legacy_config_, msg);
  }

  // Field 1001: for_testing
  if (_has_field_[1001]) {
    (*for_testing_).Serialize(msg->BeginNestedMessage<::protozero::Message>(1001));
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}

}  // namespace perfetto
}  // namespace protos
}  // namespace gen
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic pop
#endif
// gen_amalgamated begin source: gen/protos/perfetto/config/etw/etw_config.gen.cc
// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wfloat-equal"
#endif
// gen_amalgamated expanded: #include "protos/perfetto/config/etw/etw_config.gen.h"

namespace perfetto {
namespace protos {
namespace gen {

EtwConfig::EtwConfig() = default;
EtwConfig::~EtwConfig() = default;
EtwConfig::EtwConfig(const EtwConfig&) = default;
EtwConfig& EtwConfig::operator=(const EtwConfig&) = default;
EtwConfig::EtwConfig(EtwConfig&&) noexcept = default;
EtwConfig& EtwConfig::operator=(EtwConfig&&) = default;

bool EtwConfig::operator==(const EtwConfig& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(kernel_flags_, other.kernel_flags_);
}

bool EtwConfig::ParseFromArray(const void* raw, size_t size) {
  kernel_flags_.clear();
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* kernel_flags */:
        kernel_flags_.emplace_back();
        field.get(&kernel_flags_.back());
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string EtwConfig::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> EtwConfig::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void EtwConfig::Serialize(::protozero::Message* msg) const {
  // Field 1: kernel_flags
  for (auto& it : kernel_flags_) {
    ::protozero::internal::gen_helpers::SerializeVarInt(1, it, msg);
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}

}  // namespace perfetto
}  // namespace protos
}  // namespace gen
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic pop
#endif
// gen_amalgamated begin source: gen/protos/perfetto/config/interceptor_config.gen.cc
// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wfloat-equal"
#endif
// gen_amalgamated expanded: #include "protos/perfetto/config/interceptor_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/interceptors/console_config.gen.h"

namespace perfetto {
namespace protos {
namespace gen {

InterceptorConfig::InterceptorConfig() = default;
InterceptorConfig::~InterceptorConfig() = default;
InterceptorConfig::InterceptorConfig(const InterceptorConfig&) = default;
InterceptorConfig& InterceptorConfig::operator=(const InterceptorConfig&) = default;
InterceptorConfig::InterceptorConfig(InterceptorConfig&&) noexcept = default;
InterceptorConfig& InterceptorConfig::operator=(InterceptorConfig&&) = default;

bool InterceptorConfig::operator==(const InterceptorConfig& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(name_, other.name_)
   && ::protozero::internal::gen_helpers::EqualsField(console_config_, other.console_config_);
}

bool InterceptorConfig::ParseFromArray(const void* raw, size_t size) {
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* name */:
        ::protozero::internal::gen_helpers::DeserializeString(field, &name_);
        break;
      case 100 /* console_config */:
        (*console_config_).ParseFromArray(field.data(), field.size());
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string InterceptorConfig::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> InterceptorConfig::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void InterceptorConfig::Serialize(::protozero::Message* msg) const {
  // Field 1: name
  if (_has_field_[1]) {
    ::protozero::internal::gen_helpers::SerializeString(1, name_, msg);
  }

  // Field 100: console_config
  if (_has_field_[100]) {
    (*console_config_).Serialize(msg->BeginNestedMessage<::protozero::Message>(100));
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}

}  // namespace perfetto
}  // namespace protos
}  // namespace gen
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic pop
#endif
// gen_amalgamated begin source: gen/protos/perfetto/config/stress_test_config.gen.cc
// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wfloat-equal"
#endif
// gen_amalgamated expanded: #include "protos/perfetto/config/stress_test_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/trace_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/data_source_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/system_info/system_info.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/track_event/track_event_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/test_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/sys_stats/sys_stats_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/common/sys_stats_counters.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/profiling/perf_event_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/common/perf_events.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/profiling/java_hprof_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/profiling/heapprofd_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/process_stats/process_stats_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/statsd/statsd_tracing_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/statsd/atom_ids.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/power/android_power_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/interceptor_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/interceptors/console_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/inode_file/inode_file_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/gpu/vulkan_memory_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/gpu/gpu_counter_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/ftrace/ftrace_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/etw/etw_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/chrome/v8_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/chrome/chrome_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/android/surfaceflinger_transactions_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/android/surfaceflinger_layers_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/android/protolog_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/common/protolog_common.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/android/pixel_modem_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/android/packages_list_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/android/network_trace_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/android/android_sdk_sysprop_guard_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/android/android_system_property_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/android/android_polled_state_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/android/android_log_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/common/android_log_constants.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/android/android_input_event_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/android/android_game_intervention_list_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/common/builtin_clock.gen.h"

namespace perfetto {
namespace protos {
namespace gen {

StressTestConfig::StressTestConfig() = default;
StressTestConfig::~StressTestConfig() = default;
StressTestConfig::StressTestConfig(const StressTestConfig&) = default;
StressTestConfig& StressTestConfig::operator=(const StressTestConfig&) = default;
StressTestConfig::StressTestConfig(StressTestConfig&&) noexcept = default;
StressTestConfig& StressTestConfig::operator=(StressTestConfig&&) = default;

bool StressTestConfig::operator==(const StressTestConfig& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(trace_config_, other.trace_config_)
   && ::protozero::internal::gen_helpers::EqualsField(shmem_size_kb_, other.shmem_size_kb_)
   && ::protozero::internal::gen_helpers::EqualsField(shmem_page_size_kb_, other.shmem_page_size_kb_)
   && ::protozero::internal::gen_helpers::EqualsField(num_processes_, other.num_processes_)
   && ::protozero::internal::gen_helpers::EqualsField(num_threads_, other.num_threads_)
   && ::protozero::internal::gen_helpers::EqualsField(max_events_, other.max_events_)
   && ::protozero::internal::gen_helpers::EqualsField(nesting_, other.nesting_)
   && ::protozero::internal::gen_helpers::EqualsField(steady_state_timings_, other.steady_state_timings_)
   && ::protozero::internal::gen_helpers::EqualsField(burst_period_ms_, other.burst_period_ms_)
   && ::protozero::internal::gen_helpers::EqualsField(burst_duration_ms_, other.burst_duration_ms_)
   && ::protozero::internal::gen_helpers::EqualsField(burst_timings_, other.burst_timings_);
}

bool StressTestConfig::ParseFromArray(const void* raw, size_t size) {
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* trace_config */:
        (*trace_config_).ParseFromArray(field.data(), field.size());
        break;
      case 2 /* shmem_size_kb */:
        field.get(&shmem_size_kb_);
        break;
      case 3 /* shmem_page_size_kb */:
        field.get(&shmem_page_size_kb_);
        break;
      case 4 /* num_processes */:
        field.get(&num_processes_);
        break;
      case 5 /* num_threads */:
        field.get(&num_threads_);
        break;
      case 6 /* max_events */:
        field.get(&max_events_);
        break;
      case 7 /* nesting */:
        field.get(&nesting_);
        break;
      case 8 /* steady_state_timings */:
        (*steady_state_timings_).ParseFromArray(field.data(), field.size());
        break;
      case 9 /* burst_period_ms */:
        field.get(&burst_period_ms_);
        break;
      case 10 /* burst_duration_ms */:
        field.get(&burst_duration_ms_);
        break;
      case 11 /* burst_timings */:
        (*burst_timings_).ParseFromArray(field.data(), field.size());
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string StressTestConfig::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> StressTestConfig::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void StressTestConfig::Serialize(::protozero::Message* msg) const {
  // Field 1: trace_config
  if (_has_field_[1]) {
    (*trace_config_).Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
  }

  // Field 2: shmem_size_kb
  if (_has_field_[2]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(2, shmem_size_kb_, msg);
  }

  // Field 3: shmem_page_size_kb
  if (_has_field_[3]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(3, shmem_page_size_kb_, msg);
  }

  // Field 4: num_processes
  if (_has_field_[4]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(4, num_processes_, msg);
  }

  // Field 5: num_threads
  if (_has_field_[5]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(5, num_threads_, msg);
  }

  // Field 6: max_events
  if (_has_field_[6]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(6, max_events_, msg);
  }

  // Field 7: nesting
  if (_has_field_[7]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(7, nesting_, msg);
  }

  // Field 8: steady_state_timings
  if (_has_field_[8]) {
    (*steady_state_timings_).Serialize(msg->BeginNestedMessage<::protozero::Message>(8));
  }

  // Field 9: burst_period_ms
  if (_has_field_[9]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(9, burst_period_ms_, msg);
  }

  // Field 10: burst_duration_ms
  if (_has_field_[10]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(10, burst_duration_ms_, msg);
  }

  // Field 11: burst_timings
  if (_has_field_[11]) {
    (*burst_timings_).Serialize(msg->BeginNestedMessage<::protozero::Message>(11));
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}


StressTestConfig_WriterTiming::StressTestConfig_WriterTiming() = default;
StressTestConfig_WriterTiming::~StressTestConfig_WriterTiming() = default;
StressTestConfig_WriterTiming::StressTestConfig_WriterTiming(const StressTestConfig_WriterTiming&) = default;
StressTestConfig_WriterTiming& StressTestConfig_WriterTiming::operator=(const StressTestConfig_WriterTiming&) = default;
StressTestConfig_WriterTiming::StressTestConfig_WriterTiming(StressTestConfig_WriterTiming&&) noexcept = default;
StressTestConfig_WriterTiming& StressTestConfig_WriterTiming::operator=(StressTestConfig_WriterTiming&&) = default;

bool StressTestConfig_WriterTiming::operator==(const StressTestConfig_WriterTiming& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(payload_mean_, other.payload_mean_)
   && ::protozero::internal::gen_helpers::EqualsField(payload_stddev_, other.payload_stddev_)
   && ::protozero::internal::gen_helpers::EqualsField(rate_mean_, other.rate_mean_)
   && ::protozero::internal::gen_helpers::EqualsField(rate_stddev_, other.rate_stddev_)
   && ::protozero::internal::gen_helpers::EqualsField(payload_write_time_ms_, other.payload_write_time_ms_);
}

bool StressTestConfig_WriterTiming::ParseFromArray(const void* raw, size_t size) {
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* payload_mean */:
        field.get(&payload_mean_);
        break;
      case 2 /* payload_stddev */:
        field.get(&payload_stddev_);
        break;
      case 3 /* rate_mean */:
        field.get(&rate_mean_);
        break;
      case 4 /* rate_stddev */:
        field.get(&rate_stddev_);
        break;
      case 5 /* payload_write_time_ms */:
        field.get(&payload_write_time_ms_);
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string StressTestConfig_WriterTiming::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> StressTestConfig_WriterTiming::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void StressTestConfig_WriterTiming::Serialize(::protozero::Message* msg) const {
  // Field 1: payload_mean
  if (_has_field_[1]) {
    ::protozero::internal::gen_helpers::SerializeFixed(1, payload_mean_, msg);
  }

  // Field 2: payload_stddev
  if (_has_field_[2]) {
    ::protozero::internal::gen_helpers::SerializeFixed(2, payload_stddev_, msg);
  }

  // Field 3: rate_mean
  if (_has_field_[3]) {
    ::protozero::internal::gen_helpers::SerializeFixed(3, rate_mean_, msg);
  }

  // Field 4: rate_stddev
  if (_has_field_[4]) {
    ::protozero::internal::gen_helpers::SerializeFixed(4, rate_stddev_, msg);
  }

  // Field 5: payload_write_time_ms
  if (_has_field_[5]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(5, payload_write_time_ms_, msg);
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}

}  // namespace perfetto
}  // namespace protos
}  // namespace gen
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic pop
#endif
// gen_amalgamated begin source: gen/protos/perfetto/config/test_config.gen.cc
// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wfloat-equal"
#endif
// gen_amalgamated expanded: #include "protos/perfetto/config/test_config.gen.h"

namespace perfetto {
namespace protos {
namespace gen {

TestConfig::TestConfig() = default;
TestConfig::~TestConfig() = default;
TestConfig::TestConfig(const TestConfig&) = default;
TestConfig& TestConfig::operator=(const TestConfig&) = default;
TestConfig::TestConfig(TestConfig&&) noexcept = default;
TestConfig& TestConfig::operator=(TestConfig&&) = default;

bool TestConfig::operator==(const TestConfig& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(message_count_, other.message_count_)
   && ::protozero::internal::gen_helpers::EqualsField(max_messages_per_second_, other.max_messages_per_second_)
   && ::protozero::internal::gen_helpers::EqualsField(seed_, other.seed_)
   && ::protozero::internal::gen_helpers::EqualsField(message_size_, other.message_size_)
   && ::protozero::internal::gen_helpers::EqualsField(send_batch_on_register_, other.send_batch_on_register_)
   && ::protozero::internal::gen_helpers::EqualsField(dummy_fields_, other.dummy_fields_);
}

bool TestConfig::ParseFromArray(const void* raw, size_t size) {
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* message_count */:
        field.get(&message_count_);
        break;
      case 2 /* max_messages_per_second */:
        field.get(&max_messages_per_second_);
        break;
      case 3 /* seed */:
        field.get(&seed_);
        break;
      case 4 /* message_size */:
        field.get(&message_size_);
        break;
      case 5 /* send_batch_on_register */:
        field.get(&send_batch_on_register_);
        break;
      case 6 /* dummy_fields */:
        (*dummy_fields_).ParseFromArray(field.data(), field.size());
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string TestConfig::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> TestConfig::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void TestConfig::Serialize(::protozero::Message* msg) const {
  // Field 1: message_count
  if (_has_field_[1]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(1, message_count_, msg);
  }

  // Field 2: max_messages_per_second
  if (_has_field_[2]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(2, max_messages_per_second_, msg);
  }

  // Field 3: seed
  if (_has_field_[3]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(3, seed_, msg);
  }

  // Field 4: message_size
  if (_has_field_[4]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(4, message_size_, msg);
  }

  // Field 5: send_batch_on_register
  if (_has_field_[5]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(5, send_batch_on_register_, msg);
  }

  // Field 6: dummy_fields
  if (_has_field_[6]) {
    (*dummy_fields_).Serialize(msg->BeginNestedMessage<::protozero::Message>(6));
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}


TestConfig_DummyFields::TestConfig_DummyFields() = default;
TestConfig_DummyFields::~TestConfig_DummyFields() = default;
TestConfig_DummyFields::TestConfig_DummyFields(const TestConfig_DummyFields&) = default;
TestConfig_DummyFields& TestConfig_DummyFields::operator=(const TestConfig_DummyFields&) = default;
TestConfig_DummyFields::TestConfig_DummyFields(TestConfig_DummyFields&&) noexcept = default;
TestConfig_DummyFields& TestConfig_DummyFields::operator=(TestConfig_DummyFields&&) = default;

bool TestConfig_DummyFields::operator==(const TestConfig_DummyFields& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(field_uint32_, other.field_uint32_)
   && ::protozero::internal::gen_helpers::EqualsField(field_int32_, other.field_int32_)
   && ::protozero::internal::gen_helpers::EqualsField(field_uint64_, other.field_uint64_)
   && ::protozero::internal::gen_helpers::EqualsField(field_int64_, other.field_int64_)
   && ::protozero::internal::gen_helpers::EqualsField(field_fixed64_, other.field_fixed64_)
   && ::protozero::internal::gen_helpers::EqualsField(field_sfixed64_, other.field_sfixed64_)
   && ::protozero::internal::gen_helpers::EqualsField(field_fixed32_, other.field_fixed32_)
   && ::protozero::internal::gen_helpers::EqualsField(field_sfixed32_, other.field_sfixed32_)
   && ::protozero::internal::gen_helpers::EqualsField(field_double_, other.field_double_)
   && ::protozero::internal::gen_helpers::EqualsField(field_float_, other.field_float_)
   && ::protozero::internal::gen_helpers::EqualsField(field_sint64_, other.field_sint64_)
   && ::protozero::internal::gen_helpers::EqualsField(field_sint32_, other.field_sint32_)
   && ::protozero::internal::gen_helpers::EqualsField(field_string_, other.field_string_)
   && ::protozero::internal::gen_helpers::EqualsField(field_bytes_, other.field_bytes_);
}

bool TestConfig_DummyFields::ParseFromArray(const void* raw, size_t size) {
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* field_uint32 */:
        field.get(&field_uint32_);
        break;
      case 2 /* field_int32 */:
        field.get(&field_int32_);
        break;
      case 3 /* field_uint64 */:
        field.get(&field_uint64_);
        break;
      case 4 /* field_int64 */:
        field.get(&field_int64_);
        break;
      case 5 /* field_fixed64 */:
        field.get(&field_fixed64_);
        break;
      case 6 /* field_sfixed64 */:
        field.get(&field_sfixed64_);
        break;
      case 7 /* field_fixed32 */:
        field.get(&field_fixed32_);
        break;
      case 8 /* field_sfixed32 */:
        field.get(&field_sfixed32_);
        break;
      case 9 /* field_double */:
        field.get(&field_double_);
        break;
      case 10 /* field_float */:
        field.get(&field_float_);
        break;
      case 11 /* field_sint64 */:
        field.get_signed(&field_sint64_);
        break;
      case 12 /* field_sint32 */:
        field.get_signed(&field_sint32_);
        break;
      case 13 /* field_string */:
        ::protozero::internal::gen_helpers::DeserializeString(field, &field_string_);
        break;
      case 14 /* field_bytes */:
        field.get(&field_bytes_);
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string TestConfig_DummyFields::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> TestConfig_DummyFields::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void TestConfig_DummyFields::Serialize(::protozero::Message* msg) const {
  // Field 1: field_uint32
  if (_has_field_[1]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(1, field_uint32_, msg);
  }

  // Field 2: field_int32
  if (_has_field_[2]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(2, field_int32_, msg);
  }

  // Field 3: field_uint64
  if (_has_field_[3]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(3, field_uint64_, msg);
  }

  // Field 4: field_int64
  if (_has_field_[4]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(4, field_int64_, msg);
  }

  // Field 5: field_fixed64
  if (_has_field_[5]) {
    ::protozero::internal::gen_helpers::SerializeFixed(5, field_fixed64_, msg);
  }

  // Field 6: field_sfixed64
  if (_has_field_[6]) {
    ::protozero::internal::gen_helpers::SerializeFixed(6, field_sfixed64_, msg);
  }

  // Field 7: field_fixed32
  if (_has_field_[7]) {
    ::protozero::internal::gen_helpers::SerializeFixed(7, field_fixed32_, msg);
  }

  // Field 8: field_sfixed32
  if (_has_field_[8]) {
    ::protozero::internal::gen_helpers::SerializeFixed(8, field_sfixed32_, msg);
  }

  // Field 9: field_double
  if (_has_field_[9]) {
    ::protozero::internal::gen_helpers::SerializeFixed(9, field_double_, msg);
  }

  // Field 10: field_float
  if (_has_field_[10]) {
    ::protozero::internal::gen_helpers::SerializeFixed(10, field_float_, msg);
  }

  // Field 11: field_sint64
  if (_has_field_[11]) {
    ::protozero::internal::gen_helpers::SerializeSignedVarInt(11, field_sint64_, msg);
  }

  // Field 12: field_sint32
  if (_has_field_[12]) {
    ::protozero::internal::gen_helpers::SerializeSignedVarInt(12, field_sint32_, msg);
  }

  // Field 13: field_string
  if (_has_field_[13]) {
    ::protozero::internal::gen_helpers::SerializeString(13, field_string_, msg);
  }

  // Field 14: field_bytes
  if (_has_field_[14]) {
    ::protozero::internal::gen_helpers::SerializeString(14, field_bytes_, msg);
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}

}  // namespace perfetto
}  // namespace protos
}  // namespace gen
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic pop
#endif
// gen_amalgamated begin source: gen/protos/perfetto/config/trace_config.gen.cc
// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wfloat-equal"
#endif
// gen_amalgamated expanded: #include "protos/perfetto/config/trace_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/data_source_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/system_info/system_info.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/track_event/track_event_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/test_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/sys_stats/sys_stats_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/common/sys_stats_counters.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/profiling/perf_event_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/common/perf_events.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/profiling/java_hprof_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/profiling/heapprofd_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/process_stats/process_stats_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/statsd/statsd_tracing_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/statsd/atom_ids.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/power/android_power_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/interceptor_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/interceptors/console_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/inode_file/inode_file_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/gpu/vulkan_memory_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/gpu/gpu_counter_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/ftrace/ftrace_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/etw/etw_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/chrome/v8_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/chrome/chrome_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/android/surfaceflinger_transactions_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/android/surfaceflinger_layers_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/android/protolog_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/common/protolog_common.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/android/pixel_modem_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/android/packages_list_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/android/network_trace_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/android/android_sdk_sysprop_guard_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/android/android_system_property_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/android/android_polled_state_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/android/android_log_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/common/android_log_constants.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/android/android_input_event_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/android/android_game_intervention_list_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/common/builtin_clock.gen.h"

namespace perfetto {
namespace protos {
namespace gen {

TraceConfig::TraceConfig() = default;
TraceConfig::~TraceConfig() = default;
TraceConfig::TraceConfig(const TraceConfig&) = default;
TraceConfig& TraceConfig::operator=(const TraceConfig&) = default;
TraceConfig::TraceConfig(TraceConfig&&) noexcept = default;
TraceConfig& TraceConfig::operator=(TraceConfig&&) = default;

bool TraceConfig::operator==(const TraceConfig& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(buffers_, other.buffers_)
   && ::protozero::internal::gen_helpers::EqualsField(data_sources_, other.data_sources_)
   && ::protozero::internal::gen_helpers::EqualsField(builtin_data_sources_, other.builtin_data_sources_)
   && ::protozero::internal::gen_helpers::EqualsField(duration_ms_, other.duration_ms_)
   && ::protozero::internal::gen_helpers::EqualsField(prefer_suspend_clock_for_duration_, other.prefer_suspend_clock_for_duration_)
   && ::protozero::internal::gen_helpers::EqualsField(enable_extra_guardrails_, other.enable_extra_guardrails_)
   && ::protozero::internal::gen_helpers::EqualsField(lockdown_mode_, other.lockdown_mode_)
   && ::protozero::internal::gen_helpers::EqualsField(producers_, other.producers_)
   && ::protozero::internal::gen_helpers::EqualsField(statsd_metadata_, other.statsd_metadata_)
   && ::protozero::internal::gen_helpers::EqualsField(write_into_file_, other.write_into_file_)
   && ::protozero::internal::gen_helpers::EqualsField(output_path_, other.output_path_)
   && ::protozero::internal::gen_helpers::EqualsField(file_write_period_ms_, other.file_write_period_ms_)
   && ::protozero::internal::gen_helpers::EqualsField(max_file_size_bytes_, other.max_file_size_bytes_)
   && ::protozero::internal::gen_helpers::EqualsField(guardrail_overrides_, other.guardrail_overrides_)
   && ::protozero::internal::gen_helpers::EqualsField(deferred_start_, other.deferred_start_)
   && ::protozero::internal::gen_helpers::EqualsField(flush_period_ms_, other.flush_period_ms_)
   && ::protozero::internal::gen_helpers::EqualsField(flush_timeout_ms_, other.flush_timeout_ms_)
   && ::protozero::internal::gen_helpers::EqualsField(data_source_stop_timeout_ms_, other.data_source_stop_timeout_ms_)
   && ::protozero::internal::gen_helpers::EqualsField(notify_traceur_, other.notify_traceur_)
   && ::protozero::internal::gen_helpers::EqualsField(bugreport_score_, other.bugreport_score_)
   && ::protozero::internal::gen_helpers::EqualsField(bugreport_filename_, other.bugreport_filename_)
   && ::protozero::internal::gen_helpers::EqualsField(trigger_config_, other.trigger_config_)
   && ::protozero::internal::gen_helpers::EqualsField(activate_triggers_, other.activate_triggers_)
   && ::protozero::internal::gen_helpers::EqualsField(incremental_state_config_, other.incremental_state_config_)
   && ::protozero::internal::gen_helpers::EqualsField(allow_user_build_tracing_, other.allow_user_build_tracing_)
   && ::protozero::internal::gen_helpers::EqualsField(unique_session_name_, other.unique_session_name_)
   && ::protozero::internal::gen_helpers::EqualsField(compression_type_, other.compression_type_)
   && ::protozero::internal::gen_helpers::EqualsField(incident_report_config_, other.incident_report_config_)
   && ::protozero::internal::gen_helpers::EqualsField(statsd_logging_, other.statsd_logging_)
   && ::protozero::internal::gen_helpers::EqualsField(trace_uuid_msb_, other.trace_uuid_msb_)
   && ::protozero::internal::gen_helpers::EqualsField(trace_uuid_lsb_, other.trace_uuid_lsb_)
   && ::protozero::internal::gen_helpers::EqualsField(trace_filter_, other.trace_filter_)
   && ::protozero::internal::gen_helpers::EqualsField(android_report_config_, other.android_report_config_)
   && ::protozero::internal::gen_helpers::EqualsField(cmd_trace_start_delay_, other.cmd_trace_start_delay_);
}

int TraceConfig::buffers_size() const { return static_cast<int>(buffers_.size()); }
void TraceConfig::clear_buffers() { buffers_.clear(); }
TraceConfig_BufferConfig* TraceConfig::add_buffers() { buffers_.emplace_back(); return &buffers_.back(); }
int TraceConfig::data_sources_size() const { return static_cast<int>(data_sources_.size()); }
void TraceConfig::clear_data_sources() { data_sources_.clear(); }
TraceConfig_DataSource* TraceConfig::add_data_sources() { data_sources_.emplace_back(); return &data_sources_.back(); }
int TraceConfig::producers_size() const { return static_cast<int>(producers_.size()); }
void TraceConfig::clear_producers() { producers_.clear(); }
TraceConfig_ProducerConfig* TraceConfig::add_producers() { producers_.emplace_back(); return &producers_.back(); }
bool TraceConfig::ParseFromArray(const void* raw, size_t size) {
  buffers_.clear();
  data_sources_.clear();
  producers_.clear();
  activate_triggers_.clear();
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* buffers */:
        buffers_.emplace_back();
        buffers_.back().ParseFromArray(field.data(), field.size());
        break;
      case 2 /* data_sources */:
        data_sources_.emplace_back();
        data_sources_.back().ParseFromArray(field.data(), field.size());
        break;
      case 20 /* builtin_data_sources */:
        (*builtin_data_sources_).ParseFromArray(field.data(), field.size());
        break;
      case 3 /* duration_ms */:
        field.get(&duration_ms_);
        break;
      case 36 /* prefer_suspend_clock_for_duration */:
        field.get(&prefer_suspend_clock_for_duration_);
        break;
      case 4 /* enable_extra_guardrails */:
        field.get(&enable_extra_guardrails_);
        break;
      case 5 /* lockdown_mode */:
        field.get(&lockdown_mode_);
        break;
      case 6 /* producers */:
        producers_.emplace_back();
        producers_.back().ParseFromArray(field.data(), field.size());
        break;
      case 7 /* statsd_metadata */:
        (*statsd_metadata_).ParseFromArray(field.data(), field.size());
        break;
      case 8 /* write_into_file */:
        field.get(&write_into_file_);
        break;
      case 29 /* output_path */:
        ::protozero::internal::gen_helpers::DeserializeString(field, &output_path_);
        break;
      case 9 /* file_write_period_ms */:
        field.get(&file_write_period_ms_);
        break;
      case 10 /* max_file_size_bytes */:
        field.get(&max_file_size_bytes_);
        break;
      case 11 /* guardrail_overrides */:
        (*guardrail_overrides_).ParseFromArray(field.data(), field.size());
        break;
      case 12 /* deferred_start */:
        field.get(&deferred_start_);
        break;
      case 13 /* flush_period_ms */:
        field.get(&flush_period_ms_);
        break;
      case 14 /* flush_timeout_ms */:
        field.get(&flush_timeout_ms_);
        break;
      case 23 /* data_source_stop_timeout_ms */:
        field.get(&data_source_stop_timeout_ms_);
        break;
      case 16 /* notify_traceur */:
        field.get(&notify_traceur_);
        break;
      case 30 /* bugreport_score */:
        field.get(&bugreport_score_);
        break;
      case 38 /* bugreport_filename */:
        ::protozero::internal::gen_helpers::DeserializeString(field, &bugreport_filename_);
        break;
      case 17 /* trigger_config */:
        (*trigger_config_).ParseFromArray(field.data(), field.size());
        break;
      case 18 /* activate_triggers */:
        activate_triggers_.emplace_back();
        ::protozero::internal::gen_helpers::DeserializeString(field, &activate_triggers_.back());
        break;
      case 21 /* incremental_state_config */:
        (*incremental_state_config_).ParseFromArray(field.data(), field.size());
        break;
      case 19 /* allow_user_build_tracing */:
        field.get(&allow_user_build_tracing_);
        break;
      case 22 /* unique_session_name */:
        ::protozero::internal::gen_helpers::DeserializeString(field, &unique_session_name_);
        break;
      case 24 /* compression_type */:
        field.get(&compression_type_);
        break;
      case 25 /* incident_report_config */:
        (*incident_report_config_).ParseFromArray(field.data(), field.size());
        break;
      case 31 /* statsd_logging */:
        field.get(&statsd_logging_);
        break;
      case 27 /* trace_uuid_msb */:
        field.get(&trace_uuid_msb_);
        break;
      case 28 /* trace_uuid_lsb */:
        field.get(&trace_uuid_lsb_);
        break;
      case 33 /* trace_filter */:
        (*trace_filter_).ParseFromArray(field.data(), field.size());
        break;
      case 34 /* android_report_config */:
        (*android_report_config_).ParseFromArray(field.data(), field.size());
        break;
      case 35 /* cmd_trace_start_delay */:
        (*cmd_trace_start_delay_).ParseFromArray(field.data(), field.size());
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string TraceConfig::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> TraceConfig::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void TraceConfig::Serialize(::protozero::Message* msg) const {
  // Field 1: buffers
  for (auto& it : buffers_) {
    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
  }

  // Field 2: data_sources
  for (auto& it : data_sources_) {
    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(2));
  }

  // Field 20: builtin_data_sources
  if (_has_field_[20]) {
    (*builtin_data_sources_).Serialize(msg->BeginNestedMessage<::protozero::Message>(20));
  }

  // Field 3: duration_ms
  if (_has_field_[3]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(3, duration_ms_, msg);
  }

  // Field 36: prefer_suspend_clock_for_duration
  if (_has_field_[36]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(36, prefer_suspend_clock_for_duration_, msg);
  }

  // Field 4: enable_extra_guardrails
  if (_has_field_[4]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(4, enable_extra_guardrails_, msg);
  }

  // Field 5: lockdown_mode
  if (_has_field_[5]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(5, lockdown_mode_, msg);
  }

  // Field 6: producers
  for (auto& it : producers_) {
    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(6));
  }

  // Field 7: statsd_metadata
  if (_has_field_[7]) {
    (*statsd_metadata_).Serialize(msg->BeginNestedMessage<::protozero::Message>(7));
  }

  // Field 8: write_into_file
  if (_has_field_[8]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(8, write_into_file_, msg);
  }

  // Field 29: output_path
  if (_has_field_[29]) {
    ::protozero::internal::gen_helpers::SerializeString(29, output_path_, msg);
  }

  // Field 9: file_write_period_ms
  if (_has_field_[9]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(9, file_write_period_ms_, msg);
  }

  // Field 10: max_file_size_bytes
  if (_has_field_[10]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(10, max_file_size_bytes_, msg);
  }

  // Field 11: guardrail_overrides
  if (_has_field_[11]) {
    (*guardrail_overrides_).Serialize(msg->BeginNestedMessage<::protozero::Message>(11));
  }

  // Field 12: deferred_start
  if (_has_field_[12]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(12, deferred_start_, msg);
  }

  // Field 13: flush_period_ms
  if (_has_field_[13]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(13, flush_period_ms_, msg);
  }

  // Field 14: flush_timeout_ms
  if (_has_field_[14]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(14, flush_timeout_ms_, msg);
  }

  // Field 23: data_source_stop_timeout_ms
  if (_has_field_[23]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(23, data_source_stop_timeout_ms_, msg);
  }

  // Field 16: notify_traceur
  if (_has_field_[16]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(16, notify_traceur_, msg);
  }

  // Field 30: bugreport_score
  if (_has_field_[30]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(30, bugreport_score_, msg);
  }

  // Field 38: bugreport_filename
  if (_has_field_[38]) {
    ::protozero::internal::gen_helpers::SerializeString(38, bugreport_filename_, msg);
  }

  // Field 17: trigger_config
  if (_has_field_[17]) {
    (*trigger_config_).Serialize(msg->BeginNestedMessage<::protozero::Message>(17));
  }

  // Field 18: activate_triggers
  for (auto& it : activate_triggers_) {
    ::protozero::internal::gen_helpers::SerializeString(18, it, msg);
  }

  // Field 21: incremental_state_config
  if (_has_field_[21]) {
    (*incremental_state_config_).Serialize(msg->BeginNestedMessage<::protozero::Message>(21));
  }

  // Field 19: allow_user_build_tracing
  if (_has_field_[19]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(19, allow_user_build_tracing_, msg);
  }

  // Field 22: unique_session_name
  if (_has_field_[22]) {
    ::protozero::internal::gen_helpers::SerializeString(22, unique_session_name_, msg);
  }

  // Field 24: compression_type
  if (_has_field_[24]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(24, compression_type_, msg);
  }

  // Field 25: incident_report_config
  if (_has_field_[25]) {
    (*incident_report_config_).Serialize(msg->BeginNestedMessage<::protozero::Message>(25));
  }

  // Field 31: statsd_logging
  if (_has_field_[31]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(31, statsd_logging_, msg);
  }

  // Field 27: trace_uuid_msb
  if (_has_field_[27]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(27, trace_uuid_msb_, msg);
  }

  // Field 28: trace_uuid_lsb
  if (_has_field_[28]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(28, trace_uuid_lsb_, msg);
  }

  // Field 33: trace_filter
  if (_has_field_[33]) {
    (*trace_filter_).Serialize(msg->BeginNestedMessage<::protozero::Message>(33));
  }

  // Field 34: android_report_config
  if (_has_field_[34]) {
    (*android_report_config_).Serialize(msg->BeginNestedMessage<::protozero::Message>(34));
  }

  // Field 35: cmd_trace_start_delay
  if (_has_field_[35]) {
    (*cmd_trace_start_delay_).Serialize(msg->BeginNestedMessage<::protozero::Message>(35));
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}


TraceConfig_CmdTraceStartDelay::TraceConfig_CmdTraceStartDelay() = default;
TraceConfig_CmdTraceStartDelay::~TraceConfig_CmdTraceStartDelay() = default;
TraceConfig_CmdTraceStartDelay::TraceConfig_CmdTraceStartDelay(const TraceConfig_CmdTraceStartDelay&) = default;
TraceConfig_CmdTraceStartDelay& TraceConfig_CmdTraceStartDelay::operator=(const TraceConfig_CmdTraceStartDelay&) = default;
TraceConfig_CmdTraceStartDelay::TraceConfig_CmdTraceStartDelay(TraceConfig_CmdTraceStartDelay&&) noexcept = default;
TraceConfig_CmdTraceStartDelay& TraceConfig_CmdTraceStartDelay::operator=(TraceConfig_CmdTraceStartDelay&&) = default;

bool TraceConfig_CmdTraceStartDelay::operator==(const TraceConfig_CmdTraceStartDelay& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(min_delay_ms_, other.min_delay_ms_)
   && ::protozero::internal::gen_helpers::EqualsField(max_delay_ms_, other.max_delay_ms_);
}

bool TraceConfig_CmdTraceStartDelay::ParseFromArray(const void* raw, size_t size) {
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* min_delay_ms */:
        field.get(&min_delay_ms_);
        break;
      case 2 /* max_delay_ms */:
        field.get(&max_delay_ms_);
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string TraceConfig_CmdTraceStartDelay::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> TraceConfig_CmdTraceStartDelay::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void TraceConfig_CmdTraceStartDelay::Serialize(::protozero::Message* msg) const {
  // Field 1: min_delay_ms
  if (_has_field_[1]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(1, min_delay_ms_, msg);
  }

  // Field 2: max_delay_ms
  if (_has_field_[2]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(2, max_delay_ms_, msg);
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}


TraceConfig_AndroidReportConfig::TraceConfig_AndroidReportConfig() = default;
TraceConfig_AndroidReportConfig::~TraceConfig_AndroidReportConfig() = default;
TraceConfig_AndroidReportConfig::TraceConfig_AndroidReportConfig(const TraceConfig_AndroidReportConfig&) = default;
TraceConfig_AndroidReportConfig& TraceConfig_AndroidReportConfig::operator=(const TraceConfig_AndroidReportConfig&) = default;
TraceConfig_AndroidReportConfig::TraceConfig_AndroidReportConfig(TraceConfig_AndroidReportConfig&&) noexcept = default;
TraceConfig_AndroidReportConfig& TraceConfig_AndroidReportConfig::operator=(TraceConfig_AndroidReportConfig&&) = default;

bool TraceConfig_AndroidReportConfig::operator==(const TraceConfig_AndroidReportConfig& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(reporter_service_package_, other.reporter_service_package_)
   && ::protozero::internal::gen_helpers::EqualsField(reporter_service_class_, other.reporter_service_class_)
   && ::protozero::internal::gen_helpers::EqualsField(skip_report_, other.skip_report_)
   && ::protozero::internal::gen_helpers::EqualsField(use_pipe_in_framework_for_testing_, other.use_pipe_in_framework_for_testing_);
}

bool TraceConfig_AndroidReportConfig::ParseFromArray(const void* raw, size_t size) {
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* reporter_service_package */:
        ::protozero::internal::gen_helpers::DeserializeString(field, &reporter_service_package_);
        break;
      case 2 /* reporter_service_class */:
        ::protozero::internal::gen_helpers::DeserializeString(field, &reporter_service_class_);
        break;
      case 3 /* skip_report */:
        field.get(&skip_report_);
        break;
      case 4 /* use_pipe_in_framework_for_testing */:
        field.get(&use_pipe_in_framework_for_testing_);
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string TraceConfig_AndroidReportConfig::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> TraceConfig_AndroidReportConfig::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void TraceConfig_AndroidReportConfig::Serialize(::protozero::Message* msg) const {
  // Field 1: reporter_service_package
  if (_has_field_[1]) {
    ::protozero::internal::gen_helpers::SerializeString(1, reporter_service_package_, msg);
  }

  // Field 2: reporter_service_class
  if (_has_field_[2]) {
    ::protozero::internal::gen_helpers::SerializeString(2, reporter_service_class_, msg);
  }

  // Field 3: skip_report
  if (_has_field_[3]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(3, skip_report_, msg);
  }

  // Field 4: use_pipe_in_framework_for_testing
  if (_has_field_[4]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(4, use_pipe_in_framework_for_testing_, msg);
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}


TraceConfig_TraceFilter::TraceConfig_TraceFilter() = default;
TraceConfig_TraceFilter::~TraceConfig_TraceFilter() = default;
TraceConfig_TraceFilter::TraceConfig_TraceFilter(const TraceConfig_TraceFilter&) = default;
TraceConfig_TraceFilter& TraceConfig_TraceFilter::operator=(const TraceConfig_TraceFilter&) = default;
TraceConfig_TraceFilter::TraceConfig_TraceFilter(TraceConfig_TraceFilter&&) noexcept = default;
TraceConfig_TraceFilter& TraceConfig_TraceFilter::operator=(TraceConfig_TraceFilter&&) = default;

bool TraceConfig_TraceFilter::operator==(const TraceConfig_TraceFilter& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(bytecode_, other.bytecode_)
   && ::protozero::internal::gen_helpers::EqualsField(bytecode_v2_, other.bytecode_v2_)
   && ::protozero::internal::gen_helpers::EqualsField(string_filter_chain_, other.string_filter_chain_);
}

bool TraceConfig_TraceFilter::ParseFromArray(const void* raw, size_t size) {
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* bytecode */:
        field.get(&bytecode_);
        break;
      case 2 /* bytecode_v2 */:
        field.get(&bytecode_v2_);
        break;
      case 3 /* string_filter_chain */:
        (*string_filter_chain_).ParseFromArray(field.data(), field.size());
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string TraceConfig_TraceFilter::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> TraceConfig_TraceFilter::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void TraceConfig_TraceFilter::Serialize(::protozero::Message* msg) const {
  // Field 1: bytecode
  if (_has_field_[1]) {
    ::protozero::internal::gen_helpers::SerializeString(1, bytecode_, msg);
  }

  // Field 2: bytecode_v2
  if (_has_field_[2]) {
    ::protozero::internal::gen_helpers::SerializeString(2, bytecode_v2_, msg);
  }

  // Field 3: string_filter_chain
  if (_has_field_[3]) {
    (*string_filter_chain_).Serialize(msg->BeginNestedMessage<::protozero::Message>(3));
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}


TraceConfig_TraceFilter_StringFilterChain::TraceConfig_TraceFilter_StringFilterChain() = default;
TraceConfig_TraceFilter_StringFilterChain::~TraceConfig_TraceFilter_StringFilterChain() = default;
TraceConfig_TraceFilter_StringFilterChain::TraceConfig_TraceFilter_StringFilterChain(const TraceConfig_TraceFilter_StringFilterChain&) = default;
TraceConfig_TraceFilter_StringFilterChain& TraceConfig_TraceFilter_StringFilterChain::operator=(const TraceConfig_TraceFilter_StringFilterChain&) = default;
TraceConfig_TraceFilter_StringFilterChain::TraceConfig_TraceFilter_StringFilterChain(TraceConfig_TraceFilter_StringFilterChain&&) noexcept = default;
TraceConfig_TraceFilter_StringFilterChain& TraceConfig_TraceFilter_StringFilterChain::operator=(TraceConfig_TraceFilter_StringFilterChain&&) = default;

bool TraceConfig_TraceFilter_StringFilterChain::operator==(const TraceConfig_TraceFilter_StringFilterChain& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(rules_, other.rules_);
}

int TraceConfig_TraceFilter_StringFilterChain::rules_size() const { return static_cast<int>(rules_.size()); }
void TraceConfig_TraceFilter_StringFilterChain::clear_rules() { rules_.clear(); }
TraceConfig_TraceFilter_StringFilterRule* TraceConfig_TraceFilter_StringFilterChain::add_rules() { rules_.emplace_back(); return &rules_.back(); }
bool TraceConfig_TraceFilter_StringFilterChain::ParseFromArray(const void* raw, size_t size) {
  rules_.clear();
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* rules */:
        rules_.emplace_back();
        rules_.back().ParseFromArray(field.data(), field.size());
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string TraceConfig_TraceFilter_StringFilterChain::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> TraceConfig_TraceFilter_StringFilterChain::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void TraceConfig_TraceFilter_StringFilterChain::Serialize(::protozero::Message* msg) const {
  // Field 1: rules
  for (auto& it : rules_) {
    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}


TraceConfig_TraceFilter_StringFilterRule::TraceConfig_TraceFilter_StringFilterRule() = default;
TraceConfig_TraceFilter_StringFilterRule::~TraceConfig_TraceFilter_StringFilterRule() = default;
TraceConfig_TraceFilter_StringFilterRule::TraceConfig_TraceFilter_StringFilterRule(const TraceConfig_TraceFilter_StringFilterRule&) = default;
TraceConfig_TraceFilter_StringFilterRule& TraceConfig_TraceFilter_StringFilterRule::operator=(const TraceConfig_TraceFilter_StringFilterRule&) = default;
TraceConfig_TraceFilter_StringFilterRule::TraceConfig_TraceFilter_StringFilterRule(TraceConfig_TraceFilter_StringFilterRule&&) noexcept = default;
TraceConfig_TraceFilter_StringFilterRule& TraceConfig_TraceFilter_StringFilterRule::operator=(TraceConfig_TraceFilter_StringFilterRule&&) = default;

bool TraceConfig_TraceFilter_StringFilterRule::operator==(const TraceConfig_TraceFilter_StringFilterRule& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(policy_, other.policy_)
   && ::protozero::internal::gen_helpers::EqualsField(regex_pattern_, other.regex_pattern_)
   && ::protozero::internal::gen_helpers::EqualsField(atrace_payload_starts_with_, other.atrace_payload_starts_with_);
}

bool TraceConfig_TraceFilter_StringFilterRule::ParseFromArray(const void* raw, size_t size) {
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* policy */:
        field.get(&policy_);
        break;
      case 2 /* regex_pattern */:
        ::protozero::internal::gen_helpers::DeserializeString(field, &regex_pattern_);
        break;
      case 3 /* atrace_payload_starts_with */:
        ::protozero::internal::gen_helpers::DeserializeString(field, &atrace_payload_starts_with_);
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string TraceConfig_TraceFilter_StringFilterRule::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> TraceConfig_TraceFilter_StringFilterRule::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void TraceConfig_TraceFilter_StringFilterRule::Serialize(::protozero::Message* msg) const {
  // Field 1: policy
  if (_has_field_[1]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(1, policy_, msg);
  }

  // Field 2: regex_pattern
  if (_has_field_[2]) {
    ::protozero::internal::gen_helpers::SerializeString(2, regex_pattern_, msg);
  }

  // Field 3: atrace_payload_starts_with
  if (_has_field_[3]) {
    ::protozero::internal::gen_helpers::SerializeString(3, atrace_payload_starts_with_, msg);
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}


TraceConfig_IncidentReportConfig::TraceConfig_IncidentReportConfig() = default;
TraceConfig_IncidentReportConfig::~TraceConfig_IncidentReportConfig() = default;
TraceConfig_IncidentReportConfig::TraceConfig_IncidentReportConfig(const TraceConfig_IncidentReportConfig&) = default;
TraceConfig_IncidentReportConfig& TraceConfig_IncidentReportConfig::operator=(const TraceConfig_IncidentReportConfig&) = default;
TraceConfig_IncidentReportConfig::TraceConfig_IncidentReportConfig(TraceConfig_IncidentReportConfig&&) noexcept = default;
TraceConfig_IncidentReportConfig& TraceConfig_IncidentReportConfig::operator=(TraceConfig_IncidentReportConfig&&) = default;

bool TraceConfig_IncidentReportConfig::operator==(const TraceConfig_IncidentReportConfig& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(destination_package_, other.destination_package_)
   && ::protozero::internal::gen_helpers::EqualsField(destination_class_, other.destination_class_)
   && ::protozero::internal::gen_helpers::EqualsField(privacy_level_, other.privacy_level_)
   && ::protozero::internal::gen_helpers::EqualsField(skip_incidentd_, other.skip_incidentd_)
   && ::protozero::internal::gen_helpers::EqualsField(skip_dropbox_, other.skip_dropbox_);
}

bool TraceConfig_IncidentReportConfig::ParseFromArray(const void* raw, size_t size) {
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* destination_package */:
        ::protozero::internal::gen_helpers::DeserializeString(field, &destination_package_);
        break;
      case 2 /* destination_class */:
        ::protozero::internal::gen_helpers::DeserializeString(field, &destination_class_);
        break;
      case 3 /* privacy_level */:
        field.get(&privacy_level_);
        break;
      case 5 /* skip_incidentd */:
        field.get(&skip_incidentd_);
        break;
      case 4 /* skip_dropbox */:
        field.get(&skip_dropbox_);
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string TraceConfig_IncidentReportConfig::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> TraceConfig_IncidentReportConfig::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void TraceConfig_IncidentReportConfig::Serialize(::protozero::Message* msg) const {
  // Field 1: destination_package
  if (_has_field_[1]) {
    ::protozero::internal::gen_helpers::SerializeString(1, destination_package_, msg);
  }

  // Field 2: destination_class
  if (_has_field_[2]) {
    ::protozero::internal::gen_helpers::SerializeString(2, destination_class_, msg);
  }

  // Field 3: privacy_level
  if (_has_field_[3]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(3, privacy_level_, msg);
  }

  // Field 5: skip_incidentd
  if (_has_field_[5]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(5, skip_incidentd_, msg);
  }

  // Field 4: skip_dropbox
  if (_has_field_[4]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(4, skip_dropbox_, msg);
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}


TraceConfig_IncrementalStateConfig::TraceConfig_IncrementalStateConfig() = default;
TraceConfig_IncrementalStateConfig::~TraceConfig_IncrementalStateConfig() = default;
TraceConfig_IncrementalStateConfig::TraceConfig_IncrementalStateConfig(const TraceConfig_IncrementalStateConfig&) = default;
TraceConfig_IncrementalStateConfig& TraceConfig_IncrementalStateConfig::operator=(const TraceConfig_IncrementalStateConfig&) = default;
TraceConfig_IncrementalStateConfig::TraceConfig_IncrementalStateConfig(TraceConfig_IncrementalStateConfig&&) noexcept = default;
TraceConfig_IncrementalStateConfig& TraceConfig_IncrementalStateConfig::operator=(TraceConfig_IncrementalStateConfig&&) = default;

bool TraceConfig_IncrementalStateConfig::operator==(const TraceConfig_IncrementalStateConfig& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(clear_period_ms_, other.clear_period_ms_);
}

bool TraceConfig_IncrementalStateConfig::ParseFromArray(const void* raw, size_t size) {
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* clear_period_ms */:
        field.get(&clear_period_ms_);
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string TraceConfig_IncrementalStateConfig::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> TraceConfig_IncrementalStateConfig::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void TraceConfig_IncrementalStateConfig::Serialize(::protozero::Message* msg) const {
  // Field 1: clear_period_ms
  if (_has_field_[1]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(1, clear_period_ms_, msg);
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}


TraceConfig_TriggerConfig::TraceConfig_TriggerConfig() = default;
TraceConfig_TriggerConfig::~TraceConfig_TriggerConfig() = default;
TraceConfig_TriggerConfig::TraceConfig_TriggerConfig(const TraceConfig_TriggerConfig&) = default;
TraceConfig_TriggerConfig& TraceConfig_TriggerConfig::operator=(const TraceConfig_TriggerConfig&) = default;
TraceConfig_TriggerConfig::TraceConfig_TriggerConfig(TraceConfig_TriggerConfig&&) noexcept = default;
TraceConfig_TriggerConfig& TraceConfig_TriggerConfig::operator=(TraceConfig_TriggerConfig&&) = default;

bool TraceConfig_TriggerConfig::operator==(const TraceConfig_TriggerConfig& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(trigger_mode_, other.trigger_mode_)
   && ::protozero::internal::gen_helpers::EqualsField(use_clone_snapshot_if_available_, other.use_clone_snapshot_if_available_)
   && ::protozero::internal::gen_helpers::EqualsField(triggers_, other.triggers_)
   && ::protozero::internal::gen_helpers::EqualsField(trigger_timeout_ms_, other.trigger_timeout_ms_);
}

int TraceConfig_TriggerConfig::triggers_size() const { return static_cast<int>(triggers_.size()); }
void TraceConfig_TriggerConfig::clear_triggers() { triggers_.clear(); }
TraceConfig_TriggerConfig_Trigger* TraceConfig_TriggerConfig::add_triggers() { triggers_.emplace_back(); return &triggers_.back(); }
bool TraceConfig_TriggerConfig::ParseFromArray(const void* raw, size_t size) {
  triggers_.clear();
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* trigger_mode */:
        field.get(&trigger_mode_);
        break;
      case 5 /* use_clone_snapshot_if_available */:
        field.get(&use_clone_snapshot_if_available_);
        break;
      case 2 /* triggers */:
        triggers_.emplace_back();
        triggers_.back().ParseFromArray(field.data(), field.size());
        break;
      case 3 /* trigger_timeout_ms */:
        field.get(&trigger_timeout_ms_);
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string TraceConfig_TriggerConfig::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> TraceConfig_TriggerConfig::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void TraceConfig_TriggerConfig::Serialize(::protozero::Message* msg) const {
  // Field 1: trigger_mode
  if (_has_field_[1]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(1, trigger_mode_, msg);
  }

  // Field 5: use_clone_snapshot_if_available
  if (_has_field_[5]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(5, use_clone_snapshot_if_available_, msg);
  }

  // Field 2: triggers
  for (auto& it : triggers_) {
    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(2));
  }

  // Field 3: trigger_timeout_ms
  if (_has_field_[3]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(3, trigger_timeout_ms_, msg);
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}


TraceConfig_TriggerConfig_Trigger::TraceConfig_TriggerConfig_Trigger() = default;
TraceConfig_TriggerConfig_Trigger::~TraceConfig_TriggerConfig_Trigger() = default;
TraceConfig_TriggerConfig_Trigger::TraceConfig_TriggerConfig_Trigger(const TraceConfig_TriggerConfig_Trigger&) = default;
TraceConfig_TriggerConfig_Trigger& TraceConfig_TriggerConfig_Trigger::operator=(const TraceConfig_TriggerConfig_Trigger&) = default;
TraceConfig_TriggerConfig_Trigger::TraceConfig_TriggerConfig_Trigger(TraceConfig_TriggerConfig_Trigger&&) noexcept = default;
TraceConfig_TriggerConfig_Trigger& TraceConfig_TriggerConfig_Trigger::operator=(TraceConfig_TriggerConfig_Trigger&&) = default;

bool TraceConfig_TriggerConfig_Trigger::operator==(const TraceConfig_TriggerConfig_Trigger& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(name_, other.name_)
   && ::protozero::internal::gen_helpers::EqualsField(producer_name_regex_, other.producer_name_regex_)
   && ::protozero::internal::gen_helpers::EqualsField(stop_delay_ms_, other.stop_delay_ms_)
   && ::protozero::internal::gen_helpers::EqualsField(max_per_24_h_, other.max_per_24_h_)
   && ::protozero::internal::gen_helpers::EqualsField(skip_probability_, other.skip_probability_);
}

bool TraceConfig_TriggerConfig_Trigger::ParseFromArray(const void* raw, size_t size) {
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* name */:
        ::protozero::internal::gen_helpers::DeserializeString(field, &name_);
        break;
      case 2 /* producer_name_regex */:
        ::protozero::internal::gen_helpers::DeserializeString(field, &producer_name_regex_);
        break;
      case 3 /* stop_delay_ms */:
        field.get(&stop_delay_ms_);
        break;
      case 4 /* max_per_24_h */:
        field.get(&max_per_24_h_);
        break;
      case 5 /* skip_probability */:
        field.get(&skip_probability_);
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string TraceConfig_TriggerConfig_Trigger::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> TraceConfig_TriggerConfig_Trigger::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void TraceConfig_TriggerConfig_Trigger::Serialize(::protozero::Message* msg) const {
  // Field 1: name
  if (_has_field_[1]) {
    ::protozero::internal::gen_helpers::SerializeString(1, name_, msg);
  }

  // Field 2: producer_name_regex
  if (_has_field_[2]) {
    ::protozero::internal::gen_helpers::SerializeString(2, producer_name_regex_, msg);
  }

  // Field 3: stop_delay_ms
  if (_has_field_[3]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(3, stop_delay_ms_, msg);
  }

  // Field 4: max_per_24_h
  if (_has_field_[4]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(4, max_per_24_h_, msg);
  }

  // Field 5: skip_probability
  if (_has_field_[5]) {
    ::protozero::internal::gen_helpers::SerializeFixed(5, skip_probability_, msg);
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}


TraceConfig_GuardrailOverrides::TraceConfig_GuardrailOverrides() = default;
TraceConfig_GuardrailOverrides::~TraceConfig_GuardrailOverrides() = default;
TraceConfig_GuardrailOverrides::TraceConfig_GuardrailOverrides(const TraceConfig_GuardrailOverrides&) = default;
TraceConfig_GuardrailOverrides& TraceConfig_GuardrailOverrides::operator=(const TraceConfig_GuardrailOverrides&) = default;
TraceConfig_GuardrailOverrides::TraceConfig_GuardrailOverrides(TraceConfig_GuardrailOverrides&&) noexcept = default;
TraceConfig_GuardrailOverrides& TraceConfig_GuardrailOverrides::operator=(TraceConfig_GuardrailOverrides&&) = default;

bool TraceConfig_GuardrailOverrides::operator==(const TraceConfig_GuardrailOverrides& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(max_upload_per_day_bytes_, other.max_upload_per_day_bytes_)
   && ::protozero::internal::gen_helpers::EqualsField(max_tracing_buffer_size_kb_, other.max_tracing_buffer_size_kb_);
}

bool TraceConfig_GuardrailOverrides::ParseFromArray(const void* raw, size_t size) {
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* max_upload_per_day_bytes */:
        field.get(&max_upload_per_day_bytes_);
        break;
      case 2 /* max_tracing_buffer_size_kb */:
        field.get(&max_tracing_buffer_size_kb_);
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string TraceConfig_GuardrailOverrides::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> TraceConfig_GuardrailOverrides::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void TraceConfig_GuardrailOverrides::Serialize(::protozero::Message* msg) const {
  // Field 1: max_upload_per_day_bytes
  if (_has_field_[1]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(1, max_upload_per_day_bytes_, msg);
  }

  // Field 2: max_tracing_buffer_size_kb
  if (_has_field_[2]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(2, max_tracing_buffer_size_kb_, msg);
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}


TraceConfig_StatsdMetadata::TraceConfig_StatsdMetadata() = default;
TraceConfig_StatsdMetadata::~TraceConfig_StatsdMetadata() = default;
TraceConfig_StatsdMetadata::TraceConfig_StatsdMetadata(const TraceConfig_StatsdMetadata&) = default;
TraceConfig_StatsdMetadata& TraceConfig_StatsdMetadata::operator=(const TraceConfig_StatsdMetadata&) = default;
TraceConfig_StatsdMetadata::TraceConfig_StatsdMetadata(TraceConfig_StatsdMetadata&&) noexcept = default;
TraceConfig_StatsdMetadata& TraceConfig_StatsdMetadata::operator=(TraceConfig_StatsdMetadata&&) = default;

bool TraceConfig_StatsdMetadata::operator==(const TraceConfig_StatsdMetadata& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(triggering_alert_id_, other.triggering_alert_id_)
   && ::protozero::internal::gen_helpers::EqualsField(triggering_config_uid_, other.triggering_config_uid_)
   && ::protozero::internal::gen_helpers::EqualsField(triggering_config_id_, other.triggering_config_id_)
   && ::protozero::internal::gen_helpers::EqualsField(triggering_subscription_id_, other.triggering_subscription_id_);
}

bool TraceConfig_StatsdMetadata::ParseFromArray(const void* raw, size_t size) {
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* triggering_alert_id */:
        field.get(&triggering_alert_id_);
        break;
      case 2 /* triggering_config_uid */:
        field.get(&triggering_config_uid_);
        break;
      case 3 /* triggering_config_id */:
        field.get(&triggering_config_id_);
        break;
      case 4 /* triggering_subscription_id */:
        field.get(&triggering_subscription_id_);
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string TraceConfig_StatsdMetadata::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> TraceConfig_StatsdMetadata::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void TraceConfig_StatsdMetadata::Serialize(::protozero::Message* msg) const {
  // Field 1: triggering_alert_id
  if (_has_field_[1]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(1, triggering_alert_id_, msg);
  }

  // Field 2: triggering_config_uid
  if (_has_field_[2]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(2, triggering_config_uid_, msg);
  }

  // Field 3: triggering_config_id
  if (_has_field_[3]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(3, triggering_config_id_, msg);
  }

  // Field 4: triggering_subscription_id
  if (_has_field_[4]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(4, triggering_subscription_id_, msg);
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}


TraceConfig_ProducerConfig::TraceConfig_ProducerConfig() = default;
TraceConfig_ProducerConfig::~TraceConfig_ProducerConfig() = default;
TraceConfig_ProducerConfig::TraceConfig_ProducerConfig(const TraceConfig_ProducerConfig&) = default;
TraceConfig_ProducerConfig& TraceConfig_ProducerConfig::operator=(const TraceConfig_ProducerConfig&) = default;
TraceConfig_ProducerConfig::TraceConfig_ProducerConfig(TraceConfig_ProducerConfig&&) noexcept = default;
TraceConfig_ProducerConfig& TraceConfig_ProducerConfig::operator=(TraceConfig_ProducerConfig&&) = default;

bool TraceConfig_ProducerConfig::operator==(const TraceConfig_ProducerConfig& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(producer_name_, other.producer_name_)
   && ::protozero::internal::gen_helpers::EqualsField(shm_size_kb_, other.shm_size_kb_)
   && ::protozero::internal::gen_helpers::EqualsField(page_size_kb_, other.page_size_kb_);
}

bool TraceConfig_ProducerConfig::ParseFromArray(const void* raw, size_t size) {
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* producer_name */:
        ::protozero::internal::gen_helpers::DeserializeString(field, &producer_name_);
        break;
      case 2 /* shm_size_kb */:
        field.get(&shm_size_kb_);
        break;
      case 3 /* page_size_kb */:
        field.get(&page_size_kb_);
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string TraceConfig_ProducerConfig::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> TraceConfig_ProducerConfig::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void TraceConfig_ProducerConfig::Serialize(::protozero::Message* msg) const {
  // Field 1: producer_name
  if (_has_field_[1]) {
    ::protozero::internal::gen_helpers::SerializeString(1, producer_name_, msg);
  }

  // Field 2: shm_size_kb
  if (_has_field_[2]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(2, shm_size_kb_, msg);
  }

  // Field 3: page_size_kb
  if (_has_field_[3]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(3, page_size_kb_, msg);
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}


TraceConfig_BuiltinDataSource::TraceConfig_BuiltinDataSource() = default;
TraceConfig_BuiltinDataSource::~TraceConfig_BuiltinDataSource() = default;
TraceConfig_BuiltinDataSource::TraceConfig_BuiltinDataSource(const TraceConfig_BuiltinDataSource&) = default;
TraceConfig_BuiltinDataSource& TraceConfig_BuiltinDataSource::operator=(const TraceConfig_BuiltinDataSource&) = default;
TraceConfig_BuiltinDataSource::TraceConfig_BuiltinDataSource(TraceConfig_BuiltinDataSource&&) noexcept = default;
TraceConfig_BuiltinDataSource& TraceConfig_BuiltinDataSource::operator=(TraceConfig_BuiltinDataSource&&) = default;

bool TraceConfig_BuiltinDataSource::operator==(const TraceConfig_BuiltinDataSource& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(disable_clock_snapshotting_, other.disable_clock_snapshotting_)
   && ::protozero::internal::gen_helpers::EqualsField(disable_trace_config_, other.disable_trace_config_)
   && ::protozero::internal::gen_helpers::EqualsField(disable_system_info_, other.disable_system_info_)
   && ::protozero::internal::gen_helpers::EqualsField(disable_service_events_, other.disable_service_events_)
   && ::protozero::internal::gen_helpers::EqualsField(primary_trace_clock_, other.primary_trace_clock_)
   && ::protozero::internal::gen_helpers::EqualsField(snapshot_interval_ms_, other.snapshot_interval_ms_)
   && ::protozero::internal::gen_helpers::EqualsField(prefer_suspend_clock_for_snapshot_, other.prefer_suspend_clock_for_snapshot_)
   && ::protozero::internal::gen_helpers::EqualsField(disable_chunk_usage_histograms_, other.disable_chunk_usage_histograms_);
}

bool TraceConfig_BuiltinDataSource::ParseFromArray(const void* raw, size_t size) {
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* disable_clock_snapshotting */:
        field.get(&disable_clock_snapshotting_);
        break;
      case 2 /* disable_trace_config */:
        field.get(&disable_trace_config_);
        break;
      case 3 /* disable_system_info */:
        field.get(&disable_system_info_);
        break;
      case 4 /* disable_service_events */:
        field.get(&disable_service_events_);
        break;
      case 5 /* primary_trace_clock */:
        field.get(&primary_trace_clock_);
        break;
      case 6 /* snapshot_interval_ms */:
        field.get(&snapshot_interval_ms_);
        break;
      case 7 /* prefer_suspend_clock_for_snapshot */:
        field.get(&prefer_suspend_clock_for_snapshot_);
        break;
      case 8 /* disable_chunk_usage_histograms */:
        field.get(&disable_chunk_usage_histograms_);
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string TraceConfig_BuiltinDataSource::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> TraceConfig_BuiltinDataSource::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void TraceConfig_BuiltinDataSource::Serialize(::protozero::Message* msg) const {
  // Field 1: disable_clock_snapshotting
  if (_has_field_[1]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(1, disable_clock_snapshotting_, msg);
  }

  // Field 2: disable_trace_config
  if (_has_field_[2]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(2, disable_trace_config_, msg);
  }

  // Field 3: disable_system_info
  if (_has_field_[3]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(3, disable_system_info_, msg);
  }

  // Field 4: disable_service_events
  if (_has_field_[4]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(4, disable_service_events_, msg);
  }

  // Field 5: primary_trace_clock
  if (_has_field_[5]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(5, primary_trace_clock_, msg);
  }

  // Field 6: snapshot_interval_ms
  if (_has_field_[6]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(6, snapshot_interval_ms_, msg);
  }

  // Field 7: prefer_suspend_clock_for_snapshot
  if (_has_field_[7]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(7, prefer_suspend_clock_for_snapshot_, msg);
  }

  // Field 8: disable_chunk_usage_histograms
  if (_has_field_[8]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(8, disable_chunk_usage_histograms_, msg);
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}


TraceConfig_DataSource::TraceConfig_DataSource() = default;
TraceConfig_DataSource::~TraceConfig_DataSource() = default;
TraceConfig_DataSource::TraceConfig_DataSource(const TraceConfig_DataSource&) = default;
TraceConfig_DataSource& TraceConfig_DataSource::operator=(const TraceConfig_DataSource&) = default;
TraceConfig_DataSource::TraceConfig_DataSource(TraceConfig_DataSource&&) noexcept = default;
TraceConfig_DataSource& TraceConfig_DataSource::operator=(TraceConfig_DataSource&&) = default;

bool TraceConfig_DataSource::operator==(const TraceConfig_DataSource& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(config_, other.config_)
   && ::protozero::internal::gen_helpers::EqualsField(producer_name_filter_, other.producer_name_filter_)
   && ::protozero::internal::gen_helpers::EqualsField(producer_name_regex_filter_, other.producer_name_regex_filter_);
}

bool TraceConfig_DataSource::ParseFromArray(const void* raw, size_t size) {
  producer_name_filter_.clear();
  producer_name_regex_filter_.clear();
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* config */:
        (*config_).ParseFromArray(field.data(), field.size());
        break;
      case 2 /* producer_name_filter */:
        producer_name_filter_.emplace_back();
        ::protozero::internal::gen_helpers::DeserializeString(field, &producer_name_filter_.back());
        break;
      case 3 /* producer_name_regex_filter */:
        producer_name_regex_filter_.emplace_back();
        ::protozero::internal::gen_helpers::DeserializeString(field, &producer_name_regex_filter_.back());
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string TraceConfig_DataSource::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> TraceConfig_DataSource::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void TraceConfig_DataSource::Serialize(::protozero::Message* msg) const {
  // Field 1: config
  if (_has_field_[1]) {
    (*config_).Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
  }

  // Field 2: producer_name_filter
  for (auto& it : producer_name_filter_) {
    ::protozero::internal::gen_helpers::SerializeString(2, it, msg);
  }

  // Field 3: producer_name_regex_filter
  for (auto& it : producer_name_regex_filter_) {
    ::protozero::internal::gen_helpers::SerializeString(3, it, msg);
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}


TraceConfig_BufferConfig::TraceConfig_BufferConfig() = default;
TraceConfig_BufferConfig::~TraceConfig_BufferConfig() = default;
TraceConfig_BufferConfig::TraceConfig_BufferConfig(const TraceConfig_BufferConfig&) = default;
TraceConfig_BufferConfig& TraceConfig_BufferConfig::operator=(const TraceConfig_BufferConfig&) = default;
TraceConfig_BufferConfig::TraceConfig_BufferConfig(TraceConfig_BufferConfig&&) noexcept = default;
TraceConfig_BufferConfig& TraceConfig_BufferConfig::operator=(TraceConfig_BufferConfig&&) = default;

bool TraceConfig_BufferConfig::operator==(const TraceConfig_BufferConfig& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(size_kb_, other.size_kb_)
   && ::protozero::internal::gen_helpers::EqualsField(fill_policy_, other.fill_policy_)
   && ::protozero::internal::gen_helpers::EqualsField(transfer_on_clone_, other.transfer_on_clone_)
   && ::protozero::internal::gen_helpers::EqualsField(clear_before_clone_, other.clear_before_clone_);
}

bool TraceConfig_BufferConfig::ParseFromArray(const void* raw, size_t size) {
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* size_kb */:
        field.get(&size_kb_);
        break;
      case 4 /* fill_policy */:
        field.get(&fill_policy_);
        break;
      case 5 /* transfer_on_clone */:
        field.get(&transfer_on_clone_);
        break;
      case 6 /* clear_before_clone */:
        field.get(&clear_before_clone_);
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string TraceConfig_BufferConfig::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> TraceConfig_BufferConfig::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void TraceConfig_BufferConfig::Serialize(::protozero::Message* msg) const {
  // Field 1: size_kb
  if (_has_field_[1]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(1, size_kb_, msg);
  }

  // Field 4: fill_policy
  if (_has_field_[4]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(4, fill_policy_, msg);
  }

  // Field 5: transfer_on_clone
  if (_has_field_[5]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(5, transfer_on_clone_, msg);
  }

  // Field 6: clear_before_clone
  if (_has_field_[6]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(6, clear_before_clone_, msg);
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}

}  // namespace perfetto
}  // namespace protos
}  // namespace gen
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic pop
#endif
// gen_amalgamated begin source: gen/protos/perfetto/common/android_energy_consumer_descriptor.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/common/android_log_constants.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/common/builtin_clock.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/common/commit_data_request.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/common/data_source_descriptor.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/common/descriptor.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/common/ftrace_descriptor.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/common/gpu_counter_descriptor.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/common/interceptor_descriptor.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/common/observable_events.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/common/perf_events.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/common/protolog_common.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/common/sys_stats_counters.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/common/trace_stats.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/common/tracing_service_capabilities.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/common/tracing_service_state.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/common/track_event_descriptor.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/android/graphics/point.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/android/graphics/rect.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/android/winscope_extensions.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/android/protolog.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/android/shell_transition.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/android/surfaceflinger_common.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/android/surfaceflinger_layers.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/android/surfaceflinger_transactions.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/android/android_game_intervention_list.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/android/android_input_event.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/android/android_log.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/android/android_system_property.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/android/camera_event.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/android/frame_timeline_event.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/android/gpu_mem_event.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/android/graphics_frame_event.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/android/initial_display_state.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/android/network_trace.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/android/packages_list.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/android/pixel_modem_events.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/chrome/chrome_benchmark_metadata.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/chrome/chrome_metadata.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/chrome/chrome_trace_event.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/chrome/chrome_trigger.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/chrome/v8.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/gpu/gpu_counter_event.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/gpu/gpu_log.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/gpu/gpu_render_stage_event.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/gpu/vulkan_api_event.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/gpu/vulkan_memory_event.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/profiling/deobfuscation.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/profiling/heap_graph.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/profiling/profile_common.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/profiling/profile_packet.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/profiling/smaps.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_active_processes.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_application_state_info.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_compositor_scheduler_state.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_content_settings_event_info.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_frame_reporter.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_histogram_sample.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_keyed_service.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_latency_info.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_legacy_ipc.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_message_pump.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_mojo_event_info.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_process_descriptor.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_renderer_scheduler_state.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_thread_descriptor.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_user_event.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_window_handle_event_info.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/counter_descriptor.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/debug_annotation.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/log_message.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/pixel_modem.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/process_descriptor.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/range_of_interest.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/screenshot.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/source_location.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/task_execution.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/thread_descriptor.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/track_descriptor.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/track_event.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/interned_data/interned_data.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_active_processes.gen.cc
// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wfloat-equal"
#endif
// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_active_processes.gen.h"

namespace perfetto {
namespace protos {
namespace gen {

ChromeActiveProcesses::ChromeActiveProcesses() = default;
ChromeActiveProcesses::~ChromeActiveProcesses() = default;
ChromeActiveProcesses::ChromeActiveProcesses(const ChromeActiveProcesses&) = default;
ChromeActiveProcesses& ChromeActiveProcesses::operator=(const ChromeActiveProcesses&) = default;
ChromeActiveProcesses::ChromeActiveProcesses(ChromeActiveProcesses&&) noexcept = default;
ChromeActiveProcesses& ChromeActiveProcesses::operator=(ChromeActiveProcesses&&) = default;

bool ChromeActiveProcesses::operator==(const ChromeActiveProcesses& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(pid_, other.pid_);
}

bool ChromeActiveProcesses::ParseFromArray(const void* raw, size_t size) {
  pid_.clear();
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* pid */:
        pid_.emplace_back();
        field.get(&pid_.back());
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string ChromeActiveProcesses::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> ChromeActiveProcesses::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void ChromeActiveProcesses::Serialize(::protozero::Message* msg) const {
  // Field 1: pid
  for (auto& it : pid_) {
    ::protozero::internal::gen_helpers::SerializeVarInt(1, it, msg);
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}

}  // namespace perfetto
}  // namespace protos
}  // namespace gen
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic pop
#endif
// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_application_state_info.gen.cc
// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wfloat-equal"
#endif
// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_application_state_info.gen.h"

namespace perfetto {
namespace protos {
namespace gen {

ChromeApplicationStateInfo::ChromeApplicationStateInfo() = default;
ChromeApplicationStateInfo::~ChromeApplicationStateInfo() = default;
ChromeApplicationStateInfo::ChromeApplicationStateInfo(const ChromeApplicationStateInfo&) = default;
ChromeApplicationStateInfo& ChromeApplicationStateInfo::operator=(const ChromeApplicationStateInfo&) = default;
ChromeApplicationStateInfo::ChromeApplicationStateInfo(ChromeApplicationStateInfo&&) noexcept = default;
ChromeApplicationStateInfo& ChromeApplicationStateInfo::operator=(ChromeApplicationStateInfo&&) = default;

bool ChromeApplicationStateInfo::operator==(const ChromeApplicationStateInfo& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(application_state_, other.application_state_);
}

bool ChromeApplicationStateInfo::ParseFromArray(const void* raw, size_t size) {
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* application_state */:
        field.get(&application_state_);
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string ChromeApplicationStateInfo::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> ChromeApplicationStateInfo::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void ChromeApplicationStateInfo::Serialize(::protozero::Message* msg) const {
  // Field 1: application_state
  if (_has_field_[1]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(1, application_state_, msg);
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}

}  // namespace perfetto
}  // namespace protos
}  // namespace gen
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic pop
#endif
// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_compositor_scheduler_state.gen.cc
// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wfloat-equal"
#endif
// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_compositor_scheduler_state.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/source_location.gen.h"

namespace perfetto {
namespace protos {
namespace gen {

CompositorTimingHistory::CompositorTimingHistory() = default;
CompositorTimingHistory::~CompositorTimingHistory() = default;
CompositorTimingHistory::CompositorTimingHistory(const CompositorTimingHistory&) = default;
CompositorTimingHistory& CompositorTimingHistory::operator=(const CompositorTimingHistory&) = default;
CompositorTimingHistory::CompositorTimingHistory(CompositorTimingHistory&&) noexcept = default;
CompositorTimingHistory& CompositorTimingHistory::operator=(CompositorTimingHistory&&) = default;

bool CompositorTimingHistory::operator==(const CompositorTimingHistory& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(begin_main_frame_queue_critical_estimate_delta_us_, other.begin_main_frame_queue_critical_estimate_delta_us_)
   && ::protozero::internal::gen_helpers::EqualsField(begin_main_frame_queue_not_critical_estimate_delta_us_, other.begin_main_frame_queue_not_critical_estimate_delta_us_)
   && ::protozero::internal::gen_helpers::EqualsField(begin_main_frame_start_to_ready_to_commit_estimate_delta_us_, other.begin_main_frame_start_to_ready_to_commit_estimate_delta_us_)
   && ::protozero::internal::gen_helpers::EqualsField(commit_to_ready_to_activate_estimate_delta_us_, other.commit_to_ready_to_activate_estimate_delta_us_)
   && ::protozero::internal::gen_helpers::EqualsField(prepare_tiles_estimate_delta_us_, other.prepare_tiles_estimate_delta_us_)
   && ::protozero::internal::gen_helpers::EqualsField(activate_estimate_delta_us_, other.activate_estimate_delta_us_)
   && ::protozero::internal::gen_helpers::EqualsField(draw_estimate_delta_us_, other.draw_estimate_delta_us_);
}

bool CompositorTimingHistory::ParseFromArray(const void* raw, size_t size) {
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* begin_main_frame_queue_critical_estimate_delta_us */:
        field.get(&begin_main_frame_queue_critical_estimate_delta_us_);
        break;
      case 2 /* begin_main_frame_queue_not_critical_estimate_delta_us */:
        field.get(&begin_main_frame_queue_not_critical_estimate_delta_us_);
        break;
      case 3 /* begin_main_frame_start_to_ready_to_commit_estimate_delta_us */:
        field.get(&begin_main_frame_start_to_ready_to_commit_estimate_delta_us_);
        break;
      case 4 /* commit_to_ready_to_activate_estimate_delta_us */:
        field.get(&commit_to_ready_to_activate_estimate_delta_us_);
        break;
      case 5 /* prepare_tiles_estimate_delta_us */:
        field.get(&prepare_tiles_estimate_delta_us_);
        break;
      case 6 /* activate_estimate_delta_us */:
        field.get(&activate_estimate_delta_us_);
        break;
      case 7 /* draw_estimate_delta_us */:
        field.get(&draw_estimate_delta_us_);
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string CompositorTimingHistory::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> CompositorTimingHistory::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void CompositorTimingHistory::Serialize(::protozero::Message* msg) const {
  // Field 1: begin_main_frame_queue_critical_estimate_delta_us
  if (_has_field_[1]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(1, begin_main_frame_queue_critical_estimate_delta_us_, msg);
  }

  // Field 2: begin_main_frame_queue_not_critical_estimate_delta_us
  if (_has_field_[2]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(2, begin_main_frame_queue_not_critical_estimate_delta_us_, msg);
  }

  // Field 3: begin_main_frame_start_to_ready_to_commit_estimate_delta_us
  if (_has_field_[3]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(3, begin_main_frame_start_to_ready_to_commit_estimate_delta_us_, msg);
  }

  // Field 4: commit_to_ready_to_activate_estimate_delta_us
  if (_has_field_[4]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(4, commit_to_ready_to_activate_estimate_delta_us_, msg);
  }

  // Field 5: prepare_tiles_estimate_delta_us
  if (_has_field_[5]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(5, prepare_tiles_estimate_delta_us_, msg);
  }

  // Field 6: activate_estimate_delta_us
  if (_has_field_[6]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(6, activate_estimate_delta_us_, msg);
  }

  // Field 7: draw_estimate_delta_us
  if (_has_field_[7]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(7, draw_estimate_delta_us_, msg);
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}


BeginFrameSourceState::BeginFrameSourceState() = default;
BeginFrameSourceState::~BeginFrameSourceState() = default;
BeginFrameSourceState::BeginFrameSourceState(const BeginFrameSourceState&) = default;
BeginFrameSourceState& BeginFrameSourceState::operator=(const BeginFrameSourceState&) = default;
BeginFrameSourceState::BeginFrameSourceState(BeginFrameSourceState&&) noexcept = default;
BeginFrameSourceState& BeginFrameSourceState::operator=(BeginFrameSourceState&&) = default;

bool BeginFrameSourceState::operator==(const BeginFrameSourceState& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(source_id_, other.source_id_)
   && ::protozero::internal::gen_helpers::EqualsField(paused_, other.paused_)
   && ::protozero::internal::gen_helpers::EqualsField(num_observers_, other.num_observers_)
   && ::protozero::internal::gen_helpers::EqualsField(last_begin_frame_args_, other.last_begin_frame_args_);
}

bool BeginFrameSourceState::ParseFromArray(const void* raw, size_t size) {
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* source_id */:
        field.get(&source_id_);
        break;
      case 2 /* paused */:
        field.get(&paused_);
        break;
      case 3 /* num_observers */:
        field.get(&num_observers_);
        break;
      case 4 /* last_begin_frame_args */:
        (*last_begin_frame_args_).ParseFromArray(field.data(), field.size());
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string BeginFrameSourceState::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> BeginFrameSourceState::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void BeginFrameSourceState::Serialize(::protozero::Message* msg) const {
  // Field 1: source_id
  if (_has_field_[1]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(1, source_id_, msg);
  }

  // Field 2: paused
  if (_has_field_[2]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(2, paused_, msg);
  }

  // Field 3: num_observers
  if (_has_field_[3]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(3, num_observers_, msg);
  }

  // Field 4: last_begin_frame_args
  if (_has_field_[4]) {
    (*last_begin_frame_args_).Serialize(msg->BeginNestedMessage<::protozero::Message>(4));
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}


BeginFrameArgs::BeginFrameArgs() = default;
BeginFrameArgs::~BeginFrameArgs() = default;
BeginFrameArgs::BeginFrameArgs(const BeginFrameArgs&) = default;
BeginFrameArgs& BeginFrameArgs::operator=(const BeginFrameArgs&) = default;
BeginFrameArgs::BeginFrameArgs(BeginFrameArgs&&) noexcept = default;
BeginFrameArgs& BeginFrameArgs::operator=(BeginFrameArgs&&) = default;

bool BeginFrameArgs::operator==(const BeginFrameArgs& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(type_, other.type_)
   && ::protozero::internal::gen_helpers::EqualsField(source_id_, other.source_id_)
   && ::protozero::internal::gen_helpers::EqualsField(sequence_number_, other.sequence_number_)
   && ::protozero::internal::gen_helpers::EqualsField(frame_time_us_, other.frame_time_us_)
   && ::protozero::internal::gen_helpers::EqualsField(deadline_us_, other.deadline_us_)
   && ::protozero::internal::gen_helpers::EqualsField(interval_delta_us_, other.interval_delta_us_)
   && ::protozero::internal::gen_helpers::EqualsField(on_critical_path_, other.on_critical_path_)
   && ::protozero::internal::gen_helpers::EqualsField(animate_only_, other.animate_only_)
   && ::protozero::internal::gen_helpers::EqualsField(source_location_iid_, other.source_location_iid_)
   && ::protozero::internal::gen_helpers::EqualsField(source_location_, other.source_location_)
   && ::protozero::internal::gen_helpers::EqualsField(frames_throttled_since_last_, other.frames_throttled_since_last_);
}

bool BeginFrameArgs::ParseFromArray(const void* raw, size_t size) {
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* type */:
        field.get(&type_);
        break;
      case 2 /* source_id */:
        field.get(&source_id_);
        break;
      case 3 /* sequence_number */:
        field.get(&sequence_number_);
        break;
      case 4 /* frame_time_us */:
        field.get(&frame_time_us_);
        break;
      case 5 /* deadline_us */:
        field.get(&deadline_us_);
        break;
      case 6 /* interval_delta_us */:
        field.get(&interval_delta_us_);
        break;
      case 7 /* on_critical_path */:
        field.get(&on_critical_path_);
        break;
      case 8 /* animate_only */:
        field.get(&animate_only_);
        break;
      case 9 /* source_location_iid */:
        field.get(&source_location_iid_);
        break;
      case 10 /* source_location */:
        (*source_location_).ParseFromArray(field.data(), field.size());
        break;
      case 12 /* frames_throttled_since_last */:
        field.get(&frames_throttled_since_last_);
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string BeginFrameArgs::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> BeginFrameArgs::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void BeginFrameArgs::Serialize(::protozero::Message* msg) const {
  // Field 1: type
  if (_has_field_[1]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(1, type_, msg);
  }

  // Field 2: source_id
  if (_has_field_[2]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(2, source_id_, msg);
  }

  // Field 3: sequence_number
  if (_has_field_[3]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(3, sequence_number_, msg);
  }

  // Field 4: frame_time_us
  if (_has_field_[4]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(4, frame_time_us_, msg);
  }

  // Field 5: deadline_us
  if (_has_field_[5]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(5, deadline_us_, msg);
  }

  // Field 6: interval_delta_us
  if (_has_field_[6]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(6, interval_delta_us_, msg);
  }

  // Field 7: on_critical_path
  if (_has_field_[7]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(7, on_critical_path_, msg);
  }

  // Field 8: animate_only
  if (_has_field_[8]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(8, animate_only_, msg);
  }

  // Field 9: source_location_iid
  if (_has_field_[9]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(9, source_location_iid_, msg);
  }

  // Field 10: source_location
  if (_has_field_[10]) {
    (*source_location_).Serialize(msg->BeginNestedMessage<::protozero::Message>(10));
  }

  // Field 12: frames_throttled_since_last
  if (_has_field_[12]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(12, frames_throttled_since_last_, msg);
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}


BeginFrameObserverState::BeginFrameObserverState() = default;
BeginFrameObserverState::~BeginFrameObserverState() = default;
BeginFrameObserverState::BeginFrameObserverState(const BeginFrameObserverState&) = default;
BeginFrameObserverState& BeginFrameObserverState::operator=(const BeginFrameObserverState&) = default;
BeginFrameObserverState::BeginFrameObserverState(BeginFrameObserverState&&) noexcept = default;
BeginFrameObserverState& BeginFrameObserverState::operator=(BeginFrameObserverState&&) = default;

bool BeginFrameObserverState::operator==(const BeginFrameObserverState& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(dropped_begin_frame_args_, other.dropped_begin_frame_args_)
   && ::protozero::internal::gen_helpers::EqualsField(last_begin_frame_args_, other.last_begin_frame_args_);
}

bool BeginFrameObserverState::ParseFromArray(const void* raw, size_t size) {
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* dropped_begin_frame_args */:
        field.get(&dropped_begin_frame_args_);
        break;
      case 2 /* last_begin_frame_args */:
        (*last_begin_frame_args_).ParseFromArray(field.data(), field.size());
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string BeginFrameObserverState::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> BeginFrameObserverState::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void BeginFrameObserverState::Serialize(::protozero::Message* msg) const {
  // Field 1: dropped_begin_frame_args
  if (_has_field_[1]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(1, dropped_begin_frame_args_, msg);
  }

  // Field 2: last_begin_frame_args
  if (_has_field_[2]) {
    (*last_begin_frame_args_).Serialize(msg->BeginNestedMessage<::protozero::Message>(2));
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}


BeginImplFrameArgs::BeginImplFrameArgs() = default;
BeginImplFrameArgs::~BeginImplFrameArgs() = default;
BeginImplFrameArgs::BeginImplFrameArgs(const BeginImplFrameArgs&) = default;
BeginImplFrameArgs& BeginImplFrameArgs::operator=(const BeginImplFrameArgs&) = default;
BeginImplFrameArgs::BeginImplFrameArgs(BeginImplFrameArgs&&) noexcept = default;
BeginImplFrameArgs& BeginImplFrameArgs::operator=(BeginImplFrameArgs&&) = default;

bool BeginImplFrameArgs::operator==(const BeginImplFrameArgs& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(updated_at_us_, other.updated_at_us_)
   && ::protozero::internal::gen_helpers::EqualsField(finished_at_us_, other.finished_at_us_)
   && ::protozero::internal::gen_helpers::EqualsField(state_, other.state_)
   && ::protozero::internal::gen_helpers::EqualsField(current_args_, other.current_args_)
   && ::protozero::internal::gen_helpers::EqualsField(last_args_, other.last_args_)
   && ::protozero::internal::gen_helpers::EqualsField(timestamps_in_us_, other.timestamps_in_us_);
}

bool BeginImplFrameArgs::ParseFromArray(const void* raw, size_t size) {
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* updated_at_us */:
        field.get(&updated_at_us_);
        break;
      case 2 /* finished_at_us */:
        field.get(&finished_at_us_);
        break;
      case 3 /* state */:
        field.get(&state_);
        break;
      case 4 /* current_args */:
        (*current_args_).ParseFromArray(field.data(), field.size());
        break;
      case 5 /* last_args */:
        (*last_args_).ParseFromArray(field.data(), field.size());
        break;
      case 6 /* timestamps_in_us */:
        (*timestamps_in_us_).ParseFromArray(field.data(), field.size());
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string BeginImplFrameArgs::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> BeginImplFrameArgs::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void BeginImplFrameArgs::Serialize(::protozero::Message* msg) const {
  // Field 1: updated_at_us
  if (_has_field_[1]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(1, updated_at_us_, msg);
  }

  // Field 2: finished_at_us
  if (_has_field_[2]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(2, finished_at_us_, msg);
  }

  // Field 3: state
  if (_has_field_[3]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(3, state_, msg);
  }

  // Field 4: current_args
  if (_has_field_[4]) {
    (*current_args_).Serialize(msg->BeginNestedMessage<::protozero::Message>(4));
  }

  // Field 5: last_args
  if (_has_field_[5]) {
    (*last_args_).Serialize(msg->BeginNestedMessage<::protozero::Message>(5));
  }

  // Field 6: timestamps_in_us
  if (_has_field_[6]) {
    (*timestamps_in_us_).Serialize(msg->BeginNestedMessage<::protozero::Message>(6));
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}


BeginImplFrameArgs_TimestampsInUs::BeginImplFrameArgs_TimestampsInUs() = default;
BeginImplFrameArgs_TimestampsInUs::~BeginImplFrameArgs_TimestampsInUs() = default;
BeginImplFrameArgs_TimestampsInUs::BeginImplFrameArgs_TimestampsInUs(const BeginImplFrameArgs_TimestampsInUs&) = default;
BeginImplFrameArgs_TimestampsInUs& BeginImplFrameArgs_TimestampsInUs::operator=(const BeginImplFrameArgs_TimestampsInUs&) = default;
BeginImplFrameArgs_TimestampsInUs::BeginImplFrameArgs_TimestampsInUs(BeginImplFrameArgs_TimestampsInUs&&) noexcept = default;
BeginImplFrameArgs_TimestampsInUs& BeginImplFrameArgs_TimestampsInUs::operator=(BeginImplFrameArgs_TimestampsInUs&&) = default;

bool BeginImplFrameArgs_TimestampsInUs::operator==(const BeginImplFrameArgs_TimestampsInUs& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(interval_delta_, other.interval_delta_)
   && ::protozero::internal::gen_helpers::EqualsField(now_to_deadline_delta_, other.now_to_deadline_delta_)
   && ::protozero::internal::gen_helpers::EqualsField(frame_time_to_now_delta_, other.frame_time_to_now_delta_)
   && ::protozero::internal::gen_helpers::EqualsField(frame_time_to_deadline_delta_, other.frame_time_to_deadline_delta_)
   && ::protozero::internal::gen_helpers::EqualsField(now_, other.now_)
   && ::protozero::internal::gen_helpers::EqualsField(frame_time_, other.frame_time_)
   && ::protozero::internal::gen_helpers::EqualsField(deadline_, other.deadline_);
}

bool BeginImplFrameArgs_TimestampsInUs::ParseFromArray(const void* raw, size_t size) {
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* interval_delta */:
        field.get(&interval_delta_);
        break;
      case 2 /* now_to_deadline_delta */:
        field.get(&now_to_deadline_delta_);
        break;
      case 3 /* frame_time_to_now_delta */:
        field.get(&frame_time_to_now_delta_);
        break;
      case 4 /* frame_time_to_deadline_delta */:
        field.get(&frame_time_to_deadline_delta_);
        break;
      case 5 /* now */:
        field.get(&now_);
        break;
      case 6 /* frame_time */:
        field.get(&frame_time_);
        break;
      case 7 /* deadline */:
        field.get(&deadline_);
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string BeginImplFrameArgs_TimestampsInUs::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> BeginImplFrameArgs_TimestampsInUs::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void BeginImplFrameArgs_TimestampsInUs::Serialize(::protozero::Message* msg) const {
  // Field 1: interval_delta
  if (_has_field_[1]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(1, interval_delta_, msg);
  }

  // Field 2: now_to_deadline_delta
  if (_has_field_[2]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(2, now_to_deadline_delta_, msg);
  }

  // Field 3: frame_time_to_now_delta
  if (_has_field_[3]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(3, frame_time_to_now_delta_, msg);
  }

  // Field 4: frame_time_to_deadline_delta
  if (_has_field_[4]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(4, frame_time_to_deadline_delta_, msg);
  }

  // Field 5: now
  if (_has_field_[5]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(5, now_, msg);
  }

  // Field 6: frame_time
  if (_has_field_[6]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(6, frame_time_, msg);
  }

  // Field 7: deadline
  if (_has_field_[7]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(7, deadline_, msg);
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}


ChromeCompositorStateMachine::ChromeCompositorStateMachine() = default;
ChromeCompositorStateMachine::~ChromeCompositorStateMachine() = default;
ChromeCompositorStateMachine::ChromeCompositorStateMachine(const ChromeCompositorStateMachine&) = default;
ChromeCompositorStateMachine& ChromeCompositorStateMachine::operator=(const ChromeCompositorStateMachine&) = default;
ChromeCompositorStateMachine::ChromeCompositorStateMachine(ChromeCompositorStateMachine&&) noexcept = default;
ChromeCompositorStateMachine& ChromeCompositorStateMachine::operator=(ChromeCompositorStateMachine&&) = default;

bool ChromeCompositorStateMachine::operator==(const ChromeCompositorStateMachine& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(major_state_, other.major_state_)
   && ::protozero::internal::gen_helpers::EqualsField(minor_state_, other.minor_state_);
}

bool ChromeCompositorStateMachine::ParseFromArray(const void* raw, size_t size) {
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* major_state */:
        (*major_state_).ParseFromArray(field.data(), field.size());
        break;
      case 2 /* minor_state */:
        (*minor_state_).ParseFromArray(field.data(), field.size());
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string ChromeCompositorStateMachine::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> ChromeCompositorStateMachine::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void ChromeCompositorStateMachine::Serialize(::protozero::Message* msg) const {
  // Field 1: major_state
  if (_has_field_[1]) {
    (*major_state_).Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
  }

  // Field 2: minor_state
  if (_has_field_[2]) {
    (*minor_state_).Serialize(msg->BeginNestedMessage<::protozero::Message>(2));
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}


ChromeCompositorStateMachine_MinorState::ChromeCompositorStateMachine_MinorState() = default;
ChromeCompositorStateMachine_MinorState::~ChromeCompositorStateMachine_MinorState() = default;
ChromeCompositorStateMachine_MinorState::ChromeCompositorStateMachine_MinorState(const ChromeCompositorStateMachine_MinorState&) = default;
ChromeCompositorStateMachine_MinorState& ChromeCompositorStateMachine_MinorState::operator=(const ChromeCompositorStateMachine_MinorState&) = default;
ChromeCompositorStateMachine_MinorState::ChromeCompositorStateMachine_MinorState(ChromeCompositorStateMachine_MinorState&&) noexcept = default;
ChromeCompositorStateMachine_MinorState& ChromeCompositorStateMachine_MinorState::operator=(ChromeCompositorStateMachine_MinorState&&) = default;

bool ChromeCompositorStateMachine_MinorState::operator==(const ChromeCompositorStateMachine_MinorState& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(commit_count_, other.commit_count_)
   && ::protozero::internal::gen_helpers::EqualsField(current_frame_number_, other.current_frame_number_)
   && ::protozero::internal::gen_helpers::EqualsField(last_frame_number_submit_performed_, other.last_frame_number_submit_performed_)
   && ::protozero::internal::gen_helpers::EqualsField(last_frame_number_draw_performed_, other.last_frame_number_draw_performed_)
   && ::protozero::internal::gen_helpers::EqualsField(last_frame_number_begin_main_frame_sent_, other.last_frame_number_begin_main_frame_sent_)
   && ::protozero::internal::gen_helpers::EqualsField(did_draw_, other.did_draw_)
   && ::protozero::internal::gen_helpers::EqualsField(did_send_begin_main_frame_for_current_frame_, other.did_send_begin_main_frame_for_current_frame_)
   && ::protozero::internal::gen_helpers::EqualsField(did_notify_begin_main_frame_not_expected_until_, other.did_notify_begin_main_frame_not_expected_until_)
   && ::protozero::internal::gen_helpers::EqualsField(did_notify_begin_main_frame_not_expected_soon_, other.did_notify_begin_main_frame_not_expected_soon_)
   && ::protozero::internal::gen_helpers::EqualsField(wants_begin_main_frame_not_expected_, other.wants_begin_main_frame_not_expected_)
   && ::protozero::internal::gen_helpers::EqualsField(did_commit_during_frame_, other.did_commit_during_frame_)
   && ::protozero::internal::gen_helpers::EqualsField(did_invalidate_layer_tree_frame_sink_, other.did_invalidate_layer_tree_frame_sink_)
   && ::protozero::internal::gen_helpers::EqualsField(did_perform_impl_side_invalidaion_, other.did_perform_impl_side_invalidaion_)
   && ::protozero::internal::gen_helpers::EqualsField(did_prepare_tiles_, other.did_prepare_tiles_)
   && ::protozero::internal::gen_helpers::EqualsField(consecutive_checkerboard_animations_, other.consecutive_checkerboard_animations_)
   && ::protozero::internal::gen_helpers::EqualsField(pending_submit_frames_, other.pending_submit_frames_)
   && ::protozero::internal::gen_helpers::EqualsField(submit_frames_with_current_layer_tree_frame_sink_, other.submit_frames_with_current_layer_tree_frame_sink_)
   && ::protozero::internal::gen_helpers::EqualsField(needs_redraw_, other.needs_redraw_)
   && ::protozero::internal::gen_helpers::EqualsField(needs_prepare_tiles_, other.needs_prepare_tiles_)
   && ::protozero::internal::gen_helpers::EqualsField(needs_begin_main_frame_, other.needs_begin_main_frame_)
   && ::protozero::internal::gen_helpers::EqualsField(needs_one_begin_impl_frame_, other.needs_one_begin_impl_frame_)
   && ::protozero::internal::gen_helpers::EqualsField(visible_, other.visible_)
   && ::protozero::internal::gen_helpers::EqualsField(begin_frame_source_paused_, other.begin_frame_source_paused_)
   && ::protozero::internal::gen_helpers::EqualsField(can_draw_, other.can_draw_)
   && ::protozero::internal::gen_helpers::EqualsField(resourceless_draw_, other.resourceless_draw_)
   && ::protozero::internal::gen_helpers::EqualsField(has_pending_tree_, other.has_pending_tree_)
   && ::protozero::internal::gen_helpers::EqualsField(pending_tree_is_ready_for_activation_, other.pending_tree_is_ready_for_activation_)
   && ::protozero::internal::gen_helpers::EqualsField(active_tree_needs_first_draw_, other.active_tree_needs_first_draw_)
   && ::protozero::internal::gen_helpers::EqualsField(active_tree_is_ready_to_draw_, other.active_tree_is_ready_to_draw_)
   && ::protozero::internal::gen_helpers::EqualsField(did_create_and_initialize_first_layer_tree_frame_sink_, other.did_create_and_initialize_first_layer_tree_frame_sink_)
   && ::protozero::internal::gen_helpers::EqualsField(tree_priority_, other.tree_priority_)
   && ::protozero::internal::gen_helpers::EqualsField(scroll_handler_state_, other.scroll_handler_state_)
   && ::protozero::internal::gen_helpers::EqualsField(critical_begin_main_frame_to_activate_is_fast_, other.critical_begin_main_frame_to_activate_is_fast_)
   && ::protozero::internal::gen_helpers::EqualsField(main_thread_missed_last_deadline_, other.main_thread_missed_last_deadline_)
   && ::protozero::internal::gen_helpers::EqualsField(video_needs_begin_frames_, other.video_needs_begin_frames_)
   && ::protozero::internal::gen_helpers::EqualsField(defer_begin_main_frame_, other.defer_begin_main_frame_)
   && ::protozero::internal::gen_helpers::EqualsField(last_commit_had_no_updates_, other.last_commit_had_no_updates_)
   && ::protozero::internal::gen_helpers::EqualsField(did_draw_in_last_frame_, other.did_draw_in_last_frame_)
   && ::protozero::internal::gen_helpers::EqualsField(did_submit_in_last_frame_, other.did_submit_in_last_frame_)
   && ::protozero::internal::gen_helpers::EqualsField(needs_impl_side_invalidation_, other.needs_impl_side_invalidation_)
   && ::protozero::internal::gen_helpers::EqualsField(current_pending_tree_is_impl_side_, other.current_pending_tree_is_impl_side_)
   && ::protozero::internal::gen_helpers::EqualsField(previous_pending_tree_was_impl_side_, other.previous_pending_tree_was_impl_side_)
   && ::protozero::internal::gen_helpers::EqualsField(processing_animation_worklets_for_active_tree_, other.processing_animation_worklets_for_active_tree_)
   && ::protozero::internal::gen_helpers::EqualsField(processing_animation_worklets_for_pending_tree_, other.processing_animation_worklets_for_pending_tree_)
   && ::protozero::internal::gen_helpers::EqualsField(processing_paint_worklets_for_pending_tree_, other.processing_paint_worklets_for_pending_tree_);
}

bool ChromeCompositorStateMachine_MinorState::ParseFromArray(const void* raw, size_t size) {
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* commit_count */:
        field.get(&commit_count_);
        break;
      case 2 /* current_frame_number */:
        field.get(&current_frame_number_);
        break;
      case 3 /* last_frame_number_submit_performed */:
        field.get(&last_frame_number_submit_performed_);
        break;
      case 4 /* last_frame_number_draw_performed */:
        field.get(&last_frame_number_draw_performed_);
        break;
      case 5 /* last_frame_number_begin_main_frame_sent */:
        field.get(&last_frame_number_begin_main_frame_sent_);
        break;
      case 6 /* did_draw */:
        field.get(&did_draw_);
        break;
      case 7 /* did_send_begin_main_frame_for_current_frame */:
        field.get(&did_send_begin_main_frame_for_current_frame_);
        break;
      case 8 /* did_notify_begin_main_frame_not_expected_until */:
        field.get(&did_notify_begin_main_frame_not_expected_until_);
        break;
      case 9 /* did_notify_begin_main_frame_not_expected_soon */:
        field.get(&did_notify_begin_main_frame_not_expected_soon_);
        break;
      case 10 /* wants_begin_main_frame_not_expected */:
        field.get(&wants_begin_main_frame_not_expected_);
        break;
      case 11 /* did_commit_during_frame */:
        field.get(&did_commit_during_frame_);
        break;
      case 12 /* did_invalidate_layer_tree_frame_sink */:
        field.get(&did_invalidate_layer_tree_frame_sink_);
        break;
      case 13 /* did_perform_impl_side_invalidaion */:
        field.get(&did_perform_impl_side_invalidaion_);
        break;
      case 14 /* did_prepare_tiles */:
        field.get(&did_prepare_tiles_);
        break;
      case 15 /* consecutive_checkerboard_animations */:
        field.get(&consecutive_checkerboard_animations_);
        break;
      case 16 /* pending_submit_frames */:
        field.get(&pending_submit_frames_);
        break;
      case 17 /* submit_frames_with_current_layer_tree_frame_sink */:
        field.get(&submit_frames_with_current_layer_tree_frame_sink_);
        break;
      case 18 /* needs_redraw */:
        field.get(&needs_redraw_);
        break;
      case 19 /* needs_prepare_tiles */:
        field.get(&needs_prepare_tiles_);
        break;
      case 20 /* needs_begin_main_frame */:
        field.get(&needs_begin_main_frame_);
        break;
      case 21 /* needs_one_begin_impl_frame */:
        field.get(&needs_one_begin_impl_frame_);
        break;
      case 22 /* visible */:
        field.get(&visible_);
        break;
      case 23 /* begin_frame_source_paused */:
        field.get(&begin_frame_source_paused_);
        break;
      case 24 /* can_draw */:
        field.get(&can_draw_);
        break;
      case 25 /* resourceless_draw */:
        field.get(&resourceless_draw_);
        break;
      case 26 /* has_pending_tree */:
        field.get(&has_pending_tree_);
        break;
      case 27 /* pending_tree_is_ready_for_activation */:
        field.get(&pending_tree_is_ready_for_activation_);
        break;
      case 28 /* active_tree_needs_first_draw */:
        field.get(&active_tree_needs_first_draw_);
        break;
      case 29 /* active_tree_is_ready_to_draw */:
        field.get(&active_tree_is_ready_to_draw_);
        break;
      case 30 /* did_create_and_initialize_first_layer_tree_frame_sink */:
        field.get(&did_create_and_initialize_first_layer_tree_frame_sink_);
        break;
      case 31 /* tree_priority */:
        field.get(&tree_priority_);
        break;
      case 32 /* scroll_handler_state */:
        field.get(&scroll_handler_state_);
        break;
      case 33 /* critical_begin_main_frame_to_activate_is_fast */:
        field.get(&critical_begin_main_frame_to_activate_is_fast_);
        break;
      case 34 /* main_thread_missed_last_deadline */:
        field.get(&main_thread_missed_last_deadline_);
        break;
      case 36 /* video_needs_begin_frames */:
        field.get(&video_needs_begin_frames_);
        break;
      case 37 /* defer_begin_main_frame */:
        field.get(&defer_begin_main_frame_);
        break;
      case 38 /* last_commit_had_no_updates */:
        field.get(&last_commit_had_no_updates_);
        break;
      case 39 /* did_draw_in_last_frame */:
        field.get(&did_draw_in_last_frame_);
        break;
      case 40 /* did_submit_in_last_frame */:
        field.get(&did_submit_in_last_frame_);
        break;
      case 41 /* needs_impl_side_invalidation */:
        field.get(&needs_impl_side_invalidation_);
        break;
      case 42 /* current_pending_tree_is_impl_side */:
        field.get(&current_pending_tree_is_impl_side_);
        break;
      case 43 /* previous_pending_tree_was_impl_side */:
        field.get(&previous_pending_tree_was_impl_side_);
        break;
      case 44 /* processing_animation_worklets_for_active_tree */:
        field.get(&processing_animation_worklets_for_active_tree_);
        break;
      case 45 /* processing_animation_worklets_for_pending_tree */:
        field.get(&processing_animation_worklets_for_pending_tree_);
        break;
      case 46 /* processing_paint_worklets_for_pending_tree */:
        field.get(&processing_paint_worklets_for_pending_tree_);
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string ChromeCompositorStateMachine_MinorState::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> ChromeCompositorStateMachine_MinorState::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void ChromeCompositorStateMachine_MinorState::Serialize(::protozero::Message* msg) const {
  // Field 1: commit_count
  if (_has_field_[1]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(1, commit_count_, msg);
  }

  // Field 2: current_frame_number
  if (_has_field_[2]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(2, current_frame_number_, msg);
  }

  // Field 3: last_frame_number_submit_performed
  if (_has_field_[3]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(3, last_frame_number_submit_performed_, msg);
  }

  // Field 4: last_frame_number_draw_performed
  if (_has_field_[4]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(4, last_frame_number_draw_performed_, msg);
  }

  // Field 5: last_frame_number_begin_main_frame_sent
  if (_has_field_[5]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(5, last_frame_number_begin_main_frame_sent_, msg);
  }

  // Field 6: did_draw
  if (_has_field_[6]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(6, did_draw_, msg);
  }

  // Field 7: did_send_begin_main_frame_for_current_frame
  if (_has_field_[7]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(7, did_send_begin_main_frame_for_current_frame_, msg);
  }

  // Field 8: did_notify_begin_main_frame_not_expected_until
  if (_has_field_[8]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(8, did_notify_begin_main_frame_not_expected_until_, msg);
  }

  // Field 9: did_notify_begin_main_frame_not_expected_soon
  if (_has_field_[9]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(9, did_notify_begin_main_frame_not_expected_soon_, msg);
  }

  // Field 10: wants_begin_main_frame_not_expected
  if (_has_field_[10]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(10, wants_begin_main_frame_not_expected_, msg);
  }

  // Field 11: did_commit_during_frame
  if (_has_field_[11]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(11, did_commit_during_frame_, msg);
  }

  // Field 12: did_invalidate_layer_tree_frame_sink
  if (_has_field_[12]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(12, did_invalidate_layer_tree_frame_sink_, msg);
  }

  // Field 13: did_perform_impl_side_invalidaion
  if (_has_field_[13]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(13, did_perform_impl_side_invalidaion_, msg);
  }

  // Field 14: did_prepare_tiles
  if (_has_field_[14]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(14, did_prepare_tiles_, msg);
  }

  // Field 15: consecutive_checkerboard_animations
  if (_has_field_[15]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(15, consecutive_checkerboard_animations_, msg);
  }

  // Field 16: pending_submit_frames
  if (_has_field_[16]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(16, pending_submit_frames_, msg);
  }

  // Field 17: submit_frames_with_current_layer_tree_frame_sink
  if (_has_field_[17]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(17, submit_frames_with_current_layer_tree_frame_sink_, msg);
  }

  // Field 18: needs_redraw
  if (_has_field_[18]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(18, needs_redraw_, msg);
  }

  // Field 19: needs_prepare_tiles
  if (_has_field_[19]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(19, needs_prepare_tiles_, msg);
  }

  // Field 20: needs_begin_main_frame
  if (_has_field_[20]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(20, needs_begin_main_frame_, msg);
  }

  // Field 21: needs_one_begin_impl_frame
  if (_has_field_[21]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(21, needs_one_begin_impl_frame_, msg);
  }

  // Field 22: visible
  if (_has_field_[22]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(22, visible_, msg);
  }

  // Field 23: begin_frame_source_paused
  if (_has_field_[23]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(23, begin_frame_source_paused_, msg);
  }

  // Field 24: can_draw
  if (_has_field_[24]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(24, can_draw_, msg);
  }

  // Field 25: resourceless_draw
  if (_has_field_[25]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(25, resourceless_draw_, msg);
  }

  // Field 26: has_pending_tree
  if (_has_field_[26]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(26, has_pending_tree_, msg);
  }

  // Field 27: pending_tree_is_ready_for_activation
  if (_has_field_[27]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(27, pending_tree_is_ready_for_activation_, msg);
  }

  // Field 28: active_tree_needs_first_draw
  if (_has_field_[28]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(28, active_tree_needs_first_draw_, msg);
  }

  // Field 29: active_tree_is_ready_to_draw
  if (_has_field_[29]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(29, active_tree_is_ready_to_draw_, msg);
  }

  // Field 30: did_create_and_initialize_first_layer_tree_frame_sink
  if (_has_field_[30]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(30, did_create_and_initialize_first_layer_tree_frame_sink_, msg);
  }

  // Field 31: tree_priority
  if (_has_field_[31]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(31, tree_priority_, msg);
  }

  // Field 32: scroll_handler_state
  if (_has_field_[32]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(32, scroll_handler_state_, msg);
  }

  // Field 33: critical_begin_main_frame_to_activate_is_fast
  if (_has_field_[33]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(33, critical_begin_main_frame_to_activate_is_fast_, msg);
  }

  // Field 34: main_thread_missed_last_deadline
  if (_has_field_[34]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(34, main_thread_missed_last_deadline_, msg);
  }

  // Field 36: video_needs_begin_frames
  if (_has_field_[36]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(36, video_needs_begin_frames_, msg);
  }

  // Field 37: defer_begin_main_frame
  if (_has_field_[37]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(37, defer_begin_main_frame_, msg);
  }

  // Field 38: last_commit_had_no_updates
  if (_has_field_[38]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(38, last_commit_had_no_updates_, msg);
  }

  // Field 39: did_draw_in_last_frame
  if (_has_field_[39]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(39, did_draw_in_last_frame_, msg);
  }

  // Field 40: did_submit_in_last_frame
  if (_has_field_[40]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(40, did_submit_in_last_frame_, msg);
  }

  // Field 41: needs_impl_side_invalidation
  if (_has_field_[41]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(41, needs_impl_side_invalidation_, msg);
  }

  // Field 42: current_pending_tree_is_impl_side
  if (_has_field_[42]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(42, current_pending_tree_is_impl_side_, msg);
  }

  // Field 43: previous_pending_tree_was_impl_side
  if (_has_field_[43]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(43, previous_pending_tree_was_impl_side_, msg);
  }

  // Field 44: processing_animation_worklets_for_active_tree
  if (_has_field_[44]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(44, processing_animation_worklets_for_active_tree_, msg);
  }

  // Field 45: processing_animation_worklets_for_pending_tree
  if (_has_field_[45]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(45, processing_animation_worklets_for_pending_tree_, msg);
  }

  // Field 46: processing_paint_worklets_for_pending_tree
  if (_has_field_[46]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(46, processing_paint_worklets_for_pending_tree_, msg);
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}


ChromeCompositorStateMachine_MajorState::ChromeCompositorStateMachine_MajorState() = default;
ChromeCompositorStateMachine_MajorState::~ChromeCompositorStateMachine_MajorState() = default;
ChromeCompositorStateMachine_MajorState::ChromeCompositorStateMachine_MajorState(const ChromeCompositorStateMachine_MajorState&) = default;
ChromeCompositorStateMachine_MajorState& ChromeCompositorStateMachine_MajorState::operator=(const ChromeCompositorStateMachine_MajorState&) = default;
ChromeCompositorStateMachine_MajorState::ChromeCompositorStateMachine_MajorState(ChromeCompositorStateMachine_MajorState&&) noexcept = default;
ChromeCompositorStateMachine_MajorState& ChromeCompositorStateMachine_MajorState::operator=(ChromeCompositorStateMachine_MajorState&&) = default;

bool ChromeCompositorStateMachine_MajorState::operator==(const ChromeCompositorStateMachine_MajorState& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(next_action_, other.next_action_)
   && ::protozero::internal::gen_helpers::EqualsField(begin_impl_frame_state_, other.begin_impl_frame_state_)
   && ::protozero::internal::gen_helpers::EqualsField(begin_main_frame_state_, other.begin_main_frame_state_)
   && ::protozero::internal::gen_helpers::EqualsField(layer_tree_frame_sink_state_, other.layer_tree_frame_sink_state_)
   && ::protozero::internal::gen_helpers::EqualsField(forced_redraw_state_, other.forced_redraw_state_);
}

bool ChromeCompositorStateMachine_MajorState::ParseFromArray(const void* raw, size_t size) {
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* next_action */:
        field.get(&next_action_);
        break;
      case 2 /* begin_impl_frame_state */:
        field.get(&begin_impl_frame_state_);
        break;
      case 3 /* begin_main_frame_state */:
        field.get(&begin_main_frame_state_);
        break;
      case 4 /* layer_tree_frame_sink_state */:
        field.get(&layer_tree_frame_sink_state_);
        break;
      case 5 /* forced_redraw_state */:
        field.get(&forced_redraw_state_);
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string ChromeCompositorStateMachine_MajorState::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> ChromeCompositorStateMachine_MajorState::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void ChromeCompositorStateMachine_MajorState::Serialize(::protozero::Message* msg) const {
  // Field 1: next_action
  if (_has_field_[1]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(1, next_action_, msg);
  }

  // Field 2: begin_impl_frame_state
  if (_has_field_[2]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(2, begin_impl_frame_state_, msg);
  }

  // Field 3: begin_main_frame_state
  if (_has_field_[3]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(3, begin_main_frame_state_, msg);
  }

  // Field 4: layer_tree_frame_sink_state
  if (_has_field_[4]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(4, layer_tree_frame_sink_state_, msg);
  }

  // Field 5: forced_redraw_state
  if (_has_field_[5]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(5, forced_redraw_state_, msg);
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}


ChromeCompositorSchedulerState::ChromeCompositorSchedulerState() = default;
ChromeCompositorSchedulerState::~ChromeCompositorSchedulerState() = default;
ChromeCompositorSchedulerState::ChromeCompositorSchedulerState(const ChromeCompositorSchedulerState&) = default;
ChromeCompositorSchedulerState& ChromeCompositorSchedulerState::operator=(const ChromeCompositorSchedulerState&) = default;
ChromeCompositorSchedulerState::ChromeCompositorSchedulerState(ChromeCompositorSchedulerState&&) noexcept = default;
ChromeCompositorSchedulerState& ChromeCompositorSchedulerState::operator=(ChromeCompositorSchedulerState&&) = default;

bool ChromeCompositorSchedulerState::operator==(const ChromeCompositorSchedulerState& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(state_machine_, other.state_machine_)
   && ::protozero::internal::gen_helpers::EqualsField(observing_begin_frame_source_, other.observing_begin_frame_source_)
   && ::protozero::internal::gen_helpers::EqualsField(begin_impl_frame_deadline_task_, other.begin_impl_frame_deadline_task_)
   && ::protozero::internal::gen_helpers::EqualsField(pending_begin_frame_task_, other.pending_begin_frame_task_)
   && ::protozero::internal::gen_helpers::EqualsField(skipped_last_frame_missed_exceeded_deadline_, other.skipped_last_frame_missed_exceeded_deadline_)
   && ::protozero::internal::gen_helpers::EqualsField(inside_action_, other.inside_action_)
   && ::protozero::internal::gen_helpers::EqualsField(deadline_mode_, other.deadline_mode_)
   && ::protozero::internal::gen_helpers::EqualsField(deadline_us_, other.deadline_us_)
   && ::protozero::internal::gen_helpers::EqualsField(deadline_scheduled_at_us_, other.deadline_scheduled_at_us_)
   && ::protozero::internal::gen_helpers::EqualsField(now_us_, other.now_us_)
   && ::protozero::internal::gen_helpers::EqualsField(now_to_deadline_delta_us_, other.now_to_deadline_delta_us_)
   && ::protozero::internal::gen_helpers::EqualsField(now_to_deadline_scheduled_at_delta_us_, other.now_to_deadline_scheduled_at_delta_us_)
   && ::protozero::internal::gen_helpers::EqualsField(begin_impl_frame_args_, other.begin_impl_frame_args_)
   && ::protozero::internal::gen_helpers::EqualsField(begin_frame_observer_state_, other.begin_frame_observer_state_)
   && ::protozero::internal::gen_helpers::EqualsField(begin_frame_source_state_, other.begin_frame_source_state_)
   && ::protozero::internal::gen_helpers::EqualsField(compositor_timing_history_, other.compositor_timing_history_);
}

bool ChromeCompositorSchedulerState::ParseFromArray(const void* raw, size_t size) {
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* state_machine */:
        (*state_machine_).ParseFromArray(field.data(), field.size());
        break;
      case 2 /* observing_begin_frame_source */:
        field.get(&observing_begin_frame_source_);
        break;
      case 3 /* begin_impl_frame_deadline_task */:
        field.get(&begin_impl_frame_deadline_task_);
        break;
      case 4 /* pending_begin_frame_task */:
        field.get(&pending_begin_frame_task_);
        break;
      case 5 /* skipped_last_frame_missed_exceeded_deadline */:
        field.get(&skipped_last_frame_missed_exceeded_deadline_);
        break;
      case 7 /* inside_action */:
        field.get(&inside_action_);
        break;
      case 8 /* deadline_mode */:
        field.get(&deadline_mode_);
        break;
      case 9 /* deadline_us */:
        field.get(&deadline_us_);
        break;
      case 10 /* deadline_scheduled_at_us */:
        field.get(&deadline_scheduled_at_us_);
        break;
      case 11 /* now_us */:
        field.get(&now_us_);
        break;
      case 12 /* now_to_deadline_delta_us */:
        field.get(&now_to_deadline_delta_us_);
        break;
      case 13 /* now_to_deadline_scheduled_at_delta_us */:
        field.get(&now_to_deadline_scheduled_at_delta_us_);
        break;
      case 14 /* begin_impl_frame_args */:
        (*begin_impl_frame_args_).ParseFromArray(field.data(), field.size());
        break;
      case 15 /* begin_frame_observer_state */:
        (*begin_frame_observer_state_).ParseFromArray(field.data(), field.size());
        break;
      case 16 /* begin_frame_source_state */:
        (*begin_frame_source_state_).ParseFromArray(field.data(), field.size());
        break;
      case 17 /* compositor_timing_history */:
        (*compositor_timing_history_).ParseFromArray(field.data(), field.size());
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string ChromeCompositorSchedulerState::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> ChromeCompositorSchedulerState::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void ChromeCompositorSchedulerState::Serialize(::protozero::Message* msg) const {
  // Field 1: state_machine
  if (_has_field_[1]) {
    (*state_machine_).Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
  }

  // Field 2: observing_begin_frame_source
  if (_has_field_[2]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(2, observing_begin_frame_source_, msg);
  }

  // Field 3: begin_impl_frame_deadline_task
  if (_has_field_[3]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(3, begin_impl_frame_deadline_task_, msg);
  }

  // Field 4: pending_begin_frame_task
  if (_has_field_[4]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(4, pending_begin_frame_task_, msg);
  }

  // Field 5: skipped_last_frame_missed_exceeded_deadline
  if (_has_field_[5]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(5, skipped_last_frame_missed_exceeded_deadline_, msg);
  }

  // Field 7: inside_action
  if (_has_field_[7]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(7, inside_action_, msg);
  }

  // Field 8: deadline_mode
  if (_has_field_[8]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(8, deadline_mode_, msg);
  }

  // Field 9: deadline_us
  if (_has_field_[9]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(9, deadline_us_, msg);
  }

  // Field 10: deadline_scheduled_at_us
  if (_has_field_[10]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(10, deadline_scheduled_at_us_, msg);
  }

  // Field 11: now_us
  if (_has_field_[11]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(11, now_us_, msg);
  }

  // Field 12: now_to_deadline_delta_us
  if (_has_field_[12]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(12, now_to_deadline_delta_us_, msg);
  }

  // Field 13: now_to_deadline_scheduled_at_delta_us
  if (_has_field_[13]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(13, now_to_deadline_scheduled_at_delta_us_, msg);
  }

  // Field 14: begin_impl_frame_args
  if (_has_field_[14]) {
    (*begin_impl_frame_args_).Serialize(msg->BeginNestedMessage<::protozero::Message>(14));
  }

  // Field 15: begin_frame_observer_state
  if (_has_field_[15]) {
    (*begin_frame_observer_state_).Serialize(msg->BeginNestedMessage<::protozero::Message>(15));
  }

  // Field 16: begin_frame_source_state
  if (_has_field_[16]) {
    (*begin_frame_source_state_).Serialize(msg->BeginNestedMessage<::protozero::Message>(16));
  }

  // Field 17: compositor_timing_history
  if (_has_field_[17]) {
    (*compositor_timing_history_).Serialize(msg->BeginNestedMessage<::protozero::Message>(17));
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}

}  // namespace perfetto
}  // namespace protos
}  // namespace gen
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic pop
#endif
// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_content_settings_event_info.gen.cc
// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wfloat-equal"
#endif
// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_content_settings_event_info.gen.h"

namespace perfetto {
namespace protos {
namespace gen {

ChromeContentSettingsEventInfo::ChromeContentSettingsEventInfo() = default;
ChromeContentSettingsEventInfo::~ChromeContentSettingsEventInfo() = default;
ChromeContentSettingsEventInfo::ChromeContentSettingsEventInfo(const ChromeContentSettingsEventInfo&) = default;
ChromeContentSettingsEventInfo& ChromeContentSettingsEventInfo::operator=(const ChromeContentSettingsEventInfo&) = default;
ChromeContentSettingsEventInfo::ChromeContentSettingsEventInfo(ChromeContentSettingsEventInfo&&) noexcept = default;
ChromeContentSettingsEventInfo& ChromeContentSettingsEventInfo::operator=(ChromeContentSettingsEventInfo&&) = default;

bool ChromeContentSettingsEventInfo::operator==(const ChromeContentSettingsEventInfo& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(number_of_exceptions_, other.number_of_exceptions_);
}

bool ChromeContentSettingsEventInfo::ParseFromArray(const void* raw, size_t size) {
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* number_of_exceptions */:
        field.get(&number_of_exceptions_);
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string ChromeContentSettingsEventInfo::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> ChromeContentSettingsEventInfo::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void ChromeContentSettingsEventInfo::Serialize(::protozero::Message* msg) const {
  // Field 1: number_of_exceptions
  if (_has_field_[1]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(1, number_of_exceptions_, msg);
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}

}  // namespace perfetto
}  // namespace protos
}  // namespace gen
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic pop
#endif
// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_frame_reporter.gen.cc
// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wfloat-equal"
#endif
// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_frame_reporter.gen.h"

namespace perfetto {
namespace protos {
namespace gen {

ChromeFrameReporter::ChromeFrameReporter() = default;
ChromeFrameReporter::~ChromeFrameReporter() = default;
ChromeFrameReporter::ChromeFrameReporter(const ChromeFrameReporter&) = default;
ChromeFrameReporter& ChromeFrameReporter::operator=(const ChromeFrameReporter&) = default;
ChromeFrameReporter::ChromeFrameReporter(ChromeFrameReporter&&) noexcept = default;
ChromeFrameReporter& ChromeFrameReporter::operator=(ChromeFrameReporter&&) = default;

bool ChromeFrameReporter::operator==(const ChromeFrameReporter& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(state_, other.state_)
   && ::protozero::internal::gen_helpers::EqualsField(reason_, other.reason_)
   && ::protozero::internal::gen_helpers::EqualsField(frame_source_, other.frame_source_)
   && ::protozero::internal::gen_helpers::EqualsField(frame_sequence_, other.frame_sequence_)
   && ::protozero::internal::gen_helpers::EqualsField(affects_smoothness_, other.affects_smoothness_)
   && ::protozero::internal::gen_helpers::EqualsField(scroll_state_, other.scroll_state_)
   && ::protozero::internal::gen_helpers::EqualsField(has_main_animation_, other.has_main_animation_)
   && ::protozero::internal::gen_helpers::EqualsField(has_compositor_animation_, other.has_compositor_animation_)
   && ::protozero::internal::gen_helpers::EqualsField(has_smooth_input_main_, other.has_smooth_input_main_)
   && ::protozero::internal::gen_helpers::EqualsField(has_missing_content_, other.has_missing_content_)
   && ::protozero::internal::gen_helpers::EqualsField(layer_tree_host_id_, other.layer_tree_host_id_)
   && ::protozero::internal::gen_helpers::EqualsField(has_high_latency_, other.has_high_latency_)
   && ::protozero::internal::gen_helpers::EqualsField(frame_type_, other.frame_type_)
   && ::protozero::internal::gen_helpers::EqualsField(high_latency_contribution_stage_, other.high_latency_contribution_stage_);
}

bool ChromeFrameReporter::ParseFromArray(const void* raw, size_t size) {
  high_latency_contribution_stage_.clear();
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* state */:
        field.get(&state_);
        break;
      case 2 /* reason */:
        field.get(&reason_);
        break;
      case 3 /* frame_source */:
        field.get(&frame_source_);
        break;
      case 4 /* frame_sequence */:
        field.get(&frame_sequence_);
        break;
      case 5 /* affects_smoothness */:
        field.get(&affects_smoothness_);
        break;
      case 6 /* scroll_state */:
        field.get(&scroll_state_);
        break;
      case 7 /* has_main_animation */:
        field.get(&has_main_animation_);
        break;
      case 8 /* has_compositor_animation */:
        field.get(&has_compositor_animation_);
        break;
      case 9 /* has_smooth_input_main */:
        field.get(&has_smooth_input_main_);
        break;
      case 10 /* has_missing_content */:
        field.get(&has_missing_content_);
        break;
      case 11 /* layer_tree_host_id */:
        field.get(&layer_tree_host_id_);
        break;
      case 12 /* has_high_latency */:
        field.get(&has_high_latency_);
        break;
      case 13 /* frame_type */:
        field.get(&frame_type_);
        break;
      case 14 /* high_latency_contribution_stage */:
        high_latency_contribution_stage_.emplace_back();
        ::protozero::internal::gen_helpers::DeserializeString(field, &high_latency_contribution_stage_.back());
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string ChromeFrameReporter::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> ChromeFrameReporter::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void ChromeFrameReporter::Serialize(::protozero::Message* msg) const {
  // Field 1: state
  if (_has_field_[1]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(1, state_, msg);
  }

  // Field 2: reason
  if (_has_field_[2]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(2, reason_, msg);
  }

  // Field 3: frame_source
  if (_has_field_[3]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(3, frame_source_, msg);
  }

  // Field 4: frame_sequence
  if (_has_field_[4]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(4, frame_sequence_, msg);
  }

  // Field 5: affects_smoothness
  if (_has_field_[5]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(5, affects_smoothness_, msg);
  }

  // Field 6: scroll_state
  if (_has_field_[6]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(6, scroll_state_, msg);
  }

  // Field 7: has_main_animation
  if (_has_field_[7]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(7, has_main_animation_, msg);
  }

  // Field 8: has_compositor_animation
  if (_has_field_[8]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(8, has_compositor_animation_, msg);
  }

  // Field 9: has_smooth_input_main
  if (_has_field_[9]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(9, has_smooth_input_main_, msg);
  }

  // Field 10: has_missing_content
  if (_has_field_[10]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(10, has_missing_content_, msg);
  }

  // Field 11: layer_tree_host_id
  if (_has_field_[11]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(11, layer_tree_host_id_, msg);
  }

  // Field 12: has_high_latency
  if (_has_field_[12]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(12, has_high_latency_, msg);
  }

  // Field 13: frame_type
  if (_has_field_[13]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(13, frame_type_, msg);
  }

  // Field 14: high_latency_contribution_stage
  for (auto& it : high_latency_contribution_stage_) {
    ::protozero::internal::gen_helpers::SerializeString(14, it, msg);
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}

}  // namespace perfetto
}  // namespace protos
}  // namespace gen
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic pop
#endif
// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_histogram_sample.gen.cc
// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wfloat-equal"
#endif
// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_histogram_sample.gen.h"

namespace perfetto {
namespace protos {
namespace gen {

ChromeHistogramSample::ChromeHistogramSample() = default;
ChromeHistogramSample::~ChromeHistogramSample() = default;
ChromeHistogramSample::ChromeHistogramSample(const ChromeHistogramSample&) = default;
ChromeHistogramSample& ChromeHistogramSample::operator=(const ChromeHistogramSample&) = default;
ChromeHistogramSample::ChromeHistogramSample(ChromeHistogramSample&&) noexcept = default;
ChromeHistogramSample& ChromeHistogramSample::operator=(ChromeHistogramSample&&) = default;

bool ChromeHistogramSample::operator==(const ChromeHistogramSample& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(name_hash_, other.name_hash_)
   && ::protozero::internal::gen_helpers::EqualsField(name_, other.name_)
   && ::protozero::internal::gen_helpers::EqualsField(sample_, other.sample_)
   && ::protozero::internal::gen_helpers::EqualsField(name_iid_, other.name_iid_);
}

bool ChromeHistogramSample::ParseFromArray(const void* raw, size_t size) {
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* name_hash */:
        field.get(&name_hash_);
        break;
      case 2 /* name */:
        ::protozero::internal::gen_helpers::DeserializeString(field, &name_);
        break;
      case 3 /* sample */:
        field.get(&sample_);
        break;
      case 4 /* name_iid */:
        field.get(&name_iid_);
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string ChromeHistogramSample::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> ChromeHistogramSample::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void ChromeHistogramSample::Serialize(::protozero::Message* msg) const {
  // Field 1: name_hash
  if (_has_field_[1]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(1, name_hash_, msg);
  }

  // Field 2: name
  if (_has_field_[2]) {
    ::protozero::internal::gen_helpers::SerializeString(2, name_, msg);
  }

  // Field 3: sample
  if (_has_field_[3]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(3, sample_, msg);
  }

  // Field 4: name_iid
  if (_has_field_[4]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(4, name_iid_, msg);
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}


HistogramName::HistogramName() = default;
HistogramName::~HistogramName() = default;
HistogramName::HistogramName(const HistogramName&) = default;
HistogramName& HistogramName::operator=(const HistogramName&) = default;
HistogramName::HistogramName(HistogramName&&) noexcept = default;
HistogramName& HistogramName::operator=(HistogramName&&) = default;

bool HistogramName::operator==(const HistogramName& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(iid_, other.iid_)
   && ::protozero::internal::gen_helpers::EqualsField(name_, other.name_);
}

bool HistogramName::ParseFromArray(const void* raw, size_t size) {
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* iid */:
        field.get(&iid_);
        break;
      case 2 /* name */:
        ::protozero::internal::gen_helpers::DeserializeString(field, &name_);
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string HistogramName::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> HistogramName::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void HistogramName::Serialize(::protozero::Message* msg) const {
  // Field 1: iid
  if (_has_field_[1]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(1, iid_, msg);
  }

  // Field 2: name
  if (_has_field_[2]) {
    ::protozero::internal::gen_helpers::SerializeString(2, name_, msg);
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}

}  // namespace perfetto
}  // namespace protos
}  // namespace gen
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic pop
#endif
// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_keyed_service.gen.cc
// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wfloat-equal"
#endif
// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_keyed_service.gen.h"

namespace perfetto {
namespace protos {
namespace gen {

ChromeKeyedService::ChromeKeyedService() = default;
ChromeKeyedService::~ChromeKeyedService() = default;
ChromeKeyedService::ChromeKeyedService(const ChromeKeyedService&) = default;
ChromeKeyedService& ChromeKeyedService::operator=(const ChromeKeyedService&) = default;
ChromeKeyedService::ChromeKeyedService(ChromeKeyedService&&) noexcept = default;
ChromeKeyedService& ChromeKeyedService::operator=(ChromeKeyedService&&) = default;

bool ChromeKeyedService::operator==(const ChromeKeyedService& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(name_, other.name_);
}

bool ChromeKeyedService::ParseFromArray(const void* raw, size_t size) {
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* name */:
        ::protozero::internal::gen_helpers::DeserializeString(field, &name_);
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string ChromeKeyedService::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> ChromeKeyedService::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void ChromeKeyedService::Serialize(::protozero::Message* msg) const {
  // Field 1: name
  if (_has_field_[1]) {
    ::protozero::internal::gen_helpers::SerializeString(1, name_, msg);
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}

}  // namespace perfetto
}  // namespace protos
}  // namespace gen
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic pop
#endif
// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_latency_info.gen.cc
// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wfloat-equal"
#endif
// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_latency_info.gen.h"

namespace perfetto {
namespace protos {
namespace gen {

ChromeLatencyInfo::ChromeLatencyInfo() = default;
ChromeLatencyInfo::~ChromeLatencyInfo() = default;
ChromeLatencyInfo::ChromeLatencyInfo(const ChromeLatencyInfo&) = default;
ChromeLatencyInfo& ChromeLatencyInfo::operator=(const ChromeLatencyInfo&) = default;
ChromeLatencyInfo::ChromeLatencyInfo(ChromeLatencyInfo&&) noexcept = default;
ChromeLatencyInfo& ChromeLatencyInfo::operator=(ChromeLatencyInfo&&) = default;

bool ChromeLatencyInfo::operator==(const ChromeLatencyInfo& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(trace_id_, other.trace_id_)
   && ::protozero::internal::gen_helpers::EqualsField(step_, other.step_)
   && ::protozero::internal::gen_helpers::EqualsField(frame_tree_node_id_, other.frame_tree_node_id_)
   && ::protozero::internal::gen_helpers::EqualsField(component_info_, other.component_info_)
   && ::protozero::internal::gen_helpers::EqualsField(is_coalesced_, other.is_coalesced_)
   && ::protozero::internal::gen_helpers::EqualsField(gesture_scroll_id_, other.gesture_scroll_id_)
   && ::protozero::internal::gen_helpers::EqualsField(touch_id_, other.touch_id_);
}

int ChromeLatencyInfo::component_info_size() const { return static_cast<int>(component_info_.size()); }
void ChromeLatencyInfo::clear_component_info() { component_info_.clear(); }
ChromeLatencyInfo_ComponentInfo* ChromeLatencyInfo::add_component_info() { component_info_.emplace_back(); return &component_info_.back(); }
bool ChromeLatencyInfo::ParseFromArray(const void* raw, size_t size) {
  component_info_.clear();
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* trace_id */:
        field.get(&trace_id_);
        break;
      case 2 /* step */:
        field.get(&step_);
        break;
      case 3 /* frame_tree_node_id */:
        field.get(&frame_tree_node_id_);
        break;
      case 4 /* component_info */:
        component_info_.emplace_back();
        component_info_.back().ParseFromArray(field.data(), field.size());
        break;
      case 5 /* is_coalesced */:
        field.get(&is_coalesced_);
        break;
      case 6 /* gesture_scroll_id */:
        field.get(&gesture_scroll_id_);
        break;
      case 7 /* touch_id */:
        field.get(&touch_id_);
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string ChromeLatencyInfo::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> ChromeLatencyInfo::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void ChromeLatencyInfo::Serialize(::protozero::Message* msg) const {
  // Field 1: trace_id
  if (_has_field_[1]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(1, trace_id_, msg);
  }

  // Field 2: step
  if (_has_field_[2]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(2, step_, msg);
  }

  // Field 3: frame_tree_node_id
  if (_has_field_[3]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(3, frame_tree_node_id_, msg);
  }

  // Field 4: component_info
  for (auto& it : component_info_) {
    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(4));
  }

  // Field 5: is_coalesced
  if (_has_field_[5]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(5, is_coalesced_, msg);
  }

  // Field 6: gesture_scroll_id
  if (_has_field_[6]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(6, gesture_scroll_id_, msg);
  }

  // Field 7: touch_id
  if (_has_field_[7]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(7, touch_id_, msg);
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}


ChromeLatencyInfo_ComponentInfo::ChromeLatencyInfo_ComponentInfo() = default;
ChromeLatencyInfo_ComponentInfo::~ChromeLatencyInfo_ComponentInfo() = default;
ChromeLatencyInfo_ComponentInfo::ChromeLatencyInfo_ComponentInfo(const ChromeLatencyInfo_ComponentInfo&) = default;
ChromeLatencyInfo_ComponentInfo& ChromeLatencyInfo_ComponentInfo::operator=(const ChromeLatencyInfo_ComponentInfo&) = default;
ChromeLatencyInfo_ComponentInfo::ChromeLatencyInfo_ComponentInfo(ChromeLatencyInfo_ComponentInfo&&) noexcept = default;
ChromeLatencyInfo_ComponentInfo& ChromeLatencyInfo_ComponentInfo::operator=(ChromeLatencyInfo_ComponentInfo&&) = default;

bool ChromeLatencyInfo_ComponentInfo::operator==(const ChromeLatencyInfo_ComponentInfo& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(component_type_, other.component_type_)
   && ::protozero::internal::gen_helpers::EqualsField(time_us_, other.time_us_);
}

bool ChromeLatencyInfo_ComponentInfo::ParseFromArray(const void* raw, size_t size) {
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* component_type */:
        field.get(&component_type_);
        break;
      case 2 /* time_us */:
        field.get(&time_us_);
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string ChromeLatencyInfo_ComponentInfo::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> ChromeLatencyInfo_ComponentInfo::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void ChromeLatencyInfo_ComponentInfo::Serialize(::protozero::Message* msg) const {
  // Field 1: component_type
  if (_has_field_[1]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(1, component_type_, msg);
  }

  // Field 2: time_us
  if (_has_field_[2]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(2, time_us_, msg);
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}

}  // namespace perfetto
}  // namespace protos
}  // namespace gen
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic pop
#endif
// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_legacy_ipc.gen.cc
// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wfloat-equal"
#endif
// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_legacy_ipc.gen.h"

namespace perfetto {
namespace protos {
namespace gen {

ChromeLegacyIpc::ChromeLegacyIpc() = default;
ChromeLegacyIpc::~ChromeLegacyIpc() = default;
ChromeLegacyIpc::ChromeLegacyIpc(const ChromeLegacyIpc&) = default;
ChromeLegacyIpc& ChromeLegacyIpc::operator=(const ChromeLegacyIpc&) = default;
ChromeLegacyIpc::ChromeLegacyIpc(ChromeLegacyIpc&&) noexcept = default;
ChromeLegacyIpc& ChromeLegacyIpc::operator=(ChromeLegacyIpc&&) = default;

bool ChromeLegacyIpc::operator==(const ChromeLegacyIpc& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(message_class_, other.message_class_)
   && ::protozero::internal::gen_helpers::EqualsField(message_line_, other.message_line_);
}

bool ChromeLegacyIpc::ParseFromArray(const void* raw, size_t size) {
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* message_class */:
        field.get(&message_class_);
        break;
      case 2 /* message_line */:
        field.get(&message_line_);
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string ChromeLegacyIpc::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> ChromeLegacyIpc::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void ChromeLegacyIpc::Serialize(::protozero::Message* msg) const {
  // Field 1: message_class
  if (_has_field_[1]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(1, message_class_, msg);
  }

  // Field 2: message_line
  if (_has_field_[2]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(2, message_line_, msg);
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}

}  // namespace perfetto
}  // namespace protos
}  // namespace gen
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic pop
#endif
// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_message_pump.gen.cc
// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wfloat-equal"
#endif
// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_message_pump.gen.h"

namespace perfetto {
namespace protos {
namespace gen {

ChromeMessagePump::ChromeMessagePump() = default;
ChromeMessagePump::~ChromeMessagePump() = default;
ChromeMessagePump::ChromeMessagePump(const ChromeMessagePump&) = default;
ChromeMessagePump& ChromeMessagePump::operator=(const ChromeMessagePump&) = default;
ChromeMessagePump::ChromeMessagePump(ChromeMessagePump&&) noexcept = default;
ChromeMessagePump& ChromeMessagePump::operator=(ChromeMessagePump&&) = default;

bool ChromeMessagePump::operator==(const ChromeMessagePump& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(sent_messages_in_queue_, other.sent_messages_in_queue_)
   && ::protozero::internal::gen_helpers::EqualsField(io_handler_location_iid_, other.io_handler_location_iid_);
}

bool ChromeMessagePump::ParseFromArray(const void* raw, size_t size) {
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* sent_messages_in_queue */:
        field.get(&sent_messages_in_queue_);
        break;
      case 2 /* io_handler_location_iid */:
        field.get(&io_handler_location_iid_);
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string ChromeMessagePump::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> ChromeMessagePump::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void ChromeMessagePump::Serialize(::protozero::Message* msg) const {
  // Field 1: sent_messages_in_queue
  if (_has_field_[1]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(1, sent_messages_in_queue_, msg);
  }

  // Field 2: io_handler_location_iid
  if (_has_field_[2]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(2, io_handler_location_iid_, msg);
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}

}  // namespace perfetto
}  // namespace protos
}  // namespace gen
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic pop
#endif
// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_mojo_event_info.gen.cc
// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wfloat-equal"
#endif
// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_mojo_event_info.gen.h"

namespace perfetto {
namespace protos {
namespace gen {

ChromeMojoEventInfo::ChromeMojoEventInfo() = default;
ChromeMojoEventInfo::~ChromeMojoEventInfo() = default;
ChromeMojoEventInfo::ChromeMojoEventInfo(const ChromeMojoEventInfo&) = default;
ChromeMojoEventInfo& ChromeMojoEventInfo::operator=(const ChromeMojoEventInfo&) = default;
ChromeMojoEventInfo::ChromeMojoEventInfo(ChromeMojoEventInfo&&) noexcept = default;
ChromeMojoEventInfo& ChromeMojoEventInfo::operator=(ChromeMojoEventInfo&&) = default;

bool ChromeMojoEventInfo::operator==(const ChromeMojoEventInfo& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(watcher_notify_interface_tag_, other.watcher_notify_interface_tag_)
   && ::protozero::internal::gen_helpers::EqualsField(ipc_hash_, other.ipc_hash_)
   && ::protozero::internal::gen_helpers::EqualsField(mojo_interface_tag_, other.mojo_interface_tag_)
   && ::protozero::internal::gen_helpers::EqualsField(mojo_interface_method_iid_, other.mojo_interface_method_iid_)
   && ::protozero::internal::gen_helpers::EqualsField(is_reply_, other.is_reply_)
   && ::protozero::internal::gen_helpers::EqualsField(payload_size_, other.payload_size_)
   && ::protozero::internal::gen_helpers::EqualsField(data_num_bytes_, other.data_num_bytes_);
}

bool ChromeMojoEventInfo::ParseFromArray(const void* raw, size_t size) {
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* watcher_notify_interface_tag */:
        ::protozero::internal::gen_helpers::DeserializeString(field, &watcher_notify_interface_tag_);
        break;
      case 2 /* ipc_hash */:
        field.get(&ipc_hash_);
        break;
      case 3 /* mojo_interface_tag */:
        ::protozero::internal::gen_helpers::DeserializeString(field, &mojo_interface_tag_);
        break;
      case 4 /* mojo_interface_method_iid */:
        field.get(&mojo_interface_method_iid_);
        break;
      case 5 /* is_reply */:
        field.get(&is_reply_);
        break;
      case 6 /* payload_size */:
        field.get(&payload_size_);
        break;
      case 7 /* data_num_bytes */:
        field.get(&data_num_bytes_);
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string ChromeMojoEventInfo::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> ChromeMojoEventInfo::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void ChromeMojoEventInfo::Serialize(::protozero::Message* msg) const {
  // Field 1: watcher_notify_interface_tag
  if (_has_field_[1]) {
    ::protozero::internal::gen_helpers::SerializeString(1, watcher_notify_interface_tag_, msg);
  }

  // Field 2: ipc_hash
  if (_has_field_[2]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(2, ipc_hash_, msg);
  }

  // Field 3: mojo_interface_tag
  if (_has_field_[3]) {
    ::protozero::internal::gen_helpers::SerializeString(3, mojo_interface_tag_, msg);
  }

  // Field 4: mojo_interface_method_iid
  if (_has_field_[4]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(4, mojo_interface_method_iid_, msg);
  }

  // Field 5: is_reply
  if (_has_field_[5]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(5, is_reply_, msg);
  }

  // Field 6: payload_size
  if (_has_field_[6]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(6, payload_size_, msg);
  }

  // Field 7: data_num_bytes
  if (_has_field_[7]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(7, data_num_bytes_, msg);
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}

}  // namespace perfetto
}  // namespace protos
}  // namespace gen
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic pop
#endif
// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_process_descriptor.gen.cc
// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wfloat-equal"
#endif
// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_process_descriptor.gen.h"

namespace perfetto {
namespace protos {
namespace gen {

ChromeProcessDescriptor::ChromeProcessDescriptor() = default;
ChromeProcessDescriptor::~ChromeProcessDescriptor() = default;
ChromeProcessDescriptor::ChromeProcessDescriptor(const ChromeProcessDescriptor&) = default;
ChromeProcessDescriptor& ChromeProcessDescriptor::operator=(const ChromeProcessDescriptor&) = default;
ChromeProcessDescriptor::ChromeProcessDescriptor(ChromeProcessDescriptor&&) noexcept = default;
ChromeProcessDescriptor& ChromeProcessDescriptor::operator=(ChromeProcessDescriptor&&) = default;

bool ChromeProcessDescriptor::operator==(const ChromeProcessDescriptor& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(process_type_, other.process_type_)
   && ::protozero::internal::gen_helpers::EqualsField(process_priority_, other.process_priority_)
   && ::protozero::internal::gen_helpers::EqualsField(legacy_sort_index_, other.legacy_sort_index_)
   && ::protozero::internal::gen_helpers::EqualsField(host_app_package_name_, other.host_app_package_name_)
   && ::protozero::internal::gen_helpers::EqualsField(crash_trace_id_, other.crash_trace_id_);
}

bool ChromeProcessDescriptor::ParseFromArray(const void* raw, size_t size) {
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* process_type */:
        field.get(&process_type_);
        break;
      case 2 /* process_priority */:
        field.get(&process_priority_);
        break;
      case 3 /* legacy_sort_index */:
        field.get(&legacy_sort_index_);
        break;
      case 4 /* host_app_package_name */:
        ::protozero::internal::gen_helpers::DeserializeString(field, &host_app_package_name_);
        break;
      case 5 /* crash_trace_id */:
        field.get(&crash_trace_id_);
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string ChromeProcessDescriptor::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> ChromeProcessDescriptor::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void ChromeProcessDescriptor::Serialize(::protozero::Message* msg) const {
  // Field 1: process_type
  if (_has_field_[1]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(1, process_type_, msg);
  }

  // Field 2: process_priority
  if (_has_field_[2]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(2, process_priority_, msg);
  }

  // Field 3: legacy_sort_index
  if (_has_field_[3]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(3, legacy_sort_index_, msg);
  }

  // Field 4: host_app_package_name
  if (_has_field_[4]) {
    ::protozero::internal::gen_helpers::SerializeString(4, host_app_package_name_, msg);
  }

  // Field 5: crash_trace_id
  if (_has_field_[5]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(5, crash_trace_id_, msg);
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}

}  // namespace perfetto
}  // namespace protos
}  // namespace gen
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic pop
#endif
// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_renderer_scheduler_state.gen.cc
// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wfloat-equal"
#endif
// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_renderer_scheduler_state.gen.h"

namespace perfetto {
namespace protos {
namespace gen {

ChromeRendererSchedulerState::ChromeRendererSchedulerState() = default;
ChromeRendererSchedulerState::~ChromeRendererSchedulerState() = default;
ChromeRendererSchedulerState::ChromeRendererSchedulerState(const ChromeRendererSchedulerState&) = default;
ChromeRendererSchedulerState& ChromeRendererSchedulerState::operator=(const ChromeRendererSchedulerState&) = default;
ChromeRendererSchedulerState::ChromeRendererSchedulerState(ChromeRendererSchedulerState&&) noexcept = default;
ChromeRendererSchedulerState& ChromeRendererSchedulerState::operator=(ChromeRendererSchedulerState&&) = default;

bool ChromeRendererSchedulerState::operator==(const ChromeRendererSchedulerState& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(rail_mode_, other.rail_mode_)
   && ::protozero::internal::gen_helpers::EqualsField(is_backgrounded_, other.is_backgrounded_)
   && ::protozero::internal::gen_helpers::EqualsField(is_hidden_, other.is_hidden_);
}

bool ChromeRendererSchedulerState::ParseFromArray(const void* raw, size_t size) {
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* rail_mode */:
        field.get(&rail_mode_);
        break;
      case 2 /* is_backgrounded */:
        field.get(&is_backgrounded_);
        break;
      case 3 /* is_hidden */:
        field.get(&is_hidden_);
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string ChromeRendererSchedulerState::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> ChromeRendererSchedulerState::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void ChromeRendererSchedulerState::Serialize(::protozero::Message* msg) const {
  // Field 1: rail_mode
  if (_has_field_[1]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(1, rail_mode_, msg);
  }

  // Field 2: is_backgrounded
  if (_has_field_[2]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(2, is_backgrounded_, msg);
  }

  // Field 3: is_hidden
  if (_has_field_[3]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(3, is_hidden_, msg);
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}

}  // namespace perfetto
}  // namespace protos
}  // namespace gen
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic pop
#endif
// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_thread_descriptor.gen.cc
// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wfloat-equal"
#endif
// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_thread_descriptor.gen.h"

namespace perfetto {
namespace protos {
namespace gen {

ChromeThreadDescriptor::ChromeThreadDescriptor() = default;
ChromeThreadDescriptor::~ChromeThreadDescriptor() = default;
ChromeThreadDescriptor::ChromeThreadDescriptor(const ChromeThreadDescriptor&) = default;
ChromeThreadDescriptor& ChromeThreadDescriptor::operator=(const ChromeThreadDescriptor&) = default;
ChromeThreadDescriptor::ChromeThreadDescriptor(ChromeThreadDescriptor&&) noexcept = default;
ChromeThreadDescriptor& ChromeThreadDescriptor::operator=(ChromeThreadDescriptor&&) = default;

bool ChromeThreadDescriptor::operator==(const ChromeThreadDescriptor& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(thread_type_, other.thread_type_)
   && ::protozero::internal::gen_helpers::EqualsField(legacy_sort_index_, other.legacy_sort_index_);
}

bool ChromeThreadDescriptor::ParseFromArray(const void* raw, size_t size) {
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* thread_type */:
        field.get(&thread_type_);
        break;
      case 2 /* legacy_sort_index */:
        field.get(&legacy_sort_index_);
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string ChromeThreadDescriptor::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> ChromeThreadDescriptor::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void ChromeThreadDescriptor::Serialize(::protozero::Message* msg) const {
  // Field 1: thread_type
  if (_has_field_[1]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(1, thread_type_, msg);
  }

  // Field 2: legacy_sort_index
  if (_has_field_[2]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(2, legacy_sort_index_, msg);
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}

}  // namespace perfetto
}  // namespace protos
}  // namespace gen
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic pop
#endif
// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_user_event.gen.cc
// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wfloat-equal"
#endif
// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_user_event.gen.h"

namespace perfetto {
namespace protos {
namespace gen {

ChromeUserEvent::ChromeUserEvent() = default;
ChromeUserEvent::~ChromeUserEvent() = default;
ChromeUserEvent::ChromeUserEvent(const ChromeUserEvent&) = default;
ChromeUserEvent& ChromeUserEvent::operator=(const ChromeUserEvent&) = default;
ChromeUserEvent::ChromeUserEvent(ChromeUserEvent&&) noexcept = default;
ChromeUserEvent& ChromeUserEvent::operator=(ChromeUserEvent&&) = default;

bool ChromeUserEvent::operator==(const ChromeUserEvent& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(action_, other.action_)
   && ::protozero::internal::gen_helpers::EqualsField(action_hash_, other.action_hash_);
}

bool ChromeUserEvent::ParseFromArray(const void* raw, size_t size) {
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* action */:
        ::protozero::internal::gen_helpers::DeserializeString(field, &action_);
        break;
      case 2 /* action_hash */:
        field.get(&action_hash_);
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string ChromeUserEvent::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> ChromeUserEvent::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void ChromeUserEvent::Serialize(::protozero::Message* msg) const {
  // Field 1: action
  if (_has_field_[1]) {
    ::protozero::internal::gen_helpers::SerializeString(1, action_, msg);
  }

  // Field 2: action_hash
  if (_has_field_[2]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(2, action_hash_, msg);
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}

}  // namespace perfetto
}  // namespace protos
}  // namespace gen
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic pop
#endif
// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/chrome_window_handle_event_info.gen.cc
// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wfloat-equal"
#endif
// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_window_handle_event_info.gen.h"

namespace perfetto {
namespace protos {
namespace gen {

ChromeWindowHandleEventInfo::ChromeWindowHandleEventInfo() = default;
ChromeWindowHandleEventInfo::~ChromeWindowHandleEventInfo() = default;
ChromeWindowHandleEventInfo::ChromeWindowHandleEventInfo(const ChromeWindowHandleEventInfo&) = default;
ChromeWindowHandleEventInfo& ChromeWindowHandleEventInfo::operator=(const ChromeWindowHandleEventInfo&) = default;
ChromeWindowHandleEventInfo::ChromeWindowHandleEventInfo(ChromeWindowHandleEventInfo&&) noexcept = default;
ChromeWindowHandleEventInfo& ChromeWindowHandleEventInfo::operator=(ChromeWindowHandleEventInfo&&) = default;

bool ChromeWindowHandleEventInfo::operator==(const ChromeWindowHandleEventInfo& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(dpi_, other.dpi_)
   && ::protozero::internal::gen_helpers::EqualsField(message_id_, other.message_id_)
   && ::protozero::internal::gen_helpers::EqualsField(hwnd_ptr_, other.hwnd_ptr_);
}

bool ChromeWindowHandleEventInfo::ParseFromArray(const void* raw, size_t size) {
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* dpi */:
        field.get(&dpi_);
        break;
      case 2 /* message_id */:
        field.get(&message_id_);
        break;
      case 3 /* hwnd_ptr */:
        field.get(&hwnd_ptr_);
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string ChromeWindowHandleEventInfo::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> ChromeWindowHandleEventInfo::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void ChromeWindowHandleEventInfo::Serialize(::protozero::Message* msg) const {
  // Field 1: dpi
  if (_has_field_[1]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(1, dpi_, msg);
  }

  // Field 2: message_id
  if (_has_field_[2]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(2, message_id_, msg);
  }

  // Field 3: hwnd_ptr
  if (_has_field_[3]) {
    ::protozero::internal::gen_helpers::SerializeFixed(3, hwnd_ptr_, msg);
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}

}  // namespace perfetto
}  // namespace protos
}  // namespace gen
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic pop
#endif
// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/counter_descriptor.gen.cc
// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wfloat-equal"
#endif
// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/counter_descriptor.gen.h"

namespace perfetto {
namespace protos {
namespace gen {

CounterDescriptor::CounterDescriptor() = default;
CounterDescriptor::~CounterDescriptor() = default;
CounterDescriptor::CounterDescriptor(const CounterDescriptor&) = default;
CounterDescriptor& CounterDescriptor::operator=(const CounterDescriptor&) = default;
CounterDescriptor::CounterDescriptor(CounterDescriptor&&) noexcept = default;
CounterDescriptor& CounterDescriptor::operator=(CounterDescriptor&&) = default;

bool CounterDescriptor::operator==(const CounterDescriptor& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(type_, other.type_)
   && ::protozero::internal::gen_helpers::EqualsField(categories_, other.categories_)
   && ::protozero::internal::gen_helpers::EqualsField(unit_, other.unit_)
   && ::protozero::internal::gen_helpers::EqualsField(unit_name_, other.unit_name_)
   && ::protozero::internal::gen_helpers::EqualsField(unit_multiplier_, other.unit_multiplier_)
   && ::protozero::internal::gen_helpers::EqualsField(is_incremental_, other.is_incremental_);
}

bool CounterDescriptor::ParseFromArray(const void* raw, size_t size) {
  categories_.clear();
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* type */:
        field.get(&type_);
        break;
      case 2 /* categories */:
        categories_.emplace_back();
        ::protozero::internal::gen_helpers::DeserializeString(field, &categories_.back());
        break;
      case 3 /* unit */:
        field.get(&unit_);
        break;
      case 6 /* unit_name */:
        ::protozero::internal::gen_helpers::DeserializeString(field, &unit_name_);
        break;
      case 4 /* unit_multiplier */:
        field.get(&unit_multiplier_);
        break;
      case 5 /* is_incremental */:
        field.get(&is_incremental_);
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string CounterDescriptor::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> CounterDescriptor::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void CounterDescriptor::Serialize(::protozero::Message* msg) const {
  // Field 1: type
  if (_has_field_[1]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(1, type_, msg);
  }

  // Field 2: categories
  for (auto& it : categories_) {
    ::protozero::internal::gen_helpers::SerializeString(2, it, msg);
  }

  // Field 3: unit
  if (_has_field_[3]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(3, unit_, msg);
  }

  // Field 6: unit_name
  if (_has_field_[6]) {
    ::protozero::internal::gen_helpers::SerializeString(6, unit_name_, msg);
  }

  // Field 4: unit_multiplier
  if (_has_field_[4]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(4, unit_multiplier_, msg);
  }

  // Field 5: is_incremental
  if (_has_field_[5]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(5, is_incremental_, msg);
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}

}  // namespace perfetto
}  // namespace protos
}  // namespace gen
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic pop
#endif
// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/debug_annotation.gen.cc
// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wfloat-equal"
#endif
// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/debug_annotation.gen.h"

namespace perfetto {
namespace protos {
namespace gen {

DebugAnnotationValueTypeName::DebugAnnotationValueTypeName() = default;
DebugAnnotationValueTypeName::~DebugAnnotationValueTypeName() = default;
DebugAnnotationValueTypeName::DebugAnnotationValueTypeName(const DebugAnnotationValueTypeName&) = default;
DebugAnnotationValueTypeName& DebugAnnotationValueTypeName::operator=(const DebugAnnotationValueTypeName&) = default;
DebugAnnotationValueTypeName::DebugAnnotationValueTypeName(DebugAnnotationValueTypeName&&) noexcept = default;
DebugAnnotationValueTypeName& DebugAnnotationValueTypeName::operator=(DebugAnnotationValueTypeName&&) = default;

bool DebugAnnotationValueTypeName::operator==(const DebugAnnotationValueTypeName& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(iid_, other.iid_)
   && ::protozero::internal::gen_helpers::EqualsField(name_, other.name_);
}

bool DebugAnnotationValueTypeName::ParseFromArray(const void* raw, size_t size) {
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* iid */:
        field.get(&iid_);
        break;
      case 2 /* name */:
        ::protozero::internal::gen_helpers::DeserializeString(field, &name_);
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string DebugAnnotationValueTypeName::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> DebugAnnotationValueTypeName::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void DebugAnnotationValueTypeName::Serialize(::protozero::Message* msg) const {
  // Field 1: iid
  if (_has_field_[1]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(1, iid_, msg);
  }

  // Field 2: name
  if (_has_field_[2]) {
    ::protozero::internal::gen_helpers::SerializeString(2, name_, msg);
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}


DebugAnnotationName::DebugAnnotationName() = default;
DebugAnnotationName::~DebugAnnotationName() = default;
DebugAnnotationName::DebugAnnotationName(const DebugAnnotationName&) = default;
DebugAnnotationName& DebugAnnotationName::operator=(const DebugAnnotationName&) = default;
DebugAnnotationName::DebugAnnotationName(DebugAnnotationName&&) noexcept = default;
DebugAnnotationName& DebugAnnotationName::operator=(DebugAnnotationName&&) = default;

bool DebugAnnotationName::operator==(const DebugAnnotationName& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(iid_, other.iid_)
   && ::protozero::internal::gen_helpers::EqualsField(name_, other.name_);
}

bool DebugAnnotationName::ParseFromArray(const void* raw, size_t size) {
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* iid */:
        field.get(&iid_);
        break;
      case 2 /* name */:
        ::protozero::internal::gen_helpers::DeserializeString(field, &name_);
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string DebugAnnotationName::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> DebugAnnotationName::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void DebugAnnotationName::Serialize(::protozero::Message* msg) const {
  // Field 1: iid
  if (_has_field_[1]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(1, iid_, msg);
  }

  // Field 2: name
  if (_has_field_[2]) {
    ::protozero::internal::gen_helpers::SerializeString(2, name_, msg);
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}


DebugAnnotation::DebugAnnotation() = default;
DebugAnnotation::~DebugAnnotation() = default;
DebugAnnotation::DebugAnnotation(const DebugAnnotation&) = default;
DebugAnnotation& DebugAnnotation::operator=(const DebugAnnotation&) = default;
DebugAnnotation::DebugAnnotation(DebugAnnotation&&) noexcept = default;
DebugAnnotation& DebugAnnotation::operator=(DebugAnnotation&&) = default;

bool DebugAnnotation::operator==(const DebugAnnotation& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(name_iid_, other.name_iid_)
   && ::protozero::internal::gen_helpers::EqualsField(name_, other.name_)
   && ::protozero::internal::gen_helpers::EqualsField(bool_value_, other.bool_value_)
   && ::protozero::internal::gen_helpers::EqualsField(uint_value_, other.uint_value_)
   && ::protozero::internal::gen_helpers::EqualsField(int_value_, other.int_value_)
   && ::protozero::internal::gen_helpers::EqualsField(double_value_, other.double_value_)
   && ::protozero::internal::gen_helpers::EqualsField(pointer_value_, other.pointer_value_)
   && ::protozero::internal::gen_helpers::EqualsField(nested_value_, other.nested_value_)
   && ::protozero::internal::gen_helpers::EqualsField(legacy_json_value_, other.legacy_json_value_)
   && ::protozero::internal::gen_helpers::EqualsField(string_value_, other.string_value_)
   && ::protozero::internal::gen_helpers::EqualsField(string_value_iid_, other.string_value_iid_)
   && ::protozero::internal::gen_helpers::EqualsField(proto_type_name_, other.proto_type_name_)
   && ::protozero::internal::gen_helpers::EqualsField(proto_type_name_iid_, other.proto_type_name_iid_)
   && ::protozero::internal::gen_helpers::EqualsField(proto_value_, other.proto_value_)
   && ::protozero::internal::gen_helpers::EqualsField(dict_entries_, other.dict_entries_)
   && ::protozero::internal::gen_helpers::EqualsField(array_values_, other.array_values_);
}

int DebugAnnotation::dict_entries_size() const { return static_cast<int>(dict_entries_.size()); }
void DebugAnnotation::clear_dict_entries() { dict_entries_.clear(); }
DebugAnnotation* DebugAnnotation::add_dict_entries() { dict_entries_.emplace_back(); return &dict_entries_.back(); }
int DebugAnnotation::array_values_size() const { return static_cast<int>(array_values_.size()); }
void DebugAnnotation::clear_array_values() { array_values_.clear(); }
DebugAnnotation* DebugAnnotation::add_array_values() { array_values_.emplace_back(); return &array_values_.back(); }
bool DebugAnnotation::ParseFromArray(const void* raw, size_t size) {
  dict_entries_.clear();
  array_values_.clear();
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* name_iid */:
        field.get(&name_iid_);
        break;
      case 10 /* name */:
        ::protozero::internal::gen_helpers::DeserializeString(field, &name_);
        break;
      case 2 /* bool_value */:
        field.get(&bool_value_);
        break;
      case 3 /* uint_value */:
        field.get(&uint_value_);
        break;
      case 4 /* int_value */:
        field.get(&int_value_);
        break;
      case 5 /* double_value */:
        field.get(&double_value_);
        break;
      case 7 /* pointer_value */:
        field.get(&pointer_value_);
        break;
      case 8 /* nested_value */:
        (*nested_value_).ParseFromArray(field.data(), field.size());
        break;
      case 9 /* legacy_json_value */:
        ::protozero::internal::gen_helpers::DeserializeString(field, &legacy_json_value_);
        break;
      case 6 /* string_value */:
        ::protozero::internal::gen_helpers::DeserializeString(field, &string_value_);
        break;
      case 17 /* string_value_iid */:
        field.get(&string_value_iid_);
        break;
      case 16 /* proto_type_name */:
        ::protozero::internal::gen_helpers::DeserializeString(field, &proto_type_name_);
        break;
      case 13 /* proto_type_name_iid */:
        field.get(&proto_type_name_iid_);
        break;
      case 14 /* proto_value */:
        field.get(&proto_value_);
        break;
      case 11 /* dict_entries */:
        dict_entries_.emplace_back();
        dict_entries_.back().ParseFromArray(field.data(), field.size());
        break;
      case 12 /* array_values */:
        array_values_.emplace_back();
        array_values_.back().ParseFromArray(field.data(), field.size());
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string DebugAnnotation::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> DebugAnnotation::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void DebugAnnotation::Serialize(::protozero::Message* msg) const {
  // Field 1: name_iid
  if (_has_field_[1]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(1, name_iid_, msg);
  }

  // Field 10: name
  if (_has_field_[10]) {
    ::protozero::internal::gen_helpers::SerializeString(10, name_, msg);
  }

  // Field 2: bool_value
  if (_has_field_[2]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(2, bool_value_, msg);
  }

  // Field 3: uint_value
  if (_has_field_[3]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(3, uint_value_, msg);
  }

  // Field 4: int_value
  if (_has_field_[4]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(4, int_value_, msg);
  }

  // Field 5: double_value
  if (_has_field_[5]) {
    ::protozero::internal::gen_helpers::SerializeFixed(5, double_value_, msg);
  }

  // Field 7: pointer_value
  if (_has_field_[7]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(7, pointer_value_, msg);
  }

  // Field 8: nested_value
  if (_has_field_[8]) {
    (*nested_value_).Serialize(msg->BeginNestedMessage<::protozero::Message>(8));
  }

  // Field 9: legacy_json_value
  if (_has_field_[9]) {
    ::protozero::internal::gen_helpers::SerializeString(9, legacy_json_value_, msg);
  }

  // Field 6: string_value
  if (_has_field_[6]) {
    ::protozero::internal::gen_helpers::SerializeString(6, string_value_, msg);
  }

  // Field 17: string_value_iid
  if (_has_field_[17]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(17, string_value_iid_, msg);
  }

  // Field 16: proto_type_name
  if (_has_field_[16]) {
    ::protozero::internal::gen_helpers::SerializeString(16, proto_type_name_, msg);
  }

  // Field 13: proto_type_name_iid
  if (_has_field_[13]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(13, proto_type_name_iid_, msg);
  }

  // Field 14: proto_value
  if (_has_field_[14]) {
    ::protozero::internal::gen_helpers::SerializeString(14, proto_value_, msg);
  }

  // Field 11: dict_entries
  for (auto& it : dict_entries_) {
    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(11));
  }

  // Field 12: array_values
  for (auto& it : array_values_) {
    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(12));
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}


DebugAnnotation_NestedValue::DebugAnnotation_NestedValue() = default;
DebugAnnotation_NestedValue::~DebugAnnotation_NestedValue() = default;
DebugAnnotation_NestedValue::DebugAnnotation_NestedValue(const DebugAnnotation_NestedValue&) = default;
DebugAnnotation_NestedValue& DebugAnnotation_NestedValue::operator=(const DebugAnnotation_NestedValue&) = default;
DebugAnnotation_NestedValue::DebugAnnotation_NestedValue(DebugAnnotation_NestedValue&&) noexcept = default;
DebugAnnotation_NestedValue& DebugAnnotation_NestedValue::operator=(DebugAnnotation_NestedValue&&) = default;

bool DebugAnnotation_NestedValue::operator==(const DebugAnnotation_NestedValue& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(nested_type_, other.nested_type_)
   && ::protozero::internal::gen_helpers::EqualsField(dict_keys_, other.dict_keys_)
   && ::protozero::internal::gen_helpers::EqualsField(dict_values_, other.dict_values_)
   && ::protozero::internal::gen_helpers::EqualsField(array_values_, other.array_values_)
   && ::protozero::internal::gen_helpers::EqualsField(int_value_, other.int_value_)
   && ::protozero::internal::gen_helpers::EqualsField(double_value_, other.double_value_)
   && ::protozero::internal::gen_helpers::EqualsField(bool_value_, other.bool_value_)
   && ::protozero::internal::gen_helpers::EqualsField(string_value_, other.string_value_);
}

int DebugAnnotation_NestedValue::dict_values_size() const { return static_cast<int>(dict_values_.size()); }
void DebugAnnotation_NestedValue::clear_dict_values() { dict_values_.clear(); }
DebugAnnotation_NestedValue* DebugAnnotation_NestedValue::add_dict_values() { dict_values_.emplace_back(); return &dict_values_.back(); }
int DebugAnnotation_NestedValue::array_values_size() const { return static_cast<int>(array_values_.size()); }
void DebugAnnotation_NestedValue::clear_array_values() { array_values_.clear(); }
DebugAnnotation_NestedValue* DebugAnnotation_NestedValue::add_array_values() { array_values_.emplace_back(); return &array_values_.back(); }
bool DebugAnnotation_NestedValue::ParseFromArray(const void* raw, size_t size) {
  dict_keys_.clear();
  dict_values_.clear();
  array_values_.clear();
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* nested_type */:
        field.get(&nested_type_);
        break;
      case 2 /* dict_keys */:
        dict_keys_.emplace_back();
        ::protozero::internal::gen_helpers::DeserializeString(field, &dict_keys_.back());
        break;
      case 3 /* dict_values */:
        dict_values_.emplace_back();
        dict_values_.back().ParseFromArray(field.data(), field.size());
        break;
      case 4 /* array_values */:
        array_values_.emplace_back();
        array_values_.back().ParseFromArray(field.data(), field.size());
        break;
      case 5 /* int_value */:
        field.get(&int_value_);
        break;
      case 6 /* double_value */:
        field.get(&double_value_);
        break;
      case 7 /* bool_value */:
        field.get(&bool_value_);
        break;
      case 8 /* string_value */:
        ::protozero::internal::gen_helpers::DeserializeString(field, &string_value_);
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string DebugAnnotation_NestedValue::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> DebugAnnotation_NestedValue::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void DebugAnnotation_NestedValue::Serialize(::protozero::Message* msg) const {
  // Field 1: nested_type
  if (_has_field_[1]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(1, nested_type_, msg);
  }

  // Field 2: dict_keys
  for (auto& it : dict_keys_) {
    ::protozero::internal::gen_helpers::SerializeString(2, it, msg);
  }

  // Field 3: dict_values
  for (auto& it : dict_values_) {
    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(3));
  }

  // Field 4: array_values
  for (auto& it : array_values_) {
    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(4));
  }

  // Field 5: int_value
  if (_has_field_[5]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(5, int_value_, msg);
  }

  // Field 6: double_value
  if (_has_field_[6]) {
    ::protozero::internal::gen_helpers::SerializeFixed(6, double_value_, msg);
  }

  // Field 7: bool_value
  if (_has_field_[7]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(7, bool_value_, msg);
  }

  // Field 8: string_value
  if (_has_field_[8]) {
    ::protozero::internal::gen_helpers::SerializeString(8, string_value_, msg);
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}

}  // namespace perfetto
}  // namespace protos
}  // namespace gen
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic pop
#endif
// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/log_message.gen.cc
// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wfloat-equal"
#endif
// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/log_message.gen.h"

namespace perfetto {
namespace protos {
namespace gen {

LogMessageBody::LogMessageBody() = default;
LogMessageBody::~LogMessageBody() = default;
LogMessageBody::LogMessageBody(const LogMessageBody&) = default;
LogMessageBody& LogMessageBody::operator=(const LogMessageBody&) = default;
LogMessageBody::LogMessageBody(LogMessageBody&&) noexcept = default;
LogMessageBody& LogMessageBody::operator=(LogMessageBody&&) = default;

bool LogMessageBody::operator==(const LogMessageBody& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(iid_, other.iid_)
   && ::protozero::internal::gen_helpers::EqualsField(body_, other.body_);
}

bool LogMessageBody::ParseFromArray(const void* raw, size_t size) {
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* iid */:
        field.get(&iid_);
        break;
      case 2 /* body */:
        ::protozero::internal::gen_helpers::DeserializeString(field, &body_);
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string LogMessageBody::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> LogMessageBody::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void LogMessageBody::Serialize(::protozero::Message* msg) const {
  // Field 1: iid
  if (_has_field_[1]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(1, iid_, msg);
  }

  // Field 2: body
  if (_has_field_[2]) {
    ::protozero::internal::gen_helpers::SerializeString(2, body_, msg);
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}


LogMessage::LogMessage() = default;
LogMessage::~LogMessage() = default;
LogMessage::LogMessage(const LogMessage&) = default;
LogMessage& LogMessage::operator=(const LogMessage&) = default;
LogMessage::LogMessage(LogMessage&&) noexcept = default;
LogMessage& LogMessage::operator=(LogMessage&&) = default;

bool LogMessage::operator==(const LogMessage& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(source_location_iid_, other.source_location_iid_)
   && ::protozero::internal::gen_helpers::EqualsField(body_iid_, other.body_iid_)
   && ::protozero::internal::gen_helpers::EqualsField(prio_, other.prio_);
}

bool LogMessage::ParseFromArray(const void* raw, size_t size) {
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* source_location_iid */:
        field.get(&source_location_iid_);
        break;
      case 2 /* body_iid */:
        field.get(&body_iid_);
        break;
      case 3 /* prio */:
        field.get(&prio_);
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string LogMessage::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> LogMessage::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void LogMessage::Serialize(::protozero::Message* msg) const {
  // Field 1: source_location_iid
  if (_has_field_[1]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(1, source_location_iid_, msg);
  }

  // Field 2: body_iid
  if (_has_field_[2]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(2, body_iid_, msg);
  }

  // Field 3: prio
  if (_has_field_[3]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(3, prio_, msg);
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}

}  // namespace perfetto
}  // namespace protos
}  // namespace gen
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic pop
#endif
// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/pixel_modem.gen.cc
// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wfloat-equal"
#endif
// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/pixel_modem.gen.h"

namespace perfetto {
namespace protos {
namespace gen {

PixelModemEventInsight::PixelModemEventInsight() = default;
PixelModemEventInsight::~PixelModemEventInsight() = default;
PixelModemEventInsight::PixelModemEventInsight(const PixelModemEventInsight&) = default;
PixelModemEventInsight& PixelModemEventInsight::operator=(const PixelModemEventInsight&) = default;
PixelModemEventInsight::PixelModemEventInsight(PixelModemEventInsight&&) noexcept = default;
PixelModemEventInsight& PixelModemEventInsight::operator=(PixelModemEventInsight&&) = default;

bool PixelModemEventInsight::operator==(const PixelModemEventInsight& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(detokenized_message_, other.detokenized_message_);
}

bool PixelModemEventInsight::ParseFromArray(const void* raw, size_t size) {
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* detokenized_message */:
        ::protozero::internal::gen_helpers::DeserializeString(field, &detokenized_message_);
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string PixelModemEventInsight::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> PixelModemEventInsight::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void PixelModemEventInsight::Serialize(::protozero::Message* msg) const {
  // Field 1: detokenized_message
  if (_has_field_[1]) {
    ::protozero::internal::gen_helpers::SerializeString(1, detokenized_message_, msg);
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}

}  // namespace perfetto
}  // namespace protos
}  // namespace gen
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic pop
#endif
// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/process_descriptor.gen.cc
// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wfloat-equal"
#endif
// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/process_descriptor.gen.h"

namespace perfetto {
namespace protos {
namespace gen {

ProcessDescriptor::ProcessDescriptor() = default;
ProcessDescriptor::~ProcessDescriptor() = default;
ProcessDescriptor::ProcessDescriptor(const ProcessDescriptor&) = default;
ProcessDescriptor& ProcessDescriptor::operator=(const ProcessDescriptor&) = default;
ProcessDescriptor::ProcessDescriptor(ProcessDescriptor&&) noexcept = default;
ProcessDescriptor& ProcessDescriptor::operator=(ProcessDescriptor&&) = default;

bool ProcessDescriptor::operator==(const ProcessDescriptor& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(pid_, other.pid_)
   && ::protozero::internal::gen_helpers::EqualsField(cmdline_, other.cmdline_)
   && ::protozero::internal::gen_helpers::EqualsField(process_name_, other.process_name_)
   && ::protozero::internal::gen_helpers::EqualsField(process_priority_, other.process_priority_)
   && ::protozero::internal::gen_helpers::EqualsField(start_timestamp_ns_, other.start_timestamp_ns_)
   && ::protozero::internal::gen_helpers::EqualsField(chrome_process_type_, other.chrome_process_type_)
   && ::protozero::internal::gen_helpers::EqualsField(legacy_sort_index_, other.legacy_sort_index_)
   && ::protozero::internal::gen_helpers::EqualsField(process_labels_, other.process_labels_);
}

bool ProcessDescriptor::ParseFromArray(const void* raw, size_t size) {
  cmdline_.clear();
  process_labels_.clear();
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* pid */:
        field.get(&pid_);
        break;
      case 2 /* cmdline */:
        cmdline_.emplace_back();
        ::protozero::internal::gen_helpers::DeserializeString(field, &cmdline_.back());
        break;
      case 6 /* process_name */:
        ::protozero::internal::gen_helpers::DeserializeString(field, &process_name_);
        break;
      case 5 /* process_priority */:
        field.get(&process_priority_);
        break;
      case 7 /* start_timestamp_ns */:
        field.get(&start_timestamp_ns_);
        break;
      case 4 /* chrome_process_type */:
        field.get(&chrome_process_type_);
        break;
      case 3 /* legacy_sort_index */:
        field.get(&legacy_sort_index_);
        break;
      case 8 /* process_labels */:
        process_labels_.emplace_back();
        ::protozero::internal::gen_helpers::DeserializeString(field, &process_labels_.back());
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string ProcessDescriptor::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> ProcessDescriptor::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void ProcessDescriptor::Serialize(::protozero::Message* msg) const {
  // Field 1: pid
  if (_has_field_[1]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(1, pid_, msg);
  }

  // Field 2: cmdline
  for (auto& it : cmdline_) {
    ::protozero::internal::gen_helpers::SerializeString(2, it, msg);
  }

  // Field 6: process_name
  if (_has_field_[6]) {
    ::protozero::internal::gen_helpers::SerializeString(6, process_name_, msg);
  }

  // Field 5: process_priority
  if (_has_field_[5]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(5, process_priority_, msg);
  }

  // Field 7: start_timestamp_ns
  if (_has_field_[7]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(7, start_timestamp_ns_, msg);
  }

  // Field 4: chrome_process_type
  if (_has_field_[4]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(4, chrome_process_type_, msg);
  }

  // Field 3: legacy_sort_index
  if (_has_field_[3]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(3, legacy_sort_index_, msg);
  }

  // Field 8: process_labels
  for (auto& it : process_labels_) {
    ::protozero::internal::gen_helpers::SerializeString(8, it, msg);
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}

}  // namespace perfetto
}  // namespace protos
}  // namespace gen
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic pop
#endif
// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/range_of_interest.gen.cc
// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wfloat-equal"
#endif
// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/range_of_interest.gen.h"

namespace perfetto {
namespace protos {
namespace gen {

TrackEventRangeOfInterest::TrackEventRangeOfInterest() = default;
TrackEventRangeOfInterest::~TrackEventRangeOfInterest() = default;
TrackEventRangeOfInterest::TrackEventRangeOfInterest(const TrackEventRangeOfInterest&) = default;
TrackEventRangeOfInterest& TrackEventRangeOfInterest::operator=(const TrackEventRangeOfInterest&) = default;
TrackEventRangeOfInterest::TrackEventRangeOfInterest(TrackEventRangeOfInterest&&) noexcept = default;
TrackEventRangeOfInterest& TrackEventRangeOfInterest::operator=(TrackEventRangeOfInterest&&) = default;

bool TrackEventRangeOfInterest::operator==(const TrackEventRangeOfInterest& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(start_us_, other.start_us_);
}

bool TrackEventRangeOfInterest::ParseFromArray(const void* raw, size_t size) {
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* start_us */:
        field.get(&start_us_);
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string TrackEventRangeOfInterest::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> TrackEventRangeOfInterest::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void TrackEventRangeOfInterest::Serialize(::protozero::Message* msg) const {
  // Field 1: start_us
  if (_has_field_[1]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(1, start_us_, msg);
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}

}  // namespace perfetto
}  // namespace protos
}  // namespace gen
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic pop
#endif
// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/screenshot.gen.cc
// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wfloat-equal"
#endif
// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/screenshot.gen.h"

namespace perfetto {
namespace protos {
namespace gen {

Screenshot::Screenshot() = default;
Screenshot::~Screenshot() = default;
Screenshot::Screenshot(const Screenshot&) = default;
Screenshot& Screenshot::operator=(const Screenshot&) = default;
Screenshot::Screenshot(Screenshot&&) noexcept = default;
Screenshot& Screenshot::operator=(Screenshot&&) = default;

bool Screenshot::operator==(const Screenshot& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(jpg_image_, other.jpg_image_);
}

bool Screenshot::ParseFromArray(const void* raw, size_t size) {
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* jpg_image */:
        field.get(&jpg_image_);
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string Screenshot::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> Screenshot::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void Screenshot::Serialize(::protozero::Message* msg) const {
  // Field 1: jpg_image
  if (_has_field_[1]) {
    ::protozero::internal::gen_helpers::SerializeString(1, jpg_image_, msg);
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}

}  // namespace perfetto
}  // namespace protos
}  // namespace gen
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic pop
#endif
// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/source_location.gen.cc
// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wfloat-equal"
#endif
// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/source_location.gen.h"

namespace perfetto {
namespace protos {
namespace gen {

SourceLocation::SourceLocation() = default;
SourceLocation::~SourceLocation() = default;
SourceLocation::SourceLocation(const SourceLocation&) = default;
SourceLocation& SourceLocation::operator=(const SourceLocation&) = default;
SourceLocation::SourceLocation(SourceLocation&&) noexcept = default;
SourceLocation& SourceLocation::operator=(SourceLocation&&) = default;

bool SourceLocation::operator==(const SourceLocation& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(iid_, other.iid_)
   && ::protozero::internal::gen_helpers::EqualsField(file_name_, other.file_name_)
   && ::protozero::internal::gen_helpers::EqualsField(function_name_, other.function_name_)
   && ::protozero::internal::gen_helpers::EqualsField(line_number_, other.line_number_);
}

bool SourceLocation::ParseFromArray(const void* raw, size_t size) {
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* iid */:
        field.get(&iid_);
        break;
      case 2 /* file_name */:
        ::protozero::internal::gen_helpers::DeserializeString(field, &file_name_);
        break;
      case 3 /* function_name */:
        ::protozero::internal::gen_helpers::DeserializeString(field, &function_name_);
        break;
      case 4 /* line_number */:
        field.get(&line_number_);
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string SourceLocation::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> SourceLocation::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void SourceLocation::Serialize(::protozero::Message* msg) const {
  // Field 1: iid
  if (_has_field_[1]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(1, iid_, msg);
  }

  // Field 2: file_name
  if (_has_field_[2]) {
    ::protozero::internal::gen_helpers::SerializeString(2, file_name_, msg);
  }

  // Field 3: function_name
  if (_has_field_[3]) {
    ::protozero::internal::gen_helpers::SerializeString(3, function_name_, msg);
  }

  // Field 4: line_number
  if (_has_field_[4]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(4, line_number_, msg);
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}


UnsymbolizedSourceLocation::UnsymbolizedSourceLocation() = default;
UnsymbolizedSourceLocation::~UnsymbolizedSourceLocation() = default;
UnsymbolizedSourceLocation::UnsymbolizedSourceLocation(const UnsymbolizedSourceLocation&) = default;
UnsymbolizedSourceLocation& UnsymbolizedSourceLocation::operator=(const UnsymbolizedSourceLocation&) = default;
UnsymbolizedSourceLocation::UnsymbolizedSourceLocation(UnsymbolizedSourceLocation&&) noexcept = default;
UnsymbolizedSourceLocation& UnsymbolizedSourceLocation::operator=(UnsymbolizedSourceLocation&&) = default;

bool UnsymbolizedSourceLocation::operator==(const UnsymbolizedSourceLocation& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(iid_, other.iid_)
   && ::protozero::internal::gen_helpers::EqualsField(mapping_id_, other.mapping_id_)
   && ::protozero::internal::gen_helpers::EqualsField(rel_pc_, other.rel_pc_);
}

bool UnsymbolizedSourceLocation::ParseFromArray(const void* raw, size_t size) {
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* iid */:
        field.get(&iid_);
        break;
      case 2 /* mapping_id */:
        field.get(&mapping_id_);
        break;
      case 3 /* rel_pc */:
        field.get(&rel_pc_);
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string UnsymbolizedSourceLocation::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> UnsymbolizedSourceLocation::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void UnsymbolizedSourceLocation::Serialize(::protozero::Message* msg) const {
  // Field 1: iid
  if (_has_field_[1]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(1, iid_, msg);
  }

  // Field 2: mapping_id
  if (_has_field_[2]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(2, mapping_id_, msg);
  }

  // Field 3: rel_pc
  if (_has_field_[3]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(3, rel_pc_, msg);
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}

}  // namespace perfetto
}  // namespace protos
}  // namespace gen
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic pop
#endif
// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/task_execution.gen.cc
// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wfloat-equal"
#endif
// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/task_execution.gen.h"

namespace perfetto {
namespace protos {
namespace gen {

TaskExecution::TaskExecution() = default;
TaskExecution::~TaskExecution() = default;
TaskExecution::TaskExecution(const TaskExecution&) = default;
TaskExecution& TaskExecution::operator=(const TaskExecution&) = default;
TaskExecution::TaskExecution(TaskExecution&&) noexcept = default;
TaskExecution& TaskExecution::operator=(TaskExecution&&) = default;

bool TaskExecution::operator==(const TaskExecution& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(posted_from_iid_, other.posted_from_iid_);
}

bool TaskExecution::ParseFromArray(const void* raw, size_t size) {
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* posted_from_iid */:
        field.get(&posted_from_iid_);
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string TaskExecution::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> TaskExecution::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void TaskExecution::Serialize(::protozero::Message* msg) const {
  // Field 1: posted_from_iid
  if (_has_field_[1]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(1, posted_from_iid_, msg);
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}

}  // namespace perfetto
}  // namespace protos
}  // namespace gen
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic pop
#endif
// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/thread_descriptor.gen.cc
// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wfloat-equal"
#endif
// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/thread_descriptor.gen.h"

namespace perfetto {
namespace protos {
namespace gen {

ThreadDescriptor::ThreadDescriptor() = default;
ThreadDescriptor::~ThreadDescriptor() = default;
ThreadDescriptor::ThreadDescriptor(const ThreadDescriptor&) = default;
ThreadDescriptor& ThreadDescriptor::operator=(const ThreadDescriptor&) = default;
ThreadDescriptor::ThreadDescriptor(ThreadDescriptor&&) noexcept = default;
ThreadDescriptor& ThreadDescriptor::operator=(ThreadDescriptor&&) = default;

bool ThreadDescriptor::operator==(const ThreadDescriptor& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(pid_, other.pid_)
   && ::protozero::internal::gen_helpers::EqualsField(tid_, other.tid_)
   && ::protozero::internal::gen_helpers::EqualsField(thread_name_, other.thread_name_)
   && ::protozero::internal::gen_helpers::EqualsField(chrome_thread_type_, other.chrome_thread_type_)
   && ::protozero::internal::gen_helpers::EqualsField(reference_timestamp_us_, other.reference_timestamp_us_)
   && ::protozero::internal::gen_helpers::EqualsField(reference_thread_time_us_, other.reference_thread_time_us_)
   && ::protozero::internal::gen_helpers::EqualsField(reference_thread_instruction_count_, other.reference_thread_instruction_count_)
   && ::protozero::internal::gen_helpers::EqualsField(legacy_sort_index_, other.legacy_sort_index_);
}

bool ThreadDescriptor::ParseFromArray(const void* raw, size_t size) {
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* pid */:
        field.get(&pid_);
        break;
      case 2 /* tid */:
        field.get(&tid_);
        break;
      case 5 /* thread_name */:
        ::protozero::internal::gen_helpers::DeserializeString(field, &thread_name_);
        break;
      case 4 /* chrome_thread_type */:
        field.get(&chrome_thread_type_);
        break;
      case 6 /* reference_timestamp_us */:
        field.get(&reference_timestamp_us_);
        break;
      case 7 /* reference_thread_time_us */:
        field.get(&reference_thread_time_us_);
        break;
      case 8 /* reference_thread_instruction_count */:
        field.get(&reference_thread_instruction_count_);
        break;
      case 3 /* legacy_sort_index */:
        field.get(&legacy_sort_index_);
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string ThreadDescriptor::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> ThreadDescriptor::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void ThreadDescriptor::Serialize(::protozero::Message* msg) const {
  // Field 1: pid
  if (_has_field_[1]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(1, pid_, msg);
  }

  // Field 2: tid
  if (_has_field_[2]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(2, tid_, msg);
  }

  // Field 5: thread_name
  if (_has_field_[5]) {
    ::protozero::internal::gen_helpers::SerializeString(5, thread_name_, msg);
  }

  // Field 4: chrome_thread_type
  if (_has_field_[4]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(4, chrome_thread_type_, msg);
  }

  // Field 6: reference_timestamp_us
  if (_has_field_[6]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(6, reference_timestamp_us_, msg);
  }

  // Field 7: reference_thread_time_us
  if (_has_field_[7]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(7, reference_thread_time_us_, msg);
  }

  // Field 8: reference_thread_instruction_count
  if (_has_field_[8]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(8, reference_thread_instruction_count_, msg);
  }

  // Field 3: legacy_sort_index
  if (_has_field_[3]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(3, legacy_sort_index_, msg);
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}

}  // namespace perfetto
}  // namespace protos
}  // namespace gen
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic pop
#endif
// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/track_descriptor.gen.cc
// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wfloat-equal"
#endif
// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/track_descriptor.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/counter_descriptor.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/thread_descriptor.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/process_descriptor.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_thread_descriptor.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_process_descriptor.gen.h"

namespace perfetto {
namespace protos {
namespace gen {

TrackDescriptor::TrackDescriptor() = default;
TrackDescriptor::~TrackDescriptor() = default;
TrackDescriptor::TrackDescriptor(const TrackDescriptor&) = default;
TrackDescriptor& TrackDescriptor::operator=(const TrackDescriptor&) = default;
TrackDescriptor::TrackDescriptor(TrackDescriptor&&) noexcept = default;
TrackDescriptor& TrackDescriptor::operator=(TrackDescriptor&&) = default;

bool TrackDescriptor::operator==(const TrackDescriptor& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(uuid_, other.uuid_)
   && ::protozero::internal::gen_helpers::EqualsField(parent_uuid_, other.parent_uuid_)
   && ::protozero::internal::gen_helpers::EqualsField(name_, other.name_)
   && ::protozero::internal::gen_helpers::EqualsField(process_, other.process_)
   && ::protozero::internal::gen_helpers::EqualsField(chrome_process_, other.chrome_process_)
   && ::protozero::internal::gen_helpers::EqualsField(thread_, other.thread_)
   && ::protozero::internal::gen_helpers::EqualsField(chrome_thread_, other.chrome_thread_)
   && ::protozero::internal::gen_helpers::EqualsField(counter_, other.counter_)
   && ::protozero::internal::gen_helpers::EqualsField(disallow_merging_with_system_tracks_, other.disallow_merging_with_system_tracks_);
}

bool TrackDescriptor::ParseFromArray(const void* raw, size_t size) {
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* uuid */:
        field.get(&uuid_);
        break;
      case 5 /* parent_uuid */:
        field.get(&parent_uuid_);
        break;
      case 2 /* name */:
        ::protozero::internal::gen_helpers::DeserializeString(field, &name_);
        break;
      case 3 /* process */:
        (*process_).ParseFromArray(field.data(), field.size());
        break;
      case 6 /* chrome_process */:
        (*chrome_process_).ParseFromArray(field.data(), field.size());
        break;
      case 4 /* thread */:
        (*thread_).ParseFromArray(field.data(), field.size());
        break;
      case 7 /* chrome_thread */:
        (*chrome_thread_).ParseFromArray(field.data(), field.size());
        break;
      case 8 /* counter */:
        (*counter_).ParseFromArray(field.data(), field.size());
        break;
      case 9 /* disallow_merging_with_system_tracks */:
        field.get(&disallow_merging_with_system_tracks_);
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string TrackDescriptor::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> TrackDescriptor::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void TrackDescriptor::Serialize(::protozero::Message* msg) const {
  // Field 1: uuid
  if (_has_field_[1]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(1, uuid_, msg);
  }

  // Field 5: parent_uuid
  if (_has_field_[5]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(5, parent_uuid_, msg);
  }

  // Field 2: name
  if (_has_field_[2]) {
    ::protozero::internal::gen_helpers::SerializeString(2, name_, msg);
  }

  // Field 3: process
  if (_has_field_[3]) {
    (*process_).Serialize(msg->BeginNestedMessage<::protozero::Message>(3));
  }

  // Field 6: chrome_process
  if (_has_field_[6]) {
    (*chrome_process_).Serialize(msg->BeginNestedMessage<::protozero::Message>(6));
  }

  // Field 4: thread
  if (_has_field_[4]) {
    (*thread_).Serialize(msg->BeginNestedMessage<::protozero::Message>(4));
  }

  // Field 7: chrome_thread
  if (_has_field_[7]) {
    (*chrome_thread_).Serialize(msg->BeginNestedMessage<::protozero::Message>(7));
  }

  // Field 8: counter
  if (_has_field_[8]) {
    (*counter_).Serialize(msg->BeginNestedMessage<::protozero::Message>(8));
  }

  // Field 9: disallow_merging_with_system_tracks
  if (_has_field_[9]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(9, disallow_merging_with_system_tracks_, msg);
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}

}  // namespace perfetto
}  // namespace protos
}  // namespace gen
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic pop
#endif
// gen_amalgamated begin source: gen/protos/perfetto/trace/track_event/track_event.gen.cc
// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wfloat-equal"
#endif
// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/track_event.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/source_location.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/screenshot.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/pixel_modem.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_window_handle_event_info.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_user_event.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_renderer_scheduler_state.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_mojo_event_info.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_message_pump.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_legacy_ipc.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_latency_info.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_keyed_service.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_histogram_sample.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_frame_reporter.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_content_settings_event_info.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_compositor_scheduler_state.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_application_state_info.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/chrome_active_processes.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/task_execution.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/log_message.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/debug_annotation.gen.h"

namespace perfetto {
namespace protos {
namespace gen {

EventName::EventName() = default;
EventName::~EventName() = default;
EventName::EventName(const EventName&) = default;
EventName& EventName::operator=(const EventName&) = default;
EventName::EventName(EventName&&) noexcept = default;
EventName& EventName::operator=(EventName&&) = default;

bool EventName::operator==(const EventName& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(iid_, other.iid_)
   && ::protozero::internal::gen_helpers::EqualsField(name_, other.name_);
}

bool EventName::ParseFromArray(const void* raw, size_t size) {
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* iid */:
        field.get(&iid_);
        break;
      case 2 /* name */:
        ::protozero::internal::gen_helpers::DeserializeString(field, &name_);
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string EventName::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> EventName::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void EventName::Serialize(::protozero::Message* msg) const {
  // Field 1: iid
  if (_has_field_[1]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(1, iid_, msg);
  }

  // Field 2: name
  if (_has_field_[2]) {
    ::protozero::internal::gen_helpers::SerializeString(2, name_, msg);
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}


EventCategory::EventCategory() = default;
EventCategory::~EventCategory() = default;
EventCategory::EventCategory(const EventCategory&) = default;
EventCategory& EventCategory::operator=(const EventCategory&) = default;
EventCategory::EventCategory(EventCategory&&) noexcept = default;
EventCategory& EventCategory::operator=(EventCategory&&) = default;

bool EventCategory::operator==(const EventCategory& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(iid_, other.iid_)
   && ::protozero::internal::gen_helpers::EqualsField(name_, other.name_);
}

bool EventCategory::ParseFromArray(const void* raw, size_t size) {
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* iid */:
        field.get(&iid_);
        break;
      case 2 /* name */:
        ::protozero::internal::gen_helpers::DeserializeString(field, &name_);
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string EventCategory::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> EventCategory::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void EventCategory::Serialize(::protozero::Message* msg) const {
  // Field 1: iid
  if (_has_field_[1]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(1, iid_, msg);
  }

  // Field 2: name
  if (_has_field_[2]) {
    ::protozero::internal::gen_helpers::SerializeString(2, name_, msg);
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}


TrackEventDefaults::TrackEventDefaults() = default;
TrackEventDefaults::~TrackEventDefaults() = default;
TrackEventDefaults::TrackEventDefaults(const TrackEventDefaults&) = default;
TrackEventDefaults& TrackEventDefaults::operator=(const TrackEventDefaults&) = default;
TrackEventDefaults::TrackEventDefaults(TrackEventDefaults&&) noexcept = default;
TrackEventDefaults& TrackEventDefaults::operator=(TrackEventDefaults&&) = default;

bool TrackEventDefaults::operator==(const TrackEventDefaults& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(track_uuid_, other.track_uuid_)
   && ::protozero::internal::gen_helpers::EqualsField(extra_counter_track_uuids_, other.extra_counter_track_uuids_)
   && ::protozero::internal::gen_helpers::EqualsField(extra_double_counter_track_uuids_, other.extra_double_counter_track_uuids_);
}

bool TrackEventDefaults::ParseFromArray(const void* raw, size_t size) {
  extra_counter_track_uuids_.clear();
  extra_double_counter_track_uuids_.clear();
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 11 /* track_uuid */:
        field.get(&track_uuid_);
        break;
      case 31 /* extra_counter_track_uuids */:
        extra_counter_track_uuids_.emplace_back();
        field.get(&extra_counter_track_uuids_.back());
        break;
      case 45 /* extra_double_counter_track_uuids */:
        extra_double_counter_track_uuids_.emplace_back();
        field.get(&extra_double_counter_track_uuids_.back());
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string TrackEventDefaults::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> TrackEventDefaults::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void TrackEventDefaults::Serialize(::protozero::Message* msg) const {
  // Field 11: track_uuid
  if (_has_field_[11]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(11, track_uuid_, msg);
  }

  // Field 31: extra_counter_track_uuids
  for (auto& it : extra_counter_track_uuids_) {
    ::protozero::internal::gen_helpers::SerializeVarInt(31, it, msg);
  }

  // Field 45: extra_double_counter_track_uuids
  for (auto& it : extra_double_counter_track_uuids_) {
    ::protozero::internal::gen_helpers::SerializeVarInt(45, it, msg);
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}


TrackEvent::TrackEvent() = default;
TrackEvent::~TrackEvent() = default;
TrackEvent::TrackEvent(const TrackEvent&) = default;
TrackEvent& TrackEvent::operator=(const TrackEvent&) = default;
TrackEvent::TrackEvent(TrackEvent&&) noexcept = default;
TrackEvent& TrackEvent::operator=(TrackEvent&&) = default;

bool TrackEvent::operator==(const TrackEvent& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(category_iids_, other.category_iids_)
   && ::protozero::internal::gen_helpers::EqualsField(categories_, other.categories_)
   && ::protozero::internal::gen_helpers::EqualsField(name_iid_, other.name_iid_)
   && ::protozero::internal::gen_helpers::EqualsField(name_, other.name_)
   && ::protozero::internal::gen_helpers::EqualsField(type_, other.type_)
   && ::protozero::internal::gen_helpers::EqualsField(track_uuid_, other.track_uuid_)
   && ::protozero::internal::gen_helpers::EqualsField(counter_value_, other.counter_value_)
   && ::protozero::internal::gen_helpers::EqualsField(double_counter_value_, other.double_counter_value_)
   && ::protozero::internal::gen_helpers::EqualsField(extra_counter_track_uuids_, other.extra_counter_track_uuids_)
   && ::protozero::internal::gen_helpers::EqualsField(extra_counter_values_, other.extra_counter_values_)
   && ::protozero::internal::gen_helpers::EqualsField(extra_double_counter_track_uuids_, other.extra_double_counter_track_uuids_)
   && ::protozero::internal::gen_helpers::EqualsField(extra_double_counter_values_, other.extra_double_counter_values_)
   && ::protozero::internal::gen_helpers::EqualsField(flow_ids_old_, other.flow_ids_old_)
   && ::protozero::internal::gen_helpers::EqualsField(flow_ids_, other.flow_ids_)
   && ::protozero::internal::gen_helpers::EqualsField(terminating_flow_ids_old_, other.terminating_flow_ids_old_)
   && ::protozero::internal::gen_helpers::EqualsField(terminating_flow_ids_, other.terminating_flow_ids_)
   && ::protozero::internal::gen_helpers::EqualsField(debug_annotations_, other.debug_annotations_)
   && ::protozero::internal::gen_helpers::EqualsField(task_execution_, other.task_execution_)
   && ::protozero::internal::gen_helpers::EqualsField(log_message_, other.log_message_)
   && ::protozero::internal::gen_helpers::EqualsField(cc_scheduler_state_, other.cc_scheduler_state_)
   && ::protozero::internal::gen_helpers::EqualsField(chrome_user_event_, other.chrome_user_event_)
   && ::protozero::internal::gen_helpers::EqualsField(chrome_keyed_service_, other.chrome_keyed_service_)
   && ::protozero::internal::gen_helpers::EqualsField(chrome_legacy_ipc_, other.chrome_legacy_ipc_)
   && ::protozero::internal::gen_helpers::EqualsField(chrome_histogram_sample_, other.chrome_histogram_sample_)
   && ::protozero::internal::gen_helpers::EqualsField(chrome_latency_info_, other.chrome_latency_info_)
   && ::protozero::internal::gen_helpers::EqualsField(chrome_frame_reporter_, other.chrome_frame_reporter_)
   && ::protozero::internal::gen_helpers::EqualsField(chrome_application_state_info_, other.chrome_application_state_info_)
   && ::protozero::internal::gen_helpers::EqualsField(chrome_renderer_scheduler_state_, other.chrome_renderer_scheduler_state_)
   && ::protozero::internal::gen_helpers::EqualsField(chrome_window_handle_event_info_, other.chrome_window_handle_event_info_)
   && ::protozero::internal::gen_helpers::EqualsField(chrome_content_settings_event_info_, other.chrome_content_settings_event_info_)
   && ::protozero::internal::gen_helpers::EqualsField(chrome_active_processes_, other.chrome_active_processes_)
   && ::protozero::internal::gen_helpers::EqualsField(screenshot_, other.screenshot_)
   && ::protozero::internal::gen_helpers::EqualsField(pixel_modem_event_insight_, other.pixel_modem_event_insight_)
   && ::protozero::internal::gen_helpers::EqualsField(source_location_, other.source_location_)
   && ::protozero::internal::gen_helpers::EqualsField(source_location_iid_, other.source_location_iid_)
   && ::protozero::internal::gen_helpers::EqualsField(chrome_message_pump_, other.chrome_message_pump_)
   && ::protozero::internal::gen_helpers::EqualsField(chrome_mojo_event_info_, other.chrome_mojo_event_info_)
   && ::protozero::internal::gen_helpers::EqualsField(timestamp_delta_us_, other.timestamp_delta_us_)
   && ::protozero::internal::gen_helpers::EqualsField(timestamp_absolute_us_, other.timestamp_absolute_us_)
   && ::protozero::internal::gen_helpers::EqualsField(thread_time_delta_us_, other.thread_time_delta_us_)
   && ::protozero::internal::gen_helpers::EqualsField(thread_time_absolute_us_, other.thread_time_absolute_us_)
   && ::protozero::internal::gen_helpers::EqualsField(thread_instruction_count_delta_, other.thread_instruction_count_delta_)
   && ::protozero::internal::gen_helpers::EqualsField(thread_instruction_count_absolute_, other.thread_instruction_count_absolute_)
   && ::protozero::internal::gen_helpers::EqualsField(legacy_event_, other.legacy_event_);
}

int TrackEvent::debug_annotations_size() const { return static_cast<int>(debug_annotations_.size()); }
void TrackEvent::clear_debug_annotations() { debug_annotations_.clear(); }
DebugAnnotation* TrackEvent::add_debug_annotations() { debug_annotations_.emplace_back(); return &debug_annotations_.back(); }
bool TrackEvent::ParseFromArray(const void* raw, size_t size) {
  category_iids_.clear();
  categories_.clear();
  extra_counter_track_uuids_.clear();
  extra_counter_values_.clear();
  extra_double_counter_track_uuids_.clear();
  extra_double_counter_values_.clear();
  flow_ids_old_.clear();
  flow_ids_.clear();
  terminating_flow_ids_old_.clear();
  terminating_flow_ids_.clear();
  debug_annotations_.clear();
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 3 /* category_iids */:
        category_iids_.emplace_back();
        field.get(&category_iids_.back());
        break;
      case 22 /* categories */:
        categories_.emplace_back();
        ::protozero::internal::gen_helpers::DeserializeString(field, &categories_.back());
        break;
      case 10 /* name_iid */:
        field.get(&name_iid_);
        break;
      case 23 /* name */:
        ::protozero::internal::gen_helpers::DeserializeString(field, &name_);
        break;
      case 9 /* type */:
        field.get(&type_);
        break;
      case 11 /* track_uuid */:
        field.get(&track_uuid_);
        break;
      case 30 /* counter_value */:
        field.get(&counter_value_);
        break;
      case 44 /* double_counter_value */:
        field.get(&double_counter_value_);
        break;
      case 31 /* extra_counter_track_uuids */:
        extra_counter_track_uuids_.emplace_back();
        field.get(&extra_counter_track_uuids_.back());
        break;
      case 12 /* extra_counter_values */:
        extra_counter_values_.emplace_back();
        field.get(&extra_counter_values_.back());
        break;
      case 45 /* extra_double_counter_track_uuids */:
        extra_double_counter_track_uuids_.emplace_back();
        field.get(&extra_double_counter_track_uuids_.back());
        break;
      case 46 /* extra_double_counter_values */:
        extra_double_counter_values_.emplace_back();
        field.get(&extra_double_counter_values_.back());
        break;
      case 36 /* flow_ids_old */:
        flow_ids_old_.emplace_back();
        field.get(&flow_ids_old_.back());
        break;
      case 47 /* flow_ids */:
        flow_ids_.emplace_back();
        field.get(&flow_ids_.back());
        break;
      case 42 /* terminating_flow_ids_old */:
        terminating_flow_ids_old_.emplace_back();
        field.get(&terminating_flow_ids_old_.back());
        break;
      case 48 /* terminating_flow_ids */:
        terminating_flow_ids_.emplace_back();
        field.get(&terminating_flow_ids_.back());
        break;
      case 4 /* debug_annotations */:
        debug_annotations_.emplace_back();
        debug_annotations_.back().ParseFromArray(field.data(), field.size());
        break;
      case 5 /* task_execution */:
        (*task_execution_).ParseFromArray(field.data(), field.size());
        break;
      case 21 /* log_message */:
        (*log_message_).ParseFromArray(field.data(), field.size());
        break;
      case 24 /* cc_scheduler_state */:
        (*cc_scheduler_state_).ParseFromArray(field.data(), field.size());
        break;
      case 25 /* chrome_user_event */:
        (*chrome_user_event_).ParseFromArray(field.data(), field.size());
        break;
      case 26 /* chrome_keyed_service */:
        (*chrome_keyed_service_).ParseFromArray(field.data(), field.size());
        break;
      case 27 /* chrome_legacy_ipc */:
        (*chrome_legacy_ipc_).ParseFromArray(field.data(), field.size());
        break;
      case 28 /* chrome_histogram_sample */:
        (*chrome_histogram_sample_).ParseFromArray(field.data(), field.size());
        break;
      case 29 /* chrome_latency_info */:
        (*chrome_latency_info_).ParseFromArray(field.data(), field.size());
        break;
      case 32 /* chrome_frame_reporter */:
        (*chrome_frame_reporter_).ParseFromArray(field.data(), field.size());
        break;
      case 39 /* chrome_application_state_info */:
        (*chrome_application_state_info_).ParseFromArray(field.data(), field.size());
        break;
      case 40 /* chrome_renderer_scheduler_state */:
        (*chrome_renderer_scheduler_state_).ParseFromArray(field.data(), field.size());
        break;
      case 41 /* chrome_window_handle_event_info */:
        (*chrome_window_handle_event_info_).ParseFromArray(field.data(), field.size());
        break;
      case 43 /* chrome_content_settings_event_info */:
        (*chrome_content_settings_event_info_).ParseFromArray(field.data(), field.size());
        break;
      case 49 /* chrome_active_processes */:
        (*chrome_active_processes_).ParseFromArray(field.data(), field.size());
        break;
      case 50 /* screenshot */:
        (*screenshot_).ParseFromArray(field.data(), field.size());
        break;
      case 51 /* pixel_modem_event_insight */:
        (*pixel_modem_event_insight_).ParseFromArray(field.data(), field.size());
        break;
      case 33 /* source_location */:
        (*source_location_).ParseFromArray(field.data(), field.size());
        break;
      case 34 /* source_location_iid */:
        field.get(&source_location_iid_);
        break;
      case 35 /* chrome_message_pump */:
        (*chrome_message_pump_).ParseFromArray(field.data(), field.size());
        break;
      case 38 /* chrome_mojo_event_info */:
        (*chrome_mojo_event_info_).ParseFromArray(field.data(), field.size());
        break;
      case 1 /* timestamp_delta_us */:
        field.get(&timestamp_delta_us_);
        break;
      case 16 /* timestamp_absolute_us */:
        field.get(&timestamp_absolute_us_);
        break;
      case 2 /* thread_time_delta_us */:
        field.get(&thread_time_delta_us_);
        break;
      case 17 /* thread_time_absolute_us */:
        field.get(&thread_time_absolute_us_);
        break;
      case 8 /* thread_instruction_count_delta */:
        field.get(&thread_instruction_count_delta_);
        break;
      case 20 /* thread_instruction_count_absolute */:
        field.get(&thread_instruction_count_absolute_);
        break;
      case 6 /* legacy_event */:
        (*legacy_event_).ParseFromArray(field.data(), field.size());
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string TrackEvent::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> TrackEvent::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void TrackEvent::Serialize(::protozero::Message* msg) const {
  // Field 3: category_iids
  for (auto& it : category_iids_) {
    ::protozero::internal::gen_helpers::SerializeVarInt(3, it, msg);
  }

  // Field 22: categories
  for (auto& it : categories_) {
    ::protozero::internal::gen_helpers::SerializeString(22, it, msg);
  }

  // Field 10: name_iid
  if (_has_field_[10]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(10, name_iid_, msg);
  }

  // Field 23: name
  if (_has_field_[23]) {
    ::protozero::internal::gen_helpers::SerializeString(23, name_, msg);
  }

  // Field 9: type
  if (_has_field_[9]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(9, type_, msg);
  }

  // Field 11: track_uuid
  if (_has_field_[11]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(11, track_uuid_, msg);
  }

  // Field 30: counter_value
  if (_has_field_[30]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(30, counter_value_, msg);
  }

  // Field 44: double_counter_value
  if (_has_field_[44]) {
    ::protozero::internal::gen_helpers::SerializeFixed(44, double_counter_value_, msg);
  }

  // Field 31: extra_counter_track_uuids
  for (auto& it : extra_counter_track_uuids_) {
    ::protozero::internal::gen_helpers::SerializeVarInt(31, it, msg);
  }

  // Field 12: extra_counter_values
  for (auto& it : extra_counter_values_) {
    ::protozero::internal::gen_helpers::SerializeVarInt(12, it, msg);
  }

  // Field 45: extra_double_counter_track_uuids
  for (auto& it : extra_double_counter_track_uuids_) {
    ::protozero::internal::gen_helpers::SerializeVarInt(45, it, msg);
  }

  // Field 46: extra_double_counter_values
  for (auto& it : extra_double_counter_values_) {
    ::protozero::internal::gen_helpers::SerializeFixed(46, it, msg);
  }

  // Field 36: flow_ids_old
  for (auto& it : flow_ids_old_) {
    ::protozero::internal::gen_helpers::SerializeVarInt(36, it, msg);
  }

  // Field 47: flow_ids
  for (auto& it : flow_ids_) {
    ::protozero::internal::gen_helpers::SerializeFixed(47, it, msg);
  }

  // Field 42: terminating_flow_ids_old
  for (auto& it : terminating_flow_ids_old_) {
    ::protozero::internal::gen_helpers::SerializeVarInt(42, it, msg);
  }

  // Field 48: terminating_flow_ids
  for (auto& it : terminating_flow_ids_) {
    ::protozero::internal::gen_helpers::SerializeFixed(48, it, msg);
  }

  // Field 4: debug_annotations
  for (auto& it : debug_annotations_) {
    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(4));
  }

  // Field 5: task_execution
  if (_has_field_[5]) {
    (*task_execution_).Serialize(msg->BeginNestedMessage<::protozero::Message>(5));
  }

  // Field 21: log_message
  if (_has_field_[21]) {
    (*log_message_).Serialize(msg->BeginNestedMessage<::protozero::Message>(21));
  }

  // Field 24: cc_scheduler_state
  if (_has_field_[24]) {
    (*cc_scheduler_state_).Serialize(msg->BeginNestedMessage<::protozero::Message>(24));
  }

  // Field 25: chrome_user_event
  if (_has_field_[25]) {
    (*chrome_user_event_).Serialize(msg->BeginNestedMessage<::protozero::Message>(25));
  }

  // Field 26: chrome_keyed_service
  if (_has_field_[26]) {
    (*chrome_keyed_service_).Serialize(msg->BeginNestedMessage<::protozero::Message>(26));
  }

  // Field 27: chrome_legacy_ipc
  if (_has_field_[27]) {
    (*chrome_legacy_ipc_).Serialize(msg->BeginNestedMessage<::protozero::Message>(27));
  }

  // Field 28: chrome_histogram_sample
  if (_has_field_[28]) {
    (*chrome_histogram_sample_).Serialize(msg->BeginNestedMessage<::protozero::Message>(28));
  }

  // Field 29: chrome_latency_info
  if (_has_field_[29]) {
    (*chrome_latency_info_).Serialize(msg->BeginNestedMessage<::protozero::Message>(29));
  }

  // Field 32: chrome_frame_reporter
  if (_has_field_[32]) {
    (*chrome_frame_reporter_).Serialize(msg->BeginNestedMessage<::protozero::Message>(32));
  }

  // Field 39: chrome_application_state_info
  if (_has_field_[39]) {
    (*chrome_application_state_info_).Serialize(msg->BeginNestedMessage<::protozero::Message>(39));
  }

  // Field 40: chrome_renderer_scheduler_state
  if (_has_field_[40]) {
    (*chrome_renderer_scheduler_state_).Serialize(msg->BeginNestedMessage<::protozero::Message>(40));
  }

  // Field 41: chrome_window_handle_event_info
  if (_has_field_[41]) {
    (*chrome_window_handle_event_info_).Serialize(msg->BeginNestedMessage<::protozero::Message>(41));
  }

  // Field 43: chrome_content_settings_event_info
  if (_has_field_[43]) {
    (*chrome_content_settings_event_info_).Serialize(msg->BeginNestedMessage<::protozero::Message>(43));
  }

  // Field 49: chrome_active_processes
  if (_has_field_[49]) {
    (*chrome_active_processes_).Serialize(msg->BeginNestedMessage<::protozero::Message>(49));
  }

  // Field 50: screenshot
  if (_has_field_[50]) {
    (*screenshot_).Serialize(msg->BeginNestedMessage<::protozero::Message>(50));
  }

  // Field 51: pixel_modem_event_insight
  if (_has_field_[51]) {
    (*pixel_modem_event_insight_).Serialize(msg->BeginNestedMessage<::protozero::Message>(51));
  }

  // Field 33: source_location
  if (_has_field_[33]) {
    (*source_location_).Serialize(msg->BeginNestedMessage<::protozero::Message>(33));
  }

  // Field 34: source_location_iid
  if (_has_field_[34]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(34, source_location_iid_, msg);
  }

  // Field 35: chrome_message_pump
  if (_has_field_[35]) {
    (*chrome_message_pump_).Serialize(msg->BeginNestedMessage<::protozero::Message>(35));
  }

  // Field 38: chrome_mojo_event_info
  if (_has_field_[38]) {
    (*chrome_mojo_event_info_).Serialize(msg->BeginNestedMessage<::protozero::Message>(38));
  }

  // Field 1: timestamp_delta_us
  if (_has_field_[1]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(1, timestamp_delta_us_, msg);
  }

  // Field 16: timestamp_absolute_us
  if (_has_field_[16]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(16, timestamp_absolute_us_, msg);
  }

  // Field 2: thread_time_delta_us
  if (_has_field_[2]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(2, thread_time_delta_us_, msg);
  }

  // Field 17: thread_time_absolute_us
  if (_has_field_[17]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(17, thread_time_absolute_us_, msg);
  }

  // Field 8: thread_instruction_count_delta
  if (_has_field_[8]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(8, thread_instruction_count_delta_, msg);
  }

  // Field 20: thread_instruction_count_absolute
  if (_has_field_[20]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(20, thread_instruction_count_absolute_, msg);
  }

  // Field 6: legacy_event
  if (_has_field_[6]) {
    (*legacy_event_).Serialize(msg->BeginNestedMessage<::protozero::Message>(6));
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}


TrackEvent_LegacyEvent::TrackEvent_LegacyEvent() = default;
TrackEvent_LegacyEvent::~TrackEvent_LegacyEvent() = default;
TrackEvent_LegacyEvent::TrackEvent_LegacyEvent(const TrackEvent_LegacyEvent&) = default;
TrackEvent_LegacyEvent& TrackEvent_LegacyEvent::operator=(const TrackEvent_LegacyEvent&) = default;
TrackEvent_LegacyEvent::TrackEvent_LegacyEvent(TrackEvent_LegacyEvent&&) noexcept = default;
TrackEvent_LegacyEvent& TrackEvent_LegacyEvent::operator=(TrackEvent_LegacyEvent&&) = default;

bool TrackEvent_LegacyEvent::operator==(const TrackEvent_LegacyEvent& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(name_iid_, other.name_iid_)
   && ::protozero::internal::gen_helpers::EqualsField(phase_, other.phase_)
   && ::protozero::internal::gen_helpers::EqualsField(duration_us_, other.duration_us_)
   && ::protozero::internal::gen_helpers::EqualsField(thread_duration_us_, other.thread_duration_us_)
   && ::protozero::internal::gen_helpers::EqualsField(thread_instruction_delta_, other.thread_instruction_delta_)
   && ::protozero::internal::gen_helpers::EqualsField(unscoped_id_, other.unscoped_id_)
   && ::protozero::internal::gen_helpers::EqualsField(local_id_, other.local_id_)
   && ::protozero::internal::gen_helpers::EqualsField(global_id_, other.global_id_)
   && ::protozero::internal::gen_helpers::EqualsField(id_scope_, other.id_scope_)
   && ::protozero::internal::gen_helpers::EqualsField(use_async_tts_, other.use_async_tts_)
   && ::protozero::internal::gen_helpers::EqualsField(bind_id_, other.bind_id_)
   && ::protozero::internal::gen_helpers::EqualsField(bind_to_enclosing_, other.bind_to_enclosing_)
   && ::protozero::internal::gen_helpers::EqualsField(flow_direction_, other.flow_direction_)
   && ::protozero::internal::gen_helpers::EqualsField(instant_event_scope_, other.instant_event_scope_)
   && ::protozero::internal::gen_helpers::EqualsField(pid_override_, other.pid_override_)
   && ::protozero::internal::gen_helpers::EqualsField(tid_override_, other.tid_override_);
}

bool TrackEvent_LegacyEvent::ParseFromArray(const void* raw, size_t size) {
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* name_iid */:
        field.get(&name_iid_);
        break;
      case 2 /* phase */:
        field.get(&phase_);
        break;
      case 3 /* duration_us */:
        field.get(&duration_us_);
        break;
      case 4 /* thread_duration_us */:
        field.get(&thread_duration_us_);
        break;
      case 15 /* thread_instruction_delta */:
        field.get(&thread_instruction_delta_);
        break;
      case 6 /* unscoped_id */:
        field.get(&unscoped_id_);
        break;
      case 10 /* local_id */:
        field.get(&local_id_);
        break;
      case 11 /* global_id */:
        field.get(&global_id_);
        break;
      case 7 /* id_scope */:
        ::protozero::internal::gen_helpers::DeserializeString(field, &id_scope_);
        break;
      case 9 /* use_async_tts */:
        field.get(&use_async_tts_);
        break;
      case 8 /* bind_id */:
        field.get(&bind_id_);
        break;
      case 12 /* bind_to_enclosing */:
        field.get(&bind_to_enclosing_);
        break;
      case 13 /* flow_direction */:
        field.get(&flow_direction_);
        break;
      case 14 /* instant_event_scope */:
        field.get(&instant_event_scope_);
        break;
      case 18 /* pid_override */:
        field.get(&pid_override_);
        break;
      case 19 /* tid_override */:
        field.get(&tid_override_);
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string TrackEvent_LegacyEvent::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> TrackEvent_LegacyEvent::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void TrackEvent_LegacyEvent::Serialize(::protozero::Message* msg) const {
  // Field 1: name_iid
  if (_has_field_[1]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(1, name_iid_, msg);
  }

  // Field 2: phase
  if (_has_field_[2]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(2, phase_, msg);
  }

  // Field 3: duration_us
  if (_has_field_[3]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(3, duration_us_, msg);
  }

  // Field 4: thread_duration_us
  if (_has_field_[4]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(4, thread_duration_us_, msg);
  }

  // Field 15: thread_instruction_delta
  if (_has_field_[15]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(15, thread_instruction_delta_, msg);
  }

  // Field 6: unscoped_id
  if (_has_field_[6]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(6, unscoped_id_, msg);
  }

  // Field 10: local_id
  if (_has_field_[10]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(10, local_id_, msg);
  }

  // Field 11: global_id
  if (_has_field_[11]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(11, global_id_, msg);
  }

  // Field 7: id_scope
  if (_has_field_[7]) {
    ::protozero::internal::gen_helpers::SerializeString(7, id_scope_, msg);
  }

  // Field 9: use_async_tts
  if (_has_field_[9]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(9, use_async_tts_, msg);
  }

  // Field 8: bind_id
  if (_has_field_[8]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(8, bind_id_, msg);
  }

  // Field 12: bind_to_enclosing
  if (_has_field_[12]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(12, bind_to_enclosing_, msg);
  }

  // Field 13: flow_direction
  if (_has_field_[13]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(13, flow_direction_, msg);
  }

  // Field 14: instant_event_scope
  if (_has_field_[14]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(14, instant_event_scope_, msg);
  }

  // Field 18: pid_override
  if (_has_field_[18]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(18, pid_override_, msg);
  }

  // Field 19: tid_override
  if (_has_field_[19]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(19, tid_override_, msg);
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}

}  // namespace perfetto
}  // namespace protos
}  // namespace gen
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic pop
#endif
// gen_amalgamated begin source: gen/protos/perfetto/config/android/android_game_intervention_list_config.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/config/android/android_input_event_config.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/config/android/android_log_config.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/config/android/android_polled_state_config.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/config/android/android_sdk_sysprop_guard_config.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/config/android/android_system_property_config.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/config/android/network_trace_config.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/config/android/packages_list_config.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/config/android/pixel_modem_config.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/config/android/protolog_config.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/config/android/surfaceflinger_layers_config.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/config/android/surfaceflinger_transactions_config.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/config/ftrace/ftrace_config.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/config/gpu/gpu_counter_config.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/config/gpu/vulkan_memory_config.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/config/inode_file/inode_file_config.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/config/interceptors/console_config.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/config/power/android_power_config.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/config/process_stats/process_stats_config.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/config/profiling/heapprofd_config.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/config/profiling/java_hprof_config.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/config/profiling/perf_event_config.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/config/statsd/atom_ids.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/config/statsd/statsd_tracing_config.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/config/sys_stats/sys_stats_config.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/config/system_info/system_info.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/config/track_event/track_event_config.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/config/chrome/chrome_config.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/config/chrome/scenario_config.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/config/chrome/v8_config.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/config/data_source_config.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/config/etw/etw_config.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/config/interceptor_config.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/config/stress_test_config.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/config/test_config.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/config/trace_config.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/clock_snapshot.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/trace_uuid.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/trigger.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/system_info.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/etw/etw.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/etw/etw_event.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/etw/etw_event_bundle.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/filesystem/inode_file_map.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/ftrace_event.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/ftrace_event_bundle.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/ftrace_stats.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/test_bundle_wrapper.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/generic.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/android_fs.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/binder.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/block.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/cgroup.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/clk.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/cma.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/compaction.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/cpuhp.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/cros_ec.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/dma_fence.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/dmabuf_heap.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/dpu.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/drm.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/ext4.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/f2fs.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/fastrpc.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/fence.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/filemap.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/ftrace.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/g2d.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/google_icc_trace.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/google_irm_trace.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/gpu_mem.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/gpu_scheduler.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/hyp.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/i2c.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/ion.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/ipi.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/irq.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/kmem.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/kvm.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/lowmemorykiller.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/lwis.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/mali.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/mdss.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/mm_event.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/net.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/oom.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/panel.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/perf_trace_counters.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/power.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/printk.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/raw_syscalls.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/regulator.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/rpm.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/samsung.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/sched.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/scm.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/sde.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/signal.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/skb.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/sock.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/sync.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/synthetic.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/systrace.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/task.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/tcp.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/thermal.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/trusty.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/ufs.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/v4l2.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/virtio_gpu.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/virtio_video.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/vmscan.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/ftrace/workqueue.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/perfetto/perfetto_metatrace.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/perfetto/tracing_service_event.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/power/android_energy_estimation_breakdown.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/power/android_entity_state_residency.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/power/battery_counters.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/power/power_rails.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/ps/process_stats.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/ps/process_tree.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/statsd/statsd_atom.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/sys_stats/sys_stats.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/system_info/cpu_info.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/translation/translation_table.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/remote_clock_sync.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/trace_packet_defaults.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/test_event.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/test_extensions.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/trace_packet.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/trace.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/extension_descriptor.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/memory_graph.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: gen/protos/perfetto/trace/ui_state.pbzero.cc
// Intentionally empty (crbug.com/998165)
// gen_amalgamated begin source: src/tracing/trace_writer_base.cc
/*
 * Copyright (C) 2019 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// gen_amalgamated expanded: #include "perfetto/tracing/trace_writer_base.h"

namespace perfetto {

// This destructor needs to be defined in a dedicated translation unit and
// cannot be merged together with the other ones in virtual_destructors.cc.
// This is because trace_writer_base.h/cc  is part of a separate target
// (src/public:common) that is linked also by other part of the codebase.

TraceWriterBase::~TraceWriterBase() = default;

}  // namespace perfetto
// gen_amalgamated begin source: src/tracing/core/clock_snapshots.cc
// gen_amalgamated begin header: include/perfetto/tracing/core/clock_snapshots.h
/*
 * Copyright (C) 2024 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef INCLUDE_PERFETTO_TRACING_CORE_CLOCK_SNAPSHOTS_H_
#define INCLUDE_PERFETTO_TRACING_CORE_CLOCK_SNAPSHOTS_H_

#include <cstdint>
#include <vector>

namespace perfetto {
struct ClockReading {
  ClockReading(uint32_t _clock_id, uint64_t _timestamp)
      : clock_id(_clock_id), timestamp(_timestamp) {}
  ClockReading() = default;

  // Identifier of the clock domain (of type protos::pbzero::BuiltinClock).
  uint32_t clock_id = 0;
  // Clock reading as uint64_t.
  uint64_t timestamp = 0;
};

using ClockSnapshotVector = std::vector<ClockReading>;

// Takes snapshots of clock readings of all supported built-in clocks.
ClockSnapshotVector CaptureClockSnapshots();

}  // namespace perfetto

#endif  // INCLUDE_PERFETTO_TRACING_CORE_CLOCK_SNAPSHOTS_H_
/*
 * Copyright (C) 2024 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// gen_amalgamated expanded: #include "perfetto/tracing/core/clock_snapshots.h"

// gen_amalgamated expanded: #include "perfetto/base/build_config.h"
// gen_amalgamated expanded: #include "perfetto/base/time.h"
// gen_amalgamated expanded: #include "protos/perfetto/common/builtin_clock.pbzero.h"

namespace perfetto {

ClockSnapshotVector CaptureClockSnapshots() {
  ClockSnapshotVector snapshot_data;
#if !PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE) && \
    !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) &&   \
    !PERFETTO_BUILDFLAG(PERFETTO_OS_NACL)
  struct {
    clockid_t id;
    protos::pbzero::BuiltinClock type;
    struct timespec ts;
  } clocks[] = {
      {CLOCK_BOOTTIME, protos::pbzero::BUILTIN_CLOCK_BOOTTIME, {0, 0}},
      {CLOCK_REALTIME_COARSE,
       protos::pbzero::BUILTIN_CLOCK_REALTIME_COARSE,
       {0, 0}},
      {CLOCK_MONOTONIC_COARSE,
       protos::pbzero::BUILTIN_CLOCK_MONOTONIC_COARSE,
       {0, 0}},
      {CLOCK_REALTIME, protos::pbzero::BUILTIN_CLOCK_REALTIME, {0, 0}},
      {CLOCK_MONOTONIC, protos::pbzero::BUILTIN_CLOCK_MONOTONIC, {0, 0}},
      {CLOCK_MONOTONIC_RAW,
       protos::pbzero::BUILTIN_CLOCK_MONOTONIC_RAW,
       {0, 0}},
  };
  // First snapshot all the clocks as atomically as we can.
  for (auto& clock : clocks) {
    if (clock_gettime(clock.id, &clock.ts) == -1)
      PERFETTO_DLOG("clock_gettime failed for clock %d", clock.id);
  }
  for (auto& clock : clocks) {
    snapshot_data.push_back(ClockReading(
        static_cast<uint32_t>(clock.type),
        static_cast<uint64_t>(base::FromPosixTimespec(clock.ts).count())));
  }
#else  // OS_APPLE || OS_WIN && OS_NACL
  auto wall_time_ns = static_cast<uint64_t>(base::GetWallTimeNs().count());
  // The default trace clock is boot time, so we always need to emit a path to
  // it. However since we don't actually have a boot time source on these
  // platforms, pretend that wall time equals boot time.
  snapshot_data.push_back(
      ClockReading(protos::pbzero::BUILTIN_CLOCK_BOOTTIME, wall_time_ns));
  snapshot_data.push_back(
      ClockReading(protos::pbzero::BUILTIN_CLOCK_MONOTONIC, wall_time_ns));
#endif

#if PERFETTO_BUILDFLAG(PERFETTO_ARCH_CPU_X86_64)
  // X86-specific but OS-independent TSC clocksource
  snapshot_data.push_back(
      ClockReading(protos::pbzero::BUILTIN_CLOCK_TSC, base::Rdtsc()));
#endif  // PERFETTO_BUILDFLAG(PERFETTO_ARCH_CPU_X86_64)

  return snapshot_data;
}

}  // namespace perfetto
// gen_amalgamated begin source: src/tracing/core/id_allocator.cc
// gen_amalgamated begin header: src/tracing/core/id_allocator.h
/*
 * Copyright (C) 2017 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef SRC_TRACING_CORE_ID_ALLOCATOR_H_
#define SRC_TRACING_CORE_ID_ALLOCATOR_H_

#include <stdint.h>

#include <cstddef>
#include <type_traits>
#include <vector>

namespace perfetto {

// Handles assigment of IDs (int types) from a fixed-size pool.
// Zero is not considered a valid ID.
// The base class takes always a uint32_t and the derived class casts and checks
// bounds at compile time. This is to avoid bloating code with different
// instances of the main class for each size.
class IdAllocatorGeneric {
 public:
  // |max_id| is inclusive.
  explicit IdAllocatorGeneric(uint32_t max_id);
  ~IdAllocatorGeneric();

  // Returns an ID in the range [1, max_id] or 0 if no more ids are available.
  uint32_t AllocateGeneric();
  void FreeGeneric(uint32_t);

  bool IsEmpty() const;

 private:
  IdAllocatorGeneric(const IdAllocatorGeneric&) = delete;
  IdAllocatorGeneric& operator=(const IdAllocatorGeneric&) = delete;

  const uint32_t max_id_;
  uint32_t last_id_ = 0;
  std::vector<bool> ids_;
};

template <typename T = uint32_t>
class IdAllocator : public IdAllocatorGeneric {
 public:
  explicit IdAllocator(T end) : IdAllocatorGeneric(end) {
    static_assert(std::is_integral<T>::value && std::is_unsigned<T>::value,
                  "T must be an unsigned integer");
    static_assert(sizeof(T) <= sizeof(uint32_t), "T is too big");
  }

  T Allocate() { return static_cast<T>(AllocateGeneric()); }

  // Tries to allocate `n` IDs. Returns a vector of `n` valid IDs or an empty
  // vector, if not enough IDs are available.
  std::vector<T> AllocateMultiple(size_t n) {
    std::vector<T> res;
    res.reserve(n);
    for (size_t i = 0; i < n; i++) {
      T id = Allocate();
      if (id) {
        res.push_back(id);
      } else {
        for (T free_id : res) {
          Free(free_id);
        }
        return {};
      }
    }
    return res;
  }

  void Free(T id) { FreeGeneric(id); }
};

}  // namespace perfetto

#endif  // SRC_TRACING_CORE_ID_ALLOCATOR_H_
/*
 * Copyright (C) 2017 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// gen_amalgamated expanded: #include "src/tracing/core/id_allocator.h"

// gen_amalgamated expanded: #include "perfetto/base/logging.h"

namespace perfetto {

IdAllocatorGeneric::IdAllocatorGeneric(uint32_t max_id) : max_id_(max_id) {
  PERFETTO_DCHECK(max_id > 1);
}

IdAllocatorGeneric::~IdAllocatorGeneric() = default;

uint32_t IdAllocatorGeneric::AllocateGeneric() {
  for (uint32_t ignored = 1; ignored <= max_id_; ignored++) {
    last_id_ = last_id_ < max_id_ ? last_id_ + 1 : 1;
    const auto id = last_id_;

    // 0 is never a valid ID. So if we are looking for |id| == N and there are
    // N or less elements in the vector, they must necessarily be all < N.
    // e.g. if |id| == 4 and size() == 4, the vector will contain IDs 0,1,2,3.
    if (id >= ids_.size()) {
      ids_.resize(id + 1);
      ids_[id] = true;
      return id;
    }

    if (!ids_[id]) {
      ids_[id] = true;
      return id;
    }
  }
  return 0;
}

void IdAllocatorGeneric::FreeGeneric(uint32_t id) {
  if (id == 0 || id >= ids_.size() || !ids_[id]) {
    PERFETTO_DFATAL("Invalid id.");
    return;
  }
  ids_[id] = false;
}

bool IdAllocatorGeneric::IsEmpty() const {
  for (auto id : ids_) {
    if (id)
      return false;
  }
  return true;
}

}  // namespace perfetto
// gen_amalgamated begin source: src/tracing/core/in_process_shared_memory.cc
// gen_amalgamated begin header: src/tracing/core/in_process_shared_memory.h
// gen_amalgamated begin header: include/perfetto/ext/tracing/core/shared_memory.h
/*
 * Copyright (C) 2017 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef INCLUDE_PERFETTO_EXT_TRACING_CORE_SHARED_MEMORY_H_
#define INCLUDE_PERFETTO_EXT_TRACING_CORE_SHARED_MEMORY_H_

#include <stddef.h>

#include <memory>

// gen_amalgamated expanded: #include "perfetto/base/export.h"
// gen_amalgamated expanded: #include "perfetto/base/platform_handle.h"

namespace perfetto {

// An abstract interface that models the shared memory region shared between
// Service and Producer. The concrete implementation of this is up to the
// transport layer. This can be as simple as a malloc()-ed buffer, if both
// Producer and Service are hosted in the same process, or some posix shared
// memory for the out-of-process case (see src/unix_rpc).
// Both this class and the Factory are subclassed by the transport layer, which
// will attach platform specific fields to it (e.g., a unix file descriptor).
class PERFETTO_EXPORT_COMPONENT SharedMemory {
 public:
  class PERFETTO_EXPORT_COMPONENT Factory {
   public:
    virtual ~Factory();
    virtual std::unique_ptr<SharedMemory> CreateSharedMemory(size_t) = 0;
  };

  // The transport layer is expected to tear down the resource associated to
  // this object region when destroyed.
  virtual ~SharedMemory();

  virtual void* start() const = 0;
  virtual size_t size() const = 0;
};

}  // namespace perfetto

#endif  // INCLUDE_PERFETTO_EXT_TRACING_CORE_SHARED_MEMORY_H_
/*
 * Copyright (C) 2023 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef SRC_TRACING_CORE_IN_PROCESS_SHARED_MEMORY_H_
#define SRC_TRACING_CORE_IN_PROCESS_SHARED_MEMORY_H_

#include <memory>

// gen_amalgamated expanded: #include "perfetto/ext/base/paged_memory.h"
// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/shared_memory.h"

namespace perfetto {

// An implementation of the ShareMemory interface that allocates memory that can
// only be shared intra-process.
class InProcessSharedMemory : public SharedMemory {
 public:
  static constexpr size_t kDefaultSize = 128 * 1024;

  // Default ctor used for intra-process shmem between a producer and the
  // service.
  explicit InProcessSharedMemory(size_t size)
      : mem_(base::PagedMemory::Allocate(size)) {}
  ~InProcessSharedMemory() override;

  static std::unique_ptr<InProcessSharedMemory> Create(
      size_t size = kDefaultSize) {
    return std::make_unique<InProcessSharedMemory>(size);
  }

  // SharedMemory implementation.
  void* start() const override;
  size_t size() const override;

  class Factory : public SharedMemory::Factory {
   public:
    ~Factory() override;
    std::unique_ptr<SharedMemory> CreateSharedMemory(size_t size) override {
      return InProcessSharedMemory::Create(size);
    }
  };

 private:
  base::PagedMemory mem_;
};

}  // namespace perfetto

#endif  // SRC_TRACING_CORE_IN_PROCESS_SHARED_MEMORY_H_
/*
 * Copyright (C) 2023 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// gen_amalgamated expanded: #include "src/tracing/core/in_process_shared_memory.h"

namespace perfetto {

InProcessSharedMemory::~InProcessSharedMemory() = default;
InProcessSharedMemory::Factory::~Factory() = default;

void* InProcessSharedMemory::start() const {
  return mem_.Get();
}
size_t InProcessSharedMemory::size() const {
  return mem_.size();
}

}  // namespace perfetto
// gen_amalgamated begin source: src/tracing/core/null_trace_writer.cc
// gen_amalgamated begin header: src/tracing/core/null_trace_writer.h
// gen_amalgamated begin header: include/perfetto/ext/tracing/core/trace_writer.h
// gen_amalgamated begin header: include/perfetto/ext/tracing/core/basic_types.h
/*
 * Copyright (C) 2017 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef INCLUDE_PERFETTO_EXT_TRACING_CORE_BASIC_TYPES_H_
#define INCLUDE_PERFETTO_EXT_TRACING_CORE_BASIC_TYPES_H_

#include <stddef.h>
#include <stdint.h>

// gen_amalgamated expanded: #include "perfetto/ext/base/sys_types.h"

namespace perfetto {

// Unique within the scope of the tracing service.
using TracingSessionID = uint64_t;

// Unique within the scope of the tracing service.
using ProducerID = uint16_t;

// Unique within the scope of the tracing service.
using DataSourceInstanceID = uint64_t;

// Unique within the scope of a Producer.
using WriterID = uint16_t;

// Unique within the scope of the tracing service.
using FlushRequestID = uint64_t;

// Combines Producer and Writer ID in one word which can be used as key for
// hashtables and other data structures.
using ProducerAndWriterID = uint32_t;

inline ProducerAndWriterID MkProducerAndWriterID(ProducerID p, WriterID w) {
  static_assert(
      sizeof(ProducerID) + sizeof(WriterID) == sizeof(ProducerAndWriterID),
      "MkProducerAndWriterID() and GetProducerAndWriterID() need updating");
  return (static_cast<ProducerAndWriterID>(p) << (sizeof(WriterID) * 8)) | w;
}

inline void GetProducerAndWriterID(ProducerAndWriterID x,
                                   ProducerID* p,
                                   WriterID* w) {
  static constexpr auto mask = (1ull << (sizeof(WriterID) * 8)) - 1;
  *w = static_cast<WriterID>(x & mask);
  *p = static_cast<ProducerID>(x >> (sizeof(WriterID) * 8));
}

// We need one FD per producer and we are not going to be able to keep > 64k FDs
// open in the service.
static constexpr ProducerID kMaxProducerID = static_cast<ProducerID>(-1);

// 1024 Writers per producer seems a resonable bound. This reduces the ability
// to memory-DoS the service by having to keep track of too many writer IDs.
static constexpr WriterID kMaxWriterID = static_cast<WriterID>((1 << 10) - 1);

// Unique within the scope of a {ProducerID, WriterID} tuple.
using ChunkID = uint32_t;
static constexpr ChunkID kMaxChunkID = static_cast<ChunkID>(-1);

// Unique within the scope of the tracing service.
using BufferID = uint16_t;

// Target buffer ID for SharedMemoryArbiter. Values up to max uint16_t are
// equivalent to a bound BufferID. Values above max uint16_t are reservation IDs
// for the target buffer of a startup trace writer. Reservation IDs will be
// translated to actual BufferIDs after they are bound by
// SharedMemoryArbiter::BindStartupTargetBuffer().
// TODO(mohitms): Delete this type and use `struct {uint16 ; uint16;}` instead.
using MaybeUnboundBufferID = uint32_t;

// Keep this in sync with SharedMemoryABI::PageHeader::target_buffer.
static constexpr BufferID kMaxTraceBufferID = static_cast<BufferID>(-1);

// Unique within the scope of a tracing session.
using PacketSequenceID = uint32_t;
// Used for extra packets emitted by the service, such as statistics.
static constexpr PacketSequenceID kServicePacketSequenceID = 1;
static constexpr PacketSequenceID kMaxPacketSequenceID =
    static_cast<PacketSequenceID>(-1);

constexpr uint32_t kDefaultFlushTimeoutMs = 5000;

// The special id 0xffff..ffff represents the tracing session with the highest
// bugreport score. This is used for CloneSession(kBugreportSessionId).
constexpr TracingSessionID kBugreportSessionId =
    static_cast<TracingSessionID>(-1);

// The ID of a machine in a multi-machine tracing session.
using MachineID = base::MachineID;
constexpr MachineID kDefaultMachineID = base::kDefaultMachineID;

}  // namespace perfetto

#endif  // INCLUDE_PERFETTO_EXT_TRACING_CORE_BASIC_TYPES_H_
/*
 * Copyright (C) 2017 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef INCLUDE_PERFETTO_EXT_TRACING_CORE_TRACE_WRITER_H_
#define INCLUDE_PERFETTO_EXT_TRACING_CORE_TRACE_WRITER_H_

#include <functional>

// gen_amalgamated expanded: #include "perfetto/base/export.h"
// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/basic_types.h"
// gen_amalgamated expanded: #include "perfetto/protozero/message_handle.h"
// gen_amalgamated expanded: #include "perfetto/tracing/trace_writer_base.h"

namespace perfetto {

namespace protos {
namespace pbzero {
class TracePacket;
}  // namespace pbzero
}  // namespace protos

// See comments in include/perfetto/tracing/trace_writer_base.h
class PERFETTO_EXPORT_COMPONENT TraceWriter : public TraceWriterBase {
 public:
  using TracePacketHandle =
      protozero::MessageHandle<protos::pbzero::TracePacket>;

  TraceWriter();
  ~TraceWriter() override;

  virtual WriterID writer_id() const = 0;

 private:
  TraceWriter(const TraceWriter&) = delete;
  TraceWriter& operator=(const TraceWriter&) = delete;
};

}  // namespace perfetto

#endif  // INCLUDE_PERFETTO_EXT_TRACING_CORE_TRACE_WRITER_H_
/*
 * Copyright (C) 2018 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef SRC_TRACING_CORE_NULL_TRACE_WRITER_H_
#define SRC_TRACING_CORE_NULL_TRACE_WRITER_H_

// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/trace_writer.h"
// gen_amalgamated expanded: #include "perfetto/protozero/message_handle.h"
// gen_amalgamated expanded: #include "perfetto/protozero/root_message.h"
// gen_amalgamated expanded: #include "perfetto/protozero/scattered_stream_null_delegate.h"

namespace perfetto {

// A specialization of TraceWriter which no-ops all the writes routing them
// into a fixed region of memory
// See //include/perfetto/ext/tracing/core/trace_writer.h for docs.
class NullTraceWriter : public TraceWriter {
 public:
  NullTraceWriter();
  ~NullTraceWriter() override;

  // TraceWriter implementation. See documentation in trace_writer.h.
  // TracePacketHandle is defined in trace_writer.h
  TracePacketHandle NewTracePacket() override;
  void FinishTracePacket() override;
  void Flush(std::function<void()> callback = {}) override;
  WriterID writer_id() const override;
  uint64_t written() const override;

 private:
  NullTraceWriter(const NullTraceWriter&) = delete;
  NullTraceWriter& operator=(const NullTraceWriter&) = delete;

  protozero::ScatteredStreamWriterNullDelegate delegate_;
  protozero::ScatteredStreamWriter stream_;

  // The packet returned via NewTracePacket(). It is owned by this class,
  // TracePacketHandle has just a pointer to it.
  std::unique_ptr<protozero::RootMessage<protos::pbzero::TracePacket>>
      cur_packet_;
};

}  // namespace perfetto

#endif  // SRC_TRACING_CORE_NULL_TRACE_WRITER_H_
/*
 * Copyright (C) 2018 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// gen_amalgamated expanded: #include "src/tracing/core/null_trace_writer.h"

// gen_amalgamated expanded: #include "perfetto/base/logging.h"
// gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
// gen_amalgamated expanded: #include "perfetto/protozero/message.h"

// gen_amalgamated expanded: #include "protos/perfetto/trace/trace_packet.pbzero.h"

namespace perfetto {

NullTraceWriter::NullTraceWriter() : delegate_(4096), stream_(&delegate_) {
  cur_packet_.reset(new protozero::RootMessage<protos::pbzero::TracePacket>());
  cur_packet_->Finalize();  // To avoid the DCHECK in NewTracePacket().
}

NullTraceWriter::~NullTraceWriter() {}

void NullTraceWriter::Flush(std::function<void()> callback) {
  // Flush() cannot be called in the middle of a TracePacket.
  PERFETTO_CHECK(cur_packet_->is_finalized());

  if (callback)
    callback();
}

NullTraceWriter::TracePacketHandle NullTraceWriter::NewTracePacket() {
  // If we hit this, the caller is calling NewTracePacket() without having
  // finalized the previous packet.
  PERFETTO_DCHECK(cur_packet_->is_finalized());
  cur_packet_->Reset(&stream_);
  return TraceWriter::TracePacketHandle(cur_packet_.get());
}

void NullTraceWriter::FinishTracePacket() {
  cur_packet_->Finalize();
}

WriterID NullTraceWriter::writer_id() const {
  return 0;
}

uint64_t NullTraceWriter::written() const {
  return 0;
}

}  // namespace perfetto
// gen_amalgamated begin source: src/tracing/core/shared_memory_abi.cc
// gen_amalgamated begin header: include/perfetto/ext/tracing/core/shared_memory_abi.h
/*
 * Copyright (C) 2017 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef INCLUDE_PERFETTO_EXT_TRACING_CORE_SHARED_MEMORY_ABI_H_
#define INCLUDE_PERFETTO_EXT_TRACING_CORE_SHARED_MEMORY_ABI_H_

#include <stddef.h>
#include <stdint.h>

#include <array>
#include <atomic>
#include <bitset>
#include <thread>
#include <type_traits>
#include <utility>

// gen_amalgamated expanded: #include "perfetto/base/logging.h"
// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"

namespace perfetto {

// This file defines the binary interface of the memory buffers shared between
// Producer and Service. This is a long-term stable ABI and has to be backwards
// compatible to deal with mismatching Producer and Service versions.
//
// Overview
// --------
// SMB := "Shared Memory Buffer".
// In the most typical case of a multi-process architecture (i.e. Producer and
// Service are hosted by different processes), a Producer means almost always
// a "client process producing data" (almost: in some cases a process might host
// > 1 Producer, if it links two libraries, independent of each other, that both
// use Perfetto tracing).
// The Service has one SMB for each Producer.
// A producer has one or (typically) more data sources. They all share the same
// SMB.
// The SMB is a staging area to decouple data sources living in the Producer
// and allow them to do non-blocking async writes.
// The SMB is *not* the ultimate logging buffer seen by the Consumer. That one
// is larger (~MBs) and not shared with Producers.
// Each SMB is small, typically few KB. Its size is configurable by the producer
// within a max limit of ~MB (see kMaxShmSize in tracing_service_impl.cc).
// The SMB is partitioned into fixed-size Page(s). The size of the Pages are
// determined by each Producer at connection time and cannot be changed.
// Hence, different producers can have SMB(s) that have a different Page size
// from each other, but the page size will be constant throughout all the
// lifetime of the SMB.
// Page(s) are partitioned by the Producer into variable size Chunk(s):
//
// +------------+      +--------------------------+
// | Producer 1 |  <-> |      SMB 1 [~32K - 1MB]  |
// +------------+      +--------+--------+--------+
//                     |  Page  |  Page  |  Page  |
//                     +--------+--------+--------+
//                     | Chunk  |        | Chunk  |
//                     +--------+  Chunk +--------+ <----+
//                     | Chunk  |        | Chunk  |      |
//                     +--------+--------+--------+      +---------------------+
//                                                       |       Service       |
// +------------+      +--------------------------+      +---------------------+
// | Producer 2 |  <-> |      SMB 2 [~32K - 1MB]  |     /| large ring buffers  |
// +------------+      +--------+--------+--------+ <--+ | (100K - several MB) |
//                     |  Page  |  Page  |  Page  |      +---------------------+
//                     +--------+--------+--------+
//                     | Chunk  |        | Chunk  |
//                     +--------+  Chunk +--------+
//                     | Chunk  |        | Chunk  |
//                     +--------+--------+--------+
//
// * Sizes of both SMB and ring buffers are purely indicative and decided at
// configuration time by the Producer (for SMB sizes) and the Consumer (for the
// final ring buffer size).

// Page
// ----
// A page is a portion of the shared memory buffer and defines the granularity
// of the interaction between the Producer and tracing Service. When scanning
// the shared memory buffer to determine if something should be moved to the
// central logging buffers, the Service most of the times looks at and moves
// whole pages. Similarly, the Producer sends an IPC to invite the Service to
// drain the shared memory buffer only when a whole page is filled.
// Having fixed the total SMB size (hence the total memory overhead), the page
// size is a triangular tradeoff between:
// 1) IPC traffic: smaller pages -> more IPCs.
// 2) Producer lock freedom: larger pages -> larger chunks -> data sources can
//    write more data without needing to swap chunks and synchronize.
// 3) Risk of write-starving the SMB: larger pages -> higher chance that the
//    Service won't manage to drain them and the SMB remains full.
// The page size, on the other side, has no implications on wasted memory due to
// fragmentations (see Chunk below).
// The size of the page is chosen by the Service at connection time and stays
// fixed throughout all the lifetime of the Producer. Different producers (i.e.
// ~ different client processes) can use different page sizes.
// The page size must be an integer multiple of 4k (this is to allow VM page
// stealing optimizations) and obviously has to be an integer divisor of the
// total SMB size.

// Chunk
// -----
// A chunk is a portion of a Page which is written and handled by a Producer.
// A chunk contains a linear sequence of TracePacket(s) (the root proto).
// A chunk cannot be written concurrently by two data sources. Protobufs must be
// encoded as contiguous byte streams and cannot be interleaved. Therefore, on
// the Producer side, a chunk is almost always owned exclusively by one thread
// (% extremely peculiar slow-path cases).
// Chunks are essentially single-writer single-thread lock-free arenas. Locking
// happens only when a Chunk is full and a new one needs to be acquired.
// Locking happens only within the scope of a Producer process. There is no
// inter-process locking. The Producer cannot lock the Service and viceversa.
// In the worst case, any of the two can starve the SMB, by marking all chunks
// as either being read or written. But that has the only side effect of
// losing the trace data.
// The Producer can decide to partition each page into a number of limited
// configurations (e.g., 1 page == 1 chunk, 1 page == 2 chunks and so on).

// TracePacket
// -----------
// Is the atom of tracing. Putting aside pages and chunks a trace is merely a
// sequence of TracePacket(s). TracePacket is the root protobuf message.
// A TracePacket can span across several chunks (hence even across several
// pages). A TracePacket can therefore be >> chunk size, >> page size and even
// >> SMB size. The Chunk header carries metadata to deal with the TracePacket
// splitting case.

// Use only explicitly-sized types below. DO NOT use size_t or any architecture
// dependent size (e.g. size_t) in the struct fields. This buffer will be read
// and written by processes that have a different bitness in the same OS.
// Instead it's fine to assume little-endianess. Big-endian is a dream we are
// not currently pursuing.

class SharedMemoryABI {
 public:
  static constexpr size_t kMinPageSize = 4 * 1024;

  // This is due to Chunk::size being 16 bits.
  static constexpr size_t kMaxPageSize = 64 * 1024;

  // "14" is the max number that can be encoded in a 32 bit atomic word using
  // 2 state bits per Chunk and leaving 4 bits for the page layout.
  // See PageLayout below.
  static constexpr size_t kMaxChunksPerPage = 14;

  // Each TracePacket fragment in the Chunk is prefixed by a VarInt stating its
  // size that is up to 4 bytes long. Since the size is often known after the
  // fragment has been filled, the VarInt is often redundantly encoded (see
  // proto_utils.h) to be exactly 4 bytes.
  static constexpr size_t kPacketHeaderSize = 4;

  // TraceWriter specifies this invalid packet/fragment size to signal to the
  // service that a packet should be discarded, because the TraceWriter couldn't
  // write its remaining fragments (e.g. because the SMB was exhausted).
  static constexpr size_t kPacketSizeDropPacket =
      protozero::proto_utils::kMaxMessageLength;

  // Chunk states and transitions:
  //    kChunkFree  <----------------+
  //         |  (Producer)           |
  //         V                       |
  //  kChunkBeingWritten             |
  //         |  (Producer)           |
  //         V                       |
  //  kChunkComplete                 |
  //         |  (Service)            |
  //         V                       |
  //  kChunkBeingRead                |
  //        |   (Service)            |
  //        +------------------------+
  //
  // The ABI has an "emulation mode" for transports where shared memory isn't
  // supported. In this mode, kChunkBeingRead is skipped. A chunk in the
  // kChunkComplete state is released as free after the producer serializes
  // chunk content to the protobuf message.
  enum ChunkState : uint32_t {
    // The Chunk is free. The Service shall never touch it, the Producer can
    // acquire it and transition it into kChunkBeingWritten.
    kChunkFree = 0,

    // The Chunk is being used by the Producer and is not complete yet.
    // The Service shall never touch kChunkBeingWritten pages.
    kChunkBeingWritten = 1,

    // The Service is moving the page into its non-shared ring buffer. The
    // Producer shall never touch kChunkBeingRead pages.
    kChunkBeingRead = 2,

    // The Producer is done writing the page and won't touch it again. The
    // Service can now move it to its non-shared ring buffer.
    // kAllChunksComplete relies on this being == 3.
    kChunkComplete = 3,
  };
  static constexpr const char* kChunkStateStr[] = {"Free", "BeingWritten",
                                                   "BeingRead", "Complete"};

  enum PageLayout : uint32_t {
    // The page is fully free and has not been partitioned yet.
    kPageNotPartitioned = 0,

    // TODO(primiano): Aligning a chunk @ 16 bytes could allow to use faster
    // intrinsics based on quad-word moves. Do the math and check what is the
    // fragmentation loss.

    // align4(X) := the largest integer N s.t. (N % 4) == 0 && N <= X.
    // 8 == sizeof(PageHeader).
    kPageDiv1 = 1,   // Only one chunk of size: PAGE_SIZE - 8.
    kPageDiv2 = 2,   // Two chunks of size: align4((PAGE_SIZE - 8) / 2).
    kPageDiv4 = 3,   // Four chunks of size: align4((PAGE_SIZE - 8) / 4).
    kPageDiv7 = 4,   // Seven chunks of size: align4((PAGE_SIZE - 8) / 7).
    kPageDiv14 = 5,  // Fourteen chunks of size: align4((PAGE_SIZE - 8) / 14).

    // The rationale for 7 and 14 above is to maximize the page usage for the
    // likely case of |page_size| == 4096:
    // (((4096 - 8) / 14) % 4) == 0, while (((4096 - 8) / 16 % 4)) == 3. So
    // Div16 would waste 3 * 16 = 48 bytes per page for chunk alignment gaps.

    kPageDivReserved1 = 6,
    kPageDivReserved2 = 7,
    kNumPageLayouts = 8,
  };

  // Keep this consistent with the PageLayout enum above.
  static constexpr uint32_t kNumChunksForLayout[] = {0, 1, 2, 4, 7, 14, 0, 0};

  enum class ShmemMode {
    // The default mode, where the shared buffer is visible to both the producer
    // and the service.
    kDefault,

    // The emulation mode, used for producer ports without shared memory. The
    // state transitions are all done in the producer process.
    kShmemEmulation,
  };

  // Layout of a Page.
  // +===================================================+
  // | Page header [8 bytes]                             |
  // | Tells how many chunks there are, how big they are |
  // | and their state (free, read, write, complete).    |
  // +===================================================+
  // +***************************************************+
  // | Chunk #0 header [8 bytes]                         |
  // | Tells how many packets there are and whether the  |
  // | whether the 1st and last ones are fragmented.     |
  // | Also has a chunk id to reassemble fragments.    |
  // +***************************************************+
  // +---------------------------------------------------+
  // | Packet #0 size [varint, up to 4 bytes]            |
  // + - - - - - - - - - - - - - - - - - - - - - - - - - +
  // | Packet #0 payload                                 |
  // | A TracePacket protobuf message                    |
  // +---------------------------------------------------+
  //                         ...
  // + . . . . . . . . . . . . . . . . . . . . . . . . . +
  // |      Optional padding to maintain aligment        |
  // + . . . . . . . . . . . . . . . . . . . . . . . . . +
  // +---------------------------------------------------+
  // | Packet #N size [varint, up to 4 bytes]            |
  // + - - - - - - - - - - - - - - - - - - - - - - - - - +
  // | Packet #N payload                                 |
  // | A TracePacket protobuf message                    |
  // +---------------------------------------------------+
  //                         ...
  // +***************************************************+
  // | Chunk #M header [8 bytes]                         |
  //                         ...

  // Alignment applies to start offset only. The Chunk size is *not* aligned.
  static constexpr uint32_t kChunkAlignment = 4;
  static constexpr uint32_t kChunkShift = 2;
  static constexpr uint32_t kChunkMask = 0x3;
  static constexpr uint32_t kLayoutMask = 0x70000000;
  static constexpr uint32_t kLayoutShift = 28;
  static constexpr uint32_t kAllChunksMask = 0x0FFFFFFF;

  // This assumes that kChunkComplete == 3.
  static constexpr uint32_t kAllChunksComplete = 0x0FFFFFFF;
  static constexpr uint32_t kAllChunksFree = 0;
  static constexpr size_t kInvalidPageIdx = static_cast<size_t>(-1);

  // There is one page header per page, at the beginning of the page.
  struct PageHeader {
    // |layout| bits:
    // [31] [30:28] [27:26] ... [1:0]
    //  |      |       |     |    |
    //  |      |       |     |    +---------- ChunkState[0]
    //  |      |       |     +--------------- ChunkState[12..1]
    //  |      |       +--------------------- ChunkState[13]
    //  |      +----------------------------- PageLayout (0 == page fully free)
    //  +------------------------------------ Reserved for future use
    std::atomic<uint32_t> layout;

    // If we'll ever going to use this in the future it might come handy
    // reviving the kPageBeingPartitioned logic (look in git log, it was there
    // at some point in the past).
    uint32_t reserved;
  };

  // There is one Chunk header per chunk (hence PageLayout per page) at the
  // beginning of each chunk.
  struct ChunkHeader {
    enum Flags : uint8_t {
      // If set, the first TracePacket in the chunk is partial and continues
      // from |chunk_id| - 1 (within the same |writer_id|).
      kFirstPacketContinuesFromPrevChunk = 1 << 0,

      // If set, the last TracePacket in the chunk is partial and continues on
      // |chunk_id| + 1 (within the same |writer_id|).
      kLastPacketContinuesOnNextChunk = 1 << 1,

      // If set, the last (fragmented) TracePacket in the chunk has holes (even
      // if the chunk is marked as kChunkComplete) that need to be patched
      // out-of-band before the chunk can be read.
      kChunkNeedsPatching = 1 << 2,
    };

    struct Packets {
      // Number of valid TracePacket protobuf messages contained in the chunk.
      // Each TracePacket is prefixed by its own size. This field is
      // monotonically updated by the Producer with release store semantic when
      // the packet at position |count| is started. This last packet may not be
      // considered complete until |count| is incremented for the subsequent
      // packet or the chunk is completed.
      uint16_t count : 10;
      static constexpr size_t kMaxCount = (1 << 10) - 1;

      // See Flags above.
      uint16_t flags : 6;
    };

    // A monotonic counter of the chunk within the scoped of a |writer_id|.
    // The tuple (ProducerID, WriterID, ChunkID) allows to figure out if two
    // chunks are contiguous (and hence a trace packets spanning across them can
    // be glued) or we had some holes due to the ring buffer wrapping.
    // This is set only when transitioning from kChunkFree to kChunkBeingWritten
    // and remains unchanged throughout the remaining lifetime of the chunk.
    std::atomic<uint32_t> chunk_id;

    // ID of the writer, unique within the producer.
    // Like |chunk_id|, this is set only when transitioning from kChunkFree to
    // kChunkBeingWritten.
    std::atomic<uint16_t> writer_id;

    // There is no ProducerID here. The service figures that out from the IPC
    // channel, which is unspoofable.

    // Updated with release-store semantics.
    std::atomic<Packets> packets;
  };

  class Chunk {
   public:
    Chunk();  // Constructs an invalid chunk.

    // Chunk is move-only, to document the scope of the Acquire/Release
    // TryLock operations below.
    Chunk(const Chunk&) = delete;
    Chunk operator=(const Chunk&) = delete;
    Chunk(Chunk&&) noexcept;
    Chunk& operator=(Chunk&&);

    uint8_t* begin() const { return begin_; }
    uint8_t* end() const { return begin_ + size_; }

    // Size, including Chunk header.
    size_t size() const { return size_; }

    // Begin of the first packet (or packet fragment).
    uint8_t* payload_begin() const { return begin_ + sizeof(ChunkHeader); }
    size_t payload_size() const {
      PERFETTO_DCHECK(size_ >= sizeof(ChunkHeader));
      return size_ - sizeof(ChunkHeader);
    }

    bool is_valid() const { return begin_ && size_; }

    // Index of the chunk within the page [0..13] (13 comes from kPageDiv14).
    uint8_t chunk_idx() const { return chunk_idx_; }

    ChunkHeader* header() { return reinterpret_cast<ChunkHeader*>(begin_); }

    uint16_t writer_id() {
      return header()->writer_id.load(std::memory_order_relaxed);
    }

    // Returns the count of packets and the flags with acquire-load semantics.
    std::pair<uint16_t, uint8_t> GetPacketCountAndFlags() {
      auto packets = header()->packets.load(std::memory_order_acquire);
      const uint16_t packets_count = packets.count;
      const uint8_t packets_flags = packets.flags;
      return std::make_pair(packets_count, packets_flags);
    }

    // Increases |packets.count| with release semantics (note, however, that the
    // packet count is incremented *before* starting writing a packet). Returns
    // the new packet count. The increment is atomic but NOT race-free (i.e. no
    // CAS). Only the Producer is supposed to perform this increment, and it's
    // supposed to do that in a thread-safe way (holding a lock). A Chunk cannot
    // be shared by multiple Producer threads without locking. The packet count
    // is cleared by TryAcquireChunk(), when passing the new header for the
    // chunk.
    uint16_t IncrementPacketCount() {
      ChunkHeader* chunk_header = header();
      auto packets = chunk_header->packets.load(std::memory_order_relaxed);
      packets.count++;
      chunk_header->packets.store(packets, std::memory_order_release);
      return packets.count;
    }

    // Flags are cleared by TryAcquireChunk(), by passing the new header for
    // the chunk, or through ClearNeedsPatchingFlag.
    void SetFlag(ChunkHeader::Flags flag) {
      ChunkHeader* chunk_header = header();
      auto packets = chunk_header->packets.load(std::memory_order_relaxed);
      packets.flags |= flag;
      chunk_header->packets.store(packets, std::memory_order_release);
    }

    // This flag can only be cleared by the producer while it is still holding
    // on to the chunk - i.e. while the chunk is still in state
    // ChunkState::kChunkBeingWritten and hasn't been transitioned to
    // ChunkState::kChunkComplete. This is ok, because the service is oblivious
    // to the needs patching flag before the chunk is released as complete.
    void ClearNeedsPatchingFlag() {
      ChunkHeader* chunk_header = header();
      auto packets = chunk_header->packets.load(std::memory_order_relaxed);
      packets.flags &= ~ChunkHeader::kChunkNeedsPatching;
      chunk_header->packets.store(packets, std::memory_order_release);
    }

   private:
    friend class SharedMemoryABI;
    Chunk(uint8_t* begin, uint16_t size, uint8_t chunk_idx);

    // Don't add extra fields, keep the move operator fast.
    uint8_t* begin_ = nullptr;
    uint16_t size_ = 0;
    uint8_t chunk_idx_ = 0;

   public:
    static constexpr size_t kMaxSize = 1ULL << sizeof(size_) * 8;
  };

  // Construct an instance from an existing shared memory buffer.
  SharedMemoryABI(uint8_t* start,
                  size_t size,
                  size_t page_size,
                  ShmemMode mode);
  SharedMemoryABI();

  void Initialize(uint8_t* start,
                  size_t size,
                  size_t page_size,
                  ShmemMode mode);

  uint8_t* start() const { return start_; }
  uint8_t* end() const { return start_ + size_; }
  size_t size() const { return size_; }
  size_t page_size() const { return page_size_; }
  size_t num_pages() const { return num_pages_; }
  bool is_valid() { return num_pages() > 0; }

  uint8_t* page_start(size_t page_idx) {
    PERFETTO_DCHECK(page_idx < num_pages_);
    return start_ + page_size_ * page_idx;
  }

  PageHeader* page_header(size_t page_idx) {
    return reinterpret_cast<PageHeader*>(page_start(page_idx));
  }

  // Returns true if the page is fully clear and has not been partitioned yet.
  // The state of the page can change at any point after this returns (or even
  // before). The Producer should use this only as a hint to decide out whether
  // it should TryPartitionPage() or acquire an individual chunk.
  bool is_page_free(size_t page_idx) {
    return page_header(page_idx)->layout.load(std::memory_order_relaxed) == 0;
  }

  // Returns true if all chunks in the page are kChunkComplete. As above, this
  // is advisory only. The Service is supposed to use this only to decide
  // whether to TryAcquireAllChunksForReading() or not.
  bool is_page_complete(size_t page_idx) {
    auto layout = page_header(page_idx)->layout.load(std::memory_order_relaxed);
    const uint32_t num_chunks = GetNumChunksForLayout(layout);
    if (num_chunks == 0)
      return false;  // Non partitioned pages cannot be complete.
    return (layout & kAllChunksMask) ==
           (kAllChunksComplete & ((1 << (num_chunks * kChunkShift)) - 1));
  }

  // For testing / debugging only.
  std::string page_header_dbg(size_t page_idx) {
    uint32_t x = page_header(page_idx)->layout.load(std::memory_order_relaxed);
    return std::bitset<32>(x).to_string();
  }

  // Returns the page layout, which is a bitmap that specifies the chunking
  // layout of the page and each chunk's current state. Reads with an
  // acquire-load semantic to ensure a producer's writes corresponding to an
  // update of the layout (e.g. clearing a chunk's header) are observed
  // consistently.
  uint32_t GetPageLayout(size_t page_idx) {
    return page_header(page_idx)->layout.load(std::memory_order_acquire);
  }

  // Returns a bitmap in which each bit is set if the corresponding Chunk exists
  // in the page (according to the page layout) and is free. If the page is not
  // partitioned it returns 0 (as if the page had no free chunks).
  uint32_t GetFreeChunks(size_t page_idx);

  // Tries to atomically partition a page with the given |layout|. Returns true
  // if the page was free and has been partitioned with the given |layout|,
  // false if the page wasn't free anymore by the time we got there.
  // If succeeds all the chunks are atomically set in the kChunkFree state.
  bool TryPartitionPage(size_t page_idx, PageLayout layout);

  // Tries to atomically mark a single chunk within the page as
  // kChunkBeingWritten. Returns an invalid chunk if the page is not partitioned
  // or the chunk is not in the kChunkFree state. If succeeds sets the chunk
  // header to |header|.
  Chunk TryAcquireChunkForWriting(size_t page_idx,
                                  size_t chunk_idx,
                                  const ChunkHeader* header) {
    return TryAcquireChunk(page_idx, chunk_idx, kChunkBeingWritten, header);
  }

  // Similar to TryAcquireChunkForWriting. Fails if the chunk isn't in the
  // kChunkComplete state.
  Chunk TryAcquireChunkForReading(size_t page_idx, size_t chunk_idx) {
    return TryAcquireChunk(page_idx, chunk_idx, kChunkBeingRead, nullptr);
  }

  // The caller must have successfully TryAcquireAllChunksForReading() or it
  // needs to guarantee that the chunk is already in the kChunkBeingWritten
  // state.
  Chunk GetChunkUnchecked(size_t page_idx,
                          uint32_t page_layout,
                          size_t chunk_idx);

  // Creates a Chunk by adopting the given buffer (|data| and |size|) and chunk
  // index. This is used for chunk data passed over the wire (e.g. tcp or
  // vsock). The chunk should *not* be freed to the shared memory.
  static Chunk MakeChunkFromSerializedData(uint8_t* data,
                                           uint16_t size,
                                           uint8_t chunk_idx) {
    return Chunk(data, size, chunk_idx);
  }

  // Puts a chunk into the kChunkComplete state. Returns the page index.
  size_t ReleaseChunkAsComplete(Chunk chunk) {
    return ReleaseChunk(std::move(chunk), kChunkComplete);
  }

  // Puts a chunk into the kChunkFree state. Returns the page index.
  size_t ReleaseChunkAsFree(Chunk chunk) {
    return ReleaseChunk(std::move(chunk), kChunkFree);
  }

  ChunkState GetChunkState(size_t page_idx, size_t chunk_idx) {
    PageHeader* phdr = page_header(page_idx);
    uint32_t layout = phdr->layout.load(std::memory_order_relaxed);
    return GetChunkStateFromLayout(layout, chunk_idx);
  }

  std::pair<size_t, size_t> GetPageAndChunkIndex(const Chunk& chunk);

  uint16_t GetChunkSizeForLayout(uint32_t page_layout) const {
    return chunk_sizes_[(page_layout & kLayoutMask) >> kLayoutShift];
  }

  static ChunkState GetChunkStateFromLayout(uint32_t page_layout,
                                            size_t chunk_idx) {
    return static_cast<ChunkState>((page_layout >> (chunk_idx * kChunkShift)) &
                                   kChunkMask);
  }

  static constexpr uint32_t GetNumChunksForLayout(uint32_t page_layout) {
    return kNumChunksForLayout[(page_layout & kLayoutMask) >> kLayoutShift];
  }

  // Returns a bitmap in which each bit is set if the corresponding Chunk exists
  // in the page (according to the page layout) and is not free. If the page is
  // not partitioned it returns 0 (as if the page had no used chunks). Bit N
  // corresponds to Chunk N.
  static uint32_t GetUsedChunks(uint32_t page_layout) {
    const uint32_t num_chunks = GetNumChunksForLayout(page_layout);
    uint32_t res = 0;
    for (uint32_t i = 0; i < num_chunks; i++) {
      res |= ((page_layout & kChunkMask) != kChunkFree) ? (1 << i) : 0;
      page_layout >>= kChunkShift;
    }
    return res;
  }

 private:
  SharedMemoryABI(const SharedMemoryABI&) = delete;
  SharedMemoryABI& operator=(const SharedMemoryABI&) = delete;

  Chunk TryAcquireChunk(size_t page_idx,
                        size_t chunk_idx,
                        ChunkState,
                        const ChunkHeader*);
  size_t ReleaseChunk(Chunk chunk, ChunkState);

  uint8_t* start_ = nullptr;
  size_t size_ = 0;
  size_t page_size_ = 0;
  bool use_shmem_emulation_ = false;
  size_t num_pages_ = 0;
  std::array<uint16_t, kNumPageLayouts> chunk_sizes_;
};

}  // namespace perfetto

#endif  // INCLUDE_PERFETTO_EXT_TRACING_CORE_SHARED_MEMORY_ABI_H_
/*
 * Copyright (C) 2017 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the
 * License. You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an "AS
 * IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
 * express or implied. See the License for the specific language
 * governing permissions and limitations under the License.
 */
// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/shared_memory_abi.h"

// gen_amalgamated expanded: #include "perfetto/base/build_config.h"
// gen_amalgamated expanded: #include "perfetto/base/time.h"

#if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
#include <sys/mman.h>
#endif

// gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/basic_types.h"

namespace perfetto {

namespace {

constexpr int kRetryAttempts = 64;

inline void WaitBeforeNextAttempt(int attempt) {
  if (attempt < kRetryAttempts / 2) {
    std::this_thread::yield();
  } else {
    base::SleepMicroseconds((unsigned(attempt) / 10) * 1000);
  }
}

// Returns the largest 4-bytes aligned chunk size <= |page_size| / |divider|
// for each divider in PageLayout.
constexpr size_t GetChunkSize(size_t page_size, size_t divider) {
  return ((page_size - sizeof(SharedMemoryABI::PageHeader)) / divider) & ~3UL;
}

// Initializer for the const |chunk_sizes_| array.
std::array<uint16_t, SharedMemoryABI::kNumPageLayouts> InitChunkSizes(
    size_t page_size) {
  static_assert(SharedMemoryABI::kNumPageLayouts ==
                    base::ArraySize(SharedMemoryABI::kNumChunksForLayout),
                "kNumPageLayouts out of date");
  std::array<uint16_t, SharedMemoryABI::kNumPageLayouts> res = {};
  for (size_t i = 0; i < SharedMemoryABI::kNumPageLayouts; i++) {
    size_t num_chunks = SharedMemoryABI::kNumChunksForLayout[i];
    size_t size = num_chunks == 0 ? 0 : GetChunkSize(page_size, num_chunks);
    PERFETTO_CHECK(size <= std::numeric_limits<uint16_t>::max());
    res[i] = static_cast<uint16_t>(size);
  }
  return res;
}

inline void ClearChunkHeader(SharedMemoryABI::ChunkHeader* header) {
  header->writer_id.store(0u, std::memory_order_relaxed);
  header->chunk_id.store(0u, std::memory_order_relaxed);
  header->packets.store({}, std::memory_order_release);
}

}  // namespace

SharedMemoryABI::SharedMemoryABI() = default;

SharedMemoryABI::SharedMemoryABI(uint8_t* start,
                                 size_t size,
                                 size_t page_size,
                                 ShmemMode mode) {
  Initialize(start, size, page_size, mode);
}

void SharedMemoryABI::Initialize(uint8_t* start,
                                 size_t size,
                                 size_t page_size,
                                 ShmemMode mode) {
  start_ = start;
  size_ = size;
  page_size_ = page_size;
  use_shmem_emulation_ = mode == ShmemMode::kShmemEmulation;
  num_pages_ = size / page_size;
  chunk_sizes_ = InitChunkSizes(page_size);
  static_assert(sizeof(PageHeader) == 8, "PageHeader size");
  static_assert(sizeof(ChunkHeader) == 8, "ChunkHeader size");
  static_assert(sizeof(ChunkHeader::chunk_id) == sizeof(ChunkID),
                "ChunkID size");

  static_assert(sizeof(ChunkHeader::Packets) == 2, "ChunkHeader::Packets size");
  static_assert(alignof(ChunkHeader) == kChunkAlignment,
                "ChunkHeader alignment");

  // In theory std::atomic does not guarantee that the underlying type
  // consists only of the actual atomic word. Theoretically it could have
  // locks or other state. In practice most implementations just implement
  // them without extra state. The code below overlays the atomic into the
  // SMB, hence relies on this implementation detail. This should be fine
  // pragmatically (Chrome's base makes the same assumption), but let's have a
  // check for this.
  static_assert(sizeof(std::atomic<uint32_t>) == sizeof(uint32_t) &&
                    sizeof(std::atomic<uint16_t>) == sizeof(uint16_t),
                "Incompatible STL <atomic> implementation");

  // Chec that the kAllChunks(Complete,Free) are consistent with the
  // ChunkState enum values.

  // These must be zero because rely on zero-initialized memory being
  // interpreted as "free".
  static_assert(kChunkFree == 0 && kAllChunksFree == 0,
                "kChunkFree/kAllChunksFree and must be 0");

  static_assert((kAllChunksComplete & kChunkMask) == kChunkComplete,
                "kAllChunksComplete out of sync with kChunkComplete");

  // Check the consistency of the kMax... constants.
  static_assert(sizeof(ChunkHeader::writer_id) == sizeof(WriterID),
                "WriterID size");
  ChunkHeader chunk_header{};
  chunk_header.chunk_id.store(static_cast<uint32_t>(-1));
  PERFETTO_CHECK(chunk_header.chunk_id.load() == kMaxChunkID);

  chunk_header.writer_id.store(static_cast<uint16_t>(-1));
  PERFETTO_CHECK(kMaxWriterID <= chunk_header.writer_id.load());

  PERFETTO_CHECK(page_size >= kMinPageSize);
  PERFETTO_CHECK(page_size <= kMaxPageSize);
  PERFETTO_CHECK(page_size % kMinPageSize == 0);
  PERFETTO_CHECK(reinterpret_cast<uintptr_t>(start) % kMinPageSize == 0);
  PERFETTO_CHECK(size % page_size == 0);
}

SharedMemoryABI::Chunk SharedMemoryABI::GetChunkUnchecked(size_t page_idx,
                                                          uint32_t page_layout,
                                                          size_t chunk_idx) {
  const size_t num_chunks = GetNumChunksForLayout(page_layout);
  PERFETTO_DCHECK(chunk_idx < num_chunks);
  // Compute the chunk virtual address and write it into |chunk|.
  const uint16_t chunk_size = GetChunkSizeForLayout(page_layout);
  size_t chunk_offset_in_page = sizeof(PageHeader) + chunk_idx * chunk_size;

  Chunk chunk(page_start(page_idx) + chunk_offset_in_page, chunk_size,
              static_cast<uint8_t>(chunk_idx));
  PERFETTO_DCHECK(chunk.end() <= end());
  return chunk;
}

SharedMemoryABI::Chunk SharedMemoryABI::TryAcquireChunk(
    size_t page_idx,
    size_t chunk_idx,
    ChunkState desired_chunk_state,
    const ChunkHeader* header) {
  PERFETTO_DCHECK(desired_chunk_state == kChunkBeingRead ||
                  desired_chunk_state == kChunkBeingWritten);
  PageHeader* phdr = page_header(page_idx);
  for (int attempt = 0; attempt < kRetryAttempts; attempt++) {
    uint32_t layout = phdr->layout.load(std::memory_order_acquire);
    const size_t num_chunks = GetNumChunksForLayout(layout);

    // The page layout has changed (or the page is free).
    if (chunk_idx >= num_chunks)
      return Chunk();

    // Verify that the chunk is still in a state that allows the transition to
    // |desired_chunk_state|. The only allowed transitions are:
    // 1. kChunkFree -> kChunkBeingWritten (Producer).
    // 2. kChunkComplete -> kChunkBeingRead (Service).
    ChunkState expected_chunk_state =
        desired_chunk_state == kChunkBeingWritten ? kChunkFree : kChunkComplete;
    auto cur_chunk_state = (layout >> (chunk_idx * kChunkShift)) & kChunkMask;
    if (cur_chunk_state != expected_chunk_state)
      return Chunk();

    uint32_t next_layout = layout;
    next_layout &= ~(kChunkMask << (chunk_idx * kChunkShift));
    next_layout |= (desired_chunk_state << (chunk_idx * kChunkShift));
    if (phdr->layout.compare_exchange_strong(layout, next_layout,
                                             std::memory_order_acq_rel)) {
      // Compute the chunk virtual address and write it into |chunk|.
      Chunk chunk = GetChunkUnchecked(page_idx, layout, chunk_idx);
      if (desired_chunk_state == kChunkBeingWritten) {
        PERFETTO_DCHECK(header);
        ChunkHeader* new_header = chunk.header();
        new_header->writer_id.store(header->writer_id,
                                    std::memory_order_relaxed);
        new_header->chunk_id.store(header->chunk_id, std::memory_order_relaxed);
        new_header->packets.store(header->packets, std::memory_order_release);
      }
      return chunk;
    }
    WaitBeforeNextAttempt(attempt);
  }
  return Chunk();  // All our attempts failed.
}

bool SharedMemoryABI::TryPartitionPage(size_t page_idx, PageLayout layout) {
  PERFETTO_DCHECK(layout >= kPageDiv1 && layout <= kPageDiv14);
  uint32_t expected_layout = 0;  // Free page.
  uint32_t next_layout = (layout << kLayoutShift) & kLayoutMask;
  PageHeader* phdr = page_header(page_idx);
  if (!phdr->layout.compare_exchange_strong(expected_layout, next_layout,
                                            std::memory_order_acq_rel)) {
    return false;
  }
  return true;
}

uint32_t SharedMemoryABI::GetFreeChunks(size_t page_idx) {
  uint32_t layout =
      page_header(page_idx)->layout.load(std::memory_order_relaxed);
  const uint32_t num_chunks = GetNumChunksForLayout(layout);
  uint32_t res = 0;
  for (uint32_t i = 0; i < num_chunks; i++) {
    res |= ((layout & kChunkMask) == kChunkFree) ? (1 << i) : 0;
    layout >>= kChunkShift;
  }
  return res;
}

size_t SharedMemoryABI::ReleaseChunk(Chunk chunk,
                                     ChunkState desired_chunk_state) {
  PERFETTO_DCHECK(desired_chunk_state == kChunkComplete ||
                  desired_chunk_state == kChunkFree);

  size_t page_idx;
  size_t chunk_idx;
  std::tie(page_idx, chunk_idx) = GetPageAndChunkIndex(chunk);

  // Reset header fields, so that the service can identify when the chunk's
  // header has been initialized by the producer.
  if (desired_chunk_state == kChunkFree)
    ClearChunkHeader(chunk.header());

  for (int attempt = 0; attempt < kRetryAttempts; attempt++) {
    PageHeader* phdr = page_header(page_idx);
    uint32_t layout = phdr->layout.load(std::memory_order_relaxed);
    const size_t page_chunk_size = GetChunkSizeForLayout(layout);

    // TODO(primiano): this should not be a CHECK, because a malicious producer
    // could crash us by putting the chunk in an invalid state. This should
    // gracefully fail. Keep a CHECK until then.
    PERFETTO_CHECK(chunk.size() == page_chunk_size);
    const uint32_t chunk_state = GetChunkStateFromLayout(layout, chunk_idx);

    // Verify that the chunk is still in a state that allows the transition to
    // |desired_chunk_state|. The only allowed transitions are:
    // 1. kChunkBeingWritten -> kChunkComplete (Producer).
    // 2. kChunkBeingRead -> kChunkFree (Service).
    // Or in the emulation mode, the allowed transitions are:
    // 1. kChunkBeingWritten -> kChunkComplete (Producer).
    // 2. kChunkComplete -> kChunkFree (Producer).
    ChunkState expected_chunk_state;
    if (desired_chunk_state == kChunkComplete) {
      expected_chunk_state = kChunkBeingWritten;
    } else {
      expected_chunk_state =
          use_shmem_emulation_ ? kChunkComplete : kChunkBeingRead;
    }

    // TODO(primiano): should not be a CHECK (same rationale of comment above).
    PERFETTO_CHECK(chunk_state == expected_chunk_state);
    uint32_t next_layout = layout;
    next_layout &= ~(kChunkMask << (chunk_idx * kChunkShift));
    next_layout |= (desired_chunk_state << (chunk_idx * kChunkShift));

    // If we are freeing a chunk and all the other chunks in the page are free
    // we should de-partition the page and mark it as clear.
    if ((next_layout & kAllChunksMask) == kAllChunksFree)
      next_layout = 0;

    if (phdr->layout.compare_exchange_strong(layout, next_layout,
                                             std::memory_order_acq_rel)) {
      return page_idx;
    }
    WaitBeforeNextAttempt(attempt);
  }
  // Too much contention on this page. Give up. This page will be left pending
  // forever but there isn't much more we can do at this point.
  PERFETTO_DFATAL("Too much contention on page.");
  return kInvalidPageIdx;
}

SharedMemoryABI::Chunk::Chunk() = default;

SharedMemoryABI::Chunk::Chunk(uint8_t* begin, uint16_t size, uint8_t chunk_idx)
    : begin_(begin), size_(size), chunk_idx_(chunk_idx) {
  PERFETTO_CHECK(reinterpret_cast<uintptr_t>(begin) % kChunkAlignment == 0);
  PERFETTO_CHECK(size > 0);
}

SharedMemoryABI::Chunk::Chunk(Chunk&& o) noexcept {
  *this = std::move(o);
}

SharedMemoryABI::Chunk& SharedMemoryABI::Chunk::operator=(Chunk&& o) {
  begin_ = o.begin_;
  size_ = o.size_;
  chunk_idx_ = o.chunk_idx_;
  o.begin_ = nullptr;
  o.size_ = 0;
  o.chunk_idx_ = 0;
  return *this;
}

std::pair<size_t, size_t> SharedMemoryABI::GetPageAndChunkIndex(
    const Chunk& chunk) {
  PERFETTO_DCHECK(chunk.is_valid());
  PERFETTO_DCHECK(chunk.begin() >= start_);
  PERFETTO_DCHECK(chunk.end() <= start_ + size_);

  // TODO(primiano): The divisions below could be avoided if we cached
  // |page_shift_|.
  const uintptr_t rel_addr = static_cast<uintptr_t>(chunk.begin() - start_);
  const size_t page_idx = rel_addr / page_size_;
  const size_t offset = rel_addr % page_size_;
  PERFETTO_DCHECK(offset >= sizeof(PageHeader));
  PERFETTO_DCHECK(offset % kChunkAlignment == 0);
  PERFETTO_DCHECK((offset - sizeof(PageHeader)) % chunk.size() == 0);
  const size_t chunk_idx = (offset - sizeof(PageHeader)) / chunk.size();
  PERFETTO_DCHECK(chunk_idx < kMaxChunksPerPage);
  PERFETTO_DCHECK(chunk_idx < GetNumChunksForLayout(GetPageLayout(page_idx)));
  return std::make_pair(page_idx, chunk_idx);
}

}  // namespace perfetto
// gen_amalgamated begin source: src/tracing/core/shared_memory_arbiter_impl.cc
// gen_amalgamated begin header: src/tracing/core/shared_memory_arbiter_impl.h
// gen_amalgamated begin header: include/perfetto/ext/tracing/core/shared_memory_arbiter.h
// gen_amalgamated begin header: include/perfetto/ext/tracing/core/tracing_service.h
// gen_amalgamated begin header: include/perfetto/ext/tracing/core/trace_packet.h
// gen_amalgamated begin header: include/perfetto/ext/tracing/core/slice.h
/*
 * Copyright (C) 2017 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef INCLUDE_PERFETTO_EXT_TRACING_CORE_SLICE_H_
#define INCLUDE_PERFETTO_EXT_TRACING_CORE_SLICE_H_

#include <stddef.h>
#include <string.h>

#include <memory>
#include <string>
#include <vector>

// gen_amalgamated expanded: #include "perfetto/base/logging.h"

namespace perfetto {

// A simple wrapper around a virtually contiguous memory range that contains a
// TracePacket, or just a portion of it.
struct Slice {
  Slice() : start(nullptr), size(0) {}
  Slice(const void* st, size_t sz) : start(st), size(sz) {}
  Slice(Slice&& other) noexcept = default;

  // Create a Slice which owns |size| bytes of memory.
  static Slice Allocate(size_t size) {
    Slice slice;
    slice.own_data_.reset(new uint8_t[size]);
    slice.start = &slice.own_data_[0];
    slice.size = size;
    return slice;
  }

  static Slice TakeOwnership(std::unique_ptr<uint8_t[]> buf, size_t size) {
    Slice slice;
    slice.own_data_ = std::move(buf);
    slice.start = &slice.own_data_[0];
    slice.size = size;
    return slice;
  }

  uint8_t* own_data() {
    PERFETTO_DCHECK(own_data_);
    return own_data_.get();
  }

  const void* start;
  size_t size;

 private:
  Slice(const Slice&) = delete;
  void operator=(const Slice&) = delete;

  std::unique_ptr<uint8_t[]> own_data_;
};

// TODO(primiano): most TracePacket(s) fit in a slice or two. We need something
// a bit more clever here that has inline capacity for 2 slices and then uses a
// std::forward_list or a std::vector for the less likely cases.
using Slices = std::vector<Slice>;

}  // namespace perfetto

#endif  // INCLUDE_PERFETTO_EXT_TRACING_CORE_SLICE_H_
/*
 * Copyright (C) 2017 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef INCLUDE_PERFETTO_EXT_TRACING_CORE_TRACE_PACKET_H_
#define INCLUDE_PERFETTO_EXT_TRACING_CORE_TRACE_PACKET_H_

#include <stddef.h>
#include <memory>
#include <optional>
#include <tuple>

// gen_amalgamated expanded: #include "perfetto/base/export.h"
// gen_amalgamated expanded: #include "perfetto/base/logging.h"
// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/slice.h"

namespace perfetto {

// A wrapper around a byte buffer that contains a protobuf-encoded TracePacket
// (see trace_packet.proto). The TracePacket is decoded only if the Consumer
// requests that. This is to allow Consumer(s) to just stream the packet over
// the network or save it to a file without wasting time decoding it and without
// needing to depend on libprotobuf or the trace_packet.pb.h header.
// If the packets are saved / streamed and not just consumed locally, consumers
// should ensure to preserve the unknown fields in the proto. A consumer, in
// fact, might have an older version .proto which is newer on the producer.
class PERFETTO_EXPORT_COMPONENT TracePacket {
 public:
  using const_iterator = Slices::const_iterator;

  // The field id of protos::Trace::packet, static_assert()-ed in the unittest.
  static constexpr uint32_t kPacketFieldNumber = 1;

  // Maximum size of the preamble returned by GetProtoPreamble().
  static constexpr size_t kMaxPreambleBytes = 8;

  TracePacket();
  ~TracePacket();
  TracePacket(TracePacket&&) noexcept;
  TracePacket& operator=(TracePacket&&);

  // Accesses all the raw slices in the packet, for saving them to file/network.
  const Slices& slices() const { return slices_; }

  // Mutator, used only by the service and tests.
  void AddSlice(Slice);

  // Does not copy / take ownership of the memory of the slice. The TracePacket
  // will be valid only as long as the original buffer is valid.
  void AddSlice(const void* start, size_t size);

  // Total size of all slices.
  size_t size() const { return size_; }

  // Generates a protobuf preamble suitable to represent this packet as a
  // repeated field within a root trace.proto message.
  // Returns a pointer to a buffer, owned by this class, containing the preamble
  // and its size.
  std::tuple<char*, size_t> GetProtoPreamble();

  // Returns the raw protobuf bytes of the slices, all stitched together into
  // a string. Only for testing.
  std::string GetRawBytesForTesting();

  // Remembers the buffer index where this packet was taken from. This is
  // usually populated for packets from a TraceBuffer, not synthetic ones.
  std::optional<uint32_t> buffer_index_for_stats() const {
    if (buffer_index_for_stats_ == 0)
      return std::nullopt;
    return buffer_index_for_stats_ - 1;
  }
  void set_buffer_index_for_stats(uint32_t v) {
    buffer_index_for_stats_ = v + 1;
  }

 private:
  TracePacket(const TracePacket&) = delete;
  TracePacket& operator=(const TracePacket&) = delete;

  Slices slices_;     // Not owned.
  size_t size_ = 0;   // SUM(slice.size for slice in slices_).

  // Internally we store index+1, and use 0 for the "not set" case.
  uint32_t buffer_index_for_stats_ = 0;
  char preamble_[kMaxPreambleBytes];  // Deliberately not initialized.

  // Remember to update the move operators and their unittest if adding new
  // fields. ConsumerIPCClientImpl::OnReadBuffersResponse() relies on
  // std::move(TracePacket) to clear up the moved-from instance.
};

}  // namespace perfetto

#endif  // INCLUDE_PERFETTO_EXT_TRACING_CORE_TRACE_PACKET_H_
/*
 * Copyright (C) 2017 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef INCLUDE_PERFETTO_EXT_TRACING_CORE_TRACING_SERVICE_H_
#define INCLUDE_PERFETTO_EXT_TRACING_CORE_TRACING_SERVICE_H_

#include <stdint.h>

#include <functional>
#include <memory>
#include <vector>

// gen_amalgamated expanded: #include "perfetto/base/export.h"
// gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"
// gen_amalgamated expanded: #include "perfetto/ext/base/sys_types.h"
// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/basic_types.h"
// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/shared_memory.h"
// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/trace_packet.h"
// gen_amalgamated expanded: #include "perfetto/tracing/buffer_exhausted_policy.h"
// gen_amalgamated expanded: #include "perfetto/tracing/core/clock_snapshots.h"
// gen_amalgamated expanded: #include "perfetto/tracing/core/flush_flags.h"
// gen_amalgamated expanded: #include "perfetto/tracing/core/forward_decls.h"

namespace perfetto {

namespace base {
class TaskRunner;
}  // namespace base

class Consumer;
class Producer;
class SharedMemoryArbiter;
class TraceWriter;
class ClientIdentity;

// TODO: for the moment this assumes that all the calls happen on the same
// thread/sequence. Not sure this will be the case long term in Chrome.

// The API for the Producer port of the Service.
// Subclassed by:
// 1. The tracing_service_impl.cc business logic when returning it in response
//    to the ConnectProducer() method.
// 2. The transport layer (e.g., src/ipc) when the producer and
//    the service don't talk locally but via some IPC mechanism.
class PERFETTO_EXPORT_COMPONENT ProducerEndpoint {
 public:
  virtual ~ProducerEndpoint();

  // Disconnects the endpoint from the service, while keeping the shared memory
  // valid. After calling this, the endpoint will no longer call any methods
  // on the Producer.
  virtual void Disconnect() = 0;

  // Called by the Producer to (un)register data sources. Data sources are
  // identified by their name (i.e. DataSourceDescriptor.name)
  virtual void RegisterDataSource(const DataSourceDescriptor&) = 0;
  virtual void UpdateDataSource(const DataSourceDescriptor&) = 0;
  virtual void UnregisterDataSource(const std::string& name) = 0;

  // Associate the trace writer with the given |writer_id| with
  // |target_buffer|. The service may use this information to retrieve and
  // copy uncommitted chunks written by the trace writer into its associated
  // buffer, e.g. when a producer process crashes or when a flush is
  // necessary.
  virtual void RegisterTraceWriter(uint32_t writer_id,
                                   uint32_t target_buffer) = 0;

  // Remove the association of the trace writer previously created via
  // RegisterTraceWriter.
  virtual void UnregisterTraceWriter(uint32_t writer_id) = 0;

  // Called by the Producer to signal that some pages in the shared memory
  // buffer (shared between Service and Producer) have changed.
  // When the Producer and the Service are hosted in the same process and
  // hence potentially live on the same task runner, This method must call
  // TracingServiceImpl's CommitData synchronously, without any PostTask()s,
  // if on the same thread. This is to avoid a deadlock where the Producer
  // exhausts its SMB and stalls waiting for the service to catch up with
  // reads, but the Service never gets to that because it lives on the same
  // thread.
  using CommitDataCallback = std::function<void()>;
  virtual void CommitData(const CommitDataRequest&,
                          CommitDataCallback callback = {}) = 0;

  virtual SharedMemory* shared_memory() const = 0;

  // Size of shared memory buffer pages. It's always a multiple of 4K.
  // See shared_memory_abi.h
  virtual size_t shared_buffer_page_size_kb() const = 0;

  // Creates a trace writer, which allows to create events, handling the
  // underying shared memory buffer and signalling to the Service. This method
  // is thread-safe but the returned object is not. A TraceWriter should be
  // used only from a single thread, or the caller has to handle sequencing
  // via a mutex or equivalent. This method can only be called if
  // TracingService::ConnectProducer was called with |in_process=true|.
  // Args:
  // |target_buffer| is the target buffer ID where the data produced by the
  // writer should be stored by the tracing service. This value is passed
  // upon creation of the data source (StartDataSource()) in the
  // DataSourceConfig.target_buffer().
  virtual std::unique_ptr<TraceWriter> CreateTraceWriter(
      BufferID target_buffer,
      BufferExhaustedPolicy buffer_exhausted_policy =
          BufferExhaustedPolicy::kDefault) = 0;

  // TODO(eseckler): Also expose CreateStartupTraceWriter() ?

  // In some cases you can access the producer's SharedMemoryArbiter (for
  // example if TracingService::ConnectProducer is called with
  // |in_process=true|). The SharedMemoryArbiter can be used to create
  // TraceWriters which is able to directly commit chunks. For the
  // |in_process=true| case this can be done without going through an IPC layer.
  virtual SharedMemoryArbiter* MaybeSharedMemoryArbiter() = 0;

  // Whether the service accepted a shared memory buffer provided by the
  // producer.
  virtual bool IsShmemProvidedByProducer() const = 0;

  // Called in response to a Producer::Flush(request_id) call after all data
  // for the flush request has been committed.
  virtual void NotifyFlushComplete(FlushRequestID) = 0;

  // Called in response to one or more Producer::StartDataSource(),
  // if the data source registered setting the flag
  // DataSourceDescriptor.will_notify_on_start.
  virtual void NotifyDataSourceStarted(DataSourceInstanceID) = 0;

  // Called in response to one or more Producer::StopDataSource(),
  // if the data source registered setting the flag
  // DataSourceDescriptor.will_notify_on_stop.
  virtual void NotifyDataSourceStopped(DataSourceInstanceID) = 0;

  // This informs the service to activate any of these triggers if any tracing
  // session was waiting for them.
  virtual void ActivateTriggers(const std::vector<std::string>&) = 0;

  // Emits a synchronization barrier to linearize with the service. When
  // |callback| is invoked, the caller has the guarantee that the service has
  // seen and processed all the requests sent by this producer prior to the
  // Sync() call. Used mainly in tests.
  virtual void Sync(std::function<void()> callback) = 0;
};  // class ProducerEndpoint.

// The API for the Consumer port of the Service.
// Subclassed by:
// 1. The tracing_service_impl.cc business logic when returning it in response
// to
//    the ConnectConsumer() method.
// 2. The transport layer (e.g., src/ipc) when the consumer and
//    the service don't talk locally but via some IPC mechanism.
class PERFETTO_EXPORT_COMPONENT ConsumerEndpoint {
 public:
  virtual ~ConsumerEndpoint();

  // Enables tracing with the given TraceConfig. The ScopedFile argument is
  // used only when TraceConfig.write_into_file == true.
  // If TraceConfig.deferred_start == true data sources are configured via
  // SetupDataSource() but are not started until StartTracing() is called.
  // This is to support pre-initialization and fast triggering of traces.
  // The ScopedFile argument is used only when TraceConfig.write_into_file
  // == true.
  virtual void EnableTracing(const TraceConfig&,
                             base::ScopedFile = base::ScopedFile()) = 0;

  // Update the trace config of an existing tracing session; only a subset
  // of options can be changed mid-session. Currently the only
  // supported functionality is expanding the list of producer_name_filters()
  // (or removing the filter entirely) for existing data sources.
  virtual void ChangeTraceConfig(const TraceConfig&) = 0;

  // Starts all data sources configured in the trace config. This is used only
  // after calling EnableTracing() with TraceConfig.deferred_start=true.
  // It's a no-op if called after a regular EnableTracing(), without setting
  // deferred_start.
  virtual void StartTracing() = 0;

  virtual void DisableTracing() = 0;

  // Clones an existing tracing session and attaches to it. The session is
  // cloned in read-only mode and can only be used to read a snapshot of an
  // existing tracing session. Will invoke Consumer::OnSessionCloned().
  // If TracingSessionID == kBugreportSessionId (0xff...ff) the session with the
  // highest bugreport score is cloned (if any exists).
  struct CloneSessionArgs {
    // If set, the trace filter will not have effect on the cloned session.
    // Used for bugreports.
    bool skip_trace_filter = false;

    // If set, affects the generation of the FlushFlags::CloneTarget to be set
    // to kBugreport when requesting the flush to the producers.
    bool for_bugreport = false;
  };
  virtual void CloneSession(TracingSessionID, CloneSessionArgs) = 0;

  // Requests all data sources to flush their data immediately and invokes the
  // passed callback once all of them have acked the flush (in which case
  // the callback argument |success| will be true) or |timeout_ms| are elapsed
  // (in which case |success| will be false).
  // If |timeout_ms| is 0 the TraceConfig's flush_timeout_ms is used, or,
  // if that one is not set (or is set to 0), kDefaultFlushTimeoutMs (5s) is
  // used.
  using FlushCallback = std::function<void(bool /*success*/)>;
  virtual void Flush(uint32_t timeout_ms,
                     FlushCallback callback,
                     FlushFlags) = 0;

  // This is required for legacy out-of-repo clients like arctraceservice which
  // use the 2-version parameter.
  inline void Flush(uint32_t timeout_ms, FlushCallback callback) {
    Flush(timeout_ms, std::move(callback), FlushFlags());
  }

  // Tracing data will be delivered invoking Consumer::OnTraceData().
  virtual void ReadBuffers() = 0;

  virtual void FreeBuffers() = 0;

  // Will call OnDetach().
  virtual void Detach(const std::string& key) = 0;

  // Will call OnAttach().
  virtual void Attach(const std::string& key) = 0;

  // Will call OnTraceStats().
  virtual void GetTraceStats() = 0;

  // Start or stop observing events of selected types. |events_mask| specifies
  // the types of events to observe in a bitmask of ObservableEvents::Type.
  // To disable observing, pass 0.
  // Will call OnObservableEvents() repeatedly whenever an event of an enabled
  // ObservableEventType occurs.
  // TODO(eseckler): Extend this to support producers & data sources.
  virtual void ObserveEvents(uint32_t events_mask) = 0;

  // Used to obtain the list of connected data sources and other info about
  // the tracing service.
  struct QueryServiceStateArgs {
    // If set, only the TracingServiceState.tracing_sessions is filled.
    bool sessions_only = false;
  };
  using QueryServiceStateCallback =
      std::function<void(bool success, const TracingServiceState&)>;
  virtual void QueryServiceState(QueryServiceStateArgs,
                                 QueryServiceStateCallback) = 0;

  // Used for feature detection. Makes sense only when the consumer and the
  // service talk over IPC and can be from different versions.
  using QueryCapabilitiesCallback =
      std::function<void(const TracingServiceCapabilities&)>;
  virtual void QueryCapabilities(QueryCapabilitiesCallback) = 0;

  // If any tracing session with TraceConfig.bugreport_score > 0 is running,
  // this will pick the highest-score one, stop it and save it into a fixed
  // path (See kBugreportTracePath).
  // The callback is invoked when the file has been saved, in case of success,
  // or whenever an error occurs.
  // Args:
  // - success: if true, an eligible trace was found and saved into file.
  //            If false, either there was no eligible trace running or
  //            something else failed (See |msg|).
  // - msg: human readable diagnostic messages to debug failures.
  using SaveTraceForBugreportCallback =
      std::function<void(bool /*success*/, const std::string& /*msg*/)>;
  virtual void SaveTraceForBugreport(SaveTraceForBugreportCallback) = 0;
};  // class ConsumerEndpoint.

struct PERFETTO_EXPORT_COMPONENT TracingServiceInitOpts {
  // Function used by tracing service to compress packets. Takes a pointer to
  // a vector of TracePackets and replaces the packets in the vector with
  // compressed ones.
  using CompressorFn = void (*)(std::vector<TracePacket>*);
  CompressorFn compressor_fn = nullptr;

  // Whether the relay endpoint is enabled on producer transport(s).
  bool enable_relay_endpoint = false;
};

// The API for the Relay port of the Service. Subclassed by the
// tracing_service_impl.cc business logic when returning it in response to the
// ConnectRelayClient() method.
class PERFETTO_EXPORT_COMPONENT RelayEndpoint {
 public:
  virtual ~RelayEndpoint();

  // A snapshot of client and host clocks.
  struct SyncClockSnapshot {
    ClockSnapshotVector client_clock_snapshots;
    ClockSnapshotVector host_clock_snapshots;
  };

  enum class SyncMode : uint32_t { PING = 1, UPDATE = 2 };
  virtual void SyncClocks(SyncMode sync_mode,
                          ClockSnapshotVector client_clocks,
                          ClockSnapshotVector host_clocks) = 0;
  virtual void Disconnect() = 0;
};

// The public API of the tracing Service business logic.
//
// Exposed to:
// 1. The transport layer (e.g., src/unix_rpc/unix_service_host.cc),
//    which forwards commands received from a remote producer or consumer to
//    the actual service implementation.
// 2. Tests.
//
// Subclassed by:
//   The service business logic in src/core/tracing_service_impl.cc.
class PERFETTO_EXPORT_COMPONENT TracingService {
 public:
  using ProducerEndpoint = perfetto::ProducerEndpoint;
  using ConsumerEndpoint = perfetto::ConsumerEndpoint;
  using RelayEndpoint = perfetto::RelayEndpoint;
  using InitOpts = TracingServiceInitOpts;

  // Default sizes used by the service implementation and client library.
  static constexpr size_t kDefaultShmPageSize = 4096ul;
  static constexpr size_t kDefaultShmSize = 256 * 1024ul;

  enum class ProducerSMBScrapingMode {
    // Use service's default setting for SMB scraping. Currently, the default
    // mode is to disable SMB scraping, but this may change in the future.
    kDefault,

    // Enable scraping of uncommitted chunks in producers' shared memory
    // buffers.
    kEnabled,

    // Disable scraping of uncommitted chunks in producers' shared memory
    // buffers.
    kDisabled
  };

  // Implemented in src/core/tracing_service_impl.cc . CompressorFn can be
  // nullptr, in which case TracingService will not support compression.
  static std::unique_ptr<TracingService> CreateInstance(
      std::unique_ptr<SharedMemory::Factory>,
      base::TaskRunner*,
      InitOpts init_opts = {});

  virtual ~TracingService();

  // Connects a Producer instance and obtains a ProducerEndpoint, which is
  // essentially a 1:1 channel between one Producer and the Service.
  //
  // The caller has to guarantee that the passed Producer will be alive as long
  // as the returned ProducerEndpoint is alive. Both the passed Producer and the
  // returned ProducerEndpoint must live on the same task runner of the service,
  // specifically:
  // 1) The Service will call Producer::* methods on the Service's task runner.
  // 2) The Producer should call ProducerEndpoint::* methods only on the
  //    service's task runner, except for ProducerEndpoint::CreateTraceWriter(),
  //    which can be called on any thread. To disconnect just destroy the
  //    returned ProducerEndpoint object. It is safe to destroy the Producer
  //    once the Producer::OnDisconnect() has been invoked.
  //
  // |uid| is the trusted user id of the producer process, used by the consumers
  // for validating the origin of trace data. |shared_memory_size_hint_bytes|
  // and |shared_memory_page_size_hint_bytes| are optional hints on the size of
  // the shared memory buffer and its pages. The service can ignore the hints
  // (e.g., if the hints are unreasonably large or other sizes were configured
  // in a tracing session's config). |in_process| enables the ProducerEndpoint
  // to manage its own shared memory and enables use of
  // |ProducerEndpoint::CreateTraceWriter|.
  //
  // The producer can optionally provide a non-null |shm|, which the service
  // will adopt for the connection to the producer, provided it is correctly
  // sized. In this case, |shared_memory_page_size_hint_bytes| indicates the
  // page size used in this SMB. The producer can use this mechanism to record
  // tracing data to an SMB even before the tracing session is started by the
  // service. This is used in Chrome to implement startup tracing. If the buffer
  // is incorrectly sized, the service will discard the SMB and allocate a new
  // one, provided to the producer via ProducerEndpoint::shared_memory() after
  // OnTracingSetup(). To verify that the service accepted the SMB, the producer
  // may check via ProducerEndpoint::IsShmemProvidedByProducer(). If the service
  // accepted the SMB, the producer can then commit any data that is already in
  // the SMB after the tracing session was started by the service via
  // Producer::StartDataSource(). The |shm| will also be rejected when
  // connecting to a service that is too old (pre Android-11).
  //
  // Can return null in the unlikely event that service has too many producers
  // connected.
  virtual std::unique_ptr<ProducerEndpoint> ConnectProducer(
      Producer*,
      const ClientIdentity& client_identity,
      const std::string& name,
      size_t shared_memory_size_hint_bytes = 0,
      bool in_process = false,
      ProducerSMBScrapingMode smb_scraping_mode =
          ProducerSMBScrapingMode::kDefault,
      size_t shared_memory_page_size_hint_bytes = 0,
      std::unique_ptr<SharedMemory> shm = nullptr,
      const std::string& sdk_version = {}) = 0;

  // Connects a Consumer instance and obtains a ConsumerEndpoint, which is
  // essentially a 1:1 channel between one Consumer and the Service.
  // The caller has to guarantee that the passed Consumer will be alive as long
  // as the returned ConsumerEndpoint is alive.
  // To disconnect just destroy the returned ConsumerEndpoint object. It is safe
  // to destroy the Consumer once the Consumer::OnDisconnect() has been invoked.
  virtual std::unique_ptr<ConsumerEndpoint> ConnectConsumer(Consumer*,
                                                            uid_t) = 0;

  // Enable/disable scraping of chunks in the shared memory buffer. If enabled,
  // the service will copy uncommitted but non-empty chunks from the SMB when
  // flushing (e.g. to handle unresponsive producers or producers unable to
  // flush their active chunks), on producer disconnect (e.g. to recover data
  // from crashed producers), and after disabling a tracing session (e.g. to
  // gather data from producers that didn't stop their data sources in time).
  //
  // This feature is currently used by Chrome.
  virtual void SetSMBScrapingEnabled(bool enabled) = 0;

  using RelayClientID = std::pair<base::MachineID, /*client ID*/ uint64_t>;
  // Connects a remote RelayClient instance and obtains a RelayEndpoint, which
  // is a 1:1 channel between one RelayClient and the Service. To disconnect
  // just call Disconnect() of the RelayEndpoint instance. The relay client is
  // connected using an identifier of MachineID and client ID. The service
  // doesn't hold an object that represents the client because the relay port
  // only has a client-to-host SyncClock() method.
  //
  // TODO(chinglinyu): connect the relay client using a RelayClient* object when
  // we need host-to-client RPC method.
  virtual std::unique_ptr<RelayEndpoint> ConnectRelayClient(RelayClientID) = 0;
};

}  // namespace perfetto

#endif  // INCLUDE_PERFETTO_EXT_TRACING_CORE_TRACING_SERVICE_H_
/*
 * Copyright (C) 2018 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef INCLUDE_PERFETTO_EXT_TRACING_CORE_SHARED_MEMORY_ARBITER_H_
#define INCLUDE_PERFETTO_EXT_TRACING_CORE_SHARED_MEMORY_ARBITER_H_

#include <stddef.h>

#include <functional>
#include <memory>
#include <vector>

// gen_amalgamated expanded: #include "perfetto/base/export.h"
// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/basic_types.h"
// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/shared_memory_abi.h"
// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/tracing_service.h"
// gen_amalgamated expanded: #include "perfetto/tracing/buffer_exhausted_policy.h"

namespace perfetto {

namespace base {
class TaskRunner;
}

class SharedMemory;
class TraceWriter;

// Used by the Producer-side of the transport layer to vend TraceWriters
// from the SharedMemory it receives from the Service-side.
class PERFETTO_EXPORT_COMPONENT SharedMemoryArbiter {
 public:
  using ShmemMode = SharedMemoryABI::ShmemMode;

  virtual ~SharedMemoryArbiter();

  // Creates a new TraceWriter and assigns it a new WriterID. The WriterID is
  // written in each chunk header owned by a given TraceWriter and is used by
  // the Service to reconstruct TracePackets written by the same TraceWriter.
  // Returns null impl of TraceWriter if all WriterID slots are exhausted. The
  // writer will commit to the provided |target_buffer|. If the arbiter was
  // created via CreateUnbound() or CreateStartupTraceWriter() is later used,
  // only BufferExhaustedPolicy::kDrop is supported.
  virtual std::unique_ptr<TraceWriter> CreateTraceWriter(
      BufferID target_buffer,
      BufferExhaustedPolicy buffer_exhausted_policy =
          BufferExhaustedPolicy::kDefault) = 0;

  // Creates a TraceWriter that will commit to the target buffer with the given
  // reservation ID (creating a new reservation for this ID if none exists yet).
  // The buffer reservation should be bound to an actual BufferID via
  // BindStartupTargetBuffer() once the actual BufferID is known. Calling this
  // method may transition the arbiter into unbound state (see state diagram in
  // SharedMemoryArbiterImpl's class comment) and requires that all (past and
  // future) TraceWriters are created with BufferExhaustedPolicy::kDrop.
  //
  // While any unbound buffer reservation exists, all commits will be buffered
  // until all reservations were bound. Thus, until all reservations are bound,
  // the data written to the SMB will not be consumed by the service - the SMB
  // size should be chosen with this in mind. Startup writers always use
  // BufferExhaustedPolicy::kDrop, as we cannot feasibly stall while not
  // flushing to the service.
  //
  // The |target_buffer_reservation_id| should be greater than 0 but can
  // otherwise be freely chosen by the producer and is only used to translate
  // packets into the actual buffer id once
  // BindStartupTargetBuffer(reservation_id) is called. For example, Chrome uses
  // startup tracing not only for the first, but also subsequent tracing
  // sessions (to enable tracing in the browser process before it instructs the
  // tracing service to start tracing asynchronously, minimizing trace data loss
  // in the meantime), and increments the reservation ID between sessions.
  // Similarly, if more than a single target buffer per session is required
  // (e.g. for two different data sources), different reservation IDs should be
  // chosen for different target buffers.
  virtual std::unique_ptr<TraceWriter> CreateStartupTraceWriter(
      uint16_t target_buffer_reservation_id) = 0;

  // Should only be called on unbound SharedMemoryArbiters. Binds the arbiter to
  // the provided ProducerEndpoint and TaskRunner. Should be called only once
  // and on the provided |TaskRunner|. Usually called by the producer (i.e., no
  // specific data source) once it connects to the service. Both the endpoint
  // and task runner should remain valid for the remainder of the arbiter's
  // lifetime.
  virtual void BindToProducerEndpoint(TracingService::ProducerEndpoint*,
                                      base::TaskRunner*) = 0;

  // Binds commits from TraceWriters created via CreateStartupTraceWriter() with
  // the given |target_buffer_reservation_id| to |target_buffer_id|. May only be
  // called once per |target_buffer_reservation_id|. Should be called on the
  // arbiter's TaskRunner, and after BindToProducerEndpoint() was called.
  // Usually, it is called by a specific data source, after it received its
  // configuration (including the target buffer ID) from the service.
  virtual void BindStartupTargetBuffer(uint16_t target_buffer_reservation_id,
                                       BufferID target_buffer_id) = 0;

  // Treat the reservation as resolved to an invalid buffer. Commits for this
  // reservation will be flushed to the service ASAP. The service will free
  // committed chunks but otherwise ignore them. The producer can call this
  // method, for example, if connection to the tracing service failed or the
  // session was stopped concurrently before the connection was established.
  virtual void AbortStartupTracingForReservation(
      uint16_t target_buffer_reservation_id) = 0;

  // Notifies the service that all data for the given FlushRequestID has been
  // committed in the shared memory buffer. Should only be called while bound.
  virtual void NotifyFlushComplete(FlushRequestID) = 0;

  // Sets the duration during which commits are batched. Args:
  // |batch_commits_duration_ms|: The length of the period, during which commits
  // by all trace writers are accumulated, before being sent to the service.
  // When the period ends, all accumulated commits are flushed. On the first
  // commit after the last flush, another delayed flush is scheduled to run in
  // |batch_commits_duration_ms|. If an immediate flush occurs (via
  // FlushPendingCommitDataRequests()) during a batching period, any
  // accumulated commits up to that point will be sent to the service
  // immediately. And when the batching period ends, the commits that occurred
  // after the immediate flush will also be sent to the service.
  //
  // If the duration has already been set to a non-zero value before this method
  // is called, and there is already a scheduled flush with the previously-set
  // duration, the new duration will take effect after the scheduled flush
  // occurs.
  //
  // If |batch_commits_duration_ms| is non-zero, batched data that hasn't been
  // sent could be lost at the end of a tracing session. To avoid this,
  // producers should make sure that FlushPendingCommitDataRequests is called
  // after the last TraceWriter write and before the service has stopped
  // listening for commits from the tracing session's data sources (i.e.
  // data sources should stop asynchronously, see
  // DataSourceDescriptor.will_notify_on_stop=true).
  virtual void SetBatchCommitsDuration(uint32_t batch_commits_duration_ms) = 0;

  // Called to enable direct producer-side patching of chunks that have not yet
  // been committed to the service. The return value indicates whether direct
  // patching was successfully enabled. It will be true if
  // SharedMemoryArbiter::SetDirectSMBPatchingSupportedByService has been called
  // and false otherwise.
  virtual bool EnableDirectSMBPatching() = 0;

  // When the producer and service live in separate processes, this method
  // should be called if the producer receives an
  // InitializeConnectionResponse.direct_smb_patching_supported set to true by
  // the service (see producer_port.proto) .
  //
  // In the in-process case, the service will always support direct SMB patching
  // and this method should always be called.
  virtual void SetDirectSMBPatchingSupportedByService() = 0;

  // Forces an immediate commit of the completed packets, without waiting for
  // the next task or for a batching period to end. Should only be called while
  // bound.
  virtual void FlushPendingCommitDataRequests(
      std::function<void()> callback = {}) = 0;

  // Attempts to shut down this arbiter. This function prevents new trace
  // writers from being created for this this arbiter, but if there are any
  // existing trace writers, the shutdown cannot proceed and this funtion
  // returns false. The caller should not delete the arbiter before all of its
  // associated trace writers have been destroyed and this function returns
  // true.
  virtual bool TryShutdown() = 0;

  // Create a bound arbiter instance. Args:
  // |SharedMemory|: the shared memory buffer to use.
  // |page_size|: a multiple of 4KB that defines the granularity of tracing
  // pages. See tradeoff considerations in shared_memory_abi.h.
  // |ProducerEndpoint|: The service's producer endpoint used e.g. to commit
  // chunks and register trace writers.
  // |TaskRunner|: Task runner for perfetto's main thread, which executes the
  // OnPagesCompleteCallback and IPC calls to the |ProducerEndpoint|.
  //
  // Implemented in src/core/shared_memory_arbiter_impl.cc.
  static std::unique_ptr<SharedMemoryArbiter> CreateInstance(
      SharedMemory*,
      size_t page_size,
      ShmemMode,
      TracingService::ProducerEndpoint*,
      base::TaskRunner*);

  // Create an unbound arbiter instance, which should later be bound to a
  // ProducerEndpoint and TaskRunner by calling BindToProducerEndpoint(). The
  // returned arbiter will ONLY support trace writers with
  // BufferExhaustedPolicy::kDrop.
  //
  // An unbound SharedMemoryArbiter can be used to write to a producer-created
  // SharedMemory buffer before the producer connects to the tracing service.
  // The producer can then pass this SMB to the service when it connects (see
  // TracingService::ConnectProducer).
  //
  // To trace into the SMB before the service starts the tracing session, trace
  // writers can be obtained via CreateStartupTraceWriter() and later associated
  // with a target buffer via BindStartupTargetBuffer(), once the target buffer
  // is known.
  //
  // Implemented in src/core/shared_memory_arbiter_impl.cc. See CreateInstance()
  // for comments about the arguments.
  static std::unique_ptr<SharedMemoryArbiter>
  CreateUnboundInstance(SharedMemory*, size_t page_size, ShmemMode mode);
};

}  // namespace perfetto

#endif  // INCLUDE_PERFETTO_EXT_TRACING_CORE_SHARED_MEMORY_ARBITER_H_
/*
 * Copyright (C) 2017 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef SRC_TRACING_CORE_SHARED_MEMORY_ARBITER_IMPL_H_
#define SRC_TRACING_CORE_SHARED_MEMORY_ARBITER_IMPL_H_

#include <stdint.h>

#include <functional>
#include <map>
#include <memory>
#include <mutex>
#include <vector>

// gen_amalgamated expanded: #include "perfetto/ext/base/weak_ptr.h"
// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/basic_types.h"
// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/shared_memory_abi.h"
// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/shared_memory_arbiter.h"
// gen_amalgamated expanded: #include "perfetto/tracing/core/forward_decls.h"
// gen_amalgamated expanded: #include "src/tracing/core/id_allocator.h"

namespace perfetto {

class PatchList;
class Patch;
class TraceWriter;
class TraceWriterImpl;

namespace base {
class TaskRunner;
}  // namespace base

// This class handles the shared memory buffer on the producer side. It is used
// to obtain thread-local chunks and to partition pages from several threads.
// There is one arbiter instance per Producer.
// This class is thread-safe and uses locks to do so. Data sources are supposed
// to interact with this sporadically, only when they run out of space on their
// current thread-local chunk.
//
// The arbiter can become "unbound" as a consequence of:
//  (a) being created without an endpoint
//  (b) CreateStartupTraceWriter calls after creation (whether created with or
//      without endpoint).
//
// Entering the unbound state is only supported if all trace writers are created
// in kDrop mode. In the unbound state, the arbiter buffers commit messages
// until all trace writers are bound to a target buffer.
//
// The following state transitions are possible:
//
//   CreateInstance()
//    |
//    |  CreateUnboundInstance()
//    |    |
//    |    |
//    |    V
//    |  [ !fully_bound_, !endpoint_, 0 unbound buffer reservations ]
//    |      |     |
//    |      |     | CreateStartupTraceWriter(buf)
//    |      |     |  buffer reservations += buf
//    |      |     |
//    |      |     |             ----
//    |      |     |            |    | CreateStartupTraceWriter(buf)
//    |      |     |            |    |  buffer reservations += buf
//    |      |     V            |    V
//    |      |   [ !fully_bound_, !endpoint_, >=1 unbound buffer reservations ]
//    |      |                                                |
//    |      |                       BindToProducerEndpoint() |
//    |      |                                                |
//    |      | BindToProducerEndpoint()                       |
//    |      |                                                V
//    |      |   [ !fully_bound_, endpoint_, >=1 unbound buffer reservations ]
//    |      |   A    |    A                               |     A
//    |      |   |    |    |                               |     |
//    |      |   |     ----                                |     |
//    |      |   |    CreateStartupTraceWriter(buf)        |     |
//    |      |   |     buffer reservations += buf          |     |
//    |      |   |                                         |     |
//    |      |   | CreateStartupTraceWriter(buf)           |     |
//    |      |   |  where buf is not yet bound             |     |
//    |      |   |  buffer reservations += buf             |     | (yes)
//    |      |   |                                         |     |
//    |      |   |        BindStartupTargetBuffer(buf, id) |-----
//    |      |   |           buffer reservations -= buf    | reservations > 0?
//    |      |   |                                         |
//    |      |   |                                         | (no)
//    |      V   |                                         V
//     --> [ fully_bound_, endpoint_, 0 unbound buffer reservations ]
//              |    A
//              |    | CreateStartupTraceWriter(buf)
//              |    |  where buf is already bound
//               ----
class SharedMemoryArbiterImpl : public SharedMemoryArbiter {
 public:
  // See SharedMemoryArbiter::CreateInstance(). |start|, |size| define the
  // boundaries of the shared memory buffer. ProducerEndpoint and TaskRunner may
  // be |nullptr| if created unbound, see
  // SharedMemoryArbiter::CreateUnboundInstance().

  // SharedMemoryArbiterImpl(void* start,
  //                         size_t size,
  //                         size_t page_size,
  //                         TracingService::ProducerEndpoint*
  //                         producer_endpoint, base::TaskRunner* task_runner) :
  //   SharedMemoryArbiterImpl(start, size, page_size, false, producer_endpoint,
  //   task_runner) {
  // }

  SharedMemoryArbiterImpl(void* start,
                          size_t size,
                          ShmemMode mode,
                          size_t page_size,
                          TracingService::ProducerEndpoint*,
                          base::TaskRunner*);

  // Returns a new Chunk to write tracing data. Depending on the provided
  // BufferExhaustedPolicy, this may return an invalid chunk if no valid free
  // chunk could be found in the SMB.
  SharedMemoryABI::Chunk GetNewChunk(const SharedMemoryABI::ChunkHeader&,
                                     BufferExhaustedPolicy);

  // Puts back a Chunk that has been completed and sends a request to the
  // service to move it to the central tracing buffer. |target_buffer| is the
  // absolute trace buffer ID where the service should move the chunk onto (the
  // producer is just to copy back the same number received in the
  // DataSourceConfig upon the StartDataSource() reques).
  // PatchList is a pointer to the list of patches for previous chunks. The
  // first patched entries will be removed from the patched list and sent over
  // to the service in the same CommitData() IPC request.
  void ReturnCompletedChunk(SharedMemoryABI::Chunk,
                            MaybeUnboundBufferID target_buffer,
                            PatchList*);

  // Send a request to the service to apply completed patches from |patch_list|.
  // |writer_id| is the ID of the TraceWriter that calls this method,
  // |target_buffer| is the global trace buffer ID of its target buffer.
  void SendPatches(WriterID writer_id,
                   MaybeUnboundBufferID target_buffer,
                   PatchList* patch_list);

  SharedMemoryABI* shmem_abi_for_testing() { return &shmem_abi_; }

  static void set_default_layout_for_testing(SharedMemoryABI::PageLayout l) {
    default_page_layout = l;
  }

  static SharedMemoryABI::PageLayout default_page_layout_for_testing() {
    return default_page_layout;
  }

  // SharedMemoryArbiter implementation.
  // See include/perfetto/tracing/core/shared_memory_arbiter.h for comments.
  std::unique_ptr<TraceWriter> CreateTraceWriter(
      BufferID target_buffer,
      BufferExhaustedPolicy = BufferExhaustedPolicy::kDefault) override;
  std::unique_ptr<TraceWriter> CreateStartupTraceWriter(
      uint16_t target_buffer_reservation_id) override;
  void BindToProducerEndpoint(TracingService::ProducerEndpoint*,
                              base::TaskRunner*) override;
  void BindStartupTargetBuffer(uint16_t target_buffer_reservation_id,
                               BufferID target_buffer_id) override;
  void AbortStartupTracingForReservation(
      uint16_t target_buffer_reservation_id) override;
  void NotifyFlushComplete(FlushRequestID) override;

  void SetBatchCommitsDuration(uint32_t batch_commits_duration_ms) override;

  bool EnableDirectSMBPatching() override;

  void SetDirectSMBPatchingSupportedByService() override;

  void FlushPendingCommitDataRequests(
      std::function<void()> callback = {}) override;
  bool TryShutdown() override;

  base::TaskRunner* task_runner() const { return task_runner_; }
  size_t page_size() const { return shmem_abi_.page_size(); }
  size_t num_pages() const { return shmem_abi_.num_pages(); }

  base::WeakPtr<SharedMemoryArbiterImpl> GetWeakPtr() const {
    return weak_ptr_factory_.GetWeakPtr();
  }

 private:
  friend class TraceWriterImpl;
  friend class StartupTraceWriterTest;
  friend class SharedMemoryArbiterImplTest;

  struct TargetBufferReservation {
    bool resolved = false;
    BufferID target_buffer = kInvalidBufferId;
  };

  // Placeholder for the actual target buffer ID of a startup target buffer
  // reservation ID in |target_buffer_reservations_|.
  static constexpr BufferID kInvalidBufferId = 0;

  static SharedMemoryABI::PageLayout default_page_layout;

  SharedMemoryArbiterImpl(const SharedMemoryArbiterImpl&) = delete;
  SharedMemoryArbiterImpl& operator=(const SharedMemoryArbiterImpl&) = delete;

  void UpdateCommitDataRequest(SharedMemoryABI::Chunk chunk,
                               WriterID writer_id,
                               MaybeUnboundBufferID target_buffer,
                               PatchList* patch_list);

  // Search the chunks that are being batched in |commit_data_req_| for a chunk
  // that needs patching and that matches the provided |writer_id| and
  // |patch.chunk_id|. If found, apply |patch| to that chunk, and if
  // |chunk_needs_more_patching| is true, clear the needs patching flag of the
  // chunk and mark it as complete - to allow the service to read it (and other
  // chunks after it) during scraping. Returns true if the patch was applied,
  // false otherwise.
  //
  // Note: the caller must be holding |lock_| for the duration of the call.
  bool TryDirectPatchLocked(WriterID writer_id,
                            const Patch& patch,
                            bool chunk_needs_more_patching);
  std::unique_ptr<TraceWriter> CreateTraceWriterInternal(
      MaybeUnboundBufferID target_buffer,
      BufferExhaustedPolicy);

  // Called by the TraceWriter destructor.
  void ReleaseWriterID(WriterID);

  void BindStartupTargetBufferImpl(std::unique_lock<std::mutex> scoped_lock,
                                   uint16_t target_buffer_reservation_id,
                                   BufferID target_buffer_id);

  // If any flush callbacks were queued up while the arbiter or any target
  // buffer reservation was unbound, this wraps the pending callbacks into a new
  // std::function and returns it. Otherwise returns an invalid std::function.
  std::function<void()> TakePendingFlushCallbacksLocked();

  // Replace occurrences of target buffer reservation IDs in |commit_data_req_|
  // with their respective actual BufferIDs if they were already bound. Returns
  // true iff all occurrences were replaced.
  bool ReplaceCommitPlaceholderBufferIdsLocked();

  // Update and return |fully_bound_| based on the arbiter's |pending_writers_|
  // state.
  bool UpdateFullyBoundLocked();

  // Only accessed on |task_runner_| after the producer endpoint was bound.
  TracingService::ProducerEndpoint* producer_endpoint_ = nullptr;

  // Set to true when this instance runs in a emulation mode for a producer
  // endpoint that doesn't support shared memory (e.g. vsock).
  const bool use_shmem_emulation_ = false;

  // --- Begin lock-protected members ---

  std::mutex lock_;

  base::TaskRunner* task_runner_ = nullptr;
  SharedMemoryABI shmem_abi_;
  size_t page_idx_ = 0;
  std::unique_ptr<CommitDataRequest> commit_data_req_;
  size_t bytes_pending_commit_ = 0;  // SUM(chunk.size() : commit_data_req_).
  IdAllocator<WriterID> active_writer_ids_;
  bool did_shutdown_ = false;

  // Whether the arbiter itself and all startup target buffer reservations are
  // bound. Note that this can become false again later if a new target buffer
  // reservation is created by calling CreateStartupTraceWriter() with a new
  // reservation id.
  bool fully_bound_;

  // Whether the arbiter was always bound. If false, the arbiter was unbound at
  // one point in time.
  bool was_always_bound_;

  // Whether all created trace writers were created with kDrop policy.
  bool all_writers_have_drop_policy_ = true;

  // IDs of writers and their assigned target buffers that should be registered
  // with the service after the arbiter and/or their startup target buffer is
  // bound.
  std::map<WriterID, MaybeUnboundBufferID> pending_writers_;

  // Callbacks for flush requests issued while the arbiter or a target buffer
  // reservation was unbound.
  std::vector<std::function<void()>> pending_flush_callbacks_;

  // See SharedMemoryArbiter::SetBatchCommitsDuration.
  uint32_t batch_commits_duration_ms_ = 0;

  // See SharedMemoryArbiter::EnableDirectSMBPatching.
  bool direct_patching_enabled_ = false;

  // See SharedMemoryArbiter::SetDirectSMBPatchingSupportedByService.
  bool direct_patching_supported_by_service_ = false;

  // Indicates whether we have already scheduled a delayed flush for the
  // purposes of batching. Set to true at the beginning of a batching period and
  // cleared at the end of the period. Immediate flushes that happen during a
  // batching period will empty the |commit_data_req| (triggering an immediate
  // IPC to the service), but will not clear this flag and the
  // previously-scheduled delayed flush will still occur at the end of the
  // batching period.
  bool delayed_flush_scheduled_ = false;

  // Stores target buffer reservations for writers created via
  // CreateStartupTraceWriter(). A bound reservation sets
  // TargetBufferReservation::resolved to true and is associated with the actual
  // BufferID supplied in BindStartupTargetBuffer().
  //
  // TODO(eseckler): Clean up entries from this map. This would probably require
  // a method in SharedMemoryArbiter that allows a producer to invalidate a
  // reservation ID.
  std::map<MaybeUnboundBufferID, TargetBufferReservation>
      target_buffer_reservations_;

  // --- End lock-protected members ---

  // Keep at the end.
  base::WeakPtrFactory<SharedMemoryArbiterImpl> weak_ptr_factory_;
};

}  // namespace perfetto

#endif  // SRC_TRACING_CORE_SHARED_MEMORY_ARBITER_IMPL_H_
// gen_amalgamated begin header: include/perfetto/ext/tracing/core/commit_data_request.h
/*
 * Copyright (C) 2017 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef INCLUDE_PERFETTO_EXT_TRACING_CORE_COMMIT_DATA_REQUEST_H_
#define INCLUDE_PERFETTO_EXT_TRACING_CORE_COMMIT_DATA_REQUEST_H_

// Creates the aliases in the ::perfetto namespace, doing things like:
// using ::perfetto::Foo = ::perfetto::protos::gen::Foo.
// See comments in forward_decls.h for the historical reasons of this
// indirection layer.
// gen_amalgamated expanded: #include "perfetto/tracing/core/forward_decls.h"

// gen_amalgamated expanded: #include "protos/perfetto/common/commit_data_request.gen.h"

#endif  // INCLUDE_PERFETTO_EXT_TRACING_CORE_COMMIT_DATA_REQUEST_H_
// gen_amalgamated begin header: src/tracing/core/trace_writer_impl.h
// gen_amalgamated begin header: src/tracing/core/patch_list.h
/*
 * Copyright (C) 2018 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef SRC_TRACING_CORE_PATCH_LIST_H_
#define SRC_TRACING_CORE_PATCH_LIST_H_

#include <array>
#include <forward_list>

// gen_amalgamated expanded: #include "perfetto/base/logging.h"
// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/basic_types.h"
// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/shared_memory_abi.h"

namespace perfetto {

// Used to handle the backfilling of the headers (the |size_field|) of nested
// messages when a proto is fragmented over several chunks. These patches are
// sent out-of-band to the tracing service, after having returned the initial
// chunks of the fragment.
// TODO(crbug.com/904477): Re-disable the move constructors when all usses of
// this class have been fixed.
class Patch {
 public:
  using PatchContent = std::array<uint8_t, SharedMemoryABI::kPacketHeaderSize>;
  Patch(ChunkID c, uint16_t o) : chunk_id(c), offset(o) {}
  Patch(const Patch&) = default;  // For tests.

  const ChunkID chunk_id;
  const uint16_t offset;
  PatchContent size_field{};

  // |size_field| contains a varint. Any varint must start with != 0. Even in
  // the case we want to encode a size == 0, protozero will write a redundant
  // varint for that, that is [0x80, 0x80, 0x80, 0x00]. So the first byte is 0
  // iff we never wrote any varint into that.
  bool is_patched() const { return size_field[0] != 0; }

  // For tests.
  bool operator==(const Patch& o) const {
    return chunk_id == o.chunk_id && offset == o.offset &&
           size_field == o.size_field;
  }

 private:
  Patch& operator=(const Patch&) = delete;
};

// Note: the protozero::Message(s) will take pointers to the |size_field| of
// these entries. This container must guarantee that the Patch objects are never
// moved around (i.e. cannot be a vector because of reallocations can change
// addresses of pre-existing entries).
class PatchList {
 public:
  using ListType = std::forward_list<Patch>;
  using value_type = ListType::value_type;          // For gtest.
  using const_iterator = ListType::const_iterator;  // For gtest.

  PatchList() : last_(list_.before_begin()) {}

  Patch* emplace_back(ChunkID chunk_id, uint16_t offset) {
    last_ = list_.emplace_after(last_, chunk_id, offset);
    return &*last_;
  }

  void pop_front() {
    PERFETTO_DCHECK(!list_.empty());
    list_.pop_front();
    if (empty())
      last_ = list_.before_begin();
  }

  const Patch& front() const {
    PERFETTO_DCHECK(!list_.empty());
    return list_.front();
  }

  const Patch& back() const {
    PERFETTO_DCHECK(!list_.empty());
    return *last_;
  }

  ListType::const_iterator begin() const { return list_.begin(); }
  ListType::const_iterator end() const { return list_.end(); }
  bool empty() const { return list_.empty(); }

 private:
  ListType list_;
  ListType::iterator last_;
};

}  // namespace perfetto

#endif  // SRC_TRACING_CORE_PATCH_LIST_H_
/*
 * Copyright (C) 2017 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef SRC_TRACING_CORE_TRACE_WRITER_IMPL_H_
#define SRC_TRACING_CORE_TRACE_WRITER_IMPL_H_

// gen_amalgamated expanded: #include "perfetto/base/proc_utils.h"
// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/basic_types.h"
// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/shared_memory_abi.h"
// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/shared_memory_arbiter.h"
// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/trace_writer.h"
// gen_amalgamated expanded: #include "perfetto/protozero/message_handle.h"
// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
// gen_amalgamated expanded: #include "perfetto/protozero/root_message.h"
// gen_amalgamated expanded: #include "perfetto/protozero/scattered_stream_writer.h"
// gen_amalgamated expanded: #include "perfetto/tracing/buffer_exhausted_policy.h"
// gen_amalgamated expanded: #include "src/tracing/core/patch_list.h"

namespace perfetto {

class SharedMemoryArbiterImpl;

// See //include/perfetto/ext/tracing/core/trace_writer.h for docs.
//
// Locking will happen only when a chunk is exhausted and a new one is
// acquired from the arbiter.
//
// TODO: TraceWriter needs to keep the shared memory buffer alive (refcount?).
// Otherwise if the shared memory buffer goes away (e.g. the Service crashes)
// the TraceWriter will keep writing into unmapped memory.
//
class TraceWriterImpl : public TraceWriter,
                        public protozero::MessageFinalizationListener,
                        public protozero::ScatteredStreamWriter::Delegate {
 public:
  // TracePacketHandle is defined in trace_writer.h
  TraceWriterImpl(SharedMemoryArbiterImpl*,
                  WriterID,
                  MaybeUnboundBufferID buffer_id,
                  BufferExhaustedPolicy);
  ~TraceWriterImpl() override;

  // TraceWriter implementation. See documentation in trace_writer.h.
  TracePacketHandle NewTracePacket() override;
  void FinishTracePacket() override;
  // Commits the data pending for the current chunk into the shared memory
  // buffer and sends a CommitDataRequest() to the service.
  // TODO(primiano): right now the |callback| will be called on the IPC thread.
  // This is fine in the current single-thread scenario, but long-term
  // trace_writer_impl.cc should be smarter and post it on the right thread.
  void Flush(std::function<void()> callback = {}) override;
  WriterID writer_id() const override;
  uint64_t written() const override {
    return protobuf_stream_writer_.written();
  }

  void ResetChunkForTesting() {
    cur_chunk_ = SharedMemoryABI::Chunk();
    cur_chunk_packet_count_inflated_ = false;
  }
  bool drop_packets_for_testing() const { return drop_packets_; }

 private:
  TraceWriterImpl(const TraceWriterImpl&) = delete;
  TraceWriterImpl& operator=(const TraceWriterImpl&) = delete;

  // ScatteredStreamWriter::Delegate implementation.
  protozero::ContiguousMemoryRange GetNewBuffer() override;
  uint8_t* AnnotatePatch(uint8_t*) override;

  // MessageFinalizationListener implementation.
  void OnMessageFinalized(protozero::Message*) override;

  // Writes the size of the current fragment into the chunk.
  //
  // The size of nested messages inside TracePacket is written by
  // by the user, but the size of the TracePacket fragments is written by
  // TraceWriterImpl.
  void FinalizeFragmentIfRequired();

  // Returns |cur_chunk_| (for which is_valid() must be true) to the
  // |shmem_arbiter|.
  void ReturnCompletedChunk();

  // The per-producer arbiter that coordinates access to the shared memory
  // buffer from several threads.
  SharedMemoryArbiterImpl* const shmem_arbiter_;

  // ID of the current writer.
  const WriterID id_;

  // This is copied into the commit request by SharedMemoryArbiter. See comments
  // in data_source_config.proto for |target_buffer|. If this is a reservation
  // for a buffer ID in case of a startup trace writer, SharedMemoryArbiterImpl
  // will also translate the reservation ID to the actual buffer ID.
  const MaybeUnboundBufferID target_buffer_;

  // Whether GetNewChunk() should stall or return an invalid chunk if the SMB is
  // exhausted.
  const BufferExhaustedPolicy buffer_exhausted_policy_;

  // Monotonic (% wrapping) sequence id of the chunk. Together with the WriterID
  // this allows the Service to reconstruct the linear sequence of packets.
  ChunkID next_chunk_id_ = 0;

  // The chunk we are holding onto (if any).
  SharedMemoryABI::Chunk cur_chunk_;

  // Passed to protozero message to write directly into |cur_chunk_|. It
  // keeps track of the write pointer. It calls us back (GetNewBuffer()) when
  // |cur_chunk_| is filled.
  protozero::ScatteredStreamWriter protobuf_stream_writer_;

  // The packet returned via NewTracePacket(). Its owned by this class,
  // TracePacketHandle has just a pointer to it.
  //
  // The caller of NewTracePacket can use TakeStreamWriter() and use the stream
  // writer directly: in that case:
  // * cur_packet_->size() is not up to date. Only the stream writer has the
  //   correct information.
  // * cur_packet_->nested_message() is always nullptr.
  // * cur_packet_->size_field() is still used to track the start of the current
  //   fragment.
  std::unique_ptr<protozero::RootMessage<protos::pbzero::TracePacket>>
      cur_packet_;

  // The start address of |cur_packet_| within |cur_chunk_|. Used to figure out
  // fragments sizes when a TracePacket write is interrupted by GetNewBuffer().
  uint8_t* cur_fragment_start_ = nullptr;

  // true if we received a call to GetNewBuffer() after NewTracePacket(),
  // false if GetNewBuffer() happened during NewTracePacket() prologue, while
  // starting the TracePacket header.
  bool fragmenting_packet_ = false;

  // Set to |true| when the current chunk contains the maximum number of packets
  // a chunk can contain. When this is |true|, the next packet requires starting
  // a new chunk.
  bool reached_max_packets_per_chunk_ = false;

  // If we fail to acquire a new chunk when the arbiter operates in
  // SharedMemory::BufferExhaustedPolicy::kDrop mode, the trace writer enters a
  // mode in which data is written to a local garbage chunk and dropped.
  bool drop_packets_ = false;

  // Whether the trace writer should try to acquire a new chunk from the SMB
  // when the next TracePacket is started because it filled the garbage chunk at
  // least once since the last attempt.
  bool retry_new_chunk_after_packet_ = false;

  // Set to true if `cur_chunk_` has a packet counter that's inflated by one.
  // The count may be inflated to convince the tracing service scraping logic
  // that the last packet has been completed. When this is true, cur_chunk_
  // should have at least `kExtraRoomForInflatedPacket` bytes free.
  bool cur_chunk_packet_count_inflated_ = false;

  // Points to the size field of the still open fragment we're writing to the
  // current chunk. If the chunk was already returned, this is reset to
  // |nullptr|. If the fragment is finalized, this is reset to |nullptr|.
  //
  // Note: for nested messages the field is tracked somewhere else
  // (protozero::Message::size_field_ or PerfettoPbMsg::size_field). For the
  // root message, protozero::Message::size_field_ is nullptr and this is used
  // instead. This is because at the root level we deal with fragments, not
  // logical messages.
  uint8_t* cur_fragment_size_field_ = nullptr;

  // When a packet is fragmented across different chunks, the |size_field| of
  // the outstanding nested protobuf messages is redirected onto Patch entries
  // in this list at the time the Chunk is returned (because at that point we
  // have to release the ownership of the current Chunk). This list will be
  // later sent out-of-band to the tracing service, who will patch the required
  // chunks, if they are still around.
  PatchList patch_list_;

  // PID of the process that created the trace writer. Used for a DCHECK that
  // aims to detect unsupported process forks while tracing.
  const base::PlatformProcessId process_id_;

  // True for the first packet on sequence. See the comment for
  // TracePacket.first_packet_on_sequence for more details.
  bool first_packet_on_sequence_ = true;
};

}  // namespace perfetto

#endif  // SRC_TRACING_CORE_TRACE_WRITER_IMPL_H_
/*
 * Copyright (C) 2017 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// gen_amalgamated expanded: #include "src/tracing/core/shared_memory_arbiter_impl.h"

#include <algorithm>
#include <limits>
#include <utility>

// gen_amalgamated expanded: #include "perfetto/base/logging.h"
// gen_amalgamated expanded: #include "perfetto/base/task_runner.h"
// gen_amalgamated expanded: #include "perfetto/base/time.h"
// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/commit_data_request.h"
// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/shared_memory.h"
// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/shared_memory_abi.h"
// gen_amalgamated expanded: #include "src/tracing/core/null_trace_writer.h"
// gen_amalgamated expanded: #include "src/tracing/core/trace_writer_impl.h"

namespace perfetto {

using Chunk = SharedMemoryABI::Chunk;

namespace {
static_assert(sizeof(BufferID) == sizeof(uint16_t),
              "The MaybeUnboundBufferID logic requires BufferID not to grow "
              "above uint16_t.");

MaybeUnboundBufferID MakeTargetBufferIdForReservation(uint16_t reservation_id) {
  // Reservation IDs are stored in the upper bits.
  PERFETTO_CHECK(reservation_id > 0);
  return static_cast<MaybeUnboundBufferID>(reservation_id) << 16;
}

bool IsReservationTargetBufferId(MaybeUnboundBufferID buffer_id) {
  return (buffer_id >> 16) > 0;
}
}  // namespace

// static
SharedMemoryABI::PageLayout SharedMemoryArbiterImpl::default_page_layout =
    SharedMemoryABI::PageLayout::kPageDiv1;

// static
std::unique_ptr<SharedMemoryArbiter> SharedMemoryArbiter::CreateInstance(
    SharedMemory* shared_memory,
    size_t page_size,
    ShmemMode mode,
    TracingService::ProducerEndpoint* producer_endpoint,
    base::TaskRunner* task_runner) {
  return std::unique_ptr<SharedMemoryArbiterImpl>(new SharedMemoryArbiterImpl(
      shared_memory->start(), shared_memory->size(), mode, page_size,
      producer_endpoint, task_runner));
}

// static
std::unique_ptr<SharedMemoryArbiter> SharedMemoryArbiter::CreateUnboundInstance(
    SharedMemory* shared_memory,
    size_t page_size,
    ShmemMode mode) {
  return std::unique_ptr<SharedMemoryArbiterImpl>(new SharedMemoryArbiterImpl(
      shared_memory->start(), shared_memory->size(), mode, page_size,
      /*producer_endpoint=*/nullptr, /*task_runner=*/nullptr));
}

SharedMemoryArbiterImpl::SharedMemoryArbiterImpl(
    void* start,
    size_t size,
    ShmemMode mode,
    size_t page_size,
    TracingService::ProducerEndpoint* producer_endpoint,
    base::TaskRunner* task_runner)
    : producer_endpoint_(producer_endpoint),
      use_shmem_emulation_(mode == ShmemMode::kShmemEmulation),
      task_runner_(task_runner),
      shmem_abi_(reinterpret_cast<uint8_t*>(start), size, page_size, mode),
      active_writer_ids_(kMaxWriterID),
      fully_bound_(task_runner && producer_endpoint),
      was_always_bound_(fully_bound_),
      weak_ptr_factory_(this) {}

Chunk SharedMemoryArbiterImpl::GetNewChunk(
    const SharedMemoryABI::ChunkHeader& header,
    BufferExhaustedPolicy buffer_exhausted_policy) {
  int stall_count = 0;
  unsigned stall_interval_us = 0;
  bool task_runner_runs_on_current_thread = false;
  static const unsigned kMaxStallIntervalUs = 100000;
  static const int kLogAfterNStalls = 3;
  static const int kFlushCommitsAfterEveryNStalls = 2;
  static const int kAssertAtNStalls = 200;

  for (;;) {
    // TODO(primiano): Probably this lock is not really required and this code
    // could be rewritten leveraging only the Try* atomic operations in
    // SharedMemoryABI. But let's not be too adventurous for the moment.
    {
      std::unique_lock<std::mutex> scoped_lock(lock_);

      // If ever unbound, we do not support stalling. In theory, we could
      // support stalling for TraceWriters created after the arbiter and startup
      // buffer reservations were bound, but to avoid raciness between the
      // creation of startup writers and binding, we categorically forbid kStall
      // mode.
      PERFETTO_DCHECK(was_always_bound_ ||
                      buffer_exhausted_policy == BufferExhaustedPolicy::kDrop);

      task_runner_runs_on_current_thread =
          task_runner_ && task_runner_->RunsTasksOnCurrentThread();

      // If more than half of the SMB.size() is filled with completed chunks for
      // which we haven't notified the service yet (i.e. they are still enqueued
      // in |commit_data_req_|), force a synchronous CommitDataRequest() even if
      // we acquire a chunk, to reduce the likeliness of stalling the writer.
      //
      // We can only do this if we're writing on the same thread that we access
      // the producer endpoint on, since we cannot notify the producer endpoint
      // to commit synchronously on a different thread. Attempting to flush
      // synchronously on another thread will lead to subtle bugs caused by
      // out-of-order commit requests (crbug.com/919187#c28).
      bool should_commit_synchronously =
          task_runner_runs_on_current_thread &&
          buffer_exhausted_policy == BufferExhaustedPolicy::kStall &&
          commit_data_req_ && bytes_pending_commit_ >= shmem_abi_.size() / 2;

      const size_t initial_page_idx = page_idx_;
      for (size_t i = 0; i < shmem_abi_.num_pages(); i++) {
        page_idx_ = (initial_page_idx + i) % shmem_abi_.num_pages();
        bool is_new_page = false;

        // TODO(primiano): make the page layout dynamic.
        auto layout = SharedMemoryArbiterImpl::default_page_layout;

        if (shmem_abi_.is_page_free(page_idx_)) {
          // TODO(primiano): Use the |size_hint| here to decide the layout.
          is_new_page = shmem_abi_.TryPartitionPage(page_idx_, layout);
        }
        uint32_t free_chunks;
        if (is_new_page) {
          free_chunks = (1 << SharedMemoryABI::kNumChunksForLayout[layout]) - 1;
        } else {
          free_chunks = shmem_abi_.GetFreeChunks(page_idx_);
        }

        for (uint32_t chunk_idx = 0; free_chunks;
             chunk_idx++, free_chunks >>= 1) {
          if (!(free_chunks & 1))
            continue;
          // We found a free chunk.
          Chunk chunk = shmem_abi_.TryAcquireChunkForWriting(
              page_idx_, chunk_idx, &header);
          if (!chunk.is_valid())
            continue;
          if (stall_count > kLogAfterNStalls) {
            PERFETTO_LOG("Recovered from stall after %d iterations",
                         stall_count);
          }

          if (should_commit_synchronously) {
            // We can't flush while holding the lock.
            scoped_lock.unlock();
            FlushPendingCommitDataRequests();
            return chunk;
          } else {
            return chunk;
          }
        }
      }
    }  // scoped_lock

    if (buffer_exhausted_policy == BufferExhaustedPolicy::kDrop) {
      PERFETTO_DLOG("Shared memory buffer exhausted, returning invalid Chunk!");
      return Chunk();
    }

    // Stalling is not supported if we were ever unbound (see earlier comment).
    PERFETTO_CHECK(was_always_bound_);

    // All chunks are taken (either kBeingWritten by us or kBeingRead by the
    // Service).
    if (stall_count++ == kLogAfterNStalls) {
      PERFETTO_LOG("Shared memory buffer overrun! Stalling");
    }

    if (stall_count == kAssertAtNStalls) {
      PERFETTO_FATAL(
          "Shared memory buffer max stall count exceeded; possible deadlock");
    }

    // If the IPC thread itself is stalled because the current process has
    // filled up the SMB, we need to make sure that the service can process and
    // purge the chunks written by our process, by flushing any pending commit
    // requests. Because other threads in our process can continue to
    // concurrently grab, fill and commit any chunks purged by the service, it
    // is possible that the SMB remains full and the IPC thread remains stalled,
    // needing to flush the concurrently queued up commits again. This is
    // particularly likely with in-process perfetto service where the IPC thread
    // is the service thread. To avoid remaining stalled forever in such a
    // situation, we attempt to flush periodically after every N stalls.
    if (stall_count % kFlushCommitsAfterEveryNStalls == 0 &&
        task_runner_runs_on_current_thread) {
      // TODO(primiano): sending the IPC synchronously is a temporary workaround
      // until the backpressure logic in probes_producer is sorted out. Until
      // then the risk is that we stall the message loop waiting for the tracing
      // service to consume the shared memory buffer (SMB) and, for this reason,
      // never run the task that tells the service to purge the SMB. This must
      // happen iff we are on the IPC thread, not doing this will cause
      // deadlocks, doing this on the wrong thread causes out-of-order data
      // commits (crbug.com/919187#c28).
      FlushPendingCommitDataRequests();
    } else {
      base::SleepMicroseconds(stall_interval_us);
      stall_interval_us =
          std::min(kMaxStallIntervalUs, (stall_interval_us + 1) * 8);
    }
  }
}

void SharedMemoryArbiterImpl::ReturnCompletedChunk(
    Chunk chunk,
    MaybeUnboundBufferID target_buffer,
    PatchList* patch_list) {
  PERFETTO_DCHECK(chunk.is_valid());
  const WriterID writer_id = chunk.writer_id();
  UpdateCommitDataRequest(std::move(chunk), writer_id, target_buffer,
                          patch_list);
}

void SharedMemoryArbiterImpl::SendPatches(WriterID writer_id,
                                          MaybeUnboundBufferID target_buffer,
                                          PatchList* patch_list) {
  PERFETTO_DCHECK(!patch_list->empty() && patch_list->front().is_patched());
  UpdateCommitDataRequest(Chunk(), writer_id, target_buffer, patch_list);
}

void SharedMemoryArbiterImpl::UpdateCommitDataRequest(
    Chunk chunk,
    WriterID writer_id,
    MaybeUnboundBufferID target_buffer,
    PatchList* patch_list) {
  // Note: chunk will be invalid if the call came from SendPatches().
  base::TaskRunner* task_runner_to_post_delayed_callback_on = nullptr;
  // The delay with which the flush will be posted.
  uint32_t flush_delay_ms = 0;
  base::WeakPtr<SharedMemoryArbiterImpl> weak_this;
  {
    std::lock_guard<std::mutex> scoped_lock(lock_);

    if (!commit_data_req_) {
      commit_data_req_.reset(new CommitDataRequest());

      // Flushing the commit is only supported while we're |fully_bound_|. If we
      // aren't, we'll flush when |fully_bound_| is updated.
      if (fully_bound_ && !delayed_flush_scheduled_) {
        weak_this = weak_ptr_factory_.GetWeakPtr();
        task_runner_to_post_delayed_callback_on = task_runner_;
        flush_delay_ms = batch_commits_duration_ms_;
        delayed_flush_scheduled_ = true;
      }
    }

    CommitDataRequest::ChunksToMove* ctm = nullptr;  // Set if chunk is valid.
    // If a valid chunk is specified, return it and attach it to the request.
    if (chunk.is_valid()) {
      PERFETTO_DCHECK(chunk.writer_id() == writer_id);
      uint8_t chunk_idx = chunk.chunk_idx();
      bytes_pending_commit_ += chunk.size();
      size_t page_idx;

      ctm = commit_data_req_->add_chunks_to_move();
      // If the chunk needs patching, it should not be marked as complete yet,
      // because this would indicate to the service that the producer will not
      // be writing to it anymore, while the producer might still apply patches
      // to the chunk later on. In particular, when re-reading (e.g. because of
      // periodic scraping) a completed chunk, the service expects the flags of
      // that chunk not to be removed between reads. So, let's say the producer
      // marked the chunk as complete here and the service then read it for the
      // first time. If the producer then fully patched the chunk, thus removing
      // the kChunkNeedsPatching flag, and the service re-read the chunk after
      // the patching, the service would be thrown off by the removed flag.
      if (direct_patching_enabled_ &&
          (chunk.GetPacketCountAndFlags().second &
           SharedMemoryABI::ChunkHeader::kChunkNeedsPatching)) {
        page_idx = shmem_abi_.GetPageAndChunkIndex(std::move(chunk)).first;
      } else {
        // If the chunk doesn't need patching, we can mark it as complete
        // immediately. This allows the service to read it in full while
        // scraping, which would not be the case if the chunk was left in a
        // kChunkBeingWritten state.
        page_idx = shmem_abi_.ReleaseChunkAsComplete(std::move(chunk));
      }

      // DO NOT access |chunk| after this point, it has been std::move()-d
      // above.
      ctm->set_page(static_cast<uint32_t>(page_idx));
      ctm->set_chunk(chunk_idx);
      ctm->set_target_buffer(target_buffer);
    }

    // Process the completed patches for previous chunks from the |patch_list|.
    CommitDataRequest::ChunkToPatch* last_patch_req = nullptr;
    while (!patch_list->empty() && patch_list->front().is_patched()) {
      Patch curr_patch = patch_list->front();
      patch_list->pop_front();
      // Patches for the same chunk are contiguous in the |patch_list|. So, to
      // determine if there are any other patches that apply to the chunk that
      // is being patched, check if the next patch in the |patch_list| applies
      // to the same chunk.
      bool chunk_needs_more_patching =
          !patch_list->empty() &&
          patch_list->front().chunk_id == curr_patch.chunk_id;

      if (direct_patching_enabled_ &&
          TryDirectPatchLocked(writer_id, curr_patch,
                               chunk_needs_more_patching)) {
        continue;
      }

      // The chunk that this patch applies to has already been released to the
      // service, so it cannot be patches here. Add the patch to the commit data
      // request, so that it can be sent to the service and applied there.
      if (!last_patch_req ||
          last_patch_req->chunk_id() != curr_patch.chunk_id) {
        last_patch_req = commit_data_req_->add_chunks_to_patch();
        last_patch_req->set_writer_id(writer_id);
        last_patch_req->set_chunk_id(curr_patch.chunk_id);
        last_patch_req->set_target_buffer(target_buffer);
      }
      auto* patch = last_patch_req->add_patches();
      patch->set_offset(curr_patch.offset);
      patch->set_data(&curr_patch.size_field[0], curr_patch.size_field.size());
    }

    // Patches are enqueued in the |patch_list| in order and are notified to
    // the service when the chunk is returned. The only case when the current
    // patch list is incomplete is if there is an unpatched entry at the head of
    // the |patch_list| that belongs to the same ChunkID as the last one we are
    // about to send to the service.
    if (last_patch_req && !patch_list->empty() &&
        patch_list->front().chunk_id == last_patch_req->chunk_id()) {
      last_patch_req->set_has_more_patches(true);
    }

    // If the buffer is filling up or if we are given a patch for a chunk
    // that was already sent to the service, we don't want to wait for the next
    // delayed flush to happen and we flush immediately. Otherwise, if we
    // accumulate the patch and a crash occurs before the patch is sent, the
    // service will not know of the patch and won't be able to reconstruct the
    // trace.
    if (fully_bound_ &&
        (last_patch_req || bytes_pending_commit_ >= shmem_abi_.size() / 2)) {
      weak_this = weak_ptr_factory_.GetWeakPtr();
      task_runner_to_post_delayed_callback_on = task_runner_;
      flush_delay_ms = 0;
    }
  }  // scoped_lock(lock_)

  // We shouldn't post tasks while locked.
  // |task_runner_to_post_delayed_callback_on| remains valid after unlocking,
  // because |task_runner_| is never reset.
  if (task_runner_to_post_delayed_callback_on) {
    task_runner_to_post_delayed_callback_on->PostDelayedTask(
        [weak_this] {
          if (!weak_this)
            return;
          {
            std::lock_guard<std::mutex> scoped_lock(weak_this->lock_);
            // Clear |delayed_flush_scheduled_|, allowing the next call to
            // UpdateCommitDataRequest to start another batching period.
            weak_this->delayed_flush_scheduled_ = false;
          }
          weak_this->FlushPendingCommitDataRequests();
        },
        flush_delay_ms);
  }
}

bool SharedMemoryArbiterImpl::TryDirectPatchLocked(
    WriterID writer_id,
    const Patch& patch,
    bool chunk_needs_more_patching) {
  // Search the chunks that are being batched in |commit_data_req_| for a chunk
  // that needs patching and that matches the provided |writer_id| and
  // |patch.chunk_id|. Iterate |commit_data_req_| in reverse, since
  // |commit_data_req_| is appended to at the end with newly-returned chunks,
  // and patches are more likely to apply to chunks that have been returned
  // recently.
  SharedMemoryABI::Chunk chunk;
  bool chunk_found = false;
  auto& chunks_to_move = commit_data_req_->chunks_to_move();
  for (auto ctm_it = chunks_to_move.rbegin(); ctm_it != chunks_to_move.rend();
       ++ctm_it) {
    uint32_t layout = shmem_abi_.GetPageLayout(ctm_it->page());
    auto chunk_state =
        shmem_abi_.GetChunkStateFromLayout(layout, ctm_it->chunk());
    // Note: the subset of |commit_data_req_| chunks that still need patching is
    // also the subset of chunks that are still being written to. The rest of
    // the chunks in |commit_data_req_| do not need patching and have already
    // been marked as complete.
    if (chunk_state != SharedMemoryABI::kChunkBeingWritten)
      continue;

    chunk =
        shmem_abi_.GetChunkUnchecked(ctm_it->page(), layout, ctm_it->chunk());
    if (chunk.writer_id() == writer_id &&
        chunk.header()->chunk_id.load(std::memory_order_relaxed) ==
            patch.chunk_id) {
      chunk_found = true;
      break;
    }
  }

  if (!chunk_found) {
    // The chunk has already been committed to the service and the patch cannot
    // be applied in the producer.
    return false;
  }

  // Apply the patch.
  size_t page_idx;
  uint8_t chunk_idx;
  std::tie(page_idx, chunk_idx) = shmem_abi_.GetPageAndChunkIndex(chunk);
  PERFETTO_DCHECK(shmem_abi_.GetChunkState(page_idx, chunk_idx) ==
                  SharedMemoryABI::ChunkState::kChunkBeingWritten);
  auto chunk_begin = chunk.payload_begin();
  uint8_t* ptr = chunk_begin + patch.offset;
  PERFETTO_CHECK(ptr <= chunk.end() - SharedMemoryABI::kPacketHeaderSize);
  // DCHECK that we are writing into a zero-filled size field and not into
  // valid data. It relies on ScatteredStreamWriter::ReserveBytes() to
  // zero-fill reservations in debug builds.
  const char zero[SharedMemoryABI::kPacketHeaderSize]{};
  PERFETTO_DCHECK(memcmp(ptr, &zero, SharedMemoryABI::kPacketHeaderSize) == 0);

  memcpy(ptr, &patch.size_field[0], SharedMemoryABI::kPacketHeaderSize);

  if (!chunk_needs_more_patching) {
    // Mark that the chunk doesn't need more patching and mark it as complete,
    // as the producer will not write to it anymore. This allows the service to
    // read the chunk in full while scraping, which would not be the case if the
    // chunk was left in a kChunkBeingWritten state.
    chunk.ClearNeedsPatchingFlag();
    shmem_abi_.ReleaseChunkAsComplete(std::move(chunk));
  }

  return true;
}

void SharedMemoryArbiterImpl::SetBatchCommitsDuration(
    uint32_t batch_commits_duration_ms) {
  std::lock_guard<std::mutex> scoped_lock(lock_);
  batch_commits_duration_ms_ = batch_commits_duration_ms;
}

bool SharedMemoryArbiterImpl::EnableDirectSMBPatching() {
  std::lock_guard<std::mutex> scoped_lock(lock_);
  if (!direct_patching_supported_by_service_) {
    return false;
  }

  return direct_patching_enabled_ = true;
}

void SharedMemoryArbiterImpl::SetDirectSMBPatchingSupportedByService() {
  std::lock_guard<std::mutex> scoped_lock(lock_);
  direct_patching_supported_by_service_ = true;
}

// This function is quite subtle. When making changes keep in mind these two
// challenges:
// 1) If the producer stalls and we happen to be on the |task_runner_| IPC
//    thread (or, for in-process cases, on the same thread where
//    TracingServiceImpl lives), the CommitData() call must be synchronous and
//    not posted, to avoid deadlocks.
// 2) When different threads hit this function, we must guarantee that we don't
//    accidentally make commits out of order. See commit 4e4fe8f56ef and
//    crbug.com/919187 for more context.
void SharedMemoryArbiterImpl::FlushPendingCommitDataRequests(
    std::function<void()> callback) {
  std::unique_ptr<CommitDataRequest> req;
  {
    std::unique_lock<std::mutex> scoped_lock(lock_);

    // Flushing is only supported while |fully_bound_|, and there may still be
    // unbound startup trace writers. If so, skip the commit for now - it'll be
    // done when |fully_bound_| is updated.
    if (!fully_bound_) {
      if (callback)
        pending_flush_callbacks_.push_back(callback);
      return;
    }

    // May be called by TraceWriterImpl on any thread.
    base::TaskRunner* task_runner = task_runner_;
    if (!task_runner->RunsTasksOnCurrentThread()) {
      // We shouldn't post a task while holding a lock. |task_runner| remains
      // valid after unlocking, because |task_runner_| is never reset.
      scoped_lock.unlock();

      auto weak_this = weak_ptr_factory_.GetWeakPtr();
      task_runner->PostTask([weak_this, callback] {
        if (weak_this)
          weak_this->FlushPendingCommitDataRequests(std::move(callback));
      });
      return;
    }

    // |commit_data_req_| could have become a nullptr, for example when a forced
    // sync flush happens in GetNewChunk().
    if (commit_data_req_) {
      // Make sure any placeholder buffer IDs from StartupWriters are replaced
      // before sending the request.
      bool all_placeholders_replaced =
          ReplaceCommitPlaceholderBufferIdsLocked();
      // We're |fully_bound_|, thus all writers are bound and all placeholders
      // should have been replaced.
      PERFETTO_DCHECK(all_placeholders_replaced);

      // In order to allow patching in the producer we delay the kChunkComplete
      // transition and keep batched chunks in the kChunkBeingWritten state.
      // Since we are about to notify the service of all batched chunks, it will
      // not be possible to apply any more patches to them and we need to move
      // them to kChunkComplete - otherwise the service won't look at them.
      for (auto& ctm : *commit_data_req_->mutable_chunks_to_move()) {
        uint32_t layout = shmem_abi_.GetPageLayout(ctm.page());
        auto chunk_state =
            shmem_abi_.GetChunkStateFromLayout(layout, ctm.chunk());
        // Note: the subset of |commit_data_req_| chunks that still need
        // patching is also the subset of chunks that are still being written
        // to. The rest of the chunks in |commit_data_req_| do not need patching
        // and have already been marked as complete.
        if (chunk_state == SharedMemoryABI::kChunkBeingWritten) {
          auto chunk =
              shmem_abi_.GetChunkUnchecked(ctm.page(), layout, ctm.chunk());
          shmem_abi_.ReleaseChunkAsComplete(std::move(chunk));
        }

        if (use_shmem_emulation_) {
          // When running in the emulation mode:
          // 1. serialize the chunk data to |ctm| as we won't modify the chunk
          // anymore.
          // 2. free the chunk as the service won't be able to do this.
          auto chunk =
              shmem_abi_.GetChunkUnchecked(ctm.page(), layout, ctm.chunk());
          PERFETTO_CHECK(chunk.is_valid());
          ctm.set_data(chunk.begin(), chunk.size());
          shmem_abi_.ReleaseChunkAsFree(std::move(chunk));
        }
      }

      req = std::move(commit_data_req_);
      bytes_pending_commit_ = 0;
    }
  }  // scoped_lock

  if (req) {
    producer_endpoint_->CommitData(*req, callback);
  } else if (callback) {
    // If |req| was nullptr, it means that an enqueued deferred commit was
    // executed just before this. At this point send an empty commit request
    // to the service, just to linearize with it and give the guarantee to the
    // caller that the data has been flushed into the service.
    producer_endpoint_->CommitData(CommitDataRequest(), std::move(callback));
  }
}

bool SharedMemoryArbiterImpl::TryShutdown() {
  std::lock_guard<std::mutex> scoped_lock(lock_);
  did_shutdown_ = true;
  // Shutdown is safe if there are no active trace writers for this arbiter.
  return active_writer_ids_.IsEmpty();
}

std::unique_ptr<TraceWriter> SharedMemoryArbiterImpl::CreateTraceWriter(
    BufferID target_buffer,
    BufferExhaustedPolicy buffer_exhausted_policy) {
  PERFETTO_CHECK(target_buffer > 0);
  return CreateTraceWriterInternal(target_buffer, buffer_exhausted_policy);
}

std::unique_ptr<TraceWriter> SharedMemoryArbiterImpl::CreateStartupTraceWriter(
    uint16_t target_buffer_reservation_id) {
  return CreateTraceWriterInternal(
      MakeTargetBufferIdForReservation(target_buffer_reservation_id),
      BufferExhaustedPolicy::kDrop);
}

void SharedMemoryArbiterImpl::BindToProducerEndpoint(
    TracingService::ProducerEndpoint* producer_endpoint,
    base::TaskRunner* task_runner) {
  PERFETTO_DCHECK(producer_endpoint && task_runner);
  PERFETTO_DCHECK(task_runner->RunsTasksOnCurrentThread());

  bool should_flush = false;
  std::function<void()> flush_callback;
  {
    std::lock_guard<std::mutex> scoped_lock(lock_);
    PERFETTO_CHECK(!fully_bound_);
    PERFETTO_CHECK(!producer_endpoint_ && !task_runner_);

    producer_endpoint_ = producer_endpoint;
    task_runner_ = task_runner;

    // Now that we're bound to a task runner, also reset the WeakPtrFactory to
    // it. Because this code runs on the task runner, the factory's weak
    // pointers will be valid on it.
    weak_ptr_factory_.Reset(this);

    // All writers registered so far should be startup trace writers, since
    // the producer cannot feasibly know the target buffer for any future
    // session yet.
    for (const auto& entry : pending_writers_) {
      PERFETTO_CHECK(IsReservationTargetBufferId(entry.second));
    }

    // If all buffer reservations are bound, we can flush pending commits.
    if (UpdateFullyBoundLocked()) {
      should_flush = true;
      flush_callback = TakePendingFlushCallbacksLocked();
    }
  }  // scoped_lock

  // Attempt to flush any pending commits (and run pending flush callbacks). If
  // there are none, this will have no effect. If we ended up in a race that
  // changed |fully_bound_| back to false, the commit will happen once we become
  // |fully_bound_| again.
  if (should_flush)
    FlushPendingCommitDataRequests(flush_callback);
}

void SharedMemoryArbiterImpl::BindStartupTargetBuffer(
    uint16_t target_buffer_reservation_id,
    BufferID target_buffer_id) {
  PERFETTO_DCHECK(target_buffer_id > 0);

  std::unique_lock<std::mutex> scoped_lock(lock_);

  // We should already be bound to an endpoint.
  PERFETTO_CHECK(producer_endpoint_);
  PERFETTO_CHECK(task_runner_);
  PERFETTO_CHECK(task_runner_->RunsTasksOnCurrentThread());

  BindStartupTargetBufferImpl(std::move(scoped_lock),
                              target_buffer_reservation_id, target_buffer_id);
}

void SharedMemoryArbiterImpl::AbortStartupTracingForReservation(
    uint16_t target_buffer_reservation_id) {
  std::unique_lock<std::mutex> scoped_lock(lock_);

  // If we are already bound to an arbiter, we may need to flush after aborting
  // the session, and thus should be running on the arbiter's task runner.
  if (task_runner_ && !task_runner_->RunsTasksOnCurrentThread()) {
    // We shouldn't post tasks while locked.
    auto* task_runner = task_runner_;
    scoped_lock.unlock();

    auto weak_this = weak_ptr_factory_.GetWeakPtr();
    task_runner->PostTask([weak_this, target_buffer_reservation_id]() {
      if (!weak_this)
        return;
      weak_this->AbortStartupTracingForReservation(
          target_buffer_reservation_id);
    });
    return;
  }

  // Bind the target buffer reservation to an invalid buffer (ID 0), so that
  // existing commits, as well as future commits (of currently acquired chunks),
  // will be released as free free by the service but otherwise ignored (i.e.
  // not copied into any valid target buffer).
  BindStartupTargetBufferImpl(std::move(scoped_lock),
                              target_buffer_reservation_id,
                              /*target_buffer_id=*/kInvalidBufferId);
}

void SharedMemoryArbiterImpl::BindStartupTargetBufferImpl(
    std::unique_lock<std::mutex> scoped_lock,
    uint16_t target_buffer_reservation_id,
    BufferID target_buffer_id) {
  // We should already be bound to an endpoint if the target buffer is valid.
  PERFETTO_DCHECK((producer_endpoint_ && task_runner_) ||
                  target_buffer_id == kInvalidBufferId);

  PERFETTO_DLOG("Binding startup target buffer reservation %" PRIu16
                " to buffer %" PRIu16,
                target_buffer_reservation_id, target_buffer_id);

  MaybeUnboundBufferID reserved_id =
      MakeTargetBufferIdForReservation(target_buffer_reservation_id);

  bool should_flush = false;
  std::function<void()> flush_callback;
  std::vector<std::pair<WriterID, BufferID>> writers_to_register;

  TargetBufferReservation& reservation =
      target_buffer_reservations_[reserved_id];
  PERFETTO_CHECK(!reservation.resolved);
  reservation.resolved = true;
  reservation.target_buffer = target_buffer_id;

  // Collect trace writers associated with the reservation.
  for (auto it = pending_writers_.begin(); it != pending_writers_.end();) {
    if (it->second == reserved_id) {
      // No need to register writers that have an invalid target buffer.
      if (target_buffer_id != kInvalidBufferId) {
        writers_to_register.push_back(
            std::make_pair(it->first, target_buffer_id));
      }
      it = pending_writers_.erase(it);
    } else {
      it++;
    }
  }

  // If all buffer reservations are bound, we can flush pending commits.
  if (UpdateFullyBoundLocked()) {
    should_flush = true;
    flush_callback = TakePendingFlushCallbacksLocked();
  }

  scoped_lock.unlock();

  // Register any newly bound trace writers with the service.
  for (const auto& writer_and_target_buffer : writers_to_register) {
    producer_endpoint_->RegisterTraceWriter(writer_and_target_buffer.first,
                                            writer_and_target_buffer.second);
  }

  // Attempt to flush any pending commits (and run pending flush callbacks). If
  // there are none, this will have no effect. If we ended up in a race that
  // changed |fully_bound_| back to false, the commit will happen once we become
  // |fully_bound_| again.
  if (should_flush)
    FlushPendingCommitDataRequests(flush_callback);
}

std::function<void()>
SharedMemoryArbiterImpl::TakePendingFlushCallbacksLocked() {
  if (pending_flush_callbacks_.empty())
    return std::function<void()>();

  std::vector<std::function<void()>> pending_flush_callbacks;
  pending_flush_callbacks.swap(pending_flush_callbacks_);
  // Capture the callback list into the lambda by copy.
  return [pending_flush_callbacks]() {
    for (auto& callback : pending_flush_callbacks)
      callback();
  };
}

void SharedMemoryArbiterImpl::NotifyFlushComplete(FlushRequestID req_id) {
  base::TaskRunner* task_runner_to_commit_on = nullptr;

  {
    std::lock_guard<std::mutex> scoped_lock(lock_);
    // If a commit_data_req_ exists it means that somebody else already posted a
    // FlushPendingCommitDataRequests() task.
    if (!commit_data_req_) {
      commit_data_req_.reset(new CommitDataRequest());

      // Flushing the commit is only supported while we're |fully_bound_|. If we
      // aren't, we'll flush when |fully_bound_| is updated.
      if (fully_bound_)
        task_runner_to_commit_on = task_runner_;
    } else {
      // If there is another request queued and that also contains is a reply
      // to a flush request, reply with the highest id.
      req_id = std::max(req_id, commit_data_req_->flush_request_id());
    }
    commit_data_req_->set_flush_request_id(req_id);
  }  // scoped_lock

  // We shouldn't post tasks while locked. |task_runner_to_commit_on|
  // remains valid after unlocking, because |task_runner_| is never reset.
  if (task_runner_to_commit_on) {
    auto weak_this = weak_ptr_factory_.GetWeakPtr();
    task_runner_to_commit_on->PostTask([weak_this] {
      if (weak_this)
        weak_this->FlushPendingCommitDataRequests();
    });
  }
}

std::unique_ptr<TraceWriter> SharedMemoryArbiterImpl::CreateTraceWriterInternal(
    MaybeUnboundBufferID target_buffer,
    BufferExhaustedPolicy buffer_exhausted_policy) {
  WriterID id;
  base::TaskRunner* task_runner_to_register_on = nullptr;

  {
    std::lock_guard<std::mutex> scoped_lock(lock_);
    if (did_shutdown_)
      return std::unique_ptr<TraceWriter>(new NullTraceWriter());

    id = active_writer_ids_.Allocate();
    if (!id)
      return std::unique_ptr<TraceWriter>(new NullTraceWriter());

    PERFETTO_DCHECK(!pending_writers_.count(id));

    if (IsReservationTargetBufferId(target_buffer)) {
      // If the reservation is new, mark it as unbound in
      // |target_buffer_reservations_|. Otherwise, if the reservation was
      // already bound, choose the bound buffer ID now.
      auto it_and_inserted = target_buffer_reservations_.insert(
          {target_buffer, TargetBufferReservation()});
      if (it_and_inserted.first->second.resolved)
        target_buffer = it_and_inserted.first->second.target_buffer;
    }

    if (IsReservationTargetBufferId(target_buffer)) {
      // The arbiter and/or startup buffer reservations are not bound yet, so
      // buffer the registration of the writer until after we're bound.
      pending_writers_[id] = target_buffer;

      // Mark the arbiter as not fully bound, since we now have at least one
      // unbound trace writer / target buffer reservation.
      fully_bound_ = false;
      was_always_bound_ = false;
    } else if (target_buffer != kInvalidBufferId) {
      // Trace writer is bound, so arbiter should be bound to an endpoint, too.
      PERFETTO_CHECK(producer_endpoint_ && task_runner_);
      task_runner_to_register_on = task_runner_;
    }

    // All trace writers must use kDrop policy if the arbiter ever becomes
    // unbound.
    bool uses_drop_policy =
        buffer_exhausted_policy == BufferExhaustedPolicy::kDrop;
    all_writers_have_drop_policy_ &= uses_drop_policy;
    PERFETTO_DCHECK(fully_bound_ || uses_drop_policy);
    PERFETTO_CHECK(fully_bound_ || all_writers_have_drop_policy_);
    PERFETTO_CHECK(was_always_bound_ || uses_drop_policy);
  }  // scoped_lock

  // We shouldn't post tasks while locked. |task_runner_to_register_on|
  // remains valid after unlocking, because |task_runner_| is never reset.
  if (task_runner_to_register_on) {
    auto weak_this = weak_ptr_factory_.GetWeakPtr();
    task_runner_to_register_on->PostTask([weak_this, id, target_buffer] {
      if (weak_this)
        weak_this->producer_endpoint_->RegisterTraceWriter(id, target_buffer);
    });
  }

  return std::unique_ptr<TraceWriter>(
      new TraceWriterImpl(this, id, target_buffer, buffer_exhausted_policy));
}

void SharedMemoryArbiterImpl::ReleaseWriterID(WriterID id) {
  base::TaskRunner* task_runner = nullptr;
  {
    std::lock_guard<std::mutex> scoped_lock(lock_);
    active_writer_ids_.Free(id);

    auto it = pending_writers_.find(id);
    if (it != pending_writers_.end()) {
      // Writer hasn't been bound yet and thus also not yet registered with the
      // service.
      pending_writers_.erase(it);
      return;
    }

    // A trace writer from an aborted session may be destroyed before the
    // arbiter is bound to a task runner. In that case, it was never registered
    // with the service.
    if (!task_runner_)
      return;

    task_runner = task_runner_;
  }  // scoped_lock

  // We shouldn't post tasks while locked. |task_runner| remains valid after
  // unlocking, because |task_runner_| is never reset.
  auto weak_this = weak_ptr_factory_.GetWeakPtr();
  task_runner->PostTask([weak_this, id] {
    if (weak_this)
      weak_this->producer_endpoint_->UnregisterTraceWriter(id);
  });
}

bool SharedMemoryArbiterImpl::ReplaceCommitPlaceholderBufferIdsLocked() {
  if (!commit_data_req_)
    return true;

  bool all_placeholders_replaced = true;
  for (auto& chunk : *commit_data_req_->mutable_chunks_to_move()) {
    if (!IsReservationTargetBufferId(chunk.target_buffer()))
      continue;
    const auto it = target_buffer_reservations_.find(chunk.target_buffer());
    PERFETTO_DCHECK(it != target_buffer_reservations_.end());
    if (!it->second.resolved) {
      all_placeholders_replaced = false;
      continue;
    }
    chunk.set_target_buffer(it->second.target_buffer);
  }
  for (auto& chunk : *commit_data_req_->mutable_chunks_to_patch()) {
    if (!IsReservationTargetBufferId(chunk.target_buffer()))
      continue;
    const auto it = target_buffer_reservations_.find(chunk.target_buffer());
    PERFETTO_DCHECK(it != target_buffer_reservations_.end());
    if (!it->second.resolved) {
      all_placeholders_replaced = false;
      continue;
    }
    chunk.set_target_buffer(it->second.target_buffer);
  }
  return all_placeholders_replaced;
}

bool SharedMemoryArbiterImpl::UpdateFullyBoundLocked() {
  if (!producer_endpoint_) {
    PERFETTO_DCHECK(!fully_bound_);
    return false;
  }
  // We're fully bound if all target buffer reservations have a valid associated
  // BufferID.
  fully_bound_ = std::none_of(
      target_buffer_reservations_.begin(), target_buffer_reservations_.end(),
      [](std::pair<MaybeUnboundBufferID, TargetBufferReservation> entry) {
        return !entry.second.resolved;
      });
  if (!fully_bound_)
    was_always_bound_ = false;
  return fully_bound_;
}

}  // namespace perfetto
// gen_amalgamated begin source: src/tracing/core/trace_packet.cc
/*
 * Copyright (C) 2017 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/trace_packet.h"

// gen_amalgamated expanded: #include "perfetto/base/logging.h"
// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"

namespace perfetto {

TracePacket::TracePacket() = default;
TracePacket::~TracePacket() = default;

TracePacket::TracePacket(TracePacket&& other) noexcept {
  *this = std::move(other);
}

TracePacket& TracePacket::operator=(TracePacket&& other) {
  slices_ = std::move(other.slices_);
  other.slices_.clear();
  size_ = other.size_;
  other.size_ = 0;
  buffer_index_for_stats_ = other.buffer_index_for_stats_;
  other.buffer_index_for_stats_ = 0;
  return *this;
}

void TracePacket::AddSlice(Slice slice) {
  size_ += slice.size;
  slices_.push_back(std::move(slice));
}

void TracePacket::AddSlice(const void* start, size_t size) {
  size_ += size;
  slices_.emplace_back(start, size);
}

std::tuple<char*, size_t> TracePacket::GetProtoPreamble() {
  using protozero::proto_utils::MakeTagLengthDelimited;
  using protozero::proto_utils::WriteVarInt;
  uint8_t* ptr = reinterpret_cast<uint8_t*>(&preamble_[0]);

  constexpr uint8_t tag = MakeTagLengthDelimited(kPacketFieldNumber);
  static_assert(tag < 0x80, "TracePacket tag should fit in one byte");
  *(ptr++) = tag;

  ptr = WriteVarInt(size(), ptr);
  size_t preamble_size = reinterpret_cast<uintptr_t>(ptr) -
                         reinterpret_cast<uintptr_t>(&preamble_[0]);
  PERFETTO_DCHECK(preamble_size <= sizeof(preamble_));
  return std::make_tuple(&preamble_[0], preamble_size);
}

std::string TracePacket::GetRawBytesForTesting() {
  std::string data;
  data.resize(size());
  size_t pos = 0;
  for (const Slice& slice : slices()) {
    PERFETTO_CHECK(pos + slice.size <= data.size());
    memcpy(&data[pos], slice.start, slice.size);
    pos += slice.size;
  }
  return data;
}

}  // namespace perfetto
// gen_amalgamated begin source: src/tracing/core/trace_writer_impl.cc
/*
 * Copyright (C) 2017 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// gen_amalgamated expanded: #include "src/tracing/core/trace_writer_impl.h"

#include <string.h>

#include <algorithm>
#include <type_traits>
#include <utility>

// gen_amalgamated expanded: #include "perfetto/base/logging.h"
// gen_amalgamated expanded: #include "perfetto/ext/base/thread_annotations.h"
// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
// gen_amalgamated expanded: #include "perfetto/protozero/root_message.h"
// gen_amalgamated expanded: #include "perfetto/protozero/static_buffer.h"
// gen_amalgamated expanded: #include "src/tracing/core/shared_memory_arbiter_impl.h"

// gen_amalgamated expanded: #include "protos/perfetto/trace/trace_packet.pbzero.h"

using protozero::proto_utils::kMessageLengthFieldSize;
using protozero::proto_utils::WriteRedundantVarInt;
using ChunkHeader = perfetto::SharedMemoryABI::ChunkHeader;

namespace perfetto {

namespace {
constexpr size_t kPacketHeaderSize = SharedMemoryABI::kPacketHeaderSize;
// The -1 is because we want to leave extra room to inflate the counter.
constexpr size_t kMaxPacketsPerChunk = ChunkHeader::Packets::kMaxCount - 1;
// When the packet count in a chunk is inflated, TraceWriter is always going to
// leave this kExtraRoomForInflatedPacket bytes to write an empty trace packet
// if it needs to.
constexpr size_t kExtraRoomForInflatedPacket = 1;
uint8_t g_garbage_chunk[1024];
}  // namespace

TraceWriterImpl::TraceWriterImpl(SharedMemoryArbiterImpl* shmem_arbiter,
                                 WriterID id,
                                 MaybeUnboundBufferID target_buffer,
                                 BufferExhaustedPolicy buffer_exhausted_policy)
    : shmem_arbiter_(shmem_arbiter),
      id_(id),
      target_buffer_(target_buffer),
      buffer_exhausted_policy_(buffer_exhausted_policy),
      protobuf_stream_writer_(this),
      process_id_(base::GetProcessId()) {
  // TODO(primiano): we could handle the case of running out of TraceWriterID(s)
  // more gracefully and always return a no-op TracePacket in NewTracePacket().
  PERFETTO_CHECK(id_ != 0);

  cur_packet_.reset(new protozero::RootMessage<protos::pbzero::TracePacket>());
  cur_packet_->Finalize();  // To avoid the CHECK in NewTracePacket().
}

TraceWriterImpl::~TraceWriterImpl() {
  if (cur_chunk_.is_valid()) {
    cur_packet_->Finalize();
    Flush();
  }
  // This call may cause the shared memory arbiter (and the underlying memory)
  // to get asynchronously deleted if this was the last trace writer targeting
  // the arbiter and the arbiter was marked for shutdown.
  shmem_arbiter_->ReleaseWriterID(id_);
}

void TraceWriterImpl::ReturnCompletedChunk() {
  PERFETTO_DCHECK(cur_chunk_.is_valid());
  if (cur_chunk_packet_count_inflated_) {
    uint8_t zero_size = 0;
    static_assert(sizeof zero_size == kExtraRoomForInflatedPacket);
    PERFETTO_CHECK(protobuf_stream_writer_.bytes_available() != 0);
    protobuf_stream_writer_.WriteBytesUnsafe(&zero_size, sizeof zero_size);
    cur_chunk_packet_count_inflated_ = false;
  }
  shmem_arbiter_->ReturnCompletedChunk(std::move(cur_chunk_), target_buffer_,
                                       &patch_list_);
}

void TraceWriterImpl::Flush(std::function<void()> callback) {
  // Flush() cannot be called in the middle of a TracePacket.
  PERFETTO_CHECK(cur_packet_->is_finalized());
  // cur_packet_ is finalized: that means that the size is correct for all the
  // nested submessages. The root fragment size however is not handled by
  // protozero::Message::Finalize() and must be filled here.
  FinalizeFragmentIfRequired();

  if (cur_chunk_.is_valid()) {
    ReturnCompletedChunk();
  } else {
    // When in stall mode, all patches should have been returned with the last
    // chunk, since the last packet was completed. In drop_packets_ mode, this
    // may not be the case because the packet may have been fragmenting when
    // SMB exhaustion occurred and |cur_chunk_| became invalid. In this case,
    // drop_packets_ should be true.
    PERFETTO_DCHECK(patch_list_.empty() || drop_packets_);
  }

  // Always issue the Flush request, even if there is nothing to flush, just
  // for the sake of getting the callback posted back.
  shmem_arbiter_->FlushPendingCommitDataRequests(callback);
  protobuf_stream_writer_.Reset({nullptr, nullptr});
}

TraceWriterImpl::TracePacketHandle TraceWriterImpl::NewTracePacket() {
  // If we hit this, the caller is calling NewTracePacket() without having
  // finalized the previous packet.
  PERFETTO_CHECK(cur_packet_->is_finalized());
  // If we hit this, this trace writer was created in a different process. This
  // likely means that the process forked while tracing was active, and the
  // forked child process tried to emit a trace event. This is not supported, as
  // it would lead to two processes writing to the same tracing SMB.
  PERFETTO_DCHECK(process_id_ == base::GetProcessId());

  // Before starting a new packet, make sure that the last fragment size has ben
  // written correctly. The root fragment size is not written by
  // protozero::Message::Finalize().
  FinalizeFragmentIfRequired();

  fragmenting_packet_ = false;

  // Reserve space for the size of the message. Note: this call might re-enter
  // into this class invoking GetNewBuffer() if there isn't enough space or if
  // this is the very first call to NewTracePacket().
  static_assert(kPacketHeaderSize == kMessageLengthFieldSize,
                "The packet header must match the Message header size");

  bool was_dropping_packets = drop_packets_;

  // It doesn't make sense to begin a packet that is going to fragment
  // immediately after (8 is just an arbitrary estimation on the minimum size of
  // a realistic packet).
  bool chunk_too_full =
      protobuf_stream_writer_.bytes_available() < kPacketHeaderSize + 8;
  if (chunk_too_full || reached_max_packets_per_chunk_ ||
      retry_new_chunk_after_packet_) {
    protobuf_stream_writer_.Reset(GetNewBuffer());
  }

  // Send any completed patches to the service to facilitate trace data
  // recovery by the service. This should only happen when we're completing
  // the first packet in a chunk which was a continuation from the previous
  // chunk, i.e. at most once per chunk.
  if (!patch_list_.empty() && patch_list_.front().is_patched()) {
    shmem_arbiter_->SendPatches(id_, target_buffer_, &patch_list_);
  }

  cur_packet_->Reset(&protobuf_stream_writer_);
  uint8_t* header = protobuf_stream_writer_.ReserveBytes(kPacketHeaderSize);
  memset(header, 0, kPacketHeaderSize);
  cur_fragment_size_field_ = header;

  TracePacketHandle handle(cur_packet_.get());
  cur_fragment_start_ = protobuf_stream_writer_.write_ptr();
  fragmenting_packet_ = true;

  if (PERFETTO_LIKELY(!drop_packets_)) {
    uint16_t new_packet_count;
    if (cur_chunk_packet_count_inflated_) {
      new_packet_count =
          cur_chunk_.header()->packets.load(std::memory_order_relaxed).count;
      cur_chunk_packet_count_inflated_ = false;
    } else {
      new_packet_count = cur_chunk_.IncrementPacketCount();
    }
    reached_max_packets_per_chunk_ = new_packet_count == kMaxPacketsPerChunk;

    if (PERFETTO_UNLIKELY(was_dropping_packets)) {
      // We've succeeded to get a new chunk from the SMB after we entered
      // drop_packets_ mode. Record a marker into the new packet to indicate the
      // data loss.
      cur_packet_->set_previous_packet_dropped(true);
    }
  }

  if (PERFETTO_UNLIKELY(first_packet_on_sequence_)) {
    cur_packet_->set_first_packet_on_sequence(true);
    first_packet_on_sequence_ = false;
  }

  handle.set_finalization_listener(this);

  return handle;
}

// Called by the Message. We can get here in two cases:
// 1. In the middle of writing a Message,
// when |fragmenting_packet_| == true. In this case we want to update the
// chunk header with a partial packet and start a new partial packet in the
// new chunk.
// 2. While calling ReserveBytes() for the packet header in NewTracePacket().
// In this case |fragmenting_packet_| == false and we just want a new chunk
// without creating any fragments.
protozero::ContiguousMemoryRange TraceWriterImpl::GetNewBuffer() {
  if (fragmenting_packet_ && drop_packets_) {
    // We can't write the remaining data of the fragmenting packet to a new
    // chunk, because we have already lost some of its data in the garbage
    // chunk. Thus, we will wrap around in the garbage chunk, wait until the
    // current packet was completed, and then attempt to get a new chunk from
    // the SMB again. Instead, if |drop_packets_| is true and
    // |fragmenting_packet_| is false, we try to acquire a valid chunk because
    // the SMB exhaustion might be resolved.
    retry_new_chunk_after_packet_ = true;
    cur_fragment_size_field_ = nullptr;
    cur_fragment_start_ = &g_garbage_chunk[0];
    return protozero::ContiguousMemoryRange{
        &g_garbage_chunk[0], &g_garbage_chunk[0] + sizeof(g_garbage_chunk)};
  }

  // Attempt to grab the next chunk before finalizing the current one, so that
  // we know whether we need to start dropping packets before writing the
  // current packet fragment's header.
  ChunkHeader::Packets packets = {};
  if (fragmenting_packet_) {
    packets.count = 1;
    packets.flags = ChunkHeader::kFirstPacketContinuesFromPrevChunk;
  }

  // The memory order of the stores below doesn't really matter. This |header|
  // is just a local temporary object. The GetNewChunk() call below will copy it
  // into the shared buffer with the proper barriers.
  ChunkHeader header = {};
  header.writer_id.store(id_, std::memory_order_relaxed);
  header.chunk_id.store(next_chunk_id_, std::memory_order_relaxed);
  header.packets.store(packets, std::memory_order_relaxed);

  SharedMemoryABI::Chunk new_chunk =
      shmem_arbiter_->GetNewChunk(header, buffer_exhausted_policy_);
  if (!new_chunk.is_valid()) {
    // Shared memory buffer exhausted, switch into |drop_packets_| mode. We'll
    // drop data until the garbage chunk has been filled once and then retry.

    // If we started a packet in one of the previous (valid) chunks, we need to
    // tell the service to discard it.
    if (fragmenting_packet_) {
      // We can only end up here if the previous chunk was a valid chunk,
      // because we never try to acquire a new chunk in |drop_packets_| mode
      // while fragmenting.
      PERFETTO_DCHECK(!drop_packets_);

      // Backfill the last fragment's header with an invalid size (too large),
      // so that the service's TraceBuffer throws out the incomplete packet.
      // It'll restart reading from the next chunk we submit.
      WriteRedundantVarInt(SharedMemoryABI::kPacketSizeDropPacket,
                           cur_fragment_size_field_);

      // Reset the size field, since we should not write the current packet's
      // size anymore after this.
      cur_fragment_size_field_ = nullptr;

      // We don't set kLastPacketContinuesOnNextChunk or kChunkNeedsPatching on
      // the last chunk, because its last fragment will be discarded anyway.
      // However, the current packet fragment points to a valid |cur_chunk_| and
      // may have non-finalized nested messages which will continue in the
      // garbage chunk and currently still point into |cur_chunk_|. As we are
      // about to return |cur_chunk_|, we need to invalidate the size fields of
      // those nested messages. Normally we move them in the |patch_list_| (see
      // below) but in this case, it doesn't make sense to send patches for a
      // fragment that will be discarded for sure. Thus, we clean up any size
      // field references into |cur_chunk_|.
      for (auto* nested_msg = cur_packet_->nested_message(); nested_msg;
           nested_msg = nested_msg->nested_message()) {
        uint8_t* const cur_hdr = nested_msg->size_field();

        // If this is false the protozero Message has already been instructed to
        // write, upon Finalize(), its size into the patch list.
        bool size_field_points_within_chunk =
            cur_hdr >= cur_chunk_.payload_begin() &&
            cur_hdr + kMessageLengthFieldSize <= cur_chunk_.end();

        if (size_field_points_within_chunk)
          nested_msg->set_size_field(nullptr);
      }
    } else if (!drop_packets_ && cur_fragment_size_field_) {
      // If we weren't dropping packets before, we should indicate to the
      // service that we're about to lose data. We do this by invalidating the
      // size of the last packet in |cur_chunk_|. The service will record
      // statistics about packets with kPacketSizeDropPacket size.
      PERFETTO_DCHECK(cur_packet_->is_finalized());
      PERFETTO_DCHECK(cur_chunk_.is_valid());

      // |cur_fragment_size_field_| should point within |cur_chunk_|'s payload.
      PERFETTO_DCHECK(cur_fragment_size_field_ >= cur_chunk_.payload_begin() &&
                      cur_fragment_size_field_ + kMessageLengthFieldSize <=
                          cur_chunk_.end());

      WriteRedundantVarInt(SharedMemoryABI::kPacketSizeDropPacket,
                           cur_fragment_size_field_);
    }

    if (cur_chunk_.is_valid()) {
      ReturnCompletedChunk();
    }

    drop_packets_ = true;
    cur_chunk_ = SharedMemoryABI::Chunk();  // Reset to an invalid chunk.
    cur_chunk_packet_count_inflated_ = false;
    reached_max_packets_per_chunk_ = false;
    retry_new_chunk_after_packet_ = false;
    cur_fragment_size_field_ = nullptr;
    cur_fragment_start_ = &g_garbage_chunk[0];

    PERFETTO_ANNOTATE_BENIGN_RACE_SIZED(&g_garbage_chunk,
                                        sizeof(g_garbage_chunk),
                                        "nobody reads the garbage chunk")
    return protozero::ContiguousMemoryRange{
        &g_garbage_chunk[0], &g_garbage_chunk[0] + sizeof(g_garbage_chunk)};
  }  // if (!new_chunk.is_valid())

  PERFETTO_DCHECK(new_chunk.is_valid());

  if (fragmenting_packet_) {
    // We should not be fragmenting a packet after we exited drop_packets_ mode,
    // because we only retry to get a new chunk when a fresh packet is started.
    PERFETTO_DCHECK(!drop_packets_);

    uint8_t* const wptr = protobuf_stream_writer_.write_ptr();
    PERFETTO_DCHECK(wptr >= cur_fragment_start_);
    uint32_t partial_size = static_cast<uint32_t>(wptr - cur_fragment_start_);
    PERFETTO_DCHECK(partial_size < cur_chunk_.size());

    // Backfill the packet header with the fragment size.
    PERFETTO_DCHECK(partial_size > 0);
    cur_chunk_.SetFlag(ChunkHeader::kLastPacketContinuesOnNextChunk);
    WriteRedundantVarInt(partial_size, cur_fragment_size_field_);

    // Descend in the stack of non-finalized nested submessages (if any) and
    // detour their |size_field| into the |patch_list_|. At this point we have
    // to release the chunk and they cannot write anymore into that.
    for (auto* nested_msg = cur_packet_->nested_message(); nested_msg;
         nested_msg = nested_msg->nested_message()) {
      uint8_t* cur_hdr = nested_msg->size_field();

      // If this is false the protozero Message has already been instructed to
      // write, upon Finalize(), its size into the patch list.
      bool size_field_points_within_chunk =
          cur_hdr >= cur_chunk_.payload_begin() &&
          cur_hdr + kMessageLengthFieldSize <= cur_chunk_.end();

      if (size_field_points_within_chunk) {
        cur_hdr = TraceWriterImpl::AnnotatePatch(cur_hdr);
        nested_msg->set_size_field(cur_hdr);
      } else {
#if PERFETTO_DCHECK_IS_ON()
        // Ensure that the size field of the message points to an element of the
        // patch list.
        auto patch_it = std::find_if(
            patch_list_.begin(), patch_list_.end(),
            [cur_hdr](const Patch& p) { return &p.size_field[0] == cur_hdr; });
        PERFETTO_DCHECK(patch_it != patch_list_.end());
#endif
      }
    }  // for(nested_msg)
  }    // if(fragmenting_packet)

  if (cur_chunk_.is_valid()) {
    // ReturnCompletedChunk will consume the first patched entries from
    // |patch_list_| and shrink it.
    ReturnCompletedChunk();
  }

  // Switch to the new chunk.
  drop_packets_ = false;
  reached_max_packets_per_chunk_ = false;
  retry_new_chunk_after_packet_ = false;
  next_chunk_id_++;
  cur_chunk_ = std::move(new_chunk);
  cur_chunk_packet_count_inflated_ = false;
  cur_fragment_size_field_ = nullptr;

  uint8_t* payload_begin = cur_chunk_.payload_begin();
  if (fragmenting_packet_) {
    cur_fragment_size_field_ = payload_begin;
    memset(payload_begin, 0, kPacketHeaderSize);
    payload_begin += kPacketHeaderSize;
    cur_fragment_start_ = payload_begin;
  }

  return protozero::ContiguousMemoryRange{payload_begin, cur_chunk_.end()};
}

void TraceWriterImpl::FinishTracePacket() {
  // If we hit this, this trace writer was created in a different process. This
  // likely means that the process forked while tracing was active, and the
  // forked child process tried to emit a trace event. This is not supported, as
  // it would lead to two processes writing to the same tracing SMB.
  PERFETTO_DCHECK(process_id_ == base::GetProcessId());

  FinalizeFragmentIfRequired();

  cur_packet_->Reset(&protobuf_stream_writer_);
  cur_packet_->Finalize();  // To avoid the CHECK in NewTracePacket().

  // cur_chunk_packet_count_inflated_ can be true if FinishTracePacket() is
  // called multiple times.
  if (cur_chunk_.is_valid() && !cur_chunk_packet_count_inflated_) {
    if (protobuf_stream_writer_.bytes_available() <
        kExtraRoomForInflatedPacket) {
      ReturnCompletedChunk();
    } else {
      cur_chunk_packet_count_inflated_ = true;
      cur_chunk_.IncrementPacketCount();
    }
  }

  // Send any completed patches to the service to facilitate trace data
  // recovery by the service. This should only happen when we're completing
  // the first packet in a chunk which was a continuation from the previous
  // chunk, i.e. at most once per chunk.
  if (!patch_list_.empty() && patch_list_.front().is_patched()) {
    shmem_arbiter_->SendPatches(id_, target_buffer_, &patch_list_);
  }
}

void TraceWriterImpl::FinalizeFragmentIfRequired() {
  if (!cur_fragment_size_field_) {
    return;
  }
  uint8_t* const wptr = protobuf_stream_writer_.write_ptr();
  PERFETTO_DCHECK(wptr >= cur_fragment_start_);
  uint32_t partial_size = static_cast<uint32_t>(wptr - cur_fragment_start_);

  // cur_fragment_size_field_, if not nullptr, is always inside or immediately
  // before protobuf_stream_writer_.cur_range().
  if (partial_size < protozero::proto_utils::kMaxOneByteMessageLength &&
      cur_fragment_size_field_ >= protobuf_stream_writer_.cur_range().begin) {
    // This handles compaction of the root message. For nested messages, the
    // compaction is handled by protozero::Message::Finalize().
    protobuf_stream_writer_.Rewind(
        partial_size, protozero::proto_utils::kMessageLengthFieldSize - 1u);
    *cur_fragment_size_field_ = static_cast<uint8_t>(partial_size);
  } else {
    WriteRedundantVarInt(partial_size, cur_fragment_size_field_);
  }
  cur_fragment_size_field_ = nullptr;
}

uint8_t* TraceWriterImpl::AnnotatePatch(uint8_t* to_patch) {
  if (!cur_chunk_.is_valid()) {
    return nullptr;
  }
  auto offset = static_cast<uint16_t>(to_patch - cur_chunk_.payload_begin());
  const ChunkID cur_chunk_id =
      cur_chunk_.header()->chunk_id.load(std::memory_order_relaxed);
  static_assert(kPatchSize == sizeof(Patch::PatchContent),
                "Patch size mismatch");
  Patch* patch = patch_list_.emplace_back(cur_chunk_id, offset);
  // Check that the flag is not already set before setting it. This is not
  // necessary, but it makes the code faster.
  if (!(cur_chunk_.GetPacketCountAndFlags().second &
        ChunkHeader::kChunkNeedsPatching)) {
    cur_chunk_.SetFlag(ChunkHeader::kChunkNeedsPatching);
  }
  return &patch->size_field[0];
}

void TraceWriterImpl::OnMessageFinalized(protozero::Message*) {
  TraceWriterImpl::FinishTracePacket();
}

WriterID TraceWriterImpl::writer_id() const {
  return id_;
}

// Base class definitions.
TraceWriter::TraceWriter() = default;
TraceWriter::~TraceWriter() = default;

}  // namespace perfetto
// gen_amalgamated begin source: src/tracing/core/virtual_destructors.cc
// gen_amalgamated begin header: include/perfetto/ext/tracing/core/consumer.h
// gen_amalgamated begin header: include/perfetto/ext/tracing/core/observable_events.h
/*
 * Copyright (C) 2017 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef INCLUDE_PERFETTO_EXT_TRACING_CORE_OBSERVABLE_EVENTS_H_
#define INCLUDE_PERFETTO_EXT_TRACING_CORE_OBSERVABLE_EVENTS_H_

// Creates the aliases in the ::perfetto namespace, doing things like:
// using ::perfetto::Foo = ::perfetto::protos::gen::Foo.
// See comments in forward_decls.h for the historical reasons of this
// indirection layer.
// gen_amalgamated expanded: #include "perfetto/tracing/core/forward_decls.h"

// gen_amalgamated expanded: #include "protos/perfetto/common/observable_events.gen.h"

#endif  // INCLUDE_PERFETTO_EXT_TRACING_CORE_OBSERVABLE_EVENTS_H_
/*
 * Copyright (C) 2017 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef INCLUDE_PERFETTO_EXT_TRACING_CORE_CONSUMER_H_
#define INCLUDE_PERFETTO_EXT_TRACING_CORE_CONSUMER_H_

#include <vector>

// gen_amalgamated expanded: #include "perfetto/base/export.h"
// gen_amalgamated expanded: #include "perfetto/ext/base/uuid.h"
// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/basic_types.h"
// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/observable_events.h"
// gen_amalgamated expanded: #include "perfetto/tracing/core/forward_decls.h"
namespace perfetto {

class TracePacket;

class PERFETTO_EXPORT_COMPONENT Consumer {
 public:
  virtual ~Consumer();

  // Called by Service (or more typically by the transport layer, on behalf of
  // the remote Service), once the Consumer <> Service connection has been
  // established.
  virtual void OnConnect() = 0;

  // Called by the Service or by the transport layer if the connection with the
  // service drops, either voluntarily (e.g., by destroying the ConsumerEndpoint
  // obtained through Service::ConnectConsumer()) or involuntarily (e.g., if the
  // Service process crashes).
  virtual void OnDisconnect() = 0;

  // Called by the Service after the tracing session has ended. This can happen
  // for a variety of reasons:
  // - The consumer explicitly called DisableTracing()
  // - The TraceConfig's |duration_ms| has been reached.
  // - The TraceConfig's |max_file_size_bytes| has been reached.
  // - An error occurred while trying to enable tracing. In this case |error|
  //   is non-empty.
  virtual void OnTracingDisabled(const std::string& error) = 0;

  // Called back by the Service (or transport layer) after invoking
  // TracingService::ConsumerEndpoint::ReadBuffers(). This function can be
  // called more than once. Each invocation can carry one or more
  // TracePacket(s). Upon the last call, |has_more| is set to true (i.e.
  // |has_more| is a !EOF).
  virtual void OnTraceData(std::vector<TracePacket>, bool has_more) = 0;

  // Called back by the Service (or transport layer) after invoking
  // TracingService::ConsumerEndpoint::Detach().
  // The consumer can disconnect at this point and the trace session will keep
  // on going. A new consumer can later re-attach passing back the same |key|
  // passed to Detach(), but only if the two requests come from the same uid.
  virtual void OnDetach(bool success) = 0;

  // Called back by the Service (or transport layer) after invoking
  // TracingService::ConsumerEndpoint::Attach().
  virtual void OnAttach(bool success, const TraceConfig&) = 0;

  // Called back by the Service (or transport layer) after invoking
  // TracingService::ConsumerEndpoint::GetTraceStats().
  virtual void OnTraceStats(bool success, const TraceStats&) = 0;

  // Called back by the Service (or transport layer) after invoking
  // TracingService::ConsumerEndpoint::ObserveEvents() whenever one or more
  // ObservableEvents of enabled event types occur.
  virtual void OnObservableEvents(const ObservableEvents&) = 0;

  // Called back by the Service (or transport layer) after invoking
  // TracingService::ConsumerEndpoint::CloneSession().
  // TODO(primiano): make pure virtual after various 3way patches.
  struct OnSessionClonedArgs {
    bool success;
    std::string error;
    base::Uuid uuid;  // UUID of the cloned session.
  };
  virtual void OnSessionCloned(const OnSessionClonedArgs&);
};

}  // namespace perfetto

#endif  // INCLUDE_PERFETTO_EXT_TRACING_CORE_CONSUMER_H_
// gen_amalgamated begin header: include/perfetto/ext/tracing/core/producer.h
/*
 * Copyright (C) 2017 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef INCLUDE_PERFETTO_EXT_TRACING_CORE_PRODUCER_H_
#define INCLUDE_PERFETTO_EXT_TRACING_CORE_PRODUCER_H_

// gen_amalgamated expanded: #include "perfetto/base/export.h"
// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/basic_types.h"
// gen_amalgamated expanded: #include "perfetto/tracing/core/flush_flags.h"
// gen_amalgamated expanded: #include "perfetto/tracing/core/forward_decls.h"

namespace perfetto {

class SharedMemory;

// A Producer is an entity that connects to the write-only port of the Service
// and exposes the ability to produce performance data on-demand. The lifecycle
// of a Producer is as follows:
// 1. The producer connects to the service and advertises its data sources
//    (e.g., the ability to get kernel ftraces, to list process stats).
// 2. The service acknowledges the connection and sends over the SharedMemory
//    region that will be used to exchange data (together with the signalling
//    API TracingService::ProducerEndpoint::OnPageAcquired()/OnPageReleased()).
// 3. At some point later on, the Service asks the Producer to turn on some of
//    the previously registered data sources, together with some configuration
//    parameters. This happens via the StartDataSource() callback.
// 4. In response to that the Producer will spawn an instance of the given data
//    source and inject its data into the shared memory buffer (obtained during
//    OnConnect).
// This interface is subclassed by:
//  1. The actual producer code in the clients e.g., the ftrace reader process.
//  2. The transport layer when interposing RPC between service and producers.
class PERFETTO_EXPORT_COMPONENT Producer {
 public:
  virtual ~Producer();

  // Called by Service (or more typically by the transport layer, on behalf of
  // the remote Service), once the Producer <> Service connection has been
  // established.
  virtual void OnConnect() = 0;

  // Called by the Service or by the transport layer if the connection with the
  // service drops, either voluntarily (e.g., by destroying the ProducerEndpoint
  // obtained through Service::ConnectProducer()) or involuntarily (e.g., if the
  // Service process crashes).
  // The Producer is expected to tear down all its data sources if this happens.
  // Once this call returns it is possible to safely destroy the Producer
  // instance.
  virtual void OnDisconnect() = 0;

  // Called by the Service after OnConnect but before the first DataSource is
  // created. Can be used for any setup required before tracing begins.
  virtual void OnTracingSetup() = 0;

  // Called by muxer once StartupTracing is started. It will be called before
  // SetupStartupTracingBlocking is returned.
  virtual void OnStartupTracingSetup() {}

  // The lifecycle methods below are always called in the following sequence:
  // SetupDataSource  -> StartDataSource -> StopDataSource.
  // Or, in the edge case where a trace is aborted immediately:
  // SetupDataSource  -> StopDataSource.
  // The Setup+Start call sequence is always guaranateed, regardless of the
  // TraceConfig.deferred_start flags.
  // Called by the Service to configure one of the data sources previously
  // registered through TracingService::ProducerEndpoint::RegisterDataSource().
  // This method is always called before StartDataSource. There is always a
  // SetupDataSource() call before each StartDataSource() call.
  // Args:
  // - DataSourceInstanceID is an identifier chosen by the Service that should
  //   be assigned to the newly created data source instance. It is used to
  //   match the StopDataSource() request below.
  // - DataSourceConfig is the configuration for the new data source (e.g.,
  //   tells which trace categories to enable).
  virtual void SetupDataSource(DataSourceInstanceID,
                               const DataSourceConfig&) = 0;

  // Called by the Service to turn on one of the data sources previously
  // registered through TracingService::ProducerEndpoint::RegisterDataSource()
  // and initialized through SetupDataSource().
  // Both arguments are guaranteed to be identical to the ones passed to the
  // prior SetupDataSource() call.
  virtual void StartDataSource(DataSourceInstanceID,
                               const DataSourceConfig&) = 0;

  // Called by the Service to shut down an existing data source instance.
  virtual void StopDataSource(DataSourceInstanceID) = 0;

  // Called by the service to request the Producer to commit the data of the
  // given data sources and return their chunks into the shared memory buffer.
  // The Producer is expected to invoke NotifyFlushComplete(FlushRequestID) on
  // the Service after the data has been committed. The producer has to either
  // reply to the flush requests in order, or can just reply to the latest one
  // Upon seeing a NotifyFlushComplete(N), the service will assume that all
  // flushes < N have also been committed.
  virtual void Flush(FlushRequestID,
                     const DataSourceInstanceID* data_source_ids,
                     size_t num_data_sources,
                     FlushFlags) = 0;

  // Called by the service to instruct the given data sources to stop referring
  // to any trace contents emitted so far. The intent is that after processing
  // this call, the rest of the trace should be parsable even if all of the
  // packets emitted so far have been lost (for example due to ring buffer
  // overwrites).
  //
  // Called only for Producers with active data sources that have opted in by
  // setting |handles_incremental_state_clear| in their DataSourceDescriptor.
  //
  // The way this call is handled is up to the individual Producer
  // implementation. Some might wish to emit invalidation markers in the trace
  // (see TracePacket.incremental_state_cleared for an existing field), and
  // handle them when parsing the trace.
  virtual void ClearIncrementalState(
      const DataSourceInstanceID* data_source_ids,
      size_t num_data_sources) = 0;
};

}  // namespace perfetto

#endif  // INCLUDE_PERFETTO_EXT_TRACING_CORE_PRODUCER_H_
/*
 * Copyright (C) 2018 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/consumer.h"
// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/producer.h"
// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/shared_memory.h"
// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/shared_memory_arbiter.h"
// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/tracing_service.h"

// gen_amalgamated expanded: #include "protos/perfetto/common/tracing_service_state.gen.h"

// This translation unit contains the definitions for the destructor of pure
// virtual interfaces for the current build target. The alternative would be
// introducing a one-liner .cc file for each pure virtual interface, which is
// overkill. This is for compliance with -Wweak-vtables.

namespace perfetto {

Consumer::~Consumer() = default;
Producer::~Producer() = default;
TracingService::~TracingService() = default;
ConsumerEndpoint::~ConsumerEndpoint() = default;
ProducerEndpoint::~ProducerEndpoint() = default;
RelayEndpoint::~RelayEndpoint() = default;
SharedMemory::~SharedMemory() = default;
SharedMemory::Factory::~Factory() = default;
SharedMemoryArbiter::~SharedMemoryArbiter() = default;

// TODO(primiano): make pure virtual after various 3way patches.
void Consumer::OnSessionCloned(const OnSessionClonedArgs&) {}

}  // namespace perfetto
// gen_amalgamated begin source: src/tracing/console_interceptor.cc
/*
 * Copyright (C) 2020 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// gen_amalgamated expanded: #include "perfetto/tracing/console_interceptor.h"

#include <stdarg.h>

#include <algorithm>
#include <cmath>
#include <optional>
#include <tuple>

// gen_amalgamated expanded: #include "perfetto/ext/base/file_utils.h"
// gen_amalgamated expanded: #include "perfetto/ext/base/hash.h"
// gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"
// gen_amalgamated expanded: #include "perfetto/ext/base/string_utils.h"
// gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
// gen_amalgamated expanded: #include "perfetto/tracing/internal/track_event_internal.h"

// gen_amalgamated expanded: #include "protos/perfetto/common/interceptor_descriptor.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/data_source_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/interceptor_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/interceptors/console_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/trace/interned_data/interned_data.pbzero.h"
// gen_amalgamated expanded: #include "protos/perfetto/trace/trace_packet.pbzero.h"
// gen_amalgamated expanded: #include "protos/perfetto/trace/trace_packet_defaults.pbzero.h"
// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/process_descriptor.pbzero.h"
// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/thread_descriptor.pbzero.h"
// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/track_descriptor.pbzero.h"
// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/track_event.pbzero.h"

namespace perfetto {

// sRGB color.
struct ConsoleColor {
  uint8_t r;
  uint8_t g;
  uint8_t b;
};

namespace {

int g_output_fd_for_testing;

// Google Turbo colormap.
constexpr std::array<ConsoleColor, 16> kTurboColors = {{
    ConsoleColor{0x30, 0x12, 0x3b},
    ConsoleColor{0x40, 0x40, 0xa1},
    ConsoleColor{0x46, 0x6b, 0xe3},
    ConsoleColor{0x41, 0x93, 0xfe},
    ConsoleColor{0x28, 0xbb, 0xeb},
    ConsoleColor{0x17, 0xdc, 0xc2},
    ConsoleColor{0x32, 0xf1, 0x97},
    ConsoleColor{0x6d, 0xfd, 0x62},
    ConsoleColor{0xa4, 0xfc, 0x3b},
    ConsoleColor{0xcd, 0xeb, 0x34},
    ConsoleColor{0xed, 0xcf, 0x39},
    ConsoleColor{0xfd, 0xab, 0x33},
    ConsoleColor{0xfa, 0x7d, 0x20},
    ConsoleColor{0xea, 0x50, 0x0d},
    ConsoleColor{0xd0, 0x2f, 0x04},
    ConsoleColor{0xa9, 0x15, 0x01},
}};

constexpr size_t kHueBits = 4;
constexpr uint32_t kMaxHue = kTurboColors.size() << kHueBits;
constexpr uint8_t kLightness = 128u;
constexpr ConsoleColor kWhiteColor{0xff, 0xff, 0xff};

const char kDim[] = "\x1b[90m";
const char kDefault[] = "\x1b[39m";
const char kReset[] = "\x1b[0m";

#define FMT_RGB_SET "\x1b[38;2;%d;%d;%dm"
#define FMT_RGB_SET_BG "\x1b[48;2;%d;%d;%dm"

ConsoleColor Mix(ConsoleColor a, ConsoleColor b, uint8_t ratio) {
  return {
      static_cast<uint8_t>(a.r + (((b.r - a.r) * ratio) >> 8)),
      static_cast<uint8_t>(a.g + (((b.g - a.g) * ratio) >> 8)),
      static_cast<uint8_t>(a.b + (((b.b - a.b) * ratio) >> 8)),
  };
}

ConsoleColor HueToRGB(uint32_t hue) {
  PERFETTO_DCHECK(hue < kMaxHue);
  uint32_t c1 = hue >> kHueBits;
  uint32_t c2 =
      std::min(static_cast<uint32_t>(kTurboColors.size() - 1), c1 + 1u);
  uint32_t ratio = hue & ((1 << kHueBits) - 1);
  return Mix(kTurboColors[c1], kTurboColors[c2],
             static_cast<uint8_t>(ratio | (ratio << kHueBits)));
}

uint32_t CounterToHue(uint32_t counter) {
  // We split the hue space into 8 segments, reversing the order of bits so
  // successive counter values will be far from each other.
  uint32_t reversed =
      ((counter & 0x7) >> 2) | ((counter & 0x3)) | ((counter & 0x1) << 2);
  return reversed * kMaxHue / 8;
}

}  // namespace

class ConsoleInterceptor::Delegate : public TrackEventStateTracker::Delegate {
 public:
  explicit Delegate(InterceptorContext&);
  ~Delegate() override;

  TrackEventStateTracker::SessionState* GetSessionState() override;
  void OnTrackUpdated(TrackEventStateTracker::Track&) override;
  void OnTrackEvent(const TrackEventStateTracker::Track&,
                    const TrackEventStateTracker::ParsedTrackEvent&) override;

 private:
  using SelfHandle = LockedHandle<ConsoleInterceptor>;

  InterceptorContext& context_;
  std::optional<SelfHandle> locked_self_;
};

ConsoleInterceptor::~ConsoleInterceptor() = default;

ConsoleInterceptor::ThreadLocalState::ThreadLocalState(
    ThreadLocalStateArgs& args) {
  if (auto self = args.GetInterceptorLocked()) {
    start_time_ns = self->start_time_ns_;
    use_colors = self->use_colors_;
    fd = self->fd_;
  }
}

ConsoleInterceptor::ThreadLocalState::~ThreadLocalState() = default;

ConsoleInterceptor::Delegate::Delegate(InterceptorContext& context)
    : context_(context) {}
ConsoleInterceptor::Delegate::~Delegate() = default;

TrackEventStateTracker::SessionState*
ConsoleInterceptor::Delegate::GetSessionState() {
  // When the session state is retrieved for the first time, it is cached (and
  // kept locked) until we return from OnTracePacket. This avoids having to lock
  // and unlock the instance multiple times per invocation.
  if (locked_self_.has_value())
    return &locked_self_.value()->session_state_;
  locked_self_ =
      std::make_optional<SelfHandle>(context_.GetInterceptorLocked());
  return &locked_self_.value()->session_state_;
}

void ConsoleInterceptor::Delegate::OnTrackUpdated(
    TrackEventStateTracker::Track& track) {
  auto track_color = HueToRGB(CounterToHue(track.index));
  std::array<char, 16> title;
  if (!track.name.empty()) {
    snprintf(title.data(), title.size(), "%s", track.name.c_str());
  } else if (track.pid && track.tid) {
    snprintf(title.data(), title.size(), "%u:%u",
             static_cast<uint32_t>(track.pid),
             static_cast<uint32_t>(track.tid));
  } else if (track.pid) {
    snprintf(title.data(), title.size(), "%" PRId64, track.pid);
  } else {
    snprintf(title.data(), title.size(), "%" PRIu64, track.uuid);
  }
  int title_width = static_cast<int>(title.size());

  auto& tls = context_.GetThreadLocalState();
  std::array<char, 128> message_prefix{};
  size_t written = 0;
  if (tls.use_colors) {
    written = base::SprintfTrunc(message_prefix.data(), message_prefix.size(),
                                 FMT_RGB_SET_BG " %s%s %-*.*s", track_color.r,
                                 track_color.g, track_color.b, kReset, kDim,
                                 title_width, title_width, title.data());
  } else {
    written = base::SprintfTrunc(message_prefix.data(), message_prefix.size(),
                                 "%-*.*s", title_width + 2, title_width,
                                 title.data());
  }
  track.user_data.assign(
      message_prefix.begin(),
      message_prefix.begin() + static_cast<ssize_t>(written));
}

void ConsoleInterceptor::Delegate::OnTrackEvent(
    const TrackEventStateTracker::Track& track,
    const TrackEventStateTracker::ParsedTrackEvent& event) {
  // Start printing.
  auto& tls = context_.GetThreadLocalState();
  tls.buffer_pos = 0;

  // Print timestamp and track identifier.
  SetColor(context_, kDim);
  Printf(context_, "[%7.3lf] %.*s",
         static_cast<double>(event.timestamp_ns - tls.start_time_ns) / 1e9,
         static_cast<int>(track.user_data.size()), track.user_data.data());

  // Print category.
  Printf(context_, "%-5.*s ",
         std::min(5, static_cast<int>(event.category.size)),
         event.category.data);

  // Print stack depth.
  for (size_t i = 0; i < event.stack_depth; i++) {
    Printf(context_, "-  ");
  }

  // Print slice name.
  auto slice_color = HueToRGB(event.name_hash % kMaxHue);
  auto highlight_color = Mix(slice_color, kWhiteColor, kLightness);
  if (event.track_event.type() == protos::pbzero::TrackEvent::TYPE_SLICE_END) {
    SetColor(context_, kDefault);
    Printf(context_, "} ");
  }
  SetColor(context_, highlight_color);
  Printf(context_, "%.*s", static_cast<int>(event.name.size), event.name.data);
  SetColor(context_, kReset);
  if (event.track_event.type() ==
      protos::pbzero::TrackEvent::TYPE_SLICE_BEGIN) {
    SetColor(context_, kDefault);
    Printf(context_, " {");
  }

  // Print annotations.
  if (event.track_event.has_debug_annotations()) {
    PrintDebugAnnotations(context_, event.track_event, slice_color,
                          highlight_color);
  }

  // TODO(skyostil): Print typed arguments.

  // Print duration for longer events.
  constexpr uint64_t kNsPerMillisecond = 1000000u;
  if (event.duration_ns >= 10 * kNsPerMillisecond) {
    SetColor(context_, kDim);
    Printf(context_, " +%" PRIu64 "ms", event.duration_ns / kNsPerMillisecond);
  }
  SetColor(context_, kReset);
  Printf(context_, "\n");
}

// static
void ConsoleInterceptor::Register() {
  perfetto::protos::gen::InterceptorDescriptor desc;
  desc.set_name("console");
  Interceptor<ConsoleInterceptor>::Register(desc);
}

// static
void ConsoleInterceptor::SetOutputFdForTesting(int fd) {
  g_output_fd_for_testing = fd;
}

void ConsoleInterceptor::OnSetup(const SetupArgs& args) {
  int fd = STDOUT_FILENO;
  if (g_output_fd_for_testing)
    fd = g_output_fd_for_testing;
#if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) && \
    !PERFETTO_BUILDFLAG(PERFETTO_OS_WASM)
  bool use_colors = isatty(fd);
#else
  bool use_colors = false;
#endif
  const protos::gen::ConsoleConfig& config =
      args.config.interceptor_config().console_config();
  if (config.has_enable_colors())
    use_colors = config.enable_colors();
  if (config.output() == protos::gen::ConsoleConfig::OUTPUT_STDOUT) {
    fd = STDOUT_FILENO;
  } else if (config.output() == protos::gen::ConsoleConfig::OUTPUT_STDERR) {
    fd = STDERR_FILENO;
  }
  fd_ = fd;
  use_colors_ = use_colors;
}

void ConsoleInterceptor::OnStart(const StartArgs&) {
  start_time_ns_ = internal::TrackEventInternal::GetTimeNs();
}

void ConsoleInterceptor::OnStop(const StopArgs&) {}

// static
void ConsoleInterceptor::OnTracePacket(InterceptorContext context) {
  {
    auto& tls = context.GetThreadLocalState();
    Delegate delegate(context);
    perfetto::protos::pbzero::TracePacket::Decoder packet(
        context.packet_data.data, context.packet_data.size);
    TrackEventStateTracker::ProcessTracePacket(delegate, tls.sequence_state,
                                               packet);
  }  // (Potential) lock scope for session state.
  Flush(context);
}

// static
void ConsoleInterceptor::Printf(InterceptorContext& context,
                                const char* format,
                                ...) {
  auto& tls = context.GetThreadLocalState();
  ssize_t remaining = static_cast<ssize_t>(tls.message_buffer.size()) -
                      static_cast<ssize_t>(tls.buffer_pos);
  int written = 0;
  if (remaining > 0) {
    va_list args;
    va_start(args, format);
    written = vsnprintf(&tls.message_buffer[tls.buffer_pos],
                        static_cast<size_t>(remaining), format, args);
    PERFETTO_DCHECK(written >= 0);
    va_end(args);
  }

  // In case of buffer overflow, flush to the fd and write the latest message to
  // it directly instead.
  if (remaining <= 0 || written > remaining) {
    FILE* output = (tls.fd == STDOUT_FILENO) ? stdout : stderr;
    if (g_output_fd_for_testing) {
      output = fdopen(dup(g_output_fd_for_testing), "w");
    }
    Flush(context);
    va_list args;
    va_start(args, format);
    vfprintf(output, format, args);
    va_end(args);
    if (g_output_fd_for_testing) {
      fclose(output);
    }
  } else if (written > 0) {
    tls.buffer_pos += static_cast<size_t>(written);
  }
}

// static
void ConsoleInterceptor::Flush(InterceptorContext& context) {
  auto& tls = context.GetThreadLocalState();
  ssize_t res = base::WriteAll(tls.fd, &tls.message_buffer[0], tls.buffer_pos);
  PERFETTO_DCHECK(res == static_cast<ssize_t>(tls.buffer_pos));
  tls.buffer_pos = 0;
}

// static
void ConsoleInterceptor::SetColor(InterceptorContext& context,
                                  const ConsoleColor& color) {
  auto& tls = context.GetThreadLocalState();
  if (!tls.use_colors)
    return;
  Printf(context, FMT_RGB_SET, color.r, color.g, color.b);
}

// static
void ConsoleInterceptor::SetColor(InterceptorContext& context,
                                  const char* color) {
  auto& tls = context.GetThreadLocalState();
  if (!tls.use_colors)
    return;
  Printf(context, "%s", color);
}

// static
void ConsoleInterceptor::PrintDebugAnnotations(
    InterceptorContext& context,
    const protos::pbzero::TrackEvent_Decoder& track_event,
    const ConsoleColor& slice_color,
    const ConsoleColor& highlight_color) {
  SetColor(context, slice_color);
  Printf(context, "(");

  bool is_first = true;
  for (auto it = track_event.debug_annotations(); it; it++) {
    perfetto::protos::pbzero::DebugAnnotation::Decoder annotation(*it);
    SetColor(context, slice_color);
    if (!is_first)
      Printf(context, ", ");

    PrintDebugAnnotationName(context, annotation);
    Printf(context, ":");

    SetColor(context, highlight_color);
    PrintDebugAnnotationValue(context, annotation);

    is_first = false;
  }
  SetColor(context, slice_color);
  Printf(context, ")");
}

// static
void ConsoleInterceptor::PrintDebugAnnotationName(
    InterceptorContext& context,
    const perfetto::protos::pbzero::DebugAnnotation::Decoder& annotation) {
  auto& tls = context.GetThreadLocalState();
  protozero::ConstChars name{};
  if (annotation.name_iid()) {
    name.data =
        tls.sequence_state.debug_annotation_names[annotation.name_iid()].data();
    name.size =
        tls.sequence_state.debug_annotation_names[annotation.name_iid()].size();
  } else if (annotation.has_name()) {
    name.data = annotation.name().data;
    name.size = annotation.name().size;
  }
  Printf(context, "%.*s", static_cast<int>(name.size), name.data);
}

// static
void ConsoleInterceptor::PrintDebugAnnotationValue(
    InterceptorContext& context,
    const perfetto::protos::pbzero::DebugAnnotation::Decoder& annotation) {
  if (annotation.has_bool_value()) {
    Printf(context, "%s", annotation.bool_value() ? "true" : "false");
  } else if (annotation.has_uint_value()) {
    Printf(context, "%" PRIu64, annotation.uint_value());
  } else if (annotation.has_int_value()) {
    Printf(context, "%" PRId64, annotation.int_value());
  } else if (annotation.has_double_value()) {
    Printf(context, "%f", annotation.double_value());
  } else if (annotation.has_string_value()) {
    Printf(context, "%.*s", static_cast<int>(annotation.string_value().size),
           annotation.string_value().data);
  } else if (annotation.has_pointer_value()) {
    Printf(context, "%p", reinterpret_cast<void*>(annotation.pointer_value()));
  } else if (annotation.has_legacy_json_value()) {
    Printf(context, "%.*s",
           static_cast<int>(annotation.legacy_json_value().size),
           annotation.legacy_json_value().data);
  } else if (annotation.has_dict_entries()) {
    Printf(context, "{");
    bool is_first = true;
    for (auto it = annotation.dict_entries(); it; ++it) {
      if (!is_first)
        Printf(context, ", ");
      perfetto::protos::pbzero::DebugAnnotation::Decoder key_value(*it);
      PrintDebugAnnotationName(context, key_value);
      Printf(context, ":");
      PrintDebugAnnotationValue(context, key_value);
      is_first = false;
    }
    Printf(context, "}");
  } else if (annotation.has_array_values()) {
    Printf(context, "[");
    bool is_first = true;
    for (auto it = annotation.array_values(); it; ++it) {
      if (!is_first)
        Printf(context, ", ");
      perfetto::protos::pbzero::DebugAnnotation::Decoder key_value(*it);
      PrintDebugAnnotationValue(context, key_value);
      is_first = false;
    }
    Printf(context, "]");
  } else {
    Printf(context, "{}");
  }
}

}  // namespace perfetto
// gen_amalgamated begin source: src/tracing/data_source.cc
/*
 * Copyright (C) 2019 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// gen_amalgamated expanded: #include "perfetto/tracing/data_source.h"
// gen_amalgamated expanded: #include "perfetto/base/logging.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/data_source_config.gen.h"

namespace perfetto {

DataSourceBase::StopArgs::~StopArgs() = default;
DataSourceBase::FlushArgs::~FlushArgs() = default;
DataSourceBase::~DataSourceBase() = default;
void DataSourceBase::OnSetup(const SetupArgs&) {}
void DataSourceBase::OnStart(const StartArgs&) {}
void DataSourceBase::OnStop(const StopArgs&) {}
void DataSourceBase::WillClearIncrementalState(
    const ClearIncrementalStateArgs&) {}
void DataSourceBase::OnFlush(const FlushArgs&) {}

bool DataSourceBase::CanAdoptStartupSession(
    const DataSourceConfig& startup_config,
    const DataSourceConfig& service_config) {
  // Clear target buffer and tracing-service provided fields for comparison of
  // configs for startup tracing, since these fields are not available when
  // setting up data sources for startup tracing.
  DataSourceConfig startup_config_stripped = startup_config;
  DataSourceConfig service_config_stripped = service_config;

  startup_config_stripped.set_target_buffer(0);
  startup_config_stripped.set_tracing_session_id(0);
  startup_config_stripped.set_session_initiator(
      DataSourceConfig::SESSION_INITIATOR_UNSPECIFIED);
  startup_config_stripped.set_trace_duration_ms(0);
  startup_config_stripped.set_stop_timeout_ms(0);
  startup_config_stripped.set_enable_extra_guardrails(false);

  service_config_stripped.set_target_buffer(0);
  service_config_stripped.set_tracing_session_id(0);
  service_config_stripped.set_session_initiator(
      DataSourceConfig::SESSION_INITIATOR_UNSPECIFIED);
  service_config_stripped.set_trace_duration_ms(0);
  service_config_stripped.set_stop_timeout_ms(0);
  service_config_stripped.set_enable_extra_guardrails(false);

  return startup_config_stripped == service_config_stripped;
}

namespace internal {

void DataSourceType::PopulateTlsInst(
    DataSourceInstanceThreadLocalState* tls_inst,
    DataSourceState* instance_state,
    uint32_t instance_index) {
  auto* tracing_impl = TracingMuxer::Get();
  tls_inst->muxer_id_for_testing = instance_state->muxer_id_for_testing;
  tls_inst->backend_id = instance_state->backend_id;
  tls_inst->backend_connection_id = instance_state->backend_connection_id;
  tls_inst->buffer_id = instance_state->buffer_id;
  tls_inst->startup_target_buffer_reservation =
      instance_state->startup_target_buffer_reservation.load(
          std::memory_order_relaxed);
  tls_inst->data_source_instance_id = instance_state->data_source_instance_id;
  tls_inst->is_intercepted = instance_state->interceptor_id != 0;
  tls_inst->trace_writer = tracing_impl->CreateTraceWriter(
      &state_, instance_index, instance_state, buffer_exhausted_policy_);
  if (create_incremental_state_fn_) {
    PERFETTO_DCHECK(!tls_inst->incremental_state);
    CreateIncrementalState(tls_inst, instance_index);
  }
  if (create_custom_tls_fn_) {
    tls_inst->data_source_custom_tls =
        create_custom_tls_fn_(tls_inst, instance_index, user_arg_);
  }
  // Even in the case of out-of-IDs, SharedMemoryArbiterImpl returns a
  // NullTraceWriter. The returned pointer should never be null.
  PERFETTO_DCHECK(tls_inst->trace_writer);
}

}  // namespace internal
}  // namespace perfetto
// gen_amalgamated begin source: src/tracing/debug_annotation.cc
/*
 * Copyright (C) 2019 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// gen_amalgamated expanded: #include "perfetto/tracing/debug_annotation.h"

// gen_amalgamated expanded: #include "perfetto/tracing/traced_value.h"
// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/debug_annotation.pbzero.h"

namespace perfetto {

DebugAnnotation::~DebugAnnotation() = default;

void DebugAnnotation::WriteIntoTracedValue(TracedValue context) const {
  Add(context.annotation_);
}

}  // namespace perfetto
// gen_amalgamated begin source: src/tracing/event_context.cc
// gen_amalgamated begin header: include/perfetto/tracing/internal/track_event_interned_fields.h
/*
 * Copyright (C) 2021 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// gen_amalgamated expanded: #include "perfetto/base/export.h"
// gen_amalgamated expanded: #include "perfetto/tracing/track_event_interned_data_index.h"

#ifndef INCLUDE_PERFETTO_TRACING_INTERNAL_TRACK_EVENT_INTERNED_FIELDS_H_
#define INCLUDE_PERFETTO_TRACING_INTERNAL_TRACK_EVENT_INTERNED_FIELDS_H_

namespace perfetto {
namespace internal {

// These helpers are exposed here to allow Chromium-without-client library
// to share the interning buffers with Perfetto internals (e.g.
// perfetto::TracedValue implementation).

struct PERFETTO_EXPORT_COMPONENT InternedEventCategory
    : public TrackEventInternedDataIndex<
          InternedEventCategory,
          perfetto::protos::pbzero::InternedData::kEventCategoriesFieldNumber,
          const char*,
          SmallInternedDataTraits> {
  ~InternedEventCategory() override;

  static void Add(protos::pbzero::InternedData* interned_data,
                  size_t iid,
                  const char* value,
                  size_t length);
};

struct PERFETTO_EXPORT_COMPONENT InternedEventName
    : public TrackEventInternedDataIndex<
          InternedEventName,
          perfetto::protos::pbzero::InternedData::kEventNamesFieldNumber,
          const char*,
          SmallInternedDataTraits> {
  ~InternedEventName() override;

  static void Add(protos::pbzero::InternedData* interned_data,
                  size_t iid,
                  const char* value);
};

struct PERFETTO_EXPORT_COMPONENT InternedDebugAnnotationName
    : public TrackEventInternedDataIndex<
          InternedDebugAnnotationName,
          perfetto::protos::pbzero::InternedData::
              kDebugAnnotationNamesFieldNumber,
          const char*,
          SmallInternedDataTraits> {
  ~InternedDebugAnnotationName() override;

  static void Add(protos::pbzero::InternedData* interned_data,
                  size_t iid,
                  const char* value);
};

struct PERFETTO_EXPORT_COMPONENT InternedDebugAnnotationValueTypeName
    : public TrackEventInternedDataIndex<
          InternedDebugAnnotationValueTypeName,
          perfetto::protos::pbzero::InternedData::
              kDebugAnnotationValueTypeNamesFieldNumber,
          const char*,
          SmallInternedDataTraits> {
  ~InternedDebugAnnotationValueTypeName() override;

  static void Add(protos::pbzero::InternedData* interned_data,
                  size_t iid,
                  const char* value);
};

}  // namespace internal
}  // namespace perfetto

#endif  // INCLUDE_PERFETTO_TRACING_INTERNAL_TRACK_EVENT_INTERNED_FIELDS_H_
/*
 * Copyright (C) 2019 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// gen_amalgamated expanded: #include "perfetto/tracing/event_context.h"

// gen_amalgamated expanded: #include "perfetto/tracing/internal/track_event_interned_fields.h"
// gen_amalgamated expanded: #include "protos/perfetto/trace/interned_data/interned_data.pbzero.h"
// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/track_event.pbzero.h"

namespace perfetto {

EventContext::EventContext(
    TraceWriterBase* trace_writer,
    EventContext::TracePacketHandle trace_packet,
    internal::TrackEventIncrementalState* incremental_state,
    internal::TrackEventTlsState* tls_state)
    : trace_writer_(trace_writer),
      trace_packet_(std::move(trace_packet)),
      event_(trace_packet_->set_track_event()),
      incremental_state_(incremental_state),
      tls_state_(tls_state) {}

EventContext::~EventContext() {
  if (!trace_packet_)
    return;

  // When the track event is finalized (i.e., the context is destroyed), we
  // should flush any newly seen interned data to the trace. The data has
  // earlier been written to a heap allocated protobuf message
  // (|serialized_interned_data|). Here we just need to flush it to the main
  // trace.
  auto& serialized_interned_data = incremental_state_->serialized_interned_data;
  if (PERFETTO_UNLIKELY(!serialized_interned_data.empty())) {
    auto ranges = serialized_interned_data.GetRanges();
    trace_packet_->AppendScatteredBytes(
        perfetto::protos::pbzero::TracePacket::kInternedDataFieldNumber,
        &ranges[0], ranges.size());

    // Reset the message but keep one buffer allocated for future use.
    serialized_interned_data.Reset();
  }
}

protos::pbzero::DebugAnnotation* EventContext::AddDebugAnnotation(
    const char* name) {
  auto annotation = event()->add_debug_annotations();
  annotation->set_name_iid(
      internal::InternedDebugAnnotationName::Get(this, name));
  return annotation;
}

protos::pbzero::DebugAnnotation* EventContext::AddDebugAnnotation(
    ::perfetto::DynamicString name) {
  auto annotation = event()->add_debug_annotations();
  annotation->set_name(name.value);
  return annotation;
}

TrackEventTlsStateUserData* EventContext::GetTlsUserData(const void* key) {
  PERFETTO_CHECK(tls_state_);
  PERFETTO_CHECK(key);
  auto it = tls_state_->user_data.find(key);
  if (it != tls_state_->user_data.end()) {
    return it->second.get();
  }
  return nullptr;
}

void EventContext::SetTlsUserData(
    const void* key,
    std::unique_ptr<TrackEventTlsStateUserData> data) {
  PERFETTO_CHECK(tls_state_);
  PERFETTO_CHECK(key);
  tls_state_->user_data[key] = std::move(data);
}

}  // namespace perfetto
// gen_amalgamated begin source: src/tracing/interceptor.cc
/*
 * Copyright (C) 2020 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// gen_amalgamated expanded: #include "perfetto/tracing/interceptor.h"

// gen_amalgamated expanded: #include "perfetto/tracing/internal/tracing_muxer.h"

namespace perfetto {

InterceptorBase::~InterceptorBase() = default;
InterceptorBase::ThreadLocalState::~ThreadLocalState() = default;

// static
void InterceptorBase::RegisterImpl(
    const InterceptorDescriptor& descriptor,
    std::function<std::unique_ptr<InterceptorBase>()> factory,
    InterceptorBase::TLSFactory tls_factory,
    InterceptorBase::TracePacketCallback on_trace_packet) {
  auto* tracing_impl = internal::TracingMuxer::Get();
  tracing_impl->RegisterInterceptor(descriptor, factory, tls_factory,
                                    on_trace_packet);
}

}  // namespace perfetto
// gen_amalgamated begin source: src/tracing/internal/checked_scope.cc
/*
 * Copyright (C) 2021 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// gen_amalgamated expanded: #include "perfetto/tracing/internal/checked_scope.h"

#include <utility>

namespace perfetto {
namespace internal {

#if PERFETTO_DCHECK_IS_ON()
CheckedScope::CheckedScope(CheckedScope* parent_scope)
    : parent_scope_(parent_scope) {
  if (parent_scope_) {
    PERFETTO_DCHECK(parent_scope_->is_active());
    parent_scope_->set_is_active(false);
  }
}

CheckedScope::~CheckedScope() {
  Reset();
}

void CheckedScope::Reset() {
  if (!is_active_) {
    // The only case when inactive scope could be destroyed is when Reset() was
    // called explicitly or the contents of the object were moved away.
    PERFETTO_DCHECK(deleted_);
    return;
  }
  is_active_ = false;
  deleted_ = true;
  if (parent_scope_)
    parent_scope_->set_is_active(true);
}

CheckedScope::CheckedScope(CheckedScope&& other) {
  *this = std::move(other);
}

CheckedScope& CheckedScope::operator=(CheckedScope&& other) {
  is_active_ = other.is_active_;
  parent_scope_ = other.parent_scope_;
  deleted_ = other.deleted_;

  other.is_active_ = false;
  other.parent_scope_ = nullptr;
  other.deleted_ = true;

  return *this;
}
#endif

}  // namespace internal
}  // namespace perfetto
// gen_amalgamated begin source: src/tracing/internal/interceptor_trace_writer.cc
// gen_amalgamated begin header: include/perfetto/tracing/internal/interceptor_trace_writer.h
/*
 * Copyright (C) 2020 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef INCLUDE_PERFETTO_TRACING_INTERNAL_INTERCEPTOR_TRACE_WRITER_H_
#define INCLUDE_PERFETTO_TRACING_INTERNAL_INTERCEPTOR_TRACE_WRITER_H_

// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
// gen_amalgamated expanded: #include "perfetto/tracing/interceptor.h"
// gen_amalgamated expanded: #include "perfetto/tracing/internal/basic_types.h"
// gen_amalgamated expanded: #include "perfetto/tracing/trace_writer_base.h"
// gen_amalgamated expanded: #include "protos/perfetto/trace/trace_packet.pbzero.h"

namespace perfetto {
namespace internal {

// A heap-backed trace writer used to reroute trace packets to an interceptor.
class InterceptorTraceWriter : public TraceWriterBase {
 public:
  InterceptorTraceWriter(std::unique_ptr<InterceptorBase::ThreadLocalState> tls,
                         InterceptorBase::TracePacketCallback packet_callback,
                         DataSourceStaticState* static_state,
                         uint32_t instance_index);
  ~InterceptorTraceWriter() override;

  // TraceWriterBase implementation.
  protozero::MessageHandle<protos::pbzero::TracePacket> NewTracePacket()
      override;
  void FinishTracePacket() override;
  void Flush(std::function<void()> callback = {}) override;
  uint64_t written() const override;

 private:
  std::unique_ptr<InterceptorBase::ThreadLocalState> tls_;
  InterceptorBase::TracePacketCallback packet_callback_;

  protozero::HeapBuffered<protos::pbzero::TracePacket> cur_packet_;
  uint64_t bytes_written_ = 0;

  // Static state of the data source we are intercepting.
  DataSourceStaticState* const static_state_;

  // Index of the data source tracing session which we are intercepting
  // (0...kMaxDataSourceInstances - 1). Used to look up this interceptor's
  // session state (i.e., the Interceptor class instance) in the
  // DataSourceStaticState::instances array.
  const uint32_t instance_index_;

  const uint32_t sequence_id_;

  static std::atomic<uint32_t> next_sequence_id_;
};

}  // namespace internal
}  // namespace perfetto

#endif  // INCLUDE_PERFETTO_TRACING_INTERNAL_INTERCEPTOR_TRACE_WRITER_H_
/*
 * Copyright (C) 2020 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// gen_amalgamated expanded: #include "perfetto/tracing/internal/interceptor_trace_writer.h"

// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/trace_writer.h"

namespace perfetto {
namespace internal {

// static
std::atomic<uint32_t> InterceptorTraceWriter::next_sequence_id_{};

InterceptorTraceWriter::InterceptorTraceWriter(
    std::unique_ptr<InterceptorBase::ThreadLocalState> tls,
    InterceptorBase::TracePacketCallback packet_callback,
    DataSourceStaticState* static_state,
    uint32_t instance_index)
    : tls_(std::move(tls)),
      packet_callback_(std::move(packet_callback)),
      static_state_(static_state),
      instance_index_(instance_index),
      sequence_id_(++next_sequence_id_) {}

InterceptorTraceWriter::~InterceptorTraceWriter() = default;

protozero::MessageHandle<protos::pbzero::TracePacket>
InterceptorTraceWriter::NewTracePacket() {
  Flush();
  auto packet = TraceWriter::TracePacketHandle(cur_packet_.get());
  packet->set_trusted_packet_sequence_id(sequence_id_);
  return packet;
}

void InterceptorTraceWriter::Flush(std::function<void()> callback) {
  if (!cur_packet_.empty()) {
    InterceptorBase::TracePacketCallbackArgs args{};
    args.static_state = static_state_;
    args.instance_index = instance_index_;
    args.tls = tls_.get();

    const auto& slices = cur_packet_.GetSlices();
    if (slices.size() == 1) {
      // Fast path: the current packet fits into a single slice.
      auto slice_range = slices.begin()->GetUsedRange();
      args.packet_data = protozero::ConstBytes{
          slice_range.begin,
          static_cast<size_t>(slice_range.end - slice_range.begin)};
      bytes_written_ += static_cast<uint64_t>(args.packet_data.size);
      packet_callback_(std::move(args));
    } else {
      // Fallback: stitch together multiple slices.
      auto stitched_data = cur_packet_.SerializeAsArray();
      args.packet_data =
          protozero::ConstBytes{stitched_data.data(), stitched_data.size()};
      bytes_written_ += static_cast<uint64_t>(stitched_data.size());
      packet_callback_(std::move(args));
    }
    cur_packet_.Reset();
  }
  if (callback)
    callback();
}

void InterceptorTraceWriter::FinishTracePacket() {}

uint64_t InterceptorTraceWriter::written() const {
  return bytes_written_;
}

}  // namespace internal
}  // namespace perfetto
// gen_amalgamated begin source: src/tracing/internal/tracing_backend_fake.cc
// gen_amalgamated begin header: include/perfetto/tracing/internal/tracing_backend_fake.h
/*
 * Copyright (C) 2021 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef INCLUDE_PERFETTO_TRACING_INTERNAL_TRACING_BACKEND_FAKE_H_
#define INCLUDE_PERFETTO_TRACING_INTERNAL_TRACING_BACKEND_FAKE_H_

// gen_amalgamated expanded: #include "perfetto/base/export.h"
// gen_amalgamated expanded: #include "perfetto/tracing/tracing_backend.h"

namespace perfetto {
namespace internal {

// A built-in implementation of TracingBackend that fails any attempt to create
// a tracing session.
class PERFETTO_EXPORT_COMPONENT TracingBackendFake : public TracingBackend {
 public:
  static TracingBackend* GetInstance();

  // TracingBackend implementation.
  std::unique_ptr<ProducerEndpoint> ConnectProducer(
      const ConnectProducerArgs&) override;
  std::unique_ptr<ConsumerEndpoint> ConnectConsumer(
      const ConnectConsumerArgs&) override;

 private:
  TracingBackendFake();
};

}  // namespace internal
}  // namespace perfetto

#endif  // INCLUDE_PERFETTO_TRACING_INTERNAL_TRACING_BACKEND_FAKE_H_
/*
 * Copyright (C) 2021 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// gen_amalgamated expanded: #include "perfetto/tracing/internal/tracing_backend_fake.h"

// gen_amalgamated expanded: #include "perfetto/base/task_runner.h"
// gen_amalgamated expanded: #include "perfetto/ext/base/weak_ptr.h"
// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/consumer.h"
// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/producer.h"
// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/trace_writer.h"
// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/tracing_service.h"

namespace perfetto {
namespace internal {

namespace {

class UnsupportedProducerEndpoint : public ProducerEndpoint {
 public:
  UnsupportedProducerEndpoint(Producer* producer, base::TaskRunner* task_runner)
      : producer_(producer), task_runner_(task_runner) {
    // The SDK will attempt to reconnect the producer, so instead we allow it
    // to connect successfully, but never start any sessions.
    auto weak_ptr = weak_ptr_factory_.GetWeakPtr();
    task_runner_->PostTask([weak_ptr] {
      if (weak_ptr && weak_ptr->connected_)
        weak_ptr->producer_->OnConnect();
    });
  }
  ~UnsupportedProducerEndpoint() override { Disconnect(); }

  void Disconnect() override {
    if (!connected_)
      return;
    connected_ = false;
    producer_->OnDisconnect();
  }

  void RegisterDataSource(const DataSourceDescriptor&) override {}
  void UpdateDataSource(const DataSourceDescriptor&) override {}
  void UnregisterDataSource(const std::string& /*name*/) override {}

  void RegisterTraceWriter(uint32_t /*writer_id*/,
                           uint32_t /*target_buffer*/) override {}
  void UnregisterTraceWriter(uint32_t /*writer_id*/) override {}

  void CommitData(const CommitDataRequest&,
                  CommitDataCallback callback) override {
    if (connected_) {
      callback();
    }
  }

  SharedMemory* shared_memory() const override { return nullptr; }
  size_t shared_buffer_page_size_kb() const override { return 0; }

  std::unique_ptr<TraceWriter> CreateTraceWriter(
      BufferID /*target_buffer*/,
      BufferExhaustedPolicy) override {
    return nullptr;
  }

  SharedMemoryArbiter* MaybeSharedMemoryArbiter() override { return nullptr; }
  bool IsShmemProvidedByProducer() const override { return false; }

  void NotifyFlushComplete(FlushRequestID) override {}
  void NotifyDataSourceStarted(DataSourceInstanceID) override {}
  void NotifyDataSourceStopped(DataSourceInstanceID) override {}
  void ActivateTriggers(const std::vector<std::string>&) override {}

  void Sync(std::function<void()> callback) override {
    if (connected_) {
      callback();
    }
  }

 private:
  Producer* const producer_;
  base::TaskRunner* const task_runner_;
  bool connected_ = true;
  base::WeakPtrFactory<UnsupportedProducerEndpoint> weak_ptr_factory_{
      this};  // Keep last.
};

class UnsupportedConsumerEndpoint : public ConsumerEndpoint {
 public:
  UnsupportedConsumerEndpoint(Consumer* consumer, base::TaskRunner* task_runner)
      : consumer_(consumer), task_runner_(task_runner) {
    // The SDK will not to reconnect the consumer, so we just disconnect it
    // immediately, which will cancel the tracing session.
    auto weak_this = weak_ptr_factory_.GetWeakPtr();
    task_runner_->PostTask([weak_this] {
      if (weak_this)
        weak_this->consumer_->OnDisconnect();
    });
  }
  ~UnsupportedConsumerEndpoint() override = default;

  void EnableTracing(const TraceConfig&, base::ScopedFile) override {}
  void ChangeTraceConfig(const TraceConfig&) override {}

  void StartTracing() override {}
  void DisableTracing() override {}

  void Flush(uint32_t /*timeout_ms*/,
             FlushCallback callback,
             FlushFlags) override {
    callback(/*success=*/false);
  }

  void ReadBuffers() override {}
  void FreeBuffers() override {}

  void Detach(const std::string& /*key*/) override {}
  void Attach(const std::string& /*key*/) override {}

  void GetTraceStats() override {}
  void ObserveEvents(uint32_t /*events_mask*/) override {}
  void QueryServiceState(QueryServiceStateArgs,
                         QueryServiceStateCallback) override {}
  void QueryCapabilities(QueryCapabilitiesCallback) override {}

  void SaveTraceForBugreport(SaveTraceForBugreportCallback) override {}
  void CloneSession(TracingSessionID, CloneSessionArgs) override {}

 private:
  Consumer* const consumer_;
  base::TaskRunner* const task_runner_;
  base::WeakPtrFactory<UnsupportedConsumerEndpoint> weak_ptr_factory_{
      this};  // Keep last.
};

}  // namespace

// static
TracingBackend* TracingBackendFake::GetInstance() {
  static auto* instance = new TracingBackendFake();
  return instance;
}

TracingBackendFake::TracingBackendFake() = default;

std::unique_ptr<ProducerEndpoint> TracingBackendFake::ConnectProducer(
    const ConnectProducerArgs& args) {
  return std::unique_ptr<ProducerEndpoint>(
      new UnsupportedProducerEndpoint(args.producer, args.task_runner));
}

std::unique_ptr<ConsumerEndpoint> TracingBackendFake::ConnectConsumer(
    const ConnectConsumerArgs& args) {
  return std::unique_ptr<ConsumerEndpoint>(
      new UnsupportedConsumerEndpoint(args.consumer, args.task_runner));
}

}  // namespace internal
}  // namespace perfetto
// gen_amalgamated begin source: src/tracing/internal/tracing_muxer_fake.cc
// gen_amalgamated begin header: src/tracing/internal/tracing_muxer_fake.h
/*
 * Copyright (C) 2021 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef SRC_TRACING_INTERNAL_TRACING_MUXER_FAKE_H_
#define SRC_TRACING_INTERNAL_TRACING_MUXER_FAKE_H_

// gen_amalgamated expanded: #include "perfetto/base/compiler.h"
// gen_amalgamated expanded: #include "perfetto/tracing/internal/tracing_muxer.h"

namespace perfetto {
namespace internal {

// An always-fail implementation of TracingMuxer. Before tracing has been
// initialiazed, all muxer operations will route here and fail with a helpful
// error message. This is to avoid introducing null checks in
// performance-critical parts of the codebase.
class TracingMuxerFake : public TracingMuxer {
  class FakePlatform : public Platform {
   public:
    ~FakePlatform() override;
    ThreadLocalObject* GetOrCreateThreadLocalObject() override;
    std::unique_ptr<base::TaskRunner> CreateTaskRunner(
        const CreateTaskRunnerArgs&) override;
    std::string GetCurrentProcessName() override;

    static FakePlatform instance;
  };

 public:
  TracingMuxerFake() : TracingMuxer(&FakePlatform::instance) {}
  ~TracingMuxerFake() override;

  static constexpr TracingMuxerFake* Get() {
#if PERFETTO_HAS_NO_DESTROY()
    return &instance;
#else
    return nullptr;
#endif
  }

  // TracingMuxer implementation.
  bool RegisterDataSource(const DataSourceDescriptor&,
                          DataSourceFactory,
                          DataSourceParams,
                          bool,
                          DataSourceStaticState*) override;
  void UpdateDataSourceDescriptor(const DataSourceDescriptor&,
                                  const DataSourceStaticState*) override;
  std::unique_ptr<TraceWriterBase> CreateTraceWriter(
      DataSourceStaticState*,
      uint32_t data_source_instance_index,
      DataSourceState*,
      BufferExhaustedPolicy buffer_exhausted_policy) override;
  void DestroyStoppedTraceWritersForCurrentThread() override;
  void RegisterInterceptor(const InterceptorDescriptor&,
                           InterceptorFactory,
                           InterceptorBase::TLSFactory,
                           InterceptorBase::TracePacketCallback) override;
  void ActivateTriggers(const std::vector<std::string>&, uint32_t) override;

 private:
  static TracingMuxerFake instance;
};

}  // namespace internal
}  // namespace perfetto

#endif  // SRC_TRACING_INTERNAL_TRACING_MUXER_FAKE_H_
/*
 * Copyright (C) 2021 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// gen_amalgamated expanded: #include "src/tracing/internal/tracing_muxer_fake.h"

namespace perfetto {
namespace internal {
namespace {

PERFETTO_NORETURN void FailUninitialized() {
  PERFETTO_FATAL(
      "Tracing not initialized. Call perfetto::Tracing::Initialize() first.");
}

}  // namespace

#if PERFETTO_HAS_NO_DESTROY()
// static
PERFETTO_NO_DESTROY TracingMuxerFake::FakePlatform
    TracingMuxerFake::FakePlatform::instance{};
// static
PERFETTO_NO_DESTROY TracingMuxerFake TracingMuxerFake::instance{};
#endif  // PERFETTO_HAS_NO_DESTROY()

TracingMuxerFake::~TracingMuxerFake() = default;

TracingMuxerFake::FakePlatform::~FakePlatform() = default;

Platform::ThreadLocalObject*
TracingMuxerFake::FakePlatform::GetOrCreateThreadLocalObject() {
  FailUninitialized();
}

std::unique_ptr<base::TaskRunner>
TracingMuxerFake::FakePlatform::CreateTaskRunner(const CreateTaskRunnerArgs&) {
  FailUninitialized();
}

std::string TracingMuxerFake::FakePlatform::GetCurrentProcessName() {
  FailUninitialized();
}

bool TracingMuxerFake::RegisterDataSource(const DataSourceDescriptor&,
                                          DataSourceFactory,
                                          DataSourceParams,
                                          bool,
                                          DataSourceStaticState*) {
  FailUninitialized();
}

void TracingMuxerFake::UpdateDataSourceDescriptor(
    const DataSourceDescriptor&,
    const DataSourceStaticState*) {
  FailUninitialized();
}

std::unique_ptr<TraceWriterBase> TracingMuxerFake::CreateTraceWriter(
    DataSourceStaticState*,
    uint32_t,
    DataSourceState*,
    BufferExhaustedPolicy) {
  FailUninitialized();
}

void TracingMuxerFake::DestroyStoppedTraceWritersForCurrentThread() {
  FailUninitialized();
}

void TracingMuxerFake::RegisterInterceptor(
    const InterceptorDescriptor&,
    InterceptorFactory,
    InterceptorBase::TLSFactory,
    InterceptorBase::TracePacketCallback) {
  FailUninitialized();
}

void TracingMuxerFake::ActivateTriggers(const std::vector<std::string>&,
                                        uint32_t) {
  FailUninitialized();
}

}  // namespace internal
}  // namespace perfetto
// gen_amalgamated begin source: src/tracing/internal/tracing_muxer_impl.cc
// gen_amalgamated begin header: src/tracing/internal/tracing_muxer_impl.h
/*
 * Copyright (C) 2019 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef SRC_TRACING_INTERNAL_TRACING_MUXER_IMPL_H_
#define SRC_TRACING_INTERNAL_TRACING_MUXER_IMPL_H_

#include <stddef.h>
#include <stdint.h>

#include <array>
#include <atomic>
#include <bitset>
#include <functional>
#include <list>
#include <map>
#include <memory>
#include <set>
#include <utility>
#include <vector>

// gen_amalgamated expanded: #include "perfetto/base/time.h"
// gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"
// gen_amalgamated expanded: #include "perfetto/ext/base/thread_checker.h"
// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/basic_types.h"
// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/consumer.h"
// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/producer.h"
// gen_amalgamated expanded: #include "perfetto/tracing/backend_type.h"
// gen_amalgamated expanded: #include "perfetto/tracing/core/data_source_descriptor.h"
// gen_amalgamated expanded: #include "perfetto/tracing/core/forward_decls.h"
// gen_amalgamated expanded: #include "perfetto/tracing/core/trace_config.h"
// gen_amalgamated expanded: #include "perfetto/tracing/internal/basic_types.h"
// gen_amalgamated expanded: #include "perfetto/tracing/internal/tracing_muxer.h"
// gen_amalgamated expanded: #include "perfetto/tracing/tracing.h"

// gen_amalgamated expanded: #include "protos/perfetto/common/interceptor_descriptor.gen.h"

namespace perfetto {

class ConsumerEndpoint;
class DataSourceBase;
class ProducerEndpoint;
class TraceWriterBase;
class TracingBackend;
class TracingSession;
struct TracingInitArgs;

namespace base {
class TaskRunner;
}

namespace shlib {
void ResetForTesting();
}

namespace test {
class TracingMuxerImplInternalsForTest;
}

namespace internal {

struct DataSourceStaticState;

// This class acts as a bridge between the public API and the TracingBackend(s).
// It exposes a simplified view of the world to the API methods handling all the
// bookkeeping to map data source instances and trace writers to the various
// backends. It deals with N data sources, M backends (1 backend == 1 tracing
// service == 1 producer connection) and T concurrent tracing sessions.
//
// Handing data source registration and start/stop flows [producer side]:
// ----------------------------------------------------------------------
// 1. The API client subclasses perfetto::DataSource and calls
//    DataSource::Register<MyDataSource>(). In turn this calls into the
//    TracingMuxer.
// 2. The tracing muxer iterates through all the backends (1 backend == 1
//    service == 1 producer connection) and registers the data source on each
//    backend.
// 3. When any (services behind a) backend starts tracing and requests to start
//    that specific data source, the TracingMuxerImpl constructs a new instance
//    of MyDataSource and calls the OnStart() method.
//
// Controlling trace and retrieving trace data [consumer side]:
// ------------------------------------------------------------
// 1. The API client calls Tracing::NewTrace(), returns a RAII TracingSession
//    object.
// 2. NewTrace() calls into internal::TracingMuxer(Impl). TracingMuxer
//    subclasses the TracingSession object (TracingSessionImpl) and returns it.
// 3. The tracing muxer identifies the backend (according to the args passed to
//    NewTrace), creates a new Consumer and connects to it.
// 4. When the API client calls Start()/Stop()/ReadTrace() methods, the
//    TracingMuxer forwards them to the consumer associated to the
//    TracingSession. Likewise for callbacks coming from the consumer-side of
//    the service.
class TracingMuxerImpl : public TracingMuxer {
 public:
  // This is different than TracingSessionID because it's global across all
  // backends. TracingSessionID is global only within the scope of one service.
  using TracingSessionGlobalID = uint64_t;

  struct RegisteredDataSource {
    DataSourceDescriptor descriptor;
    DataSourceFactory factory{};
    bool supports_multiple_instances = false;
    bool requires_callbacks_under_lock = false;
    bool no_flush = false;
    DataSourceStaticState* static_state = nullptr;
  };

  static void InitializeInstance(const TracingInitArgs&);
  static void ResetForTesting();
  static void Shutdown();

  // TracingMuxer implementation.
  bool RegisterDataSource(const DataSourceDescriptor&,
                          DataSourceFactory,
                          DataSourceParams,
                          bool no_flush,
                          DataSourceStaticState*) override;
  void UpdateDataSourceDescriptor(const DataSourceDescriptor&,
                                  const DataSourceStaticState*) override;
  std::unique_ptr<TraceWriterBase> CreateTraceWriter(
      DataSourceStaticState*,
      uint32_t data_source_instance_index,
      DataSourceState*,
      BufferExhaustedPolicy buffer_exhausted_policy) override;
  void DestroyStoppedTraceWritersForCurrentThread() override;
  void RegisterInterceptor(const InterceptorDescriptor&,
                           InterceptorFactory,
                           InterceptorBase::TLSFactory,
                           InterceptorBase::TracePacketCallback) override;

  void ActivateTriggers(const std::vector<std::string>&, uint32_t) override;

  std::unique_ptr<TracingSession> CreateTracingSession(
      BackendType,
      TracingConsumerBackend* (*system_backend_factory)());
  std::unique_ptr<StartupTracingSession> CreateStartupTracingSession(
      const TraceConfig& config,
      Tracing::SetupStartupTracingOpts);
  std::unique_ptr<StartupTracingSession> CreateStartupTracingSessionBlocking(
      const TraceConfig& config,
      Tracing::SetupStartupTracingOpts);

  // Producer-side bookkeeping methods.
  void UpdateDataSourcesOnAllBackends();
  void SetupDataSource(TracingBackendId,
                       uint32_t backend_connection_id,
                       DataSourceInstanceID,
                       const DataSourceConfig&);
  void StartDataSource(TracingBackendId, DataSourceInstanceID);
  void StopDataSource_AsyncBegin(TracingBackendId, DataSourceInstanceID);
  void ClearDataSourceIncrementalState(TracingBackendId, DataSourceInstanceID);
  void SyncProducersForTesting();

  // Consumer-side bookkeeping methods.
  void SetupTracingSession(TracingSessionGlobalID,
                           const std::shared_ptr<TraceConfig>&,
                           base::ScopedFile trace_fd = base::ScopedFile());
  void StartTracingSession(TracingSessionGlobalID);
  void ChangeTracingSessionConfig(TracingSessionGlobalID, const TraceConfig&);
  void StopTracingSession(TracingSessionGlobalID);
  void DestroyTracingSession(TracingSessionGlobalID);
  void FlushTracingSession(TracingSessionGlobalID,
                           uint32_t,
                           std::function<void(bool)>);
  void ReadTracingSessionData(
      TracingSessionGlobalID,
      std::function<void(TracingSession::ReadTraceCallbackArgs)>);
  void GetTraceStats(TracingSessionGlobalID,
                     TracingSession::GetTraceStatsCallback);
  void QueryServiceState(TracingSessionGlobalID,
                         TracingSession::QueryServiceStateCallback);

  // Sets the batching period to |batch_commits_duration_ms| on the backends
  // with type |backend_type|.
  void SetBatchCommitsDurationForTesting(uint32_t batch_commits_duration_ms,
                                         BackendType backend_type);

  // Enables direct SMB patching on the backends with type |backend_type| (see
  // SharedMemoryArbiter::EnableDirectSMBPatching). Returns true if the
  // operation succeeded for all backends with type |backend_type|, false
  // otherwise.
  bool EnableDirectSMBPatchingForTesting(BackendType backend_type);

  void SetMaxProducerReconnectionsForTesting(uint32_t count);

 private:
  friend class test::TracingMuxerImplInternalsForTest;
  friend void shlib::ResetForTesting();

  // For each TracingBackend we create and register one ProducerImpl instance.
  // This talks to the producer-side of the service, gets start/stop requests
  // from it and routes them to the registered data sources.
  // One ProducerImpl == one backend == one tracing service.
  // This class is needed to disambiguate callbacks coming from different
  // services. TracingMuxerImpl can't directly implement the Producer interface
  // because the Producer virtual methods don't allow to identify the service.
  class ProducerImpl : public Producer {
   public:
    ProducerImpl(TracingMuxerImpl*,
                 TracingBackendId,
                 uint32_t shmem_batch_commits_duration_ms,
                 bool shmem_direct_patching_enabled);
    ~ProducerImpl() override;

    void Initialize(std::unique_ptr<ProducerEndpoint> endpoint);
    void RegisterDataSource(const DataSourceDescriptor&,
                            DataSourceFactory,
                            DataSourceStaticState*);
    void DisposeConnection();

    // perfetto::Producer implementation.
    void OnConnect() override;
    void OnDisconnect() override;
    void OnTracingSetup() override;
    void OnStartupTracingSetup() override;
    void SetupDataSource(DataSourceInstanceID,
                         const DataSourceConfig&) override;
    void StartDataSource(DataSourceInstanceID,
                         const DataSourceConfig&) override;
    void StopDataSource(DataSourceInstanceID) override;
    void Flush(FlushRequestID,
               const DataSourceInstanceID*,
               size_t,
               FlushFlags) override;
    void ClearIncrementalState(const DataSourceInstanceID*, size_t) override;

    bool SweepDeadServices();
    void SendOnConnectTriggers();
    void NotifyFlushForDataSourceDone(DataSourceInstanceID, FlushRequestID);

    PERFETTO_THREAD_CHECKER(thread_checker_)
    TracingMuxerImpl* muxer_;
    TracingBackendId const backend_id_;
    bool connected_ = false;
    bool did_setup_tracing_ = false;
    bool did_setup_startup_tracing_ = false;
    std::atomic<uint32_t> connection_id_{0};
    uint16_t last_startup_target_buffer_reservation_ = 0;
    bool is_producer_provided_smb_ = false;
    bool producer_provided_smb_failed_ = false;

    const uint32_t shmem_batch_commits_duration_ms_ = 0;
    const bool shmem_direct_patching_enabled_ = false;

    // Set of data sources that have been actually registered on this producer.
    // This can be a subset of the global |data_sources_|, because data sources
    // can register before the producer is fully connected.
    std::bitset<kMaxDataSources> registered_data_sources_{};

    // A collection of disconnected service endpoints. Since trace writers on
    // arbitrary threads might continue writing data to disconnected services,
    // we keep the old services around and periodically try to clean up ones
    // that no longer have any writers (see SweepDeadServices).
    std::list<std::shared_ptr<ProducerEndpoint>> dead_services_;

    // Triggers that should be sent when the service connects (trigger_name,
    // expiration).
    std::list<std::pair<std::string, base::TimeMillis>> on_connect_triggers_;

    std::map<FlushRequestID, std::set<DataSourceInstanceID>> pending_flushes_;

    // The currently active service endpoint is maintained as an atomic shared
    // pointer so it won't get deleted from underneath threads that are creating
    // trace writers. At any given time one endpoint can be shared (and thus
    // kept alive) by the |service_| pointer, an entry in |dead_services_| and
    // as a pointer on the stack in CreateTraceWriter() (on an arbitrary
    // thread). The endpoint is never shared outside ProducerImpl itself.
    //
    // WARNING: Any *write* access to this variable or any *read* access from a
    // non-muxer thread must be done through std::atomic_{load,store} to avoid
    // data races.
    std::shared_ptr<ProducerEndpoint> service_;  // Keep last.
  };

  // For each TracingSession created by the API client (Tracing::NewTrace() we
  // create and register one ConsumerImpl instance.
  // This talks to the consumer-side of the service, gets end-of-trace and
  // on-trace-data callbacks and routes them to the API client callbacks.
  // This class is needed to disambiguate callbacks coming from different
  // tracing sessions.
  class ConsumerImpl : public Consumer {
   public:
    ConsumerImpl(TracingMuxerImpl*, BackendType, TracingSessionGlobalID);
    ~ConsumerImpl() override;

    void Initialize(std::unique_ptr<ConsumerEndpoint> endpoint);

    // perfetto::Consumer implementation.
    void OnConnect() override;
    void OnDisconnect() override;
    void OnTracingDisabled(const std::string& error) override;
    void OnTraceData(std::vector<TracePacket>, bool has_more) override;
    void OnDetach(bool success) override;
    void OnAttach(bool success, const TraceConfig&) override;
    void OnTraceStats(bool success, const TraceStats&) override;
    void OnObservableEvents(const ObservableEvents&) override;
    void OnSessionCloned(const OnSessionClonedArgs&) override;

    void NotifyStartComplete();
    void NotifyError(const TracingError&);
    void NotifyStopComplete();

    // Will eventually inform the |muxer_| when it is safe to remove |this|.
    void Disconnect();

    TracingMuxerImpl* muxer_;
    BackendType const backend_type_;
    TracingSessionGlobalID const session_id_;
    bool connected_ = false;

    // This is to handle the case where the Setup call from the API client
    // arrives before the consumer has connected. In this case we keep around
    // the config and check if we have it after connection.
    bool start_pending_ = false;

    // Similarly if the session is stopped before the consumer was connected, we
    // need to wait until the session has started before stopping it.
    bool stop_pending_ = false;

    // Similarly we need to buffer a call to get trace statistics if the
    // consumer wasn't connected yet.
    bool get_trace_stats_pending_ = false;

    // Whether this session was already stopped. This will happen in response to
    // Stop{,Blocking}, but also if the service stops the session for us
    // automatically (e.g., when there are no data sources).
    bool stopped_ = false;

    // shared_ptr because it's posted across threads. This is to avoid copying
    // it more than once.
    std::shared_ptr<TraceConfig> trace_config_;
    base::ScopedFile trace_fd_;

    // If the API client passes a callback to start, we should invoke this when
    // NotifyStartComplete() is invoked.
    std::function<void()> start_complete_callback_;

    // An internal callback used to implement StartBlocking().
    std::function<void()> blocking_start_complete_callback_;

    // If the API client passes a callback to get notification about the
    // errors, we should invoke this when NotifyError() is invoked.
    std::function<void(TracingError)> error_callback_;

    // If the API client passes a callback to stop, we should invoke this when
    // OnTracingDisabled() is invoked.
    std::function<void()> stop_complete_callback_;

    // An internal callback used to implement StopBlocking().
    std::function<void()> blocking_stop_complete_callback_;

    // Callback passed to ReadTrace().
    std::function<void(TracingSession::ReadTraceCallbackArgs)>
        read_trace_callback_;

    // Callback passed to GetTraceStats().
    TracingSession::GetTraceStatsCallback get_trace_stats_callback_;

    // Callback for a pending call to QueryServiceState().
    TracingSession::QueryServiceStateCallback query_service_state_callback_;

    // The states of all data sources in this tracing session. |true| means the
    // data source has started tracing.
    using DataSourceHandle = std::pair<std::string, std::string>;
    std::map<DataSourceHandle, bool> data_source_states_;

    std::unique_ptr<ConsumerEndpoint> service_;  // Keep before last.
    PERFETTO_THREAD_CHECKER(thread_checker_)     // Keep last.
  };

  // This object is returned to API clients when they call
  // Tracing::CreateTracingSession().
  class TracingSessionImpl : public TracingSession {
   public:
    TracingSessionImpl(TracingMuxerImpl*, TracingSessionGlobalID, BackendType);
    ~TracingSessionImpl() override;
    void Setup(const TraceConfig&, int fd) override;
    void Start() override;
    void StartBlocking() override;
    void SetOnStartCallback(std::function<void()>) override;
    void SetOnErrorCallback(std::function<void(TracingError)>) override;
    void Stop() override;
    void StopBlocking() override;
    void Flush(std::function<void(bool)>, uint32_t timeout_ms) override;
    void ReadTrace(ReadTraceCallback) override;
    void SetOnStopCallback(std::function<void()>) override;
    void GetTraceStats(GetTraceStatsCallback) override;
    void QueryServiceState(QueryServiceStateCallback) override;
    void ChangeTraceConfig(const TraceConfig&) override;

   private:
    TracingMuxerImpl* const muxer_;
    TracingSessionGlobalID const session_id_;
    BackendType const backend_type_;
  };

  // This object is returned to API clients when they call
  // Tracing::SetupStartupTracing().
  class StartupTracingSessionImpl : public StartupTracingSession {
   public:
    StartupTracingSessionImpl(TracingMuxerImpl*,
                              TracingSessionGlobalID,
                              BackendType);
    ~StartupTracingSessionImpl() override;
    void Abort() override;
    void AbortBlocking() override;

   private:
    TracingMuxerImpl* const muxer_;
    TracingSessionGlobalID const session_id_;
    BackendType backend_type_;
  };

  struct RegisteredInterceptor {
    protos::gen::InterceptorDescriptor descriptor;
    InterceptorFactory factory{};
    InterceptorBase::TLSFactory tls_factory{};
    InterceptorBase::TracePacketCallback packet_callback{};
  };

  struct RegisteredStartupSession {
    TracingSessionID session_id = 0;
    int num_unbound_data_sources = 0;

    bool is_aborting = false;
    int num_aborting_data_sources = 0;

    std::function<void()> on_aborted;
    std::function<void()> on_adopted;
  };

  struct RegisteredProducerBackend {
    // Backends are supposed to have static lifetime.
    TracingProducerBackend* backend = nullptr;
    TracingBackendId id = 0;
    BackendType type{};

    TracingBackend::ConnectProducerArgs producer_conn_args;
    std::unique_ptr<ProducerImpl> producer;

    std::vector<RegisteredStartupSession> startup_sessions;
  };

  struct RegisteredConsumerBackend {
    // Backends are supposed to have static lifetime.
    TracingConsumerBackend* backend = nullptr;
    BackendType type{};
    // The calling code can request more than one concurrently active tracing
    // session for the same backend. We need to create one consumer per session.
    std::vector<std::unique_ptr<ConsumerImpl>> consumers;
  };

  void UpdateDataSourceOnAllBackends(RegisteredDataSource& rds,
                                     bool is_changed);
  explicit TracingMuxerImpl(const TracingInitArgs&);
  void Initialize(const TracingInitArgs& args);
  void AddBackends(const TracingInitArgs& args);
  void AddConsumerBackend(TracingConsumerBackend* backend, BackendType type);
  void AddProducerBackend(TracingProducerBackend* backend,
                          BackendType type,
                          const TracingInitArgs& args);
  ConsumerImpl* FindConsumer(TracingSessionGlobalID session_id);
  std::pair<ConsumerImpl*, RegisteredConsumerBackend*> FindConsumerAndBackend(
      TracingSessionGlobalID session_id);
  RegisteredProducerBackend* FindProducerBackendById(TracingBackendId id);
  RegisteredProducerBackend* FindProducerBackendByType(BackendType type);
  RegisteredConsumerBackend* FindConsumerBackendByType(BackendType type);
  void InitializeConsumer(TracingSessionGlobalID session_id);
  void OnConsumerDisconnected(ConsumerImpl* consumer);
  void OnProducerDisconnected(ProducerImpl* producer);
  // Test only method.
  void SweepDeadBackends();

  struct FindDataSourceRes {
    FindDataSourceRes() = default;
    FindDataSourceRes(DataSourceStaticState* a,
                      DataSourceState* b,
                      uint32_t c,
                      bool d)
        : static_state(a),
          internal_state(b),
          instance_idx(c),
          requires_callbacks_under_lock(d) {}
    explicit operator bool() const { return !!internal_state; }

    DataSourceStaticState* static_state = nullptr;
    DataSourceState* internal_state = nullptr;
    uint32_t instance_idx = 0;
    bool requires_callbacks_under_lock = false;
  };
  FindDataSourceRes FindDataSource(TracingBackendId, DataSourceInstanceID);

  FindDataSourceRes SetupDataSourceImpl(
      const RegisteredDataSource&,
      TracingBackendId,
      uint32_t backend_connection_id,
      DataSourceInstanceID,
      const DataSourceConfig&,
      TracingSessionGlobalID startup_session_id);
  void StartDataSourceImpl(const FindDataSourceRes&);
  void StopDataSource_AsyncBeginImpl(const FindDataSourceRes&);
  void StopDataSource_AsyncEnd(TracingBackendId,
                               uint32_t backend_connection_id,
                               DataSourceInstanceID,
                               const FindDataSourceRes&);
  bool FlushDataSource_AsyncBegin(TracingBackendId,
                                  DataSourceInstanceID,
                                  FlushRequestID,
                                  FlushFlags);
  void FlushDataSource_AsyncEnd(TracingBackendId,
                                uint32_t backend_connection_id,
                                DataSourceInstanceID,
                                const FindDataSourceRes&,
                                FlushRequestID);
  void AbortStartupTracingSession(TracingSessionGlobalID, BackendType);
  // When ResetForTesting() is executed, `cb` will be called on the calling
  // thread and on the muxer thread.
  void AppendResetForTestingCallback(std::function<void()> cb);

  // WARNING: If you add new state here, be sure to update ResetForTesting.
  std::unique_ptr<base::TaskRunner> task_runner_;
  std::vector<RegisteredDataSource> data_sources_;
  // These lists can only have one backend per BackendType. The elements are
  // sorted by BackendType priority (see BackendTypePriority). They always
  // contain a fake low-priority kUnspecifiedBackend at the end.
  std::list<RegisteredProducerBackend> producer_backends_;
  std::list<RegisteredConsumerBackend> consumer_backends_;
  std::vector<RegisteredInterceptor> interceptors_;
  TracingPolicy* policy_ = nullptr;

  // Learn more at TracingInitArgs::supports_multiple_data_source_instances
  bool supports_multiple_data_source_instances_ = true;

  std::atomic<TracingSessionGlobalID> next_tracing_session_id_{};
  std::atomic<uint32_t> next_data_source_index_{};
  uint32_t muxer_id_for_testing_{};

  // Maximum number of times we will try to reconnect producer backend.
  // Should only be modified for testing purposes.
  std::atomic<uint32_t> max_producer_reconnections_{100u};

  // Test only member.
  // After ResetForTesting() is called, holds tracing backends which needs to be
  // kept alive until all inbound references have gone away. See
  // SweepDeadBackends().
  std::list<RegisteredProducerBackend> dead_backends_;

  // Test only member.
  // Executes these cleanup functions on the calling thread and on the muxer
  // thread when ResetForTesting() is called.
  std::list<std::function<void()>> reset_callbacks_;

  PERFETTO_THREAD_CHECKER(thread_checker_)
};

}  // namespace internal
}  // namespace perfetto

#endif  // SRC_TRACING_INTERNAL_TRACING_MUXER_IMPL_H_
// gen_amalgamated begin header: include/perfetto/ext/tracing/core/trace_stats.h
/*
 * Copyright (C) 2017 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef INCLUDE_PERFETTO_EXT_TRACING_CORE_TRACE_STATS_H_
#define INCLUDE_PERFETTO_EXT_TRACING_CORE_TRACE_STATS_H_

// Creates the aliases in the ::perfetto namespace, doing things like:
// using ::perfetto::Foo = ::perfetto::protos::gen::Foo.
// See comments in forward_decls.h for the historical reasons of this
// indirection layer.
// gen_amalgamated expanded: #include "perfetto/tracing/core/forward_decls.h"

// gen_amalgamated expanded: #include "protos/perfetto/common/trace_stats.gen.h"

#endif  // INCLUDE_PERFETTO_EXT_TRACING_CORE_TRACE_STATS_H_
// gen_amalgamated begin header: include/perfetto/tracing/core/tracing_service_state.h
/*
 * Copyright (C) 2017 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */


#ifndef INCLUDE_PERFETTO_TRACING_CORE_TRACING_SERVICE_STATE_H_
#define INCLUDE_PERFETTO_TRACING_CORE_TRACING_SERVICE_STATE_H_

// Creates the aliases in the ::perfetto namespace, doing things like:
// using ::perfetto::Foo = ::perfetto::protos::gen::Foo.
// See comments in forward_decls.h for the historical reasons of this
// indirection layer.
// gen_amalgamated expanded: #include "perfetto/tracing/core/forward_decls.h"

// gen_amalgamated expanded: #include "protos/perfetto/common/tracing_service_state.gen.h"

#endif  // INCLUDE_PERFETTO_TRACING_CORE_TRACING_SERVICE_STATE_H_
/*
 * Copyright (C) 2019 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// gen_amalgamated expanded: #include "src/tracing/internal/tracing_muxer_impl.h"

#include <algorithm>
#include <atomic>
#include <mutex>
#include <optional>
#include <vector>

// gen_amalgamated expanded: #include "perfetto/base/build_config.h"
// gen_amalgamated expanded: #include "perfetto/base/logging.h"
// gen_amalgamated expanded: #include "perfetto/base/task_runner.h"
// gen_amalgamated expanded: #include "perfetto/base/time.h"
// gen_amalgamated expanded: #include "perfetto/ext/base/hash.h"
// gen_amalgamated expanded: #include "perfetto/ext/base/thread_checker.h"
// gen_amalgamated expanded: #include "perfetto/ext/base/waitable_event.h"
// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/shared_memory_arbiter.h"
// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/trace_packet.h"
// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/trace_stats.h"
// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/trace_writer.h"
// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/tracing_service.h"
// gen_amalgamated expanded: #include "perfetto/tracing/buffer_exhausted_policy.h"
// gen_amalgamated expanded: #include "perfetto/tracing/core/data_source_config.h"
// gen_amalgamated expanded: #include "perfetto/tracing/core/tracing_service_state.h"
// gen_amalgamated expanded: #include "perfetto/tracing/data_source.h"
// gen_amalgamated expanded: #include "perfetto/tracing/internal/data_source_internal.h"
// gen_amalgamated expanded: #include "perfetto/tracing/internal/interceptor_trace_writer.h"
// gen_amalgamated expanded: #include "perfetto/tracing/internal/tracing_backend_fake.h"
// gen_amalgamated expanded: #include "perfetto/tracing/trace_writer_base.h"
// gen_amalgamated expanded: #include "perfetto/tracing/tracing.h"
// gen_amalgamated expanded: #include "perfetto/tracing/tracing_backend.h"
// gen_amalgamated expanded: #include "src/tracing/core/null_trace_writer.h"
// gen_amalgamated expanded: #include "src/tracing/internal/tracing_muxer_fake.h"

// gen_amalgamated expanded: #include "protos/perfetto/config/interceptor_config.gen.h"

#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
#include <io.h>  // For dup()
#else
#include <unistd.h>  // For dup()
#endif

namespace perfetto {
namespace internal {

namespace {

using RegisteredDataSource = TracingMuxerImpl::RegisteredDataSource;

// A task runner which prevents calls to DataSource::Trace() while an operation
// is in progress. Used to guard against unexpected re-entrancy where the
// user-provided task runner implementation tries to enter a trace point under
// the hood.
class NonReentrantTaskRunner : public base::TaskRunner {
 public:
  NonReentrantTaskRunner(TracingMuxer* muxer,
                         std::unique_ptr<base::TaskRunner> task_runner)
      : muxer_(muxer), task_runner_(std::move(task_runner)) {}

  // base::TaskRunner implementation.
  void PostTask(std::function<void()> task) override {
    CallWithGuard([&] { task_runner_->PostTask(std::move(task)); });
  }

  void PostDelayedTask(std::function<void()> task, uint32_t delay_ms) override {
    CallWithGuard(
        [&] { task_runner_->PostDelayedTask(std::move(task), delay_ms); });
  }

  void AddFileDescriptorWatch(base::PlatformHandle fd,
                              std::function<void()> callback) override {
    CallWithGuard(
        [&] { task_runner_->AddFileDescriptorWatch(fd, std::move(callback)); });
  }

  void RemoveFileDescriptorWatch(base::PlatformHandle fd) override {
    CallWithGuard([&] { task_runner_->RemoveFileDescriptorWatch(fd); });
  }

  bool RunsTasksOnCurrentThread() const override {
    bool result;
    CallWithGuard([&] { result = task_runner_->RunsTasksOnCurrentThread(); });
    return result;
  }

 private:
  template <typename T>
  void CallWithGuard(T lambda) const {
    auto* root_tls = muxer_->GetOrCreateTracingTLS();
    if (PERFETTO_UNLIKELY(root_tls->is_in_trace_point)) {
      lambda();
      return;
    }
    ScopedReentrancyAnnotator scoped_annotator(*root_tls);
    lambda();
  }

  TracingMuxer* const muxer_;
  std::unique_ptr<base::TaskRunner> task_runner_;
};

class StopArgsImpl : public DataSourceBase::StopArgs {
 public:
  std::function<void()> HandleStopAsynchronously() const override {
    auto closure = std::move(async_stop_closure);
    async_stop_closure = std::function<void()>();
    return closure;
  }

  mutable std::function<void()> async_stop_closure;
};

class FlushArgsImpl : public DataSourceBase::FlushArgs {
 public:
  std::function<void()> HandleFlushAsynchronously() const override {
    auto closure = std::move(async_flush_closure);
    async_flush_closure = std::function<void()>();
    return closure;
  }

  mutable std::function<void()> async_flush_closure;
};

// Holds an earlier TracingMuxerImpl instance after ResetForTesting() is called.
static TracingMuxerImpl* g_prev_instance{};

template <typename RegisteredBackend>
struct CompareBackendByType {
  static int BackendTypePriority(BackendType type) {
    switch (type) {
      case kSystemBackend:
        return 0;
      case kInProcessBackend:
        return 1;
      case kCustomBackend:
        return 2;
      // The UnspecifiedBackend has the highest priority so that
      // TracingBackendFake is the last one on the backend lists.
      case kUnspecifiedBackend:
        break;
    }
    return 3;
  }
  bool operator()(BackendType type, const RegisteredBackend& b) {
    return BackendTypePriority(type) < BackendTypePriority(b.type);
  }
};

}  // namespace

// ----- Begin of TracingMuxerImpl::ProducerImpl
TracingMuxerImpl::ProducerImpl::ProducerImpl(
    TracingMuxerImpl* muxer,
    TracingBackendId backend_id,
    uint32_t shmem_batch_commits_duration_ms,
    bool shmem_direct_patching_enabled)
    : muxer_(muxer),
      backend_id_(backend_id),
      shmem_batch_commits_duration_ms_(shmem_batch_commits_duration_ms),
      shmem_direct_patching_enabled_(shmem_direct_patching_enabled) {}

TracingMuxerImpl::ProducerImpl::~ProducerImpl() {
  muxer_ = nullptr;
}

void TracingMuxerImpl::ProducerImpl::Initialize(
    std::unique_ptr<ProducerEndpoint> endpoint) {
  PERFETTO_DCHECK_THREAD(thread_checker_);
  PERFETTO_DCHECK(!connected_);
  connection_id_.fetch_add(1, std::memory_order_relaxed);
  is_producer_provided_smb_ = endpoint->shared_memory();
  last_startup_target_buffer_reservation_ = 0;

  // Adopt the endpoint into a shared pointer so that we can safely share it
  // across threads that create trace writers. The custom deleter function
  // ensures that the endpoint is always destroyed on the muxer's thread. (Note
  // that |task_runner| is assumed to outlive tracing sessions on all threads.)
  auto* task_runner = muxer_->task_runner_.get();
  auto deleter = [task_runner](ProducerEndpoint* e) {
    if (task_runner->RunsTasksOnCurrentThread()) {
      delete e;
      return;
    }
    task_runner->PostTask([e] { delete e; });
  };
  std::shared_ptr<ProducerEndpoint> service(endpoint.release(), deleter);
  // This atomic store is needed because another thread might be concurrently
  // creating a trace writer using the previous (disconnected) |service_|. See
  // CreateTraceWriter().
  std::atomic_store(&service_, std::move(service));
  // Don't try to use the service here since it may not have connected yet. See
  // OnConnect().
}

void TracingMuxerImpl::ProducerImpl::OnConnect() {
  PERFETTO_DLOG("Producer connected");
  PERFETTO_DCHECK_THREAD(thread_checker_);
  PERFETTO_DCHECK(!connected_);
  if (is_producer_provided_smb_ && !service_->IsShmemProvidedByProducer()) {
    PERFETTO_ELOG(
        "The service likely doesn't support producer-provided SMBs. Preventing "
        "future attempts to use producer-provided SMB again with this "
        "backend.");
    producer_provided_smb_failed_ = true;
    // Will call OnDisconnect() and cause a reconnect without producer-provided
    // SMB.
    service_->Disconnect();
    return;
  }
  connected_ = true;
  muxer_->UpdateDataSourcesOnAllBackends();
  SendOnConnectTriggers();
}

void TracingMuxerImpl::ProducerImpl::OnDisconnect() {
  PERFETTO_DCHECK_THREAD(thread_checker_);
  // If we're being destroyed, bail out.
  if (!muxer_)
    return;
  connected_ = false;
  // Active data sources for this producer will be stopped by
  // DestroyStoppedTraceWritersForCurrentThread() since the reconnected producer
  // will have a different connection id (even before it has finished
  // connecting).
  registered_data_sources_.reset();
  DisposeConnection();

  // Try reconnecting the producer.
  muxer_->OnProducerDisconnected(this);
}

void TracingMuxerImpl::ProducerImpl::DisposeConnection() {
  // Keep the old service around as a dead connection in case it has active
  // trace writers. If any tracing sessions were created, we can't clear
  // |service_| here because other threads may be concurrently creating new
  // trace writers. Any reconnection attempt will atomically swap the new
  // service in place of the old one.
  if (did_setup_tracing_ || did_setup_startup_tracing_) {
    dead_services_.push_back(service_);
  } else {
    service_.reset();
  }
}

void TracingMuxerImpl::ProducerImpl::OnTracingSetup() {
  PERFETTO_DCHECK_THREAD(thread_checker_);
  did_setup_tracing_ = true;
  service_->MaybeSharedMemoryArbiter()->SetBatchCommitsDuration(
      shmem_batch_commits_duration_ms_);
  if (shmem_direct_patching_enabled_) {
    service_->MaybeSharedMemoryArbiter()->EnableDirectSMBPatching();
  }
}

void TracingMuxerImpl::ProducerImpl::OnStartupTracingSetup() {
  PERFETTO_DCHECK_THREAD(thread_checker_);
  did_setup_startup_tracing_ = true;
}

void TracingMuxerImpl::ProducerImpl::SetupDataSource(
    DataSourceInstanceID id,
    const DataSourceConfig& cfg) {
  PERFETTO_DCHECK_THREAD(thread_checker_);
  if (!muxer_)
    return;
  muxer_->SetupDataSource(
      backend_id_, connection_id_.load(std::memory_order_relaxed), id, cfg);
}

void TracingMuxerImpl::ProducerImpl::StartDataSource(DataSourceInstanceID id,
                                                     const DataSourceConfig&) {
  PERFETTO_DCHECK_THREAD(thread_checker_);
  if (!muxer_)
    return;
  muxer_->StartDataSource(backend_id_, id);
  service_->NotifyDataSourceStarted(id);
}

void TracingMuxerImpl::ProducerImpl::StopDataSource(DataSourceInstanceID id) {
  PERFETTO_DCHECK_THREAD(thread_checker_);
  if (!muxer_)
    return;
  muxer_->StopDataSource_AsyncBegin(backend_id_, id);
}

void TracingMuxerImpl::ProducerImpl::Flush(
    FlushRequestID flush_id,
    const DataSourceInstanceID* instances,
    size_t instance_count,
    FlushFlags flush_flags) {
  PERFETTO_DCHECK_THREAD(thread_checker_);
  bool all_handled = true;
  if (muxer_) {
    for (size_t i = 0; i < instance_count; i++) {
      DataSourceInstanceID ds_id = instances[i];
      bool handled = muxer_->FlushDataSource_AsyncBegin(backend_id_, ds_id,
                                                        flush_id, flush_flags);
      if (!handled) {
        pending_flushes_[flush_id].insert(ds_id);
        all_handled = false;
      }
    }
  }

  if (all_handled) {
    service_->NotifyFlushComplete(flush_id);
  }
}

void TracingMuxerImpl::ProducerImpl::ClearIncrementalState(
    const DataSourceInstanceID* instances,
    size_t instance_count) {
  PERFETTO_DCHECK_THREAD(thread_checker_);
  if (!muxer_)
    return;
  for (size_t inst_idx = 0; inst_idx < instance_count; inst_idx++) {
    muxer_->ClearDataSourceIncrementalState(backend_id_, instances[inst_idx]);
  }
}

bool TracingMuxerImpl::ProducerImpl::SweepDeadServices() {
  PERFETTO_DCHECK_THREAD(thread_checker_);
  auto is_unused = [](const std::shared_ptr<ProducerEndpoint>& endpoint) {
    auto* arbiter = endpoint->MaybeSharedMemoryArbiter();
    return !arbiter || arbiter->TryShutdown();
  };
  for (auto it = dead_services_.begin(); it != dead_services_.end();) {
    auto next_it = it;
    next_it++;
    if (is_unused(*it)) {
      dead_services_.erase(it);
    }
    it = next_it;
  }
  return dead_services_.empty();
}

void TracingMuxerImpl::ProducerImpl::SendOnConnectTriggers() {
  PERFETTO_DCHECK_THREAD(thread_checker_);
  base::TimeMillis now = base::GetWallTimeMs();
  std::vector<std::string> triggers;
  while (!on_connect_triggers_.empty()) {
    // Skip if we passed TTL.
    if (on_connect_triggers_.front().second > now) {
      triggers.push_back(std::move(on_connect_triggers_.front().first));
    }
    on_connect_triggers_.pop_front();
  }
  if (!triggers.empty()) {
    service_->ActivateTriggers(triggers);
  }
}

void TracingMuxerImpl::ProducerImpl::NotifyFlushForDataSourceDone(
    DataSourceInstanceID ds_id,
    FlushRequestID flush_id) {
  if (!connected_) {
    return;
  }

  {
    auto it = pending_flushes_.find(flush_id);
    if (it == pending_flushes_.end()) {
      return;
    }
    std::set<DataSourceInstanceID>& ds_ids = it->second;
    ds_ids.erase(ds_id);
  }

  std::optional<DataSourceInstanceID> biggest_flush_id;
  for (auto it = pending_flushes_.begin(); it != pending_flushes_.end();) {
    if (it->second.empty()) {
      biggest_flush_id = it->first;
      it = pending_flushes_.erase(it);
    } else {
      break;
    }
  }

  if (biggest_flush_id) {
    service_->NotifyFlushComplete(*biggest_flush_id);
  }
}

// ----- End of TracingMuxerImpl::ProducerImpl methods.

// ----- Begin of TracingMuxerImpl::ConsumerImpl
TracingMuxerImpl::ConsumerImpl::ConsumerImpl(TracingMuxerImpl* muxer,
                                             BackendType backend_type,
                                             TracingSessionGlobalID session_id)
    : muxer_(muxer), backend_type_(backend_type), session_id_(session_id) {}

TracingMuxerImpl::ConsumerImpl::~ConsumerImpl() {
  muxer_ = nullptr;
}

void TracingMuxerImpl::ConsumerImpl::Initialize(
    std::unique_ptr<ConsumerEndpoint> endpoint) {
  PERFETTO_DCHECK_THREAD(thread_checker_);
  service_ = std::move(endpoint);
  // Don't try to use the service here since it may not have connected yet. See
  // OnConnect().
}

void TracingMuxerImpl::ConsumerImpl::OnConnect() {
  PERFETTO_DCHECK_THREAD(thread_checker_);
  PERFETTO_DCHECK(!connected_);
  connected_ = true;

  // Observe data source instance events so we get notified when tracing starts.
  service_->ObserveEvents(ObservableEvents::TYPE_DATA_SOURCES_INSTANCES |
                          ObservableEvents::TYPE_ALL_DATA_SOURCES_STARTED);

  // If the API client configured and started tracing before we connected,
  // tell the backend about it now.
  if (trace_config_)
    muxer_->SetupTracingSession(session_id_, trace_config_);
  if (start_pending_)
    muxer_->StartTracingSession(session_id_);
  if (get_trace_stats_pending_) {
    auto callback = std::move(get_trace_stats_callback_);
    get_trace_stats_callback_ = nullptr;
    muxer_->GetTraceStats(session_id_, std::move(callback));
  }
  if (query_service_state_callback_) {
    auto callback = std::move(query_service_state_callback_);
    query_service_state_callback_ = nullptr;
    muxer_->QueryServiceState(session_id_, std::move(callback));
  }
  if (stop_pending_)
    muxer_->StopTracingSession(session_id_);
}

void TracingMuxerImpl::ConsumerImpl::OnDisconnect() {
  PERFETTO_DCHECK_THREAD(thread_checker_);
  // If we're being destroyed, bail out.
  if (!muxer_)
    return;
#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
  if (!connected_ && backend_type_ == kSystemBackend) {
    PERFETTO_ELOG(
        "Unable to connect to the system tracing service as a consumer. On "
        "Android, use the \"perfetto\" command line tool instead to start "
        "system-wide tracing sessions");
  }
#endif  // PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)

  // Notify the client about disconnection.
  NotifyError(TracingError{TracingError::kDisconnected, "Peer disconnected"});

  // Make sure the client doesn't hang in a blocking start/stop because of the
  // disconnection.
  NotifyStartComplete();
  NotifyStopComplete();

  // It shouldn't be necessary to call StopTracingSession. If we get this call
  // it means that the service did shutdown before us, so there is no point
  // trying it to ask it to stop the session. We should just remember to cleanup
  // the consumer vector.
  connected_ = false;

  // Notify the muxer that it is safe to destroy |this|. This is needed because
  // the ConsumerEndpoint stored in |service_| requires that |this| be safe to
  // access until OnDisconnect() is called.
  muxer_->OnConsumerDisconnected(this);
}

void TracingMuxerImpl::ConsumerImpl::Disconnect() {
  // This is weird and deserves a comment.
  //
  // When we called the ConnectConsumer method on the service it returns
  // us a ConsumerEndpoint which we stored in |service_|, however this
  // ConsumerEndpoint holds a pointer to the ConsumerImpl pointed to by
  // |this|. Part of the API contract to TracingService::ConnectConsumer is that
  // the ConsumerImpl pointer has to be valid until the
  // ConsumerImpl::OnDisconnect method is called. Therefore we reset the
  // ConsumerEndpoint |service_|. Eventually this will call
  // ConsumerImpl::OnDisconnect and we will inform the muxer it is safe to
  // call the destructor of |this|.
  service_.reset();
}

void TracingMuxerImpl::ConsumerImpl::OnTracingDisabled(
    const std::string& error) {
  PERFETTO_DCHECK_THREAD(thread_checker_);
  PERFETTO_DCHECK(!stopped_);
  stopped_ = true;

  if (!error.empty())
    NotifyError(TracingError{TracingError::kTracingFailed, error});

  // If we're still waiting for the start event, fire it now. This may happen if
  // there are no active data sources in the session.
  NotifyStartComplete();
  NotifyStopComplete();
}

void TracingMuxerImpl::ConsumerImpl::NotifyStartComplete() {
  PERFETTO_DCHECK_THREAD(thread_checker_);
  if (start_complete_callback_) {
    muxer_->task_runner_->PostTask(std::move(start_complete_callback_));
    start_complete_callback_ = nullptr;
  }
  if (blocking_start_complete_callback_) {
    muxer_->task_runner_->PostTask(
        std::move(blocking_start_complete_callback_));
    blocking_start_complete_callback_ = nullptr;
  }
}

void TracingMuxerImpl::ConsumerImpl::NotifyError(const TracingError& error) {
  PERFETTO_DCHECK_THREAD(thread_checker_);
  if (error_callback_) {
    muxer_->task_runner_->PostTask(
        std::bind(std::move(error_callback_), error));
  }
}

void TracingMuxerImpl::ConsumerImpl::NotifyStopComplete() {
  PERFETTO_DCHECK_THREAD(thread_checker_);
  if (stop_complete_callback_) {
    muxer_->task_runner_->PostTask(std::move(stop_complete_callback_));
    stop_complete_callback_ = nullptr;
  }
  if (blocking_stop_complete_callback_) {
    muxer_->task_runner_->PostTask(std::move(blocking_stop_complete_callback_));
    blocking_stop_complete_callback_ = nullptr;
  }
}

void TracingMuxerImpl::ConsumerImpl::OnTraceData(
    std::vector<TracePacket> packets,
    bool has_more) {
  PERFETTO_DCHECK_THREAD(thread_checker_);
  if (!read_trace_callback_)
    return;

  size_t capacity = 0;
  for (const auto& packet : packets) {
    // 16 is an over-estimation of the proto preamble size
    capacity += packet.size() + 16;
  }

  // The shared_ptr is to avoid making a copy of the buffer when PostTask-ing.
  std::shared_ptr<std::vector<char>> buf(new std::vector<char>());
  buf->reserve(capacity);
  for (auto& packet : packets) {
    char* start;
    size_t size;
    std::tie(start, size) = packet.GetProtoPreamble();
    buf->insert(buf->end(), start, start + size);
    for (auto& slice : packet.slices()) {
      const auto* slice_data = reinterpret_cast<const char*>(slice.start);
      buf->insert(buf->end(), slice_data, slice_data + slice.size);
    }
  }

  auto callback = read_trace_callback_;
  muxer_->task_runner_->PostTask([callback, buf, has_more] {
    TracingSession::ReadTraceCallbackArgs callback_arg{};
    callback_arg.data = buf->empty() ? nullptr : &(*buf)[0];
    callback_arg.size = buf->size();
    callback_arg.has_more = has_more;
    callback(callback_arg);
  });

  if (!has_more)
    read_trace_callback_ = nullptr;
}

void TracingMuxerImpl::ConsumerImpl::OnObservableEvents(
    const ObservableEvents& events) {
  if (events.instance_state_changes_size()) {
    for (const auto& state_change : events.instance_state_changes()) {
      DataSourceHandle handle{state_change.producer_name(),
                              state_change.data_source_name()};
      data_source_states_[handle] =
          state_change.state() ==
          ObservableEvents::DATA_SOURCE_INSTANCE_STATE_STARTED;
    }
  }

  if (events.instance_state_changes_size() ||
      events.all_data_sources_started()) {
    // Data sources are first reported as being stopped before starting, so once
    // all the data sources we know about have started we can declare tracing
    // begun. In the case where there are no matching data sources for the
    // session, the service will report the all_data_sources_started() event
    // without adding any instances (only since Android S / Perfetto v10.0).
    if (start_complete_callback_ || blocking_start_complete_callback_) {
      bool all_data_sources_started = std::all_of(
          data_source_states_.cbegin(), data_source_states_.cend(),
          [](std::pair<DataSourceHandle, bool> state) { return state.second; });
      if (all_data_sources_started)
        NotifyStartComplete();
    }
  }
}

void TracingMuxerImpl::ConsumerImpl::OnSessionCloned(
    const OnSessionClonedArgs&) {
  // CloneSession is not exposed in the SDK. This should never happen.
  PERFETTO_DCHECK(false);
}

void TracingMuxerImpl::ConsumerImpl::OnTraceStats(
    bool success,
    const TraceStats& trace_stats) {
  if (!get_trace_stats_callback_)
    return;
  TracingSession::GetTraceStatsCallbackArgs callback_arg{};
  callback_arg.success = success;
  callback_arg.trace_stats_data = trace_stats.SerializeAsArray();
  muxer_->task_runner_->PostTask(
      std::bind(std::move(get_trace_stats_callback_), std::move(callback_arg)));
  get_trace_stats_callback_ = nullptr;
}

// The callbacks below are not used.
void TracingMuxerImpl::ConsumerImpl::OnDetach(bool) {}
void TracingMuxerImpl::ConsumerImpl::OnAttach(bool, const TraceConfig&) {}
// ----- End of TracingMuxerImpl::ConsumerImpl

// ----- Begin of TracingMuxerImpl::TracingSessionImpl

// TracingSessionImpl is the RAII object returned to API clients when they
// invoke Tracing::CreateTracingSession. They use it for starting/stopping
// tracing.

TracingMuxerImpl::TracingSessionImpl::TracingSessionImpl(
    TracingMuxerImpl* muxer,
    TracingSessionGlobalID session_id,
    BackendType backend_type)
    : muxer_(muxer), session_id_(session_id), backend_type_(backend_type) {}

// Can be destroyed from any thread.
TracingMuxerImpl::TracingSessionImpl::~TracingSessionImpl() {
  auto* muxer = muxer_;
  auto session_id = session_id_;
  muxer->task_runner_->PostTask(
      [muxer, session_id] { muxer->DestroyTracingSession(session_id); });
}

// Can be called from any thread.
void TracingMuxerImpl::TracingSessionImpl::Setup(const TraceConfig& cfg,
                                                 int fd) {
  auto* muxer = muxer_;
  auto session_id = session_id_;
  std::shared_ptr<TraceConfig> trace_config(new TraceConfig(cfg));
  if (fd >= 0) {
    base::ignore_result(backend_type_);  // For -Wunused in the amalgamation.
#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
    if (backend_type_ != kInProcessBackend) {
      PERFETTO_FATAL(
          "Passing a file descriptor to TracingSession::Setup() is only "
          "supported with the kInProcessBackend on Windows. Use "
          "TracingSession::ReadTrace() instead");
    }
#endif
    trace_config->set_write_into_file(true);
    fd = dup(fd);
  }
  muxer->task_runner_->PostTask([muxer, session_id, trace_config, fd] {
    muxer->SetupTracingSession(session_id, trace_config, base::ScopedFile(fd));
  });
}

// Can be called from any thread.
void TracingMuxerImpl::TracingSessionImpl::Start() {
  auto* muxer = muxer_;
  auto session_id = session_id_;
  muxer->task_runner_->PostTask(
      [muxer, session_id] { muxer->StartTracingSession(session_id); });
}

// Can be called from any thread.
void TracingMuxerImpl::TracingSessionImpl::ChangeTraceConfig(
    const TraceConfig& cfg) {
  auto* muxer = muxer_;
  auto session_id = session_id_;
  muxer->task_runner_->PostTask([muxer, session_id, cfg] {
    muxer->ChangeTracingSessionConfig(session_id, cfg);
  });
}

// Can be called from any thread except the service thread.
void TracingMuxerImpl::TracingSessionImpl::StartBlocking() {
  PERFETTO_DCHECK(!muxer_->task_runner_->RunsTasksOnCurrentThread());
  auto* muxer = muxer_;
  auto session_id = session_id_;
  base::WaitableEvent tracing_started;
  muxer->task_runner_->PostTask([muxer, session_id, &tracing_started] {
    auto* consumer = muxer->FindConsumer(session_id);
    if (!consumer) {
      // TODO(skyostil): Signal an error to the user.
      tracing_started.Notify();
      return;
    }
    PERFETTO_DCHECK(!consumer->blocking_start_complete_callback_);
    consumer->blocking_start_complete_callback_ = [&] {
      tracing_started.Notify();
    };
    muxer->StartTracingSession(session_id);
  });
  tracing_started.Wait();
}

// Can be called from any thread.
void TracingMuxerImpl::TracingSessionImpl::Flush(
    std::function<void(bool)> user_callback,
    uint32_t timeout_ms) {
  auto* muxer = muxer_;
  auto session_id = session_id_;
  muxer->task_runner_->PostTask([muxer, session_id, timeout_ms, user_callback] {
    auto* consumer = muxer->FindConsumer(session_id);
    if (!consumer) {
      std::move(user_callback)(false);
      return;
    }
    muxer->FlushTracingSession(session_id, timeout_ms,
                               std::move(user_callback));
  });
}

// Can be called from any thread.
void TracingMuxerImpl::TracingSessionImpl::Stop() {
  auto* muxer = muxer_;
  auto session_id = session_id_;
  muxer->task_runner_->PostTask(
      [muxer, session_id] { muxer->StopTracingSession(session_id); });
}

// Can be called from any thread except the service thread.
void TracingMuxerImpl::TracingSessionImpl::StopBlocking() {
  PERFETTO_DCHECK(!muxer_->task_runner_->RunsTasksOnCurrentThread());
  auto* muxer = muxer_;
  auto session_id = session_id_;
  base::WaitableEvent tracing_stopped;
  muxer->task_runner_->PostTask([muxer, session_id, &tracing_stopped] {
    auto* consumer = muxer->FindConsumer(session_id);
    if (!consumer) {
      // TODO(skyostil): Signal an error to the user.
      tracing_stopped.Notify();
      return;
    }
    PERFETTO_DCHECK(!consumer->blocking_stop_complete_callback_);
    consumer->blocking_stop_complete_callback_ = [&] {
      tracing_stopped.Notify();
    };
    muxer->StopTracingSession(session_id);
  });
  tracing_stopped.Wait();
}

// Can be called from any thread.
void TracingMuxerImpl::TracingSessionImpl::ReadTrace(ReadTraceCallback cb) {
  auto* muxer = muxer_;
  auto session_id = session_id_;
  muxer->task_runner_->PostTask([muxer, session_id, cb] {
    muxer->ReadTracingSessionData(session_id, std::move(cb));
  });
}

// Can be called from any thread.
void TracingMuxerImpl::TracingSessionImpl::SetOnStartCallback(
    std::function<void()> cb) {
  auto* muxer = muxer_;
  auto session_id = session_id_;
  muxer->task_runner_->PostTask([muxer, session_id, cb] {
    auto* consumer = muxer->FindConsumer(session_id);
    if (!consumer)
      return;
    consumer->start_complete_callback_ = cb;
  });
}

// Can be called from any thread
void TracingMuxerImpl::TracingSessionImpl::SetOnErrorCallback(
    std::function<void(TracingError)> cb) {
  auto* muxer = muxer_;
  auto session_id = session_id_;
  muxer->task_runner_->PostTask([muxer, session_id, cb] {
    auto* consumer = muxer->FindConsumer(session_id);
    if (!consumer) {
      // Notify the client about concurrent disconnection of the session.
      if (cb)
        cb(TracingError{TracingError::kDisconnected, "Peer disconnected"});
      return;
    }
    consumer->error_callback_ = cb;
  });
}

// Can be called from any thread.
void TracingMuxerImpl::TracingSessionImpl::SetOnStopCallback(
    std::function<void()> cb) {
  auto* muxer = muxer_;
  auto session_id = session_id_;
  muxer->task_runner_->PostTask([muxer, session_id, cb] {
    auto* consumer = muxer->FindConsumer(session_id);
    if (!consumer)
      return;
    consumer->stop_complete_callback_ = cb;
  });
}

// Can be called from any thread.
void TracingMuxerImpl::TracingSessionImpl::GetTraceStats(
    GetTraceStatsCallback cb) {
  auto* muxer = muxer_;
  auto session_id = session_id_;
  muxer->task_runner_->PostTask([muxer, session_id, cb] {
    muxer->GetTraceStats(session_id, std::move(cb));
  });
}

// Can be called from any thread.
void TracingMuxerImpl::TracingSessionImpl::QueryServiceState(
    QueryServiceStateCallback cb) {
  auto* muxer = muxer_;
  auto session_id = session_id_;
  muxer->task_runner_->PostTask([muxer, session_id, cb] {
    muxer->QueryServiceState(session_id, std::move(cb));
  });
}

// ----- End of TracingMuxerImpl::TracingSessionImpl

// ----- Begin of TracingMuxerImpl::StartupTracingSessionImpl

TracingMuxerImpl::StartupTracingSessionImpl::StartupTracingSessionImpl(
    TracingMuxerImpl* muxer,
    TracingSessionGlobalID session_id,
    BackendType backend_type)
    : muxer_(muxer), session_id_(session_id), backend_type_(backend_type) {}

// Can be destroyed from any thread.
TracingMuxerImpl::StartupTracingSessionImpl::~StartupTracingSessionImpl() =
    default;

void TracingMuxerImpl::StartupTracingSessionImpl::Abort() {
  auto* muxer = muxer_;
  auto session_id = session_id_;
  auto backend_type = backend_type_;
  muxer->task_runner_->PostTask([muxer, session_id, backend_type] {
    muxer->AbortStartupTracingSession(session_id, backend_type);
  });
}

// Must not be called from the SDK's internal thread.
void TracingMuxerImpl::StartupTracingSessionImpl::AbortBlocking() {
  auto* muxer = muxer_;
  auto session_id = session_id_;
  auto backend_type = backend_type_;
  PERFETTO_CHECK(!muxer->task_runner_->RunsTasksOnCurrentThread());
  base::WaitableEvent event;
  muxer->task_runner_->PostTask([muxer, session_id, backend_type, &event] {
    muxer->AbortStartupTracingSession(session_id, backend_type);
    event.Notify();
  });
  event.Wait();
}

// ----- End of TracingMuxerImpl::StartupTracingSessionImpl

// static
TracingMuxer* TracingMuxer::instance_ = TracingMuxerFake::Get();

// This is called by perfetto::Tracing::Initialize().
// Can be called on any thread. Typically, but not necessarily, that will be
// the embedder's main thread.
TracingMuxerImpl::TracingMuxerImpl(const TracingInitArgs& args)
    : TracingMuxer(args.platform ? args.platform
                                 : Platform::GetDefaultPlatform()) {
  PERFETTO_DETACH_FROM_THREAD(thread_checker_);
  instance_ = this;

  // Create the thread where muxer, producers and service will live.
  Platform::CreateTaskRunnerArgs tr_args{/*name_for_debugging=*/"TracingMuxer"};
  task_runner_.reset(new NonReentrantTaskRunner(
      this, platform_->CreateTaskRunner(std::move(tr_args))));

  // Run the initializer on that thread.
  task_runner_->PostTask([this, args] {
    Initialize(args);
    AddBackends(args);
  });
}

void TracingMuxerImpl::Initialize(const TracingInitArgs& args) {
  PERFETTO_DCHECK_THREAD(thread_checker_);  // Rebind the thread checker.

  policy_ = args.tracing_policy;
  supports_multiple_data_source_instances_ =
      args.supports_multiple_data_source_instances;

  // Fallback backend for producer creation for an unsupported backend type.
  PERFETTO_CHECK(producer_backends_.empty());
  AddProducerBackend(internal::TracingBackendFake::GetInstance(),
                     BackendType::kUnspecifiedBackend, args);
  // Fallback backend for consumer creation for an unsupported backend type.
  // This backend simply fails any attempt to start a tracing session.
  PERFETTO_CHECK(consumer_backends_.empty());
  AddConsumerBackend(internal::TracingBackendFake::GetInstance(),
                     BackendType::kUnspecifiedBackend);
}

void TracingMuxerImpl::AddConsumerBackend(TracingConsumerBackend* backend,
                                          BackendType type) {
  if (!backend) {
    // We skip the log in release builds because the *_backend_fake.cc code
    // has already an ELOG before returning a nullptr.
    PERFETTO_DLOG("Consumer backend creation failed, type %d",
                  static_cast<int>(type));
    return;
  }
  // Keep the backends sorted by type.
  auto it =
      std::upper_bound(consumer_backends_.begin(), consumer_backends_.end(),
                       type, CompareBackendByType<RegisteredConsumerBackend>());
  it = consumer_backends_.emplace(it);

  RegisteredConsumerBackend& rb = *it;
  rb.backend = backend;
  rb.type = type;
}

void TracingMuxerImpl::AddProducerBackend(TracingProducerBackend* backend,
                                          BackendType type,
                                          const TracingInitArgs& args) {
  if (!backend) {
    // We skip the log in release builds because the *_backend_fake.cc code
    // has already an ELOG before returning a nullptr.
    PERFETTO_DLOG("Producer backend creation failed, type %d",
                  static_cast<int>(type));
    return;
  }
  TracingBackendId backend_id = producer_backends_.size();
  // Keep the backends sorted by type.
  auto it =
      std::upper_bound(producer_backends_.begin(), producer_backends_.end(),
                       type, CompareBackendByType<RegisteredProducerBackend>());
  it = producer_backends_.emplace(it);

  RegisteredProducerBackend& rb = *it;
  rb.backend = backend;
  rb.id = backend_id;
  rb.type = type;
  rb.producer.reset(new ProducerImpl(this, backend_id,
                                     args.shmem_batch_commits_duration_ms,
                                     args.shmem_direct_patching_enabled));
  rb.producer_conn_args.producer = rb.producer.get();
  rb.producer_conn_args.producer_name = platform_->GetCurrentProcessName();
  rb.producer_conn_args.task_runner = task_runner_.get();
  rb.producer_conn_args.shmem_size_hint_bytes = args.shmem_size_hint_kb * 1024;
  rb.producer_conn_args.shmem_page_size_hint_bytes =
      args.shmem_page_size_hint_kb * 1024;
  rb.producer_conn_args.create_socket_async = args.create_socket_async;
  rb.producer->Initialize(rb.backend->ConnectProducer(rb.producer_conn_args));
}

TracingMuxerImpl::RegisteredProducerBackend*
TracingMuxerImpl::FindProducerBackendById(TracingBackendId id) {
  for (RegisteredProducerBackend& b : producer_backends_) {
    if (b.id == id) {
      return &b;
    }
  }
  return nullptr;
}

TracingMuxerImpl::RegisteredProducerBackend*
TracingMuxerImpl::FindProducerBackendByType(BackendType type) {
  for (RegisteredProducerBackend& b : producer_backends_) {
    if (b.type == type) {
      return &b;
    }
  }
  return nullptr;
}

TracingMuxerImpl::RegisteredConsumerBackend*
TracingMuxerImpl::FindConsumerBackendByType(BackendType type) {
  for (RegisteredConsumerBackend& b : consumer_backends_) {
    if (b.type == type) {
      return &b;
    }
  }
  return nullptr;
}

void TracingMuxerImpl::AddBackends(const TracingInitArgs& args) {
  if (args.backends & kSystemBackend) {
    PERFETTO_CHECK(args.system_producer_backend_factory_);
    if (FindProducerBackendByType(kSystemBackend) == nullptr) {
      AddProducerBackend(args.system_producer_backend_factory_(),
                         kSystemBackend, args);
    }
    if (args.enable_system_consumer) {
      PERFETTO_CHECK(args.system_consumer_backend_factory_);
      if (FindConsumerBackendByType(kSystemBackend) == nullptr) {
        AddConsumerBackend(args.system_consumer_backend_factory_(),
                           kSystemBackend);
      }
    }
  }

  if (args.backends & kInProcessBackend) {
    TracingBackend* b = nullptr;
    if (FindProducerBackendByType(kInProcessBackend) == nullptr) {
      if (!b) {
        PERFETTO_CHECK(args.in_process_backend_factory_);
        b = args.in_process_backend_factory_();
      }
      AddProducerBackend(b, kInProcessBackend, args);
    }
    if (FindConsumerBackendByType(kInProcessBackend) == nullptr) {
      if (!b) {
        PERFETTO_CHECK(args.in_process_backend_factory_);
        b = args.in_process_backend_factory_();
      }
      AddConsumerBackend(b, kInProcessBackend);
    }
  }

  if (args.backends & kCustomBackend) {
    PERFETTO_CHECK(args.custom_backend);
    if (FindProducerBackendByType(kCustomBackend) == nullptr) {
      AddProducerBackend(args.custom_backend, kCustomBackend, args);
    }
    if (FindConsumerBackendByType(kCustomBackend) == nullptr) {
      AddConsumerBackend(args.custom_backend, kCustomBackend);
    }
  }

  if (args.backends & ~(kSystemBackend | kInProcessBackend | kCustomBackend)) {
    PERFETTO_FATAL("Unsupported tracing backend type");
  }
}

// Can be called from any thread (but not concurrently).
bool TracingMuxerImpl::RegisterDataSource(
    const DataSourceDescriptor& descriptor,
    DataSourceFactory factory,
    DataSourceParams params,
    bool no_flush,
    DataSourceStaticState* static_state) {
  // Ignore repeated registrations.
  if (static_state->index != kMaxDataSources)
    return true;

  uint32_t new_index = next_data_source_index_++;
  if (new_index >= kMaxDataSources) {
    PERFETTO_DLOG(
        "RegisterDataSource failed: too many data sources already registered");
    return false;
  }

  // Initialize the static state.
  static_assert(sizeof(static_state->instances[0]) >= sizeof(DataSourceState),
                "instances[] size mismatch");
  for (size_t i = 0; i < static_state->instances.size(); i++)
    new (&static_state->instances[i]) DataSourceState{};

  static_state->index = new_index;

  // Generate a semi-unique id for this data source.
  base::Hasher hash;
  hash.Update(reinterpret_cast<intptr_t>(static_state));
  hash.Update(base::GetWallTimeNs().count());
  static_state->id = hash.digest() ? hash.digest() : 1;

  task_runner_->PostTask([this, descriptor, factory, static_state, params,
                          no_flush] {
    data_sources_.emplace_back();
    RegisteredDataSource& rds = data_sources_.back();
    rds.descriptor = descriptor;
    rds.factory = factory;
    rds.supports_multiple_instances =
        supports_multiple_data_source_instances_ &&
        params.supports_multiple_instances;
    rds.requires_callbacks_under_lock = params.requires_callbacks_under_lock;
    rds.static_state = static_state;
    rds.no_flush = no_flush;

    UpdateDataSourceOnAllBackends(rds, /*is_changed=*/false);
  });
  return true;
}

// Can be called from any thread (but not concurrently).
void TracingMuxerImpl::UpdateDataSourceDescriptor(
    const DataSourceDescriptor& descriptor,
    const DataSourceStaticState* static_state) {
  task_runner_->PostTask([this, descriptor, static_state] {
    for (auto& rds : data_sources_) {
      if (rds.static_state == static_state) {
        PERFETTO_CHECK(rds.descriptor.name() == descriptor.name());
        rds.descriptor = descriptor;
        rds.descriptor.set_id(static_state->id);
        UpdateDataSourceOnAllBackends(rds, /*is_changed=*/true);
        return;
      }
    }
  });
}

// Can be called from any thread (but not concurrently).
void TracingMuxerImpl::RegisterInterceptor(
    const InterceptorDescriptor& descriptor,
    InterceptorFactory factory,
    InterceptorBase::TLSFactory tls_factory,
    InterceptorBase::TracePacketCallback packet_callback) {
  task_runner_->PostTask([this, descriptor, factory, tls_factory,
                          packet_callback] {
    // Ignore repeated registrations.
    for (const auto& interceptor : interceptors_) {
      if (interceptor.descriptor.name() == descriptor.name()) {
        PERFETTO_DCHECK(interceptor.tls_factory == tls_factory);
        PERFETTO_DCHECK(interceptor.packet_callback == packet_callback);
        return;
      }
    }
    // Only allow certain interceptors for now.
    if (descriptor.name() != "test_interceptor" &&
        descriptor.name() != "console" && descriptor.name() != "etwexport") {
      PERFETTO_ELOG(
          "Interceptors are experimental. If you want to use them, please "
          "get in touch with the project maintainers "
          "(https://perfetto.dev/docs/contributing/"
          "getting-started#community).");
      return;
    }
    interceptors_.emplace_back();
    RegisteredInterceptor& interceptor = interceptors_.back();
    interceptor.descriptor = descriptor;
    interceptor.factory = factory;
    interceptor.tls_factory = tls_factory;
    interceptor.packet_callback = packet_callback;
  });
}

void TracingMuxerImpl::ActivateTriggers(
    const std::vector<std::string>& triggers,
    uint32_t ttl_ms) {
  base::TimeMillis expire_time =
      base::GetWallTimeMs() + base::TimeMillis(ttl_ms);
  task_runner_->PostTask([this, triggers, expire_time] {
    for (RegisteredProducerBackend& backend : producer_backends_) {
      if (backend.producer->connected_) {
        backend.producer->service_->ActivateTriggers(triggers);
      } else {
        for (const std::string& trigger : triggers) {
          backend.producer->on_connect_triggers_.emplace_back(trigger,
                                                              expire_time);
        }
      }
    }
  });
}

// Checks if there is any matching startup tracing data source instance for a
// new SetupDataSource call. If so, moves the data source to this tracing
// session (and its target buffer) and returns true, otherwise returns false.
static bool MaybeAdoptStartupTracingInDataSource(
    TracingBackendId backend_id,
    uint32_t backend_connection_id,
    DataSourceInstanceID instance_id,
    const DataSourceConfig& cfg,
    const std::vector<RegisteredDataSource>& data_sources) {
  for (const auto& rds : data_sources) {
    DataSourceStaticState* static_state = rds.static_state;
    for (uint32_t i = 0; i < kMaxDataSourceInstances; i++) {
      auto* internal_state = static_state->TryGet(i);

      if (internal_state &&
          internal_state->startup_target_buffer_reservation.load(
              std::memory_order_relaxed) &&
          internal_state->data_source_instance_id == 0 &&
          internal_state->backend_id == backend_id &&
          internal_state->backend_connection_id == backend_connection_id &&
          internal_state->config &&
          internal_state->data_source->CanAdoptStartupSession(
              *internal_state->config, cfg)) {
        PERFETTO_DLOG("Setting up data source %" PRIu64
                      " %s by adopting it from a startup tracing session",
                      instance_id, cfg.name().c_str());

        std::lock_guard<std::recursive_mutex> lock(internal_state->lock);
        // Set the associations. The actual takeover happens in
        // StartDataSource().
        internal_state->data_source_instance_id = instance_id;
        internal_state->buffer_id =
            static_cast<internal::BufferId>(cfg.target_buffer());
        internal_state->config.reset(new DataSourceConfig(cfg));

        // TODO(eseckler): Should the data souce config provided by the service
        // be allowed to specify additional interceptors / additional data
        // source params?

        return true;
      }
    }
  }
  return false;
}

// Called by the service of one of the backends.
void TracingMuxerImpl::SetupDataSource(TracingBackendId backend_id,
                                       uint32_t backend_connection_id,
                                       DataSourceInstanceID instance_id,
                                       const DataSourceConfig& cfg) {
  PERFETTO_DLOG("Setting up data source %" PRIu64 " %s", instance_id,
                cfg.name().c_str());
  PERFETTO_DCHECK_THREAD(thread_checker_);

  // First check if there is any matching startup tracing data source instance.
  if (MaybeAdoptStartupTracingInDataSource(backend_id, backend_connection_id,
                                           instance_id, cfg, data_sources_)) {
    return;
  }

  for (const auto& rds : data_sources_) {
    if (rds.descriptor.name() != cfg.name())
      continue;
    DataSourceStaticState& static_state = *rds.static_state;

    // If this data source is already active for this exact config, don't start
    // another instance. This happens when we have several data sources with the
    // same name, in which case the service sends one SetupDataSource event for
    // each one. Since we can't map which event maps to which data source, we
    // ensure each event only starts one data source instance.
    // TODO(skyostil): Register a unique id with each data source to the service
    // to disambiguate.
    bool active_for_config = false;
    for (uint32_t i = 0; i < kMaxDataSourceInstances; i++) {
      if (!static_state.TryGet(i))
        continue;
      auto* internal_state =
          reinterpret_cast<DataSourceState*>(&static_state.instances[i]);
      if (internal_state->backend_id == backend_id &&
          internal_state->backend_connection_id == backend_connection_id &&
          internal_state->config && *internal_state->config == cfg) {
        active_for_config = true;
        break;
      }
    }
    if (active_for_config) {
      PERFETTO_DLOG(
          "Data source %s is already active with this config, skipping",
          cfg.name().c_str());
      continue;
    }

    SetupDataSourceImpl(rds, backend_id, backend_connection_id, instance_id,
                        cfg, /*startup_session_id=*/0);
    return;
  }
}

TracingMuxerImpl::FindDataSourceRes TracingMuxerImpl::SetupDataSourceImpl(
    const RegisteredDataSource& rds,
    TracingBackendId backend_id,
    uint32_t backend_connection_id,
    DataSourceInstanceID instance_id,
    const DataSourceConfig& cfg,
    TracingSessionGlobalID startup_session_id) {
  PERFETTO_DCHECK_THREAD(thread_checker_);
  DataSourceStaticState& static_state = *rds.static_state;

  // If any bit is set in `static_state.valid_instances` then at least one
  // other instance of data source is running.
  if (!rds.supports_multiple_instances &&
      static_state.valid_instances.load(std::memory_order_acquire) != 0) {
    PERFETTO_ELOG(
        "Failed to setup data source because some another instance of this "
        "data source is already active");
    return FindDataSourceRes();
  }

  for (uint32_t i = 0; i < kMaxDataSourceInstances; i++) {
    // Find a free slot.
    if (static_state.TryGet(i))
      continue;

    auto* internal_state =
        reinterpret_cast<DataSourceState*>(&static_state.instances[i]);
    std::unique_lock<std::recursive_mutex> lock(internal_state->lock);
    static_assert(
        std::is_same<decltype(internal_state->data_source_instance_id),
                     DataSourceInstanceID>::value,
        "data_source_instance_id type mismatch");
    internal_state->muxer_id_for_testing = muxer_id_for_testing_;
    RegisteredProducerBackend& backend = *FindProducerBackendById(backend_id);

    if (startup_session_id) {
      uint16_t& last_reservation =
          backend.producer->last_startup_target_buffer_reservation_;
      if (last_reservation == std::numeric_limits<uint16_t>::max()) {
        PERFETTO_ELOG(
            "Startup buffer reservations exhausted, dropping data source");
        return FindDataSourceRes();
      }
      internal_state->startup_target_buffer_reservation.store(
          ++last_reservation, std::memory_order_relaxed);
    } else {
      internal_state->startup_target_buffer_reservation.store(
          0, std::memory_order_relaxed);
    }

    internal_state->backend_id = backend_id;
    internal_state->backend_connection_id = backend_connection_id;
    internal_state->data_source_instance_id = instance_id;
    internal_state->buffer_id =
        static_cast<internal::BufferId>(cfg.target_buffer());
    internal_state->config.reset(new DataSourceConfig(cfg));
    internal_state->startup_session_id = startup_session_id;
    internal_state->data_source = rds.factory();
    internal_state->interceptor = nullptr;
    internal_state->interceptor_id = 0;

    if (cfg.has_interceptor_config()) {
      for (size_t j = 0; j < interceptors_.size(); j++) {
        if (cfg.interceptor_config().name() ==
            interceptors_[j].descriptor.name()) {
          PERFETTO_DLOG("Intercepting data source %" PRIu64
                        " \"%s\" into \"%s\"",
                        instance_id, cfg.name().c_str(),
                        cfg.interceptor_config().name().c_str());
          internal_state->interceptor_id = static_cast<uint32_t>(j + 1);
          internal_state->interceptor = interceptors_[j].factory();
          internal_state->interceptor->OnSetup({cfg});
          break;
        }
      }
      if (!internal_state->interceptor_id) {
        PERFETTO_ELOG("Unknown interceptor configured for data source: %s",
                      cfg.interceptor_config().name().c_str());
      }
    }

    // This must be made at the end. See matching acquire-load in
    // DataSource::Trace().
    static_state.valid_instances.fetch_or(1 << i, std::memory_order_release);

    DataSourceBase::SetupArgs setup_args;
    setup_args.config = &cfg;
    setup_args.backend_type = backend.type;
    setup_args.internal_instance_index = i;

    if (!rds.requires_callbacks_under_lock)
      lock.unlock();
    internal_state->data_source->OnSetup(setup_args);

    return FindDataSourceRes(&static_state, internal_state, i,
                             rds.requires_callbacks_under_lock);
  }
  PERFETTO_ELOG(
      "Maximum number of data source instances exhausted. "
      "Dropping data source %" PRIu64,
      instance_id);
  return FindDataSourceRes();
}

// Called by the service of one of the backends.
void TracingMuxerImpl::StartDataSource(TracingBackendId backend_id,
                                       DataSourceInstanceID instance_id) {
  PERFETTO_DLOG("Starting data source %" PRIu64, instance_id);
  PERFETTO_DCHECK_THREAD(thread_checker_);

  auto ds = FindDataSource(backend_id, instance_id);
  if (!ds) {
    PERFETTO_ELOG("Could not find data source to start");
    return;
  }

  // Check if the data source was already started for startup tracing.
  uint16_t startup_reservation =
      ds.internal_state->startup_target_buffer_reservation.load(
          std::memory_order_relaxed);
  if (startup_reservation) {
    RegisteredProducerBackend& backend = *FindProducerBackendById(backend_id);
    TracingSessionGlobalID session_id = ds.internal_state->startup_session_id;
    auto session_it = std::find_if(
        backend.startup_sessions.begin(), backend.startup_sessions.end(),
        [session_id](const RegisteredStartupSession& session) {
          return session.session_id == session_id;
        });
    PERFETTO_DCHECK(session_it != backend.startup_sessions.end());

    if (session_it->is_aborting) {
      PERFETTO_DLOG("Data source %" PRIu64
                    " was already aborted for startup tracing, not starting it",
                    instance_id);
      return;
    }

    PERFETTO_DLOG(
        "Data source %" PRIu64
        " was already started for startup tracing, binding its target buffer",
        instance_id);

    backend.producer->service_->MaybeSharedMemoryArbiter()
        ->BindStartupTargetBuffer(startup_reservation,
                                  ds.internal_state->buffer_id);

    // The reservation ID can be used even after binding it, so there's no need
    // for any barriers here - we just need atomicity.
    ds.internal_state->startup_target_buffer_reservation.store(
        0, std::memory_order_relaxed);

    // TODO(eseckler): Should we reset incremental state at this point, or
    // notify the data source some other way?

    // The session should not have been fully bound yet (or aborted).
    PERFETTO_DCHECK(session_it->num_unbound_data_sources > 0);

    session_it->num_unbound_data_sources--;
    if (session_it->num_unbound_data_sources == 0) {
      if (session_it->on_adopted)
        task_runner_->PostTask(session_it->on_adopted);
      backend.startup_sessions.erase(session_it);
    }
    return;
  }

  StartDataSourceImpl(ds);
}

void TracingMuxerImpl::StartDataSourceImpl(const FindDataSourceRes& ds) {
  PERFETTO_DCHECK_THREAD(thread_checker_);

  DataSourceBase::StartArgs start_args{};
  start_args.internal_instance_index = ds.instance_idx;

  std::unique_lock<std::recursive_mutex> lock(ds.internal_state->lock);
  if (ds.internal_state->interceptor)
    ds.internal_state->interceptor->OnStart({});
  ds.internal_state->trace_lambda_enabled.store(true,
                                                std::memory_order_relaxed);
  PERFETTO_DCHECK(ds.internal_state->data_source != nullptr);

  if (!ds.requires_callbacks_under_lock)
    lock.unlock();
  ds.internal_state->data_source->OnStart(start_args);
}

// Called by the service of one of the backends.
void TracingMuxerImpl::StopDataSource_AsyncBegin(
    TracingBackendId backend_id,
    DataSourceInstanceID instance_id) {
  PERFETTO_DLOG("Stopping data source %" PRIu64, instance_id);
  PERFETTO_DCHECK_THREAD(thread_checker_);

  auto ds = FindDataSource(backend_id, instance_id);
  if (!ds) {
    PERFETTO_ELOG("Could not find data source to stop");
    return;
  }

  StopDataSource_AsyncBeginImpl(ds);
}

void TracingMuxerImpl::StopDataSource_AsyncBeginImpl(
    const FindDataSourceRes& ds) {
  TracingBackendId backend_id = ds.internal_state->backend_id;
  uint32_t backend_connection_id = ds.internal_state->backend_connection_id;
  DataSourceInstanceID instance_id = ds.internal_state->data_source_instance_id;

  StopArgsImpl stop_args{};
  stop_args.internal_instance_index = ds.instance_idx;
  stop_args.async_stop_closure = [this, backend_id, backend_connection_id,
                                  instance_id, ds] {
    // TracingMuxerImpl is long lived, capturing |this| is okay.
    // The notification closure can be moved out of the StopArgs by the
    // embedder to handle stop asynchronously. The embedder might then
    // call the closure on a different thread than the current one, hence
    // this nested PostTask().
    task_runner_->PostTask(
        [this, backend_id, backend_connection_id, instance_id, ds] {
          StopDataSource_AsyncEnd(backend_id, backend_connection_id,
                                  instance_id, ds);
        });
  };

  {
    std::unique_lock<std::recursive_mutex> lock(ds.internal_state->lock);

    // Don't call OnStop again if the datasource is already stopping.
    if (ds.internal_state->async_stop_in_progress)
      return;
    ds.internal_state->async_stop_in_progress = true;

    if (ds.internal_state->interceptor)
      ds.internal_state->interceptor->OnStop({});

    if (!ds.requires_callbacks_under_lock)
      lock.unlock();
    ds.internal_state->data_source->OnStop(stop_args);
  }

  // If the embedder hasn't called StopArgs.HandleStopAsynchronously() run the
  // async closure here. In theory we could avoid the PostTask and call
  // straight into CompleteDataSourceAsyncStop(). We keep that to reduce
  // divergencies between the deferred-stop vs non-deferred-stop code paths.
  if (stop_args.async_stop_closure)
    std::move(stop_args.async_stop_closure)();
}

void TracingMuxerImpl::StopDataSource_AsyncEnd(TracingBackendId backend_id,
                                               uint32_t backend_connection_id,
                                               DataSourceInstanceID instance_id,
                                               const FindDataSourceRes& ds) {
  PERFETTO_DLOG("Ending async stop of data source %" PRIu64, instance_id);
  PERFETTO_DCHECK_THREAD(thread_checker_);

  // Check that the data source instance is still active and was not modified
  // while it was being stopped.
  if (!ds.static_state->TryGet(ds.instance_idx) ||
      ds.internal_state->backend_id != backend_id ||
      ds.internal_state->backend_connection_id != backend_connection_id ||
      ds.internal_state->data_source_instance_id != instance_id) {
    PERFETTO_ELOG(
        "Async stop of data source %" PRIu64
        " failed. This might be due to calling the async_stop_closure twice.",
        instance_id);
    return;
  }

  const uint32_t mask = ~(1 << ds.instance_idx);
  ds.static_state->valid_instances.fetch_and(mask, std::memory_order_acq_rel);

  // Take the mutex to prevent that the data source is in the middle of
  // a Trace() execution where it called GetDataSourceLocked() while we
  // destroy it.
  uint16_t startup_buffer_reservation;
  TracingSessionGlobalID startup_session_id;
  {
    std::lock_guard<std::recursive_mutex> guard(ds.internal_state->lock);
    ds.internal_state->trace_lambda_enabled.store(false,
                                                  std::memory_order_relaxed);
    ds.internal_state->data_source.reset();
    ds.internal_state->interceptor.reset();
    ds.internal_state->config.reset();
    ds.internal_state->async_stop_in_progress = false;
    startup_buffer_reservation =
        ds.internal_state->startup_target_buffer_reservation.load(
            std::memory_order_relaxed);
    startup_session_id = ds.internal_state->startup_session_id;
  }

  // The other fields of internal_state are deliberately *not* cleared.
  // See races-related comments of DataSource::Trace().

  TracingMuxer::generation_++;

  // |producer_backends_| is append-only, Backend instances are always valid.
  PERFETTO_CHECK(backend_id < producer_backends_.size());
  RegisteredProducerBackend& backend = *FindProducerBackendById(backend_id);
  ProducerImpl* producer = backend.producer.get();
  if (!producer)
    return;

  // If the data source instance still has a startup buffer reservation, it was
  // only active for startup tracing and never started by the service. Discard
  // the startup buffer reservation.
  if (startup_buffer_reservation) {
    PERFETTO_DCHECK(startup_session_id);

    if (producer->service_ && producer->service_->MaybeSharedMemoryArbiter()) {
      producer->service_->MaybeSharedMemoryArbiter()
          ->AbortStartupTracingForReservation(startup_buffer_reservation);
    }

    auto session_it = std::find_if(
        backend.startup_sessions.begin(), backend.startup_sessions.end(),
        [startup_session_id](const RegisteredStartupSession& session) {
          return session.session_id == startup_session_id;
        });

    // Session should not be removed until abortion of all data source instances
    // is complete.
    PERFETTO_DCHECK(session_it != backend.startup_sessions.end());

    session_it->num_aborting_data_sources--;
    if (session_it->num_aborting_data_sources == 0) {
      if (session_it->on_aborted)
        task_runner_->PostTask(session_it->on_aborted);

      backend.startup_sessions.erase(session_it);
    }
  }

  if (producer->connected_ &&
      backend.producer->connection_id_.load(std::memory_order_relaxed) ==
          backend_connection_id) {
    // Flush any commits that might have been batched by SharedMemoryArbiter.
    producer->service_->MaybeSharedMemoryArbiter()
        ->FlushPendingCommitDataRequests();
    if (instance_id)
      producer->service_->NotifyDataSourceStopped(instance_id);
  }
  producer->SweepDeadServices();
}

void TracingMuxerImpl::ClearDataSourceIncrementalState(
    TracingBackendId backend_id,
    DataSourceInstanceID instance_id) {
  PERFETTO_DCHECK_THREAD(thread_checker_);
  PERFETTO_DLOG("Clearing incremental state for data source %" PRIu64,
                instance_id);
  auto ds = FindDataSource(backend_id, instance_id);
  if (!ds) {
    PERFETTO_ELOG("Could not find data source to clear incremental state for");
    return;
  }

  DataSourceBase::ClearIncrementalStateArgs clear_incremental_state_args;
  clear_incremental_state_args.internal_instance_index = ds.instance_idx;
  {
    std::unique_lock<std::recursive_mutex> lock;
    if (ds.requires_callbacks_under_lock)
      lock = std::unique_lock<std::recursive_mutex>(ds.internal_state->lock);
    ds.internal_state->data_source->WillClearIncrementalState(
        clear_incremental_state_args);
  }

  // Make DataSource::TraceContext::GetIncrementalState() eventually notice that
  // the incremental state should be cleared.
  ds.static_state->incremental_state_generation.fetch_add(
      1, std::memory_order_relaxed);
}

bool TracingMuxerImpl::FlushDataSource_AsyncBegin(
    TracingBackendId backend_id,
    DataSourceInstanceID instance_id,
    FlushRequestID flush_id,
    FlushFlags flush_flags) {
  PERFETTO_DLOG("Flushing data source %" PRIu64, instance_id);
  auto ds = FindDataSource(backend_id, instance_id);
  if (!ds) {
    PERFETTO_ELOG("Could not find data source to flush");
    return true;
  }

  uint32_t backend_connection_id = ds.internal_state->backend_connection_id;

  FlushArgsImpl flush_args;
  flush_args.flush_flags = flush_flags;
  flush_args.internal_instance_index = ds.instance_idx;
  flush_args.async_flush_closure = [this, backend_id, backend_connection_id,
                                    instance_id, ds, flush_id] {
    // TracingMuxerImpl is long lived, capturing |this| is okay.
    // The notification closure can be moved out of the StopArgs by the
    // embedder to handle stop asynchronously. The embedder might then
    // call the closure on a different thread than the current one, hence
    // this nested PostTask().
    task_runner_->PostTask(
        [this, backend_id, backend_connection_id, instance_id, ds, flush_id] {
          FlushDataSource_AsyncEnd(backend_id, backend_connection_id,
                                   instance_id, ds, flush_id);
        });
  };
  {
    std::unique_lock<std::recursive_mutex> lock;
    if (ds.requires_callbacks_under_lock)
      lock = std::unique_lock<std::recursive_mutex>(ds.internal_state->lock);
    ds.internal_state->data_source->OnFlush(flush_args);
  }

  // |async_flush_closure| is moved out of |flush_args| if the producer
  // requested to handle the flush asynchronously.
  bool handled = static_cast<bool>(flush_args.async_flush_closure);
  return handled;
}

void TracingMuxerImpl::FlushDataSource_AsyncEnd(
    TracingBackendId backend_id,
    uint32_t backend_connection_id,
    DataSourceInstanceID instance_id,
    const FindDataSourceRes& ds,
    FlushRequestID flush_id) {
  PERFETTO_DLOG("Ending async flush of data source %" PRIu64, instance_id);
  PERFETTO_DCHECK_THREAD(thread_checker_);

  // Check that the data source instance is still active and was not modified
  // while it was being flushed.
  if (!ds.static_state->TryGet(ds.instance_idx) ||
      ds.internal_state->backend_id != backend_id ||
      ds.internal_state->backend_connection_id != backend_connection_id ||
      ds.internal_state->data_source_instance_id != instance_id) {
    PERFETTO_ELOG("Async flush of data source %" PRIu64
                  " failed. This might be due to the data source being stopped "
                  "in the meantime",
                  instance_id);
    return;
  }

  // |producer_backends_| is append-only, Backend instances are always valid.
  PERFETTO_CHECK(backend_id < producer_backends_.size());
  RegisteredProducerBackend& backend = *FindProducerBackendById(backend_id);

  ProducerImpl* producer = backend.producer.get();
  if (!producer)
    return;

  // If the tracing service disconnects and reconnects while a data source is
  // handling a flush request, there's no point is sending the flush reply to
  // the newly reconnected producer.
  if (producer->connected_ &&
      backend.producer->connection_id_.load(std::memory_order_relaxed) ==
          backend_connection_id) {
    producer->NotifyFlushForDataSourceDone(instance_id, flush_id);
  }
}

void TracingMuxerImpl::SyncProducersForTesting() {
  std::mutex mutex;
  std::condition_variable cv;

  // IPC-based producers don't report connection errors explicitly for each
  // command, but instead with an asynchronous callback
  // (ProducerImpl::OnDisconnected). This means that the sync command below
  // may have completed but failed to reach the service because of a
  // disconnection, but we can't tell until the disconnection message comes
  // through. To guard against this, we run two whole rounds of sync round-trips
  // before returning; the first one will detect any disconnected producers and
  // the second one will ensure any reconnections have completed and all data
  // sources are registered in the service again.
  for (size_t i = 0; i < 2; i++) {
    size_t countdown = std::numeric_limits<size_t>::max();
    task_runner_->PostTask([this, &mutex, &cv, &countdown] {
      {
        std::unique_lock<std::mutex> countdown_lock(mutex);
        countdown = producer_backends_.size();
      }
      for (auto& backend : producer_backends_) {
        auto* producer = backend.producer.get();
        producer->service_->Sync([&mutex, &cv, &countdown] {
          std::unique_lock<std::mutex> countdown_lock(mutex);
          countdown--;
          cv.notify_one();
        });
      }
    });

    {
      std::unique_lock<std::mutex> countdown_lock(mutex);
      cv.wait(countdown_lock, [&countdown] { return !countdown; });
    }
  }

  // Check that all producers are indeed connected.
  bool done = false;
  bool all_producers_connected = true;
  task_runner_->PostTask([this, &mutex, &cv, &done, &all_producers_connected] {
    for (auto& backend : producer_backends_)
      all_producers_connected &= backend.producer->connected_;
    std::unique_lock<std::mutex> lock(mutex);
    done = true;
    cv.notify_one();
  });

  {
    std::unique_lock<std::mutex> lock(mutex);
    cv.wait(lock, [&done] { return done; });
  }
  PERFETTO_DCHECK(all_producers_connected);
}

void TracingMuxerImpl::DestroyStoppedTraceWritersForCurrentThread() {
  // Iterate across all possible data source types.
  auto cur_generation = generation_.load(std::memory_order_acquire);
  auto* root_tls = GetOrCreateTracingTLS();

  auto destroy_stopped_instances = [](DataSourceThreadLocalState& tls) {
    // |tls| has a vector of per-data-source-instance thread-local state.
    DataSourceStaticState* static_state = tls.static_state;
    if (!static_state)
      return;  // Slot not used.

    // Iterate across all possible instances for this data source.
    for (uint32_t inst = 0; inst < kMaxDataSourceInstances; inst++) {
      DataSourceInstanceThreadLocalState& ds_tls = tls.per_instance[inst];
      if (!ds_tls.trace_writer)
        continue;

      DataSourceState* ds_state = static_state->TryGet(inst);
      if (ds_state &&
          ds_state->muxer_id_for_testing == ds_tls.muxer_id_for_testing &&
          ds_state->backend_id == ds_tls.backend_id &&
          ds_state->backend_connection_id == ds_tls.backend_connection_id &&
          ds_state->startup_target_buffer_reservation.load(
              std::memory_order_relaxed) ==
              ds_tls.startup_target_buffer_reservation &&
          ds_state->buffer_id == ds_tls.buffer_id &&
          ds_state->data_source_instance_id == ds_tls.data_source_instance_id) {
        continue;
      }

      // The DataSource instance has been destroyed or recycled.
      ds_tls.Reset();  // Will also destroy the |ds_tls.trace_writer|.
    }
  };

  for (size_t ds_idx = 0; ds_idx < kMaxDataSources; ds_idx++) {
    // |tls| has a vector of per-data-source-instance thread-local state.
    DataSourceThreadLocalState& tls = root_tls->data_sources_tls[ds_idx];
    destroy_stopped_instances(tls);
  }
  destroy_stopped_instances(root_tls->track_event_tls);
  root_tls->generation = cur_generation;
}

// Called both when a new data source is registered or when a new backend
// connects. In both cases we want to be sure we reflected the data source
// registrations on the backends.
void TracingMuxerImpl::UpdateDataSourcesOnAllBackends() {
  PERFETTO_DCHECK_THREAD(thread_checker_);
  for (RegisteredDataSource& rds : data_sources_) {
    UpdateDataSourceOnAllBackends(rds, /*is_changed=*/false);
  }
}

void TracingMuxerImpl::UpdateDataSourceOnAllBackends(RegisteredDataSource& rds,
                                                     bool is_changed) {
  PERFETTO_DCHECK_THREAD(thread_checker_);
  for (RegisteredProducerBackend& backend : producer_backends_) {
    // We cannot call RegisterDataSource on the backend before it connects.
    if (!backend.producer->connected_)
      continue;

    PERFETTO_DCHECK(rds.static_state->index < kMaxDataSources);
    bool is_registered = backend.producer->registered_data_sources_.test(
        rds.static_state->index);
    if (is_registered && !is_changed)
      continue;

    if (!rds.descriptor.no_flush()) {
      rds.descriptor.set_no_flush(rds.no_flush);
    }
    rds.descriptor.set_will_notify_on_start(true);
    rds.descriptor.set_will_notify_on_stop(true);
    rds.descriptor.set_handles_incremental_state_clear(true);
    rds.descriptor.set_id(rds.static_state->id);
    if (is_registered) {
      backend.producer->service_->UpdateDataSource(rds.descriptor);
    } else {
      backend.producer->service_->RegisterDataSource(rds.descriptor);
    }
    backend.producer->registered_data_sources_.set(rds.static_state->index);
  }
}

void TracingMuxerImpl::SetupTracingSession(
    TracingSessionGlobalID session_id,
    const std::shared_ptr<TraceConfig>& trace_config,
    base::ScopedFile trace_fd) {
  PERFETTO_DCHECK_THREAD(thread_checker_);
  PERFETTO_CHECK(!trace_fd || trace_config->write_into_file());

  auto* consumer = FindConsumer(session_id);
  if (!consumer)
    return;

  consumer->trace_config_ = trace_config;
  if (trace_fd)
    consumer->trace_fd_ = std::move(trace_fd);

  if (!consumer->connected_)
    return;

  // Only used in the deferred start mode.
  if (trace_config->deferred_start()) {
    consumer->service_->EnableTracing(*trace_config,
                                      std::move(consumer->trace_fd_));
  }
}

void TracingMuxerImpl::StartTracingSession(TracingSessionGlobalID session_id) {
  PERFETTO_DCHECK_THREAD(thread_checker_);

  auto* consumer = FindConsumer(session_id);

  if (!consumer)
    return;

  if (!consumer->trace_config_) {
    PERFETTO_ELOG("Must call Setup(config) first");
    return;
  }

  if (!consumer->connected_) {
    consumer->start_pending_ = true;
    return;
  }

  consumer->start_pending_ = false;
  if (consumer->trace_config_->deferred_start()) {
    consumer->service_->StartTracing();
  } else {
    consumer->service_->EnableTracing(*consumer->trace_config_,
                                      std::move(consumer->trace_fd_));
  }

  // TODO implement support for the deferred-start + fast-triggering case.
}

void TracingMuxerImpl::ChangeTracingSessionConfig(
    TracingSessionGlobalID session_id,
    const TraceConfig& trace_config) {
  PERFETTO_DCHECK_THREAD(thread_checker_);

  auto* consumer = FindConsumer(session_id);

  if (!consumer)
    return;

  if (!consumer->trace_config_) {
    // Changing the config is only supported for started sessions.
    PERFETTO_ELOG("Must call Setup(config) and Start() first");
    return;
  }

  consumer->trace_config_ = std::make_shared<TraceConfig>(trace_config);
  if (consumer->connected_)
    consumer->service_->ChangeTraceConfig(trace_config);
}

void TracingMuxerImpl::FlushTracingSession(TracingSessionGlobalID session_id,
                                           uint32_t timeout_ms,
                                           std::function<void(bool)> callback) {
  PERFETTO_DCHECK_THREAD(thread_checker_);
  auto* consumer = FindConsumer(session_id);
  if (!consumer || consumer->start_pending_ || consumer->stop_pending_ ||
      !consumer->trace_config_) {
    PERFETTO_ELOG("Flush() can be called only after Start() and before Stop()");
    std::move(callback)(false);
    return;
  }

  // For now we don't want to expose the flush reason to the consumer-side SDK
  // users to avoid misuses until there is a strong need.
  consumer->service_->Flush(timeout_ms, std::move(callback),
                            FlushFlags(FlushFlags::Initiator::kConsumerSdk,
                                       FlushFlags::Reason::kExplicit));
}

void TracingMuxerImpl::StopTracingSession(TracingSessionGlobalID session_id) {
  PERFETTO_DCHECK_THREAD(thread_checker_);
  auto* consumer = FindConsumer(session_id);
  if (!consumer)
    return;

  if (consumer->start_pending_) {
    // If the session hasn't started yet, wait until it does before stopping.
    consumer->stop_pending_ = true;
    return;
  }

  consumer->stop_pending_ = false;
  if (consumer->stopped_) {
    // If the session was already stopped (e.g., it failed to start), don't try
    // stopping again.
    consumer->NotifyStopComplete();
  } else if (!consumer->trace_config_) {
    PERFETTO_ELOG("Must call Setup(config) and Start() first");
    return;
  } else {
    consumer->service_->DisableTracing();
  }

  consumer->trace_config_.reset();
}

void TracingMuxerImpl::DestroyTracingSession(
    TracingSessionGlobalID session_id) {
  PERFETTO_DCHECK_THREAD(thread_checker_);
  for (RegisteredConsumerBackend& backend : consumer_backends_) {
    // We need to find the consumer (if any) and call Disconnect as we destroy
    // the tracing session. We can't call Disconnect() inside this for loop
    // because in the in-process case this will end up to a synchronous call to
    // OnConsumerDisconnect which will invalidate all the iterators to
    // |backend.consumers|.
    ConsumerImpl* consumer = nullptr;
    for (auto& con : backend.consumers) {
      if (con->session_id_ == session_id) {
        consumer = con.get();
        break;
      }
    }
    if (consumer) {
      // We broke out of the loop above on the assumption that each backend will
      // only have a single consumer per session. This DCHECK ensures that
      // this is the case.
      PERFETTO_DCHECK(
          std::count_if(backend.consumers.begin(), backend.consumers.end(),
                        [session_id](const std::unique_ptr<ConsumerImpl>& con) {
                          return con->session_id_ == session_id;
                        }) == 1u);
      consumer->Disconnect();
    }
  }
}

void TracingMuxerImpl::ReadTracingSessionData(
    TracingSessionGlobalID session_id,
    std::function<void(TracingSession::ReadTraceCallbackArgs)> callback) {
  PERFETTO_DCHECK_THREAD(thread_checker_);
  auto* consumer = FindConsumer(session_id);
  if (!consumer) {
    // TODO(skyostil): Signal an error to the user.
    TracingSession::ReadTraceCallbackArgs callback_arg{};
    callback(callback_arg);
    return;
  }
  PERFETTO_DCHECK(!consumer->read_trace_callback_);
  consumer->read_trace_callback_ = std::move(callback);
  consumer->service_->ReadBuffers();
}

void TracingMuxerImpl::GetTraceStats(
    TracingSessionGlobalID session_id,
    TracingSession::GetTraceStatsCallback callback) {
  PERFETTO_DCHECK_THREAD(thread_checker_);
  auto* consumer = FindConsumer(session_id);
  if (!consumer) {
    TracingSession::GetTraceStatsCallbackArgs callback_arg{};
    callback_arg.success = false;
    callback(std::move(callback_arg));
    return;
  }
  PERFETTO_DCHECK(!consumer->get_trace_stats_callback_);
  consumer->get_trace_stats_callback_ = std::move(callback);
  if (!consumer->connected_) {
    consumer->get_trace_stats_pending_ = true;
    return;
  }
  consumer->get_trace_stats_pending_ = false;
  consumer->service_->GetTraceStats();
}

void TracingMuxerImpl::QueryServiceState(
    TracingSessionGlobalID session_id,
    TracingSession::QueryServiceStateCallback callback) {
  PERFETTO_DCHECK_THREAD(thread_checker_);
  auto* consumer = FindConsumer(session_id);
  if (!consumer) {
    TracingSession::QueryServiceStateCallbackArgs callback_arg{};
    callback_arg.success = false;
    callback(std::move(callback_arg));
    return;
  }
  PERFETTO_DCHECK(!consumer->query_service_state_callback_);
  if (!consumer->connected_) {
    consumer->query_service_state_callback_ = std::move(callback);
    return;
  }
  auto callback_wrapper = [callback](bool success,
                                     protos::gen::TracingServiceState state) {
    TracingSession::QueryServiceStateCallbackArgs callback_arg{};
    callback_arg.success = success;
    callback_arg.service_state_data = state.SerializeAsArray();
    callback(std::move(callback_arg));
  };
  consumer->service_->QueryServiceState({}, std::move(callback_wrapper));
}

void TracingMuxerImpl::SetBatchCommitsDurationForTesting(
    uint32_t batch_commits_duration_ms,
    BackendType backend_type) {
  for (RegisteredProducerBackend& backend : producer_backends_) {
    if (backend.producer && backend.producer->connected_ &&
        backend.type == backend_type) {
      backend.producer->service_->MaybeSharedMemoryArbiter()
          ->SetBatchCommitsDuration(batch_commits_duration_ms);
    }
  }
}

bool TracingMuxerImpl::EnableDirectSMBPatchingForTesting(
    BackendType backend_type) {
  for (RegisteredProducerBackend& backend : producer_backends_) {
    if (backend.producer && backend.producer->connected_ &&
        backend.type == backend_type &&
        !backend.producer->service_->MaybeSharedMemoryArbiter()
             ->EnableDirectSMBPatching()) {
      return false;
    }
  }
  return true;
}

TracingMuxerImpl::ConsumerImpl* TracingMuxerImpl::FindConsumer(
    TracingSessionGlobalID session_id) {
  PERFETTO_DCHECK_THREAD(thread_checker_);
  return FindConsumerAndBackend(session_id).first;
}

std::pair<TracingMuxerImpl::ConsumerImpl*,
          TracingMuxerImpl::RegisteredConsumerBackend*>
TracingMuxerImpl::FindConsumerAndBackend(TracingSessionGlobalID session_id) {
  PERFETTO_DCHECK_THREAD(thread_checker_);
  for (RegisteredConsumerBackend& backend : consumer_backends_) {
    for (auto& consumer : backend.consumers) {
      if (consumer->session_id_ == session_id) {
        return {consumer.get(), &backend};
      }
    }
  }
  return {nullptr, nullptr};
}

void TracingMuxerImpl::InitializeConsumer(TracingSessionGlobalID session_id) {
  PERFETTO_DCHECK_THREAD(thread_checker_);

  auto res = FindConsumerAndBackend(session_id);
  if (!res.first || !res.second)
    return;
  TracingMuxerImpl::ConsumerImpl* consumer = res.first;
  RegisteredConsumerBackend& backend = *res.second;

  TracingBackend::ConnectConsumerArgs conn_args;
  conn_args.consumer = consumer;
  conn_args.task_runner = task_runner_.get();
  consumer->Initialize(backend.backend->ConnectConsumer(conn_args));
}

void TracingMuxerImpl::OnConsumerDisconnected(ConsumerImpl* consumer) {
  PERFETTO_DCHECK_THREAD(thread_checker_);
  for (RegisteredConsumerBackend& backend : consumer_backends_) {
    auto pred = [consumer](const std::unique_ptr<ConsumerImpl>& con) {
      return con.get() == consumer;
    };
    backend.consumers.erase(std::remove_if(backend.consumers.begin(),
                                           backend.consumers.end(), pred),
                            backend.consumers.end());
  }
}

void TracingMuxerImpl::SetMaxProducerReconnectionsForTesting(uint32_t count) {
  max_producer_reconnections_.store(count);
}

void TracingMuxerImpl::OnProducerDisconnected(ProducerImpl* producer) {
  PERFETTO_DCHECK_THREAD(thread_checker_);
  for (RegisteredProducerBackend& backend : producer_backends_) {
    if (backend.producer.get() != producer)
      continue;

    // The tracing service is disconnected. It does not make sense to keep
    // tracing (we wouldn't be able to commit). On reconnection, the tracing
    // service will restart the data sources.
    for (const auto& rds : data_sources_) {
      DataSourceStaticState* static_state = rds.static_state;
      for (uint32_t i = 0; i < kMaxDataSourceInstances; i++) {
        auto* internal_state = static_state->TryGet(i);
        if (internal_state && internal_state->backend_id == backend.id &&
            internal_state->backend_connection_id ==
                backend.producer->connection_id_.load(
                    std::memory_order_relaxed)) {
          StopDataSource_AsyncBeginImpl(
              FindDataSourceRes(static_state, internal_state, i,
                                rds.requires_callbacks_under_lock));
        }
      }
    }

    // Try reconnecting the disconnected producer. If the connection succeeds,
    // all the data sources will be automatically re-registered.
    if (producer->connection_id_.load(std::memory_order_relaxed) >
        max_producer_reconnections_.load()) {
      // Avoid reconnecting a failing producer too many times. Instead we just
      // leak the producer instead of trying to avoid further complicating
      // cross-thread trace writer creation.
      PERFETTO_ELOG("Producer disconnected too many times; not reconnecting");
      continue;
    }

    backend.producer->Initialize(
        backend.backend->ConnectProducer(backend.producer_conn_args));
    // Don't use producer-provided SMBs for the next connection unless startup
    // tracing requires it again.
    backend.producer_conn_args.use_producer_provided_smb = false;
  }
}

void TracingMuxerImpl::SweepDeadBackends() {
  PERFETTO_DCHECK_THREAD(thread_checker_);
  for (auto it = dead_backends_.begin(); it != dead_backends_.end();) {
    auto next_it = it;
    next_it++;
    if (it->producer->SweepDeadServices())
      dead_backends_.erase(it);
    it = next_it;
  }
}

TracingMuxerImpl::FindDataSourceRes TracingMuxerImpl::FindDataSource(
    TracingBackendId backend_id,
    DataSourceInstanceID instance_id) {
  PERFETTO_DCHECK_THREAD(thread_checker_);
  RegisteredProducerBackend& backend = *FindProducerBackendById(backend_id);
  for (const auto& rds : data_sources_) {
    DataSourceStaticState* static_state = rds.static_state;
    for (uint32_t i = 0; i < kMaxDataSourceInstances; i++) {
      auto* internal_state = static_state->TryGet(i);
      if (internal_state && internal_state->backend_id == backend_id &&
          internal_state->backend_connection_id ==
              backend.producer->connection_id_.load(
                  std::memory_order_relaxed) &&
          internal_state->data_source_instance_id == instance_id) {
        return FindDataSourceRes(static_state, internal_state, i,
                                 rds.requires_callbacks_under_lock);
      }
    }
  }
  return FindDataSourceRes();
}

// Can be called from any thread.
std::unique_ptr<TraceWriterBase> TracingMuxerImpl::CreateTraceWriter(
    DataSourceStaticState* static_state,
    uint32_t data_source_instance_index,
    DataSourceState* data_source,
    BufferExhaustedPolicy buffer_exhausted_policy) {
  if (PERFETTO_UNLIKELY(data_source->interceptor_id)) {
    // If the session is being intercepted, return a heap-backed trace writer
    // instead. This is safe because all the data given to the interceptor is
    // either thread-local (|instance_index|), statically allocated
    // (|static_state|) or constant after initialization (|interceptor|). Access
    // to the interceptor instance itself through |data_source| is protected by
    // a statically allocated lock (similarly to the data source instance).
    auto& interceptor = interceptors_[data_source->interceptor_id - 1];
    return std::unique_ptr<TraceWriterBase>(new InterceptorTraceWriter(
        interceptor.tls_factory(static_state, data_source_instance_index),
        interceptor.packet_callback, static_state, data_source_instance_index));
  }
  ProducerImpl* producer =
      FindProducerBackendById(data_source->backend_id)->producer.get();
  // Atomically load the current service endpoint. We keep the pointer as a
  // shared pointer on the stack to guard against it from being concurrently
  // modified on the thread by ProducerImpl::Initialize() swapping in a
  // reconnected service on the muxer task runner thread.
  //
  // The endpoint may also be concurrently modified by SweepDeadServices()
  // clearing out old disconnected services. We guard against that by
  // SharedMemoryArbiter keeping track of any outstanding trace writers. After
  // shutdown has started, the trace writer created below will be a null one
  // which will drop any written data. See SharedMemoryArbiter::TryShutdown().
  //
  // We use an atomic pointer instead of holding a lock because
  // CreateTraceWriter posts tasks under the hood.
  std::shared_ptr<ProducerEndpoint> service =
      std::atomic_load(&producer->service_);

  // The service may have been disconnected and reconnected concurrently after
  // the data source was enabled, in which case we may not have an arbiter, or
  // would be creating a TraceWriter for the wrong (a newer) connection / SMB.
  // Instead, early-out now. A relaxed load is fine here because the atomic_load
  // above ensures that the |service| isn't newer.
  if (producer->connection_id_.load(std::memory_order_relaxed) !=
      data_source->backend_connection_id) {
    return std::unique_ptr<TraceWriter>(new NullTraceWriter());
  }

  // We just need a relaxed atomic read here: We can use the reservation ID even
  // after the buffer was bound, we just need to be sure to read it atomically.
  uint16_t startup_buffer_reservation =
      data_source->startup_target_buffer_reservation.load(
          std::memory_order_relaxed);
  if (startup_buffer_reservation) {
    return service->MaybeSharedMemoryArbiter()->CreateStartupTraceWriter(
        startup_buffer_reservation);
  }
  return service->CreateTraceWriter(data_source->buffer_id,
                                    buffer_exhausted_policy);
}

// This is called via the public API Tracing::NewTrace().
// Can be called from any thread.
std::unique_ptr<TracingSession> TracingMuxerImpl::CreateTracingSession(
    BackendType requested_backend_type,
    TracingConsumerBackend* (*system_backend_factory)()) {
  TracingSessionGlobalID session_id = ++next_tracing_session_id_;

  // |backend_type| can only specify one backend, not an OR-ed mask.
  PERFETTO_CHECK((requested_backend_type & (requested_backend_type - 1)) == 0);

  // Capturing |this| is fine because the TracingMuxer is a leaky singleton.
  task_runner_->PostTask([this, requested_backend_type, session_id,
                          system_backend_factory] {
    if (requested_backend_type == kSystemBackend && system_backend_factory &&
        !FindConsumerBackendByType(kSystemBackend)) {
      AddConsumerBackend(system_backend_factory(), kSystemBackend);
    }
    for (RegisteredConsumerBackend& backend : consumer_backends_) {
      if (requested_backend_type && backend.type &&
          backend.type != requested_backend_type) {
        continue;
      }

      // Create the consumer now, even if we have to ask the embedder below, so
      // that any other tasks executing after this one can find the consumer and
      // change its pending attributes.
      backend.consumers.emplace_back(
          new ConsumerImpl(this, backend.type, session_id));

      // The last registered backend in |consumer_backends_| is the unsupported
      // backend without a valid type.
      if (!backend.type) {
        PERFETTO_ELOG(
            "No tracing backend ready for type=%d, consumer will disconnect",
            requested_backend_type);
        InitializeConsumer(session_id);
        return;
      }

      // Check if the embedder wants to be asked for permission before
      // connecting the consumer.
      if (!policy_) {
        InitializeConsumer(session_id);
        return;
      }

      BackendType type = backend.type;
      TracingPolicy::ShouldAllowConsumerSessionArgs args;
      args.backend_type = backend.type;
      args.result_callback = [this, type, session_id](bool allow) {
        task_runner_->PostTask([this, type, session_id, allow] {
          if (allow) {
            InitializeConsumer(session_id);
            return;
          }

          PERFETTO_ELOG(
              "Consumer session for backend type type=%d forbidden, "
              "consumer will disconnect",
              type);

          auto* consumer = FindConsumer(session_id);
          if (!consumer)
            return;

          consumer->OnDisconnect();
        });
      };
      policy_->ShouldAllowConsumerSession(args);
      return;
    }
    PERFETTO_DFATAL("Not reached");
  });

  return std::unique_ptr<TracingSession>(
      new TracingSessionImpl(this, session_id, requested_backend_type));
}

// static
// This is called via the public API Tracing::SetupStartupTracing().
// Can be called from any thread.
std::unique_ptr<StartupTracingSession>
TracingMuxerImpl::CreateStartupTracingSession(
    const TraceConfig& config,
    Tracing::SetupStartupTracingOpts opts) {
  BackendType backend_type = opts.backend;
  // |backend_type| can only specify one backend, not an OR-ed mask.
  PERFETTO_CHECK((backend_type & (backend_type - 1)) == 0);
  // The in-process backend doesn't support startup tracing.
  PERFETTO_CHECK(backend_type != BackendType::kInProcessBackend);

  TracingSessionGlobalID session_id = ++next_tracing_session_id_;

  // Capturing |this| is fine because the TracingMuxer is a leaky singleton.
  task_runner_->PostTask([this, config, opts, backend_type, session_id] {
    for (RegisteredProducerBackend& backend : producer_backends_) {
      if (backend_type && backend.type && backend.type != backend_type) {
        continue;
      }

      TracingBackendId backend_id = backend.id;

      // The last registered backend in |producer_backends_| is the unsupported
      // backend without a valid type.
      if (!backend.type) {
        PERFETTO_ELOG(
            "No tracing backend initialized for type=%d, startup tracing "
            "failed",
            backend_type);
        if (opts.on_setup)
          opts.on_setup(Tracing::OnStartupTracingSetupCallbackArgs{
              0 /* num_data_sources_started */});
        return;
      }

      if (!backend.producer->service_ ||
          !backend.producer->service_->shared_memory()) {
        // If we unsuccessfully attempted to use a producer-provided SMB in the
        // past, don't try again.
        if (backend.producer->producer_provided_smb_failed_) {
          PERFETTO_ELOG(
              "Backend %zu doesn't seem to support producer-provided "
              "SMBs, startup tracing failed",
              backend_id);
          if (opts.on_setup)
            opts.on_setup(Tracing::OnStartupTracingSetupCallbackArgs{
                0 /* num_data_sources_started */});
          return;
        }

        PERFETTO_DLOG("Reconnecting backend %zu for startup tracing",
                      backend_id);
        backend.producer_conn_args.use_producer_provided_smb = true;
        backend.producer->service_->Disconnect();  // Causes a reconnect.
        PERFETTO_DCHECK(backend.producer->service_ &&
                        backend.producer->service_->MaybeSharedMemoryArbiter());
      }

      RegisteredStartupSession session;
      session.session_id = session_id;
      session.on_aborted = opts.on_aborted;
      session.on_adopted = opts.on_adopted;

      for (const TraceConfig::DataSource& ds_cfg : config.data_sources()) {
        // Find all matching data sources and start one instance of each.
        for (const auto& rds : data_sources_) {
          if (rds.descriptor.name() != ds_cfg.config().name())
            continue;

          PERFETTO_DLOG(
              "Setting up data source %s for startup tracing with target "
              "buffer reservation %" PRIi32,
              rds.descriptor.name().c_str(),
              backend.producer->last_startup_target_buffer_reservation_ + 1u);
          auto ds = SetupDataSourceImpl(
              rds, backend_id,
              backend.producer->connection_id_.load(std::memory_order_relaxed),
              /*instance_id=*/0, ds_cfg.config(),
              /*startup_session_id=*/session_id);
          if (ds) {
            StartDataSourceImpl(ds);
            session.num_unbound_data_sources++;
          }
        }
      }

      int num_ds = session.num_unbound_data_sources;
      auto on_setup = opts.on_setup;
      if (on_setup) {
        backend.producer->OnStartupTracingSetup();
        task_runner_->PostTask([on_setup, num_ds] {
          on_setup(Tracing::OnStartupTracingSetupCallbackArgs{num_ds});
        });
      }

      if (num_ds > 0) {
        backend.startup_sessions.push_back(std::move(session));

        if (opts.timeout_ms > 0) {
          task_runner_->PostDelayedTask(
              [this, session_id, backend_type] {
                AbortStartupTracingSession(session_id, backend_type);
              },
              opts.timeout_ms);
        }
      }
      return;
    }
    PERFETTO_DFATAL("Invalid startup tracing session backend");
  });

  return std::unique_ptr<StartupTracingSession>(
      new StartupTracingSessionImpl(this, session_id, backend_type));
}

// Must not be called from the SDK's internal thread.
std::unique_ptr<StartupTracingSession>
TracingMuxerImpl::CreateStartupTracingSessionBlocking(
    const TraceConfig& config,
    Tracing::SetupStartupTracingOpts opts) {
  auto previous_on_setup = std::move(opts.on_setup);
  PERFETTO_CHECK(!task_runner_->RunsTasksOnCurrentThread());
  base::WaitableEvent event;
  // It is safe to capture by reference because once on_setup is called only
  // once before this method returns.
  opts.on_setup = [&](Tracing::OnStartupTracingSetupCallbackArgs args) {
    if (previous_on_setup) {
      previous_on_setup(std::move(args));
    }
    event.Notify();
  };
  auto session = CreateStartupTracingSession(config, std::move(opts));
  event.Wait();
  return session;
}

void TracingMuxerImpl::AbortStartupTracingSession(
    TracingSessionGlobalID session_id,
    BackendType backend_type) {
  PERFETTO_DCHECK_THREAD(thread_checker_);

  for (RegisteredProducerBackend& backend : producer_backends_) {
    if (backend_type != backend.type)
      continue;

    auto session_it = std::find_if(
        backend.startup_sessions.begin(), backend.startup_sessions.end(),
        [session_id](const RegisteredStartupSession& session) {
          return session.session_id == session_id;
        });

    // The startup session may have already been aborted or fully adopted.
    if (session_it == backend.startup_sessions.end())
      return;
    if (session_it->is_aborting)
      return;

    session_it->is_aborting = true;

    // Iterate all data sources and abort them if they weren't adopted yet.
    for (const auto& rds : data_sources_) {
      DataSourceStaticState* static_state = rds.static_state;
      for (uint32_t i = 0; i < kMaxDataSourceInstances; i++) {
        auto* internal_state = static_state->TryGet(i);
        if (internal_state &&
            internal_state->startup_target_buffer_reservation.load(
                std::memory_order_relaxed) &&
            internal_state->data_source_instance_id == 0 &&
            internal_state->startup_session_id == session_id) {
          PERFETTO_DLOG(
              "Aborting startup tracing for data source %s (target buffer "
              "reservation %" PRIu16 ")",
              rds.descriptor.name().c_str(),
              internal_state->startup_target_buffer_reservation.load(
                  std::memory_order_relaxed));

          // Abort the instance asynchronously by stopping it. From this point
          // onwards, the service will not be able to adopt it via
          // StartDataSource().
          session_it->num_aborting_data_sources++;
          StopDataSource_AsyncBeginImpl(
              FindDataSourceRes(static_state, internal_state, i,
                                rds.requires_callbacks_under_lock));
        }
      }
    }

    // If we did everything right, we should have aborted all still-unbound data
    // source instances.
    PERFETTO_DCHECK(session_it->num_unbound_data_sources ==
                    session_it->num_aborting_data_sources);

    if (session_it->num_aborting_data_sources == 0) {
      if (session_it->on_aborted)
        task_runner_->PostTask(session_it->on_aborted);

      backend.startup_sessions.erase(session_it);
    }
    return;
  }
  // We might reach here in tests because when we start a trace, we post the
  // Task(AbortStartupTrace, delay=timeout). When we do
  // perfetto::ResetForTesting, we sweep dead backends, and we are not able to
  // kill those delayed tasks because TaskRunner doesn't have support for
  // deleting scheduled future tasks and TaskRunner doesn't have any API for us
  // to wait for the completion of all the scheduled tasks (apart from
  // deleting the TaskRunner) and we want to avoid doing that because we need
  // a long running TaskRunner in muxer.
  PERFETTO_DLOG("Invalid startup tracing session backend");
}

void TracingMuxerImpl::InitializeInstance(const TracingInitArgs& args) {
  if (instance_ != TracingMuxerFake::Get()) {
    // The tracing muxer was already initialized. We might need to initialize
    // additional backends that were not configured earlier.
    auto* muxer = static_cast<TracingMuxerImpl*>(instance_);
    muxer->task_runner_->PostTask([muxer, args] { muxer->AddBackends(args); });
    return;
  }
  // If we previously had a TracingMuxerImpl instance which was reset,
  // reinitialize and reuse it instead of trying to create a new one. See
  // ResetForTesting().
  if (g_prev_instance) {
    auto* muxer = g_prev_instance;
    g_prev_instance = nullptr;
    instance_ = muxer;
    muxer->task_runner_->PostTask([muxer, args] {
      muxer->Initialize(args);
      muxer->AddBackends(args);
    });
  } else {
    new TracingMuxerImpl(args);
  }
}

// static
void TracingMuxerImpl::ResetForTesting() {
  // Ideally we'd tear down the entire TracingMuxerImpl, but the lifetimes of
  // various objects make that a non-starter. In particular:
  //
  // 1) Any thread that has entered a trace event has a TraceWriter, which holds
  //    a reference back to ProducerImpl::service_.
  //
  // 2) ProducerImpl::service_ has a reference back to the ProducerImpl.
  //
  // 3) ProducerImpl holds reference to TracingMuxerImpl::task_runner_, which in
  //    turn depends on TracingMuxerImpl itself.
  //
  // Because of this, it's not safe to deallocate TracingMuxerImpl until all
  // threads have dropped their TraceWriters. Since we can't really ask the
  // caller to guarantee this, we'll instead reset enough of the muxer's state
  // so that it can be reinitialized later and ensure all necessary objects from
  // the old state remain alive until all references have gone away.
  auto* muxer = reinterpret_cast<TracingMuxerImpl*>(instance_);

  base::WaitableEvent reset_done;
  auto do_reset = [muxer, &reset_done] {
    muxer->DestroyStoppedTraceWritersForCurrentThread();
    // Unregister all data sources so they don't interfere with any future
    // tracing sessions.
    for (RegisteredDataSource& rds : muxer->data_sources_) {
      for (RegisteredProducerBackend& backend : muxer->producer_backends_) {
        if (!backend.producer->service_ || !backend.producer->connected_)
          continue;
        backend.producer->service_->UnregisterDataSource(rds.descriptor.name());
      }
    }
    for (auto& backend : muxer->consumer_backends_) {
      // Check that no consumer session is currently active on any backend.
      for (auto& consumer : backend.consumers)
        PERFETTO_CHECK(!consumer->service_);
    }
    for (auto& backend : muxer->producer_backends_) {
      backend.producer->muxer_ = nullptr;
      backend.producer->DisposeConnection();
      muxer->dead_backends_.push_back(std::move(backend));
    }
    muxer->consumer_backends_.clear();
    muxer->producer_backends_.clear();
    muxer->interceptors_.clear();

    for (auto& ds : muxer->data_sources_) {
      ds.static_state->ResetForTesting();
    }

    muxer->data_sources_.clear();
    muxer->next_data_source_index_ = 0;

    // Free all backends without active trace writers or other inbound
    // references. Note that even if all the backends get swept, the muxer still
    // needs to stay around since |task_runner_| is assumed to be long-lived.
    muxer->SweepDeadBackends();

    // Make sure we eventually discard any per-thread trace writers from the
    // previous instance.
    muxer->muxer_id_for_testing_++;

    g_prev_instance = muxer;
    instance_ = TracingMuxerFake::Get();

    // Call the user provided cleanups on the muxer thread.
    for (auto& cb : muxer->reset_callbacks_) {
      cb();
    }

    reset_done.Notify();
  };

  // Some tests run the muxer and the test on the same thread. In these cases,
  // we can reset synchronously.
  if (muxer->task_runner_->RunsTasksOnCurrentThread()) {
    do_reset();
  } else {
    muxer->DestroyStoppedTraceWritersForCurrentThread();
    muxer->task_runner_->PostTask(std::move(do_reset));
    reset_done.Wait();
    // Call the user provided cleanups also on this thread.
    for (auto& cb : muxer->reset_callbacks_) {
      cb();
    }
  }
  muxer->reset_callbacks_.clear();
}

// static
void TracingMuxerImpl::Shutdown() {
  auto* muxer = reinterpret_cast<TracingMuxerImpl*>(instance_);

  // Shutting down on the muxer thread would lead to a deadlock.
  PERFETTO_CHECK(!muxer->task_runner_->RunsTasksOnCurrentThread());
  muxer->DestroyStoppedTraceWritersForCurrentThread();

  std::unique_ptr<base::TaskRunner> owned_task_runner(
      muxer->task_runner_.get());
  base::WaitableEvent shutdown_done;
  owned_task_runner->PostTask([muxer, &shutdown_done] {
    // Check that no consumer session is currently active on any backend.
    // Producers will be automatically disconnected as a part of deleting the
    // muxer below.
    for (auto& backend : muxer->consumer_backends_) {
      for (auto& consumer : backend.consumers) {
        PERFETTO_CHECK(!consumer->service_);
      }
    }
    // Make sure no trace writers are lingering around on the muxer thread. Note
    // that we can't do this for any arbitrary thread in the process; it is the
    // caller's responsibility to clean them up before shutting down Perfetto.
    muxer->DestroyStoppedTraceWritersForCurrentThread();
    // The task runner must be deleted outside the muxer thread. This is done by
    // `owned_task_runner` above.
    muxer->task_runner_.release();
    auto* platform = muxer->platform_;
    delete muxer;
    instance_ = TracingMuxerFake::Get();
    platform->Shutdown();
    shutdown_done.Notify();
  });
  shutdown_done.Wait();
}

void TracingMuxerImpl::AppendResetForTestingCallback(std::function<void()> cb) {
  reset_callbacks_.push_back(std::move(cb));
}

TracingMuxer::~TracingMuxer() = default;

static_assert(std::is_same<internal::BufferId, BufferID>::value,
              "public's BufferId and tracing/core's BufferID diverged");

}  // namespace internal
}  // namespace perfetto
// gen_amalgamated begin source: src/tracing/internal/track_event_internal.cc
/*
 * Copyright (C) 2019 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// gen_amalgamated expanded: #include "perfetto/tracing/internal/track_event_internal.h"

// gen_amalgamated expanded: #include "perfetto/base/proc_utils.h"
// gen_amalgamated expanded: #include "perfetto/base/time.h"
// gen_amalgamated expanded: #include "perfetto/tracing/core/data_source_config.h"
// gen_amalgamated expanded: #include "perfetto/tracing/internal/track_event_interned_fields.h"
// gen_amalgamated expanded: #include "perfetto/tracing/track_event.h"
// gen_amalgamated expanded: #include "perfetto/tracing/track_event_category_registry.h"
// gen_amalgamated expanded: #include "perfetto/tracing/track_event_interned_data_index.h"
// gen_amalgamated expanded: #include "protos/perfetto/common/data_source_descriptor.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/common/track_event_descriptor.pbzero.h"
// gen_amalgamated expanded: #include "protos/perfetto/trace/clock_snapshot.pbzero.h"
// gen_amalgamated expanded: #include "protos/perfetto/trace/interned_data/interned_data.pbzero.h"
// gen_amalgamated expanded: #include "protos/perfetto/trace/trace_packet_defaults.pbzero.h"
// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/debug_annotation.pbzero.h"
// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/track_descriptor.pbzero.h"

using perfetto::protos::pbzero::ClockSnapshot;

namespace perfetto {

TrackEventSessionObserver::~TrackEventSessionObserver() = default;
void TrackEventSessionObserver::OnSetup(const DataSourceBase::SetupArgs&) {}
void TrackEventSessionObserver::OnStart(const DataSourceBase::StartArgs&) {}
void TrackEventSessionObserver::OnStop(const DataSourceBase::StopArgs&) {}
void TrackEventSessionObserver::WillClearIncrementalState(
    const DataSourceBase::ClearIncrementalStateArgs&) {}

TrackEventTlsStateUserData::~TrackEventTlsStateUserData() = default;

namespace internal {

BaseTrackEventInternedDataIndex::~BaseTrackEventInternedDataIndex() = default;

namespace {

static constexpr const char kLegacySlowPrefix[] = "disabled-by-default-";
static constexpr const char kSlowTag[] = "slow";
static constexpr const char kDebugTag[] = "debug";
static constexpr const char kFilteredEventName[] = "FILTERED";

constexpr auto kClockIdIncremental =
    TrackEventIncrementalState::kClockIdIncremental;

constexpr auto kClockIdAbsolute = TrackEventIncrementalState::kClockIdAbsolute;

class TrackEventSessionObserverRegistry {
 public:
  static TrackEventSessionObserverRegistry* GetInstance() {
    static TrackEventSessionObserverRegistry* instance =
        new TrackEventSessionObserverRegistry();  // leaked
    return instance;
  }

  void AddObserverForRegistry(const TrackEventCategoryRegistry& registry,
                              TrackEventSessionObserver* observer) {
    std::unique_lock<std::recursive_mutex> lock(mutex_);
    observers_.emplace_back(&registry, observer);
  }

  void RemoveObserverForRegistry(const TrackEventCategoryRegistry& registry,
                                 TrackEventSessionObserver* observer) {
    std::unique_lock<std::recursive_mutex> lock(mutex_);
    observers_.erase(std::remove(observers_.begin(), observers_.end(),
                                 RegisteredObserver(&registry, observer)),
                     observers_.end());
  }

  void ForEachObserverForRegistry(
      const TrackEventCategoryRegistry& registry,
      std::function<void(TrackEventSessionObserver*)> callback) {
    std::unique_lock<std::recursive_mutex> lock(mutex_);
    for (auto& registered_observer : observers_) {
      if (&registry == registered_observer.registry) {
        callback(registered_observer.observer);
      }
    }
  }

 private:
  struct RegisteredObserver {
    RegisteredObserver(const TrackEventCategoryRegistry* r,
                       TrackEventSessionObserver* o)
        : registry(r), observer(o) {}
    bool operator==(const RegisteredObserver& other) {
      return registry == other.registry && observer == other.observer;
    }
    const TrackEventCategoryRegistry* registry;
    TrackEventSessionObserver* observer;
  };

  std::recursive_mutex mutex_;
  std::vector<RegisteredObserver> observers_;
};

enum class MatchType { kExact, kPattern };

bool NameMatchesPattern(const std::string& pattern,
                        const std::string& name,
                        MatchType match_type) {
  // To avoid pulling in all of std::regex, for now we only support a single "*"
  // wildcard at the end of the pattern.
  size_t i = pattern.find('*');
  if (i != std::string::npos) {
    PERFETTO_DCHECK(i == pattern.size() - 1);
    if (match_type != MatchType::kPattern)
      return false;
    return name.substr(0, i) == pattern.substr(0, i);
  }
  return name == pattern;
}

bool NameMatchesPatternList(const std::vector<std::string>& patterns,
                            const std::string& name,
                            MatchType match_type) {
  for (const auto& pattern : patterns) {
    if (NameMatchesPattern(pattern, name, match_type))
      return true;
  }
  return false;
}

}  // namespace

// static
const Track TrackEventInternal::kDefaultTrack{};

// static
std::atomic<int> TrackEventInternal::session_count_{};

// static
bool TrackEventInternal::Initialize(
    const TrackEventCategoryRegistry& registry,
    bool (*register_data_source)(const DataSourceDescriptor&)) {
  DataSourceDescriptor dsd;
  dsd.set_name("track_event");

  protozero::HeapBuffered<protos::pbzero::TrackEventDescriptor> ted;
  for (size_t i = 0; i < registry.category_count(); i++) {
    auto category = registry.GetCategory(i);
    // Don't register group categories.
    if (category->IsGroup())
      continue;
    auto cat = ted->add_available_categories();
    cat->set_name(category->name);
    if (category->description)
      cat->set_description(category->description);
    for (const auto& tag : category->tags) {
      if (tag)
        cat->add_tags(tag);
    }
    // Disabled-by-default categories get a "slow" tag.
    if (!strncmp(category->name, kLegacySlowPrefix, strlen(kLegacySlowPrefix)))
      cat->add_tags(kSlowTag);
  }
  dsd.set_track_event_descriptor_raw(ted.SerializeAsString());

  return register_data_source(dsd);
}

// static
bool TrackEventInternal::AddSessionObserver(
    const TrackEventCategoryRegistry& registry,
    TrackEventSessionObserver* observer) {
  TrackEventSessionObserverRegistry::GetInstance()->AddObserverForRegistry(
      registry, observer);
  return true;
}

// static
void TrackEventInternal::RemoveSessionObserver(
    const TrackEventCategoryRegistry& registry,
    TrackEventSessionObserver* observer) {
  TrackEventSessionObserverRegistry::GetInstance()->RemoveObserverForRegistry(
      registry, observer);
}

#if !PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE) && \
    !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
static constexpr protos::pbzero::BuiltinClock kDefaultTraceClock =
    protos::pbzero::BUILTIN_CLOCK_BOOTTIME;
#else
static constexpr protos::pbzero::BuiltinClock kDefaultTraceClock =
    protos::pbzero::BUILTIN_CLOCK_MONOTONIC;
#endif

// static
protos::pbzero::BuiltinClock TrackEventInternal::clock_ = kDefaultTraceClock;

// static
bool TrackEventInternal::disallow_merging_with_system_tracks_ = false;

// static
void TrackEventInternal::EnableTracing(
    const TrackEventCategoryRegistry& registry,
    const protos::gen::TrackEventConfig& config,
    const DataSourceBase::SetupArgs& args) {
  for (size_t i = 0; i < registry.category_count(); i++) {
    if (IsCategoryEnabled(registry, config, *registry.GetCategory(i)))
      registry.EnableCategoryForInstance(i, args.internal_instance_index);
  }
  TrackEventSessionObserverRegistry::GetInstance()->ForEachObserverForRegistry(
      registry, [&](TrackEventSessionObserver* o) { o->OnSetup(args); });
}

// static
void TrackEventInternal::OnStart(const TrackEventCategoryRegistry& registry,
                                 const DataSourceBase::StartArgs& args) {
  session_count_.fetch_add(1);
  TrackEventSessionObserverRegistry::GetInstance()->ForEachObserverForRegistry(
      registry, [&](TrackEventSessionObserver* o) { o->OnStart(args); });
}

// static
void TrackEventInternal::OnStop(const TrackEventCategoryRegistry& registry,
                                const DataSourceBase::StopArgs& args) {
  TrackEventSessionObserverRegistry::GetInstance()->ForEachObserverForRegistry(
      registry, [&](TrackEventSessionObserver* o) { o->OnStop(args); });
}

// static
void TrackEventInternal::DisableTracing(
    const TrackEventCategoryRegistry& registry,
    uint32_t internal_instance_index) {
  for (size_t i = 0; i < registry.category_count(); i++)
    registry.DisableCategoryForInstance(i, internal_instance_index);
}

// static
void TrackEventInternal::WillClearIncrementalState(
    const TrackEventCategoryRegistry& registry,
    const DataSourceBase::ClearIncrementalStateArgs& args) {
  TrackEventSessionObserverRegistry::GetInstance()->ForEachObserverForRegistry(
      registry, [&](TrackEventSessionObserver* o) {
        o->WillClearIncrementalState(args);
      });
}

// static
bool TrackEventInternal::IsCategoryEnabled(
    const TrackEventCategoryRegistry& registry,
    const protos::gen::TrackEventConfig& config,
    const Category& category) {
  // If this is a group category, check if any of its constituent categories are
  // enabled. If so, then this one is enabled too.
  if (category.IsGroup()) {
    bool result = false;
    category.ForEachGroupMember([&](const char* member_name, size_t name_size) {
      for (size_t i = 0; i < registry.category_count(); i++) {
        const auto ref_category = registry.GetCategory(i);
        // Groups can't refer to other groups.
        if (ref_category->IsGroup())
          continue;
        // Require an exact match.
        if (ref_category->name_size() != name_size ||
            strncmp(ref_category->name, member_name, name_size)) {
          continue;
        }
        if (IsCategoryEnabled(registry, config, *ref_category)) {
          result = true;
          // Break ForEachGroupMember() loop.
          return false;
        }
        break;
      }
      // No match? Must be a dynamic category.
      DynamicCategory dyn_category(std::string(member_name, name_size));
      Category ref_category{Category::FromDynamicCategory(dyn_category)};
      if (IsCategoryEnabled(registry, config, ref_category)) {
        result = true;
        // Break ForEachGroupMember() loop.
        return false;
      }
      // No match found => keep iterating.
      return true;
    });
    return result;
  }

  auto has_matching_tag = [&](std::function<bool(const char*)> matcher) {
    for (const auto& tag : category.tags) {
      if (!tag)
        break;
      if (matcher(tag))
        return true;
    }
    // Legacy "disabled-by-default" categories automatically get the "slow" tag.
    if (!strncmp(category.name, kLegacySlowPrefix, strlen(kLegacySlowPrefix)) &&
        matcher(kSlowTag)) {
      return true;
    }
    return false;
  };

  // First try exact matches, then pattern matches.
  const std::array<MatchType, 2> match_types = {
      {MatchType::kExact, MatchType::kPattern}};
  for (auto match_type : match_types) {
    // 1. Enabled categories.
    if (NameMatchesPatternList(config.enabled_categories(), category.name,
                               match_type)) {
      return true;
    }

    // 2. Enabled tags.
    if (has_matching_tag([&](const char* tag) {
          return NameMatchesPatternList(config.enabled_tags(), tag, match_type);
        })) {
      return true;
    }

    // 2.5. A special case for Chrome's legacy disabled-by-default categories.
    // We treat them as having a "slow" tag with one exception: they can be
    // enabled by a pattern if the pattern starts with "disabled-by-default-"
    // itself.
    if (match_type == MatchType::kExact &&
        !strncmp(category.name, kLegacySlowPrefix, strlen(kLegacySlowPrefix))) {
      for (const auto& pattern : config.enabled_categories()) {
        if (!strncmp(pattern.c_str(), kLegacySlowPrefix,
                     strlen(kLegacySlowPrefix)) &&
            NameMatchesPattern(pattern, category.name, MatchType::kPattern)) {
          return true;
        }
      }
    }

    // 3. Disabled categories.
    if (NameMatchesPatternList(config.disabled_categories(), category.name,
                               match_type)) {
      return false;
    }

    // 4. Disabled tags.
    if (has_matching_tag([&](const char* tag) {
          if (config.disabled_tags_size()) {
            return NameMatchesPatternList(config.disabled_tags(), tag,
                                          match_type);
          } else {
            // The "slow" and "debug" tags are disabled by default.
            return NameMatchesPattern(kSlowTag, tag, match_type) ||
                   NameMatchesPattern(kDebugTag, tag, match_type);
          }
        })) {
      return false;
    }
  }

  // If nothing matched, enable the category by default.
  return true;
}

// static
uint64_t TrackEventInternal::GetTimeNs() {
  if (GetClockId() == protos::pbzero::BUILTIN_CLOCK_BOOTTIME)
    return static_cast<uint64_t>(perfetto::base::GetBootTimeNs().count());
  else if (GetClockId() == protos::pbzero::BUILTIN_CLOCK_MONOTONIC)
    return static_cast<uint64_t>(perfetto::base::GetWallTimeNs().count());
  PERFETTO_DCHECK(GetClockId() == protos::pbzero::BUILTIN_CLOCK_MONOTONIC_RAW);
  return static_cast<uint64_t>(perfetto::base::GetWallTimeRawNs().count());
}

// static
TraceTimestamp TrackEventInternal::GetTraceTime() {
  return {kClockIdIncremental, GetTimeNs()};
}

// static
int TrackEventInternal::GetSessionCount() {
  return session_count_.load();
}

// static
void TrackEventInternal::ResetIncrementalState(
    TraceWriterBase* trace_writer,
    TrackEventIncrementalState* incr_state,
    const TrackEventTlsState& tls_state,
    const TraceTimestamp& timestamp) {
  auto sequence_timestamp = timestamp;
  if (timestamp.clock_id != kClockIdIncremental) {
    sequence_timestamp = TrackEventInternal::GetTraceTime();
  }

  incr_state->last_timestamp_ns = sequence_timestamp.value;
  auto default_track = ThreadTrack::Current();
  auto ts_unit_multiplier = tls_state.timestamp_unit_multiplier;
  auto thread_time_counter_track =
      CounterTrack("thread_time", default_track)
          .set_is_incremental(true)
          .set_unit_multiplier(static_cast<int64_t>(ts_unit_multiplier))
          .set_type(protos::gen::CounterDescriptor::COUNTER_THREAD_TIME_NS);
  {
    // Mark any incremental state before this point invalid. Also set up
    // defaults so that we don't need to repeat constant data for each packet.
    auto packet = NewTracePacket(
        trace_writer, incr_state, tls_state, timestamp,
        protos::pbzero::TracePacket::SEQ_INCREMENTAL_STATE_CLEARED);
    auto defaults = packet->set_trace_packet_defaults();
    defaults->set_timestamp_clock_id(tls_state.default_clock);
    // Establish the default track for this event sequence.
    auto track_defaults = defaults->set_track_event_defaults();
    track_defaults->set_track_uuid(default_track.uuid);
    if (tls_state.enable_thread_time_sampling) {
      track_defaults->add_extra_counter_track_uuids(
          thread_time_counter_track.uuid);
    }

    if (tls_state.default_clock != static_cast<uint32_t>(GetClockId())) {
      ClockSnapshot* clocks = packet->set_clock_snapshot();
      // Trace clock.
      ClockSnapshot::Clock* trace_clock = clocks->add_clocks();
      trace_clock->set_clock_id(static_cast<uint32_t>(GetClockId()));
      trace_clock->set_timestamp(sequence_timestamp.value);

      if (PERFETTO_LIKELY(tls_state.default_clock == kClockIdIncremental)) {
        // Delta-encoded incremental clock in nanoseconds by default but
        // configurable by |tls_state.timestamp_unit_multiplier|.
        ClockSnapshot::Clock* clock_incremental = clocks->add_clocks();
        clock_incremental->set_clock_id(kClockIdIncremental);
        clock_incremental->set_timestamp(sequence_timestamp.value /
                                         ts_unit_multiplier);
        clock_incremental->set_is_incremental(true);
        clock_incremental->set_unit_multiplier_ns(ts_unit_multiplier);
      }
      if (ts_unit_multiplier > 1) {
        // absolute clock with custom timestamp_unit_multiplier.
        ClockSnapshot::Clock* absolute_clock = clocks->add_clocks();
        absolute_clock->set_clock_id(kClockIdAbsolute);
        absolute_clock->set_timestamp(sequence_timestamp.value /
                                      ts_unit_multiplier);
        absolute_clock->set_is_incremental(false);
        absolute_clock->set_unit_multiplier_ns(ts_unit_multiplier);
      }
    }
  }

  // Every thread should write a descriptor for its default track, because most
  // trace points won't explicitly reference it. We also write the process
  // descriptor from every thread that writes trace events to ensure it gets
  // emitted at least once.
  WriteTrackDescriptor(default_track, trace_writer, incr_state, tls_state,
                       sequence_timestamp);

  WriteTrackDescriptor(ProcessTrack::Current(), trace_writer, incr_state,
                       tls_state, sequence_timestamp);

  if (tls_state.enable_thread_time_sampling) {
    WriteTrackDescriptor(thread_time_counter_track, trace_writer, incr_state,
                         tls_state, sequence_timestamp);
  }
}

// static
protozero::MessageHandle<protos::pbzero::TracePacket>
TrackEventInternal::NewTracePacket(TraceWriterBase* trace_writer,
                                   TrackEventIncrementalState* incr_state,
                                   const TrackEventTlsState& tls_state,
                                   TraceTimestamp timestamp,
                                   uint32_t seq_flags) {
  if (PERFETTO_UNLIKELY(tls_state.default_clock != kClockIdIncremental &&
                        timestamp.clock_id == kClockIdIncremental)) {
    timestamp.clock_id = tls_state.default_clock;
  }
  auto packet = trace_writer->NewTracePacket();
  auto ts_unit_multiplier = tls_state.timestamp_unit_multiplier;
  if (PERFETTO_LIKELY(timestamp.clock_id == kClockIdIncremental)) {
    if (PERFETTO_LIKELY(incr_state->last_timestamp_ns <= timestamp.value)) {
      // No need to set the clock id here, since kClockIdIncremental is the
      // clock id assumed by default.
      auto time_diff_ns = timestamp.value - incr_state->last_timestamp_ns;
      auto time_diff_units = time_diff_ns / ts_unit_multiplier;
      packet->set_timestamp(time_diff_units);
      incr_state->last_timestamp_ns += time_diff_units * ts_unit_multiplier;
    } else {
      packet->set_timestamp(timestamp.value / ts_unit_multiplier);
      packet->set_timestamp_clock_id(ts_unit_multiplier == 1
                                         ? static_cast<uint32_t>(GetClockId())
                                         : kClockIdAbsolute);
    }
  } else if (PERFETTO_LIKELY(timestamp.clock_id == tls_state.default_clock)) {
    packet->set_timestamp(timestamp.value / ts_unit_multiplier);
  } else {
    packet->set_timestamp(timestamp.value);
    packet->set_timestamp_clock_id(timestamp.clock_id);
  }
  packet->set_sequence_flags(seq_flags);
  return packet;
}

// static
void TrackEventInternal::WriteEventName(StaticString event_name,
                                        perfetto::EventContext& event_ctx,
                                        const TrackEventTlsState&) {
  if (PERFETTO_LIKELY(event_name.value != nullptr)) {
    size_t name_iid = InternedEventName::Get(&event_ctx, event_name.value);
    event_ctx.event()->set_name_iid(name_iid);
  }
}

// static
void TrackEventInternal::WriteEventName(perfetto::DynamicString event_name,
                                        perfetto::EventContext& event_ctx,
                                        const TrackEventTlsState& tls_state) {
  if (PERFETTO_UNLIKELY(tls_state.filter_dynamic_event_names)) {
    event_ctx.event()->set_name(kFilteredEventName,
                                sizeof(kFilteredEventName) - 1);
  } else {
    event_ctx.event()->set_name(event_name.value, event_name.length);
  }
}

// static
EventContext TrackEventInternal::WriteEvent(
    TraceWriterBase* trace_writer,
    TrackEventIncrementalState* incr_state,
    TrackEventTlsState& tls_state,
    const Category* category,
    perfetto::protos::pbzero::TrackEvent::Type type,
    const TraceTimestamp& timestamp,
    bool on_current_thread_track) {
  PERFETTO_DCHECK(!incr_state->was_cleared);
  auto packet = NewTracePacket(trace_writer, incr_state, tls_state, timestamp);
  EventContext ctx(trace_writer, std::move(packet), incr_state, &tls_state);

  auto track_event = ctx.event();
  if (type != protos::pbzero::TrackEvent::TYPE_UNSPECIFIED)
    track_event->set_type(type);

  if (tls_state.enable_thread_time_sampling && on_current_thread_track) {
    int64_t thread_time_ns = base::GetThreadCPUTimeNs().count();
    auto thread_time_delta_ns =
        thread_time_ns - incr_state->last_thread_time_ns;
    incr_state->last_thread_time_ns = thread_time_ns;
    track_event->add_extra_counter_values(
        thread_time_delta_ns /
        static_cast<int64_t>(tls_state.timestamp_unit_multiplier));
  }

  // We assume that |category| points to the string with static lifetime.
  // This means we can use their addresses as interning keys.
  // TODO(skyostil): Intern categories at compile time.
  if (category && type != protos::pbzero::TrackEvent::TYPE_SLICE_END &&
      type != protos::pbzero::TrackEvent::TYPE_COUNTER) {
    category->ForEachGroupMember(
        [&](const char* member_name, size_t name_size) {
          size_t category_iid =
              InternedEventCategory::Get(&ctx, member_name, name_size);
          track_event->add_category_iids(category_iid);
          return true;
        });
  }
  return ctx;
}

// static
protos::pbzero::DebugAnnotation* TrackEventInternal::AddDebugAnnotation(
    perfetto::EventContext* event_ctx,
    const char* name) {
  auto annotation = event_ctx->event()->add_debug_annotations();
  annotation->set_name_iid(InternedDebugAnnotationName::Get(event_ctx, name));
  return annotation;
}

// static
protos::pbzero::DebugAnnotation* TrackEventInternal::AddDebugAnnotation(
    perfetto::EventContext* event_ctx,
    perfetto::DynamicString name) {
  auto annotation = event_ctx->event()->add_debug_annotations();
  annotation->set_name(name.value);
  return annotation;
}

}  // namespace internal
}  // namespace perfetto
// gen_amalgamated begin source: src/tracing/internal/track_event_interned_fields.cc
/*
 * Copyright (C) 2021 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// gen_amalgamated expanded: #include "perfetto/tracing/internal/track_event_interned_fields.h"

namespace perfetto {
namespace internal {

InternedEventCategory::~InternedEventCategory() = default;

// static
void InternedEventCategory::Add(protos::pbzero::InternedData* interned_data,
                                size_t iid,
                                const char* value,
                                size_t length) {
  auto category = interned_data->add_event_categories();
  category->set_iid(iid);
  category->set_name(value, length);
}

InternedEventName::~InternedEventName() = default;

// static
void InternedEventName::Add(protos::pbzero::InternedData* interned_data,
                            size_t iid,
                            const char* value) {
  auto name = interned_data->add_event_names();
  name->set_iid(iid);
  name->set_name(value);
}

InternedDebugAnnotationName::~InternedDebugAnnotationName() = default;

// static
void InternedDebugAnnotationName::Add(
    protos::pbzero::InternedData* interned_data,
    size_t iid,
    const char* value) {
  auto name = interned_data->add_debug_annotation_names();
  name->set_iid(iid);
  name->set_name(value);
}

InternedDebugAnnotationValueTypeName::~InternedDebugAnnotationValueTypeName() =
    default;

// static
void InternedDebugAnnotationValueTypeName::Add(
    protos::pbzero::InternedData* interned_data,
    size_t iid,
    const char* value) {
  auto name = interned_data->add_debug_annotation_value_type_names();
  name->set_iid(iid);
  name->set_name(value);
}

}  // namespace internal
}  // namespace perfetto
// gen_amalgamated begin source: src/tracing/platform.cc
/*
 * Copyright (C) 2019 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// gen_amalgamated expanded: #include "perfetto/tracing/platform.h"
// gen_amalgamated expanded: #include "perfetto/tracing/internal/tracing_tls.h"
// gen_amalgamated expanded: #include "perfetto/tracing/trace_writer_base.h"

namespace perfetto {

PlatformThreadLocalObject::~PlatformThreadLocalObject() = default;
Platform::~Platform() = default;

void Platform::Shutdown() {}

base::PlatformThreadId Platform::GetCurrentThreadId() {
  return base::GetThreadId();
}

// static
std::unique_ptr<PlatformThreadLocalObject>
PlatformThreadLocalObject::CreateInstance() {
  return std::unique_ptr<PlatformThreadLocalObject>(new internal::TracingTLS());
}

// static
base::PlatformProcessId Platform::process_id_ = 0;

}  // namespace perfetto
// gen_amalgamated begin source: src/tracing/traced_value.cc
/*
 * Copyright (C) 2021 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// gen_amalgamated expanded: #include "perfetto/tracing/traced_value.h"

// gen_amalgamated expanded: #include "perfetto/base/logging.h"
// gen_amalgamated expanded: #include "perfetto/tracing/debug_annotation.h"
// gen_amalgamated expanded: #include "perfetto/tracing/internal/track_event_interned_fields.h"
// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/debug_annotation.pbzero.h"

namespace perfetto {

namespace internal {

TracedValue CreateTracedValueFromProto(
    protos::pbzero::DebugAnnotation* annotation,
    EventContext* event_context) {
  return TracedValue::CreateFromProto(annotation, event_context);
}

}  // namespace internal

// static
TracedValue TracedValue::CreateFromProto(
    protos::pbzero::DebugAnnotation* annotation,
    EventContext* event_context) {
  return TracedValue(annotation, event_context, nullptr);
}

TracedValue::TracedValue(TracedValue&&) = default;
TracedValue::~TracedValue() = default;

void TracedValue::WriteInt64(int64_t value) && {
  PERFETTO_DCHECK(checked_scope_.is_active());
  annotation_->set_int_value(value);
}

void TracedValue::WriteUInt64(uint64_t value) && {
  PERFETTO_DCHECK(checked_scope_.is_active());
  annotation_->set_uint_value(value);
}

void TracedValue::WriteDouble(double value) && {
  PERFETTO_DCHECK(checked_scope_.is_active());
  annotation_->set_double_value(value);
}

void TracedValue::WriteBoolean(bool value) && {
  PERFETTO_DCHECK(checked_scope_.is_active());
  annotation_->set_bool_value(value);
}

void TracedValue::WriteString(const char* value) && {
  PERFETTO_DCHECK(checked_scope_.is_active());
  annotation_->set_string_value(value);
}

void TracedValue::WriteString(const char* value, size_t len) && {
  PERFETTO_DCHECK(checked_scope_.is_active());
  annotation_->set_string_value(value, len);
}

void TracedValue::WriteString(const std::string& value) && {
  PERFETTO_DCHECK(checked_scope_.is_active());
  annotation_->set_string_value(value);
}

void TracedValue::WriteString(std::string_view value) && {
  PERFETTO_DCHECK(checked_scope_.is_active());
  annotation_->set_string_value(value.data(), value.size());
}

void TracedValue::WritePointer(const void* value) && {
  PERFETTO_DCHECK(checked_scope_.is_active());
  annotation_->set_pointer_value(reinterpret_cast<uint64_t>(value));
}

TracedDictionary TracedValue::WriteDictionary() && {
  // Note: this passes |checked_scope_.is_active_| bit to the parent to be
  // picked up later by the new TracedDictionary.
  PERFETTO_DCHECK(checked_scope_.is_active());
  checked_scope_.Reset();

  PERFETTO_DCHECK(!annotation_->is_finalized());
  return TracedDictionary(annotation_,
                          protos::pbzero::DebugAnnotation::kDictEntries,
                          event_context_, checked_scope_.parent_scope());
}

TracedArray TracedValue::WriteArray() && {
  // Note: this passes |checked_scope_.is_active_| bit to the parent to be
  // picked up later by the new TracedDictionary.
  PERFETTO_DCHECK(checked_scope_.is_active());
  checked_scope_.Reset();

  PERFETTO_DCHECK(!annotation_->is_finalized());
  return TracedArray(annotation_, event_context_,
                     checked_scope_.parent_scope());
}

protozero::Message* TracedValue::WriteProtoInternal(const char* name) {
  if (event_context_) {
    annotation_->set_proto_type_name_iid(
        internal::InternedDebugAnnotationValueTypeName::Get(event_context_,
                                                            name));
  } else {
    annotation_->set_proto_type_name(name);
  }
  return annotation_->template BeginNestedMessage<protozero::Message>(
      protos::pbzero::DebugAnnotation::kProtoValueFieldNumber);
}

TracedArray::TracedArray(TracedValue annotation)
    : TracedArray(std::move(annotation).WriteArray()) {}

TracedValue TracedArray::AppendItem() {
  PERFETTO_DCHECK(checked_scope_.is_active());
  return TracedValue(annotation_->add_array_values(), event_context_,
                     &checked_scope_);
}

TracedDictionary TracedArray::AppendDictionary() {
  PERFETTO_DCHECK(checked_scope_.is_active());
  return AppendItem().WriteDictionary();
}

TracedArray TracedArray::AppendArray() {
  PERFETTO_DCHECK(checked_scope_.is_active());
  return AppendItem().WriteArray();
}

TracedDictionary::TracedDictionary(TracedValue annotation)
    : TracedDictionary(std::move(annotation).WriteDictionary()) {}

TracedValue TracedDictionary::AddItem(StaticString key) {
  PERFETTO_DCHECK(checked_scope_.is_active());
  protos::pbzero::DebugAnnotation* item =
      message_->BeginNestedMessage<protos::pbzero::DebugAnnotation>(field_id_);
  item->set_name(key.value);
  return TracedValue(item, event_context_, &checked_scope_);
}

TracedValue TracedDictionary::AddItem(DynamicString key) {
  PERFETTO_DCHECK(checked_scope_.is_active());
  protos::pbzero::DebugAnnotation* item =
      message_->BeginNestedMessage<protos::pbzero::DebugAnnotation>(field_id_);
  item->set_name(key.value);
  return TracedValue(item, event_context_, &checked_scope_);
}

TracedDictionary TracedDictionary::AddDictionary(StaticString key) {
  PERFETTO_DCHECK(checked_scope_.is_active());
  return AddItem(key).WriteDictionary();
}

TracedDictionary TracedDictionary::AddDictionary(DynamicString key) {
  PERFETTO_DCHECK(checked_scope_.is_active());
  return AddItem(key).WriteDictionary();
}

TracedArray TracedDictionary::AddArray(StaticString key) {
  PERFETTO_DCHECK(checked_scope_.is_active());
  return AddItem(key).WriteArray();
}

TracedArray TracedDictionary::AddArray(DynamicString key) {
  PERFETTO_DCHECK(checked_scope_.is_active());
  return AddItem(key).WriteArray();
}

}  // namespace perfetto
// gen_amalgamated begin source: src/tracing/tracing.cc
/*
 * Copyright (C) 2019 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// gen_amalgamated expanded: #include "perfetto/tracing/tracing.h"

#include <atomic>
#include <condition_variable>
#include <mutex>

// gen_amalgamated expanded: #include "perfetto/base/time.h"
// gen_amalgamated expanded: #include "perfetto/ext/base/no_destructor.h"
// gen_amalgamated expanded: #include "perfetto/ext/base/waitable_event.h"
// gen_amalgamated expanded: #include "perfetto/tracing/internal/track_event_internal.h"
// gen_amalgamated expanded: #include "src/tracing/internal/tracing_muxer_impl.h"

namespace perfetto {
namespace {
bool g_was_initialized = false;

// Wrapped in a function to avoid global constructor
std::mutex& InitializedMutex() {
  static base::NoDestructor<std::mutex> initialized_mutex;
  return initialized_mutex.ref();
}
}  // namespace

// static
void Tracing::InitializeInternal(const TracingInitArgs& args) {
  base::InitializeTime();
  std::unique_lock<std::mutex> lock(InitializedMutex());
  // If it's the first time Initialize is called, set some global params.
  if (!g_was_initialized) {
    // Make sure the headers and implementation files agree on the build config.
    PERFETTO_CHECK(args.dcheck_is_on_ == PERFETTO_DCHECK_IS_ON());
    if (args.log_message_callback) {
      base::SetLogMessageCallback(args.log_message_callback);
    }

    if (args.use_monotonic_clock) {
      PERFETTO_CHECK(!args.use_monotonic_raw_clock);
      internal::TrackEventInternal::SetClockId(
          protos::pbzero::BUILTIN_CLOCK_MONOTONIC);
    } else if (args.use_monotonic_raw_clock) {
      internal::TrackEventInternal::SetClockId(
          protos::pbzero::BUILTIN_CLOCK_MONOTONIC_RAW);
    }

    if (args.disallow_merging_with_system_tracks) {
      internal::TrackEventInternal::SetDisallowMergingWithSystemTracks(true);
    }
  }

  internal::TracingMuxerImpl::InitializeInstance(args);
  internal::TrackRegistry::InitializeInstance();
  g_was_initialized = true;
}

// static
bool Tracing::IsInitialized() {
  std::unique_lock<std::mutex> lock(InitializedMutex());
  return g_was_initialized;
}

// static
void Tracing::Shutdown() {
  std::unique_lock<std::mutex> lock(InitializedMutex());
  if (!g_was_initialized)
    return;
  internal::TracingMuxerImpl::Shutdown();
  g_was_initialized = false;
}

// static
void Tracing::ResetForTesting() {
  std::unique_lock<std::mutex> lock(InitializedMutex());
  if (!g_was_initialized)
    return;
  base::SetLogMessageCallback(nullptr);
  internal::TracingMuxerImpl::ResetForTesting();
  internal::TrackRegistry::ResetForTesting();
  g_was_initialized = false;
}

//  static
std::unique_ptr<TracingSession> Tracing::NewTraceInternal(
    BackendType backend,
    TracingConsumerBackend* (*system_backend_factory)()) {
  return static_cast<internal::TracingMuxerImpl*>(internal::TracingMuxer::Get())
      ->CreateTracingSession(backend, system_backend_factory);
}

//  static
std::unique_ptr<StartupTracingSession> Tracing::SetupStartupTracing(
    const TraceConfig& config,
    Tracing::SetupStartupTracingOpts opts) {
  return static_cast<internal::TracingMuxerImpl*>(internal::TracingMuxer::Get())
      ->CreateStartupTracingSession(config, std::move(opts));
}

//  static
std::unique_ptr<StartupTracingSession> Tracing::SetupStartupTracingBlocking(
    const TraceConfig& config,
    Tracing::SetupStartupTracingOpts opts) {
  return static_cast<internal::TracingMuxerImpl*>(internal::TracingMuxer::Get())
      ->CreateStartupTracingSessionBlocking(config, std::move(opts));
}

//  static
void Tracing::ActivateTriggers(const std::vector<std::string>& triggers,
                               uint32_t ttl_ms) {
  internal::TracingMuxer::Get()->ActivateTriggers(triggers, ttl_ms);
}

TracingSession::~TracingSession() = default;

// Can be called from any thread.
bool TracingSession::FlushBlocking(uint32_t timeout_ms) {
  std::atomic<bool> flush_result;
  base::WaitableEvent flush_ack;

  // The non blocking Flush() can be called on any thread. It does the PostTask
  // internally.
  Flush(
      [&flush_ack, &flush_result](bool res) {
        flush_result = res;
        flush_ack.Notify();
      },
      timeout_ms);
  flush_ack.Wait();
  return flush_result;
}

std::vector<char> TracingSession::ReadTraceBlocking() {
  std::vector<char> raw_trace;
  std::mutex mutex;
  std::condition_variable cv;

  bool all_read = false;

  ReadTrace([&mutex, &raw_trace, &all_read, &cv](ReadTraceCallbackArgs cb) {
    raw_trace.insert(raw_trace.end(), cb.data, cb.data + cb.size);
    std::unique_lock<std::mutex> lock(mutex);
    all_read = !cb.has_more;
    if (all_read)
      cv.notify_one();
  });

  {
    std::unique_lock<std::mutex> lock(mutex);
    cv.wait(lock, [&all_read] { return all_read; });
  }
  return raw_trace;
}

TracingSession::GetTraceStatsCallbackArgs
TracingSession::GetTraceStatsBlocking() {
  std::mutex mutex;
  std::condition_variable cv;
  GetTraceStatsCallbackArgs result;
  bool stats_read = false;

  GetTraceStats(
      [&mutex, &result, &stats_read, &cv](GetTraceStatsCallbackArgs args) {
        result = std::move(args);
        std::unique_lock<std::mutex> lock(mutex);
        stats_read = true;
        cv.notify_one();
      });

  {
    std::unique_lock<std::mutex> lock(mutex);
    cv.wait(lock, [&stats_read] { return stats_read; });
  }
  return result;
}

TracingSession::QueryServiceStateCallbackArgs
TracingSession::QueryServiceStateBlocking() {
  std::mutex mutex;
  std::condition_variable cv;
  QueryServiceStateCallbackArgs result;
  bool status_read = false;

  QueryServiceState(
      [&mutex, &result, &status_read, &cv](QueryServiceStateCallbackArgs args) {
        result = std::move(args);
        std::unique_lock<std::mutex> lock(mutex);
        status_read = true;
        cv.notify_one();
      });

  {
    std::unique_lock<std::mutex> lock(mutex);
    cv.wait(lock, [&status_read] { return status_read; });
  }
  return result;
}

StartupTracingSession::~StartupTracingSession() = default;

}  // namespace perfetto
// gen_amalgamated begin source: src/tracing/tracing_policy.cc
/*
 * Copyright (C) 2021 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// gen_amalgamated expanded: #include "perfetto/tracing/tracing_policy.h"

namespace perfetto {

TracingPolicy::~TracingPolicy() = default;

}  // namespace perfetto
// gen_amalgamated begin source: src/tracing/track.cc
/*
 * Copyright (C) 2019 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// gen_amalgamated expanded: #include "perfetto/tracing/track.h"

// gen_amalgamated expanded: #include "perfetto/ext/base/file_utils.h"
// gen_amalgamated expanded: #include "perfetto/ext/base/hash.h"
// gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"
// gen_amalgamated expanded: #include "perfetto/ext/base/string_splitter.h"
// gen_amalgamated expanded: #include "perfetto/ext/base/string_utils.h"
// gen_amalgamated expanded: #include "perfetto/ext/base/thread_utils.h"
// gen_amalgamated expanded: #include "perfetto/ext/base/uuid.h"
// gen_amalgamated expanded: #include "perfetto/tracing/internal/track_event_data_source.h"
// gen_amalgamated expanded: #include "perfetto/tracing/internal/track_event_internal.h"
// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/counter_descriptor.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/process_descriptor.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/process_descriptor.pbzero.h"
// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/thread_descriptor.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/thread_descriptor.pbzero.h"

namespace perfetto {

// static
uint64_t Track::process_uuid;

protos::gen::TrackDescriptor Track::Serialize() const {
  protos::gen::TrackDescriptor desc;
  desc.set_uuid(uuid);
  if (parent_uuid)
    desc.set_parent_uuid(parent_uuid);
  return desc;
}

void Track::Serialize(protos::pbzero::TrackDescriptor* desc) const {
  auto bytes = Serialize().SerializeAsString();
  desc->AppendRawProtoBytes(bytes.data(), bytes.size());
}

protos::gen::TrackDescriptor ProcessTrack::Serialize() const {
  auto desc = Track::Serialize();
  auto pd = desc.mutable_process();
  pd->set_pid(static_cast<int32_t>(pid));
#if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
    PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
  std::string cmdline;
  if (base::ReadFile("/proc/self/cmdline", &cmdline)) {
    // Since cmdline is a zero-terminated list of arguments, this ends up
    // writing just the first element, i.e., the process name, into the process
    // name field.
    pd->set_process_name(cmdline.c_str());
    base::StringSplitter splitter(std::move(cmdline), '\0');
    while (splitter.Next()) {
      pd->add_cmdline(
          std::string(splitter.cur_token(), splitter.cur_token_size()));
    }
  }
  // TODO(skyostil): Record command line on Windows and Mac.
#endif
  return desc;
}

void ProcessTrack::Serialize(protos::pbzero::TrackDescriptor* desc) const {
  auto bytes = Serialize().SerializeAsString();
  desc->AppendRawProtoBytes(bytes.data(), bytes.size());
}

protos::gen::TrackDescriptor ThreadTrack::Serialize() const {
  auto desc = Track::Serialize();
  auto td = desc.mutable_thread();
  td->set_pid(static_cast<int32_t>(pid));
  td->set_tid(static_cast<int32_t>(tid));
  if (disallow_merging_with_system_tracks) {
    desc.set_disallow_merging_with_system_tracks(true);
  }
  std::string thread_name;
  if (base::GetThreadName(thread_name))
    td->set_thread_name(thread_name);
  return desc;
}

// static
ThreadTrack ThreadTrack::Current() {
  return ThreadTrack(
      internal::TracingMuxer::Get()->GetCurrentThreadId(),
      internal::TrackEventInternal::GetDisallowMergingWithSystemTracks());
}

// static
ThreadTrack ThreadTrack::ForThread(base::PlatformThreadId tid_) {
  return ThreadTrack(
      tid_, internal::TrackEventInternal::GetDisallowMergingWithSystemTracks());
}

void ThreadTrack::Serialize(protos::pbzero::TrackDescriptor* desc) const {
  auto bytes = Serialize().SerializeAsString();
  desc->AppendRawProtoBytes(bytes.data(), bytes.size());
}

protos::gen::TrackDescriptor CounterTrack::Serialize() const {
  auto desc = Track::Serialize();
  desc.set_name(name_);
  auto* counter = desc.mutable_counter();
  if (category_)
    counter->add_categories(category_);
  if (unit_ != perfetto::protos::pbzero::CounterDescriptor::UNIT_UNSPECIFIED)
    counter->set_unit(static_cast<protos::gen::CounterDescriptor_Unit>(unit_));
  {
    // if |type| is set, we don't want to emit |unit_name|. Trace processor
    // infers the track name from the type in that case.
    if (type_ !=
        perfetto::protos::gen::CounterDescriptor::COUNTER_UNSPECIFIED) {
      counter->set_type(type_);
    } else if (unit_name_) {
      counter->set_unit_name(unit_name_);
    }
  }
  if (unit_multiplier_ != 1)
    counter->set_unit_multiplier(unit_multiplier_);
  if (is_incremental_)
    counter->set_is_incremental(is_incremental_);
  return desc;
}

void CounterTrack::Serialize(protos::pbzero::TrackDescriptor* desc) const {
  auto bytes = Serialize().SerializeAsString();
  desc->AppendRawProtoBytes(bytes.data(), bytes.size());
}

namespace internal {
namespace {

uint64_t GetProcessStartTime() {
#if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
  std::string stat;
  if (!base::ReadFile("/proc/self/stat", &stat))
    return 0u;
  // The stat file is a single line split into space-separated fields as "pid
  // (comm) state ppid ...". However because the command name can contain any
  // characters (including parentheses and spaces), we need to skip past it
  // before parsing the rest of the fields. To do that, we look for the last
  // instance of ") " (parentheses followed by space) and parse forward from
  // that point.
  size_t comm_end = stat.rfind(") ");
  if (comm_end == std::string::npos)
    return 0u;
  stat = stat.substr(comm_end + strlen(") "));
  base::StringSplitter splitter(stat, ' ');
  for (size_t skip = 0; skip < 20; skip++) {
    if (!splitter.Next())
      return 0u;
  }
  return base::CStringToUInt64(splitter.cur_token()).value_or(0u);
#else
  return 0;
#endif  // !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
}

}  // namespace

// static
TrackRegistry* TrackRegistry::instance_;

TrackRegistry::TrackRegistry() = default;
TrackRegistry::~TrackRegistry() = default;

// static
void TrackRegistry::InitializeInstance() {
  if (instance_)
    return;
  instance_ = new TrackRegistry();
  Track::process_uuid = ComputeProcessUuid();
}

// static
uint64_t TrackRegistry::ComputeProcessUuid() {
  // Use the process start time + pid as the unique identifier for this process.
  // This ensures that if there are two independent copies of the Perfetto SDK
  // in the same process (e.g., one in the app and another in a system
  // framework), events emitted by each will be consistently interleaved on
  // common thread and process tracks.
  if (uint64_t start_time = GetProcessStartTime()) {
    base::Hasher hash;
    hash.Update(start_time);
    hash.Update(Platform::GetCurrentProcessId());
    return hash.digest();
  }
  // Fall back to a randomly generated identifier.
  static uint64_t random_once = static_cast<uint64_t>(base::Uuidv4().lsb());
  return random_once;
}

void TrackRegistry::ResetForTesting() {
  instance_->tracks_.clear();
}

void TrackRegistry::UpdateTrack(Track track,
                                const std::string& serialized_desc) {
  std::lock_guard<std::mutex> lock(mutex_);
  tracks_[track.uuid] = std::move(serialized_desc);
}

void TrackRegistry::UpdateTrackImpl(
    Track track,
    std::function<void(protos::pbzero::TrackDescriptor*)> fill_function) {
  constexpr size_t kInitialSliceSize = 32;
  constexpr size_t kMaximumSliceSize = 4096;
  protozero::HeapBuffered<protos::pbzero::TrackDescriptor> new_descriptor(
      kInitialSliceSize, kMaximumSliceSize);
  fill_function(new_descriptor.get());
  auto serialized_desc = new_descriptor.SerializeAsString();
  UpdateTrack(track, serialized_desc);
}

void TrackRegistry::EraseTrack(Track track) {
  std::lock_guard<std::mutex> lock(mutex_);
  tracks_.erase(track.uuid);
}

// static
void TrackRegistry::WriteTrackDescriptor(
    const SerializedTrackDescriptor& desc,
    protozero::MessageHandle<protos::pbzero::TracePacket> packet) {
  packet->AppendString(
      perfetto::protos::pbzero::TracePacket::kTrackDescriptorFieldNumber, desc);
}

}  // namespace internal
}  // namespace perfetto
// gen_amalgamated begin source: src/tracing/track_event_category_registry.cc
/*
 * Copyright (C) 2019 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// gen_amalgamated expanded: #include "perfetto/tracing/track_event_category_registry.h"

namespace perfetto {

// static
Category Category::FromDynamicCategory(const char* name) {
  if (GetNthNameSize(1, name, name)) {
    Category group(Group(name));
    PERFETTO_DCHECK(group.name);
    return group;
  }
  Category category(name);
  PERFETTO_DCHECK(category.name);
  return category;
}

Category Category::FromDynamicCategory(
    const DynamicCategory& dynamic_category) {
  return FromDynamicCategory(dynamic_category.name.c_str());
}

namespace internal {

perfetto::DynamicCategory NullCategory(const perfetto::DynamicCategory&) {
  return perfetto::DynamicCategory{};
}

void TrackEventCategoryRegistry::EnableCategoryForInstance(
    size_t category_index,
    uint32_t instance_index) const {
  PERFETTO_DCHECK(instance_index < kMaxDataSourceInstances);
  PERFETTO_DCHECK(category_index < category_count_);
  // Matches the acquire_load in DataSource::Trace().
  state_storage_[category_index].fetch_or(
      static_cast<uint8_t>(1u << instance_index), std::memory_order_release);
}

void TrackEventCategoryRegistry::DisableCategoryForInstance(
    size_t category_index,
    uint32_t instance_index) const {
  PERFETTO_DCHECK(instance_index < kMaxDataSourceInstances);
  PERFETTO_DCHECK(category_index < category_count_);
  // Matches the acquire_load in DataSource::Trace().
  state_storage_[category_index].fetch_and(
      static_cast<uint8_t>(~(1u << instance_index)), std::memory_order_release);
}

}  // namespace internal
}  // namespace perfetto
// gen_amalgamated begin source: src/tracing/track_event_legacy.cc
/*
 * Copyright (C) 2020 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// gen_amalgamated expanded: #include "perfetto/tracing/track_event_legacy.h"
// gen_amalgamated expanded: #include "perfetto/ext/base/hash.h"

// gen_amalgamated expanded: #include "perfetto/tracing/track.h"

namespace perfetto {
namespace legacy {

template <>
ThreadTrack ConvertThreadId(const PerfettoLegacyCurrentThreadId&) {
  // Because of the short-circuit in PERFETTO_INTERNAL_LEGACY_EVENT, we should
  // never get here.
  PERFETTO_DCHECK(false);
  return ThreadTrack::Current();
}

}  // namespace legacy

namespace internal {

void LegacyTraceId::Write(protos::pbzero::TrackEvent::LegacyEvent* event,
                          uint32_t event_flags) const {
  // Legacy flow events always use bind_id.
  if (event_flags &
      (legacy::kTraceEventFlagFlowOut | legacy::kTraceEventFlagFlowIn)) {
    // Flow bind_ids don't have scopes, so we need to mangle in-process ones to
    // avoid collisions.
    if (id_flags_ & legacy::kTraceEventFlagHasLocalId) {
      event->set_bind_id(raw_id_ ^ ProcessTrack::Current().uuid);
    } else {
      event->set_bind_id(raw_id_);
    }
    return;
  }

  uint32_t scope_flags = id_flags_ & (legacy::kTraceEventFlagHasId |
                                      legacy::kTraceEventFlagHasLocalId |
                                      legacy::kTraceEventFlagHasGlobalId);
  uint64_t id = raw_id_;
  if (scope_ && scope_flags != legacy::kTraceEventFlagHasGlobalId) {
    id = base::Hasher::Combine(id, scope_);
  }

  switch (scope_flags) {
    case legacy::kTraceEventFlagHasId:
      event->set_unscoped_id(id);
      break;
    case legacy::kTraceEventFlagHasLocalId:
      event->set_local_id(id);
      break;
    case legacy::kTraceEventFlagHasGlobalId:
      event->set_global_id(id);
      break;
  }
  if (scope_)
    event->set_id_scope(scope_);
}

}  // namespace internal
}  // namespace perfetto
// gen_amalgamated begin source: src/tracing/track_event_state_tracker.cc
/*
 * Copyright (C) 2020 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// gen_amalgamated expanded: #include "perfetto/tracing/track_event_state_tracker.h"

// gen_amalgamated expanded: #include "perfetto/ext/base/hash.h"
// gen_amalgamated expanded: #include "perfetto/tracing/internal/track_event_internal.h"

// gen_amalgamated expanded: #include "protos/perfetto/common/interceptor_descriptor.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/trace/clock_snapshot.pbzero.h"
// gen_amalgamated expanded: #include "protos/perfetto/trace/interned_data/interned_data.pbzero.h"
// gen_amalgamated expanded: #include "protos/perfetto/trace/trace_packet.pbzero.h"
// gen_amalgamated expanded: #include "protos/perfetto/trace/trace_packet_defaults.pbzero.h"
// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/debug_annotation.pbzero.h"
// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/process_descriptor.pbzero.h"
// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/thread_descriptor.pbzero.h"
// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/track_descriptor.pbzero.h"
// gen_amalgamated expanded: #include "protos/perfetto/trace/track_event/track_event.pbzero.h"

namespace perfetto {

using internal::TrackEventIncrementalState;

TrackEventStateTracker::~TrackEventStateTracker() = default;
TrackEventStateTracker::Delegate::~Delegate() = default;

// static
void TrackEventStateTracker::ProcessTracePacket(
    Delegate& delegate,
    SequenceState& sequence_state,
    const protos::pbzero::TracePacket_Decoder& packet) {
  UpdateIncrementalState(delegate, sequence_state, packet);

  if (!packet.has_track_event())
    return;
  perfetto::protos::pbzero::TrackEvent::Decoder track_event(
      packet.track_event());

  auto clock_id = packet.timestamp_clock_id();
  if (!packet.has_timestamp_clock_id())
    clock_id = sequence_state.default_clock_id;
  uint64_t timestamp = packet.timestamp();
  // TODO(mohitms): Incorporate unit multiplier as well.
  if (clock_id == internal::TrackEventIncrementalState::kClockIdIncremental) {
    timestamp += sequence_state.most_recent_absolute_time_ns;
    sequence_state.most_recent_absolute_time_ns = timestamp;
  }

  Track* track = &sequence_state.track;
  if (track_event.has_track_uuid()) {
    auto* session_state = delegate.GetSessionState();
    if (!session_state)
      return;  // Tracing must have ended.
    track = &session_state->tracks[track_event.track_uuid()];
  }

  // We only log the first category of each event.
  protozero::ConstChars category{};
  uint64_t category_iid = 0;
  if (auto iid_it = track_event.category_iids()) {
    category_iid = *iid_it;
    category.data = sequence_state.event_categories[category_iid].data();
    category.size = sequence_state.event_categories[category_iid].size();
  } else if (auto cat_it = track_event.categories()) {
    category.data = reinterpret_cast<const char*>(cat_it->data());
    category.size = cat_it->size();
  }

  protozero::ConstChars name{};
  uint64_t name_iid = track_event.name_iid();
  uint64_t name_hash = 0;
  uint64_t duration = 0;
  if (name_iid) {
    name.data = sequence_state.event_names[name_iid].data();
    name.size = sequence_state.event_names[name_iid].size();
  } else if (track_event.has_name()) {
    name.data = track_event.name().data;
    name.size = track_event.name().size;
  }

  if (name.data) {
    base::Hasher hash;
    hash.Update(name.data, name.size);
    name_hash = hash.digest();
  }

  size_t depth = track->stack.size();
  switch (track_event.type()) {
    case protos::pbzero::TrackEvent::TYPE_SLICE_BEGIN: {
      StackFrame frame;
      frame.timestamp = timestamp;
      frame.name_hash = name_hash;
      if (track_event.has_track_uuid()) {
        frame.name = name.ToStdString();
        frame.category = category.ToStdString();
      } else {
        frame.name_iid = name_iid;
        frame.category_iid = category_iid;
      }
      track->stack.push_back(std::move(frame));
      break;
    }
    case protos::pbzero::TrackEvent::TYPE_SLICE_END:
      if (!track->stack.empty()) {
        const auto& prev_frame = track->stack.back();
        if (prev_frame.name_iid) {
          name.data = sequence_state.event_names[prev_frame.name_iid].data();
          name.size = sequence_state.event_names[prev_frame.name_iid].size();
        } else {
          name.data = prev_frame.name.data();
          name.size = prev_frame.name.size();
        }
        name_hash = prev_frame.name_hash;
        if (prev_frame.category_iid) {
          category.data =
              sequence_state.event_categories[prev_frame.category_iid].data();
          category.size =
              sequence_state.event_categories[prev_frame.category_iid].size();
        } else {
          category.data = prev_frame.category.data();
          category.size = prev_frame.category.size();
        }
        duration = timestamp - prev_frame.timestamp;
        depth--;
      }
      break;
    case protos::pbzero::TrackEvent::TYPE_INSTANT:
      break;
    case protos::pbzero::TrackEvent::TYPE_COUNTER:
    case protos::pbzero::TrackEvent::TYPE_UNSPECIFIED:
      // TODO(skyostil): Support counters.
      return;
  }

  ParsedTrackEvent parsed_event{track_event};
  parsed_event.timestamp_ns = timestamp;
  parsed_event.duration_ns = duration;
  parsed_event.stack_depth = depth;
  parsed_event.category = category;
  parsed_event.name = name;
  parsed_event.name_hash = name_hash;
  delegate.OnTrackEvent(*track, parsed_event);

  if (track_event.type() == protos::pbzero::TrackEvent::TYPE_SLICE_END &&
      !track->stack.empty()) {
    track->stack.pop_back();
  }
}

// static
void TrackEventStateTracker::UpdateIncrementalState(
    Delegate& delegate,
    SequenceState& sequence_state,
    const protos::pbzero::TracePacket_Decoder& packet) {
#if PERFETTO_DCHECK_IS_ON()
  if (!sequence_state.sequence_id) {
    sequence_state.sequence_id = packet.trusted_packet_sequence_id();
  } else {
    PERFETTO_DCHECK(sequence_state.sequence_id ==
                    packet.trusted_packet_sequence_id());
  }
#endif

  perfetto::protos::pbzero::ClockSnapshot::Decoder snapshot(
      packet.clock_snapshot());
  for (auto it = snapshot.clocks(); it; ++it) {
    perfetto::protos::pbzero::ClockSnapshot::Clock::Decoder clock(*it);
    // TODO(mohitms) : Handle the incremental clock other than default one.
    if (clock.is_incremental() &&
        clock.clock_id() ==
            internal::TrackEventIncrementalState::kClockIdIncremental) {
      sequence_state.most_recent_absolute_time_ns =
          clock.timestamp() * clock.unit_multiplier_ns();
      break;
    }
  }

  if (packet.sequence_flags() &
      perfetto::protos::pbzero::TracePacket::SEQ_INCREMENTAL_STATE_CLEARED) {
    // Convert any existing event names and categories on the stack to
    // non-interned strings so we can look up their names even after the
    // incremental state is gone.
    for (auto& frame : sequence_state.track.stack) {
      if (frame.name_iid) {
        frame.name = sequence_state.event_names[frame.name_iid];
        frame.name_iid = 0u;
      }
      if (frame.category_iid) {
        frame.category = sequence_state.event_categories[frame.category_iid];
        frame.category_iid = 0u;
      }
    }
    sequence_state.event_names.clear();
    sequence_state.event_categories.clear();
    sequence_state.debug_annotation_names.clear();
    sequence_state.track.uuid = 0u;
    sequence_state.track.index = 0u;
  }
  if (packet.has_interned_data()) {
    perfetto::protos::pbzero::InternedData::Decoder interned_data(
        packet.interned_data());
    for (auto it = interned_data.event_names(); it; it++) {
      perfetto::protos::pbzero::EventName::Decoder entry(*it);
      sequence_state.event_names[entry.iid()] = entry.name().ToStdString();
    }
    for (auto it = interned_data.event_categories(); it; it++) {
      perfetto::protos::pbzero::EventCategory::Decoder entry(*it);
      sequence_state.event_categories[entry.iid()] = entry.name().ToStdString();
    }
    for (auto it = interned_data.debug_annotation_names(); it; it++) {
      perfetto::protos::pbzero::DebugAnnotationName::Decoder entry(*it);
      sequence_state.debug_annotation_names[entry.iid()] =
          entry.name().ToStdString();
    }
  }
  if (packet.has_trace_packet_defaults()) {
    perfetto::protos::pbzero::TracePacketDefaults::Decoder defaults(
        packet.trace_packet_defaults());
    if (defaults.has_track_event_defaults()) {
      perfetto::protos::pbzero::TrackEventDefaults::Decoder
          track_event_defaults(defaults.track_event_defaults());
      sequence_state.track.uuid = track_event_defaults.track_uuid();
      if (defaults.has_timestamp_clock_id())
        sequence_state.default_clock_id = defaults.timestamp_clock_id();
    }
  }
  if (packet.has_track_descriptor()) {
    perfetto::protos::pbzero::TrackDescriptor::Decoder track_descriptor(
        packet.track_descriptor());
    auto* session_state = delegate.GetSessionState();
    auto& track = session_state->tracks[track_descriptor.uuid()];
    if (!track.index)
      track.index = static_cast<uint32_t>(session_state->tracks.size() + 1);
    track.uuid = track_descriptor.uuid();

    track.name = track_descriptor.name().ToStdString();
    track.pid = 0;
    track.tid = 0;
    if (track_descriptor.has_process()) {
      perfetto::protos::pbzero::ProcessDescriptor::Decoder process(
          track_descriptor.process());
      track.pid = process.pid();
      if (track.name.empty())
        track.name = process.process_name().ToStdString();
    } else if (track_descriptor.has_thread()) {
      perfetto::protos::pbzero::ThreadDescriptor::Decoder thread(
          track_descriptor.thread());
      track.pid = thread.pid();
      track.tid = thread.tid();
      if (track.name.empty())
        track.name = thread.thread_name().ToStdString();
    }
    delegate.OnTrackUpdated(track);

    // Mirror properties to the default track of the sequence. Note that
    // this does not catch updates to the default track written through other
    // sequences.
    if (track.uuid == sequence_state.track.uuid) {
      sequence_state.track.index = track.index;
      sequence_state.track.name = track.name;
      sequence_state.track.pid = track.pid;
      sequence_state.track.tid = track.tid;
      sequence_state.track.user_data = track.user_data;
    }
  }
}

TrackEventStateTracker::ParsedTrackEvent::ParsedTrackEvent(
    const perfetto::protos::pbzero::TrackEvent::Decoder& track_event_)
    : track_event(track_event_) {}

}  // namespace perfetto
// gen_amalgamated begin source: src/tracing/virtual_destructors.cc
/*
 * Copyright (C) 2019 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// gen_amalgamated expanded: #include "perfetto/tracing/internal/tracing_tls.h"
// gen_amalgamated expanded: #include "perfetto/tracing/tracing.h"
// gen_amalgamated expanded: #include "perfetto/tracing/tracing_backend.h"

// This translation unit contains the definitions for the destructor of pure
// virtual interfaces for the src/public:public target. The alternative would be
// introducing a one-liner .cc file for each pure virtual interface, which is
// overkill. This is for compliance with -Wweak-vtables.

namespace perfetto {
namespace internal {

TracingTLS::~TracingTLS() {
  // Avoid entering trace points while the thread is being torn down.
  // This is the problem: when a thread exits, the at-thread-exit destroys the
  // TracingTLS. As part of that the various TraceWriter for the active data
  // sources are destroyd. A TraceWriter dtor will issue a PostTask on the IPC
  // thread to issue a final flush and unregister its ID with the service.
  // The PostTask, in chromium, might have a trace event that will try to
  // re-enter the tracing system.
  // We fix this by resetting the TLS key to the TracingTLS object that is
  // being destroyed in the platform impl (platform_posix.cc,
  // platform_windows.cc, chromium's platform.cc). We carefully rely on the fact
  // that all the tracing path that will be invoked during thread exit will
  // early out if |is_in_trace_point| == true and will not depend on the other
  // TLS state that has been destroyed.
  is_in_trace_point = true;
}

}  // namespace internal

TracingProducerBackend::~TracingProducerBackend() = default;
TracingConsumerBackend::~TracingConsumerBackend() = default;
TracingBackend::~TracingBackend() = default;

}  // namespace perfetto
// gen_amalgamated begin source: src/android_stats/statsd_logging_helper.cc
// gen_amalgamated begin header: src/android_stats/statsd_logging_helper.h
// gen_amalgamated begin header: src/android_stats/perfetto_atoms.h
/*
 * Copyright (C) 2020 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef SRC_ANDROID_STATS_PERFETTO_ATOMS_H_
#define SRC_ANDROID_STATS_PERFETTO_ATOMS_H_

namespace perfetto {

// This must match the values of the PerfettoUploadEvent enum in:
// frameworks/proto_logging/stats/atoms.proto
enum class PerfettoStatsdAtom {
  kUndefined = 0,

  // Checkpoints inside perfetto_cmd before tracing is finished.
  kTraceBegin = 1,
  kBackgroundTraceBegin = 2,
  kOnConnect = 3,

  // Guardrails inside perfetto_cmd before tracing is finished.
  kOnTimeout = 16,
  kCmdUserBuildTracingNotAllowed = 43,

  // Checkpoints inside traced.
  kTracedEnableTracing = 37,
  kTracedStartTracing = 38,
  kTracedDisableTracing = 39,
  kTracedNotifyTracingDisabled = 40,

  // Trigger checkpoints inside traced.
  // These atoms are special because, along with the UUID,
  // they log the trigger name.
  kTracedTriggerStartTracing = 41,
  kTracedTriggerStopTracing = 42,
  kTracedTriggerCloneSnapshot = 53,

  // Guardrails inside traced.
  kTracedEnableTracingExistingTraceSession = 18,
  kTracedEnableTracingTooLongTrace = 19,
  kTracedEnableTracingInvalidTriggerTimeout = 20,
  kTracedEnableTracingDurationWithTrigger = 21,
  kTracedEnableTracingStopTracingWriteIntoFile = 22,
  kTracedEnableTracingDuplicateTriggerName = 23,
  kTracedEnableTracingInvalidDeferredStart = 24,
  kTracedEnableTracingInvalidBufferSize = 25,
  kTracedEnableTracingBufferSizeTooLarge = 26,
  kTracedEnableTracingTooManyBuffers = 27,
  kTracedEnableTracingDuplicateSessionName = 28,
  kTracedEnableTracingSessionNameTooRecent = 29,
  kTracedEnableTracingTooManySessionsForUid = 30,
  kTracedEnableTracingTooManyConcurrentSessions = 31,
  kTracedEnableTracingInvalidFdOutputFile = 32,
  kTracedEnableTracingFailedToCreateFile = 33,
  kTracedEnableTracingOom = 34,
  kTracedEnableTracingUnknown = 35,
  kTracedStartTracingInvalidSessionState = 36,
  kTracedEnableTracingInvalidFilter = 47,
  kTracedEnableTracingOobTargetBuffer = 48,
  kTracedEnableTracingInvalidTriggerMode = 52,
  kTracedEnableTracingInvalidBrFilename = 54,

  // Checkpoints inside perfetto_cmd after tracing has finished.
  kOnTracingDisabled = 4,
  kFinalizeTraceAndExit = 11,
  kCmdFwReportBegin = 49,
  // Will be removed once incidentd is no longer used.
  kUploadIncidentBegin = 8,
  kNotUploadingEmptyTrace = 17,

  // Guardrails inside perfetto_cmd after tracing has finished.
  kCmdFwReportEmptyTrace = 50,
  // Will be removed once incidentd is no longer used.
  kUploadIncidentFailure = 10,

  // "Successful" terminal states inside perfetto_cmd.
  kCmdFwReportHandoff = 51,

  // Deprecated as "success" is misleading; it simply means we were
  // able to communicate with incidentd. Will be removed once
  // incidentd is no longer used.
  kUploadIncidentSuccess = 9,

  // Contained trigger begin/success/failure. Replaced by
  // |PerfettoTriggerAtom| to allow aggregation using a count metric
  // and reduce spam.
  // reserved 12, 13, 14;

  // Contained that a guardrail in perfetto_cmd was hit. Replaced with
  // kCmd* guardrails.
  // reserved 15;

  // Contained status of Dropbox uploads. Removed as Perfetto no
  // longer supports uploading traces using Dropbox.
  // reserved 5, 6, 7;

  // Contained status of guardrail state initalization and upload limit in
  // perfetto_cmd. Removed as perfetto no longer manages stateful guardrails
  // reserved 44, 45, 46;
};

// This must match the values of the PerfettoTrigger::TriggerType enum in:
// frameworks/proto_logging/stats/atoms.proto
enum PerfettoTriggerAtom {
  kUndefined = 0,

  kCmdTrigger = 1,
  kCmdTriggerFail = 2,

  kTriggerPerfettoTrigger = 3,
  kTriggerPerfettoTriggerFail = 4,

  kTracedLimitProbability = 5,
  kTracedLimitMaxPer24h = 6,

  kProbesProducerTrigger = 7,
  kProbesProducerTriggerFail = 8,
};

}  // namespace perfetto

#endif  // SRC_ANDROID_STATS_PERFETTO_ATOMS_H_
/*
 * Copyright (C) 2020 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef SRC_ANDROID_STATS_STATSD_LOGGING_HELPER_H_
#define SRC_ANDROID_STATS_STATSD_LOGGING_HELPER_H_

#include <stdint.h>
#include <string>
#include <vector>

// gen_amalgamated expanded: #include "src/android_stats/perfetto_atoms.h"

namespace perfetto {
namespace android_stats {

// Functions in this file are only active on built in the Android
// tree. On other platforms (including Android standalone and Chromium
// on Android) these functions are a noop.

// Logs the upload event to statsd if built in the Android tree.
void MaybeLogUploadEvent(PerfettoStatsdAtom atom,
                         int64_t uuid_lsb,
                         int64_t uuid_msb,
                         const std::string& trigger_name = "");

// Logs the trigger events to statsd if built in the Android tree.
void MaybeLogTriggerEvent(PerfettoTriggerAtom atom, const std::string& trigger);

// Logs the trigger events to statsd if built in the Android tree.
void MaybeLogTriggerEvents(PerfettoTriggerAtom atom,
                           const std::vector<std::string>& triggers);

}  // namespace android_stats
}  // namespace perfetto

#endif  // SRC_ANDROID_STATS_STATSD_LOGGING_HELPER_H_
/*
 * Copyright (C) 2020 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// gen_amalgamated expanded: #include "src/android_stats/statsd_logging_helper.h"

#include <string>

// gen_amalgamated expanded: #include "perfetto/base/build_config.h"
// gen_amalgamated expanded: #include "perfetto/base/compiler.h"

#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) && \
    PERFETTO_BUILDFLAG(PERFETTO_ANDROID_BUILD)
// gen_amalgamated expanded: #include "src/android_internal/lazy_library_loader.h"  // nogncheck
// gen_amalgamated expanded: #include "src/android_internal/statsd_logging.h"       // nogncheck
#endif

namespace perfetto {
namespace android_stats {

// Make sure we don't accidentally log on non-Android tree build. Note that even
// removing this ifdef still doesn't make uploads work on OS_ANDROID.
// PERFETTO_LAZY_LOAD will return a nullptr on non-Android and non-in-tree
// builds as libperfetto_android_internal will not be available.
#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) && \
    PERFETTO_BUILDFLAG(PERFETTO_ANDROID_BUILD)

void MaybeLogUploadEvent(PerfettoStatsdAtom atom,
                         int64_t uuid_lsb,
                         int64_t uuid_msb,
                         const std::string& trigger_name) {
  PERFETTO_LAZY_LOAD(android_internal::StatsdLogUploadEvent, log_event_fn);
  if (log_event_fn) {
    log_event_fn(atom, uuid_lsb, uuid_msb, trigger_name.c_str());
  }
}

void MaybeLogTriggerEvent(PerfettoTriggerAtom atom,
                          const std::string& trigger_name) {
  PERFETTO_LAZY_LOAD(android_internal::StatsdLogTriggerEvent, log_event_fn);
  if (log_event_fn) {
    log_event_fn(atom, trigger_name.c_str());
  }
}

void MaybeLogTriggerEvents(PerfettoTriggerAtom atom,
                           const std::vector<std::string>& triggers) {
  PERFETTO_LAZY_LOAD(android_internal::StatsdLogTriggerEvent, log_event_fn);
  if (log_event_fn) {
    for (const std::string& trigger_name : triggers) {
      log_event_fn(atom, trigger_name.c_str());
    }
  }
}

#else
void MaybeLogUploadEvent(PerfettoStatsdAtom,
                         int64_t,
                         int64_t,
                         const std::string&) {}
void MaybeLogTriggerEvent(PerfettoTriggerAtom, const std::string&) {}
void MaybeLogTriggerEvents(PerfettoTriggerAtom,
                           const std::vector<std::string>&) {}
#endif

}  // namespace android_stats
}  // namespace perfetto
// gen_amalgamated begin source: src/base/version.cc
// gen_amalgamated begin header: include/perfetto/ext/base/version.h
/*
 * Copyright (C) 2020 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef INCLUDE_PERFETTO_EXT_BASE_VERSION_H_
#define INCLUDE_PERFETTO_EXT_BASE_VERSION_H_

namespace perfetto {
namespace base {

// The returned pointer is a static string and safe to pass around.
// Returns a human readable string currently of the approximate form:
// Perfetto v42.1-deadbeef0 (deadbeef03c641e4b4ea9cf38e9b5696670175a9)
// However you should not depend on the format of this string.
// It maybe not be possible to determine the version. In which case the
// string will be of the approximate form:
// Perfetto v0.0 (unknown)
const char* GetVersionString();

// The returned pointer is a static string and safe to pass around.
// Returns the short code used to identity the version:
// v42.1-deadbeef0
// It maybe not be possible to determine the version. In which case
// this returns nullptr.
// This can be compared with equality to other
// version codes to detect matched builds (for example to see if
// trace_processor_shell and the UI were built at the same revision)
// but you should not attempt to parse it as the format may change
// without warning.
const char* GetVersionCode();

}  // namespace base
}  // namespace perfetto

#endif  // INCLUDE_PERFETTO_EXT_BASE_VERSION_H_
// gen_amalgamated begin header: gen/perfetto_version.gen.h
// Generated by write_version_header.py

#ifndef GEN_PERFETTO_VERSION_GEN_H_
#define GEN_PERFETTO_VERSION_GEN_H_

#define PERFETTO_VERSION_STRING() "v45.0-3252c170d"
#define PERFETTO_VERSION_SCM_REVISION() "3252c170da369d935b34d93a9f5906e6ab890cdf"

#endif  // GEN_PERFETTO_VERSION_GEN_H_
/*
 * Copyright (C) 2020 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// gen_amalgamated expanded: #include "perfetto/ext/base/version.h"

// gen_amalgamated expanded: #include "perfetto/base/build_config.h"

#include <stdio.h>

#if PERFETTO_BUILDFLAG(PERFETTO_VERSION_GEN)
// gen_amalgamated expanded: #include "perfetto_version.gen.h"
#else
#define PERFETTO_VERSION_STRING() nullptr
#define PERFETTO_VERSION_SCM_REVISION() "unknown"
#endif

namespace perfetto {
namespace base {

const char* GetVersionCode() {
  return PERFETTO_VERSION_STRING();
}

const char* GetVersionString() {
  static const char* version_str = [] {
    static constexpr size_t kMaxLen = 256;
    const char* version_code = PERFETTO_VERSION_STRING();
    if (version_code == nullptr) {
      version_code = "v0.0";
    }
    char* version = new char[kMaxLen + 1];
    snprintf(version, kMaxLen, "Perfetto %s (%s)", version_code,
             PERFETTO_VERSION_SCM_REVISION());
    return version;
  }();
  return version_str;
}

}  // namespace base
}  // namespace perfetto
// gen_amalgamated begin source: src/protozero/filtering/filter_bytecode_parser.cc
// gen_amalgamated begin header: src/protozero/filtering/filter_bytecode_parser.h
/*
 * Copyright (C) 2021 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef SRC_PROTOZERO_FILTERING_FILTER_BYTECODE_PARSER_H_
#define SRC_PROTOZERO_FILTERING_FILTER_BYTECODE_PARSER_H_

#include <stddef.h>
#include <stdint.h>

#include <optional>
#include <vector>

namespace protozero {

// Loads the proto-encoded bytecode in memory and allows fast lookups for tuples
// (msg_index, field_id) to tell if a given field should be allowed or not and,
// in the case of nested fields, what is the next message index to recurse into.
// This class does two things:
// 1. Expands the array of varint from the proto into a vector<uint32_t>. This
//    is to avoid performing varint decoding on every lookup, at the cost of
//    some extra memory (2KB-4KB). Note that the expanded vector is not just a
//    1:1 copy of the proto one (more below). This is to avoid O(Fields) linear
//    lookup complexity.
// 2. Creates an index of offsets to remember the start word for each message.
//    This is so we can jump to O(1) to the N-th message when recursing into a
//    nested fields, without having to scan and find the (N-1)-th END_OF_MESSAGE
//    marker.
// Overall lookups are O(1) for field ids < 128 (kDirectlyIndexLimit) and O(N),
// with N being the number of allowed field ranges for other fields.
// See comments around |word_| below for the structure of the word vector.
class FilterBytecodeParser {
 public:
  // Result of a Query() operation
  struct QueryResult {
    bool allowed;  // Whether the field is allowed at all or no.

    // If |allowed|==true && nested_msg_field() == true, this tells the message
    // index of the nested field that should be used when recursing in the
    // parser.
    uint32_t nested_msg_index;

    // If |allowed|==true, specifies if the field is of a simple type (varint,
    // fixed32/64, string or byte).
    bool simple_field() const { return nested_msg_index == kSimpleField; }

    // If |allowed|==true, specifies if this field is a string field that needs
    // to be filtered.
    bool filter_string_field() const {
      return nested_msg_index == kFilterStringField;
    }

    // If |allowed|==true, specifies if the field is a nested field that needs
    // recursion. The caller is expected to use |nested_msg_index| for the next
    // Query() calls.
    bool nested_msg_field() const {
      static_assert(kFilterStringField < kSimpleField,
                    "kFilterStringField < kSimpleField");
      return nested_msg_index < kFilterStringField;
    }
  };

  // Loads a filter. The filter data consists of a sequence of varints which
  // contains the filter opcodes and a final checksum.
  bool Load(const void* filter_data, size_t len);

  // Checks wheter a given field is allowed or not.
  // msg_index = 0 is the index of the root message, where all queries should
  // start from (typically perfetto.protos.Trace).
  QueryResult Query(uint32_t msg_index, uint32_t field_id) const;

  void Reset();
  void set_suppress_logs_for_fuzzer(bool x) { suppress_logs_for_fuzzer_ = x; }

 private:
  static constexpr uint32_t kDirectlyIndexLimit = 128;
  static constexpr uint32_t kAllowed = 1u << 31u;
  static constexpr uint32_t kSimpleField = 0x7fffffff;
  static constexpr uint32_t kFilterStringField = 0x7ffffffe;

  bool LoadInternal(const uint8_t* filter_data, size_t len);

  // The state of all fields for all messages is stored in one contiguous array.
  // This is to avoid memory fragmentation and allocator overhead.
  // We expect a high number of messages (hundreds), but each message is small.
  // For each message we store two sets of uint32:
  // 1. A set of "directly indexed" fields, for field ids < 128.
  // 2. The remainder is a set of ranges.
  // So each message descriptor consists of a sequence of words as follows:
  //
  // [0] -> how many directly indexed fields are stored next (up to 128)
  //
  // [1..N] -> One word per field id (See "field state" below).
  //
  // [N + 1] -> Start of field id range 1
  // [N + 2] -> End of field id range 1 (exclusive, STL-style).
  // [N + 3] -> Field state for fields in range 1 (below)
  //
  // [N + 4] -> Start of field id range 2
  // [N + 5] -> End of field id range 2 (exclusive, STL-style).
  // [N + 6] -> Field state for fields in range 2 (below)

  // The "field state" word is as follows:
  // Bit 31: 1 if the field is allowed, 0 if disallowed.
  //         Only directly indexed fields can be 0 (it doesn't make sense to add
  //         a range and then say "btw it's NOT allowed".. don't add it then.
  //         0 is only used for filling gaps in the directly indexed bucket.
  // Bits [30..0] (only when MSB == allowed):
  //  0x7fffffff: The field is "simple" (varint, fixed32/64, string, bytes) and
  //      can be directly passed through in output. No recursion is needed.
  //  0x7ffffffe: The field is string field which needs to be filtered.
  //  [0, 7ffffffd]: The field is a nested submessage. The value is the index
  //     that must be passed as first argument to the next Query() calls.
  //     Note that the message index is purely a monotonic counter in the
  std::vector<uint32_t> words_;

  // One entry for each message index stored in the filter plus a sentinel at
  // the end. Maps each message index to the offset in |words_| where the
  // Nth message start.
  // message_offset_.size() - 2 == the max message id that can be parsed.
  std::vector<uint32_t> message_offset_;

  bool suppress_logs_for_fuzzer_ = false;
};

}  // namespace protozero

#endif  // SRC_PROTOZERO_FILTERING_FILTER_BYTECODE_PARSER_H_
// gen_amalgamated begin header: src/protozero/filtering/filter_bytecode_common.h
/*
 * Copyright (C) 2021 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef SRC_PROTOZERO_FILTERING_FILTER_BYTECODE_COMMON_H_
#define SRC_PROTOZERO_FILTERING_FILTER_BYTECODE_COMMON_H_

#include <stdint.h>

namespace protozero {

enum FilterOpcode : uint32_t {
  // The immediate value is 0 in this case.
  kFilterOpcode_EndOfMessage = 0,

  // The immediate value is the id of the allowed field.
  kFilterOpcode_SimpleField = 1,

  // The immediate value is the start of the range. The next word (without
  // any shifting) is the length of the range.
  kFilterOpcode_SimpleFieldRange = 2,

  // The immediate value is the id of the allowed field. The next word
  // (without any shifting) is the index of the filter that should be used to
  // recurse into the nested message.
  kFilterOpcode_NestedField = 3,

  // The imediate value is the id of the allowed field. The behaviour of this
  // opcode is the same as kFilterOpcode_SimpleField, with the further semantic
  // that the field is a string and needs to be processed using the string
  // filtering fules.
  kFilterOpcode_FilterString = 4,
};

}  // namespace protozero

#endif  // SRC_PROTOZERO_FILTERING_FILTER_BYTECODE_COMMON_H_
/*
 * Copyright (C) 2021 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// gen_amalgamated expanded: #include "src/protozero/filtering/filter_bytecode_parser.h"

// gen_amalgamated expanded: #include "perfetto/base/logging.h"
// gen_amalgamated expanded: #include "perfetto/ext/base/hash.h"
// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
// gen_amalgamated expanded: #include "src/protozero/filtering/filter_bytecode_common.h"

namespace protozero {

void FilterBytecodeParser::Reset() {
  bool suppress = suppress_logs_for_fuzzer_;
  *this = FilterBytecodeParser();
  suppress_logs_for_fuzzer_ = suppress;
}

bool FilterBytecodeParser::Load(const void* filter_data, size_t len) {
  Reset();
  bool res = LoadInternal(static_cast<const uint8_t*>(filter_data), len);
  // If load fails, don't leave the parser in a half broken state.
  if (!res)
    Reset();
  return res;
}

bool FilterBytecodeParser::LoadInternal(const uint8_t* bytecode_data,
                                        size_t len) {
  // First unpack the varints into a plain uint32 vector, so it's easy to
  // iterate through them and look ahead.
  std::vector<uint32_t> words;
  bool packed_parse_err = false;
  words.reserve(len);  // An overestimation, but avoids reallocations.
  using BytecodeDecoder =
      PackedRepeatedFieldIterator<proto_utils::ProtoWireType::kVarInt,
                                  uint32_t>;
  for (BytecodeDecoder it(bytecode_data, len, &packed_parse_err); it; ++it)
    words.emplace_back(*it);

  if (packed_parse_err || words.empty())
    return false;

  perfetto::base::Hasher hasher;
  for (size_t i = 0; i < words.size() - 1; ++i)
    hasher.Update(words[i]);

  uint32_t expected_csum = static_cast<uint32_t>(hasher.digest());
  if (expected_csum != words.back()) {
    if (!suppress_logs_for_fuzzer_) {
      PERFETTO_ELOG("Filter bytecode checksum failed. Expected: %x, actual: %x",
                    expected_csum, words.back());
    }
    return false;
  }

  words.pop_back();  // Pop the checksum.

  // Temporay storage for each message. Cleared on every END_OF_MESSAGE.
  std::vector<uint32_t> direct_indexed_fields;
  std::vector<uint32_t> ranges;
  uint32_t max_msg_index = 0;

  auto add_directly_indexed_field = [&](uint32_t field_id, uint32_t msg_id) {
    PERFETTO_DCHECK(field_id > 0 && field_id < kDirectlyIndexLimit);
    direct_indexed_fields.resize(std::max(direct_indexed_fields.size(),
                                          static_cast<size_t>(field_id) + 1));
    direct_indexed_fields[field_id] = kAllowed | msg_id;
  };

  auto add_range = [&](uint32_t id_start, uint32_t id_end, uint32_t msg_id) {
    PERFETTO_DCHECK(id_end > id_start);
    PERFETTO_DCHECK(id_start >= kDirectlyIndexLimit);
    ranges.emplace_back(id_start);
    ranges.emplace_back(id_end);
    ranges.emplace_back(kAllowed | msg_id);
  };

  bool is_eom = true;
  for (size_t i = 0; i < words.size(); ++i) {
    const uint32_t word = words[i];
    const bool has_next_word = i < words.size() - 1;
    const uint32_t opcode = word & 0x7u;
    const uint32_t field_id = word >> 3;

    is_eom = opcode == kFilterOpcode_EndOfMessage;
    if (field_id == 0 && opcode != kFilterOpcode_EndOfMessage) {
      PERFETTO_DLOG("bytecode error @ word %zu, invalid field id (0)", i);
      return false;
    }

    if (opcode == kFilterOpcode_SimpleField ||
        opcode == kFilterOpcode_NestedField ||
        opcode == kFilterOpcode_FilterString) {
      // Field words are organized as follow:
      // MSB: 1 if allowed, 0 if not allowed.
      // Remaining bits:
      //   Message index in the case of nested (non-simple) messages.
      //   0x7f..e in the case of string fields which need filtering.
      //   0x7f..f in the case of simple fields.
      uint32_t msg_id;
      if (opcode == kFilterOpcode_SimpleField) {
        msg_id = kSimpleField;
      } else if (opcode == kFilterOpcode_FilterString) {
        msg_id = kFilterStringField;
      } else {  // FILTER_OPCODE_NESTED_FIELD
        // The next word in the bytecode contains the message index.
        if (!has_next_word) {
          PERFETTO_DLOG("bytecode error @ word %zu: unterminated nested field",
                        i);
          return false;
        }
        msg_id = words[++i];
        max_msg_index = std::max(max_msg_index, msg_id);
      }

      if (field_id < kDirectlyIndexLimit) {
        add_directly_indexed_field(field_id, msg_id);
      } else {
        // In the case of a large field id (rare) we waste an extra word and
        // represent it as a range. Doesn't make sense to introduce extra
        // complexity to deal with rare cases like this.
        add_range(field_id, field_id + 1, msg_id);
      }
    } else if (opcode == kFilterOpcode_SimpleFieldRange) {
      if (!has_next_word) {
        PERFETTO_DLOG("bytecode error @ word %zu: unterminated range", i);
        return false;
      }
      const uint32_t range_len = words[++i];
      const uint32_t range_end = field_id + range_len;  // STL-style, excl.
      uint32_t id = field_id;

      // Here's the subtle complexity: at the bytecode level, we don't know
      // anything about the kDirectlyIndexLimit. It is legit to define a range
      // that spans across the direct-indexing threshold (e.g. 126-132). In that
      // case we want to add all the elements < the indexing to the O(1) bucket
      // and add only the remaining range as a non-indexed range.
      for (; id < range_end && id < kDirectlyIndexLimit; ++id)
        add_directly_indexed_field(id, kAllowed | kSimpleField);
      PERFETTO_DCHECK(id >= kDirectlyIndexLimit || id == range_end);
      if (id < range_end)
        add_range(id, range_end, kSimpleField);
    } else if (opcode == kFilterOpcode_EndOfMessage) {
      // For each message append:
      // 1. The "header" word telling how many directly indexed fields there
      //    are.
      // 2. The words for the directly indexed fields (id < 128).
      // 3. The rest of the fields, encoded as ranges.
      // Also update the |message_offset_| index to remember the word offset for
      // the current message.
      message_offset_.emplace_back(static_cast<uint32_t>(words_.size()));
      words_.emplace_back(static_cast<uint32_t>(direct_indexed_fields.size()));
      words_.insert(words_.end(), direct_indexed_fields.begin(),
                    direct_indexed_fields.end());
      words_.insert(words_.end(), ranges.begin(), ranges.end());
      direct_indexed_fields.clear();
      ranges.clear();
    } else {
      PERFETTO_DLOG("bytecode error @ word %zu: invalid opcode (%x)", i, word);
      return false;
    }
  }  // (for word in bytecode).

  if (!is_eom) {
    PERFETTO_DLOG(
        "bytecode error: end of message not the last word in the bytecode");
    return false;
  }

  if (max_msg_index > 0 && max_msg_index >= message_offset_.size()) {
    PERFETTO_DLOG(
        "bytecode error: a message index (%u) is out of range "
        "(num_messages=%zu)",
        max_msg_index, message_offset_.size());
    return false;
  }

  // Add a final entry to |message_offset_| so we can tell where the last
  // message ends without an extra branch in the Query() hotpath.
  message_offset_.emplace_back(static_cast<uint32_t>(words_.size()));

  return true;
}

FilterBytecodeParser::QueryResult FilterBytecodeParser::Query(
    uint32_t msg_index,
    uint32_t field_id) const {
  FilterBytecodeParser::QueryResult res{false, 0u};
  if (static_cast<uint64_t>(msg_index) + 1 >=
      static_cast<uint64_t>(message_offset_.size())) {
    return res;
  }
  const uint32_t start_offset = message_offset_[msg_index];
  // These are DCHECKs and not just CHECKS because the |words_| is populated
  // by the LoadInternal call above. These cannot be violated with a malformed
  // bytecode.
  PERFETTO_DCHECK(start_offset < words_.size());
  const uint32_t* word = &words_[start_offset];
  const uint32_t end_off = message_offset_[msg_index + 1];
  const uint32_t* const end = words_.data() + end_off;
  PERFETTO_DCHECK(end > word && end <= words_.data() + words_.size());
  const uint32_t num_directly_indexed = *(word++);
  PERFETTO_DCHECK(num_directly_indexed <= kDirectlyIndexLimit);
  PERFETTO_DCHECK(word + num_directly_indexed <= end);
  uint32_t field_state = 0;
  if (PERFETTO_LIKELY(field_id < num_directly_indexed)) {
    PERFETTO_DCHECK(&word[field_id] < end);
    field_state = word[field_id];
  } else {
    for (word = word + num_directly_indexed; word + 2 < end;) {
      const uint32_t range_start = *(word++);
      const uint32_t range_end = *(word++);
      const uint32_t range_state = *(word++);
      if (field_id >= range_start && field_id < range_end) {
        field_state = range_state;
        break;
      }
    }  // for (word in ranges)
  }    // if (field_id >= num_directly_indexed)

  res.allowed = (field_state & kAllowed) != 0;
  res.nested_msg_index = field_state & ~kAllowed;
  PERFETTO_DCHECK(!res.nested_msg_field() ||
                  res.nested_msg_index < message_offset_.size() - 1);
  return res;
}

}  // namespace protozero
// gen_amalgamated begin source: src/protozero/filtering/string_filter.cc
// gen_amalgamated begin header: src/protozero/filtering/string_filter.h
/*
 * Copyright (C) 2023 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef SRC_PROTOZERO_FILTERING_STRING_FILTER_H_
#define SRC_PROTOZERO_FILTERING_STRING_FILTER_H_

#include <regex>
#include <string>
#include <string_view>

namespace protozero {

// Performs filtering of strings in an "iptables" style. See the comments in
// |TraceConfig.TraceFilter| for information on how this class works.
class StringFilter {
 public:
  enum class Policy {
    kMatchRedactGroups = 1,
    kAtraceMatchRedactGroups = 2,
    kMatchBreak = 3,
    kAtraceMatchBreak = 4,
    kAtraceRepeatedSearchRedactGroups = 5,
  };

  // Adds a new rule for filtering strings.
  void AddRule(Policy policy,
               std::string_view pattern,
               std::string atrace_payload_starts_with);

  // Tries to filter the given string. Returns true if the string was modified
  // in any way, false otherwise.
  bool MaybeFilter(char* ptr, size_t len) const {
    if (len == 0 || rules_.empty()) {
      return false;
    }
    return MaybeFilterInternal(ptr, len);
  }

 private:
  struct Rule {
    Policy policy;
    std::regex pattern;
    std::string atrace_payload_starts_with;
  };

  bool MaybeFilterInternal(char* ptr, size_t len) const;

  std::vector<Rule> rules_;
};

}  // namespace protozero

#endif  // SRC_PROTOZERO_FILTERING_STRING_FILTER_H_
/*
 * Copyright (C) 2023 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// gen_amalgamated expanded: #include "src/protozero/filtering/string_filter.h"

#include <cstring>
#include <regex>
#include <string_view>

// gen_amalgamated expanded: #include "perfetto/base/compiler.h"
// gen_amalgamated expanded: #include "perfetto/base/logging.h"
// gen_amalgamated expanded: #include "perfetto/ext/base/string_view.h"
// gen_amalgamated expanded: #include "perfetto/public/compiler.h"

namespace protozero {
namespace {

using Matches = std::match_results<char*>;

static constexpr std::string_view kRedacted = "P60REDACTED";
static constexpr char kRedactedDash = '-';

// Returns a pointer to the first character after the tgid pipe character in
// the atrace string given by [ptr, end). Returns null if no such character
// exists.
//
// Examples:
// E|1024 -> nullptr
// foobarbaz -> nullptr
// B|1024|x -> pointer to x
const char* FindAtracePayloadPtr(const char* ptr, const char* end) {
  // Don't even bother checking any strings which are so short that they could
  // not contain a post-tgid section. This filters out strings like "E|" which
  // emitted by Bionic.
  //
  // Also filter out any other strings starting with "E" as they never contain
  // anything past the tgid: this removes >half of the strings for ~zero cost.
  static constexpr size_t kEarliestSecondPipeIndex = 2;
  const char* search_start = ptr + kEarliestSecondPipeIndex;
  if (search_start >= end || *ptr == 'E') {
    return nullptr;
  }

  // We skipped past the first '|' character by starting at the character at
  // index 2. Just find the next pipe character (i.e. the one after tgid) using
  // memchr.
  const char* pipe = static_cast<const char*>(
      memchr(search_start, '|', size_t(end - search_start)));
  return pipe ? pipe + 1 : nullptr;
}

bool StartsWith(const char* ptr,
                const char* end,
                const std::string& starts_with) {
  // Verify that the atrace string has enough characters to match against all
  // the characters in the "starts with" string. If it does, memcmp to check if
  // all the characters match and return true if they do.
  return ptr + starts_with.size() <= end &&
         memcmp(ptr, starts_with.data(), starts_with.size()) == 0;
}

void RedactMatches(const Matches& matches) {
  // Go through every group in the matches.
  for (size_t i = 1; i < matches.size(); ++i) {
    const auto& match = matches[i];
    PERFETTO_CHECK(match.second >= match.first);

    // Overwrite the match with characters from |kRedacted|. If match is
    // smaller, we will not use all of |kRedacted| but that's fine (i.e. we
    // will overwrite with a truncated |kRedacted|).
    size_t match_len = static_cast<size_t>(match.second - match.first);
    size_t redacted_len = std::min(match_len, kRedacted.size());
    memcpy(match.first, kRedacted.data(), redacted_len);

    // Overwrite any characters after |kRedacted| with |kRedactedDash|.
    memset(match.first + redacted_len, kRedactedDash, match_len - redacted_len);
  }
}

}  // namespace

void StringFilter::AddRule(Policy policy,
                           std::string_view pattern_str,
                           std::string atrace_payload_starts_with) {
  rules_.emplace_back(StringFilter::Rule{
      policy,
      std::regex(pattern_str.begin(), pattern_str.end(),
                 std::regex::ECMAScript | std::regex_constants::optimize),
      std::move(atrace_payload_starts_with)});
}

bool StringFilter::MaybeFilterInternal(char* ptr, size_t len) const {
  std::match_results<char*> matches;
  bool atrace_find_tried = false;
  const char* atrace_payload_ptr = nullptr;
  for (const Rule& rule : rules_) {
    switch (rule.policy) {
      case Policy::kMatchRedactGroups:
      case Policy::kMatchBreak:
        if (std::regex_match(ptr, ptr + len, matches, rule.pattern)) {
          if (rule.policy == Policy::kMatchBreak) {
            return false;
          }
          RedactMatches(matches);
          return true;
        }
        break;
      case Policy::kAtraceMatchRedactGroups:
      case Policy::kAtraceMatchBreak:
        atrace_payload_ptr = atrace_find_tried
                                 ? atrace_payload_ptr
                                 : FindAtracePayloadPtr(ptr, ptr + len);
        atrace_find_tried = true;
        if (atrace_payload_ptr &&
            StartsWith(atrace_payload_ptr, ptr + len,
                       rule.atrace_payload_starts_with) &&
            std::regex_match(ptr, ptr + len, matches, rule.pattern)) {
          if (rule.policy == Policy::kAtraceMatchBreak) {
            return false;
          }
          RedactMatches(matches);
          return true;
        }
        break;
      case Policy::kAtraceRepeatedSearchRedactGroups:
        atrace_payload_ptr = atrace_find_tried
                                 ? atrace_payload_ptr
                                 : FindAtracePayloadPtr(ptr, ptr + len);
        atrace_find_tried = true;
        if (atrace_payload_ptr && StartsWith(atrace_payload_ptr, ptr + len,
                                             rule.atrace_payload_starts_with)) {
          auto beg = std::regex_iterator<char*>(ptr, ptr + len, rule.pattern);
          auto end = std::regex_iterator<char*>();
          bool has_any_matches = beg != end;
          for (auto it = std::move(beg); it != end; ++it) {
            RedactMatches(*it);
          }
          if (has_any_matches) {
            return true;
          }
        }
        break;
    }
  }
  return false;
}

}  // namespace protozero
// gen_amalgamated begin source: src/protozero/filtering/message_filter.cc
// gen_amalgamated begin header: src/protozero/filtering/message_filter.h
// gen_amalgamated begin header: src/protozero/filtering/message_tokenizer.h
/*
 * Copyright (C) 2021 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef SRC_PROTOZERO_FILTERING_MESSAGE_TOKENIZER_H_
#define SRC_PROTOZERO_FILTERING_MESSAGE_TOKENIZER_H_

#include <stdint.h>

// gen_amalgamated expanded: #include "perfetto/base/compiler.h"
// gen_amalgamated expanded: #include "perfetto/base/logging.h"
// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"

namespace protozero {

// A helper class for schema-less tokenizing of protobuf messages.
// This class takes a stream of proto-encoded bytes, pushed one by one in input
// via Push(octet), and returns a stream of tokens (each Push() call can return
// 0 or 1 token).
// A "token" contains metadata about a field, specifically: its ID, its wire
// type and:
//  - For varint and fixed32/64 fields: its payload.
//  - For string and bytes fields: the length of its payload.
//    In this case the caller is supposed to "eat" those N bytes before calling
//    Push() again.
// Note that this class cannot differentiate between a string/bytes field or
// a submessage, because they are encoded in the same way. The caller is
// supposed to know whether a field can be recursed into by just keep calling
// Push() or is a string that should be skipped.
// This is inline to allow the compiler to see through the Push method and
// avoid a function call for each byte.
class MessageTokenizer {
 public:
  struct Token {
    uint32_t field_id;  // 0 == not valid.
    proto_utils::ProtoWireType type;

    // For kLengthDelimited, |value| represent the length of the payload.
    uint64_t value;

    inline bool valid() const { return field_id != 0; }
    bool operator==(const Token& o) const {
      return field_id == o.field_id && type == o.type && value == o.value;
    }
  };

  // Pushes a byte in input and returns a token, only when getting to the last
  // byte of each field. Specifically:
  // - For varint and fixed32 fields, the Token is returned after the last byte
  //   of the numeric payload is pushed.
  // - For length-delimited fields, this returns after the last byte of the
  //   length is pushed (i.e. right before the payload starts). The caller is
  //   expected to either skip the next |value| bytes (in the case of a string
  //   or bytes fields) or keep calling Push, in the case of a submessage.
  inline Token Push(uint8_t octet) {
    using protozero::proto_utils::ProtoWireType;

    // Parsing a fixed32/64 field is the only case where we don't have to do
    // any varint decoding. This is why this block is before the remaining
    // switch statement below (all the rest is a varint).
    if (PERFETTO_UNLIKELY(state_ == kFixedIntValue)) {
      PERFETTO_DCHECK(fixed_int_bits_ == 32 || fixed_int_bits_ == 64);
      fixed_int_value_ |= static_cast<uint64_t>(octet) << fixed_int_shift_;
      fixed_int_shift_ += 8;
      if (fixed_int_shift_ < fixed_int_bits_)
        return Token{};  // Intermediate byte of a fixed32/64.
      auto wire_type = fixed_int_bits_ == 32 ? ProtoWireType::kFixed32
                                             : ProtoWireType::kFixed64;
      uint64_t fixed_int_value = fixed_int_value_;
      fixed_int_value_ = fixed_int_shift_ = fixed_int_bits_ = 0;
      state_ = kFieldPreamble;
      return Token{field_id_, wire_type, fixed_int_value};
    }

    // At this point either we are: (i) parsing a field preamble; (ii) parsing a
    // varint field paylod; (iii) parsing the length of a length-delimited
    // field. In all cases, we need to decode a varint before proceeding.
    varint_ |= static_cast<uint64_t>(octet & 0x7F) << varint_shift_;
    if (octet & 0x80) {
      varint_shift_ += 7;
      if (PERFETTO_UNLIKELY(varint_shift_ >= 64)) {
        varint_shift_ = 0;
        state_ = kInvalidVarInt;
      }
      return Token{};  // Still parsing a varint.
    }

    uint64_t varint = varint_;
    varint_ = 0;
    varint_shift_ = 0;

    switch (state_) {
      case kFieldPreamble: {
        auto field_type = static_cast<uint32_t>(varint & 7u);  // 7 = 0..0111
        field_id_ = static_cast<uint32_t>(varint >> 3);

        // The field type is legit, now check it's well formed and within
        // boundaries.
        if (field_type == static_cast<uint32_t>(ProtoWireType::kVarInt)) {
          state_ = kVarIntValue;
        } else if (field_type ==
                       static_cast<uint32_t>(ProtoWireType::kFixed32) ||
                   field_type ==
                       static_cast<uint32_t>(ProtoWireType::kFixed64)) {
          state_ = kFixedIntValue;
          fixed_int_shift_ = 0;
          fixed_int_value_ = 0;
          fixed_int_bits_ =
              field_type == static_cast<uint32_t>(ProtoWireType::kFixed32) ? 32
                                                                           : 64;
        } else if (field_type ==
                   static_cast<uint32_t>(ProtoWireType::kLengthDelimited)) {
          state_ = kLenDelimited;
        } else {
          state_ = kInvalidFieldType;
        }
        return Token{};
      }

      case kVarIntValue: {
        // Return the varint field payload and go back to the next field.
        state_ = kFieldPreamble;
        return Token{field_id_, ProtoWireType::kVarInt, varint};
      }

      case kLenDelimited: {
        const auto payload_len = varint;
        if (payload_len > protozero::proto_utils::kMaxMessageLength) {
          state_ = kMessageTooBig;
          return Token{};
        }
        state_ = kFieldPreamble;
        // At this point the caller is expected to consume the next
        // |payload_len| bytes.
        return Token{field_id_, ProtoWireType::kLengthDelimited, payload_len};
      }

      case kFixedIntValue:
        // Unreacheable because of the if before the switch.
        PERFETTO_DCHECK(false);
        break;

      // Unrecoverable error states.
      case kInvalidFieldType:
      case kMessageTooBig:
      case kInvalidVarInt:
        break;
    }  // switch(state_)

    return Token{};  // Keep GCC happy.
  }

  // Returns true if the tokenizer FSM has reached quiescence (i.e. if we are
  // NOT in the middle of parsing a field).
  bool idle() const {
    return state_ == kFieldPreamble && varint_shift_ == 0 &&
           fixed_int_shift_ == 0;
  }

  // Only for reporting parser errors in the trace.
  uint32_t state() const { return static_cast<uint32_t>(state_); }

 private:
  enum State {
    kFieldPreamble = 0,  // Parsing the varint for the field preamble.
    kVarIntValue = 1,    // Parsing the payload of a varint field.
    kFixedIntValue = 2,  // Parsing the payload of a fixed32/64 field.
    kLenDelimited = 3,   // Parsing the length of a length-delimited field.

    // Unrecoverable error states:
    kInvalidFieldType = 4,  // Encountered an invalid field type.
    kMessageTooBig = 5,     // Size of the length delimited message was too big.
    kInvalidVarInt = 6,     // Varint larger than 64 bits.
  };

  State state_ = kFieldPreamble;
  uint32_t field_id_ = 0;
  uint64_t varint_ = 0;
  uint32_t varint_shift_ = 0;
  uint32_t fixed_int_shift_ = 0;
  uint32_t fixed_int_bits_ = 0;
  uint64_t fixed_int_value_ = 0;
};

}  // namespace protozero

#endif  // SRC_PROTOZERO_FILTERING_MESSAGE_TOKENIZER_H_
/*
 * Copyright (C) 2021 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef SRC_PROTOZERO_FILTERING_MESSAGE_FILTER_H_
#define SRC_PROTOZERO_FILTERING_MESSAGE_FILTER_H_

#include <stdint.h>

#include <memory>
#include <string>
#include <unordered_map>

// gen_amalgamated expanded: #include "src/protozero/filtering/filter_bytecode_parser.h"
// gen_amalgamated expanded: #include "src/protozero/filtering/message_tokenizer.h"
// gen_amalgamated expanded: #include "src/protozero/filtering/string_filter.h"

namespace protozero {

// A class to filter binary-encoded proto messages using an allow-list of field
// ids, also known as "filter bytecode". The filter determines which fields are
// allowed to be passed through in output and strips all the other fields.
// See go/trace-filtering for full design.
// This class takes in input:
// 1) The filter bytecode, loaded once via the LoadFilterBytecode() method.
// 2) A proto-encoded binary message. The message doesn't have to be contiguous,
//    it can be passed as an array of arbitrarily chunked fragments.
// The FilterMessage*() method returns in output a proto message, stripping out
// all unknown fields. If the input is malformed (e.g., unknown proto field wire
// types, lengths out of bound) the whole filtering failed and the |error| flag
// of the FilteredMessage object is set to true.
// The filtering operation is based on rewriting a copy of the message into a
// self-allocated buffer, which is then returned in the output. The input buffer
// is NOT altered.
// Note also that the process of rewriting the protos gets rid of most redundant
// varint encoding (if present). So even if all fields are allow-listed, the
// output might NOT be bitwise identical to the input (but it will be
// semantically equivalent).
// Furthermore the enable_field_usage_tracking() method allows to keep track of
// a histogram of allowed / denied fields. It slows down filtering and is
// intended only on host tools.
class MessageFilter {
 public:
  class Config {
   public:
    bool LoadFilterBytecode(const void* filter_data, size_t len);
    bool SetFilterRoot(std::initializer_list<uint32_t> field_ids);

    const FilterBytecodeParser& filter() const { return filter_; }
    const StringFilter& string_filter() const { return string_filter_; }
    StringFilter& string_filter() { return string_filter_; }
    uint32_t root_msg_index() const { return root_msg_index_; }

   private:
    FilterBytecodeParser filter_;
    StringFilter string_filter_;
    uint32_t root_msg_index_ = 0;
  };

  MessageFilter();
  explicit MessageFilter(Config);
  ~MessageFilter();

  struct InputSlice {
    const void* data;
    size_t len;
  };

  struct FilteredMessage {
    FilteredMessage(std::unique_ptr<uint8_t[]> d, size_t s)
        : data(std::move(d)), size(s) {}
    std::unique_ptr<uint8_t[]> data;
    size_t size;  // The used bytes in |data|. This is <= sizeof(data).
    bool error = false;
  };

  // Loads the filter bytecode that will be used to filter any subsequent
  // message. Must be called before the first call to FilterMessage*().
  // |filter_data| must point to a byte buffer for a proto-encoded ProtoFilter
  // message (see proto_filter.proto).
  bool LoadFilterBytecode(const void* filter_data, size_t len) {
    return config_.LoadFilterBytecode(filter_data, len);
  }

  // This affects the filter starting point of the subsequent FilterMessage*()
  // calls. By default the filtering process starts from the message @ index 0,
  // the root message passed to proto_filter when generating the bytecode
  // (in typical tracing use-cases, this is perfetto.protos.Trace). However, the
  // caller (TracingServiceImpl) might want to filter packets from the 2nd level
  // (perfetto.protos.TracePacket) because the root level is pre-pended after
  // the fact. This call allows to change the root message for the filter.
  // The argument |field_ids| is an array of proto field ids and determines the
  // path to the new root. For instance, in the case of [1,2,3] SetFilterRoot
  // will identify the sub-message for the field "root.1.2.3" and use that.
  // In order for this to succeed all the fields in the path must be allowed
  // in the filter and must be a nested message type.
  bool SetFilterRoot(std::initializer_list<uint32_t> field_ids) {
    return config_.SetFilterRoot(field_ids);
  }

  // Takes an input message, fragmented in arbitrary slices, and returns a
  // filtered message in output.
  FilteredMessage FilterMessageFragments(const InputSlice*, size_t num_slices);

  // Helper for tests, where the input is a contiguous buffer.
  FilteredMessage FilterMessage(const void* data, size_t len) {
    InputSlice slice{data, len};
    return FilterMessageFragments(&slice, 1);
  }

  // When enabled returns a map of "field path" to "usage counter".
  // The key (std::string) is a binary buffer (i.e. NOT an ASCII/UTF-8 string)
  // which contains a varint for each field. Consider the following:
  // message Root { Sub1 f1 = 1; };
  // message Sub1 { Sub2 f2 = 7;}
  // message Sub2 { string f3 = 5; }
  // The field .f1.f2.f3 will be encoded as \x01\0x07\x05.
  // The value is the number of times that field has been encountered. If the
  // field is not allow-listed in the bytecode (the field is stripped in output)
  // the count will be negative.
  void enable_field_usage_tracking(bool x) { track_field_usage_ = x; }
  const std::unordered_map<std::string, int32_t>& field_usage() const {
    return field_usage_;
  }

  const Config& config() const { return config_; }

  // Retuns the helper class used to perform string filtering.
  StringFilter& string_filter() { return config_.string_filter(); }

 private:
  // This is called by FilterMessageFragments().
  // Inlining allows the compiler turn the per-byte call/return into a for loop,
  // while, at the same time, keeping the code easy to read and reason about.
  // It gives a 20-25% speedup (265ms vs 215ms for a 25MB trace).
  void FilterOneByte(uint8_t octet) PERFETTO_ALWAYS_INLINE;

  // No-inline because this is a slowpath (only when usage tracking is enabled).
  void IncrementCurrentFieldUsage(uint32_t field_id,
                                  bool allowed) PERFETTO_NO_INLINE;

  // Gets into an error state which swallows all the input and emits no output.
  void SetUnrecoverableErrorState();

  // We keep track of the nest of messages in a stack. Each StackState
  // object corresponds to a level of nesting in the proto message structure.
  // Every time a new field of type len-delimited that has a corresponding
  // sub-message in the bytecode is encountered, a new StackState is pushed in
  // |stack_|. stack_[0] is a sentinel to prevent over-popping without adding
  // extra branches in the fastpath.
  // |stack_|. stack_[1] is the state of the root message.
  struct StackState {
    uint32_t in_bytes = 0;  // Number of input bytes processed.

    // When |in_bytes| reaches this value, the current state should be popped.
    // This is set when recursing into nested submessages. This is 0 only for
    // stack_[0] (we don't know the size of the root message upfront).
    uint32_t in_bytes_limit = 0;

    // This is set when a len-delimited message is encountered, either a string
    // or a nested submessage that is NOT allow-listed in the bytecode.
    // This causes input bytes to be consumed without being parsed from the
    // input stream. If |passthrough_eaten_bytes| == true, they will be copied
    // as-is in output (e.g. in the case of an allowed string/bytes field).
    uint32_t eat_next_bytes = 0;

    // Keeps tracks of the stream_writer output counter (out_.written()) then
    // the StackState is pushed. This is used to work out, when popping, how
    // many bytes have been written for the current submessage.
    uint32_t out_bytes_written_at_start = 0;

    uint32_t field_id = 0;   // The proto field id for the current message.
    uint32_t msg_index = 0;  // The index of the message filter in the bytecode.

    // This is a pointer to the proto preamble for the current submessage
    // (it's nullptr for stack_[0] and non-null elsewhere). This will be filled
    // with the actual size of the message (out_.written() -
    // |out_bytes_written_at_start|) when finishing (popping) the message.
    // This must be filled using WriteRedundantVarint(). Note that the
    // |size_field_len| is variable and depends on the actual length of the
    // input message. If the output message has roughly the same size of the
    // input message, the length will not be redundant.
    // In other words: the length of the field is reserved when the submessage
    // starts. At that point we know the upper-bound for the output message
    // (a filtered submessage can be <= the original one, but not >). So we
    // reserve as many bytes it takes to write the input length in varint.
    // Then, when the message is finalized and we know the actual output size
    // we backfill the field.
    // Consider the example of a submessage where the input size = 130 (>127,
    // 2 varint bytes) and the output is 120 bytes. The length will be 2 bytes
    // wide even though could have been encoded with just one byte.
    uint8_t* size_field = nullptr;
    uint32_t size_field_len = 0;

    // The pointer to the start of the string to update the string if it is
    // filtered.
    uint8_t* filter_string_ptr = nullptr;

    // How |eat_next_bytes| should be handled. It seems that keeping this field
    // at the end rather than next to |eat_next_bytes| makes the filter a little
    // (but measurably) faster. (likely something related with struct layout vs
    // cache sizes).
    enum FilterAction {
      kDrop,
      kPassthrough,
      kFilterString,
    };
    FilterAction action = FilterAction::kDrop;
  };

  uint32_t out_written() { return static_cast<uint32_t>(out_ - &out_buf_[0]); }

  Config config_;

  std::unique_ptr<uint8_t[]> out_buf_;
  uint8_t* out_ = nullptr;
  uint8_t* out_end_ = nullptr;

  MessageTokenizer tokenizer_;
  std::vector<StackState> stack_;

  bool error_ = false;
  bool track_field_usage_ = false;
  std::unordered_map<std::string, int32_t> field_usage_;
};

}  // namespace protozero

#endif  // SRC_PROTOZERO_FILTERING_MESSAGE_FILTER_H_
/*
 * Copyright (C) 2021 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// gen_amalgamated expanded: #include "src/protozero/filtering/message_filter.h"

// gen_amalgamated expanded: #include "perfetto/base/logging.h"
// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"
// gen_amalgamated expanded: #include "src/protozero/filtering/string_filter.h"

namespace protozero {

namespace {

// Inline helpers to append proto fields in output. They are the equivalent of
// the protozero::Message::AppendXXX() fields but don't require building and
// maintaining a full protozero::Message object or dealing with scattered
// output slices.
// All these functions assume there is enough space in the output buffer, which
// should be always the case assuming that we don't end up generating more
// output than input.

inline void AppendVarInt(uint32_t field_id, uint64_t value, uint8_t** out) {
  *out = proto_utils::WriteVarInt(proto_utils::MakeTagVarInt(field_id), *out);
  *out = proto_utils::WriteVarInt(value, *out);
}

// For fixed32 / fixed64.
template <typename INT_T /* uint32_t | uint64_t*/>
inline void AppendFixed(uint32_t field_id, INT_T value, uint8_t** out) {
  *out = proto_utils::WriteVarInt(proto_utils::MakeTagFixed<INT_T>(field_id),
                                  *out);
  memcpy(*out, &value, sizeof(value));
  *out += sizeof(value);
}

// For length-delimited (string, bytes) fields. Note: this function appends only
// the proto preamble and the varint field that states the length of the payload
// not the payload itself.
// In the case of submessages, the caller needs to re-write the length at the
// end in the in the returned memory area.
// The problem here is that, because of filtering, the length of a submessage
// might be < original length (the original length is still an upper-bound).
// Returns a pair with: (1) the pointer where the final length should be written
// into, (2) the length of the size field.
// The caller must write a redundant varint to match the original size (i.e.
// needs to use WriteRedundantVarInt()).
inline std::pair<uint8_t*, uint32_t> AppendLenDelim(uint32_t field_id,
                                                    uint32_t len,
                                                    uint8_t** out) {
  *out = proto_utils::WriteVarInt(proto_utils::MakeTagLengthDelimited(field_id),
                                  *out);
  uint8_t* size_field_start = *out;
  *out = proto_utils::WriteVarInt(len, *out);
  const size_t size_field_len = static_cast<size_t>(*out - size_field_start);
  return std::make_pair(size_field_start, size_field_len);
}
}  // namespace

MessageFilter::MessageFilter(Config config) : config_(std::move(config)) {
  // Push a state on the stack for the implicit root message.
  stack_.emplace_back();
}

MessageFilter::MessageFilter() : MessageFilter(Config()) {}

MessageFilter::~MessageFilter() = default;

bool MessageFilter::Config::LoadFilterBytecode(const void* filter_data,
                                               size_t len) {
  return filter_.Load(filter_data, len);
}

bool MessageFilter::Config::SetFilterRoot(
    std::initializer_list<uint32_t> field_ids) {
  uint32_t root_msg_idx = 0;
  for (uint32_t field_id : field_ids) {
    auto res = filter_.Query(root_msg_idx, field_id);
    if (!res.allowed || !res.nested_msg_field())
      return false;
    root_msg_idx = res.nested_msg_index;
  }
  root_msg_index_ = root_msg_idx;
  return true;
}

MessageFilter::FilteredMessage MessageFilter::FilterMessageFragments(
    const InputSlice* slices,
    size_t num_slices) {
  // First compute the upper bound for the output. The filtered message cannot
  // be > the original message.
  uint32_t total_len = 0;
  for (size_t i = 0; i < num_slices; ++i)
    total_len += slices[i].len;
  out_buf_.reset(new uint8_t[total_len]);
  out_ = out_buf_.get();
  out_end_ = out_ + total_len;

  // Reset the parser state.
  tokenizer_ = MessageTokenizer();
  error_ = false;
  stack_.clear();
  stack_.resize(2);
  // stack_[0] is a sentinel and should never be hit in nominal cases. If we
  // end up there we will just keep consuming the input stream and detecting
  // at the end, without hurting the fastpath.
  stack_[0].in_bytes_limit = UINT32_MAX;
  stack_[0].eat_next_bytes = UINT32_MAX;
  // stack_[1] is the actual root message.
  stack_[1].in_bytes_limit = total_len;
  stack_[1].msg_index = config_.root_msg_index();

  // Process the input data and write the output.
  for (size_t slice_idx = 0; slice_idx < num_slices; ++slice_idx) {
    const InputSlice& slice = slices[slice_idx];
    const uint8_t* data = static_cast<const uint8_t*>(slice.data);
    for (size_t i = 0; i < slice.len; ++i)
      FilterOneByte(data[i]);
  }

  // Construct the output object.
  PERFETTO_CHECK(out_ >= out_buf_.get() && out_ <= out_end_);
  auto used_size = static_cast<size_t>(out_ - out_buf_.get());
  FilteredMessage res{std::move(out_buf_), used_size};
  res.error = error_;
  if (stack_.size() != 1 || !tokenizer_.idle() ||
      stack_[0].in_bytes != total_len) {
    res.error = true;
  }
  return res;
}

void MessageFilter::FilterOneByte(uint8_t octet) {
  PERFETTO_DCHECK(!stack_.empty());

  auto* state = &stack_.back();
  StackState next_state{};
  bool push_next_state = false;

  if (state->eat_next_bytes > 0) {
    // This is the case where the previous tokenizer_.Push() call returned a
    // length delimited message which is NOT a submessage (a string or a bytes
    // field). We just want to consume it, and pass it through/filter strings
    // if the field was allowed.
    --state->eat_next_bytes;
    if (state->action == StackState::kPassthrough) {
      *(out_++) = octet;
    } else if (state->action == StackState::kFilterString) {
      *(out_++) = octet;
      if (state->eat_next_bytes == 0) {
        config_.string_filter().MaybeFilter(
            reinterpret_cast<char*>(state->filter_string_ptr),
            static_cast<size_t>(out_ - state->filter_string_ptr));
      }
    }
  } else {
    MessageTokenizer::Token token = tokenizer_.Push(octet);
    // |token| will not be valid() in most cases and this is WAI. When pushing
    // a varint field, only the last byte yields a token, all the other bytes
    // return an invalid token, they just update the internal tokenizer state.
    if (token.valid()) {
      auto filter = config_.filter().Query(state->msg_index, token.field_id);
      switch (token.type) {
        case proto_utils::ProtoWireType::kVarInt:
          if (filter.allowed && filter.simple_field())
            AppendVarInt(token.field_id, token.value, &out_);
          break;
        case proto_utils::ProtoWireType::kFixed32:
          if (filter.allowed && filter.simple_field())
            AppendFixed(token.field_id, static_cast<uint32_t>(token.value),
                        &out_);
          break;
        case proto_utils::ProtoWireType::kFixed64:
          if (filter.allowed && filter.simple_field())
            AppendFixed(token.field_id, static_cast<uint64_t>(token.value),
                        &out_);
          break;
        case proto_utils::ProtoWireType::kLengthDelimited:
          // Here we have two cases:
          // A. A simple string/bytes field: we just want to consume the next
          //    bytes (the string payload), optionally passing them through in
          //    output if the field is allowed.
          // B. This is a nested submessage. In this case we want to recurse and
          //    push a new state on the stack.
          // Note that we can't tell the difference between a
          // "non-allowed string" and a "non-allowed submessage". But it doesn't
          // matter because in both cases we just want to skip the next N bytes.
          const auto submessage_len = static_cast<uint32_t>(token.value);
          auto in_bytes_left = state->in_bytes_limit - state->in_bytes - 1;
          if (PERFETTO_UNLIKELY(submessage_len > in_bytes_left)) {
            // This is a malicious / malformed string/bytes/submessage that
            // claims to be larger than the outer message that contains it.
            return SetUnrecoverableErrorState();
          }

          if (filter.allowed && filter.nested_msg_field() &&
              submessage_len > 0) {
            // submessage_len == 0 is the edge case of a message with a 0-len
            // (but present) submessage. In this case, if allowed, we don't want
            // to push any further state (doing so would desync the FSM) but we
            // still want to emit it.
            // At this point |submessage_len| is only an upper bound. The
            // final message written in output can be <= the one in input,
            // only some of its fields might be allowed (also remember that
            // this class implicitly removes redundancy varint encoding of
            // len-delimited field lengths). The final length varint (the
            // return value of AppendLenDelim()) will be filled when popping
            // from |stack_|.
            auto size_field =
                AppendLenDelim(token.field_id, submessage_len, &out_);
            push_next_state = true;
            next_state.field_id = token.field_id;
            next_state.msg_index = filter.nested_msg_index;
            next_state.in_bytes_limit = submessage_len;
            next_state.size_field = size_field.first;
            next_state.size_field_len = size_field.second;
            next_state.out_bytes_written_at_start = out_written();
          } else {
            // A string or bytes field, or a 0 length submessage.
            state->eat_next_bytes = submessage_len;
            if (filter.allowed && filter.filter_string_field()) {
              state->action = StackState::kFilterString;
              AppendLenDelim(token.field_id, submessage_len, &out_);
              state->filter_string_ptr = out_;
            } else if (filter.allowed) {
              state->action = StackState::kPassthrough;
              AppendLenDelim(token.field_id, submessage_len, &out_);
            } else {
              state->action = StackState::kDrop;
            }
          }
          break;
      }  // switch(type)

      if (PERFETTO_UNLIKELY(track_field_usage_)) {
        IncrementCurrentFieldUsage(token.field_id, filter.allowed);
      }
    }  // if (token.valid)
  }    // if (eat_next_bytes == 0)

  ++state->in_bytes;
  while (state->in_bytes >= state->in_bytes_limit) {
    PERFETTO_DCHECK(state->in_bytes == state->in_bytes_limit);
    push_next_state = false;

    // We can't possibly write more than we read.
    const uint32_t msg_bytes_written = static_cast<uint32_t>(
        out_written() - state->out_bytes_written_at_start);
    PERFETTO_DCHECK(msg_bytes_written <= state->in_bytes_limit);

    // Backfill the length field of the
    proto_utils::WriteRedundantVarInt(msg_bytes_written, state->size_field,
                                      state->size_field_len);

    const uint32_t in_bytes_processes_for_last_msg = state->in_bytes;
    stack_.pop_back();
    PERFETTO_CHECK(!stack_.empty());
    state = &stack_.back();
    state->in_bytes += in_bytes_processes_for_last_msg;
    if (PERFETTO_UNLIKELY(!tokenizer_.idle())) {
      // If we hit this case, it means that we got to the end of a submessage
      // while decoding a field. We can't recover from this and we don't want to
      // propagate a broken sub-message.
      return SetUnrecoverableErrorState();
    }
  }

  if (push_next_state) {
    PERFETTO_DCHECK(tokenizer_.idle());
    stack_.emplace_back(std::move(next_state));
    state = &stack_.back();
  }
}

void MessageFilter::SetUnrecoverableErrorState() {
  error_ = true;
  stack_.clear();
  stack_.resize(1);
  auto& state = stack_[0];
  state.eat_next_bytes = UINT32_MAX;
  state.in_bytes_limit = UINT32_MAX;
  state.action = StackState::kDrop;
  out_ = out_buf_.get();  // Reset the write pointer.
}

void MessageFilter::IncrementCurrentFieldUsage(uint32_t field_id,
                                               bool allowed) {
  // Slowpath. Used mainly in offline tools and tests to workout used fields in
  // a proto.
  PERFETTO_DCHECK(track_field_usage_);

  // Field path contains a concatenation of varints, one for each nesting level.
  // e.g. y in message Root { Sub x = 2; }; message Sub { SubSub y = 7; }
  // is encoded as [varint(2) + varint(7)].
  // We use varint to take the most out of SSO (small string opt). In most cases
  // the path will fit in the on-stack 22 bytes, requiring no heap.
  std::string field_path;

  auto append_field_id = [&field_path](uint32_t id) {
    uint8_t buf[10];
    uint8_t* end = proto_utils::WriteVarInt(id, buf);
    field_path.append(reinterpret_cast<char*>(buf),
                      static_cast<size_t>(end - buf));
  };

  // Append all the ancestors IDs from the state stack.
  // The first entry of the stack has always ID 0 and we skip it (we don't know
  // the ID of the root message itself).
  PERFETTO_DCHECK(stack_.size() >= 2 && stack_[1].field_id == 0);
  for (size_t i = 2; i < stack_.size(); ++i)
    append_field_id(stack_[i].field_id);
  // Append the id of the field in the current message.
  append_field_id(field_id);
  field_usage_[field_path] += allowed ? 1 : -1;
}

}  // namespace protozero
// gen_amalgamated begin source: src/tracing/service/metatrace_writer.cc
// gen_amalgamated begin header: src/tracing/service/metatrace_writer.h
/*
 * Copyright (C) 2019 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef SRC_TRACING_SERVICE_METATRACE_WRITER_H_
#define SRC_TRACING_SERVICE_METATRACE_WRITER_H_

#include <functional>
#include <memory>

// gen_amalgamated expanded: #include "perfetto/ext/base/metatrace.h"
// gen_amalgamated expanded: #include "perfetto/ext/base/thread_checker.h"
// gen_amalgamated expanded: #include "perfetto/ext/base/weak_ptr.h"

namespace perfetto {

namespace base {
class TaskRunner;
}

class TraceWriter;

// Complements the base::metatrace infrastructure.
// It hooks a callback to metatrace::Enable() and writes metatrace events into
// a TraceWriter whenever the metatrace ring buffer is half full.
// It is safe to create and attempt to start multiple instances of this class,
// however only the first one will succeed because the metatrace framework
// doesn't support multiple instances.
// This class is defined here (instead of directly in src/probes/) so it can
// be reused by other components (e.g. heapprofd).
class MetatraceWriter {
 public:
  static constexpr char kDataSourceName[] = "perfetto.metatrace";

  MetatraceWriter();
  ~MetatraceWriter();

  MetatraceWriter(const MetatraceWriter&) = delete;
  MetatraceWriter& operator=(const MetatraceWriter&) = delete;
  MetatraceWriter(MetatraceWriter&&) = delete;
  MetatraceWriter& operator=(MetatraceWriter&&) = delete;

  void Enable(base::TaskRunner*, std::unique_ptr<TraceWriter>, uint32_t tags);
  void Disable();
  void WriteAllAndFlushTraceWriter(std::function<void()> callback);

 private:
  void WriteAllAvailableEvents();

  bool started_ = false;
  base::TaskRunner* task_runner_ = nullptr;
  std::unique_ptr<TraceWriter> trace_writer_;
  PERFETTO_THREAD_CHECKER(thread_checker_)
  base::WeakPtrFactory<MetatraceWriter> weak_ptr_factory_;  // Keep last.
};

}  // namespace perfetto

#endif  // SRC_TRACING_SERVICE_METATRACE_WRITER_H_
/*
 * Copyright (C) 2019 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// gen_amalgamated expanded: #include "src/tracing/service/metatrace_writer.h"

// gen_amalgamated expanded: #include "perfetto/base/logging.h"
// gen_amalgamated expanded: #include "perfetto/base/task_runner.h"
// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/trace_writer.h"
// gen_amalgamated expanded: #include "perfetto/tracing/core/data_source_descriptor.h"

// gen_amalgamated expanded: #include "protos/perfetto/trace/perfetto/perfetto_metatrace.pbzero.h"
// gen_amalgamated expanded: #include "protos/perfetto/trace/trace_packet.pbzero.h"

namespace perfetto {

MetatraceWriter::MetatraceWriter() : weak_ptr_factory_(this) {}

MetatraceWriter::~MetatraceWriter() {
  Disable();
}

void MetatraceWriter::Enable(base::TaskRunner* task_runner,
                             std::unique_ptr<TraceWriter> trace_writer,
                             uint32_t tags) {
  PERFETTO_DCHECK_THREAD(thread_checker_);
  if (started_) {
    PERFETTO_DFATAL_OR_ELOG("Metatrace already started from this instance");
    return;
  }
  task_runner_ = task_runner;
  trace_writer_ = std::move(trace_writer);
  auto weak_ptr = weak_ptr_factory_.GetWeakPtr();
  bool enabled = metatrace::Enable(
      [weak_ptr] {
        if (weak_ptr)
          weak_ptr->WriteAllAvailableEvents();
      },
      task_runner, tags);
  if (!enabled)
    return;
  started_ = true;
}

void MetatraceWriter::Disable() {
  PERFETTO_DCHECK_THREAD(thread_checker_);
  if (!started_)
    return;
  metatrace::Disable();
  started_ = false;
  trace_writer_.reset();
}

void MetatraceWriter::WriteAllAvailableEvents() {
  PERFETTO_DCHECK_THREAD(thread_checker_);
  if (!started_)
    return;
  for (auto it = metatrace::RingBuffer::GetReadIterator(); it; ++it) {
    auto type_and_id = it->type_and_id.load(std::memory_order_acquire);
    if (type_and_id == 0)
      break;  // Stop at the first incomplete event.

    auto packet = trace_writer_->NewTracePacket();
    packet->set_timestamp(it->timestamp_ns());
    auto* evt = packet->set_perfetto_metatrace();
    uint16_t type = type_and_id & metatrace::Record::kTypeMask;
    uint16_t id = type_and_id & ~metatrace::Record::kTypeMask;
    if (type == metatrace::Record::kTypeCounter) {
      evt->set_counter_id(id);
      evt->set_counter_value(it->counter_value);
    } else {
      evt->set_event_id(id);
      evt->set_event_duration_ns(it->duration_ns);
    }

    evt->set_thread_id(static_cast<uint32_t>(it->thread_id));

    if (metatrace::RingBuffer::has_overruns())
      evt->set_has_overruns(true);
  }
  // The |it| destructor will automatically update the read index position in
  // the meta-trace ring buffer.
}

void MetatraceWriter::WriteAllAndFlushTraceWriter(
    std::function<void()> callback) {
  PERFETTO_DCHECK_THREAD(thread_checker_);
  if (!started_)
    return;
  WriteAllAvailableEvents();
  trace_writer_->Flush(std::move(callback));
}

}  // namespace perfetto
// gen_amalgamated begin source: src/tracing/service/packet_stream_validator.cc
// gen_amalgamated begin header: src/tracing/service/packet_stream_validator.h
/*
 * Copyright (C) 2018 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef SRC_TRACING_SERVICE_PACKET_STREAM_VALIDATOR_H_
#define SRC_TRACING_SERVICE_PACKET_STREAM_VALIDATOR_H_

// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/slice.h"

namespace perfetto {

// Checks that the stream of trace packets sent by the producer is well formed.
// This includes:
//
// - Checking that the packets are not truncated.
// - There are no dangling bytes left over in the packets.
// - Any trusted fields (e.g., uid) are not set.
//
// Note that we only validate top-level fields in the trace proto; sub-messages
// are simply skipped.
class PacketStreamValidator {
 public:
  PacketStreamValidator() = delete;

  static bool Validate(const Slices&);
};

}  // namespace perfetto

#endif  // SRC_TRACING_SERVICE_PACKET_STREAM_VALIDATOR_H_
/*
 * Copyright (C) 2018 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// gen_amalgamated expanded: #include "src/tracing/service/packet_stream_validator.h"

#include <stddef.h>

#include <cinttypes>

// gen_amalgamated expanded: #include "perfetto/base/logging.h"
// gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"

// gen_amalgamated expanded: #include "protos/perfetto/trace/trace_packet.pbzero.h"

namespace perfetto {

namespace {

using protozero::proto_utils::ProtoWireType;

const uint32_t kReservedFieldIds[] = {
    protos::pbzero::TracePacket::kTrustedUidFieldNumber,
    protos::pbzero::TracePacket::kTrustedPacketSequenceIdFieldNumber,
    protos::pbzero::TracePacket::kTraceConfigFieldNumber,
    protos::pbzero::TracePacket::kTraceStatsFieldNumber,
    protos::pbzero::TracePacket::kCompressedPacketsFieldNumber,
    protos::pbzero::TracePacket::kSynchronizationMarkerFieldNumber,
    protos::pbzero::TracePacket::kTrustedPidFieldNumber,
    protos::pbzero::TracePacket::kMachineIdFieldNumber,
};

// This translation unit is quite subtle and perf-sensitive. Remember to check
// BM_PacketStreamValidator in perfetto_benchmarks when making changes.

// Checks that a packet, spread over several slices, is well-formed and doesn't
// contain reserved top-level fields.
// The checking logic is based on a state-machine that skips the fields' payload
// and operates as follows:
//              +-------------------------------+ <-------------------------+
// +----------> | Read field preamble (varint)  | <----------------------+  |
// |            +-------------------------------+                        |  |
// |              |              |            |                          |  |
// |       <Varint>        <Fixed 32/64>     <Length-delimited field>    |  |
// |          V                  |                      V                |  |
// |  +------------------+       |               +--------------+        |  |
// |  | Read field value |       |               | Read length  |        |  |
// |  | (another varint) |       |               |   (varint)   |        |  |
// |  +------------------+       |               +--------------+        |  |
// |           |                 V                      V                |  |
// +-----------+        +----------------+     +-----------------+       |  |
//                      | Skip 4/8 Bytes |     | Skip $len Bytes |-------+  |
//                      +----------------+     +-----------------+          |
//                               |                                          |
//                               +------------------------------------------+
class ProtoFieldParserFSM {
 public:
  // This method effectively continuously parses varints (either for the field
  // preamble or the payload or the submessage length) and tells the caller
  // (the Validate() method) how many bytes to skip until the next field.
  size_t Push(uint8_t octet) {
    varint_ |= static_cast<uint64_t>(octet & 0x7F) << varint_shift_;
    if (octet & 0x80) {
      varint_shift_ += 7;
      if (varint_shift_ >= 64) {
        // Do not invoke UB on next call.
        varint_shift_ = 0;
        state_ = kInvalidVarInt;
      }
      return 0;
    }
    uint64_t varint = varint_;
    varint_ = 0;
    varint_shift_ = 0;

    switch (state_) {
      case kFieldPreamble: {
        uint64_t field_type = varint & 7;  // 7 = 0..0111
        auto field_id = static_cast<uint32_t>(varint >> 3);
        // Check if the field id is reserved, go into an error state if it is.
        for (size_t i = 0; i < base::ArraySize(kReservedFieldIds); ++i) {
          if (field_id == kReservedFieldIds[i]) {
            state_ = kWroteReservedField;
            return 0;
          }
        }
        // The field type is legit, now check it's well formed and within
        // boundaries.
        if (field_type == static_cast<uint64_t>(ProtoWireType::kVarInt)) {
          state_ = kVarIntValue;
        } else if (field_type ==
                   static_cast<uint64_t>(ProtoWireType::kFixed32)) {
          return 4;
        } else if (field_type ==
                   static_cast<uint64_t>(ProtoWireType::kFixed64)) {
          return 8;
        } else if (field_type ==
                   static_cast<uint64_t>(ProtoWireType::kLengthDelimited)) {
          state_ = kLenDelimitedLen;
        } else {
          state_ = kUnknownFieldType;
        }
        return 0;
      }

      case kVarIntValue: {
        // Consume the int field payload and go back to the next field.
        state_ = kFieldPreamble;
        return 0;
      }

      case kLenDelimitedLen: {
        if (varint > protozero::proto_utils::kMaxMessageLength) {
          state_ = kMessageTooBig;
          return 0;
        }
        state_ = kFieldPreamble;
        return static_cast<size_t>(varint);
      }

      case kWroteReservedField:
      case kUnknownFieldType:
      case kMessageTooBig:
      case kInvalidVarInt:
        // Persistent error states.
        return 0;

    }          // switch(state_)
    return 0;  // To keep GCC happy.
  }

  // Queried at the end of the all payload. A message is well-formed only
  // if the FSM is back to the state where it should parse the next field and
  // hasn't started parsing any preamble.
  bool valid() const { return state_ == kFieldPreamble && varint_shift_ == 0; }
  int state() const { return static_cast<int>(state_); }

 private:
  enum State {
    kFieldPreamble = 0,  // Parsing the varint for the field preamble.
    kVarIntValue,        // Parsing the varint value for the field payload.
    kLenDelimitedLen,    // Parsing the length of the length-delimited field.

    // Error states:
    kWroteReservedField,  // Tried to set a reserved field id.
    kUnknownFieldType,    // Encountered an invalid field type.
    kMessageTooBig,       // Size of the length delimited message was too big.
    kInvalidVarInt,       // VarInt larger than 64 bits.
  };

  State state_ = kFieldPreamble;
  uint64_t varint_ = 0;
  uint32_t varint_shift_ = 0;
};

}  // namespace

// static
bool PacketStreamValidator::Validate(const Slices& slices) {
  ProtoFieldParserFSM parser;
  size_t skip_bytes = 0;
  for (const Slice& slice : slices) {
    for (size_t i = 0; i < slice.size;) {
      const size_t skip_bytes_cur_slice = std::min(skip_bytes, slice.size - i);
      if (skip_bytes_cur_slice > 0) {
        i += skip_bytes_cur_slice;
        skip_bytes -= skip_bytes_cur_slice;
      } else {
        uint8_t octet = *(reinterpret_cast<const uint8_t*>(slice.start) + i);
        skip_bytes = parser.Push(octet);
        i++;
      }
    }
  }
  if (skip_bytes == 0 && parser.valid())
    return true;

  PERFETTO_DLOG("Packet validation error (state %d, skip = %zu)",
                parser.state(), skip_bytes);
  return false;
}

}  // namespace perfetto
// gen_amalgamated begin source: src/tracing/service/trace_buffer.cc
// gen_amalgamated begin header: src/tracing/service/trace_buffer.h
// gen_amalgamated begin header: include/perfetto/ext/base/flat_hash_map.h
/*
 * Copyright (C) 2021 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef INCLUDE_PERFETTO_EXT_BASE_FLAT_HASH_MAP_H_
#define INCLUDE_PERFETTO_EXT_BASE_FLAT_HASH_MAP_H_

// gen_amalgamated expanded: #include "perfetto/base/compiler.h"
// gen_amalgamated expanded: #include "perfetto/base/logging.h"
// gen_amalgamated expanded: #include "perfetto/ext/base/hash.h"
// gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"

#include <algorithm>
#include <limits>

namespace perfetto {
namespace base {

// An open-addressing hashmap implementation.
// Pointers are not stable, neither for keys nor values.
// Has similar performances of a RobinHood hash (without the complications)
// and 2x an unordered map.
// Doc: http://go/perfetto-hashtables .
//
// When used to implement a string pool in TraceProcessor, the performance
// characteristics obtained by replaying the set of strings seeen in a 4GB trace
// (226M strings, 1M unique) are the following (see flat_hash_map_benchmark.cc):
// This(Linear+AppendOnly)    879,383,676 ns    258.013M insertions/s
// This(LinearProbe):         909,206,047 ns    249.546M insertions/s
// This(QuadraticProbe):    1,083,844,388 ns    209.363M insertions/s
// std::unordered_map:      6,203,351,870 ns    36.5811M insertions/s
// tsl::robin_map:            931,403,397 ns    243.622M insertions/s
// absl::flat_hash_map:       998,013,459 ns    227.379M insertions/s
// FollyF14FastMap:         1,181,480,602 ns    192.074M insertions/s
//
// TODO(primiano): the table regresses for heavy insert+erase workloads since we
// don't clean up tombstones outside of resizes. In the limit, the entire
// table's capacity is made up of values/tombstones, so each search has to
// exhaustively scan the full capacity.

// The structs below define the probing algorithm used to probe slots upon a
// collision. They are guaranteed to visit all slots as our table size is always
// a power of two (see https://en.wikipedia.org/wiki/Quadratic_probing).

// Linear probing can be faster if the hashing is well distributed and the load
// is not high. For TraceProcessor's StringPool this is the fastest. It can
// degenerate badly if the hashing doesn't spread (e.g., if using directly pids
// as keys, with a no-op hashing function).
struct LinearProbe {
  static inline size_t Calc(size_t key_hash, size_t step, size_t capacity) {
    return (key_hash + step) & (capacity - 1);  // Linear probe
  }
};

// Generates the sequence: 0, 3, 10, 21, 36, 55, ...
// Can be a bit (~5%) slower than LinearProbe because it's less cache hot, but
// avoids degenerating badly if the hash function is bad and causes clusters.
// A good default choice unless benchmarks prove otherwise.
struct QuadraticProbe {
  static inline size_t Calc(size_t key_hash, size_t step, size_t capacity) {
    return (key_hash + 2 * step * step + step) & (capacity - 1);
  }
};

// Tends to perform in the middle between linear and quadratic.
// It's a bit more cache-effective than the QuadraticProbe but can create more
// clustering if the hash function doesn't spread well.
// Generates the sequence: 0, 1, 3, 6, 10, 15, 21, ...
struct QuadraticHalfProbe {
  static inline size_t Calc(size_t key_hash, size_t step, size_t capacity) {
    return (key_hash + (step * step + step) / 2) & (capacity - 1);
  }
};

template <typename Key,
          typename Value,
          typename Hasher = base::Hash<Key>,
          typename Probe = QuadraticProbe,
          bool AppendOnly = false>
class FlatHashMap {
 public:
  class Iterator {
   public:
    explicit Iterator(const FlatHashMap* map) : map_(map) { FindNextNonFree(); }
    ~Iterator() = default;
    Iterator(const Iterator&) = default;
    Iterator& operator=(const Iterator&) = default;
    Iterator(Iterator&&) noexcept = default;
    Iterator& operator=(Iterator&&) noexcept = default;

    Key& key() { return map_->keys_[idx_]; }
    Value& value() { return map_->values_[idx_]; }
    const Key& key() const { return map_->keys_[idx_]; }
    const Value& value() const { return map_->values_[idx_]; }

    explicit operator bool() const { return idx_ != kEnd; }
    Iterator& operator++() {
      PERFETTO_DCHECK(idx_ < map_->capacity_);
      ++idx_;
      FindNextNonFree();
      return *this;
    }

   private:
    static constexpr size_t kEnd = std::numeric_limits<size_t>::max();

    void FindNextNonFree() {
      const auto& tags = map_->tags_;
      for (; idx_ < map_->capacity_; idx_++) {
        if (tags[idx_] != kFreeSlot && (AppendOnly || tags[idx_] != kTombstone))
          return;
      }
      idx_ = kEnd;
    }

    const FlatHashMap* map_ = nullptr;
    size_t idx_ = 0;
  };  // Iterator

  static constexpr int kDefaultLoadLimitPct = 75;
  explicit FlatHashMap(size_t initial_capacity = 0,
                       int load_limit_pct = kDefaultLoadLimitPct)
      : load_limit_percent_(load_limit_pct) {
    if (initial_capacity > 0)
      Reset(initial_capacity);
  }

  // We are calling Clear() so that the destructors for the inserted entries are
  // called (unless they are trivial, in which case it will be a no-op).
  ~FlatHashMap() { Clear(); }

  FlatHashMap(FlatHashMap&& other) noexcept {
    tags_ = std::move(other.tags_);
    keys_ = std::move(other.keys_);
    values_ = std::move(other.values_);
    capacity_ = other.capacity_;
    size_ = other.size_;
    max_probe_length_ = other.max_probe_length_;
    load_limit_ = other.load_limit_;
    load_limit_percent_ = other.load_limit_percent_;

    new (&other) FlatHashMap();
  }

  FlatHashMap& operator=(FlatHashMap&& other) noexcept {
    this->~FlatHashMap();
    new (this) FlatHashMap(std::move(other));
    return *this;
  }

  FlatHashMap(const FlatHashMap&) = delete;
  FlatHashMap& operator=(const FlatHashMap&) = delete;

  std::pair<Value*, bool> Insert(Key key, Value value) {
    const size_t key_hash = Hasher{}(key);
    const uint8_t tag = HashToTag(key_hash);
    static constexpr size_t kSlotNotFound = std::numeric_limits<size_t>::max();

    // This for loop does in reality at most two attempts:
    // The first iteration either:
    //  - Early-returns, because the key exists already,
    //  - Finds an insertion slot and proceeds because the load is < limit.
    // The second iteration is only hit in the unlikely case of this insertion
    // bringing the table beyond the target |load_limit_| (or the edge case
    // of the HT being full, if |load_limit_pct_| = 100).
    // We cannot simply pre-grow the table before insertion, because we must
    // guarantee that calling Insert() with a key that already exists doesn't
    // invalidate iterators.
    size_t insertion_slot;
    size_t probe_len;
    for (;;) {
      PERFETTO_DCHECK((capacity_ & (capacity_ - 1)) == 0);  // Must be a pow2.
      insertion_slot = kSlotNotFound;
      // Start the iteration at the desired slot (key_hash % capacity_)
      // searching either for a free slot or a tombstone. In the worst case we
      // might end up scanning the whole array of slots. The Probe functions are
      // guaranteed to visit all the slots within |capacity_| steps. If we find
      // a free slot, we can stop the search immediately (a free slot acts as an
      // "end of chain for entries having the same hash". If we find a
      // tombstones (a deleted slot) we remember its position, but have to keep
      // searching until a free slot to make sure we don't insert a duplicate
      // key.
      for (probe_len = 0; probe_len < capacity_;) {
        const size_t idx = Probe::Calc(key_hash, probe_len, capacity_);
        PERFETTO_DCHECK(idx < capacity_);
        const uint8_t tag_idx = tags_[idx];
        ++probe_len;
        if (tag_idx == kFreeSlot) {
          // Rationale for "insertion_slot == kSlotNotFound": if we encountered
          // a tombstone while iterating we should reuse that rather than
          // taking another slot.
          if (AppendOnly || insertion_slot == kSlotNotFound)
            insertion_slot = idx;
          break;
        }
        // We should never encounter tombstones in AppendOnly mode.
        PERFETTO_DCHECK(!(tag_idx == kTombstone && AppendOnly));
        if (!AppendOnly && tag_idx == kTombstone) {
          insertion_slot = idx;
          continue;
        }
        if (tag_idx == tag && keys_[idx] == key) {
          // The key is already in the map.
          return std::make_pair(&values_[idx], false);
        }
      }  // for (idx)

      // If we got to this point the key does not exist (otherwise we would have
      // hit the return above) and we are going to insert a new entry.
      // Before doing so, ensure we stay under the target load limit.
      if (PERFETTO_UNLIKELY(size_ >= load_limit_)) {
        MaybeGrowAndRehash(/*grow=*/true);
        continue;
      }
      PERFETTO_DCHECK(insertion_slot != kSlotNotFound);
      break;
    }  // for (attempt)

    PERFETTO_CHECK(insertion_slot < capacity_);

    // We found a free slot (or a tombstone). Proceed with the insertion.
    Value* value_idx = &values_[insertion_slot];
    new (&keys_[insertion_slot]) Key(std::move(key));
    new (value_idx) Value(std::move(value));
    tags_[insertion_slot] = tag;
    PERFETTO_DCHECK(probe_len > 0 && probe_len <= capacity_);
    max_probe_length_ = std::max(max_probe_length_, probe_len);
    size_++;

    return std::make_pair(value_idx, true);
  }

  Value* Find(const Key& key) const {
    const size_t idx = FindInternal(key);
    if (idx == kNotFound)
      return nullptr;
    return &values_[idx];
  }

  bool Erase(const Key& key) {
    if (AppendOnly)
      PERFETTO_FATAL("Erase() not supported because AppendOnly=true");
    size_t idx = FindInternal(key);
    if (idx == kNotFound)
      return false;
    EraseInternal(idx);
    return true;
  }

  void Clear() {
    // Avoid trivial heap operations on zero-capacity std::move()-d objects.
    if (PERFETTO_UNLIKELY(capacity_ == 0))
      return;

    for (size_t i = 0; i < capacity_; ++i) {
      const uint8_t tag = tags_[i];
      if (tag != kFreeSlot && tag != kTombstone)
        EraseInternal(i);
    }
    // Clear all tombstones. We really need to do this for AppendOnly.
    MaybeGrowAndRehash(/*grow=*/false);
  }

  Value& operator[](Key key) {
    auto it_and_inserted = Insert(std::move(key), Value{});
    return *it_and_inserted.first;
  }

  Iterator GetIterator() { return Iterator(this); }
  const Iterator GetIterator() const { return Iterator(this); }

  size_t size() const { return size_; }
  size_t capacity() const { return capacity_; }

  // "protected" here is only for the flat_hash_map_benchmark.cc. Everything
  // below is by all means private.
 protected:
  enum ReservedTags : uint8_t { kFreeSlot = 0, kTombstone = 1 };
  static constexpr size_t kNotFound = std::numeric_limits<size_t>::max();

  size_t FindInternal(const Key& key) const {
    const size_t key_hash = Hasher{}(key);
    const uint8_t tag = HashToTag(key_hash);
    PERFETTO_DCHECK((capacity_ & (capacity_ - 1)) == 0);  // Must be a pow2.
    PERFETTO_DCHECK(max_probe_length_ <= capacity_);
    for (size_t i = 0; i < max_probe_length_; ++i) {
      const size_t idx = Probe::Calc(key_hash, i, capacity_);
      const uint8_t tag_idx = tags_[idx];

      if (tag_idx == kFreeSlot)
        return kNotFound;
      // HashToTag() never returns kTombstone, so the tag-check below cannot
      // possibly match. Also we just want to skip tombstones.
      if (tag_idx == tag && keys_[idx] == key) {
        PERFETTO_DCHECK(tag_idx > kTombstone);
        return idx;
      }
    }  // for (idx)
    return kNotFound;
  }

  void EraseInternal(size_t idx) {
    PERFETTO_DCHECK(tags_[idx] > kTombstone);
    PERFETTO_DCHECK(size_ > 0);
    tags_[idx] = kTombstone;
    keys_[idx].~Key();
    values_[idx].~Value();
    size_--;
  }

  PERFETTO_NO_INLINE void MaybeGrowAndRehash(bool grow) {
    PERFETTO_DCHECK(size_ <= capacity_);
    const size_t old_capacity = capacity_;

    // Grow quickly up to 1MB, then chill.
    const size_t old_size_bytes = old_capacity * (sizeof(Key) + sizeof(Value));
    const size_t grow_factor = old_size_bytes < (1024u * 1024u) ? 8 : 2;
    const size_t new_capacity =
        grow ? std::max(old_capacity * grow_factor, size_t(1024))
             : old_capacity;

    auto old_tags(std::move(tags_));
    auto old_keys(std::move(keys_));
    auto old_values(std::move(values_));
    size_t old_size = size_;

    // This must be a CHECK (i.e. not just a DCHECK) to prevent UAF attacks on
    // 32-bit archs that try to double the size of the table until wrapping.
    PERFETTO_CHECK(new_capacity >= old_capacity);
    Reset(new_capacity);

    size_t new_size = 0;  // Recompute the size.
    for (size_t i = 0; i < old_capacity; ++i) {
      const uint8_t old_tag = old_tags[i];
      if (old_tag != kFreeSlot && old_tag != kTombstone) {
        Insert(std::move(old_keys[i]), std::move(old_values[i]));
        old_keys[i].~Key();  // Destroy the old objects.
        old_values[i].~Value();
        new_size++;
      }
    }
    PERFETTO_DCHECK(new_size == old_size);
    size_ = new_size;
  }

  // Doesn't call destructors. Use Clear() for that.
  PERFETTO_NO_INLINE void Reset(size_t n) {
    PERFETTO_DCHECK((n & (n - 1)) == 0);  // Must be a pow2.

    capacity_ = n;
    max_probe_length_ = 0;
    size_ = 0;
    load_limit_ = n * static_cast<size_t>(load_limit_percent_) / 100;
    load_limit_ = std::min(load_limit_, n);

    tags_.reset(new uint8_t[n]);
    memset(&tags_[0], 0, n);                  // Clear all tags.
    keys_ = AlignedAllocTyped<Key[]>(n);      // Deliberately not 0-initialized.
    values_ = AlignedAllocTyped<Value[]>(n);  // Deliberately not 0-initialized.
  }

  static inline uint8_t HashToTag(size_t full_hash) {
    uint8_t tag = full_hash >> (sizeof(full_hash) * 8 - 8);
    // Ensure the hash is always >= 2. We use 0, 1 for kFreeSlot and kTombstone.
    tag += (tag <= kTombstone) << 1;
    PERFETTO_DCHECK(tag > kTombstone);
    return tag;
  }

  size_t capacity_ = 0;
  size_t size_ = 0;
  size_t max_probe_length_ = 0;
  size_t load_limit_ = 0;  // Updated every time |capacity_| changes.
  int load_limit_percent_ =
      kDefaultLoadLimitPct;  // Load factor limit in % of |capacity_|.

  // These arrays have always the |capacity_| elements.
  // Note: AlignedUniquePtr just allocates memory, doesn't invoke any ctor/dtor.
  std::unique_ptr<uint8_t[]> tags_;
  AlignedUniquePtr<Key[]> keys_;
  AlignedUniquePtr<Value[]> values_;
};

}  // namespace base
}  // namespace perfetto

#endif  // INCLUDE_PERFETTO_EXT_BASE_FLAT_HASH_MAP_H_
// gen_amalgamated begin header: include/perfetto/ext/tracing/core/client_identity.h
/*
 * Copyright (C) 2023 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef INCLUDE_PERFETTO_EXT_TRACING_CORE_CLIENT_IDENTITY_H_
#define INCLUDE_PERFETTO_EXT_TRACING_CORE_CLIENT_IDENTITY_H_

// gen_amalgamated expanded: #include "perfetto/ext/base/sys_types.h"
// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/basic_types.h"

namespace perfetto {

// This class groups data fields of a connected client that can get passed in
// the tracing core to be emitted to trace packets.
class ClientIdentity {
 public:
  ClientIdentity() = default;
  ClientIdentity(uid_t uid, pid_t pid, MachineID machine_id = kDefaultMachineID)
      : uid_(uid), pid_(pid), machine_id_(machine_id) {}

  bool has_uid() const { return uid_ != base::kInvalidUid; }
  uid_t uid() const { return uid_; }

  bool has_pid() const { return pid_ != base::kInvalidPid; }
  pid_t pid() const { return pid_; }

  bool has_non_default_machine_id() const {
    return machine_id_ != kDefaultMachineID;
  }
  base::MachineID machine_id() const { return machine_id_; }

 private:
  uid_t uid_ = base::kInvalidUid;
  pid_t pid_ = base::kInvalidPid;
  MachineID machine_id_ = kDefaultMachineID;
};
}  // namespace perfetto

#endif  // INCLUDE_PERFETTO_EXT_TRACING_CORE_CLIENT_IDENTITY_H_
// gen_amalgamated begin header: src/tracing/service/histogram.h
/*
 * Copyright (C) 2023 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef SRC_TRACING_SERVICE_HISTOGRAM_H_
#define SRC_TRACING_SERVICE_HISTOGRAM_H_

#include <stddef.h>
#include <stdint.h>

#include <limits>

// gen_amalgamated expanded: #include "perfetto/base/logging.h"

namespace perfetto {

using HistValue = int64_t;

// Usage:
// Histogram<10, 100, 1000> h;  // A histogram with 3 + 1 (overflow) bucket.
// h.Add(value);
// h.GetBucketSum(0);  // Returns SUM(x) for 0 < x <= 10
// h.GetBucketSum(1);  // Returns SUM(x) for 10 < x <= 100
// h.GetBucketSum(2);  // Returns SUM(x) for 100 < x <= 1000
// h.GetBucketSum(3);  // Returns SUM(x) for x > 1000
// Likewise h.GetBucketCount(x) returns the COUNT(x).
template <HistValue... thresholds>
class Histogram {
 public:
  // 1+ is for the overflow bucket (anything > the last threshold).
  static constexpr size_t kNumBuckets = 1 + sizeof...(thresholds);

  void Add(HistValue value) {
    size_t bucket = BucketForValue(value);
    bucket_sum_[bucket] += value;
    ++bucket_count_[bucket];
  }

  static constexpr size_t num_buckets() { return kNumBuckets; }

  HistValue GetBucketThres(size_t n) const {
    PERFETTO_DCHECK(n < kNumBuckets);
    return bucket_thres_[n];
  }

  uint64_t GetBucketCount(size_t n) const {
    PERFETTO_DCHECK(n < kNumBuckets);
    return bucket_count_[n];
  }

  HistValue GetBucketSum(size_t n) const {
    PERFETTO_DCHECK(n < kNumBuckets);
    return bucket_sum_[n];
  }

  void Merge(const Histogram& other) {
    for (size_t i = 0; i < kNumBuckets; ++i) {
      bucket_sum_[i] += other.bucket_sum_[i];
      bucket_count_[i] += other.bucket_count_[i];
    }
  }

 private:
  static size_t BucketForValue(HistValue value) {
    for (size_t i = 0; i < kNumBuckets - 1; i++) {
      if (value <= bucket_thres_[i])
        return i;
    }
    return kNumBuckets - 1;
  }

  static constexpr HistValue bucket_thres_[kNumBuckets]{
      thresholds..., std::numeric_limits<HistValue>::max()};

  HistValue bucket_sum_[kNumBuckets]{};
  uint64_t bucket_count_[kNumBuckets]{};
};

}  // namespace perfetto

#endif  // SRC_TRACING_SERVICE_HISTOGRAM_H_
/*
 * Copyright (C) 2018 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef SRC_TRACING_SERVICE_TRACE_BUFFER_H_
#define SRC_TRACING_SERVICE_TRACE_BUFFER_H_

#include <stdint.h>
#include <string.h>

#include <array>
#include <limits>
#include <map>
#include <tuple>

// gen_amalgamated expanded: #include "perfetto/base/logging.h"
// gen_amalgamated expanded: #include "perfetto/ext/base/flat_hash_map.h"
// gen_amalgamated expanded: #include "perfetto/ext/base/paged_memory.h"
// gen_amalgamated expanded: #include "perfetto/ext/base/thread_annotations.h"
// gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/basic_types.h"
// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/client_identity.h"
// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/slice.h"
// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/trace_stats.h"
// gen_amalgamated expanded: #include "src/tracing/service/histogram.h"

namespace perfetto {

class TracePacket;

// The main buffer, owned by the tracing service, where all the trace data is
// ultimately stored into. The service will own several instances of this class,
// at least one per active consumer (as defined in the |buffers| section of
// trace_config.proto) and will copy chunks from the producer's shared memory
// buffers into here when a CommitData IPC is received.
//
// Writing into the buffer
// -----------------------
// Data is copied from the SMB(s) using CopyChunkUntrusted(). The buffer will
// hence contain data coming from different producers and different writer
// sequences, more specifically:
// - The service receives data by several producer(s), identified by their ID.
// - Each producer writes several sequences identified by the same WriterID.
//   (they correspond to TraceWriter instances in the producer).
// - Each Writer writes, in order, several chunks.
// - Each chunk contains zero, one, or more TracePacket(s), or even just
//   fragments of packets (when they span across several chunks).
//
// So at any point in time, the buffer will contain a variable number of logical
// sequences identified by the {ProducerID, WriterID} tuple. Any given chunk
// will only contain packets (or fragments) belonging to the same sequence.
//
// The buffer operates by default as a ring buffer.
// It has two overwrite policies:
//  1. kOverwrite (default): if the write pointer reaches the read pointer, old
//     unread chunks will be overwritten by new chunks.
//  2. kDiscard: if the write pointer reaches the read pointer, unread chunks
//     are preserved and the new chunks are discarded. Any future write becomes
//     a no-op, even if the reader manages to fully catch up. This is because
//     once a chunk is discarded, the sequence of packets is broken and trying
//     to recover would be too hard (also due to the fact that, at the same
//     time, we allow out-of-order commits and chunk re-writes).
//
// Chunks are (over)written in the same order of the CopyChunkUntrusted() calls.
// When overwriting old content, entire chunks are overwritten or clobbered.
// The buffer never leaves a partial chunk around. Chunks' payload is copied
// as-is, but their header is not and is repacked in order to keep the
// ProducerID around.
//
// Chunks are stored in the buffer next to each other. Each chunk is prefixed by
// an inline header (ChunkRecord), which contains most of the fields of the
// SharedMemoryABI ChunkHeader + the ProducerID + the size of the payload.
// It's a conventional binary object stream essentially, where each ChunkRecord
// tells where it ends and hence where to find the next one, like this:
//
//          .-------------------------. 16 byte boundary
//          | ChunkRecord:   16 bytes |
//          | - chunk id:     4 bytes |
//          | - producer id:  2 bytes |
//          | - writer id:    2 bytes |
//          | - #fragments:   2 bytes |
//    +-----+ - record size:  2 bytes |
//    |     | - flags+pad:    4 bytes |
//    |     +-------------------------+
//    |     |                         |
//    |     :     Chunk payload       :
//    |     |                         |
//    |     +-------------------------+
//    |     |    Optional padding     |
//    +---> +-------------------------+ 16 byte boundary
//          |      ChunkRecord        |
//          :                         :
// Chunks stored in the buffer are always rounded up to 16 bytes (that is
// sizeof(ChunkRecord)), in order to avoid further inner fragmentation.
// Special "padding" chunks can be put in the buffer, e.g. in the case when we
// try to write a chunk of size N while the write pointer is at the end of the
// buffer, but the write pointer is < N bytes from the end (and hence needs to
// wrap over).
// Because of this, the buffer is self-describing: the contents of the buffer
// can be reconstructed by just looking at the buffer content (this will be
// quite useful in future to recover the buffer from crash reports).
//
// However, in order to keep some operations (patching and reading) fast, a
// lookaside index is maintained (in |index_|), keeping each chunk in the buffer
// indexed by their {ProducerID, WriterID, ChunkID} tuple.
//
// Patching data out-of-band
// -------------------------
// This buffer also supports patching chunks' payload out-of-band, after they
// have been stored. This is to allow producers to backfill the "size" fields
// of the protos that spawn across several chunks, when the previous chunks are
// returned to the service. The MaybePatchChunkContents() deals with the fact
// that a chunk might have been lost (because of wrapping) by the time the OOB
// IPC comes.
//
// Reading from the buffer
// -----------------------
// This class supports one reader only (the consumer). Reads are NOT idempotent
// as they move the read cursors around. Reading back the buffer is the most
// conceptually complex part. The ReadNextTracePacket() method operates with
// whole packet granularity. Packets are returned only when all their fragments
// are available.
// This class takes care of:
// - Gluing packets within the same sequence, even if they are not stored
//   adjacently in the buffer.
// - Re-ordering chunks within a sequence (using the ChunkID, which wraps).
// - Detecting holes in packet fragments (because of loss of chunks).
// Reads guarantee that packets for the same sequence are read in FIFO order
// (according to their ChunkID), but don't give any guarantee about the read
// order of packets from different sequences, see comments in
// ReadNextTracePacket() below.
class TraceBuffer {
 public:
  static const size_t InlineChunkHeaderSize;  // For test/fake_packet.{cc,h}.

  // See comment in the header above.
  enum OverwritePolicy { kOverwrite, kDiscard };

  // Argument for out-of-band patches applied through TryPatchChunkContents().
  struct Patch {
    // From SharedMemoryABI::kPacketHeaderSize.
    static constexpr size_t kSize = 4;

    size_t offset_untrusted;
    std::array<uint8_t, kSize> data;
  };

  // Identifiers that are constant for a packet sequence.
  struct PacketSequenceProperties {
    ProducerID producer_id_trusted;
    ClientIdentity client_identity_trusted;
    WriterID writer_id;

    uid_t producer_uid_trusted() const { return client_identity_trusted.uid(); }
    pid_t producer_pid_trusted() const { return client_identity_trusted.pid(); }
  };

  // Holds the "used chunk" stats for each <Producer, Writer> tuple.
  struct WriterStats {
    Histogram<8, 32, 128, 512, 1024, 2048, 4096, 8192, 12288, 16384>
        used_chunk_hist;
  };

  using WriterStatsMap = base::FlatHashMap<ProducerAndWriterID,
                                           WriterStats,
                                           std::hash<ProducerAndWriterID>,
                                           base::QuadraticProbe,
                                           /*AppendOnly=*/true>;

  // Can return nullptr if the memory allocation fails.
  static std::unique_ptr<TraceBuffer> Create(size_t size_in_bytes,
                                             OverwritePolicy = kOverwrite);

  ~TraceBuffer();

  // Copies a Chunk from a producer Shared Memory Buffer into the trace buffer.
  // |src| points to the first packet in the SharedMemoryABI's chunk shared with
  // an untrusted producer. "untrusted" here means: the producer might be
  // malicious and might change |src| concurrently while we read it (internally
  // this method memcpy()-s first the chunk before processing it). None of the
  // arguments should be trusted, unless otherwise stated. We can trust that
  // |src| points to a valid memory area, but not its contents.
  //
  // This method may be called multiple times for the same chunk. In this case,
  // the original chunk's payload will be overridden and its number of fragments
  // and flags adjusted to match |num_fragments| and |chunk_flags|. The service
  // may use this to insert partial chunks (|chunk_complete = false|) before the
  // producer has committed them.
  //
  // If |chunk_complete| is |false|, the TraceBuffer will only consider the
  // first |num_fragments - 1| packets to be complete, since the producer may
  // not have finished writing the latest packet. Reading from a sequence will
  // also not progress past any incomplete chunks until they were rewritten with
  // |chunk_complete = true|, e.g. after a producer's commit.
  //
  // TODO(eseckler): Pass in a PacketStreamProperties instead of individual IDs.
  void CopyChunkUntrusted(ProducerID producer_id_trusted,
                          const ClientIdentity& client_identity_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);

  // Applies a batch of |patches| to the given chunk, if the given chunk is
  // still in the buffer. Does nothing if the given ChunkID is gone.
  // Returns true if the chunk has been found and patched, false otherwise.
  // |other_patches_pending| is used to determine whether this is the only
  // batch of patches for the chunk or there is more.
  // If |other_patches_pending| == false, the chunk is marked as ready to be
  // consumed. If true, the state of the chunk is not altered.
  //
  // Note: If the producer is batching commits (see shared_memory_arbiter.h), it
  // will also attempt to do patching locally. Namely, if nested messages are
  // completed while the chunk on which they started is being batched (i.e.
  // before it has been committed to the service), the producer will apply the
  // respective patches to the batched chunk. These patches will not be sent to
  // the service - i.e. only the patches that the producer did not manage to
  // apply before committing the chunk will be applied here.
  bool TryPatchChunkContents(ProducerID,
                             WriterID,
                             ChunkID,
                             const Patch* patches,
                             size_t patches_size,
                             bool other_patches_pending);

  // To read the contents of the buffer the caller needs to:
  //   BeginRead()
  //   while (ReadNextTracePacket(packet_fragments)) { ... }
  // No other calls to any other method should be interleaved between
  // BeginRead() and ReadNextTracePacket().
  // Reads in the TraceBuffer are NOT idempotent.
  void BeginRead();

  // Returns the next packet in the buffer, if any, and the producer_id,
  // producer_uid, and writer_id of the producer/writer that wrote it (as passed
  // in the CopyChunkUntrusted() call). Returns false if no packets can be read
  // at this point. If a packet was read successfully,
  // |previous_packet_on_sequence_dropped| is set to |true| if the previous
  // packet on the sequence was dropped from the buffer before it could be read
  // (e.g. because its chunk was overridden due to the ring buffer wrapping or
  // due to an ABI violation), and to |false| otherwise.
  //
  // This function returns only complete packets. Specifically:
  // When there is at least one complete packet in the buffer, this function
  // returns true and populates the TracePacket argument with the boundaries of
  // each fragment for one packet.
  // TracePacket will have at least one slice when this function returns true.
  // When there are no whole packets eligible to read (e.g. we are still missing
  // fragments) this function returns false.
  // This function guarantees also that packets for a given
  // {ProducerID, WriterID} are read in FIFO order.
  // This function does not guarantee any ordering w.r.t. packets belonging to
  // different WriterID(s). For instance, given the following packets copied
  // into the buffer:
  //   {ProducerID: 1, WriterID: 1}: P1 P2 P3
  //   {ProducerID: 1, WriterID: 2}: P4 P5 P6
  //   {ProducerID: 2, WriterID: 1}: P7 P8 P9
  // The following read sequence is possible:
  //   P1, P4, P7, P2, P3, P5, P8, P9, P6
  // But the following is guaranteed to NOT happen:
  //   P1, P5, P7, P4 (P4 cannot come after P5)
  bool ReadNextTracePacket(TracePacket*,
                           PacketSequenceProperties* sequence_properties,
                           bool* previous_packet_on_sequence_dropped);

  // Creates a read-only clone of the trace buffer. The read iterators of the
  // new buffer will be reset, as if no Read() had been called. Calls to
  // CopyChunkUntrusted() and TryPatchChunkContents() on the returned cloned
  // TraceBuffer will CHECK().
  std::unique_ptr<TraceBuffer> CloneReadOnly() const;

  void set_read_only() { read_only_ = true; }
  const WriterStatsMap& writer_stats() const { return writer_stats_; }
  const TraceStats::BufferStats& stats() const { return stats_; }
  size_t size() const { return size_; }
  size_t used_size() const { return used_size_; }
  OverwritePolicy overwrite_policy() const { return overwrite_policy_; }
  bool has_data() const { return has_data_; }

 private:
  friend class TraceBufferTest;

  // ChunkRecord is a Chunk header stored inline in the |data_| buffer, before
  // the chunk payload (the packets' data). The |data_| buffer looks like this:
  // +---------------+------------------++---------------+-----------------+
  // | ChunkRecord 1 | Chunk payload 1  || ChunkRecord 2 | Chunk payload 2 | ...
  // +---------------+------------------++---------------+-----------------+
  // Most of the ChunkRecord fields are copied from SharedMemoryABI::ChunkHeader
  // (the chunk header used in the shared memory buffers).
  // A ChunkRecord can be a special "padding" record. In this case its payload
  // should be ignored and the record should be just skipped.
  //
  // Full page move optimization:
  // This struct has to be exactly (sizeof(PageHeader) + sizeof(ChunkHeader))
  // (from shared_memory_abi.h) to allow full page move optimizations
  // (TODO(primiano): not implemented yet). In the special case of moving a full
  // 4k page that contains only one chunk, in fact, we can just ask the kernel
  // to move the full SHM page (see SPLICE_F_{GIFT,MOVE}) and overlay the
  // ChunkRecord on top of the moved SMB's header (page + chunk header).
  // This special requirement is covered by static_assert(s) in the .cc file.
  struct ChunkRecord {
    explicit ChunkRecord(size_t sz) : flags{0}, is_padding{0} {
      PERFETTO_DCHECK(sz >= sizeof(ChunkRecord) &&
                      sz % sizeof(ChunkRecord) == 0 && sz <= kMaxSize);
      size = static_cast<decltype(size)>(sz);
    }

    bool is_valid() const { return size != 0; }

    // Keep this structure packed and exactly 16 bytes (128 bits) big.

    // [32 bits] Monotonic counter within the same writer_id.
    ChunkID chunk_id = 0;

    // [16 bits] ID of the Producer from which the Chunk was copied from.
    ProducerID producer_id = 0;

    // [16 bits] Unique per Producer (but not within the service).
    // If writer_id == kWriterIdPadding the record should just be skipped.
    WriterID writer_id = 0;

    // Number of fragments contained in the chunk.
    uint16_t num_fragments = 0;

    // Size in bytes, including sizeof(ChunkRecord) itself.
    uint16_t size;

    uint8_t flags : 6;  // See SharedMemoryABI::ChunkHeader::flags.
    static constexpr size_t kFlagsBitMask = (1 << 6) - 1;

    uint8_t is_padding : 1;
    uint8_t unused_flag : 1;

    // Not strictly needed, can be reused for more fields in the future. But
    // right now helps to spot chunks in hex dumps.
    char unused[3] = {'C', 'H', 'U'};

    static constexpr size_t kMaxSize =
        std::numeric_limits<decltype(size)>::max();
  };

  // Lookaside index entry. This serves two purposes:
  // 1) Allow a fast lookup of ChunkRecord by their ID (the tuple
  //   {ProducerID, WriterID, ChunkID}). This is used when applying out-of-band
  //   patches to the contents of the chunks after they have been copied into
  //   the TraceBuffer.
  // 2) keep the chunks ordered by their ID. This is used when reading back.
  // 3) Keep metadata about the status of the chunk, e.g. whether the contents
  //    have been read already and should be skipped in a future read pass.
  // This struct should not have any field that is essential for reconstructing
  // the contents of the buffer from a crash dump.
  struct ChunkMeta {
    // Key used for sorting in the map.
    struct Key {
      Key(ProducerID p, WriterID w, ChunkID c)
          : producer_id{p}, writer_id{w}, chunk_id{c} {}

      Key(const Key&) noexcept = default;
      Key& operator=(const Key&) = default;

      explicit Key(const ChunkRecord& cr)
          : Key(cr.producer_id, cr.writer_id, cr.chunk_id) {}

      // Note that this sorting doesn't keep into account the fact that ChunkID
      // will wrap over at some point. The extra logic in SequenceIterator deals
      // with that.
      bool operator<(const Key& other) const {
        return std::tie(producer_id, writer_id, chunk_id) <
               std::tie(other.producer_id, other.writer_id, other.chunk_id);
      }

      bool operator==(const Key& other) const {
        return std::tie(producer_id, writer_id, chunk_id) ==
               std::tie(other.producer_id, other.writer_id, other.chunk_id);
      }

      bool operator!=(const Key& other) const { return !(*this == other); }

      // These fields should match at all times the corresponding fields in
      // the |chunk_record|. They are copied here purely for efficiency to avoid
      // dereferencing the buffer all the time.
      ProducerID producer_id;
      WriterID writer_id;
      ChunkID chunk_id;
    };

    enum IndexFlags : uint8_t {
      // If set, the chunk state was kChunkComplete at the time it was copied.
      // If unset, the chunk was still kChunkBeingWritten while copied. When
      // reading from the chunk's sequence, the sequence will not advance past
      // this chunk until this flag is set.
      kComplete = 1 << 0,

      // If set, we skipped the last packet that we read from this chunk e.g.
      // because we it was a continuation from a previous chunk that was dropped
      // or due to an ABI violation.
      kLastReadPacketSkipped = 1 << 1
    };

    ChunkMeta(uint32_t _record_off,
              uint16_t _num_fragments,
              bool complete,
              uint8_t _flags,
              const ClientIdentity& client_identity)
        : record_off{_record_off},
          client_identity_trusted(client_identity),
          flags{_flags},
          num_fragments{_num_fragments} {
      if (complete)
        index_flags = kComplete;
    }

    ChunkMeta(const ChunkMeta&) noexcept = default;

    bool is_complete() const { return index_flags & kComplete; }

    void set_complete(bool complete) {
      if (complete) {
        index_flags |= kComplete;
      } else {
        index_flags &= ~kComplete;
      }
    }

    bool last_read_packet_skipped() const {
      return index_flags & kLastReadPacketSkipped;
    }

    void set_last_read_packet_skipped(bool skipped) {
      if (skipped) {
        index_flags |= kLastReadPacketSkipped;
      } else {
        index_flags &= ~kLastReadPacketSkipped;
      }
    }

    const uint32_t record_off;  // Offset of ChunkRecord within |data_|.
    const ClientIdentity client_identity_trusted;
    // Flags set by TraceBuffer to track the state of the chunk in the index.
    uint8_t index_flags = 0;

    // Correspond to |chunk_record->flags| and |chunk_record->num_fragments|.
    // Copied here for performance reasons (avoids having to dereference
    // |chunk_record| while iterating over ChunkMeta) and to aid debugging in
    // case the buffer gets corrupted.
    uint8_t flags = 0;           // See SharedMemoryABI::ChunkHeader::flags.
    uint16_t num_fragments = 0;  // Total number of packet fragments.

    uint16_t num_fragments_read = 0;  // Number of fragments already read.

    // The start offset of the next fragment (the |num_fragments_read|-th) to be
    // read. This is the offset in bytes from the beginning of the ChunkRecord's
    // payload (the 1st fragment starts at |chunk_record| +
    // sizeof(ChunkRecord)).
    uint16_t cur_fragment_offset = 0;
  };

  using ChunkMap = std::map<ChunkMeta::Key, ChunkMeta>;

  // Allows to iterate over a sub-sequence of |index_| for all keys belonging to
  // the same {ProducerID,WriterID}. Furthermore takes into account the wrapping
  // of ChunkID. Instances are valid only as long as the |index_| is not altered
  // (can be used safely only between adjacent ReadNextTracePacket() calls).
  // The order of the iteration will proceed in the following order:
  // |wrapping_id| + 1 -> |seq_end|, |seq_begin| -> |wrapping_id|.
  // Practical example:
  // - Assume that kMaxChunkID == 7
  // - Assume that we have all 8 chunks in the range (0..7).
  // - Hence, |seq_begin| == c0, |seq_end| == c7
  // - Assume |wrapping_id| = 4 (c4 is the last chunk copied over
  //   through a CopyChunkUntrusted()).
  // The resulting iteration order will be: c5, c6, c7, c0, c1, c2, c3, c4.
  struct SequenceIterator {
    // Points to the 1st key (the one with the numerically min ChunkID).
    ChunkMap::iterator seq_begin;

    // Points one past the last key (the one with the numerically max ChunkID).
    ChunkMap::iterator seq_end;

    // Current iterator, always >= seq_begin && <= seq_end.
    ChunkMap::iterator cur;

    // The latest ChunkID written. Determines the start/end of the sequence.
    ChunkID wrapping_id;

    bool is_valid() const { return cur != seq_end; }

    ProducerID producer_id() const {
      PERFETTO_DCHECK(is_valid());
      return cur->first.producer_id;
    }

    WriterID writer_id() const {
      PERFETTO_DCHECK(is_valid());
      return cur->first.writer_id;
    }

    ChunkID chunk_id() const {
      PERFETTO_DCHECK(is_valid());
      return cur->first.chunk_id;
    }

    ChunkMeta& operator*() {
      PERFETTO_DCHECK(is_valid());
      return cur->second;
    }

    // Moves |cur| to the next chunk in the index.
    // is_valid() will become false after calling this, if this was the last
    // entry of the sequence.
    void MoveNext();

    void MoveToEnd() { cur = seq_end; }
  };

  enum class ReadAheadResult {
    kSucceededReturnSlices,
    kFailedMoveToNextSequence,
    kFailedStayOnSameSequence,
  };

  enum class ReadPacketResult {
    kSucceeded,
    kFailedInvalidPacket,
    kFailedEmptyPacket,
  };

  explicit TraceBuffer(OverwritePolicy);
  TraceBuffer(const TraceBuffer&) = delete;
  TraceBuffer& operator=(const TraceBuffer&) = delete;

  // Not using the implicit copy ctor to avoid unintended copies.
  // This tagged ctor should be used only for Clone().
  struct CloneCtor {};
  TraceBuffer(CloneCtor, const TraceBuffer&);

  bool Initialize(size_t size);

  // Returns an object that allows to iterate over chunks in the |index_| that
  // have the same {ProducerID, WriterID} of
  // |seq_begin.first.{producer,writer}_id|. |seq_begin| must be an iterator to
  // the first entry in the |index_| that has a different {ProducerID, WriterID}
  // from the previous one. It is valid for |seq_begin| to be == index_.end()
  // (i.e. if the index is empty). The iteration takes care of ChunkID wrapping,
  // by using |last_chunk_id_|.
  SequenceIterator GetReadIterForSequence(ChunkMap::iterator seq_begin);

  // Used as a last resort when a buffer corruption is detected.
  void ClearContentsAndResetRWCursors();

  // Adds a padding record of the given size (must be a multiple of
  // sizeof(ChunkRecord)).
  void AddPaddingRecord(size_t);

  // Look for contiguous fragment of the same packet starting from |read_iter_|.
  // If a contiguous packet is found, all the fragments are pushed into
  // TracePacket and the function returns kSucceededReturnSlices. If not, the
  // function returns either kFailedMoveToNextSequence or
  // kFailedStayOnSameSequence, telling the caller to continue looking for
  // packets.
  ReadAheadResult ReadAhead(TracePacket*);

  // Deletes (by marking the record invalid and removing form the index) all
  // chunks from |wptr_| to |wptr_| + |bytes_to_clear|.
  // Returns:
  //   * The size of the gap left between the next valid Chunk and the end of
  //     the deletion range.
  //   * 0 if no next valid chunk exists (if the buffer is still zeroed).
  //   * -1 if the buffer |overwrite_policy_| == kDiscard and the deletion would
  //     cause unread chunks to be overwritten. In this case the buffer is left
  //     untouched.
  // Graphically, assume the initial situation is the following (|wptr_| = 10).
  // |0        |10 (wptr_)       |30       |40                 |60
  // +---------+-----------------+---------+-------------------+---------+
  // | Chunk 1 | Chunk 2         | Chunk 3 | Chunk 4           | Chunk 5 |
  // +---------+-----------------+---------+-------------------+---------+
  //           |_________Deletion range_______|~~return value~~|
  //
  // A call to DeleteNextChunksFor(32) will remove chunks 2,3,4 and return 18
  // (60 - 42), the distance between chunk 5 and the end of the deletion range.
  ssize_t DeleteNextChunksFor(size_t bytes_to_clear);

  // Decodes the boundaries of the next packet (or a fragment) pointed by
  // ChunkMeta and pushes that into |TracePacket|. It also increments the
  // |num_fragments_read| counter.
  // TracePacket can be nullptr, in which case the read state is still advanced.
  // When TracePacket is not nullptr, ProducerID must also be not null and will
  // be updated with the ProducerID that originally wrote the chunk.
  ReadPacketResult ReadNextPacketInChunk(ProducerAndWriterID,
                                         ChunkMeta*,
                                         TracePacket*);

  void DcheckIsAlignedAndWithinBounds(const uint8_t* ptr) const {
    PERFETTO_DCHECK(ptr >= begin() && ptr <= end() - sizeof(ChunkRecord));
    PERFETTO_DCHECK(
        (reinterpret_cast<uintptr_t>(ptr) & (alignof(ChunkRecord) - 1)) == 0);
  }

  ChunkRecord* GetChunkRecordAt(uint8_t* ptr) {
    DcheckIsAlignedAndWithinBounds(ptr);
    // We may be accessing a new (empty) record.
    EnsureCommitted(static_cast<size_t>(ptr + sizeof(ChunkRecord) - begin()));
    return reinterpret_cast<ChunkRecord*>(ptr);
  }

  void EnsureCommitted(size_t size) {
    PERFETTO_DCHECK(size <= size_);
    data_.EnsureCommitted(size);
    used_size_ = std::max(used_size_, size);
  }

  void DiscardWrite();

  // |src| can be nullptr (in which case |size| must be ==
  // record.size - sizeof(ChunkRecord)), for the case of writing a padding
  // record. |wptr_| is NOT advanced by this function, the caller must do that.
  void WriteChunkRecord(uint8_t* wptr,
                        const ChunkRecord& record,
                        const uint8_t* src,
                        size_t size) {
    // Note: |record.size| will be slightly bigger than |size| because of the
    // ChunkRecord header and rounding, to ensure that all ChunkRecord(s) are
    // multiple of sizeof(ChunkRecord). The invariant is:
    // record.size >= |size| + sizeof(ChunkRecord) (== if no rounding).
    PERFETTO_DCHECK(size <= ChunkRecord::kMaxSize);
    PERFETTO_DCHECK(record.size >= sizeof(record));
    PERFETTO_DCHECK(record.size % sizeof(record) == 0);
    PERFETTO_DCHECK(record.size >= size + sizeof(record));
    DcheckIsAlignedAndWithinBounds(wptr);

    // We may be writing to this area for the first time.
    EnsureCommitted(static_cast<size_t>(wptr + record.size - begin()));

    // Deliberately not a *D*CHECK.
    PERFETTO_CHECK(wptr + sizeof(record) + size <= end());
    memcpy(wptr, &record, sizeof(record));
    if (PERFETTO_LIKELY(src)) {
      // If the producer modifies the data in the shared memory buffer while we
      // are copying it to the central buffer, TSAN will (rightfully) flag that
      // as a race. However the entire purpose of copying the data into the
      // central buffer is that we can validate it without worrying that the
      // producer changes it from under our feet, so this race is benign. The
      // alternative would be to try computing which part of the buffer is safe
      // to read (assuming a well-behaving client), but the risk of introducing
      // a bug that way outweighs the benefit.
      PERFETTO_ANNOTATE_BENIGN_RACE_SIZED(
          src, size, "Benign race when copying chunk from shared memory.")
      memcpy(wptr + sizeof(record), src, size);
    } else {
      PERFETTO_DCHECK(size == record.size - sizeof(record));
    }
    const size_t rounding_size = record.size - sizeof(record) - size;
    memset(wptr + sizeof(record) + size, 0, rounding_size);
  }

  uint32_t GetOffset(const void* _addr) {
    const uintptr_t addr = reinterpret_cast<uintptr_t>(_addr);
    const uintptr_t buf_start = reinterpret_cast<uintptr_t>(begin());
    PERFETTO_DCHECK(addr >= buf_start && addr < buf_start + size_);
    return static_cast<uint32_t>(addr - buf_start);
  }

  uint8_t* begin() const { return reinterpret_cast<uint8_t*>(data_.Get()); }
  uint8_t* end() const { return begin() + size_; }
  size_t size_to_end() const { return static_cast<size_t>(end() - wptr_); }

  base::PagedMemory data_;
  size_t size_ = 0;            // Size in bytes of |data_|.

  // High watermark. The number of bytes (<= |size_|) written into the buffer
  // before the first wraparound. This increases as data is written into the
  // buffer and then saturates at |size_|. Used for CloneReadOnly().
  size_t used_size_ = 0;

  size_t max_chunk_size_ = 0;  // Max size in bytes allowed for a chunk.
  uint8_t* wptr_ = nullptr;    // Write pointer.

  // An index that keeps track of the positions and metadata of each
  // ChunkRecord.
  ChunkMap index_;

  // Read iterator used for ReadNext(). It is reset by calling BeginRead().
  // It becomes invalid after any call to methods that alters the |index_|.
  SequenceIterator read_iter_;

  // See comments at the top of the file.
  OverwritePolicy overwrite_policy_ = kOverwrite;

  // This buffer is a read-only snapshot obtained via Clone(). If this is true
  // calls to CopyChunkUntrusted() and TryPatchChunkContents() will CHECK().
  bool read_only_ = false;

  // Only used when |overwrite_policy_ == kDiscard|. This is set the first time
  // a write fails because it would overwrite unread chunks.
  bool discard_writes_ = false;

  // Keeps track of the highest ChunkID written for a given sequence, taking
  // into account a potential overflow of ChunkIDs. In the case of overflow,
  // stores the highest ChunkID written since the overflow.
  //
  // TODO(primiano): should clean up keys from this map. Right now it grows
  // without bounds (although realistically is not a problem unless we have too
  // many producers/writers within the same trace session).
  std::map<std::pair<ProducerID, WriterID>, ChunkID> last_chunk_id_written_;

  // Statistics about buffer usage.
  TraceStats::BufferStats stats_;

  // Per-{Producer, Writer} statistics.
  WriterStatsMap writer_stats_;

  // Set to true upon the very first call to CopyChunkUntrusted() and never
  // cleared. This is used to tell if the buffer has never been used since its
  // creation (which in turn is used to optimize `clear_before_clone`).
  bool has_data_ = false;

#if PERFETTO_DCHECK_IS_ON()
  bool changed_since_last_read_ = false;
#endif

  // When true disable some DCHECKs that have been put in place to detect
  // bugs in the producers. This is for tests that feed malicious inputs and
  // hence mimic a buggy producer.
  bool suppress_client_dchecks_for_testing_ = false;
};

}  // namespace perfetto

#endif  // SRC_TRACING_SERVICE_TRACE_BUFFER_H_
/*
 * Copyright (C) 2018 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// gen_amalgamated expanded: #include "src/tracing/service/trace_buffer.h"

#include <limits>

// gen_amalgamated expanded: #include "perfetto/base/logging.h"
// gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/client_identity.h"
// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/shared_memory_abi.h"
// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/trace_packet.h"
// gen_amalgamated expanded: #include "perfetto/protozero/proto_utils.h"

#define TRACE_BUFFER_VERBOSE_LOGGING() 0  // Set to 1 when debugging unittests.
#if TRACE_BUFFER_VERBOSE_LOGGING()
#define TRACE_BUFFER_DLOG PERFETTO_DLOG
#else
#define TRACE_BUFFER_DLOG(...) void()
#endif

namespace perfetto {

namespace {
constexpr uint8_t kFirstPacketContinuesFromPrevChunk =
    SharedMemoryABI::ChunkHeader::kFirstPacketContinuesFromPrevChunk;
constexpr uint8_t kLastPacketContinuesOnNextChunk =
    SharedMemoryABI::ChunkHeader::kLastPacketContinuesOnNextChunk;
constexpr uint8_t kChunkNeedsPatching =
    SharedMemoryABI::ChunkHeader::kChunkNeedsPatching;
}  // namespace.

const size_t TraceBuffer::InlineChunkHeaderSize = sizeof(ChunkRecord);

// static
std::unique_ptr<TraceBuffer> TraceBuffer::Create(size_t size_in_bytes,
                                                 OverwritePolicy pol) {
  std::unique_ptr<TraceBuffer> trace_buffer(new TraceBuffer(pol));
  if (!trace_buffer->Initialize(size_in_bytes))
    return nullptr;
  return trace_buffer;
}

TraceBuffer::TraceBuffer(OverwritePolicy pol) : overwrite_policy_(pol) {
  // See comments in ChunkRecord for the rationale of this.
  static_assert(sizeof(ChunkRecord) == sizeof(SharedMemoryABI::PageHeader) +
                                           sizeof(SharedMemoryABI::ChunkHeader),
                "ChunkRecord out of sync with the layout of SharedMemoryABI");
}

TraceBuffer::~TraceBuffer() = default;

bool TraceBuffer::Initialize(size_t size) {
  static_assert(
      SharedMemoryABI::kMinPageSize % sizeof(ChunkRecord) == 0,
      "sizeof(ChunkRecord) must be an integer divider of a page size");
  auto max_size = std::numeric_limits<decltype(ChunkMeta::record_off)>::max();
  PERFETTO_CHECK(size <= static_cast<size_t>(max_size));
  data_ = base::PagedMemory::Allocate(
      size, base::PagedMemory::kMayFail | base::PagedMemory::kDontCommit);
  if (!data_.IsValid()) {
    PERFETTO_ELOG("Trace buffer allocation failed (size: %zu)", size);
    return false;
  }
  size_ = size;
  used_size_ = 0;
  stats_.set_buffer_size(size);
  max_chunk_size_ = std::min(size, ChunkRecord::kMaxSize);
  wptr_ = begin();
  index_.clear();
  last_chunk_id_written_.clear();
  read_iter_ = GetReadIterForSequence(index_.end());
  return true;
}

// Note: |src| points to a shmem region that is shared with the producer. Assume
// that the producer is malicious and will change the content of |src|
// while we execute here. Don't do any processing on it other than memcpy().
void TraceBuffer::CopyChunkUntrusted(
    ProducerID producer_id_trusted,
    const ClientIdentity& client_identity_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) {
  PERFETTO_CHECK(!read_only_);

  // |record_size| = |size| + sizeof(ChunkRecord), rounded up to avoid to end
  // up in a fragmented state where size_to_end() < sizeof(ChunkRecord).
  const size_t record_size =
      base::AlignUp<sizeof(ChunkRecord)>(size + sizeof(ChunkRecord));
  TRACE_BUFFER_DLOG("CopyChunk @ %" PRIdPTR ", size=%zu", wptr_ - begin(), record_size);
  if (PERFETTO_UNLIKELY(record_size > max_chunk_size_)) {
    stats_.set_abi_violations(stats_.abi_violations() + 1);
    PERFETTO_DCHECK(suppress_client_dchecks_for_testing_);
    return;
  }

  has_data_ = true;
#if PERFETTO_DCHECK_IS_ON()
  changed_since_last_read_ = true;
#endif

  // If the chunk hasn't been completed, we should only consider the first
  // |num_fragments - 1| packets complete. For simplicity, we simply disregard
  // the last one when we copy the chunk.
  if (PERFETTO_UNLIKELY(!chunk_complete)) {
    if (num_fragments > 0) {
      num_fragments--;
      // These flags should only affect the last packet in the chunk. We clear
      // them, so that TraceBuffer is able to look at the remaining packets in
      // this chunk.
      chunk_flags &= ~kLastPacketContinuesOnNextChunk;
      chunk_flags &= ~kChunkNeedsPatching;
    }
  }

  ChunkRecord record(record_size);
  record.producer_id = producer_id_trusted;
  record.chunk_id = chunk_id;
  record.writer_id = writer_id;
  record.num_fragments = num_fragments;
  record.flags = chunk_flags & ChunkRecord::kFlagsBitMask;
  ChunkMeta::Key key(record);

  // Check whether we have already copied the same chunk previously. This may
  // happen if the service scrapes chunks in a potentially incomplete state
  // before receiving commit requests for them from the producer. Note that the
  // service may scrape and thus override chunks in arbitrary order since the
  // chunks aren't ordered in the SMB.
  const auto it = index_.find(key);
  if (PERFETTO_UNLIKELY(it != index_.end())) {
    ChunkMeta* record_meta = &it->second;
    ChunkRecord* prev = GetChunkRecordAt(begin() + record_meta->record_off);

    // Verify that the old chunk's metadata corresponds to the new one.
    // Overridden chunks should never change size, since the page layout is
    // fixed per writer. The number of fragments should also never decrease and
    // flags should not be removed.
    if (PERFETTO_UNLIKELY(ChunkMeta::Key(*prev) != key ||
                          prev->size != record_size ||
                          prev->num_fragments > num_fragments ||
                          (prev->flags & chunk_flags) != prev->flags)) {
      stats_.set_abi_violations(stats_.abi_violations() + 1);
      PERFETTO_DCHECK(suppress_client_dchecks_for_testing_);
      return;
    }

    // If this chunk was previously copied with the same number of fragments and
    // the number didn't change, there's no need to copy it again. If the
    // previous chunk was complete already, this should always be the case.
    PERFETTO_DCHECK(suppress_client_dchecks_for_testing_ ||
                    !record_meta->is_complete() ||
                    (chunk_complete && prev->num_fragments == num_fragments));
    if (prev->num_fragments == num_fragments) {
      TRACE_BUFFER_DLOG("  skipping recommit of identical chunk");
      return;
    }

    // If we've already started reading from chunk N+1 following this chunk N,
    // don't override chunk N. Otherwise we may end up reading a packet from
    // chunk N after having read from chunk N+1, thereby violating sequential
    // read of packets. This shouldn't happen if the producer is well-behaved,
    // because it shouldn't start chunk N+1 before completing chunk N.
    ChunkMeta::Key subsequent_key = key;
    static_assert(std::numeric_limits<ChunkID>::max() == kMaxChunkID,
                  "ChunkID wraps");
    subsequent_key.chunk_id++;
    const auto subsequent_it = index_.find(subsequent_key);
    if (subsequent_it != index_.end() &&
        subsequent_it->second.num_fragments_read > 0) {
      stats_.set_abi_violations(stats_.abi_violations() + 1);
      PERFETTO_DCHECK(suppress_client_dchecks_for_testing_);
      return;
    }

    // We should not have read past the last packet.
    if (record_meta->num_fragments_read > prev->num_fragments) {
      PERFETTO_ELOG(
          "TraceBuffer read too many fragments from an incomplete chunk");
      PERFETTO_DCHECK(suppress_client_dchecks_for_testing_);
      return;
    }

    uint8_t* wptr = reinterpret_cast<uint8_t*>(prev);
    TRACE_BUFFER_DLOG("  overriding chunk @ %" PRIdPTR ", size=%zu", wptr - begin(),
                      record_size);

    // Update chunk meta data stored in the index, as it may have changed.
    record_meta->num_fragments = num_fragments;
    record_meta->flags = chunk_flags;
    record_meta->set_complete(chunk_complete);

    // Override the ChunkRecord contents at the original |wptr|.
    TRACE_BUFFER_DLOG("  copying @ [%" PRIdPTR " - %" PRIdPTR "] %zu", wptr - begin(),
                      uintptr_t(wptr - begin()) + record_size, record_size);
    WriteChunkRecord(wptr, record, src, size);
    TRACE_BUFFER_DLOG("Chunk raw: %s",
                      base::HexDump(wptr, record_size).c_str());
    stats_.set_chunks_rewritten(stats_.chunks_rewritten() + 1);
    return;
  }

  if (PERFETTO_UNLIKELY(discard_writes_))
    return DiscardWrite();

  // If there isn't enough room from the given write position. Write a padding
  // record to clear the end of the buffer and wrap back.
  const size_t cached_size_to_end = size_to_end();
  if (PERFETTO_UNLIKELY(record_size > cached_size_to_end)) {
    ssize_t res = DeleteNextChunksFor(cached_size_to_end);
    if (res == -1)
      return DiscardWrite();
    PERFETTO_DCHECK(static_cast<size_t>(res) <= cached_size_to_end);
    AddPaddingRecord(cached_size_to_end);
    wptr_ = begin();
    stats_.set_write_wrap_count(stats_.write_wrap_count() + 1);
    PERFETTO_DCHECK(size_to_end() >= record_size);
  }

  // At this point either |wptr_| points to an untouched part of the buffer
  // (i.e. *wptr_ == 0) or we are about to overwrite one or more ChunkRecord(s).
  // In the latter case we need to first figure out where the next valid
  // ChunkRecord is (if it exists) and add padding between the new record.
  // Example ((w) == write cursor):
  //
  // Initial state (wtpr_ == 0):
  // |0 (w)    |10               |30                  |50
  // +---------+-----------------+--------------------+--------------------+
  // | Chunk 1 | Chunk 2         | Chunk 3            | Chunk 4            |
  // +---------+-----------------+--------------------+--------------------+
  //
  // Let's assume we now want now write a 5th Chunk of size == 35. The final
  // state should look like this:
  // |0                                |35 (w)         |50
  // +---------------------------------+---------------+--------------------+
  // | Chunk 5                         | Padding Chunk | Chunk 4            |
  // +---------------------------------+---------------+--------------------+

  // Deletes all chunks from |wptr_| to |wptr_| + |record_size|.
  ssize_t del_res = DeleteNextChunksFor(record_size);
  if (del_res == -1)
    return DiscardWrite();
  size_t padding_size = static_cast<size_t>(del_res);

  // Now first insert the new chunk. At the end, if necessary, add the padding.
  stats_.set_chunks_written(stats_.chunks_written() + 1);
  stats_.set_bytes_written(stats_.bytes_written() + record_size);

  uint32_t chunk_off = GetOffset(GetChunkRecordAt(wptr_));
  auto it_and_inserted =
      index_.emplace(key, ChunkMeta(chunk_off, num_fragments, chunk_complete,
                                    chunk_flags, client_identity_trusted));
  PERFETTO_DCHECK(it_and_inserted.second);
  TRACE_BUFFER_DLOG("  copying @ [%" PRIdPTR " - %" PRIdPTR "] %zu", wptr_ - begin(),
                    uintptr_t(wptr_ - begin()) + record_size, record_size);
  WriteChunkRecord(wptr_, record, src, size);
  TRACE_BUFFER_DLOG("Chunk raw: %s", base::HexDump(wptr_, record_size).c_str());
  wptr_ += record_size;
  if (wptr_ >= end()) {
    PERFETTO_DCHECK(padding_size == 0);
    wptr_ = begin();
    stats_.set_write_wrap_count(stats_.write_wrap_count() + 1);
  }
  DcheckIsAlignedAndWithinBounds(wptr_);

  // Chunks may be received out of order, so only update last_chunk_id if the
  // new chunk_id is larger. But take into account overflows by only selecting
  // the new ID if its distance to the latest ID is smaller than half the number
  // space.
  //
  // This accounts for both the case where the new ID has just overflown and
  // last_chunk_id be updated even though it's smaller (e.g. |chunk_id| = 1 and
  // |last_chunk_id| = kMaxChunkId; chunk_id - last_chunk_id = 0) and the case
  // where the new ID is an out-of-order ID right after an overflow and
  // last_chunk_id shouldn't be updated even though it's larger (e.g. |chunk_id|
  // = kMaxChunkId and |last_chunk_id| = 1; chunk_id - last_chunk_id =
  // kMaxChunkId - 1).
  auto producer_and_writer_id = std::make_pair(producer_id_trusted, writer_id);
  ChunkID& last_chunk_id = last_chunk_id_written_[producer_and_writer_id];
  static_assert(std::numeric_limits<ChunkID>::max() == kMaxChunkID,
                "This code assumes that ChunkID wraps at kMaxChunkID");
  if (chunk_id - last_chunk_id < kMaxChunkID / 2) {
    last_chunk_id = chunk_id;
  } else {
    stats_.set_chunks_committed_out_of_order(
        stats_.chunks_committed_out_of_order() + 1);
  }

  if (padding_size)
    AddPaddingRecord(padding_size);
}

ssize_t TraceBuffer::DeleteNextChunksFor(size_t bytes_to_clear) {
  PERFETTO_CHECK(!discard_writes_);

  // Find the position of the first chunk which begins at or after
  // (|wptr_| + |bytes|). Note that such a chunk might not exist and we might
  // either reach the end of the buffer or a zeroed region of the buffer.
  uint8_t* next_chunk_ptr = wptr_;
  uint8_t* search_end = wptr_ + bytes_to_clear;
  TRACE_BUFFER_DLOG("Delete [%zu %zu]", wptr_ - begin(), search_end - begin());
  DcheckIsAlignedAndWithinBounds(wptr_);
  PERFETTO_DCHECK(search_end <= end());
  std::vector<ChunkMap::iterator> index_delete;
  uint64_t chunks_overwritten = stats_.chunks_overwritten();
  uint64_t bytes_overwritten = stats_.bytes_overwritten();
  uint64_t padding_bytes_cleared = stats_.padding_bytes_cleared();
  while (next_chunk_ptr < search_end) {
    const ChunkRecord& next_chunk = *GetChunkRecordAt(next_chunk_ptr);
    TRACE_BUFFER_DLOG(
        "  scanning chunk [%zu %zu] (valid=%d)", next_chunk_ptr - begin(),
        next_chunk_ptr - begin() + next_chunk.size, next_chunk.is_valid());

    // We just reached the untouched part of the buffer, it's going to be all
    // zeroes from here to end().
    // Optimization: if during Initialize() we fill the buffer with padding
    // records we could get rid of this branch.
    if (PERFETTO_UNLIKELY(!next_chunk.is_valid())) {
      // This should happen only at the first iteration. The zeroed area can
      // only begin precisely at the |wptr_|, not after. Otherwise it means that
      // we wrapped but screwed up the ChunkRecord chain.
      PERFETTO_DCHECK(next_chunk_ptr == wptr_);
      return 0;
    }

    // Remove |next_chunk| from the index, unless it's a padding record (padding
    // records are not part of the index).
    if (PERFETTO_LIKELY(!next_chunk.is_padding)) {
      ChunkMeta::Key key(next_chunk);
      auto it = index_.find(key);
      bool will_remove = false;
      if (PERFETTO_LIKELY(it != index_.end())) {
        const ChunkMeta& meta = it->second;
        if (PERFETTO_UNLIKELY(meta.num_fragments_read < meta.num_fragments)) {
          if (overwrite_policy_ == kDiscard)
            return -1;
          chunks_overwritten++;
          bytes_overwritten += next_chunk.size;
        }
        index_delete.push_back(it);
        will_remove = true;
      }
      TRACE_BUFFER_DLOG(
          "  del index {%" PRIu32 ",%" PRIu32 ",%u} @ [%" PRIdPTR " - %" PRIdPTR "] %d",
          key.producer_id, key.writer_id, key.chunk_id,
          next_chunk_ptr - begin(), next_chunk_ptr - begin() + next_chunk.size,
          will_remove);
      PERFETTO_DCHECK(will_remove);
    } else {
      padding_bytes_cleared += next_chunk.size;
    }

    next_chunk_ptr += next_chunk.size;

    // We should never hit this, unless we managed to screw up while writing
    // to the buffer and breaking the ChunkRecord(s) chain.
    // TODO(primiano): Write more meaningful logging with the status of the
    // buffer, to get more actionable bugs in case we hit this.
    PERFETTO_CHECK(next_chunk_ptr <= end());
  }

  // Remove from the index.
  for (auto it : index_delete) {
    index_.erase(it);
  }
  stats_.set_chunks_overwritten(chunks_overwritten);
  stats_.set_bytes_overwritten(bytes_overwritten);
  stats_.set_padding_bytes_cleared(padding_bytes_cleared);

  PERFETTO_DCHECK(next_chunk_ptr >= search_end && next_chunk_ptr <= end());
  return static_cast<ssize_t>(next_chunk_ptr - search_end);
}

void TraceBuffer::AddPaddingRecord(size_t size) {
  PERFETTO_DCHECK(size >= sizeof(ChunkRecord) && size <= ChunkRecord::kMaxSize);
  ChunkRecord record(size);
  record.is_padding = 1;
  TRACE_BUFFER_DLOG("AddPaddingRecord @ [%" PRIdPTR " - %" PRIdPTR "] %zu", wptr_ - begin(),
                    uintptr_t(wptr_ - begin()) + size, size);
  WriteChunkRecord(wptr_, record, nullptr, size - sizeof(ChunkRecord));
  stats_.set_padding_bytes_written(stats_.padding_bytes_written() + size);
  // |wptr_| is deliberately not advanced when writing a padding record.
}

bool TraceBuffer::TryPatchChunkContents(ProducerID producer_id,
                                        WriterID writer_id,
                                        ChunkID chunk_id,
                                        const Patch* patches,
                                        size_t patches_size,
                                        bool other_patches_pending) {
  PERFETTO_CHECK(!read_only_);
  ChunkMeta::Key key(producer_id, writer_id, chunk_id);
  auto it = index_.find(key);
  if (it == index_.end()) {
    stats_.set_patches_failed(stats_.patches_failed() + 1);
    return false;
  }
  ChunkMeta& chunk_meta = it->second;

  // Check that the index is consistent with the actual ProducerID/WriterID
  // stored in the ChunkRecord.

  ChunkRecord* chunk_record = GetChunkRecordAt(begin() + chunk_meta.record_off);
  PERFETTO_DCHECK(ChunkMeta::Key(*chunk_record) == key);
  uint8_t* chunk_begin = reinterpret_cast<uint8_t*>(chunk_record);
  PERFETTO_DCHECK(chunk_begin >= begin());
  uint8_t* chunk_end = chunk_begin + chunk_record->size;
  PERFETTO_DCHECK(chunk_end <= end());

  static_assert(Patch::kSize == SharedMemoryABI::kPacketHeaderSize,
                "Patch::kSize out of sync with SharedMemoryABI");

  for (size_t i = 0; i < patches_size; i++) {
    uint8_t* ptr =
        chunk_begin + sizeof(ChunkRecord) + patches[i].offset_untrusted;
    TRACE_BUFFER_DLOG("PatchChunk {%" PRIu32 ",%" PRIu32
                      ",%u} size=%zu @ %zu with {%02x %02x %02x %02x} cur "
                      "{%02x %02x %02x %02x}",
                      producer_id, writer_id, chunk_id, chunk_end - chunk_begin,
                      patches[i].offset_untrusted, patches[i].data[0],
                      patches[i].data[1], patches[i].data[2],
                      patches[i].data[3], ptr[0], ptr[1], ptr[2], ptr[3]);
    if (ptr < chunk_begin + sizeof(ChunkRecord) ||
        ptr > chunk_end - Patch::kSize) {
      // Either the IPC was so slow and in the meantime the writer managed to
      // wrap over |chunk_id| or the producer sent a malicious IPC.
      stats_.set_patches_failed(stats_.patches_failed() + 1);
      return false;
    }

    memcpy(ptr, &patches[i].data[0], Patch::kSize);
  }
  TRACE_BUFFER_DLOG("Chunk raw (after patch): %s",
                    base::HexDump(chunk_begin, chunk_record->size).c_str());

  stats_.set_patches_succeeded(stats_.patches_succeeded() + patches_size);
  if (!other_patches_pending) {
    chunk_meta.flags &= ~kChunkNeedsPatching;
    chunk_record->flags = chunk_meta.flags & ChunkRecord::kFlagsBitMask;
  }
  return true;
}

void TraceBuffer::BeginRead() {
  read_iter_ = GetReadIterForSequence(index_.begin());
#if PERFETTO_DCHECK_IS_ON()
  changed_since_last_read_ = false;
#endif
}

TraceBuffer::SequenceIterator TraceBuffer::GetReadIterForSequence(
    ChunkMap::iterator seq_begin) {
  SequenceIterator iter;
  iter.seq_begin = seq_begin;
  if (seq_begin == index_.end()) {
    iter.cur = iter.seq_end = index_.end();
    return iter;
  }

#if PERFETTO_DCHECK_IS_ON()
  // Either |seq_begin| is == index_.begin() or the item immediately before must
  // belong to a different {ProducerID, WriterID} sequence.
  if (seq_begin != index_.begin() && seq_begin != index_.end()) {
    auto prev_it = seq_begin;
    prev_it--;
    PERFETTO_DCHECK(
        seq_begin == index_.begin() ||
        std::tie(prev_it->first.producer_id, prev_it->first.writer_id) <
            std::tie(seq_begin->first.producer_id, seq_begin->first.writer_id));
  }
#endif

  // Find the first entry that has a greater {ProducerID, WriterID} (or just
  // index_.end() if we reached the end).
  ChunkMeta::Key key = seq_begin->first;  // Deliberate copy.
  key.chunk_id = kMaxChunkID;
  iter.seq_end = index_.upper_bound(key);
  PERFETTO_DCHECK(iter.seq_begin != iter.seq_end);

  // Now find the first entry between [seq_begin, seq_end) that is
  // > last_chunk_id_written_. This is where we the sequence will start (see
  // notes about wrapping of IDs in the header).
  auto producer_and_writer_id = std::make_pair(key.producer_id, key.writer_id);
  PERFETTO_DCHECK(last_chunk_id_written_.count(producer_and_writer_id));
  iter.wrapping_id = last_chunk_id_written_[producer_and_writer_id];
  key.chunk_id = iter.wrapping_id;
  iter.cur = index_.upper_bound(key);
  if (iter.cur == iter.seq_end)
    iter.cur = iter.seq_begin;
  return iter;
}

void TraceBuffer::SequenceIterator::MoveNext() {
  // Stop iterating when we reach the end of the sequence.
  // Note: |seq_begin| might be == |seq_end|.
  if (cur == seq_end || cur->first.chunk_id == wrapping_id) {
    cur = seq_end;
    return;
  }

  // If the current chunk wasn't completed yet, we shouldn't advance past it as
  // it may be rewritten with additional packets.
  if (!cur->second.is_complete()) {
    cur = seq_end;
    return;
  }

  ChunkID last_chunk_id = cur->first.chunk_id;
  if (++cur == seq_end)
    cur = seq_begin;

  // There may be a missing chunk in the sequence of chunks, in which case the
  // next chunk's ID won't follow the last one's. If so, skip the rest of the
  // sequence. We'll return to it later once the hole is filled.
  if (last_chunk_id + 1 != cur->first.chunk_id)
    cur = seq_end;
}

bool TraceBuffer::ReadNextTracePacket(
    TracePacket* packet,
    PacketSequenceProperties* sequence_properties,
    bool* previous_packet_on_sequence_dropped) {
  // Note: MoveNext() moves only within the next chunk within the same
  // {ProducerID, WriterID} sequence. Here we want to:
  // - return the next patched+complete packet in the current sequence, if any.
  // - return the first patched+complete packet in the next sequence, if any.
  // - return false if none of the above is found.
  TRACE_BUFFER_DLOG("ReadNextTracePacket()");

  // Just in case we forget to initialize these below.
  *sequence_properties = {0, ClientIdentity(), 0};
  *previous_packet_on_sequence_dropped = false;

  // At the start of each sequence iteration, we consider the last read packet
  // dropped. While iterating over the chunks in the sequence, we update this
  // flag based on our knowledge about the last packet that was read from each
  // chunk (|last_read_packet_skipped| in ChunkMeta).
  bool previous_packet_dropped = true;

#if PERFETTO_DCHECK_IS_ON()
  PERFETTO_DCHECK(!changed_since_last_read_);
#endif
  for (;; read_iter_.MoveNext()) {
    if (PERFETTO_UNLIKELY(!read_iter_.is_valid())) {
      // We ran out of chunks in the current {ProducerID, WriterID} sequence or
      // we just reached the index_.end().

      if (PERFETTO_UNLIKELY(read_iter_.seq_end == index_.end()))
        return false;

      // We reached the end of sequence, move to the next one.
      // Note: ++read_iter_.seq_end might become index_.end(), but
      // GetReadIterForSequence() knows how to deal with that.
      read_iter_ = GetReadIterForSequence(read_iter_.seq_end);
      PERFETTO_DCHECK(read_iter_.is_valid() && read_iter_.cur != index_.end());
      previous_packet_dropped = true;
    }

    ChunkMeta* chunk_meta = &*read_iter_;

    // If the chunk has holes that are awaiting to be patched out-of-band,
    // skip the current sequence and move to the next one.
    if (chunk_meta->flags & kChunkNeedsPatching) {
      read_iter_.MoveToEnd();
      continue;
    }

    const ProducerID trusted_producer_id = read_iter_.producer_id();
    const WriterID writer_id = read_iter_.writer_id();
    const ProducerAndWriterID producer_and_writer_id =
        MkProducerAndWriterID(trusted_producer_id, writer_id);
    const ClientIdentity& client_identity = chunk_meta->client_identity_trusted;

    // At this point we have a chunk in |chunk_meta| that has not been fully
    // read. We don't know yet whether we have enough data to read the full
    // packet (in the case it's fragmented over several chunks) and we are about
    // to find that out. Specifically:
    // A) If the first fragment is unread and is a fragment continuing from a
    //    previous chunk, it means we have missed the previous ChunkID. In
    //    fact, if this wasn't the case, a previous call to ReadNext() shouldn't
    //    have moved the cursor to this chunk.
    // B) Any fragment > 0 && < last is always readable. By definition an inner
    //    packet is never fragmented and hence doesn't require neither stitching
    //    nor any out-of-band patching. The same applies to the last packet
    //    iff it doesn't continue on the next chunk.
    // C) If the last packet (which might be also the only packet in the chunk)
    //    is a fragment and continues on the next chunk, we peek at the next
    //    chunks and, if we have all of them, mark as read and move the cursor.
    //
    // +---------------+   +-------------------+  +---------------+
    // | ChunkID: 1    |   | ChunkID: 2        |  | ChunkID: 3    |
    // |---------------+   +-------------------+  +---------------+
    // | Packet 1      |   |                   |  | ... Packet 3  |
    // | Packet 2      |   | ... Packet 3  ... |  | Packet 4      |
    // | Packet 3  ... |   |                   |  | Packet 5 ...  |
    // +---------------+   +-------------------+  +---------------+

    PERFETTO_DCHECK(chunk_meta->num_fragments_read <=
                    chunk_meta->num_fragments);

    // If we didn't read any packets from this chunk, the last packet was from
    // the previous chunk we iterated over; so don't update
    // |previous_packet_dropped| in this case.
    if (chunk_meta->num_fragments_read > 0)
      previous_packet_dropped = chunk_meta->last_read_packet_skipped();

    while (chunk_meta->num_fragments_read < chunk_meta->num_fragments) {
      enum { kSkip = 0, kReadOnePacket, kTryReadAhead } action;
      if (chunk_meta->num_fragments_read == 0) {
        if (chunk_meta->flags & kFirstPacketContinuesFromPrevChunk) {
          action = kSkip;  // Case A.
        } else if (chunk_meta->num_fragments == 1 &&
                   (chunk_meta->flags & kLastPacketContinuesOnNextChunk)) {
          action = kTryReadAhead;  // Case C.
        } else {
          action = kReadOnePacket;  // Case B.
        }
      } else if (chunk_meta->num_fragments_read <
                     chunk_meta->num_fragments - 1 ||
                 !(chunk_meta->flags & kLastPacketContinuesOnNextChunk)) {
        action = kReadOnePacket;  // Case B.
      } else {
        action = kTryReadAhead;  // Case C.
      }

      TRACE_BUFFER_DLOG("  chunk %u, packet %hu of %hu, action=%d",
                        read_iter_.chunk_id(), chunk_meta->num_fragments_read,
                        chunk_meta->num_fragments, action);

      if (action == kSkip) {
        // This fragment will be skipped forever, not just in this ReadPacket()
        // iteration. This happens by virtue of ReadNextPacketInChunk()
        // incrementing the |num_fragments_read| and marking the fragment as
        // read even if we didn't really.
        ReadNextPacketInChunk(producer_and_writer_id, chunk_meta, nullptr);
        chunk_meta->set_last_read_packet_skipped(true);
        previous_packet_dropped = true;
        continue;
      }

      if (action == kReadOnePacket) {
        // The easy peasy case B.
        ReadPacketResult result =
            ReadNextPacketInChunk(producer_and_writer_id, chunk_meta, packet);

        if (PERFETTO_LIKELY(result == ReadPacketResult::kSucceeded)) {
          *sequence_properties = {trusted_producer_id, client_identity,
                                  writer_id};
          *previous_packet_on_sequence_dropped = previous_packet_dropped;
          return true;
        } else if (result == ReadPacketResult::kFailedEmptyPacket) {
          // We can ignore and skip empty packets.
          PERFETTO_DCHECK(packet->slices().empty());
          continue;
        }

        // In extremely rare cases (producer bugged / malicious) the chunk might
        // contain an invalid fragment. In such case we don't want to stall the
        // sequence but just skip the chunk and move on. ReadNextPacketInChunk()
        // marks the chunk as fully read, so we don't attempt to read from it
        // again in a future call to ReadBuffers(). It also already records an
        // abi violation for this.
        PERFETTO_DCHECK(result == ReadPacketResult::kFailedInvalidPacket);
        chunk_meta->set_last_read_packet_skipped(true);
        previous_packet_dropped = true;
        break;
      }

      PERFETTO_DCHECK(action == kTryReadAhead);
      ReadAheadResult ra_res = ReadAhead(packet);
      if (ra_res == ReadAheadResult::kSucceededReturnSlices) {
        stats_.set_readaheads_succeeded(stats_.readaheads_succeeded() + 1);
        *sequence_properties = {trusted_producer_id, client_identity,
                                writer_id};
        *previous_packet_on_sequence_dropped = previous_packet_dropped;
        return true;
      }

      if (ra_res == ReadAheadResult::kFailedMoveToNextSequence) {
        // readahead didn't find a contiguous packet sequence. We'll try again
        // on the next ReadPacket() call.
        stats_.set_readaheads_failed(stats_.readaheads_failed() + 1);

        // TODO(primiano): optimization: this MoveToEnd() is the reason why
        // MoveNext() (that is called in the outer for(;;MoveNext)) needs to
        // deal gracefully with the case of |cur|==|seq_end|. Maybe we can do
        // something to avoid that check by reshuffling the code here?
        read_iter_.MoveToEnd();

        // This break will go back to beginning of the for(;;MoveNext()). That
        // will move to the next sequence because we set the read iterator to
        // its end.
        break;
      }

      PERFETTO_DCHECK(ra_res == ReadAheadResult::kFailedStayOnSameSequence);

      // In this case ReadAhead() might advance |read_iter_|, so we need to
      // re-cache the |chunk_meta| pointer to point to the current chunk.
      chunk_meta = &*read_iter_;
      chunk_meta->set_last_read_packet_skipped(true);
      previous_packet_dropped = true;
    }  // while(...)  [iterate over packet fragments for the current chunk].
  }    // for(;;MoveNext()) [iterate over chunks].
}

TraceBuffer::ReadAheadResult TraceBuffer::ReadAhead(TracePacket* packet) {
  static_assert(static_cast<ChunkID>(kMaxChunkID + 1) == 0,
                "relying on kMaxChunkID to wrap naturally");
  TRACE_BUFFER_DLOG(" readahead start @ chunk %u", read_iter_.chunk_id());
  ChunkID next_chunk_id = read_iter_.chunk_id() + 1;
  SequenceIterator it = read_iter_;
  for (it.MoveNext(); it.is_valid(); it.MoveNext(), next_chunk_id++) {
    // We should stay within the same sequence while iterating here.
    PERFETTO_DCHECK(it.producer_id() == read_iter_.producer_id() &&
                    it.writer_id() == read_iter_.writer_id());

    TRACE_BUFFER_DLOG("   expected chunk ID: %u, actual ID: %u", next_chunk_id,
                      it.chunk_id());

    if (PERFETTO_UNLIKELY((*it).num_fragments == 0))
      continue;

    // If we miss the next chunk, stop looking in the current sequence and
    // try another sequence. This chunk might come in the near future.
    // The second condition is the edge case of a buggy/malicious
    // producer. The ChunkID is contiguous but its flags don't make sense.
    if (it.chunk_id() != next_chunk_id ||
        PERFETTO_UNLIKELY(
            !((*it).flags & kFirstPacketContinuesFromPrevChunk))) {
      return ReadAheadResult::kFailedMoveToNextSequence;
    }

    // If the chunk is contiguous but has not been patched yet move to the next
    // sequence and try coming back here on the next ReadNextTracePacket() call.
    // TODO(primiano): add a test to cover this, it's a subtle case.
    if ((*it).flags & kChunkNeedsPatching)
      return ReadAheadResult::kFailedMoveToNextSequence;

    // This is the case of an intermediate chunk which contains only one
    // fragment which continues on the next chunk. This is the case for large
    // packets, e.g.: [Packet0, Packet1(0)] [Packet1(1)] [Packet1(2), ...]
    // (Packet1(X) := fragment X of Packet1).
    if ((*it).num_fragments == 1 &&
        ((*it).flags & kLastPacketContinuesOnNextChunk)) {
      continue;
    }

    // We made it! We got all fragments for the packet without holes.
    TRACE_BUFFER_DLOG("  readahead success @ chunk %u", it.chunk_id());
    PERFETTO_DCHECK(((*it).num_fragments == 1 &&
                     !((*it).flags & kLastPacketContinuesOnNextChunk)) ||
                    (*it).num_fragments > 1);

    // Now let's re-iterate over the [read_iter_, it] sequence and mark
    // all the fragments as read.
    bool packet_corruption = false;
    for (;;) {
      PERFETTO_DCHECK(read_iter_.is_valid());
      TRACE_BUFFER_DLOG("    commit chunk %u", read_iter_.chunk_id());
      if (PERFETTO_LIKELY((*read_iter_).num_fragments > 0)) {
        // In the unlikely case of a corrupted packet (corrupted or empty
        // fragment), invalidate the all stitching and move on to the next chunk
        // in the same sequence, if any.
        auto pw_id = MkProducerAndWriterID(it.producer_id(), it.writer_id());
        packet_corruption |=
            ReadNextPacketInChunk(pw_id, &*read_iter_, packet) ==
            ReadPacketResult::kFailedInvalidPacket;
      }
      if (read_iter_.cur == it.cur)
        break;
      read_iter_.MoveNext();
    }  // for(;;)
    PERFETTO_DCHECK(read_iter_.cur == it.cur);

    if (PERFETTO_UNLIKELY(packet_corruption)) {
      // ReadNextPacketInChunk() already records an abi violation for this case.
      *packet = TracePacket();  // clear.
      return ReadAheadResult::kFailedStayOnSameSequence;
    }

    return ReadAheadResult::kSucceededReturnSlices;
  }  // for(it...)  [readahead loop]
  return ReadAheadResult::kFailedMoveToNextSequence;
}

TraceBuffer::ReadPacketResult TraceBuffer::ReadNextPacketInChunk(
    ProducerAndWriterID producer_and_writer_id,
    ChunkMeta* const chunk_meta,
    TracePacket* packet) {
  PERFETTO_DCHECK(chunk_meta->num_fragments_read < chunk_meta->num_fragments);
  PERFETTO_DCHECK(!(chunk_meta->flags & kChunkNeedsPatching));

  const uint8_t* record_begin = begin() + chunk_meta->record_off;
  DcheckIsAlignedAndWithinBounds(record_begin);
  auto* chunk_record = reinterpret_cast<const ChunkRecord*>(record_begin);
  const uint8_t* record_end = record_begin + chunk_record->size;
  const uint8_t* packets_begin = record_begin + sizeof(ChunkRecord);
  const uint8_t* packet_begin = packets_begin + chunk_meta->cur_fragment_offset;

  if (PERFETTO_UNLIKELY(packet_begin < packets_begin ||
                        packet_begin >= record_end)) {
    // The producer has a bug or is malicious and did declare that the chunk
    // contains more packets beyond its boundaries.
    stats_.set_abi_violations(stats_.abi_violations() + 1);
    PERFETTO_DCHECK(suppress_client_dchecks_for_testing_);
    chunk_meta->cur_fragment_offset = 0;
    chunk_meta->num_fragments_read = chunk_meta->num_fragments;
    if (PERFETTO_LIKELY(chunk_meta->is_complete())) {
      stats_.set_chunks_read(stats_.chunks_read() + 1);
      stats_.set_bytes_read(stats_.bytes_read() + chunk_record->size);
    }
    return ReadPacketResult::kFailedInvalidPacket;
  }

  // A packet (or a fragment) starts with a varint stating its size, followed
  // by its content. The varint shouldn't be larger than 4 bytes (just in case
  // the producer is using a redundant encoding)
  uint64_t packet_size = 0;
  const uint8_t* header_end =
      std::min(packet_begin + protozero::proto_utils::kMessageLengthFieldSize,
               record_end);
  const uint8_t* packet_data = protozero::proto_utils::ParseVarInt(
      packet_begin, header_end, &packet_size);

  const uint8_t* next_packet = packet_data + packet_size;
  if (PERFETTO_UNLIKELY(next_packet <= packet_begin ||
                        next_packet > record_end)) {
    // In BufferExhaustedPolicy::kDrop mode, TraceWriter may abort a fragmented
    // packet by writing an invalid size in the last fragment's header. We
    // should handle this case without recording an ABI violation (since Android
    // R).
    if (packet_size != SharedMemoryABI::kPacketSizeDropPacket) {
      stats_.set_abi_violations(stats_.abi_violations() + 1);
      PERFETTO_DCHECK(suppress_client_dchecks_for_testing_);
    } else {
      stats_.set_trace_writer_packet_loss(stats_.trace_writer_packet_loss() +
                                          1);
    }
    chunk_meta->cur_fragment_offset = 0;
    chunk_meta->num_fragments_read = chunk_meta->num_fragments;
    if (PERFETTO_LIKELY(chunk_meta->is_complete())) {
      stats_.set_chunks_read(stats_.chunks_read() + 1);
      stats_.set_bytes_read(stats_.bytes_read() + chunk_record->size);
    }
    return ReadPacketResult::kFailedInvalidPacket;
  }

  chunk_meta->cur_fragment_offset =
      static_cast<uint16_t>(next_packet - packets_begin);
  chunk_meta->num_fragments_read++;

  if (PERFETTO_UNLIKELY(chunk_meta->num_fragments_read ==
                            chunk_meta->num_fragments &&
                        chunk_meta->is_complete())) {
    stats_.set_chunks_read(stats_.chunks_read() + 1);
    stats_.set_bytes_read(stats_.bytes_read() + chunk_record->size);
    auto* writer_stats = writer_stats_.Insert(producer_and_writer_id, {}).first;
    writer_stats->used_chunk_hist.Add(chunk_meta->cur_fragment_offset);
  } else {
    // We have at least one more packet to parse. It should be within the chunk.
    if (chunk_meta->cur_fragment_offset + sizeof(ChunkRecord) >=
        chunk_record->size) {
      PERFETTO_DCHECK(suppress_client_dchecks_for_testing_);
    }
  }

  chunk_meta->set_last_read_packet_skipped(false);

  if (PERFETTO_UNLIKELY(packet_size == 0))
    return ReadPacketResult::kFailedEmptyPacket;

  if (PERFETTO_LIKELY(packet))
    packet->AddSlice(packet_data, static_cast<size_t>(packet_size));

  return ReadPacketResult::kSucceeded;
}

void TraceBuffer::DiscardWrite() {
  PERFETTO_DCHECK(overwrite_policy_ == kDiscard);
  discard_writes_ = true;
  stats_.set_chunks_discarded(stats_.chunks_discarded() + 1);
  TRACE_BUFFER_DLOG("  discarding write");
}

std::unique_ptr<TraceBuffer> TraceBuffer::CloneReadOnly() const {
  std::unique_ptr<TraceBuffer> buf(new TraceBuffer(CloneCtor(), *this));
  if (!buf->data_.IsValid())
    return nullptr;  // PagedMemory::Allocate() failed. We are out of memory.
  return buf;
}

TraceBuffer::TraceBuffer(CloneCtor, const TraceBuffer& src)
    : overwrite_policy_(src.overwrite_policy_),
      read_only_(true),
      discard_writes_(src.discard_writes_) {
  if (!Initialize(src.data_.size()))
    return;  // TraceBuffer::Clone() will check |data_| and return nullptr.

  // The assignments below must be done after Initialize().

  EnsureCommitted(src.used_size_);
  memcpy(data_.Get(), src.data_.Get(), src.used_size_);
  last_chunk_id_written_ = src.last_chunk_id_written_;

  stats_ = src.stats_;
  stats_.set_bytes_read(0);
  stats_.set_chunks_read(0);
  stats_.set_readaheads_failed(0);
  stats_.set_readaheads_succeeded(0);

  // Copy the index of chunk metadata and reset the read states.
  index_ = ChunkMap(src.index_);
  for (auto& kv : index_) {
    ChunkMeta& chunk_meta = kv.second;
    chunk_meta.num_fragments_read = 0;
    chunk_meta.cur_fragment_offset = 0;
    chunk_meta.set_last_read_packet_skipped(false);
  }
  read_iter_ = SequenceIterator();
}

}  // namespace perfetto
// gen_amalgamated begin source: src/tracing/service/tracing_service_impl.cc
// gen_amalgamated begin header: src/tracing/service/tracing_service_impl.h
// gen_amalgamated begin header: include/perfetto/ext/base/circular_queue.h
/*
 * Copyright (C) 2019 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef INCLUDE_PERFETTO_EXT_BASE_CIRCULAR_QUEUE_H_
#define INCLUDE_PERFETTO_EXT_BASE_CIRCULAR_QUEUE_H_

#include <stdint.h>
#include <stdlib.h>

#include <cstddef>
#include <iterator>

// gen_amalgamated expanded: #include "perfetto/base/logging.h"
// gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"

namespace perfetto {
namespace base {

// CircularQueue is a push-back-only / pop-front-only queue with the following
// characteristics:
// - The storage is based on a flat circular buffer. Beginning and end wrap
//   as necessary, to keep pushes and pops O(1) as long as capacity expansion is
//   not required.
// - Capacity is automatically expanded like in a std::vector. Expansion has a
//   O(N) cost.
// - It allows random access, allowing in-place std::sort.
// - Iterators are not stable. Mutating the container invalidates all iterators.
// - It doesn't bother with const-correctness.
//
// Implementation details:
// Internally, |begin|, |end| and iterators use 64-bit monotonic indexes, which
// are incremented as if the queue was backed by unlimited storage.
// Even assuming that elements are inserted and removed every nanosecond, 64 bit
// is enough for 584 years.
// Wrapping happens only when addressing elements in the underlying circular
// storage. This limits the complexity and avoiding dealing with modular
// arithmetic all over the places.
template <class T>
class CircularQueue {
 public:
  class Iterator {
   public:
    using difference_type = ptrdiff_t;
    using value_type = T;
    using pointer = T*;
    using reference = T&;
    using iterator_category = std::random_access_iterator_tag;

    Iterator(CircularQueue* queue, uint64_t pos, uint32_t generation)
        : queue_(queue),
          pos_(pos)
#if PERFETTO_DCHECK_IS_ON()
          ,
          generation_(generation)
#endif
    {
      ignore_result(generation);
    }

    Iterator(const Iterator&) noexcept = default;
    Iterator& operator=(const Iterator&) noexcept = default;
    Iterator(Iterator&&) noexcept = default;
    Iterator& operator=(Iterator&&) noexcept = default;

    T* operator->() const {
#if PERFETTO_DCHECK_IS_ON()
      PERFETTO_DCHECK(generation_ == queue_->generation());
#endif
      return queue_->Get(pos_);
    }

    T& operator*() const { return *(operator->()); }

    value_type& operator[](difference_type i) { return *(*this + i); }

    Iterator& operator++() {
      Add(1);
      return *this;
    }

    Iterator operator++(int) {
      Iterator ret = *this;
      Add(1);
      return ret;
    }

    Iterator& operator--() {
      Add(-1);
      return *this;
    }

    Iterator operator--(int) {
      Iterator ret = *this;
      Add(-1);
      return ret;
    }

    friend Iterator operator+(const Iterator& iter, difference_type offset) {
      Iterator ret = iter;
      ret.Add(offset);
      return ret;
    }

    Iterator& operator+=(difference_type offset) {
      Add(offset);
      return *this;
    }

    friend Iterator operator-(const Iterator& iter, difference_type offset) {
      Iterator ret = iter;
      ret.Add(-offset);
      return ret;
    }

    Iterator& operator-=(difference_type offset) {
      Add(-offset);
      return *this;
    }

    friend ptrdiff_t operator-(const Iterator& lhs, const Iterator& rhs) {
      return static_cast<ptrdiff_t>(lhs.pos_) -
             static_cast<ptrdiff_t>(rhs.pos_);
    }

    friend bool operator==(const Iterator& lhs, const Iterator& rhs) {
      return lhs.pos_ == rhs.pos_;
    }

    friend bool operator!=(const Iterator& lhs, const Iterator& rhs) {
      return lhs.pos_ != rhs.pos_;
    }

    friend bool operator<(const Iterator& lhs, const Iterator& rhs) {
      return lhs.pos_ < rhs.pos_;
    }

    friend bool operator<=(const Iterator& lhs, const Iterator& rhs) {
      return lhs.pos_ <= rhs.pos_;
    }

    friend bool operator>(const Iterator& lhs, const Iterator& rhs) {
      return lhs.pos_ > rhs.pos_;
    }

    friend bool operator>=(const Iterator& lhs, const Iterator& rhs) {
      return lhs.pos_ >= rhs.pos_;
    }

   private:
    inline void Add(difference_type offset) {
      pos_ = static_cast<uint64_t>(static_cast<difference_type>(pos_) + offset);
      PERFETTO_DCHECK(pos_ <= queue_->end_);
    }

    CircularQueue* queue_;
    uint64_t pos_;

#if PERFETTO_DCHECK_IS_ON()
    uint32_t generation_;
#endif
  };

  explicit CircularQueue(size_t initial_capacity = 1024) {
    Grow(initial_capacity);
  }

  CircularQueue(CircularQueue&& other) noexcept
      : entries_(std::move(other.entries_)),
        capacity_(other.capacity_),
        begin_(other.begin_),
        end_(other.end_) {
    increment_generation();
    new (&other) CircularQueue();  // Reset the old queue so it's still usable.
  }

  CircularQueue& operator=(CircularQueue&& other) noexcept {
    this->~CircularQueue();                      // Destroy the current state.
    new (this) CircularQueue(std::move(other));  // Use the move ctor above.
    return *this;
  }

  explicit CircularQueue(const CircularQueue& other) noexcept {
    Grow(other.capacity());
    for (const auto& e : const_cast<CircularQueue&>(other))
      emplace_back(e);
    PERFETTO_DCHECK(size() == other.size());
  }

  CircularQueue& operator=(const CircularQueue& other) noexcept {
    this->~CircularQueue();           // Destroy the current state.
    new (this) CircularQueue(other);  // Use the copy ctor above.
    return *this;
  }

  ~CircularQueue() {
    if (!entries_) {
      PERFETTO_DCHECK(empty());
      return;
    }
    clear();  // Invoke destructors on all alive entries.
    PERFETTO_DCHECK(empty());
  }

  template <typename... Args>
  void emplace_back(Args&&... args) {
    increment_generation();
    if (PERFETTO_UNLIKELY(size() >= capacity_))
      Grow();
    T* slot = Get(end_++);
    new (slot) T(std::forward<Args>(args)...);
  }

  void erase_front(size_t n) {
    increment_generation();
    for (; n && (begin_ < end_); --n) {
      Get(begin_)->~T();
      begin_++;  // This needs to be its own statement, Get() checks begin_.
    }
  }

  void pop_front() { erase_front(1); }

  void clear() { erase_front(size()); }

  void shrink_to_fit() {
    // We only bother shrinking if we can fit in quarter of the capacity we are
    // currently using. Moreover, don't bother shrinking below 4096 elements as
    // that will cause a lot of reallocations for little benefit.
    if (size() > capacity() / 2 || capacity() <= 4096) {
      return;
    }
    ChangeCapacity(capacity() / 2);
  }

  T& at(size_t idx) {
    PERFETTO_DCHECK(idx < size());
    return *Get(begin_ + idx);
  }

  Iterator begin() { return Iterator(this, begin_, generation()); }
  Iterator end() { return Iterator(this, end_, generation()); }
  T& front() { return *begin(); }
  T& back() { return *(end() - 1); }

  bool empty() const { return size() == 0; }

  size_t size() const {
    PERFETTO_DCHECK(end_ - begin_ <= capacity_);
    return static_cast<size_t>(end_ - begin_);
  }

  size_t capacity() const { return capacity_; }

#if PERFETTO_DCHECK_IS_ON()
  uint32_t generation() const { return generation_; }
  void increment_generation() { ++generation_; }
#else
  uint32_t generation() const { return 0; }
  void increment_generation() {}
#endif

 private:
  void Grow(size_t new_capacity = 0) {
    // Capacity must be always a power of two. This allows Get() to use a simple
    // bitwise-AND for handling the wrapping instead of a full division.
    new_capacity = new_capacity ? new_capacity : capacity_ * 2;
    PERFETTO_CHECK((new_capacity & (new_capacity - 1)) == 0);  // Must be pow2.

    // On 32-bit systems this might hit the 4GB wall and overflow. We can't do
    // anything other than crash in this case.
    PERFETTO_CHECK(new_capacity > capacity_);

    ChangeCapacity(new_capacity);
  }

  void ChangeCapacity(size_t new_capacity) {
    // We should still have enough space to fit all the elements in the queue.
    PERFETTO_CHECK(new_capacity >= size());

    AlignedUniquePtr<T[]> new_vec = AlignedAllocTyped<T[]>(new_capacity);

    // Move all elements in the expanded array.
    size_t new_size = 0;
    for (uint64_t i = begin_; i < end_; i++)
      new (&new_vec[new_size++]) T(std::move(*Get(i)));  // Placement move ctor.

    // Even if all the elements are std::move()-d and likely empty, we are still
    // required to call the dtor for them.
    for (uint64_t i = begin_; i < end_; i++)
      Get(i)->~T();

    begin_ = 0;
    end_ = new_size;
    capacity_ = new_capacity;
    entries_ = std::move(new_vec);
  }

  inline T* Get(uint64_t pos) {
    PERFETTO_DCHECK(pos >= begin_ && pos < end_);
    PERFETTO_DCHECK((capacity_ & (capacity_ - 1)) == 0);  // Must be a pow2.
    auto index = static_cast<size_t>(pos & (capacity_ - 1));
    return &entries_[index];
  }

  // Underlying storage. It's raw malloc-ed rather than being a unique_ptr<T[]>
  // to allow having uninitialized entries inside it.
  AlignedUniquePtr<T[]> entries_;
  size_t capacity_ = 0;  // Number of allocated slots (NOT bytes) in |entries_|.

  // The |begin_| and |end_| indexes are monotonic and never wrap. Modular arith
  // is used only when dereferencing entries in the vector.
  uint64_t begin_ = 0;
  uint64_t end_ = 0;

// Generation is used in debug builds only for checking iterator validity.
#if PERFETTO_DCHECK_IS_ON()
  uint32_t generation_ = 0;
#endif
};

}  // namespace base
}  // namespace perfetto

#endif  // INCLUDE_PERFETTO_EXT_BASE_CIRCULAR_QUEUE_H_
/*
 * Copyright (C) 2017 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef SRC_TRACING_SERVICE_TRACING_SERVICE_IMPL_H_
#define SRC_TRACING_SERVICE_TRACING_SERVICE_IMPL_H_

#include <algorithm>
#include <functional>
#include <map>
#include <memory>
#include <optional>
#include <random>
#include <set>
#include <utility>
#include <vector>

// gen_amalgamated expanded: #include "perfetto/base/logging.h"
// gen_amalgamated expanded: #include "perfetto/base/status.h"
// gen_amalgamated expanded: #include "perfetto/base/time.h"
// gen_amalgamated expanded: #include "perfetto/ext/base/circular_queue.h"
// gen_amalgamated expanded: #include "perfetto/ext/base/periodic_task.h"
// gen_amalgamated expanded: #include "perfetto/ext/base/uuid.h"
// gen_amalgamated expanded: #include "perfetto/ext/base/weak_ptr.h"
// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/basic_types.h"
// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/client_identity.h"
// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/commit_data_request.h"
// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/observable_events.h"
// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/shared_memory_abi.h"
// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/trace_stats.h"
// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/tracing_service.h"
// gen_amalgamated expanded: #include "perfetto/tracing/core/data_source_config.h"
// gen_amalgamated expanded: #include "perfetto/tracing/core/data_source_descriptor.h"
// gen_amalgamated expanded: #include "perfetto/tracing/core/forward_decls.h"
// gen_amalgamated expanded: #include "perfetto/tracing/core/trace_config.h"
// gen_amalgamated expanded: #include "src/android_stats/perfetto_atoms.h"
// gen_amalgamated expanded: #include "src/tracing/core/id_allocator.h"

namespace protozero {
class MessageFilter;
}

namespace perfetto {

namespace base {
class TaskRunner;
}  // namespace base

namespace protos {
namespace gen {
enum TraceStats_FinalFlushOutcome : int;
}
}  // namespace protos

class Consumer;
class Producer;
class SharedMemory;
class SharedMemoryArbiterImpl;
class TraceBuffer;
class TracePacket;

// The tracing service business logic.
class TracingServiceImpl : public TracingService {
 private:
  struct DataSourceInstance;

 public:
  static constexpr size_t kMaxShmSize = 32 * 1024 * 1024ul;
  static constexpr uint32_t kDataSourceStopTimeoutMs = 5000;
  static constexpr uint8_t kSyncMarker[] = {0x82, 0x47, 0x7a, 0x76, 0xb2, 0x8d,
                                            0x42, 0xba, 0x81, 0xdc, 0x33, 0x32,
                                            0x6d, 0x57, 0xa0, 0x79};
  static constexpr size_t kMaxTracePacketSliceSize =
      128 * 1024 - 512;  // This is ipc::kIPCBufferSize - 512, see assertion in
                         // tracing_integration_test.cc and b/195065199

  // This is a rough threshold to determine how many bytes to read from the
  // buffers on each iteration when writing into a file. Since filtering and
  // compression allocate memory, this effectively limits the amount of memory
  // allocated.
  static constexpr size_t kWriteIntoFileChunkSize = 1024 * 1024ul;

  // The implementation behind the service endpoint exposed to each producer.
  class ProducerEndpointImpl : public TracingService::ProducerEndpoint {
   public:
    ProducerEndpointImpl(ProducerID,
                         const ClientIdentity& client_identity,
                         TracingServiceImpl*,
                         base::TaskRunner*,
                         Producer*,
                         const std::string& producer_name,
                         const std::string& sdk_version,
                         bool in_process,
                         bool smb_scraping_enabled);
    ~ProducerEndpointImpl() override;

    // TracingService::ProducerEndpoint implementation.
    void Disconnect() override;
    void RegisterDataSource(const DataSourceDescriptor&) override;
    void UpdateDataSource(const DataSourceDescriptor&) override;
    void UnregisterDataSource(const std::string& name) override;
    void RegisterTraceWriter(uint32_t writer_id,
                             uint32_t target_buffer) override;
    void UnregisterTraceWriter(uint32_t writer_id) override;
    void CommitData(const CommitDataRequest&, CommitDataCallback) override;
    void SetupSharedMemory(std::unique_ptr<SharedMemory>,
                           size_t page_size_bytes,
                           bool provided_by_producer);
    std::unique_ptr<TraceWriter> CreateTraceWriter(
        BufferID,
        BufferExhaustedPolicy) override;
    SharedMemoryArbiter* MaybeSharedMemoryArbiter() override;
    bool IsShmemProvidedByProducer() const override;
    void NotifyFlushComplete(FlushRequestID) override;
    void NotifyDataSourceStarted(DataSourceInstanceID) override;
    void NotifyDataSourceStopped(DataSourceInstanceID) override;
    SharedMemory* shared_memory() const override;
    size_t shared_buffer_page_size_kb() const override;
    void ActivateTriggers(const std::vector<std::string>&) override;
    void Sync(std::function<void()> callback) override;

    void OnTracingSetup();
    void SetupDataSource(DataSourceInstanceID, const DataSourceConfig&);
    void StartDataSource(DataSourceInstanceID, const DataSourceConfig&);
    void StopDataSource(DataSourceInstanceID);
    void Flush(FlushRequestID,
               const std::vector<DataSourceInstanceID>&,
               FlushFlags);
    void OnFreeBuffers(const std::vector<BufferID>& target_buffers);
    void ClearIncrementalState(const std::vector<DataSourceInstanceID>&);

    bool is_allowed_target_buffer(BufferID buffer_id) const {
      return allowed_target_buffers_.count(buffer_id);
    }

    std::optional<BufferID> buffer_id_for_writer(WriterID writer_id) const {
      const auto it = writers_.find(writer_id);
      if (it != writers_.end())
        return it->second;
      return std::nullopt;
    }

    uid_t uid() const { return client_identity_.uid(); }
    pid_t pid() const { return client_identity_.pid(); }
    const ClientIdentity& client_identity() const { return client_identity_; }

   private:
    friend class TracingServiceImpl;
    friend class TracingServiceImplTest;
    friend class TracingIntegrationTest;
    ProducerEndpointImpl(const ProducerEndpointImpl&) = delete;
    ProducerEndpointImpl& operator=(const ProducerEndpointImpl&) = delete;

    ProducerID const id_;
    ClientIdentity const client_identity_;
    TracingServiceImpl* const service_;
    base::TaskRunner* const task_runner_;
    Producer* producer_;
    std::unique_ptr<SharedMemory> shared_memory_;
    size_t shared_buffer_page_size_kb_ = 0;
    SharedMemoryABI shmem_abi_;
    size_t shmem_size_hint_bytes_ = 0;
    size_t shmem_page_size_hint_bytes_ = 0;
    bool is_shmem_provided_by_producer_ = false;
    const std::string name_;
    std::string sdk_version_;
    bool in_process_;
    bool smb_scraping_enabled_;

    // Set of the global target_buffer IDs that the producer is configured to
    // write into in any active tracing session.
    std::set<BufferID> allowed_target_buffers_;

    // Maps registered TraceWriter IDs to their target buffers as registered by
    // the producer. Note that producers aren't required to register their
    // writers, so we may see commits of chunks with WriterIDs that aren't
    // contained in this map. However, if a producer does register a writer, the
    // service will prevent the writer from writing into any other buffer than
    // the one associated with it here. The BufferIDs stored in this map are
    // untrusted, so need to be verified against |allowed_target_buffers_|
    // before use.
    std::map<WriterID, BufferID> writers_;

    // This is used only in in-process configurations.
    // SharedMemoryArbiterImpl methods themselves are thread-safe.
    std::unique_ptr<SharedMemoryArbiterImpl> inproc_shmem_arbiter_;

    PERFETTO_THREAD_CHECKER(thread_checker_)
    base::WeakPtrFactory<ProducerEndpointImpl> weak_ptr_factory_;  // Keep last.
  };

  // The implementation behind the service endpoint exposed to each consumer.
  class ConsumerEndpointImpl : public TracingService::ConsumerEndpoint {
   public:
    ConsumerEndpointImpl(TracingServiceImpl*,
                         base::TaskRunner*,
                         Consumer*,
                         uid_t uid);
    ~ConsumerEndpointImpl() override;

    void NotifyOnTracingDisabled(const std::string& error);
    void NotifyCloneSnapshotTrigger();

    // TracingService::ConsumerEndpoint implementation.
    void EnableTracing(const TraceConfig&, base::ScopedFile) override;
    void ChangeTraceConfig(const TraceConfig& cfg) override;
    void StartTracing() override;
    void DisableTracing() override;
    void ReadBuffers() override;
    void FreeBuffers() override;
    void Flush(uint32_t timeout_ms, FlushCallback, FlushFlags) override;
    void Detach(const std::string& key) override;
    void Attach(const std::string& key) override;
    void GetTraceStats() override;
    void ObserveEvents(uint32_t enabled_event_types) override;
    void QueryServiceState(QueryServiceStateArgs,
                           QueryServiceStateCallback) override;
    void QueryCapabilities(QueryCapabilitiesCallback) override;
    void SaveTraceForBugreport(SaveTraceForBugreportCallback) override;
    void CloneSession(TracingSessionID, CloneSessionArgs) override;

    // Will queue a task to notify the consumer about the state change.
    void OnDataSourceInstanceStateChange(const ProducerEndpointImpl&,
                                         const DataSourceInstance&);
    void OnAllDataSourcesStarted();

    base::WeakPtr<ConsumerEndpointImpl> GetWeakPtr() {
      return weak_ptr_factory_.GetWeakPtr();
    }

   private:
    friend class TracingServiceImpl;
    ConsumerEndpointImpl(const ConsumerEndpointImpl&) = delete;
    ConsumerEndpointImpl& operator=(const ConsumerEndpointImpl&) = delete;

    // Returns a pointer to an ObservableEvents object that the caller can fill
    // and schedules a task to send the ObservableEvents to the consumer.
    ObservableEvents* AddObservableEvents();

    base::TaskRunner* const task_runner_;
    TracingServiceImpl* const service_;
    Consumer* const consumer_;
    uid_t const uid_;
    TracingSessionID tracing_session_id_ = 0;

    // Whether the consumer is interested in DataSourceInstance state change
    // events.
    uint32_t observable_events_mask_ = 0;

    // ObservableEvents that will be sent to the consumer. If set, a task to
    // flush the events to the consumer has been queued.
    std::unique_ptr<ObservableEvents> observable_events_;

    PERFETTO_THREAD_CHECKER(thread_checker_)
    base::WeakPtrFactory<ConsumerEndpointImpl> weak_ptr_factory_;  // Keep last.
  };

  class RelayEndpointImpl : public TracingService::RelayEndpoint {
   public:
    using SyncMode = RelayEndpoint::SyncMode;

    struct SyncedClockSnapshots {
      SyncedClockSnapshots(SyncMode _sync_mode,
                           ClockSnapshotVector _client_clocks,
                           ClockSnapshotVector _host_clocks)
          : sync_mode(_sync_mode),
            client_clocks(std::move(_client_clocks)),
            host_clocks(std::move(_host_clocks)) {}
      SyncMode sync_mode;
      ClockSnapshotVector client_clocks;
      ClockSnapshotVector host_clocks;
    };

    explicit RelayEndpointImpl(RelayClientID relay_client_id,
                               TracingServiceImpl* service);
    ~RelayEndpointImpl() override;
    void SyncClocks(SyncMode sync_mode,
                    ClockSnapshotVector client_clocks,
                    ClockSnapshotVector host_clocks) override;
    void Disconnect() override;

    MachineID machine_id() const { return relay_client_id_.first; }

    base::CircularQueue<SyncedClockSnapshots>& synced_clocks() {
      return synced_clocks_;
    }

   private:
    RelayEndpointImpl(const RelayEndpointImpl&) = delete;
    RelayEndpointImpl& operator=(const RelayEndpointImpl&) = delete;

    RelayClientID relay_client_id_;
    TracingServiceImpl* const service_;
    base::CircularQueue<SyncedClockSnapshots> synced_clocks_;

    PERFETTO_THREAD_CHECKER(thread_checker_)
  };

  explicit TracingServiceImpl(std::unique_ptr<SharedMemory::Factory>,
                              base::TaskRunner*,
                              InitOpts = {});
  ~TracingServiceImpl() override;

  // Called by ProducerEndpointImpl.
  void DisconnectProducer(ProducerID);
  void RegisterDataSource(ProducerID, const DataSourceDescriptor&);
  void UpdateDataSource(ProducerID, const DataSourceDescriptor&);
  void UnregisterDataSource(ProducerID, const std::string& name);
  void CopyProducerPageIntoLogBuffer(ProducerID,
                                     const ClientIdentity&,
                                     WriterID,
                                     ChunkID,
                                     BufferID,
                                     uint16_t num_fragments,
                                     uint8_t chunk_flags,
                                     bool chunk_complete,
                                     const uint8_t* src,
                                     size_t size);
  void ApplyChunkPatches(ProducerID,
                         const std::vector<CommitDataRequest::ChunkToPatch>&);
  void NotifyFlushDoneForProducer(ProducerID, FlushRequestID);
  void NotifyDataSourceStarted(ProducerID, DataSourceInstanceID);
  void NotifyDataSourceStopped(ProducerID, DataSourceInstanceID);
  void ActivateTriggers(ProducerID, const std::vector<std::string>& triggers);

  // Called by ConsumerEndpointImpl.
  bool DetachConsumer(ConsumerEndpointImpl*, const std::string& key);
  bool AttachConsumer(ConsumerEndpointImpl*, const std::string& key);
  void DisconnectConsumer(ConsumerEndpointImpl*);
  base::Status EnableTracing(ConsumerEndpointImpl*,
                             const TraceConfig&,
                             base::ScopedFile);
  void ChangeTraceConfig(ConsumerEndpointImpl*, const TraceConfig&);

  base::Status StartTracing(TracingSessionID);
  void DisableTracing(TracingSessionID, bool disable_immediately = false);
  void Flush(TracingSessionID tsid,
             uint32_t timeout_ms,
             ConsumerEndpoint::FlushCallback,
             FlushFlags);
  void FlushAndDisableTracing(TracingSessionID);
  void FlushAndCloneSession(ConsumerEndpointImpl*,
                            TracingSessionID,
                            bool skip_filter,
                            bool for_bugreport);

  // Starts reading the internal tracing buffers from the tracing session `tsid`
  // and sends them to `*consumer` (which must be != nullptr).
  //
  // Only reads a limited amount of data in one call. If there's more data,
  // immediately schedules itself on a PostTask.
  //
  // Returns false in case of error.
  bool ReadBuffersIntoConsumer(TracingSessionID tsid,
                               ConsumerEndpointImpl* consumer);

  // Reads all the tracing buffers from the tracing session `tsid` and writes
  // them into the associated file.
  //
  // Reads all the data in the buffers (or until the file is full) before
  // returning.
  //
  // If the tracing session write_period_ms is 0, the file is full or there has
  // been an error, flushes the file and closes it. Otherwise, schedules itself
  // to be executed after write_period_ms.
  //
  // Returns false in case of error.
  bool ReadBuffersIntoFile(TracingSessionID);

  void FreeBuffers(TracingSessionID);

  // Service implementation.
  std::unique_ptr<TracingService::ProducerEndpoint> ConnectProducer(
      Producer*,
      const ClientIdentity& client_identity,
      const std::string& producer_name,
      size_t shared_memory_size_hint_bytes = 0,
      bool in_process = false,
      ProducerSMBScrapingMode smb_scraping_mode =
          ProducerSMBScrapingMode::kDefault,
      size_t shared_memory_page_size_hint_bytes = 0,
      std::unique_ptr<SharedMemory> shm = nullptr,
      const std::string& sdk_version = {}) override;

  std::unique_ptr<TracingService::ConsumerEndpoint> ConnectConsumer(
      Consumer*,
      uid_t) override;

  std::unique_ptr<TracingService::RelayEndpoint> ConnectRelayClient(
      RelayClientID) override;

  void DisconnectRelayClient(RelayClientID);

  // Set whether SMB scraping should be enabled by default or not. Producers can
  // override this setting for their own SMBs.
  void SetSMBScrapingEnabled(bool enabled) override {
    smb_scraping_enabled_ = enabled;
  }

  // Exposed mainly for testing.
  size_t num_producers() const { return producers_.size(); }
  ProducerEndpointImpl* GetProducer(ProducerID) const;

 private:
  friend class TracingServiceImplTest;
  friend class TracingIntegrationTest;

  static constexpr int64_t kOneDayInNs = 24ll * 60 * 60 * 1000 * 1000 * 1000;

  struct TriggerHistory {
    int64_t timestamp_ns;
    uint64_t name_hash;

    bool operator<(const TriggerHistory& other) const {
      return timestamp_ns < other.timestamp_ns;
    }
  };

  struct RegisteredDataSource {
    ProducerID producer_id;
    DataSourceDescriptor descriptor;
  };

  // Represents an active data source for a tracing session.
  struct DataSourceInstance {
    DataSourceInstance(DataSourceInstanceID id,
                       const DataSourceConfig& cfg,
                       const std::string& ds_name,
                       bool notify_on_start,
                       bool notify_on_stop,
                       bool handles_incremental_state_invalidation,
                       bool no_flush_)
        : instance_id(id),
          config(cfg),
          data_source_name(ds_name),
          will_notify_on_start(notify_on_start),
          will_notify_on_stop(notify_on_stop),
          handles_incremental_state_clear(
              handles_incremental_state_invalidation),
          no_flush(no_flush_) {}
    DataSourceInstance(const DataSourceInstance&) = delete;
    DataSourceInstance& operator=(const DataSourceInstance&) = delete;

    DataSourceInstanceID instance_id;
    DataSourceConfig config;
    std::string data_source_name;
    bool will_notify_on_start;
    bool will_notify_on_stop;
    bool handles_incremental_state_clear;
    bool no_flush;

    enum DataSourceInstanceState {
      CONFIGURED,
      STARTING,
      STARTED,
      STOPPING,
      STOPPED
    };
    DataSourceInstanceState state = CONFIGURED;
  };

  struct PendingFlush {
    std::set<ProducerID> producers;
    ConsumerEndpoint::FlushCallback callback;
    explicit PendingFlush(decltype(callback) cb) : callback(std::move(cb)) {}
  };

  using PendingCloneID = uint64_t;

  struct PendingClone {
    size_t pending_flush_cnt = 0;
    // This vector might not be populated all at once. Some buffers might be
    // nullptr while flushing is not done.
    std::vector<std::unique_ptr<TraceBuffer>> buffers;
    bool flush_failed = false;
    base::WeakPtr<ConsumerEndpointImpl> weak_consumer;
    bool skip_trace_filter = false;
  };

  // Holds the state of a tracing session. A tracing session is uniquely bound
  // a specific Consumer. Each Consumer can own one or more sessions.
  struct TracingSession {
    enum State {
      DISABLED = 0,
      CONFIGURED,
      STARTED,
      DISABLING_WAITING_STOP_ACKS,
      CLONED_READ_ONLY,
    };

    TracingSession(TracingSessionID,
                   ConsumerEndpointImpl*,
                   const TraceConfig&,
                   base::TaskRunner*);
    TracingSession(TracingSession&&) = delete;
    TracingSession& operator=(TracingSession&&) = delete;

    size_t num_buffers() const { return buffers_index.size(); }

    uint32_t delay_to_next_write_period_ms() const {
      PERFETTO_DCHECK(write_period_ms > 0);
      return write_period_ms -
             static_cast<uint32_t>(base::GetWallTimeMs().count() %
                                   write_period_ms);
    }

    uint32_t flush_timeout_ms() {
      uint32_t timeout_ms = config.flush_timeout_ms();
      return timeout_ms ? timeout_ms : kDefaultFlushTimeoutMs;
    }

    uint32_t data_source_stop_timeout_ms() {
      uint32_t timeout_ms = config.data_source_stop_timeout_ms();
      return timeout_ms ? timeout_ms : kDataSourceStopTimeoutMs;
    }

    PacketSequenceID GetPacketSequenceID(MachineID machine_id,
                                         ProducerID producer_id,
                                         WriterID writer_id) {
      auto key = std::make_tuple(machine_id, producer_id, writer_id);
      auto it = packet_sequence_ids.find(key);
      if (it != packet_sequence_ids.end())
        return it->second;
      // We shouldn't run out of sequence IDs (producer ID is 16 bit, writer IDs
      // are limited to 1024).
      static_assert(kMaxPacketSequenceID > kMaxProducerID * kMaxWriterID,
                    "PacketSequenceID value space doesn't cover service "
                    "sequence ID and all producer/writer ID combinations!");
      PERFETTO_DCHECK(last_packet_sequence_id < kMaxPacketSequenceID);
      PacketSequenceID sequence_id = ++last_packet_sequence_id;
      packet_sequence_ids[key] = sequence_id;
      return sequence_id;
    }

    DataSourceInstance* GetDataSourceInstance(
        ProducerID producer_id,
        DataSourceInstanceID instance_id) {
      for (auto& inst_kv : data_source_instances) {
        if (inst_kv.first != producer_id ||
            inst_kv.second.instance_id != instance_id) {
          continue;
        }
        return &inst_kv.second;
      }
      return nullptr;
    }

    bool AllDataSourceInstancesStarted() {
      return std::all_of(
          data_source_instances.begin(), data_source_instances.end(),
          [](decltype(data_source_instances)::const_reference x) {
            return x.second.state == DataSourceInstance::STARTED;
          });
    }

    bool AllDataSourceInstancesStopped() {
      return std::all_of(
          data_source_instances.begin(), data_source_instances.end(),
          [](decltype(data_source_instances)::const_reference x) {
            return x.second.state == DataSourceInstance::STOPPED;
          });
    }

    // Checks whether |clone_uid| is allowed to clone the current tracing
    // session.
    bool IsCloneAllowed(uid_t clone_uid) const;

    const TracingSessionID id;

    // The consumer that started the session.
    // Can be nullptr if the consumer detached from the session.
    ConsumerEndpointImpl* consumer_maybe_null;

    // Unix uid of the consumer. This is valid even after the consumer detaches
    // and does not change for the entire duration of the session. It is used to
    // prevent that a consumer re-attaches to a session from a different uid.
    uid_t const consumer_uid;

    // The list of triggers this session received while alive and the time they
    // were received at. This is used to insert 'fake' packets back to the
    // consumer so they can tell when some event happened. The order matches the
    // order they were received.
    struct TriggerInfo {
      uint64_t boot_time_ns;
      std::string trigger_name;
      std::string producer_name;
      uid_t producer_uid;
    };
    std::vector<TriggerInfo> received_triggers;

    // The trace config provided by the Consumer when calling
    // EnableTracing(), plus any updates performed by ChangeTraceConfig.
    TraceConfig config;

    // List of data source instances that have been enabled on the various
    // producers for this tracing session.
    std::multimap<ProducerID, DataSourceInstance> data_source_instances;

    // For each Flush(N) request, keeps track of the set of producers for which
    // we are still awaiting a NotifyFlushComplete(N) ack.
    std::map<FlushRequestID, PendingFlush> pending_flushes;

    // For each Clone request, keeps track of the flushes acknowledgement that
    // we are still waiting for.
    std::map<PendingCloneID, PendingClone> pending_clones;

    PendingCloneID last_pending_clone_id_ = 0;

    // Maps a per-trace-session buffer index into the corresponding global
    // BufferID (shared namespace amongst all consumers). This vector has as
    // many entries as |config.buffers_size()|.
    std::vector<BufferID> buffers_index;

    std::map<std::tuple<MachineID, ProducerID, WriterID>, PacketSequenceID>
        packet_sequence_ids;
    PacketSequenceID last_packet_sequence_id = kServicePacketSequenceID;

    // Whether we should emit the trace stats next time we reach EOF while
    // performing ReadBuffers.
    bool should_emit_stats = false;

    // Whether we should emit the sync marker the next time ReadBuffers() is
    // called.
    bool should_emit_sync_marker = false;

    // Whether we put the initial packets (trace config, system info,
    // etc.) into the trace output yet.
    bool did_emit_initial_packets = false;

    // Whether we emitted clock offsets for relay clients yet.
    bool did_emit_remote_clock_sync_ = false;

    // Whether we should compress TracePackets after reading them.
    bool compress_deflate = false;

    // The number of received triggers we've emitted into the trace output.
    size_t num_triggers_emitted_into_trace = 0;

    // Packets that failed validation of the TrustedPacket.
    uint64_t invalid_packets = 0;

    // Flush() stats. See comments in trace_stats.proto for more.
    uint64_t flushes_requested = 0;
    uint64_t flushes_succeeded = 0;
    uint64_t flushes_failed = 0;

    // Outcome of the final Flush() done by FlushAndDisableTracing().
    protos::gen::TraceStats_FinalFlushOutcome final_flush_outcome{};

    // Set to true on the first call to MaybeNotifyAllDataSourcesStarted().
    bool did_notify_all_data_source_started = false;

    // Stores all lifecycle events of a particular type (i.e. associated with a
    // single field id in the TracingServiceEvent proto).
    struct LifecycleEvent {
      LifecycleEvent(uint32_t f_id, uint32_t m_size = 1)
          : field_id(f_id), max_size(m_size), timestamps(m_size) {}

      // The field id of the event in the TracingServiceEvent proto.
      uint32_t field_id;

      // Stores the max size of |timestamps|. Set to 1 by default (in
      // the constructor) but can be overriden in TraceSession constructor
      // if a larger size is required.
      uint32_t max_size;

      // Stores the timestamps emitted for each event type (in nanoseconds).
      // Emitted into the trace and cleared when the consumer next calls
      // ReadBuffers.
      base::CircularQueue<int64_t> timestamps;
    };
    std::vector<LifecycleEvent> lifecycle_events;

    using ClockSnapshotData = ClockSnapshotVector;

    // Initial clock snapshot, captured at trace start time (when state goes to
    // TracingSession::STARTED). Emitted into the trace when the consumer first
    // calls ReadBuffers().
    ClockSnapshotData initial_clock_snapshot;

    // Stores clock snapshots to emit into the trace as a ring buffer. This
    // buffer is populated both periodically and when lifecycle events happen
    // but only when significant clock drift is detected. Emitted into the trace
    // and cleared when the consumer next calls ReadBuffers().
    base::CircularQueue<ClockSnapshotData> clock_snapshot_ring_buffer;

    State state = DISABLED;

    // If the consumer detached the session, this variable defines the key used
    // for identifying the session later when reattaching.
    std::string detach_key;

    // This is set when the Consumer calls sets |write_into_file| == true in the
    // TraceConfig. In this case this represents the file we should stream the
    // trace packets into, rather than returning it to the consumer via
    // OnTraceData().
    base::ScopedFile write_into_file;
    uint32_t write_period_ms = 0;
    uint64_t max_file_size_bytes = 0;
    uint64_t bytes_written_into_file = 0;

    // Periodic task for snapshotting service events (e.g. clocks, sync markers
    // etc)
    base::PeriodicTask snapshot_periodic_task;

    // Deferred task that stops the trace when |duration_ms| expires. This is
    // to handle the case of |prefer_suspend_clock_for_duration| which cannot
    // use PostDelayedTask.
    base::PeriodicTask timed_stop_task;

    // When non-NULL the packets should be post-processed using the filter.
    std::unique_ptr<protozero::MessageFilter> trace_filter;
    uint64_t filter_input_packets = 0;
    uint64_t filter_input_bytes = 0;
    uint64_t filter_output_bytes = 0;
    uint64_t filter_errors = 0;
    uint64_t filter_time_taken_ns = 0;
    std::vector<uint64_t> filter_bytes_discarded_per_buffer;

    // A randomly generated trace identifier. Note that this does NOT always
    // match the requested TraceConfig.trace_uuid_msb/lsb. Spcifically, it does
    // until a gap-less snapshot is requested. Each snapshot re-generates the
    // uuid to avoid emitting two different traces with the same uuid.
    base::Uuid trace_uuid;

    // NOTE: when adding new fields here consider whether that state should be
    // copied over in DoCloneSession() or not. Ask yourself: is this a
    // "runtime state" (e.g. active data sources) or a "trace (meta)data state"?
    // If the latter, it should be handled by DoCloneSession()).
  };

  TracingServiceImpl(const TracingServiceImpl&) = delete;
  TracingServiceImpl& operator=(const TracingServiceImpl&) = delete;

  bool IsInitiatorPrivileged(const TracingSession&);

  DataSourceInstance* SetupDataSource(const TraceConfig::DataSource&,
                                      const TraceConfig::ProducerConfig&,
                                      const RegisteredDataSource&,
                                      TracingSession*);

  // Returns the next available ProducerID that is not in |producers_|.
  ProducerID GetNextProducerID();

  // Returns a pointer to the |tracing_sessions_| entry or nullptr if the
  // session doesn't exists.
  TracingSession* GetTracingSession(TracingSessionID);

  // Returns a pointer to the tracing session that has the highest
  // TraceConfig.bugreport_score, if any, or nullptr.
  TracingSession* FindTracingSessionWithMaxBugreportScore();

  // Returns a pointer to the |tracing_sessions_| entry, matching the given
  // uid and detach key, or nullptr if no such session exists.
  TracingSession* GetDetachedSession(uid_t, const std::string& key);

  // Update the memory guard rail by using the latest information from the
  // shared memory and trace buffers.
  void UpdateMemoryGuardrail();

  void StartDataSourceInstance(ProducerEndpointImpl*,
                               TracingSession*,
                               DataSourceInstance*);
  void StopDataSourceInstance(ProducerEndpointImpl*,
                              TracingSession*,
                              DataSourceInstance*,
                              bool disable_immediately);
  void PeriodicSnapshotTask(TracingSessionID);
  void MaybeSnapshotClocksIntoRingBuffer(TracingSession*);
  bool SnapshotClocks(TracingSession::ClockSnapshotData*);
  void SnapshotLifecyleEvent(TracingSession*,
                             uint32_t field_id,
                             bool snapshot_clocks);
  void EmitClockSnapshot(TracingSession*,
                         TracingSession::ClockSnapshotData,
                         std::vector<TracePacket>*);
  void EmitSyncMarker(std::vector<TracePacket>*);
  void EmitStats(TracingSession*, std::vector<TracePacket>*);
  TraceStats GetTraceStats(TracingSession*);
  void EmitLifecycleEvents(TracingSession*, std::vector<TracePacket>*);
  void EmitUuid(TracingSession*, std::vector<TracePacket>*);
  void MaybeEmitTraceConfig(TracingSession*, std::vector<TracePacket>*);
  void EmitSystemInfo(std::vector<TracePacket>*);
  void MaybeEmitReceivedTriggers(TracingSession*, std::vector<TracePacket>*);
  void MaybeEmitRemoteClockSync(TracingSession*, std::vector<TracePacket>*);
  void MaybeNotifyAllDataSourcesStarted(TracingSession*);
  void OnFlushTimeout(TracingSessionID, FlushRequestID);
  void OnDisableTracingTimeout(TracingSessionID);
  void DisableTracingNotifyConsumerAndFlushFile(TracingSession*);
  void PeriodicFlushTask(TracingSessionID, bool post_next_only);
  void CompleteFlush(TracingSessionID tsid,
                     ConsumerEndpoint::FlushCallback callback,
                     bool success);
  void ScrapeSharedMemoryBuffers(TracingSession*, ProducerEndpointImpl*);
  void PeriodicClearIncrementalStateTask(TracingSessionID, bool post_next_only);
  TraceBuffer* GetBufferByID(BufferID);
  void FlushDataSourceInstances(
      TracingSession*,
      uint32_t timeout_ms,
      const std::map<ProducerID, std::vector<DataSourceInstanceID>>&,
      ConsumerEndpoint::FlushCallback,
      FlushFlags);
  std::map<ProducerID, std::vector<DataSourceInstanceID>>
  GetFlushableDataSourceInstancesForBuffers(TracingSession*,
                                            const std::set<BufferID>&);
  bool DoCloneBuffers(TracingSession*,
                      const std::set<BufferID>&,
                      std::vector<std::unique_ptr<TraceBuffer>>*);
  base::Status FinishCloneSession(ConsumerEndpointImpl*,
                                  TracingSessionID,
                                  std::vector<std::unique_ptr<TraceBuffer>>,
                                  bool skip_filter,
                                  bool final_flush_outcome,
                                  base::Uuid*);
  void OnFlushDoneForClone(TracingSessionID src_tsid,
                           PendingCloneID clone_id,
                           const std::set<BufferID>& buf_ids,
                           bool final_flush_outcome);

  // Returns true if `*tracing_session` is waiting for a trigger that hasn't
  // happened.
  static bool IsWaitingForTrigger(TracingSession* tracing_session);

  // Reads the buffers from `*tracing_session` and returns them (along with some
  // metadata packets).
  //
  // The function stops when the cumulative size of the return packets exceeds
  // `threshold` (so it's not a strict upper bound) and sets `*has_more` to
  // true, or when there are no more packets (and sets `*has_more` to false).
  std::vector<TracePacket> ReadBuffers(TracingSession* tracing_session,
                                       size_t threshold,
                                       bool* has_more);

  // If `*tracing_session` has a filter, applies it to `*packets`. Doesn't
  // change the number of `*packets`, only their content.
  void MaybeFilterPackets(TracingSession* tracing_session,
                          std::vector<TracePacket>* packets);

  // If `*tracing_session` has compression enabled, compress `*packets`.
  void MaybeCompressPackets(TracingSession* tracing_session,
                            std::vector<TracePacket>* packets);

  // If `*tracing_session` is configured to write into a file, writes `packets`
  // into the file.
  //
  // Returns true if the file should be closed (because it's full or there has
  // been an error), false otherwise.
  bool WriteIntoFile(TracingSession* tracing_session,
                     std::vector<TracePacket> packets);
  void OnStartTriggersTimeout(TracingSessionID tsid);
  void MaybeLogUploadEvent(const TraceConfig&,
                           const base::Uuid&,
                           PerfettoStatsdAtom atom,
                           const std::string& trigger_name = "");
  void MaybeLogTriggerEvent(const TraceConfig&,
                            PerfettoTriggerAtom atom,
                            const std::string& trigger_name);
  size_t PurgeExpiredAndCountTriggerInWindow(int64_t now_ns,
                                             uint64_t trigger_name_hash);
  static void StopOnDurationMsExpiry(base::WeakPtr<TracingServiceImpl>,
                                     TracingSessionID);

  base::TaskRunner* const task_runner_;
  const InitOpts init_opts_;
  std::unique_ptr<SharedMemory::Factory> shm_factory_;
  ProducerID last_producer_id_ = 0;
  DataSourceInstanceID last_data_source_instance_id_ = 0;
  TracingSessionID last_tracing_session_id_ = 0;
  FlushRequestID last_flush_request_id_ = 0;
  uid_t uid_ = 0;

  // Buffer IDs are global across all consumers (because a Producer can produce
  // data for more than one trace session, hence more than one consumer).
  IdAllocator<BufferID> buffer_ids_;

  std::multimap<std::string /*name*/, RegisteredDataSource> data_sources_;
  std::map<ProducerID, ProducerEndpointImpl*> producers_;
  std::set<ConsumerEndpointImpl*> consumers_;
  std::map<RelayClientID, RelayEndpointImpl*> relay_clients_;
  std::map<TracingSessionID, TracingSession> tracing_sessions_;
  std::map<BufferID, std::unique_ptr<TraceBuffer>> buffers_;
  std::map<std::string, int64_t> session_to_last_trace_s_;

  // Contains timestamps of triggers.
  // The queue is sorted by timestamp and invocations older than
  // |trigger_window_ns_| are purged when a trigger happens.
  base::CircularQueue<TriggerHistory> trigger_history_;

  bool smb_scraping_enabled_ = false;
  bool lockdown_mode_ = false;
  uint32_t min_write_period_ms_ = 100;       // Overridable for testing.
  int64_t trigger_window_ns_ = kOneDayInNs;  // Overridable for testing.

  std::minstd_rand trigger_probability_rand_;
  std::uniform_real_distribution<> trigger_probability_dist_;
  double trigger_rnd_override_for_testing_ = 0;  // Overridable for testing.

  uint8_t sync_marker_packet_[32];  // Lazily initialized.
  size_t sync_marker_packet_size_ = 0;

  // Stats.
  uint64_t chunks_discarded_ = 0;
  uint64_t patches_discarded_ = 0;

  PERFETTO_THREAD_CHECKER(thread_checker_)

  base::WeakPtrFactory<TracingServiceImpl>
      weak_ptr_factory_;  // Keep at the end.
};

}  // namespace perfetto

#endif  // SRC_TRACING_SERVICE_TRACING_SERVICE_IMPL_H_
// gen_amalgamated begin header: include/perfetto/tracing/core/tracing_service_capabilities.h
/*
 * Copyright (C) 2020 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef INCLUDE_PERFETTO_TRACING_CORE_TRACING_SERVICE_CAPABILITIES_H_
#define INCLUDE_PERFETTO_TRACING_CORE_TRACING_SERVICE_CAPABILITIES_H_

// Creates the aliases in the ::perfetto namespace, doing things like:
// using ::perfetto::Foo = ::perfetto::protos::gen::Foo.
// See comments in forward_decls.h for the historical reasons of this
// indirection layer.
// gen_amalgamated expanded: #include "perfetto/tracing/core/forward_decls.h"

// gen_amalgamated expanded: #include "protos/perfetto/common/tracing_service_capabilities.gen.h"

#endif  // INCLUDE_PERFETTO_TRACING_CORE_TRACING_SERVICE_CAPABILITIES_H_
/*
 * Copyright (C) 2017 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// gen_amalgamated expanded: #include "src/tracing/service/tracing_service_impl.h"

#include <limits.h>
#include <string.h>

#include <cinttypes>
#include <cstdint>
#include <limits>
#include <optional>
#include <regex>
#include <unordered_set>
// gen_amalgamated expanded: #include "perfetto/base/time.h"
// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/client_identity.h"
// gen_amalgamated expanded: #include "perfetto/tracing/core/clock_snapshots.h"

#if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) && \
    !PERFETTO_BUILDFLAG(PERFETTO_OS_NACL)
#include <sys/uio.h>
#include <sys/utsname.h>
#include <unistd.h>
#endif

#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) && \
    PERFETTO_BUILDFLAG(PERFETTO_ANDROID_BUILD)
// gen_amalgamated expanded: #include "src/android_internal/lazy_library_loader.h"    // nogncheck
// gen_amalgamated expanded: #include "src/android_internal/tracing_service_proxy.h"  // nogncheck
#endif

#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \
    PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) ||   \
    PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
#define PERFETTO_HAS_CHMOD
#include <sys/stat.h>
#endif

#include <algorithm>

// gen_amalgamated expanded: #include "perfetto/base/build_config.h"
// gen_amalgamated expanded: #include "perfetto/base/status.h"
// gen_amalgamated expanded: #include "perfetto/base/task_runner.h"
// gen_amalgamated expanded: #include "perfetto/ext/base/android_utils.h"
// gen_amalgamated expanded: #include "perfetto/ext/base/file_utils.h"
// gen_amalgamated expanded: #include "perfetto/ext/base/metatrace.h"
// gen_amalgamated expanded: #include "perfetto/ext/base/string_utils.h"
// gen_amalgamated expanded: #include "perfetto/ext/base/string_view.h"
// gen_amalgamated expanded: #include "perfetto/ext/base/sys_types.h"
// gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
// gen_amalgamated expanded: #include "perfetto/ext/base/uuid.h"
// gen_amalgamated expanded: #include "perfetto/ext/base/version.h"
// gen_amalgamated expanded: #include "perfetto/ext/base/watchdog.h"
// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/basic_types.h"
// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/consumer.h"
// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/observable_events.h"
// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/producer.h"
// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/shared_memory.h"
// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/shared_memory_abi.h"
// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/trace_packet.h"
// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/trace_writer.h"
// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
// gen_amalgamated expanded: #include "perfetto/protozero/static_buffer.h"
// gen_amalgamated expanded: #include "perfetto/tracing/core/data_source_descriptor.h"
// gen_amalgamated expanded: #include "perfetto/tracing/core/tracing_service_capabilities.h"
// gen_amalgamated expanded: #include "perfetto/tracing/core/tracing_service_state.h"
// gen_amalgamated expanded: #include "src/android_stats/statsd_logging_helper.h"
// gen_amalgamated expanded: #include "src/protozero/filtering/message_filter.h"
// gen_amalgamated expanded: #include "src/protozero/filtering/string_filter.h"
// gen_amalgamated expanded: #include "src/tracing/core/shared_memory_arbiter_impl.h"
// gen_amalgamated expanded: #include "src/tracing/service/packet_stream_validator.h"
// gen_amalgamated expanded: #include "src/tracing/service/trace_buffer.h"

// gen_amalgamated expanded: #include "protos/perfetto/common/builtin_clock.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/common/builtin_clock.pbzero.h"
// gen_amalgamated expanded: #include "protos/perfetto/common/trace_stats.pbzero.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/trace_config.pbzero.h"
// gen_amalgamated expanded: #include "protos/perfetto/trace/clock_snapshot.pbzero.h"
// gen_amalgamated expanded: #include "protos/perfetto/trace/perfetto/tracing_service_event.pbzero.h"
// gen_amalgamated expanded: #include "protos/perfetto/trace/remote_clock_sync.pbzero.h"
// gen_amalgamated expanded: #include "protos/perfetto/trace/system_info.pbzero.h"
// gen_amalgamated expanded: #include "protos/perfetto/trace/trace_packet.pbzero.h"
// gen_amalgamated expanded: #include "protos/perfetto/trace/trace_uuid.pbzero.h"
// gen_amalgamated expanded: #include "protos/perfetto/trace/trigger.pbzero.h"

// General note: this class must assume that Producers are malicious and will
// try to crash / exploit this class. We can trust pointers because they come
// from the IPC layer, but we should never assume that that the producer calls
// come in the right order or their arguments are sane / within bounds.

// This is a macro because we want the call-site line number for the ELOG.
#define PERFETTO_SVC_ERR(...) \
  (PERFETTO_ELOG(__VA_ARGS__), ::perfetto::base::ErrStatus(__VA_ARGS__))

namespace perfetto {

namespace {
constexpr int kMaxBuffersPerConsumer = 128;
constexpr uint32_t kDefaultSnapshotsIntervalMs = 10 * 1000;
constexpr int kDefaultWriteIntoFilePeriodMs = 5000;
constexpr int kMaxConcurrentTracingSessions = 15;
constexpr int kMaxConcurrentTracingSessionsPerUid = 5;
constexpr int kMaxConcurrentTracingSessionsForStatsdUid = 10;
constexpr int64_t kMinSecondsBetweenTracesGuardrail = 5 * 60;

constexpr uint32_t kMillisPerHour = 3600000;
constexpr uint32_t kMillisPerDay = kMillisPerHour * 24;
constexpr uint32_t kMaxTracingDurationMillis = 7 * 24 * kMillisPerHour;

// These apply only if enable_extra_guardrails is true.
constexpr uint32_t kGuardrailsMaxTracingBufferSizeKb = 128 * 1024;
constexpr uint32_t kGuardrailsMaxTracingDurationMillis = 24 * kMillisPerHour;

#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) || PERFETTO_BUILDFLAG(PERFETTO_OS_NACL)
struct iovec {
  void* iov_base;  // Address
  size_t iov_len;  // Block size
};

// Simple implementation of writev. Note that this does not give the atomicity
// guarantees of a real writev, but we don't depend on these (we aren't writing
// to the same file from another thread).
ssize_t writev(int fd, const struct iovec* iov, int iovcnt) {
  ssize_t total_size = 0;
  for (int i = 0; i < iovcnt; ++i) {
    ssize_t current_size = base::WriteAll(fd, iov[i].iov_base, iov[i].iov_len);
    if (current_size != static_cast<ssize_t>(iov[i].iov_len))
      return -1;
    total_size += current_size;
  }
  return total_size;
}

#define IOV_MAX 1024  // Linux compatible limit.

#endif  // PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) ||
        // PERFETTO_BUILDFLAG(PERFETTO_OS_NACL)

// Partially encodes a CommitDataRequest in an int32 for the purposes of
// metatracing. Note that it encodes only the bottom 10 bits of the producer id
// (which is technically 16 bits wide).
//
// Format (by bit range):
// [   31 ][         30 ][             29:20 ][            19:10 ][        9:0]
// [unused][has flush id][num chunks to patch][num chunks to move][producer id]
int32_t EncodeCommitDataRequest(ProducerID producer_id,
                                const CommitDataRequest& req_untrusted) {
  uint32_t cmov = static_cast<uint32_t>(req_untrusted.chunks_to_move_size());
  uint32_t cpatch = static_cast<uint32_t>(req_untrusted.chunks_to_patch_size());
  uint32_t has_flush_id = req_untrusted.flush_request_id() != 0;

  uint32_t mask = (1 << 10) - 1;
  uint32_t acc = 0;
  acc |= has_flush_id << 30;
  acc |= (cpatch & mask) << 20;
  acc |= (cmov & mask) << 10;
  acc |= (producer_id & mask);
  return static_cast<int32_t>(acc);
}

void SerializeAndAppendPacket(std::vector<TracePacket>* packets,
                              std::vector<uint8_t> packet) {
  Slice slice = Slice::Allocate(packet.size());
  memcpy(slice.own_data(), packet.data(), packet.size());
  packets->emplace_back();
  packets->back().AddSlice(std::move(slice));
}

std::tuple<size_t /*shm_size*/, size_t /*page_size*/> EnsureValidShmSizes(
    size_t shm_size,
    size_t page_size) {
  // Theoretically the max page size supported by the ABI is 64KB.
  // However, the current implementation of TraceBuffer (the non-shared
  // userspace buffer where the service copies data) supports at most
  // 32K. Setting 64K "works" from the producer<>consumer viewpoint
  // but then causes the data to be discarded when copying it into
  // TraceBuffer.
  constexpr size_t kMaxPageSize = 32 * 1024;
  static_assert(kMaxPageSize <= SharedMemoryABI::kMaxPageSize, "");

  if (page_size == 0)
    page_size = TracingServiceImpl::kDefaultShmPageSize;
  if (shm_size == 0)
    shm_size = TracingServiceImpl::kDefaultShmSize;

  page_size = std::min<size_t>(page_size, kMaxPageSize);
  shm_size = std::min<size_t>(shm_size, TracingServiceImpl::kMaxShmSize);

  // The tracing page size has to be multiple of 4K. On some systems (e.g. Mac
  // on Arm64) the system page size can be larger (e.g., 16K). That doesn't
  // matter here, because the tracing page size is just a logical partitioning
  // and does not have any dependencies on kernel mm syscalls (read: it's fine
  // to have trace page sizes of 4K on a system where the kernel page size is
  // 16K).
  bool page_size_is_valid = page_size >= SharedMemoryABI::kMinPageSize;
  page_size_is_valid &= page_size % SharedMemoryABI::kMinPageSize == 0;

  // Only allow power of two numbers of pages, i.e. 1, 2, 4, 8 pages.
  size_t num_pages = page_size / SharedMemoryABI::kMinPageSize;
  page_size_is_valid &= (num_pages & (num_pages - 1)) == 0;

  if (!page_size_is_valid || shm_size < page_size ||
      shm_size % page_size != 0) {
    return std::make_tuple(TracingServiceImpl::kDefaultShmSize,
                           TracingServiceImpl::kDefaultShmPageSize);
  }
  return std::make_tuple(shm_size, page_size);
}

bool NameMatchesFilter(const std::string& name,
                       const std::vector<std::string>& name_filter,
                       const std::vector<std::string>& name_regex_filter) {
  bool filter_is_set = !name_filter.empty() || !name_regex_filter.empty();
  if (!filter_is_set)
    return true;
  bool filter_matches = std::find(name_filter.begin(), name_filter.end(),
                                  name) != name_filter.end();
  bool filter_regex_matches =
      std::find_if(name_regex_filter.begin(), name_regex_filter.end(),
                   [&](const std::string& regex) {
                     return std::regex_match(
                         name, std::regex(regex, std::regex::extended));
                   }) != name_regex_filter.end();
  return filter_matches || filter_regex_matches;
}

// Used when TraceConfig.write_into_file == true and output_path is not empty.
base::ScopedFile CreateTraceFile(const std::string& path, bool overwrite) {
#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) && \
    PERFETTO_BUILDFLAG(PERFETTO_ANDROID_BUILD)
  // This is NOT trying to preserve any security property, SELinux does that.
  // It just improves the actionability of the error when people try to save the
  // trace in a location that is not SELinux-allowed (a generic "permission
  // denied" vs "don't put it here, put it there").
  // These are the only SELinux approved dir for trace files that are created
  // directly by traced.
  static const char* kTraceDirBasePath = "/data/misc/perfetto-traces/";
  if (!base::StartsWith(path, kTraceDirBasePath)) {
    PERFETTO_ELOG("Invalid output_path %s. On Android it must be within %s.",
                  path.c_str(), kTraceDirBasePath);
    return base::ScopedFile();
  }
#endif
  // O_CREAT | O_EXCL will fail if the file exists already.
  const int flags = O_RDWR | O_CREAT | (overwrite ? O_TRUNC : O_EXCL);
  auto fd = base::OpenFile(path, flags, 0600);
  if (fd) {
#if defined(PERFETTO_HAS_CHMOD)
    // Passing 0644 directly above won't work because of umask.
    PERFETTO_CHECK(fchmod(*fd, 0644) == 0);
#endif
  } else {
    PERFETTO_PLOG("Failed to create %s", path.c_str());
  }
  return fd;
}

bool ShouldLogEvent(const TraceConfig& cfg) {
  switch (cfg.statsd_logging()) {
    case TraceConfig::STATSD_LOGGING_ENABLED:
      return true;
    case TraceConfig::STATSD_LOGGING_DISABLED:
      return false;
    case TraceConfig::STATSD_LOGGING_UNSPECIFIED:
      break;
  }
  // For backward compatibility with older versions of perfetto_cmd.
  return cfg.enable_extra_guardrails();
}

// Appends `data` (which has `size` bytes), to `*packet`. Splits the data in
// slices no larger than `max_slice_size`.
void AppendOwnedSlicesToPacket(std::unique_ptr<uint8_t[]> data,
                               size_t size,
                               size_t max_slice_size,
                               perfetto::TracePacket* packet) {
  if (size <= max_slice_size) {
    packet->AddSlice(Slice::TakeOwnership(std::move(data), size));
    return;
  }
  uint8_t* src_ptr = data.get();
  for (size_t size_left = size; size_left > 0;) {
    const size_t slice_size = std::min(size_left, max_slice_size);

    Slice slice = Slice::Allocate(slice_size);
    memcpy(slice.own_data(), src_ptr, slice_size);
    packet->AddSlice(std::move(slice));

    src_ptr += slice_size;
    size_left -= slice_size;
  }
}

using TraceFilter = protos::gen::TraceConfig::TraceFilter;
std::optional<protozero::StringFilter::Policy> ConvertPolicy(
    TraceFilter::StringFilterPolicy policy) {
  switch (policy) {
    case TraceFilter::SFP_UNSPECIFIED:
      return std::nullopt;
    case TraceFilter::SFP_MATCH_REDACT_GROUPS:
      return protozero::StringFilter::Policy::kMatchRedactGroups;
    case TraceFilter::SFP_ATRACE_MATCH_REDACT_GROUPS:
      return protozero::StringFilter::Policy::kAtraceMatchRedactGroups;
    case TraceFilter::SFP_MATCH_BREAK:
      return protozero::StringFilter::Policy::kMatchBreak;
    case TraceFilter::SFP_ATRACE_MATCH_BREAK:
      return protozero::StringFilter::Policy::kAtraceMatchBreak;
    case TraceFilter::SFP_ATRACE_REPEATED_SEARCH_REDACT_GROUPS:
      return protozero::StringFilter::Policy::kAtraceRepeatedSearchRedactGroups;
  }
  return std::nullopt;
}

}  // namespace

// static
std::unique_ptr<TracingService> TracingService::CreateInstance(
    std::unique_ptr<SharedMemory::Factory> shm_factory,
    base::TaskRunner* task_runner,
    InitOpts init_opts) {
  return std::unique_ptr<TracingService>(
      new TracingServiceImpl(std::move(shm_factory), task_runner, init_opts));
}

TracingServiceImpl::TracingServiceImpl(
    std::unique_ptr<SharedMemory::Factory> shm_factory,
    base::TaskRunner* task_runner,
    InitOpts init_opts)
    : task_runner_(task_runner),
      init_opts_(init_opts),
      shm_factory_(std::move(shm_factory)),
      uid_(base::GetCurrentUserId()),
      buffer_ids_(kMaxTraceBufferID),
      trigger_probability_rand_(
          static_cast<uint32_t>(base::GetWallTimeNs().count())),
      weak_ptr_factory_(this) {
  PERFETTO_DCHECK(task_runner_);
}

TracingServiceImpl::~TracingServiceImpl() {
  // TODO(fmayer): handle teardown of all Producer.
}

std::unique_ptr<TracingService::ProducerEndpoint>
TracingServiceImpl::ConnectProducer(Producer* producer,
                                    const ClientIdentity& client_identity,
                                    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) {
  PERFETTO_DCHECK_THREAD(thread_checker_);

  auto uid = client_identity.uid();
  if (lockdown_mode_ && uid != base::GetCurrentUserId()) {
    PERFETTO_DLOG("Lockdown mode. Rejecting producer with UID %ld",
                  static_cast<unsigned long>(uid));
    return nullptr;
  }

  if (producers_.size() >= kMaxProducerID) {
    PERFETTO_DFATAL("Too many producers.");
    return nullptr;
  }
  const ProducerID id = GetNextProducerID();
  PERFETTO_DLOG("Producer %" PRIu16 " connected, uid=%d", id,
                static_cast<int>(uid));
  bool smb_scraping_enabled = smb_scraping_enabled_;
  switch (smb_scraping_mode) {
    case ProducerSMBScrapingMode::kDefault:
      break;
    case ProducerSMBScrapingMode::kEnabled:
      smb_scraping_enabled = true;
      break;
    case ProducerSMBScrapingMode::kDisabled:
      smb_scraping_enabled = false;
      break;
  }

  std::unique_ptr<ProducerEndpointImpl> endpoint(new ProducerEndpointImpl(
      id, client_identity, this, task_runner_, producer, producer_name,
      sdk_version, in_process, smb_scraping_enabled));
  auto it_and_inserted = producers_.emplace(id, endpoint.get());
  PERFETTO_DCHECK(it_and_inserted.second);
  endpoint->shmem_size_hint_bytes_ = shared_memory_size_hint_bytes;
  endpoint->shmem_page_size_hint_bytes_ = shared_memory_page_size_hint_bytes;

  // Producer::OnConnect() should run before Producer::OnTracingSetup(). The
  // latter may be posted by SetupSharedMemory() below, so post OnConnect() now.
  auto weak_ptr = endpoint->weak_ptr_factory_.GetWeakPtr();
  task_runner_->PostTask([weak_ptr] {
    if (weak_ptr)
      weak_ptr->producer_->OnConnect();
  });

  if (shm) {
    // The producer supplied an SMB. This is used only by Chrome; in the most
    // common cases the SMB is created by the service and passed via
    // OnTracingSetup(). Verify that it is correctly sized before we attempt to
    // use it. The transport layer has to verify the integrity of the SMB (e.g.
    // ensure that the producer can't resize if after the fact).
    size_t shm_size, page_size;
    std::tie(shm_size, page_size) =
        EnsureValidShmSizes(shm->size(), endpoint->shmem_page_size_hint_bytes_);
    if (shm_size == shm->size() &&
        page_size == endpoint->shmem_page_size_hint_bytes_) {
      PERFETTO_DLOG(
          "Adopting producer-provided SMB of %zu kB for producer \"%s\"",
          shm_size / 1024, endpoint->name_.c_str());
      endpoint->SetupSharedMemory(std::move(shm), page_size,
                                  /*provided_by_producer=*/true);
    } else {
      PERFETTO_LOG(
          "Discarding incorrectly sized producer-provided SMB for producer "
          "\"%s\", falling back to service-provided SMB. Requested sizes: %zu "
          "B total, %zu B page size; suggested corrected sizes: %zu B total, "
          "%zu B page size",
          endpoint->name_.c_str(), shm->size(),
          endpoint->shmem_page_size_hint_bytes_, shm_size, page_size);
      shm.reset();
    }
  }

  return std::unique_ptr<ProducerEndpoint>(std::move(endpoint));
}

void TracingServiceImpl::DisconnectProducer(ProducerID id) {
  PERFETTO_DCHECK_THREAD(thread_checker_);
  PERFETTO_DLOG("Producer %" PRIu16 " disconnected", id);
  PERFETTO_DCHECK(producers_.count(id));

  // Scrape remaining chunks for this producer to ensure we don't lose data.
  if (auto* producer = GetProducer(id)) {
    for (auto& session_id_and_session : tracing_sessions_)
      ScrapeSharedMemoryBuffers(&session_id_and_session.second, producer);
  }

  for (auto it = data_sources_.begin(); it != data_sources_.end();) {
    auto next = it;
    next++;
    if (it->second.producer_id == id)
      UnregisterDataSource(id, it->second.descriptor.name());
    it = next;
  }

  producers_.erase(id);
  UpdateMemoryGuardrail();
}

TracingServiceImpl::ProducerEndpointImpl* TracingServiceImpl::GetProducer(
    ProducerID id) const {
  PERFETTO_DCHECK_THREAD(thread_checker_);
  auto it = producers_.find(id);
  if (it == producers_.end())
    return nullptr;
  return it->second;
}

std::unique_ptr<TracingService::ConsumerEndpoint>
TracingServiceImpl::ConnectConsumer(Consumer* consumer, uid_t uid) {
  PERFETTO_DCHECK_THREAD(thread_checker_);
  PERFETTO_DLOG("Consumer %p connected from UID %" PRIu64,
                reinterpret_cast<void*>(consumer), static_cast<uint64_t>(uid));
  std::unique_ptr<ConsumerEndpointImpl> endpoint(
      new ConsumerEndpointImpl(this, task_runner_, consumer, uid));
  auto it_and_inserted = consumers_.emplace(endpoint.get());
  PERFETTO_DCHECK(it_and_inserted.second);
  // Consumer might go away before we're able to send the connect notification,
  // if that is the case just bail out.
  auto weak_ptr = endpoint->weak_ptr_factory_.GetWeakPtr();
  task_runner_->PostTask([weak_ptr] {
    if (weak_ptr)
      weak_ptr->consumer_->OnConnect();
  });
  return std::unique_ptr<ConsumerEndpoint>(std::move(endpoint));
}

void TracingServiceImpl::DisconnectConsumer(ConsumerEndpointImpl* consumer) {
  PERFETTO_DCHECK_THREAD(thread_checker_);
  PERFETTO_DLOG("Consumer %p disconnected", reinterpret_cast<void*>(consumer));
  PERFETTO_DCHECK(consumers_.count(consumer));

  // TODO(primiano) : Check that this is safe (what happens if there are
  // ReadBuffers() calls posted in the meantime? They need to become noop).
  if (consumer->tracing_session_id_)
    FreeBuffers(consumer->tracing_session_id_);  // Will also DisableTracing().
  consumers_.erase(consumer);

  // At this point no more pointers to |consumer| should be around.
  PERFETTO_DCHECK(!std::any_of(
      tracing_sessions_.begin(), tracing_sessions_.end(),
      [consumer](const std::pair<const TracingSessionID, TracingSession>& kv) {
        return kv.second.consumer_maybe_null == consumer;
      }));
}

bool TracingServiceImpl::DetachConsumer(ConsumerEndpointImpl* consumer,
                                        const std::string& key) {
  PERFETTO_DCHECK_THREAD(thread_checker_);
  PERFETTO_DLOG("Consumer %p detached", reinterpret_cast<void*>(consumer));
  PERFETTO_DCHECK(consumers_.count(consumer));

  TracingSessionID tsid = consumer->tracing_session_id_;
  TracingSession* tracing_session;
  if (!tsid || !(tracing_session = GetTracingSession(tsid)))
    return false;

  if (GetDetachedSession(consumer->uid_, key)) {
    PERFETTO_ELOG("Another session has been detached with the same key \"%s\"",
                  key.c_str());
    return false;
  }

  PERFETTO_DCHECK(tracing_session->consumer_maybe_null == consumer);
  tracing_session->consumer_maybe_null = nullptr;
  tracing_session->detach_key = key;
  consumer->tracing_session_id_ = 0;
  return true;
}

std::unique_ptr<TracingService::RelayEndpoint>
TracingServiceImpl::ConnectRelayClient(RelayClientID relay_client_id) {
  PERFETTO_DCHECK_THREAD(thread_checker_);

  auto endpoint = std::make_unique<RelayEndpointImpl>(relay_client_id, this);
  relay_clients_[relay_client_id] = endpoint.get();

  return std::move(endpoint);
}

void TracingServiceImpl::DisconnectRelayClient(RelayClientID relay_client_id) {
  PERFETTO_DCHECK_THREAD(thread_checker_);

  if (relay_clients_.find(relay_client_id) == relay_clients_.end())
    return;
  relay_clients_.erase(relay_client_id);
}

bool TracingServiceImpl::AttachConsumer(ConsumerEndpointImpl* consumer,
                                        const std::string& key) {
  PERFETTO_DCHECK_THREAD(thread_checker_);
  PERFETTO_DLOG("Consumer %p attaching to session %s",
                reinterpret_cast<void*>(consumer), key.c_str());
  PERFETTO_DCHECK(consumers_.count(consumer));

  if (consumer->tracing_session_id_) {
    PERFETTO_ELOG(
        "Cannot reattach consumer to session %s"
        " while it already attached tracing session ID %" PRIu64,
        key.c_str(), consumer->tracing_session_id_);
    return false;
  }

  auto* tracing_session = GetDetachedSession(consumer->uid_, key);
  if (!tracing_session) {
    PERFETTO_ELOG(
        "Failed to attach consumer, session '%s' not found for uid %d",
        key.c_str(), static_cast<int>(consumer->uid_));
    return false;
  }

  consumer->tracing_session_id_ = tracing_session->id;
  tracing_session->consumer_maybe_null = consumer;
  tracing_session->detach_key.clear();
  return true;
}

base::Status TracingServiceImpl::EnableTracing(ConsumerEndpointImpl* consumer,
                                               const TraceConfig& cfg,
                                               base::ScopedFile fd) {
  PERFETTO_DCHECK_THREAD(thread_checker_);

  // If the producer is specifying a UUID, respect that (at least for the first
  // snapshot). Otherwise generate a new UUID.
  base::Uuid uuid(cfg.trace_uuid_lsb(), cfg.trace_uuid_msb());
  if (!uuid)
    uuid = base::Uuidv4();

  PERFETTO_DLOG("Enabling tracing for consumer %p, UUID: %s",
                reinterpret_cast<void*>(consumer),
                uuid.ToPrettyString().c_str());
  MaybeLogUploadEvent(cfg, uuid, PerfettoStatsdAtom::kTracedEnableTracing);
  if (cfg.lockdown_mode() == TraceConfig::LOCKDOWN_SET)
    lockdown_mode_ = true;
  if (cfg.lockdown_mode() == TraceConfig::LOCKDOWN_CLEAR)
    lockdown_mode_ = false;

  // Scope |tracing_session| to this block to prevent accidental use of a null
  // pointer later in this function.
  {
    TracingSession* tracing_session =
        GetTracingSession(consumer->tracing_session_id_);
    if (tracing_session) {
      MaybeLogUploadEvent(
          cfg, uuid,
          PerfettoStatsdAtom::kTracedEnableTracingExistingTraceSession);
      return PERFETTO_SVC_ERR(
          "A Consumer is trying to EnableTracing() but another tracing "
          "session is already active (forgot a call to FreeBuffers() ?)");
    }
  }

  const uint32_t max_duration_ms = cfg.enable_extra_guardrails()
                                       ? kGuardrailsMaxTracingDurationMillis
                                       : kMaxTracingDurationMillis;
  if (cfg.duration_ms() > max_duration_ms) {
    MaybeLogUploadEvent(cfg, uuid,
                        PerfettoStatsdAtom::kTracedEnableTracingTooLongTrace);
    return PERFETTO_SVC_ERR("Requested too long trace (%" PRIu32
                            "ms  > %" PRIu32 " ms)",
                            cfg.duration_ms(), max_duration_ms);
  }

  const bool has_trigger_config =
      GetTriggerMode(cfg) != TraceConfig::TriggerConfig::UNSPECIFIED;
  if (has_trigger_config &&
      (cfg.trigger_config().trigger_timeout_ms() == 0 ||
       cfg.trigger_config().trigger_timeout_ms() > max_duration_ms)) {
    MaybeLogUploadEvent(
        cfg, uuid,
        PerfettoStatsdAtom::kTracedEnableTracingInvalidTriggerTimeout);
    return PERFETTO_SVC_ERR(
        "Traces with START_TRACING triggers must provide a positive "
        "trigger_timeout_ms < 7 days (received %" PRIu32 "ms)",
        cfg.trigger_config().trigger_timeout_ms());
  }

  // This check has been introduced in May 2023 after finding b/274931668.
  if (static_cast<int>(cfg.trigger_config().trigger_mode()) >
      TraceConfig::TriggerConfig::TriggerMode_MAX) {
    MaybeLogUploadEvent(
        cfg, uuid, PerfettoStatsdAtom::kTracedEnableTracingInvalidTriggerMode);
    return PERFETTO_SVC_ERR(
        "The trace config specified an invalid trigger_mode");
  }

  if (cfg.trigger_config().use_clone_snapshot_if_available() &&
      cfg.trigger_config().trigger_mode() !=
          TraceConfig::TriggerConfig::STOP_TRACING) {
    MaybeLogUploadEvent(
        cfg, uuid, PerfettoStatsdAtom::kTracedEnableTracingInvalidTriggerMode);
    return PERFETTO_SVC_ERR(
        "trigger_mode must be STOP_TRACING when "
        "use_clone_snapshot_if_available=true");
  }

  if (has_trigger_config && cfg.duration_ms() != 0) {
    MaybeLogUploadEvent(
        cfg, uuid, PerfettoStatsdAtom::kTracedEnableTracingDurationWithTrigger);
    return PERFETTO_SVC_ERR(
        "duration_ms was set, this must not be set for traces with triggers.");
  }

  for (char c : cfg.bugreport_filename()) {
    if (!((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') ||
          (c >= '0' && c <= '9') || c == '-' || c == '_' || c == '.')) {
      MaybeLogUploadEvent(
          cfg, uuid, PerfettoStatsdAtom::kTracedEnableTracingInvalidBrFilename);
      return PERFETTO_SVC_ERR(
          "bugreport_filename contains invalid chars. Use [a-zA-Z0-9-_.]+");
    }
  }

  if ((GetTriggerMode(cfg) == TraceConfig::TriggerConfig::STOP_TRACING ||
       GetTriggerMode(cfg) == TraceConfig::TriggerConfig::CLONE_SNAPSHOT) &&
      cfg.write_into_file()) {
    // We don't support this usecase because there are subtle assumptions which
    // break around TracingServiceEvents and windowed sorting (i.e. if we don't
    // drain the events in ReadBuffersIntoFile because we are waiting for
    // STOP_TRACING, we can end up queueing up a lot of TracingServiceEvents and
    // emitting them wildy out of order breaking windowed sorting in trace
    // processor).
    MaybeLogUploadEvent(
        cfg, uuid,
        PerfettoStatsdAtom::kTracedEnableTracingStopTracingWriteIntoFile);
    return PERFETTO_SVC_ERR(
        "Specifying trigger mode STOP_TRACING/CLONE_SNAPSHOT and "
        "write_into_file together is unsupported");
  }

  std::unordered_set<std::string> triggers;
  for (const auto& trigger : cfg.trigger_config().triggers()) {
    if (!triggers.insert(trigger.name()).second) {
      MaybeLogUploadEvent(
          cfg, uuid,
          PerfettoStatsdAtom::kTracedEnableTracingDuplicateTriggerName);
      return PERFETTO_SVC_ERR("Duplicate trigger name: %s",
                              trigger.name().c_str());
    }
  }

  if (cfg.enable_extra_guardrails()) {
    if (cfg.deferred_start()) {
      MaybeLogUploadEvent(
          cfg, uuid,
          PerfettoStatsdAtom::kTracedEnableTracingInvalidDeferredStart);
      return PERFETTO_SVC_ERR(
          "deferred_start=true is not supported in unsupervised traces");
    }
    uint64_t buf_size_sum = 0;
    for (const auto& buf : cfg.buffers()) {
      if (buf.size_kb() % 4 != 0) {
        MaybeLogUploadEvent(
            cfg, uuid,
            PerfettoStatsdAtom::kTracedEnableTracingInvalidBufferSize);
        return PERFETTO_SVC_ERR(
            "buffers.size_kb must be a multiple of 4, got %" PRIu32,
            buf.size_kb());
      }
      buf_size_sum += buf.size_kb();
    }

    uint32_t max_tracing_buffer_size_kb =
        std::max(kGuardrailsMaxTracingBufferSizeKb,
                 cfg.guardrail_overrides().max_tracing_buffer_size_kb());
    if (buf_size_sum > max_tracing_buffer_size_kb) {
      MaybeLogUploadEvent(
          cfg, uuid,
          PerfettoStatsdAtom::kTracedEnableTracingBufferSizeTooLarge);
      return PERFETTO_SVC_ERR("Requested too large trace buffer (%" PRIu64
                              "kB  > %" PRIu32 " kB)",
                              buf_size_sum, max_tracing_buffer_size_kb);
    }
  }

  if (cfg.buffers_size() > kMaxBuffersPerConsumer) {
    MaybeLogUploadEvent(cfg, uuid,
                        PerfettoStatsdAtom::kTracedEnableTracingTooManyBuffers);
    return PERFETTO_SVC_ERR("Too many buffers configured (%d)",
                            cfg.buffers_size());
  }
  // Check that the config specifies all buffers for its data sources. This
  // is also checked in SetupDataSource, but it is simpler to return a proper
  // error to the consumer from here (and there will be less state to undo).
  for (const TraceConfig::DataSource& cfg_data_source : cfg.data_sources()) {
    size_t num_buffers = static_cast<size_t>(cfg.buffers_size());
    size_t target_buffer = cfg_data_source.config().target_buffer();
    if (target_buffer >= num_buffers) {
      MaybeLogUploadEvent(
          cfg, uuid, PerfettoStatsdAtom::kTracedEnableTracingOobTargetBuffer);
      return PERFETTO_SVC_ERR(
          "Data source \"%s\" specified an out of bounds target_buffer (%zu >= "
          "%zu)",
          cfg_data_source.config().name().c_str(), target_buffer, num_buffers);
    }
  }

  if (!cfg.unique_session_name().empty()) {
    const std::string& name = cfg.unique_session_name();
    for (auto& kv : tracing_sessions_) {
      if (kv.second.state == TracingSession::CLONED_READ_ONLY)
        continue;  // Don't consider cloned sessions in uniqueness checks.
      if (kv.second.config.unique_session_name() == name) {
        MaybeLogUploadEvent(
            cfg, uuid,
            PerfettoStatsdAtom::kTracedEnableTracingDuplicateSessionName);
        static const char fmt[] =
            "A trace with this unique session name (%s) already exists";
        // This happens frequently, don't make it an "E"LOG.
        PERFETTO_LOG(fmt, name.c_str());
        return base::ErrStatus(fmt, name.c_str());
      }
    }
  }

  if (cfg.enable_extra_guardrails()) {
    // unique_session_name can be empty
    const std::string& name = cfg.unique_session_name();
    int64_t now_s = base::GetBootTimeS().count();

    // Remove any entries where the time limit has passed so this map doesn't
    // grow indefinitely:
    std::map<std::string, int64_t>& sessions = session_to_last_trace_s_;
    for (auto it = sessions.cbegin(); it != sessions.cend();) {
      if (now_s - it->second > kMinSecondsBetweenTracesGuardrail) {
        it = sessions.erase(it);
      } else {
        ++it;
      }
    }

    int64_t& previous_s = session_to_last_trace_s_[name];
    if (previous_s == 0) {
      previous_s = now_s;
    } else {
      MaybeLogUploadEvent(
          cfg, uuid,
          PerfettoStatsdAtom::kTracedEnableTracingSessionNameTooRecent);
      return PERFETTO_SVC_ERR(
          "A trace with unique session name \"%s\" began less than %" PRId64
          "s ago (%" PRId64 "s)",
          name.c_str(), kMinSecondsBetweenTracesGuardrail, now_s - previous_s);
    }
  }

  const int sessions_for_uid = static_cast<int>(std::count_if(
      tracing_sessions_.begin(), tracing_sessions_.end(),
      [consumer](const decltype(tracing_sessions_)::value_type& s) {
        return s.second.consumer_uid == consumer->uid_;
      }));

  int per_uid_limit = kMaxConcurrentTracingSessionsPerUid;
  if (consumer->uid_ == 1066 /* AID_STATSD*/) {
    per_uid_limit = kMaxConcurrentTracingSessionsForStatsdUid;
  }
  if (sessions_for_uid >= per_uid_limit) {
    MaybeLogUploadEvent(
        cfg, uuid,
        PerfettoStatsdAtom::kTracedEnableTracingTooManySessionsForUid);
    return PERFETTO_SVC_ERR(
        "Too many concurrent tracing sesions (%d) for uid %d limit is %d",
        sessions_for_uid, static_cast<int>(consumer->uid_), per_uid_limit);
  }

  // TODO(primiano): This is a workaround to prevent that a producer gets stuck
  // in a state where it stalls by design by having more TraceWriterImpl
  // instances than free pages in the buffer. This is really a bug in
  // trace_probes and the way it handles stalls in the shmem buffer.
  if (tracing_sessions_.size() >= kMaxConcurrentTracingSessions) {
    MaybeLogUploadEvent(
        cfg, uuid,
        PerfettoStatsdAtom::kTracedEnableTracingTooManyConcurrentSessions);
    return PERFETTO_SVC_ERR("Too many concurrent tracing sesions (%zu)",
                            tracing_sessions_.size());
  }

  // If the trace config provides a filter bytecode, setup the filter now.
  // If the filter loading fails, abort the tracing session rather than running
  // unfiltered.
  std::unique_ptr<protozero::MessageFilter> trace_filter;
  if (cfg.has_trace_filter()) {
    const auto& filt = cfg.trace_filter();
    trace_filter.reset(new protozero::MessageFilter());

    protozero::StringFilter& string_filter = trace_filter->string_filter();
    for (const auto& rule : filt.string_filter_chain().rules()) {
      auto opt_policy = ConvertPolicy(rule.policy());
      if (!opt_policy.has_value()) {
        MaybeLogUploadEvent(
            cfg, uuid, PerfettoStatsdAtom::kTracedEnableTracingInvalidFilter);
        return PERFETTO_SVC_ERR(
            "Trace filter has invalid string filtering rules, aborting");
      }
      string_filter.AddRule(*opt_policy, rule.regex_pattern(),
                            rule.atrace_payload_starts_with());
    }

    const std::string& bytecode_v1 = filt.bytecode();
    const std::string& bytecode_v2 = filt.bytecode_v2();
    const std::string& bytecode =
        bytecode_v2.empty() ? bytecode_v1 : bytecode_v2;
    if (!trace_filter->LoadFilterBytecode(bytecode.data(), bytecode.size())) {
      MaybeLogUploadEvent(
          cfg, uuid, PerfettoStatsdAtom::kTracedEnableTracingInvalidFilter);
      return PERFETTO_SVC_ERR("Trace filter bytecode invalid, aborting");
    }

    // The filter is created using perfetto.protos.Trace as root message
    // (because that makes it possible to play around with the `proto_filter`
    // tool on actual traces). Here in the service, however, we deal with
    // perfetto.protos.TracePacket(s), which are one level down (Trace.packet).
    // The IPC client (or the write_into_filte logic in here) are responsible
    // for pre-pending the packet preamble (See GetProtoPreamble() calls), but
    // the preamble is not there at ReadBuffer time. Hence we change the root of
    // the filtering to start at the Trace.packet level.
    if (!trace_filter->SetFilterRoot({TracePacket::kPacketFieldNumber})) {
      MaybeLogUploadEvent(
          cfg, uuid, PerfettoStatsdAtom::kTracedEnableTracingInvalidFilter);
      return PERFETTO_SVC_ERR("Failed to set filter root.");
    }
  }

  const TracingSessionID tsid = ++last_tracing_session_id_;
  TracingSession* tracing_session =
      &tracing_sessions_
           .emplace(std::piecewise_construct, std::forward_as_tuple(tsid),
                    std::forward_as_tuple(tsid, consumer, cfg, task_runner_))
           .first->second;

  tracing_session->trace_uuid = uuid;

  if (trace_filter)
    tracing_session->trace_filter = std::move(trace_filter);

  if (cfg.write_into_file()) {
    if (!fd ^ !cfg.output_path().empty()) {
      MaybeLogUploadEvent(
          tracing_session->config, uuid,
          PerfettoStatsdAtom::kTracedEnableTracingInvalidFdOutputFile);
      tracing_sessions_.erase(tsid);
      return PERFETTO_SVC_ERR(
          "When write_into_file==true either a FD needs to be passed or "
          "output_path must be populated (but not both)");
    }
    if (!cfg.output_path().empty()) {
      fd = CreateTraceFile(cfg.output_path(), /*overwrite=*/false);
      if (!fd) {
        MaybeLogUploadEvent(
            tracing_session->config, uuid,
            PerfettoStatsdAtom::kTracedEnableTracingFailedToCreateFile);
        tracing_sessions_.erase(tsid);
        return PERFETTO_SVC_ERR("Failed to create the trace file %s",
                                cfg.output_path().c_str());
      }
    }
    tracing_session->write_into_file = std::move(fd);
    uint32_t write_period_ms = cfg.file_write_period_ms();
    if (write_period_ms == 0)
      write_period_ms = kDefaultWriteIntoFilePeriodMs;
    if (write_period_ms < min_write_period_ms_)
      write_period_ms = min_write_period_ms_;
    tracing_session->write_period_ms = write_period_ms;
    tracing_session->max_file_size_bytes = cfg.max_file_size_bytes();
    tracing_session->bytes_written_into_file = 0;
  }

  if (cfg.compression_type() == TraceConfig::COMPRESSION_TYPE_DEFLATE) {
    if (init_opts_.compressor_fn) {
      tracing_session->compress_deflate = true;
    } else {
      PERFETTO_LOG(
          "COMPRESSION_TYPE_DEFLATE is not supported in the current build "
          "configuration. Skipping compression");
    }
  }

  // Initialize the log buffers.
  bool did_allocate_all_buffers = true;
  bool invalid_buffer_config = false;

  // Allocate the trace buffers. Also create a map to translate a consumer
  // relative index (TraceConfig.DataSourceConfig.target_buffer) into the
  // corresponding BufferID, which is a global ID namespace for the service and
  // all producers.
  size_t total_buf_size_kb = 0;
  const size_t num_buffers = static_cast<size_t>(cfg.buffers_size());
  tracing_session->buffers_index.reserve(num_buffers);
  for (size_t i = 0; i < num_buffers; i++) {
    const TraceConfig::BufferConfig& buffer_cfg = cfg.buffers()[i];
    BufferID global_id = buffer_ids_.Allocate();
    if (!global_id) {
      did_allocate_all_buffers = false;  // We ran out of IDs.
      break;
    }
    tracing_session->buffers_index.push_back(global_id);
    // TraceBuffer size is limited to 32-bit.
    const uint32_t buf_size_kb = buffer_cfg.size_kb();
    const uint64_t buf_size_bytes = buf_size_kb * static_cast<uint64_t>(1024);
    const size_t buf_size = static_cast<size_t>(buf_size_bytes);
    if (buf_size_bytes == 0 ||
        buf_size_bytes > std::numeric_limits<uint32_t>::max() ||
        buf_size != buf_size_bytes) {
      invalid_buffer_config = true;
      did_allocate_all_buffers = false;
      break;
    }
    total_buf_size_kb += buf_size_kb;
    TraceBuffer::OverwritePolicy policy =
        buffer_cfg.fill_policy() == TraceConfig::BufferConfig::DISCARD
            ? TraceBuffer::kDiscard
            : TraceBuffer::kOverwrite;
    auto it_and_inserted =
        buffers_.emplace(global_id, TraceBuffer::Create(buf_size, policy));
    PERFETTO_DCHECK(it_and_inserted.second);  // buffers_.count(global_id) == 0.
    std::unique_ptr<TraceBuffer>& trace_buffer = it_and_inserted.first->second;
    if (!trace_buffer) {
      did_allocate_all_buffers = false;
      break;
    }
  }

  // This can happen if either:
  // - All the kMaxTraceBufferID slots are taken.
  // - OOM, or, more realistically, we exhausted virtual memory.
  // - The buffer size in the config is invalid.
  // In any case, free all the previously allocated buffers and abort.
  if (!did_allocate_all_buffers) {
    for (BufferID global_id : tracing_session->buffers_index) {
      buffer_ids_.Free(global_id);
      buffers_.erase(global_id);
    }
    MaybeLogUploadEvent(tracing_session->config, uuid,
                        PerfettoStatsdAtom::kTracedEnableTracingOom);
    tracing_sessions_.erase(tsid);
    if (invalid_buffer_config) {
      return PERFETTO_SVC_ERR(
          "Failed to allocate tracing buffers: Invalid buffer sizes");
    }
    return PERFETTO_SVC_ERR(
        "Failed to allocate tracing buffers: OOM or too many buffers");
  }

  UpdateMemoryGuardrail();

  consumer->tracing_session_id_ = tsid;

  // Setup the data sources on the producers without starting them.
  for (const TraceConfig::DataSource& cfg_data_source : cfg.data_sources()) {
    // Scan all the registered data sources with a matching name.
    auto range = data_sources_.equal_range(cfg_data_source.config().name());
    for (auto it = range.first; it != range.second; it++) {
      TraceConfig::ProducerConfig producer_config;
      for (const auto& config : cfg.producers()) {
        if (GetProducer(it->second.producer_id)->name_ ==
            config.producer_name()) {
          producer_config = config;
          break;
        }
      }
      SetupDataSource(cfg_data_source, producer_config, it->second,
                      tracing_session);
    }
  }

  bool has_start_trigger = false;
  auto weak_this = weak_ptr_factory_.GetWeakPtr();
  switch (GetTriggerMode(cfg)) {
    case TraceConfig::TriggerConfig::UNSPECIFIED:
      // no triggers are specified so this isn't a trace that is using triggers.
      PERFETTO_DCHECK(!has_trigger_config);
      break;
    case TraceConfig::TriggerConfig::START_TRACING:
      // For traces which use START_TRACE triggers we need to ensure that the
      // tracing session will be cleaned up when it times out.
      has_start_trigger = true;
      task_runner_->PostDelayedTask(
          [weak_this, tsid]() {
            if (weak_this)
              weak_this->OnStartTriggersTimeout(tsid);
          },
          cfg.trigger_config().trigger_timeout_ms());
      break;
    case TraceConfig::TriggerConfig::STOP_TRACING:
    case TraceConfig::TriggerConfig::CLONE_SNAPSHOT:
      // Update the tracing_session's duration_ms to ensure that if no trigger
      // is received the session will end and be cleaned up equal to the
      // timeout.
      //
      // TODO(nuskos): Refactor this so that rather then modifying the config we
      // have a field we look at on the tracing_session.
      tracing_session->config.set_duration_ms(
          cfg.trigger_config().trigger_timeout_ms());
      break;

      // The case of unknown modes (coming from future versions of the service)
      // is handled few lines above (search for TriggerMode_MAX).
  }

  tracing_session->state = TracingSession::CONFIGURED;
  PERFETTO_LOG(
      "Configured tracing session %" PRIu64
      ", #sources:%zu, duration:%d ms%s, #buffers:%d, total "
      "buffer size:%zu KB, total sessions:%zu, uid:%d session name: \"%s\"",
      tsid, cfg.data_sources().size(), tracing_session->config.duration_ms(),
      tracing_session->config.prefer_suspend_clock_for_duration()
          ? " (suspend_clock)"
          : "",
      cfg.buffers_size(), total_buf_size_kb, tracing_sessions_.size(),
      static_cast<unsigned int>(consumer->uid_),
      cfg.unique_session_name().c_str());

  // Start the data sources, unless this is a case of early setup + fast
  // triggering, either through TraceConfig.deferred_start or
  // TraceConfig.trigger_config(). If both are specified which ever one occurs
  // first will initiate the trace.
  if (!cfg.deferred_start() && !has_start_trigger)
    return StartTracing(tsid);

  return base::OkStatus();
}

void TracingServiceImpl::ChangeTraceConfig(ConsumerEndpointImpl* consumer,
                                           const TraceConfig& updated_cfg) {
  PERFETTO_DCHECK_THREAD(thread_checker_);
  TracingSession* tracing_session =
      GetTracingSession(consumer->tracing_session_id_);
  PERFETTO_DCHECK(tracing_session);

  if ((tracing_session->state != TracingSession::STARTED) &&
      (tracing_session->state != TracingSession::CONFIGURED)) {
    PERFETTO_ELOG(
        "ChangeTraceConfig() was called for a tracing session which isn't "
        "running.");
    return;
  }

  // We only support updating producer_name_{,regex}_filter (and pass-through
  // configs) for now; null out any changeable fields and make sure the rest are
  // identical.
  TraceConfig new_config_copy(updated_cfg);
  for (auto& ds_cfg : *new_config_copy.mutable_data_sources()) {
    ds_cfg.clear_producer_name_filter();
    ds_cfg.clear_producer_name_regex_filter();
  }

  TraceConfig current_config_copy(tracing_session->config);
  for (auto& ds_cfg : *current_config_copy.mutable_data_sources()) {
    ds_cfg.clear_producer_name_filter();
    ds_cfg.clear_producer_name_regex_filter();
  }

  if (new_config_copy != current_config_copy) {
    PERFETTO_LOG(
        "ChangeTraceConfig() was called with a config containing unsupported "
        "changes; only adding to the producer_name_{,regex}_filter is "
        "currently supported and will have an effect.");
  }

  for (TraceConfig::DataSource& cfg_data_source :
       *tracing_session->config.mutable_data_sources()) {
    // Find the updated producer_filter in the new config.
    std::vector<std::string> new_producer_name_filter;
    std::vector<std::string> new_producer_name_regex_filter;
    bool found_data_source = false;
    for (const auto& it : updated_cfg.data_sources()) {
      if (cfg_data_source.config().name() == it.config().name()) {
        new_producer_name_filter = it.producer_name_filter();
        new_producer_name_regex_filter = it.producer_name_regex_filter();
        found_data_source = true;
        break;
      }
    }

    // Bail out if data source not present in the new config.
    if (!found_data_source) {
      PERFETTO_ELOG(
          "ChangeTraceConfig() called without a current data source also "
          "present in the new config: %s",
          cfg_data_source.config().name().c_str());
      continue;
    }

    // TODO(oysteine): Just replacing the filter means that if
    // there are any filter entries which were present in the original config,
    // but removed from the config passed to ChangeTraceConfig, any matching
    // producers will keep producing but newly added producers after this
    // point will never start.
    *cfg_data_source.mutable_producer_name_filter() = new_producer_name_filter;
    *cfg_data_source.mutable_producer_name_regex_filter() =
        new_producer_name_regex_filter;

    // Get the list of producers that are already set up.
    std::unordered_set<uint16_t> set_up_producers;
    auto& ds_instances = tracing_session->data_source_instances;
    for (auto instance_it = ds_instances.begin();
         instance_it != ds_instances.end(); ++instance_it) {
      set_up_producers.insert(instance_it->first);
    }

    // Scan all the registered data sources with a matching name.
    auto range = data_sources_.equal_range(cfg_data_source.config().name());
    for (auto it = range.first; it != range.second; it++) {
      ProducerEndpointImpl* producer = GetProducer(it->second.producer_id);
      PERFETTO_DCHECK(producer);

      // Check if the producer name of this data source is present
      // in the name filters. We currently only support new filters, not
      // removing old ones.
      if (!NameMatchesFilter(producer->name_, new_producer_name_filter,
                             new_producer_name_regex_filter)) {
        continue;
      }

      // If this producer is already set up, we assume that all datasources
      // in it started already.
      if (set_up_producers.count(it->second.producer_id))
        continue;

      // If it wasn't previously setup, set it up now.
      // (The per-producer config is optional).
      TraceConfig::ProducerConfig producer_config;
      for (const auto& config : tracing_session->config.producers()) {
        if (producer->name_ == config.producer_name()) {
          producer_config = config;
          break;
        }
      }

      DataSourceInstance* ds_inst = SetupDataSource(
          cfg_data_source, producer_config, it->second, tracing_session);

      if (ds_inst && tracing_session->state == TracingSession::STARTED)
        StartDataSourceInstance(producer, tracing_session, ds_inst);
    }
  }
}

base::Status TracingServiceImpl::StartTracing(TracingSessionID tsid) {
  PERFETTO_DCHECK_THREAD(thread_checker_);

  auto weak_this = weak_ptr_factory_.GetWeakPtr();
  TracingSession* tracing_session = GetTracingSession(tsid);
  if (!tracing_session) {
    return PERFETTO_SVC_ERR(
        "StartTracing() failed, invalid session ID %" PRIu64, tsid);
  }

  MaybeLogUploadEvent(tracing_session->config, tracing_session->trace_uuid,
                      PerfettoStatsdAtom::kTracedStartTracing);

  if (tracing_session->state != TracingSession::CONFIGURED) {
    MaybeLogUploadEvent(
        tracing_session->config, tracing_session->trace_uuid,
        PerfettoStatsdAtom::kTracedStartTracingInvalidSessionState);
    return PERFETTO_SVC_ERR("StartTracing() failed, invalid session state: %d",
                            tracing_session->state);
  }

  tracing_session->state = TracingSession::STARTED;

  // We store the start of trace snapshot separately as it's important to make
  // sure we can interpret all the data in the trace and storing it in the ring
  // buffer means it could be overwritten by a later snapshot.
  if (!tracing_session->config.builtin_data_sources()
           .disable_clock_snapshotting()) {
    SnapshotClocks(&tracing_session->initial_clock_snapshot);
  }

  // We don't snapshot the clocks here because we just did this above.
  SnapshotLifecyleEvent(
      tracing_session,
      protos::pbzero::TracingServiceEvent::kTracingStartedFieldNumber,
      false /* snapshot_clocks */);

  // Periodically snapshot clocks, stats, sync markers while the trace is
  // active. The snapshots are emitted on the future ReadBuffers() calls, which
  // means that:
  //  (a) If we're streaming to a file (or to a consumer) while tracing, we
  //      write snapshots periodically into the trace.
  //  (b) If ReadBuffers() is only called after tracing ends, we emit the latest
  //      snapshot into the trace. For clock snapshots, we keep track of the
  //      snapshot recorded at the beginning of the session
  //      (initial_clock_snapshot above), as well as the most recent sampled
  //      snapshots that showed significant new drift between different clocks.
  //      The latter clock snapshots are sampled periodically and at lifecycle
  //      events.
  base::PeriodicTask::Args snapshot_task_args;
  snapshot_task_args.start_first_task_immediately = true;
  snapshot_task_args.use_suspend_aware_timer =
      tracing_session->config.builtin_data_sources()
          .prefer_suspend_clock_for_snapshot();
  snapshot_task_args.task = [weak_this, tsid] {
    if (weak_this)
      weak_this->PeriodicSnapshotTask(tsid);
  };
  snapshot_task_args.period_ms =
      tracing_session->config.builtin_data_sources().snapshot_interval_ms();
  if (!snapshot_task_args.period_ms)
    snapshot_task_args.period_ms = kDefaultSnapshotsIntervalMs;
  tracing_session->snapshot_periodic_task.Start(snapshot_task_args);

  // Trigger delayed task if the trace is time limited.
  const uint32_t trace_duration_ms = tracing_session->config.duration_ms();
  if (trace_duration_ms > 0) {
    auto stop_task =
        std::bind(&TracingServiceImpl::StopOnDurationMsExpiry, weak_this, tsid);
    if (tracing_session->config.prefer_suspend_clock_for_duration()) {
      base::PeriodicTask::Args stop_args;
      stop_args.use_suspend_aware_timer = true;
      stop_args.period_ms = trace_duration_ms;
      stop_args.one_shot = true;
      stop_args.task = std::move(stop_task);
      tracing_session->timed_stop_task.Start(stop_args);
    } else {
      task_runner_->PostDelayedTask(std::move(stop_task), trace_duration_ms);
    }
  }  // if (trace_duration_ms > 0).

  // Start the periodic drain tasks if we should to save the trace into a file.
  if (tracing_session->config.write_into_file()) {
    task_runner_->PostDelayedTask(
        [weak_this, tsid] {
          if (weak_this)
            weak_this->ReadBuffersIntoFile(tsid);
        },
        tracing_session->delay_to_next_write_period_ms());
  }

  // Start the periodic flush tasks if the config specified a flush period.
  if (tracing_session->config.flush_period_ms())
    PeriodicFlushTask(tsid, /*post_next_only=*/true);

  // Start the periodic incremental state clear tasks if the config specified a
  // period.
  if (tracing_session->config.incremental_state_config().clear_period_ms()) {
    PeriodicClearIncrementalStateTask(tsid, /*post_next_only=*/true);
  }

  for (auto& [prod_id, data_source] : tracing_session->data_source_instances) {
    ProducerEndpointImpl* producer = GetProducer(prod_id);
    if (!producer) {
      PERFETTO_DFATAL("Producer does not exist.");
      continue;
    }
    StartDataSourceInstance(producer, tracing_session, &data_source);
  }

  MaybeNotifyAllDataSourcesStarted(tracing_session);
  return base::OkStatus();
}

// static
void TracingServiceImpl::StopOnDurationMsExpiry(
    base::WeakPtr<TracingServiceImpl> weak_this,
    TracingSessionID tsid) {
  // Skip entirely the flush if the trace session doesn't exist anymore.
  // This is to prevent misleading error messages to be logged.
  if (!weak_this)
    return;
  auto* tracing_session_ptr = weak_this->GetTracingSession(tsid);
  if (!tracing_session_ptr)
    return;
  // If this trace was using STOP_TRACING triggers and we've seen
  // one, then the trigger overrides the normal timeout. In this
  // case we just return and let the other task clean up this trace.
  if (GetTriggerMode(tracing_session_ptr->config) ==
          TraceConfig::TriggerConfig::STOP_TRACING &&
      !tracing_session_ptr->received_triggers.empty())
    return;
  // In all other cases (START_TRACING or no triggers) we flush
  // after |trace_duration_ms| unconditionally.
  weak_this->FlushAndDisableTracing(tsid);
}

void TracingServiceImpl::StartDataSourceInstance(
    ProducerEndpointImpl* producer,
    TracingSession* tracing_session,
    TracingServiceImpl::DataSourceInstance* instance) {
  PERFETTO_DCHECK(instance->state == DataSourceInstance::CONFIGURED);
  if (instance->will_notify_on_start) {
    instance->state = DataSourceInstance::STARTING;
  } else {
    instance->state = DataSourceInstance::STARTED;
  }
  if (tracing_session->consumer_maybe_null) {
    tracing_session->consumer_maybe_null->OnDataSourceInstanceStateChange(
        *producer, *instance);
  }
  producer->StartDataSource(instance->instance_id, instance->config);

  // If all data sources are started, notify the consumer.
  if (instance->state == DataSourceInstance::STARTED)
    MaybeNotifyAllDataSourcesStarted(tracing_session);
}

// DisableTracing just stops the data sources but doesn't free up any buffer.
// This is to allow the consumer to freeze the buffers (by stopping the trace)
// and then drain the buffers. The actual teardown of the TracingSession happens
// in FreeBuffers().
void TracingServiceImpl::DisableTracing(TracingSessionID tsid,
                                        bool disable_immediately) {
  PERFETTO_DCHECK_THREAD(thread_checker_);
  TracingSession* tracing_session = GetTracingSession(tsid);
  if (!tracing_session) {
    // Can happen if the consumer calls this before EnableTracing() or after
    // FreeBuffers().
    PERFETTO_DLOG("DisableTracing() failed, invalid session ID %" PRIu64, tsid);
    return;
  }

  MaybeLogUploadEvent(tracing_session->config, tracing_session->trace_uuid,
                      PerfettoStatsdAtom::kTracedDisableTracing);

  switch (tracing_session->state) {
    // Spurious call to DisableTracing() while already disabled, nothing to do.
    case TracingSession::DISABLED:
      PERFETTO_DCHECK(tracing_session->AllDataSourceInstancesStopped());
      return;

    case TracingSession::CLONED_READ_ONLY:
      PERFETTO_DLOG("DisableTracing() cannot be called on a cloned session");
      return;

    // This is either:
    // A) The case of a graceful DisableTracing() call followed by a call to
    //    FreeBuffers(), iff |disable_immediately| == true. In this case we want
    //    to forcefully transition in the disabled state without waiting for the
    //    outstanding acks because the buffers are going to be destroyed soon.
    // B) A spurious call, iff |disable_immediately| == false, in which case
    //    there is nothing to do.
    case TracingSession::DISABLING_WAITING_STOP_ACKS:
      PERFETTO_DCHECK(!tracing_session->AllDataSourceInstancesStopped());
      if (disable_immediately)
        DisableTracingNotifyConsumerAndFlushFile(tracing_session);
      return;

    // Continues below.
    case TracingSession::CONFIGURED:
      // If the session didn't even start there is no need to orchestrate a
      // graceful stop of data sources.
      disable_immediately = true;
      break;

    // This is the nominal case, continues below.
    case TracingSession::STARTED:
      break;
  }

  for (auto& data_source_inst : tracing_session->data_source_instances) {
    const ProducerID producer_id = data_source_inst.first;
    DataSourceInstance& instance = data_source_inst.second;
    ProducerEndpointImpl* producer = GetProducer(producer_id);
    PERFETTO_DCHECK(producer);
    PERFETTO_DCHECK(instance.state == DataSourceInstance::CONFIGURED ||
                    instance.state == DataSourceInstance::STARTING ||
                    instance.state == DataSourceInstance::STARTED);
    StopDataSourceInstance(producer, tracing_session, &instance,
                           disable_immediately);
  }

  // If the periodic task is running, we can stop the periodic snapshot timer
  // here instead of waiting until FreeBuffers to prevent useless snapshots
  // which won't be read.
  tracing_session->snapshot_periodic_task.Reset();

  // Either this request is flagged with |disable_immediately| or there are no
  // data sources that are requesting a final handshake. In both cases just mark
  // the session as disabled immediately, notify the consumer and flush the
  // trace file (if used).
  if (tracing_session->AllDataSourceInstancesStopped())
    return DisableTracingNotifyConsumerAndFlushFile(tracing_session);

  tracing_session->state = TracingSession::DISABLING_WAITING_STOP_ACKS;
  auto weak_this = weak_ptr_factory_.GetWeakPtr();
  task_runner_->PostDelayedTask(
      [weak_this, tsid] {
        if (weak_this)
          weak_this->OnDisableTracingTimeout(tsid);
      },
      tracing_session->data_source_stop_timeout_ms());

  // Deliberately NOT removing the session from |tracing_session_|, it's still
  // needed to call ReadBuffers(). FreeBuffers() will erase() the session.
}

void TracingServiceImpl::NotifyDataSourceStarted(
    ProducerID producer_id,
    DataSourceInstanceID instance_id) {
  PERFETTO_DCHECK_THREAD(thread_checker_);
  for (auto& kv : tracing_sessions_) {
    TracingSession& tracing_session = kv.second;
    DataSourceInstance* instance =
        tracing_session.GetDataSourceInstance(producer_id, instance_id);

    if (!instance)
      continue;

    // If the tracing session was already stopped, ignore this notification.
    if (tracing_session.state != TracingSession::STARTED)
      continue;

    if (instance->state != DataSourceInstance::STARTING) {
      PERFETTO_ELOG("Started data source instance in incorrect state: %d",
                    instance->state);
      continue;
    }

    instance->state = DataSourceInstance::STARTED;

    ProducerEndpointImpl* producer = GetProducer(producer_id);
    PERFETTO_DCHECK(producer);
    if (tracing_session.consumer_maybe_null) {
      tracing_session.consumer_maybe_null->OnDataSourceInstanceStateChange(
          *producer, *instance);
    }

    // If all data sources are started, notify the consumer.
    MaybeNotifyAllDataSourcesStarted(&tracing_session);
  }  // for (tracing_session)
}

void TracingServiceImpl::MaybeNotifyAllDataSourcesStarted(
    TracingSession* tracing_session) {
  if (!tracing_session->consumer_maybe_null)
    return;

  if (!tracing_session->AllDataSourceInstancesStarted())
    return;

  // In some rare cases, we can get in this state more than once. Consider the
  // following scenario: 3 data sources are registered -> trace starts ->
  // all 3 data sources ack -> OnAllDataSourcesStarted() is called.
  // Imagine now that a 4th data source registers while the trace is ongoing.
  // This would hit the AllDataSourceInstancesStarted() condition again.
  // In this case, however, we don't want to re-notify the consumer again.
  // That would be unexpected (even if, perhaps, technically correct) and
  // trigger bugs in the consumer.
  if (tracing_session->did_notify_all_data_source_started)
    return;

  PERFETTO_DLOG("All data sources started");

  SnapshotLifecyleEvent(
      tracing_session,
      protos::pbzero::TracingServiceEvent::kAllDataSourcesStartedFieldNumber,
      true /* snapshot_clocks */);

  tracing_session->did_notify_all_data_source_started = true;
  tracing_session->consumer_maybe_null->OnAllDataSourcesStarted();
}

void TracingServiceImpl::NotifyDataSourceStopped(
    ProducerID producer_id,
    DataSourceInstanceID instance_id) {
  PERFETTO_DCHECK_THREAD(thread_checker_);
  for (auto& kv : tracing_sessions_) {
    TracingSession& tracing_session = kv.second;
    DataSourceInstance* instance =
        tracing_session.GetDataSourceInstance(producer_id, instance_id);

    if (!instance)
      continue;

    if (instance->state != DataSourceInstance::STOPPING) {
      PERFETTO_ELOG("Stopped data source instance in incorrect state: %d",
                    instance->state);
      continue;
    }

    instance->state = DataSourceInstance::STOPPED;

    ProducerEndpointImpl* producer = GetProducer(producer_id);
    PERFETTO_DCHECK(producer);
    if (tracing_session.consumer_maybe_null) {
      tracing_session.consumer_maybe_null->OnDataSourceInstanceStateChange(
          *producer, *instance);
    }

    if (!tracing_session.AllDataSourceInstancesStopped())
      continue;

    if (tracing_session.state != TracingSession::DISABLING_WAITING_STOP_ACKS)
      continue;

    // All data sources acked the termination.
    DisableTracingNotifyConsumerAndFlushFile(&tracing_session);
  }  // for (tracing_session)
}

void TracingServiceImpl::ActivateTriggers(
    ProducerID producer_id,
    const std::vector<std::string>& triggers) {
  PERFETTO_DCHECK_THREAD(thread_checker_);
  auto* producer = GetProducer(producer_id);
  PERFETTO_DCHECK(producer);

  int64_t now_ns = base::GetBootTimeNs().count();
  for (const auto& trigger_name : triggers) {
    PERFETTO_DLOG("Received ActivateTriggers request for \"%s\"",
                  trigger_name.c_str());
    base::Hasher hash;
    hash.Update(trigger_name.c_str(), trigger_name.size());
    std::string triggered_session_name;
    base::Uuid triggered_session_uuid;
    TracingSessionID triggered_session_id = 0;
    auto trigger_mode = TraceConfig::TriggerConfig::UNSPECIFIED;

    uint64_t trigger_name_hash = hash.digest();
    size_t count_in_window =
        PurgeExpiredAndCountTriggerInWindow(now_ns, trigger_name_hash);

    bool trigger_matched = false;
    bool trigger_activated = false;
    for (auto& id_and_tracing_session : tracing_sessions_) {
      auto& tracing_session = id_and_tracing_session.second;
      TracingSessionID tsid = id_and_tracing_session.first;
      auto iter = std::find_if(
          tracing_session.config.trigger_config().triggers().begin(),
          tracing_session.config.trigger_config().triggers().end(),
          [&trigger_name](const TraceConfig::TriggerConfig::Trigger& trigger) {
            return trigger.name() == trigger_name;
          });
      if (iter == tracing_session.config.trigger_config().triggers().end())
        continue;
      if (tracing_session.state == TracingSession::CLONED_READ_ONLY)
        continue;

      // If this trigger requires a certain producer to have sent it
      // (non-empty producer_name()) ensure the producer who sent this trigger
      // matches.
      if (!iter->producer_name_regex().empty() &&
          !std::regex_match(
              producer->name_,
              std::regex(iter->producer_name_regex(), std::regex::extended))) {
        continue;
      }

      // Use a random number between 0 and 1 to check if we should allow this
      // trigger through or not.
      double trigger_rnd =
          trigger_rnd_override_for_testing_ > 0
              ? trigger_rnd_override_for_testing_
              : trigger_probability_dist_(trigger_probability_rand_);
      PERFETTO_DCHECK(trigger_rnd >= 0 && trigger_rnd < 1);
      if (trigger_rnd < iter->skip_probability()) {
        MaybeLogTriggerEvent(tracing_session.config,
                             PerfettoTriggerAtom::kTracedLimitProbability,
                             trigger_name);
        continue;
      }

      // If we already triggered more times than the limit, silently ignore
      // this trigger.
      if (iter->max_per_24_h() > 0 && count_in_window >= iter->max_per_24_h()) {
        MaybeLogTriggerEvent(tracing_session.config,
                             PerfettoTriggerAtom::kTracedLimitMaxPer24h,
                             trigger_name);
        continue;
      }
      trigger_matched = true;
      triggered_session_id = tracing_session.id;
      triggered_session_name = tracing_session.config.unique_session_name();
      triggered_session_uuid.set_lsb_msb(tracing_session.trace_uuid.lsb(),
                                         tracing_session.trace_uuid.msb());
      trigger_mode = GetTriggerMode(tracing_session.config);

      const bool triggers_already_received =
          !tracing_session.received_triggers.empty();
      tracing_session.received_triggers.push_back(
          {static_cast<uint64_t>(now_ns), iter->name(), producer->name_,
           producer->uid()});
      auto weak_this = weak_ptr_factory_.GetWeakPtr();
      switch (trigger_mode) {
        case TraceConfig::TriggerConfig::START_TRACING:
          // If the session has already been triggered and moved past
          // CONFIGURED then we don't need to repeat StartTracing. This would
          // work fine (StartTracing would return false) but would add error
          // logs.
          if (tracing_session.state != TracingSession::CONFIGURED)
            break;

          trigger_activated = true;
          MaybeLogUploadEvent(
              tracing_session.config, tracing_session.trace_uuid,
              PerfettoStatsdAtom::kTracedTriggerStartTracing, iter->name());

          // We override the trace duration to be the trigger's requested
          // value, this ensures that the trace will end after this amount
          // of time has passed.
          tracing_session.config.set_duration_ms(iter->stop_delay_ms());
          StartTracing(tsid);
          break;
        case TraceConfig::TriggerConfig::STOP_TRACING:
          // Only stop the trace once to avoid confusing log messages. I.E.
          // when we've already hit the first trigger we've already Posted the
          // task to FlushAndDisable. So all future triggers will just break
          // out.
          if (triggers_already_received)
            break;

          trigger_activated = true;
          MaybeLogUploadEvent(
              tracing_session.config, tracing_session.trace_uuid,
              PerfettoStatsdAtom::kTracedTriggerStopTracing, iter->name());

          // Now that we've seen a trigger we need to stop, flush, and disable
          // this session after the configured |stop_delay_ms|.
          task_runner_->PostDelayedTask(
              [weak_this, tsid] {
                // Skip entirely the flush if the trace session doesn't exist
                // anymore. This is to prevent misleading error messages to be
                // logged.
                if (weak_this && weak_this->GetTracingSession(tsid))
                  weak_this->FlushAndDisableTracing(tsid);
              },
              // If this trigger is zero this will immediately executable and
              // will happen shortly.
              iter->stop_delay_ms());
          break;

        case TraceConfig::TriggerConfig::CLONE_SNAPSHOT:
          trigger_activated = true;
          MaybeLogUploadEvent(
              tracing_session.config, tracing_session.trace_uuid,
              PerfettoStatsdAtom::kTracedTriggerCloneSnapshot, iter->name());
          task_runner_->PostDelayedTask(
              [weak_this, tsid] {
                if (!weak_this)
                  return;
                auto* tsess = weak_this->GetTracingSession(tsid);
                if (!tsess || !tsess->consumer_maybe_null)
                  return;
                tsess->consumer_maybe_null->NotifyCloneSnapshotTrigger();
              },
              iter->stop_delay_ms());
          break;

        case TraceConfig::TriggerConfig::UNSPECIFIED:
          PERFETTO_ELOG("Trigger activated but trigger mode unspecified.");
          break;
      }
    }  // for (.. : tracing_sessions_)

    if (trigger_matched) {
      trigger_history_.emplace_back(TriggerHistory{now_ns, trigger_name_hash});
    }

    if (trigger_activated) {
      // Log only the trigger that actually caused a trace stop/start, don't log
      // the follow-up ones, even if they matched.
      PERFETTO_LOG(
          "Trace trigger activated: trigger_name=\"%s\" trigger_mode=%d "
          "trace_name=\"%s\" trace_uuid=\"%s\" tsid=%" PRIu64,
          trigger_name.c_str(), trigger_mode, triggered_session_name.c_str(),
          triggered_session_uuid.ToPrettyString().c_str(),
          triggered_session_id);
    }
  }  // for (trigger_name : triggers)
}

// Always invoked TraceConfig.data_source_stop_timeout_ms (by default
// kDataSourceStopTimeoutMs) after DisableTracing(). In nominal conditions all
// data sources should have acked the stop and this will early out.
void TracingServiceImpl::OnDisableTracingTimeout(TracingSessionID tsid) {
  PERFETTO_DCHECK_THREAD(thread_checker_);
  TracingSession* tracing_session = GetTracingSession(tsid);
  if (!tracing_session ||
      tracing_session->state != TracingSession::DISABLING_WAITING_STOP_ACKS) {
    return;  // Tracing session was successfully disabled.
  }

  PERFETTO_ILOG("Timeout while waiting for ACKs for tracing session %" PRIu64,
                tsid);
  PERFETTO_DCHECK(!tracing_session->AllDataSourceInstancesStopped());
  DisableTracingNotifyConsumerAndFlushFile(tracing_session);
}

void TracingServiceImpl::DisableTracingNotifyConsumerAndFlushFile(
    TracingSession* tracing_session) {
  PERFETTO_DCHECK(tracing_session->state != TracingSession::DISABLED);
  for (auto& inst_kv : tracing_session->data_source_instances) {
    if (inst_kv.second.state == DataSourceInstance::STOPPED)
      continue;
    inst_kv.second.state = DataSourceInstance::STOPPED;
    ProducerEndpointImpl* producer = GetProducer(inst_kv.first);
    PERFETTO_DCHECK(producer);
    if (tracing_session->consumer_maybe_null) {
      tracing_session->consumer_maybe_null->OnDataSourceInstanceStateChange(
          *producer, inst_kv.second);
    }
  }
  tracing_session->state = TracingSession::DISABLED;

  // Scrape any remaining chunks that weren't flushed by the producers.
  for (auto& producer_id_and_producer : producers_)
    ScrapeSharedMemoryBuffers(tracing_session, producer_id_and_producer.second);

  SnapshotLifecyleEvent(
      tracing_session,
      protos::pbzero::TracingServiceEvent::kTracingDisabledFieldNumber,
      true /* snapshot_clocks */);

  if (tracing_session->write_into_file) {
    tracing_session->write_period_ms = 0;
    ReadBuffersIntoFile(tracing_session->id);
  }

  MaybeLogUploadEvent(tracing_session->config, tracing_session->trace_uuid,
                      PerfettoStatsdAtom::kTracedNotifyTracingDisabled);

  if (tracing_session->consumer_maybe_null)
    tracing_session->consumer_maybe_null->NotifyOnTracingDisabled("");
}

void TracingServiceImpl::Flush(TracingSessionID tsid,
                               uint32_t timeout_ms,
                               ConsumerEndpoint::FlushCallback callback,
                               FlushFlags flush_flags) {
  PERFETTO_DCHECK_THREAD(thread_checker_);
  TracingSession* tracing_session = GetTracingSession(tsid);
  if (!tracing_session) {
    PERFETTO_DLOG("Flush() failed, invalid session ID %" PRIu64, tsid);
    return;
  }

  std::map<ProducerID, std::vector<DataSourceInstanceID>> data_source_instances;
  for (const auto& [producer_id, ds_inst] :
       tracing_session->data_source_instances) {
    if (ds_inst.no_flush)
      continue;
    data_source_instances[producer_id].push_back(ds_inst.instance_id);
  }
  FlushDataSourceInstances(tracing_session, timeout_ms, data_source_instances,
                           std::move(callback), flush_flags);
}

void TracingServiceImpl::FlushDataSourceInstances(
    TracingSession* tracing_session,
    uint32_t timeout_ms,
    const std::map<ProducerID, std::vector<DataSourceInstanceID>>&
        data_source_instances,
    ConsumerEndpoint::FlushCallback callback,
    FlushFlags flush_flags) {
  PERFETTO_DCHECK_THREAD(thread_checker_);
  if (!timeout_ms)
    timeout_ms = tracing_session->flush_timeout_ms();

  if (tracing_session->pending_flushes.size() > 1000) {
    PERFETTO_ELOG("Too many flushes (%zu) pending for the tracing session",
                  tracing_session->pending_flushes.size());
    callback(false);
    return;
  }

  if (tracing_session->state != TracingSession::STARTED) {
    PERFETTO_LOG("Flush() called, but tracing has not been started");
    callback(false);
    return;
  }

  ++tracing_session->flushes_requested;
  FlushRequestID flush_request_id = ++last_flush_request_id_;
  PendingFlush& pending_flush =
      tracing_session->pending_flushes
          .emplace_hint(tracing_session->pending_flushes.end(),
                        flush_request_id, PendingFlush(std::move(callback)))
          ->second;

  // Send a flush request to each producer involved in the tracing session. In
  // order to issue a flush request we have to build a map of all data source
  // instance ids enabled for each producer.

  for (const auto& [producer_id, data_sources] : data_source_instances) {
    ProducerEndpointImpl* producer = GetProducer(producer_id);
    producer->Flush(flush_request_id, data_sources, flush_flags);
    pending_flush.producers.insert(producer_id);
  }

  // If there are no producers to flush (realistically this happens only in
  // some tests) fire OnFlushTimeout() straight away, without waiting.
  if (data_source_instances.empty())
    timeout_ms = 0;

  auto weak_this = weak_ptr_factory_.GetWeakPtr();
  task_runner_->PostDelayedTask(
      [weak_this, tsid = tracing_session->id, flush_request_id] {
        if (weak_this)
          weak_this->OnFlushTimeout(tsid, flush_request_id);
      },
      timeout_ms);
}

void TracingServiceImpl::NotifyFlushDoneForProducer(
    ProducerID producer_id,
    FlushRequestID flush_request_id) {
  for (auto& kv : tracing_sessions_) {
    // Remove all pending flushes <= |flush_request_id| for |producer_id|.
    auto& pending_flushes = kv.second.pending_flushes;
    auto end_it = pending_flushes.upper_bound(flush_request_id);
    for (auto it = pending_flushes.begin(); it != end_it;) {
      PendingFlush& pending_flush = it->second;
      pending_flush.producers.erase(producer_id);
      if (pending_flush.producers.empty()) {
        auto weak_this = weak_ptr_factory_.GetWeakPtr();
        TracingSessionID tsid = kv.first;
        auto callback = std::move(pending_flush.callback);
        task_runner_->PostTask([weak_this, tsid, callback]() {
          if (weak_this) {
            weak_this->CompleteFlush(tsid, std::move(callback),
                                     /*success=*/true);
          }
        });
        it = pending_flushes.erase(it);
      } else {
        it++;
      }
    }  // for (pending_flushes)
  }    // for (tracing_session)
}

void TracingServiceImpl::OnFlushTimeout(TracingSessionID tsid,
                                        FlushRequestID flush_request_id) {
  TracingSession* tracing_session = GetTracingSession(tsid);
  if (!tracing_session)
    return;
  auto it = tracing_session->pending_flushes.find(flush_request_id);
  if (it == tracing_session->pending_flushes.end())
    return;  // Nominal case: flush was completed and acked on time.

  // If there were no producers to flush, consider it a success.
  bool success = it->second.producers.empty();
  auto callback = std::move(it->second.callback);
  tracing_session->pending_flushes.erase(it);
  CompleteFlush(tsid, std::move(callback), success);
}

void TracingServiceImpl::CompleteFlush(TracingSessionID tsid,
                                       ConsumerEndpoint::FlushCallback callback,
                                       bool success) {
  TracingSession* tracing_session = GetTracingSession(tsid);
  if (!tracing_session) {
    callback(false);
    return;
  }
  // Producers may not have been able to flush all their data, even if they
  // indicated flush completion. If possible, also collect uncommitted chunks
  // to make sure we have everything they wrote so far.
  for (auto& producer_id_and_producer : producers_) {
    ScrapeSharedMemoryBuffers(tracing_session, producer_id_and_producer.second);
  }
  SnapshotLifecyleEvent(
      tracing_session,
      protos::pbzero::TracingServiceEvent::kAllDataSourcesFlushedFieldNumber,
      true /* snapshot_clocks */);

  tracing_session->flushes_succeeded += success ? 1 : 0;
  tracing_session->flushes_failed += success ? 0 : 1;
  callback(success);
}

void TracingServiceImpl::ScrapeSharedMemoryBuffers(
    TracingSession* tracing_session,
    ProducerEndpointImpl* producer) {
  if (!producer->smb_scraping_enabled_)
    return;

  // Can't copy chunks if we don't know about any trace writers.
  if (producer->writers_.empty())
    return;

  // Performance optimization: On flush or session disconnect, this method is
  // called for each producer. If the producer doesn't participate in the
  // session, there's no need to scape its chunks right now. We can tell if a
  // producer participates in the session by checking if the producer is allowed
  // to write into the session's log buffers.
  const auto& session_buffers = tracing_session->buffers_index;
  bool producer_in_session =
      std::any_of(session_buffers.begin(), session_buffers.end(),
                  [producer](BufferID buffer_id) {
                    return producer->allowed_target_buffers_.count(buffer_id);
                  });
  if (!producer_in_session)
    return;

  PERFETTO_DLOG("Scraping SMB for producer %" PRIu16, producer->id_);

  // Find and copy any uncommitted chunks from the SMB.
  //
  // In nominal conditions, the page layout of the used SMB pages should never
  // change because the service is the only one who is supposed to modify used
  // pages (to make them free again).
  //
  // However, the code here needs to deal with the case of a malicious producer
  // altering the SMB in unpredictable ways. Thankfully the SMB size is
  // immutable, so a chunk will always point to some valid memory, even if the
  // producer alters the intended layout and chunk header concurrently.
  // Ultimately a malicious producer altering the SMB's chunk layout while we
  // are iterating in this function is not any different from the case of a
  // malicious producer asking to commit a chunk made of random data, which is
  // something this class has to deal with regardless.
  //
  // The only legitimate mutations that can happen from sane producers,
  // concurrently to this function, are:
  //   A. free pages being partitioned,
  //   B. free chunks being migrated to kChunkBeingWritten,
  //   C. kChunkBeingWritten chunks being migrated to kChunkCompleted.

  SharedMemoryABI* abi = &producer->shmem_abi_;
  // num_pages() is immutable after the SMB is initialized and cannot be changed
  // even by a producer even if malicious.
  for (size_t page_idx = 0; page_idx < abi->num_pages(); page_idx++) {
    uint32_t layout = abi->GetPageLayout(page_idx);

    uint32_t used_chunks = abi->GetUsedChunks(layout);  // Returns a bitmap.
    // Skip empty pages.
    if (used_chunks == 0)
      continue;

    // Scrape the chunks that are currently used. These should be either in
    // state kChunkBeingWritten or kChunkComplete.
    for (uint32_t chunk_idx = 0; used_chunks; chunk_idx++, used_chunks >>= 1) {
      if (!(used_chunks & 1))
        continue;

      SharedMemoryABI::ChunkState state =
          SharedMemoryABI::GetChunkStateFromLayout(layout, chunk_idx);
      PERFETTO_DCHECK(state == SharedMemoryABI::kChunkBeingWritten ||
                      state == SharedMemoryABI::kChunkComplete);
      bool chunk_complete = state == SharedMemoryABI::kChunkComplete;

      SharedMemoryABI::Chunk chunk =
          abi->GetChunkUnchecked(page_idx, layout, chunk_idx);

      uint16_t packet_count;
      uint8_t flags;
      // GetPacketCountAndFlags has acquire_load semantics.
      std::tie(packet_count, flags) = chunk.GetPacketCountAndFlags();

      // It only makes sense to copy an incomplete chunk if there's at least
      // one full packet available. (The producer may not have completed the
      // last packet in it yet, so we need at least 2.)
      if (!chunk_complete && packet_count < 2)
        continue;

      // At this point, it is safe to access the remaining header fields of
      // the chunk. Even if the chunk was only just transferred from
      // kChunkFree into kChunkBeingWritten state, the header should be
      // written completely once the packet count increased above 1 (it was
      // reset to 0 by the service when the chunk was freed).

      WriterID writer_id = chunk.writer_id();
      std::optional<BufferID> target_buffer_id =
          producer->buffer_id_for_writer(writer_id);

      // We can only scrape this chunk if we know which log buffer to copy it
      // into.
      if (!target_buffer_id)
        continue;

      // Skip chunks that don't belong to the requested tracing session.
      bool target_buffer_belongs_to_session =
          std::find(session_buffers.begin(), session_buffers.end(),
                    *target_buffer_id) != session_buffers.end();
      if (!target_buffer_belongs_to_session)
        continue;

      uint32_t chunk_id =
          chunk.header()->chunk_id.load(std::memory_order_relaxed);

      CopyProducerPageIntoLogBuffer(
          producer->id_, producer->client_identity_, writer_id, chunk_id,
          *target_buffer_id, packet_count, flags, chunk_complete,
          chunk.payload_begin(), chunk.payload_size());
    }
  }
}

void TracingServiceImpl::FlushAndDisableTracing(TracingSessionID tsid) {
  PERFETTO_DCHECK_THREAD(thread_checker_);
  PERFETTO_DLOG("Triggering final flush for %" PRIu64, tsid);
  auto weak_this = weak_ptr_factory_.GetWeakPtr();
  Flush(
      tsid, 0,
      [weak_this, tsid](bool success) {
        // This was a DLOG up to Jun 2021 (v16, Android S).
        PERFETTO_LOG("FlushAndDisableTracing(%" PRIu64 ") done, success=%d",
                     tsid, success);
        if (!weak_this)
          return;
        TracingSession* session = weak_this->GetTracingSession(tsid);
        if (!session) {
          return;
        }
        session->final_flush_outcome = success
                                           ? TraceStats::FINAL_FLUSH_SUCCEEDED
                                           : TraceStats::FINAL_FLUSH_FAILED;
        if (session->consumer_maybe_null) {
          // If the consumer is still attached, just disable the session but
          // give it a chance to read the contents.
          weak_this->DisableTracing(tsid);
        } else {
          // If the consumer detached, destroy the session. If the consumer did
          // start the session in long-tracing mode, the service will have saved
          // the contents to the passed file. If not, the contents will be
          // destroyed.
          weak_this->FreeBuffers(tsid);
        }
      },
      FlushFlags(FlushFlags::Initiator::kTraced,
                 FlushFlags::Reason::kTraceStop));
}

void TracingServiceImpl::PeriodicFlushTask(TracingSessionID tsid,
                                           bool post_next_only) {
  PERFETTO_DCHECK_THREAD(thread_checker_);
  TracingSession* tracing_session = GetTracingSession(tsid);
  if (!tracing_session || tracing_session->state != TracingSession::STARTED)
    return;

  uint32_t flush_period_ms = tracing_session->config.flush_period_ms();
  auto weak_this = weak_ptr_factory_.GetWeakPtr();
  task_runner_->PostDelayedTask(
      [weak_this, tsid] {
        if (weak_this)
          weak_this->PeriodicFlushTask(tsid, /*post_next_only=*/false);
      },
      flush_period_ms - static_cast<uint32_t>(base::GetWallTimeMs().count() %
                                              flush_period_ms));

  if (post_next_only)
    return;

  PERFETTO_DLOG("Triggering periodic flush for trace session %" PRIu64, tsid);
  Flush(
      tsid, 0,
      [](bool success) {
        if (!success)
          PERFETTO_ELOG("Periodic flush timed out");
      },
      FlushFlags(FlushFlags::Initiator::kTraced,
                 FlushFlags::Reason::kPeriodic));
}

void TracingServiceImpl::PeriodicClearIncrementalStateTask(
    TracingSessionID tsid,
    bool post_next_only) {
  PERFETTO_DCHECK_THREAD(thread_checker_);
  TracingSession* tracing_session = GetTracingSession(tsid);
  if (!tracing_session || tracing_session->state != TracingSession::STARTED)
    return;

  uint32_t clear_period_ms =
      tracing_session->config.incremental_state_config().clear_period_ms();
  auto weak_this = weak_ptr_factory_.GetWeakPtr();
  task_runner_->PostDelayedTask(
      [weak_this, tsid] {
        if (weak_this)
          weak_this->PeriodicClearIncrementalStateTask(
              tsid, /*post_next_only=*/false);
      },
      clear_period_ms - static_cast<uint32_t>(base::GetWallTimeMs().count() %
                                              clear_period_ms));

  if (post_next_only)
    return;

  PERFETTO_DLOG(
      "Performing periodic incremental state clear for trace session %" PRIu64,
      tsid);

  // Queue the IPCs to producers with active data sources that opted in.
  std::map<ProducerID, std::vector<DataSourceInstanceID>> clear_map;
  for (const auto& kv : tracing_session->data_source_instances) {
    ProducerID producer_id = kv.first;
    const DataSourceInstance& data_source = kv.second;
    if (data_source.handles_incremental_state_clear) {
      clear_map[producer_id].push_back(data_source.instance_id);
    }
  }

  for (const auto& kv : clear_map) {
    ProducerID producer_id = kv.first;
    const std::vector<DataSourceInstanceID>& data_sources = kv.second;
    ProducerEndpointImpl* producer = GetProducer(producer_id);
    if (!producer) {
      PERFETTO_DFATAL("Producer does not exist.");
      continue;
    }
    producer->ClearIncrementalState(data_sources);
  }
}

bool TracingServiceImpl::ReadBuffersIntoConsumer(
    TracingSessionID tsid,
    ConsumerEndpointImpl* consumer) {
  PERFETTO_DCHECK(consumer);
  PERFETTO_DCHECK_THREAD(thread_checker_);
  TracingSession* tracing_session = GetTracingSession(tsid);
  if (!tracing_session) {
    PERFETTO_DLOG(
        "Cannot ReadBuffersIntoConsumer(): no tracing session is active");
    return false;
  }

  if (tracing_session->write_into_file) {
    // If the consumer enabled tracing and asked to save the contents into the
    // passed file makes little sense to also try to read the buffers over IPC,
    // as that would just steal data from the periodic draining task.
    PERFETTO_ELOG("Consumer trying to read from write_into_file session.");
    return false;
  }

  if (IsWaitingForTrigger(tracing_session))
    return false;

  // This is a rough threshold to determine how much to read from the buffer in
  // each task. This is to avoid executing a single huge sending task for too
  // long and risk to hit the watchdog. This is *not* an upper bound: we just
  // stop accumulating new packets and PostTask *after* we cross this threshold.
  // This constant essentially balances the PostTask and IPC overhead vs the
  // responsiveness of the service. An extremely small value will cause one IPC
  // and one PostTask for each slice but will keep the service extremely
  // responsive. An extremely large value will batch the send for the full
  // buffer in one large task, will hit the blocking send() once the socket
  // buffers are full and hang the service for a bit (until the consumer
  // catches up).
  static constexpr size_t kApproxBytesPerTask = 32768;
  bool has_more;
  std::vector<TracePacket> packets =
      ReadBuffers(tracing_session, kApproxBytesPerTask, &has_more);

  if (has_more) {
    auto weak_consumer = consumer->weak_ptr_factory_.GetWeakPtr();
    auto weak_this = weak_ptr_factory_.GetWeakPtr();
    task_runner_->PostTask([weak_this, weak_consumer, tsid] {
      if (!weak_this || !weak_consumer)
        return;
      weak_this->ReadBuffersIntoConsumer(tsid, weak_consumer.get());
    });
  }

  // Keep this as tail call, just in case the consumer re-enters.
  consumer->consumer_->OnTraceData(std::move(packets), has_more);
  return true;
}

bool TracingServiceImpl::ReadBuffersIntoFile(TracingSessionID tsid) {
  PERFETTO_DCHECK_THREAD(thread_checker_);
  TracingSession* tracing_session = GetTracingSession(tsid);
  if (!tracing_session) {
    // This will be hit systematically from the PostDelayedTask. Avoid logging,
    // it would be just spam.
    return false;
  }

  // This can happen if the file is closed by a previous task because it reaches
  // |max_file_size_bytes|.
  if (!tracing_session->write_into_file)
    return false;

  if (IsWaitingForTrigger(tracing_session))
    return false;

  // ReadBuffers() can allocate memory internally, for filtering. By limiting
  // the data that ReadBuffers() reads to kWriteIntoChunksSize per iteration,
  // we limit the amount of memory used on each iteration.
  //
  // It would be tempting to split this into multiple tasks like in
  // ReadBuffersIntoConsumer, but that's not currently possible.
  // ReadBuffersIntoFile has to read the whole available data before returning,
  // to support the disable_immediately=true code paths.
  bool has_more = true;
  bool stop_writing_into_file = false;
  do {
    std::vector<TracePacket> packets =
        ReadBuffers(tracing_session, kWriteIntoFileChunkSize, &has_more);

    stop_writing_into_file = WriteIntoFile(tracing_session, std::move(packets));
  } while (has_more && !stop_writing_into_file);

  if (stop_writing_into_file || tracing_session->write_period_ms == 0) {
    // Ensure all data was written to the file before we close it.
    base::FlushFile(tracing_session->write_into_file.get());
    tracing_session->write_into_file.reset();
    tracing_session->write_period_ms = 0;
    if (tracing_session->state == TracingSession::STARTED)
      DisableTracing(tsid);
    return true;
  }

  auto weak_this = weak_ptr_factory_.GetWeakPtr();
  task_runner_->PostDelayedTask(
      [weak_this, tsid] {
        if (weak_this)
          weak_this->ReadBuffersIntoFile(tsid);
      },
      tracing_session->delay_to_next_write_period_ms());
  return true;
}

bool TracingServiceImpl::IsWaitingForTrigger(TracingSession* tracing_session) {
  // Ignore the logic below for cloned tracing sessions. In this case we
  // actually want to read the (cloned) trace buffers even if no trigger was
  // hit.
  if (tracing_session->state == TracingSession::CLONED_READ_ONLY) {
    return false;
  }

  // When a tracing session is waiting for a trigger, it is considered empty. If
  // a tracing session finishes and moves into DISABLED without ever receiving a
  // trigger, the trace should never return any data. This includes the
  // synthetic packets like TraceConfig and Clock snapshots. So we bail out
  // early and let the consumer know there is no data.
  if (!tracing_session->config.trigger_config().triggers().empty() &&
      tracing_session->received_triggers.empty()) {
    PERFETTO_DLOG(
        "ReadBuffers(): tracing session has not received a trigger yet.");
    return true;
  }

  // Traces with CLONE_SNAPSHOT triggers are a special case of the above. They
  // can be read only via a CloneSession() request. This is to keep the
  // behavior consistent with the STOP_TRACING+triggers case and avoid periodic
  // finalizations and uploads of the main CLONE_SNAPSHOT triggers.
  if (GetTriggerMode(tracing_session->config) ==
      TraceConfig::TriggerConfig::CLONE_SNAPSHOT) {
    PERFETTO_DLOG(
        "ReadBuffers(): skipping because the tracing session has "
        "CLONE_SNAPSHOT triggers defined");
    return true;
  }

  return false;
}

std::vector<TracePacket> TracingServiceImpl::ReadBuffers(
    TracingSession* tracing_session,
    size_t threshold,
    bool* has_more) {
  PERFETTO_DCHECK_THREAD(thread_checker_);
  PERFETTO_DCHECK(tracing_session);
  *has_more = false;

  std::vector<TracePacket> packets;
  packets.reserve(1024);  // Just an educated guess to avoid trivial expansions.

  if (!tracing_session->initial_clock_snapshot.empty()) {
    EmitClockSnapshot(tracing_session,
                      std::move(tracing_session->initial_clock_snapshot),
                      &packets);
  }

  for (auto& snapshot : tracing_session->clock_snapshot_ring_buffer) {
    PERFETTO_DCHECK(!snapshot.empty());
    EmitClockSnapshot(tracing_session, std::move(snapshot), &packets);
  }
  tracing_session->clock_snapshot_ring_buffer.clear();

  if (tracing_session->should_emit_sync_marker) {
    EmitSyncMarker(&packets);
    tracing_session->should_emit_sync_marker = false;
  }

  if (!tracing_session->config.builtin_data_sources().disable_trace_config()) {
    MaybeEmitTraceConfig(tracing_session, &packets);
    MaybeEmitReceivedTriggers(tracing_session, &packets);
  }
  if (!tracing_session->did_emit_initial_packets) {
    EmitUuid(tracing_session, &packets);
    if (!tracing_session->config.builtin_data_sources().disable_system_info())
      EmitSystemInfo(&packets);
  }
  tracing_session->did_emit_initial_packets = true;

  // Note that in the proto comment, we guarantee that the tracing_started
  // lifecycle event will be emitted before any data packets so make sure to
  // keep this before reading the tracing buffers.
  if (!tracing_session->config.builtin_data_sources().disable_service_events())
    EmitLifecycleEvents(tracing_session, &packets);

  // In a multi-machine tracing session, emit clock synchronization messages for
  // remote machines.
  if (!relay_clients_.empty())
    MaybeEmitRemoteClockSync(tracing_session, &packets);

  size_t packets_bytes = 0;  // SUM(slice.size() for each slice in |packets|).

  // Add up size for packets added by the Maybe* calls above.
  for (const TracePacket& packet : packets) {
    packets_bytes += packet.size();
  }

  bool did_hit_threshold = false;

  for (size_t buf_idx = 0;
       buf_idx < tracing_session->num_buffers() && !did_hit_threshold;
       buf_idx++) {
    auto tbuf_iter = buffers_.find(tracing_session->buffers_index[buf_idx]);
    if (tbuf_iter == buffers_.end()) {
      PERFETTO_DFATAL("Buffer not found.");
      continue;
    }
    TraceBuffer& tbuf = *tbuf_iter->second;
    tbuf.BeginRead();
    while (!did_hit_threshold) {
      TracePacket packet;
      TraceBuffer::PacketSequenceProperties sequence_properties{};
      bool previous_packet_dropped;
      if (!tbuf.ReadNextTracePacket(&packet, &sequence_properties,
                                    &previous_packet_dropped)) {
        break;
      }
      packet.set_buffer_index_for_stats(static_cast<uint32_t>(buf_idx));
      PERFETTO_DCHECK(sequence_properties.producer_id_trusted != 0);
      PERFETTO_DCHECK(sequence_properties.writer_id != 0);
      PERFETTO_DCHECK(sequence_properties.client_identity_trusted.has_uid());
      // Not checking sequence_properties.client_identity_trusted.has_pid():
      // it is false if the platform doesn't support it.

      PERFETTO_DCHECK(packet.size() > 0);
      if (!PacketStreamValidator::Validate(packet.slices())) {
        tracing_session->invalid_packets++;
        PERFETTO_DLOG("Dropping invalid packet");
        continue;
      }

      // Append a slice with the trusted field data. This can't be spoofed
      // because above we validated that the existing slices don't contain any
      // trusted fields. For added safety we append instead of prepending
      // because according to protobuf semantics, if the same field is
      // encountered multiple times the last instance takes priority. Note that
      // truncated packets are also rejected, so the producer can't give us a
      // partial packet (e.g., a truncated string) which only becomes valid when
      // the trusted data is appended here.
      Slice slice = Slice::Allocate(32);
      protozero::StaticBuffered<protos::pbzero::TracePacket> trusted_packet(
          slice.own_data(), slice.size);
      const auto& client_identity_trusted =
          sequence_properties.client_identity_trusted;
      trusted_packet->set_trusted_uid(
          static_cast<int32_t>(client_identity_trusted.uid()));
      trusted_packet->set_trusted_packet_sequence_id(
          tracing_session->GetPacketSequenceID(
              client_identity_trusted.machine_id(),
              sequence_properties.producer_id_trusted,
              sequence_properties.writer_id));
      if (client_identity_trusted.has_pid()) {
        // Not supported on all platforms.
        trusted_packet->set_trusted_pid(
            static_cast<int32_t>(client_identity_trusted.pid()));
      }
      if (client_identity_trusted.has_non_default_machine_id()) {
        trusted_packet->set_machine_id(client_identity_trusted.machine_id());
      }
      if (previous_packet_dropped)
        trusted_packet->set_previous_packet_dropped(previous_packet_dropped);
      slice.size = trusted_packet.Finalize();
      packet.AddSlice(std::move(slice));

      // Append the packet (inclusive of the trusted uid) to |packets|.
      packets_bytes += packet.size();
      did_hit_threshold = packets_bytes >= threshold;
      packets.emplace_back(std::move(packet));
    }  // for(packets...)
  }    // for(buffers...)

  *has_more = did_hit_threshold;

  // Only emit the "read complete" lifetime event when there is no more trace
  // data available to read. These events are used as safe points to limit
  // sorting in trace processor: the code shouldn't emit the event unless the
  // buffers are empty.
  if (!*has_more && !tracing_session->config.builtin_data_sources()
                         .disable_service_events()) {
    // We don't bother snapshotting clocks here because we wouldn't be able to
    // emit it and we shouldn't have significant drift from the last snapshot in
    // any case.
    SnapshotLifecyleEvent(tracing_session,
                          protos::pbzero::TracingServiceEvent::
                              kReadTracingBuffersCompletedFieldNumber,
                          false /* snapshot_clocks */);
    EmitLifecycleEvents(tracing_session, &packets);
  }

  // Only emit the stats when there is no more trace data is available to read.
  // That way, any problems that occur while reading from the buffers are
  // reflected in the emitted stats. This is particularly important for use
  // cases where ReadBuffers is only ever called after the tracing session is
  // stopped.
  if (!*has_more && tracing_session->should_emit_stats) {
    EmitStats(tracing_session, &packets);
    tracing_session->should_emit_stats = false;
  }

  MaybeFilterPackets(tracing_session, &packets);

  MaybeCompressPackets(tracing_session, &packets);

  if (!*has_more) {
    // We've observed some extremely high memory usage by scudo after
    // MaybeFilterPackets in the past. The original bug (b/195145848) is fixed
    // now, but this code asks scudo to release memory just in case.
    base::MaybeReleaseAllocatorMemToOS();
  }

  return packets;
}

void TracingServiceImpl::MaybeFilterPackets(TracingSession* tracing_session,
                                            std::vector<TracePacket>* packets) {
  // If the tracing session specified a filter, run all packets through the
  // filter and replace them with the filter results.
  // The process below mantains the cardinality of input packets. Even if an
  // entire packet is filtered out, we emit a zero-sized TracePacket proto. That
  // makes debugging and reasoning about the trace stats easier.
  // This place swaps the contents of each |packets| entry in place.
  if (!tracing_session->trace_filter) {
    return;
  }
  protozero::MessageFilter& trace_filter = *tracing_session->trace_filter;
  // The filter root should be reset from protos.Trace to protos.TracePacket
  // by the earlier call to SetFilterRoot() in EnableTracing().
  PERFETTO_DCHECK(trace_filter.config().root_msg_index() != 0);
  std::vector<protozero::MessageFilter::InputSlice> filter_input;
  auto start = base::GetWallTimeNs();
  for (TracePacket& packet : *packets) {
    const auto& packet_slices = packet.slices();
    const size_t input_packet_size = packet.size();
    filter_input.clear();
    filter_input.resize(packet_slices.size());
    ++tracing_session->filter_input_packets;
    tracing_session->filter_input_bytes += input_packet_size;
    for (size_t i = 0; i < packet_slices.size(); ++i)
      filter_input[i] = {packet_slices[i].start, packet_slices[i].size};
    auto filtered_packet = trace_filter.FilterMessageFragments(
        &filter_input[0], filter_input.size());

    // Replace the packet in-place with the filtered one (unless failed).
    std::optional<uint32_t> maybe_buffer_idx = packet.buffer_index_for_stats();
    packet = TracePacket();
    if (filtered_packet.error) {
      ++tracing_session->filter_errors;
      PERFETTO_DLOG("Trace packet filtering failed @ packet %" PRIu64,
                    tracing_session->filter_input_packets);
      continue;
    }
    tracing_session->filter_output_bytes += filtered_packet.size;
    if (maybe_buffer_idx.has_value()) {
      // Keep the per-buffer stats updated. Also propagate the
      // buffer_index_for_stats in the output packet to allow accounting by
      // other parts of the ReadBuffer pipeline.
      uint32_t buffer_idx = maybe_buffer_idx.value();
      packet.set_buffer_index_for_stats(buffer_idx);
      auto& vec = tracing_session->filter_bytes_discarded_per_buffer;
      if (static_cast<size_t>(buffer_idx) >= vec.size())
        vec.resize(buffer_idx + 1);
      PERFETTO_DCHECK(input_packet_size >= filtered_packet.size);
      size_t bytes_filtered_out = input_packet_size - filtered_packet.size;
      vec[buffer_idx] += bytes_filtered_out;
    }
    AppendOwnedSlicesToPacket(std::move(filtered_packet.data),
                              filtered_packet.size, kMaxTracePacketSliceSize,
                              &packet);
  }
  auto end = base::GetWallTimeNs();
  tracing_session->filter_time_taken_ns +=
      static_cast<uint64_t>((end - start).count());
}

void TracingServiceImpl::MaybeCompressPackets(
    TracingSession* tracing_session,
    std::vector<TracePacket>* packets) {
  if (!tracing_session->compress_deflate) {
    return;
  }

  init_opts_.compressor_fn(packets);
}

bool TracingServiceImpl::WriteIntoFile(TracingSession* tracing_session,
                                       std::vector<TracePacket> packets) {
  if (!tracing_session->write_into_file) {
    return false;
  }
  const uint64_t max_size = tracing_session->max_file_size_bytes
                                ? tracing_session->max_file_size_bytes
                                : std::numeric_limits<size_t>::max();

  size_t total_slices = 0;
  for (const TracePacket& packet : packets) {
    total_slices += packet.slices().size();
  }
  // When writing into a file, the file should look like a root trace.proto
  // message. Each packet should be prepended with a proto preamble stating
  // its field id (within trace.proto) and size. Hence the addition below.
  const size_t max_iovecs = total_slices + packets.size();

  size_t num_iovecs = 0;
  bool stop_writing_into_file = false;
  std::unique_ptr<struct iovec[]> iovecs(new struct iovec[max_iovecs]);
  size_t num_iovecs_at_last_packet = 0;
  uint64_t bytes_about_to_be_written = 0;
  for (TracePacket& packet : packets) {
    std::tie(iovecs[num_iovecs].iov_base, iovecs[num_iovecs].iov_len) =
        packet.GetProtoPreamble();
    bytes_about_to_be_written += iovecs[num_iovecs].iov_len;
    num_iovecs++;
    for (const Slice& slice : packet.slices()) {
      // writev() doesn't change the passed pointer. However, struct iovec
      // take a non-const ptr because it's the same struct used by readv().
      // Hence the const_cast here.
      char* start = static_cast<char*>(const_cast<void*>(slice.start));
      bytes_about_to_be_written += slice.size;
      iovecs[num_iovecs++] = {start, slice.size};
    }

    if (tracing_session->bytes_written_into_file + bytes_about_to_be_written >=
        max_size) {
      stop_writing_into_file = true;
      num_iovecs = num_iovecs_at_last_packet;
      break;
    }

    num_iovecs_at_last_packet = num_iovecs;
  }
  PERFETTO_DCHECK(num_iovecs <= max_iovecs);
  int fd = *tracing_session->write_into_file;

  uint64_t total_wr_size = 0;

  // writev() can take at most IOV_MAX entries per call. Batch them.
  constexpr size_t kIOVMax = IOV_MAX;
  for (size_t i = 0; i < num_iovecs; i += kIOVMax) {
    int iov_batch_size = static_cast<int>(std::min(num_iovecs - i, kIOVMax));
    ssize_t wr_size = PERFETTO_EINTR(writev(fd, &iovecs[i], iov_batch_size));
    if (wr_size <= 0) {
      PERFETTO_PLOG("writev() failed");
      stop_writing_into_file = true;
      break;
    }
    total_wr_size += static_cast<size_t>(wr_size);
  }

  tracing_session->bytes_written_into_file += total_wr_size;

  PERFETTO_DLOG("Draining into file, written: %" PRIu64 " KB, stop: %d",
                (total_wr_size + 1023) / 1024, stop_writing_into_file);
  return stop_writing_into_file;
}

void TracingServiceImpl::FreeBuffers(TracingSessionID tsid) {
  PERFETTO_DCHECK_THREAD(thread_checker_);
  PERFETTO_DLOG("Freeing buffers for session %" PRIu64, tsid);
  TracingSession* tracing_session = GetTracingSession(tsid);
  if (!tracing_session) {
    PERFETTO_DLOG("FreeBuffers() failed, invalid session ID %" PRIu64, tsid);
    return;  // TODO(primiano): signal failure?
  }
  DisableTracing(tsid, /*disable_immediately=*/true);

  PERFETTO_DCHECK(tracing_session->AllDataSourceInstancesStopped());
  tracing_session->data_source_instances.clear();

  for (auto& producer_entry : producers_) {
    ProducerEndpointImpl* producer = producer_entry.second;
    producer->OnFreeBuffers(tracing_session->buffers_index);
  }

  for (BufferID buffer_id : tracing_session->buffers_index) {
    buffer_ids_.Free(buffer_id);
    PERFETTO_DCHECK(buffers_.count(buffer_id) == 1);
    buffers_.erase(buffer_id);
  }
  bool notify_traceur =
      tracing_session->config.notify_traceur() &&
      tracing_session->state != TracingSession::CLONED_READ_ONLY;
  bool is_long_trace =
      (tracing_session->config.write_into_file() &&
       tracing_session->config.file_write_period_ms() < kMillisPerDay);
  tracing_sessions_.erase(tsid);
  tracing_session = nullptr;
  UpdateMemoryGuardrail();

  PERFETTO_LOG("Tracing session %" PRIu64 " ended, total sessions:%zu", tsid,
               tracing_sessions_.size());
#if PERFETTO_BUILDFLAG(PERFETTO_ANDROID_BUILD) && \
    PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
  if (notify_traceur && is_long_trace) {
    PERFETTO_LAZY_LOAD(android_internal::NotifyTraceSessionEnded, notify_fn);
    if (!notify_fn || !notify_fn(/*session_stolen=*/false))
      PERFETTO_ELOG("Failed to notify Traceur long tracing has ended");
  }
#else
  base::ignore_result(notify_traceur);
  base::ignore_result(is_long_trace);
#endif
}

void TracingServiceImpl::RegisterDataSource(ProducerID producer_id,
                                            const DataSourceDescriptor& desc) {
  PERFETTO_DCHECK_THREAD(thread_checker_);
  if (desc.name().empty()) {
    PERFETTO_DLOG("Received RegisterDataSource() with empty name");
    return;
  }

  ProducerEndpointImpl* producer = GetProducer(producer_id);
  if (!producer) {
    PERFETTO_DFATAL("Producer not found.");
    return;
  }

  // Check that the producer doesn't register two data sources with the same ID.
  // Note that we tolerate |id| == 0 because until Android T / v22 the |id|
  // field didn't exist.
  for (const auto& kv : data_sources_) {
    if (desc.id() && kv.second.producer_id == producer_id &&
        kv.second.descriptor.id() == desc.id()) {
      PERFETTO_ELOG(
          "Failed to register data source \"%s\". A data source with the same "
          "id %" PRIu64 " (name=\"%s\") is already registered for producer %d",
          desc.name().c_str(), desc.id(), kv.second.descriptor.name().c_str(),
          producer_id);
      return;
    }
  }

  PERFETTO_DLOG("Producer %" PRIu16 " registered data source \"%s\"",
                producer_id, desc.name().c_str());

  auto reg_ds = data_sources_.emplace(desc.name(),
                                      RegisteredDataSource{producer_id, desc});

  // If there are existing tracing sessions, we need to check if the new
  // data source is enabled by any of them.
  for (auto& iter : tracing_sessions_) {
    TracingSession& tracing_session = iter.second;
    if (tracing_session.state != TracingSession::STARTED &&
        tracing_session.state != TracingSession::CONFIGURED) {
      continue;
    }

    TraceConfig::ProducerConfig producer_config;
    for (const auto& config : tracing_session.config.producers()) {
      if (producer->name_ == config.producer_name()) {
        producer_config = config;
        break;
      }
    }
    for (const TraceConfig::DataSource& cfg_data_source :
         tracing_session.config.data_sources()) {
      if (cfg_data_source.config().name() != desc.name())
        continue;
      DataSourceInstance* ds_inst = SetupDataSource(
          cfg_data_source, producer_config, reg_ds->second, &tracing_session);
      if (ds_inst && tracing_session.state == TracingSession::STARTED)
        StartDataSourceInstance(producer, &tracing_session, ds_inst);
    }
  }  // for(iter : tracing_sessions_)
}

void TracingServiceImpl::UpdateDataSource(
    ProducerID producer_id,
    const DataSourceDescriptor& new_desc) {
  if (new_desc.id() == 0) {
    PERFETTO_ELOG("UpdateDataSource() must have a non-zero id");
    return;
  }

  // If this producer has already registered a matching descriptor name and id,
  // just update the descriptor.
  RegisteredDataSource* data_source = nullptr;
  auto range = data_sources_.equal_range(new_desc.name());
  for (auto it = range.first; it != range.second; ++it) {
    if (it->second.producer_id == producer_id &&
        it->second.descriptor.id() == new_desc.id()) {
      data_source = &it->second;
      break;
    }
  }

  if (!data_source) {
    PERFETTO_ELOG(
        "UpdateDataSource() failed, could not find an existing data source "
        "with name=\"%s\" id=%" PRIu64,
        new_desc.name().c_str(), new_desc.id());
    return;
  }

  data_source->descriptor = new_desc;
}

void TracingServiceImpl::StopDataSourceInstance(ProducerEndpointImpl* producer,
                                                TracingSession* tracing_session,
                                                DataSourceInstance* instance,
                                                bool disable_immediately) {
  const DataSourceInstanceID ds_inst_id = instance->instance_id;
  if (instance->will_notify_on_stop && !disable_immediately) {
    instance->state = DataSourceInstance::STOPPING;
  } else {
    instance->state = DataSourceInstance::STOPPED;
  }
  if (tracing_session->consumer_maybe_null) {
    tracing_session->consumer_maybe_null->OnDataSourceInstanceStateChange(
        *producer, *instance);
  }
  producer->StopDataSource(ds_inst_id);
}

void TracingServiceImpl::UnregisterDataSource(ProducerID producer_id,
                                              const std::string& name) {
  PERFETTO_DCHECK_THREAD(thread_checker_);
  PERFETTO_DLOG("Producer %" PRIu16 " unregistered data source \"%s\"",
                producer_id, name.c_str());
  PERFETTO_CHECK(producer_id);
  ProducerEndpointImpl* producer = GetProducer(producer_id);
  PERFETTO_DCHECK(producer);
  for (auto& kv : tracing_sessions_) {
    auto& ds_instances = kv.second.data_source_instances;
    bool removed = false;
    for (auto it = ds_instances.begin(); it != ds_instances.end();) {
      if (it->first == producer_id && it->second.data_source_name == name) {
        DataSourceInstanceID ds_inst_id = it->second.instance_id;
        if (it->second.state != DataSourceInstance::STOPPED) {
          if (it->second.state != DataSourceInstance::STOPPING) {
            StopDataSourceInstance(producer, &kv.second, &it->second,
                                   /* disable_immediately = */ false);
          }

          // Mark the instance as stopped immediately, since we are
          // unregistering it below.
          //
          //  The StopDataSourceInstance above might have set the state to
          //  STOPPING so this condition isn't an else.
          if (it->second.state == DataSourceInstance::STOPPING)
            NotifyDataSourceStopped(producer_id, ds_inst_id);
        }
        it = ds_instances.erase(it);
        removed = true;
      } else {
        ++it;
      }
    }  // for (data_source_instances)
    if (removed)
      MaybeNotifyAllDataSourcesStarted(&kv.second);
  }  // for (tracing_session)

  for (auto it = data_sources_.begin(); it != data_sources_.end(); ++it) {
    if (it->second.producer_id == producer_id &&
        it->second.descriptor.name() == name) {
      data_sources_.erase(it);
      return;
    }
  }

  PERFETTO_DFATAL(
      "Tried to unregister a non-existent data source \"%s\" for "
      "producer %" PRIu16,
      name.c_str(), producer_id);
}

bool TracingServiceImpl::IsInitiatorPrivileged(
    const TracingSession& tracing_session) {
#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
  if (tracing_session.consumer_uid == 1066 /* AID_STATSD */ &&
      tracing_session.config.statsd_metadata().triggering_config_uid() !=
          2000 /* AID_SHELL */
      && tracing_session.config.statsd_metadata().triggering_config_uid() !=
             0 /* AID_ROOT */) {
    // StatsD can be triggered either by shell, root or an app that has DUMP and
    // USAGE_STATS permission. When triggered by shell or root, we do not want
    // to consider the trace a trusted system trace, as it was initiated by the
    // user. Otherwise, it has to come from an app with DUMP and
    // PACKAGE_USAGE_STATS, which has to be preinstalled and trusted by the
    // system.
    // Check for shell / root: https://bit.ly/3b7oZNi
    // Check for DUMP or PACKAGE_USAGE_STATS: https://bit.ly/3ep0NrR
    return true;
  }
  if (tracing_session.consumer_uid == 1000 /* AID_SYSTEM */) {
    // AID_SYSTEM is considered a privileged initiator so that system_server can
    // profile apps that are not profileable by shell. Other AID_SYSTEM
    // processes are not allowed by SELinux to connect to the consumer socket or
    // to exec perfetto.
    return true;
  }
#else
  base::ignore_result(tracing_session);
#endif
  return false;
}

TracingServiceImpl::DataSourceInstance* TracingServiceImpl::SetupDataSource(
    const TraceConfig::DataSource& cfg_data_source,
    const TraceConfig::ProducerConfig& producer_config,
    const RegisteredDataSource& data_source,
    TracingSession* tracing_session) {
  PERFETTO_DCHECK_THREAD(thread_checker_);
  ProducerEndpointImpl* producer = GetProducer(data_source.producer_id);
  PERFETTO_DCHECK(producer);
  // An existing producer that is not ftrace could have registered itself as
  // ftrace, we must not enable it in that case.
  if (lockdown_mode_ && producer->uid() != uid_) {
    PERFETTO_DLOG("Lockdown mode: not enabling producer %hu", producer->id_);
    return nullptr;
  }
  // TODO(primiano): Add tests for registration ordering (data sources vs
  // consumers).
  if (!NameMatchesFilter(producer->name_,
                         cfg_data_source.producer_name_filter(),
                         cfg_data_source.producer_name_regex_filter())) {
    PERFETTO_DLOG("Data source: %s is filtered out for producer: %s",
                  cfg_data_source.config().name().c_str(),
                  producer->name_.c_str());
    return nullptr;
  }

  auto relative_buffer_id = cfg_data_source.config().target_buffer();
  if (relative_buffer_id >= tracing_session->num_buffers()) {
    PERFETTO_LOG(
        "The TraceConfig for DataSource %s specified a target_buffer out of "
        "bound (%d). Skipping it.",
        cfg_data_source.config().name().c_str(), relative_buffer_id);
    return nullptr;
  }

  // Create a copy of the DataSourceConfig specified in the trace config. This
  // will be passed to the producer after translating the |target_buffer| id.
  // The |target_buffer| parameter passed by the consumer in the trace config is
  // relative to the buffers declared in the same trace config. This has to be
  // translated to the global BufferID before passing it to the producers, which
  // don't know anything about tracing sessions and consumers.

  DataSourceInstanceID inst_id = ++last_data_source_instance_id_;
  auto insert_iter = tracing_session->data_source_instances.emplace(
      std::piecewise_construct,  //
      std::forward_as_tuple(producer->id_),
      std::forward_as_tuple(
          inst_id,
          cfg_data_source.config(),  //  Deliberate copy.
          data_source.descriptor.name(),
          data_source.descriptor.will_notify_on_start(),
          data_source.descriptor.will_notify_on_stop(),
          data_source.descriptor.handles_incremental_state_clear(),
          data_source.descriptor.no_flush()));
  DataSourceInstance* ds_instance = &insert_iter->second;

  // New data source instance starts out in CONFIGURED state.
  if (tracing_session->consumer_maybe_null) {
    tracing_session->consumer_maybe_null->OnDataSourceInstanceStateChange(
        *producer, *ds_instance);
  }

  DataSourceConfig& ds_config = ds_instance->config;
  ds_config.set_trace_duration_ms(tracing_session->config.duration_ms());

  // Rationale for `if (prefer) set_prefer(true)`, rather than `set(prefer)`:
  // ComputeStartupConfigHash() in tracing_muxer_impl.cc compares hashes of the
  // DataSourceConfig and expects to know (and clear) the fields generated by
  // the tracing service. Unconditionally adding a new field breaks backward
  // compatibility of startup tracing with older SDKs, because the serialization
  // also propagates unkonwn fields, breaking the hash matching check.
  if (tracing_session->config.prefer_suspend_clock_for_duration())
    ds_config.set_prefer_suspend_clock_for_duration(true);

  ds_config.set_stop_timeout_ms(tracing_session->data_source_stop_timeout_ms());
  ds_config.set_enable_extra_guardrails(
      tracing_session->config.enable_extra_guardrails());
  if (IsInitiatorPrivileged(*tracing_session)) {
    ds_config.set_session_initiator(
        DataSourceConfig::SESSION_INITIATOR_TRUSTED_SYSTEM);
  } else {
    // Unset in case the consumer set it.
    // We need to be able to trust this field.
    ds_config.set_session_initiator(
        DataSourceConfig::SESSION_INITIATOR_UNSPECIFIED);
  }
  ds_config.set_tracing_session_id(tracing_session->id);
  BufferID global_id = tracing_session->buffers_index[relative_buffer_id];
  PERFETTO_DCHECK(global_id);
  ds_config.set_target_buffer(global_id);

  PERFETTO_DLOG("Setting up data source %s with target buffer %" PRIu16,
                ds_config.name().c_str(), global_id);
  if (!producer->shared_memory()) {
    // Determine the SMB page size. Must be an integer multiple of 4k.
    // As for the SMB size below, the decision tree is as follows:
    // 1. Give priority to what is defined in the trace config.
    // 2. If unset give priority to the hint passed by the producer.
    // 3. Keep within bounds and ensure it's a multiple of 4k.
    size_t page_size = producer_config.page_size_kb() * 1024;
    if (page_size == 0)
      page_size = producer->shmem_page_size_hint_bytes_;

    // Determine the SMB size. Must be an integer multiple of the SMB page size.
    // The decision tree is as follows:
    // 1. Give priority to what defined in the trace config.
    // 2. If unset give priority to the hint passed by the producer.
    // 3. Keep within bounds and ensure it's a multiple of the page size.
    size_t shm_size = producer_config.shm_size_kb() * 1024;
    if (shm_size == 0)
      shm_size = producer->shmem_size_hint_bytes_;

    auto valid_sizes = EnsureValidShmSizes(shm_size, page_size);
    if (valid_sizes != std::tie(shm_size, page_size)) {
      PERFETTO_DLOG(
          "Invalid configured SMB sizes: shm_size %zu page_size %zu. Falling "
          "back to shm_size %zu page_size %zu.",
          shm_size, page_size, std::get<0>(valid_sizes),
          std::get<1>(valid_sizes));
    }
    std::tie(shm_size, page_size) = valid_sizes;

    // TODO(primiano): right now Create() will suicide in case of OOM if the
    // mmap fails. We should instead gracefully fail the request and tell the
    // client to go away.
    PERFETTO_DLOG("Creating SMB of %zu KB for producer \"%s\"", shm_size / 1024,
                  producer->name_.c_str());
    auto shared_memory = shm_factory_->CreateSharedMemory(shm_size);
    producer->SetupSharedMemory(std::move(shared_memory), page_size,
                                /*provided_by_producer=*/false);
  }
  producer->SetupDataSource(inst_id, ds_config);
  return ds_instance;
}

// Note: all the fields % *_trusted ones are untrusted, as in, the Producer
// might be lying / returning garbage contents. |src| and |size| can be trusted
// in terms of being a valid pointer, but not the contents.
void TracingServiceImpl::CopyProducerPageIntoLogBuffer(
    ProducerID producer_id_trusted,
    const ClientIdentity& client_identity_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) {
  PERFETTO_DCHECK_THREAD(thread_checker_);

  ProducerEndpointImpl* producer = GetProducer(producer_id_trusted);
  if (!producer) {
    PERFETTO_DFATAL("Producer not found.");
    chunks_discarded_++;
    return;
  }

  TraceBuffer* buf = GetBufferByID(buffer_id);
  if (!buf) {
    PERFETTO_DLOG("Could not find target buffer %" PRIu16
                  " for producer %" PRIu16,
                  buffer_id, producer_id_trusted);
    chunks_discarded_++;
    return;
  }

  // Verify that the producer is actually allowed to write into the target
  // buffer specified in the request. This prevents a malicious producer from
  // injecting data into a log buffer that belongs to a tracing session the
  // producer is not part of.
  if (!producer->is_allowed_target_buffer(buffer_id)) {
    PERFETTO_ELOG("Producer %" PRIu16
                  " tried to write into forbidden target buffer %" PRIu16,
                  producer_id_trusted, buffer_id);
    PERFETTO_DFATAL("Forbidden target buffer");
    chunks_discarded_++;
    return;
  }

  // If the writer was registered by the producer, it should only write into the
  // buffer it was registered with.
  std::optional<BufferID> associated_buffer =
      producer->buffer_id_for_writer(writer_id);
  if (associated_buffer && *associated_buffer != buffer_id) {
    PERFETTO_ELOG("Writer %" PRIu16 " of producer %" PRIu16
                  " was registered to write into target buffer %" PRIu16
                  ", but tried to write into buffer %" PRIu16,
                  writer_id, producer_id_trusted, *associated_buffer,
                  buffer_id);
    PERFETTO_DFATAL("Wrong target buffer");
    chunks_discarded_++;
    return;
  }

  buf->CopyChunkUntrusted(producer_id_trusted, client_identity_trusted,
                          writer_id, chunk_id, num_fragments, chunk_flags,
                          chunk_complete, src, size);
}

void TracingServiceImpl::ApplyChunkPatches(
    ProducerID producer_id_trusted,
    const std::vector<CommitDataRequest::ChunkToPatch>& chunks_to_patch) {
  PERFETTO_DCHECK_THREAD(thread_checker_);

  for (const auto& chunk : chunks_to_patch) {
    const ChunkID chunk_id = static_cast<ChunkID>(chunk.chunk_id());
    const WriterID writer_id = static_cast<WriterID>(chunk.writer_id());
    TraceBuffer* buf =
        GetBufferByID(static_cast<BufferID>(chunk.target_buffer()));
    static_assert(std::numeric_limits<ChunkID>::max() == kMaxChunkID,
                  "Add a '|| chunk_id > kMaxChunkID' below if this fails");
    if (!writer_id || writer_id > kMaxWriterID || !buf) {
      // This can genuinely happen when the trace is stopped. The producers
      // might see the stop signal with some delay and try to keep sending
      // patches left soon after.
      PERFETTO_DLOG(
          "Received invalid chunks_to_patch request from Producer: %" PRIu16
          ", BufferID: %" PRIu32 " ChunkdID: %" PRIu32 " WriterID: %" PRIu16,
          producer_id_trusted, chunk.target_buffer(), chunk_id, writer_id);
      patches_discarded_ += static_cast<uint64_t>(chunk.patches_size());
      continue;
    }

    // Note, there's no need to validate that the producer is allowed to write
    // to the specified buffer ID (or that it's the correct buffer ID for a
    // registered TraceWriter). That's because TraceBuffer uses the producer ID
    // and writer ID to look up the chunk to patch. If the producer specifies an
    // incorrect buffer, this lookup will fail and TraceBuffer will ignore the
    // patches. Because the producer ID is trusted, there's also no way for a
    // malicious producer to patch another producer's data.

    // Speculate on the fact that there are going to be a limited amount of
    // patches per request, so we can allocate the |patches| array on the stack.
    std::array<TraceBuffer::Patch, 1024> patches;  // Uninitialized.
    if (chunk.patches().size() > patches.size()) {
      PERFETTO_ELOG("Too many patches (%zu) batched in the same request",
                    patches.size());
      PERFETTO_DFATAL("Too many patches");
      patches_discarded_ += static_cast<uint64_t>(chunk.patches_size());
      continue;
    }

    size_t i = 0;
    for (const auto& patch : chunk.patches()) {
      const std::string& patch_data = patch.data();
      if (patch_data.size() != patches[i].data.size()) {
        PERFETTO_ELOG("Received patch from producer: %" PRIu16
                      " of unexpected size %zu",
                      producer_id_trusted, patch_data.size());
        patches_discarded_++;
        continue;
      }
      patches[i].offset_untrusted = patch.offset();
      memcpy(&patches[i].data[0], patch_data.data(), patches[i].data.size());
      i++;
    }
    buf->TryPatchChunkContents(producer_id_trusted, writer_id, chunk_id,
                               &patches[0], i, chunk.has_more_patches());
  }
}

TracingServiceImpl::TracingSession* TracingServiceImpl::GetDetachedSession(
    uid_t uid,
    const std::string& key) {
  PERFETTO_DCHECK_THREAD(thread_checker_);
  for (auto& kv : tracing_sessions_) {
    TracingSession* session = &kv.second;
    if (session->consumer_uid == uid && session->detach_key == key) {
      PERFETTO_DCHECK(session->consumer_maybe_null == nullptr);
      return session;
    }
  }
  return nullptr;
}

TracingServiceImpl::TracingSession* TracingServiceImpl::GetTracingSession(
    TracingSessionID tsid) {
  PERFETTO_DCHECK_THREAD(thread_checker_);
  auto it = tsid ? tracing_sessions_.find(tsid) : tracing_sessions_.end();
  if (it == tracing_sessions_.end())
    return nullptr;
  return &it->second;
}

TracingServiceImpl::TracingSession*
TracingServiceImpl::FindTracingSessionWithMaxBugreportScore() {
  TracingSession* max_session = nullptr;
  for (auto& session_id_and_session : tracing_sessions_) {
    auto& session = session_id_and_session.second;
    const int32_t score = session.config.bugreport_score();
    // Exclude sessions with 0 (or below) score. By default tracing sessions
    // should NOT be eligible to be attached to bugreports.
    if (score <= 0 || session.state != TracingSession::STARTED)
      continue;

    if (!max_session || score > max_session->config.bugreport_score())
      max_session = &session;
  }
  return max_session;
}

ProducerID TracingServiceImpl::GetNextProducerID() {
  PERFETTO_DCHECK_THREAD(thread_checker_);
  PERFETTO_CHECK(producers_.size() < kMaxProducerID);
  do {
    ++last_producer_id_;
  } while (producers_.count(last_producer_id_) || last_producer_id_ == 0);
  PERFETTO_DCHECK(last_producer_id_ > 0 && last_producer_id_ <= kMaxProducerID);
  return last_producer_id_;
}

TraceBuffer* TracingServiceImpl::GetBufferByID(BufferID buffer_id) {
  auto buf_iter = buffers_.find(buffer_id);
  if (buf_iter == buffers_.end())
    return nullptr;
  return &*buf_iter->second;
}

void TracingServiceImpl::OnStartTriggersTimeout(TracingSessionID tsid) {
  // Skip entirely the flush if the trace session doesn't exist anymore.
  // This is to prevent misleading error messages to be logged.
  //
  // if the trace has started from the trigger we rely on
  // the |stop_delay_ms| from the trigger so don't flush and
  // disable if we've moved beyond a CONFIGURED state
  auto* tracing_session_ptr = GetTracingSession(tsid);
  if (tracing_session_ptr &&
      tracing_session_ptr->state == TracingSession::CONFIGURED) {
    PERFETTO_DLOG("Disabling TracingSession %" PRIu64
                  " since no triggers activated.",
                  tsid);
    // No data should be returned from ReadBuffers() regardless of if we
    // call FreeBuffers() or DisableTracing(). This is because in
    // STOP_TRACING we need this promise in either case, and using
    // DisableTracing() allows a graceful shutdown. Consumers can follow
    // their normal path and check the buffers through ReadBuffers() and
    // the code won't hang because the tracing session will still be
    // alive just disabled.
    DisableTracing(tsid);
  }
}

void TracingServiceImpl::UpdateMemoryGuardrail() {
#if PERFETTO_BUILDFLAG(PERFETTO_WATCHDOG)
  uint64_t total_buffer_bytes = 0;

  // Sum up all the shared memory buffers.
  for (const auto& id_to_producer : producers_) {
    if (id_to_producer.second->shared_memory())
      total_buffer_bytes += id_to_producer.second->shared_memory()->size();
  }

  // Sum up all the trace buffers.
  for (const auto& id_to_buffer : buffers_) {
    total_buffer_bytes += id_to_buffer.second->size();
  }

  // Sum up all the cloned traced buffers.
  for (const auto& id_to_ts : tracing_sessions_) {
    const TracingSession& ts = id_to_ts.second;
    for (const auto& id_to_pending_clone : ts.pending_clones) {
      const PendingClone& pending_clone = id_to_pending_clone.second;
      for (const std::unique_ptr<TraceBuffer>& buf : pending_clone.buffers) {
        if (buf) {
          total_buffer_bytes += buf->size();
        }
      }
    }
  }

  // Set the guard rail to 32MB + the sum of all the buffers over a 30 second
  // interval.
  uint64_t guardrail = base::kWatchdogDefaultMemorySlack + total_buffer_bytes;
  base::Watchdog::GetInstance()->SetMemoryLimit(guardrail, 30 * 1000);
#endif
}

void TracingServiceImpl::PeriodicSnapshotTask(TracingSessionID tsid) {
  auto* tracing_session = GetTracingSession(tsid);
  if (!tracing_session)
    return;
  if (tracing_session->state != TracingSession::STARTED)
    return;
  tracing_session->should_emit_sync_marker = true;
  tracing_session->should_emit_stats = true;
  MaybeSnapshotClocksIntoRingBuffer(tracing_session);
}

void TracingServiceImpl::SnapshotLifecyleEvent(TracingSession* tracing_session,
                                               uint32_t field_id,
                                               bool snapshot_clocks) {
  // field_id should be an id of a field in TracingServiceEvent.
  auto& lifecycle_events = tracing_session->lifecycle_events;
  auto event_it =
      std::find_if(lifecycle_events.begin(), lifecycle_events.end(),
                   [field_id](const TracingSession::LifecycleEvent& event) {
                     return event.field_id == field_id;
                   });

  TracingSession::LifecycleEvent* event;
  if (event_it == lifecycle_events.end()) {
    lifecycle_events.emplace_back(field_id);
    event = &lifecycle_events.back();
  } else {
    event = &*event_it;
  }

  // Snapshot the clocks before capturing the timestamp for the event so we can
  // use this snapshot to resolve the event timestamp if necessary.
  if (snapshot_clocks)
    MaybeSnapshotClocksIntoRingBuffer(tracing_session);

  // Erase before emplacing to prevent a unncessary doubling of memory if
  // not needed.
  if (event->timestamps.size() >= event->max_size) {
    event->timestamps.erase_front(1 + event->timestamps.size() -
                                  event->max_size);
  }
  event->timestamps.emplace_back(base::GetBootTimeNs().count());
}

void TracingServiceImpl::MaybeSnapshotClocksIntoRingBuffer(
    TracingSession* tracing_session) {
  if (tracing_session->config.builtin_data_sources()
          .disable_clock_snapshotting()) {
    return;
  }

  // We are making an explicit copy of the latest snapshot (if it exists)
  // because SnapshotClocks reads this data and computes the drift based on its
  // content. If the clock drift is high enough, it will update the contents of
  // |snapshot| and return true. Otherwise, it will return false.
  TracingSession::ClockSnapshotData snapshot =
      tracing_session->clock_snapshot_ring_buffer.empty()
          ? TracingSession::ClockSnapshotData()
          : tracing_session->clock_snapshot_ring_buffer.back();
  bool did_update = SnapshotClocks(&snapshot);
  if (did_update) {
    // This means clocks drifted enough since last snapshot. See the comment
    // in SnapshotClocks.
    auto* snapshot_buffer = &tracing_session->clock_snapshot_ring_buffer;

    // Erase before emplacing to prevent a unncessary doubling of memory if
    // not needed.
    static constexpr uint32_t kClockSnapshotRingBufferSize = 16;
    if (snapshot_buffer->size() >= kClockSnapshotRingBufferSize) {
      snapshot_buffer->erase_front(1 + snapshot_buffer->size() -
                                   kClockSnapshotRingBufferSize);
    }
    snapshot_buffer->emplace_back(std::move(snapshot));
  }
}

// Returns true when the data in |snapshot_data| is updated with the new state
// of the clocks and false otherwise.
bool TracingServiceImpl::SnapshotClocks(
    TracingSession::ClockSnapshotData* snapshot_data) {
  // Minimum drift that justifies replacing a prior clock snapshot that hasn't
  // been emitted into the trace yet (see comment below).
  static constexpr int64_t kSignificantDriftNs = 10 * 1000 * 1000;  // 10 ms

  TracingSession::ClockSnapshotData new_snapshot_data = CaptureClockSnapshots();
  // If we're about to update a session's latest clock snapshot that hasn't been
  // emitted into the trace yet, check whether the clocks have drifted enough to
  // warrant overriding the current snapshot values. The older snapshot would be
  // valid for a larger part of the currently buffered trace data because the
  // clock sync protocol in trace processor uses the latest clock <= timestamp
  // to translate times (see https://perfetto.dev/docs/concepts/clock-sync), so
  // we try to keep it if we can.
  if (!snapshot_data->empty()) {
    PERFETTO_DCHECK(snapshot_data->size() == new_snapshot_data.size());
    PERFETTO_DCHECK((*snapshot_data)[0].clock_id ==
                    protos::gen::BUILTIN_CLOCK_BOOTTIME);

    bool update_snapshot = false;
    uint64_t old_boot_ns = (*snapshot_data)[0].timestamp;
    uint64_t new_boot_ns = new_snapshot_data[0].timestamp;
    int64_t boot_diff =
        static_cast<int64_t>(new_boot_ns) - static_cast<int64_t>(old_boot_ns);

    for (size_t i = 1; i < snapshot_data->size(); i++) {
      uint64_t old_ns = (*snapshot_data)[i].timestamp;
      uint64_t new_ns = new_snapshot_data[i].timestamp;

      int64_t diff =
          static_cast<int64_t>(new_ns) - static_cast<int64_t>(old_ns);

      // Compare the boottime delta against the delta of this clock.
      if (std::abs(boot_diff - diff) >= kSignificantDriftNs) {
        update_snapshot = true;
        break;
      }
    }
    if (!update_snapshot)
      return false;
    snapshot_data->clear();
  }

  *snapshot_data = std::move(new_snapshot_data);
  return true;
}

void TracingServiceImpl::EmitClockSnapshot(
    TracingSession* tracing_session,
    TracingSession::ClockSnapshotData snapshot_data,
    std::vector<TracePacket>* packets) {
  PERFETTO_DCHECK(!tracing_session->config.builtin_data_sources()
                       .disable_clock_snapshotting());

  protozero::HeapBuffered<protos::pbzero::TracePacket> packet;
  auto* snapshot = packet->set_clock_snapshot();

  protos::gen::BuiltinClock trace_clock =
      tracing_session->config.builtin_data_sources().primary_trace_clock();
  if (!trace_clock)
    trace_clock = protos::gen::BUILTIN_CLOCK_BOOTTIME;
  snapshot->set_primary_trace_clock(
      static_cast<protos::pbzero::BuiltinClock>(trace_clock));

  for (auto& clock_id_and_ts : snapshot_data) {
    auto* c = snapshot->add_clocks();
    c->set_clock_id(clock_id_and_ts.clock_id);
    c->set_timestamp(clock_id_and_ts.timestamp);
  }

  packet->set_trusted_uid(static_cast<int32_t>(uid_));
  packet->set_trusted_packet_sequence_id(kServicePacketSequenceID);
  SerializeAndAppendPacket(packets, packet.SerializeAsArray());
}

void TracingServiceImpl::EmitSyncMarker(std::vector<TracePacket>* packets) {
  // The sync marks are used to tokenize large traces efficiently.
  // See description in trace_packet.proto.
  if (sync_marker_packet_size_ == 0) {
    // The marker ABI expects that the marker is written after the uid.
    // Protozero guarantees that fields are written in the same order of the
    // calls. The ResynchronizeTraceStreamUsingSyncMarker test verifies the ABI.
    protozero::StaticBuffered<protos::pbzero::TracePacket> packet(
        &sync_marker_packet_[0], sizeof(sync_marker_packet_));
    packet->set_trusted_uid(static_cast<int32_t>(uid_));
    packet->set_trusted_packet_sequence_id(kServicePacketSequenceID);

    // Keep this last.
    packet->set_synchronization_marker(kSyncMarker, sizeof(kSyncMarker));
    sync_marker_packet_size_ = packet.Finalize();
  }
  packets->emplace_back();
  packets->back().AddSlice(&sync_marker_packet_[0], sync_marker_packet_size_);
}

void TracingServiceImpl::EmitStats(TracingSession* tracing_session,
                                   std::vector<TracePacket>* packets) {
  protozero::HeapBuffered<protos::pbzero::TracePacket> packet;
  packet->set_trusted_uid(static_cast<int32_t>(uid_));
  packet->set_trusted_packet_sequence_id(kServicePacketSequenceID);
  GetTraceStats(tracing_session).Serialize(packet->set_trace_stats());
  SerializeAndAppendPacket(packets, packet.SerializeAsArray());
}

TraceStats TracingServiceImpl::GetTraceStats(TracingSession* tracing_session) {
  TraceStats trace_stats;
  trace_stats.set_producers_connected(static_cast<uint32_t>(producers_.size()));
  trace_stats.set_producers_seen(last_producer_id_);
  trace_stats.set_data_sources_registered(
      static_cast<uint32_t>(data_sources_.size()));
  trace_stats.set_data_sources_seen(last_data_source_instance_id_);
  trace_stats.set_tracing_sessions(
      static_cast<uint32_t>(tracing_sessions_.size()));
  trace_stats.set_total_buffers(static_cast<uint32_t>(buffers_.size()));
  trace_stats.set_chunks_discarded(chunks_discarded_);
  trace_stats.set_patches_discarded(patches_discarded_);
  trace_stats.set_invalid_packets(tracing_session->invalid_packets);
  trace_stats.set_flushes_requested(tracing_session->flushes_requested);
  trace_stats.set_flushes_succeeded(tracing_session->flushes_succeeded);
  trace_stats.set_flushes_failed(tracing_session->flushes_failed);
  trace_stats.set_final_flush_outcome(tracing_session->final_flush_outcome);

  if (tracing_session->trace_filter) {
    auto* filt_stats = trace_stats.mutable_filter_stats();
    filt_stats->set_input_packets(tracing_session->filter_input_packets);
    filt_stats->set_input_bytes(tracing_session->filter_input_bytes);
    filt_stats->set_output_bytes(tracing_session->filter_output_bytes);
    filt_stats->set_errors(tracing_session->filter_errors);
    filt_stats->set_time_taken_ns(tracing_session->filter_time_taken_ns);
    for (uint64_t value : tracing_session->filter_bytes_discarded_per_buffer)
      filt_stats->add_bytes_discarded_per_buffer(value);
  }

  for (BufferID buf_id : tracing_session->buffers_index) {
    TraceBuffer* buf = GetBufferByID(buf_id);
    if (!buf) {
      PERFETTO_DFATAL("Buffer not found.");
      continue;
    }
    *trace_stats.add_buffer_stats() = buf->stats();
  }  // for (buf in session).

  if (!tracing_session->config.builtin_data_sources()
           .disable_chunk_usage_histograms()) {
    // Emit chunk usage stats broken down by sequence ID (i.e. by trace-writer).
    // Writer stats are updated by each TraceBuffer object at ReadBuffers time,
    // and there can be >1 buffer per session. A trace writer never writes to
    // more than one buffer (it's technically allowed but doesn't happen in the
    // current impl of the tracing SDK).

    bool has_written_bucket_definition = false;
    uint32_t buf_idx = static_cast<uint32_t>(-1);
    for (const BufferID buf_id : tracing_session->buffers_index) {
      ++buf_idx;
      const TraceBuffer* buf = GetBufferByID(buf_id);
      if (!buf)
        continue;
      for (auto it = buf->writer_stats().GetIterator(); it; ++it) {
        const auto& hist = it.value().used_chunk_hist;
        ProducerID p;
        WriterID w;
        GetProducerAndWriterID(it.key(), &p, &w);
        if (!has_written_bucket_definition) {
          // Serialize one-off the histogram bucket definition, which is the
          // same for all entries in the map.
          has_written_bucket_definition = true;
          // The -1 in the loop below is to skip the implicit overflow bucket.
          for (size_t i = 0; i < hist.num_buckets() - 1; ++i) {
            trace_stats.add_chunk_payload_histogram_def(hist.GetBucketThres(i));
          }
        }  // if(!has_written_bucket_definition)
        auto* wri_stats = trace_stats.add_writer_stats();
        wri_stats->set_sequence_id(
            tracing_session->GetPacketSequenceID(kDefaultMachineID, p, w));
        wri_stats->set_buffer(buf_idx);
        for (size_t i = 0; i < hist.num_buckets(); ++i) {
          wri_stats->add_chunk_payload_histogram_counts(hist.GetBucketCount(i));
          wri_stats->add_chunk_payload_histogram_sum(hist.GetBucketSum(i));
        }
      }  // for each sequence (writer).
    }    // for each buffer.
  }      // if (!disable_chunk_usage_histograms)

  return trace_stats;
}

void TracingServiceImpl::EmitUuid(TracingSession* tracing_session,
                                  std::vector<TracePacket>* packets) {
  protozero::HeapBuffered<protos::pbzero::TracePacket> packet;
  packet->set_trusted_uid(static_cast<int32_t>(uid_));
  packet->set_trusted_packet_sequence_id(kServicePacketSequenceID);
  auto* uuid = packet->set_trace_uuid();
  uuid->set_lsb(tracing_session->trace_uuid.lsb());
  uuid->set_msb(tracing_session->trace_uuid.msb());
  SerializeAndAppendPacket(packets, packet.SerializeAsArray());
}

void TracingServiceImpl::MaybeEmitTraceConfig(
    TracingSession* tracing_session,
    std::vector<TracePacket>* packets) {
  if (tracing_session->did_emit_initial_packets)
    return;
  protozero::HeapBuffered<protos::pbzero::TracePacket> packet;
  packet->set_trusted_uid(static_cast<int32_t>(uid_));
  packet->set_trusted_packet_sequence_id(kServicePacketSequenceID);
  tracing_session->config.Serialize(packet->set_trace_config());
  SerializeAndAppendPacket(packets, packet.SerializeAsArray());
}

void TracingServiceImpl::EmitSystemInfo(std::vector<TracePacket>* packets) {
  protozero::HeapBuffered<protos::pbzero::TracePacket> packet;
  auto* info = packet->set_system_info();
  info->set_tracing_service_version(base::GetVersionString());

  std::optional<int32_t> tzoff = base::GetTimezoneOffsetMins();
  if (tzoff.has_value())
    info->set_timezone_off_mins(*tzoff);

#if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) && \
    !PERFETTO_BUILDFLAG(PERFETTO_OS_NACL)
  struct utsname uname_info;
  if (uname(&uname_info) == 0) {
    auto* utsname_info = info->set_utsname();
    utsname_info->set_sysname(uname_info.sysname);
    utsname_info->set_version(uname_info.version);
    utsname_info->set_machine(uname_info.machine);
    utsname_info->set_release(uname_info.release);
  }
  info->set_page_size(static_cast<uint32_t>(sysconf(_SC_PAGESIZE)));
  info->set_num_cpus(static_cast<uint32_t>(sysconf(_SC_NPROCESSORS_CONF)));
#endif  // !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
  std::string fingerprint_value = base::GetAndroidProp("ro.build.fingerprint");
  if (!fingerprint_value.empty()) {
    info->set_android_build_fingerprint(fingerprint_value);
  } else {
    PERFETTO_ELOG("Unable to read ro.build.fingerprint");
  }

  std::string sdk_str_value = base::GetAndroidProp("ro.build.version.sdk");
  std::optional<uint64_t> sdk_value = base::StringToUInt64(sdk_str_value);
  if (sdk_value.has_value()) {
    info->set_android_sdk_version(*sdk_value);
  } else {
    PERFETTO_ELOG("Unable to read ro.build.version.sdk");
  }
#endif  // PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
  packet->set_trusted_uid(static_cast<int32_t>(uid_));
  packet->set_trusted_packet_sequence_id(kServicePacketSequenceID);
  SerializeAndAppendPacket(packets, packet.SerializeAsArray());
}

void TracingServiceImpl::EmitLifecycleEvents(
    TracingSession* tracing_session,
    std::vector<TracePacket>* packets) {
  using TimestampedPacket =
      std::pair<int64_t /* ts */, std::vector<uint8_t> /* serialized packet */>;

  std::vector<TimestampedPacket> timestamped_packets;
  for (auto& event : tracing_session->lifecycle_events) {
    for (int64_t ts : event.timestamps) {
      protozero::HeapBuffered<protos::pbzero::TracePacket> packet;
      packet->set_timestamp(static_cast<uint64_t>(ts));
      packet->set_trusted_uid(static_cast<int32_t>(uid_));
      packet->set_trusted_packet_sequence_id(kServicePacketSequenceID);

      auto* service_event = packet->set_service_event();
      service_event->AppendVarInt(event.field_id, 1);
      timestamped_packets.emplace_back(ts, packet.SerializeAsArray());
    }
    event.timestamps.clear();
  }

  // We sort by timestamp here to ensure that the "sequence" of lifecycle
  // packets has monotonic timestamps like other sequences in the trace.
  // Note that these events could still be out of order with respect to other
  // events on the service packet sequence (e.g. trigger received packets).
  std::sort(timestamped_packets.begin(), timestamped_packets.end(),
            [](const TimestampedPacket& a, const TimestampedPacket& b) {
              return a.first < b.first;
            });

  for (auto& pair : timestamped_packets)
    SerializeAndAppendPacket(packets, std::move(pair.second));
}

void TracingServiceImpl::MaybeEmitRemoteClockSync(
    TracingSession* tracing_session,
    std::vector<TracePacket>* packets) {
  if (tracing_session->did_emit_remote_clock_sync_)
    return;

  std::unordered_set<MachineID> did_emit_machines;
  for (const auto& id_and_relay_client : relay_clients_) {
    const auto& relay_client = id_and_relay_client.second;
    auto machine_id = relay_client->machine_id();
    if (did_emit_machines.find(machine_id) != did_emit_machines.end())
      continue;  // Already emitted for the machine (e.g. multiple clients).

    auto& sync_clock_snapshots = relay_client->synced_clocks();
    if (sync_clock_snapshots.empty()) {
      PERFETTO_DLOG("Clock not synchronized for machine ID = %" PRIu32,
                    machine_id);
      continue;
    }

    // Don't emit twice for the same machine.
    did_emit_machines.insert(machine_id);

    protozero::HeapBuffered<protos::pbzero::TracePacket> sync_packet;
    sync_packet->set_machine_id(machine_id);
    sync_packet->set_trusted_uid(static_cast<int32_t>(uid_));
    auto* remote_clock_sync = sync_packet->set_remote_clock_sync();
    for (const auto& sync_exchange : relay_client->synced_clocks()) {
      auto* sync_exchange_msg = remote_clock_sync->add_synced_clocks();

      auto* client_snapshots = sync_exchange_msg->set_client_clocks();
      for (const auto& client_clock : sync_exchange.client_clocks) {
        auto* clock = client_snapshots->add_clocks();
        clock->set_clock_id(client_clock.clock_id);
        clock->set_timestamp(client_clock.timestamp);
      }

      auto* host_snapshots = sync_exchange_msg->set_host_clocks();
      for (const auto& host_clock : sync_exchange.host_clocks) {
        auto* clock = host_snapshots->add_clocks();
        clock->set_clock_id(host_clock.clock_id);
        clock->set_timestamp(host_clock.timestamp);
      }
    }

    SerializeAndAppendPacket(packets, sync_packet.SerializeAsArray());
  }

  tracing_session->did_emit_remote_clock_sync_ = true;
}

void TracingServiceImpl::MaybeEmitReceivedTriggers(
    TracingSession* tracing_session,
    std::vector<TracePacket>* packets) {
  PERFETTO_DCHECK(tracing_session->num_triggers_emitted_into_trace <=
                  tracing_session->received_triggers.size());
  for (size_t i = tracing_session->num_triggers_emitted_into_trace;
       i < tracing_session->received_triggers.size(); ++i) {
    const auto& info = tracing_session->received_triggers[i];
    protozero::HeapBuffered<protos::pbzero::TracePacket> packet;
    auto* trigger = packet->set_trigger();
    trigger->set_trigger_name(info.trigger_name);
    trigger->set_producer_name(info.producer_name);
    trigger->set_trusted_producer_uid(static_cast<int32_t>(info.producer_uid));

    packet->set_timestamp(info.boot_time_ns);
    packet->set_trusted_uid(static_cast<int32_t>(uid_));
    packet->set_trusted_packet_sequence_id(kServicePacketSequenceID);
    SerializeAndAppendPacket(packets, packet.SerializeAsArray());
    ++tracing_session->num_triggers_emitted_into_trace;
  }
}

void TracingServiceImpl::MaybeLogUploadEvent(const TraceConfig& cfg,
                                             const base::Uuid& uuid,
                                             PerfettoStatsdAtom atom,
                                             const std::string& trigger_name) {
  if (!ShouldLogEvent(cfg))
    return;

  PERFETTO_DCHECK(uuid);  // The UUID must be set at this point.
  android_stats::MaybeLogUploadEvent(atom, uuid.lsb(), uuid.msb(),
                                     trigger_name);
}

void TracingServiceImpl::MaybeLogTriggerEvent(const TraceConfig& cfg,
                                              PerfettoTriggerAtom atom,
                                              const std::string& trigger_name) {
  if (!ShouldLogEvent(cfg))
    return;
  android_stats::MaybeLogTriggerEvent(atom, trigger_name);
}

size_t TracingServiceImpl::PurgeExpiredAndCountTriggerInWindow(
    int64_t now_ns,
    uint64_t trigger_name_hash) {
  PERFETTO_DCHECK(
      std::is_sorted(trigger_history_.begin(), trigger_history_.end()));
  size_t remove_count = 0;
  size_t trigger_count = 0;
  for (const TriggerHistory& h : trigger_history_) {
    if (h.timestamp_ns < now_ns - trigger_window_ns_) {
      remove_count++;
    } else if (h.name_hash == trigger_name_hash) {
      trigger_count++;
    }
  }
  trigger_history_.erase_front(remove_count);
  return trigger_count;
}

void TracingServiceImpl::FlushAndCloneSession(ConsumerEndpointImpl* consumer,
                                              TracingSessionID tsid,
                                              bool skip_trace_filter,
                                              bool for_bugreport) {
  PERFETTO_DCHECK_THREAD(thread_checker_);
  auto clone_target = FlushFlags::CloneTarget::kUnknown;

  if (tsid == kBugreportSessionId) {
    // This branch is only here to support the legacy protocol where we could
    // clone only a single session using the magic ID kBugreportSessionId.
    // The newer perfetto --clone-all-for-bugreport first queries the existing
    // sessions and then issues individual clone requests specifying real
    // session IDs, setting args.{for_bugreport,skip_trace_filter}=true.
    PERFETTO_LOG("Looking for sessions for bugreport");
    TracingSession* session = FindTracingSessionWithMaxBugreportScore();
    if (!session) {
      consumer->consumer_->OnSessionCloned(
          {false, "No tracing sessions eligible for bugreport found", {}});
      return;
    }
    tsid = session->id;
    clone_target = FlushFlags::CloneTarget::kBugreport;
    skip_trace_filter = true;
    for_bugreport = true;
  } else if (for_bugreport) {
    clone_target = FlushFlags::CloneTarget::kBugreport;
  }

  TracingSession* session = GetTracingSession(tsid);
  if (!session) {
    consumer->consumer_->OnSessionCloned(
        {false, "Tracing session not found", {}});
    return;
  }

  // If any of the buffers are marked as clear_before_clone, reset them before
  // issuing the Flush(kCloneReason).
  size_t buf_idx = 0;
  for (BufferID src_buf_id : session->buffers_index) {
    if (!session->config.buffers()[buf_idx++].clear_before_clone())
      continue;
    auto buf_iter = buffers_.find(src_buf_id);
    PERFETTO_CHECK(buf_iter != buffers_.end());
    std::unique_ptr<TraceBuffer>& buf = buf_iter->second;

    // No need to reset the buffer if nothing has been written into it yet.
    // This is the canonical case if producers behive nicely and don't timeout
    // the handling of writes during the flush.
    // This check avoids a useless re-mmap upon every Clone() if the buffer is
    // already empty (when used in combination with `transfer_on_clone`).
    if (!buf->has_data())
      continue;

    // Some leftover data was left in the buffer. Recreate it to empty it.
    const auto buf_policy = buf->overwrite_policy();
    const auto buf_size = buf->size();
    std::unique_ptr<TraceBuffer> old_buf = std::move(buf);
    buf = TraceBuffer::Create(buf_size, buf_policy);
    if (!buf) {
      // This is extremely rare but could happen on 32-bit. If the new buffer
      // allocation failed, put back the buffer where it was and fail the clone.
      // We cannot leave the original tracing session buffer-less as it would
      // cause crashes when data sources commit new data.
      buf = std::move(old_buf);
      consumer->consumer_->OnSessionCloned(
          {false, "Buffer allocation failed while attempting to clone", {}});
      return;
    }
  }

  auto weak_this = weak_ptr_factory_.GetWeakPtr();
  auto weak_consumer = consumer->GetWeakPtr();

  const PendingCloneID clone_id = session->last_pending_clone_id_++;

  auto& clone_op = session->pending_clones[clone_id];
  clone_op.pending_flush_cnt = 0;
  clone_op.buffers =
      std::vector<std::unique_ptr<TraceBuffer>>(session->buffers_index.size());
  clone_op.weak_consumer = weak_consumer;
  clone_op.skip_trace_filter = skip_trace_filter;

  // Issue separate flush requests for separate buffer groups. The buffer marked
  // as transfer_on_clone will be flushed and cloned separately: even if they're
  // slower (like in the case of Winscope tracing), they will not delay the
  // snapshot of the other buffers.
  //
  // In the future we might want to split the buffer into more groups and maybe
  // allow this to be configurable.
  std::array<std::set<BufferID>, 2> bufs_groups;
  for (size_t i = 0; i < session->buffers_index.size(); i++) {
    if (session->config.buffers()[i].transfer_on_clone()) {
      bufs_groups[0].insert(session->buffers_index[i]);
    } else {
      bufs_groups[1].insert(session->buffers_index[i]);
    }
  }

  clone_op.pending_flush_cnt = bufs_groups.size();
  for (const std::set<BufferID>& buf_group : bufs_groups) {
    FlushDataSourceInstances(
        session, 0,
        GetFlushableDataSourceInstancesForBuffers(session, buf_group),
        [tsid, clone_id, buf_group, weak_this](bool final_flush) {
          if (!weak_this)
            return;
          weak_this->OnFlushDoneForClone(tsid, clone_id, buf_group,
                                         final_flush);
        },
        FlushFlags(FlushFlags::Initiator::kTraced,
                   FlushFlags::Reason::kTraceClone, clone_target));
  }
}

std::map<ProducerID, std::vector<DataSourceInstanceID>>
TracingServiceImpl::GetFlushableDataSourceInstancesForBuffers(
    TracingSession* session,
    const std::set<BufferID>& bufs) {
  std::map<ProducerID, std::vector<DataSourceInstanceID>> data_source_instances;

  for (const auto& [producer_id, ds_inst] : session->data_source_instances) {
    // TODO(ddiproietto): Consider if we should skip instances if ds_inst.state
    // != DataSourceInstance::STARTED
    if (ds_inst.no_flush) {
      continue;
    }
    if (!bufs.count(static_cast<BufferID>(ds_inst.config.target_buffer()))) {
      continue;
    }
    data_source_instances[producer_id].push_back(ds_inst.instance_id);
  }

  return data_source_instances;
}

void TracingServiceImpl::OnFlushDoneForClone(TracingSessionID tsid,
                                             PendingCloneID clone_id,
                                             const std::set<BufferID>& buf_ids,
                                             bool final_flush_outcome) {
  TracingSession* src = GetTracingSession(tsid);
  // The session might be gone by the time we try to clone it.
  if (!src) {
    return;
  }

  auto it = src->pending_clones.find(clone_id);
  if (it == src->pending_clones.end()) {
    return;
  }
  auto& clone_op = it->second;

  if (final_flush_outcome == false) {
    clone_op.flush_failed = true;
  }

  base::Status result;
  base::Uuid uuid;

  // First clone the flushed TraceBuffer(s). This can fail because of ENOMEM. If
  // it happens bail out early before creating any session.
  if (!DoCloneBuffers(src, buf_ids, &clone_op.buffers)) {
    result = PERFETTO_SVC_ERR("Buffer allocation failed");
  }

  if (result.ok()) {
    UpdateMemoryGuardrail();

    if (--clone_op.pending_flush_cnt != 0) {
      // Wait for more pending flushes.
      return;
    }

    PERFETTO_LOG("FlushAndCloneSession(%" PRIu64 ") started, success=%d", tsid,
                 final_flush_outcome);

    if (clone_op.weak_consumer) {
      result = FinishCloneSession(
          &*clone_op.weak_consumer, tsid, std::move(clone_op.buffers),
          clone_op.skip_trace_filter, !clone_op.flush_failed, &uuid);
    }
  }  // if (result.ok())

  if (clone_op.weak_consumer) {
    clone_op.weak_consumer->consumer_->OnSessionCloned(
        {result.ok(), result.message(), uuid});
  }

  src->pending_clones.erase(it);
  UpdateMemoryGuardrail();
}

bool TracingServiceImpl::DoCloneBuffers(
    TracingSession* src,
    const std::set<BufferID>& buf_ids,
    std::vector<std::unique_ptr<TraceBuffer>>* buf_snaps) {
  PERFETTO_DCHECK(src->num_buffers() == src->config.buffers().size());
  buf_snaps->resize(src->buffers_index.size());

  for (size_t buf_idx = 0; buf_idx < src->buffers_index.size(); buf_idx++) {
    BufferID src_buf_id = src->buffers_index[buf_idx];
    if (buf_ids.count(src_buf_id) == 0)
      continue;
    auto buf_iter = buffers_.find(src_buf_id);
    PERFETTO_CHECK(buf_iter != buffers_.end());
    std::unique_ptr<TraceBuffer>& src_buf = buf_iter->second;
    std::unique_ptr<TraceBuffer> new_buf;
    if (src->config.buffers()[buf_idx].transfer_on_clone()) {
      const auto buf_policy = src_buf->overwrite_policy();
      const auto buf_size = src_buf->size();
      new_buf = std::move(src_buf);
      src_buf = TraceBuffer::Create(buf_size, buf_policy);
      if (!src_buf) {
        // If the allocation fails put the buffer back and let the code below
        // handle the failure gracefully.
        src_buf = std::move(new_buf);
      }
    } else {
      new_buf = src_buf->CloneReadOnly();
    }
    if (!new_buf.get()) {
      return false;
    }
    (*buf_snaps)[buf_idx] = std::move(new_buf);
  }
  return true;
}

base::Status TracingServiceImpl::FinishCloneSession(
    ConsumerEndpointImpl* consumer,
    TracingSessionID src_tsid,
    std::vector<std::unique_ptr<TraceBuffer>> buf_snaps,
    bool skip_trace_filter,
    bool final_flush_outcome,
    base::Uuid* new_uuid) {
  PERFETTO_DLOG("CloneSession(%" PRIu64
                ", skip_trace_filter=%d) started, consumer uid: %d",
                src_tsid, skip_trace_filter, static_cast<int>(consumer->uid_));

  TracingSession* src = GetTracingSession(src_tsid);

  // The session might be gone by the time we try to clone it.
  if (!src)
    return PERFETTO_SVC_ERR("session not found");

  if (consumer->tracing_session_id_) {
    return PERFETTO_SVC_ERR(
        "The consumer is already attached to another tracing session");
  }

  // Skip the UID check for sessions marked with a bugreport_score > 0.
  // Those sessions, by design, can be stolen by any other consumer for the
  // sake of creating snapshots for bugreports.
  if (!src->IsCloneAllowed(consumer->uid_)) {
    return PERFETTO_SVC_ERR("Not allowed to clone a session from another UID");
  }

  std::vector<BufferID> buf_ids =
      buffer_ids_.AllocateMultiple(buf_snaps.size());
  if (buf_ids.size() != buf_snaps.size()) {
    return PERFETTO_SVC_ERR("Buffer id allocation failed");
  }

  PERFETTO_CHECK(std::none_of(
      buf_snaps.begin(), buf_snaps.end(),
      [](const std::unique_ptr<TraceBuffer>& buf) { return buf == nullptr; }));

  const TracingSessionID tsid = ++last_tracing_session_id_;
  TracingSession* cloned_session =
      &tracing_sessions_
           .emplace(
               std::piecewise_construct, std::forward_as_tuple(tsid),
               std::forward_as_tuple(tsid, consumer, src->config, task_runner_))
           .first->second;

  // Generate a new UUID for the cloned session, but preserve the LSB. In some
  // contexts the LSB is used to tie the trace back to the statsd subscription
  // that triggered it. See the corresponding code in perfetto_cmd.cc which
  // reads at triggering_subscription_id().
  const int64_t orig_uuid_lsb = src->trace_uuid.lsb();
  cloned_session->state = TracingSession::CLONED_READ_ONLY;
  cloned_session->trace_uuid = base::Uuidv4();
  cloned_session->trace_uuid.set_lsb(orig_uuid_lsb);
  *new_uuid = cloned_session->trace_uuid;

  for (size_t i = 0; i < buf_snaps.size(); i++) {
    BufferID buf_global_id = buf_ids[i];
    std::unique_ptr<TraceBuffer>& buf = buf_snaps[i];
    // This is only needed for transfer_on_clone. Other buffers are already
    // marked as read-only by CloneReadOnly(). We cannot do this early because
    // in case of an allocation failure we will put std::move() the original
    // buffer back in its place and in that case should not be made read-only.
    buf->set_read_only();
    buffers_.emplace(buf_global_id, std::move(buf));
    cloned_session->buffers_index.emplace_back(buf_global_id);
  }
  UpdateMemoryGuardrail();

  // Copy over relevant state that we want to persist in the cloned session.
  // Mostly stats and metadata that is emitted in the trace file by the service.
  // Also clear the received trigger list in the main tracing session. A
  // CLONE_SNAPSHOT session can go in ring buffer mode for several hours and get
  // snapshotted several times. This causes two issues with `received_triggers`:
  // 1. Adding noise in the cloned trace emitting triggers that happened too
  //    far back (see b/290799105).
  // 2. Bloating memory (see b/290798988).
  cloned_session->should_emit_stats = true;
  cloned_session->received_triggers = std::move(src->received_triggers);
  src->received_triggers.clear();
  src->num_triggers_emitted_into_trace = 0;
  cloned_session->lifecycle_events =
      std::vector<TracingSession::LifecycleEvent>(src->lifecycle_events);
  cloned_session->initial_clock_snapshot = src->initial_clock_snapshot;
  cloned_session->clock_snapshot_ring_buffer = src->clock_snapshot_ring_buffer;
  cloned_session->invalid_packets = src->invalid_packets;
  cloned_session->flushes_requested = src->flushes_requested;
  cloned_session->flushes_succeeded = src->flushes_succeeded;
  cloned_session->flushes_failed = src->flushes_failed;
  cloned_session->compress_deflate = src->compress_deflate;
  if (src->trace_filter && !skip_trace_filter) {
    // Copy the trace filter, unless it's a clone-for-bugreport (b/317065412).
    cloned_session->trace_filter.reset(
        new protozero::MessageFilter(src->trace_filter->config()));
  }

  SnapshotLifecyleEvent(
      cloned_session,
      protos::pbzero::TracingServiceEvent::kTracingDisabledFieldNumber,
      true /* snapshot_clocks */);

  PERFETTO_DLOG("Consumer (uid:%d) cloned tracing session %" PRIu64
                " -> %" PRIu64,
                static_cast<int>(consumer->uid_), src_tsid, tsid);

  consumer->tracing_session_id_ = tsid;
  cloned_session->final_flush_outcome = final_flush_outcome
                                            ? TraceStats::FINAL_FLUSH_SUCCEEDED
                                            : TraceStats::FINAL_FLUSH_FAILED;
  return base::OkStatus();
}

bool TracingServiceImpl::TracingSession::IsCloneAllowed(uid_t clone_uid) const {
  if (clone_uid == 0)
    return true;  // Root is always allowed to clone everything.
  if (clone_uid == this->consumer_uid)
    return true;  // Allow cloning if the uids match.
#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
  // On Android allow shell to clone sessions marked as exported for bugreport.
  // Dumpstate (invoked by adb bugreport) invokes commands as shell.
  if (clone_uid == AID_SHELL && this->config.bugreport_score() > 0)
    return true;
#endif
  return false;
}

////////////////////////////////////////////////////////////////////////////////
// TracingServiceImpl::ConsumerEndpointImpl implementation
////////////////////////////////////////////////////////////////////////////////

TracingServiceImpl::ConsumerEndpointImpl::ConsumerEndpointImpl(
    TracingServiceImpl* service,
    base::TaskRunner* task_runner,
    Consumer* consumer,
    uid_t uid)
    : task_runner_(task_runner),
      service_(service),
      consumer_(consumer),
      uid_(uid),
      weak_ptr_factory_(this) {}

TracingServiceImpl::ConsumerEndpointImpl::~ConsumerEndpointImpl() {
  service_->DisconnectConsumer(this);
  consumer_->OnDisconnect();
}

void TracingServiceImpl::ConsumerEndpointImpl::NotifyOnTracingDisabled(
    const std::string& error) {
  PERFETTO_DCHECK_THREAD(thread_checker_);
  auto weak_this = weak_ptr_factory_.GetWeakPtr();
  task_runner_->PostTask([weak_this, error /* deliberate copy */] {
    if (weak_this)
      weak_this->consumer_->OnTracingDisabled(error);
  });
}

void TracingServiceImpl::ConsumerEndpointImpl::EnableTracing(
    const TraceConfig& cfg,
    base::ScopedFile fd) {
  PERFETTO_DCHECK_THREAD(thread_checker_);
  auto status = service_->EnableTracing(this, cfg, std::move(fd));
  if (!status.ok())
    NotifyOnTracingDisabled(status.message());
}

void TracingServiceImpl::ConsumerEndpointImpl::ChangeTraceConfig(
    const TraceConfig& cfg) {
  if (!tracing_session_id_) {
    PERFETTO_LOG(
        "Consumer called ChangeTraceConfig() but tracing was "
        "not active");
    return;
  }
  service_->ChangeTraceConfig(this, cfg);
}

void TracingServiceImpl::ConsumerEndpointImpl::StartTracing() {
  PERFETTO_DCHECK_THREAD(thread_checker_);
  if (!tracing_session_id_) {
    PERFETTO_LOG("Consumer called StartTracing() but tracing was not active");
    return;
  }
  service_->StartTracing(tracing_session_id_);
}

void TracingServiceImpl::ConsumerEndpointImpl::DisableTracing() {
  PERFETTO_DCHECK_THREAD(thread_checker_);
  if (!tracing_session_id_) {
    PERFETTO_LOG("Consumer called DisableTracing() but tracing was not active");
    return;
  }
  service_->DisableTracing(tracing_session_id_);
}

void TracingServiceImpl::ConsumerEndpointImpl::ReadBuffers() {
  PERFETTO_DCHECK_THREAD(thread_checker_);
  if (!tracing_session_id_) {
    PERFETTO_LOG("Consumer called ReadBuffers() but tracing was not active");
    consumer_->OnTraceData({}, /* has_more = */ false);
    return;
  }
  if (!service_->ReadBuffersIntoConsumer(tracing_session_id_, this)) {
    consumer_->OnTraceData({}, /* has_more = */ false);
  }
}

void TracingServiceImpl::ConsumerEndpointImpl::FreeBuffers() {
  PERFETTO_DCHECK_THREAD(thread_checker_);
  if (!tracing_session_id_) {
    PERFETTO_LOG("Consumer called FreeBuffers() but tracing was not active");
    return;
  }
  service_->FreeBuffers(tracing_session_id_);
  tracing_session_id_ = 0;
}

void TracingServiceImpl::ConsumerEndpointImpl::Flush(uint32_t timeout_ms,
                                                     FlushCallback callback,
                                                     FlushFlags flush_flags) {
  PERFETTO_DCHECK_THREAD(thread_checker_);
  if (!tracing_session_id_) {
    PERFETTO_LOG("Consumer called Flush() but tracing was not active");
    return;
  }
  service_->Flush(tracing_session_id_, timeout_ms, callback, flush_flags);
}

void TracingServiceImpl::ConsumerEndpointImpl::Detach(const std::string& key) {
  PERFETTO_DCHECK_THREAD(thread_checker_);
  bool success = service_->DetachConsumer(this, key);
  auto weak_this = weak_ptr_factory_.GetWeakPtr();
  task_runner_->PostTask([weak_this, success] {
    if (weak_this)
      weak_this->consumer_->OnDetach(success);
  });
}

void TracingServiceImpl::ConsumerEndpointImpl::Attach(const std::string& key) {
  PERFETTO_DCHECK_THREAD(thread_checker_);
  bool success = service_->AttachConsumer(this, key);
  auto weak_this = weak_ptr_factory_.GetWeakPtr();
  task_runner_->PostTask([weak_this, success] {
    if (!weak_this)
      return;
    Consumer* consumer = weak_this->consumer_;
    TracingSession* session =
        weak_this->service_->GetTracingSession(weak_this->tracing_session_id_);
    if (!session) {
      consumer->OnAttach(false, TraceConfig());
      return;
    }
    consumer->OnAttach(success, session->config);
  });
}

void TracingServiceImpl::ConsumerEndpointImpl::GetTraceStats() {
  PERFETTO_DCHECK_THREAD(thread_checker_);
  bool success = false;
  TraceStats stats;
  TracingSession* session = service_->GetTracingSession(tracing_session_id_);
  if (session) {
    success = true;
    stats = service_->GetTraceStats(session);
  }
  auto weak_this = weak_ptr_factory_.GetWeakPtr();
  task_runner_->PostTask([weak_this, success, stats] {
    if (weak_this)
      weak_this->consumer_->OnTraceStats(success, stats);
  });
}

void TracingServiceImpl::ConsumerEndpointImpl::ObserveEvents(
    uint32_t events_mask) {
  PERFETTO_DCHECK_THREAD(thread_checker_);
  observable_events_mask_ = events_mask;
  TracingSession* session = service_->GetTracingSession(tracing_session_id_);
  if (!session)
    return;

  if (observable_events_mask_ & ObservableEvents::TYPE_DATA_SOURCES_INSTANCES) {
    // Issue initial states.
    for (const auto& kv : session->data_source_instances) {
      ProducerEndpointImpl* producer = service_->GetProducer(kv.first);
      PERFETTO_DCHECK(producer);
      OnDataSourceInstanceStateChange(*producer, kv.second);
    }
  }

  // If the ObserveEvents() call happens after data sources have acked already
  // notify immediately.
  if (observable_events_mask_ &
      ObservableEvents::TYPE_ALL_DATA_SOURCES_STARTED) {
    service_->MaybeNotifyAllDataSourcesStarted(session);
  }
}

void TracingServiceImpl::ConsumerEndpointImpl::OnDataSourceInstanceStateChange(
    const ProducerEndpointImpl& producer,
    const DataSourceInstance& instance) {
  if (!(observable_events_mask_ &
        ObservableEvents::TYPE_DATA_SOURCES_INSTANCES)) {
    return;
  }

  if (instance.state != DataSourceInstance::CONFIGURED &&
      instance.state != DataSourceInstance::STARTED &&
      instance.state != DataSourceInstance::STOPPED) {
    return;
  }

  auto* observable_events = AddObservableEvents();
  auto* change = observable_events->add_instance_state_changes();
  change->set_producer_name(producer.name_);
  change->set_data_source_name(instance.data_source_name);
  if (instance.state == DataSourceInstance::STARTED) {
    change->set_state(ObservableEvents::DATA_SOURCE_INSTANCE_STATE_STARTED);
  } else {
    change->set_state(ObservableEvents::DATA_SOURCE_INSTANCE_STATE_STOPPED);
  }
}

void TracingServiceImpl::ConsumerEndpointImpl::OnAllDataSourcesStarted() {
  if (!(observable_events_mask_ &
        ObservableEvents::TYPE_ALL_DATA_SOURCES_STARTED)) {
    return;
  }
  auto* observable_events = AddObservableEvents();
  observable_events->set_all_data_sources_started(true);
}

void TracingServiceImpl::ConsumerEndpointImpl::NotifyCloneSnapshotTrigger() {
  if (!(observable_events_mask_ & ObservableEvents::TYPE_CLONE_TRIGGER_HIT)) {
    return;
  }
  auto* observable_events = AddObservableEvents();
  auto* clone_trig = observable_events->mutable_clone_trigger_hit();
  clone_trig->set_tracing_session_id(static_cast<int64_t>(tracing_session_id_));
}

ObservableEvents*
TracingServiceImpl::ConsumerEndpointImpl::AddObservableEvents() {
  PERFETTO_DCHECK_THREAD(thread_checker_);
  if (!observable_events_) {
    observable_events_.reset(new ObservableEvents());
    auto weak_this = weak_ptr_factory_.GetWeakPtr();
    task_runner_->PostTask([weak_this] {
      if (!weak_this)
        return;

      // Move into a temporary to allow reentrancy in OnObservableEvents.
      auto observable_events = std::move(weak_this->observable_events_);
      weak_this->consumer_->OnObservableEvents(*observable_events);
    });
  }
  return observable_events_.get();
}

void TracingServiceImpl::ConsumerEndpointImpl::QueryServiceState(
    QueryServiceStateArgs args,
    QueryServiceStateCallback callback) {
  PERFETTO_DCHECK_THREAD(thread_checker_);
  TracingServiceState svc_state;

  const auto& sessions = service_->tracing_sessions_;
  svc_state.set_tracing_service_version(base::GetVersionString());
  svc_state.set_num_sessions(static_cast<int>(sessions.size()));

  int num_started = 0;
  for (const auto& kv : sessions)
    num_started += kv.second.state == TracingSession::State::STARTED ? 1 : 0;
  svc_state.set_num_sessions_started(num_started);

  for (const auto& kv : service_->producers_) {
    if (args.sessions_only)
      break;
    auto* producer = svc_state.add_producers();
    producer->set_id(static_cast<int>(kv.first));
    producer->set_name(kv.second->name_);
    producer->set_sdk_version(kv.second->sdk_version_);
    producer->set_uid(static_cast<int32_t>(kv.second->uid()));
    producer->set_pid(static_cast<int32_t>(kv.second->pid()));
  }

  for (const auto& kv : service_->data_sources_) {
    if (args.sessions_only)
      break;
    const auto& registered_data_source = kv.second;
    auto* data_source = svc_state.add_data_sources();
    *data_source->mutable_ds_descriptor() = registered_data_source.descriptor;
    data_source->set_producer_id(
        static_cast<int>(registered_data_source.producer_id));
  }

  svc_state.set_supports_tracing_sessions(true);
  for (const auto& kv : service_->tracing_sessions_) {
    const TracingSession& s = kv.second;
    if (!s.IsCloneAllowed(uid_))
      continue;
    auto* session = svc_state.add_tracing_sessions();
    session->set_id(s.id);
    session->set_consumer_uid(static_cast<int>(s.consumer_uid));
    session->set_duration_ms(s.config.duration_ms());
    session->set_num_data_sources(
        static_cast<uint32_t>(s.data_source_instances.size()));
    session->set_unique_session_name(s.config.unique_session_name());
    if (s.config.has_bugreport_score())
      session->set_bugreport_score(s.config.bugreport_score());
    if (s.config.has_bugreport_filename())
      session->set_bugreport_filename(s.config.bugreport_filename());
    for (const auto& snap_kv : s.initial_clock_snapshot) {
      if (snap_kv.clock_id == protos::pbzero::BUILTIN_CLOCK_REALTIME)
        session->set_start_realtime_ns(static_cast<int64_t>(snap_kv.timestamp));
    }
    for (const auto& buf : s.config.buffers())
      session->add_buffer_size_kb(buf.size_kb());

    switch (s.state) {
      case TracingSession::State::DISABLED:
        session->set_state("DISABLED");
        break;
      case TracingSession::State::CONFIGURED:
        session->set_state("CONFIGURED");
        break;
      case TracingSession::State::STARTED:
        session->set_is_started(true);
        session->set_state("STARTED");
        break;
      case TracingSession::State::DISABLING_WAITING_STOP_ACKS:
        session->set_state("STOP_WAIT");
        break;
      case TracingSession::State::CLONED_READ_ONLY:
        session->set_state("CLONED_READ_ONLY");
        break;
    }
  }
  callback(/*success=*/true, svc_state);
}

void TracingServiceImpl::ConsumerEndpointImpl::QueryCapabilities(
    QueryCapabilitiesCallback callback) {
  PERFETTO_DCHECK_THREAD(thread_checker_);
  TracingServiceCapabilities caps;
  caps.set_has_query_capabilities(true);
  caps.set_has_trace_config_output_path(true);
  caps.set_has_clone_session(true);
  caps.add_observable_events(ObservableEvents::TYPE_DATA_SOURCES_INSTANCES);
  caps.add_observable_events(ObservableEvents::TYPE_ALL_DATA_SOURCES_STARTED);
  caps.add_observable_events(ObservableEvents::TYPE_CLONE_TRIGGER_HIT);
  static_assert(
      ObservableEvents::Type_MAX == ObservableEvents::TYPE_CLONE_TRIGGER_HIT,
      "");
  callback(caps);
}

void TracingServiceImpl::ConsumerEndpointImpl::SaveTraceForBugreport(
    SaveTraceForBugreportCallback consumer_callback) {
  consumer_callback(false,
                    "SaveTraceForBugreport is deprecated. Use "
                    "CloneSession(kBugreportSessionId) instead.");
}

void TracingServiceImpl::ConsumerEndpointImpl::CloneSession(
    TracingSessionID tsid,
    CloneSessionArgs args) {
  PERFETTO_DCHECK_THREAD(thread_checker_);
  // FlushAndCloneSession will call OnSessionCloned after the async flush.
  service_->FlushAndCloneSession(this, tsid, args.skip_trace_filter,
                                 args.for_bugreport);
}

////////////////////////////////////////////////////////////////////////////////
// TracingServiceImpl::ProducerEndpointImpl implementation
////////////////////////////////////////////////////////////////////////////////

TracingServiceImpl::ProducerEndpointImpl::ProducerEndpointImpl(
    ProducerID id,
    const ClientIdentity& client_identity,
    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)
    : id_(id),
      client_identity_(client_identity),
      service_(service),
      task_runner_(task_runner),
      producer_(producer),
      name_(producer_name),
      sdk_version_(sdk_version),
      in_process_(in_process),
      smb_scraping_enabled_(smb_scraping_enabled),
      weak_ptr_factory_(this) {}

TracingServiceImpl::ProducerEndpointImpl::~ProducerEndpointImpl() {
  service_->DisconnectProducer(id_);
  producer_->OnDisconnect();
}

void TracingServiceImpl::ProducerEndpointImpl::Disconnect() {
  PERFETTO_DCHECK_THREAD(thread_checker_);
  // Disconnection is only supported via destroying the ProducerEndpoint.
  PERFETTO_FATAL("Not supported");
}

void TracingServiceImpl::ProducerEndpointImpl::RegisterDataSource(
    const DataSourceDescriptor& desc) {
  PERFETTO_DCHECK_THREAD(thread_checker_);
  service_->RegisterDataSource(id_, desc);
}

void TracingServiceImpl::ProducerEndpointImpl::UpdateDataSource(
    const DataSourceDescriptor& desc) {
  PERFETTO_DCHECK_THREAD(thread_checker_);
  service_->UpdateDataSource(id_, desc);
}

void TracingServiceImpl::ProducerEndpointImpl::UnregisterDataSource(
    const std::string& name) {
  PERFETTO_DCHECK_THREAD(thread_checker_);
  service_->UnregisterDataSource(id_, name);
}

void TracingServiceImpl::ProducerEndpointImpl::RegisterTraceWriter(
    uint32_t writer_id,
    uint32_t target_buffer) {
  PERFETTO_DCHECK_THREAD(thread_checker_);
  writers_[static_cast<WriterID>(writer_id)] =
      static_cast<BufferID>(target_buffer);
}

void TracingServiceImpl::ProducerEndpointImpl::UnregisterTraceWriter(
    uint32_t writer_id) {
  PERFETTO_DCHECK_THREAD(thread_checker_);
  writers_.erase(static_cast<WriterID>(writer_id));
}

void TracingServiceImpl::ProducerEndpointImpl::CommitData(
    const CommitDataRequest& req_untrusted,
    CommitDataCallback callback) {
  PERFETTO_DCHECK_THREAD(thread_checker_);

  if (metatrace::IsEnabled(metatrace::TAG_TRACE_SERVICE)) {
    PERFETTO_METATRACE_COUNTER(TAG_TRACE_SERVICE, TRACE_SERVICE_COMMIT_DATA,
                               EncodeCommitDataRequest(id_, req_untrusted));
  }

  if (!shared_memory_) {
    PERFETTO_DLOG(
        "Attempted to commit data before the shared memory was allocated.");
    return;
  }
  PERFETTO_DCHECK(shmem_abi_.is_valid());
  for (const auto& entry : req_untrusted.chunks_to_move()) {
    const uint32_t page_idx = entry.page();
    if (page_idx >= shmem_abi_.num_pages())
      continue;  // A buggy or malicious producer.

    SharedMemoryABI::Chunk chunk;
    bool commit_data_over_ipc = entry.has_data();
    if (PERFETTO_UNLIKELY(commit_data_over_ipc)) {
      // Chunk data is passed over the wire. Create a chunk using the serialized
      // protobuf message.
      const std::string& data = entry.data();
      if (data.size() > SharedMemoryABI::Chunk::kMaxSize) {
        PERFETTO_DFATAL("IPC data commit too large: %zu", data.size());
        continue;  // A malicious or buggy producer
      }
      // |data| is not altered, but we need to const_cast becasue Chunk data
      // members are non-const.
      chunk = SharedMemoryABI::MakeChunkFromSerializedData(
          reinterpret_cast<uint8_t*>(const_cast<char*>(data.data())),
          static_cast<uint16_t>(entry.data().size()),
          static_cast<uint8_t>(entry.chunk()));
    } else
      chunk = shmem_abi_.TryAcquireChunkForReading(page_idx, entry.chunk());
    if (!chunk.is_valid()) {
      PERFETTO_DLOG("Asked to move chunk %d:%d, but it's not complete",
                    entry.page(), entry.chunk());
      continue;
    }

    // TryAcquireChunkForReading() has load-acquire semantics. Once acquired,
    // the ABI contract expects the producer to not touch the chunk anymore
    // (until the service marks that as free). This is why all the reads below
    // are just memory_order_relaxed. Also, the code here assumes that all this
    // data can be malicious and just gives up if anything is malformed.
    BufferID buffer_id = static_cast<BufferID>(entry.target_buffer());
    const SharedMemoryABI::ChunkHeader& chunk_header = *chunk.header();
    WriterID writer_id = chunk_header.writer_id.load(std::memory_order_relaxed);
    ChunkID chunk_id = chunk_header.chunk_id.load(std::memory_order_relaxed);
    auto packets = chunk_header.packets.load(std::memory_order_relaxed);
    uint16_t num_fragments = packets.count;
    uint8_t chunk_flags = packets.flags;

    service_->CopyProducerPageIntoLogBuffer(
        id_, client_identity_, writer_id, chunk_id, buffer_id, num_fragments,
        chunk_flags,
        /*chunk_complete=*/true, chunk.payload_begin(), chunk.payload_size());

    if (!commit_data_over_ipc) {
      // This one has release-store semantics.
      shmem_abi_.ReleaseChunkAsFree(std::move(chunk));
    }
  }  // for(chunks_to_move)

  service_->ApplyChunkPatches(id_, req_untrusted.chunks_to_patch());

  if (req_untrusted.flush_request_id()) {
    service_->NotifyFlushDoneForProducer(id_, req_untrusted.flush_request_id());
  }

  // Keep this invocation last. ProducerIPCService::CommitData() relies on this
  // callback being invoked within the same callstack and not posted. If this
  // changes, the code there needs to be changed accordingly.
  if (callback)
    callback();
}

void TracingServiceImpl::ProducerEndpointImpl::SetupSharedMemory(
    std::unique_ptr<SharedMemory> shared_memory,
    size_t page_size_bytes,
    bool provided_by_producer) {
  PERFETTO_DCHECK(!shared_memory_ && !shmem_abi_.is_valid());
  PERFETTO_DCHECK(page_size_bytes % 1024 == 0);

  shared_memory_ = std::move(shared_memory);
  shared_buffer_page_size_kb_ = page_size_bytes / 1024;
  is_shmem_provided_by_producer_ = provided_by_producer;

  shmem_abi_.Initialize(reinterpret_cast<uint8_t*>(shared_memory_->start()),
                        shared_memory_->size(),
                        shared_buffer_page_size_kb() * 1024,
                        SharedMemoryABI::ShmemMode::kDefault);
  if (in_process_) {
    inproc_shmem_arbiter_.reset(new SharedMemoryArbiterImpl(
        shared_memory_->start(), shared_memory_->size(),
        SharedMemoryABI::ShmemMode::kDefault,
        shared_buffer_page_size_kb_ * 1024, this, task_runner_));
    inproc_shmem_arbiter_->SetDirectSMBPatchingSupportedByService();
  }

  OnTracingSetup();
  service_->UpdateMemoryGuardrail();
}

SharedMemory* TracingServiceImpl::ProducerEndpointImpl::shared_memory() const {
  PERFETTO_DCHECK_THREAD(thread_checker_);
  return shared_memory_.get();
}

size_t TracingServiceImpl::ProducerEndpointImpl::shared_buffer_page_size_kb()
    const {
  return shared_buffer_page_size_kb_;
}

void TracingServiceImpl::ProducerEndpointImpl::ActivateTriggers(
    const std::vector<std::string>& triggers) {
  service_->ActivateTriggers(id_, triggers);
}

void TracingServiceImpl::ProducerEndpointImpl::StopDataSource(
    DataSourceInstanceID ds_inst_id) {
  // TODO(primiano): When we'll support tearing down the SMB, at this point we
  // should send the Producer a TearDownTracing if all its data sources have
  // been disabled (see b/77532839 and aosp/655179 PS1).
  PERFETTO_DCHECK_THREAD(thread_checker_);
  auto weak_this = weak_ptr_factory_.GetWeakPtr();
  task_runner_->PostTask([weak_this, ds_inst_id] {
    if (weak_this)
      weak_this->producer_->StopDataSource(ds_inst_id);
  });
}

SharedMemoryArbiter*
TracingServiceImpl::ProducerEndpointImpl::MaybeSharedMemoryArbiter() {
  if (!inproc_shmem_arbiter_) {
    PERFETTO_FATAL(
        "The in-process SharedMemoryArbiter can only be used when "
        "CreateProducer has been called with in_process=true and after tracing "
        "has started.");
  }

  PERFETTO_DCHECK(in_process_);
  return inproc_shmem_arbiter_.get();
}

bool TracingServiceImpl::ProducerEndpointImpl::IsShmemProvidedByProducer()
    const {
  return is_shmem_provided_by_producer_;
}

// Can be called on any thread.
std::unique_ptr<TraceWriter>
TracingServiceImpl::ProducerEndpointImpl::CreateTraceWriter(
    BufferID buf_id,
    BufferExhaustedPolicy buffer_exhausted_policy) {
  PERFETTO_DCHECK(MaybeSharedMemoryArbiter());
  return MaybeSharedMemoryArbiter()->CreateTraceWriter(buf_id,
                                                       buffer_exhausted_policy);
}

void TracingServiceImpl::ProducerEndpointImpl::NotifyFlushComplete(
    FlushRequestID id) {
  PERFETTO_DCHECK_THREAD(thread_checker_);
  PERFETTO_DCHECK(MaybeSharedMemoryArbiter());
  return MaybeSharedMemoryArbiter()->NotifyFlushComplete(id);
}

void TracingServiceImpl::ProducerEndpointImpl::OnTracingSetup() {
  auto weak_this = weak_ptr_factory_.GetWeakPtr();
  task_runner_->PostTask([weak_this] {
    if (weak_this)
      weak_this->producer_->OnTracingSetup();
  });
}

void TracingServiceImpl::ProducerEndpointImpl::Flush(
    FlushRequestID flush_request_id,
    const std::vector<DataSourceInstanceID>& data_sources,
    FlushFlags flush_flags) {
  PERFETTO_DCHECK_THREAD(thread_checker_);
  auto weak_this = weak_ptr_factory_.GetWeakPtr();
  task_runner_->PostTask(
      [weak_this, flush_request_id, data_sources, flush_flags] {
        if (weak_this) {
          weak_this->producer_->Flush(flush_request_id, data_sources.data(),
                                      data_sources.size(), flush_flags);
        }
      });
}

void TracingServiceImpl::ProducerEndpointImpl::SetupDataSource(
    DataSourceInstanceID ds_id,
    const DataSourceConfig& config) {
  PERFETTO_DCHECK_THREAD(thread_checker_);
  allowed_target_buffers_.insert(static_cast<BufferID>(config.target_buffer()));
  auto weak_this = weak_ptr_factory_.GetWeakPtr();
  task_runner_->PostTask([weak_this, ds_id, config] {
    if (weak_this)
      weak_this->producer_->SetupDataSource(ds_id, std::move(config));
  });
}

void TracingServiceImpl::ProducerEndpointImpl::StartDataSource(
    DataSourceInstanceID ds_id,
    const DataSourceConfig& config) {
  PERFETTO_DCHECK_THREAD(thread_checker_);
  auto weak_this = weak_ptr_factory_.GetWeakPtr();
  task_runner_->PostTask([weak_this, ds_id, config] {
    if (weak_this)
      weak_this->producer_->StartDataSource(ds_id, std::move(config));
  });
}

void TracingServiceImpl::ProducerEndpointImpl::NotifyDataSourceStarted(
    DataSourceInstanceID data_source_id) {
  PERFETTO_DCHECK_THREAD(thread_checker_);
  service_->NotifyDataSourceStarted(id_, data_source_id);
}

void TracingServiceImpl::ProducerEndpointImpl::NotifyDataSourceStopped(
    DataSourceInstanceID data_source_id) {
  PERFETTO_DCHECK_THREAD(thread_checker_);
  service_->NotifyDataSourceStopped(id_, data_source_id);
}

void TracingServiceImpl::ProducerEndpointImpl::OnFreeBuffers(
    const std::vector<BufferID>& target_buffers) {
  if (allowed_target_buffers_.empty())
    return;
  for (BufferID buffer : target_buffers)
    allowed_target_buffers_.erase(buffer);
}

void TracingServiceImpl::ProducerEndpointImpl::ClearIncrementalState(
    const std::vector<DataSourceInstanceID>& data_sources) {
  PERFETTO_DCHECK_THREAD(thread_checker_);
  auto weak_this = weak_ptr_factory_.GetWeakPtr();
  task_runner_->PostTask([weak_this, data_sources] {
    if (weak_this) {
      base::StringView producer_name(weak_this->name_);
      weak_this->producer_->ClearIncrementalState(data_sources.data(),
                                                  data_sources.size());
    }
  });
}

void TracingServiceImpl::ProducerEndpointImpl::Sync(
    std::function<void()> callback) {
  task_runner_->PostTask(callback);
}

////////////////////////////////////////////////////////////////////////////////
// TracingServiceImpl::TracingSession implementation
////////////////////////////////////////////////////////////////////////////////

TracingServiceImpl::TracingSession::TracingSession(
    TracingSessionID session_id,
    ConsumerEndpointImpl* consumer,
    const TraceConfig& new_config,
    base::TaskRunner* task_runner)
    : id(session_id),
      consumer_maybe_null(consumer),
      consumer_uid(consumer->uid_),
      config(new_config),
      snapshot_periodic_task(task_runner),
      timed_stop_task(task_runner) {
  // all_data_sources_flushed is special because we store up to 64 events of
  // this type. Other events will go through the default case in
  // SnapshotLifecycleEvent() where they will be given a max history of 1.
  lifecycle_events.emplace_back(
      protos::pbzero::TracingServiceEvent::kAllDataSourcesFlushedFieldNumber,
      64 /* max_size */);
}

////////////////////////////////////////////////////////////////////////////////
// TracingServiceImpl::RelayEndpointImpl implementation
////////////////////////////////////////////////////////////////////////////////
TracingServiceImpl::RelayEndpointImpl::RelayEndpointImpl(
    RelayClientID relay_client_id,
    TracingServiceImpl* service)
    : relay_client_id_(relay_client_id), service_(service) {}
TracingServiceImpl::RelayEndpointImpl::~RelayEndpointImpl() = default;

void TracingServiceImpl::RelayEndpointImpl::SyncClocks(
    SyncMode sync_mode,
    ClockSnapshotVector client_clocks,
    ClockSnapshotVector host_clocks) {
  // We keep only the most recent 5 clock sync snapshots.
  static constexpr size_t kNumSyncClocks = 5;
  if (synced_clocks_.size() >= kNumSyncClocks)
    synced_clocks_.pop_front();

  synced_clocks_.emplace_back(sync_mode, std::move(client_clocks),
                              std::move(host_clocks));
}

void TracingServiceImpl::RelayEndpointImpl::Disconnect() {
  service_->DisconnectRelayClient(relay_client_id_);
}

}  // namespace perfetto
// gen_amalgamated begin source: src/tracing/internal/in_process_tracing_backend.cc
/*
 * Copyright (C) 2019 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// gen_amalgamated expanded: #include "perfetto/tracing/internal/in_process_tracing_backend.h"

// gen_amalgamated expanded: #include "perfetto/base/logging.h"
// gen_amalgamated expanded: #include "perfetto/base/task_runner.h"
// gen_amalgamated expanded: #include "perfetto/ext/base/paged_memory.h"
// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/client_identity.h"
// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/shared_memory.h"
// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/tracing_service.h"

// gen_amalgamated expanded: #include "src/tracing/core/in_process_shared_memory.h"

// TODO(primiano): When the in-process backend is used, we should never end up
// in a situation where the thread where the TracingService and Producer live
// writes a packet and hence can get into the GetNewChunk() stall.
// This would happen only if the API client code calls Trace() from one of the
// callbacks it receives (e.g. OnStart(), OnStop()). We should either cause a
// hard crash or ignore traces from that thread if that happens, because it
// will deadlock (the Service will never free up the SMB because won't ever get
// to run the task).

namespace perfetto {
namespace internal {

// static
TracingBackend* InProcessTracingBackend::GetInstance() {
  static auto* instance = new InProcessTracingBackend();
  return instance;
}

InProcessTracingBackend::InProcessTracingBackend() = default;
InProcessTracingBackend::~InProcessTracingBackend() = default;

std::unique_ptr<ProducerEndpoint> InProcessTracingBackend::ConnectProducer(
    const ConnectProducerArgs& args) {
  PERFETTO_DCHECK(args.task_runner->RunsTasksOnCurrentThread());
  return GetOrCreateService(args.task_runner)
      ->ConnectProducer(args.producer, ClientIdentity(/*uid=*/0, /*pid=*/0),
                        args.producer_name, args.shmem_size_hint_bytes,
                        /*in_process=*/true,
                        TracingService::ProducerSMBScrapingMode::kEnabled,
                        args.shmem_page_size_hint_bytes);
}

std::unique_ptr<ConsumerEndpoint> InProcessTracingBackend::ConnectConsumer(
    const ConnectConsumerArgs& args) {
  return GetOrCreateService(args.task_runner)
      ->ConnectConsumer(args.consumer, /*uid=*/0);
}

TracingService* InProcessTracingBackend::GetOrCreateService(
    base::TaskRunner* task_runner) {
  if (!service_) {
    std::unique_ptr<InProcessSharedMemory::Factory> shm(
        new InProcessSharedMemory::Factory());
    service_ = TracingService::CreateInstance(std::move(shm), task_runner);
    service_->SetSMBScrapingEnabled(true);
  }
  return service_.get();
}

}  // namespace internal
}  // namespace perfetto
// gen_amalgamated begin source: gen/protos/perfetto/ipc/consumer_port.gen.cc
// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wfloat-equal"
#endif
// gen_amalgamated expanded: #include "protos/perfetto/ipc/consumer_port.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/trace_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/data_source_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/system_info/system_info.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/track_event/track_event_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/test_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/sys_stats/sys_stats_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/common/sys_stats_counters.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/profiling/perf_event_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/common/perf_events.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/profiling/java_hprof_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/profiling/heapprofd_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/process_stats/process_stats_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/statsd/statsd_tracing_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/statsd/atom_ids.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/power/android_power_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/interceptor_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/interceptors/console_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/inode_file/inode_file_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/gpu/vulkan_memory_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/gpu/gpu_counter_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/ftrace/ftrace_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/etw/etw_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/chrome/v8_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/chrome/chrome_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/android/surfaceflinger_transactions_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/android/surfaceflinger_layers_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/android/protolog_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/common/protolog_common.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/android/pixel_modem_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/android/packages_list_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/android/network_trace_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/android/android_sdk_sysprop_guard_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/android/android_system_property_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/android/android_polled_state_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/android/android_log_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/common/android_log_constants.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/android/android_input_event_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/android/android_game_intervention_list_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/common/builtin_clock.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/common/trace_stats.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/common/tracing_service_capabilities.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/common/observable_events.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/common/tracing_service_state.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/common/data_source_descriptor.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/common/track_event_descriptor.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/common/gpu_counter_descriptor.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/common/ftrace_descriptor.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/common/observable_events.gen.h"

namespace perfetto {
namespace protos {
namespace gen {

CloneSessionResponse::CloneSessionResponse() = default;
CloneSessionResponse::~CloneSessionResponse() = default;
CloneSessionResponse::CloneSessionResponse(const CloneSessionResponse&) = default;
CloneSessionResponse& CloneSessionResponse::operator=(const CloneSessionResponse&) = default;
CloneSessionResponse::CloneSessionResponse(CloneSessionResponse&&) noexcept = default;
CloneSessionResponse& CloneSessionResponse::operator=(CloneSessionResponse&&) = default;

bool CloneSessionResponse::operator==(const CloneSessionResponse& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(success_, other.success_)
   && ::protozero::internal::gen_helpers::EqualsField(error_, other.error_)
   && ::protozero::internal::gen_helpers::EqualsField(uuid_msb_, other.uuid_msb_)
   && ::protozero::internal::gen_helpers::EqualsField(uuid_lsb_, other.uuid_lsb_);
}

bool CloneSessionResponse::ParseFromArray(const void* raw, size_t size) {
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* success */:
        field.get(&success_);
        break;
      case 2 /* error */:
        ::protozero::internal::gen_helpers::DeserializeString(field, &error_);
        break;
      case 3 /* uuid_msb */:
        field.get(&uuid_msb_);
        break;
      case 4 /* uuid_lsb */:
        field.get(&uuid_lsb_);
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string CloneSessionResponse::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> CloneSessionResponse::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void CloneSessionResponse::Serialize(::protozero::Message* msg) const {
  // Field 1: success
  if (_has_field_[1]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(1, success_, msg);
  }

  // Field 2: error
  if (_has_field_[2]) {
    ::protozero::internal::gen_helpers::SerializeString(2, error_, msg);
  }

  // Field 3: uuid_msb
  if (_has_field_[3]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(3, uuid_msb_, msg);
  }

  // Field 4: uuid_lsb
  if (_has_field_[4]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(4, uuid_lsb_, msg);
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}


CloneSessionRequest::CloneSessionRequest() = default;
CloneSessionRequest::~CloneSessionRequest() = default;
CloneSessionRequest::CloneSessionRequest(const CloneSessionRequest&) = default;
CloneSessionRequest& CloneSessionRequest::operator=(const CloneSessionRequest&) = default;
CloneSessionRequest::CloneSessionRequest(CloneSessionRequest&&) noexcept = default;
CloneSessionRequest& CloneSessionRequest::operator=(CloneSessionRequest&&) = default;

bool CloneSessionRequest::operator==(const CloneSessionRequest& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(session_id_, other.session_id_)
   && ::protozero::internal::gen_helpers::EqualsField(skip_trace_filter_, other.skip_trace_filter_)
   && ::protozero::internal::gen_helpers::EqualsField(for_bugreport_, other.for_bugreport_);
}

bool CloneSessionRequest::ParseFromArray(const void* raw, size_t size) {
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* session_id */:
        field.get(&session_id_);
        break;
      case 2 /* skip_trace_filter */:
        field.get(&skip_trace_filter_);
        break;
      case 3 /* for_bugreport */:
        field.get(&for_bugreport_);
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string CloneSessionRequest::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> CloneSessionRequest::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void CloneSessionRequest::Serialize(::protozero::Message* msg) const {
  // Field 1: session_id
  if (_has_field_[1]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(1, session_id_, msg);
  }

  // Field 2: skip_trace_filter
  if (_has_field_[2]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(2, skip_trace_filter_, msg);
  }

  // Field 3: for_bugreport
  if (_has_field_[3]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(3, for_bugreport_, msg);
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}


SaveTraceForBugreportResponse::SaveTraceForBugreportResponse() = default;
SaveTraceForBugreportResponse::~SaveTraceForBugreportResponse() = default;
SaveTraceForBugreportResponse::SaveTraceForBugreportResponse(const SaveTraceForBugreportResponse&) = default;
SaveTraceForBugreportResponse& SaveTraceForBugreportResponse::operator=(const SaveTraceForBugreportResponse&) = default;
SaveTraceForBugreportResponse::SaveTraceForBugreportResponse(SaveTraceForBugreportResponse&&) noexcept = default;
SaveTraceForBugreportResponse& SaveTraceForBugreportResponse::operator=(SaveTraceForBugreportResponse&&) = default;

bool SaveTraceForBugreportResponse::operator==(const SaveTraceForBugreportResponse& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(success_, other.success_)
   && ::protozero::internal::gen_helpers::EqualsField(msg_, other.msg_);
}

bool SaveTraceForBugreportResponse::ParseFromArray(const void* raw, size_t size) {
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* success */:
        field.get(&success_);
        break;
      case 2 /* msg */:
        ::protozero::internal::gen_helpers::DeserializeString(field, &msg_);
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string SaveTraceForBugreportResponse::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> SaveTraceForBugreportResponse::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void SaveTraceForBugreportResponse::Serialize(::protozero::Message* msg) const {
  // Field 1: success
  if (_has_field_[1]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(1, success_, msg);
  }

  // Field 2: msg
  if (_has_field_[2]) {
    ::protozero::internal::gen_helpers::SerializeString(2, msg_, msg);
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}


SaveTraceForBugreportRequest::SaveTraceForBugreportRequest() = default;
SaveTraceForBugreportRequest::~SaveTraceForBugreportRequest() = default;
SaveTraceForBugreportRequest::SaveTraceForBugreportRequest(const SaveTraceForBugreportRequest&) = default;
SaveTraceForBugreportRequest& SaveTraceForBugreportRequest::operator=(const SaveTraceForBugreportRequest&) = default;
SaveTraceForBugreportRequest::SaveTraceForBugreportRequest(SaveTraceForBugreportRequest&&) noexcept = default;
SaveTraceForBugreportRequest& SaveTraceForBugreportRequest::operator=(SaveTraceForBugreportRequest&&) = default;

bool SaveTraceForBugreportRequest::operator==(const SaveTraceForBugreportRequest& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_);
}

bool SaveTraceForBugreportRequest::ParseFromArray(const void* raw, size_t size) {
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string SaveTraceForBugreportRequest::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> SaveTraceForBugreportRequest::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void SaveTraceForBugreportRequest::Serialize(::protozero::Message* msg) const {
  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}


QueryCapabilitiesResponse::QueryCapabilitiesResponse() = default;
QueryCapabilitiesResponse::~QueryCapabilitiesResponse() = default;
QueryCapabilitiesResponse::QueryCapabilitiesResponse(const QueryCapabilitiesResponse&) = default;
QueryCapabilitiesResponse& QueryCapabilitiesResponse::operator=(const QueryCapabilitiesResponse&) = default;
QueryCapabilitiesResponse::QueryCapabilitiesResponse(QueryCapabilitiesResponse&&) noexcept = default;
QueryCapabilitiesResponse& QueryCapabilitiesResponse::operator=(QueryCapabilitiesResponse&&) = default;

bool QueryCapabilitiesResponse::operator==(const QueryCapabilitiesResponse& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(capabilities_, other.capabilities_);
}

bool QueryCapabilitiesResponse::ParseFromArray(const void* raw, size_t size) {
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* capabilities */:
        (*capabilities_).ParseFromArray(field.data(), field.size());
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string QueryCapabilitiesResponse::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> QueryCapabilitiesResponse::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void QueryCapabilitiesResponse::Serialize(::protozero::Message* msg) const {
  // Field 1: capabilities
  if (_has_field_[1]) {
    (*capabilities_).Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}


QueryCapabilitiesRequest::QueryCapabilitiesRequest() = default;
QueryCapabilitiesRequest::~QueryCapabilitiesRequest() = default;
QueryCapabilitiesRequest::QueryCapabilitiesRequest(const QueryCapabilitiesRequest&) = default;
QueryCapabilitiesRequest& QueryCapabilitiesRequest::operator=(const QueryCapabilitiesRequest&) = default;
QueryCapabilitiesRequest::QueryCapabilitiesRequest(QueryCapabilitiesRequest&&) noexcept = default;
QueryCapabilitiesRequest& QueryCapabilitiesRequest::operator=(QueryCapabilitiesRequest&&) = default;

bool QueryCapabilitiesRequest::operator==(const QueryCapabilitiesRequest& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_);
}

bool QueryCapabilitiesRequest::ParseFromArray(const void* raw, size_t size) {
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string QueryCapabilitiesRequest::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> QueryCapabilitiesRequest::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void QueryCapabilitiesRequest::Serialize(::protozero::Message* msg) const {
  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}


QueryServiceStateResponse::QueryServiceStateResponse() = default;
QueryServiceStateResponse::~QueryServiceStateResponse() = default;
QueryServiceStateResponse::QueryServiceStateResponse(const QueryServiceStateResponse&) = default;
QueryServiceStateResponse& QueryServiceStateResponse::operator=(const QueryServiceStateResponse&) = default;
QueryServiceStateResponse::QueryServiceStateResponse(QueryServiceStateResponse&&) noexcept = default;
QueryServiceStateResponse& QueryServiceStateResponse::operator=(QueryServiceStateResponse&&) = default;

bool QueryServiceStateResponse::operator==(const QueryServiceStateResponse& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(service_state_, other.service_state_);
}

bool QueryServiceStateResponse::ParseFromArray(const void* raw, size_t size) {
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* service_state */:
        (*service_state_).ParseFromArray(field.data(), field.size());
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string QueryServiceStateResponse::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> QueryServiceStateResponse::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void QueryServiceStateResponse::Serialize(::protozero::Message* msg) const {
  // Field 1: service_state
  if (_has_field_[1]) {
    (*service_state_).Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}


QueryServiceStateRequest::QueryServiceStateRequest() = default;
QueryServiceStateRequest::~QueryServiceStateRequest() = default;
QueryServiceStateRequest::QueryServiceStateRequest(const QueryServiceStateRequest&) = default;
QueryServiceStateRequest& QueryServiceStateRequest::operator=(const QueryServiceStateRequest&) = default;
QueryServiceStateRequest::QueryServiceStateRequest(QueryServiceStateRequest&&) noexcept = default;
QueryServiceStateRequest& QueryServiceStateRequest::operator=(QueryServiceStateRequest&&) = default;

bool QueryServiceStateRequest::operator==(const QueryServiceStateRequest& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(sessions_only_, other.sessions_only_);
}

bool QueryServiceStateRequest::ParseFromArray(const void* raw, size_t size) {
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* sessions_only */:
        field.get(&sessions_only_);
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string QueryServiceStateRequest::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> QueryServiceStateRequest::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void QueryServiceStateRequest::Serialize(::protozero::Message* msg) const {
  // Field 1: sessions_only
  if (_has_field_[1]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(1, sessions_only_, msg);
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}


ObserveEventsResponse::ObserveEventsResponse() = default;
ObserveEventsResponse::~ObserveEventsResponse() = default;
ObserveEventsResponse::ObserveEventsResponse(const ObserveEventsResponse&) = default;
ObserveEventsResponse& ObserveEventsResponse::operator=(const ObserveEventsResponse&) = default;
ObserveEventsResponse::ObserveEventsResponse(ObserveEventsResponse&&) noexcept = default;
ObserveEventsResponse& ObserveEventsResponse::operator=(ObserveEventsResponse&&) = default;

bool ObserveEventsResponse::operator==(const ObserveEventsResponse& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(events_, other.events_);
}

bool ObserveEventsResponse::ParseFromArray(const void* raw, size_t size) {
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* events */:
        (*events_).ParseFromArray(field.data(), field.size());
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string ObserveEventsResponse::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> ObserveEventsResponse::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void ObserveEventsResponse::Serialize(::protozero::Message* msg) const {
  // Field 1: events
  if (_has_field_[1]) {
    (*events_).Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}


ObserveEventsRequest::ObserveEventsRequest() = default;
ObserveEventsRequest::~ObserveEventsRequest() = default;
ObserveEventsRequest::ObserveEventsRequest(const ObserveEventsRequest&) = default;
ObserveEventsRequest& ObserveEventsRequest::operator=(const ObserveEventsRequest&) = default;
ObserveEventsRequest::ObserveEventsRequest(ObserveEventsRequest&&) noexcept = default;
ObserveEventsRequest& ObserveEventsRequest::operator=(ObserveEventsRequest&&) = default;

bool ObserveEventsRequest::operator==(const ObserveEventsRequest& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(events_to_observe_, other.events_to_observe_);
}

bool ObserveEventsRequest::ParseFromArray(const void* raw, size_t size) {
  events_to_observe_.clear();
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* events_to_observe */:
        events_to_observe_.emplace_back();
        field.get(&events_to_observe_.back());
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string ObserveEventsRequest::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> ObserveEventsRequest::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void ObserveEventsRequest::Serialize(::protozero::Message* msg) const {
  // Field 1: events_to_observe
  for (auto& it : events_to_observe_) {
    ::protozero::internal::gen_helpers::SerializeVarInt(1, it, msg);
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}


GetTraceStatsResponse::GetTraceStatsResponse() = default;
GetTraceStatsResponse::~GetTraceStatsResponse() = default;
GetTraceStatsResponse::GetTraceStatsResponse(const GetTraceStatsResponse&) = default;
GetTraceStatsResponse& GetTraceStatsResponse::operator=(const GetTraceStatsResponse&) = default;
GetTraceStatsResponse::GetTraceStatsResponse(GetTraceStatsResponse&&) noexcept = default;
GetTraceStatsResponse& GetTraceStatsResponse::operator=(GetTraceStatsResponse&&) = default;

bool GetTraceStatsResponse::operator==(const GetTraceStatsResponse& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(trace_stats_, other.trace_stats_);
}

bool GetTraceStatsResponse::ParseFromArray(const void* raw, size_t size) {
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* trace_stats */:
        (*trace_stats_).ParseFromArray(field.data(), field.size());
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string GetTraceStatsResponse::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> GetTraceStatsResponse::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void GetTraceStatsResponse::Serialize(::protozero::Message* msg) const {
  // Field 1: trace_stats
  if (_has_field_[1]) {
    (*trace_stats_).Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}


GetTraceStatsRequest::GetTraceStatsRequest() = default;
GetTraceStatsRequest::~GetTraceStatsRequest() = default;
GetTraceStatsRequest::GetTraceStatsRequest(const GetTraceStatsRequest&) = default;
GetTraceStatsRequest& GetTraceStatsRequest::operator=(const GetTraceStatsRequest&) = default;
GetTraceStatsRequest::GetTraceStatsRequest(GetTraceStatsRequest&&) noexcept = default;
GetTraceStatsRequest& GetTraceStatsRequest::operator=(GetTraceStatsRequest&&) = default;

bool GetTraceStatsRequest::operator==(const GetTraceStatsRequest& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_);
}

bool GetTraceStatsRequest::ParseFromArray(const void* raw, size_t size) {
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string GetTraceStatsRequest::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> GetTraceStatsRequest::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void GetTraceStatsRequest::Serialize(::protozero::Message* msg) const {
  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}


AttachResponse::AttachResponse() = default;
AttachResponse::~AttachResponse() = default;
AttachResponse::AttachResponse(const AttachResponse&) = default;
AttachResponse& AttachResponse::operator=(const AttachResponse&) = default;
AttachResponse::AttachResponse(AttachResponse&&) noexcept = default;
AttachResponse& AttachResponse::operator=(AttachResponse&&) = default;

bool AttachResponse::operator==(const AttachResponse& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(trace_config_, other.trace_config_);
}

bool AttachResponse::ParseFromArray(const void* raw, size_t size) {
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* trace_config */:
        (*trace_config_).ParseFromArray(field.data(), field.size());
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string AttachResponse::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> AttachResponse::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void AttachResponse::Serialize(::protozero::Message* msg) const {
  // Field 1: trace_config
  if (_has_field_[1]) {
    (*trace_config_).Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}


AttachRequest::AttachRequest() = default;
AttachRequest::~AttachRequest() = default;
AttachRequest::AttachRequest(const AttachRequest&) = default;
AttachRequest& AttachRequest::operator=(const AttachRequest&) = default;
AttachRequest::AttachRequest(AttachRequest&&) noexcept = default;
AttachRequest& AttachRequest::operator=(AttachRequest&&) = default;

bool AttachRequest::operator==(const AttachRequest& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(key_, other.key_);
}

bool AttachRequest::ParseFromArray(const void* raw, size_t size) {
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* key */:
        ::protozero::internal::gen_helpers::DeserializeString(field, &key_);
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string AttachRequest::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> AttachRequest::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void AttachRequest::Serialize(::protozero::Message* msg) const {
  // Field 1: key
  if (_has_field_[1]) {
    ::protozero::internal::gen_helpers::SerializeString(1, key_, msg);
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}


DetachResponse::DetachResponse() = default;
DetachResponse::~DetachResponse() = default;
DetachResponse::DetachResponse(const DetachResponse&) = default;
DetachResponse& DetachResponse::operator=(const DetachResponse&) = default;
DetachResponse::DetachResponse(DetachResponse&&) noexcept = default;
DetachResponse& DetachResponse::operator=(DetachResponse&&) = default;

bool DetachResponse::operator==(const DetachResponse& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_);
}

bool DetachResponse::ParseFromArray(const void* raw, size_t size) {
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string DetachResponse::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> DetachResponse::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void DetachResponse::Serialize(::protozero::Message* msg) const {
  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}


DetachRequest::DetachRequest() = default;
DetachRequest::~DetachRequest() = default;
DetachRequest::DetachRequest(const DetachRequest&) = default;
DetachRequest& DetachRequest::operator=(const DetachRequest&) = default;
DetachRequest::DetachRequest(DetachRequest&&) noexcept = default;
DetachRequest& DetachRequest::operator=(DetachRequest&&) = default;

bool DetachRequest::operator==(const DetachRequest& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(key_, other.key_);
}

bool DetachRequest::ParseFromArray(const void* raw, size_t size) {
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* key */:
        ::protozero::internal::gen_helpers::DeserializeString(field, &key_);
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string DetachRequest::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> DetachRequest::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void DetachRequest::Serialize(::protozero::Message* msg) const {
  // Field 1: key
  if (_has_field_[1]) {
    ::protozero::internal::gen_helpers::SerializeString(1, key_, msg);
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}


FlushResponse::FlushResponse() = default;
FlushResponse::~FlushResponse() = default;
FlushResponse::FlushResponse(const FlushResponse&) = default;
FlushResponse& FlushResponse::operator=(const FlushResponse&) = default;
FlushResponse::FlushResponse(FlushResponse&&) noexcept = default;
FlushResponse& FlushResponse::operator=(FlushResponse&&) = default;

bool FlushResponse::operator==(const FlushResponse& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_);
}

bool FlushResponse::ParseFromArray(const void* raw, size_t size) {
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string FlushResponse::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> FlushResponse::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void FlushResponse::Serialize(::protozero::Message* msg) const {
  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}


FlushRequest::FlushRequest() = default;
FlushRequest::~FlushRequest() = default;
FlushRequest::FlushRequest(const FlushRequest&) = default;
FlushRequest& FlushRequest::operator=(const FlushRequest&) = default;
FlushRequest::FlushRequest(FlushRequest&&) noexcept = default;
FlushRequest& FlushRequest::operator=(FlushRequest&&) = default;

bool FlushRequest::operator==(const FlushRequest& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(timeout_ms_, other.timeout_ms_)
   && ::protozero::internal::gen_helpers::EqualsField(flags_, other.flags_);
}

bool FlushRequest::ParseFromArray(const void* raw, size_t size) {
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* timeout_ms */:
        field.get(&timeout_ms_);
        break;
      case 2 /* flags */:
        field.get(&flags_);
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string FlushRequest::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> FlushRequest::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void FlushRequest::Serialize(::protozero::Message* msg) const {
  // Field 1: timeout_ms
  if (_has_field_[1]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(1, timeout_ms_, msg);
  }

  // Field 2: flags
  if (_has_field_[2]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(2, flags_, msg);
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}


FreeBuffersResponse::FreeBuffersResponse() = default;
FreeBuffersResponse::~FreeBuffersResponse() = default;
FreeBuffersResponse::FreeBuffersResponse(const FreeBuffersResponse&) = default;
FreeBuffersResponse& FreeBuffersResponse::operator=(const FreeBuffersResponse&) = default;
FreeBuffersResponse::FreeBuffersResponse(FreeBuffersResponse&&) noexcept = default;
FreeBuffersResponse& FreeBuffersResponse::operator=(FreeBuffersResponse&&) = default;

bool FreeBuffersResponse::operator==(const FreeBuffersResponse& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_);
}

bool FreeBuffersResponse::ParseFromArray(const void* raw, size_t size) {
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string FreeBuffersResponse::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> FreeBuffersResponse::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void FreeBuffersResponse::Serialize(::protozero::Message* msg) const {
  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}


FreeBuffersRequest::FreeBuffersRequest() = default;
FreeBuffersRequest::~FreeBuffersRequest() = default;
FreeBuffersRequest::FreeBuffersRequest(const FreeBuffersRequest&) = default;
FreeBuffersRequest& FreeBuffersRequest::operator=(const FreeBuffersRequest&) = default;
FreeBuffersRequest::FreeBuffersRequest(FreeBuffersRequest&&) noexcept = default;
FreeBuffersRequest& FreeBuffersRequest::operator=(FreeBuffersRequest&&) = default;

bool FreeBuffersRequest::operator==(const FreeBuffersRequest& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(buffer_ids_, other.buffer_ids_);
}

bool FreeBuffersRequest::ParseFromArray(const void* raw, size_t size) {
  buffer_ids_.clear();
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* buffer_ids */:
        buffer_ids_.emplace_back();
        field.get(&buffer_ids_.back());
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string FreeBuffersRequest::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> FreeBuffersRequest::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void FreeBuffersRequest::Serialize(::protozero::Message* msg) const {
  // Field 1: buffer_ids
  for (auto& it : buffer_ids_) {
    ::protozero::internal::gen_helpers::SerializeVarInt(1, it, msg);
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}


ReadBuffersResponse::ReadBuffersResponse() = default;
ReadBuffersResponse::~ReadBuffersResponse() = default;
ReadBuffersResponse::ReadBuffersResponse(const ReadBuffersResponse&) = default;
ReadBuffersResponse& ReadBuffersResponse::operator=(const ReadBuffersResponse&) = default;
ReadBuffersResponse::ReadBuffersResponse(ReadBuffersResponse&&) noexcept = default;
ReadBuffersResponse& ReadBuffersResponse::operator=(ReadBuffersResponse&&) = default;

bool ReadBuffersResponse::operator==(const ReadBuffersResponse& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(slices_, other.slices_);
}

int ReadBuffersResponse::slices_size() const { return static_cast<int>(slices_.size()); }
void ReadBuffersResponse::clear_slices() { slices_.clear(); }
ReadBuffersResponse_Slice* ReadBuffersResponse::add_slices() { slices_.emplace_back(); return &slices_.back(); }
bool ReadBuffersResponse::ParseFromArray(const void* raw, size_t size) {
  slices_.clear();
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 2 /* slices */:
        slices_.emplace_back();
        slices_.back().ParseFromArray(field.data(), field.size());
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string ReadBuffersResponse::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> ReadBuffersResponse::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void ReadBuffersResponse::Serialize(::protozero::Message* msg) const {
  // Field 2: slices
  for (auto& it : slices_) {
    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(2));
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}


ReadBuffersResponse_Slice::ReadBuffersResponse_Slice() = default;
ReadBuffersResponse_Slice::~ReadBuffersResponse_Slice() = default;
ReadBuffersResponse_Slice::ReadBuffersResponse_Slice(const ReadBuffersResponse_Slice&) = default;
ReadBuffersResponse_Slice& ReadBuffersResponse_Slice::operator=(const ReadBuffersResponse_Slice&) = default;
ReadBuffersResponse_Slice::ReadBuffersResponse_Slice(ReadBuffersResponse_Slice&&) noexcept = default;
ReadBuffersResponse_Slice& ReadBuffersResponse_Slice::operator=(ReadBuffersResponse_Slice&&) = default;

bool ReadBuffersResponse_Slice::operator==(const ReadBuffersResponse_Slice& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(data_, other.data_)
   && ::protozero::internal::gen_helpers::EqualsField(last_slice_for_packet_, other.last_slice_for_packet_);
}

bool ReadBuffersResponse_Slice::ParseFromArray(const void* raw, size_t size) {
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* data */:
        field.get(&data_);
        break;
      case 2 /* last_slice_for_packet */:
        field.get(&last_slice_for_packet_);
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string ReadBuffersResponse_Slice::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> ReadBuffersResponse_Slice::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void ReadBuffersResponse_Slice::Serialize(::protozero::Message* msg) const {
  // Field 1: data
  if (_has_field_[1]) {
    ::protozero::internal::gen_helpers::SerializeString(1, data_, msg);
  }

  // Field 2: last_slice_for_packet
  if (_has_field_[2]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(2, last_slice_for_packet_, msg);
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}


ReadBuffersRequest::ReadBuffersRequest() = default;
ReadBuffersRequest::~ReadBuffersRequest() = default;
ReadBuffersRequest::ReadBuffersRequest(const ReadBuffersRequest&) = default;
ReadBuffersRequest& ReadBuffersRequest::operator=(const ReadBuffersRequest&) = default;
ReadBuffersRequest::ReadBuffersRequest(ReadBuffersRequest&&) noexcept = default;
ReadBuffersRequest& ReadBuffersRequest::operator=(ReadBuffersRequest&&) = default;

bool ReadBuffersRequest::operator==(const ReadBuffersRequest& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_);
}

bool ReadBuffersRequest::ParseFromArray(const void* raw, size_t size) {
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string ReadBuffersRequest::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> ReadBuffersRequest::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void ReadBuffersRequest::Serialize(::protozero::Message* msg) const {
  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}


DisableTracingResponse::DisableTracingResponse() = default;
DisableTracingResponse::~DisableTracingResponse() = default;
DisableTracingResponse::DisableTracingResponse(const DisableTracingResponse&) = default;
DisableTracingResponse& DisableTracingResponse::operator=(const DisableTracingResponse&) = default;
DisableTracingResponse::DisableTracingResponse(DisableTracingResponse&&) noexcept = default;
DisableTracingResponse& DisableTracingResponse::operator=(DisableTracingResponse&&) = default;

bool DisableTracingResponse::operator==(const DisableTracingResponse& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_);
}

bool DisableTracingResponse::ParseFromArray(const void* raw, size_t size) {
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string DisableTracingResponse::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> DisableTracingResponse::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void DisableTracingResponse::Serialize(::protozero::Message* msg) const {
  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}


DisableTracingRequest::DisableTracingRequest() = default;
DisableTracingRequest::~DisableTracingRequest() = default;
DisableTracingRequest::DisableTracingRequest(const DisableTracingRequest&) = default;
DisableTracingRequest& DisableTracingRequest::operator=(const DisableTracingRequest&) = default;
DisableTracingRequest::DisableTracingRequest(DisableTracingRequest&&) noexcept = default;
DisableTracingRequest& DisableTracingRequest::operator=(DisableTracingRequest&&) = default;

bool DisableTracingRequest::operator==(const DisableTracingRequest& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_);
}

bool DisableTracingRequest::ParseFromArray(const void* raw, size_t size) {
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string DisableTracingRequest::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> DisableTracingRequest::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void DisableTracingRequest::Serialize(::protozero::Message* msg) const {
  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}


ChangeTraceConfigResponse::ChangeTraceConfigResponse() = default;
ChangeTraceConfigResponse::~ChangeTraceConfigResponse() = default;
ChangeTraceConfigResponse::ChangeTraceConfigResponse(const ChangeTraceConfigResponse&) = default;
ChangeTraceConfigResponse& ChangeTraceConfigResponse::operator=(const ChangeTraceConfigResponse&) = default;
ChangeTraceConfigResponse::ChangeTraceConfigResponse(ChangeTraceConfigResponse&&) noexcept = default;
ChangeTraceConfigResponse& ChangeTraceConfigResponse::operator=(ChangeTraceConfigResponse&&) = default;

bool ChangeTraceConfigResponse::operator==(const ChangeTraceConfigResponse& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_);
}

bool ChangeTraceConfigResponse::ParseFromArray(const void* raw, size_t size) {
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string ChangeTraceConfigResponse::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> ChangeTraceConfigResponse::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void ChangeTraceConfigResponse::Serialize(::protozero::Message* msg) const {
  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}


ChangeTraceConfigRequest::ChangeTraceConfigRequest() = default;
ChangeTraceConfigRequest::~ChangeTraceConfigRequest() = default;
ChangeTraceConfigRequest::ChangeTraceConfigRequest(const ChangeTraceConfigRequest&) = default;
ChangeTraceConfigRequest& ChangeTraceConfigRequest::operator=(const ChangeTraceConfigRequest&) = default;
ChangeTraceConfigRequest::ChangeTraceConfigRequest(ChangeTraceConfigRequest&&) noexcept = default;
ChangeTraceConfigRequest& ChangeTraceConfigRequest::operator=(ChangeTraceConfigRequest&&) = default;

bool ChangeTraceConfigRequest::operator==(const ChangeTraceConfigRequest& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(trace_config_, other.trace_config_);
}

bool ChangeTraceConfigRequest::ParseFromArray(const void* raw, size_t size) {
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* trace_config */:
        (*trace_config_).ParseFromArray(field.data(), field.size());
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string ChangeTraceConfigRequest::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> ChangeTraceConfigRequest::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void ChangeTraceConfigRequest::Serialize(::protozero::Message* msg) const {
  // Field 1: trace_config
  if (_has_field_[1]) {
    (*trace_config_).Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}


StartTracingResponse::StartTracingResponse() = default;
StartTracingResponse::~StartTracingResponse() = default;
StartTracingResponse::StartTracingResponse(const StartTracingResponse&) = default;
StartTracingResponse& StartTracingResponse::operator=(const StartTracingResponse&) = default;
StartTracingResponse::StartTracingResponse(StartTracingResponse&&) noexcept = default;
StartTracingResponse& StartTracingResponse::operator=(StartTracingResponse&&) = default;

bool StartTracingResponse::operator==(const StartTracingResponse& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_);
}

bool StartTracingResponse::ParseFromArray(const void* raw, size_t size) {
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string StartTracingResponse::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> StartTracingResponse::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void StartTracingResponse::Serialize(::protozero::Message* msg) const {
  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}


StartTracingRequest::StartTracingRequest() = default;
StartTracingRequest::~StartTracingRequest() = default;
StartTracingRequest::StartTracingRequest(const StartTracingRequest&) = default;
StartTracingRequest& StartTracingRequest::operator=(const StartTracingRequest&) = default;
StartTracingRequest::StartTracingRequest(StartTracingRequest&&) noexcept = default;
StartTracingRequest& StartTracingRequest::operator=(StartTracingRequest&&) = default;

bool StartTracingRequest::operator==(const StartTracingRequest& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_);
}

bool StartTracingRequest::ParseFromArray(const void* raw, size_t size) {
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string StartTracingRequest::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> StartTracingRequest::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void StartTracingRequest::Serialize(::protozero::Message* msg) const {
  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}


EnableTracingResponse::EnableTracingResponse() = default;
EnableTracingResponse::~EnableTracingResponse() = default;
EnableTracingResponse::EnableTracingResponse(const EnableTracingResponse&) = default;
EnableTracingResponse& EnableTracingResponse::operator=(const EnableTracingResponse&) = default;
EnableTracingResponse::EnableTracingResponse(EnableTracingResponse&&) noexcept = default;
EnableTracingResponse& EnableTracingResponse::operator=(EnableTracingResponse&&) = default;

bool EnableTracingResponse::operator==(const EnableTracingResponse& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(disabled_, other.disabled_)
   && ::protozero::internal::gen_helpers::EqualsField(error_, other.error_);
}

bool EnableTracingResponse::ParseFromArray(const void* raw, size_t size) {
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* disabled */:
        field.get(&disabled_);
        break;
      case 3 /* error */:
        ::protozero::internal::gen_helpers::DeserializeString(field, &error_);
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string EnableTracingResponse::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> EnableTracingResponse::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void EnableTracingResponse::Serialize(::protozero::Message* msg) const {
  // Field 1: disabled
  if (_has_field_[1]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(1, disabled_, msg);
  }

  // Field 3: error
  if (_has_field_[3]) {
    ::protozero::internal::gen_helpers::SerializeString(3, error_, msg);
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}


EnableTracingRequest::EnableTracingRequest() = default;
EnableTracingRequest::~EnableTracingRequest() = default;
EnableTracingRequest::EnableTracingRequest(const EnableTracingRequest&) = default;
EnableTracingRequest& EnableTracingRequest::operator=(const EnableTracingRequest&) = default;
EnableTracingRequest::EnableTracingRequest(EnableTracingRequest&&) noexcept = default;
EnableTracingRequest& EnableTracingRequest::operator=(EnableTracingRequest&&) = default;

bool EnableTracingRequest::operator==(const EnableTracingRequest& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(trace_config_, other.trace_config_)
   && ::protozero::internal::gen_helpers::EqualsField(attach_notification_only_, other.attach_notification_only_);
}

bool EnableTracingRequest::ParseFromArray(const void* raw, size_t size) {
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* trace_config */:
        (*trace_config_).ParseFromArray(field.data(), field.size());
        break;
      case 2 /* attach_notification_only */:
        field.get(&attach_notification_only_);
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string EnableTracingRequest::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> EnableTracingRequest::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void EnableTracingRequest::Serialize(::protozero::Message* msg) const {
  // Field 1: trace_config
  if (_has_field_[1]) {
    (*trace_config_).Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
  }

  // Field 2: attach_notification_only
  if (_has_field_[2]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(2, attach_notification_only_, msg);
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}

}  // namespace perfetto
}  // namespace protos
}  // namespace gen
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic pop
#endif
// gen_amalgamated begin source: gen/protos/perfetto/ipc/producer_port.gen.cc
// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wfloat-equal"
#endif
// gen_amalgamated expanded: #include "protos/perfetto/ipc/producer_port.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/common/data_source_descriptor.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/common/track_event_descriptor.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/common/gpu_counter_descriptor.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/common/ftrace_descriptor.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/data_source_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/system_info/system_info.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/track_event/track_event_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/test_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/sys_stats/sys_stats_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/common/sys_stats_counters.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/profiling/perf_event_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/common/perf_events.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/profiling/java_hprof_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/profiling/heapprofd_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/process_stats/process_stats_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/statsd/statsd_tracing_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/statsd/atom_ids.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/power/android_power_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/interceptor_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/interceptors/console_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/inode_file/inode_file_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/gpu/vulkan_memory_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/gpu/gpu_counter_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/ftrace/ftrace_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/etw/etw_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/chrome/v8_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/chrome/chrome_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/android/surfaceflinger_transactions_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/android/surfaceflinger_layers_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/android/protolog_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/common/protolog_common.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/android/pixel_modem_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/android/packages_list_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/android/network_trace_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/android/android_sdk_sysprop_guard_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/android/android_system_property_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/android/android_polled_state_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/android/android_log_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/common/android_log_constants.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/android/android_input_event_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/android/android_game_intervention_list_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/common/commit_data_request.gen.h"

namespace perfetto {
namespace protos {
namespace gen {

SyncResponse::SyncResponse() = default;
SyncResponse::~SyncResponse() = default;
SyncResponse::SyncResponse(const SyncResponse&) = default;
SyncResponse& SyncResponse::operator=(const SyncResponse&) = default;
SyncResponse::SyncResponse(SyncResponse&&) noexcept = default;
SyncResponse& SyncResponse::operator=(SyncResponse&&) = default;

bool SyncResponse::operator==(const SyncResponse& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_);
}

bool SyncResponse::ParseFromArray(const void* raw, size_t size) {
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string SyncResponse::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> SyncResponse::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void SyncResponse::Serialize(::protozero::Message* msg) const {
  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}


SyncRequest::SyncRequest() = default;
SyncRequest::~SyncRequest() = default;
SyncRequest::SyncRequest(const SyncRequest&) = default;
SyncRequest& SyncRequest::operator=(const SyncRequest&) = default;
SyncRequest::SyncRequest(SyncRequest&&) noexcept = default;
SyncRequest& SyncRequest::operator=(SyncRequest&&) = default;

bool SyncRequest::operator==(const SyncRequest& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_);
}

bool SyncRequest::ParseFromArray(const void* raw, size_t size) {
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string SyncRequest::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> SyncRequest::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void SyncRequest::Serialize(::protozero::Message* msg) const {
  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}


GetAsyncCommandResponse::GetAsyncCommandResponse() = default;
GetAsyncCommandResponse::~GetAsyncCommandResponse() = default;
GetAsyncCommandResponse::GetAsyncCommandResponse(const GetAsyncCommandResponse&) = default;
GetAsyncCommandResponse& GetAsyncCommandResponse::operator=(const GetAsyncCommandResponse&) = default;
GetAsyncCommandResponse::GetAsyncCommandResponse(GetAsyncCommandResponse&&) noexcept = default;
GetAsyncCommandResponse& GetAsyncCommandResponse::operator=(GetAsyncCommandResponse&&) = default;

bool GetAsyncCommandResponse::operator==(const GetAsyncCommandResponse& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(setup_tracing_, other.setup_tracing_)
   && ::protozero::internal::gen_helpers::EqualsField(setup_data_source_, other.setup_data_source_)
   && ::protozero::internal::gen_helpers::EqualsField(start_data_source_, other.start_data_source_)
   && ::protozero::internal::gen_helpers::EqualsField(stop_data_source_, other.stop_data_source_)
   && ::protozero::internal::gen_helpers::EqualsField(flush_, other.flush_)
   && ::protozero::internal::gen_helpers::EqualsField(clear_incremental_state_, other.clear_incremental_state_);
}

bool GetAsyncCommandResponse::ParseFromArray(const void* raw, size_t size) {
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 3 /* setup_tracing */:
        (*setup_tracing_).ParseFromArray(field.data(), field.size());
        break;
      case 6 /* setup_data_source */:
        (*setup_data_source_).ParseFromArray(field.data(), field.size());
        break;
      case 1 /* start_data_source */:
        (*start_data_source_).ParseFromArray(field.data(), field.size());
        break;
      case 2 /* stop_data_source */:
        (*stop_data_source_).ParseFromArray(field.data(), field.size());
        break;
      case 5 /* flush */:
        (*flush_).ParseFromArray(field.data(), field.size());
        break;
      case 7 /* clear_incremental_state */:
        (*clear_incremental_state_).ParseFromArray(field.data(), field.size());
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string GetAsyncCommandResponse::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> GetAsyncCommandResponse::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void GetAsyncCommandResponse::Serialize(::protozero::Message* msg) const {
  // Field 3: setup_tracing
  if (_has_field_[3]) {
    (*setup_tracing_).Serialize(msg->BeginNestedMessage<::protozero::Message>(3));
  }

  // Field 6: setup_data_source
  if (_has_field_[6]) {
    (*setup_data_source_).Serialize(msg->BeginNestedMessage<::protozero::Message>(6));
  }

  // Field 1: start_data_source
  if (_has_field_[1]) {
    (*start_data_source_).Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
  }

  // Field 2: stop_data_source
  if (_has_field_[2]) {
    (*stop_data_source_).Serialize(msg->BeginNestedMessage<::protozero::Message>(2));
  }

  // Field 5: flush
  if (_has_field_[5]) {
    (*flush_).Serialize(msg->BeginNestedMessage<::protozero::Message>(5));
  }

  // Field 7: clear_incremental_state
  if (_has_field_[7]) {
    (*clear_incremental_state_).Serialize(msg->BeginNestedMessage<::protozero::Message>(7));
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}


GetAsyncCommandResponse_ClearIncrementalState::GetAsyncCommandResponse_ClearIncrementalState() = default;
GetAsyncCommandResponse_ClearIncrementalState::~GetAsyncCommandResponse_ClearIncrementalState() = default;
GetAsyncCommandResponse_ClearIncrementalState::GetAsyncCommandResponse_ClearIncrementalState(const GetAsyncCommandResponse_ClearIncrementalState&) = default;
GetAsyncCommandResponse_ClearIncrementalState& GetAsyncCommandResponse_ClearIncrementalState::operator=(const GetAsyncCommandResponse_ClearIncrementalState&) = default;
GetAsyncCommandResponse_ClearIncrementalState::GetAsyncCommandResponse_ClearIncrementalState(GetAsyncCommandResponse_ClearIncrementalState&&) noexcept = default;
GetAsyncCommandResponse_ClearIncrementalState& GetAsyncCommandResponse_ClearIncrementalState::operator=(GetAsyncCommandResponse_ClearIncrementalState&&) = default;

bool GetAsyncCommandResponse_ClearIncrementalState::operator==(const GetAsyncCommandResponse_ClearIncrementalState& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(data_source_ids_, other.data_source_ids_);
}

bool GetAsyncCommandResponse_ClearIncrementalState::ParseFromArray(const void* raw, size_t size) {
  data_source_ids_.clear();
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* data_source_ids */:
        data_source_ids_.emplace_back();
        field.get(&data_source_ids_.back());
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string GetAsyncCommandResponse_ClearIncrementalState::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> GetAsyncCommandResponse_ClearIncrementalState::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void GetAsyncCommandResponse_ClearIncrementalState::Serialize(::protozero::Message* msg) const {
  // Field 1: data_source_ids
  for (auto& it : data_source_ids_) {
    ::protozero::internal::gen_helpers::SerializeVarInt(1, it, msg);
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}


GetAsyncCommandResponse_Flush::GetAsyncCommandResponse_Flush() = default;
GetAsyncCommandResponse_Flush::~GetAsyncCommandResponse_Flush() = default;
GetAsyncCommandResponse_Flush::GetAsyncCommandResponse_Flush(const GetAsyncCommandResponse_Flush&) = default;
GetAsyncCommandResponse_Flush& GetAsyncCommandResponse_Flush::operator=(const GetAsyncCommandResponse_Flush&) = default;
GetAsyncCommandResponse_Flush::GetAsyncCommandResponse_Flush(GetAsyncCommandResponse_Flush&&) noexcept = default;
GetAsyncCommandResponse_Flush& GetAsyncCommandResponse_Flush::operator=(GetAsyncCommandResponse_Flush&&) = default;

bool GetAsyncCommandResponse_Flush::operator==(const GetAsyncCommandResponse_Flush& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(data_source_ids_, other.data_source_ids_)
   && ::protozero::internal::gen_helpers::EqualsField(request_id_, other.request_id_)
   && ::protozero::internal::gen_helpers::EqualsField(flags_, other.flags_);
}

bool GetAsyncCommandResponse_Flush::ParseFromArray(const void* raw, size_t size) {
  data_source_ids_.clear();
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* data_source_ids */:
        data_source_ids_.emplace_back();
        field.get(&data_source_ids_.back());
        break;
      case 2 /* request_id */:
        field.get(&request_id_);
        break;
      case 3 /* flags */:
        field.get(&flags_);
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string GetAsyncCommandResponse_Flush::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> GetAsyncCommandResponse_Flush::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void GetAsyncCommandResponse_Flush::Serialize(::protozero::Message* msg) const {
  // Field 1: data_source_ids
  for (auto& it : data_source_ids_) {
    ::protozero::internal::gen_helpers::SerializeVarInt(1, it, msg);
  }

  // Field 2: request_id
  if (_has_field_[2]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(2, request_id_, msg);
  }

  // Field 3: flags
  if (_has_field_[3]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(3, flags_, msg);
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}


GetAsyncCommandResponse_StopDataSource::GetAsyncCommandResponse_StopDataSource() = default;
GetAsyncCommandResponse_StopDataSource::~GetAsyncCommandResponse_StopDataSource() = default;
GetAsyncCommandResponse_StopDataSource::GetAsyncCommandResponse_StopDataSource(const GetAsyncCommandResponse_StopDataSource&) = default;
GetAsyncCommandResponse_StopDataSource& GetAsyncCommandResponse_StopDataSource::operator=(const GetAsyncCommandResponse_StopDataSource&) = default;
GetAsyncCommandResponse_StopDataSource::GetAsyncCommandResponse_StopDataSource(GetAsyncCommandResponse_StopDataSource&&) noexcept = default;
GetAsyncCommandResponse_StopDataSource& GetAsyncCommandResponse_StopDataSource::operator=(GetAsyncCommandResponse_StopDataSource&&) = default;

bool GetAsyncCommandResponse_StopDataSource::operator==(const GetAsyncCommandResponse_StopDataSource& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(instance_id_, other.instance_id_);
}

bool GetAsyncCommandResponse_StopDataSource::ParseFromArray(const void* raw, size_t size) {
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* instance_id */:
        field.get(&instance_id_);
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string GetAsyncCommandResponse_StopDataSource::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> GetAsyncCommandResponse_StopDataSource::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void GetAsyncCommandResponse_StopDataSource::Serialize(::protozero::Message* msg) const {
  // Field 1: instance_id
  if (_has_field_[1]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(1, instance_id_, msg);
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}


GetAsyncCommandResponse_StartDataSource::GetAsyncCommandResponse_StartDataSource() = default;
GetAsyncCommandResponse_StartDataSource::~GetAsyncCommandResponse_StartDataSource() = default;
GetAsyncCommandResponse_StartDataSource::GetAsyncCommandResponse_StartDataSource(const GetAsyncCommandResponse_StartDataSource&) = default;
GetAsyncCommandResponse_StartDataSource& GetAsyncCommandResponse_StartDataSource::operator=(const GetAsyncCommandResponse_StartDataSource&) = default;
GetAsyncCommandResponse_StartDataSource::GetAsyncCommandResponse_StartDataSource(GetAsyncCommandResponse_StartDataSource&&) noexcept = default;
GetAsyncCommandResponse_StartDataSource& GetAsyncCommandResponse_StartDataSource::operator=(GetAsyncCommandResponse_StartDataSource&&) = default;

bool GetAsyncCommandResponse_StartDataSource::operator==(const GetAsyncCommandResponse_StartDataSource& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(new_instance_id_, other.new_instance_id_)
   && ::protozero::internal::gen_helpers::EqualsField(config_, other.config_);
}

bool GetAsyncCommandResponse_StartDataSource::ParseFromArray(const void* raw, size_t size) {
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* new_instance_id */:
        field.get(&new_instance_id_);
        break;
      case 2 /* config */:
        (*config_).ParseFromArray(field.data(), field.size());
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string GetAsyncCommandResponse_StartDataSource::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> GetAsyncCommandResponse_StartDataSource::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void GetAsyncCommandResponse_StartDataSource::Serialize(::protozero::Message* msg) const {
  // Field 1: new_instance_id
  if (_has_field_[1]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(1, new_instance_id_, msg);
  }

  // Field 2: config
  if (_has_field_[2]) {
    (*config_).Serialize(msg->BeginNestedMessage<::protozero::Message>(2));
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}


GetAsyncCommandResponse_SetupDataSource::GetAsyncCommandResponse_SetupDataSource() = default;
GetAsyncCommandResponse_SetupDataSource::~GetAsyncCommandResponse_SetupDataSource() = default;
GetAsyncCommandResponse_SetupDataSource::GetAsyncCommandResponse_SetupDataSource(const GetAsyncCommandResponse_SetupDataSource&) = default;
GetAsyncCommandResponse_SetupDataSource& GetAsyncCommandResponse_SetupDataSource::operator=(const GetAsyncCommandResponse_SetupDataSource&) = default;
GetAsyncCommandResponse_SetupDataSource::GetAsyncCommandResponse_SetupDataSource(GetAsyncCommandResponse_SetupDataSource&&) noexcept = default;
GetAsyncCommandResponse_SetupDataSource& GetAsyncCommandResponse_SetupDataSource::operator=(GetAsyncCommandResponse_SetupDataSource&&) = default;

bool GetAsyncCommandResponse_SetupDataSource::operator==(const GetAsyncCommandResponse_SetupDataSource& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(new_instance_id_, other.new_instance_id_)
   && ::protozero::internal::gen_helpers::EqualsField(config_, other.config_);
}

bool GetAsyncCommandResponse_SetupDataSource::ParseFromArray(const void* raw, size_t size) {
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* new_instance_id */:
        field.get(&new_instance_id_);
        break;
      case 2 /* config */:
        (*config_).ParseFromArray(field.data(), field.size());
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string GetAsyncCommandResponse_SetupDataSource::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> GetAsyncCommandResponse_SetupDataSource::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void GetAsyncCommandResponse_SetupDataSource::Serialize(::protozero::Message* msg) const {
  // Field 1: new_instance_id
  if (_has_field_[1]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(1, new_instance_id_, msg);
  }

  // Field 2: config
  if (_has_field_[2]) {
    (*config_).Serialize(msg->BeginNestedMessage<::protozero::Message>(2));
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}


GetAsyncCommandResponse_SetupTracing::GetAsyncCommandResponse_SetupTracing() = default;
GetAsyncCommandResponse_SetupTracing::~GetAsyncCommandResponse_SetupTracing() = default;
GetAsyncCommandResponse_SetupTracing::GetAsyncCommandResponse_SetupTracing(const GetAsyncCommandResponse_SetupTracing&) = default;
GetAsyncCommandResponse_SetupTracing& GetAsyncCommandResponse_SetupTracing::operator=(const GetAsyncCommandResponse_SetupTracing&) = default;
GetAsyncCommandResponse_SetupTracing::GetAsyncCommandResponse_SetupTracing(GetAsyncCommandResponse_SetupTracing&&) noexcept = default;
GetAsyncCommandResponse_SetupTracing& GetAsyncCommandResponse_SetupTracing::operator=(GetAsyncCommandResponse_SetupTracing&&) = default;

bool GetAsyncCommandResponse_SetupTracing::operator==(const GetAsyncCommandResponse_SetupTracing& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(shared_buffer_page_size_kb_, other.shared_buffer_page_size_kb_)
   && ::protozero::internal::gen_helpers::EqualsField(shm_key_windows_, other.shm_key_windows_);
}

bool GetAsyncCommandResponse_SetupTracing::ParseFromArray(const void* raw, size_t size) {
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* shared_buffer_page_size_kb */:
        field.get(&shared_buffer_page_size_kb_);
        break;
      case 2 /* shm_key_windows */:
        ::protozero::internal::gen_helpers::DeserializeString(field, &shm_key_windows_);
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string GetAsyncCommandResponse_SetupTracing::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> GetAsyncCommandResponse_SetupTracing::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void GetAsyncCommandResponse_SetupTracing::Serialize(::protozero::Message* msg) const {
  // Field 1: shared_buffer_page_size_kb
  if (_has_field_[1]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(1, shared_buffer_page_size_kb_, msg);
  }

  // Field 2: shm_key_windows
  if (_has_field_[2]) {
    ::protozero::internal::gen_helpers::SerializeString(2, shm_key_windows_, msg);
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}


GetAsyncCommandRequest::GetAsyncCommandRequest() = default;
GetAsyncCommandRequest::~GetAsyncCommandRequest() = default;
GetAsyncCommandRequest::GetAsyncCommandRequest(const GetAsyncCommandRequest&) = default;
GetAsyncCommandRequest& GetAsyncCommandRequest::operator=(const GetAsyncCommandRequest&) = default;
GetAsyncCommandRequest::GetAsyncCommandRequest(GetAsyncCommandRequest&&) noexcept = default;
GetAsyncCommandRequest& GetAsyncCommandRequest::operator=(GetAsyncCommandRequest&&) = default;

bool GetAsyncCommandRequest::operator==(const GetAsyncCommandRequest& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_);
}

bool GetAsyncCommandRequest::ParseFromArray(const void* raw, size_t size) {
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string GetAsyncCommandRequest::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> GetAsyncCommandRequest::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void GetAsyncCommandRequest::Serialize(::protozero::Message* msg) const {
  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}


ActivateTriggersResponse::ActivateTriggersResponse() = default;
ActivateTriggersResponse::~ActivateTriggersResponse() = default;
ActivateTriggersResponse::ActivateTriggersResponse(const ActivateTriggersResponse&) = default;
ActivateTriggersResponse& ActivateTriggersResponse::operator=(const ActivateTriggersResponse&) = default;
ActivateTriggersResponse::ActivateTriggersResponse(ActivateTriggersResponse&&) noexcept = default;
ActivateTriggersResponse& ActivateTriggersResponse::operator=(ActivateTriggersResponse&&) = default;

bool ActivateTriggersResponse::operator==(const ActivateTriggersResponse& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_);
}

bool ActivateTriggersResponse::ParseFromArray(const void* raw, size_t size) {
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string ActivateTriggersResponse::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> ActivateTriggersResponse::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void ActivateTriggersResponse::Serialize(::protozero::Message* msg) const {
  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}


ActivateTriggersRequest::ActivateTriggersRequest() = default;
ActivateTriggersRequest::~ActivateTriggersRequest() = default;
ActivateTriggersRequest::ActivateTriggersRequest(const ActivateTriggersRequest&) = default;
ActivateTriggersRequest& ActivateTriggersRequest::operator=(const ActivateTriggersRequest&) = default;
ActivateTriggersRequest::ActivateTriggersRequest(ActivateTriggersRequest&&) noexcept = default;
ActivateTriggersRequest& ActivateTriggersRequest::operator=(ActivateTriggersRequest&&) = default;

bool ActivateTriggersRequest::operator==(const ActivateTriggersRequest& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(trigger_names_, other.trigger_names_);
}

bool ActivateTriggersRequest::ParseFromArray(const void* raw, size_t size) {
  trigger_names_.clear();
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* trigger_names */:
        trigger_names_.emplace_back();
        ::protozero::internal::gen_helpers::DeserializeString(field, &trigger_names_.back());
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string ActivateTriggersRequest::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> ActivateTriggersRequest::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void ActivateTriggersRequest::Serialize(::protozero::Message* msg) const {
  // Field 1: trigger_names
  for (auto& it : trigger_names_) {
    ::protozero::internal::gen_helpers::SerializeString(1, it, msg);
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}


NotifyDataSourceStoppedResponse::NotifyDataSourceStoppedResponse() = default;
NotifyDataSourceStoppedResponse::~NotifyDataSourceStoppedResponse() = default;
NotifyDataSourceStoppedResponse::NotifyDataSourceStoppedResponse(const NotifyDataSourceStoppedResponse&) = default;
NotifyDataSourceStoppedResponse& NotifyDataSourceStoppedResponse::operator=(const NotifyDataSourceStoppedResponse&) = default;
NotifyDataSourceStoppedResponse::NotifyDataSourceStoppedResponse(NotifyDataSourceStoppedResponse&&) noexcept = default;
NotifyDataSourceStoppedResponse& NotifyDataSourceStoppedResponse::operator=(NotifyDataSourceStoppedResponse&&) = default;

bool NotifyDataSourceStoppedResponse::operator==(const NotifyDataSourceStoppedResponse& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_);
}

bool NotifyDataSourceStoppedResponse::ParseFromArray(const void* raw, size_t size) {
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string NotifyDataSourceStoppedResponse::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> NotifyDataSourceStoppedResponse::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void NotifyDataSourceStoppedResponse::Serialize(::protozero::Message* msg) const {
  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}


NotifyDataSourceStoppedRequest::NotifyDataSourceStoppedRequest() = default;
NotifyDataSourceStoppedRequest::~NotifyDataSourceStoppedRequest() = default;
NotifyDataSourceStoppedRequest::NotifyDataSourceStoppedRequest(const NotifyDataSourceStoppedRequest&) = default;
NotifyDataSourceStoppedRequest& NotifyDataSourceStoppedRequest::operator=(const NotifyDataSourceStoppedRequest&) = default;
NotifyDataSourceStoppedRequest::NotifyDataSourceStoppedRequest(NotifyDataSourceStoppedRequest&&) noexcept = default;
NotifyDataSourceStoppedRequest& NotifyDataSourceStoppedRequest::operator=(NotifyDataSourceStoppedRequest&&) = default;

bool NotifyDataSourceStoppedRequest::operator==(const NotifyDataSourceStoppedRequest& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(data_source_id_, other.data_source_id_);
}

bool NotifyDataSourceStoppedRequest::ParseFromArray(const void* raw, size_t size) {
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* data_source_id */:
        field.get(&data_source_id_);
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string NotifyDataSourceStoppedRequest::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> NotifyDataSourceStoppedRequest::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void NotifyDataSourceStoppedRequest::Serialize(::protozero::Message* msg) const {
  // Field 1: data_source_id
  if (_has_field_[1]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(1, data_source_id_, msg);
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}


NotifyDataSourceStartedResponse::NotifyDataSourceStartedResponse() = default;
NotifyDataSourceStartedResponse::~NotifyDataSourceStartedResponse() = default;
NotifyDataSourceStartedResponse::NotifyDataSourceStartedResponse(const NotifyDataSourceStartedResponse&) = default;
NotifyDataSourceStartedResponse& NotifyDataSourceStartedResponse::operator=(const NotifyDataSourceStartedResponse&) = default;
NotifyDataSourceStartedResponse::NotifyDataSourceStartedResponse(NotifyDataSourceStartedResponse&&) noexcept = default;
NotifyDataSourceStartedResponse& NotifyDataSourceStartedResponse::operator=(NotifyDataSourceStartedResponse&&) = default;

bool NotifyDataSourceStartedResponse::operator==(const NotifyDataSourceStartedResponse& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_);
}

bool NotifyDataSourceStartedResponse::ParseFromArray(const void* raw, size_t size) {
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string NotifyDataSourceStartedResponse::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> NotifyDataSourceStartedResponse::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void NotifyDataSourceStartedResponse::Serialize(::protozero::Message* msg) const {
  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}


NotifyDataSourceStartedRequest::NotifyDataSourceStartedRequest() = default;
NotifyDataSourceStartedRequest::~NotifyDataSourceStartedRequest() = default;
NotifyDataSourceStartedRequest::NotifyDataSourceStartedRequest(const NotifyDataSourceStartedRequest&) = default;
NotifyDataSourceStartedRequest& NotifyDataSourceStartedRequest::operator=(const NotifyDataSourceStartedRequest&) = default;
NotifyDataSourceStartedRequest::NotifyDataSourceStartedRequest(NotifyDataSourceStartedRequest&&) noexcept = default;
NotifyDataSourceStartedRequest& NotifyDataSourceStartedRequest::operator=(NotifyDataSourceStartedRequest&&) = default;

bool NotifyDataSourceStartedRequest::operator==(const NotifyDataSourceStartedRequest& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(data_source_id_, other.data_source_id_);
}

bool NotifyDataSourceStartedRequest::ParseFromArray(const void* raw, size_t size) {
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* data_source_id */:
        field.get(&data_source_id_);
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string NotifyDataSourceStartedRequest::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> NotifyDataSourceStartedRequest::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void NotifyDataSourceStartedRequest::Serialize(::protozero::Message* msg) const {
  // Field 1: data_source_id
  if (_has_field_[1]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(1, data_source_id_, msg);
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}


CommitDataResponse::CommitDataResponse() = default;
CommitDataResponse::~CommitDataResponse() = default;
CommitDataResponse::CommitDataResponse(const CommitDataResponse&) = default;
CommitDataResponse& CommitDataResponse::operator=(const CommitDataResponse&) = default;
CommitDataResponse::CommitDataResponse(CommitDataResponse&&) noexcept = default;
CommitDataResponse& CommitDataResponse::operator=(CommitDataResponse&&) = default;

bool CommitDataResponse::operator==(const CommitDataResponse& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_);
}

bool CommitDataResponse::ParseFromArray(const void* raw, size_t size) {
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string CommitDataResponse::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> CommitDataResponse::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void CommitDataResponse::Serialize(::protozero::Message* msg) const {
  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}


UnregisterTraceWriterResponse::UnregisterTraceWriterResponse() = default;
UnregisterTraceWriterResponse::~UnregisterTraceWriterResponse() = default;
UnregisterTraceWriterResponse::UnregisterTraceWriterResponse(const UnregisterTraceWriterResponse&) = default;
UnregisterTraceWriterResponse& UnregisterTraceWriterResponse::operator=(const UnregisterTraceWriterResponse&) = default;
UnregisterTraceWriterResponse::UnregisterTraceWriterResponse(UnregisterTraceWriterResponse&&) noexcept = default;
UnregisterTraceWriterResponse& UnregisterTraceWriterResponse::operator=(UnregisterTraceWriterResponse&&) = default;

bool UnregisterTraceWriterResponse::operator==(const UnregisterTraceWriterResponse& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_);
}

bool UnregisterTraceWriterResponse::ParseFromArray(const void* raw, size_t size) {
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string UnregisterTraceWriterResponse::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> UnregisterTraceWriterResponse::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void UnregisterTraceWriterResponse::Serialize(::protozero::Message* msg) const {
  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}


UnregisterTraceWriterRequest::UnregisterTraceWriterRequest() = default;
UnregisterTraceWriterRequest::~UnregisterTraceWriterRequest() = default;
UnregisterTraceWriterRequest::UnregisterTraceWriterRequest(const UnregisterTraceWriterRequest&) = default;
UnregisterTraceWriterRequest& UnregisterTraceWriterRequest::operator=(const UnregisterTraceWriterRequest&) = default;
UnregisterTraceWriterRequest::UnregisterTraceWriterRequest(UnregisterTraceWriterRequest&&) noexcept = default;
UnregisterTraceWriterRequest& UnregisterTraceWriterRequest::operator=(UnregisterTraceWriterRequest&&) = default;

bool UnregisterTraceWriterRequest::operator==(const UnregisterTraceWriterRequest& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(trace_writer_id_, other.trace_writer_id_);
}

bool UnregisterTraceWriterRequest::ParseFromArray(const void* raw, size_t size) {
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* trace_writer_id */:
        field.get(&trace_writer_id_);
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string UnregisterTraceWriterRequest::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> UnregisterTraceWriterRequest::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void UnregisterTraceWriterRequest::Serialize(::protozero::Message* msg) const {
  // Field 1: trace_writer_id
  if (_has_field_[1]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(1, trace_writer_id_, msg);
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}


RegisterTraceWriterResponse::RegisterTraceWriterResponse() = default;
RegisterTraceWriterResponse::~RegisterTraceWriterResponse() = default;
RegisterTraceWriterResponse::RegisterTraceWriterResponse(const RegisterTraceWriterResponse&) = default;
RegisterTraceWriterResponse& RegisterTraceWriterResponse::operator=(const RegisterTraceWriterResponse&) = default;
RegisterTraceWriterResponse::RegisterTraceWriterResponse(RegisterTraceWriterResponse&&) noexcept = default;
RegisterTraceWriterResponse& RegisterTraceWriterResponse::operator=(RegisterTraceWriterResponse&&) = default;

bool RegisterTraceWriterResponse::operator==(const RegisterTraceWriterResponse& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_);
}

bool RegisterTraceWriterResponse::ParseFromArray(const void* raw, size_t size) {
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string RegisterTraceWriterResponse::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> RegisterTraceWriterResponse::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void RegisterTraceWriterResponse::Serialize(::protozero::Message* msg) const {
  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}


RegisterTraceWriterRequest::RegisterTraceWriterRequest() = default;
RegisterTraceWriterRequest::~RegisterTraceWriterRequest() = default;
RegisterTraceWriterRequest::RegisterTraceWriterRequest(const RegisterTraceWriterRequest&) = default;
RegisterTraceWriterRequest& RegisterTraceWriterRequest::operator=(const RegisterTraceWriterRequest&) = default;
RegisterTraceWriterRequest::RegisterTraceWriterRequest(RegisterTraceWriterRequest&&) noexcept = default;
RegisterTraceWriterRequest& RegisterTraceWriterRequest::operator=(RegisterTraceWriterRequest&&) = default;

bool RegisterTraceWriterRequest::operator==(const RegisterTraceWriterRequest& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(trace_writer_id_, other.trace_writer_id_)
   && ::protozero::internal::gen_helpers::EqualsField(target_buffer_, other.target_buffer_);
}

bool RegisterTraceWriterRequest::ParseFromArray(const void* raw, size_t size) {
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* trace_writer_id */:
        field.get(&trace_writer_id_);
        break;
      case 2 /* target_buffer */:
        field.get(&target_buffer_);
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string RegisterTraceWriterRequest::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> RegisterTraceWriterRequest::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void RegisterTraceWriterRequest::Serialize(::protozero::Message* msg) const {
  // Field 1: trace_writer_id
  if (_has_field_[1]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(1, trace_writer_id_, msg);
  }

  // Field 2: target_buffer
  if (_has_field_[2]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(2, target_buffer_, msg);
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}


UnregisterDataSourceResponse::UnregisterDataSourceResponse() = default;
UnregisterDataSourceResponse::~UnregisterDataSourceResponse() = default;
UnregisterDataSourceResponse::UnregisterDataSourceResponse(const UnregisterDataSourceResponse&) = default;
UnregisterDataSourceResponse& UnregisterDataSourceResponse::operator=(const UnregisterDataSourceResponse&) = default;
UnregisterDataSourceResponse::UnregisterDataSourceResponse(UnregisterDataSourceResponse&&) noexcept = default;
UnregisterDataSourceResponse& UnregisterDataSourceResponse::operator=(UnregisterDataSourceResponse&&) = default;

bool UnregisterDataSourceResponse::operator==(const UnregisterDataSourceResponse& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_);
}

bool UnregisterDataSourceResponse::ParseFromArray(const void* raw, size_t size) {
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string UnregisterDataSourceResponse::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> UnregisterDataSourceResponse::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void UnregisterDataSourceResponse::Serialize(::protozero::Message* msg) const {
  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}


UnregisterDataSourceRequest::UnregisterDataSourceRequest() = default;
UnregisterDataSourceRequest::~UnregisterDataSourceRequest() = default;
UnregisterDataSourceRequest::UnregisterDataSourceRequest(const UnregisterDataSourceRequest&) = default;
UnregisterDataSourceRequest& UnregisterDataSourceRequest::operator=(const UnregisterDataSourceRequest&) = default;
UnregisterDataSourceRequest::UnregisterDataSourceRequest(UnregisterDataSourceRequest&&) noexcept = default;
UnregisterDataSourceRequest& UnregisterDataSourceRequest::operator=(UnregisterDataSourceRequest&&) = default;

bool UnregisterDataSourceRequest::operator==(const UnregisterDataSourceRequest& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(data_source_name_, other.data_source_name_);
}

bool UnregisterDataSourceRequest::ParseFromArray(const void* raw, size_t size) {
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* data_source_name */:
        ::protozero::internal::gen_helpers::DeserializeString(field, &data_source_name_);
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string UnregisterDataSourceRequest::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> UnregisterDataSourceRequest::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void UnregisterDataSourceRequest::Serialize(::protozero::Message* msg) const {
  // Field 1: data_source_name
  if (_has_field_[1]) {
    ::protozero::internal::gen_helpers::SerializeString(1, data_source_name_, msg);
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}


UpdateDataSourceResponse::UpdateDataSourceResponse() = default;
UpdateDataSourceResponse::~UpdateDataSourceResponse() = default;
UpdateDataSourceResponse::UpdateDataSourceResponse(const UpdateDataSourceResponse&) = default;
UpdateDataSourceResponse& UpdateDataSourceResponse::operator=(const UpdateDataSourceResponse&) = default;
UpdateDataSourceResponse::UpdateDataSourceResponse(UpdateDataSourceResponse&&) noexcept = default;
UpdateDataSourceResponse& UpdateDataSourceResponse::operator=(UpdateDataSourceResponse&&) = default;

bool UpdateDataSourceResponse::operator==(const UpdateDataSourceResponse& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_);
}

bool UpdateDataSourceResponse::ParseFromArray(const void* raw, size_t size) {
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string UpdateDataSourceResponse::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> UpdateDataSourceResponse::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void UpdateDataSourceResponse::Serialize(::protozero::Message* msg) const {
  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}


UpdateDataSourceRequest::UpdateDataSourceRequest() = default;
UpdateDataSourceRequest::~UpdateDataSourceRequest() = default;
UpdateDataSourceRequest::UpdateDataSourceRequest(const UpdateDataSourceRequest&) = default;
UpdateDataSourceRequest& UpdateDataSourceRequest::operator=(const UpdateDataSourceRequest&) = default;
UpdateDataSourceRequest::UpdateDataSourceRequest(UpdateDataSourceRequest&&) noexcept = default;
UpdateDataSourceRequest& UpdateDataSourceRequest::operator=(UpdateDataSourceRequest&&) = default;

bool UpdateDataSourceRequest::operator==(const UpdateDataSourceRequest& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(data_source_descriptor_, other.data_source_descriptor_);
}

bool UpdateDataSourceRequest::ParseFromArray(const void* raw, size_t size) {
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* data_source_descriptor */:
        (*data_source_descriptor_).ParseFromArray(field.data(), field.size());
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string UpdateDataSourceRequest::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> UpdateDataSourceRequest::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void UpdateDataSourceRequest::Serialize(::protozero::Message* msg) const {
  // Field 1: data_source_descriptor
  if (_has_field_[1]) {
    (*data_source_descriptor_).Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}


RegisterDataSourceResponse::RegisterDataSourceResponse() = default;
RegisterDataSourceResponse::~RegisterDataSourceResponse() = default;
RegisterDataSourceResponse::RegisterDataSourceResponse(const RegisterDataSourceResponse&) = default;
RegisterDataSourceResponse& RegisterDataSourceResponse::operator=(const RegisterDataSourceResponse&) = default;
RegisterDataSourceResponse::RegisterDataSourceResponse(RegisterDataSourceResponse&&) noexcept = default;
RegisterDataSourceResponse& RegisterDataSourceResponse::operator=(RegisterDataSourceResponse&&) = default;

bool RegisterDataSourceResponse::operator==(const RegisterDataSourceResponse& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(error_, other.error_);
}

bool RegisterDataSourceResponse::ParseFromArray(const void* raw, size_t size) {
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* error */:
        ::protozero::internal::gen_helpers::DeserializeString(field, &error_);
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string RegisterDataSourceResponse::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> RegisterDataSourceResponse::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void RegisterDataSourceResponse::Serialize(::protozero::Message* msg) const {
  // Field 1: error
  if (_has_field_[1]) {
    ::protozero::internal::gen_helpers::SerializeString(1, error_, msg);
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}


RegisterDataSourceRequest::RegisterDataSourceRequest() = default;
RegisterDataSourceRequest::~RegisterDataSourceRequest() = default;
RegisterDataSourceRequest::RegisterDataSourceRequest(const RegisterDataSourceRequest&) = default;
RegisterDataSourceRequest& RegisterDataSourceRequest::operator=(const RegisterDataSourceRequest&) = default;
RegisterDataSourceRequest::RegisterDataSourceRequest(RegisterDataSourceRequest&&) noexcept = default;
RegisterDataSourceRequest& RegisterDataSourceRequest::operator=(RegisterDataSourceRequest&&) = default;

bool RegisterDataSourceRequest::operator==(const RegisterDataSourceRequest& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(data_source_descriptor_, other.data_source_descriptor_);
}

bool RegisterDataSourceRequest::ParseFromArray(const void* raw, size_t size) {
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* data_source_descriptor */:
        (*data_source_descriptor_).ParseFromArray(field.data(), field.size());
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string RegisterDataSourceRequest::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> RegisterDataSourceRequest::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void RegisterDataSourceRequest::Serialize(::protozero::Message* msg) const {
  // Field 1: data_source_descriptor
  if (_has_field_[1]) {
    (*data_source_descriptor_).Serialize(msg->BeginNestedMessage<::protozero::Message>(1));
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}


InitializeConnectionResponse::InitializeConnectionResponse() = default;
InitializeConnectionResponse::~InitializeConnectionResponse() = default;
InitializeConnectionResponse::InitializeConnectionResponse(const InitializeConnectionResponse&) = default;
InitializeConnectionResponse& InitializeConnectionResponse::operator=(const InitializeConnectionResponse&) = default;
InitializeConnectionResponse::InitializeConnectionResponse(InitializeConnectionResponse&&) noexcept = default;
InitializeConnectionResponse& InitializeConnectionResponse::operator=(InitializeConnectionResponse&&) = default;

bool InitializeConnectionResponse::operator==(const InitializeConnectionResponse& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(using_shmem_provided_by_producer_, other.using_shmem_provided_by_producer_)
   && ::protozero::internal::gen_helpers::EqualsField(direct_smb_patching_supported_, other.direct_smb_patching_supported_)
   && ::protozero::internal::gen_helpers::EqualsField(use_shmem_emulation_, other.use_shmem_emulation_);
}

bool InitializeConnectionResponse::ParseFromArray(const void* raw, size_t size) {
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* using_shmem_provided_by_producer */:
        field.get(&using_shmem_provided_by_producer_);
        break;
      case 2 /* direct_smb_patching_supported */:
        field.get(&direct_smb_patching_supported_);
        break;
      case 3 /* use_shmem_emulation */:
        field.get(&use_shmem_emulation_);
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string InitializeConnectionResponse::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> InitializeConnectionResponse::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void InitializeConnectionResponse::Serialize(::protozero::Message* msg) const {
  // Field 1: using_shmem_provided_by_producer
  if (_has_field_[1]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(1, using_shmem_provided_by_producer_, msg);
  }

  // Field 2: direct_smb_patching_supported
  if (_has_field_[2]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(2, direct_smb_patching_supported_, msg);
  }

  // Field 3: use_shmem_emulation
  if (_has_field_[3]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(3, use_shmem_emulation_, msg);
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}


InitializeConnectionRequest::InitializeConnectionRequest() = default;
InitializeConnectionRequest::~InitializeConnectionRequest() = default;
InitializeConnectionRequest::InitializeConnectionRequest(const InitializeConnectionRequest&) = default;
InitializeConnectionRequest& InitializeConnectionRequest::operator=(const InitializeConnectionRequest&) = default;
InitializeConnectionRequest::InitializeConnectionRequest(InitializeConnectionRequest&&) noexcept = default;
InitializeConnectionRequest& InitializeConnectionRequest::operator=(InitializeConnectionRequest&&) = default;

bool InitializeConnectionRequest::operator==(const InitializeConnectionRequest& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(shared_memory_page_size_hint_bytes_, other.shared_memory_page_size_hint_bytes_)
   && ::protozero::internal::gen_helpers::EqualsField(shared_memory_size_hint_bytes_, other.shared_memory_size_hint_bytes_)
   && ::protozero::internal::gen_helpers::EqualsField(producer_name_, other.producer_name_)
   && ::protozero::internal::gen_helpers::EqualsField(smb_scraping_mode_, other.smb_scraping_mode_)
   && ::protozero::internal::gen_helpers::EqualsField(producer_provided_shmem_, other.producer_provided_shmem_)
   && ::protozero::internal::gen_helpers::EqualsField(sdk_version_, other.sdk_version_)
   && ::protozero::internal::gen_helpers::EqualsField(shm_key_windows_, other.shm_key_windows_);
}

bool InitializeConnectionRequest::ParseFromArray(const void* raw, size_t size) {
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* shared_memory_page_size_hint_bytes */:
        field.get(&shared_memory_page_size_hint_bytes_);
        break;
      case 2 /* shared_memory_size_hint_bytes */:
        field.get(&shared_memory_size_hint_bytes_);
        break;
      case 3 /* producer_name */:
        ::protozero::internal::gen_helpers::DeserializeString(field, &producer_name_);
        break;
      case 4 /* smb_scraping_mode */:
        field.get(&smb_scraping_mode_);
        break;
      case 6 /* producer_provided_shmem */:
        field.get(&producer_provided_shmem_);
        break;
      case 8 /* sdk_version */:
        ::protozero::internal::gen_helpers::DeserializeString(field, &sdk_version_);
        break;
      case 7 /* shm_key_windows */:
        ::protozero::internal::gen_helpers::DeserializeString(field, &shm_key_windows_);
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string InitializeConnectionRequest::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> InitializeConnectionRequest::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void InitializeConnectionRequest::Serialize(::protozero::Message* msg) const {
  // Field 1: shared_memory_page_size_hint_bytes
  if (_has_field_[1]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(1, shared_memory_page_size_hint_bytes_, msg);
  }

  // Field 2: shared_memory_size_hint_bytes
  if (_has_field_[2]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(2, shared_memory_size_hint_bytes_, msg);
  }

  // Field 3: producer_name
  if (_has_field_[3]) {
    ::protozero::internal::gen_helpers::SerializeString(3, producer_name_, msg);
  }

  // Field 4: smb_scraping_mode
  if (_has_field_[4]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(4, smb_scraping_mode_, msg);
  }

  // Field 6: producer_provided_shmem
  if (_has_field_[6]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(6, producer_provided_shmem_, msg);
  }

  // Field 8: sdk_version
  if (_has_field_[8]) {
    ::protozero::internal::gen_helpers::SerializeString(8, sdk_version_, msg);
  }

  // Field 7: shm_key_windows
  if (_has_field_[7]) {
    ::protozero::internal::gen_helpers::SerializeString(7, shm_key_windows_, msg);
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}

}  // namespace perfetto
}  // namespace protos
}  // namespace gen
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic pop
#endif
// gen_amalgamated begin source: gen/protos/perfetto/ipc/relay_port.gen.cc
// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wfloat-equal"
#endif
// gen_amalgamated expanded: #include "protos/perfetto/ipc/relay_port.gen.h"

namespace perfetto {
namespace protos {
namespace gen {

SyncClockResponse::SyncClockResponse() = default;
SyncClockResponse::~SyncClockResponse() = default;
SyncClockResponse::SyncClockResponse(const SyncClockResponse&) = default;
SyncClockResponse& SyncClockResponse::operator=(const SyncClockResponse&) = default;
SyncClockResponse::SyncClockResponse(SyncClockResponse&&) noexcept = default;
SyncClockResponse& SyncClockResponse::operator=(SyncClockResponse&&) = default;

bool SyncClockResponse::operator==(const SyncClockResponse& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_);
}

bool SyncClockResponse::ParseFromArray(const void* raw, size_t size) {
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string SyncClockResponse::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> SyncClockResponse::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void SyncClockResponse::Serialize(::protozero::Message* msg) const {
  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}


SyncClockRequest::SyncClockRequest() = default;
SyncClockRequest::~SyncClockRequest() = default;
SyncClockRequest::SyncClockRequest(const SyncClockRequest&) = default;
SyncClockRequest& SyncClockRequest::operator=(const SyncClockRequest&) = default;
SyncClockRequest::SyncClockRequest(SyncClockRequest&&) noexcept = default;
SyncClockRequest& SyncClockRequest::operator=(SyncClockRequest&&) = default;

bool SyncClockRequest::operator==(const SyncClockRequest& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(phase_, other.phase_)
   && ::protozero::internal::gen_helpers::EqualsField(clocks_, other.clocks_);
}

int SyncClockRequest::clocks_size() const { return static_cast<int>(clocks_.size()); }
void SyncClockRequest::clear_clocks() { clocks_.clear(); }
SyncClockRequest_Clock* SyncClockRequest::add_clocks() { clocks_.emplace_back(); return &clocks_.back(); }
bool SyncClockRequest::ParseFromArray(const void* raw, size_t size) {
  clocks_.clear();
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* phase */:
        field.get(&phase_);
        break;
      case 2 /* clocks */:
        clocks_.emplace_back();
        clocks_.back().ParseFromArray(field.data(), field.size());
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string SyncClockRequest::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> SyncClockRequest::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void SyncClockRequest::Serialize(::protozero::Message* msg) const {
  // Field 1: phase
  if (_has_field_[1]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(1, phase_, msg);
  }

  // Field 2: clocks
  for (auto& it : clocks_) {
    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(2));
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}


SyncClockRequest_Clock::SyncClockRequest_Clock() = default;
SyncClockRequest_Clock::~SyncClockRequest_Clock() = default;
SyncClockRequest_Clock::SyncClockRequest_Clock(const SyncClockRequest_Clock&) = default;
SyncClockRequest_Clock& SyncClockRequest_Clock::operator=(const SyncClockRequest_Clock&) = default;
SyncClockRequest_Clock::SyncClockRequest_Clock(SyncClockRequest_Clock&&) noexcept = default;
SyncClockRequest_Clock& SyncClockRequest_Clock::operator=(SyncClockRequest_Clock&&) = default;

bool SyncClockRequest_Clock::operator==(const SyncClockRequest_Clock& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(clock_id_, other.clock_id_)
   && ::protozero::internal::gen_helpers::EqualsField(timestamp_, other.timestamp_);
}

bool SyncClockRequest_Clock::ParseFromArray(const void* raw, size_t size) {
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* clock_id */:
        field.get(&clock_id_);
        break;
      case 2 /* timestamp */:
        field.get(&timestamp_);
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string SyncClockRequest_Clock::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> SyncClockRequest_Clock::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void SyncClockRequest_Clock::Serialize(::protozero::Message* msg) const {
  // Field 1: clock_id
  if (_has_field_[1]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(1, clock_id_, msg);
  }

  // Field 2: timestamp
  if (_has_field_[2]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(2, timestamp_, msg);
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}

}  // namespace perfetto
}  // namespace protos
}  // namespace gen
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic pop
#endif
// gen_amalgamated begin source: gen/protos/perfetto/ipc/wire_protocol.gen.cc
// gen_amalgamated expanded: #include "perfetto/protozero/gen_field_helpers.h"
// gen_amalgamated expanded: #include "perfetto/protozero/message.h"
// gen_amalgamated expanded: #include "perfetto/protozero/packed_repeated_fields.h"
// gen_amalgamated expanded: #include "perfetto/protozero/proto_decoder.h"
// gen_amalgamated expanded: #include "perfetto/protozero/scattered_heap_buffer.h"
// DO NOT EDIT. Autogenerated by Perfetto cppgen_plugin
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wfloat-equal"
#endif
// gen_amalgamated expanded: #include "protos/perfetto/ipc/wire_protocol.gen.h"

namespace perfetto {
namespace protos {
namespace gen {

IPCFrame::IPCFrame() = default;
IPCFrame::~IPCFrame() = default;
IPCFrame::IPCFrame(const IPCFrame&) = default;
IPCFrame& IPCFrame::operator=(const IPCFrame&) = default;
IPCFrame::IPCFrame(IPCFrame&&) noexcept = default;
IPCFrame& IPCFrame::operator=(IPCFrame&&) = default;

bool IPCFrame::operator==(const IPCFrame& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(request_id_, other.request_id_)
   && ::protozero::internal::gen_helpers::EqualsField(msg_bind_service_, other.msg_bind_service_)
   && ::protozero::internal::gen_helpers::EqualsField(msg_bind_service_reply_, other.msg_bind_service_reply_)
   && ::protozero::internal::gen_helpers::EqualsField(msg_invoke_method_, other.msg_invoke_method_)
   && ::protozero::internal::gen_helpers::EqualsField(msg_invoke_method_reply_, other.msg_invoke_method_reply_)
   && ::protozero::internal::gen_helpers::EqualsField(msg_request_error_, other.msg_request_error_)
   && ::protozero::internal::gen_helpers::EqualsField(set_peer_identity_, other.set_peer_identity_)
   && ::protozero::internal::gen_helpers::EqualsField(data_for_testing_, other.data_for_testing_);
}

bool IPCFrame::ParseFromArray(const void* raw, size_t size) {
  data_for_testing_.clear();
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 2 /* request_id */:
        field.get(&request_id_);
        break;
      case 3 /* msg_bind_service */:
        (*msg_bind_service_).ParseFromArray(field.data(), field.size());
        break;
      case 4 /* msg_bind_service_reply */:
        (*msg_bind_service_reply_).ParseFromArray(field.data(), field.size());
        break;
      case 5 /* msg_invoke_method */:
        (*msg_invoke_method_).ParseFromArray(field.data(), field.size());
        break;
      case 6 /* msg_invoke_method_reply */:
        (*msg_invoke_method_reply_).ParseFromArray(field.data(), field.size());
        break;
      case 7 /* msg_request_error */:
        (*msg_request_error_).ParseFromArray(field.data(), field.size());
        break;
      case 8 /* set_peer_identity */:
        (*set_peer_identity_).ParseFromArray(field.data(), field.size());
        break;
      case 1 /* data_for_testing */:
        data_for_testing_.emplace_back();
        field.get(&data_for_testing_.back());
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string IPCFrame::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> IPCFrame::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void IPCFrame::Serialize(::protozero::Message* msg) const {
  // Field 2: request_id
  if (_has_field_[2]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(2, request_id_, msg);
  }

  // Field 3: msg_bind_service
  if (_has_field_[3]) {
    (*msg_bind_service_).Serialize(msg->BeginNestedMessage<::protozero::Message>(3));
  }

  // Field 4: msg_bind_service_reply
  if (_has_field_[4]) {
    (*msg_bind_service_reply_).Serialize(msg->BeginNestedMessage<::protozero::Message>(4));
  }

  // Field 5: msg_invoke_method
  if (_has_field_[5]) {
    (*msg_invoke_method_).Serialize(msg->BeginNestedMessage<::protozero::Message>(5));
  }

  // Field 6: msg_invoke_method_reply
  if (_has_field_[6]) {
    (*msg_invoke_method_reply_).Serialize(msg->BeginNestedMessage<::protozero::Message>(6));
  }

  // Field 7: msg_request_error
  if (_has_field_[7]) {
    (*msg_request_error_).Serialize(msg->BeginNestedMessage<::protozero::Message>(7));
  }

  // Field 8: set_peer_identity
  if (_has_field_[8]) {
    (*set_peer_identity_).Serialize(msg->BeginNestedMessage<::protozero::Message>(8));
  }

  // Field 1: data_for_testing
  for (auto& it : data_for_testing_) {
    ::protozero::internal::gen_helpers::SerializeString(1, it, msg);
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}


IPCFrame_SetPeerIdentity::IPCFrame_SetPeerIdentity() = default;
IPCFrame_SetPeerIdentity::~IPCFrame_SetPeerIdentity() = default;
IPCFrame_SetPeerIdentity::IPCFrame_SetPeerIdentity(const IPCFrame_SetPeerIdentity&) = default;
IPCFrame_SetPeerIdentity& IPCFrame_SetPeerIdentity::operator=(const IPCFrame_SetPeerIdentity&) = default;
IPCFrame_SetPeerIdentity::IPCFrame_SetPeerIdentity(IPCFrame_SetPeerIdentity&&) noexcept = default;
IPCFrame_SetPeerIdentity& IPCFrame_SetPeerIdentity::operator=(IPCFrame_SetPeerIdentity&&) = default;

bool IPCFrame_SetPeerIdentity::operator==(const IPCFrame_SetPeerIdentity& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(pid_, other.pid_)
   && ::protozero::internal::gen_helpers::EqualsField(uid_, other.uid_)
   && ::protozero::internal::gen_helpers::EqualsField(machine_id_hint_, other.machine_id_hint_);
}

bool IPCFrame_SetPeerIdentity::ParseFromArray(const void* raw, size_t size) {
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* pid */:
        field.get(&pid_);
        break;
      case 2 /* uid */:
        field.get(&uid_);
        break;
      case 3 /* machine_id_hint */:
        ::protozero::internal::gen_helpers::DeserializeString(field, &machine_id_hint_);
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string IPCFrame_SetPeerIdentity::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> IPCFrame_SetPeerIdentity::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void IPCFrame_SetPeerIdentity::Serialize(::protozero::Message* msg) const {
  // Field 1: pid
  if (_has_field_[1]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(1, pid_, msg);
  }

  // Field 2: uid
  if (_has_field_[2]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(2, uid_, msg);
  }

  // Field 3: machine_id_hint
  if (_has_field_[3]) {
    ::protozero::internal::gen_helpers::SerializeString(3, machine_id_hint_, msg);
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}


IPCFrame_RequestError::IPCFrame_RequestError() = default;
IPCFrame_RequestError::~IPCFrame_RequestError() = default;
IPCFrame_RequestError::IPCFrame_RequestError(const IPCFrame_RequestError&) = default;
IPCFrame_RequestError& IPCFrame_RequestError::operator=(const IPCFrame_RequestError&) = default;
IPCFrame_RequestError::IPCFrame_RequestError(IPCFrame_RequestError&&) noexcept = default;
IPCFrame_RequestError& IPCFrame_RequestError::operator=(IPCFrame_RequestError&&) = default;

bool IPCFrame_RequestError::operator==(const IPCFrame_RequestError& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(error_, other.error_);
}

bool IPCFrame_RequestError::ParseFromArray(const void* raw, size_t size) {
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* error */:
        ::protozero::internal::gen_helpers::DeserializeString(field, &error_);
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string IPCFrame_RequestError::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> IPCFrame_RequestError::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void IPCFrame_RequestError::Serialize(::protozero::Message* msg) const {
  // Field 1: error
  if (_has_field_[1]) {
    ::protozero::internal::gen_helpers::SerializeString(1, error_, msg);
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}


IPCFrame_InvokeMethodReply::IPCFrame_InvokeMethodReply() = default;
IPCFrame_InvokeMethodReply::~IPCFrame_InvokeMethodReply() = default;
IPCFrame_InvokeMethodReply::IPCFrame_InvokeMethodReply(const IPCFrame_InvokeMethodReply&) = default;
IPCFrame_InvokeMethodReply& IPCFrame_InvokeMethodReply::operator=(const IPCFrame_InvokeMethodReply&) = default;
IPCFrame_InvokeMethodReply::IPCFrame_InvokeMethodReply(IPCFrame_InvokeMethodReply&&) noexcept = default;
IPCFrame_InvokeMethodReply& IPCFrame_InvokeMethodReply::operator=(IPCFrame_InvokeMethodReply&&) = default;

bool IPCFrame_InvokeMethodReply::operator==(const IPCFrame_InvokeMethodReply& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(success_, other.success_)
   && ::protozero::internal::gen_helpers::EqualsField(has_more_, other.has_more_)
   && ::protozero::internal::gen_helpers::EqualsField(reply_proto_, other.reply_proto_);
}

bool IPCFrame_InvokeMethodReply::ParseFromArray(const void* raw, size_t size) {
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* success */:
        field.get(&success_);
        break;
      case 2 /* has_more */:
        field.get(&has_more_);
        break;
      case 3 /* reply_proto */:
        field.get(&reply_proto_);
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string IPCFrame_InvokeMethodReply::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> IPCFrame_InvokeMethodReply::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void IPCFrame_InvokeMethodReply::Serialize(::protozero::Message* msg) const {
  // Field 1: success
  if (_has_field_[1]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(1, success_, msg);
  }

  // Field 2: has_more
  if (_has_field_[2]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(2, has_more_, msg);
  }

  // Field 3: reply_proto
  if (_has_field_[3]) {
    ::protozero::internal::gen_helpers::SerializeString(3, reply_proto_, msg);
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}


IPCFrame_InvokeMethod::IPCFrame_InvokeMethod() = default;
IPCFrame_InvokeMethod::~IPCFrame_InvokeMethod() = default;
IPCFrame_InvokeMethod::IPCFrame_InvokeMethod(const IPCFrame_InvokeMethod&) = default;
IPCFrame_InvokeMethod& IPCFrame_InvokeMethod::operator=(const IPCFrame_InvokeMethod&) = default;
IPCFrame_InvokeMethod::IPCFrame_InvokeMethod(IPCFrame_InvokeMethod&&) noexcept = default;
IPCFrame_InvokeMethod& IPCFrame_InvokeMethod::operator=(IPCFrame_InvokeMethod&&) = default;

bool IPCFrame_InvokeMethod::operator==(const IPCFrame_InvokeMethod& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(service_id_, other.service_id_)
   && ::protozero::internal::gen_helpers::EqualsField(method_id_, other.method_id_)
   && ::protozero::internal::gen_helpers::EqualsField(args_proto_, other.args_proto_)
   && ::protozero::internal::gen_helpers::EqualsField(drop_reply_, other.drop_reply_);
}

bool IPCFrame_InvokeMethod::ParseFromArray(const void* raw, size_t size) {
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* service_id */:
        field.get(&service_id_);
        break;
      case 2 /* method_id */:
        field.get(&method_id_);
        break;
      case 3 /* args_proto */:
        field.get(&args_proto_);
        break;
      case 4 /* drop_reply */:
        field.get(&drop_reply_);
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string IPCFrame_InvokeMethod::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> IPCFrame_InvokeMethod::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void IPCFrame_InvokeMethod::Serialize(::protozero::Message* msg) const {
  // Field 1: service_id
  if (_has_field_[1]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(1, service_id_, msg);
  }

  // Field 2: method_id
  if (_has_field_[2]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(2, method_id_, msg);
  }

  // Field 3: args_proto
  if (_has_field_[3]) {
    ::protozero::internal::gen_helpers::SerializeString(3, args_proto_, msg);
  }

  // Field 4: drop_reply
  if (_has_field_[4]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(4, drop_reply_, msg);
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}


IPCFrame_BindServiceReply::IPCFrame_BindServiceReply() = default;
IPCFrame_BindServiceReply::~IPCFrame_BindServiceReply() = default;
IPCFrame_BindServiceReply::IPCFrame_BindServiceReply(const IPCFrame_BindServiceReply&) = default;
IPCFrame_BindServiceReply& IPCFrame_BindServiceReply::operator=(const IPCFrame_BindServiceReply&) = default;
IPCFrame_BindServiceReply::IPCFrame_BindServiceReply(IPCFrame_BindServiceReply&&) noexcept = default;
IPCFrame_BindServiceReply& IPCFrame_BindServiceReply::operator=(IPCFrame_BindServiceReply&&) = default;

bool IPCFrame_BindServiceReply::operator==(const IPCFrame_BindServiceReply& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(success_, other.success_)
   && ::protozero::internal::gen_helpers::EqualsField(service_id_, other.service_id_)
   && ::protozero::internal::gen_helpers::EqualsField(methods_, other.methods_);
}

int IPCFrame_BindServiceReply::methods_size() const { return static_cast<int>(methods_.size()); }
void IPCFrame_BindServiceReply::clear_methods() { methods_.clear(); }
IPCFrame_BindServiceReply_MethodInfo* IPCFrame_BindServiceReply::add_methods() { methods_.emplace_back(); return &methods_.back(); }
bool IPCFrame_BindServiceReply::ParseFromArray(const void* raw, size_t size) {
  methods_.clear();
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* success */:
        field.get(&success_);
        break;
      case 2 /* service_id */:
        field.get(&service_id_);
        break;
      case 3 /* methods */:
        methods_.emplace_back();
        methods_.back().ParseFromArray(field.data(), field.size());
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string IPCFrame_BindServiceReply::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> IPCFrame_BindServiceReply::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void IPCFrame_BindServiceReply::Serialize(::protozero::Message* msg) const {
  // Field 1: success
  if (_has_field_[1]) {
    ::protozero::internal::gen_helpers::SerializeTinyVarInt(1, success_, msg);
  }

  // Field 2: service_id
  if (_has_field_[2]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(2, service_id_, msg);
  }

  // Field 3: methods
  for (auto& it : methods_) {
    it.Serialize(msg->BeginNestedMessage<::protozero::Message>(3));
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}


IPCFrame_BindServiceReply_MethodInfo::IPCFrame_BindServiceReply_MethodInfo() = default;
IPCFrame_BindServiceReply_MethodInfo::~IPCFrame_BindServiceReply_MethodInfo() = default;
IPCFrame_BindServiceReply_MethodInfo::IPCFrame_BindServiceReply_MethodInfo(const IPCFrame_BindServiceReply_MethodInfo&) = default;
IPCFrame_BindServiceReply_MethodInfo& IPCFrame_BindServiceReply_MethodInfo::operator=(const IPCFrame_BindServiceReply_MethodInfo&) = default;
IPCFrame_BindServiceReply_MethodInfo::IPCFrame_BindServiceReply_MethodInfo(IPCFrame_BindServiceReply_MethodInfo&&) noexcept = default;
IPCFrame_BindServiceReply_MethodInfo& IPCFrame_BindServiceReply_MethodInfo::operator=(IPCFrame_BindServiceReply_MethodInfo&&) = default;

bool IPCFrame_BindServiceReply_MethodInfo::operator==(const IPCFrame_BindServiceReply_MethodInfo& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(id_, other.id_)
   && ::protozero::internal::gen_helpers::EqualsField(name_, other.name_);
}

bool IPCFrame_BindServiceReply_MethodInfo::ParseFromArray(const void* raw, size_t size) {
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* id */:
        field.get(&id_);
        break;
      case 2 /* name */:
        ::protozero::internal::gen_helpers::DeserializeString(field, &name_);
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string IPCFrame_BindServiceReply_MethodInfo::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> IPCFrame_BindServiceReply_MethodInfo::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void IPCFrame_BindServiceReply_MethodInfo::Serialize(::protozero::Message* msg) const {
  // Field 1: id
  if (_has_field_[1]) {
    ::protozero::internal::gen_helpers::SerializeVarInt(1, id_, msg);
  }

  // Field 2: name
  if (_has_field_[2]) {
    ::protozero::internal::gen_helpers::SerializeString(2, name_, msg);
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}


IPCFrame_BindService::IPCFrame_BindService() = default;
IPCFrame_BindService::~IPCFrame_BindService() = default;
IPCFrame_BindService::IPCFrame_BindService(const IPCFrame_BindService&) = default;
IPCFrame_BindService& IPCFrame_BindService::operator=(const IPCFrame_BindService&) = default;
IPCFrame_BindService::IPCFrame_BindService(IPCFrame_BindService&&) noexcept = default;
IPCFrame_BindService& IPCFrame_BindService::operator=(IPCFrame_BindService&&) = default;

bool IPCFrame_BindService::operator==(const IPCFrame_BindService& other) const {
  return ::protozero::internal::gen_helpers::EqualsField(unknown_fields_, other.unknown_fields_)
   && ::protozero::internal::gen_helpers::EqualsField(service_name_, other.service_name_);
}

bool IPCFrame_BindService::ParseFromArray(const void* raw, size_t size) {
  unknown_fields_.clear();
  bool packed_error = false;

  ::protozero::ProtoDecoder dec(raw, size);
  for (auto field = dec.ReadField(); field.valid(); field = dec.ReadField()) {
    if (field.id() < _has_field_.size()) {
      _has_field_.set(field.id());
    }
    switch (field.id()) {
      case 1 /* service_name */:
        ::protozero::internal::gen_helpers::DeserializeString(field, &service_name_);
        break;
      default:
        field.SerializeAndAppendTo(&unknown_fields_);
        break;
    }
  }
  return !packed_error && !dec.bytes_left();
}

std::string IPCFrame_BindService::SerializeAsString() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsString();
}

std::vector<uint8_t> IPCFrame_BindService::SerializeAsArray() const {
  ::protozero::internal::gen_helpers::MessageSerializer msg;
  Serialize(msg.get());
  return msg.SerializeAsArray();
}

void IPCFrame_BindService::Serialize(::protozero::Message* msg) const {
  // Field 1: service_name
  if (_has_field_[1]) {
    ::protozero::internal::gen_helpers::SerializeString(1, service_name_, msg);
  }

  protozero::internal::gen_helpers::SerializeUnknownFields(unknown_fields_, msg);
}

}  // namespace perfetto
}  // namespace protos
}  // namespace gen
#if defined(__GNUC__) || defined(__clang__)
#pragma GCC diagnostic pop
#endif
// gen_amalgamated begin source: src/base/unix_socket.cc
// gen_amalgamated begin header: include/perfetto/ext/base/unix_socket.h
/*
 * Copyright (C) 2017 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef INCLUDE_PERFETTO_EXT_BASE_UNIX_SOCKET_H_
#define INCLUDE_PERFETTO_EXT_BASE_UNIX_SOCKET_H_

#include <stdint.h>
#include <sys/types.h>

#include <memory>
#include <string>
#include <utility>

// gen_amalgamated expanded: #include "perfetto/base/build_config.h"
// gen_amalgamated expanded: #include "perfetto/base/compiler.h"
// gen_amalgamated expanded: #include "perfetto/base/export.h"
// gen_amalgamated expanded: #include "perfetto/base/logging.h"
// gen_amalgamated expanded: #include "perfetto/base/platform_handle.h"
// gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"
// gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
// gen_amalgamated expanded: #include "perfetto/ext/base/weak_ptr.h"

struct msghdr;

namespace perfetto {
namespace base {

// Define the ScopedSocketHandle type.

#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
int CloseSocket(SocketHandle);   // A wrapper around ::closesocket().
using ScopedSocketHandle =
    ScopedResource<SocketHandle, CloseSocket, static_cast<SocketHandle>(-1)>;
#else
using ScopedSocketHandle = ScopedFile;
#endif

class TaskRunner;

// Use arbitrarily high values to avoid that some code accidentally ends up
// assuming that these enum values match the sysroot's SOCK_xxx defines rather
// than using MkSockType() / MkSockFamily().
enum class SockType { kStream = 100, kDgram, kSeqPacket };
enum class SockFamily { kUnspec = 0, kUnix = 200, kInet, kInet6, kVsock };

// Controls the getsockopt(SO_PEERCRED) behavior, which allows to obtain the
// peer credentials.
enum class SockPeerCredMode {
  // Obtain the peer credentials immediately after connection and cache them.
  kReadOnConnect = 0,

  // Don't read peer credentials at all. Calls to peer_uid()/peer_pid() will
  // hit a DCHECK and return kInvalidUid/Pid in release builds.
  kIgnore = 1,

#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) || \
    PERFETTO_BUILDFLAG(PERFETTO_OS_FUCHSIA)
  kDefault = kIgnore,
#else
  kDefault = kReadOnConnect,
#endif
};

// Returns the socket family from the full addres that perfetto uses.
// Addr can be:
// - /path/to/socket : for linked AF_UNIX sockets.
// - @abstract_name  : for abstract AF_UNIX sockets.
// - 1.2.3.4:8080    : for Inet sockets.
// - [::1]:8080      : for Inet6 sockets.
// - vsock://-1:3000 : for VM sockets.
SockFamily GetSockFamily(const char* addr);

// Returns whether inter-process shared memory is supported for the socket.
inline bool SockShmemSupported(SockFamily sock_family) {
#if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
  return sock_family == SockFamily::kUnix;
#else
  base::ignore_result(sock_family);
  // On Windows shm is negotiated by sharing an unguessable token
  // over TCP sockets. In theory works on any socket type, in practice
  // we need to tell the difference between a local and a remote
  // connection. For now we assume everything is local.
  // See comments on r.android.com/2951909 .
  return true;
#endif
}
inline bool SockShmemSupported(const char* addr) {
  return SockShmemSupported(GetSockFamily(addr));
}

// UnixSocketRaw is a basic wrapper around sockets. It exposes wrapper
// methods that take care of most common pitfalls (e.g., marking fd as
// O_CLOEXEC, avoiding SIGPIPE, properly handling partial writes). It is used as
// a building block for the more sophisticated UnixSocket class which depends
// on base::TaskRunner.
class UnixSocketRaw {
 public:
  // Creates a new unconnected unix socket.
  static UnixSocketRaw CreateMayFail(SockFamily family, SockType type);

#if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
  // Crates a pair of connected sockets.
  static std::pair<UnixSocketRaw, UnixSocketRaw> CreatePairPosix(SockFamily,
                                                                 SockType);
#endif

  // Creates an uninitialized unix socket.
  UnixSocketRaw();

  // Creates a unix socket adopting an existing file descriptor. This is
  // typically used to inherit fds from init via environment variables.
  UnixSocketRaw(ScopedSocketHandle, SockFamily, SockType);

  ~UnixSocketRaw() = default;
  UnixSocketRaw(UnixSocketRaw&&) noexcept = default;
  UnixSocketRaw& operator=(UnixSocketRaw&&) = default;

  bool Bind(const std::string& socket_name);
  bool Listen();
  bool Connect(const std::string& socket_name);
  bool SetTxTimeout(uint32_t timeout_ms);
  bool SetRxTimeout(uint32_t timeout_ms);
  void Shutdown();
  void SetBlocking(bool);
  void DcheckIsBlocking(bool expected) const;  // No-op on release and Win.
  void SetRetainOnExec(bool retain);
  std::string GetSockAddr() const;
  SockType type() const { return type_; }
  SockFamily family() const { return family_; }
  SocketHandle fd() const { return *fd_; }
  explicit operator bool() const { return !!fd_; }

  // This is the handle that passed to TaskRunner.AddFileDescriptorWatch().
  // On UNIX this is just the socket FD. On Windows, we need to create a
  // dedicated event object.
  PlatformHandle watch_handle() const {
#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
    return *event_handle_;
#else
    return *fd_;
#endif
  }

  ScopedSocketHandle ReleaseFd() { return std::move(fd_); }

  // |send_fds| and |num_fds| are ignored on Windows.
  ssize_t Send(const void* msg,
               size_t len,
               const int* send_fds = nullptr,
               size_t num_fds = 0);

  ssize_t SendStr(const std::string& str) {
    return Send(str.data(), str.size());
  }

  // |fd_vec| and |max_files| are ignored on Windows.
  ssize_t Receive(void* msg,
                  size_t len,
                  ScopedFile* fd_vec = nullptr,
                  size_t max_files = 0);

#if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
  // UNIX-specific helpers to deal with SCM_RIGHTS.

  // Re-enter sendmsg until all the data has been sent or an error occurs.
  // TODO(fmayer): Figure out how to do timeouts here for heapprofd.
  ssize_t SendMsgAllPosix(struct msghdr* msg);

  // Exposed for testing only.
  // Update msghdr so subsequent sendmsg will send data that remains after n
  // bytes have already been sent.
  static void ShiftMsgHdrPosix(size_t n, struct msghdr* msg);
#endif

 private:
  UnixSocketRaw(SockFamily, SockType);

  UnixSocketRaw(const UnixSocketRaw&) = delete;
  UnixSocketRaw& operator=(const UnixSocketRaw&) = delete;

  ScopedSocketHandle fd_;
#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
  ScopedPlatformHandle event_handle_;
#endif
  SockFamily family_ = SockFamily::kUnix;
  SockType type_ = SockType::kStream;
  uint32_t tx_timeout_ms_ = 0;
};

// A non-blocking UNIX domain socket. Allows also to transfer file descriptors.
// None of the methods in this class are blocking.
// The main design goal is making strong guarantees on the EventListener
// callbacks, in order to avoid ending in some undefined state.
// In case of any error it will aggressively just shut down the socket and
// notify the failure with OnConnect(false) or OnDisconnect() depending on the
// state of the socket (see below).
// EventListener callbacks stop happening as soon as the instance is destroyed.
//
// Lifecycle of a client socket:
//
//                           Connect()
//                               |
//            +------------------+------------------+
//            | (success)                           | (failure or Shutdown())
//            V                                     V
//     OnConnect(true)                         OnConnect(false)
//            |
//            V
//    OnDataAvailable()
//            |
//            V
//     OnDisconnect()  (failure or shutdown)
//
//
// Lifecycle of a server socket:
//
//                          Listen()  --> returns false in case of errors.
//                             |
//                             V
//              OnNewIncomingConnection(new_socket)
//
//          (|new_socket| inherits the same EventListener)
//                             |
//                             V
//                     OnDataAvailable()
//                             | (failure or Shutdown())
//                             V
//                       OnDisconnect()
class PERFETTO_EXPORT_COMPONENT UnixSocket {
 public:
  class EventListener {
   public:
    EventListener() = default;
    virtual ~EventListener();

    EventListener(const EventListener&) = delete;
    EventListener& operator=(const EventListener&) = delete;

    EventListener(EventListener&&) noexcept = default;
    EventListener& operator=(EventListener&&) noexcept = default;

    // After Listen().
    // |self| may be null if the connection was not accepted via a listen
    // socket.
    virtual void OnNewIncomingConnection(
        UnixSocket* self,
        std::unique_ptr<UnixSocket> new_connection);

    // After Connect(), whether successful or not.
    virtual void OnConnect(UnixSocket* self, bool connected);

    // After a successful Connect() or OnNewIncomingConnection(). Either the
    // other endpoint did disconnect or some other error happened.
    virtual void OnDisconnect(UnixSocket* self);

    // Whenever there is data available to Receive(). Note that spurious FD
    // watch events are possible, so it is possible that Receive() soon after
    // OnDataAvailable() returns 0 (just ignore those).
    virtual void OnDataAvailable(UnixSocket* self);
  };

  enum class State {
    kDisconnected = 0,  // Failed connection, peer disconnection or Shutdown().
    kConnecting,  // Soon after Connect(), before it either succeeds or fails.
    kConnected,   // After a successful Connect().
    kListening    // After Listen(), until Shutdown().
  };

  // Creates a socket and starts listening. If SockFamily::kUnix and
  // |socket_name| starts with a '@', an abstract UNIX dmoain socket will be
  // created instead of a filesystem-linked UNIX socket (Linux/Android only).
  // If SockFamily::kInet, |socket_name| is host:port (e.g., "1.2.3.4:8000").
  // If SockFamily::kInet6, |socket_name| is [host]:port (e.g., "[::1]:8000").
  // Returns nullptr if the socket creation or bind fails. If listening fails,
  // (e.g. if another socket with the same name is already listening) the
  // returned socket will have is_listening() == false.
  static std::unique_ptr<UnixSocket> Listen(const std::string& socket_name,
                                            EventListener*,
                                            TaskRunner*,
                                            SockFamily,
                                            SockType);

  // Attaches to a pre-existing socket. The socket must have been created in
  // SOCK_STREAM mode and the caller must have called bind() on it.
  static std::unique_ptr<UnixSocket> Listen(ScopedSocketHandle,
                                            EventListener*,
                                            TaskRunner*,
                                            SockFamily,
                                            SockType);

  // Creates a Unix domain socket and connects to the listening endpoint.
  // Returns always an instance. EventListener::OnConnect(bool success) will
  // be called always, whether the connection succeeded or not.
  static std::unique_ptr<UnixSocket> Connect(
      const std::string& socket_name,
      EventListener*,
      TaskRunner*,
      SockFamily,
      SockType,
      SockPeerCredMode = SockPeerCredMode::kDefault);

  // Constructs a UnixSocket using the given connected socket.
  static std::unique_ptr<UnixSocket> AdoptConnected(
      ScopedSocketHandle,
      EventListener*,
      TaskRunner*,
      SockFamily,
      SockType,
      SockPeerCredMode = SockPeerCredMode::kDefault);

  UnixSocket(const UnixSocket&) = delete;
  UnixSocket& operator=(const UnixSocket&) = delete;
  // Cannot be easily moved because of tasks from the FileDescriptorWatch.
  UnixSocket(UnixSocket&&) = delete;
  UnixSocket& operator=(UnixSocket&&) = delete;

  // This class gives the hard guarantee that no callback is called on the
  // passed EventListener immediately after the object has been destroyed.
  // Any queued callback will be silently dropped.
  ~UnixSocket();

  // Shuts down the current connection, if any. If the socket was Listen()-ing,
  // stops listening. The socket goes back to kNotInitialized state, so it can
  // be reused with Listen() or Connect().
  void Shutdown(bool notify);

  void SetTxTimeout(uint32_t timeout_ms) {
    PERFETTO_CHECK(sock_raw_.SetTxTimeout(timeout_ms));
  }
  void SetRxTimeout(uint32_t timeout_ms) {
    PERFETTO_CHECK(sock_raw_.SetRxTimeout(timeout_ms));
  }

  std::string GetSockAddr() const { return sock_raw_.GetSockAddr(); }

  // Returns true is the message was queued, false if there was no space in the
  // output buffer, in which case the client should retry or give up.
  // If any other error happens the socket will be shutdown and
  // EventListener::OnDisconnect() will be called.
  // If the socket is not connected, Send() will just return false.
  // Does not append a null string terminator to msg in any case.
  bool Send(const void* msg, size_t len, const int* send_fds, size_t num_fds);

  inline bool Send(const void* msg, size_t len, int send_fd = -1) {
    if (send_fd != -1)
      return Send(msg, len, &send_fd, 1);
    return Send(msg, len, nullptr, 0);
  }

  inline bool SendStr(const std::string& msg) {
    return Send(msg.data(), msg.size(), -1);
  }

  // Returns the number of bytes (<= |len|) written in |msg| or 0 if there
  // is no data in the buffer to read or an error occurs (in which case a
  // EventListener::OnDisconnect() will follow).
  // If the ScopedFile pointer is not null and a FD is received, it moves the
  // received FD into that. If a FD is received but the ScopedFile pointer is
  // null, the FD will be automatically closed.
  size_t Receive(void* msg, size_t len, ScopedFile*, size_t max_files = 1);

  inline size_t Receive(void* msg, size_t len) {
    return Receive(msg, len, nullptr, 0);
  }

  // Only for tests. This is slower than Receive() as it requires a heap
  // allocation and a copy for the std::string. Guarantees that the returned
  // string is null terminated even if the underlying message sent by the peer
  // is not.
  std::string ReceiveString(size_t max_length = 1024);

  bool is_connected() const { return state_ == State::kConnected; }
  bool is_listening() const { return state_ == State::kListening; }
  SocketHandle fd() const { return sock_raw_.fd(); }
  SockFamily family() const { return sock_raw_.family(); }

  // User ID of the peer, as returned by the kernel. If the client disconnects
  // and the socket goes into the kDisconnected state, it retains the uid of
  // the last peer.
#if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) && \
    !PERFETTO_BUILDFLAG(PERFETTO_OS_FUCHSIA)
  uid_t peer_uid_posix(bool skip_check_for_testing = false) const {
    PERFETTO_DCHECK((!is_listening() && peer_uid_ != kInvalidUid) ||
                    skip_check_for_testing);

    return peer_uid_;
  }
#endif

#if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
    PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
  // Process ID of the peer, as returned by the kernel. If the client
  // disconnects and the socket goes into the kDisconnected state, it
  // retains the pid of the last peer.
  //
  // This is only available on Linux / Android.
  pid_t peer_pid_linux(bool skip_check_for_testing = false) const {
    PERFETTO_DCHECK((!is_listening() && peer_pid_ != kInvalidPid) ||
                    skip_check_for_testing);
    return peer_pid_;
  }
#endif

  // This makes the UnixSocket unusable.
  UnixSocketRaw ReleaseSocket();

 private:
  UnixSocket(EventListener*,
             TaskRunner*,
             SockFamily,
             SockType,
             SockPeerCredMode);
  UnixSocket(EventListener*,
             TaskRunner*,
             ScopedSocketHandle,
             State,
             SockFamily,
             SockType,
             SockPeerCredMode);

  // Called once by the corresponding public static factory methods.
  void DoConnect(const std::string& socket_name);

#if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
  void ReadPeerCredentialsPosix();
#endif

  void OnEvent();
  void NotifyConnectionState(bool success);

  UnixSocketRaw sock_raw_;
  State state_ = State::kDisconnected;
  SockPeerCredMode peer_cred_mode_ = SockPeerCredMode::kDefault;

#if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) && \
    !PERFETTO_BUILDFLAG(PERFETTO_OS_FUCHSIA)
  uid_t peer_uid_ = kInvalidUid;
#endif
#if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
    PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
  pid_t peer_pid_ = kInvalidPid;
#endif
  EventListener* const event_listener_;
  TaskRunner* const task_runner_;
  WeakPtrFactory<UnixSocket> weak_ptr_factory_;  // Keep last.
};

}  // namespace base
}  // namespace perfetto

#endif  // INCLUDE_PERFETTO_EXT_BASE_UNIX_SOCKET_H_
// gen_amalgamated begin header: src/base/vm_sockets.h
/*
 * Copyright (C) 2023 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef SRC_BASE_VM_SOCKETS_H_
#define SRC_BASE_VM_SOCKETS_H_

// gen_amalgamated expanded: #include "perfetto/base/build_config.h"

#if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
    PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)

#include <sys/socket.h>

#ifdef AF_VSOCK
// Use system vm_socket.h if avaialbe.
#include <linux/vm_sockets.h>
#else  // defined(AF_SOCK)
// Fallback and use the stripped copy from the UAPI vm_sockets.h.

#include <stdint.h>  // For uint8_t.

#define AF_VSOCK 40

struct sockaddr_vm {
  sa_family_t svm_family;
  unsigned short svm_reserved1;
  unsigned int svm_port;
  unsigned int svm_cid;
  uint8_t svm_flags;
  unsigned char svm_zero[sizeof(struct sockaddr) - sizeof(sa_family_t) -
                         sizeof(unsigned short) - sizeof(unsigned int) -
                         sizeof(unsigned int) - sizeof(uint8_t)];
};

#endif  // defined(AF_SOCK)

#endif  // PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) ||
        // PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)

#endif  // SRC_BASE_VM_SOCKETS_H_
/*
 * Copyright (C) 2017 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// gen_amalgamated expanded: #include "perfetto/ext/base/unix_socket.h"

#include <errno.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
// gen_amalgamated expanded: #include "perfetto/base/compiler.h"
// gen_amalgamated expanded: #include "perfetto/ext/base/string_utils.h"

#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
// The include order matters on these three Windows header groups.
#include <Windows.h>

#include <WS2tcpip.h>
#include <WinSock2.h>

#include <afunix.h>
#else
#include <arpa/inet.h>
#include <netdb.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <poll.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <unistd.h>
#endif

#if PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
#include <sys/ucred.h>
#endif

#include <algorithm>
#include <memory>

// gen_amalgamated expanded: #include "perfetto/base/build_config.h"
// gen_amalgamated expanded: #include "perfetto/base/logging.h"
// gen_amalgamated expanded: #include "perfetto/base/task_runner.h"
// gen_amalgamated expanded: #include "perfetto/base/time.h"
// gen_amalgamated expanded: #include "perfetto/ext/base/string_utils.h"
// gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"

#if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
    PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
// Use a local stripped copy of vm_sockets.h from UAPI.
// gen_amalgamated expanded: #include "src/base/vm_sockets.h"
#endif

namespace perfetto {
namespace base {

// The CMSG_* macros use NULL instead of nullptr.
// Note: MSVC doesn't have #pragma GCC diagnostic, hence the if __GNUC__.
#if defined(__GNUC__) && !PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant"
#endif

namespace {

// Android takes an int instead of socklen_t for the control buffer size.
#if PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
using CBufLenType = size_t;
#else
using CBufLenType = socklen_t;
#endif

#if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
    PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
constexpr char kVsockNamePrefix[] = "vsock://";
#endif

// A wrapper around variable-size sockaddr structs.
// This is solving the following problem: when calling connect() or bind(), the
// caller needs to take care to allocate the right struct (sockaddr_un for
// AF_UNIX, sockaddr_in for AF_INET).   Those structs have different sizes and,
// more importantly, are bigger than the base struct sockaddr.
struct SockaddrAny {
  SockaddrAny() : size() {}
  SockaddrAny(const void* addr, socklen_t sz)
      : data(new char[static_cast<size_t>(sz)]), size(sz) {
    memcpy(data.get(), addr, static_cast<size_t>(size));
  }

  const struct sockaddr* addr() const {
    return reinterpret_cast<const struct sockaddr*>(data.get());
  }

  std::unique_ptr<char[]> data;
  socklen_t size;
};

inline int MkSockFamily(SockFamily family) {
  switch (family) {
    case SockFamily::kUnix:
      return AF_UNIX;
    case SockFamily::kInet:
      return AF_INET;
    case SockFamily::kInet6:
      return AF_INET6;
    case SockFamily::kVsock:
#ifdef AF_VSOCK
      return AF_VSOCK;
#else
      return AF_UNSPEC;  // Return AF_UNSPEC on unsupported platforms.
#endif
    case SockFamily::kUnspec:
      return AF_UNSPEC;
  }
  PERFETTO_CHECK(false);  // For GCC.
}

inline int MkSockType(SockType type) {
#if defined(SOCK_CLOEXEC)
  constexpr int kSockCloExec = SOCK_CLOEXEC;
#else
  constexpr int kSockCloExec = 0;
#endif
  switch (type) {
    case SockType::kStream:
      return SOCK_STREAM | kSockCloExec;
    case SockType::kDgram:
      return SOCK_DGRAM | kSockCloExec;
    case SockType::kSeqPacket:
      return SOCK_SEQPACKET | kSockCloExec;
  }
  PERFETTO_CHECK(false);  // For GCC.
}

SockaddrAny MakeSockAddr(SockFamily family, const std::string& socket_name) {
  switch (family) {
    case SockFamily::kUnix: {
      struct sockaddr_un saddr {};
      const size_t name_len = socket_name.size();
      if (name_len + 1 /* for trailing \0 */ >= sizeof(saddr.sun_path)) {
        errno = ENAMETOOLONG;
        return SockaddrAny();
      }
      memcpy(saddr.sun_path, socket_name.data(), name_len);
      if (saddr.sun_path[0] == '@') {
        saddr.sun_path[0] = '\0';
#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
        // The MSDN blog claims that abstract (non-filesystem based) AF_UNIX
        // socket are supported, but that doesn't seem true.
        PERFETTO_ELOG(
            "Abstract AF_UNIX sockets are not supported on Windows, see "
            "https://github.com/microsoft/WSL/issues/4240");
        return SockaddrAny();
#endif
      }
      saddr.sun_family = AF_UNIX;
      auto size = static_cast<socklen_t>(
          __builtin_offsetof(sockaddr_un, sun_path) + name_len + 1);

      // Abstract sockets do NOT require a trailing null terminator (which is
      // instad mandatory for filesystem sockets). Any byte up to `size`,
      // including '\0' will become part of the socket name.
      if (saddr.sun_path[0] == '\0')
        --size;
      PERFETTO_CHECK(static_cast<size_t>(size) <= sizeof(saddr));
      return SockaddrAny(&saddr, size);
    }
    case SockFamily::kInet: {
      auto parts = SplitString(socket_name, ":");
      PERFETTO_CHECK(parts.size() == 2);
      struct addrinfo* addr_info = nullptr;
      struct addrinfo hints {};
      hints.ai_family = AF_INET;
      PERFETTO_CHECK(getaddrinfo(parts[0].c_str(), parts[1].c_str(), &hints,
                                 &addr_info) == 0);
      PERFETTO_CHECK(addr_info->ai_family == AF_INET);
      SockaddrAny res(addr_info->ai_addr,
                      static_cast<socklen_t>(addr_info->ai_addrlen));
      freeaddrinfo(addr_info);
      return res;
    }
    case SockFamily::kInet6: {
      auto parts = SplitString(socket_name, "]");
      PERFETTO_CHECK(parts.size() == 2);
      auto address = SplitString(parts[0], "[");
      PERFETTO_CHECK(address.size() == 1);
      auto port = SplitString(parts[1], ":");
      PERFETTO_CHECK(port.size() == 1);
      struct addrinfo* addr_info = nullptr;
      struct addrinfo hints {};
      hints.ai_family = AF_INET6;
      PERFETTO_CHECK(getaddrinfo(address[0].c_str(), port[0].c_str(), &hints,
                                 &addr_info) == 0);
      PERFETTO_CHECK(addr_info->ai_family == AF_INET6);
      SockaddrAny res(addr_info->ai_addr,
                      static_cast<socklen_t>(addr_info->ai_addrlen));
      freeaddrinfo(addr_info);
      return res;
    }
    case SockFamily::kVsock: {
#if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
    PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
      PERFETTO_CHECK(StartsWith(socket_name, kVsockNamePrefix));
      auto address_port = StripPrefix(socket_name, kVsockNamePrefix);
      auto parts = SplitString(address_port, ":");
      PERFETTO_CHECK(parts.size() == 2);
      sockaddr_vm addr;
      memset(&addr, 0, sizeof(addr));
      addr.svm_family = AF_VSOCK;
      addr.svm_cid = *base::StringToUInt32(parts[0]);
      addr.svm_port = *base::StringToUInt32(parts[1]);
      SockaddrAny res(&addr, sizeof(addr));
      return res;
#else
      errno = ENOTSOCK;
      return SockaddrAny();
#endif
    }
    case SockFamily::kUnspec:
      errno = ENOTSOCK;
      return SockaddrAny();
  }
  PERFETTO_CHECK(false);  // For GCC.
}

ScopedSocketHandle CreateSocketHandle(SockFamily family, SockType type) {
#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
  static bool init_winsock_once = [] {
    WSADATA ignored{};
    return WSAStartup(MAKEWORD(2, 2), &ignored) == 0;
  }();
  PERFETTO_CHECK(init_winsock_once);
#endif
  return ScopedSocketHandle(socket(MkSockFamily(family), MkSockType(type), 0));
}

}  // namespace

#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
int CloseSocket(SocketHandle s) {
  return ::closesocket(s);
}
#endif

SockFamily GetSockFamily(const char* addr) {
  if (strlen(addr) == 0)
    return SockFamily::kUnspec;

  if (addr[0] == '@')
    return SockFamily::kUnix;  // Abstract AF_UNIX sockets.

#if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
    PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
  // Vsock address starts with vsock://.
  if (strncmp(addr, kVsockNamePrefix, strlen(kVsockNamePrefix)) == 0)
    return SockFamily::kVsock;
#endif

  // If `addr` ends in :NNNN it's either a kInet or kInet6 socket.
  const char* col = strrchr(addr, ':');
  if (col && CStringToInt32(col + 1).has_value()) {
    return addr[0] == '[' ? SockFamily::kInet6 : SockFamily::kInet;
  }

  return SockFamily::kUnix;  // For anything else assume it's a linked AF_UNIX.
}

// +-----------------------+
// | UnixSocketRaw methods |
// +-----------------------+

#if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
// static
void UnixSocketRaw::ShiftMsgHdrPosix(size_t n, struct msghdr* msg) {
  using LenType = decltype(msg->msg_iovlen);  // Mac and Linux don't agree.
  for (LenType i = 0; i < msg->msg_iovlen; ++i) {
    struct iovec* vec = &msg->msg_iov[i];
    if (n < vec->iov_len) {
      // We sent a part of this iovec.
      vec->iov_base = reinterpret_cast<char*>(vec->iov_base) + n;
      vec->iov_len -= n;
      msg->msg_iov = vec;
      msg->msg_iovlen -= i;
      return;
    }
    // We sent the whole iovec.
    n -= vec->iov_len;
  }
  // We sent all the iovecs.
  PERFETTO_CHECK(n == 0);
  msg->msg_iovlen = 0;
  msg->msg_iov = nullptr;
}

// static
std::pair<UnixSocketRaw, UnixSocketRaw> UnixSocketRaw::CreatePairPosix(
    SockFamily family,
    SockType type) {
  int fds[2];
  if (socketpair(MkSockFamily(family), MkSockType(type), 0, fds) != 0) {
    return std::make_pair(UnixSocketRaw(), UnixSocketRaw());
  }
  return std::make_pair(UnixSocketRaw(ScopedFile(fds[0]), family, type),
                        UnixSocketRaw(ScopedFile(fds[1]), family, type));
}
#endif

// static
UnixSocketRaw UnixSocketRaw::CreateMayFail(SockFamily family, SockType type) {
  auto fd = CreateSocketHandle(family, type);
  if (!fd)
    return UnixSocketRaw();
  return UnixSocketRaw(std::move(fd), family, type);
}

UnixSocketRaw::UnixSocketRaw() = default;

UnixSocketRaw::UnixSocketRaw(SockFamily family, SockType type)
    : UnixSocketRaw(CreateSocketHandle(family, type), family, type) {}

UnixSocketRaw::UnixSocketRaw(ScopedSocketHandle fd,
                             SockFamily family,
                             SockType type)
    : fd_(std::move(fd)), family_(family), type_(type) {
  PERFETTO_CHECK(fd_);
#if PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
  const int no_sigpipe = 1;
  setsockopt(*fd_, SOL_SOCKET, SO_NOSIGPIPE, &no_sigpipe, sizeof(no_sigpipe));
#endif

  if (family == SockFamily::kInet || family == SockFamily::kInet6 ||
      family == SockFamily::kVsock) {
    int flag = 1;
    // The reinterpret_cast<const char*> is needed for Windows, where the 4th
    // arg is a const char* (on other POSIX system is a const void*).
    PERFETTO_CHECK(!setsockopt(*fd_, SOL_SOCKET, SO_REUSEADDR,
                               reinterpret_cast<const char*>(&flag),
                               sizeof(flag)));
  }

  if (family == SockFamily::kInet || family == SockFamily::kInet6) {
    int flag = 1;
    // Disable Nagle's algorithm, optimize for low-latency.
    // See https://github.com/google/perfetto/issues/70.
    setsockopt(*fd_, IPPROTO_TCP, TCP_NODELAY,
               reinterpret_cast<const char*>(&flag), sizeof(flag));
  }

#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
  // We use one event handle for all socket events, to stay consistent to what
  // we do on UNIX with the base::TaskRunner's poll().
  event_handle_.reset(WSACreateEvent());
  PERFETTO_CHECK(event_handle_);
#else
  // There is no reason why a socket should outlive the process in case of
  // exec() by default, this is just working around a broken unix design.
  SetRetainOnExec(false);
#endif
}

void UnixSocketRaw::SetBlocking(bool is_blocking) {
  PERFETTO_DCHECK(fd_);
#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
  unsigned long flag = is_blocking ? 0 : 1;  // FIONBIO has reverse logic.
  if (is_blocking) {
    // When switching between non-blocking -> blocking mode, we need to reset
    // the event handle registration, otherwise the call will fail.
    PERFETTO_CHECK(WSAEventSelect(*fd_, *event_handle_, 0) == 0);
  }
  PERFETTO_CHECK(ioctlsocket(*fd_, static_cast<long>(FIONBIO), &flag) == 0);
  if (!is_blocking) {
    PERFETTO_CHECK(
        WSAEventSelect(*fd_, *event_handle_,
                       FD_ACCEPT | FD_CONNECT | FD_READ | FD_CLOSE) == 0);
  }
#else
  int flags = fcntl(*fd_, F_GETFL, 0);
  if (!is_blocking) {
    flags |= O_NONBLOCK;
  } else {
    flags &= ~static_cast<int>(O_NONBLOCK);
  }
  int fcntl_res = fcntl(*fd_, F_SETFL, flags);
  PERFETTO_CHECK(fcntl_res == 0);
#endif
}

void UnixSocketRaw::SetRetainOnExec(bool retain) {
#if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN) && \
    !PERFETTO_BUILDFLAG(PERFETTO_OS_FUCHSIA)
  PERFETTO_DCHECK(fd_);
  int flags = fcntl(*fd_, F_GETFD, 0);
  if (retain) {
    flags &= ~static_cast<int>(FD_CLOEXEC);
  } else {
    flags |= FD_CLOEXEC;
  }
  int fcntl_res = fcntl(*fd_, F_SETFD, flags);
  PERFETTO_CHECK(fcntl_res == 0);
#else
  ignore_result(retain);
#endif
}

void UnixSocketRaw::DcheckIsBlocking(bool expected) const {
#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
  ignore_result(expected);
#else
  PERFETTO_DCHECK(fd_);
  bool is_blocking = (fcntl(*fd_, F_GETFL, 0) & O_NONBLOCK) == 0;
  PERFETTO_DCHECK(is_blocking == expected);
#endif
}

bool UnixSocketRaw::Bind(const std::string& socket_name) {
  PERFETTO_DCHECK(fd_);
  SockaddrAny addr = MakeSockAddr(family_, socket_name);
  if (addr.size == 0)
    return false;

  if (bind(*fd_, addr.addr(), addr.size)) {
    PERFETTO_DPLOG("bind(%s)", socket_name.c_str());
    return false;
  }

  return true;
}

bool UnixSocketRaw::Listen() {
  PERFETTO_DCHECK(fd_);
  PERFETTO_DCHECK(type_ == SockType::kStream || type_ == SockType::kSeqPacket);
  return listen(*fd_, SOMAXCONN) == 0;
}

bool UnixSocketRaw::Connect(const std::string& socket_name) {
  PERFETTO_DCHECK(fd_);
  SockaddrAny addr = MakeSockAddr(family_, socket_name);
  if (addr.size == 0)
    return false;

  int res = PERFETTO_EINTR(connect(*fd_, addr.addr(), addr.size));
#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
  bool continue_async = WSAGetLastError() == WSAEWOULDBLOCK;
#else
  bool continue_async = errno == EINPROGRESS;
#endif
  if (res && !continue_async)
    return false;

  return true;
}

void UnixSocketRaw::Shutdown() {
#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
  // Somebody felt very strongly about the naming of this constant.
  shutdown(*fd_, SD_BOTH);
#else
  shutdown(*fd_, SHUT_RDWR);
#endif
  fd_.reset();
}

#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)

ssize_t UnixSocketRaw::Send(const void* msg,
                            size_t len,
                            const int* /*send_fds*/,
                            size_t num_fds) {
  PERFETTO_DCHECK(num_fds == 0);
  return sendto(*fd_, static_cast<const char*>(msg), static_cast<int>(len), 0,
                nullptr, 0);
}

ssize_t UnixSocketRaw::Receive(void* msg,
                               size_t len,
                               ScopedFile* /*fd_vec*/,
                               size_t /*max_files*/) {
  return recv(*fd_, static_cast<char*>(msg), static_cast<int>(len), 0);
}

#else
// For the interested reader, Linux kernel dive to verify this is not only a
// theoretical possibility: sock_stream_sendmsg, if sock_alloc_send_pskb returns
// NULL [1] (which it does when it gets interrupted [2]), returns early with the
// amount of bytes already sent.
//
// [1]:
// https://elixir.bootlin.com/linux/v4.18.10/source/net/unix/af_unix.c#L1872
// [2]: https://elixir.bootlin.com/linux/v4.18.10/source/net/core/sock.c#L2101
ssize_t UnixSocketRaw::SendMsgAllPosix(struct msghdr* msg) {
  // This does not make sense on non-blocking sockets.
  PERFETTO_DCHECK(fd_);

  const bool is_blocking_with_timeout =
      tx_timeout_ms_ > 0 && ((fcntl(*fd_, F_GETFL, 0) & O_NONBLOCK) == 0);
  const int64_t start_ms = GetWallTimeMs().count();

  // Waits until some space is available in the tx buffer.
  // Returns true if some buffer space is available, false if times out.
  auto poll_or_timeout = [&] {
    PERFETTO_DCHECK(is_blocking_with_timeout);
    const int64_t deadline = start_ms + tx_timeout_ms_;
    const int64_t now_ms = GetWallTimeMs().count();
    if (now_ms >= deadline)
      return false;  // Timed out
    const int timeout_ms = static_cast<int>(deadline - now_ms);
    pollfd pfd{*fd_, POLLOUT, 0};
    return PERFETTO_EINTR(poll(&pfd, 1, timeout_ms)) > 0;
  };

// We implement blocking sends that require a timeout as non-blocking + poll.
// This is because SO_SNDTIMEO doesn't work as expected (b/193234818). On linux
// we can just pass MSG_DONTWAIT to force the send to be non-blocking. On Mac,
// instead we need to flip the O_NONBLOCK flag back and forth.
#if PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
  // MSG_NOSIGNAL is not supported on Mac OS X, but in that case the socket is
  // created with SO_NOSIGPIPE (See InitializeSocket()).
  int send_flags = 0;

  if (is_blocking_with_timeout)
    SetBlocking(false);

  auto reset_nonblock_on_exit = OnScopeExit([&] {
    if (is_blocking_with_timeout)
      SetBlocking(true);
  });
#else
  int send_flags = MSG_NOSIGNAL | (is_blocking_with_timeout ? MSG_DONTWAIT : 0);
#endif

  ssize_t total_sent = 0;
  while (msg->msg_iov) {
    ssize_t send_res = PERFETTO_EINTR(sendmsg(*fd_, msg, send_flags));
    if (send_res == -1 && IsAgain(errno)) {
      if (is_blocking_with_timeout && poll_or_timeout()) {
        continue;  // Tx buffer unblocked, repeat the loop.
      }
      return total_sent;
    } else if (send_res <= 0) {
      return send_res;  // An error occurred.
    } else {
      total_sent += send_res;
      ShiftMsgHdrPosix(static_cast<size_t>(send_res), msg);
      // Only send the ancillary data with the first sendmsg call.
      msg->msg_control = nullptr;
      msg->msg_controllen = 0;
    }
  }
  return total_sent;
}

ssize_t UnixSocketRaw::Send(const void* msg,
                            size_t len,
                            const int* send_fds,
                            size_t num_fds) {
  PERFETTO_DCHECK(fd_);
  msghdr msg_hdr = {};
  iovec iov = {const_cast<void*>(msg), len};
  msg_hdr.msg_iov = &iov;
  msg_hdr.msg_iovlen = 1;
  alignas(cmsghdr) char control_buf[256];

  if (num_fds > 0) {
    const auto raw_ctl_data_sz = num_fds * sizeof(int);
    const CBufLenType control_buf_len =
        static_cast<CBufLenType>(CMSG_SPACE(raw_ctl_data_sz));
    PERFETTO_CHECK(control_buf_len <= sizeof(control_buf));
    memset(control_buf, 0, sizeof(control_buf));
    msg_hdr.msg_control = control_buf;
    msg_hdr.msg_controllen = control_buf_len;  // used by CMSG_FIRSTHDR
    struct cmsghdr* cmsg = CMSG_FIRSTHDR(&msg_hdr);
    cmsg->cmsg_level = SOL_SOCKET;
    cmsg->cmsg_type = SCM_RIGHTS;
    cmsg->cmsg_len = static_cast<CBufLenType>(CMSG_LEN(raw_ctl_data_sz));
    memcpy(CMSG_DATA(cmsg), send_fds, num_fds * sizeof(int));
    // note: if we were to send multiple cmsghdr structures, then
    // msg_hdr.msg_controllen would need to be adjusted, see "man 3 cmsg".
  }

  return SendMsgAllPosix(&msg_hdr);
}

ssize_t UnixSocketRaw::Receive(void* msg,
                               size_t len,
                               ScopedFile* fd_vec,
                               size_t max_files) {
  PERFETTO_DCHECK(fd_);
  msghdr msg_hdr = {};
  iovec iov = {msg, len};
  msg_hdr.msg_iov = &iov;
  msg_hdr.msg_iovlen = 1;
  alignas(cmsghdr) char control_buf[256];

  if (max_files > 0) {
    msg_hdr.msg_control = control_buf;
    msg_hdr.msg_controllen =
        static_cast<CBufLenType>(CMSG_SPACE(max_files * sizeof(int)));
    PERFETTO_CHECK(msg_hdr.msg_controllen <= sizeof(control_buf));
  }
  const ssize_t sz = PERFETTO_EINTR(recvmsg(*fd_, &msg_hdr, 0));
  if (sz <= 0) {
    return sz;
  }
  PERFETTO_CHECK(static_cast<size_t>(sz) <= len);

  int* fds = nullptr;
  uint32_t fds_len = 0;

  if (max_files > 0) {
    for (cmsghdr* cmsg = CMSG_FIRSTHDR(&msg_hdr); cmsg;
         cmsg = CMSG_NXTHDR(&msg_hdr, cmsg)) {
      const size_t payload_len = cmsg->cmsg_len - CMSG_LEN(0);
      if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_RIGHTS) {
        PERFETTO_DCHECK(payload_len % sizeof(int) == 0u);
        PERFETTO_CHECK(fds == nullptr);
        fds = reinterpret_cast<int*>(CMSG_DATA(cmsg));
        fds_len = static_cast<uint32_t>(payload_len / sizeof(int));
      }
    }
  }

  if (msg_hdr.msg_flags & MSG_TRUNC || msg_hdr.msg_flags & MSG_CTRUNC) {
    for (size_t i = 0; fds && i < fds_len; ++i)
      close(fds[i]);
    PERFETTO_ELOG(
        "Socket message truncated. This might be due to a SELinux denial on "
        "fd:use.");
    errno = EMSGSIZE;
    return -1;
  }

  for (size_t i = 0; fds && i < fds_len; ++i) {
    if (i < max_files)
      fd_vec[i].reset(fds[i]);
    else
      close(fds[i]);
  }

  return sz;
}
#endif  // OS_WIN

bool UnixSocketRaw::SetTxTimeout(uint32_t timeout_ms) {
  PERFETTO_DCHECK(fd_);
  // On Unix-based systems, SO_SNDTIMEO isn't used for Send() because it's
  // unreliable (b/193234818). Instead we use non-blocking sendmsg() + poll().
  // See SendMsgAllPosix(). We still make the setsockopt call because
  // SO_SNDTIMEO also affects connect().
  tx_timeout_ms_ = timeout_ms;
#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
  DWORD timeout = timeout_ms;
  ignore_result(tx_timeout_ms_);
#else
  struct timeval timeout {};
  uint32_t timeout_sec = timeout_ms / 1000;
  timeout.tv_sec = static_cast<decltype(timeout.tv_sec)>(timeout_sec);
  timeout.tv_usec = static_cast<decltype(timeout.tv_usec)>(
      (timeout_ms - (timeout_sec * 1000)) * 1000);
#endif
  return setsockopt(*fd_, SOL_SOCKET, SO_SNDTIMEO,
                    reinterpret_cast<const char*>(&timeout),
                    sizeof(timeout)) == 0;
}

bool UnixSocketRaw::SetRxTimeout(uint32_t timeout_ms) {
  PERFETTO_DCHECK(fd_);
#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
  DWORD timeout = timeout_ms;
#else
  struct timeval timeout {};
  uint32_t timeout_sec = timeout_ms / 1000;
  timeout.tv_sec = static_cast<decltype(timeout.tv_sec)>(timeout_sec);
  timeout.tv_usec = static_cast<decltype(timeout.tv_usec)>(
      (timeout_ms - (timeout_sec * 1000)) * 1000);
#endif
  return setsockopt(*fd_, SOL_SOCKET, SO_RCVTIMEO,
                    reinterpret_cast<const char*>(&timeout),
                    sizeof(timeout)) == 0;
}

std::string UnixSocketRaw::GetSockAddr() const {
  struct sockaddr_storage stg {};
  socklen_t slen = sizeof(stg);
  PERFETTO_CHECK(
      getsockname(*fd_, reinterpret_cast<struct sockaddr*>(&stg), &slen) == 0);
  char addr[255]{};

  if (stg.ss_family == AF_UNIX) {
    auto* saddr = reinterpret_cast<struct sockaddr_un*>(&stg);
    static_assert(sizeof(addr) >= sizeof(saddr->sun_path), "addr too small");
    memcpy(addr, saddr->sun_path, sizeof(saddr->sun_path));
    addr[0] = addr[0] == '\0' ? '@' : addr[0];
    addr[sizeof(saddr->sun_path) - 1] = '\0';
    return std::string(addr);
  }

  if (stg.ss_family == AF_INET) {
    auto* saddr = reinterpret_cast<struct sockaddr_in*>(&stg);
    PERFETTO_CHECK(inet_ntop(AF_INET, &saddr->sin_addr, addr, sizeof(addr)));
    uint16_t port = ntohs(saddr->sin_port);
    base::StackString<255> addr_and_port("%s:%" PRIu16, addr, port);
    return addr_and_port.ToStdString();
  }

  if (stg.ss_family == AF_INET6) {
    auto* saddr = reinterpret_cast<struct sockaddr_in6*>(&stg);
    PERFETTO_CHECK(inet_ntop(AF_INET6, &saddr->sin6_addr, addr, sizeof(addr)));
    auto port = ntohs(saddr->sin6_port);
    base::StackString<255> addr_and_port("[%s]:%" PRIu16, addr, port);
    return addr_and_port.ToStdString();
  }

#if defined(AF_VSOCK) && (PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
                          PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID))
  if (stg.ss_family == AF_VSOCK) {
    auto* saddr = reinterpret_cast<struct sockaddr_vm*>(&stg);
    base::StackString<255> addr_and_port("%s%d:%d", kVsockNamePrefix,
                                         saddr->svm_cid, saddr->svm_port);
    return addr_and_port.ToStdString();
  }
#endif

  PERFETTO_FATAL("GetSockAddr() unsupported on family %d", stg.ss_family);
}

#if defined(__GNUC__) && !PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
#pragma GCC diagnostic pop
#endif

// +--------------------+
// | UnixSocket methods |
// +--------------------+

// TODO(primiano): Add ThreadChecker to methods of this class.

// static
std::unique_ptr<UnixSocket> UnixSocket::Listen(const std::string& socket_name,
                                               EventListener* event_listener,
                                               TaskRunner* task_runner,
                                               SockFamily sock_family,
                                               SockType sock_type) {
  auto sock_raw = UnixSocketRaw::CreateMayFail(sock_family, sock_type);
  if (!sock_raw || !sock_raw.Bind(socket_name))
    return nullptr;

  // Forward the call to the Listen() overload below.
  return Listen(sock_raw.ReleaseFd(), event_listener, task_runner, sock_family,
                sock_type);
}

// static
std::unique_ptr<UnixSocket> UnixSocket::Listen(ScopedSocketHandle fd,
                                               EventListener* event_listener,
                                               TaskRunner* task_runner,
                                               SockFamily sock_family,
                                               SockType sock_type) {
  return std::unique_ptr<UnixSocket>(new UnixSocket(
      event_listener, task_runner, std::move(fd), State::kListening,
      sock_family, sock_type, SockPeerCredMode::kDefault));
}

// static
std::unique_ptr<UnixSocket> UnixSocket::Connect(
    const std::string& socket_name,
    EventListener* event_listener,
    TaskRunner* task_runner,
    SockFamily sock_family,
    SockType sock_type,
    SockPeerCredMode peer_cred_mode) {
  std::unique_ptr<UnixSocket> sock(new UnixSocket(
      event_listener, task_runner, sock_family, sock_type, peer_cred_mode));
  sock->DoConnect(socket_name);
  return sock;
}

// static
std::unique_ptr<UnixSocket> UnixSocket::AdoptConnected(
    ScopedSocketHandle fd,
    EventListener* event_listener,
    TaskRunner* task_runner,
    SockFamily sock_family,
    SockType sock_type,
    SockPeerCredMode peer_cred_mode) {
  return std::unique_ptr<UnixSocket>(new UnixSocket(
      event_listener, task_runner, std::move(fd), State::kConnected,
      sock_family, sock_type, peer_cred_mode));
}

UnixSocket::UnixSocket(EventListener* event_listener,
                       TaskRunner* task_runner,
                       SockFamily sock_family,
                       SockType sock_type,
                       SockPeerCredMode peer_cred_mode)
    : UnixSocket(event_listener,
                 task_runner,
                 ScopedSocketHandle(),
                 State::kDisconnected,
                 sock_family,
                 sock_type,
                 peer_cred_mode) {}

UnixSocket::UnixSocket(EventListener* event_listener,
                       TaskRunner* task_runner,
                       ScopedSocketHandle adopt_fd,
                       State adopt_state,
                       SockFamily sock_family,
                       SockType sock_type,
                       SockPeerCredMode peer_cred_mode)
    : peer_cred_mode_(peer_cred_mode),
      event_listener_(event_listener),
      task_runner_(task_runner),
      weak_ptr_factory_(this) {
  state_ = State::kDisconnected;
  if (adopt_state == State::kDisconnected) {
    PERFETTO_DCHECK(!adopt_fd);
    sock_raw_ = UnixSocketRaw::CreateMayFail(sock_family, sock_type);
    if (!sock_raw_)
      return;
  } else if (adopt_state == State::kConnected) {
    PERFETTO_DCHECK(adopt_fd);
    sock_raw_ = UnixSocketRaw(std::move(adopt_fd), sock_family, sock_type);
    state_ = State::kConnected;
#if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
    if (peer_cred_mode_ == SockPeerCredMode::kReadOnConnect)
      ReadPeerCredentialsPosix();
#endif
  } else if (adopt_state == State::kListening) {
    // We get here from Listen().

    // |adopt_fd| might genuinely be invalid if the bind() failed.
    if (!adopt_fd)
      return;

    sock_raw_ = UnixSocketRaw(std::move(adopt_fd), sock_family, sock_type);
    if (!sock_raw_.Listen()) {
      PERFETTO_DPLOG("listen() failed");
      return;
    }
    state_ = State::kListening;
  } else {
    PERFETTO_FATAL("Unexpected adopt_state");  // Unfeasible.
  }

  PERFETTO_CHECK(sock_raw_);

  sock_raw_.SetBlocking(false);

  WeakPtr<UnixSocket> weak_ptr = weak_ptr_factory_.GetWeakPtr();

  task_runner_->AddFileDescriptorWatch(sock_raw_.watch_handle(), [weak_ptr] {
    if (weak_ptr)
      weak_ptr->OnEvent();
  });
}

UnixSocket::~UnixSocket() {
  // The implicit dtor of |weak_ptr_factory_| will no-op pending callbacks.
  Shutdown(true);
}

UnixSocketRaw UnixSocket::ReleaseSocket() {
  // This will invalidate any pending calls to OnEvent.
  state_ = State::kDisconnected;
  if (sock_raw_)
    task_runner_->RemoveFileDescriptorWatch(sock_raw_.watch_handle());

  return std::move(sock_raw_);
}

// Called only by the Connect() static constructor.
void UnixSocket::DoConnect(const std::string& socket_name) {
  PERFETTO_DCHECK(state_ == State::kDisconnected);

  // This is the only thing that can gracefully fail in the ctor.
  if (!sock_raw_)
    return NotifyConnectionState(false);

  if (!sock_raw_.Connect(socket_name))
    return NotifyConnectionState(false);

  // At this point either connect() succeeded or started asynchronously
  // (errno = EINPROGRESS).
  state_ = State::kConnecting;

  // Even if the socket is non-blocking, connecting to a UNIX socket can be
  // acknowledged straight away rather than returning EINPROGRESS.
  // The decision here is to deal with the two cases uniformly, at the cost of
  // delaying the straight-away-connect() case by one task, to avoid depending
  // on implementation details of UNIX socket on the various OSes.
  // Posting the OnEvent() below emulates a wakeup of the FD watch. OnEvent(),
  // which knows how to deal with spurious wakeups, will poll the SO_ERROR and
  // evolve, if necessary, the state into either kConnected or kDisconnected.
  WeakPtr<UnixSocket> weak_ptr = weak_ptr_factory_.GetWeakPtr();
  task_runner_->PostTask([weak_ptr] {
    if (weak_ptr)
      weak_ptr->OnEvent();
  });
}

#if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
void UnixSocket::ReadPeerCredentialsPosix() {
  // Peer credentials are supported only on AF_UNIX sockets.
  if (sock_raw_.family() != SockFamily::kUnix)
    return;
  PERFETTO_CHECK(peer_cred_mode_ != SockPeerCredMode::kIgnore);

#if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
    PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
  struct ucred user_cred;
  socklen_t len = sizeof(user_cred);
  int fd = sock_raw_.fd();
  int res = getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &user_cred, &len);
  PERFETTO_CHECK(res == 0);
  peer_uid_ = user_cred.uid;
  peer_pid_ = user_cred.pid;
#elif PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
  struct xucred user_cred;
  socklen_t len = sizeof(user_cred);
  int res = getsockopt(sock_raw_.fd(), 0, LOCAL_PEERCRED, &user_cred, &len);
  PERFETTO_CHECK(res == 0 && user_cred.cr_version == XUCRED_VERSION);
  peer_uid_ = static_cast<uid_t>(user_cred.cr_uid);
  // There is no pid in the LOCAL_PEERCREDS for MacOS / FreeBSD.
#endif
}
#endif  // !OS_WIN

#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
void UnixSocket::OnEvent() {
  WSANETWORKEVENTS evts{};
  PERFETTO_CHECK(WSAEnumNetworkEvents(sock_raw_.fd(), sock_raw_.watch_handle(),
                                      &evts) == 0);
  if (state_ == State::kDisconnected)
    return;  // Some spurious event, typically queued just before Shutdown().

  if (state_ == State::kConnecting && (evts.lNetworkEvents & FD_CONNECT)) {
    PERFETTO_DCHECK(sock_raw_);
    int err = evts.iErrorCode[FD_CONNECT_BIT];
    if (err) {
      PERFETTO_DPLOG("Connection error: %d", err);
      Shutdown(false);
      event_listener_->OnConnect(this, false /* connected */);
      return;
    }

    // kReadOnConnect is not supported on Windows.
    PERFETTO_DCHECK(peer_cred_mode_ != SockPeerCredMode::kReadOnConnect);
    state_ = State::kConnected;
    event_listener_->OnConnect(this, true /* connected */);
  }

  // This is deliberately NOT an else-if. When a client socket connects and
  // there is already data queued, the following will happen within the same
  // OnEvent() call:
  // 1. The block above will transition kConnecting -> kConnected.
  // 2. This block will cause an OnDataAvailable() call.
  // Unlike UNIX, where poll() keeps signalling the event until the client
  // does a recv(), Windows is more picky and stops signalling the event until
  // the next call to recv() is made. In other words, in Windows we cannot
  // miss an OnDataAvailable() call or the event pump will stop.
  if (state_ == State::kConnected) {
    if (evts.lNetworkEvents & FD_READ) {
      event_listener_->OnDataAvailable(this);
      // TODO(primiano): I am very conflicted here. Because of the behavior
      // described above, if the event listener doesn't do a Recv() call in
      // the OnDataAvailable() callback, WinSock won't notify the event ever
      // again. On one side, I don't see any reason why a client should decide
      // to not do a Recv() in OnDataAvailable. On the other side, the
      // behavior here diverges from UNIX, where OnDataAvailable() would be
      // re-posted immediately. In both cases, not doing a Recv() in
      // OnDataAvailable, leads to something bad (getting stuck on Windows,
      // getting in a hot loop on Linux), so doesn't feel we should worry too
      // much about this. If we wanted to keep the behavrior consistent, here
      // we should do something like: `if (sock_raw_)
      // sock_raw_.SetBlocking(false)` (Note that the socket might be closed
      // by the time we come back here, hence the if part).
      return;
    }
    // Could read EOF and disconnect here.
    if (evts.lNetworkEvents & FD_CLOSE) {
      Shutdown(true);
      return;
    }
  }

  // New incoming connection.
  if (state_ == State::kListening && (evts.lNetworkEvents & FD_ACCEPT)) {
    // There could be more than one incoming connection behind each FD watch
    // notification. Drain'em all.
    for (;;) {
      // Note: right now we don't need the remote endpoint, hence we pass
      // nullptr to |addr| and |addrlen|. If we ever need to do so, be
      // extremely careful. Windows' WinSock API will happily write more than
      // |addrlen| (hence corrupt the stack) if the |addr| argument passed is
      // not big enough (e.g. passing a struct sockaddr_in to a AF_UNIX
      // socket, where sizeof(sockaddr_un) is >> sizef(sockaddr_in)). It seems
      // a Windows / CRT bug in the AF_UNIX implementation.
      ScopedSocketHandle new_fd(accept(sock_raw_.fd(), nullptr, nullptr));
      if (!new_fd)
        return;
      std::unique_ptr<UnixSocket> new_sock(new UnixSocket(
          event_listener_, task_runner_, std::move(new_fd), State::kConnected,
          sock_raw_.family(), sock_raw_.type(), peer_cred_mode_));
      event_listener_->OnNewIncomingConnection(this, std::move(new_sock));
    }
  }
}
#else
void UnixSocket::OnEvent() {
  if (state_ == State::kDisconnected)
    return;  // Some spurious event, typically queued just before Shutdown().

  if (state_ == State::kConnected)
    return event_listener_->OnDataAvailable(this);

  if (state_ == State::kConnecting) {
    PERFETTO_DCHECK(sock_raw_);
    int sock_err = EINVAL;
    socklen_t err_len = sizeof(sock_err);
    int res =
        getsockopt(sock_raw_.fd(), SOL_SOCKET, SO_ERROR, &sock_err, &err_len);

    if (res == 0 && sock_err == EINPROGRESS)
      return;  // Not connected yet, just a spurious FD watch wakeup.
    if (res == 0 && sock_err == 0) {
      if (peer_cred_mode_ == SockPeerCredMode::kReadOnConnect)
        ReadPeerCredentialsPosix();
      state_ = State::kConnected;
      return event_listener_->OnConnect(this, true /* connected */);
    }
    PERFETTO_DLOG("Connection error: %s", strerror(sock_err));
    Shutdown(false);
    return event_listener_->OnConnect(this, false /* connected */);
  }

  // New incoming connection.
  if (state_ == State::kListening) {
    // There could be more than one incoming connection behind each FD watch
    // notification. Drain'em all.
    for (;;) {
      ScopedFile new_fd(
          PERFETTO_EINTR(accept(sock_raw_.fd(), nullptr, nullptr)));
      if (!new_fd)
        return;
      std::unique_ptr<UnixSocket> new_sock(new UnixSocket(
          event_listener_, task_runner_, std::move(new_fd), State::kConnected,
          sock_raw_.family(), sock_raw_.type(), peer_cred_mode_));
      event_listener_->OnNewIncomingConnection(this, std::move(new_sock));
    }
  }
}
#endif

bool UnixSocket::Send(const void* msg,
                      size_t len,
                      const int* send_fds,
                      size_t num_fds) {
  if (state_ != State::kConnected) {
    errno = ENOTCONN;
    return false;
  }

  sock_raw_.SetBlocking(true);
  const ssize_t sz = sock_raw_.Send(msg, len, send_fds, num_fds);
  sock_raw_.SetBlocking(false);

  if (sz == static_cast<ssize_t>(len)) {
    return true;
  }

  // If we ever decide to support non-blocking sends again, here we should
  // watch for both EAGAIN and EWOULDBLOCK (see base::IsAgain()).

  // If sendmsg() succeeds but the returned size is >= 0 and < |len| it means
  // that the endpoint disconnected in the middle of the read, and we managed
  // to send only a portion of the buffer.
  // If sz < 0, either the other endpoint disconnected (ECONNRESET) or some
  // other error happened. In both cases we should just give up.
  PERFETTO_DPLOG("sendmsg() failed");
  Shutdown(true);
  return false;
}

void UnixSocket::Shutdown(bool notify) {
  WeakPtr<UnixSocket> weak_ptr = weak_ptr_factory_.GetWeakPtr();
  if (notify) {
    if (state_ == State::kConnected) {
      task_runner_->PostTask([weak_ptr] {
        if (weak_ptr)
          weak_ptr->event_listener_->OnDisconnect(weak_ptr.get());
      });
    } else if (state_ == State::kConnecting) {
      task_runner_->PostTask([weak_ptr] {
        if (weak_ptr)
          weak_ptr->event_listener_->OnConnect(weak_ptr.get(), false);
      });
    }
  }

  if (sock_raw_) {
    task_runner_->RemoveFileDescriptorWatch(sock_raw_.watch_handle());
    sock_raw_.Shutdown();
  }
  state_ = State::kDisconnected;
}

size_t UnixSocket::Receive(void* msg,
                           size_t len,
                           ScopedFile* fd_vec,
                           size_t max_files) {
  if (state_ != State::kConnected)
    return 0;

  const ssize_t sz = sock_raw_.Receive(msg, len, fd_vec, max_files);
#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
  bool async_would_block = WSAGetLastError() == WSAEWOULDBLOCK;
#else
  bool async_would_block = IsAgain(errno);
#endif
  if (sz < 0 && async_would_block)
    return 0;

  if (sz <= 0) {
    Shutdown(true);
    return 0;
  }
  PERFETTO_CHECK(static_cast<size_t>(sz) <= len);
  return static_cast<size_t>(sz);
}

std::string UnixSocket::ReceiveString(size_t max_length) {
  std::unique_ptr<char[]> buf(new char[max_length + 1]);
  size_t rsize = Receive(buf.get(), max_length);
  PERFETTO_CHECK(rsize <= max_length);
  buf[rsize] = '\0';
  return std::string(buf.get());
}

void UnixSocket::NotifyConnectionState(bool success) {
  if (!success)
    Shutdown(false);

  WeakPtr<UnixSocket> weak_ptr = weak_ptr_factory_.GetWeakPtr();
  task_runner_->PostTask([weak_ptr, success] {
    if (weak_ptr)
      weak_ptr->event_listener_->OnConnect(weak_ptr.get(), success);
  });
}

UnixSocket::EventListener::~EventListener() {}
void UnixSocket::EventListener::OnNewIncomingConnection(
    UnixSocket*,
    std::unique_ptr<UnixSocket>) {}
void UnixSocket::EventListener::OnConnect(UnixSocket*, bool) {}
void UnixSocket::EventListener::OnDisconnect(UnixSocket*) {}
void UnixSocket::EventListener::OnDataAvailable(UnixSocket*) {}

}  // namespace base
}  // namespace perfetto
// gen_amalgamated begin source: src/ipc/buffered_frame_deserializer.cc
// gen_amalgamated begin header: src/ipc/buffered_frame_deserializer.h
// gen_amalgamated begin header: include/perfetto/ext/ipc/basic_types.h
/*
 * Copyright (C) 2017 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef INCLUDE_PERFETTO_EXT_IPC_BASIC_TYPES_H_
#define INCLUDE_PERFETTO_EXT_IPC_BASIC_TYPES_H_

#include <stddef.h>
#include <stdint.h>
#include <sys/types.h>

// gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
// gen_amalgamated expanded: #include "perfetto/protozero/cpp_message_obj.h"

namespace perfetto {
namespace ipc {

using ProtoMessage = ::protozero::CppMessageObj;
using ServiceID = uint32_t;
using MethodID = uint32_t;
using ClientID = uint64_t;
using RequestID = uint64_t;

#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
// AF_UNIX on Windows is supported only on Windows 10 from build 17063.
// Also it doesn't bring major advantages compared to a TCP socket.
// See go/perfetto-win .
constexpr bool kUseTCPSocket = true;
#else
// Android, Linux, Mac, Fuchsia use local sockets.
constexpr bool kUseTCPSocket = false;
#endif

// This determines the maximum size allowed for an IPC message. Trying to send
// or receive a larger message will hit DCHECK(s) and auto-disconnect.
constexpr size_t kIPCBufferSize = 128 * 1024;

constexpr uid_t kInvalidUid = static_cast<uid_t>(-1);

}  // namespace ipc
}  // namespace perfetto

#endif  // INCLUDE_PERFETTO_EXT_IPC_BASIC_TYPES_H_
/*
 * Copyright (C) 2017 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef SRC_IPC_BUFFERED_FRAME_DESERIALIZER_H_
#define SRC_IPC_BUFFERED_FRAME_DESERIALIZER_H_

#include <stddef.h>

#include <list>
#include <memory>

// gen_amalgamated expanded: #include "perfetto/ext/base/paged_memory.h"
// gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
// gen_amalgamated expanded: #include "perfetto/ext/ipc/basic_types.h"

namespace perfetto {

namespace protos {
namespace gen {
class IPCFrame;
}  // namespace gen
}  // namespace protos

namespace ipc {

using Frame = ::perfetto::protos::gen::IPCFrame;

// Deserializes incoming frames, taking care of buffering and tokenization.
// Used by both host and client to decode incoming frames.
//
// Which problem does it solve?
// ----------------------------
// The wire protocol is as follows:
// [32-bit frame size][proto-encoded Frame], e.g:
// [06 00 00 00][00 11 22 33 44 55 66]
// [02 00 00 00][AA BB]
// [04 00 00 00][CC DD EE FF]
// However, given that the socket works in SOCK_STREAM mode, the recv() calls
// might see the following:
// 06 00 00
// 00 00 11 22 33 44 55
// 66 02 00 00 00 ...
// This class takes care of buffering efficiently the data received, without
// making any assumption on how the incoming data will be chunked by the socket.
// For instance, it is possible that a recv() doesn't produce any frame (because
// it received only a part of the frame) or produces more than one frame.
//
// Usage
// -----
// Both host and client use this as follows:
//
// auto buf = rpc_frame_decoder.BeginReceive();
// size_t rsize = socket.recv(buf.first, buf.second);
// rpc_frame_decoder.EndReceive(rsize);
// while (Frame frame = rpc_frame_decoder.PopNextFrame()) {
//   ... process |frame|
// }
//
// Design goals:
// -------------
// - Optimize for the realistic case of each recv() receiving one or more
//   whole frames. In this case no memmove is performed.
// - Guarantee that frames lay in a virtually contiguous memory area.
//   This allows to use the protobuf-lite deserialization API (scattered
//   deserialization is supported only by libprotobuf-full).
// - Put a hard boundary to the size of the incoming buffer. This is to prevent
//   that a malicious sends an abnormally large frame and OOMs us.
// - Simplicity: just use a linear mmap region. No reallocations or scattering.
//   Takes care of madvise()-ing unused memory.

class BufferedFrameDeserializer {
 public:
  struct ReceiveBuffer {
    char* data;
    size_t size;
  };

  // |max_capacity| is overridable only for tests.
  explicit BufferedFrameDeserializer(size_t max_capacity = kIPCBufferSize);
  ~BufferedFrameDeserializer();

  // This function doesn't really belong here as it does Serialization, unlike
  // the rest of this class. However it is so small and has so many dependencies
  // in common that doesn't justify having its own class.
  static std::string Serialize(const Frame&);

  // Returns a buffer that can be passed to recv(). The buffer is deliberately
  // not initialized.
  ReceiveBuffer BeginReceive();

  // Must be called soon after BeginReceive().
  // |recv_size| is the number of valid bytes that have been written into the
  // buffer previously returned by BeginReceive() (the return value of recv()).
  // Returns false if a header > |max_capacity| is received, in which case the
  // caller is expected to shutdown the socket and terminate the ipc.
  bool EndReceive(size_t recv_size) PERFETTO_WARN_UNUSED_RESULT;

  // Decodes and returns the next decoded frame in the buffer if any, nullptr
  // if no further frames have been decoded.
  std::unique_ptr<Frame> PopNextFrame();

  size_t capacity() const { return capacity_; }
  size_t size() const { return size_; }

 private:
  BufferedFrameDeserializer(const BufferedFrameDeserializer&) = delete;
  BufferedFrameDeserializer& operator=(const BufferedFrameDeserializer&) =
      delete;

  // If a valid frame is decoded it is added to |decoded_frames_|.
  void DecodeFrame(const char*, size_t);

  char* buf() { return reinterpret_cast<char*>(buf_.Get()); }

  base::PagedMemory buf_;
  const size_t capacity_ = 0;  // sizeof(|buf_|).

  // THe number of bytes in |buf_| that contain valid data (as a result of
  // EndReceive()). This is always <= |capacity_|.
  size_t size_ = 0;

  std::list<std::unique_ptr<Frame>> decoded_frames_;
};

}  // namespace ipc
}  // namespace perfetto

#endif  // SRC_IPC_BUFFERED_FRAME_DESERIALIZER_H_
/*
 * Copyright (C) 2017 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// gen_amalgamated expanded: #include "src/ipc/buffered_frame_deserializer.h"

#include <algorithm>
#include <cinttypes>
#include <type_traits>
#include <utility>

// gen_amalgamated expanded: #include "perfetto/base/logging.h"
// gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"

// gen_amalgamated expanded: #include "protos/perfetto/ipc/wire_protocol.gen.h"

namespace perfetto {
namespace ipc {

namespace {

// The header is just the number of bytes of the Frame protobuf message.
constexpr size_t kHeaderSize = sizeof(uint32_t);
}  // namespace

BufferedFrameDeserializer::BufferedFrameDeserializer(size_t max_capacity)
    : capacity_(max_capacity) {
  PERFETTO_CHECK(max_capacity % base::GetSysPageSize() == 0);
  PERFETTO_CHECK(max_capacity >= base::GetSysPageSize());
}

BufferedFrameDeserializer::~BufferedFrameDeserializer() = default;

BufferedFrameDeserializer::ReceiveBuffer
BufferedFrameDeserializer::BeginReceive() {
  // Upon the first recv initialize the buffer to the max message size but
  // release the physical memory for all but the first page. The kernel will
  // automatically give us physical pages back as soon as we page-fault on them.
  if (!buf_.IsValid()) {
    PERFETTO_DCHECK(size_ == 0);
    // TODO(eseckler): Don't commit all of the buffer at once on Windows.
    buf_ = base::PagedMemory::Allocate(capacity_);

    // Surely we are going to use at least the first page, but we may not need
    // the rest for a bit.
    const auto page_size = base::GetSysPageSize();
    buf_.AdviseDontNeed(buf() + page_size, capacity_ - page_size);
  }

  PERFETTO_CHECK(capacity_ > size_);
  return ReceiveBuffer{buf() + size_, capacity_ - size_};
}

bool BufferedFrameDeserializer::EndReceive(size_t recv_size) {
  const auto page_size = base::GetSysPageSize();
  PERFETTO_CHECK(recv_size + size_ <= capacity_);
  size_ += recv_size;

  // At this point the contents buf_ can contain:
  // A) Only a fragment of the header (the size of the frame). E.g.,
  //    03 00 00 (the header is 4 bytes, one is missing).
  //
  // B) A header and a part of the frame. E.g.,
  //     05 00 00 00         11 22 33
  //    [ header, size=5 ]  [ Partial frame ]
  //
  // C) One or more complete header+frame. E.g.,
  //     05 00 00 00         11 22 33 44 55   03 00 00 00        AA BB CC
  //    [ header, size=5 ]  [ Whole frame ]  [ header, size=3 ] [ Whole frame ]
  //
  // D) Some complete header+frame(s) and a partial header or frame (C + A/B).
  //
  // C Is the more likely case and the one we are optimizing for. A, B, D can
  // happen because of the streaming nature of the socket.
  // The invariant of this function is that, when it returns, buf_ is either
  // empty (we drained all the complete frames) or starts with the header of the
  // next, still incomplete, frame.

  size_t consumed_size = 0;
  for (;;) {
    if (size_ < consumed_size + kHeaderSize)
      break;  // Case A, not enough data to read even the header.

    // Read the header into |payload_size|.
    uint32_t payload_size = 0;
    const char* rd_ptr = buf() + consumed_size;
    memcpy(base::AssumeLittleEndian(&payload_size), rd_ptr, kHeaderSize);

    // Saturate the |payload_size| to prevent overflows. The > capacity_ check
    // below will abort the parsing.
    size_t next_frame_size =
        std::min(static_cast<size_t>(payload_size), capacity_);
    next_frame_size += kHeaderSize;
    rd_ptr += kHeaderSize;

    if (size_ < consumed_size + next_frame_size) {
      // Case B. We got the header but not the whole frame.
      if (next_frame_size > capacity_) {
        // The caller is expected to shut down the socket and give up at this
        // point. If it doesn't do that and insists going on at some point it
        // will hit the capacity check in BeginReceive().
        PERFETTO_LOG("IPC Frame too large (size %zu)", next_frame_size);
        return false;
      }
      break;
    }

    // Case C. We got at least one header and whole frame.
    DecodeFrame(rd_ptr, payload_size);
    consumed_size += next_frame_size;
  }

  PERFETTO_DCHECK(consumed_size <= size_);
  if (consumed_size > 0) {
    // Shift out the consumed data from the buffer. In the typical case (C)
    // there is nothing to shift really, just setting size_ = 0 is enough.
    // Shifting is only for the (unlikely) case D.
    size_ -= consumed_size;
    if (size_ > 0) {
      // Case D. We consumed some frames but there is a leftover at the end of
      // the buffer. Shift out the consumed bytes, so that on the next round
      // |buf_| starts with the header of the next unconsumed frame.
      const char* move_begin = buf() + consumed_size;
      PERFETTO_CHECK(move_begin > buf());
      PERFETTO_CHECK(move_begin + size_ <= buf() + capacity_);
      memmove(buf(), move_begin, size_);
    }
    // If we just finished decoding a large frame that used more than one page,
    // release the extra memory in the buffer. Large frames should be quite
    // rare.
    if (consumed_size > page_size) {
      size_t size_rounded_up = (size_ / page_size + 1) * page_size;
      if (size_rounded_up < capacity_) {
        char* madvise_begin = buf() + size_rounded_up;
        const size_t madvise_size = capacity_ - size_rounded_up;
        PERFETTO_CHECK(madvise_begin > buf() + size_);
        PERFETTO_CHECK(madvise_begin + madvise_size <= buf() + capacity_);
        buf_.AdviseDontNeed(madvise_begin, madvise_size);
      }
    }
  }
  // At this point |size_| == 0 for case C, > 0 for cases A, B, D.
  return true;
}

std::unique_ptr<Frame> BufferedFrameDeserializer::PopNextFrame() {
  if (decoded_frames_.empty())
    return nullptr;
  std::unique_ptr<Frame> frame = std::move(decoded_frames_.front());
  decoded_frames_.pop_front();
  return frame;
}

void BufferedFrameDeserializer::DecodeFrame(const char* data, size_t size) {
  if (size == 0)
    return;
  std::unique_ptr<Frame> frame(new Frame);
  if (frame->ParseFromArray(data, size))
    decoded_frames_.push_back(std::move(frame));
}

// static
std::string BufferedFrameDeserializer::Serialize(const Frame& frame) {
  std::vector<uint8_t> payload = frame.SerializeAsArray();
  const uint32_t payload_size = static_cast<uint32_t>(payload.size());
  std::string buf;
  buf.resize(kHeaderSize + payload_size);
  memcpy(&buf[0], base::AssumeLittleEndian(&payload_size), kHeaderSize);
  memcpy(&buf[kHeaderSize], payload.data(), payload.size());
  return buf;
}

}  // namespace ipc
}  // namespace perfetto
// gen_amalgamated begin source: src/ipc/deferred.cc
// gen_amalgamated begin header: include/perfetto/ext/ipc/deferred.h
// gen_amalgamated begin header: include/perfetto/ext/ipc/async_result.h
/*
 * Copyright (C) 2017 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef INCLUDE_PERFETTO_EXT_IPC_ASYNC_RESULT_H_
#define INCLUDE_PERFETTO_EXT_IPC_ASYNC_RESULT_H_

#include <memory>
#include <type_traits>
#include <utility>

// gen_amalgamated expanded: #include "perfetto/ext/ipc/basic_types.h"

namespace perfetto {
namespace ipc {

// Wraps the result of an asynchronous invocation. This is the equivalent of a
// std::pair<unique_ptr<T>, bool> with syntactic sugar. It is used as callback
// argument by Deferred<T>. T is a ProtoMessage subclass (i.e. generated .pb.h).
template <typename T>
class AsyncResult {
 public:
  static AsyncResult Create() {
    return AsyncResult(std::unique_ptr<T>(new T()));
  }

  AsyncResult(std::unique_ptr<T> msg = nullptr,
              bool has_more = false,
              int fd = -1)
      : msg_(std::move(msg)), has_more_(has_more), fd_(fd) {
    static_assert(std::is_base_of<ProtoMessage, T>::value, "T->ProtoMessage");
  }
  AsyncResult(AsyncResult&&) noexcept = default;
  AsyncResult& operator=(AsyncResult&&) = default;

  bool success() const { return !!msg_; }
  explicit operator bool() const { return success(); }

  bool has_more() const { return has_more_; }
  void set_has_more(bool has_more) { has_more_ = has_more; }

  void set_msg(std::unique_ptr<T> msg) { msg_ = std::move(msg); }
  T* release_msg() { return msg_.release(); }
  T* operator->() { return msg_.get(); }
  T& operator*() { return *msg_; }

  void set_fd(int fd) { fd_ = fd; }
  int fd() const { return fd_; }

 private:
  std::unique_ptr<T> msg_;
  bool has_more_ = false;

  // Optional. Only for messages that convey a file descriptor, for sharing
  // memory across processes.
  int fd_ = -1;
};

}  // namespace ipc
}  // namespace perfetto

#endif  // INCLUDE_PERFETTO_EXT_IPC_ASYNC_RESULT_H_
/*
 * Copyright (C) 2017 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef INCLUDE_PERFETTO_EXT_IPC_DEFERRED_H_
#define INCLUDE_PERFETTO_EXT_IPC_DEFERRED_H_

#include <functional>
#include <memory>
#include <utility>

// gen_amalgamated expanded: #include "perfetto/ext/ipc/async_result.h"
// gen_amalgamated expanded: #include "perfetto/ext/ipc/basic_types.h"

namespace perfetto {
namespace ipc {

// This class is a wrapper for a callback handling async results.
// The problem this is solving is the following: For each result argument of the
// methods generated from the .proto file:
// - The client wants to see something on which it can Bind() a callback, which
//   is invoked asynchronously once reply is received from the host.
// - The host wants to expose something to user code that implements the IPC
//   methods to allow them to provide an asynchronous reply back to the client.
//   Eventually even more than once, for the case streaming replies.
//
// In both cases we want to make sure that callbacks don't get lost along the
// way. To address this, this class will automatically reject the callbacks
// if they are not resolved at destructor time (or the object is std::move()'d).
//
// The client is supposed to use this class as follows:
//   class GreeterProxy {
//      void SayHello(const HelloRequest&, Deferred<HelloReply> reply)
//   }
//  ...
//  Deferred<HelloReply> reply;
//  reply.Bind([] (AsyncResult<HelloReply> reply) {
//    std::cout << reply.success() ? reply->message : "failure";
//  });
//  host_proxy_instance.SayHello(req, std::move(reply));
//
// The host instead is supposed to use this as follows:
//   class GreeterImpl : public Greeter {
//     void SayHello(const HelloRequest& req, Deferred<HelloReply> reply) {
//        AsyncResult<HelloReply> reply = AsyncResult<HelloReply>::Create();
//        reply->set_greeting("Hello " + req.name)
//        reply.Resolve(std::move(reply));
//     }
//   }
// Or for more complex cases, the deferred object can be std::move()'d outside
// and the reply can continue asynchronously later.

template <typename T>
class Deferred;

class DeferredBase {
 public:
  explicit DeferredBase(
      std::function<void(AsyncResult<ProtoMessage>)> callback = nullptr);

  ~DeferredBase();
  DeferredBase(DeferredBase&&) noexcept;
  DeferredBase& operator=(DeferredBase&&);
  void Bind(std::function<void(AsyncResult<ProtoMessage>)> callback);
  bool IsBound() const;
  void Resolve(AsyncResult<ProtoMessage>);
  void Reject();

 protected:
  template <typename T>
  friend class Deferred;
  void Move(DeferredBase&);

  std::function<void(AsyncResult<ProtoMessage>)> callback_;
};

template <typename T>  // T : ProtoMessage subclass
class Deferred : public DeferredBase {
 public:
  explicit Deferred(std::function<void(AsyncResult<T>)> callback = nullptr) {
    Bind(std::move(callback));
  }

  // This move constructor (and the similar one in DeferredBase) is meant to be
  // called only by the autogenerated code. The caller has to guarantee that the
  // moved-from and moved-to types match. The behavior is otherwise undefined.
  explicit Deferred(DeferredBase&& other) {
    callback_ = std::move(other.callback_);
    other.callback_ = nullptr;
  }

  void Bind(std::function<void(AsyncResult<T>)> callback) {
    if (!callback)
      return;

    // Here we need a callback adapter to downcast the callback to a generic
    // callback that takes an AsyncResult<ProtoMessage>, so that it can be
    // stored in the base class |callback_|.
    auto callback_adapter = [callback](
                                AsyncResult<ProtoMessage> async_result_base) {
      // Upcast the async_result from <ProtoMessage> -> <T : ProtoMessage>.
      static_assert(std::is_base_of<ProtoMessage, T>::value, "T:ProtoMessage");
      AsyncResult<T> async_result(
          std::unique_ptr<T>(static_cast<T*>(async_result_base.release_msg())),
          async_result_base.has_more(), async_result_base.fd());
      callback(std::move(async_result));
    };
    DeferredBase::Bind(callback_adapter);
  }

  // If no more messages are expected, |callback_| is released.
  void Resolve(AsyncResult<T> async_result) {
    // Convert the |async_result| to the generic base one (T -> ProtoMessage).
    AsyncResult<ProtoMessage> async_result_base(
        std::unique_ptr<ProtoMessage>(async_result.release_msg()),
        async_result.has_more(), async_result.fd());
    DeferredBase::Resolve(std::move(async_result_base));
  }
};

}  // namespace ipc
}  // namespace perfetto

#endif  // INCLUDE_PERFETTO_EXT_IPC_DEFERRED_H_
/*
 * Copyright (C) 2017 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// gen_amalgamated expanded: #include "perfetto/ext/ipc/deferred.h"

// gen_amalgamated expanded: #include "perfetto/base/logging.h"
// gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"

namespace perfetto {
namespace ipc {

DeferredBase::DeferredBase(
    std::function<void(AsyncResult<ProtoMessage>)> callback)
    : callback_(std::move(callback)) {}

DeferredBase::~DeferredBase() {
  if (callback_)
    Reject();
}

// Can't just use "= default" here because the default move operator for
// std::function doesn't necessarily swap and hence can leave a copy of the
// bind state around, which is undesirable.
DeferredBase::DeferredBase(DeferredBase&& other) noexcept {
  Move(other);
}

DeferredBase& DeferredBase::operator=(DeferredBase&& other) {
  if (callback_)
    Reject();
  Move(other);
  return *this;
}

void DeferredBase::Move(DeferredBase& other) {
  callback_ = std::move(other.callback_);
  other.callback_ = nullptr;
}

void DeferredBase::Bind(
    std::function<void(AsyncResult<ProtoMessage>)> callback) {
  callback_ = std::move(callback);
}

bool DeferredBase::IsBound() const {
  return !!callback_;
}

void DeferredBase::Resolve(AsyncResult<ProtoMessage> async_result) {
  if (!callback_) {
    PERFETTO_DFATAL("No callback set.");
    return;
  }
  bool has_more = async_result.has_more();
  callback_(std::move(async_result));
  if (!has_more)
    callback_ = nullptr;
}

// Resolves with a nullptr |msg_|, signalling failure to |callback_|.
void DeferredBase::Reject() {
  Resolve(AsyncResult<ProtoMessage>());
}

}  // namespace ipc
}  // namespace perfetto
// gen_amalgamated begin source: src/ipc/virtual_destructors.cc
// gen_amalgamated begin header: include/perfetto/ext/ipc/client.h
/*
 * Copyright (C) 2017 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef INCLUDE_PERFETTO_EXT_IPC_CLIENT_H_
#define INCLUDE_PERFETTO_EXT_IPC_CLIENT_H_

#include <functional>
#include <memory>

// gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"
// gen_amalgamated expanded: #include "perfetto/ext/base/unix_socket.h"
// gen_amalgamated expanded: #include "perfetto/ext/base/weak_ptr.h"
// gen_amalgamated expanded: #include "perfetto/ext/ipc/basic_types.h"

namespace perfetto {

namespace base {
class TaskRunner;
}  // namespace base

namespace ipc {
class ServiceProxy;

// The client-side class that talks to the host over the socket and multiplexes
// requests coming from the various autogenerated ServiceProxy stubs.
// This is meant to be used by the user code as follows:
// auto client = Client::CreateInstance("socket_name", task_runner);
// std::unique_ptr<GreeterService> svc(new GreeterService());
// client.BindService(svc);
// svc.OnConnect([] () {
//    svc.SayHello(..., ...);
// });
class Client {
 public:
  // struct ConnArgs is used for creating a client in 2 connection modes:
  // 1. Connect using a socket name with the option to retry the connection on
  //    connection failure.
  // 2. Adopt a connected socket.
  struct ConnArgs {
    ConnArgs(const char* sock_name, bool sock_retry)
        : socket_name(sock_name), retry(sock_retry) {}
    explicit ConnArgs(base::ScopedSocketHandle sock_fd)
        : socket_fd(std::move(sock_fd)) {}

    // Disallow copy. Only supports move.
    ConnArgs(const ConnArgs& other) = delete;
    ConnArgs(ConnArgs&& other) = default;

    base::ScopedSocketHandle socket_fd;
    const char* socket_name = nullptr;
    bool retry = false;  // Only for connecting with |socket_name|.
    std::function<int(void)> receive_shmem_fd_cb_fuchsia;
  };

  static std::unique_ptr<Client> CreateInstance(ConnArgs, base::TaskRunner*);
  virtual ~Client();

  virtual void BindService(base::WeakPtr<ServiceProxy>) = 0;

  // There is no need to call this method explicitly. Destroying the
  // ServiceProxy instance is sufficient and will automatically unbind it. This
  // method is exposed only for the ServiceProxy destructor.
  virtual void UnbindService(ServiceID) = 0;

  // Returns (with move semantics) the last file descriptor received on the IPC
  // channel. No buffering is performed: if a service sends two file descriptors
  // and the caller doesn't read them immediately, the first one will be
  // automatically closed when the second is received (and will hit a DCHECK in
  // debug builds).
  virtual base::ScopedFile TakeReceivedFD() = 0;
};

}  // namespace ipc
}  // namespace perfetto

#endif  // INCLUDE_PERFETTO_EXT_IPC_CLIENT_H_
// gen_amalgamated begin header: include/perfetto/ext/ipc/host.h
/*
 * Copyright (C) 2017 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef INCLUDE_PERFETTO_EXT_IPC_HOST_H_
#define INCLUDE_PERFETTO_EXT_IPC_HOST_H_

#include <memory>

// gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"
// gen_amalgamated expanded: #include "perfetto/ext/base/unix_socket.h"
// gen_amalgamated expanded: #include "perfetto/ext/ipc/basic_types.h"

namespace perfetto {

namespace base {
class TaskRunner;
}  // namespace base

namespace ipc {

class Service;

// The host-side of the IPC layer. This class acts as a registry and request
// dispatcher. It listen on the UnixSocket |socket_name| for incoming requests
// (coming Client instances) and dispatches their requests to the various
// Services exposed.
class Host {
 public:
  // Creates an instance and starts listening on the given |socket_name|.
  // Returns nullptr if listening on the socket fails.
  static std::unique_ptr<Host> CreateInstance(const char* socket_name,
                                              base::TaskRunner*);

  // Like the above but takes a file descriptor to a pre-bound unix socket.
  // Returns nullptr if listening on the socket fails.
  static std::unique_ptr<Host> CreateInstance(base::ScopedSocketHandle,
                                              base::TaskRunner*);

  // Creates a Host which is not backed by a POSIX listening socket.
  // Instead, it accepts sockets passed in via AdoptConnectedSocket_Fuchsia().
  // See go/fuchsetto for more details.
  static std::unique_ptr<Host> CreateInstance_Fuchsia(base::TaskRunner*);

  virtual ~Host();

  // Registers a new service and makes it available to remote IPC peers.
  // All the exposed Service instances will be destroyed when destroying the
  // Host instance if ExposeService succeeds and returns true, or immediately
  // after the call in case of failure.
  // Returns true if the register has been successfully registered, false in
  // case of errors (e.g., another service with the same name is already
  // registered).
  virtual bool ExposeService(std::unique_ptr<Service>) = 0;

  // Accepts a pre-connected socket handle and a callback used to send a
  // shared memory FD to the remote client.
  // The callback returns false if the FD could not be sent.
  // Should only be used in conjunction with CreateInstance_Fuchsia().
  virtual void AdoptConnectedSocket_Fuchsia(
      base::ScopedSocketHandle,
      std::function<bool(int)> send_fd_cb) = 0;

  // Overrides the default send timeout for the per-connection sockets.
  virtual void SetSocketSendTimeoutMs(uint32_t timeout_ms) = 0;
};

}  // namespace ipc
}  // namespace perfetto

#endif  // INCLUDE_PERFETTO_EXT_IPC_HOST_H_
// gen_amalgamated begin header: include/perfetto/ext/ipc/service.h
// gen_amalgamated begin header: include/perfetto/ext/ipc/client_info.h
/*
 * Copyright (C) 2017 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef INCLUDE_PERFETTO_EXT_IPC_CLIENT_INFO_H_
#define INCLUDE_PERFETTO_EXT_IPC_CLIENT_INFO_H_

// gen_amalgamated expanded: #include "perfetto/base/logging.h"
// gen_amalgamated expanded: #include "perfetto/ext/base/sys_types.h"
// gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
// gen_amalgamated expanded: #include "perfetto/ext/ipc/basic_types.h"

namespace perfetto {
namespace ipc {

// Passed to Service(s) to identify remote clients.
class ClientInfo {
 public:
  ClientInfo() = default;
  ClientInfo(ClientID client_id,
             uid_t uid,
             pid_t pid,
             base::MachineID machine_id)
      : client_id_(client_id), uid_(uid), pid_(pid), machine_id_(machine_id) {}

  bool operator==(const ClientInfo& other) const {
    return std::tie(client_id_, uid_, pid_, machine_id_) ==
           std::tie(other.client_id_, other.uid_, other.pid_,
                    other.machine_id_);
  }
  bool operator!=(const ClientInfo& other) const { return !(*this == other); }

  // For map<> and other sorted containers.
  bool operator<(const ClientInfo& other) const {
    PERFETTO_DCHECK(client_id_ != other.client_id_ || *this == other);
    return client_id_ < other.client_id_;
  }

  bool is_valid() const { return client_id_ != 0; }

  // A monotonic counter.
  ClientID client_id() const { return client_id_; }

  // Posix User ID. Comes from the kernel, can be trusted.
  uid_t uid() const { return uid_; }

  // Posix process ID. Comes from the kernel and can be trusted.
  int32_t pid() const { return pid_; }

  // An integral ID that identifies the machine the client is on.
  base::MachineID machine_id() const { return machine_id_; }

 private:
  ClientID client_id_ = 0;
  // The following fields are emitted to trace packets and should be kept in
  // sync with perfetto::ClientIdentity.
  uid_t uid_ = kInvalidUid;
  pid_t pid_ = base::kInvalidPid;
  base::MachineID machine_id_ = base::kDefaultMachineID;
};

}  // namespace ipc
}  // namespace perfetto

#endif  // INCLUDE_PERFETTO_EXT_IPC_CLIENT_INFO_H_
/*
 * Copyright (C) 2017 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef INCLUDE_PERFETTO_EXT_IPC_SERVICE_H_
#define INCLUDE_PERFETTO_EXT_IPC_SERVICE_H_

// gen_amalgamated expanded: #include "perfetto/base/logging.h"
// gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"
// gen_amalgamated expanded: #include "perfetto/ext/ipc/client_info.h"

namespace perfetto {
namespace ipc {

class ServiceDescriptor;

// The base class for all the autogenerated host-side service interfaces.
class Service {
 public:
  virtual ~Service();

  // Overridden by the auto-generated class. Provides the list of methods and
  // the protobuf (de)serialization functions for their arguments.
  virtual const ServiceDescriptor& GetDescriptor() = 0;

  // Invoked when a remote client disconnects. Use client_info() to obtain
  // details about the client that disconnected.
  virtual void OnClientDisconnected() {}

  // Returns the ClientInfo for the current IPC request. Returns an invalid
  // ClientInfo if called outside the scope of an IPC method.
  const ClientInfo& client_info() {
    PERFETTO_DCHECK(client_info_.is_valid());
    return client_info_;
  }

  base::ScopedFile TakeReceivedFD() {
    if (received_fd_)
      return std::move(*received_fd_);
    return base::ScopedFile();
  }

  bool use_shmem_emulation() { return use_shmem_emulation_; }

 private:
  friend class HostImpl;
  ClientInfo client_info_;
  // This is a pointer because the received fd needs to remain owned by the
  // ClientConnection, as we will provide it to all method invocations
  // for that client until one of them calls Service::TakeReceivedFD.
  //
  // Different clients might have sent different FDs so this cannot be owned
  // here.
  //
  // Note that this means that there can always only be one outstanding
  // invocation per client that supplies an FD and the client needs to
  // wait for this one to return before calling another one.
  base::ScopedFile* received_fd_;

  // Whether the socket needs to emulate shared memory buffer. Set by HostImpl
  // when the service is exposed.
  bool use_shmem_emulation_ = false;
};

}  // namespace ipc
}  // namespace perfetto

#endif  // INCLUDE_PERFETTO_EXT_IPC_SERVICE_H_
// gen_amalgamated begin header: include/perfetto/ext/ipc/service_proxy.h
/*
 * Copyright (C) 2017 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef INCLUDE_PERFETTO_EXT_IPC_SERVICE_PROXY_H_
#define INCLUDE_PERFETTO_EXT_IPC_SERVICE_PROXY_H_

// gen_amalgamated expanded: #include "perfetto/ext/ipc/basic_types.h"

#include <assert.h>

#include <functional>
#include <map>
#include <memory>
#include <string>

// gen_amalgamated expanded: #include "perfetto/base/export.h"
// gen_amalgamated expanded: #include "perfetto/ext/base/weak_ptr.h"
// gen_amalgamated expanded: #include "perfetto/ext/ipc/deferred.h"

namespace perfetto {
namespace ipc {

class Client;
class ServiceDescriptor;

// The base class for the client-side autogenerated stubs that forward method
// invocations to the host. All the methods of this class are meant to be called
// only by the autogenerated code.
class PERFETTO_EXPORT_COMPONENT ServiceProxy {
 public:
  class EventListener {
   public:
    virtual ~EventListener();

    // Called once after Client::BindService() if the ServiceProxy has been
    // successfully bound to the host. It is possible to start sending IPC
    // requests soon after this.
    virtual void OnConnect() {}

    // Called if the connection fails to be established or drops after having
    // been established.
    virtual void OnDisconnect() {}
  };

  // Guarantees that no callback will happen after this object has been
  // destroyed. The caller has to guarantee that the |event_listener| stays
  // alive at least as long as the ServiceProxy instance.
  explicit ServiceProxy(EventListener*);
  virtual ~ServiceProxy();

  void InitializeBinding(base::WeakPtr<Client>,
                         ServiceID,
                         std::map<std::string, MethodID>);

  // Called by the IPC methods in the autogenerated classes.
  void BeginInvoke(const std::string& method_name,
                   const ProtoMessage& request,
                   DeferredBase reply,
                   int fd = -1);

  // Called by ClientImpl.
  // |reply_args| == nullptr means request failure.
  void EndInvoke(RequestID,
                 std::unique_ptr<ProtoMessage> reply_arg,
                 bool has_more);

  // Called by ClientImpl.
  void OnConnect(bool success);
  void OnDisconnect();
  bool connected() const { return service_id_ != 0; }

  base::WeakPtr<ServiceProxy> GetWeakPtr() const;

  // Implemented by the autogenerated class.
  virtual const ServiceDescriptor& GetDescriptor() = 0;

 private:
  base::WeakPtr<Client> client_;
  ServiceID service_id_ = 0;
  std::map<std::string, MethodID> remote_method_ids_;
  std::map<RequestID, DeferredBase> pending_callbacks_;
  EventListener* const event_listener_;
  base::WeakPtrFactory<ServiceProxy> weak_ptr_factory_;  // Keep last.
};

}  // namespace ipc
}  // namespace perfetto

#endif  // INCLUDE_PERFETTO_EXT_IPC_SERVICE_PROXY_H_
/*
 * Copyright (C) 2018 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// gen_amalgamated expanded: #include "perfetto/ext/ipc/client.h"
// gen_amalgamated expanded: #include "perfetto/ext/ipc/host.h"
// gen_amalgamated expanded: #include "perfetto/ext/ipc/service.h"
// gen_amalgamated expanded: #include "perfetto/ext/ipc/service_proxy.h"

// This translation unit contains the definitions for the destructor of pure
// virtual interfaces for the current build target. The alternative would be
// introducing a one-liner .cc file for each pure virtual interface, which is
// overkill. This is for compliance with -Wweak-vtables.

namespace perfetto {
namespace ipc {

Client::~Client() = default;
Host::~Host() = default;
Service::~Service() = default;
ServiceProxy::EventListener::~EventListener() = default;

}  // namespace ipc
}  // namespace perfetto
// gen_amalgamated begin source: src/ipc/client_impl.cc
// gen_amalgamated begin header: src/ipc/client_impl.h
/*
 * Copyright (C) 2017 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef SRC_IPC_CLIENT_IMPL_H_
#define SRC_IPC_CLIENT_IMPL_H_

#include <list>
#include <map>
#include <memory>

// gen_amalgamated expanded: #include "perfetto/base/task_runner.h"
// gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"
// gen_amalgamated expanded: #include "perfetto/ext/base/unix_socket.h"
// gen_amalgamated expanded: #include "perfetto/ext/ipc/client.h"
// gen_amalgamated expanded: #include "src/ipc/buffered_frame_deserializer.h"

namespace perfetto {

namespace protos {
namespace gen {
class IPCFrame_BindServiceReply;
class IPCFrame_InvokeMethodReply;
}  // namespace gen
}  // namespace protos

namespace base {
class TaskRunner;
}  // namespace base

namespace ipc {

class ServiceDescriptor;

class ClientImpl : public Client, public base::UnixSocket::EventListener {
 public:
  ClientImpl(ConnArgs, base::TaskRunner*);
  ~ClientImpl() override;

  // Client implementation.
  void BindService(base::WeakPtr<ServiceProxy>) override;
  void UnbindService(ServiceID) override;
  base::ScopedFile TakeReceivedFD() override;

  // base::UnixSocket::EventListener implementation.
  void OnConnect(base::UnixSocket*, bool connected) override;
  void OnDisconnect(base::UnixSocket*) override;
  void OnDataAvailable(base::UnixSocket*) override;

  RequestID BeginInvoke(ServiceID,
                        const std::string& method_name,
                        MethodID remote_method_id,
                        const ProtoMessage& method_args,
                        bool drop_reply,
                        base::WeakPtr<ServiceProxy>,
                        int fd = -1);

  base::UnixSocket* GetUnixSocketForTesting() { return sock_.get(); }

 private:
  struct QueuedRequest {
    QueuedRequest();
    int type = 0;  // From Frame::msg_case(), see wire_protocol.proto.
    RequestID request_id = 0;
    base::WeakPtr<ServiceProxy> service_proxy;

    // Only for type == kMsgInvokeMethod.
    std::string method_name;
  };

  ClientImpl(const ClientImpl&) = delete;
  ClientImpl& operator=(const ClientImpl&) = delete;

  void TryConnect();
  bool SendFrame(const Frame&, int fd = -1);
  void OnFrameReceived(const Frame&);
  void OnBindServiceReply(QueuedRequest,
                          const protos::gen::IPCFrame_BindServiceReply&);
  void OnInvokeMethodReply(QueuedRequest,
                           const protos::gen::IPCFrame_InvokeMethodReply&);

  bool invoking_method_reply_ = false;
  const char* socket_name_ = nullptr;
  bool socket_retry_ = false;
  uint32_t socket_backoff_ms_ = 0;
  std::unique_ptr<base::UnixSocket> sock_;
  base::TaskRunner* const task_runner_;
  RequestID last_request_id_ = 0;
  BufferedFrameDeserializer frame_deserializer_;
  base::ScopedFile received_fd_;
  std::map<RequestID, QueuedRequest> queued_requests_;
  std::map<ServiceID, base::WeakPtr<ServiceProxy>> service_bindings_;

  // Queue of calls to BindService() that happened before the socket connected.
  std::list<base::WeakPtr<ServiceProxy>> queued_bindings_;

  base::WeakPtrFactory<Client> weak_ptr_factory_;  // Keep last.
};

}  // namespace ipc
}  // namespace perfetto

#endif  // SRC_IPC_CLIENT_IMPL_H_
// gen_amalgamated begin header: include/perfetto/ext/ipc/service_descriptor.h
/*
 * Copyright (C) 2017 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef INCLUDE_PERFETTO_EXT_IPC_SERVICE_DESCRIPTOR_H_
#define INCLUDE_PERFETTO_EXT_IPC_SERVICE_DESCRIPTOR_H_

#include <functional>
#include <string>
#include <utility>
#include <vector>

// gen_amalgamated expanded: #include "perfetto/ext/ipc/basic_types.h"
// gen_amalgamated expanded: #include "perfetto/ext/ipc/deferred.h"

namespace perfetto {
namespace ipc {

class Service;

// This is a pure data structure which holds factory methods and strings for the
// services and their methods that get generated in the .h/.cc files.
// Each autogenerated class has a GetDescriptor() method that returns one
// instance of these and allows both client and hosts to map service and method
// names to IDs and provide function pointers to the protobuf decoder fuctions.
class ServiceDescriptor {
 public:
  struct Method {
    const char* name;

    // DecoderFunc is pointer to a function that takes a string in input
    // containing protobuf encoded data and returns a decoded protobuf message.
    using DecoderFunc = std::unique_ptr<ProtoMessage> (*)(const std::string&);

    // Function pointer to decode the request argument of the method.
    DecoderFunc request_proto_decoder;

    // Function pointer to decoded the reply argument of the method.
    DecoderFunc reply_proto_decoder;

    // Function pointer that dispatches the generic request to the corresponding
    // method implementation.
    using InvokerFunc = void (*)(Service*,
                                 const ProtoMessage& /* request_args */,
                                 DeferredBase /* deferred_reply */);
    InvokerFunc invoker;
  };

  const char* service_name = nullptr;

  // Note that methods order is not stable. Client and Host might have different
  // method indexes, depending on their versions. The Client can't just rely
  // on the indexes and has to keep a [string -> remote index] translation map.
  std::vector<Method> methods;
};

}  // namespace ipc
}  // namespace perfetto

#endif  // INCLUDE_PERFETTO_EXT_IPC_SERVICE_DESCRIPTOR_H_
/*
 * Copyright (C) 2017 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// gen_amalgamated expanded: #include "src/ipc/client_impl.h"

#include <fcntl.h>

#include <cinttypes>
#include <utility>

// gen_amalgamated expanded: #include "perfetto/base/task_runner.h"
// gen_amalgamated expanded: #include "perfetto/ext/base/unix_socket.h"
// gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
// gen_amalgamated expanded: #include "perfetto/ext/ipc/service_descriptor.h"
// gen_amalgamated expanded: #include "perfetto/ext/ipc/service_proxy.h"

// gen_amalgamated expanded: #include "protos/perfetto/ipc/wire_protocol.gen.h"

// TODO(primiano): Add ThreadChecker everywhere.

// TODO(primiano): Add timeouts.

namespace perfetto {
namespace ipc {

namespace {
constexpr base::SockFamily kClientSockFamily =
    kUseTCPSocket ? base::SockFamily::kInet : base::SockFamily::kUnix;
}  // namespace

// static
std::unique_ptr<Client> Client::CreateInstance(ConnArgs conn_args,
                                               base::TaskRunner* task_runner) {
  std::unique_ptr<Client> client(
      new ClientImpl(std::move(conn_args), task_runner));
  return client;
}

ClientImpl::ClientImpl(ConnArgs conn_args, base::TaskRunner* task_runner)
    : socket_name_(conn_args.socket_name),
      socket_retry_(conn_args.retry),
      task_runner_(task_runner),
      weak_ptr_factory_(this) {
  if (conn_args.socket_fd) {
    // Create the client using a connected socket. This code path will never hit
    // OnConnect().
    sock_ = base::UnixSocket::AdoptConnected(
        std::move(conn_args.socket_fd), this, task_runner_, kClientSockFamily,
        base::SockType::kStream, base::SockPeerCredMode::kIgnore);
  } else {
    // Connect using the socket name.
    TryConnect();
  }
}

ClientImpl::~ClientImpl() {
  // Ensure we are not destroyed in the middle of invoking a reply.
  PERFETTO_DCHECK(!invoking_method_reply_);
  OnDisconnect(
      nullptr);  // The base::UnixSocket* ptr is not used in OnDisconnect().
}

void ClientImpl::TryConnect() {
  PERFETTO_DCHECK(socket_name_);
  sock_ = base::UnixSocket::Connect(
      socket_name_, this, task_runner_, base::GetSockFamily(socket_name_),
      base::SockType::kStream, base::SockPeerCredMode::kIgnore);
}

void ClientImpl::BindService(base::WeakPtr<ServiceProxy> service_proxy) {
  if (!service_proxy)
    return;
  if (!sock_->is_connected()) {
    queued_bindings_.emplace_back(service_proxy);
    return;
  }
  RequestID request_id = ++last_request_id_;
  Frame frame;
  frame.set_request_id(request_id);
  Frame::BindService* req = frame.mutable_msg_bind_service();
  const char* const service_name = service_proxy->GetDescriptor().service_name;
  req->set_service_name(service_name);
  if (!SendFrame(frame)) {
    PERFETTO_DLOG("BindService(%s) failed", service_name);
    return service_proxy->OnConnect(false /* success */);
  }
  QueuedRequest qr;
  qr.type = Frame::kMsgBindServiceFieldNumber;
  qr.request_id = request_id;
  qr.service_proxy = service_proxy;
  queued_requests_.emplace(request_id, std::move(qr));
}

void ClientImpl::UnbindService(ServiceID service_id) {
  service_bindings_.erase(service_id);
}

RequestID ClientImpl::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) {
  RequestID request_id = ++last_request_id_;
  Frame frame;
  frame.set_request_id(request_id);
  Frame::InvokeMethod* req = frame.mutable_msg_invoke_method();
  req->set_service_id(service_id);
  req->set_method_id(remote_method_id);
  req->set_drop_reply(drop_reply);
  req->set_args_proto(method_args.SerializeAsString());
  if (!SendFrame(frame, fd)) {
    PERFETTO_DLOG("BeginInvoke() failed while sending the frame");
    return 0;
  }
  if (drop_reply)
    return 0;
  QueuedRequest qr;
  qr.type = Frame::kMsgInvokeMethodFieldNumber;
  qr.request_id = request_id;
  qr.method_name = method_name;
  qr.service_proxy = std::move(service_proxy);
  queued_requests_.emplace(request_id, std::move(qr));
  return request_id;
}

bool ClientImpl::SendFrame(const Frame& frame, int fd) {
  // Serialize the frame into protobuf, add the size header, and send it.
  std::string buf = BufferedFrameDeserializer::Serialize(frame);

  // TODO(primiano): this should do non-blocking I/O. But then what if the
  // socket buffer is full? We might want to either drop the request or throttle
  // the send and PostTask the reply later? Right now we are making Send()
  // blocking as a workaround. Propagate bakpressure to the caller instead.
  bool res = sock_->Send(buf.data(), buf.size(), fd);
  PERFETTO_CHECK(res || !sock_->is_connected());
  return res;
}

void ClientImpl::OnConnect(base::UnixSocket*, bool connected) {
  if (!connected && socket_retry_) {
    socket_backoff_ms_ =
        (socket_backoff_ms_ < 10000) ? socket_backoff_ms_ + 1000 : 30000;
    PERFETTO_DLOG(
        "Connection to traced's UNIX socket failed, retrying in %u seconds",
        socket_backoff_ms_ / 1000);
    auto weak_this = weak_ptr_factory_.GetWeakPtr();
    task_runner_->PostDelayedTask(
        [weak_this] {
          if (weak_this)
            static_cast<ClientImpl&>(*weak_this).TryConnect();
        },
        socket_backoff_ms_);
    return;
  }

  // Drain the BindService() calls that were queued before establishing the
  // connection with the host. Note that if we got disconnected, the call to
  // OnConnect below might delete |this|, so move everything on the stack first.
  auto queued_bindings = std::move(queued_bindings_);
  queued_bindings_.clear();
  for (base::WeakPtr<ServiceProxy>& service_proxy : queued_bindings) {
    if (connected) {
      BindService(service_proxy);
    } else if (service_proxy) {
      service_proxy->OnConnect(false /* success */);
    }
  }
  // Don't access |this| below here.
}

void ClientImpl::OnDisconnect(base::UnixSocket*) {
  for (const auto& it : service_bindings_) {
    base::WeakPtr<ServiceProxy> service_proxy = it.second;
    task_runner_->PostTask([service_proxy] {
      if (service_proxy)
        service_proxy->OnDisconnect();
    });
  }
  for (const auto& it : queued_requests_) {
    const QueuedRequest& queued_request = it.second;
    if (queued_request.type != Frame::kMsgBindServiceFieldNumber) {
      continue;
    }
    base::WeakPtr<ServiceProxy> service_proxy = queued_request.service_proxy;
    task_runner_->PostTask([service_proxy] {
      if (service_proxy)
        service_proxy->OnConnect(false);
    });
  }
  service_bindings_.clear();
  queued_bindings_.clear();
}

void ClientImpl::OnDataAvailable(base::UnixSocket*) {
  size_t rsize;
  do {
    auto buf = frame_deserializer_.BeginReceive();
    base::ScopedFile fd;
    rsize = sock_->Receive(buf.data, buf.size, &fd);
#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
    PERFETTO_DCHECK(!fd);
#else
    if (fd) {
      PERFETTO_DCHECK(!received_fd_);
      int res = fcntl(*fd, F_SETFD, FD_CLOEXEC);
      PERFETTO_DCHECK(res == 0);
      received_fd_ = std::move(fd);
    }
#endif
    if (!frame_deserializer_.EndReceive(rsize)) {
      // The endpoint tried to send a frame that is way too large.
      return sock_->Shutdown(true);  // In turn will trigger an OnDisconnect().
      // TODO(fmayer): check this.
    }
  } while (rsize > 0);

  while (std::unique_ptr<Frame> frame = frame_deserializer_.PopNextFrame())
    OnFrameReceived(*frame);
}

void ClientImpl::OnFrameReceived(const Frame& frame) {
  auto queued_requests_it = queued_requests_.find(frame.request_id());
  if (queued_requests_it == queued_requests_.end()) {
    PERFETTO_DLOG("OnFrameReceived(): got invalid request_id=%" PRIu64,
                  static_cast<uint64_t>(frame.request_id()));
    return;
  }
  QueuedRequest req = std::move(queued_requests_it->second);
  queued_requests_.erase(queued_requests_it);

  if (req.type == Frame::kMsgBindServiceFieldNumber &&
      frame.has_msg_bind_service_reply()) {
    return OnBindServiceReply(std::move(req), frame.msg_bind_service_reply());
  }
  if (req.type == Frame::kMsgInvokeMethodFieldNumber &&
      frame.has_msg_invoke_method_reply()) {
    return OnInvokeMethodReply(std::move(req), frame.msg_invoke_method_reply());
  }
  if (frame.has_msg_request_error()) {
    PERFETTO_DLOG("Host error: %s", frame.msg_request_error().error().c_str());
    return;
  }

  PERFETTO_DLOG(
      "OnFrameReceived() request type=%d, received unknown frame in reply to "
      "request_id=%" PRIu64,
      req.type, static_cast<uint64_t>(frame.request_id()));
}

void ClientImpl::OnBindServiceReply(QueuedRequest req,
                                    const Frame::BindServiceReply& reply) {
  base::WeakPtr<ServiceProxy>& service_proxy = req.service_proxy;
  if (!service_proxy)
    return;
  const char* svc_name = service_proxy->GetDescriptor().service_name;
  if (!reply.success()) {
    PERFETTO_DLOG("BindService(): unknown service_name=\"%s\"", svc_name);
    return service_proxy->OnConnect(false /* success */);
  }

  auto prev_service = service_bindings_.find(reply.service_id());
  if (prev_service != service_bindings_.end() && prev_service->second.get()) {
    PERFETTO_DLOG(
        "BindService(): Trying to bind service \"%s\" but another service "
        "named \"%s\" is already bound with the same ID.",
        svc_name, prev_service->second->GetDescriptor().service_name);
    return service_proxy->OnConnect(false /* success */);
  }

  // Build the method [name] -> [remote_id] map.
  std::map<std::string, MethodID> methods;
  for (const auto& method : reply.methods()) {
    if (method.name().empty() || method.id() <= 0) {
      PERFETTO_DLOG("OnBindServiceReply(): invalid method \"%s\" -> %" PRIu64,
                    method.name().c_str(), static_cast<uint64_t>(method.id()));
      continue;
    }
    methods[method.name()] = method.id();
  }
  service_proxy->InitializeBinding(weak_ptr_factory_.GetWeakPtr(),
                                   reply.service_id(), std::move(methods));
  service_bindings_[reply.service_id()] = service_proxy;
  service_proxy->OnConnect(true /* success */);
}

void ClientImpl::OnInvokeMethodReply(QueuedRequest req,
                                     const Frame::InvokeMethodReply& reply) {
  base::WeakPtr<ServiceProxy> service_proxy = req.service_proxy;
  if (!service_proxy)
    return;
  std::unique_ptr<ProtoMessage> decoded_reply;
  if (reply.success()) {
    // If this becomes a hotspot, optimize by maintaining a dedicated hashtable.
    for (const auto& method : service_proxy->GetDescriptor().methods) {
      if (req.method_name == method.name) {
        decoded_reply = method.reply_proto_decoder(reply.reply_proto());
        break;
      }
    }
  }
  const RequestID request_id = req.request_id;
  invoking_method_reply_ = true;
  service_proxy->EndInvoke(request_id, std::move(decoded_reply),
                           reply.has_more());
  invoking_method_reply_ = false;

  // If this is a streaming method and future replies will be resolved, put back
  // the |req| with the callback into the set of active requests.
  if (reply.has_more())
    queued_requests_.emplace(request_id, std::move(req));
}

ClientImpl::QueuedRequest::QueuedRequest() = default;

base::ScopedFile ClientImpl::TakeReceivedFD() {
  return std::move(received_fd_);
}

}  // namespace ipc
}  // namespace perfetto
// gen_amalgamated begin source: src/ipc/service_proxy.cc
/*
 * Copyright (C) 2017 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// gen_amalgamated expanded: #include "perfetto/ext/ipc/service_proxy.h"

#include <utility>

// gen_amalgamated expanded: #include "perfetto/base/logging.h"
// gen_amalgamated expanded: #include "perfetto/ext/base/weak_ptr.h"
// gen_amalgamated expanded: #include "perfetto/ext/ipc/service_descriptor.h"
// gen_amalgamated expanded: #include "src/ipc/client_impl.h"

// gen_amalgamated expanded: #include "protos/perfetto/ipc/wire_protocol.gen.h"

namespace perfetto {
namespace ipc {

ServiceProxy::ServiceProxy(EventListener* event_listener)
    : event_listener_(event_listener), weak_ptr_factory_(this) {}

ServiceProxy::~ServiceProxy() {
  if (client_ && connected())
    client_->UnbindService(service_id_);
}

void ServiceProxy::InitializeBinding(
    base::WeakPtr<Client> client,
    ServiceID service_id,
    std::map<std::string, MethodID> remote_method_ids) {
  client_ = std::move(client);
  service_id_ = service_id;
  remote_method_ids_ = std::move(remote_method_ids);
}

void ServiceProxy::BeginInvoke(const std::string& method_name,
                               const ProtoMessage& request,
                               DeferredBase reply,
                               int fd) {
  // |reply| will auto-resolve if it gets out of scope early.
  if (!connected()) {
    PERFETTO_DFATAL("Not connected.");
    return;
  }
  if (!client_)
    return;  // The Client object has been destroyed in the meantime.

  auto remote_method_it = remote_method_ids_.find(method_name);
  RequestID request_id = 0;
  const bool drop_reply = !reply.IsBound();
  if (remote_method_it != remote_method_ids_.end()) {
    request_id =
        static_cast<ClientImpl*>(client_.get())
            ->BeginInvoke(service_id_, method_name, remote_method_it->second,
                          request, drop_reply, weak_ptr_factory_.GetWeakPtr(),
                          fd);
  } else {
    PERFETTO_DLOG("Cannot find method \"%s\" on the host", method_name.c_str());
  }

  // When passing |drop_reply| == true, the returned |request_id| should be 0.
  PERFETTO_DCHECK(!drop_reply || !request_id);

  if (!request_id)
    return;
  PERFETTO_DCHECK(pending_callbacks_.count(request_id) == 0);
  pending_callbacks_.emplace(request_id, std::move(reply));
}

void ServiceProxy::EndInvoke(RequestID request_id,
                             std::unique_ptr<ProtoMessage> result,
                             bool has_more) {
  auto callback_it = pending_callbacks_.find(request_id);
  if (callback_it == pending_callbacks_.end()) {
    // Either we are getting a reply for a method we never invoked, or we are
    // getting a reply to a method marked drop_reply (that has been invoked
    // without binding any callback in the Defererd response object).
    PERFETTO_DFATAL("Unexpected reply received.");
    return;
  }
  DeferredBase& reply_callback = callback_it->second;
  AsyncResult<ProtoMessage> reply(std::move(result), has_more);
  reply_callback.Resolve(std::move(reply));
  if (!has_more)
    pending_callbacks_.erase(callback_it);
}

void ServiceProxy::OnConnect(bool success) {
  if (success) {
    PERFETTO_DCHECK(service_id_);
    return event_listener_->OnConnect();
  }
  return event_listener_->OnDisconnect();
}

void ServiceProxy::OnDisconnect() {
  pending_callbacks_.clear();  // Will Reject() all the pending callbacks.
  event_listener_->OnDisconnect();
}

base::WeakPtr<ServiceProxy> ServiceProxy::GetWeakPtr() const {
  return weak_ptr_factory_.GetWeakPtr();
}

}  // namespace ipc
}  // namespace perfetto
// gen_amalgamated begin source: src/ipc/host_impl.cc
// gen_amalgamated begin header: src/ipc/host_impl.h
/*
 * Copyright (C) 2017 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef SRC_IPC_HOST_IMPL_H_
#define SRC_IPC_HOST_IMPL_H_

#include <map>
#include <set>
#include <string>
#include <vector>

// gen_amalgamated expanded: #include "perfetto/base/task_runner.h"
// gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"
// gen_amalgamated expanded: #include "perfetto/ext/base/sys_types.h"
// gen_amalgamated expanded: #include "perfetto/ext/base/thread_checker.h"
// gen_amalgamated expanded: #include "perfetto/ext/base/unix_socket.h"
// gen_amalgamated expanded: #include "perfetto/ext/ipc/deferred.h"
// gen_amalgamated expanded: #include "perfetto/ext/ipc/host.h"
// gen_amalgamated expanded: #include "src/ipc/buffered_frame_deserializer.h"

namespace perfetto {
namespace ipc {

constexpr uint32_t kDefaultIpcTxTimeoutMs = 10000;

class HostImpl : public Host, public base::UnixSocket::EventListener {
 public:
  HostImpl(const char* socket_name, base::TaskRunner*);
  HostImpl(base::ScopedSocketHandle, base::TaskRunner*);
  HostImpl(base::TaskRunner* task_runner);
  ~HostImpl() override;

  // Host implementation.
  bool ExposeService(std::unique_ptr<Service>) override;
  void AdoptConnectedSocket_Fuchsia(
      base::ScopedSocketHandle,
      std::function<bool(int)> send_fd_cb) override;
  void SetSocketSendTimeoutMs(uint32_t timeout_ms) override;

  // base::UnixSocket::EventListener implementation.
  void OnNewIncomingConnection(base::UnixSocket*,
                               std::unique_ptr<base::UnixSocket>) override;
  void OnDisconnect(base::UnixSocket*) override;
  void OnDataAvailable(base::UnixSocket*) override;

  const base::UnixSocket* sock() const { return sock_.get(); }

 private:
  // Owns the per-client receive buffer (BufferedFrameDeserializer).
  struct ClientConnection {
    ~ClientConnection();
    ClientID id;
    std::unique_ptr<base::UnixSocket> sock;
    BufferedFrameDeserializer frame_deserializer;
    base::ScopedFile received_fd;
    std::function<bool(int)> send_fd_cb_fuchsia;
    // Peer identity set using IPCFrame sent by the client. These 3 fields
    // should be used only for non-AF_UNIX connections AF_UNIX connections
    // should only rely on the peer identity obtained from the socket.
    uid_t uid_override = base::kInvalidUid;
    pid_t pid_override = base::kInvalidPid;

    // |machine_id| is mapped from machine_id_hint (or socket hostname if
    // |the client doesn't support machine_id_hint).
    base::MachineID machine_id = base::kDefaultMachineID;

    pid_t GetLinuxPeerPid() const;
    uid_t GetPosixPeerUid() const;
    base::MachineID GetMachineID() const { return machine_id; }
  };
  struct ExposedService {
    ExposedService(ServiceID, const std::string&, std::unique_ptr<Service>);
    ~ExposedService();
    ExposedService(ExposedService&&) noexcept;
    ExposedService& operator=(ExposedService&&);

    ServiceID id;
    std::string name;
    std::unique_ptr<Service> instance;
  };

  HostImpl(const HostImpl&) = delete;
  HostImpl& operator=(const HostImpl&) = delete;

  bool Initialize(const char* socket_name);
  void OnReceivedFrame(ClientConnection*, const Frame&);
  void OnBindService(ClientConnection*, const Frame&);
  void OnInvokeMethod(ClientConnection*, const Frame&);
  void OnSetPeerIdentity(ClientConnection*, const Frame&);

  void ReplyToMethodInvocation(ClientID, RequestID, AsyncResult<ProtoMessage>);
  const ExposedService* GetServiceByName(const std::string&);

  static void SendFrame(ClientConnection*, const Frame&, int fd = -1);

  base::TaskRunner* const task_runner_;
  std::map<ServiceID, ExposedService> services_;
  std::unique_ptr<base::UnixSocket> sock_;  // The listening socket.
  std::map<ClientID, std::unique_ptr<ClientConnection>> clients_;
  std::map<base::UnixSocket*, ClientConnection*> clients_by_socket_;
  ServiceID last_service_id_ = 0;
  ClientID last_client_id_ = 0;
  uint32_t socket_tx_timeout_ms_ = kDefaultIpcTxTimeoutMs;
  PERFETTO_THREAD_CHECKER(thread_checker_)
  base::WeakPtrFactory<HostImpl> weak_ptr_factory_;  // Keep last.
};

}  // namespace ipc
}  // namespace perfetto

#endif  // SRC_IPC_HOST_IMPL_H_
/*
 * Copyright (C) 2017 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// gen_amalgamated expanded: #include "src/ipc/host_impl.h"

#include <algorithm>
#include <cinttypes>
#include <utility>

// gen_amalgamated expanded: #include "perfetto/base/build_config.h"
// gen_amalgamated expanded: #include "perfetto/base/compiler.h"
// gen_amalgamated expanded: #include "perfetto/base/logging.h"
// gen_amalgamated expanded: #include "perfetto/base/task_runner.h"
// gen_amalgamated expanded: #include "perfetto/base/time.h"
// gen_amalgamated expanded: #include "perfetto/ext/base/crash_keys.h"
// gen_amalgamated expanded: #include "perfetto/ext/base/sys_types.h"
// gen_amalgamated expanded: #include "perfetto/ext/base/unix_socket.h"
// gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
// gen_amalgamated expanded: #include "perfetto/ext/ipc/service.h"
// gen_amalgamated expanded: #include "perfetto/ext/ipc/service_descriptor.h"

// gen_amalgamated expanded: #include "protos/perfetto/ipc/wire_protocol.gen.h"

// TODO(primiano): put limits on #connections/uid and req. queue (b/69093705).

namespace perfetto {
namespace ipc {

namespace {

constexpr base::SockFamily kHostSockFamily =
    kUseTCPSocket ? base::SockFamily::kInet : base::SockFamily::kUnix;

base::CrashKey g_crash_key_uid("ipc_uid");

base::MachineID GenerateMachineID(base::UnixSocket* sock,
                                  const std::string& machine_id_hint) {
  // The special value of base::kDefaultMachineID is reserved for local
  // producers.
  if (!sock->is_connected() || sock->family() == base::SockFamily::kUnix)
    return base::kDefaultMachineID;

  base::Hasher hasher;
  // Use the hint from the client, or fallback to hostname if the client
  // doesn't provide a hint.
  if (!machine_id_hint.empty()) {
    hasher.Update(machine_id_hint);
  } else {
    // Use the socket address without the port number part as the hint.
    auto host_id = sock->GetSockAddr();
    auto pos = std::string::npos;
    switch (sock->family()) {
      case base::SockFamily::kInet:
        PERFETTO_FALLTHROUGH;
      case base::SockFamily::kInet6:
        PERFETTO_FALLTHROUGH;
      case base::SockFamily::kVsock:
        pos = host_id.rfind(":");
        if (pos != std::string::npos)
          host_id.resize(pos);
        break;
      case base::SockFamily::kUnspec:
        PERFETTO_FALLTHROUGH;
      case base::SockFamily::kUnix:
        PERFETTO_DFATAL("Should be unreachable.");
        return base::kDefaultMachineID;
    }
    hasher.Update(host_id);
  }

  // Take the lower 32-bit from the hash.
  uint32_t digest = static_cast<uint32_t>(hasher.digest());
  // Avoid the extremely unlikely case that the hasher digest happens to be 0.
  return digest == base::kDefaultMachineID ? 1 : digest;
}
}  // namespace

uid_t HostImpl::ClientConnection::GetPosixPeerUid() const {
#if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) ||   \
    PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \
    PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
  if (sock->family() == base::SockFamily::kUnix)
    return sock->peer_uid_posix();
#endif

  // For non-unix sockets, check if the UID is set in OnSetPeerIdentity().
  if (uid_override != base::kInvalidUid)
    return uid_override;
  // Must be != kInvalidUid or the PacketValidator will fail.
  return 0;
}

pid_t HostImpl::ClientConnection::GetLinuxPeerPid() const {
#if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
    PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
  if (sock->family() == base::SockFamily::kUnix)
    return sock->peer_pid_linux();
#endif

  // For non-unix sockets, return the PID set in OnSetPeerIdentity().
  return pid_override;
}

// static
std::unique_ptr<Host> Host::CreateInstance(const char* socket_name,
                                           base::TaskRunner* task_runner) {
  std::unique_ptr<HostImpl> host(new HostImpl(socket_name, task_runner));
  if (!host->sock() || !host->sock()->is_listening())
    return nullptr;
  return std::unique_ptr<Host>(std::move(host));
}

// static
std::unique_ptr<Host> Host::CreateInstance(base::ScopedSocketHandle socket_fd,
                                           base::TaskRunner* task_runner) {
  std::unique_ptr<HostImpl> host(
      new HostImpl(std::move(socket_fd), task_runner));
  if (!host->sock() || !host->sock()->is_listening())
    return nullptr;
  return std::unique_ptr<Host>(std::move(host));
}

// static
std::unique_ptr<Host> Host::CreateInstance_Fuchsia(
    base::TaskRunner* task_runner) {
  return std::unique_ptr<HostImpl>(new HostImpl(task_runner));
}

HostImpl::HostImpl(base::ScopedSocketHandle socket_fd,
                   base::TaskRunner* task_runner)
    : task_runner_(task_runner), weak_ptr_factory_(this) {
  PERFETTO_DCHECK_THREAD(thread_checker_);
  sock_ = base::UnixSocket::Listen(std::move(socket_fd), this, task_runner_,
                                   kHostSockFamily, base::SockType::kStream);
}

HostImpl::HostImpl(const char* socket_name, base::TaskRunner* task_runner)
    : task_runner_(task_runner), weak_ptr_factory_(this) {
  PERFETTO_DCHECK_THREAD(thread_checker_);
  sock_ = base::UnixSocket::Listen(socket_name, this, task_runner_,
                                   base::GetSockFamily(socket_name),
                                   base::SockType::kStream);
  if (!sock_) {
    PERFETTO_PLOG("Failed to create %s", socket_name);
  }
}

HostImpl::HostImpl(base::TaskRunner* task_runner)
    : task_runner_(task_runner), weak_ptr_factory_(this) {
  PERFETTO_DCHECK_THREAD(thread_checker_);
}

HostImpl::~HostImpl() = default;

bool HostImpl::ExposeService(std::unique_ptr<Service> service) {
  PERFETTO_DCHECK_THREAD(thread_checker_);
  const std::string& service_name = service->GetDescriptor().service_name;
  if (GetServiceByName(service_name)) {
    PERFETTO_DLOG("Duplicate ExposeService(): %s", service_name.c_str());
    return false;
  }
  service->use_shmem_emulation_ =
      sock() && !base::SockShmemSupported(sock()->family());
  ServiceID sid = ++last_service_id_;
  ExposedService exposed_service(sid, service_name, std::move(service));
  services_.emplace(sid, std::move(exposed_service));
  return true;
}

void HostImpl::AdoptConnectedSocket_Fuchsia(
    base::ScopedSocketHandle connected_socket,
    std::function<bool(int)> send_fd_cb) {
  PERFETTO_DCHECK_THREAD(thread_checker_);
  PERFETTO_DCHECK(connected_socket);
  // Should not be used in conjunction with listen sockets.
  PERFETTO_DCHECK(!sock_);

  auto unix_socket = base::UnixSocket::AdoptConnected(
      std::move(connected_socket), this, task_runner_, kHostSockFamily,
      base::SockType::kStream);

  auto* unix_socket_ptr = unix_socket.get();
  OnNewIncomingConnection(nullptr, std::move(unix_socket));
  ClientConnection* client_connection = clients_by_socket_[unix_socket_ptr];
  client_connection->send_fd_cb_fuchsia = std::move(send_fd_cb);
  PERFETTO_DCHECK(client_connection->send_fd_cb_fuchsia);
}

void HostImpl::SetSocketSendTimeoutMs(uint32_t timeout_ms) {
  PERFETTO_DCHECK_THREAD(thread_checker_);
  // Should be less than the watchdog period (30s).
  socket_tx_timeout_ms_ = timeout_ms;
}

void HostImpl::OnNewIncomingConnection(
    base::UnixSocket*,
    std::unique_ptr<base::UnixSocket> new_conn) {
  PERFETTO_DCHECK_THREAD(thread_checker_);
  std::unique_ptr<ClientConnection> client(new ClientConnection());
  ClientID client_id = ++last_client_id_;
  clients_by_socket_[new_conn.get()] = client.get();
  client->id = client_id;
  client->sock = std::move(new_conn);
  client->sock->SetTxTimeout(socket_tx_timeout_ms_);
  clients_[client_id] = std::move(client);
}

void HostImpl::OnDataAvailable(base::UnixSocket* sock) {
  PERFETTO_DCHECK_THREAD(thread_checker_);
  auto it = clients_by_socket_.find(sock);
  if (it == clients_by_socket_.end())
    return;
  ClientConnection* client = it->second;
  BufferedFrameDeserializer& frame_deserializer = client->frame_deserializer;

  auto peer_uid = client->GetPosixPeerUid();
  auto scoped_key = g_crash_key_uid.SetScoped(static_cast<int64_t>(peer_uid));

  size_t rsize;
  do {
    auto buf = frame_deserializer.BeginReceive();
    base::ScopedFile fd;
    rsize = client->sock->Receive(buf.data, buf.size, &fd);
    if (fd) {
      PERFETTO_DCHECK(!client->received_fd);
      client->received_fd = std::move(fd);
    }
    if (!frame_deserializer.EndReceive(rsize))
      return OnDisconnect(client->sock.get());
  } while (rsize > 0);

  for (;;) {
    std::unique_ptr<Frame> frame = frame_deserializer.PopNextFrame();
    if (!frame)
      break;
    OnReceivedFrame(client, *frame);
  }
}

void HostImpl::OnReceivedFrame(ClientConnection* client,
                               const Frame& req_frame) {
  if (req_frame.has_msg_bind_service())
    return OnBindService(client, req_frame);
  if (req_frame.has_msg_invoke_method())
    return OnInvokeMethod(client, req_frame);
  if (req_frame.has_set_peer_identity())
    return OnSetPeerIdentity(client, req_frame);

  PERFETTO_DLOG("Received invalid RPC frame from client %" PRIu64, client->id);
  Frame reply_frame;
  reply_frame.set_request_id(req_frame.request_id());
  reply_frame.mutable_msg_request_error()->set_error("unknown request");
  SendFrame(client, reply_frame);
}

void HostImpl::OnBindService(ClientConnection* client, const Frame& req_frame) {
  // Binding a service doesn't do anything major. It just returns back the
  // service id and its method map.
  const Frame::BindService& req = req_frame.msg_bind_service();
  Frame reply_frame;
  reply_frame.set_request_id(req_frame.request_id());
  auto* reply = reply_frame.mutable_msg_bind_service_reply();
  const ExposedService* service = GetServiceByName(req.service_name());
  if (service) {
    reply->set_success(true);
    reply->set_service_id(service->id);
    uint32_t method_id = 1;  // method ids start at index 1.
    for (const auto& desc_method : service->instance->GetDescriptor().methods) {
      Frame::BindServiceReply::MethodInfo* method_info = reply->add_methods();
      method_info->set_name(desc_method.name);
      method_info->set_id(method_id++);
    }
  }
  SendFrame(client, reply_frame);
}

void HostImpl::OnInvokeMethod(ClientConnection* client,
                              const Frame& req_frame) {
  const Frame::InvokeMethod& req = req_frame.msg_invoke_method();
  Frame reply_frame;
  RequestID request_id = req_frame.request_id();
  reply_frame.set_request_id(request_id);
  reply_frame.mutable_msg_invoke_method_reply()->set_success(false);
  auto svc_it = services_.find(req.service_id());
  if (svc_it == services_.end())
    return SendFrame(client, reply_frame);  // |success| == false by default.

  Service* service = svc_it->second.instance.get();
  const ServiceDescriptor& svc = service->GetDescriptor();
  const auto& methods = svc.methods;
  const uint32_t method_id = req.method_id();
  if (method_id == 0 || method_id > methods.size())
    return SendFrame(client, reply_frame);

  const ServiceDescriptor::Method& method = methods[method_id - 1];
  std::unique_ptr<ProtoMessage> decoded_req_args(
      method.request_proto_decoder(req.args_proto()));
  if (!decoded_req_args)
    return SendFrame(client, reply_frame);

  Deferred<ProtoMessage> deferred_reply;
  base::WeakPtr<HostImpl> host_weak_ptr = weak_ptr_factory_.GetWeakPtr();
  ClientID client_id = client->id;

  if (!req.drop_reply()) {
    deferred_reply.Bind([host_weak_ptr, client_id,
                         request_id](AsyncResult<ProtoMessage> reply) {
      if (!host_weak_ptr)
        return;  // The reply came too late, the HostImpl has gone.
      host_weak_ptr->ReplyToMethodInvocation(client_id, request_id,
                                             std::move(reply));
    });
  }

  auto peer_uid = client->GetPosixPeerUid();
  auto scoped_key = g_crash_key_uid.SetScoped(static_cast<int64_t>(peer_uid));
  service->client_info_ = ClientInfo(
      client->id, peer_uid, client->GetLinuxPeerPid(), client->GetMachineID());
  service->received_fd_ = &client->received_fd;
  method.invoker(service, *decoded_req_args, std::move(deferred_reply));
  service->received_fd_ = nullptr;
  service->client_info_ = ClientInfo();
}

void HostImpl::OnSetPeerIdentity(ClientConnection* client,
                                 const Frame& req_frame) {
  if (client->sock->family() == base::SockFamily::kUnix) {
    PERFETTO_DLOG("SetPeerIdentity is ignored for unix socket connections.");
    return;
  }

  // This is can only be set once by the relay service.
  if (client->pid_override != base::kInvalidPid ||
      client->uid_override != base::kInvalidUid) {
    PERFETTO_DLOG("Already received SetPeerIdentity.");
    return;
  }

  const auto& set_peer_identity = req_frame.set_peer_identity();
  client->pid_override = set_peer_identity.pid();
  client->uid_override = static_cast<uid_t>(set_peer_identity.uid());

  client->machine_id = GenerateMachineID(client->sock.get(),
                                         set_peer_identity.machine_id_hint());
}

void HostImpl::ReplyToMethodInvocation(ClientID client_id,
                                       RequestID request_id,
                                       AsyncResult<ProtoMessage> reply) {
  auto client_iter = clients_.find(client_id);
  if (client_iter == clients_.end())
    return;  // client has disconnected by the time we got the async reply.

  ClientConnection* client = client_iter->second.get();
  Frame reply_frame;
  reply_frame.set_request_id(request_id);

  // TODO(fmayer): add a test to guarantee that the reply is consumed within the
  // same call stack and not kept around. ConsumerIPCService::OnTraceData()
  // relies on this behavior.
  auto* reply_frame_data = reply_frame.mutable_msg_invoke_method_reply();
  reply_frame_data->set_has_more(reply.has_more());
  if (reply.success()) {
    std::string reply_proto = reply->SerializeAsString();
    reply_frame_data->set_reply_proto(reply_proto);
    reply_frame_data->set_success(true);
  }
  SendFrame(client, reply_frame, reply.fd());
}

// static
void HostImpl::SendFrame(ClientConnection* client, const Frame& frame, int fd) {
  auto peer_uid = client->GetPosixPeerUid();
  auto scoped_key = g_crash_key_uid.SetScoped(static_cast<int64_t>(peer_uid));

  std::string buf = BufferedFrameDeserializer::Serialize(frame);

  // On Fuchsia, |send_fd_cb_fuchsia_| is used to send the FD to the client
  // and therefore must be set.
  PERFETTO_DCHECK(!PERFETTO_BUILDFLAG(PERFETTO_OS_FUCHSIA) ||
                  client->send_fd_cb_fuchsia);
  if (client->send_fd_cb_fuchsia && fd != base::ScopedFile::kInvalid) {
    if (!client->send_fd_cb_fuchsia(fd)) {
      client->sock->Shutdown(true);
      return;
    }
    fd = base::ScopedFile::kInvalid;
  }

  // When a new Client connects in OnNewClientConnection we set a timeout on
  // Send (see call to SetTxTimeout).
  //
  // The old behaviour was to do a blocking I/O call, which caused crashes from
  // misbehaving producers (see b/169051440).
  bool res = client->sock->Send(buf.data(), buf.size(), fd);
  // If we timeout |res| will be false, but the UnixSocket will have called
  // UnixSocket::ShutDown() and thus |is_connected()| is false.
  PERFETTO_CHECK(res || !client->sock->is_connected());
}

void HostImpl::OnDisconnect(base::UnixSocket* sock) {
  PERFETTO_DCHECK_THREAD(thread_checker_);
  auto it = clients_by_socket_.find(sock);
  if (it == clients_by_socket_.end())
    return;
  auto* client = it->second;
  ClientID client_id = client->id;

  ClientInfo client_info(client_id, client->GetPosixPeerUid(),
                         client->GetLinuxPeerPid(), client->GetMachineID());

  clients_by_socket_.erase(it);
  PERFETTO_DCHECK(clients_.count(client_id));
  clients_.erase(client_id);

  for (const auto& service_it : services_) {
    Service& service = *service_it.second.instance;
    service.client_info_ = client_info;
    service.OnClientDisconnected();
    service.client_info_ = ClientInfo();
  }
}

const HostImpl::ExposedService* HostImpl::GetServiceByName(
    const std::string& name) {
  // This could be optimized by using another map<name,ServiceID>. However this
  // is used only by Bind/ExposeService that are quite rare (once per client
  // connection and once per service instance), not worth it.
  for (const auto& it : services_) {
    if (it.second.name == name)
      return &it.second;
  }
  return nullptr;
}

HostImpl::ExposedService::ExposedService(ServiceID id_,
                                         const std::string& name_,
                                         std::unique_ptr<Service> instance_)
    : id(id_), name(name_), instance(std::move(instance_)) {}

HostImpl::ExposedService::ExposedService(ExposedService&&) noexcept = default;
HostImpl::ExposedService& HostImpl::ExposedService::operator=(
    HostImpl::ExposedService&&) = default;
HostImpl::ExposedService::~ExposedService() = default;

HostImpl::ClientConnection::~ClientConnection() = default;

}  // namespace ipc
}  // namespace perfetto
// gen_amalgamated begin source: gen/protos/perfetto/ipc/consumer_port.ipc.cc
// gen_amalgamated begin header: gen/protos/perfetto/ipc/consumer_port.ipc.h
// DO NOT EDIT. Autogenerated by Perfetto IPC
#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_IPC_CONSUMER_PORT_PROTO_H_
#define PERFETTO_PROTOS_PROTOS_PERFETTO_IPC_CONSUMER_PORT_PROTO_H_

// gen_amalgamated expanded: #include "perfetto/ext/ipc/deferred.h"
// gen_amalgamated expanded: #include "perfetto/ext/ipc/service.h"
// gen_amalgamated expanded: #include "perfetto/ext/ipc/service_descriptor.h"
// gen_amalgamated expanded: #include "perfetto/ext/ipc/service_proxy.h"

// gen_amalgamated expanded: #include "protos/perfetto/ipc/consumer_port.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/common/observable_events.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/common/tracing_service_state.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/common/tracing_service_capabilities.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/common/trace_stats.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/trace_config.gen.h"

namespace perfetto {
namespace protos {
namespace gen {

class ConsumerPort : public ::perfetto::ipc::Service {
 private:
  static ::perfetto::ipc::ServiceDescriptor* NewDescriptor();

 public:
  ~ConsumerPort() override;

  static const ::perfetto::ipc::ServiceDescriptor& GetDescriptorStatic();

  // Service implementation.
  const ::perfetto::ipc::ServiceDescriptor& GetDescriptor() override;

  // Methods from the .proto file
  using DeferredEnableTracingResponse = ::perfetto::ipc::Deferred<EnableTracingResponse>;
  virtual void EnableTracing(const EnableTracingRequest&, DeferredEnableTracingResponse) = 0;

  using DeferredDisableTracingResponse = ::perfetto::ipc::Deferred<DisableTracingResponse>;
  virtual void DisableTracing(const DisableTracingRequest&, DeferredDisableTracingResponse) = 0;

  using DeferredReadBuffersResponse = ::perfetto::ipc::Deferred<ReadBuffersResponse>;
  virtual void ReadBuffers(const ReadBuffersRequest&, DeferredReadBuffersResponse) = 0;

  using DeferredFreeBuffersResponse = ::perfetto::ipc::Deferred<FreeBuffersResponse>;
  virtual void FreeBuffers(const FreeBuffersRequest&, DeferredFreeBuffersResponse) = 0;

  using DeferredFlushResponse = ::perfetto::ipc::Deferred<FlushResponse>;
  virtual void Flush(const FlushRequest&, DeferredFlushResponse) = 0;

  using DeferredStartTracingResponse = ::perfetto::ipc::Deferred<StartTracingResponse>;
  virtual void StartTracing(const StartTracingRequest&, DeferredStartTracingResponse) = 0;

  using DeferredChangeTraceConfigResponse = ::perfetto::ipc::Deferred<ChangeTraceConfigResponse>;
  virtual void ChangeTraceConfig(const ChangeTraceConfigRequest&, DeferredChangeTraceConfigResponse) = 0;

  using DeferredDetachResponse = ::perfetto::ipc::Deferred<DetachResponse>;
  virtual void Detach(const DetachRequest&, DeferredDetachResponse) = 0;

  using DeferredAttachResponse = ::perfetto::ipc::Deferred<AttachResponse>;
  virtual void Attach(const AttachRequest&, DeferredAttachResponse) = 0;

  using DeferredGetTraceStatsResponse = ::perfetto::ipc::Deferred<GetTraceStatsResponse>;
  virtual void GetTraceStats(const GetTraceStatsRequest&, DeferredGetTraceStatsResponse) = 0;

  using DeferredObserveEventsResponse = ::perfetto::ipc::Deferred<ObserveEventsResponse>;
  virtual void ObserveEvents(const ObserveEventsRequest&, DeferredObserveEventsResponse) = 0;

  using DeferredQueryServiceStateResponse = ::perfetto::ipc::Deferred<QueryServiceStateResponse>;
  virtual void QueryServiceState(const QueryServiceStateRequest&, DeferredQueryServiceStateResponse) = 0;

  using DeferredQueryCapabilitiesResponse = ::perfetto::ipc::Deferred<QueryCapabilitiesResponse>;
  virtual void QueryCapabilities(const QueryCapabilitiesRequest&, DeferredQueryCapabilitiesResponse) = 0;

  using DeferredSaveTraceForBugreportResponse = ::perfetto::ipc::Deferred<SaveTraceForBugreportResponse>;
  virtual void SaveTraceForBugreport(const SaveTraceForBugreportRequest&, DeferredSaveTraceForBugreportResponse) = 0;

  using DeferredCloneSessionResponse = ::perfetto::ipc::Deferred<CloneSessionResponse>;
  virtual void CloneSession(const CloneSessionRequest&, DeferredCloneSessionResponse) = 0;

};


class ConsumerPortProxy : public ::perfetto::ipc::ServiceProxy {
 public:
   explicit ConsumerPortProxy(::perfetto::ipc::ServiceProxy::EventListener*);
   ~ConsumerPortProxy() override;

  // ServiceProxy implementation.
  const ::perfetto::ipc::ServiceDescriptor& GetDescriptor() override;

  // Methods from the .proto file
  using DeferredEnableTracingResponse = ::perfetto::ipc::Deferred<EnableTracingResponse>;
  void EnableTracing(const EnableTracingRequest&, DeferredEnableTracingResponse, int fd = -1);

  using DeferredDisableTracingResponse = ::perfetto::ipc::Deferred<DisableTracingResponse>;
  void DisableTracing(const DisableTracingRequest&, DeferredDisableTracingResponse, int fd = -1);

  using DeferredReadBuffersResponse = ::perfetto::ipc::Deferred<ReadBuffersResponse>;
  void ReadBuffers(const ReadBuffersRequest&, DeferredReadBuffersResponse, int fd = -1);

  using DeferredFreeBuffersResponse = ::perfetto::ipc::Deferred<FreeBuffersResponse>;
  void FreeBuffers(const FreeBuffersRequest&, DeferredFreeBuffersResponse, int fd = -1);

  using DeferredFlushResponse = ::perfetto::ipc::Deferred<FlushResponse>;
  void Flush(const FlushRequest&, DeferredFlushResponse, int fd = -1);

  using DeferredStartTracingResponse = ::perfetto::ipc::Deferred<StartTracingResponse>;
  void StartTracing(const StartTracingRequest&, DeferredStartTracingResponse, int fd = -1);

  using DeferredChangeTraceConfigResponse = ::perfetto::ipc::Deferred<ChangeTraceConfigResponse>;
  void ChangeTraceConfig(const ChangeTraceConfigRequest&, DeferredChangeTraceConfigResponse, int fd = -1);

  using DeferredDetachResponse = ::perfetto::ipc::Deferred<DetachResponse>;
  void Detach(const DetachRequest&, DeferredDetachResponse, int fd = -1);

  using DeferredAttachResponse = ::perfetto::ipc::Deferred<AttachResponse>;
  void Attach(const AttachRequest&, DeferredAttachResponse, int fd = -1);

  using DeferredGetTraceStatsResponse = ::perfetto::ipc::Deferred<GetTraceStatsResponse>;
  void GetTraceStats(const GetTraceStatsRequest&, DeferredGetTraceStatsResponse, int fd = -1);

  using DeferredObserveEventsResponse = ::perfetto::ipc::Deferred<ObserveEventsResponse>;
  void ObserveEvents(const ObserveEventsRequest&, DeferredObserveEventsResponse, int fd = -1);

  using DeferredQueryServiceStateResponse = ::perfetto::ipc::Deferred<QueryServiceStateResponse>;
  void QueryServiceState(const QueryServiceStateRequest&, DeferredQueryServiceStateResponse, int fd = -1);

  using DeferredQueryCapabilitiesResponse = ::perfetto::ipc::Deferred<QueryCapabilitiesResponse>;
  void QueryCapabilities(const QueryCapabilitiesRequest&, DeferredQueryCapabilitiesResponse, int fd = -1);

  using DeferredSaveTraceForBugreportResponse = ::perfetto::ipc::Deferred<SaveTraceForBugreportResponse>;
  void SaveTraceForBugreport(const SaveTraceForBugreportRequest&, DeferredSaveTraceForBugreportResponse, int fd = -1);

  using DeferredCloneSessionResponse = ::perfetto::ipc::Deferred<CloneSessionResponse>;
  void CloneSession(const CloneSessionRequest&, DeferredCloneSessionResponse, int fd = -1);

};

}  // namespace perfetto
}  // namespace protos
}  // namespace gen

#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_IPC_CONSUMER_PORT_PROTO_H_
// gen_amalgamated begin header: include/perfetto/ext/ipc/codegen_helpers.h
/*
 * Copyright (C) 2017 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// This file is only meant to be included in autogenerated .cc files.

#ifndef INCLUDE_PERFETTO_EXT_IPC_CODEGEN_HELPERS_H_
#define INCLUDE_PERFETTO_EXT_IPC_CODEGEN_HELPERS_H_

#include <memory>

// gen_amalgamated expanded: #include "perfetto/ext/ipc/basic_types.h"
// gen_amalgamated expanded: #include "perfetto/ext/ipc/deferred.h"
// gen_amalgamated expanded: #include "perfetto/ext/ipc/service.h"

// A templated protobuf message decoder. Returns nullptr in case of failure.
template <typename T>
::std::unique_ptr<::perfetto::ipc::ProtoMessage> _IPC_Decoder(
    const std::string& proto_data) {
  ::std::unique_ptr<::perfetto::ipc::ProtoMessage> msg(new T());
  if (msg->ParseFromString(proto_data))
    return msg;
  return nullptr;
}

// Templated method dispatcher. Used to obtain a function pointer to a given
// IPC method (Method) of a given service (TSvc) that can be invoked by the
// host-side machinery starting from a generic Service pointer and a generic
// ProtoMessage request argument.
template <typename TSvc,    // Type of the actual Service subclass.
          typename TReq,    // Type of the request argument.
          typename TReply,  // Type of the reply argument.
          void (TSvc::*Method)(const TReq&, ::perfetto::ipc::Deferred<TReply>)>
void _IPC_Invoker(::perfetto::ipc::Service* s,
                  const ::perfetto::ipc::ProtoMessage& req,
                  ::perfetto::ipc::DeferredBase reply) {
  (*static_cast<TSvc*>(s).*Method)(
      static_cast<const TReq&>(req),
      ::perfetto::ipc::Deferred<TReply>(::std::move(reply)));
}

#endif  // INCLUDE_PERFETTO_EXT_IPC_CODEGEN_HELPERS_H_
// DO NOT EDIT. Autogenerated by Perfetto IPC
// gen_amalgamated expanded: #include "protos/perfetto/ipc/consumer_port.ipc.h"
// gen_amalgamated expanded: #include "perfetto/ext/ipc/codegen_helpers.h"

#include <memory>

namespace perfetto {
namespace protos {
namespace gen {
::perfetto::ipc::ServiceDescriptor* ConsumerPort::NewDescriptor() {
  auto* desc = new ::perfetto::ipc::ServiceDescriptor();
  desc->service_name = "ConsumerPort";

  desc->methods.emplace_back(::perfetto::ipc::ServiceDescriptor::Method{
     "EnableTracing",
     &_IPC_Decoder<EnableTracingRequest>,
     &_IPC_Decoder<EnableTracingResponse>,
     &_IPC_Invoker<ConsumerPort, EnableTracingRequest, EnableTracingResponse, &ConsumerPort::EnableTracing>});

  desc->methods.emplace_back(::perfetto::ipc::ServiceDescriptor::Method{
     "DisableTracing",
     &_IPC_Decoder<DisableTracingRequest>,
     &_IPC_Decoder<DisableTracingResponse>,
     &_IPC_Invoker<ConsumerPort, DisableTracingRequest, DisableTracingResponse, &ConsumerPort::DisableTracing>});

  desc->methods.emplace_back(::perfetto::ipc::ServiceDescriptor::Method{
     "ReadBuffers",
     &_IPC_Decoder<ReadBuffersRequest>,
     &_IPC_Decoder<ReadBuffersResponse>,
     &_IPC_Invoker<ConsumerPort, ReadBuffersRequest, ReadBuffersResponse, &ConsumerPort::ReadBuffers>});

  desc->methods.emplace_back(::perfetto::ipc::ServiceDescriptor::Method{
     "FreeBuffers",
     &_IPC_Decoder<FreeBuffersRequest>,
     &_IPC_Decoder<FreeBuffersResponse>,
     &_IPC_Invoker<ConsumerPort, FreeBuffersRequest, FreeBuffersResponse, &ConsumerPort::FreeBuffers>});

  desc->methods.emplace_back(::perfetto::ipc::ServiceDescriptor::Method{
     "Flush",
     &_IPC_Decoder<FlushRequest>,
     &_IPC_Decoder<FlushResponse>,
     &_IPC_Invoker<ConsumerPort, FlushRequest, FlushResponse, &ConsumerPort::Flush>});

  desc->methods.emplace_back(::perfetto::ipc::ServiceDescriptor::Method{
     "StartTracing",
     &_IPC_Decoder<StartTracingRequest>,
     &_IPC_Decoder<StartTracingResponse>,
     &_IPC_Invoker<ConsumerPort, StartTracingRequest, StartTracingResponse, &ConsumerPort::StartTracing>});

  desc->methods.emplace_back(::perfetto::ipc::ServiceDescriptor::Method{
     "ChangeTraceConfig",
     &_IPC_Decoder<ChangeTraceConfigRequest>,
     &_IPC_Decoder<ChangeTraceConfigResponse>,
     &_IPC_Invoker<ConsumerPort, ChangeTraceConfigRequest, ChangeTraceConfigResponse, &ConsumerPort::ChangeTraceConfig>});

  desc->methods.emplace_back(::perfetto::ipc::ServiceDescriptor::Method{
     "Detach",
     &_IPC_Decoder<DetachRequest>,
     &_IPC_Decoder<DetachResponse>,
     &_IPC_Invoker<ConsumerPort, DetachRequest, DetachResponse, &ConsumerPort::Detach>});

  desc->methods.emplace_back(::perfetto::ipc::ServiceDescriptor::Method{
     "Attach",
     &_IPC_Decoder<AttachRequest>,
     &_IPC_Decoder<AttachResponse>,
     &_IPC_Invoker<ConsumerPort, AttachRequest, AttachResponse, &ConsumerPort::Attach>});

  desc->methods.emplace_back(::perfetto::ipc::ServiceDescriptor::Method{
     "GetTraceStats",
     &_IPC_Decoder<GetTraceStatsRequest>,
     &_IPC_Decoder<GetTraceStatsResponse>,
     &_IPC_Invoker<ConsumerPort, GetTraceStatsRequest, GetTraceStatsResponse, &ConsumerPort::GetTraceStats>});

  desc->methods.emplace_back(::perfetto::ipc::ServiceDescriptor::Method{
     "ObserveEvents",
     &_IPC_Decoder<ObserveEventsRequest>,
     &_IPC_Decoder<ObserveEventsResponse>,
     &_IPC_Invoker<ConsumerPort, ObserveEventsRequest, ObserveEventsResponse, &ConsumerPort::ObserveEvents>});

  desc->methods.emplace_back(::perfetto::ipc::ServiceDescriptor::Method{
     "QueryServiceState",
     &_IPC_Decoder<QueryServiceStateRequest>,
     &_IPC_Decoder<QueryServiceStateResponse>,
     &_IPC_Invoker<ConsumerPort, QueryServiceStateRequest, QueryServiceStateResponse, &ConsumerPort::QueryServiceState>});

  desc->methods.emplace_back(::perfetto::ipc::ServiceDescriptor::Method{
     "QueryCapabilities",
     &_IPC_Decoder<QueryCapabilitiesRequest>,
     &_IPC_Decoder<QueryCapabilitiesResponse>,
     &_IPC_Invoker<ConsumerPort, QueryCapabilitiesRequest, QueryCapabilitiesResponse, &ConsumerPort::QueryCapabilities>});

  desc->methods.emplace_back(::perfetto::ipc::ServiceDescriptor::Method{
     "SaveTraceForBugreport",
     &_IPC_Decoder<SaveTraceForBugreportRequest>,
     &_IPC_Decoder<SaveTraceForBugreportResponse>,
     &_IPC_Invoker<ConsumerPort, SaveTraceForBugreportRequest, SaveTraceForBugreportResponse, &ConsumerPort::SaveTraceForBugreport>});

  desc->methods.emplace_back(::perfetto::ipc::ServiceDescriptor::Method{
     "CloneSession",
     &_IPC_Decoder<CloneSessionRequest>,
     &_IPC_Decoder<CloneSessionResponse>,
     &_IPC_Invoker<ConsumerPort, CloneSessionRequest, CloneSessionResponse, &ConsumerPort::CloneSession>});
  desc->methods.shrink_to_fit();
  return desc;
}


const ::perfetto::ipc::ServiceDescriptor& ConsumerPort::GetDescriptorStatic() {
  static auto* instance = NewDescriptor();
  return *instance;
}

// Host-side definitions.
ConsumerPort::~ConsumerPort() = default;

const ::perfetto::ipc::ServiceDescriptor& ConsumerPort::GetDescriptor() {
  return GetDescriptorStatic();
}

// Client-side definitions.
ConsumerPortProxy::ConsumerPortProxy(::perfetto::ipc::ServiceProxy::EventListener* event_listener)
    : ::perfetto::ipc::ServiceProxy(event_listener) {}

ConsumerPortProxy::~ConsumerPortProxy() = default;

const ::perfetto::ipc::ServiceDescriptor& ConsumerPortProxy::GetDescriptor() {
  return ConsumerPort::GetDescriptorStatic();
}

void ConsumerPortProxy::EnableTracing(const EnableTracingRequest& request, DeferredEnableTracingResponse reply, int fd) {
  BeginInvoke("EnableTracing", request, ::perfetto::ipc::DeferredBase(std::move(reply)),
              fd);
}

void ConsumerPortProxy::DisableTracing(const DisableTracingRequest& request, DeferredDisableTracingResponse reply, int fd) {
  BeginInvoke("DisableTracing", request, ::perfetto::ipc::DeferredBase(std::move(reply)),
              fd);
}

void ConsumerPortProxy::ReadBuffers(const ReadBuffersRequest& request, DeferredReadBuffersResponse reply, int fd) {
  BeginInvoke("ReadBuffers", request, ::perfetto::ipc::DeferredBase(std::move(reply)),
              fd);
}

void ConsumerPortProxy::FreeBuffers(const FreeBuffersRequest& request, DeferredFreeBuffersResponse reply, int fd) {
  BeginInvoke("FreeBuffers", request, ::perfetto::ipc::DeferredBase(std::move(reply)),
              fd);
}

void ConsumerPortProxy::Flush(const FlushRequest& request, DeferredFlushResponse reply, int fd) {
  BeginInvoke("Flush", request, ::perfetto::ipc::DeferredBase(std::move(reply)),
              fd);
}

void ConsumerPortProxy::StartTracing(const StartTracingRequest& request, DeferredStartTracingResponse reply, int fd) {
  BeginInvoke("StartTracing", request, ::perfetto::ipc::DeferredBase(std::move(reply)),
              fd);
}

void ConsumerPortProxy::ChangeTraceConfig(const ChangeTraceConfigRequest& request, DeferredChangeTraceConfigResponse reply, int fd) {
  BeginInvoke("ChangeTraceConfig", request, ::perfetto::ipc::DeferredBase(std::move(reply)),
              fd);
}

void ConsumerPortProxy::Detach(const DetachRequest& request, DeferredDetachResponse reply, int fd) {
  BeginInvoke("Detach", request, ::perfetto::ipc::DeferredBase(std::move(reply)),
              fd);
}

void ConsumerPortProxy::Attach(const AttachRequest& request, DeferredAttachResponse reply, int fd) {
  BeginInvoke("Attach", request, ::perfetto::ipc::DeferredBase(std::move(reply)),
              fd);
}

void ConsumerPortProxy::GetTraceStats(const GetTraceStatsRequest& request, DeferredGetTraceStatsResponse reply, int fd) {
  BeginInvoke("GetTraceStats", request, ::perfetto::ipc::DeferredBase(std::move(reply)),
              fd);
}

void ConsumerPortProxy::ObserveEvents(const ObserveEventsRequest& request, DeferredObserveEventsResponse reply, int fd) {
  BeginInvoke("ObserveEvents", request, ::perfetto::ipc::DeferredBase(std::move(reply)),
              fd);
}

void ConsumerPortProxy::QueryServiceState(const QueryServiceStateRequest& request, DeferredQueryServiceStateResponse reply, int fd) {
  BeginInvoke("QueryServiceState", request, ::perfetto::ipc::DeferredBase(std::move(reply)),
              fd);
}

void ConsumerPortProxy::QueryCapabilities(const QueryCapabilitiesRequest& request, DeferredQueryCapabilitiesResponse reply, int fd) {
  BeginInvoke("QueryCapabilities", request, ::perfetto::ipc::DeferredBase(std::move(reply)),
              fd);
}

void ConsumerPortProxy::SaveTraceForBugreport(const SaveTraceForBugreportRequest& request, DeferredSaveTraceForBugreportResponse reply, int fd) {
  BeginInvoke("SaveTraceForBugreport", request, ::perfetto::ipc::DeferredBase(std::move(reply)),
              fd);
}

void ConsumerPortProxy::CloneSession(const CloneSessionRequest& request, DeferredCloneSessionResponse reply, int fd) {
  BeginInvoke("CloneSession", request, ::perfetto::ipc::DeferredBase(std::move(reply)),
              fd);
}
}  // namespace perfetto
}  // namespace protos
}  // namespace gen
// gen_amalgamated begin source: gen/protos/perfetto/ipc/producer_port.ipc.cc
// gen_amalgamated begin header: gen/protos/perfetto/ipc/producer_port.ipc.h
// DO NOT EDIT. Autogenerated by Perfetto IPC
#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_IPC_PRODUCER_PORT_PROTO_H_
#define PERFETTO_PROTOS_PROTOS_PERFETTO_IPC_PRODUCER_PORT_PROTO_H_

// gen_amalgamated expanded: #include "perfetto/ext/ipc/deferred.h"
// gen_amalgamated expanded: #include "perfetto/ext/ipc/service.h"
// gen_amalgamated expanded: #include "perfetto/ext/ipc/service_descriptor.h"
// gen_amalgamated expanded: #include "perfetto/ext/ipc/service_proxy.h"

// gen_amalgamated expanded: #include "protos/perfetto/ipc/producer_port.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/common/commit_data_request.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/config/data_source_config.gen.h"
// gen_amalgamated expanded: #include "protos/perfetto/common/data_source_descriptor.gen.h"

namespace perfetto {
namespace protos {
namespace gen {

class ProducerPort : public ::perfetto::ipc::Service {
 private:
  static ::perfetto::ipc::ServiceDescriptor* NewDescriptor();

 public:
  ~ProducerPort() override;

  static const ::perfetto::ipc::ServiceDescriptor& GetDescriptorStatic();

  // Service implementation.
  const ::perfetto::ipc::ServiceDescriptor& GetDescriptor() override;

  // Methods from the .proto file
  using DeferredInitializeConnectionResponse = ::perfetto::ipc::Deferred<InitializeConnectionResponse>;
  virtual void InitializeConnection(const InitializeConnectionRequest&, DeferredInitializeConnectionResponse) = 0;

  using DeferredRegisterDataSourceResponse = ::perfetto::ipc::Deferred<RegisterDataSourceResponse>;
  virtual void RegisterDataSource(const RegisterDataSourceRequest&, DeferredRegisterDataSourceResponse) = 0;

  using DeferredUnregisterDataSourceResponse = ::perfetto::ipc::Deferred<UnregisterDataSourceResponse>;
  virtual void UnregisterDataSource(const UnregisterDataSourceRequest&, DeferredUnregisterDataSourceResponse) = 0;

  using DeferredCommitDataResponse = ::perfetto::ipc::Deferred<CommitDataResponse>;
  virtual void CommitData(const CommitDataRequest&, DeferredCommitDataResponse) = 0;

  using DeferredGetAsyncCommandResponse = ::perfetto::ipc::Deferred<GetAsyncCommandResponse>;
  virtual void GetAsyncCommand(const GetAsyncCommandRequest&, DeferredGetAsyncCommandResponse) = 0;

  using DeferredRegisterTraceWriterResponse = ::perfetto::ipc::Deferred<RegisterTraceWriterResponse>;
  virtual void RegisterTraceWriter(const RegisterTraceWriterRequest&, DeferredRegisterTraceWriterResponse) = 0;

  using DeferredUnregisterTraceWriterResponse = ::perfetto::ipc::Deferred<UnregisterTraceWriterResponse>;
  virtual void UnregisterTraceWriter(const UnregisterTraceWriterRequest&, DeferredUnregisterTraceWriterResponse) = 0;

  using DeferredNotifyDataSourceStartedResponse = ::perfetto::ipc::Deferred<NotifyDataSourceStartedResponse>;
  virtual void NotifyDataSourceStarted(const NotifyDataSourceStartedRequest&, DeferredNotifyDataSourceStartedResponse) = 0;

  using DeferredNotifyDataSourceStoppedResponse = ::perfetto::ipc::Deferred<NotifyDataSourceStoppedResponse>;
  virtual void NotifyDataSourceStopped(const NotifyDataSourceStoppedRequest&, DeferredNotifyDataSourceStoppedResponse) = 0;

  using DeferredActivateTriggersResponse = ::perfetto::ipc::Deferred<ActivateTriggersResponse>;
  virtual void ActivateTriggers(const ActivateTriggersRequest&, DeferredActivateTriggersResponse) = 0;

  using DeferredSyncResponse = ::perfetto::ipc::Deferred<SyncResponse>;
  virtual void Sync(const SyncRequest&, DeferredSyncResponse) = 0;

  using DeferredUpdateDataSourceResponse = ::perfetto::ipc::Deferred<UpdateDataSourceResponse>;
  virtual void UpdateDataSource(const UpdateDataSourceRequest&, DeferredUpdateDataSourceResponse) = 0;

};


class ProducerPortProxy : public ::perfetto::ipc::ServiceProxy {
 public:
   explicit ProducerPortProxy(::perfetto::ipc::ServiceProxy::EventListener*);
   ~ProducerPortProxy() override;

  // ServiceProxy implementation.
  const ::perfetto::ipc::ServiceDescriptor& GetDescriptor() override;

  // Methods from the .proto file
  using DeferredInitializeConnectionResponse = ::perfetto::ipc::Deferred<InitializeConnectionResponse>;
  void InitializeConnection(const InitializeConnectionRequest&, DeferredInitializeConnectionResponse, int fd = -1);

  using DeferredRegisterDataSourceResponse = ::perfetto::ipc::Deferred<RegisterDataSourceResponse>;
  void RegisterDataSource(const RegisterDataSourceRequest&, DeferredRegisterDataSourceResponse, int fd = -1);

  using DeferredUnregisterDataSourceResponse = ::perfetto::ipc::Deferred<UnregisterDataSourceResponse>;
  void UnregisterDataSource(const UnregisterDataSourceRequest&, DeferredUnregisterDataSourceResponse, int fd = -1);

  using DeferredCommitDataResponse = ::perfetto::ipc::Deferred<CommitDataResponse>;
  void CommitData(const CommitDataRequest&, DeferredCommitDataResponse, int fd = -1);

  using DeferredGetAsyncCommandResponse = ::perfetto::ipc::Deferred<GetAsyncCommandResponse>;
  void GetAsyncCommand(const GetAsyncCommandRequest&, DeferredGetAsyncCommandResponse, int fd = -1);

  using DeferredRegisterTraceWriterResponse = ::perfetto::ipc::Deferred<RegisterTraceWriterResponse>;
  void RegisterTraceWriter(const RegisterTraceWriterRequest&, DeferredRegisterTraceWriterResponse, int fd = -1);

  using DeferredUnregisterTraceWriterResponse = ::perfetto::ipc::Deferred<UnregisterTraceWriterResponse>;
  void UnregisterTraceWriter(const UnregisterTraceWriterRequest&, DeferredUnregisterTraceWriterResponse, int fd = -1);

  using DeferredNotifyDataSourceStartedResponse = ::perfetto::ipc::Deferred<NotifyDataSourceStartedResponse>;
  void NotifyDataSourceStarted(const NotifyDataSourceStartedRequest&, DeferredNotifyDataSourceStartedResponse, int fd = -1);

  using DeferredNotifyDataSourceStoppedResponse = ::perfetto::ipc::Deferred<NotifyDataSourceStoppedResponse>;
  void NotifyDataSourceStopped(const NotifyDataSourceStoppedRequest&, DeferredNotifyDataSourceStoppedResponse, int fd = -1);

  using DeferredActivateTriggersResponse = ::perfetto::ipc::Deferred<ActivateTriggersResponse>;
  void ActivateTriggers(const ActivateTriggersRequest&, DeferredActivateTriggersResponse, int fd = -1);

  using DeferredSyncResponse = ::perfetto::ipc::Deferred<SyncResponse>;
  void Sync(const SyncRequest&, DeferredSyncResponse, int fd = -1);

  using DeferredUpdateDataSourceResponse = ::perfetto::ipc::Deferred<UpdateDataSourceResponse>;
  void UpdateDataSource(const UpdateDataSourceRequest&, DeferredUpdateDataSourceResponse, int fd = -1);

};

}  // namespace perfetto
}  // namespace protos
}  // namespace gen

#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_IPC_PRODUCER_PORT_PROTO_H_
// DO NOT EDIT. Autogenerated by Perfetto IPC
// gen_amalgamated expanded: #include "protos/perfetto/ipc/producer_port.ipc.h"
// gen_amalgamated expanded: #include "perfetto/ext/ipc/codegen_helpers.h"

#include <memory>

namespace perfetto {
namespace protos {
namespace gen {
::perfetto::ipc::ServiceDescriptor* ProducerPort::NewDescriptor() {
  auto* desc = new ::perfetto::ipc::ServiceDescriptor();
  desc->service_name = "ProducerPort";

  desc->methods.emplace_back(::perfetto::ipc::ServiceDescriptor::Method{
     "InitializeConnection",
     &_IPC_Decoder<InitializeConnectionRequest>,
     &_IPC_Decoder<InitializeConnectionResponse>,
     &_IPC_Invoker<ProducerPort, InitializeConnectionRequest, InitializeConnectionResponse, &ProducerPort::InitializeConnection>});

  desc->methods.emplace_back(::perfetto::ipc::ServiceDescriptor::Method{
     "RegisterDataSource",
     &_IPC_Decoder<RegisterDataSourceRequest>,
     &_IPC_Decoder<RegisterDataSourceResponse>,
     &_IPC_Invoker<ProducerPort, RegisterDataSourceRequest, RegisterDataSourceResponse, &ProducerPort::RegisterDataSource>});

  desc->methods.emplace_back(::perfetto::ipc::ServiceDescriptor::Method{
     "UnregisterDataSource",
     &_IPC_Decoder<UnregisterDataSourceRequest>,
     &_IPC_Decoder<UnregisterDataSourceResponse>,
     &_IPC_Invoker<ProducerPort, UnregisterDataSourceRequest, UnregisterDataSourceResponse, &ProducerPort::UnregisterDataSource>});

  desc->methods.emplace_back(::perfetto::ipc::ServiceDescriptor::Method{
     "CommitData",
     &_IPC_Decoder<CommitDataRequest>,
     &_IPC_Decoder<CommitDataResponse>,
     &_IPC_Invoker<ProducerPort, CommitDataRequest, CommitDataResponse, &ProducerPort::CommitData>});

  desc->methods.emplace_back(::perfetto::ipc::ServiceDescriptor::Method{
     "GetAsyncCommand",
     &_IPC_Decoder<GetAsyncCommandRequest>,
     &_IPC_Decoder<GetAsyncCommandResponse>,
     &_IPC_Invoker<ProducerPort, GetAsyncCommandRequest, GetAsyncCommandResponse, &ProducerPort::GetAsyncCommand>});

  desc->methods.emplace_back(::perfetto::ipc::ServiceDescriptor::Method{
     "RegisterTraceWriter",
     &_IPC_Decoder<RegisterTraceWriterRequest>,
     &_IPC_Decoder<RegisterTraceWriterResponse>,
     &_IPC_Invoker<ProducerPort, RegisterTraceWriterRequest, RegisterTraceWriterResponse, &ProducerPort::RegisterTraceWriter>});

  desc->methods.emplace_back(::perfetto::ipc::ServiceDescriptor::Method{
     "UnregisterTraceWriter",
     &_IPC_Decoder<UnregisterTraceWriterRequest>,
     &_IPC_Decoder<UnregisterTraceWriterResponse>,
     &_IPC_Invoker<ProducerPort, UnregisterTraceWriterRequest, UnregisterTraceWriterResponse, &ProducerPort::UnregisterTraceWriter>});

  desc->methods.emplace_back(::perfetto::ipc::ServiceDescriptor::Method{
     "NotifyDataSourceStarted",
     &_IPC_Decoder<NotifyDataSourceStartedRequest>,
     &_IPC_Decoder<NotifyDataSourceStartedResponse>,
     &_IPC_Invoker<ProducerPort, NotifyDataSourceStartedRequest, NotifyDataSourceStartedResponse, &ProducerPort::NotifyDataSourceStarted>});

  desc->methods.emplace_back(::perfetto::ipc::ServiceDescriptor::Method{
     "NotifyDataSourceStopped",
     &_IPC_Decoder<NotifyDataSourceStoppedRequest>,
     &_IPC_Decoder<NotifyDataSourceStoppedResponse>,
     &_IPC_Invoker<ProducerPort, NotifyDataSourceStoppedRequest, NotifyDataSourceStoppedResponse, &ProducerPort::NotifyDataSourceStopped>});

  desc->methods.emplace_back(::perfetto::ipc::ServiceDescriptor::Method{
     "ActivateTriggers",
     &_IPC_Decoder<ActivateTriggersRequest>,
     &_IPC_Decoder<ActivateTriggersResponse>,
     &_IPC_Invoker<ProducerPort, ActivateTriggersRequest, ActivateTriggersResponse, &ProducerPort::ActivateTriggers>});

  desc->methods.emplace_back(::perfetto::ipc::ServiceDescriptor::Method{
     "Sync",
     &_IPC_Decoder<SyncRequest>,
     &_IPC_Decoder<SyncResponse>,
     &_IPC_Invoker<ProducerPort, SyncRequest, SyncResponse, &ProducerPort::Sync>});

  desc->methods.emplace_back(::perfetto::ipc::ServiceDescriptor::Method{
     "UpdateDataSource",
     &_IPC_Decoder<UpdateDataSourceRequest>,
     &_IPC_Decoder<UpdateDataSourceResponse>,
     &_IPC_Invoker<ProducerPort, UpdateDataSourceRequest, UpdateDataSourceResponse, &ProducerPort::UpdateDataSource>});
  desc->methods.shrink_to_fit();
  return desc;
}


const ::perfetto::ipc::ServiceDescriptor& ProducerPort::GetDescriptorStatic() {
  static auto* instance = NewDescriptor();
  return *instance;
}

// Host-side definitions.
ProducerPort::~ProducerPort() = default;

const ::perfetto::ipc::ServiceDescriptor& ProducerPort::GetDescriptor() {
  return GetDescriptorStatic();
}

// Client-side definitions.
ProducerPortProxy::ProducerPortProxy(::perfetto::ipc::ServiceProxy::EventListener* event_listener)
    : ::perfetto::ipc::ServiceProxy(event_listener) {}

ProducerPortProxy::~ProducerPortProxy() = default;

const ::perfetto::ipc::ServiceDescriptor& ProducerPortProxy::GetDescriptor() {
  return ProducerPort::GetDescriptorStatic();
}

void ProducerPortProxy::InitializeConnection(const InitializeConnectionRequest& request, DeferredInitializeConnectionResponse reply, int fd) {
  BeginInvoke("InitializeConnection", request, ::perfetto::ipc::DeferredBase(std::move(reply)),
              fd);
}

void ProducerPortProxy::RegisterDataSource(const RegisterDataSourceRequest& request, DeferredRegisterDataSourceResponse reply, int fd) {
  BeginInvoke("RegisterDataSource", request, ::perfetto::ipc::DeferredBase(std::move(reply)),
              fd);
}

void ProducerPortProxy::UnregisterDataSource(const UnregisterDataSourceRequest& request, DeferredUnregisterDataSourceResponse reply, int fd) {
  BeginInvoke("UnregisterDataSource", request, ::perfetto::ipc::DeferredBase(std::move(reply)),
              fd);
}

void ProducerPortProxy::CommitData(const CommitDataRequest& request, DeferredCommitDataResponse reply, int fd) {
  BeginInvoke("CommitData", request, ::perfetto::ipc::DeferredBase(std::move(reply)),
              fd);
}

void ProducerPortProxy::GetAsyncCommand(const GetAsyncCommandRequest& request, DeferredGetAsyncCommandResponse reply, int fd) {
  BeginInvoke("GetAsyncCommand", request, ::perfetto::ipc::DeferredBase(std::move(reply)),
              fd);
}

void ProducerPortProxy::RegisterTraceWriter(const RegisterTraceWriterRequest& request, DeferredRegisterTraceWriterResponse reply, int fd) {
  BeginInvoke("RegisterTraceWriter", request, ::perfetto::ipc::DeferredBase(std::move(reply)),
              fd);
}

void ProducerPortProxy::UnregisterTraceWriter(const UnregisterTraceWriterRequest& request, DeferredUnregisterTraceWriterResponse reply, int fd) {
  BeginInvoke("UnregisterTraceWriter", request, ::perfetto::ipc::DeferredBase(std::move(reply)),
              fd);
}

void ProducerPortProxy::NotifyDataSourceStarted(const NotifyDataSourceStartedRequest& request, DeferredNotifyDataSourceStartedResponse reply, int fd) {
  BeginInvoke("NotifyDataSourceStarted", request, ::perfetto::ipc::DeferredBase(std::move(reply)),
              fd);
}

void ProducerPortProxy::NotifyDataSourceStopped(const NotifyDataSourceStoppedRequest& request, DeferredNotifyDataSourceStoppedResponse reply, int fd) {
  BeginInvoke("NotifyDataSourceStopped", request, ::perfetto::ipc::DeferredBase(std::move(reply)),
              fd);
}

void ProducerPortProxy::ActivateTriggers(const ActivateTriggersRequest& request, DeferredActivateTriggersResponse reply, int fd) {
  BeginInvoke("ActivateTriggers", request, ::perfetto::ipc::DeferredBase(std::move(reply)),
              fd);
}

void ProducerPortProxy::Sync(const SyncRequest& request, DeferredSyncResponse reply, int fd) {
  BeginInvoke("Sync", request, ::perfetto::ipc::DeferredBase(std::move(reply)),
              fd);
}

void ProducerPortProxy::UpdateDataSource(const UpdateDataSourceRequest& request, DeferredUpdateDataSourceResponse reply, int fd) {
  BeginInvoke("UpdateDataSource", request, ::perfetto::ipc::DeferredBase(std::move(reply)),
              fd);
}
}  // namespace perfetto
}  // namespace protos
}  // namespace gen
// gen_amalgamated begin source: gen/protos/perfetto/ipc/relay_port.ipc.cc
// gen_amalgamated begin header: gen/protos/perfetto/ipc/relay_port.ipc.h
// DO NOT EDIT. Autogenerated by Perfetto IPC
#ifndef PERFETTO_PROTOS_PROTOS_PERFETTO_IPC_RELAY_PORT_PROTO_H_
#define PERFETTO_PROTOS_PROTOS_PERFETTO_IPC_RELAY_PORT_PROTO_H_

// gen_amalgamated expanded: #include "perfetto/ext/ipc/deferred.h"
// gen_amalgamated expanded: #include "perfetto/ext/ipc/service.h"
// gen_amalgamated expanded: #include "perfetto/ext/ipc/service_descriptor.h"
// gen_amalgamated expanded: #include "perfetto/ext/ipc/service_proxy.h"

// gen_amalgamated expanded: #include "protos/perfetto/ipc/relay_port.gen.h"

namespace perfetto {
namespace protos {
namespace gen {

class RelayPort : public ::perfetto::ipc::Service {
 private:
  static ::perfetto::ipc::ServiceDescriptor* NewDescriptor();

 public:
  ~RelayPort() override;

  static const ::perfetto::ipc::ServiceDescriptor& GetDescriptorStatic();

  // Service implementation.
  const ::perfetto::ipc::ServiceDescriptor& GetDescriptor() override;

  // Methods from the .proto file
  using DeferredSyncClockResponse = ::perfetto::ipc::Deferred<SyncClockResponse>;
  virtual void SyncClock(const SyncClockRequest&, DeferredSyncClockResponse) = 0;

};


class RelayPortProxy : public ::perfetto::ipc::ServiceProxy {
 public:
   explicit RelayPortProxy(::perfetto::ipc::ServiceProxy::EventListener*);
   ~RelayPortProxy() override;

  // ServiceProxy implementation.
  const ::perfetto::ipc::ServiceDescriptor& GetDescriptor() override;

  // Methods from the .proto file
  using DeferredSyncClockResponse = ::perfetto::ipc::Deferred<SyncClockResponse>;
  void SyncClock(const SyncClockRequest&, DeferredSyncClockResponse, int fd = -1);

};

}  // namespace perfetto
}  // namespace protos
}  // namespace gen

#endif  // PERFETTO_PROTOS_PROTOS_PERFETTO_IPC_RELAY_PORT_PROTO_H_
// DO NOT EDIT. Autogenerated by Perfetto IPC
// gen_amalgamated expanded: #include "protos/perfetto/ipc/relay_port.ipc.h"
// gen_amalgamated expanded: #include "perfetto/ext/ipc/codegen_helpers.h"

#include <memory>

namespace perfetto {
namespace protos {
namespace gen {
::perfetto::ipc::ServiceDescriptor* RelayPort::NewDescriptor() {
  auto* desc = new ::perfetto::ipc::ServiceDescriptor();
  desc->service_name = "RelayPort";

  desc->methods.emplace_back(::perfetto::ipc::ServiceDescriptor::Method{
     "SyncClock",
     &_IPC_Decoder<SyncClockRequest>,
     &_IPC_Decoder<SyncClockResponse>,
     &_IPC_Invoker<RelayPort, SyncClockRequest, SyncClockResponse, &RelayPort::SyncClock>});
  desc->methods.shrink_to_fit();
  return desc;
}


const ::perfetto::ipc::ServiceDescriptor& RelayPort::GetDescriptorStatic() {
  static auto* instance = NewDescriptor();
  return *instance;
}

// Host-side definitions.
RelayPort::~RelayPort() = default;

const ::perfetto::ipc::ServiceDescriptor& RelayPort::GetDescriptor() {
  return GetDescriptorStatic();
}

// Client-side definitions.
RelayPortProxy::RelayPortProxy(::perfetto::ipc::ServiceProxy::EventListener* event_listener)
    : ::perfetto::ipc::ServiceProxy(event_listener) {}

RelayPortProxy::~RelayPortProxy() = default;

const ::perfetto::ipc::ServiceDescriptor& RelayPortProxy::GetDescriptor() {
  return RelayPort::GetDescriptorStatic();
}

void RelayPortProxy::SyncClock(const SyncClockRequest& request, DeferredSyncClockResponse reply, int fd) {
  BeginInvoke("SyncClock", request, ::perfetto::ipc::DeferredBase(std::move(reply)),
              fd);
}
}  // namespace perfetto
}  // namespace protos
}  // namespace gen
// gen_amalgamated begin source: src/tracing/ipc/default_socket.cc
/*
 * Copyright (C) 2018 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// gen_amalgamated expanded: #include "perfetto/tracing/default_socket.h"

// gen_amalgamated expanded: #include "perfetto/base/build_config.h"
// gen_amalgamated expanded: #include "perfetto/base/logging.h"
// gen_amalgamated expanded: #include "perfetto/ext/base/string_utils.h"
// gen_amalgamated expanded: #include "perfetto/ext/base/utils.h"
// gen_amalgamated expanded: #include "perfetto/ext/ipc/basic_types.h"
// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/basic_types.h"

#include <stdlib.h>

#if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) ||   \
    PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \
    PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
#include <unistd.h>
#endif

namespace perfetto {
namespace {

const char* kRunPerfettoBaseDir = "/run/perfetto/";

// On Linux and CrOS, check /run/perfetto/ before using /tmp/ as the socket
// base directory.
bool UseRunPerfettoBaseDir() {
#if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX)
  // Note that the trailing / in |kRunPerfettoBaseDir| ensures we are checking
  // against a directory, not a file.
  int res = PERFETTO_EINTR(access(kRunPerfettoBaseDir, X_OK));
  if (!res)
    return true;

  // If the path doesn't exist (ENOENT), fail silently to the caller. Otherwise,
  // fail with an explicit error message.
  if (errno != ENOENT
#if PERFETTO_BUILDFLAG(PERFETTO_CHROMIUM_BUILD)
      // access(2) won't return EPERM, but Chromium sandbox returns EPERM if the
      // sandbox doesn't allow the call (e.g. in the child processes).
      && errno != EPERM
#endif
  ) {
    PERFETTO_PLOG("%s exists but cannot be accessed. Falling back on /tmp/ ",
                  kRunPerfettoBaseDir);
  }
  return false;
#else
  base::ignore_result(kRunPerfettoBaseDir);
  return false;
#endif
}

}  // anonymous namespace

const char* GetProducerSocket() {
  const char* name = getenv("PERFETTO_PRODUCER_SOCK_NAME");
  if (name == nullptr) {
#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
    name = "127.0.0.1:32278";
#elif PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
    name = "/dev/socket/traced_producer";
#else
    // Use /run/perfetto if it exists. Then fallback to /tmp.
    static const char* producer_socket =
        UseRunPerfettoBaseDir() ? "/run/perfetto/traced-producer.sock"
                                : "/tmp/perfetto-producer";
    name = producer_socket;
#endif
  }
  base::ignore_result(UseRunPerfettoBaseDir);  // Silence unused func warnings.
  return name;
}

const char* GetRelaySocket() {
  // The relay socket is optional and is connected only when the env var is set.
  return getenv("PERFETTO_RELAY_SOCK_NAME");
}

std::vector<std::string> TokenizeProducerSockets(
    const char* producer_socket_names) {
  return base::SplitString(producer_socket_names, ",");
}

const char* GetConsumerSocket() {
  const char* name = getenv("PERFETTO_CONSUMER_SOCK_NAME");
  if (name == nullptr) {
#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
    name = "127.0.0.1:32279";
#elif PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
    name = "/dev/socket/traced_consumer";
#else
    // Use /run/perfetto if it exists. Then fallback to /tmp.
    static const char* consumer_socket =
        UseRunPerfettoBaseDir() ? "/run/perfetto/traced-consumer.sock"
                                : "/tmp/perfetto-consumer";
    name = consumer_socket;
#endif
  }
  return name;
}

}  // namespace perfetto
// gen_amalgamated begin source: src/tracing/ipc/memfd.cc
// gen_amalgamated begin header: src/tracing/ipc/memfd.h
/*
 * Copyright (C) 2020 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef SRC_TRACING_IPC_MEMFD_H_
#define SRC_TRACING_IPC_MEMFD_H_

// gen_amalgamated expanded: #include "perfetto/base/build_config.h"

// gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"

// Some android build bots use a sysroot that doesn't support memfd when
// compiling for the host, so we define the flags we need ourselves.

// from memfd.h
#ifndef MFD_CLOEXEC
#define MFD_CLOEXEC 0x0001U
#define MFD_ALLOW_SEALING 0x0002U
#endif

// from fcntl.h
#ifndef F_ADD_SEALS
#define F_ADD_SEALS 1033
#define F_GET_SEALS 1034
#define F_SEAL_SEAL 0x0001
#define F_SEAL_SHRINK 0x0002
#define F_SEAL_GROW 0x0004
#define F_SEAL_WRITE 0x0008
#endif

namespace perfetto {

// Whether the operating system supports memfd.
bool HasMemfdSupport();

// Call memfd(2) if available on platform and return the fd as result. This call
// also makes a kernel version check for safety on older kernels (b/116769556).
// Returns an invalid ScopedFile on failure.
base::ScopedFile CreateMemfd(const char* name, unsigned int flags);

}  // namespace perfetto

#endif  // SRC_TRACING_IPC_MEMFD_H_
/*
 * Copyright (C) 2020 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// gen_amalgamated expanded: #include "src/tracing/ipc/memfd.h"

#include <errno.h>

#define PERFETTO_MEMFD_ENABLED()             \
  PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \
      PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX)

#if PERFETTO_MEMFD_ENABLED()

#include <stdio.h>
#include <string.h>
#include <sys/syscall.h>
#include <sys/utsname.h>
#include <unistd.h>

// Some android build bots use a sysroot that doesn't support memfd when
// compiling for the host, so we redefine it if necessary.
#if !defined(__NR_memfd_create)
#if defined(__x86_64__)
#define __NR_memfd_create 319
#elif defined(__i386__)
#define __NR_memfd_create 356
#elif defined(__aarch64__)
#define __NR_memfd_create 279
#elif defined(__arm__)
#define __NR_memfd_create 385
#else
#error "unsupported sysroot without memfd support"
#endif
#endif  // !defined(__NR_memfd_create)

namespace perfetto {
bool HasMemfdSupport() {
  static bool kSupportsMemfd = [] {
    // Check kernel version supports memfd_create(). Some older kernels segfault
    // executing memfd_create() rather than returning ENOSYS (b/116769556).
    static constexpr int kRequiredMajor = 3;
    static constexpr int kRequiredMinor = 17;
    struct utsname uts;
    int major, minor;
    if (uname(&uts) == 0 && strcmp(uts.sysname, "Linux") == 0 &&
        sscanf(uts.release, "%d.%d", &major, &minor) == 2 &&
        ((major < kRequiredMajor ||
          (major == kRequiredMajor && minor < kRequiredMinor)))) {
      return false;
    }

    base::ScopedFile fd;
    fd.reset(static_cast<int>(syscall(__NR_memfd_create, "perfetto_shmem",
                                      MFD_CLOEXEC | MFD_ALLOW_SEALING)));
    return !!fd;
  }();
  return kSupportsMemfd;
}

base::ScopedFile CreateMemfd(const char* name, unsigned int flags) {
  if (!HasMemfdSupport()) {
    errno = ENOSYS;
    return base::ScopedFile();
  }
  return base::ScopedFile(
      static_cast<int>(syscall(__NR_memfd_create, name, flags)));
}
}  // namespace perfetto

#else  // PERFETTO_MEMFD_ENABLED()

namespace perfetto {
bool HasMemfdSupport() {
  return false;
}
base::ScopedFile CreateMemfd(const char*, unsigned int) {
  errno = ENOSYS;
  return base::ScopedFile();
}
}  // namespace perfetto

#endif  // PERFETTO_MEMFD_ENABLED()
// gen_amalgamated begin source: src/tracing/ipc/posix_shared_memory.cc
// gen_amalgamated begin header: src/tracing/ipc/posix_shared_memory.h
/*
 * Copyright (C) 2017 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef SRC_TRACING_IPC_POSIX_SHARED_MEMORY_H_
#define SRC_TRACING_IPC_POSIX_SHARED_MEMORY_H_

// gen_amalgamated expanded: #include "perfetto/base/build_config.h"

#if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) ||   \
    PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \
    PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE) ||   \
    PERFETTO_BUILDFLAG(PERFETTO_OS_FUCHSIA) || \
    PERFETTO_BUILDFLAG(PERFETTO_OS_WASM)

#include <stddef.h>

#include <memory>

// gen_amalgamated expanded: #include "perfetto/base/build_config.h"
// gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"
// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/shared_memory.h"

namespace perfetto {

// Implements the SharedMemory and its factory for the posix-based transport.
class PosixSharedMemory : public SharedMemory {
 public:
  class Factory : public SharedMemory::Factory {
   public:
    ~Factory() override;
    std::unique_ptr<SharedMemory> CreateSharedMemory(size_t) override;
  };

  // Create a brand new SHM region.
  static std::unique_ptr<PosixSharedMemory> Create(size_t size);

  // Mmaps a file descriptor to an existing SHM region. If
  // |require_seals_if_supported| is true and the system supports
  // memfd_create(), the FD is required to be a sealed memfd with F_SEAL_SEAL,
  // F_SEAL_GROW, and F_SEAL_SHRINK seals set (otherwise, nullptr is returned).
  // May also return nullptr if mapping fails for another reason (e.g. OOM).
  static std::unique_ptr<PosixSharedMemory> AttachToFd(
      base::ScopedFile,
      bool require_seals_if_supported = true);

  ~PosixSharedMemory() override;

  int fd() const { return fd_.get(); }

  // SharedMemory implementation.
  void* start() const override { return start_; }
  size_t size() const override { return size_; }

 private:
  static std::unique_ptr<PosixSharedMemory> MapFD(base::ScopedFile, size_t);

  PosixSharedMemory(void* start, size_t size, base::ScopedFile);
  PosixSharedMemory(const PosixSharedMemory&) = delete;
  PosixSharedMemory& operator=(const PosixSharedMemory&) = delete;

  void* const start_;
  const size_t size_;
  base::ScopedFile fd_;
};

}  // namespace perfetto

#endif  // OS_LINUX || OS_ANDROID || OS_APPLE
#endif  // SRC_TRACING_IPC_POSIX_SHARED_MEMORY_H_
/*
 * Copyright (C) 2017 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// gen_amalgamated expanded: #include "src/tracing/ipc/posix_shared_memory.h"

#if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) ||   \
    PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \
    PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE) ||   \
    PERFETTO_BUILDFLAG(PERFETTO_OS_FUCHSIA) || \
    PERFETTO_BUILDFLAG(PERFETTO_OS_WASM)

#include <fcntl.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <unistd.h>

#include <memory>
#include <utility>

// gen_amalgamated expanded: #include "perfetto/base/compiler.h"
// gen_amalgamated expanded: #include "perfetto/base/logging.h"
// gen_amalgamated expanded: #include "perfetto/ext/base/temp_file.h"
// gen_amalgamated expanded: #include "src/tracing/ipc/memfd.h"

namespace perfetto {

namespace {
int kFileSeals = F_SEAL_SHRINK | F_SEAL_GROW | F_SEAL_SEAL;
}  // namespace

// static
std::unique_ptr<PosixSharedMemory> PosixSharedMemory::Create(size_t size) {
  base::ScopedFile fd =
      CreateMemfd("perfetto_shmem", MFD_CLOEXEC | MFD_ALLOW_SEALING);
  bool is_memfd = !!fd;

  // In-tree builds only allow mem_fd, so we can inspect the seals to verify the
  // fd is appropriately sealed. We'll crash in the PERFETTO_CHECK(fd) below if
  // memfd_create failed.
#if !PERFETTO_BUILDFLAG(PERFETTO_ANDROID_BUILD)
  if (!fd) {
    // TODO: if this fails on Android we should fall back on ashmem.
    PERFETTO_DPLOG("memfd_create() failed");
    fd = base::TempFile::CreateUnlinked().ReleaseFD();
  }
#endif

  PERFETTO_CHECK(fd);
  int res = ftruncate(fd.get(), static_cast<off_t>(size));
  PERFETTO_CHECK(res == 0);

  if (is_memfd) {
    // When memfd is supported, file seals should be, too.
    res = fcntl(*fd, F_ADD_SEALS, kFileSeals);
    PERFETTO_DCHECK(res == 0);
  }

  return MapFD(std::move(fd), size);
}

// static
std::unique_ptr<PosixSharedMemory> PosixSharedMemory::AttachToFd(
    base::ScopedFile fd,
    bool require_seals_if_supported) {
  bool requires_seals = require_seals_if_supported;

#if PERFETTO_BUILDFLAG(PERFETTO_ANDROID_BUILD)
  // In-tree kernels all support memfd.
  PERFETTO_CHECK(HasMemfdSupport());
#else
  // In out-of-tree builds, we only require seals if the kernel supports memfd.
  if (requires_seals)
    requires_seals = HasMemfdSupport();
#endif

  if (requires_seals) {
    // If the system supports memfd, we require a sealed memfd.
    int res = fcntl(*fd, F_GET_SEALS);
    if (res == -1 || (res & kFileSeals) != kFileSeals) {
      PERFETTO_PLOG("Couldn't verify file seals on shmem FD");
      return nullptr;
    }
  }

  struct stat stat_buf = {};
  int res = fstat(fd.get(), &stat_buf);
  PERFETTO_CHECK(res == 0 && stat_buf.st_size > 0);
  return MapFD(std::move(fd), static_cast<size_t>(stat_buf.st_size));
}

// static
std::unique_ptr<PosixSharedMemory> PosixSharedMemory::MapFD(base::ScopedFile fd,
                                                            size_t size) {
  PERFETTO_DCHECK(fd);
  PERFETTO_DCHECK(size > 0);
  void* start =
      mmap(nullptr, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd.get(), 0);
  PERFETTO_CHECK(start != MAP_FAILED);
  return std::unique_ptr<PosixSharedMemory>(
      new PosixSharedMemory(start, size, std::move(fd)));
}

PosixSharedMemory::PosixSharedMemory(void* start,
                                     size_t size,
                                     base::ScopedFile fd)
    : start_(start), size_(size), fd_(std::move(fd)) {}

PosixSharedMemory::~PosixSharedMemory() {
  munmap(start(), size());
}

PosixSharedMemory::Factory::~Factory() {}

std::unique_ptr<SharedMemory> PosixSharedMemory::Factory::CreateSharedMemory(
    size_t size) {
  return PosixSharedMemory::Create(size);
}

}  // namespace perfetto

#endif  // OS_LINUX || OS_ANDROID || OS_APPLE
// gen_amalgamated begin source: src/tracing/ipc/shared_memory_windows.cc
// gen_amalgamated begin header: src/tracing/ipc/shared_memory_windows.h
/*
 * Copyright (C) 2021 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef SRC_TRACING_IPC_SHARED_MEMORY_WINDOWS_H_
#define SRC_TRACING_IPC_SHARED_MEMORY_WINDOWS_H_

// gen_amalgamated expanded: #include "perfetto/base/build_config.h"

#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)

#include <string>

// gen_amalgamated expanded: #include "perfetto/base/build_config.h"
// gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"
// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/shared_memory.h"

namespace perfetto {

// Implements the SharedMemory and its factory for the Windows IPC transport.
// This used only for standalone builds and NOT in chromium, which instead uses
// a custom Mojo wrapper (MojoSharedMemory in chromium's //services/tracing/).
class SharedMemoryWindows : public SharedMemory {
 public:
  class Factory : public SharedMemory::Factory {
   public:
    ~Factory() override;
    std::unique_ptr<SharedMemory> CreateSharedMemory(size_t) override;
  };

  // Create a brand new SHM region.
  enum Flags { kNone = 0, kInheritableHandles };
  static std::unique_ptr<SharedMemoryWindows> Create(
      size_t size, Flags flags=Flags::kNone);
  static std::unique_ptr<SharedMemoryWindows> Attach(const std::string& key);
  static std::unique_ptr<SharedMemoryWindows> AttachToHandleWithKey(
      base::ScopedPlatformHandle fd, const std::string& key);
  ~SharedMemoryWindows() override;
  const std::string& key() const { return key_; }
  const base::ScopedPlatformHandle& handle() const { return handle_; }

  // SharedMemory implementation.
  void* start() const override { return start_; }
  size_t size() const override { return size_; }

 private:
  SharedMemoryWindows(void* start,
                      size_t size,
                      std::string,
                      base::ScopedPlatformHandle);
  SharedMemoryWindows(const SharedMemoryWindows&) = delete;
  SharedMemoryWindows& operator=(const SharedMemoryWindows&) = delete;

  void* const start_;
  const size_t size_;
  std::string key_;
  base::ScopedPlatformHandle handle_;
};

}  // namespace perfetto

#endif  // OS_WIN

#endif  // SRC_TRACING_IPC_SHARED_MEMORY_WINDOWS_H_
/*
 * Copyright (C) 2021 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// gen_amalgamated expanded: #include "src/tracing/ipc/shared_memory_windows.h"

#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)

#include <memory>
#include <random>

#include <Windows.h>

// gen_amalgamated expanded: #include "perfetto/base/logging.h"
// gen_amalgamated expanded: #include "perfetto/ext/base/string_utils.h"

namespace perfetto {

// static
std::unique_ptr<SharedMemoryWindows> SharedMemoryWindows::Create(
    size_t size, Flags flags) {
  base::ScopedPlatformHandle shmem_handle;
  std::random_device rnd_dev;
  uint64_t rnd_key = (static_cast<uint64_t>(rnd_dev()) << 32) | rnd_dev();
  std::string key = "perfetto_shm_" + base::Uint64ToHexStringNoPrefix(rnd_key);

  SECURITY_ATTRIBUTES security_attributes = {};
  security_attributes.nLength = sizeof(SECURITY_ATTRIBUTES);
  if (flags & Flags::kInheritableHandles)
    security_attributes.bInheritHandle = TRUE;

  shmem_handle.reset(CreateFileMappingA(
      INVALID_HANDLE_VALUE,  // Use paging file.
      &security_attributes,
      PAGE_READWRITE,
      static_cast<DWORD>(size >> 32),  // maximum object size (high-order DWORD)
      static_cast<DWORD>(size),        // maximum object size (low-order DWORD)
      key.c_str()));

  if (!shmem_handle) {
    PERFETTO_PLOG("CreateFileMapping() call failed");
    return nullptr;
  }
  void* start =
      MapViewOfFile(*shmem_handle, FILE_MAP_ALL_ACCESS, /*offsetHigh=*/0,
                    /*offsetLow=*/0, size);
  if (!start) {
    PERFETTO_PLOG("MapViewOfFile() failed");
    return nullptr;
  }

  return std::unique_ptr<SharedMemoryWindows>(new SharedMemoryWindows(
      start, size, std::move(key), std::move(shmem_handle)));
}

// static
std::unique_ptr<SharedMemoryWindows> SharedMemoryWindows::Attach(
    const std::string& key) {
  base::ScopedPlatformHandle shmem_handle;
  shmem_handle.reset(
      OpenFileMappingA(FILE_MAP_ALL_ACCESS, /*inherit=*/false, key.c_str()));
  if (!shmem_handle) {
    PERFETTO_PLOG("Failed to OpenFileMapping()");
    return nullptr;
  }

  void* start =
      MapViewOfFile(*shmem_handle, FILE_MAP_ALL_ACCESS, /*offsetHigh=*/0,
                    /*offsetLow=*/0, /*dwNumberOfBytesToMap=*/0);
  if (!start) {
    PERFETTO_PLOG("MapViewOfFile() failed");
    return nullptr;
  }

  MEMORY_BASIC_INFORMATION info{};
  if (!VirtualQuery(start, &info, sizeof(info))) {
    PERFETTO_PLOG("VirtualQuery() failed");
    return nullptr;
  }
  size_t size = info.RegionSize;
  return std::unique_ptr<SharedMemoryWindows>(
      new SharedMemoryWindows(start, size, key, std::move(shmem_handle)));
}

// static
std::unique_ptr<SharedMemoryWindows> SharedMemoryWindows::AttachToHandleWithKey(
    base::ScopedPlatformHandle shmem_handle, const std::string& key) {
  void* start =
      MapViewOfFile(*shmem_handle, FILE_MAP_ALL_ACCESS, /*offsetHigh=*/0,
                    /*offsetLow=*/0, /*dwNumberOfBytesToMap=*/0);
  if (!start) {
    PERFETTO_PLOG("MapViewOfFile() failed");
    return nullptr;
  }

  MEMORY_BASIC_INFORMATION info{};
  if (!VirtualQuery(start, &info, sizeof(info))) {
    PERFETTO_PLOG("VirtualQuery() failed");
    return nullptr;
  }
  size_t size = info.RegionSize;

  return std::unique_ptr<SharedMemoryWindows>(
      new SharedMemoryWindows(start, size, key, std::move(shmem_handle)));
}

SharedMemoryWindows::SharedMemoryWindows(void* start,
                                         size_t size,
                                         std::string key,
                                         base::ScopedPlatformHandle handle)
    : start_(start),
      size_(size),
      key_(std::move(key)),
      handle_(std::move(handle)) {}

SharedMemoryWindows::~SharedMemoryWindows() {
  if (start_)
    UnmapViewOfFile(start_);
}

SharedMemoryWindows::Factory::~Factory() = default;

std::unique_ptr<SharedMemory> SharedMemoryWindows::Factory::CreateSharedMemory(
    size_t size) {
  return SharedMemoryWindows::Create(size);
}

}  // namespace perfetto

#endif  // !OS_WIN
// gen_amalgamated begin source: src/tracing/ipc/consumer/consumer_ipc_client_impl.cc
// gen_amalgamated begin header: src/tracing/ipc/consumer/consumer_ipc_client_impl.h
// gen_amalgamated begin header: include/perfetto/ext/tracing/ipc/consumer_ipc_client.h
/*
 * Copyright (C) 2017 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef INCLUDE_PERFETTO_EXT_TRACING_IPC_CONSUMER_IPC_CLIENT_H_
#define INCLUDE_PERFETTO_EXT_TRACING_IPC_CONSUMER_IPC_CLIENT_H_

#include <memory>
#include <string>

// gen_amalgamated expanded: #include "perfetto/base/export.h"
// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/tracing_service.h"

namespace perfetto {

class Consumer;

// Allows to connect to a remote Service through a UNIX domain socket.
// Exposed to:
//   Consumer(s) of the tracing library.
// Implemented in:
//   src/tracing/ipc/consumer/consumer_ipc_client_impl.cc
class PERFETTO_EXPORT_COMPONENT ConsumerIPCClient {
 public:
  // Connects to the producer port of the Service listening on the given
  // |service_sock_name|. If the connection is successful, the OnConnect()
  // method will be invoked asynchronously on the passed Consumer interface.
  // If the connection fails, OnDisconnect() will be invoked instead.
  // The returned ConsumerEndpoint serves also to delimit the scope of the
  // callbacks invoked on the Consumer interface: no more Consumer callbacks are
  // invoked immediately after its destruction and any pending callback will be
  // dropped.
  static std::unique_ptr<TracingService::ConsumerEndpoint>
  Connect(const char* service_sock_name, Consumer*, base::TaskRunner*);

 protected:
  ConsumerIPCClient() = delete;
};

}  // namespace perfetto

#endif  // INCLUDE_PERFETTO_EXT_TRACING_IPC_CONSUMER_IPC_CLIENT_H_
/*
 * Copyright (C) 2017 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef SRC_TRACING_IPC_CONSUMER_CONSUMER_IPC_CLIENT_IMPL_H_
#define SRC_TRACING_IPC_CONSUMER_CONSUMER_IPC_CLIENT_IMPL_H_

#include <stdint.h>

#include <list>
#include <vector>

// gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"
// gen_amalgamated expanded: #include "perfetto/ext/base/weak_ptr.h"
// gen_amalgamated expanded: #include "perfetto/ext/ipc/service_proxy.h"
// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/basic_types.h"
// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/trace_packet.h"
// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/tracing_service.h"
// gen_amalgamated expanded: #include "perfetto/ext/tracing/ipc/consumer_ipc_client.h"
// gen_amalgamated expanded: #include "perfetto/tracing/core/forward_decls.h"

// gen_amalgamated expanded: #include "protos/perfetto/ipc/consumer_port.ipc.h"

namespace perfetto {

namespace base {
class TaskRunner;
}  // namespace base

namespace ipc {
class Client;
}  // namespace ipc

class Consumer;

// Exposes a Service endpoint to Consumer(s), proxying all requests through a
// IPC channel to the remote Service. This class is the glue layer between the
// generic Service interface exposed to the clients of the library and the
// actual IPC transport.
class ConsumerIPCClientImpl : public TracingService::ConsumerEndpoint,
                              public ipc::ServiceProxy::EventListener {
 public:
  ConsumerIPCClientImpl(const char* service_sock_name,
                        Consumer*,
                        base::TaskRunner*);
  ~ConsumerIPCClientImpl() override;

  // TracingService::ConsumerEndpoint implementation.
  // These methods are invoked by the actual Consumer(s) code by clients of the
  // tracing library, which know nothing about the IPC transport.
  void EnableTracing(const TraceConfig&, base::ScopedFile) override;
  void StartTracing() override;
  void ChangeTraceConfig(const TraceConfig&) override;
  void DisableTracing() override;
  void ReadBuffers() override;
  void FreeBuffers() override;
  void Flush(uint32_t timeout_ms, FlushCallback, FlushFlags) override;
  void Detach(const std::string& key) override;
  void Attach(const std::string& key) override;
  void GetTraceStats() override;
  void ObserveEvents(uint32_t enabled_event_types) override;
  void QueryServiceState(QueryServiceStateArgs,
                         QueryServiceStateCallback) override;
  void QueryCapabilities(QueryCapabilitiesCallback) override;
  void SaveTraceForBugreport(SaveTraceForBugreportCallback) override;
  void CloneSession(TracingSessionID, CloneSessionArgs) override;

  // ipc::ServiceProxy::EventListener implementation.
  // These methods are invoked by the IPC layer, which knows nothing about
  // tracing, consumers and consumers.
  void OnConnect() override;
  void OnDisconnect() override;

 private:
  struct PendingQueryServiceRequest {
    QueryServiceStateCallback callback;

    // All the replies will be appended here until |has_more| == false.
    std::vector<uint8_t> merged_resp;
  };

  // List because we need stable iterators.
  using PendingQueryServiceRequests = std::list<PendingQueryServiceRequest>;

  void OnReadBuffersResponse(
      ipc::AsyncResult<protos::gen::ReadBuffersResponse>);
  void OnEnableTracingResponse(
      ipc::AsyncResult<protos::gen::EnableTracingResponse>);
  void OnQueryServiceStateResponse(
      ipc::AsyncResult<protos::gen::QueryServiceStateResponse>,
      PendingQueryServiceRequests::iterator);

  // TODO(primiano): think to dtor order, do we rely on any specific sequence?
  Consumer* const consumer_;

  // The object that owns the client socket and takes care of IPC traffic.
  std::unique_ptr<ipc::Client> ipc_channel_;

  // The proxy interface for the consumer port of the service. It is bound
  // to |ipc_channel_| and (de)serializes method invocations over the wire.
  protos::gen::ConsumerPortProxy consumer_port_;

  bool connected_ = false;

  PendingQueryServiceRequests pending_query_svc_reqs_;

  // When a packet is too big to fit into a ReadBuffersResponse IPC, the service
  // will chunk it into several IPCs, each containing few slices of the packet
  // (a packet's slice is always guaranteed to be << kIPCBufferSize). When
  // chunking happens this field accumulates the slices received until the
  // one with |last_slice_for_packet| == true is received.
  TracePacket partial_packet_;

  // Keep last.
  base::WeakPtrFactory<ConsumerIPCClientImpl> weak_ptr_factory_;
};

}  // namespace perfetto

#endif  // SRC_TRACING_IPC_CONSUMER_CONSUMER_IPC_CLIENT_IMPL_H_
/*
 * Copyright (C) 2017 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// gen_amalgamated expanded: #include "src/tracing/ipc/consumer/consumer_ipc_client_impl.h"

#include <string.h>

#include <cinttypes>

// gen_amalgamated expanded: #include "perfetto/base/task_runner.h"
// gen_amalgamated expanded: #include "perfetto/ext/ipc/client.h"
// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/consumer.h"
// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/observable_events.h"
// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/trace_stats.h"
// gen_amalgamated expanded: #include "perfetto/tracing/core/trace_config.h"
// gen_amalgamated expanded: #include "perfetto/tracing/core/tracing_service_state.h"

// TODO(fmayer): Add a test to check to what happens when ConsumerIPCClientImpl
// gets destroyed w.r.t. the Consumer pointer. Also think to lifetime of the
// Consumer* during the callbacks.

namespace perfetto {

// static. (Declared in include/tracing/ipc/consumer_ipc_client.h).
std::unique_ptr<TracingService::ConsumerEndpoint> ConsumerIPCClient::Connect(
    const char* service_sock_name,
    Consumer* consumer,
    base::TaskRunner* task_runner) {
  return std::unique_ptr<TracingService::ConsumerEndpoint>(
      new ConsumerIPCClientImpl(service_sock_name, consumer, task_runner));
}

ConsumerIPCClientImpl::ConsumerIPCClientImpl(const char* service_sock_name,
                                             Consumer* consumer,
                                             base::TaskRunner* task_runner)
    : consumer_(consumer),
      ipc_channel_(
          ipc::Client::CreateInstance({service_sock_name, /*sock_retry=*/false},
                                      task_runner)),
      consumer_port_(this /* event_listener */),
      weak_ptr_factory_(this) {
  ipc_channel_->BindService(consumer_port_.GetWeakPtr());
}

ConsumerIPCClientImpl::~ConsumerIPCClientImpl() = default;

// Called by the IPC layer if the BindService() succeeds.
void ConsumerIPCClientImpl::OnConnect() {
  connected_ = true;
  consumer_->OnConnect();
}

void ConsumerIPCClientImpl::OnDisconnect() {
  PERFETTO_DLOG("Tracing service connection failure");
  connected_ = false;
  consumer_->OnDisconnect();  // Note: may delete |this|.
}

void ConsumerIPCClientImpl::EnableTracing(const TraceConfig& trace_config,
                                          base::ScopedFile fd) {
  if (!connected_) {
    PERFETTO_DLOG("Cannot EnableTracing(), not connected to tracing service");
    return;
  }

#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
  if (fd) {
    consumer_->OnTracingDisabled(
        "Passing FDs for write_into_file is not supported on Windows");
    return;
  }
#endif

  protos::gen::EnableTracingRequest req;
  *req.mutable_trace_config() = trace_config;
  ipc::Deferred<protos::gen::EnableTracingResponse> async_response;
  auto weak_this = weak_ptr_factory_.GetWeakPtr();
  async_response.Bind(
      [weak_this](
          ipc::AsyncResult<protos::gen::EnableTracingResponse> response) {
        if (weak_this)
          weak_this->OnEnableTracingResponse(std::move(response));
      });

  // |fd| will be closed when this function returns, but it's fine because the
  // IPC layer dup()'s it when sending the IPC.
  consumer_port_.EnableTracing(req, std::move(async_response), *fd);
}

void ConsumerIPCClientImpl::ChangeTraceConfig(const TraceConfig& trace_config) {
  if (!connected_) {
    PERFETTO_DLOG(
        "Cannot ChangeTraceConfig(), not connected to tracing service");
    return;
  }

  ipc::Deferred<protos::gen::ChangeTraceConfigResponse> async_response;
  async_response.Bind(
      [](ipc::AsyncResult<protos::gen::ChangeTraceConfigResponse> response) {
        if (!response)
          PERFETTO_DLOG("ChangeTraceConfig() failed");
      });
  protos::gen::ChangeTraceConfigRequest req;
  *req.mutable_trace_config() = trace_config;
  consumer_port_.ChangeTraceConfig(req, std::move(async_response));
}

void ConsumerIPCClientImpl::StartTracing() {
  if (!connected_) {
    PERFETTO_DLOG("Cannot StartTracing(), not connected to tracing service");
    return;
  }

  ipc::Deferred<protos::gen::StartTracingResponse> async_response;
  async_response.Bind(
      [](ipc::AsyncResult<protos::gen::StartTracingResponse> response) {
        if (!response)
          PERFETTO_DLOG("StartTracing() failed");
      });
  protos::gen::StartTracingRequest req;
  consumer_port_.StartTracing(req, std::move(async_response));
}

void ConsumerIPCClientImpl::DisableTracing() {
  if (!connected_) {
    PERFETTO_DLOG("Cannot DisableTracing(), not connected to tracing service");
    return;
  }

  ipc::Deferred<protos::gen::DisableTracingResponse> async_response;
  async_response.Bind(
      [](ipc::AsyncResult<protos::gen::DisableTracingResponse> response) {
        if (!response)
          PERFETTO_DLOG("DisableTracing() failed");
      });
  consumer_port_.DisableTracing(protos::gen::DisableTracingRequest(),
                                std::move(async_response));
}

void ConsumerIPCClientImpl::ReadBuffers() {
  if (!connected_) {
    PERFETTO_DLOG("Cannot ReadBuffers(), not connected to tracing service");
    return;
  }

  ipc::Deferred<protos::gen::ReadBuffersResponse> async_response;

  // The IPC layer guarantees that callbacks are destroyed after this object
  // is destroyed (by virtue of destroying the |consumer_port_|). In turn the
  // contract of this class expects the caller to not destroy the Consumer class
  // before having destroyed this class. Hence binding |this| here is safe.
  async_response.Bind(
      [this](ipc::AsyncResult<protos::gen::ReadBuffersResponse> response) {
        OnReadBuffersResponse(std::move(response));
      });
  consumer_port_.ReadBuffers(protos::gen::ReadBuffersRequest(),
                             std::move(async_response));
}

void ConsumerIPCClientImpl::OnReadBuffersResponse(
    ipc::AsyncResult<protos::gen::ReadBuffersResponse> response) {
  if (!response) {
    PERFETTO_DLOG("ReadBuffers() failed");
    return;
  }
  std::vector<TracePacket> trace_packets;
  for (auto& resp_slice : response->slices()) {
    const std::string& slice_data = resp_slice.data();
    Slice slice = Slice::Allocate(slice_data.size());
    memcpy(slice.own_data(), slice_data.data(), slice.size);
    partial_packet_.AddSlice(std::move(slice));
    if (resp_slice.last_slice_for_packet())
      trace_packets.emplace_back(std::move(partial_packet_));
  }
  if (!trace_packets.empty() || !response.has_more())
    consumer_->OnTraceData(std::move(trace_packets), response.has_more());
}

void ConsumerIPCClientImpl::OnEnableTracingResponse(
    ipc::AsyncResult<protos::gen::EnableTracingResponse> response) {
  std::string error;
  // |response| might be empty when the request gets rejected (if the connection
  // with the service is dropped all outstanding requests are auto-rejected).
  if (!response) {
    error =
        "EnableTracing IPC request rejected. This is likely due to a loss of "
        "the traced connection";
  } else {
    error = response->error();
  }
  if (!response || response->disabled())
    consumer_->OnTracingDisabled(error);
}

void ConsumerIPCClientImpl::FreeBuffers() {
  if (!connected_) {
    PERFETTO_DLOG("Cannot FreeBuffers(), not connected to tracing service");
    return;
  }

  protos::gen::FreeBuffersRequest req;
  ipc::Deferred<protos::gen::FreeBuffersResponse> async_response;
  async_response.Bind(
      [](ipc::AsyncResult<protos::gen::FreeBuffersResponse> response) {
        if (!response)
          PERFETTO_DLOG("FreeBuffers() failed");
      });
  consumer_port_.FreeBuffers(req, std::move(async_response));
}

void ConsumerIPCClientImpl::Flush(uint32_t timeout_ms,
                                  FlushCallback callback,
                                  FlushFlags flush_flags) {
  if (!connected_) {
    PERFETTO_DLOG("Cannot Flush(), not connected to tracing service");
    return callback(/*success=*/false);
  }

  protos::gen::FlushRequest req;
  req.set_timeout_ms(static_cast<uint32_t>(timeout_ms));
  req.set_flags(flush_flags.flags());
  ipc::Deferred<protos::gen::FlushResponse> async_response;
  async_response.Bind(
      [callback](ipc::AsyncResult<protos::gen::FlushResponse> response) {
        callback(!!response);
      });
  consumer_port_.Flush(req, std::move(async_response));
}

void ConsumerIPCClientImpl::Detach(const std::string& key) {
  if (!connected_) {
    PERFETTO_DLOG("Cannot Detach(), not connected to tracing service");
    return;
  }

  protos::gen::DetachRequest req;
  req.set_key(key);
  ipc::Deferred<protos::gen::DetachResponse> async_response;
  auto weak_this = weak_ptr_factory_.GetWeakPtr();

  async_response.Bind(
      [weak_this](ipc::AsyncResult<protos::gen::DetachResponse> response) {
        if (weak_this)
          weak_this->consumer_->OnDetach(!!response);
      });
  consumer_port_.Detach(req, std::move(async_response));
}

void ConsumerIPCClientImpl::Attach(const std::string& key) {
  if (!connected_) {
    PERFETTO_DLOG("Cannot Attach(), not connected to tracing service");
    return;
  }

  {
    protos::gen::AttachRequest req;
    req.set_key(key);
    ipc::Deferred<protos::gen::AttachResponse> async_response;
    auto weak_this = weak_ptr_factory_.GetWeakPtr();

    async_response.Bind(
        [weak_this](ipc::AsyncResult<protos::gen::AttachResponse> response) {
          if (!weak_this)
            return;
          if (!response) {
            weak_this->consumer_->OnAttach(/*success=*/false, TraceConfig());
            return;
          }
          const TraceConfig& trace_config = response->trace_config();

          // If attached successfully, also attach to the end-of-trace
          // notificaton callback, via EnableTracing(attach_notification_only).
          protos::gen::EnableTracingRequest enable_req;
          enable_req.set_attach_notification_only(true);
          ipc::Deferred<protos::gen::EnableTracingResponse> enable_resp;
          enable_resp.Bind(
              [weak_this](
                  ipc::AsyncResult<protos::gen::EnableTracingResponse> resp) {
                if (weak_this)
                  weak_this->OnEnableTracingResponse(std::move(resp));
              });
          weak_this->consumer_port_.EnableTracing(enable_req,
                                                  std::move(enable_resp));

          weak_this->consumer_->OnAttach(/*success=*/true, trace_config);
        });
    consumer_port_.Attach(req, std::move(async_response));
  }
}

void ConsumerIPCClientImpl::GetTraceStats() {
  if (!connected_) {
    PERFETTO_DLOG("Cannot GetTraceStats(), not connected to tracing service");
    return;
  }

  protos::gen::GetTraceStatsRequest req;
  ipc::Deferred<protos::gen::GetTraceStatsResponse> async_response;

  // The IPC layer guarantees that callbacks are destroyed after this object
  // is destroyed (by virtue of destroying the |consumer_port_|). In turn the
  // contract of this class expects the caller to not destroy the Consumer class
  // before having destroyed this class. Hence binding |this| here is safe.
  async_response.Bind(
      [this](ipc::AsyncResult<protos::gen::GetTraceStatsResponse> response) {
        if (!response) {
          consumer_->OnTraceStats(/*success=*/false, TraceStats());
          return;
        }
        consumer_->OnTraceStats(/*success=*/true, response->trace_stats());
      });
  consumer_port_.GetTraceStats(req, std::move(async_response));
}

void ConsumerIPCClientImpl::ObserveEvents(uint32_t enabled_event_types) {
  if (!connected_) {
    PERFETTO_DLOG("Cannot ObserveEvents(), not connected to tracing service");
    return;
  }

  protos::gen::ObserveEventsRequest req;
  for (uint32_t i = 0; i < 32; i++) {
    const uint32_t event_id = 1u << i;
    if (enabled_event_types & event_id)
      req.add_events_to_observe(static_cast<ObservableEvents::Type>(event_id));
  }

  ipc::Deferred<protos::gen::ObserveEventsResponse> async_response;
  // The IPC layer guarantees that callbacks are destroyed after this object
  // is destroyed (by virtue of destroying the |consumer_port_|). In turn the
  // contract of this class expects the caller to not destroy the Consumer class
  // before having destroyed this class. Hence binding |this| here is safe.
  async_response.Bind(
      [this](ipc::AsyncResult<protos::gen::ObserveEventsResponse> response) {
        // Skip empty response, which the service sends to close the stream.
        if (!response.has_more()) {
          PERFETTO_DCHECK(!response.success());
          return;
        }
        consumer_->OnObservableEvents(response->events());
      });
  consumer_port_.ObserveEvents(req, std::move(async_response));
}

void ConsumerIPCClientImpl::QueryServiceState(
    QueryServiceStateArgs args,
    QueryServiceStateCallback callback) {
  if (!connected_) {
    PERFETTO_DLOG(
        "Cannot QueryServiceState(), not connected to tracing service");
    return;
  }

  auto it = pending_query_svc_reqs_.insert(pending_query_svc_reqs_.end(),
                                           {std::move(callback), {}});
  protos::gen::QueryServiceStateRequest req;
  req.set_sessions_only(args.sessions_only);
  ipc::Deferred<protos::gen::QueryServiceStateResponse> async_response;
  auto weak_this = weak_ptr_factory_.GetWeakPtr();
  async_response.Bind(
      [weak_this,
       it](ipc::AsyncResult<protos::gen::QueryServiceStateResponse> response) {
        if (weak_this)
          weak_this->OnQueryServiceStateResponse(std::move(response), it);
      });
  consumer_port_.QueryServiceState(req, std::move(async_response));
}

void ConsumerIPCClientImpl::OnQueryServiceStateResponse(
    ipc::AsyncResult<protos::gen::QueryServiceStateResponse> response,
    PendingQueryServiceRequests::iterator req_it) {
  PERFETTO_DCHECK(req_it->callback);

  if (!response) {
    auto callback = std::move(req_it->callback);
    pending_query_svc_reqs_.erase(req_it);
    callback(false, TracingServiceState());
    return;
  }

  // The QueryServiceState response can be split in several chunks if the
  // service has several data sources. The client is supposed to merge all the
  // replies. The easiest way to achieve this is to re-serialize the partial
  // response and then re-decode the merged result in one shot.
  std::vector<uint8_t>& merged_resp = req_it->merged_resp;
  std::vector<uint8_t> part = response->service_state().SerializeAsArray();
  merged_resp.insert(merged_resp.end(), part.begin(), part.end());

  if (response.has_more())
    return;

  // All replies have been received. Decode the merged result and reply to the
  // callback.
  protos::gen::TracingServiceState svc_state;
  bool ok = svc_state.ParseFromArray(merged_resp.data(), merged_resp.size());
  if (!ok)
    PERFETTO_ELOG("Failed to decode merged QueryServiceStateResponse");
  auto callback = std::move(req_it->callback);
  pending_query_svc_reqs_.erase(req_it);
  callback(ok, std::move(svc_state));
}

void ConsumerIPCClientImpl::QueryCapabilities(
    QueryCapabilitiesCallback callback) {
  if (!connected_) {
    PERFETTO_DLOG(
        "Cannot QueryCapabilities(), not connected to tracing service");
    return;
  }

  protos::gen::QueryCapabilitiesRequest req;
  ipc::Deferred<protos::gen::QueryCapabilitiesResponse> async_response;
  async_response.Bind(
      [callback](
          ipc::AsyncResult<protos::gen::QueryCapabilitiesResponse> response) {
        if (!response) {
          // If the IPC fails, we are talking to an older version of the service
          // that didn't support QueryCapabilities at all. In this case return
          // an empty capabilities message.
          callback(TracingServiceCapabilities());
        } else {
          callback(response->capabilities());
        }
      });
  consumer_port_.QueryCapabilities(req, std::move(async_response));
}

void ConsumerIPCClientImpl::SaveTraceForBugreport(
    SaveTraceForBugreportCallback callback) {
  if (!connected_) {
    PERFETTO_DLOG(
        "Cannot SaveTraceForBugreport(), not connected to tracing service");
    return;
  }

  protos::gen::SaveTraceForBugreportRequest req;
  ipc::Deferred<protos::gen::SaveTraceForBugreportResponse> async_response;
  async_response.Bind(
      [callback](ipc::AsyncResult<protos::gen::SaveTraceForBugreportResponse>
                     response) {
        if (!response) {
          // If the IPC fails, we are talking to an older version of the service
          // that didn't support SaveTraceForBugreport at all.
          callback(
              false,
              "The tracing service doesn't support SaveTraceForBugreport()");
        } else {
          callback(response->success(), response->msg());
        }
      });
  consumer_port_.SaveTraceForBugreport(req, std::move(async_response));
}

void ConsumerIPCClientImpl::CloneSession(TracingSessionID tsid,
                                         CloneSessionArgs args) {
  if (!connected_) {
    PERFETTO_DLOG("Cannot CloneSession(), not connected to tracing service");
    return;
  }

  protos::gen::CloneSessionRequest req;
  req.set_session_id(tsid);
  req.set_skip_trace_filter(args.skip_trace_filter);
  req.set_for_bugreport(args.for_bugreport);
  ipc::Deferred<protos::gen::CloneSessionResponse> async_response;
  auto weak_this = weak_ptr_factory_.GetWeakPtr();

  async_response.Bind(
      [weak_this](
          ipc::AsyncResult<protos::gen::CloneSessionResponse> response) {
        if (!weak_this)
          return;
        if (!response) {
          // If the IPC fails, we are talking to an older version of the service
          // that didn't support CloneSession at all.
          weak_this->consumer_->OnSessionCloned(
              {false, "CloneSession IPC not supported", {}});
        } else {
          base::Uuid uuid(response->uuid_lsb(), response->uuid_msb());
          weak_this->consumer_->OnSessionCloned(
              {response->success(), response->error(), uuid});
        }
      });
  consumer_port_.CloneSession(req, std::move(async_response));
}
}  // namespace perfetto
// gen_amalgamated begin source: src/tracing/ipc/producer/producer_ipc_client_impl.cc
// gen_amalgamated begin header: src/tracing/ipc/producer/producer_ipc_client_impl.h
// gen_amalgamated begin header: include/perfetto/ext/tracing/ipc/producer_ipc_client.h
/*
 * Copyright (C) 2017 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef INCLUDE_PERFETTO_EXT_TRACING_IPC_PRODUCER_IPC_CLIENT_H_
#define INCLUDE_PERFETTO_EXT_TRACING_IPC_PRODUCER_IPC_CLIENT_H_

#include <memory>
#include <string>

// gen_amalgamated expanded: #include "perfetto/base/export.h"
// gen_amalgamated expanded: #include "perfetto/ext/ipc/client.h"
// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/shared_memory.h"
// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/shared_memory_arbiter.h"
// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/tracing_service.h"
// gen_amalgamated expanded: #include "perfetto/tracing/tracing_backend.h"

namespace perfetto {

class Producer;

// Allows to connect to a remote Service through a UNIX domain socket.
// Exposed to:
//   Producer(s) of the tracing library.
// Implemented in:
//   src/tracing/ipc/producer/producer_ipc_client_impl.cc
class PERFETTO_EXPORT_COMPONENT ProducerIPCClient {
 public:
  enum class ConnectionFlags {
    // Fails immediately with OnConnect(false) if the service connection cannot
    // be established.
    kDefault = 0,

    // Keeps retrying with exponential backoff indefinitely. The caller will
    // never see an OnConnect(false).
    kRetryIfUnreachable = 1,
  };

  // Connects to the producer port of the Service listening on the given
  // |service_sock_name|. If the connection is successful, the OnConnect()
  // method will be invoked asynchronously on the passed Producer interface. If
  // the connection fails, OnDisconnect() will be invoked instead. The returned
  // ProducerEndpoint serves also to delimit the scope of the callbacks invoked
  // on the Producer interface: no more Producer callbacks are invoked
  // immediately after its destruction and any pending callback will be dropped.
  // To provide a producer-allocated shared memory buffer, both |shm| and
  // |shm_arbiter| should be set. |shm_arbiter| should be an unbound
  // SharedMemoryArbiter instance. When |shm| and |shm_arbiter| are provided,
  // the service will attempt to adopt the provided SMB. If this fails, the
  // ProducerEndpoint will disconnect, but the SMB and arbiter will remain valid
  // until the client is destroyed.
  //
  // TODO(eseckler): Support adoption failure more gracefully.
  // TODO(primiano): move all the existing use cases to the Connect(ConnArgs)
  // below. Also move the functionality of ConnectionFlags into ConnArgs.
  static std::unique_ptr<TracingService::ProducerEndpoint> Connect(
      const char* service_sock_name,
      Producer*,
      const std::string& producer_name,
      base::TaskRunner*,
      TracingService::ProducerSMBScrapingMode smb_scraping_mode =
          TracingService::ProducerSMBScrapingMode::kDefault,
      size_t shared_memory_size_hint_bytes = 0,
      size_t shared_memory_page_size_hint_bytes = 0,
      std::unique_ptr<SharedMemory> shm = nullptr,
      std::unique_ptr<SharedMemoryArbiter> shm_arbiter = nullptr,
      ConnectionFlags = ConnectionFlags::kDefault);

  // Overload of Connect() to support adopting a connected socket using
  // ipc::Client::ConnArgs.
  static std::unique_ptr<TracingService::ProducerEndpoint> Connect(
      ipc::Client::ConnArgs,
      Producer*,
      const std::string& producer_name,
      base::TaskRunner*,
      TracingService::ProducerSMBScrapingMode smb_scraping_mode =
          TracingService::ProducerSMBScrapingMode::kDefault,
      size_t shared_memory_size_hint_bytes = 0,
      size_t shared_memory_page_size_hint_bytes = 0,
      std::unique_ptr<SharedMemory> shm = nullptr,
      std::unique_ptr<SharedMemoryArbiter> shm_arbiter = nullptr,
      CreateSocketAsync create_socket_async = nullptr);

 protected:
  ProducerIPCClient() = delete;
};

}  // namespace perfetto

#endif  // INCLUDE_PERFETTO_EXT_TRACING_IPC_PRODUCER_IPC_CLIENT_H_
/*
 * Copyright (C) 2017 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef SRC_TRACING_IPC_PRODUCER_PRODUCER_IPC_CLIENT_IMPL_H_
#define SRC_TRACING_IPC_PRODUCER_PRODUCER_IPC_CLIENT_IMPL_H_

#include <stdint.h>

#include <set>
#include <vector>

// gen_amalgamated expanded: #include "perfetto/ext/base/thread_checker.h"
// gen_amalgamated expanded: #include "perfetto/ext/base/weak_ptr.h"
// gen_amalgamated expanded: #include "perfetto/ext/ipc/client.h"
// gen_amalgamated expanded: #include "perfetto/ext/ipc/service_proxy.h"
// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/basic_types.h"
// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/shared_memory.h"
// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/tracing_service.h"
// gen_amalgamated expanded: #include "perfetto/ext/tracing/ipc/producer_ipc_client.h"

// gen_amalgamated expanded: #include "protos/perfetto/ipc/producer_port.ipc.h"

namespace perfetto {

namespace base {
class TaskRunner;
}  // namespace base

class Producer;
class SharedMemoryArbiter;

// Exposes a Service endpoint to Producer(s), proxying all requests through a
// IPC channel to the remote Service. This class is the glue layer between the
// generic Service interface exposed to the clients of the library and the
// actual IPC transport.
// If create_socket_async is set, it will be called to create and connect to a
// socket to the service. If unset, the producer will create and connect itself.
class ProducerIPCClientImpl : public TracingService::ProducerEndpoint,
                              public ipc::ServiceProxy::EventListener {
 public:
  ProducerIPCClientImpl(ipc::Client::ConnArgs,
                        Producer*,
                        const std::string& producer_name,
                        base::TaskRunner*,
                        TracingService::ProducerSMBScrapingMode,
                        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,
                        CreateSocketAsync create_socket_async);
  ~ProducerIPCClientImpl() override;

  // TracingService::ProducerEndpoint implementation.
  // These methods are invoked by the actual Producer(s) code by clients of the
  // tracing library, which know nothing about the IPC transport.
  void Disconnect() override;
  void RegisterDataSource(const DataSourceDescriptor&) override;
  void UpdateDataSource(const DataSourceDescriptor&) override;
  void UnregisterDataSource(const std::string& name) override;
  void RegisterTraceWriter(uint32_t writer_id, uint32_t target_buffer) override;
  void UnregisterTraceWriter(uint32_t writer_id) override;
  void CommitData(const CommitDataRequest&, CommitDataCallback) override;
  void NotifyDataSourceStarted(DataSourceInstanceID) override;
  void NotifyDataSourceStopped(DataSourceInstanceID) override;
  void ActivateTriggers(const std::vector<std::string>&) override;
  void Sync(std::function<void()> callback) override;

  std::unique_ptr<TraceWriter> CreateTraceWriter(
      BufferID target_buffer,
      BufferExhaustedPolicy) override;
  SharedMemoryArbiter* MaybeSharedMemoryArbiter() override;
  bool IsShmemProvidedByProducer() const override;
  void NotifyFlushComplete(FlushRequestID) override;
  SharedMemory* shared_memory() const override;
  size_t shared_buffer_page_size_kb() const override;

  // ipc::ServiceProxy::EventListener implementation.
  // These methods are invoked by the IPC layer, which knows nothing about
  // tracing, producers and consumers.
  void OnConnect() override;
  void OnDisconnect() override;

  ipc::Client* GetClientForTesting() { return ipc_channel_.get(); }

 private:
  // Drops the provider connection if a protocol error was detected while
  // processing an IPC command.
  void ScheduleDisconnect();

  // Invoked soon after having established the connection with the service.
  void OnConnectionInitialized(bool connection_succeeded,
                               bool using_shmem_provided_by_producer,
                               bool direct_smb_patching_supported,
                               bool use_shmem_emulation);

  // Invoked when the remote Service sends an IPC to tell us to do something
  // (e.g. start/stop a data source).
  void OnServiceRequest(const protos::gen::GetAsyncCommandResponse&);

  // TODO think to destruction order, do we rely on any specific dtor sequence?
  Producer* const producer_;
  base::TaskRunner* const task_runner_;

  // A callback used to receive the shmem region out of band of the socket.
  std::function<int(void)> receive_shmem_fd_cb_fuchsia_;

  // The object that owns the client socket and takes care of IPC traffic.
  std::unique_ptr<ipc::Client> ipc_channel_;

  // The proxy interface for the producer port of the service. It is bound
  // to |ipc_channel_| and (de)serializes method invocations over the wire.
  std::unique_ptr<protos::gen::ProducerPortProxy> producer_port_;

  std::unique_ptr<SharedMemory> shared_memory_;
  std::unique_ptr<SharedMemoryArbiter> shared_memory_arbiter_;
  size_t shared_buffer_page_size_kb_ = 0;
  std::set<DataSourceInstanceID> data_sources_setup_;
  bool connected_ = false;
  std::string const name_;
  size_t shared_memory_page_size_hint_bytes_ = 0;
  size_t shared_memory_size_hint_bytes_ = 0;
  TracingService::ProducerSMBScrapingMode const smb_scraping_mode_;
  bool is_shmem_provided_by_producer_ = false;
  bool direct_smb_patching_supported_ = false;
  bool use_shmem_emulation_ = false;
  std::vector<std::function<void()>> pending_sync_reqs_;
  base::WeakPtrFactory<ProducerIPCClientImpl> weak_factory_{this};
  PERFETTO_THREAD_CHECKER(thread_checker_)
};

}  // namespace perfetto

#endif  // SRC_TRACING_IPC_PRODUCER_PRODUCER_IPC_CLIENT_IMPL_H_
/*
 * Copyright (C) 2017 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// gen_amalgamated expanded: #include "src/tracing/ipc/producer/producer_ipc_client_impl.h"

#include <cinttypes>

#include <string.h>

// gen_amalgamated expanded: #include "perfetto/base/logging.h"
// gen_amalgamated expanded: #include "perfetto/base/task_runner.h"
// gen_amalgamated expanded: #include "perfetto/ext/base/unix_socket.h"
// gen_amalgamated expanded: #include "perfetto/ext/base/version.h"
// gen_amalgamated expanded: #include "perfetto/ext/ipc/client.h"
// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/commit_data_request.h"
// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/producer.h"
// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/shared_memory_abi.h"
// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/shared_memory_arbiter.h"
// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/trace_writer.h"
// gen_amalgamated expanded: #include "perfetto/tracing/core/data_source_config.h"
// gen_amalgamated expanded: #include "perfetto/tracing/core/data_source_descriptor.h"
// gen_amalgamated expanded: #include "perfetto/tracing/core/trace_config.h"
// gen_amalgamated expanded: #include "src/tracing/core/in_process_shared_memory.h"

#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
// gen_amalgamated expanded: #include "src/tracing/ipc/shared_memory_windows.h"
#else
// gen_amalgamated expanded: #include "src/tracing/ipc/posix_shared_memory.h"
#endif

// TODO(fmayer): think to what happens when ProducerIPCClientImpl gets destroyed
// w.r.t. the Producer pointer. Also think to lifetime of the Producer* during
// the callbacks.

namespace perfetto {

// static. (Declared in include/tracing/ipc/producer_ipc_client.h).
std::unique_ptr<TracingService::ProducerEndpoint> ProducerIPCClient::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) {
  return std::unique_ptr<TracingService::ProducerEndpoint>(
      new ProducerIPCClientImpl(
          {service_sock_name,
           conn_flags ==
               ProducerIPCClient::ConnectionFlags::kRetryIfUnreachable},
          producer, producer_name, task_runner, smb_scraping_mode,
          shared_memory_size_hint_bytes, shared_memory_page_size_hint_bytes,
          std::move(shm), std::move(shm_arbiter), nullptr));
}

// static. (Declared in include/tracing/ipc/producer_ipc_client.h).
std::unique_ptr<TracingService::ProducerEndpoint> ProducerIPCClient::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,
    CreateSocketAsync create_socket_async) {
  return std::unique_ptr<TracingService::ProducerEndpoint>(
      new ProducerIPCClientImpl(
          std::move(conn_args), producer, producer_name, task_runner,
          smb_scraping_mode, shared_memory_size_hint_bytes,
          shared_memory_page_size_hint_bytes, std::move(shm),
          std::move(shm_arbiter), create_socket_async));
}

ProducerIPCClientImpl::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,
    CreateSocketAsync create_socket_async)
    : producer_(producer),
      task_runner_(task_runner),
      receive_shmem_fd_cb_fuchsia_(
          std::move(conn_args.receive_shmem_fd_cb_fuchsia)),
      producer_port_(
          new protos::gen::ProducerPortProxy(this /* event_listener */)),
      shared_memory_(std::move(shm)),
      shared_memory_arbiter_(std::move(shm_arbiter)),
      name_(producer_name),
      shared_memory_page_size_hint_bytes_(shared_memory_page_size_hint_bytes),
      shared_memory_size_hint_bytes_(shared_memory_size_hint_bytes),
      smb_scraping_mode_(smb_scraping_mode) {
  // Check for producer-provided SMB (used by Chrome for startup tracing).
  if (shared_memory_) {
    // We also expect a valid (unbound) arbiter. Bind it to this endpoint now.
    PERFETTO_CHECK(shared_memory_arbiter_);
    shared_memory_arbiter_->BindToProducerEndpoint(this, task_runner_);

    // If the service accepts our SMB, then it must match our requested page
    // layout. The protocol doesn't allow the service to change the size and
    // layout when the SMB is provided by the producer.
    shared_buffer_page_size_kb_ = shared_memory_page_size_hint_bytes_ / 1024;
  }

  if (create_socket_async) {
    PERFETTO_DCHECK(conn_args.socket_name);
    auto weak_this = weak_factory_.GetWeakPtr();
    create_socket_async(
        [weak_this, task_runner = task_runner_](base::SocketHandle fd) {
          task_runner->PostTask([weak_this, fd] {
            base::ScopedSocketHandle handle(fd);
            if (!weak_this) {
              return;
            }
            ipc::Client::ConnArgs args(std::move(handle));
            weak_this->ipc_channel_ = ipc::Client::CreateInstance(
                std::move(args), weak_this->task_runner_);
            weak_this->ipc_channel_->BindService(
                weak_this->producer_port_->GetWeakPtr());
          });
        });
  } else {
    ipc_channel_ =
        ipc::Client::CreateInstance(std::move(conn_args), task_runner);
    ipc_channel_->BindService(producer_port_->GetWeakPtr());
  }
  PERFETTO_DCHECK_THREAD(thread_checker_);
}

ProducerIPCClientImpl::~ProducerIPCClientImpl() {
  PERFETTO_DCHECK_THREAD(thread_checker_);
}

void ProducerIPCClientImpl::Disconnect() {
  PERFETTO_DCHECK_THREAD(thread_checker_);
  if (!producer_port_)
    return;
  // Reset the producer port so that no further IPCs are received and IPC
  // callbacks are no longer executed. Also reset the IPC channel so that the
  // service is notified of the disconnection.
  producer_port_.reset();
  ipc_channel_.reset();
  // Perform disconnect synchronously.
  OnDisconnect();
}

// Called by the IPC layer if the BindService() succeeds.
void ProducerIPCClientImpl::OnConnect() {
  PERFETTO_DCHECK_THREAD(thread_checker_);
  connected_ = true;

  // The IPC layer guarantees that any outstanding callback will be dropped on
  // the floor if producer_port_ is destroyed between the request and the reply.
  // Binding |this| is hence safe.
  ipc::Deferred<protos::gen::InitializeConnectionResponse> on_init;
  on_init.Bind(
      [this](ipc::AsyncResult<protos::gen::InitializeConnectionResponse> resp) {
        OnConnectionInitialized(
            resp.success(),
            resp.success() ? resp->using_shmem_provided_by_producer() : false,
            resp.success() ? resp->direct_smb_patching_supported() : false,
            resp.success() ? resp->use_shmem_emulation() : false);
      });
  protos::gen::InitializeConnectionRequest req;
  req.set_producer_name(name_);
  req.set_shared_memory_size_hint_bytes(
      static_cast<uint32_t>(shared_memory_size_hint_bytes_));
  req.set_shared_memory_page_size_hint_bytes(
      static_cast<uint32_t>(shared_memory_page_size_hint_bytes_));
  switch (smb_scraping_mode_) {
    case TracingService::ProducerSMBScrapingMode::kDefault:
      // No need to set the mode, it defaults to use the service default if
      // unspecified.
      break;
    case TracingService::ProducerSMBScrapingMode::kEnabled:
      req.set_smb_scraping_mode(
          protos::gen::InitializeConnectionRequest::SMB_SCRAPING_ENABLED);
      break;
    case TracingService::ProducerSMBScrapingMode::kDisabled:
      req.set_smb_scraping_mode(
          protos::gen::InitializeConnectionRequest::SMB_SCRAPING_DISABLED);
      break;
  }

  int shm_fd = -1;
  if (shared_memory_) {
    req.set_producer_provided_shmem(true);
#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
    auto key = static_cast<SharedMemoryWindows*>(shared_memory_.get())->key();
    req.set_shm_key_windows(key);
#else
    shm_fd = static_cast<PosixSharedMemory*>(shared_memory_.get())->fd();
#endif
  }

  req.set_sdk_version(base::GetVersionString());
  producer_port_->InitializeConnection(req, std::move(on_init), shm_fd);

  // Create the back channel to receive commands from the Service.
  ipc::Deferred<protos::gen::GetAsyncCommandResponse> on_cmd;
  on_cmd.Bind(
      [this](ipc::AsyncResult<protos::gen::GetAsyncCommandResponse> resp) {
        if (!resp)
          return;  // The IPC channel was closed and |resp| was auto-rejected.
        OnServiceRequest(*resp);
      });
  producer_port_->GetAsyncCommand(protos::gen::GetAsyncCommandRequest(),
                                  std::move(on_cmd));

  // If there are pending Sync() requests, send them now.
  for (const auto& pending_sync : pending_sync_reqs_)
    Sync(std::move(pending_sync));
  pending_sync_reqs_.clear();
}

void ProducerIPCClientImpl::OnDisconnect() {
  PERFETTO_DCHECK_THREAD(thread_checker_);
  PERFETTO_DLOG("Tracing service connection failure");
  connected_ = false;
  data_sources_setup_.clear();
  producer_->OnDisconnect();  // Note: may delete |this|.
}

void ProducerIPCClientImpl::ScheduleDisconnect() {
  // |ipc_channel| doesn't allow disconnection in the middle of handling
  // an IPC call, so the connection drop must take place over two phases.

  // First, synchronously drop the |producer_port_| so that no more IPC
  // messages are handled.
  producer_port_.reset();

  // Then schedule an async task for performing the remainder of the
  // disconnection operations outside the context of the IPC method handler.
  auto weak_this = weak_factory_.GetWeakPtr();
  task_runner_->PostTask([weak_this]() {
    if (weak_this) {
      weak_this->Disconnect();
    }
  });
}

void ProducerIPCClientImpl::OnConnectionInitialized(
    bool connection_succeeded,
    bool using_shmem_provided_by_producer,
    bool direct_smb_patching_supported,
    bool use_shmem_emulation) {
  PERFETTO_DCHECK_THREAD(thread_checker_);
  // If connection_succeeded == false, the OnDisconnect() call will follow next
  // and there we'll notify the |producer_|. TODO: add a test for this.
  if (!connection_succeeded)
    return;
  is_shmem_provided_by_producer_ = using_shmem_provided_by_producer;
  direct_smb_patching_supported_ = direct_smb_patching_supported;
  // The tracing service may reject using shared memory and tell the client to
  // commit data over the socket. This can happen when the client connects to
  // the service via a relay service:
  // client <-Unix socket-> relay service <- vsock -> tracing service.
  use_shmem_emulation_ = use_shmem_emulation;
  producer_->OnConnect();

  // Bail out if the service failed to adopt our producer-allocated SMB.
  // TODO(eseckler): Handle adoption failure more gracefully.
  if (shared_memory_ && !is_shmem_provided_by_producer_) {
    PERFETTO_DLOG("Service failed adopt producer-provided SMB, disconnecting.");
    Disconnect();
    return;
  }
}

void ProducerIPCClientImpl::OnServiceRequest(
    const protos::gen::GetAsyncCommandResponse& cmd) {
  PERFETTO_DCHECK_THREAD(thread_checker_);

  // This message is sent only when connecting to a service running Android Q+.
  // See comment below in kStartDataSource.
  if (cmd.has_setup_data_source()) {
    const auto& req = cmd.setup_data_source();
    const DataSourceInstanceID dsid = req.new_instance_id();
    data_sources_setup_.insert(dsid);
    producer_->SetupDataSource(dsid, req.config());
    return;
  }

  if (cmd.has_start_data_source()) {
    const auto& req = cmd.start_data_source();
    const DataSourceInstanceID dsid = req.new_instance_id();
    const DataSourceConfig& cfg = req.config();
    if (!data_sources_setup_.count(dsid)) {
      // When connecting with an older (Android P) service, the service will not
      // send a SetupDataSource message. We synthesize it here in that case.
      producer_->SetupDataSource(dsid, cfg);
    }
    producer_->StartDataSource(dsid, cfg);
    return;
  }

  if (cmd.has_stop_data_source()) {
    const DataSourceInstanceID dsid = cmd.stop_data_source().instance_id();
    producer_->StopDataSource(dsid);
    data_sources_setup_.erase(dsid);
    return;
  }

  if (cmd.has_setup_tracing()) {
    std::unique_ptr<SharedMemory> ipc_shared_memory;
#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
    const std::string& shm_key = cmd.setup_tracing().shm_key_windows();
    if (!shm_key.empty())
      ipc_shared_memory = SharedMemoryWindows::Attach(shm_key);
#elif PERFETTO_BUILDFLAG(PERFETTO_OS_FUCHSIA)
    // On Fuchsia, the embedder is responsible for routing the shared memory
    // FD, which is provided to this code via a blocking callback.
    PERFETTO_CHECK(receive_shmem_fd_cb_fuchsia_);

    base::ScopedFile shmem_fd(receive_shmem_fd_cb_fuchsia_());
    if (!shmem_fd) {
      // Failure to get a shared memory buffer is a protocol violation and
      // therefore we should drop the Protocol connection.
      PERFETTO_ELOG("Could not get shared memory FD from embedder.");
      ScheduleDisconnect();
      return;
    }

    ipc_shared_memory =
        PosixSharedMemory::AttachToFd(std::move(shmem_fd),
                                      /*require_seals_if_supported=*/false);
#else
    base::ScopedFile shmem_fd = ipc_channel_->TakeReceivedFD();
    if (shmem_fd) {
      // TODO(primiano): handle mmap failure in case of OOM.
      ipc_shared_memory =
          PosixSharedMemory::AttachToFd(std::move(shmem_fd),
                                        /*require_seals_if_supported=*/false);
    }
#endif
    if (use_shmem_emulation_) {
      PERFETTO_CHECK(!ipc_shared_memory);
      // Need to create an emulated shmem buffer when the transport deosn't
      // support it.
      // TODO(chinglinyu): Let the tracing service decide on the shmem size and
      // propagate the size in InitializeConnectionResponse.
      ipc_shared_memory = InProcessSharedMemory::Create(
          /*size=*/InProcessSharedMemory::kDefaultSize);
    }
    if (ipc_shared_memory) {
      auto shmem_mode = use_shmem_emulation_
                            ? SharedMemoryABI::ShmemMode::kShmemEmulation
                            : SharedMemoryABI::ShmemMode::kDefault;
      // This is the nominal case used in most configurations, where the service
      // provides the SMB.
      PERFETTO_CHECK(!is_shmem_provided_by_producer_ && !shared_memory_);
      shared_memory_ = std::move(ipc_shared_memory);
      shared_buffer_page_size_kb_ =
          cmd.setup_tracing().shared_buffer_page_size_kb();
      shared_memory_arbiter_ = SharedMemoryArbiter::CreateInstance(
          shared_memory_.get(), shared_buffer_page_size_kb_ * 1024, shmem_mode,
          this, task_runner_);
      if (direct_smb_patching_supported_)
        shared_memory_arbiter_->SetDirectSMBPatchingSupportedByService();
    } else {
      // Producer-provided SMB (used by Chrome for startup tracing).
      PERFETTO_CHECK(is_shmem_provided_by_producer_ && shared_memory_ &&
                     shared_memory_arbiter_);
    }
    producer_->OnTracingSetup();
    return;
  }

  if (cmd.has_flush()) {
    // This cast boilerplate is required only because protobuf uses its own
    // uint64 and not stdint's uint64_t. On some 64 bit archs they differ on the
    // type (long vs long long) even though they have the same size.
    const auto* data_source_ids = cmd.flush().data_source_ids().data();
    static_assert(sizeof(data_source_ids[0]) == sizeof(DataSourceInstanceID),
                  "data_source_ids should be 64-bit");

    FlushFlags flags(cmd.flush().flags());
    producer_->Flush(
        cmd.flush().request_id(),
        reinterpret_cast<const DataSourceInstanceID*>(data_source_ids),
        static_cast<size_t>(cmd.flush().data_source_ids().size()), flags);
    return;
  }

  if (cmd.has_clear_incremental_state()) {
    const auto* data_source_ids =
        cmd.clear_incremental_state().data_source_ids().data();
    static_assert(sizeof(data_source_ids[0]) == sizeof(DataSourceInstanceID),
                  "data_source_ids should be 64-bit");
    producer_->ClearIncrementalState(
        reinterpret_cast<const DataSourceInstanceID*>(data_source_ids),
        static_cast<size_t>(
            cmd.clear_incremental_state().data_source_ids().size()));
    return;
  }

  PERFETTO_DFATAL("Unknown async request received from tracing service");
}

void ProducerIPCClientImpl::RegisterDataSource(
    const DataSourceDescriptor& descriptor) {
  PERFETTO_DCHECK_THREAD(thread_checker_);
  if (!connected_) {
    PERFETTO_DLOG(
        "Cannot RegisterDataSource(), not connected to tracing service");
  }
  protos::gen::RegisterDataSourceRequest req;
  *req.mutable_data_source_descriptor() = descriptor;
  ipc::Deferred<protos::gen::RegisterDataSourceResponse> async_response;
  async_response.Bind(
      [](ipc::AsyncResult<protos::gen::RegisterDataSourceResponse> response) {
        if (!response)
          PERFETTO_DLOG("RegisterDataSource() failed: connection reset");
      });
  producer_port_->RegisterDataSource(req, std::move(async_response));
}

void ProducerIPCClientImpl::UpdateDataSource(
    const DataSourceDescriptor& descriptor) {
  PERFETTO_DCHECK_THREAD(thread_checker_);
  if (!connected_) {
    PERFETTO_DLOG(
        "Cannot UpdateDataSource(), not connected to tracing service");
  }
  protos::gen::UpdateDataSourceRequest req;
  *req.mutable_data_source_descriptor() = descriptor;
  ipc::Deferred<protos::gen::UpdateDataSourceResponse> async_response;
  async_response.Bind(
      [](ipc::AsyncResult<protos::gen::UpdateDataSourceResponse> response) {
        if (!response)
          PERFETTO_DLOG("UpdateDataSource() failed: connection reset");
      });
  producer_port_->UpdateDataSource(req, std::move(async_response));
}

void ProducerIPCClientImpl::UnregisterDataSource(const std::string& name) {
  PERFETTO_DCHECK_THREAD(thread_checker_);
  if (!connected_) {
    PERFETTO_DLOG(
        "Cannot UnregisterDataSource(), not connected to tracing service");
    return;
  }
  protos::gen::UnregisterDataSourceRequest req;
  req.set_data_source_name(name);
  producer_port_->UnregisterDataSource(
      req, ipc::Deferred<protos::gen::UnregisterDataSourceResponse>());
}

void ProducerIPCClientImpl::RegisterTraceWriter(uint32_t writer_id,
                                                uint32_t target_buffer) {
  PERFETTO_DCHECK_THREAD(thread_checker_);
  if (!connected_) {
    PERFETTO_DLOG(
        "Cannot RegisterTraceWriter(), not connected to tracing service");
    return;
  }
  protos::gen::RegisterTraceWriterRequest req;
  req.set_trace_writer_id(writer_id);
  req.set_target_buffer(target_buffer);
  producer_port_->RegisterTraceWriter(
      req, ipc::Deferred<protos::gen::RegisterTraceWriterResponse>());
}

void ProducerIPCClientImpl::UnregisterTraceWriter(uint32_t writer_id) {
  PERFETTO_DCHECK_THREAD(thread_checker_);
  if (!connected_) {
    PERFETTO_DLOG(
        "Cannot UnregisterTraceWriter(), not connected to tracing service");
    return;
  }
  protos::gen::UnregisterTraceWriterRequest req;
  req.set_trace_writer_id(writer_id);
  producer_port_->UnregisterTraceWriter(
      req, ipc::Deferred<protos::gen::UnregisterTraceWriterResponse>());
}

void ProducerIPCClientImpl::CommitData(const CommitDataRequest& req,
                                       CommitDataCallback callback) {
  PERFETTO_DCHECK_THREAD(thread_checker_);
  if (!connected_) {
    PERFETTO_DLOG("Cannot CommitData(), not connected to tracing service");
    return;
  }
  ipc::Deferred<protos::gen::CommitDataResponse> async_response;
  // TODO(primiano): add a test that destroys ProducerIPCClientImpl soon after
  // this call and checks that the callback is dropped.
  if (callback) {
    async_response.Bind(
        [callback](ipc::AsyncResult<protos::gen::CommitDataResponse> response) {
          if (!response) {
            PERFETTO_DLOG("CommitData() failed: connection reset");
            return;
          }
          callback();
        });
  }
  producer_port_->CommitData(req, std::move(async_response));
}

void ProducerIPCClientImpl::NotifyDataSourceStarted(DataSourceInstanceID id) {
  PERFETTO_DCHECK_THREAD(thread_checker_);
  if (!connected_) {
    PERFETTO_DLOG(
        "Cannot NotifyDataSourceStarted(), not connected to tracing service");
    return;
  }
  protos::gen::NotifyDataSourceStartedRequest req;
  req.set_data_source_id(id);
  producer_port_->NotifyDataSourceStarted(
      req, ipc::Deferred<protos::gen::NotifyDataSourceStartedResponse>());
}

void ProducerIPCClientImpl::NotifyDataSourceStopped(DataSourceInstanceID id) {
  PERFETTO_DCHECK_THREAD(thread_checker_);
  if (!connected_) {
    PERFETTO_DLOG(
        "Cannot NotifyDataSourceStopped(), not connected to tracing service");
    return;
  }
  protos::gen::NotifyDataSourceStoppedRequest req;
  req.set_data_source_id(id);
  producer_port_->NotifyDataSourceStopped(
      req, ipc::Deferred<protos::gen::NotifyDataSourceStoppedResponse>());
}

void ProducerIPCClientImpl::ActivateTriggers(
    const std::vector<std::string>& triggers) {
  PERFETTO_DCHECK_THREAD(thread_checker_);
  if (!connected_) {
    PERFETTO_DLOG(
        "Cannot ActivateTriggers(), not connected to tracing service");
    return;
  }
  protos::gen::ActivateTriggersRequest proto_req;
  for (const auto& name : triggers) {
    *proto_req.add_trigger_names() = name;
  }
  producer_port_->ActivateTriggers(
      proto_req, ipc::Deferred<protos::gen::ActivateTriggersResponse>());
}

void ProducerIPCClientImpl::Sync(std::function<void()> callback) {
  PERFETTO_DCHECK_THREAD(thread_checker_);
  if (!connected_) {
    pending_sync_reqs_.emplace_back(std::move(callback));
    return;
  }
  ipc::Deferred<protos::gen::SyncResponse> resp;
  resp.Bind([callback](ipc::AsyncResult<protos::gen::SyncResponse>) {
    // Here we ACK the callback even if the service replies with a failure
    // (i.e. the service is too old and doesn't understand Sync()). In that
    // case the service has still seen the request, the IPC roundtrip is
    // still a (weaker) linearization fence.
    callback();
  });
  producer_port_->Sync(protos::gen::SyncRequest(), std::move(resp));
}

std::unique_ptr<TraceWriter> ProducerIPCClientImpl::CreateTraceWriter(
    BufferID target_buffer,
    BufferExhaustedPolicy buffer_exhausted_policy) {
  // This method can be called by different threads. |shared_memory_arbiter_| is
  // thread-safe but be aware of accessing any other state in this function.
  return shared_memory_arbiter_->CreateTraceWriter(target_buffer,
                                                   buffer_exhausted_policy);
}

SharedMemoryArbiter* ProducerIPCClientImpl::MaybeSharedMemoryArbiter() {
  return shared_memory_arbiter_.get();
}

bool ProducerIPCClientImpl::IsShmemProvidedByProducer() const {
  return is_shmem_provided_by_producer_;
}

void ProducerIPCClientImpl::NotifyFlushComplete(FlushRequestID req_id) {
  return shared_memory_arbiter_->NotifyFlushComplete(req_id);
}

SharedMemory* ProducerIPCClientImpl::shared_memory() const {
  return shared_memory_.get();
}

size_t ProducerIPCClientImpl::shared_buffer_page_size_kb() const {
  return shared_buffer_page_size_kb_;
}

}  // namespace perfetto
// gen_amalgamated begin source: src/tracing/ipc/service/consumer_ipc_service.cc
// gen_amalgamated begin header: src/tracing/ipc/service/consumer_ipc_service.h
/*
 * Copyright (C) 2017 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef SRC_TRACING_IPC_SERVICE_CONSUMER_IPC_SERVICE_H_
#define SRC_TRACING_IPC_SERVICE_CONSUMER_IPC_SERVICE_H_

#include <list>
#include <map>
#include <memory>
#include <string>

// gen_amalgamated expanded: #include "perfetto/ext/base/weak_ptr.h"
// gen_amalgamated expanded: #include "perfetto/ext/ipc/basic_types.h"
// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/consumer.h"
// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/tracing_service.h"
// gen_amalgamated expanded: #include "perfetto/tracing/core/forward_decls.h"
// gen_amalgamated expanded: #include "protos/perfetto/ipc/consumer_port.ipc.h"

namespace perfetto {

namespace ipc {
class Host;
}  // namespace ipc

// Implements the Consumer port of the IPC service. This class proxies requests
// and responses between the core service logic (|svc_|) and remote Consumer(s)
// on the IPC socket, through the methods overriddden from ConsumerPort.
class ConsumerIPCService : public protos::gen::ConsumerPort {
 public:
  explicit ConsumerIPCService(TracingService* core_service);
  ~ConsumerIPCService() override;

  // ConsumerPort implementation (from .proto IPC definition).
  void EnableTracing(const protos::gen::EnableTracingRequest&,
                     DeferredEnableTracingResponse) override;
  void StartTracing(const protos::gen::StartTracingRequest&,
                    DeferredStartTracingResponse) override;
  void ChangeTraceConfig(const protos::gen::ChangeTraceConfigRequest&,
                         DeferredChangeTraceConfigResponse) override;
  void DisableTracing(const protos::gen::DisableTracingRequest&,
                      DeferredDisableTracingResponse) override;
  void ReadBuffers(const protos::gen::ReadBuffersRequest&,
                   DeferredReadBuffersResponse) override;
  void FreeBuffers(const protos::gen::FreeBuffersRequest&,
                   DeferredFreeBuffersResponse) override;
  void Flush(const protos::gen::FlushRequest&, DeferredFlushResponse) override;
  void Detach(const protos::gen::DetachRequest&,
              DeferredDetachResponse) override;
  void Attach(const protos::gen::AttachRequest&,
              DeferredAttachResponse) override;
  void GetTraceStats(const protos::gen::GetTraceStatsRequest&,
                     DeferredGetTraceStatsResponse) override;
  void ObserveEvents(const protos::gen::ObserveEventsRequest&,
                     DeferredObserveEventsResponse) override;
  void QueryServiceState(const protos::gen::QueryServiceStateRequest&,
                         DeferredQueryServiceStateResponse) override;
  void QueryCapabilities(const protos::gen::QueryCapabilitiesRequest&,
                         DeferredQueryCapabilitiesResponse) override;
  void SaveTraceForBugreport(const protos::gen::SaveTraceForBugreportRequest&,
                             DeferredSaveTraceForBugreportResponse) override;
  void CloneSession(const protos::gen::CloneSessionRequest&,
                    DeferredCloneSessionResponse) override;
  void OnClientDisconnected() override;

 private:
  // Acts like a Consumer with the core Service business logic (which doesn't
  // know anything about the remote transport), but all it does is proxying
  // methods to the remote Consumer on the other side of the IPC channel.
  class RemoteConsumer : public Consumer {
   public:
    RemoteConsumer();
    ~RemoteConsumer() override;

    // These methods are called by the |core_service_| business logic. There is
    // no connection here, these methods are posted straight away.
    void OnConnect() override;
    void OnDisconnect() override;
    void OnTracingDisabled(const std::string& error) override;
    void OnTraceData(std::vector<TracePacket>, bool has_more) override;
    void OnDetach(bool) override;
    void OnAttach(bool, const TraceConfig&) override;
    void OnTraceStats(bool, const TraceStats&) override;
    void OnObservableEvents(const ObservableEvents&) override;
    void OnSessionCloned(const OnSessionClonedArgs&) override;

    void CloseObserveEventsResponseStream();

    // The interface obtained from the core service business logic through
    // TracingService::ConnectConsumer(this). This allows to invoke methods for
    // a specific Consumer on the Service business logic.
    std::unique_ptr<TracingService::ConsumerEndpoint> service_endpoint;

    // After ReadBuffers() is invoked, this binds the async callback that
    // allows to stream trace packets back to the client.
    DeferredReadBuffersResponse read_buffers_response;

    // After EnableTracing() is invoked, this binds the async callback that
    // allows to send the OnTracingDisabled notification.
    DeferredEnableTracingResponse enable_tracing_response;

    // After Detach() is invoked, this binds the async callback that allows to
    // send the session id to the consumer.
    DeferredDetachResponse detach_response;

    // As above, but for the Attach() case.
    DeferredAttachResponse attach_response;

    // As above, but for GetTraceStats().
    DeferredGetTraceStatsResponse get_trace_stats_response;

    // As above, but for CloneSession().
    DeferredCloneSessionResponse clone_session_response;

    // After ObserveEvents() is invoked, this binds the async callback that
    // allows to stream ObservableEvents back to the client.
    DeferredObserveEventsResponse observe_events_response;
  };

  // This has to be a container that doesn't invalidate iterators.
  using PendingFlushResponses = std::list<DeferredFlushResponse>;
  using PendingQuerySvcResponses = std::list<DeferredQueryServiceStateResponse>;
  using PendingQueryCapabilitiesResponses =
      std::list<DeferredQueryCapabilitiesResponse>;
  using PendingSaveTraceForBugreportResponses =
      std::list<DeferredSaveTraceForBugreportResponse>;

  ConsumerIPCService(const ConsumerIPCService&) = delete;
  ConsumerIPCService& operator=(const ConsumerIPCService&) = delete;

  // Returns the ConsumerEndpoint in the core business logic that corresponds to
  // the current IPC request.
  RemoteConsumer* GetConsumerForCurrentRequest();

  void OnFlushCallback(bool success, PendingFlushResponses::iterator);
  void OnQueryServiceCallback(bool success,
                              const TracingServiceState&,
                              PendingQuerySvcResponses::iterator);
  void OnQueryCapabilitiesCallback(const TracingServiceCapabilities&,
                                   PendingQueryCapabilitiesResponses::iterator);
  void OnSaveTraceForBugreportCallback(
      bool success,
      const std::string& msg,
      PendingSaveTraceForBugreportResponses::iterator);

  TracingService* const core_service_;

  // Maps IPC clients to ConsumerEndpoint instances registered on the
  // |core_service_| business logic.
  std::map<ipc::ClientID, std::unique_ptr<RemoteConsumer>> consumers_;

  PendingFlushResponses pending_flush_responses_;
  PendingQuerySvcResponses pending_query_service_responses_;
  PendingQueryCapabilitiesResponses pending_query_capabilities_responses_;
  PendingSaveTraceForBugreportResponses pending_bugreport_responses_;

  base::WeakPtrFactory<ConsumerIPCService> weak_ptr_factory_;  // Keep last.
};

}  // namespace perfetto

#endif  // SRC_TRACING_IPC_SERVICE_CONSUMER_IPC_SERVICE_H_
/*
 * Copyright (C) 2017 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// gen_amalgamated expanded: #include "src/tracing/ipc/service/consumer_ipc_service.h"

#include <cinttypes>

// gen_amalgamated expanded: #include "perfetto/base/logging.h"
// gen_amalgamated expanded: #include "perfetto/base/task_runner.h"
// gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"
// gen_amalgamated expanded: #include "perfetto/ext/ipc/basic_types.h"
// gen_amalgamated expanded: #include "perfetto/ext/ipc/host.h"
// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/shared_memory_abi.h"
// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/slice.h"
// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/trace_packet.h"
// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/trace_stats.h"
// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/tracing_service.h"
// gen_amalgamated expanded: #include "perfetto/tracing/core/trace_config.h"
// gen_amalgamated expanded: #include "perfetto/tracing/core/tracing_service_capabilities.h"
// gen_amalgamated expanded: #include "perfetto/tracing/core/tracing_service_state.h"

namespace perfetto {

ConsumerIPCService::ConsumerIPCService(TracingService* core_service)
    : core_service_(core_service), weak_ptr_factory_(this) {}

ConsumerIPCService::~ConsumerIPCService() = default;

ConsumerIPCService::RemoteConsumer*
ConsumerIPCService::GetConsumerForCurrentRequest() {
  const ipc::ClientID ipc_client_id = ipc::Service::client_info().client_id();
  const uid_t uid = ipc::Service::client_info().uid();
  PERFETTO_CHECK(ipc_client_id);
  auto it = consumers_.find(ipc_client_id);
  if (it == consumers_.end()) {
    auto* remote_consumer = new RemoteConsumer();
    consumers_[ipc_client_id].reset(remote_consumer);
    remote_consumer->service_endpoint =
        core_service_->ConnectConsumer(remote_consumer, uid);
    return remote_consumer;
  }
  return it->second.get();
}

// Called by the IPC layer.
void ConsumerIPCService::OnClientDisconnected() {
  ipc::ClientID client_id = ipc::Service::client_info().client_id();
  consumers_.erase(client_id);
}

// Called by the IPC layer.
void ConsumerIPCService::EnableTracing(
    const protos::gen::EnableTracingRequest& req,
    DeferredEnableTracingResponse resp) {
  RemoteConsumer* remote_consumer = GetConsumerForCurrentRequest();
  if (req.attach_notification_only()) {
    remote_consumer->enable_tracing_response = std::move(resp);
    return;
  }
  const TraceConfig& trace_config = req.trace_config();
  base::ScopedFile fd;
  if (trace_config.write_into_file() && trace_config.output_path().empty())
    fd = ipc::Service::TakeReceivedFD();
  remote_consumer->service_endpoint->EnableTracing(trace_config, std::move(fd));
  remote_consumer->enable_tracing_response = std::move(resp);
}

// Called by the IPC layer.
void ConsumerIPCService::StartTracing(const protos::gen::StartTracingRequest&,
                                      DeferredStartTracingResponse resp) {
  RemoteConsumer* remote_consumer = GetConsumerForCurrentRequest();
  remote_consumer->service_endpoint->StartTracing();
  resp.Resolve(ipc::AsyncResult<protos::gen::StartTracingResponse>::Create());
}

// Called by the IPC layer.
void ConsumerIPCService::ChangeTraceConfig(
    const protos::gen::ChangeTraceConfigRequest& req,
    DeferredChangeTraceConfigResponse resp) {
  RemoteConsumer* remote_consumer = GetConsumerForCurrentRequest();
  remote_consumer->service_endpoint->ChangeTraceConfig(req.trace_config());
  resp.Resolve(
      ipc::AsyncResult<protos::gen::ChangeTraceConfigResponse>::Create());
}

// Called by the IPC layer.
void ConsumerIPCService::DisableTracing(
    const protos::gen::DisableTracingRequest&,
    DeferredDisableTracingResponse resp) {
  GetConsumerForCurrentRequest()->service_endpoint->DisableTracing();
  resp.Resolve(ipc::AsyncResult<protos::gen::DisableTracingResponse>::Create());
}

// Called by the IPC layer.
void ConsumerIPCService::ReadBuffers(const protos::gen::ReadBuffersRequest&,
                                     DeferredReadBuffersResponse resp) {
  RemoteConsumer* remote_consumer = GetConsumerForCurrentRequest();
  remote_consumer->read_buffers_response = std::move(resp);
  remote_consumer->service_endpoint->ReadBuffers();
}

// Called by the IPC layer.
void ConsumerIPCService::FreeBuffers(const protos::gen::FreeBuffersRequest&,
                                     DeferredFreeBuffersResponse resp) {
  GetConsumerForCurrentRequest()->service_endpoint->FreeBuffers();
  resp.Resolve(ipc::AsyncResult<protos::gen::FreeBuffersResponse>::Create());
}

// Called by the IPC layer.
void ConsumerIPCService::Flush(const protos::gen::FlushRequest& req,
                               DeferredFlushResponse resp) {
  auto it = pending_flush_responses_.insert(pending_flush_responses_.end(),
                                            std::move(resp));
  auto weak_this = weak_ptr_factory_.GetWeakPtr();
  auto callback = [weak_this, it](bool success) {
    if (weak_this)
      weak_this->OnFlushCallback(success, std::move(it));
  };
  FlushFlags flags(req.flags());
  GetConsumerForCurrentRequest()->service_endpoint->Flush(
      req.timeout_ms(), std::move(callback), flags);
}

// Called by the IPC layer.
void ConsumerIPCService::Detach(const protos::gen::DetachRequest& req,
                                DeferredDetachResponse resp) {
  // OnDetach() will resolve the |detach_response|.
  RemoteConsumer* remote_consumer = GetConsumerForCurrentRequest();
  remote_consumer->detach_response = std::move(resp);
  remote_consumer->service_endpoint->Detach(req.key());
}

// Called by the IPC layer.
void ConsumerIPCService::Attach(const protos::gen::AttachRequest& req,
                                DeferredAttachResponse resp) {
  // OnAttach() will resolve the |attach_response|.
  RemoteConsumer* remote_consumer = GetConsumerForCurrentRequest();
  remote_consumer->attach_response = std::move(resp);
  remote_consumer->service_endpoint->Attach(req.key());
}

// Called by the IPC layer.
void ConsumerIPCService::GetTraceStats(const protos::gen::GetTraceStatsRequest&,
                                       DeferredGetTraceStatsResponse resp) {
  // OnTraceStats() will resolve the |get_trace_stats_response|.
  RemoteConsumer* remote_consumer = GetConsumerForCurrentRequest();
  remote_consumer->get_trace_stats_response = std::move(resp);
  remote_consumer->service_endpoint->GetTraceStats();
}

// Called by the IPC layer.
void ConsumerIPCService::ObserveEvents(
    const protos::gen::ObserveEventsRequest& req,
    DeferredObserveEventsResponse resp) {
  RemoteConsumer* remote_consumer = GetConsumerForCurrentRequest();

  // If there's a prior stream, close it so that client can clean it up.
  remote_consumer->CloseObserveEventsResponseStream();

  remote_consumer->observe_events_response = std::move(resp);

  uint32_t events_mask = 0;
  for (const auto& type : req.events_to_observe()) {
    events_mask |= static_cast<uint32_t>(type);
  }
  remote_consumer->service_endpoint->ObserveEvents(events_mask);

  // If no events are to be observed, close the stream immediately so that the
  // client can clean up.
  if (events_mask == 0)
    remote_consumer->CloseObserveEventsResponseStream();
}

// Called by the IPC layer.
void ConsumerIPCService::QueryServiceState(
    const protos::gen::QueryServiceStateRequest& req,
    DeferredQueryServiceStateResponse resp) {
  RemoteConsumer* remote_consumer = GetConsumerForCurrentRequest();
  auto it = pending_query_service_responses_.insert(
      pending_query_service_responses_.end(), std::move(resp));
  auto weak_this = weak_ptr_factory_.GetWeakPtr();
  auto callback = [weak_this, it](bool success,
                                  const TracingServiceState& svc_state) {
    if (weak_this)
      weak_this->OnQueryServiceCallback(success, svc_state, std::move(it));
  };
  ConsumerEndpoint::QueryServiceStateArgs args;
  args.sessions_only = req.sessions_only();
  remote_consumer->service_endpoint->QueryServiceState(args, callback);
}

// Called by the service in response to service_endpoint->QueryServiceState().
void ConsumerIPCService::OnQueryServiceCallback(
    bool success,
    const TracingServiceState& svc_state,
    PendingQuerySvcResponses::iterator pending_response_it) {
  DeferredQueryServiceStateResponse response(std::move(*pending_response_it));
  pending_query_service_responses_.erase(pending_response_it);
  if (!success) {
    response.Reject();
    return;
  }

  // The TracingServiceState object might be too big to fit into a single IPC
  // message because it contains the DataSourceDescriptor of each data source.
  // Here we split it in chunks to fit in the IPC limit, observing the
  // following rule: each chunk must be invididually a valid TracingServiceState
  // message; all the chunks concatenated together must form the original
  // message. This is to deal with the legacy API that was just sending one
  // whole message (failing in presence of too many data sources, b/153142114).
  // The message is split as follows: we take the whole TracingServiceState,
  // take out the data sources section (which is a top-level repeated field)
  // and re-add them one-by-one. If, in the process of appending, the IPC msg
  // size is reached, a new chunk is created. This assumes that the rest of
  // TracingServiceState fits in one IPC message and each DataSourceDescriptor
  // fits in the worst case in a dedicated message (which is true, because
  // otherwise the RegisterDataSource() which passes the descriptor in the first
  // place would fail).

  std::vector<uint8_t> chunked_reply;

  // Transmits the current chunk and starts a new one.
  bool sent_eof = false;
  auto send_chunked_reply = [&chunked_reply, &response,
                             &sent_eof](bool has_more) {
    PERFETTO_CHECK(!sent_eof);
    sent_eof = !has_more;
    auto resp =
        ipc::AsyncResult<protos::gen::QueryServiceStateResponse>::Create();
    resp.set_has_more(has_more);
    PERFETTO_CHECK(resp->mutable_service_state()->ParseFromArray(
        chunked_reply.data(), chunked_reply.size()));
    chunked_reply.clear();
    response.Resolve(std::move(resp));
  };

  // Create a copy of the whole response and cut away the data_sources section.
  protos::gen::TracingServiceState svc_state_copy = svc_state;
  auto data_sources = std::move(*svc_state_copy.mutable_data_sources());
  chunked_reply = svc_state_copy.SerializeAsArray();

  // Now re-add them fitting within the IPC message limits (- some margin for
  // the outer IPC frame).
  constexpr size_t kMaxMsgSize = ipc::kIPCBufferSize - 128;
  for (const auto& data_source : data_sources) {
    protos::gen::TracingServiceState tmp;
    tmp.mutable_data_sources()->emplace_back(std::move(data_source));
    std::vector<uint8_t> chunk = tmp.SerializeAsArray();
    if (chunked_reply.size() + chunk.size() < kMaxMsgSize) {
      chunked_reply.insert(chunked_reply.end(), chunk.begin(), chunk.end());
    } else {
      send_chunked_reply(/*has_more=*/true);
      chunked_reply = std::move(chunk);
    }
  }

  PERFETTO_DCHECK(!chunked_reply.empty());
  send_chunked_reply(/*has_more=*/false);
  PERFETTO_CHECK(sent_eof);
}

// Called by the service in response to a service_endpoint->Flush() request.
void ConsumerIPCService::OnFlushCallback(
    bool success,
    PendingFlushResponses::iterator pending_response_it) {
  DeferredFlushResponse response(std::move(*pending_response_it));
  pending_flush_responses_.erase(pending_response_it);
  if (success) {
    response.Resolve(ipc::AsyncResult<protos::gen::FlushResponse>::Create());
  } else {
    response.Reject();
  }
}

void ConsumerIPCService::QueryCapabilities(
    const protos::gen::QueryCapabilitiesRequest&,
    DeferredQueryCapabilitiesResponse resp) {
  RemoteConsumer* remote_consumer = GetConsumerForCurrentRequest();
  auto it = pending_query_capabilities_responses_.insert(
      pending_query_capabilities_responses_.end(), std::move(resp));
  auto weak_this = weak_ptr_factory_.GetWeakPtr();
  auto callback = [weak_this, it](const TracingServiceCapabilities& caps) {
    if (weak_this)
      weak_this->OnQueryCapabilitiesCallback(caps, std::move(it));
  };
  remote_consumer->service_endpoint->QueryCapabilities(callback);
}

// Called by the service in response to service_endpoint->QueryCapabilities().
void ConsumerIPCService::OnQueryCapabilitiesCallback(
    const TracingServiceCapabilities& caps,
    PendingQueryCapabilitiesResponses::iterator pending_response_it) {
  DeferredQueryCapabilitiesResponse response(std::move(*pending_response_it));
  pending_query_capabilities_responses_.erase(pending_response_it);
  auto resp =
      ipc::AsyncResult<protos::gen::QueryCapabilitiesResponse>::Create();
  *resp->mutable_capabilities() = caps;
  response.Resolve(std::move(resp));
}

void ConsumerIPCService::SaveTraceForBugreport(
    const protos::gen::SaveTraceForBugreportRequest&,
    DeferredSaveTraceForBugreportResponse resp) {
  RemoteConsumer* remote_consumer = GetConsumerForCurrentRequest();
  auto it = pending_bugreport_responses_.insert(
      pending_bugreport_responses_.end(), std::move(resp));
  auto weak_this = weak_ptr_factory_.GetWeakPtr();
  auto callback = [weak_this, it](bool success, const std::string& msg) {
    if (weak_this)
      weak_this->OnSaveTraceForBugreportCallback(success, msg, std::move(it));
  };
  remote_consumer->service_endpoint->SaveTraceForBugreport(callback);
}

void ConsumerIPCService::CloneSession(
    const protos::gen::CloneSessionRequest& req,
    DeferredCloneSessionResponse resp) {
  RemoteConsumer* remote_consumer = GetConsumerForCurrentRequest();
  remote_consumer->clone_session_response = std::move(resp);
  ConsumerEndpoint::CloneSessionArgs args;
  args.skip_trace_filter = req.skip_trace_filter();
  args.for_bugreport = req.for_bugreport();
  remote_consumer->service_endpoint->CloneSession(req.session_id(),
                                                  std::move(args));
}

// Called by the service in response to
// service_endpoint->SaveTraceForBugreport().
void ConsumerIPCService::OnSaveTraceForBugreportCallback(
    bool success,
    const std::string& msg,
    PendingSaveTraceForBugreportResponses::iterator pending_response_it) {
  DeferredSaveTraceForBugreportResponse response(
      std::move(*pending_response_it));
  pending_bugreport_responses_.erase(pending_response_it);
  auto resp =
      ipc::AsyncResult<protos::gen::SaveTraceForBugreportResponse>::Create();
  resp->set_success(success);
  resp->set_msg(msg);
  response.Resolve(std::move(resp));
}

////////////////////////////////////////////////////////////////////////////////
// RemoteConsumer methods
////////////////////////////////////////////////////////////////////////////////

ConsumerIPCService::RemoteConsumer::RemoteConsumer() = default;
ConsumerIPCService::RemoteConsumer::~RemoteConsumer() = default;

// Invoked by the |core_service_| business logic after the ConnectConsumer()
// call. There is nothing to do here, we really expected the ConnectConsumer()
// to just work in the local case.
void ConsumerIPCService::RemoteConsumer::OnConnect() {}

// Invoked by the |core_service_| business logic after we destroy the
// |service_endpoint| (in the RemoteConsumer dtor).
void ConsumerIPCService::RemoteConsumer::OnDisconnect() {}

void ConsumerIPCService::RemoteConsumer::OnTracingDisabled(
    const std::string& error) {
  if (enable_tracing_response.IsBound()) {
    auto result =
        ipc::AsyncResult<protos::gen::EnableTracingResponse>::Create();
    result->set_disabled(true);
    if (!error.empty())
      result->set_error(error);
    enable_tracing_response.Resolve(std::move(result));
  }
}

void ConsumerIPCService::RemoteConsumer::OnTraceData(
    std::vector<TracePacket> trace_packets,
    bool has_more) {
  if (!read_buffers_response.IsBound())
    return;

  auto result = ipc::AsyncResult<protos::gen::ReadBuffersResponse>::Create();

  // A TracePacket might be too big to fit into a single IPC message (max
  // kIPCBufferSize). However a TracePacket is made of slices and each slice
  // is way smaller than kIPCBufferSize (a slice size is effectively bounded by
  // the max chunk size of the SharedMemoryABI). When sending a TracePacket,
  // if its slices don't fit within one IPC, chunk them over several contiguous
  // IPCs using the |last_slice_for_packet| for glueing on the other side.
  static_assert(ipc::kIPCBufferSize >= SharedMemoryABI::kMaxPageSize * 2,
                "kIPCBufferSize too small given the max possible slice size");

  auto send_ipc_reply = [this, &result](bool more) {
    result.set_has_more(more);
    read_buffers_response.Resolve(std::move(result));
    result = ipc::AsyncResult<protos::gen::ReadBuffersResponse>::Create();
  };

  size_t approx_reply_size = 0;
  for (const TracePacket& trace_packet : trace_packets) {
    size_t num_slices_left_for_packet = trace_packet.slices().size();
    for (const Slice& slice : trace_packet.slices()) {
      // Check if this slice would cause the IPC to overflow its max size and,
      // if that is the case, split the IPCs. The "16" and "64" below are
      // over-estimations of, respectively:
      // 16: the preamble that prefixes each slice (there are 2 x size fields
      //     in the proto + the |last_slice_for_packet| bool).
      // 64: the overhead of the IPC InvokeMethodReply + wire_protocol's frame.
      // If these estimations are wrong, BufferedFrameDeserializer::Serialize()
      // will hit a DCHECK anyways.
      const size_t approx_slice_size = slice.size + 16;
      if (approx_reply_size + approx_slice_size > ipc::kIPCBufferSize - 64) {
        // If we hit this CHECK we got a single slice that is > kIPCBufferSize.
        PERFETTO_CHECK(result->slices_size() > 0);
        send_ipc_reply(/*has_more=*/true);
        approx_reply_size = 0;
      }
      approx_reply_size += approx_slice_size;

      auto* res_slice = result->add_slices();
      res_slice->set_last_slice_for_packet(--num_slices_left_for_packet == 0);
      res_slice->set_data(slice.start, slice.size);
    }
  }
  send_ipc_reply(has_more);
}

void ConsumerIPCService::RemoteConsumer::OnDetach(bool success) {
  if (!success) {
    std::move(detach_response).Reject();
    return;
  }
  auto resp = ipc::AsyncResult<protos::gen::DetachResponse>::Create();
  std::move(detach_response).Resolve(std::move(resp));
}

void ConsumerIPCService::RemoteConsumer::OnAttach(
    bool success,
    const TraceConfig& trace_config) {
  if (!success) {
    std::move(attach_response).Reject();
    return;
  }
  auto response = ipc::AsyncResult<protos::gen::AttachResponse>::Create();
  *response->mutable_trace_config() = trace_config;
  std::move(attach_response).Resolve(std::move(response));
}

void ConsumerIPCService::RemoteConsumer::OnTraceStats(bool success,
                                                      const TraceStats& stats) {
  if (!success) {
    std::move(get_trace_stats_response).Reject();
    return;
  }
  auto response =
      ipc::AsyncResult<protos::gen::GetTraceStatsResponse>::Create();
  *response->mutable_trace_stats() = stats;
  std::move(get_trace_stats_response).Resolve(std::move(response));
}

void ConsumerIPCService::RemoteConsumer::OnObservableEvents(
    const ObservableEvents& events) {
  if (!observe_events_response.IsBound())
    return;

  auto result = ipc::AsyncResult<protos::gen::ObserveEventsResponse>::Create();
  result.set_has_more(true);
  *result->mutable_events() = events;
  observe_events_response.Resolve(std::move(result));
}

void ConsumerIPCService::RemoteConsumer::CloseObserveEventsResponseStream() {
  if (!observe_events_response.IsBound())
    return;

  auto result = ipc::AsyncResult<protos::gen::ObserveEventsResponse>::Create();
  result.set_has_more(false);
  observe_events_response.Resolve(std::move(result));
}

void ConsumerIPCService::RemoteConsumer::OnSessionCloned(
    const OnSessionClonedArgs& args) {
  if (!clone_session_response.IsBound())
    return;

  auto resp = ipc::AsyncResult<protos::gen::CloneSessionResponse>::Create();
  resp->set_success(args.success);
  resp->set_error(args.error);
  resp->set_uuid_msb(args.uuid.msb());
  resp->set_uuid_lsb(args.uuid.lsb());
  std::move(clone_session_response).Resolve(std::move(resp));
}

}  // namespace perfetto
// gen_amalgamated begin source: src/tracing/ipc/service/producer_ipc_service.cc
// gen_amalgamated begin header: src/tracing/ipc/service/producer_ipc_service.h
/*
 * Copyright (C) 2017 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef SRC_TRACING_IPC_SERVICE_PRODUCER_IPC_SERVICE_H_
#define SRC_TRACING_IPC_SERVICE_PRODUCER_IPC_SERVICE_H_

#include <list>
#include <map>
#include <memory>
#include <string>

// gen_amalgamated expanded: #include "perfetto/ext/base/weak_ptr.h"
// gen_amalgamated expanded: #include "perfetto/ext/ipc/basic_types.h"
// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/producer.h"
// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/tracing_service.h"

// gen_amalgamated expanded: #include "protos/perfetto/ipc/producer_port.ipc.h"

namespace perfetto {

namespace ipc {
class Host;
}  // namespace ipc

// Implements the Producer port of the IPC service. This class proxies requests
// and responses between the core service logic (|svc_|) and remote Producer(s)
// on the IPC socket, through the methods overriddden from ProducerPort.
class ProducerIPCService : public protos::gen::ProducerPort {
 public:
  explicit ProducerIPCService(TracingService* core_service);
  ~ProducerIPCService() override;

  // ProducerPort implementation (from .proto IPC definition).
  void InitializeConnection(const protos::gen::InitializeConnectionRequest&,
                            DeferredInitializeConnectionResponse) override;
  void RegisterDataSource(const protos::gen::RegisterDataSourceRequest&,
                          DeferredRegisterDataSourceResponse) override;
  void UpdateDataSource(const protos::gen::UpdateDataSourceRequest&,
                        DeferredUpdateDataSourceResponse) override;
  void UnregisterDataSource(const protos::gen::UnregisterDataSourceRequest&,
                            DeferredUnregisterDataSourceResponse) override;
  void RegisterTraceWriter(const protos::gen::RegisterTraceWriterRequest&,
                           DeferredRegisterTraceWriterResponse) override;
  void UnregisterTraceWriter(const protos::gen::UnregisterTraceWriterRequest&,
                             DeferredUnregisterTraceWriterResponse) override;
  void CommitData(const protos::gen::CommitDataRequest&,
                  DeferredCommitDataResponse) override;
  void NotifyDataSourceStarted(
      const protos::gen::NotifyDataSourceStartedRequest&,
      DeferredNotifyDataSourceStartedResponse) override;
  void NotifyDataSourceStopped(
      const protos::gen::NotifyDataSourceStoppedRequest&,
      DeferredNotifyDataSourceStoppedResponse) override;
  void ActivateTriggers(const protos::gen::ActivateTriggersRequest&,
                        DeferredActivateTriggersResponse) override;

  void GetAsyncCommand(const protos::gen::GetAsyncCommandRequest&,
                       DeferredGetAsyncCommandResponse) override;
  void Sync(const protos::gen::SyncRequest&, DeferredSyncResponse) override;
  void OnClientDisconnected() override;

 private:
  // Acts like a Producer with the core Service business logic (which doesn't
  // know anything about the remote transport), but all it does is proxying
  // methods to the remote Producer on the other side of the IPC channel.
  class RemoteProducer : public Producer {
   public:
    RemoteProducer();
    ~RemoteProducer() override;

    // These methods are called by the |core_service_| business logic. There is
    // no connection here, these methods are posted straight away.
    void OnConnect() override;
    void OnDisconnect() override;
    void SetupDataSource(DataSourceInstanceID,
                         const DataSourceConfig&) override;
    void StartDataSource(DataSourceInstanceID,
                         const DataSourceConfig&) override;
    void StopDataSource(DataSourceInstanceID) override;
    void OnTracingSetup() override;
    void Flush(FlushRequestID,
               const DataSourceInstanceID* data_source_ids,
               size_t num_data_sources,
               FlushFlags) override;

    void ClearIncrementalState(const DataSourceInstanceID* data_source_ids,
                               size_t num_data_sources) override;

    void SendSetupTracing();

    // The interface obtained from the core service business logic through
    // Service::ConnectProducer(this). This allows to invoke methods for a
    // specific Producer on the Service business logic.
    std::unique_ptr<TracingService::ProducerEndpoint> service_endpoint;

    // The back-channel (based on a never ending stream request) that allows us
    // to send asynchronous commands to the remote Producer (e.g. start/stop a
    // data source).
    DeferredGetAsyncCommandResponse async_producer_commands;

    // Set if the service calls OnTracingSetup() before the
    // |async_producer_commands| was bound by the service. In this case, we
    // forward the SetupTracing command when it is bound later.
    bool send_setup_tracing_on_async_commands_bound = false;
  };

  ProducerIPCService(const ProducerIPCService&) = delete;
  ProducerIPCService& operator=(const ProducerIPCService&) = delete;

  // Returns the ProducerEndpoint in the core business logic that corresponds to
  // the current IPC request.
  RemoteProducer* GetProducerForCurrentRequest();

  TracingService* const core_service_;

  // Maps IPC clients to ProducerEndpoint instances registered on the
  // |core_service_| business logic.
  std::map<ipc::ClientID, std::unique_ptr<RemoteProducer>> producers_;

  // List because pointers need to be stable.
  std::list<DeferredSyncResponse> pending_syncs_;

  base::WeakPtrFactory<ProducerIPCService> weak_ptr_factory_;  // Keep last.
};

}  // namespace perfetto

#endif  // SRC_TRACING_IPC_SERVICE_PRODUCER_IPC_SERVICE_H_
/*
 * Copyright (C) 2017 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// gen_amalgamated expanded: #include "src/tracing/ipc/service/producer_ipc_service.h"

#include <cinttypes>

// gen_amalgamated expanded: #include "perfetto/base/logging.h"
// gen_amalgamated expanded: #include "perfetto/base/task_runner.h"
// gen_amalgamated expanded: #include "perfetto/ext/ipc/host.h"
// gen_amalgamated expanded: #include "perfetto/ext/ipc/service.h"
// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/client_identity.h"
// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/commit_data_request.h"
// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/tracing_service.h"
// gen_amalgamated expanded: #include "perfetto/tracing/core/data_source_config.h"
// gen_amalgamated expanded: #include "perfetto/tracing/core/data_source_descriptor.h"

#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
// gen_amalgamated expanded: #include "src/tracing/ipc/shared_memory_windows.h"
#else
// gen_amalgamated expanded: #include "src/tracing/ipc/posix_shared_memory.h"
#endif

// The remote Producer(s) are not trusted. All the methods from the ProducerPort
// IPC layer (e.g. RegisterDataSource()) must assume that the remote Producer is
// compromised.

namespace perfetto {

ProducerIPCService::ProducerIPCService(TracingService* core_service)
    : core_service_(core_service), weak_ptr_factory_(this) {}

ProducerIPCService::~ProducerIPCService() = default;

ProducerIPCService::RemoteProducer*
ProducerIPCService::GetProducerForCurrentRequest() {
  const ipc::ClientID ipc_client_id = ipc::Service::client_info().client_id();
  PERFETTO_CHECK(ipc_client_id);
  auto it = producers_.find(ipc_client_id);
  if (it == producers_.end())
    return nullptr;
  return it->second.get();
}

// Called by the remote Producer through the IPC channel soon after connecting.
void ProducerIPCService::InitializeConnection(
    const protos::gen::InitializeConnectionRequest& req,
    DeferredInitializeConnectionResponse response) {
  const auto& client_info = ipc::Service::client_info();
  const ipc::ClientID ipc_client_id = client_info.client_id();
  PERFETTO_CHECK(ipc_client_id);

  if (producers_.count(ipc_client_id) > 0) {
    PERFETTO_DLOG(
        "The remote Producer is trying to re-initialize the connection");
    return response.Reject();
  }

  // Create a new entry.
  std::unique_ptr<RemoteProducer> producer(new RemoteProducer());

  TracingService::ProducerSMBScrapingMode smb_scraping_mode =
      TracingService::ProducerSMBScrapingMode::kDefault;
  switch (req.smb_scraping_mode()) {
    case protos::gen::InitializeConnectionRequest::SMB_SCRAPING_UNSPECIFIED:
      break;
    case protos::gen::InitializeConnectionRequest::SMB_SCRAPING_DISABLED:
      smb_scraping_mode = TracingService::ProducerSMBScrapingMode::kDisabled;
      break;
    case protos::gen::InitializeConnectionRequest::SMB_SCRAPING_ENABLED:
      smb_scraping_mode = TracingService::ProducerSMBScrapingMode::kEnabled;
      break;
  }

  // If the producer provided an SMB, tell the service to attempt to adopt it.
  std::unique_ptr<SharedMemory> shmem;
  if (req.producer_provided_shmem()) {
#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
    if (!req.has_shm_key_windows() || req.shm_key_windows().empty()) {
      PERFETTO_ELOG(
          "shm_key_windows must be non-empty when "
          "producer_provided_shmem = true");
    } else {
      shmem = SharedMemoryWindows::Attach(req.shm_key_windows());
      // Attach() does error logging if something fails, no need to extra ELOGs.
    }
#else
    base::ScopedFile shmem_fd = ipc::Service::TakeReceivedFD();

    if (shmem_fd) {
      shmem = PosixSharedMemory::AttachToFd(
          std::move(shmem_fd), /*require_seals_if_supported=*/true);
      if (!shmem) {
        PERFETTO_ELOG(
            "Couldn't map producer-provided SMB, falling back to "
            "service-provided SMB");
      }
    } else {
      PERFETTO_DLOG(
          "InitializeConnectionRequest's producer_provided_shmem flag is set "
          "but the producer didn't provide an FD");
    }
#endif
  }

  // Copy the data fields to be emitted to trace packets into ClientIdentity.
  ClientIdentity client_identity(client_info.uid(), client_info.pid(),
                                 client_info.machine_id());
  // ConnectProducer will call OnConnect() on the next task.
  producer->service_endpoint = core_service_->ConnectProducer(
      producer.get(), client_identity, req.producer_name(),
      req.shared_memory_size_hint_bytes(),
      /*in_process=*/false, smb_scraping_mode,
      req.shared_memory_page_size_hint_bytes(), std::move(shmem),
      req.sdk_version());

  // Could happen if the service has too many producers connected.
  if (!producer->service_endpoint) {
    response.Reject();
    return;
  }

  bool use_shmem_emulation = ipc::Service::use_shmem_emulation();
  bool using_producer_shmem =
      !use_shmem_emulation &&
      producer->service_endpoint->IsShmemProvidedByProducer();

  producers_.emplace(ipc_client_id, std::move(producer));
  // Because of the std::move() |producer| is invalid after this point.

  auto async_res =
      ipc::AsyncResult<protos::gen::InitializeConnectionResponse>::Create();
  async_res->set_using_shmem_provided_by_producer(using_producer_shmem);
  async_res->set_direct_smb_patching_supported(true);
  async_res->set_use_shmem_emulation(use_shmem_emulation);
  response.Resolve(std::move(async_res));
}

// Called by the remote Producer through the IPC channel.
void ProducerIPCService::RegisterDataSource(
    const protos::gen::RegisterDataSourceRequest& req,
    DeferredRegisterDataSourceResponse response) {
  RemoteProducer* producer = GetProducerForCurrentRequest();
  if (!producer) {
    PERFETTO_DLOG(
        "Producer invoked RegisterDataSource() before InitializeConnection()");
    if (response.IsBound())
      response.Reject();
    return;
  }

  const DataSourceDescriptor& dsd = req.data_source_descriptor();
  GetProducerForCurrentRequest()->service_endpoint->RegisterDataSource(dsd);

  // RegisterDataSource doesn't expect any meaningful response.
  if (response.IsBound()) {
    response.Resolve(
        ipc::AsyncResult<protos::gen::RegisterDataSourceResponse>::Create());
  }
}

// Called by the remote Producer through the IPC channel.
void ProducerIPCService::UpdateDataSource(
    const protos::gen::UpdateDataSourceRequest& req,
    DeferredUpdateDataSourceResponse response) {
  RemoteProducer* producer = GetProducerForCurrentRequest();
  if (!producer) {
    PERFETTO_DLOG(
        "Producer invoked UpdateDataSource() before InitializeConnection()");
    if (response.IsBound())
      response.Reject();
    return;
  }

  const DataSourceDescriptor& dsd = req.data_source_descriptor();
  GetProducerForCurrentRequest()->service_endpoint->UpdateDataSource(dsd);

  // UpdateDataSource doesn't expect any meaningful response.
  if (response.IsBound()) {
    response.Resolve(
        ipc::AsyncResult<protos::gen::UpdateDataSourceResponse>::Create());
  }
}

// Called by the IPC layer.
void ProducerIPCService::OnClientDisconnected() {
  ipc::ClientID client_id = ipc::Service::client_info().client_id();
  PERFETTO_DLOG("Client %" PRIu64 " disconnected", client_id);
  producers_.erase(client_id);
}

// TODO(fmayer): test what happens if we receive the following tasks, in order:
// RegisterDataSource, UnregisterDataSource, OnDataSourceRegistered.
// which essentially means that the client posted back to back a
// ReqisterDataSource and UnregisterDataSource speculating on the next id.
// Called by the remote Service through the IPC channel.
void ProducerIPCService::UnregisterDataSource(
    const protos::gen::UnregisterDataSourceRequest& req,
    DeferredUnregisterDataSourceResponse response) {
  RemoteProducer* producer = GetProducerForCurrentRequest();
  if (!producer) {
    PERFETTO_DLOG(
        "Producer invoked UnregisterDataSource() before "
        "InitializeConnection()");
    if (response.IsBound())
      response.Reject();
    return;
  }
  producer->service_endpoint->UnregisterDataSource(req.data_source_name());

  // UnregisterDataSource doesn't expect any meaningful response.
  if (response.IsBound()) {
    response.Resolve(
        ipc::AsyncResult<protos::gen::UnregisterDataSourceResponse>::Create());
  }
}

void ProducerIPCService::RegisterTraceWriter(
    const protos::gen::RegisterTraceWriterRequest& req,
    DeferredRegisterTraceWriterResponse response) {
  RemoteProducer* producer = GetProducerForCurrentRequest();
  if (!producer) {
    PERFETTO_DLOG(
        "Producer invoked RegisterTraceWriter() before "
        "InitializeConnection()");
    if (response.IsBound())
      response.Reject();
    return;
  }
  producer->service_endpoint->RegisterTraceWriter(req.trace_writer_id(),
                                                  req.target_buffer());

  // RegisterTraceWriter doesn't expect any meaningful response.
  if (response.IsBound()) {
    response.Resolve(
        ipc::AsyncResult<protos::gen::RegisterTraceWriterResponse>::Create());
  }
}

void ProducerIPCService::UnregisterTraceWriter(
    const protos::gen::UnregisterTraceWriterRequest& req,
    DeferredUnregisterTraceWriterResponse response) {
  RemoteProducer* producer = GetProducerForCurrentRequest();
  if (!producer) {
    PERFETTO_DLOG(
        "Producer invoked UnregisterTraceWriter() before "
        "InitializeConnection()");
    if (response.IsBound())
      response.Reject();
    return;
  }
  producer->service_endpoint->UnregisterTraceWriter(req.trace_writer_id());

  // UnregisterTraceWriter doesn't expect any meaningful response.
  if (response.IsBound()) {
    response.Resolve(
        ipc::AsyncResult<protos::gen::UnregisterTraceWriterResponse>::Create());
  }
}

void ProducerIPCService::CommitData(const protos::gen::CommitDataRequest& req,
                                    DeferredCommitDataResponse resp) {
  RemoteProducer* producer = GetProducerForCurrentRequest();
  if (!producer) {
    PERFETTO_DLOG(
        "Producer invoked CommitData() before InitializeConnection()");
    if (resp.IsBound())
      resp.Reject();
    return;
  }

  // We don't want to send a response if the client didn't attach a callback to
  // the original request. Doing so would generate unnecessary wakeups and
  // context switches.
  std::function<void()> callback;
  if (resp.IsBound()) {
    // Capturing |resp| by reference here speculates on the fact that
    // CommitData() in tracing_service_impl.cc invokes the passed callback
    // inline, without posting it. If that assumption changes this code needs to
    // wrap the response in a shared_ptr (C+11 lambdas don't support move) and
    // use a weak ptr in the caller.
    callback = [&resp] {
      resp.Resolve(ipc::AsyncResult<protos::gen::CommitDataResponse>::Create());
    };
  }
  producer->service_endpoint->CommitData(req, callback);
}

void ProducerIPCService::NotifyDataSourceStarted(
    const protos::gen::NotifyDataSourceStartedRequest& request,
    DeferredNotifyDataSourceStartedResponse response) {
  RemoteProducer* producer = GetProducerForCurrentRequest();
  if (!producer) {
    PERFETTO_DLOG(
        "Producer invoked NotifyDataSourceStarted() before "
        "InitializeConnection()");
    if (response.IsBound())
      response.Reject();
    return;
  }
  producer->service_endpoint->NotifyDataSourceStarted(request.data_source_id());

  // NotifyDataSourceStopped shouldn't expect any meaningful response, avoid
  // a useless IPC in that case.
  if (response.IsBound()) {
    response.Resolve(ipc::AsyncResult<
                     protos::gen::NotifyDataSourceStartedResponse>::Create());
  }
}

void ProducerIPCService::NotifyDataSourceStopped(
    const protos::gen::NotifyDataSourceStoppedRequest& request,
    DeferredNotifyDataSourceStoppedResponse response) {
  RemoteProducer* producer = GetProducerForCurrentRequest();
  if (!producer) {
    PERFETTO_DLOG(
        "Producer invoked NotifyDataSourceStopped() before "
        "InitializeConnection()");
    if (response.IsBound())
      response.Reject();
    return;
  }
  producer->service_endpoint->NotifyDataSourceStopped(request.data_source_id());

  // NotifyDataSourceStopped shouldn't expect any meaningful response, avoid
  // a useless IPC in that case.
  if (response.IsBound()) {
    response.Resolve(ipc::AsyncResult<
                     protos::gen::NotifyDataSourceStoppedResponse>::Create());
  }
}

void ProducerIPCService::ActivateTriggers(
    const protos::gen::ActivateTriggersRequest& proto_req,
    DeferredActivateTriggersResponse resp) {
  RemoteProducer* producer = GetProducerForCurrentRequest();
  if (!producer) {
    PERFETTO_DLOG(
        "Producer invoked ActivateTriggers() before InitializeConnection()");
    if (resp.IsBound())
      resp.Reject();
    return;
  }
  std::vector<std::string> triggers;
  for (const auto& name : proto_req.trigger_names()) {
    triggers.push_back(name);
  }
  producer->service_endpoint->ActivateTriggers(triggers);
  // ActivateTriggers shouldn't expect any meaningful response, avoid
  // a useless IPC in that case.
  if (resp.IsBound()) {
    resp.Resolve(
        ipc::AsyncResult<protos::gen::ActivateTriggersResponse>::Create());
  }
}

void ProducerIPCService::GetAsyncCommand(
    const protos::gen::GetAsyncCommandRequest&,
    DeferredGetAsyncCommandResponse response) {
  RemoteProducer* producer = GetProducerForCurrentRequest();
  if (!producer) {
    PERFETTO_DLOG(
        "Producer invoked GetAsyncCommand() before "
        "InitializeConnection()");
    return response.Reject();
  }
  // Keep the back channel open, without ever resolving the ipc::Deferred fully,
  // to send async commands to the RemoteProducer (e.g., starting/stopping a
  // data source).
  producer->async_producer_commands = std::move(response);

  // Service may already have issued the OnTracingSetup() event, in which case
  // we should forward it to the producer now.
  if (producer->send_setup_tracing_on_async_commands_bound)
    producer->SendSetupTracing();
}

void ProducerIPCService::Sync(const protos::gen::SyncRequest&,
                              DeferredSyncResponse resp) {
  RemoteProducer* producer = GetProducerForCurrentRequest();
  if (!producer) {
    PERFETTO_DLOG("Producer invoked Sync() before InitializeConnection()");
    return resp.Reject();
  }
  auto weak_this = weak_ptr_factory_.GetWeakPtr();
  auto resp_it = pending_syncs_.insert(pending_syncs_.end(), std::move(resp));
  auto callback = [weak_this, resp_it]() {
    if (!weak_this)
      return;
    auto pending_resp = std::move(*resp_it);
    weak_this->pending_syncs_.erase(resp_it);
    pending_resp.Resolve(ipc::AsyncResult<protos::gen::SyncResponse>::Create());
  };
  producer->service_endpoint->Sync(callback);
}

////////////////////////////////////////////////////////////////////////////////
// RemoteProducer methods
////////////////////////////////////////////////////////////////////////////////

ProducerIPCService::RemoteProducer::RemoteProducer() = default;
ProducerIPCService::RemoteProducer::~RemoteProducer() = default;

// Invoked by the |core_service_| business logic after the ConnectProducer()
// call. There is nothing to do here, we really expected the ConnectProducer()
// to just work in the local case.
void ProducerIPCService::RemoteProducer::OnConnect() {}

// Invoked by the |core_service_| business logic after we destroy the
// |service_endpoint| (in the RemoteProducer dtor).
void ProducerIPCService::RemoteProducer::OnDisconnect() {}

// Invoked by the |core_service_| business logic when it wants to create a new
// data source.
void ProducerIPCService::RemoteProducer::SetupDataSource(
    DataSourceInstanceID dsid,
    const DataSourceConfig& cfg) {
  if (!async_producer_commands.IsBound()) {
    PERFETTO_DLOG(
        "The Service tried to create a new data source but the remote Producer "
        "has not yet initialized the connection");
    return;
  }
  auto cmd = ipc::AsyncResult<protos::gen::GetAsyncCommandResponse>::Create();
  cmd.set_has_more(true);
  cmd->mutable_setup_data_source()->set_new_instance_id(dsid);
  *cmd->mutable_setup_data_source()->mutable_config() = cfg;
  async_producer_commands.Resolve(std::move(cmd));
}

// Invoked by the |core_service_| business logic when it wants to start a new
// data source.
void ProducerIPCService::RemoteProducer::StartDataSource(
    DataSourceInstanceID dsid,
    const DataSourceConfig& cfg) {
  if (!async_producer_commands.IsBound()) {
    PERFETTO_DLOG(
        "The Service tried to start a new data source but the remote Producer "
        "has not yet initialized the connection");
    return;
  }
  auto cmd = ipc::AsyncResult<protos::gen::GetAsyncCommandResponse>::Create();
  cmd.set_has_more(true);
  cmd->mutable_start_data_source()->set_new_instance_id(dsid);
  *cmd->mutable_start_data_source()->mutable_config() = cfg;
  async_producer_commands.Resolve(std::move(cmd));
}

void ProducerIPCService::RemoteProducer::StopDataSource(
    DataSourceInstanceID dsid) {
  if (!async_producer_commands.IsBound()) {
    PERFETTO_DLOG(
        "The Service tried to stop a data source but the remote Producer "
        "has not yet initialized the connection");
    return;
  }
  auto cmd = ipc::AsyncResult<protos::gen::GetAsyncCommandResponse>::Create();
  cmd.set_has_more(true);
  cmd->mutable_stop_data_source()->set_instance_id(dsid);
  async_producer_commands.Resolve(std::move(cmd));
}

void ProducerIPCService::RemoteProducer::OnTracingSetup() {
  if (!async_producer_commands.IsBound()) {
    // Service may call this before the producer issued GetAsyncCommand.
    send_setup_tracing_on_async_commands_bound = true;
    return;
  }
  SendSetupTracing();
}

void ProducerIPCService::RemoteProducer::SendSetupTracing() {
  PERFETTO_CHECK(async_producer_commands.IsBound());
  PERFETTO_CHECK(service_endpoint->shared_memory());
  auto cmd = ipc::AsyncResult<protos::gen::GetAsyncCommandResponse>::Create();
  cmd.set_has_more(true);
  auto setup_tracing = cmd->mutable_setup_tracing();
  if (!service_endpoint->IsShmemProvidedByProducer()) {
    // Nominal case (% Chrome): service provides SMB.
    setup_tracing->set_shared_buffer_page_size_kb(
        static_cast<uint32_t>(service_endpoint->shared_buffer_page_size_kb()));
#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
    const std::string& shm_key =
        static_cast<SharedMemoryWindows*>(service_endpoint->shared_memory())
            ->key();
    setup_tracing->set_shm_key_windows(shm_key);
#else
    const int shm_fd =
        static_cast<PosixSharedMemory*>(service_endpoint->shared_memory())
            ->fd();
    cmd.set_fd(shm_fd);
#endif
  }
  async_producer_commands.Resolve(std::move(cmd));
}

void ProducerIPCService::RemoteProducer::Flush(
    FlushRequestID flush_request_id,
    const DataSourceInstanceID* data_source_ids,
    size_t num_data_sources,
    FlushFlags flush_flags) {
  if (!async_producer_commands.IsBound()) {
    PERFETTO_DLOG(
        "The Service tried to request a flush but the remote Producer has not "
        "yet initialized the connection");
    return;
  }
  auto cmd = ipc::AsyncResult<protos::gen::GetAsyncCommandResponse>::Create();
  cmd.set_has_more(true);
  for (size_t i = 0; i < num_data_sources; i++)
    cmd->mutable_flush()->add_data_source_ids(data_source_ids[i]);
  cmd->mutable_flush()->set_request_id(flush_request_id);
  cmd->mutable_flush()->set_flags(flush_flags.flags());
  async_producer_commands.Resolve(std::move(cmd));
}

void ProducerIPCService::RemoteProducer::ClearIncrementalState(
    const DataSourceInstanceID* data_source_ids,
    size_t num_data_sources) {
  if (!async_producer_commands.IsBound()) {
    PERFETTO_DLOG(
        "The Service tried to request an incremental state invalidation, but "
        "the remote Producer has not yet initialized the connection");
    return;
  }
  auto cmd = ipc::AsyncResult<protos::gen::GetAsyncCommandResponse>::Create();
  cmd.set_has_more(true);
  for (size_t i = 0; i < num_data_sources; i++)
    cmd->mutable_clear_incremental_state()->add_data_source_ids(
        data_source_ids[i]);
  async_producer_commands.Resolve(std::move(cmd));
}

}  // namespace perfetto
// gen_amalgamated begin source: src/tracing/ipc/service/relay_ipc_service.cc
// gen_amalgamated begin header: src/tracing/ipc/service/relay_ipc_service.h
/*
 * Copyright (C) 2024 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef SRC_TRACING_IPC_SERVICE_RELAY_IPC_SERVICE_H_
#define SRC_TRACING_IPC_SERVICE_RELAY_IPC_SERVICE_H_

#include <limits>
#include <list>

// gen_amalgamated expanded: #include "perfetto/ext/base/flat_hash_map.h"
// gen_amalgamated expanded: #include "perfetto/ext/base/sys_types.h"
// gen_amalgamated expanded: #include "perfetto/ext/base/weak_ptr.h"
// gen_amalgamated expanded: #include "perfetto/ext/ipc/basic_types.h"
// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/tracing_service.h"

// gen_amalgamated expanded: #include "protos/perfetto/ipc/relay_port.ipc.h"

namespace perfetto {

// Implements the RelayPort IPC service.
class RelayIPCService : public protos::gen::RelayPort {
 public:
  explicit RelayIPCService(TracingService* core_service);
  ~RelayIPCService() override = default;

  void OnClientDisconnected() override;
  void SyncClock(const protos::gen::SyncClockRequest&,
                 DeferredSyncClockResponse) override;

 private:
  TracingService* const core_service_;

  using ClockSnapshots =
      base::FlatHashMap<uint32_t, std::pair<uint64_t, uint64_t>>;
  struct ClockSnapshotRecords {
    base::MachineID machine_id = base::kDefaultMachineID;

    // Keep track of most recent clock snapshots, ordered by local timestamps
    // (CLOCK_BOOTTIME).
    std::list<ClockSnapshots> clock_snapshots;

    uint64_t min_rtt = std::numeric_limits<uint64_t>::max();
  };

  TracingService::RelayEndpoint* GetRelayEndpoint(ipc::ClientID);

  base::FlatHashMap<ipc::ClientID,
                    std::unique_ptr<TracingService::RelayEndpoint>>
      relay_endpoints_;

  base::WeakPtrFactory<RelayIPCService> weak_ptr_factory_;  // Keep last.
};

}  // namespace perfetto

#endif  // SRC_TRACING_IPC_SERVICE_RELAY_IPC_SERVICE_H_
/*
 * Copyright (C) 2024 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// gen_amalgamated expanded: #include "src/tracing/ipc/service/relay_ipc_service.h"

#include <cinttypes>
#include <utility>

// gen_amalgamated expanded: #include "perfetto/base/logging.h"
// gen_amalgamated expanded: #include "perfetto/ext/ipc/service.h"
// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/tracing_service.h"
// gen_amalgamated expanded: #include "perfetto/tracing/core/clock_snapshots.h"
// gen_amalgamated expanded: #include "perfetto/tracing/core/forward_decls.h"

namespace perfetto {

RelayIPCService::RelayIPCService(TracingService* core_service)
    : core_service_(core_service), weak_ptr_factory_(this) {}

TracingService::RelayEndpoint* RelayIPCService::GetRelayEndpoint(
    ipc::ClientID client_id) {
  auto* endpoint = relay_endpoints_.Find(client_id);
  if (!endpoint)
    return nullptr;
  return endpoint->get();
}

void RelayIPCService::OnClientDisconnected() {
  auto client_id = ipc::Service::client_info().client_id();
  PERFETTO_DLOG("Relay endpoint %" PRIu64 "disconnected ", client_id);

  auto* endpoint = GetRelayEndpoint(client_id);
  if (!endpoint)
    return;

  endpoint->Disconnect();
  relay_endpoints_.Erase(client_id);
}

void RelayIPCService::SyncClock(const protos::gen::SyncClockRequest& req,
                                DeferredSyncClockResponse resp) {
  auto host_clock_snapshots = CaptureClockSnapshots();

  // Send the response to client to reduce RTT.
  auto async_resp = ipc::AsyncResult<protos::gen::SyncClockResponse>::Create();
  resp.Resolve(std::move(async_resp));

  ClockSnapshotVector client_clock_snapshots;
  for (size_t i = 0; i < req.clocks().size(); i++) {
    auto& client_clock = req.clocks()[i];
    client_clock_snapshots.emplace_back(client_clock.clock_id(),
                                        client_clock.timestamp());
  }

  // Handle the request in the core service.
  auto machine_id = ipc::Service::client_info().machine_id();
  auto client_id = ipc::Service::client_info().client_id();
  auto* endpoint = GetRelayEndpoint(client_id);
  if (!endpoint) {
    auto ep = core_service_->ConnectRelayClient(
        std::make_pair(machine_id, client_id));
    endpoint = ep.get();
    relay_endpoints_.Insert(client_id, std::move(ep));
  }

  RelayEndpoint::SyncMode mode = req.phase() == SyncClockRequest::PING
                                     ? RelayEndpoint::SyncMode::PING
                                     : RelayEndpoint::SyncMode::UPDATE;
  endpoint->SyncClocks(mode, std::move(client_clock_snapshots),
                       std::move(host_clock_snapshots));
}
}  // namespace perfetto
// gen_amalgamated begin source: src/tracing/ipc/service/service_ipc_host_impl.cc
// gen_amalgamated begin header: src/tracing/ipc/service/service_ipc_host_impl.h
// gen_amalgamated begin header: include/perfetto/ext/tracing/ipc/service_ipc_host.h
/*
 * Copyright (C) 2017 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef INCLUDE_PERFETTO_EXT_TRACING_IPC_SERVICE_IPC_HOST_H_
#define INCLUDE_PERFETTO_EXT_TRACING_IPC_SERVICE_IPC_HOST_H_

#include <memory>

// gen_amalgamated expanded: #include "perfetto/base/export.h"
// gen_amalgamated expanded: #include "perfetto/ext/base/scoped_file.h"
// gen_amalgamated expanded: #include "perfetto/ext/base/unix_socket.h"
// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/basic_types.h"
// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/tracing_service.h"
// gen_amalgamated expanded: #include "perfetto/tracing/default_socket.h"

namespace perfetto {
namespace base {
class TaskRunner;
}  // namespace base.

namespace ipc {
class Host;
}  // namespace ipc

// Creates an instance of the service (business logic + UNIX socket transport).
// Exposed to:
//   The code in the tracing client that will host the service e.g., traced.
// Implemented in:
//   src/tracing/ipc/service/service_ipc_host_impl.cc
class PERFETTO_EXPORT_COMPONENT ServiceIPCHost {
 public:
  static std::unique_ptr<ServiceIPCHost> CreateInstance(
      base::TaskRunner*,
      TracingService::InitOpts = {});
  virtual ~ServiceIPCHost();

  // The overload to wrap the multi-value producer socket name in the
  // single-value variant for compatibility in tests.
  bool Start(const char* producer_socket_name,
             const char* consumer_socket_name) {
    return Start(TokenizeProducerSockets(producer_socket_name),
                 consumer_socket_name);
  }
  // Start listening on the Producer & Consumer ports. Returns false in case of
  // failure (e.g., something else is listening on |socket_name|).
  virtual bool Start(const std::vector<std::string>& producer_socket_names,
                     const char* consumer_socket_name) = 0;

  // Like the above, but takes two file descriptors to already bound sockets.
  // This is used when building as part of the Android tree, where init opens
  // and binds the socket beore exec()-ing us.
  virtual bool Start(base::ScopedSocketHandle producer_socket_fd,
                     base::ScopedSocketHandle consumer_socket_fd) = 0;

  // Allows callers to supply preconstructed Hosts.
  virtual bool Start(std::unique_ptr<ipc::Host> producer_host,
                     std::unique_ptr<ipc::Host> consumer_host) = 0;

  virtual TracingService* service() const = 0;

 protected:
  ServiceIPCHost();

 private:
  ServiceIPCHost(const ServiceIPCHost&) = delete;
  ServiceIPCHost& operator=(const ServiceIPCHost&) = delete;
};

}  // namespace perfetto

#endif  // INCLUDE_PERFETTO_EXT_TRACING_IPC_SERVICE_IPC_HOST_H_
/*
 * Copyright (C) 2017 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef SRC_TRACING_IPC_SERVICE_SERVICE_IPC_HOST_IMPL_H_
#define SRC_TRACING_IPC_SERVICE_SERVICE_IPC_HOST_IMPL_H_

#include <memory>

// gen_amalgamated expanded: #include "perfetto/ext/tracing/ipc/service_ipc_host.h"

namespace perfetto {

namespace ipc {
class Host;
}

// The implementation of the IPC host for the tracing service. This class does
// very few things: it mostly initializes the IPC transport. The actual
// implementation of the IPC <> Service business logic glue lives in
// producer_ipc_service.cc and consumer_ipc_service.cc.
class ServiceIPCHostImpl : public ServiceIPCHost {
 public:
  explicit ServiceIPCHostImpl(base::TaskRunner*,
                              TracingService::InitOpts init_opts = {});
  ~ServiceIPCHostImpl() override;

  // ServiceIPCHost implementation.
  bool Start(const std::vector<std::string>& producer_socket_names,
             const char* consumer_socket_name) override;
  bool Start(base::ScopedSocketHandle producer_socket_fd,
             base::ScopedSocketHandle consumer_socket_fd) override;
  bool Start(std::unique_ptr<ipc::Host> producer_host,
             std::unique_ptr<ipc::Host> consumer_host) override;

  TracingService* service() const override;

 private:
  bool DoStart();
  void Shutdown();

  base::TaskRunner* const task_runner_;
  const TracingService::InitOpts init_opts_;
  std::unique_ptr<TracingService> svc_;  // The service business logic.

  // The IPC hosts that listen on the Producer sockets. They own the
  // PosixServiceProducerPort instances which deal with all producers' IPC(s).
  // Note that there can be multiple producer sockets if it's specified in the
  // producer socket name (e.g. for listening both on vsock for VMs and AF_UNIX
  // for processes on the same machine).
  std::vector<std::unique_ptr<ipc::Host>> producer_ipc_ports_;

  // As above, but for the Consumer port.
  std::unique_ptr<ipc::Host> consumer_ipc_port_;
};

}  // namespace perfetto

#endif  // SRC_TRACING_IPC_SERVICE_SERVICE_IPC_HOST_IMPL_H_
/*
 * Copyright (C) 2017 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// gen_amalgamated expanded: #include "src/tracing/ipc/service/service_ipc_host_impl.h"

// gen_amalgamated expanded: #include "perfetto/base/logging.h"
// gen_amalgamated expanded: #include "perfetto/base/task_runner.h"
// gen_amalgamated expanded: #include "perfetto/ext/ipc/host.h"
// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/tracing_service.h"
// gen_amalgamated expanded: #include "src/tracing/ipc/service/consumer_ipc_service.h"
// gen_amalgamated expanded: #include "src/tracing/ipc/service/producer_ipc_service.h"
// gen_amalgamated expanded: #include "src/tracing/ipc/service/relay_ipc_service.h"

#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
// gen_amalgamated expanded: #include "src/tracing/ipc/shared_memory_windows.h"
#else
// gen_amalgamated expanded: #include "src/tracing/ipc/posix_shared_memory.h"
#endif

namespace perfetto {

namespace {
constexpr uint32_t kProducerSocketTxTimeoutMs = 10;
}

// TODO(fmayer): implement per-uid connection limit (b/69093705).

// Implements the publicly exposed factory method declared in
// include/tracing/posix_ipc/posix_service_host.h.
std::unique_ptr<ServiceIPCHost> ServiceIPCHost::CreateInstance(
    base::TaskRunner* task_runner,
    TracingService::InitOpts init_opts) {
  return std::unique_ptr<ServiceIPCHost>(
      new ServiceIPCHostImpl(task_runner, init_opts));
}

ServiceIPCHostImpl::ServiceIPCHostImpl(base::TaskRunner* task_runner,
                                       TracingService::InitOpts init_opts)
    : task_runner_(task_runner), init_opts_(init_opts) {}

ServiceIPCHostImpl::~ServiceIPCHostImpl() {}

bool ServiceIPCHostImpl::Start(
    const std::vector<std::string>& producer_socket_names,
    const char* consumer_socket_name) {
  PERFETTO_CHECK(!svc_);  // Check if already started.

  // Initialize the IPC transport.
  for (const auto& producer_socket_name : producer_socket_names)
    producer_ipc_ports_.emplace_back(
        ipc::Host::CreateInstance(producer_socket_name.c_str(), task_runner_));
  consumer_ipc_port_ =
      ipc::Host::CreateInstance(consumer_socket_name, task_runner_);
  return DoStart();
}

bool ServiceIPCHostImpl::Start(base::ScopedSocketHandle producer_socket_fd,
                               base::ScopedSocketHandle consumer_socket_fd) {
  PERFETTO_CHECK(!svc_);  // Check if already started.

  // Initialize the IPC transport.
  producer_ipc_ports_.emplace_back(
      ipc::Host::CreateInstance(std::move(producer_socket_fd), task_runner_));
  consumer_ipc_port_ =
      ipc::Host::CreateInstance(std::move(consumer_socket_fd), task_runner_);
  return DoStart();
}

bool ServiceIPCHostImpl::Start(std::unique_ptr<ipc::Host> producer_host,
                               std::unique_ptr<ipc::Host> consumer_host) {
  PERFETTO_CHECK(!svc_);  // Check if already started.
  PERFETTO_DCHECK(producer_host);
  PERFETTO_DCHECK(consumer_host);

  // Initialize the IPC transport.
  producer_ipc_ports_.emplace_back(std::move(producer_host));
  consumer_ipc_port_ = std::move(consumer_host);

  return DoStart();
}

bool ServiceIPCHostImpl::DoStart() {
  // Create and initialize the platform-independent tracing business logic.
#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
  std::unique_ptr<SharedMemory::Factory> shm_factory(
      new SharedMemoryWindows::Factory());
#else
  std::unique_ptr<SharedMemory::Factory> shm_factory(
      new PosixSharedMemory::Factory());
#endif
  svc_ = TracingService::CreateInstance(std::move(shm_factory), task_runner_,
                                        init_opts_);

  if (producer_ipc_ports_.empty() || !consumer_ipc_port_) {
    Shutdown();
    return false;
  }

  // Lower the timeout for blocking socket sends to producers as we shouldn't
  // normally exhaust the kernel send buffer unless the producer is
  // unresponsive. We'll drop the connection if the timeout is hit (see
  // UnixSocket::Send). Context in b/236813972, b/193234818.
  // Consumer port continues using the default timeout (10s) as there are
  // generally fewer consumer processes, and they're better behaved. Also the
  // consumer port ipcs might exhaust the send buffer under normal operation
  // due to large messages such as ReadBuffersResponse.
  for (auto& producer_ipc_port : producer_ipc_ports_)
    producer_ipc_port->SetSocketSendTimeoutMs(kProducerSocketTxTimeoutMs);

  // TODO(fmayer): add a test that destroyes the ServiceIPCHostImpl soon after
  // Start() and checks that no spurious callbacks are issued.
  for (auto& producer_ipc_port : producer_ipc_ports_) {
    bool producer_service_exposed = producer_ipc_port->ExposeService(
        std::unique_ptr<ipc::Service>(new ProducerIPCService(svc_.get())));
    PERFETTO_CHECK(producer_service_exposed);

    if (!init_opts_.enable_relay_endpoint)
      continue;
    // Expose a secondary service for sync with remote relay service
    // if requested.
    bool relay_service_exposed = producer_ipc_port->ExposeService(
        std::unique_ptr<ipc::Service>(new RelayIPCService(svc_.get())));
    PERFETTO_CHECK(relay_service_exposed);
  }

  bool consumer_service_exposed = consumer_ipc_port_->ExposeService(
      std::unique_ptr<ipc::Service>(new ConsumerIPCService(svc_.get())));
  PERFETTO_CHECK(consumer_service_exposed);

  return true;
}

TracingService* ServiceIPCHostImpl::service() const {
  return svc_.get();
}

void ServiceIPCHostImpl::Shutdown() {
  // TODO(primiano): add a test that causes the Shutdown() and checks that no
  // spurious callbacks are issued.
  producer_ipc_ports_.clear();
  consumer_ipc_port_.reset();
  svc_.reset();
}

// Definitions for the base class ctor/dtor.
ServiceIPCHost::ServiceIPCHost() = default;
ServiceIPCHost::~ServiceIPCHost() = default;

}  // namespace perfetto
// gen_amalgamated begin source: src/tracing/internal/system_tracing_backend.cc
/*
 * Copyright (C) 2019 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// gen_amalgamated expanded: #include "perfetto/tracing/internal/system_tracing_backend.h"

// gen_amalgamated expanded: #include "perfetto/base/logging.h"
// gen_amalgamated expanded: #include "perfetto/base/task_runner.h"
// gen_amalgamated expanded: #include "perfetto/ext/tracing/core/tracing_service.h"
// gen_amalgamated expanded: #include "perfetto/ext/tracing/ipc/producer_ipc_client.h"
// gen_amalgamated expanded: #include "perfetto/tracing/default_socket.h"

#if PERFETTO_BUILDFLAG(PERFETTO_SYSTEM_CONSUMER)
// gen_amalgamated expanded: #include "perfetto/ext/tracing/ipc/consumer_ipc_client.h"
#endif

#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
// gen_amalgamated expanded: #include "src/tracing/ipc/shared_memory_windows.h"
#else
// gen_amalgamated expanded: #include "src/tracing/ipc/posix_shared_memory.h"
#endif

namespace perfetto {
namespace internal {

// static
TracingProducerBackend* SystemProducerTracingBackend::GetInstance() {
  static auto* instance = new SystemProducerTracingBackend();
  return instance;
}

SystemProducerTracingBackend::SystemProducerTracingBackend() {}

std::unique_ptr<ProducerEndpoint> SystemProducerTracingBackend::ConnectProducer(
    const ConnectProducerArgs& args) {
  PERFETTO_DCHECK(args.task_runner->RunsTasksOnCurrentThread());

  std::unique_ptr<SharedMemory> shm;
  std::unique_ptr<SharedMemoryArbiter> arbiter;
  uint32_t shmem_size_hint = args.shmem_size_hint_bytes;
  uint32_t shmem_page_size_hint = args.shmem_page_size_hint_bytes;
  if (args.use_producer_provided_smb) {
    if (shmem_size_hint == 0)
      shmem_size_hint = TracingService::kDefaultShmSize;
    if (shmem_page_size_hint == 0)
      shmem_page_size_hint = TracingService::kDefaultShmPageSize;
#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
    shm = SharedMemoryWindows::Create(shmem_size_hint);
#else
    shm = PosixSharedMemory::Create(shmem_size_hint);
#endif
    arbiter = SharedMemoryArbiter::CreateUnboundInstance(
        shm.get(), shmem_page_size_hint, SharedMemoryABI::ShmemMode::kDefault);
  }

  ipc::Client::ConnArgs conn_args(GetProducerSocket(), true);
  auto endpoint = ProducerIPCClient::Connect(
      std::move(conn_args), args.producer, args.producer_name, args.task_runner,
      TracingService::ProducerSMBScrapingMode::kEnabled, shmem_size_hint,
      shmem_page_size_hint, std::move(shm), std::move(arbiter),
      args.create_socket_async);
  PERFETTO_CHECK(endpoint);
  return endpoint;
}

// static
TracingConsumerBackend* SystemConsumerTracingBackend::GetInstance() {
  static auto* instance = new SystemConsumerTracingBackend();
  return instance;
}

SystemConsumerTracingBackend::SystemConsumerTracingBackend() {}

std::unique_ptr<ConsumerEndpoint> SystemConsumerTracingBackend::ConnectConsumer(
    const ConnectConsumerArgs& args) {
#if PERFETTO_BUILDFLAG(PERFETTO_SYSTEM_CONSUMER)
  auto endpoint = ConsumerIPCClient::Connect(GetConsumerSocket(), args.consumer,
                                             args.task_runner);
  PERFETTO_CHECK(endpoint);
  return endpoint;
#else
  base::ignore_result(args);
  PERFETTO_FATAL("System backend consumer support disabled");
  return nullptr;
#endif
}

}  // namespace internal
}  // namespace perfetto
// gen_amalgamated begin source: src/tracing/platform_posix.cc
/*
 * Copyright (C) 2019 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// gen_amalgamated expanded: #include "perfetto/base/build_config.h"

#if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) ||   \
    PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID) || \
    PERFETTO_BUILDFLAG(PERFETTO_OS_FUCHSIA) || \
    PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)

// gen_amalgamated expanded: #include "perfetto/ext/base/file_utils.h"
// gen_amalgamated expanded: #include "perfetto/ext/base/thread_task_runner.h"
// gen_amalgamated expanded: #include "perfetto/tracing/internal/tracing_tls.h"
// gen_amalgamated expanded: #include "perfetto/tracing/platform.h"
// gen_amalgamated expanded: #include "perfetto/tracing/trace_writer_base.h"

#include <pthread.h>
#include <stdlib.h>

namespace perfetto {

namespace {

class PlatformPosix : public Platform {
 public:
  PlatformPosix();
  ~PlatformPosix() override;

  ThreadLocalObject* GetOrCreateThreadLocalObject() override;

  std::unique_ptr<base::TaskRunner> CreateTaskRunner(
      const CreateTaskRunnerArgs&) override;
  std::string GetCurrentProcessName() override;
  void Shutdown() override;

 private:
  pthread_key_t tls_key_{};
};

PlatformPosix* g_instance = nullptr;

using ThreadLocalObject = Platform::ThreadLocalObject;

PlatformPosix::PlatformPosix() {
  PERFETTO_CHECK(!g_instance);
  g_instance = this;
  auto tls_dtor = [](void* obj) {
    // The Posix TLS implementation resets the key before calling this dtor.
    // Here we re-reset it to the object we are about to delete. This is to
    // handle re-entrant usages of tracing in the PostTask done during the dtor
    // (see comments in TracingTLS::~TracingTLS()). Chromium's platform
    // implementation (which does NOT use this platform impl) has a similar
    // workaround (https://crrev.com/c/2748300).
    pthread_setspecific(g_instance->tls_key_, obj);
    delete static_cast<ThreadLocalObject*>(obj);
    pthread_setspecific(g_instance->tls_key_, nullptr);
  };
  PERFETTO_CHECK(pthread_key_create(&tls_key_, tls_dtor) == 0);
}

PlatformPosix::~PlatformPosix() {
  // pthread_key_delete doesn't call destructors, so do it manually for the
  // calling thread.
  void* tls_ptr = pthread_getspecific(tls_key_);
  delete static_cast<ThreadLocalObject*>(tls_ptr);

  pthread_key_delete(tls_key_);
  g_instance = nullptr;
}

void PlatformPosix::Shutdown() {
  PERFETTO_CHECK(g_instance == this);
  delete this;
  PERFETTO_CHECK(!g_instance);
  // We're not clearing out the instance in GetDefaultPlatform() since it's not
  // possible to re-initialize Perfetto after calling this function anyway.
}

ThreadLocalObject* PlatformPosix::GetOrCreateThreadLocalObject() {
  // In chromium this should be implemented using base::ThreadLocalStorage.
  void* tls_ptr = pthread_getspecific(tls_key_);

  // This is needed to handle re-entrant calls during TLS dtor.
  // See comments in platform.cc and aosp/1712371 .
  ThreadLocalObject* tls = static_cast<ThreadLocalObject*>(tls_ptr);
  if (!tls) {
    tls = ThreadLocalObject::CreateInstance().release();
    pthread_setspecific(tls_key_, tls);
  }
  return tls;
}

std::unique_ptr<base::TaskRunner> PlatformPosix::CreateTaskRunner(
    const CreateTaskRunnerArgs& args) {
  return std::unique_ptr<base::TaskRunner>(new base::ThreadTaskRunner(
      base::ThreadTaskRunner::CreateAndStart(args.name_for_debugging)));
}

std::string PlatformPosix::GetCurrentProcessName() {
#if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
    PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
  std::string cmdline;
  base::ReadFile("/proc/self/cmdline", &cmdline);
  return cmdline.substr(0, cmdline.find('\0'));
#elif PERFETTO_BUILDFLAG(PERFETTO_OS_APPLE)
  return std::string(getprogname());
#else
  return "unknown_producer";
#endif
}

}  // namespace

// static
Platform* Platform::GetDefaultPlatform() {
  static PlatformPosix* instance = new PlatformPosix();
  return instance;
}

}  // namespace perfetto
#endif  // OS_LINUX || OS_ANDROID || OS_APPLE || OS_FUCHSIA
// gen_amalgamated begin source: src/tracing/platform_windows.cc
/*
 * Copyright (C) 2021 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// gen_amalgamated expanded: #include "perfetto/base/build_config.h"

#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)

#include <Windows.h>

// gen_amalgamated expanded: #include "perfetto/ext/base/thread_task_runner.h"
// gen_amalgamated expanded: #include "perfetto/tracing/internal/tracing_tls.h"
// gen_amalgamated expanded: #include "perfetto/tracing/platform.h"

// Thread Termination Callbacks.
// Windows doesn't support a per-thread destructor with its
// TLS primitives. So, we build it manually by inserting a
// function to be called on each thread's exit.
// This magic is from chromium's base/threading/thread_local_storage_win.cc
// which in turn is from http://www.codeproject.com/threads/tls.asp.

#ifdef _WIN64
#pragma comment(linker, "/INCLUDE:_tls_used")
#pragma comment(linker, "/INCLUDE:perfetto_thread_callback_base")
#else
#pragma comment(linker, "/INCLUDE:__tls_used")
#pragma comment(linker, "/INCLUDE:_perfetto_thread_callback_base")
#endif

namespace perfetto {

namespace {

class PlatformWindows : public Platform {
 public:
  static PlatformWindows* instance;
  PlatformWindows();
  ~PlatformWindows() override;

  ThreadLocalObject* GetOrCreateThreadLocalObject() override;
  std::unique_ptr<base::TaskRunner> CreateTaskRunner(
      const CreateTaskRunnerArgs&) override;
  std::string GetCurrentProcessName() override;
  void OnThreadExit();

 private:
  DWORD tls_key_{};
};

using ThreadLocalObject = Platform::ThreadLocalObject;

// static
PlatformWindows* PlatformWindows::instance = nullptr;

PlatformWindows::PlatformWindows() {
  instance = this;
  tls_key_ = ::TlsAlloc();
  PERFETTO_CHECK(tls_key_ != TLS_OUT_OF_INDEXES);
}

PlatformWindows::~PlatformWindows() {
  ::TlsFree(tls_key_);
  instance = nullptr;
}

void PlatformWindows::OnThreadExit() {
  auto tls = static_cast<ThreadLocalObject*>(::TlsGetValue(tls_key_));
  if (tls) {
    // At this point we rely on the TLS object to be still set to the TracingTLS
    // we are deleting. See comments in TracingTLS::~TracingTLS().
    delete tls;
  }
}

ThreadLocalObject* PlatformWindows::GetOrCreateThreadLocalObject() {
  void* tls_ptr = ::TlsGetValue(tls_key_);

  auto* tls = static_cast<ThreadLocalObject*>(tls_ptr);
  if (!tls) {
    tls = ThreadLocalObject::CreateInstance().release();
    ::TlsSetValue(tls_key_, tls);
  }
  return tls;
}

std::unique_ptr<base::TaskRunner> PlatformWindows::CreateTaskRunner(
    const CreateTaskRunnerArgs& args) {
  return std::unique_ptr<base::TaskRunner>(new base::ThreadTaskRunner(
      base::ThreadTaskRunner::CreateAndStart(args.name_for_debugging)));
}

std::string PlatformWindows::GetCurrentProcessName() {
  char buf[MAX_PATH];
  auto len = ::GetModuleFileNameA(nullptr /*current*/, buf, sizeof(buf));
  std::string name(buf, static_cast<size_t>(len));
  size_t sep = name.find_last_of('\\');
  if (sep != std::string::npos)
    name = name.substr(sep + 1);
  return name;
}

}  // namespace

// static
Platform* Platform::GetDefaultPlatform() {
  static PlatformWindows* thread_safe_init_instance = new PlatformWindows();
  return thread_safe_init_instance;
}

}  // namespace perfetto

// -----------------------
// Thread-local destructor
// -----------------------

// .CRT$XLA to .CRT$XLZ is an array of PIMAGE_TLS_CALLBACK pointers that are
// called automatically by the OS loader code (not the CRT) when the module is
// loaded and on thread creation. They are NOT called if the module has been
// loaded by a LoadLibrary() call. It must have implicitly been loaded at
// process startup.
// See VC\crt\src\tlssup.c for reference.

// extern "C" suppresses C++ name mangling so we know the symbol name for the
// linker /INCLUDE:symbol pragma above.
extern "C" {
// The linker must not discard perfetto_thread_callback_base. (We force a
// reference to this variable with a linker /INCLUDE:symbol pragma to ensure
// that.) If this variable is discarded, the OnThreadExit function will never be
// called.

void NTAPI PerfettoOnThreadExit(PVOID, DWORD, PVOID);
void NTAPI PerfettoOnThreadExit(PVOID, DWORD reason, PVOID) {
  if (reason == DLL_THREAD_DETACH || reason == DLL_PROCESS_DETACH) {
    if (perfetto::PlatformWindows::instance)
      perfetto::PlatformWindows::instance->OnThreadExit();
  }
}

#ifdef _WIN64

// .CRT section is merged with .rdata on x64 so it must be constant data.
#pragma const_seg(".CRT$XLP")

// When defining a const variable, it must have external linkage to be sure the
// linker doesn't discard it.
extern const PIMAGE_TLS_CALLBACK perfetto_thread_callback_base;
const PIMAGE_TLS_CALLBACK perfetto_thread_callback_base = PerfettoOnThreadExit;

// Reset the default section.
#pragma const_seg()

#else  // _WIN64

#pragma data_seg(".CRT$XLP")
PIMAGE_TLS_CALLBACK perfetto_thread_callback_base = PerfettoOnThreadExit;
// Reset the default section.
#pragma data_seg()

#endif  // _WIN64

}  // extern "C"

#endif  // OS_WIN

