Introduce Consumer API

This introduces the most relevant classes for the Consumer
API surface.
The IPC plumbing and the implementation inside the service
will come in upcoming CLs.

The static_cast in the generated .cc files are needed to
suppress warning/errors in the following cases:
- When assigning a protobuf enum to a generated enum.
  Even if the underlying type is the same (int), they are
  different types for the compiler.
- Protobuf generated classes do NOT use stdint.h and use
  uint64 instead of uint64_t. Interestingly, on some 64-bit
  architectures they typedef to slightly different types
  (long long vs long). And even if ultimately they map to
  the same bitness, the compiler sees them as different
  types.


Bug: 70284518
Change-Id: If65c345028a9f5f78cd39c4b92ab1b50b966044b
diff --git a/Android.bp b/Android.bp
index 9ce2e99..8dfec21 100644
--- a/Android.bp
+++ b/Android.bp
@@ -420,47 +420,85 @@
 filegroup {
   name: "perfetto_tracing",
   srcs: [
+    "src/tracing/core/data_source_config.cc",
+    "src/tracing/core/data_source_descriptor.cc",
     "src/tracing/core/service_impl.cc",
+    "src/tracing/core/trace_config.cc",
+    "src/tracing/core/trace_packet.cc",
   ]
 }
 
+// These protos contains only messages that require the standard protoc.
 filegroup {
   name: "perfetto_tracing_messages",
   srcs:  [
-    "src/tracing/ipc/data_source_config.proto",
-    "src/tracing/ipc/data_source_descriptor.proto",
-    "src/tracing/ipc/producer_port.proto",
+    "protos/tracing_service/data_source_config.proto",
+    "protos/tracing_service/data_source_descriptor.proto",
+    "protos/tracing_service/trace_config.proto",
   ]
 }
 
 cc_genrule {
   name: "perfetto_tracing_messages_lite",
-  tools: [ "aprotoc", "perfetto_ipc_protoc_plugin" ],
+  tools: [ "aprotoc" ],
   srcs: [ ":perfetto_tracing_messages" ],
-  cmd: ipcc_cmd,
+  cmd: protoc_cmd,
   out: [
-    "external/perfetto/src/tracing/ipc/data_source_config.ipc.cc",
-    "external/perfetto/src/tracing/ipc/data_source_config.pb.cc",
-    "external/perfetto/src/tracing/ipc/data_source_descriptor.ipc.cc",
-    "external/perfetto/src/tracing/ipc/data_source_descriptor.pb.cc",
-    "external/perfetto/src/tracing/ipc/producer_port.ipc.cc",
-    "external/perfetto/src/tracing/ipc/producer_port.pb.cc",
+    "external/perfetto/protos/tracing_service/data_source_config.pb.cc",
+    "external/perfetto/protos/tracing_service/data_source_descriptor.pb.cc",
+    "external/perfetto/protos/tracing_service/trace_config.pb.cc",
   ]
 }
 
 cc_genrule {
   name: "perfetto_tracing_messages_lite_headers",
-  tools: [ "aprotoc", "perfetto_ipc_protoc_plugin" ],
+  tools: [ "aprotoc" ],
   srcs: [ ":perfetto_tracing_messages" ],
+  cmd: protoc_cmd,
+  export_include_dirs: [ "." ],
+  out: [
+    "external/perfetto/protos/tracing_service/data_source_config.pb.h",
+    "external/perfetto/protos/tracing_service/data_source_descriptor.pb.h",
+    "external/perfetto/protos/tracing_service/trace_config.pb.h",
+  ]
+}
+
+
+// These protos, instead, contains IPC definitions that require the use of the
+// IPC plugin, together with protoc.
+
+filegroup {
+  name: "perfetto_tracing_ipcs",
+  srcs:  [
+    "protos/tracing_service/consumer_port.proto",
+    "protos/tracing_service/producer_port.proto",
+  ]
+}
+
+cc_genrule {
+  name: "perfetto_tracing_ipcs_lite",
+  tools: [ "aprotoc", "perfetto_ipc_protoc_plugin" ],
+  srcs: [ ":perfetto_tracing_ipcs" ],
+  cmd: ipcc_cmd,
+  out: [
+    "external/perfetto/protos/tracing_service/consumer_port.ipc.cc",
+    "external/perfetto/protos/tracing_service/consumer_port.pb.cc",
+    "external/perfetto/protos/tracing_service/producer_port.ipc.cc",
+    "external/perfetto/protos/tracing_service/producer_port.pb.cc",
+  ]
+}
+
+cc_genrule {
+  name: "perfetto_tracing_ipcs_lite_headers",
+  tools: [ "aprotoc", "perfetto_ipc_protoc_plugin" ],
+  srcs: [ ":perfetto_tracing_ipcs" ],
   cmd: ipcc_cmd,
   export_include_dirs: [ "." ],
   out: [
-    "external/perfetto/src/tracing/ipc/data_source_config.ipc.h",
-    "external/perfetto/src/tracing/ipc/data_source_config.pb.h",
-    "external/perfetto/src/tracing/ipc/data_source_descriptor.ipc.h",
-    "external/perfetto/src/tracing/ipc/data_source_descriptor.pb.h",
-    "external/perfetto/src/tracing/ipc/producer_port.ipc.h",
-    "external/perfetto/src/tracing/ipc/producer_port.pb.h",
+    "external/perfetto/protos/tracing_service/consumer_port.ipc.h",
+    "external/perfetto/protos/tracing_service/consumer_port.pb.h",
+    "external/perfetto/protos/tracing_service/producer_port.ipc.h",
+    "external/perfetto/protos/tracing_service/producer_port.pb.h",
   ]
 }
 
@@ -497,6 +535,7 @@
     ":perfetto_tracing",
     ":perfetto_tracing_ipc",
     ":perfetto_tracing_messages_lite",
+    ":perfetto_tracing_ipcs_lite",
     ":protozero",
     ":protozero_testing_messages_lite",
     ":protozero_testing_messages_zero",
@@ -533,6 +572,7 @@
     "perfetto_messages_lite_headers",
     "perfetto_messages_zero_headers",
     "perfetto_tracing_messages_lite_headers",
+    "perfetto_tracing_ipcs_lite_headers",
     "protozero_testing_messages_lite_headers",
     "protozero_testing_messages_zero_headers",
   ],
