perfetto: Move FtraceConfig to own file

Bug: 73231296
Change-Id: I547865ef6c5f7a365f54acece2142063191d95a1
diff --git a/Android.bp b/Android.bp
index 84c80ea..c4fa5a6 100644
--- a/Android.bp
+++ b/Android.bp
@@ -56,6 +56,7 @@
     "src/traced/service/service.cc",
     "src/tracing/core/data_source_config.cc",
     "src/tracing/core/data_source_descriptor.cc",
+    "src/tracing/core/ftrace_config.cc",
     "src/tracing/core/id_allocator.cc",
     "src/tracing/core/packet_stream_validator.cc",
     "src/tracing/core/service_impl.cc",
@@ -126,6 +127,7 @@
     "src/traced/perfetto_cmd/perfetto_cmd.cc",
     "src/tracing/core/data_source_config.cc",
     "src/tracing/core/data_source_descriptor.cc",
+    "src/tracing/core/ftrace_config.cc",
     "src/tracing/core/id_allocator.cc",
     "src/tracing/core/packet_stream_validator.cc",
     "src/tracing/core/service_impl.cc",
@@ -238,6 +240,7 @@
     "src/traced/probes/probes_producer.cc",
     "src/tracing/core/data_source_config.cc",
     "src/tracing/core/data_source_descriptor.cc",
+    "src/tracing/core/ftrace_config.cc",
     "src/tracing/core/id_allocator.cc",
     "src/tracing/core/packet_stream_validator.cc",
     "src/tracing/core/service_impl.cc",
@@ -294,6 +297,7 @@
   srcs: [
     "protos/perfetto/config/data_source_config.proto",
     "protos/perfetto/config/data_source_descriptor.proto",
+    "protos/perfetto/config/ftrace/ftrace_config.proto",
     "protos/perfetto/config/trace_config.proto",
   ],
   tools: [
@@ -303,6 +307,7 @@
   out: [
     "external/perfetto/protos/perfetto/config/data_source_config.pb.cc",
     "external/perfetto/protos/perfetto/config/data_source_descriptor.pb.cc",
+    "external/perfetto/protos/perfetto/config/ftrace/ftrace_config.pb.cc",
     "external/perfetto/protos/perfetto/config/trace_config.pb.cc",
   ],
 }