diff --git a/src/ipc/ipc_library.gni b/gn/ipc_library.gni
similarity index 95%
rename from src/ipc/ipc_library.gni
rename to gn/ipc_library.gni
index 5231351..db4d72c 100644
--- a/src/ipc/ipc_library.gni
+++ b/gn/ipc_library.gni
@@ -12,7 +12,6 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-import("../../gn/perfetto.gni")
 import("//build_overrides/build.gni")
 
 if (!build_with_chromium) {
@@ -29,10 +28,13 @@
     generator_plugin_label =
         perfetto_root_path + "src/ipc/protoc_plugin:ipc_plugin"
     generator_plugin_suffix = ".ipc"
-
     deps = [
       "${perfetto_root_path}src/ipc",
     ]
+    if (defined(invoker.deps)) {
+      deps += invoker.deps
+    }
+
     proto_out_dir = "protos_lite"
     forward_variables_from(invoker,
                            [
diff --git a/include/perfetto/tracing/core/BUILD.gn b/include/perfetto/tracing/core/BUILD.gn
index ff765c3..cadc9f0 100644
--- a/include/perfetto/tracing/core/BUILD.gn
+++ b/include/perfetto/tracing/core/BUILD.gn
@@ -25,5 +25,7 @@
     "producer.h",
     "service.h",
     "shared_memory.h",
+    "trace_config.h",
+    "trace_packet.h",
   ]
 }
diff --git a/include/perfetto/tracing/core/data_source_config.h b/include/perfetto/tracing/core/data_source_config.h
index ad818a8..10b2719 100644
--- a/include/perfetto/tracing/core/data_source_config.h
+++ b/include/perfetto/tracing/core/data_source_config.h
@@ -14,29 +14,70 @@
  * limitations under the License.
  */
 
+/*******************************************************************************
+ * AUTOGENERATED - DO NOT EDIT
+ *******************************************************************************
+ * This file has been generated from the protobuf message
+ * protos/tracing_service/data_source_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_DATA_SOURCE_CONFIG_H_
 #define INCLUDE_PERFETTO_TRACING_CORE_DATA_SOURCE_CONFIG_H_
 
+#include <stdint.h>
 #include <string>
+#include <type_traits>
+#include <vector>
+#include "perfetto/base/build_config.h"
+
+// Forward declarations for protobuf types.
+namespace perfetto {
+namespace protos {
+class DataSourceConfig;
+}
+}  // namespace perfetto
 
 namespace perfetto {
 
-// This class contains the configuration that the Service sends back to the
-// Producer when it tells it to enable a given data source. This is the way
-// that, for instance, the Service will tell the producer "turn tracing on,
-// enable categories 'foo' and 'bar' and emit only the fields X and Y".
-
-// This has to be kept in sync with src/ipc/data_source_config.proto .
-// TODO(primiano): find a way to auto-generate this and the glue code that
-// converts DataSourceConfig <> proto::DataSourceConfig.
 class DataSourceConfig {
  public:
-  std::string data_source_name;  // e.g., "org.chromium.trace_events"
+  DataSourceConfig();
+  ~DataSourceConfig();
+  DataSourceConfig(DataSourceConfig&&) noexcept;
+  DataSourceConfig& operator=(DataSourceConfig&&);
+  DataSourceConfig(const DataSourceConfig&) = delete;
+  DataSourceConfig& operator=(const DataSourceConfig&) = delete;
 
-  // TODO(primiano): temporary, for testing only.
-  std::string trace_category_filters;  // e.g., "ipc,media,toplvel"
+  // Conversion methods from/to the corresponding protobuf types.
+  void FromProto(const perfetto::protos::DataSourceConfig&);
+  void ToProto(perfetto::protos::DataSourceConfig*) const;
+
+  const std::string& name() const { return name_; }
+  void set_name(const std::string& value) { name_ = value; }
+
+  uint32_t target_buffer() const { return target_buffer_; }
+  void set_target_buffer(uint32_t value) { target_buffer_ = value; }
+
+  const std::string& trace_category_filters() const {
+    return trace_category_filters_;
+  }
+  void set_trace_category_filters(const std::string& value) {
+    trace_category_filters_ = value;
+  }
+
+ private:
+  std::string name_ = {};
+  uint32_t target_buffer_ = {};
+  std::string trace_category_filters_ = {};
+
+  // 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_DATA_SOURCE_CONFIG_H_
diff --git a/include/perfetto/tracing/core/data_source_descriptor.h b/include/perfetto/tracing/core/data_source_descriptor.h
index 58eb3c8..98b47b3 100644
--- a/include/perfetto/tracing/core/data_source_descriptor.h
+++ b/include/perfetto/tracing/core/data_source_descriptor.h
@@ -14,27 +14,58 @@
  * limitations under the License.
  */
 
+/*******************************************************************************
+ * AUTOGENERATED - DO NOT EDIT
+ *******************************************************************************
+ * This file has been generated from the protobuf message
+ * protos/tracing_service/data_source_descriptor.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_DATA_SOURCE_DESCRIPTOR_H_
 #define INCLUDE_PERFETTO_TRACING_CORE_DATA_SOURCE_DESCRIPTOR_H_
 
+#include <stdint.h>
 #include <string>
+#include <type_traits>
+#include <vector>
+#include "perfetto/base/build_config.h"
+
+// Forward declarations for protobuf types.
+namespace perfetto {
+namespace protos {
+class DataSourceDescriptor;
+}
+}  // namespace perfetto
 
 namespace perfetto {
 
-// This class contains the details of the DataSource that Producer(s) advertise
-// to the Service through Service::ProducerEndpoint::RegisterDataSource().
-// This is to pass information such as exposed field, supported filters etc.
-
-// This has to be kept in sync with src/ipc/data_source_descriptor.proto .
-// TODO(primiano): find a way to auto-generate this and the glue code that
-// converts DataSourceDescriptor <> proto::DataSourceDescriptor.
 class DataSourceDescriptor {
  public:
-  std::string name;  // e.g., org.chromium.trace_events.
+  DataSourceDescriptor();
+  ~DataSourceDescriptor();
+  DataSourceDescriptor(DataSourceDescriptor&&) noexcept;
+  DataSourceDescriptor& operator=(DataSourceDescriptor&&);
+  DataSourceDescriptor(const DataSourceDescriptor&) = delete;
+  DataSourceDescriptor& operator=(const DataSourceDescriptor&) = delete;
 
-  // TODO(primiano): fill this in next CLs.
+  // Conversion methods from/to the corresponding protobuf types.
+  void FromProto(const perfetto::protos::DataSourceDescriptor&);
+  void ToProto(perfetto::protos::DataSourceDescriptor*) const;
+
+  const std::string& name() const { return name_; }
+  void set_name(const std::string& value) { name_ = value; }
+
+ private:
+  std::string name_ = {};
+
+  // 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_DATA_SOURCE_DESCRIPTOR_H_
diff --git a/include/perfetto/tracing/core/trace_config.h b/include/perfetto/tracing/core/trace_config.h
new file mode 100644
index 0000000..8a2d90d
--- /dev/null
+++ b/include/perfetto/tracing/core/trace_config.h
@@ -0,0 +1,168 @@
+/*
+ * 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
+ * protos/tracing_service/trace_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_TRACE_CONFIG_H_
+#define INCLUDE_PERFETTO_TRACING_CORE_TRACE_CONFIG_H_
+
+#include <stdint.h>
+#include <string>
+#include <type_traits>
+#include <vector>
+#include "perfetto/base/build_config.h"
+
+#include "include/perfetto/tracing/core/data_source_config.h"
+
+// Forward declarations for protobuf types.
+namespace perfetto {
+namespace protos {
+class TraceConfig;
+class TraceConfig_BufferConfig;
+class TraceConfig_DataSource;
+class DataSourceConfig;
+}  // namespace protos
+}  // namespace perfetto
+
+namespace perfetto {
+
+class TraceConfig {
+ public:
+  class BufferConfig {
+   public:
+    enum OptimizeFor {
+      ONE_SHOT_READ = 0,
+    };
+    enum FillPolicy {
+      RING_BUFFER = 0,
+    };
+    BufferConfig();
+    ~BufferConfig();
+    BufferConfig(BufferConfig&&) noexcept;
+    BufferConfig& operator=(BufferConfig&&);
+    BufferConfig(const BufferConfig&) = delete;
+    BufferConfig& operator=(const BufferConfig&) = delete;
+
+    // Conversion methods from/to the corresponding protobuf types.
+    void FromProto(const perfetto::protos::TraceConfig_BufferConfig&);
+    void ToProto(perfetto::protos::TraceConfig_BufferConfig*) const;
+
+    uint32_t size_kb() const { return size_kb_; }
+    void set_size_kb(uint32_t value) { size_kb_ = value; }
+
+    OptimizeFor optimize_for() const { return optimize_for_; }
+    void set_optimize_for(OptimizeFor value) { optimize_for_ = value; }
+
+    FillPolicy fill_policy() const { return fill_policy_; }
+    void set_fill_policy(FillPolicy value) { fill_policy_ = value; }
+
+   private:
+    uint32_t size_kb_ = {};
+    OptimizeFor optimize_for_ = {};
+    FillPolicy fill_policy_ = {};
+
+    // Allows to preserve unknown protobuf fields for compatibility
+    // with future versions of .proto files.
+    std::string unknown_fields_;
+  };
+
+  class DataSource {
+   public:
+    DataSource();
+    ~DataSource();
+    DataSource(DataSource&&) noexcept;
+    DataSource& operator=(DataSource&&);
+    DataSource(const DataSource&) = delete;
+    DataSource& operator=(const DataSource&) = delete;
+
+    // Conversion methods from/to the corresponding protobuf types.
+    void FromProto(const perfetto::protos::TraceConfig_DataSource&);
+    void ToProto(perfetto::protos::TraceConfig_DataSource*) const;
+
+    const DataSourceConfig& config() const { return config_; }
+    DataSourceConfig* mutable_config() { return &config_; }
+
+    int producer_name_filter_size() const {
+      return static_cast<int>(producer_name_filter_.size());
+    }
+    const std::vector<std::string>& producer_name_filter() const {
+      return producer_name_filter_;
+    }
+    std::string* add_producer_name_filter() {
+      producer_name_filter_.emplace_back();
+      return &producer_name_filter_.back();
+    }
+
+   private:
+    DataSourceConfig config_ = {};
+    std::vector<std::string> producer_name_filter_;
+
+    // Allows to preserve unknown protobuf fields for compatibility
+    // with future versions of .proto files.
+    std::string unknown_fields_;
+  };
+
+  TraceConfig();
+  ~TraceConfig();
+  TraceConfig(TraceConfig&&) noexcept;
+  TraceConfig& operator=(TraceConfig&&);
+  TraceConfig(const TraceConfig&) = delete;
+  TraceConfig& operator=(const TraceConfig&) = delete;
+
+  // Conversion methods from/to the corresponding protobuf types.
+  void FromProto(const perfetto::protos::TraceConfig&);
+  void ToProto(perfetto::protos::TraceConfig*) const;
+
+  int buffers_size() const { return static_cast<int>(buffers_.size()); }
+  const std::vector<BufferConfig>& buffers() const { return buffers_; }
+  BufferConfig* add_buffers() {
+    buffers_.emplace_back();
+    return &buffers_.back();
+  }
+
+  int data_sources_size() const {
+    return static_cast<int>(data_sources_.size());
+  }
+  const std::vector<DataSource>& data_sources() const { return data_sources_; }
+  DataSource* add_data_sources() {
+    data_sources_.emplace_back();
+    return &data_sources_.back();
+  }
+
+  uint32_t duration_ms() const { return duration_ms_; }
+  void set_duration_ms(uint32_t value) { duration_ms_ = value; }
+
+ private:
+  std::vector<BufferConfig> buffers_;
+  std::vector<DataSource> data_sources_;
+  uint32_t duration_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_TRACE_CONFIG_H_
diff --git a/protos/BUILD.gn b/protos/BUILD.gn
index 4fa7cd7..0c1d6ec 100644
--- a/protos/BUILD.gn
+++ b/protos/BUILD.gn
@@ -32,6 +32,7 @@
 proto_library("lite") {
   deps = [
     "ftrace:lite",
+    "tracing_service:lite",
   ]
   sources = proto_sources
   proto_out_dir = "protos_lite"
diff --git a/protos/trace_packet.proto b/protos/trace_packet.proto
index 7f4fcca..5db2b1b 100644
--- a/protos/trace_packet.proto
+++ b/protos/trace_packet.proto
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-syntax = "proto3";
+syntax = "proto2";
 option optimize_for = LITE_RUNTIME;
 
 import "protos/ftrace/ftrace_event_bundle.proto";
@@ -25,5 +25,5 @@
 // TracePacket(s).
 message TracePacket {
   oneof data { FtraceEventBundle ftrace_events = 1; }
-  string test = 2;
+  optional string test = 2;
 }
diff --git a/protos/tracing_service/BUILD.gn b/protos/tracing_service/BUILD.gn
new file mode 100644
index 0000000..da47ab8
--- /dev/null
+++ b/protos/tracing_service/BUILD.gn
@@ -0,0 +1,38 @@
+# 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.
+
+import("../../gn/perfetto.gni")
+import("../../gn/ipc_library.gni")
+
+# IPC service definitions.
+ipc_library("tracing_service") {
+  deps = [
+    ":lite",
+  ]
+  proto_in_dir = perfetto_root_path
+  sources = [
+    "consumer_port.proto",
+    "producer_port.proto",
+  ]
+}
+
+proto_library("lite") {
+  proto_in_dir = perfetto_root_path
+  proto_out_dir = "protos_lite"
+  sources = [
+    "data_source_config.proto",
+    "data_source_descriptor.proto",
+    "trace_config.proto",
+  ]
+}
diff --git a/protos/tracing_service/consumer_port.proto b/protos/tracing_service/consumer_port.proto
new file mode 100644
index 0000000..0a34bcc
--- /dev/null
+++ b/protos/tracing_service/consumer_port.proto
@@ -0,0 +1,109 @@
+/*
+ * 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;
+
+import "protos/tracing_service/data_source_config.proto";
+import "protos/tracing_service/trace_config.proto";
+
+package perfetto;
+
+// IPC interface definition for the consumer port of the tracing service.
+service ConsumerPort {
+  // Creates the ring buffers that will be used for the tracing session.
+  // TODO(primiano): not implemented yet. EnableTracing will implicitly create
+  // the required buffer. This is to allow Enabling/Disabling tracing with
+  // different configs without losing the contents of the buffers for the
+  // previous tracing session.
+  // rpc CreateBuffers(CreateBuffersRequest) returns (CreateBuffersResponse) {}
+
+  // Enables tracing for one or more data sources. At least one buffer must have
+  // been previously created.
+  rpc EnableTracing(EnableTracingRequest) returns (EnableTracingResponse) {}
+
+  // Disables tracing for one or more data sources.
+  rpc DisableTracing(DisableTracingRequest) returns (DisableTracingResponse) {}
+
+  // Streams back the contents of one or more buffers. At the moment this can
+  // be called once only after calling DisableTracing(). In future it will be
+  // possible to call this while the trace is enabled to stream continuously the
+  // contents of the buffer(s). One call is enough to drain all the buffers. The
+  // response consists in a sequence of ReadBufferResponse messages (hence the
+  // "stream" in the return type), each carrying one or more TracePacket(s).
+  // An EOF flag is attached to the last ReadBufferResponse through the
+  // |has_more| == false field.
+  // TODO: add the ability to pass a file descriptor and just let the service
+  // write into that.
+  rpc ReadBuffers(ReadBuffersRequest) returns (stream ReadBuffersResponse) {}
+
+  // Destroys the buffers previously created. Note: all buffers are destroyed
+  // implicitly if the Consumer disconnects.
+  rpc FreeBuffers(FreeBuffersRequest) returns (FreeBuffersResponse) {}
+
+  // TODO rpc ListDataSources(), for the UI.
+  // TODO rpc KillSwitch().
+}
+
+// Arguments for rpc EnableTracing().
+message EnableTracingRequest {
+  optional protos.TraceConfig trace_config = 1;
+}
+
+message EnableTracingResponse {}
+
+// Arguments for rpc DisableTracing().
+message DisableTracingRequest {
+  // TODO: not supported yet, selectively disable only some data sources.
+  // repeated string data_source_name;
+}
+
+message DisableTracingResponse {}
+
+// Arguments for rpc ReadBuffers().
+message ReadBuffersRequest {
+  // The |id|s of the buffer, as passed to CreateBuffers().
+  // TODO: repeated uint32 buffer_ids = 1;
+}
+
+message ReadBuffersResponse {
+  // TODO: uint32 buffer_id = 1;
+
+  // Each streaming reply returns one or more trace packets (see
+  // trace_packet.proto).
+  // Why "bytes" here? If we just return the full TracePacket object, that will
+  // force the Consumer to deserialize it. In many occasions, the Consumer will
+  // not consume the TracePacket(s) locally but will just forward them over
+  // the network or save them to a file. Deserializing them on-device would be
+  // a waste of time, memory and energy.
+
+  // TODO: in the past we agreed that a TracePacket can be very large (MBs).
+  // However here it will hit the limit of the IPC layer in order to keep
+  // the socket buffer bounded. On one side we could upgrade this protocol to
+  // support chunks, so we could directly propagate the chunked TracePacket
+  // stored in the log buffer. On the other side, this will likely just move
+  // the problem on the consumer, that will need larger buffers for reassembly.
+  // Perhaps we should just cap the size of a TracePacket to a lower size?
+  repeated bytes trace_packets = 2;
+}
+
+// Arguments for rpc FreeBuffers().
+message FreeBuffersRequest {
+  // The |id|s of the buffer, as passed to CreateBuffers().
+  repeated uint32 buffer_ids = 1;
+}
+
+message FreeBuffersResponse {}
diff --git a/protos/tracing_service/data_source_config.proto b/protos/tracing_service/data_source_config.proto
new file mode 100644
index 0000000..4eb44a3
--- /dev/null
+++ b/protos/tracing_service/data_source_config.proto
@@ -0,0 +1,41 @@
+/*
+ * 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.
+
+// The configuration that is passed to each data source when starting tracing.
+message DataSourceConfig {
+  // 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()).
+  optional string name = 1;
+
+  // The index of the logging buffer where TracePacket(s) will be stored.
+  // This field doesn't make a major difference for the Producer(s). The final
+  // logging buffers, in fact, are completely owned by the Service. We just ask
+  // the Producer to copy this number into the chunk headers it emits, so that
+  // the Service can quickly identify the buffer where to move the chunks into
+  // without expensive lookups on its fastpath.
+  optional uint32 target_buffer = 2;
+
+  optional string trace_category_filters = 3;  // TODO: temporary for tests.
+}
diff --git a/src/tracing/ipc/data_source_descriptor.proto b/protos/tracing_service/data_source_descriptor.proto
similarity index 80%
rename from src/tracing/ipc/data_source_descriptor.proto
rename to protos/tracing_service/data_source_descriptor.proto
index 869ff0a..acaee4c 100644
--- a/src/tracing/ipc/data_source_descriptor.proto
+++ b/protos/tracing_service/data_source_descriptor.proto
@@ -14,16 +14,19 @@
  * limitations under the License.
  */
 
-syntax = "proto3";
+syntax = "proto2";
 option optimize_for = LITE_RUNTIME;
 
-package perfetto.proto;
+package perfetto.protos;
+
+// When editing this file run ./tools/gen_tracing_cpp_headers_from_protos.py
+// to reflect changes in the corresponding C++ headers.
 
 // This message is sent from Producer(s) to the tracing Service when registering
 // to advertise their capabilities. It describes the structure of tracing
 // protos that will be produced by the data source and the supported filters.
 message DataSourceDescriptor {
-  string name = 1;  // e.g., "linux.ftrace", "chromium.tracing"
+  optional string name = 1;  // e.g., "linux.ftrace", "chromium.tracing"
 
   // TODO: this should have a structure to enable reflection of the proto
   // fields emitted (see go/perfetto-logging).
diff --git a/src/tracing/ipc/producer_port.proto b/protos/tracing_service/producer_port.proto
similarity index 81%
rename from src/tracing/ipc/producer_port.proto
rename to protos/tracing_service/producer_port.proto
index 0215627..d9ec3ec 100644
--- a/src/tracing/ipc/producer_port.proto
+++ b/protos/tracing_service/producer_port.proto
@@ -14,11 +14,11 @@
  * limitations under the License.
  */
 
-syntax = "proto3";
+syntax = "proto2";
 option optimize_for = LITE_RUNTIME;
 
-import "src/tracing/ipc/data_source_config.proto";
-import "src/tracing/ipc/data_source_descriptor.proto";
+import "protos/tracing_service/data_source_config.proto";
+import "protos/tracing_service/data_source_descriptor.proto";
 
 package perfetto;
 
@@ -52,10 +52,14 @@
 
 // Arguments for rpc InitializeConnection().
 message InitializeConnectionRequest {
+  // Defines the granularity of the tracing pages. Must be an integer multiple
+  // of 4096. See tradeoff considerations in shared_memory_abi.h.
+  optional uint32 shared_buffer_page_size_bytes = 1;
+
   // Optional. Provides a hint to the tracing service about the suggested size
   // of the shared memory buffer. The service is not required to respect this
   // and might return a smaller buffer.
-  uint32 shared_buffer_size_hint_bytes = 1;
+  optional uint32 shared_buffer_size_hint_bytes = 2;
 }
 
 message InitializeConnectionResponse {
@@ -65,15 +69,15 @@
 // Arguments for rpc RegisterDataSource().
 
 message RegisterDataSourceRequest {
-  proto.DataSourceDescriptor data_source_descriptor = 1;
+  optional protos.DataSourceDescriptor data_source_descriptor = 1;
 }
 
 message RegisterDataSourceResponse {
   // The ID assigned by the service to this data source. 0 in case of errors.
-  uint64 data_source_id = 1;
+  optional uint64 data_source_id = 1;
 
   // Only set in case of errors, when |data_source_id| == 0.
-  string error = 2;
+  optional string error = 2;
 };
 
 // Arguments for rpc UnregisterDataSource().
@@ -81,7 +85,7 @@
 message UnregisterDataSourceRequest {
   // The ID of the data source to unregister, as previously returned in
   // |RegisterDataSourceResponse.data_source_id|.
-  uint64 data_source_id = 1;
+  optional uint64 data_source_id = 1;
 }
 
 message UnregisterDataSourceResponse {}
@@ -100,11 +104,11 @@
 
 message GetAsyncCommandResponse {
   message StartDataSource {
-    uint64 new_instance_id = 1;
-    proto.DataSourceConfig config = 2;
+    optional uint64 new_instance_id = 1;
+    optional protos.DataSourceConfig config = 2;
   }
 
-  message StopDataSource { uint64 instance_id = 1; }
+  message StopDataSource { optional uint64 instance_id = 1; }
 
   oneof cmd {
     StartDataSource start_data_source = 1;
diff --git a/protos/tracing_service/trace_config.proto b/protos/tracing_service/trace_config.proto
new file mode 100644
index 0000000..6129dfc
--- /dev/null
+++ b/protos/tracing_service/trace_config.proto
@@ -0,0 +1,86 @@
+/*
+ * 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;
+
+import "protos/tracing_service/data_source_config.proto";
+
+package perfetto.protos;
+
+// When editing this file run ./tools/gen_tracing_cpp_headers_from_protos.py
+// to reflect changes in the corresponding C++ headers.
+
+// The overall config that is used when starting a new tracing session through
+// ProducerPort::StartTracing().
+// It contains the general config for the logging buffer(s) and the configs for
+// all the data source being enabled.
+message TraceConfig {
+  message BufferConfig {
+    optional uint32 size_kb = 1;
+    // TODO: uint32 page_size = 2;
+
+    enum OptimizeFor {
+      // The log buffer is drained sporadically (typically only once after
+      // DisableTracing()). This mode minimizes the Service overhead when moving
+      // the pages from the Producer(s) shared staging buffers into the central
+      // log buffer, at the cost of doing some extra memory moves to reorder and
+      // reassemble the logged TracePacket(s).
+      ONE_SHOT_READ = 0;
+
+      // The log buffer is streamed continuously to the Consumer.
+      // Advantages:
+      // - It allows to use a smaller log buffer size, as the buffer is only
+      //   needed to cover the pipe latency between Service and Consumer.
+      // - It reduces the total cpu cost of tracing, as TracePackets are
+      //   reshuffled only once when collected from the Producers shmem buffers.
+      // Disadvantage:
+      // - More scheduling intrusive, as will periodically wake up the Consumer
+      //   to stream data.
+      // TODO: Not implemented yet.
+      // CONTINUOUS_STREAMING = 1;
+    }
+    optional OptimizeFor optimize_for = 3;
+
+    enum FillPolicy {
+      RING_BUFFER = 0;
+      // TODO: not implemented yet.
+      // STOP_WHEN_FULL = 1;
+    }
+    optional FillPolicy fill_policy = 4;
+  }
+  repeated BufferConfig buffers = 1;
+
+  message DataSource {
+    // Filters and data-source specific config. It contains also the unique name
+    // of the data source, the one passed in the  DataSourceDescriptor when they
+    // register on the service.
+    optional protos.DataSourceConfig config = 1;
+
+    // Optional. If multiple producers (~processes) expose the same data source
+    // and |producer_name_filter| != "", the data source is enabled only for
+    // producers whose names match any of the producer_name_filter below.
+    // The |producer_name_filter| has to be an exact match. (TODO(primiano):
+    // support wildcards or regex).
+    // This allows to enable a data source only for specific processes.
+    // The "repeated" field has OR sematics: specifying a filter ["foo", "bar"]
+    // will enable data source on both "foo" and "bar" (if existent).
+    repeated string producer_name_filter = 2;
+  }
+  repeated DataSource data_sources = 2;
+
+  optional uint32 duration_ms = 3;
+}
diff --git a/src/ipc/BUILD.gn b/src/ipc/BUILD.gn
index 1439094..c65e270 100644
--- a/src/ipc/BUILD.gn
+++ b/src/ipc/BUILD.gn
@@ -13,8 +13,9 @@
 # limitations under the License.
 
 import("../../gn/perfetto.gni")
+
+import("../../gn/ipc_library.gni")
 import("../../gn/proto_library.gni")
-import("ipc_library.gni")
 
 source_set("ipc") {
   public_configs = [ "../../gn:default_config" ]
diff --git a/src/tracing/BUILD.gn b/src/tracing/BUILD.gn
index 09aef66..0a0f3de 100644
--- a/src/tracing/BUILD.gn
+++ b/src/tracing/BUILD.gn
@@ -14,7 +14,6 @@
 
 import("../../gn/perfetto.gni")
 import("//build_overrides/build.gni")
-import("../ipc/ipc_library.gni")
 
 # Core tracing library, platform independent, no transport layer.
 source_set("tracing") {
@@ -29,22 +28,15 @@
   sources = [
     "core/chunked_protobuf_input_stream.cc",
     "core/chunked_protobuf_input_stream.h",
+    "core/data_source_config.cc",
+    "core/data_source_descriptor.cc",
     "core/service_impl.cc",
     "core/service_impl.h",
+    "core/trace_config.cc",
     "core/trace_packet.cc",
   ]
 }
 
-# IPC service definitions.
-ipc_library("ipc_protos") {
-  proto_in_dir = perfetto_root_path
-  sources = [
-    "ipc/data_source_config.proto",
-    "ipc/data_source_descriptor.proto",
-    "ipc/producer_port.proto",
-  ]
-}
-
 # Posix specialization of the tracing library for Linux/Android/Mac. Provides
 # an IPC transport over a UNIX domain socket.
 source_set("ipc") {
@@ -63,9 +55,9 @@
     "ipc/service/service_ipc_host_impl.h",
   ]
   deps = [
-    ":ipc_protos",
     ":tracing",
     "../../gn:default_deps",
+    "../../protos/tracing_service",
     "../base",
     "../ipc",
   ]
diff --git a/src/tracing/core/data_source_config.cc b/src/tracing/core/data_source_config.cc
new file mode 100644
index 0000000..60cd68c
--- /dev/null
+++ b/src/tracing/core/data_source_config.cc
@@ -0,0 +1,77 @@
+/*
+ * 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
+ * protos/tracing_service/data_source_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 "include/perfetto/tracing/core/data_source_config.h"
+
+#include "protos/tracing_service/data_source_config.pb.h"
+
+namespace perfetto {
+
+DataSourceConfig::DataSourceConfig() = default;
+DataSourceConfig::~DataSourceConfig() = default;
+DataSourceConfig::DataSourceConfig(DataSourceConfig&&) noexcept = default;
+DataSourceConfig& DataSourceConfig::operator=(DataSourceConfig&&) = default;
+
+void DataSourceConfig::FromProto(
+    const perfetto::protos::DataSourceConfig& proto) {
+  static_assert(sizeof(name_) == sizeof(proto.name()), "size mismatch");
+  name_ = static_cast<decltype(name_)>(proto.name());
+
+  static_assert(sizeof(target_buffer_) == sizeof(proto.target_buffer()),
+                "size mismatch");
+  target_buffer_ = static_cast<decltype(target_buffer_)>(proto.target_buffer());
+
+  static_assert(
+      sizeof(trace_category_filters_) == sizeof(proto.trace_category_filters()),
+      "size mismatch");
+  trace_category_filters_ = static_cast<decltype(trace_category_filters_)>(
+      proto.trace_category_filters());
+  unknown_fields_ = proto.unknown_fields();
+}
+
+void DataSourceConfig::ToProto(
+    perfetto::protos::DataSourceConfig* proto) const {
+  proto->Clear();
+
+  static_assert(sizeof(name_) == sizeof(proto->name()), "size mismatch");
+  proto->set_name(static_cast<decltype(proto->name())>(name_));
+
+  static_assert(sizeof(target_buffer_) == sizeof(proto->target_buffer()),
+                "size mismatch");
+  proto->set_target_buffer(
+      static_cast<decltype(proto->target_buffer())>(target_buffer_));
+
+  static_assert(sizeof(trace_category_filters_) ==
+                    sizeof(proto->trace_category_filters()),
+                "size mismatch");
+  proto->set_trace_category_filters(
+      static_cast<decltype(proto->trace_category_filters())>(
+          trace_category_filters_));
+  *(proto->mutable_unknown_fields()) = unknown_fields_;
+}
+
+}  // namespace perfetto
diff --git a/src/tracing/core/data_source_descriptor.cc b/src/tracing/core/data_source_descriptor.cc
new file mode 100644
index 0000000..5a3882c
--- /dev/null
+++ b/src/tracing/core/data_source_descriptor.cc
@@ -0,0 +1,57 @@
+/*
+ * 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
+ * protos/tracing_service/data_source_descriptor.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 "include/perfetto/tracing/core/data_source_descriptor.h"
+
+#include "protos/tracing_service/data_source_descriptor.pb.h"
+
+namespace perfetto {
+
+DataSourceDescriptor::DataSourceDescriptor() = default;
+DataSourceDescriptor::~DataSourceDescriptor() = default;
+DataSourceDescriptor::DataSourceDescriptor(DataSourceDescriptor&&) noexcept =
+    default;
+DataSourceDescriptor& DataSourceDescriptor::operator=(DataSourceDescriptor&&) =
+    default;
+
+void DataSourceDescriptor::FromProto(
+    const perfetto::protos::DataSourceDescriptor& proto) {
+  static_assert(sizeof(name_) == sizeof(proto.name()), "size mismatch");
+  name_ = static_cast<decltype(name_)>(proto.name());
+  unknown_fields_ = proto.unknown_fields();
+}
+
+void DataSourceDescriptor::ToProto(
+    perfetto::protos::DataSourceDescriptor* proto) const {
+  proto->Clear();
+
+  static_assert(sizeof(name_) == sizeof(proto->name()), "size mismatch");
+  proto->set_name(static_cast<decltype(proto->name())>(name_));
+  *(proto->mutable_unknown_fields()) = unknown_fields_;
+}
+
+}  // namespace perfetto
diff --git a/src/tracing/core/service_impl_unittest.cc b/src/tracing/core/service_impl_unittest.cc
index 83e5b95..44ee135 100644
--- a/src/tracing/core/service_impl_unittest.cc
+++ b/src/tracing/core/service_impl_unittest.cc
@@ -71,16 +71,20 @@
   ASSERT_EQ(producer_endpoint_1.get(), svc->GetProducer(1));
   ASSERT_EQ(producer_endpoint_2.get(), svc->GetProducer(2));
 
+  DataSourceDescriptor ds_desc1;
+  ds_desc1.set_name("foo");
   producer_endpoint_1->RegisterDataSource(
-      {"foo"}, [&task_runner, &producer_endpoint_1](DataSourceID id) {
+      ds_desc1, [&task_runner, &producer_endpoint_1](DataSourceID id) {
         EXPECT_EQ(1u, id);
         task_runner.PostTask(
             std::bind(&Service::ProducerEndpoint::UnregisterDataSource,
                       producer_endpoint_1.get(), id));
       });
 
+  DataSourceDescriptor ds_desc2;
+  ds_desc2.set_name("bar");
   producer_endpoint_2->RegisterDataSource(
-      {"bar"}, [&task_runner, &producer_endpoint_2](DataSourceID id) {
+      ds_desc2, [&task_runner, &producer_endpoint_2](DataSourceID id) {
         EXPECT_EQ(1u, id);
         task_runner.PostTask(
             std::bind(&Service::ProducerEndpoint::UnregisterDataSource,
diff --git a/src/tracing/core/trace_config.cc b/src/tracing/core/trace_config.cc
new file mode 100644
index 0000000..87feef4
--- /dev/null
+++ b/src/tracing/core/trace_config.cc
@@ -0,0 +1,158 @@
+/*
+ * 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
+ * protos/tracing_service/trace_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 "include/perfetto/tracing/core/trace_config.h"
+
+#include "protos/tracing_service/data_source_config.pb.h"
+#include "protos/tracing_service/trace_config.pb.h"
+
+namespace perfetto {
+
+TraceConfig::TraceConfig() = default;
+TraceConfig::~TraceConfig() = default;
+TraceConfig::TraceConfig(TraceConfig&&) noexcept = default;
+TraceConfig& TraceConfig::operator=(TraceConfig&&) = default;
+
+void TraceConfig::FromProto(const perfetto::protos::TraceConfig& proto) {
+  buffers_.clear();
+  for (const auto& field : proto.buffers()) {
+    buffers_.emplace_back();
+    buffers_.back().FromProto(field);
+  }
+
+  data_sources_.clear();
+  for (const auto& field : proto.data_sources()) {
+    data_sources_.emplace_back();
+    data_sources_.back().FromProto(field);
+  }
+
+  static_assert(sizeof(duration_ms_) == sizeof(proto.duration_ms()),
+                "size mismatch");
+  duration_ms_ = static_cast<decltype(duration_ms_)>(proto.duration_ms());
+  unknown_fields_ = proto.unknown_fields();
+}
+
+void TraceConfig::ToProto(perfetto::protos::TraceConfig* proto) const {
+  proto->Clear();
+
+  for (const auto& it : buffers_) {
+    auto* entry = proto->add_buffers();
+    it.ToProto(entry);
+  }
+
+  for (const auto& it : data_sources_) {
+    auto* entry = proto->add_data_sources();
+    it.ToProto(entry);
+  }
+
+  static_assert(sizeof(duration_ms_) == sizeof(proto->duration_ms()),
+                "size mismatch");
+  proto->set_duration_ms(
+      static_cast<decltype(proto->duration_ms())>(duration_ms_));
+  *(proto->mutable_unknown_fields()) = unknown_fields_;
+}
+
+TraceConfig::BufferConfig::BufferConfig() = default;
+TraceConfig::BufferConfig::~BufferConfig() = default;
+TraceConfig::BufferConfig::BufferConfig(TraceConfig::BufferConfig&&) noexcept =
+    default;
+TraceConfig::BufferConfig& TraceConfig::BufferConfig::operator=(
+    TraceConfig::BufferConfig&&) = default;
+
+void TraceConfig::BufferConfig::FromProto(
+    const perfetto::protos::TraceConfig_BufferConfig& proto) {
+  static_assert(sizeof(size_kb_) == sizeof(proto.size_kb()), "size mismatch");
+  size_kb_ = static_cast<decltype(size_kb_)>(proto.size_kb());
+
+  static_assert(sizeof(optimize_for_) == sizeof(proto.optimize_for()),
+                "size mismatch");
+  optimize_for_ = static_cast<decltype(optimize_for_)>(proto.optimize_for());
+
+  static_assert(sizeof(fill_policy_) == sizeof(proto.fill_policy()),
+                "size mismatch");
+  fill_policy_ = static_cast<decltype(fill_policy_)>(proto.fill_policy());
+  unknown_fields_ = proto.unknown_fields();
+}
+
+void TraceConfig::BufferConfig::ToProto(
+    perfetto::protos::TraceConfig_BufferConfig* proto) const {
+  proto->Clear();
+
+  static_assert(sizeof(size_kb_) == sizeof(proto->size_kb()), "size mismatch");
+  proto->set_size_kb(static_cast<decltype(proto->size_kb())>(size_kb_));
+
+  static_assert(sizeof(optimize_for_) == sizeof(proto->optimize_for()),
+                "size mismatch");
+  proto->set_optimize_for(
+      static_cast<decltype(proto->optimize_for())>(optimize_for_));
+
+  static_assert(sizeof(fill_policy_) == sizeof(proto->fill_policy()),
+                "size mismatch");
+  proto->set_fill_policy(
+      static_cast<decltype(proto->fill_policy())>(fill_policy_));
+  *(proto->mutable_unknown_fields()) = unknown_fields_;
+}
+
+TraceConfig::DataSource::DataSource() = default;
+TraceConfig::DataSource::~DataSource() = default;
+TraceConfig::DataSource::DataSource(TraceConfig::DataSource&&) noexcept =
+    default;
+TraceConfig::DataSource& TraceConfig::DataSource::operator=(
+    TraceConfig::DataSource&&) = default;
+
+void TraceConfig::DataSource::FromProto(
+    const perfetto::protos::TraceConfig_DataSource& proto) {
+  config_.FromProto(proto.config());
+
+  producer_name_filter_.clear();
+  for (const auto& field : proto.producer_name_filter()) {
+    producer_name_filter_.emplace_back();
+    static_assert(sizeof(producer_name_filter_.back()) ==
+                      sizeof(proto.producer_name_filter(0)),
+                  "size mismatch");
+    producer_name_filter_.back() =
+        static_cast<decltype(producer_name_filter_)::value_type>(field);
+  }
+  unknown_fields_ = proto.unknown_fields();
+}
+
+void TraceConfig::DataSource::ToProto(
+    perfetto::protos::TraceConfig_DataSource* proto) const {
+  proto->Clear();
+
+  config_.ToProto(proto->mutable_config());
+
+  for (const auto& it : producer_name_filter_) {
+    auto* entry = proto->add_producer_name_filter();
+    static_assert(sizeof(it) == sizeof(proto->producer_name_filter(0)),
+                  "size mismatch");
+    *entry = static_cast<decltype(proto->producer_name_filter(0))>(it);
+  }
+  *(proto->mutable_unknown_fields()) = unknown_fields_;
+}
+
+}  // namespace perfetto
diff --git a/src/tracing/ipc/data_source_config.proto b/src/tracing/ipc/data_source_config.proto
deleted file mode 100644
index 89fa725..0000000
--- a/src/tracing/ipc/data_source_config.proto
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * 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 = "proto3";
-option optimize_for = LITE_RUNTIME;
-
-package perfetto.proto;
-
-message DataSourceConfig {
-  string trace_category_filters = 1;  // TODO: temporary for tests.
-}
diff --git a/src/tracing/ipc/producer/producer_ipc_client_impl.cc b/src/tracing/ipc/producer/producer_ipc_client_impl.cc
index 57fd2c8..548c767 100644
--- a/src/tracing/ipc/producer/producer_ipc_client_impl.cc
+++ b/src/tracing/ipc/producer/producer_ipc_client_impl.cc
@@ -101,9 +101,9 @@
     // Keep this in sync with chages in data_source_config.proto.
     const auto& req = cmd.start_data_source();
     const DataSourceInstanceID dsid = req.new_instance_id();
-    const proto::DataSourceConfig& proto_cfg = req.config();
+    const protos::DataSourceConfig& proto_cfg = req.config();
     DataSourceConfig cfg;
-    cfg.trace_category_filters = proto_cfg.trace_category_filters();
+    cfg.set_trace_category_filters(proto_cfg.trace_category_filters());
     producer_->CreateDataSourceInstance(dsid, cfg);
     return;
   }
@@ -129,7 +129,7 @@
   // Keep this in sync with changes in data_source_descriptor.proto.
   RegisterDataSourceRequest req;
   auto* proto_descriptor = req.mutable_data_source_descriptor();
-  proto_descriptor->set_name(descriptor.name);
+  proto_descriptor->set_name(descriptor.name());
   ipc::Deferred<RegisterDataSourceResponse> async_response;
   // TODO: add a test that destroys the IPC channel soon after this call and
   // checks that the callback(0) is invoked.
diff --git a/src/tracing/ipc/producer/producer_ipc_client_impl.h b/src/tracing/ipc/producer/producer_ipc_client_impl.h
index 3f1f736..020032c 100644
--- a/src/tracing/ipc/producer/producer_ipc_client_impl.h
+++ b/src/tracing/ipc/producer/producer_ipc_client_impl.h
@@ -24,9 +24,9 @@
 #include "perfetto/ipc/service_proxy.h"
 #include "perfetto/tracing/core/basic_types.h"
 #include "perfetto/tracing/core/service.h"
-
 #include "perfetto/tracing/ipc/producer_ipc_client.h"
-#include "src/tracing/ipc/producer_port.ipc.h"  // From producer_port.proto.
+
+#include "protos/tracing_service/producer_port.ipc.h"
 
 namespace perfetto {
 
diff --git a/src/tracing/ipc/service/producer_ipc_service.cc b/src/tracing/ipc/service/producer_ipc_service.cc
index e4c0e69..46bd166 100644
--- a/src/tracing/ipc/service/producer_ipc_service.cc
+++ b/src/tracing/ipc/service/producer_ipc_service.cc
@@ -99,7 +99,7 @@
   // Deserialize IPC proto -> core DataSourceDescriptor. Keep this in sync with
   // changes to data_source_descriptor.proto.
   DataSourceDescriptor dsd;
-  dsd.name = data_source_name;
+  dsd.set_name(data_source_name);
   producer->pending_data_sources[data_source_name] = std::move(response);
   auto weak_this = weak_ptr_factory_.GetWeakPtr();
 
@@ -235,7 +235,7 @@
   // Keep this in sync with data_source_config.proto.
   cmd->mutable_start_data_source()
       ->mutable_config()
-      ->set_trace_category_filters(cfg.trace_category_filters);
+      ->set_trace_category_filters(cfg.trace_category_filters());
   async_producer_commands.Resolve(std::move(cmd));
 }
 
diff --git a/src/tracing/ipc/service/producer_ipc_service.h b/src/tracing/ipc/service/producer_ipc_service.h
index 7dc7651..ebe7d21 100644
--- a/src/tracing/ipc/service/producer_ipc_service.h
+++ b/src/tracing/ipc/service/producer_ipc_service.h
@@ -26,7 +26,7 @@
 #include "perfetto/tracing/core/producer.h"
 #include "perfetto/tracing/core/service.h"
 
-#include "src/tracing/ipc/producer_port.ipc.h"  // From producer_port.proto.
+#include "protos/tracing_service/producer_port.ipc.h"
 
 namespace perfetto {