@@ -313,6 +318,7 @@
   srcs: [
     "protos/perfetto/config/data_source_config.proto",
     "protos/perfetto/config/data_source_descriptor.proto",
+    "protos/perfetto/config/ftrace/ftrace_config.proto",
     "protos/perfetto/config/trace_config.proto",
   ],
   tools: [
@@ -322,6 +328,7 @@
   out: [
     "external/perfetto/protos/perfetto/config/data_source_config.pb.h",
     "external/perfetto/protos/perfetto/config/data_source_descriptor.pb.h",
+    "external/perfetto/protos/perfetto/config/ftrace/ftrace_config.pb.h",
     "external/perfetto/protos/perfetto/config/trace_config.pb.h",
   ],
   export_include_dirs: [
@@ -1821,6 +1828,7 @@
     "src/protozero/scattered_stream_writer.cc",
     "src/tracing/core/data_source_config.cc",
     "src/tracing/core/data_source_descriptor.cc",
+    "src/tracing/core/ftrace_config.cc",
     "src/tracing/core/id_allocator.cc",
     "src/tracing/core/packet_stream_validator.cc",
     "src/tracing/core/service_impl.cc",
@@ -1951,6 +1959,7 @@
     "src/protozero/test/protozero_conformance_unittest.cc",
     "src/tracing/core/data_source_config.cc",
     "src/tracing/core/data_source_descriptor.cc",
+    "src/tracing/core/ftrace_config.cc",
     "src/tracing/core/id_allocator.cc",
     "src/tracing/core/id_allocator_unittest.cc",
     "src/tracing/core/packet_stream_validator.cc",
diff --git a/include/perfetto/ftrace_reader/ftrace_config.h b/include/perfetto/ftrace_reader/ftrace_config.h
index a0b78f6..201cd8f 100644
--- a/include/perfetto/ftrace_reader/ftrace_config.h
+++ b/include/perfetto/ftrace_reader/ftrace_config.h
@@ -20,13 +20,10 @@
 #include <set>
 #include <string>
 
-#include "perfetto/tracing/core/data_source_config.h"
+#include "perfetto/tracing/core/ftrace_config.h"
 
 namespace perfetto {
 
-// Alias FtraceConfig to avoid unnecessary typing.
-using FtraceConfig = DataSourceConfig::FtraceConfig;
-
 // Utility method for the common case where we don't care about atrace events.
 FtraceConfig CreateFtraceConfig(std::set<std::string> names);
 
diff --git a/include/perfetto/tracing/core/data_source_config.h b/include/perfetto/tracing/core/data_source_config.h
index b31133e..4f1c712 100644
--- a/include/perfetto/tracing/core/data_source_config.h
+++ b/include/perfetto/tracing/core/data_source_config.h
@@ -33,11 +33,13 @@
 #include <type_traits>
 #include <vector>
 
+#include "perfetto/tracing/core/ftrace_config.h"
+
 // Forward declarations for protobuf types.
 namespace perfetto {
 namespace protos {
 class DataSourceConfig;
-class DataSourceConfig_FtraceConfig;
+class FtraceConfig;
 }  // namespace protos
 }  // namespace perfetto
 
@@ -45,66 +47,6 @@
 
 class DataSourceConfig {
  public:
-  class FtraceConfig {
-   public:
-    FtraceConfig();
-    ~FtraceConfig();
-    FtraceConfig(FtraceConfig&&) noexcept;
-    FtraceConfig& operator=(FtraceConfig&&);
-    FtraceConfig(const FtraceConfig&);
-    FtraceConfig& operator=(const FtraceConfig&);
-
-    // Conversion methods from/to the corresponding protobuf types.
-    void FromProto(const perfetto::protos::DataSourceConfig_FtraceConfig&);
-    void ToProto(perfetto::protos::DataSourceConfig_FtraceConfig*) const;
-
-    int event_names_size() const {
-      return static_cast<int>(event_names_.size());
-    }
-    const std::vector<std::string>& event_names() const { return event_names_; }
-    std::string* add_event_names() {
-      event_names_.emplace_back();
-      return &event_names_.back();
-    }
-
-    int atrace_categories_size() const {
-      return static_cast<int>(atrace_categories_.size());
-    }
-    const std::vector<std::string>& atrace_categories() const {
-      return atrace_categories_;
-    }
-    std::string* add_atrace_categories() {
-      atrace_categories_.emplace_back();
-      return &atrace_categories_.back();
-    }
-
-    int atrace_apps_size() const {
-      return static_cast<int>(atrace_apps_.size());
-    }
-    const std::vector<std::string>& atrace_apps() const { return atrace_apps_; }
-    std::string* add_atrace_apps() {
-      atrace_apps_.emplace_back();
-      return &atrace_apps_.back();
-    }
-
-    uint32_t buffer_size_kb() const { return buffer_size_kb_; }
-    void set_buffer_size_kb(uint32_t value) { buffer_size_kb_ = value; }
-
-    uint32_t drain_period_ms() const { return drain_period_ms_; }
-    void set_drain_period_ms(uint32_t value) { drain_period_ms_ = value; }
-
-   private:
-    std::vector<std::string> event_names_;
-    std::vector<std::string> atrace_categories_;
-    std::vector<std::string> atrace_apps_;
-    uint32_t buffer_size_kb_ = {};
-    uint32_t drain_period_ms_ = {};
-
-    // Allows to preserve unknown protobuf fields for compatibility
-    // with future versions of .proto files.
-    std::string unknown_fields_;
-  };
-
   DataSourceConfig();
   ~DataSourceConfig();
   DataSourceConfig(DataSourceConfig&&) noexcept;
diff --git a/include/perfetto/tracing/core/ftrace_config.h b/include/perfetto/tracing/core/ftrace_config.h
new file mode 100644
index 0000000..ac38f71
--- /dev/null
+++ b/include/perfetto/tracing/core/ftrace_config.h
@@ -0,0 +1,102 @@
+/*
+ * 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.
+ */
+
+/*******************************************************************************
+ * AUTOGENERATED - DO NOT EDIT
+ *******************************************************************************
+ * This file has been generated from the protobuf message
+ * perfetto/config/ftrace/ftrace_config.proto
+ * by
+ * ../../tools/proto_to_cpp/proto_to_cpp.cc.
+ * If you need to make changes here, change the .proto file and then run
+ * ./tools/gen_tracing_cpp_headers_from_protos.py
+ */
+
+#ifndef INCLUDE_PERFETTO_TRACING_CORE_FTRACE_CONFIG_H_
+#define INCLUDE_PERFETTO_TRACING_CORE_FTRACE_CONFIG_H_
+
+#include <stdint.h>
+#include <string>
+#include <type_traits>
+#include <vector>
+
+// Forward declarations for protobuf types.
+namespace perfetto {
+namespace protos {
+class FtraceConfig;
+}
+}  // namespace perfetto
+
+namespace perfetto {
+
+class FtraceConfig {
+ public:
+  FtraceConfig();
+  ~FtraceConfig();
+  FtraceConfig(FtraceConfig&&) noexcept;
+  FtraceConfig& operator=(FtraceConfig&&);
+  FtraceConfig(const FtraceConfig&);
+  FtraceConfig& operator=(const FtraceConfig&);
+
+  // Conversion methods from/to the corresponding protobuf types.
+  void FromProto(const perfetto::protos::FtraceConfig&);
+  void ToProto(perfetto::protos::FtraceConfig*) const;
+
+  int event_names_size() const { return static_cast<int>(event_names_.size()); }
+  const std::vector<std::string>& event_names() const { return event_names_; }
+  std::string* add_event_names() {
+    event_names_.emplace_back();
+    return &event_names_.back();
+  }
+
+  int atrace_categories_size() const {
+    return static_cast<int>(atrace_categories_.size());
+  }
+  const std::vector<std::string>& atrace_categories() const {
+    return atrace_categories_;
+  }
+  std::string* add_atrace_categories() {
+    atrace_categories_.emplace_back();
+    return &atrace_categories_.back();
+  }
+
+  int atrace_apps_size() const { return static_cast<int>(atrace_apps_.size()); }
+  const std::vector<std::string>& atrace_apps() const { return atrace_apps_; }
+  std::string* add_atrace_apps() {
+    atrace_apps_.emplace_back();
+    return &atrace_apps_.back();
+  }
+
+  uint32_t buffer_size_kb() const { return buffer_size_kb_; }
+  void set_buffer_size_kb(uint32_t value) { buffer_size_kb_ = value; }
+
+  uint32_t drain_period_ms() const { return drain_period_ms_; }
+  void set_drain_period_ms(uint32_t value) { drain_period_ms_ = value; }
+
+ private:
+  std::vector<std::string> event_names_;
+  std::vector<std::string> atrace_categories_;
+  std::vector<std::string> atrace_apps_;
+  uint32_t buffer_size_kb_ = {};
+  uint32_t drain_period_ms_ = {};
+
+  // Allows to preserve unknown protobuf fields for compatibility
+  // with future versions of .proto files.
+  std::string unknown_fields_;
+};
+
+}  // namespace perfetto
+#endif  // INCLUDE_PERFETTO_TRACING_CORE_FTRACE_CONFIG_H_
diff --git a/include/perfetto/tracing/core/trace_config.h b/include/perfetto/tracing/core/trace_config.h
index de28d21..e57f728 100644
--- a/include/perfetto/tracing/core/trace_config.h
+++ b/include/perfetto/tracing/core/trace_config.h
@@ -42,7 +42,7 @@
 class TraceConfig_BufferConfig;
 class TraceConfig_DataSource;
 class DataSourceConfig;
-class DataSourceConfig_FtraceConfig;
+class FtraceConfig;
 }  // namespace protos
 }  // namespace perfetto
 
diff --git a/protos/perfetto/config/BUILD.gn b/protos/perfetto/config/BUILD.gn
index d916737..abe1d69 100644
--- a/protos/perfetto/config/BUILD.gn
+++ b/protos/perfetto/config/BUILD.gn
@@ -22,6 +22,7 @@
   sources = [
     "data_source_config.proto",
     "data_source_descriptor.proto",
+    "ftrace/ftrace_config.proto",
     "trace_config.proto",
   ]
 }
diff --git a/protos/perfetto/config/data_source_config.proto b/protos/perfetto/config/data_source_config.proto
index 4c3d54b..a46d6fe 100644
--- a/protos/perfetto/config/data_source_config.proto
+++ b/protos/perfetto/config/data_source_config.proto
@@ -19,21 +19,13 @@
 
 package perfetto.protos;
 
+import "perfetto/config/ftrace/ftrace_config.proto";
+
 // When editing this file run ./tools/gen_tracing_cpp_headers_from_protos.py
 // to reflect changes in the corresponding C++ headers.
 
 // The configuration that is passed to each data source when starting tracing.
 message DataSourceConfig {
-  // TODO(hjd): Move to own file when rearranging protos.
-  message FtraceConfig {
-    repeated string event_names = 1;
-    repeated string atrace_categories = 2;
-    repeated string atrace_apps = 3;
-    // *Per-CPU* buffer size.
-    optional uint32 buffer_size_kb = 10;
-    optional uint32 drain_period_ms = 11;
-  }
-
   // Data source unique name, e.g., "org.chromium.trace_events". This must match
   // the name passed by the data source when it registers (see
   // RegisterDataSource()).
diff --git a/protos/perfetto/config/ftrace/ftrace_config.proto b/protos/perfetto/config/ftrace/ftrace_config.proto
new file mode 100644
index 0000000..91bb55a
--- /dev/null
+++ b/protos/perfetto/config/ftrace/ftrace_config.proto
@@ -0,0 +1,32 @@
+/*
+ * 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.
+ */
+
+syntax = "proto2";
+option optimize_for = LITE_RUNTIME;
+
+package perfetto.protos;
+
+// When editing this file run ./tools/gen_tracing_cpp_headers_from_protos.py
+// to reflect changes in the corresponding C++ headers.
+
+message FtraceConfig {
+  repeated string event_names = 1;
+  repeated string atrace_categories = 2;
+  repeated string atrace_apps = 3;
+  // *Per-CPU* buffer size.
+  optional uint32 buffer_size_kb = 10;
+  optional uint32 drain_period_ms = 11;
+}
diff --git a/protos/perfetto/config/perfetto_config.proto b/protos/perfetto/config/perfetto_config.proto
index 2f7747c..7536107 100644
--- a/protos/perfetto/config/perfetto_config.proto
+++ b/protos/perfetto/config/perfetto_config.proto
@@ -18,16 +18,6 @@
 
 // The configuration that is passed to each data source when starting tracing.
 message DataSourceConfig {
-  // TODO: Move to own file when rearranging protos.
-  message FtraceConfig {
-    repeated string event_names = 1;
-    repeated string atrace_categories = 2;
-    repeated string atrace_apps = 3;
-    // *Per-CPU* buffer size.
-    optional uint32 buffer_size_kb = 10;
-    optional uint32 drain_period_ms = 11;
-  }
-
   // Data source unique name, e.g., "org.chromium.trace_events". This must match
   // the name passed by the data source when it registers (see
   // RegisterDataSource()).
@@ -53,6 +43,22 @@
 
 // End of protos/perfetto/config/data_source_config.proto
 
+// Begin of protos/perfetto/config/ftrace/ftrace_config.proto
+
+// When editing this file run ./tools/gen_tracing_cpp_headers_from_protos.py
+// to reflect changes in the corresponding C++ headers.
+
+message FtraceConfig {
+  repeated string event_names = 1;
+  repeated string atrace_categories = 2;
+  repeated string atrace_apps = 3;
+  // *Per-CPU* buffer size.
+  optional uint32 buffer_size_kb = 10;
+  optional uint32 drain_period_ms = 11;
+}
+
+// End of protos/perfetto/config/ftrace/ftrace_config.proto
+
 // Begin of protos/perfetto/config/trace_config.proto
 
 // When editing this file run ./tools/gen_tracing_cpp_headers_from_protos.py
diff --git a/src/traced/probes/probes_producer.cc b/src/traced/probes/probes_producer.cc
index d3a96b9..7c81c1d 100644
--- a/src/traced/probes/probes_producer.cc
+++ b/src/traced/probes/probes_producer.cc
@@ -23,6 +23,7 @@
 #include "perfetto/traced/traced.h"
 #include "perfetto/tracing/core/data_source_config.h"
 #include "perfetto/tracing/core/data_source_descriptor.h"
+#include "perfetto/tracing/core/ftrace_config.h"
 #include "perfetto/tracing/core/trace_config.h"
 #include "perfetto/tracing/core/trace_packet.h"
 
@@ -122,8 +123,7 @@
   PERFETTO_LOG("Ftrace start (id=%" PRIu64 ", target_buf=%" PRIu32 ")", id,
                source_config.target_buffer());
 
-  // TODO(hjd): Would be nice if ftrace_reader could use the generated config.
-  DataSourceConfig::FtraceConfig proto_config = source_config.ftrace_config();
+  FtraceConfig proto_config = source_config.ftrace_config();
 
   // TODO(hjd): Static cast is bad, target_buffer() should return a BufferID.
   auto trace_writer = endpoint_->CreateTraceWriter(
diff --git a/src/tracing/BUILD.gn b/src/tracing/BUILD.gn
index e56c7ea..d0dcf6c 100644
--- a/src/tracing/BUILD.gn
+++ b/src/tracing/BUILD.gn
@@ -31,6 +31,7 @@
   sources = [
     "core/data_source_config.cc",
     "core/data_source_descriptor.cc",
+    "core/ftrace_config.cc",
     "core/id_allocator.cc",
     "core/id_allocator.h",
     "core/packet_stream_validator.cc",
diff --git a/src/tracing/core/data_source_config.cc b/src/tracing/core/data_source_config.cc
index 9adb447..2c86ac9 100644
--- a/src/tracing/core/data_source_config.cc
+++ b/src/tracing/core/data_source_config.cc
@@ -28,6 +28,7 @@
 #include "perfetto/tracing/core/data_source_config.h"
 
 #include "perfetto/config/data_source_config.pb.h"
+#include "perfetto/config/ftrace/ftrace_config.pb.h"
 
 namespace perfetto {
 
@@ -79,92 +80,4 @@
   *(proto->mutable_unknown_fields()) = unknown_fields_;
 }
 
-DataSourceConfig::FtraceConfig::FtraceConfig() = default;
-DataSourceConfig::FtraceConfig::~FtraceConfig() = default;
-DataSourceConfig::FtraceConfig::FtraceConfig(
-    const DataSourceConfig::FtraceConfig&) = default;
-DataSourceConfig::FtraceConfig& DataSourceConfig::FtraceConfig::operator=(
-    const DataSourceConfig::FtraceConfig&) = default;
-DataSourceConfig::FtraceConfig::FtraceConfig(
-    DataSourceConfig::FtraceConfig&&) noexcept = default;
-DataSourceConfig::FtraceConfig& DataSourceConfig::FtraceConfig::operator=(
-    DataSourceConfig::FtraceConfig&&) = default;
-
-void DataSourceConfig::FtraceConfig::FromProto(
-    const perfetto::protos::DataSourceConfig_FtraceConfig& proto) {
-  event_names_.clear();
-  for (const auto& field : proto.event_names()) {
-    event_names_.emplace_back();
-    static_assert(sizeof(event_names_.back()) == sizeof(proto.event_names(0)),
-                  "size mismatch");
-    event_names_.back() =
-        static_cast<decltype(event_names_)::value_type>(field);
-  }
-
-  atrace_categories_.clear();
-  for (const auto& field : proto.atrace_categories()) {
-    atrace_categories_.emplace_back();
-    static_assert(
-        sizeof(atrace_categories_.back()) == sizeof(proto.atrace_categories(0)),
-        "size mismatch");
-    atrace_categories_.back() =
-        static_cast<decltype(atrace_categories_)::value_type>(field);
-  }
-
-  atrace_apps_.clear();
-  for (const auto& field : proto.atrace_apps()) {
-    atrace_apps_.emplace_back();
-    static_assert(sizeof(atrace_apps_.back()) == sizeof(proto.atrace_apps(0)),
-                  "size mismatch");
-    atrace_apps_.back() =
-        static_cast<decltype(atrace_apps_)::value_type>(field);
-  }
-
-  static_assert(sizeof(buffer_size_kb_) == sizeof(proto.buffer_size_kb()),
-                "size mismatch");
-  buffer_size_kb_ =
-      static_cast<decltype(buffer_size_kb_)>(proto.buffer_size_kb());
-
-  static_assert(sizeof(drain_period_ms_) == sizeof(proto.drain_period_ms()),
-                "size mismatch");
-  drain_period_ms_ =
-      static_cast<decltype(drain_period_ms_)>(proto.drain_period_ms());
-  unknown_fields_ = proto.unknown_fields();
-}
-
-void DataSourceConfig::FtraceConfig::ToProto(
-    perfetto::protos::DataSourceConfig_FtraceConfig* proto) const {
-  proto->Clear();
-
-  for (const auto& it : event_names_) {
-    auto* entry = proto->add_event_names();
-    static_assert(sizeof(it) == sizeof(proto->event_names(0)), "size mismatch");
-    *entry = static_cast<decltype(proto->event_names(0))>(it);
-  }
-
-  for (const auto& it : atrace_categories_) {
-    auto* entry = proto->add_atrace_categories();
-    static_assert(sizeof(it) == sizeof(proto->atrace_categories(0)),
-                  "size mismatch");
-    *entry = static_cast<decltype(proto->atrace_categories(0))>(it);
-  }
-
-  for (const auto& it : atrace_apps_) {
-    auto* entry = proto->add_atrace_apps();
-    static_assert(sizeof(it) == sizeof(proto->atrace_apps(0)), "size mismatch");
-    *entry = static_cast<decltype(proto->atrace_apps(0))>(it);
-  }
-
-  static_assert(sizeof(buffer_size_kb_) == sizeof(proto->buffer_size_kb()),
-                "size mismatch");
-  proto->set_buffer_size_kb(
-      static_cast<decltype(proto->buffer_size_kb())>(buffer_size_kb_));
-
-  static_assert(sizeof(drain_period_ms_) == sizeof(proto->drain_period_ms()),
-                "size mismatch");
-  proto->set_drain_period_ms(
-      static_cast<decltype(proto->drain_period_ms())>(drain_period_ms_));
-  *(proto->mutable_unknown_fields()) = unknown_fields_;
-}
-
 }  // namespace perfetto
diff --git a/src/tracing/core/ftrace_config.cc b/src/tracing/core/ftrace_config.cc
new file mode 100644
index 0000000..d03fbc2
--- /dev/null
+++ b/src/tracing/core/ftrace_config.cc
@@ -0,0 +1,116 @@
+/*
+ * 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.
+ */
+
+/*******************************************************************************
+ * AUTOGENERATED - DO NOT EDIT
+ *******************************************************************************
+ * This file has been generated from the protobuf message
+ * perfetto/config/ftrace/ftrace_config.proto
+ * by
+ * ../../tools/proto_to_cpp/proto_to_cpp.cc.
+ * If you need to make changes here, change the .proto file and then run
+ * ./tools/gen_tracing_cpp_headers_from_protos.py
+ */
+
+#include "perfetto/tracing/core/ftrace_config.h"
+
+#include "perfetto/config/ftrace/ftrace_config.pb.h"
+
+namespace perfetto {
+
+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;
+
+void FtraceConfig::FromProto(const perfetto::protos::FtraceConfig& proto) {
+  event_names_.clear();
+  for (const auto& field : proto.event_names()) {
+    event_names_.emplace_back();
+    static_assert(sizeof(event_names_.back()) == sizeof(proto.event_names(0)),
+                  "size mismatch");
+    event_names_.back() =
+        static_cast<decltype(event_names_)::value_type>(field);
+  }
+
+  atrace_categories_.clear();
+  for (const auto& field : proto.atrace_categories()) {
+    atrace_categories_.emplace_back();
+    static_assert(
+        sizeof(atrace_categories_.back()) == sizeof(proto.atrace_categories(0)),
+        "size mismatch");
+    atrace_categories_.back() =
+        static_cast<decltype(atrace_categories_)::value_type>(field);
+  }
+
+  atrace_apps_.clear();
+  for (const auto& field : proto.atrace_apps()) {
+    atrace_apps_.emplace_back();
+    static_assert(sizeof(atrace_apps_.back()) == sizeof(proto.atrace_apps(0)),
+                  "size mismatch");
+    atrace_apps_.back() =
+        static_cast<decltype(atrace_apps_)::value_type>(field);
+  }
+
+  static_assert(sizeof(buffer_size_kb_) == sizeof(proto.buffer_size_kb()),
+                "size mismatch");
+  buffer_size_kb_ =
+      static_cast<decltype(buffer_size_kb_)>(proto.buffer_size_kb());
+
+  static_assert(sizeof(drain_period_ms_) == sizeof(proto.drain_period_ms()),
+                "size mismatch");
+  drain_period_ms_ =
+      static_cast<decltype(drain_period_ms_)>(proto.drain_period_ms());
+  unknown_fields_ = proto.unknown_fields();
+}
+
+void FtraceConfig::ToProto(perfetto::protos::FtraceConfig* proto) const {
+  proto->Clear();
+
+  for (const auto& it : event_names_) {
+    auto* entry = proto->add_event_names();
+    static_assert(sizeof(it) == sizeof(proto->event_names(0)), "size mismatch");
+    *entry = static_cast<decltype(proto->event_names(0))>(it);
+  }
+
+  for (const auto& it : atrace_categories_) {
+    auto* entry = proto->add_atrace_categories();
+    static_assert(sizeof(it) == sizeof(proto->atrace_categories(0)),
+                  "size mismatch");
+    *entry = static_cast<decltype(proto->atrace_categories(0))>(it);
+  }
+
+  for (const auto& it : atrace_apps_) {
+    auto* entry = proto->add_atrace_apps();
+    static_assert(sizeof(it) == sizeof(proto->atrace_apps(0)), "size mismatch");
+    *entry = static_cast<decltype(proto->atrace_apps(0))>(it);
+  }
+
+  static_assert(sizeof(buffer_size_kb_) == sizeof(proto->buffer_size_kb()),
+                "size mismatch");
+  proto->set_buffer_size_kb(
+      static_cast<decltype(proto->buffer_size_kb())>(buffer_size_kb_));
+
+  static_assert(sizeof(drain_period_ms_) == sizeof(proto->drain_period_ms()),
+                "size mismatch");
+  proto->set_drain_period_ms(
+      static_cast<decltype(proto->drain_period_ms())>(drain_period_ms_));
+  *(proto->mutable_unknown_fields()) = unknown_fields_;
+}
+
+}  // namespace perfetto
diff --git a/tools/gen_merged_trace_config b/tools/gen_merged_trace_config
index 15d776c..18ce3bd 100755
--- a/tools/gen_merged_trace_config
+++ b/tools/gen_merged_trace_config
@@ -20,6 +20,7 @@
 
 PROTOS = (
   'protos/perfetto/config/data_source_config.proto',
+  'protos/perfetto/config/ftrace/ftrace_config.proto',
   'protos/perfetto/config/trace_config.proto',
 )
 
diff --git a/tools/gen_tracing_cpp_headers_from_protos.py b/tools/gen_tracing_cpp_headers_from_protos.py
index ea6ce95..650092f 100755
--- a/tools/gen_tracing_cpp_headers_from_protos.py
+++ b/tools/gen_tracing_cpp_headers_from_protos.py
@@ -18,9 +18,10 @@
 import sys
 
 PROTOS = (
-  'perfetto/config/trace_config.proto',
   'perfetto/config/data_source_config.proto',
   'perfetto/config/data_source_descriptor.proto',
+  'perfetto/config/ftrace/ftrace_config.proto',
+  'perfetto/config/trace_config.proto',
 )
 
 HEADER_PATH = 'include/perfetto/tracing/core'