Merge changes I0666a890,Idb306e32,I4f3afd96

* changes:
  Added process tree config.
  Allow to configure scan roots.
  Allow to configure InodeFileDataSource.
diff --git a/Android.bp b/Android.bp
index 6113911..4fd984e 100644
--- a/Android.bp
+++ b/Android.bp
@@ -79,8 +79,10 @@
     "src/tracing/core/data_source_descriptor.cc",
     "src/tracing/core/ftrace_config.cc",
     "src/tracing/core/id_allocator.cc",
+    "src/tracing/core/inode_file_config.cc",
     "src/tracing/core/null_trace_writer.cc",
     "src/tracing/core/packet_stream_validator.cc",
+    "src/tracing/core/process_stats_config.cc",
     "src/tracing/core/service_impl.cc",
     "src/tracing/core/shared_memory_abi.cc",
     "src/tracing/core/shared_memory_arbiter_impl.cc",
@@ -173,8 +175,10 @@
     "src/tracing/core/data_source_descriptor.cc",
     "src/tracing/core/ftrace_config.cc",
     "src/tracing/core/id_allocator.cc",
+    "src/tracing/core/inode_file_config.cc",
     "src/tracing/core/null_trace_writer.cc",
     "src/tracing/core/packet_stream_validator.cc",
+    "src/tracing/core/process_stats_config.cc",
     "src/tracing/core/service_impl.cc",
     "src/tracing/core/shared_memory_abi.cc",
     "src/tracing/core/shared_memory_arbiter_impl.cc",
@@ -316,8 +320,10 @@
     "src/tracing/core/data_source_descriptor.cc",
     "src/tracing/core/ftrace_config.cc",
     "src/tracing/core/id_allocator.cc",
+    "src/tracing/core/inode_file_config.cc",
     "src/tracing/core/null_trace_writer.cc",
     "src/tracing/core/packet_stream_validator.cc",
+    "src/tracing/core/process_stats_config.cc",
     "src/tracing/core/service_impl.cc",
     "src/tracing/core/shared_memory_abi.cc",
     "src/tracing/core/shared_memory_arbiter_impl.cc",
@@ -415,6 +421,8 @@
     "protos/perfetto/config/data_source_config.proto",
     "protos/perfetto/config/data_source_descriptor.proto",
     "protos/perfetto/config/ftrace/ftrace_config.proto",
+    "protos/perfetto/config/inode_file/inode_file_config.proto",
+    "protos/perfetto/config/process_stats/process_stats_config.proto",
     "protos/perfetto/config/test_config.proto",
     "protos/perfetto/config/trace_config.proto",
   ],
@@ -427,6 +435,8 @@
     "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/inode_file/inode_file_config.pb.cc",
+    "external/perfetto/protos/perfetto/config/process_stats/process_stats_config.pb.cc",
     "external/perfetto/protos/perfetto/config/test_config.pb.cc",
     "external/perfetto/protos/perfetto/config/trace_config.pb.cc",
   ],
@@ -440,6 +450,8 @@
     "protos/perfetto/config/data_source_config.proto",
     "protos/perfetto/config/data_source_descriptor.proto",
     "protos/perfetto/config/ftrace/ftrace_config.proto",
+    "protos/perfetto/config/inode_file/inode_file_config.proto",
+    "protos/perfetto/config/process_stats/process_stats_config.proto",
     "protos/perfetto/config/test_config.proto",
     "protos/perfetto/config/trace_config.proto",
   ],
@@ -452,6 +464,8 @@
     "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/inode_file/inode_file_config.pb.h",
+    "external/perfetto/protos/perfetto/config/process_stats/process_stats_config.pb.h",
     "external/perfetto/protos/perfetto/config/test_config.pb.h",
     "external/perfetto/protos/perfetto/config/trace_config.pb.h",
   ],
@@ -468,6 +482,8 @@
     "protos/perfetto/config/data_source_config.proto",
     "protos/perfetto/config/data_source_descriptor.proto",
     "protos/perfetto/config/ftrace/ftrace_config.proto",
+    "protos/perfetto/config/inode_file/inode_file_config.proto",
+    "protos/perfetto/config/process_stats/process_stats_config.proto",
     "protos/perfetto/config/test_config.proto",
     "protos/perfetto/config/trace_config.proto",
   ],
@@ -481,6 +497,8 @@
     "external/perfetto/protos/perfetto/config/data_source_config.pbzero.cc",
     "external/perfetto/protos/perfetto/config/data_source_descriptor.pbzero.cc",
     "external/perfetto/protos/perfetto/config/ftrace/ftrace_config.pbzero.cc",
+    "external/perfetto/protos/perfetto/config/inode_file/inode_file_config.pbzero.cc",
+    "external/perfetto/protos/perfetto/config/process_stats/process_stats_config.pbzero.cc",
     "external/perfetto/protos/perfetto/config/test_config.pbzero.cc",
     "external/perfetto/protos/perfetto/config/trace_config.pbzero.cc",
   ],
@@ -494,6 +512,8 @@
     "protos/perfetto/config/data_source_config.proto",
     "protos/perfetto/config/data_source_descriptor.proto",
     "protos/perfetto/config/ftrace/ftrace_config.proto",
+    "protos/perfetto/config/inode_file/inode_file_config.proto",
+    "protos/perfetto/config/process_stats/process_stats_config.proto",
     "protos/perfetto/config/test_config.proto",
     "protos/perfetto/config/trace_config.proto",
   ],
@@ -507,6 +527,8 @@
     "external/perfetto/protos/perfetto/config/data_source_config.pbzero.h",
     "external/perfetto/protos/perfetto/config/data_source_descriptor.pbzero.h",
     "external/perfetto/protos/perfetto/config/ftrace/ftrace_config.pbzero.h",
+    "external/perfetto/protos/perfetto/config/inode_file/inode_file_config.pbzero.h",
+    "external/perfetto/protos/perfetto/config/process_stats/process_stats_config.pbzero.h",
     "external/perfetto/protos/perfetto/config/test_config.pbzero.h",
     "external/perfetto/protos/perfetto/config/trace_config.pbzero.h",
   ],
@@ -3134,8 +3156,10 @@
     "src/tracing/core/data_source_descriptor.cc",
     "src/tracing/core/ftrace_config.cc",
     "src/tracing/core/id_allocator.cc",
+    "src/tracing/core/inode_file_config.cc",
     "src/tracing/core/null_trace_writer.cc",
     "src/tracing/core/packet_stream_validator.cc",
+    "src/tracing/core/process_stats_config.cc",
     "src/tracing/core/service_impl.cc",
     "src/tracing/core/shared_memory_abi.cc",
     "src/tracing/core/shared_memory_arbiter_impl.cc",
@@ -3362,11 +3386,13 @@
     "src/tracing/core/ftrace_config.cc",
     "src/tracing/core/id_allocator.cc",
     "src/tracing/core/id_allocator_unittest.cc",
+    "src/tracing/core/inode_file_config.cc",
     "src/tracing/core/null_trace_writer.cc",
     "src/tracing/core/null_trace_writer_unittest.cc",
     "src/tracing/core/packet_stream_validator.cc",
     "src/tracing/core/packet_stream_validator_unittest.cc",
     "src/tracing/core/patch_list_unittest.cc",
+    "src/tracing/core/process_stats_config.cc",
     "src/tracing/core/service_impl.cc",
     "src/tracing/core/service_impl_unittest.cc",
     "src/tracing/core/shared_memory_abi.cc",
diff --git a/gn/standalone/BUILD.gn b/gn/standalone/BUILD.gn
index d0b8a20..ce1088c 100644
--- a/gn/standalone/BUILD.gn
+++ b/gn/standalone/BUILD.gn
@@ -74,6 +74,7 @@
     cflags += [
       "-fcolor-diagnostics",
       "-Wno-unknown-warning-option",
+      "-fdiagnostics-show-template-tree",
     ]
   } else {
     cflags += [ "-Wno-unknown-warning" ]
diff --git a/include/perfetto/tracing/core/data_source_config.h b/include/perfetto/tracing/core/data_source_config.h
index c722cbb..619168b 100644
--- a/include/perfetto/tracing/core/data_source_config.h
+++ b/include/perfetto/tracing/core/data_source_config.h
@@ -37,6 +37,8 @@
 
 #include "perfetto/tracing/core/chrome_config.h"
 #include "perfetto/tracing/core/ftrace_config.h"
+#include "perfetto/tracing/core/inode_file_config.h"
+#include "perfetto/tracing/core/process_stats_config.h"
 #include "perfetto/tracing/core/test_config.h"
 
 // Forward declarations for protobuf types.
@@ -45,6 +47,9 @@
 class DataSourceConfig;
 class FtraceConfig;
 class ChromeConfig;
+class InodeFileConfig;
+class InodeFileConfig_MountPointMappingEntry;
+class ProcessStatsConfig;
 class TestConfig;
 }  // namespace protos
 }  // namespace perfetto
@@ -79,6 +84,18 @@
   const ChromeConfig& chrome_config() const { return chrome_config_; }
   ChromeConfig* mutable_chrome_config() { return &chrome_config_; }
 
+  const InodeFileConfig& inode_file_config() const {
+    return inode_file_config_;
+  }
+  InodeFileConfig* mutable_inode_file_config() { return &inode_file_config_; }
+
+  const ProcessStatsConfig& process_stats_config() const {
+    return process_stats_config_;
+  }
+  ProcessStatsConfig* mutable_process_stats_config() {
+    return &process_stats_config_;
+  }
+
   const std::string& legacy_config() const { return legacy_config_; }
   void set_legacy_config(const std::string& value) { legacy_config_ = value; }
 
@@ -91,6 +108,8 @@
   uint32_t trace_duration_ms_ = {};
   FtraceConfig ftrace_config_ = {};
   ChromeConfig chrome_config_ = {};
+  InodeFileConfig inode_file_config_ = {};
+  ProcessStatsConfig process_stats_config_ = {};
   std::string legacy_config_ = {};
   TestConfig for_testing_ = {};
 
diff --git a/include/perfetto/tracing/core/inode_file_config.h b/include/perfetto/tracing/core/inode_file_config.h
new file mode 100644
index 0000000..7704fcd
--- /dev/null
+++ b/include/perfetto/tracing/core/inode_file_config.h
@@ -0,0 +1,143 @@
+/*
+ * 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/inode_file/inode_file_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_INODE_FILE_CONFIG_H_
+#define INCLUDE_PERFETTO_TRACING_CORE_INODE_FILE_CONFIG_H_
+
+#include <stdint.h>
+#include <string>
+#include <type_traits>
+#include <vector>
+
+#include "perfetto/base/export.h"
+
+// Forward declarations for protobuf types.
+namespace perfetto {
+namespace protos {
+class InodeFileConfig;
+class InodeFileConfig_MountPointMappingEntry;
+}  // namespace protos
+}  // namespace perfetto
+
+namespace perfetto {
+
+class PERFETTO_EXPORT InodeFileConfig {
+ public:
+  class PERFETTO_EXPORT MountPointMappingEntry {
+   public:
+    MountPointMappingEntry();
+    ~MountPointMappingEntry();
+    MountPointMappingEntry(MountPointMappingEntry&&) noexcept;
+    MountPointMappingEntry& operator=(MountPointMappingEntry&&);
+    MountPointMappingEntry(const MountPointMappingEntry&);
+    MountPointMappingEntry& operator=(const MountPointMappingEntry&);
+
+    // Conversion methods from/to the corresponding protobuf types.
+    void FromProto(
+        const perfetto::protos::InodeFileConfig_MountPointMappingEntry&);
+    void ToProto(
+        perfetto::protos::InodeFileConfig_MountPointMappingEntry*) const;
+
+    const std::string& mountpoint() const { return mountpoint_; }
+    void set_mountpoint(const std::string& value) { mountpoint_ = value; }
+
+    int scan_roots_size() const { return static_cast<int>(scan_roots_.size()); }
+    const std::vector<std::string>& scan_roots() const { return scan_roots_; }
+    std::string* add_scan_roots() {
+      scan_roots_.emplace_back();
+      return &scan_roots_.back();
+    }
+
+   private:
+    std::string mountpoint_ = {};
+    std::vector<std::string> scan_roots_;
+
+    // Allows to preserve unknown protobuf fields for compatibility
+    // with future versions of .proto files.
+    std::string unknown_fields_;
+  };
+
+  InodeFileConfig();
+  ~InodeFileConfig();
+  InodeFileConfig(InodeFileConfig&&) noexcept;
+  InodeFileConfig& operator=(InodeFileConfig&&);
+  InodeFileConfig(const InodeFileConfig&);
+  InodeFileConfig& operator=(const InodeFileConfig&);
+
+  // Conversion methods from/to the corresponding protobuf types.
+  void FromProto(const perfetto::protos::InodeFileConfig&);
+  void ToProto(perfetto::protos::InodeFileConfig*) const;
+
+  uint64_t scan_interval_ms() const { return scan_interval_ms_; }
+  void set_scan_interval_ms(uint64_t value) { scan_interval_ms_ = value; }
+
+  uint64_t scan_delay_ms() const { return scan_delay_ms_; }
+  void set_scan_delay_ms(uint64_t value) { scan_delay_ms_ = value; }
+
+  uint64_t scan_batch_size() const { return scan_batch_size_; }
+  void set_scan_batch_size(uint64_t value) { scan_batch_size_ = value; }
+
+  bool do_not_scan() const { return do_not_scan_; }
+  void set_do_not_scan(bool value) { do_not_scan_ = value; }
+
+  int scan_mount_points_size() const {
+    return static_cast<int>(scan_mount_points_.size());
+  }
+  const std::vector<std::string>& scan_mount_points() const {
+    return scan_mount_points_;
+  }
+  std::string* add_scan_mount_points() {
+    scan_mount_points_.emplace_back();
+    return &scan_mount_points_.back();
+  }
+
+  int mount_point_mapping_size() const {
+    return static_cast<int>(mount_point_mapping_.size());
+  }
+  const std::vector<MountPointMappingEntry>& mount_point_mapping() const {
+    return mount_point_mapping_;
+  }
+  MountPointMappingEntry* add_mount_point_mapping() {
+    mount_point_mapping_.emplace_back();
+    return &mount_point_mapping_.back();
+  }
+
+ private:
+  uint64_t scan_interval_ms_ = {};
+  uint64_t scan_delay_ms_ = {};
+  uint64_t scan_batch_size_ = {};
+  bool do_not_scan_ = {};
+  std::vector<std::string> scan_mount_points_;
+  std::vector<MountPointMappingEntry> mount_point_mapping_;
+
+  // 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_INODE_FILE_CONFIG_H_
diff --git a/include/perfetto/tracing/core/process_stats_config.h b/include/perfetto/tracing/core/process_stats_config.h
new file mode 100644
index 0000000..2601ca0
--- /dev/null
+++ b/include/perfetto/tracing/core/process_stats_config.h
@@ -0,0 +1,81 @@
+/*
+ * 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/process_stats/process_stats_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_PROCESS_STATS_CONFIG_H_
+#define INCLUDE_PERFETTO_TRACING_CORE_PROCESS_STATS_CONFIG_H_
+
+#include <stdint.h>
+#include <string>
+#include <type_traits>
+#include <vector>
+
+#include "perfetto/base/export.h"
+
+// Forward declarations for protobuf types.
+namespace perfetto {
+namespace protos {
+class ProcessStatsConfig;
+}
+}  // namespace perfetto
+
+namespace perfetto {
+
+class PERFETTO_EXPORT ProcessStatsConfig {
+ public:
+  enum Quirks {
+    QUIRKS_UNSPECIFIED = 0,
+    DISABLE_INITIAL_DUMP = 1,
+    DISABLE_ON_DEMAND = 2,
+  };
+  ProcessStatsConfig();
+  ~ProcessStatsConfig();
+  ProcessStatsConfig(ProcessStatsConfig&&) noexcept;
+  ProcessStatsConfig& operator=(ProcessStatsConfig&&);
+  ProcessStatsConfig(const ProcessStatsConfig&);
+  ProcessStatsConfig& operator=(const ProcessStatsConfig&);
+
+  // Conversion methods from/to the corresponding protobuf types.
+  void FromProto(const perfetto::protos::ProcessStatsConfig&);
+  void ToProto(perfetto::protos::ProcessStatsConfig*) const;
+
+  int quirks_size() const { return static_cast<int>(quirks_.size()); }
+  const std::vector<Quirks>& quirks() const { return quirks_; }
+  Quirks* add_quirks() {
+    quirks_.emplace_back();
+    return &quirks_.back();
+  }
+
+ private:
+  std::vector<Quirks> quirks_;
+
+  // 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_PROCESS_STATS_CONFIG_H_
diff --git a/include/perfetto/tracing/core/trace_config.h b/include/perfetto/tracing/core/trace_config.h
index 2d5bde6..2097906 100644
--- a/include/perfetto/tracing/core/trace_config.h
+++ b/include/perfetto/tracing/core/trace_config.h
@@ -46,6 +46,9 @@
 class DataSourceConfig;
 class FtraceConfig;
 class ChromeConfig;
+class InodeFileConfig;
+class InodeFileConfig_MountPointMappingEntry;
+class ProcessStatsConfig;
 class TestConfig;
 class TraceConfig_ProducerConfig;
 class TraceConfig_StatsdMetadata;
diff --git a/protos/perfetto/config/BUILD.gn b/protos/perfetto/config/BUILD.gn
index 77dc8613..74fa6c1 100644
--- a/protos/perfetto/config/BUILD.gn
+++ b/protos/perfetto/config/BUILD.gn
@@ -25,6 +25,8 @@
     "data_source_config.proto",
     "data_source_descriptor.proto",
     "ftrace/ftrace_config.proto",
+    "inode_file/inode_file_config.proto",
+    "process_stats/process_stats_config.proto",
     "test_config.proto",
     "trace_config.proto",
   ]
@@ -38,6 +40,8 @@
     "data_source_config.proto",
     "data_source_descriptor.proto",
     "ftrace/ftrace_config.proto",
+    "inode_file/inode_file_config.proto",
+    "process_stats/process_stats_config.proto",
     "test_config.proto",
     "trace_config.proto",
   ]
diff --git a/protos/perfetto/config/data_source_config.proto b/protos/perfetto/config/data_source_config.proto
index 07824fe..c7b2f21 100644
--- a/protos/perfetto/config/data_source_config.proto
+++ b/protos/perfetto/config/data_source_config.proto
@@ -21,6 +21,8 @@
 
 import "perfetto/config/chrome/chrome_config.proto";
 import "perfetto/config/ftrace/ftrace_config.proto";
+import "perfetto/config/inode_file/inode_file_config.proto";
+import "perfetto/config/process_stats/process_stats_config.proto";
 import "perfetto/config/test_config.proto";
 // When editing this file run ./tools/gen_tracing_cpp_headers_from_protos.py
 // to reflect changes in the corresponding C++ headers.
@@ -49,6 +51,8 @@
 
   optional FtraceConfig ftrace_config = 100;
   optional ChromeConfig chrome_config = 101;
+  optional InodeFileConfig inode_file_config = 102;
+  optional ProcessStatsConfig process_stats_config = 103;
 
   // This is a fallback mechanism to send a free-form text config to the
   // producer. In theory this should never be needed. All the code that
diff --git a/protos/perfetto/config/inode_file/inode_file_config.proto b/protos/perfetto/config/inode_file/inode_file_config.proto
new file mode 100644
index 0000000..a1127ff
--- /dev/null
+++ b/protos/perfetto/config/inode_file/inode_file_config.proto
@@ -0,0 +1,50 @@
+/*
+ * 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 InodeFileConfig {
+  message MountPointMappingEntry {
+    optional string mountpoint = 1;
+    repeated string scan_roots = 2;
+  }
+
+  // How long to pause between batches.
+  optional uint64 scan_interval_ms = 1;
+
+  // How long to wait before the first scan in order to accumulate inodes.
+  optional uint64 scan_delay_ms = 2;
+
+  // How many inodes to scan in one batch.
+  optional uint64 scan_batch_size = 3;
+
+  // Do not scan for inodes not found in the static map.
+  optional bool do_not_scan = 4;
+
+  // If non-empty, only scan inodes corresponding to block devices named in
+  // this list.
+  repeated string scan_mount_points = 5;
+
+  // When encountering an inode belonging to a block device corresponding
+  // to one of the mount points in this map, scan its scan_roots instead.
+  repeated MountPointMappingEntry mount_point_mapping = 6;
+}
diff --git a/protos/perfetto/config/perfetto_config.proto b/protos/perfetto/config/perfetto_config.proto
index e8f5d7b..4efae27 100644
--- a/protos/perfetto/config/perfetto_config.proto
+++ b/protos/perfetto/config/perfetto_config.proto
@@ -22,6 +22,58 @@
 
 // End of protos/perfetto/config/chrome/chrome_config.proto
 
+// Begin of protos/perfetto/config/inode_file/inode_file_config.proto
+
+// When editing this file run ./tools/gen_tracing_cpp_headers_from_protos.py
+// to reflect changes in the corresponding C++ headers.
+
+message InodeFileConfig {
+  message MountPointMappingEntry {
+    optional string mountpoint = 1;
+    repeated string scan_roots = 2;
+  }
+
+  // How long to pause between batches.
+  optional uint64 scan_interval_ms = 1;
+
+  // How long to wait before the first scan in order to accumulate inodes.
+  optional uint64 scan_delay_ms = 2;
+
+  // How many inodes to scan in one batch.
+  optional uint64 scan_batch_size = 3;
+
+  // Do not scan for inodes not found in the static map.
+  optional bool do_not_scan = 4;
+
+  // If non-empty, only scan inodes corresponding to block devices named in
+  // this list.
+  repeated string scan_mount_points = 5;
+
+  // When encountering an inode belonging to a block device corresponding
+  // to one of the mount points in this map, scan its scan_roots instead.
+  repeated MountPointMappingEntry mount_point_mapping = 6;
+}
+
+// End of protos/perfetto/config/inode_file/inode_file_config.proto
+
+// Begin of protos/perfetto/config/process_stats/process_stats_config.proto
+
+// When editing this file run ./tools/gen_tracing_cpp_headers_from_protos.py
+// to reflect changes in the corresponding C++ headers.
+
+message ProcessStatsConfig {
+  enum Quirks {
+    QUIRKS_UNSPECIFIED = 0;
+    DISABLE_INITIAL_DUMP = 1;
+    // TODO(taylori) Not implemented.
+    DISABLE_ON_DEMAND = 2;
+  }
+
+  repeated Quirks quirks = 1;
+}
+
+// End of protos/perfetto/config/process_stats/process_stats_config.proto
+
 // Begin of protos/perfetto/config/data_source_config.proto
 
 // When editing this file run ./tools/gen_tracing_cpp_headers_from_protos.py
@@ -51,6 +103,8 @@
 
   optional FtraceConfig ftrace_config = 100;
   optional ChromeConfig chrome_config = 101;
+  optional InodeFileConfig inode_file_config = 102;
+  optional ProcessStatsConfig process_stats_config = 103;
 
   // This is a fallback mechanism to send a free-form text config to the
   // producer. In theory this should never be needed. All the code that
diff --git a/protos/perfetto/config/process_stats/process_stats_config.proto b/protos/perfetto/config/process_stats/process_stats_config.proto
new file mode 100644
index 0000000..bce97e7
--- /dev/null
+++ b/protos/perfetto/config/process_stats/process_stats_config.proto
@@ -0,0 +1,34 @@
+/*
+ * 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.
+ */
+
+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 ProcessStatsConfig {
+  enum Quirks {
+    QUIRKS_UNSPECIFIED = 0;
+    DISABLE_INITIAL_DUMP = 1;
+    // TODO(taylori) Not implemented.
+    DISABLE_ON_DEMAND = 2;
+  }
+
+  repeated Quirks quirks = 1;
+}
diff --git a/src/traced/probes/filesystem/inode_file_data_source.cc b/src/traced/probes/filesystem/inode_file_data_source.cc
index b75fc02..fd70ff7 100644
--- a/src/traced/probes/filesystem/inode_file_data_source.cc
+++ b/src/traced/probes/filesystem/inode_file_data_source.cc
@@ -33,8 +33,37 @@
 
 namespace perfetto {
 namespace {
-const int kScanIntervalMs = 10000;  // 10s
-uint64_t kScanBatchSize = 15000;
+constexpr uint64_t kScanIntervalMs = 10000;  // 10s
+constexpr uint64_t kScanDelayMs = 10000;     // 10s
+constexpr uint64_t kScanBatchSize = 15000;
+
+uint64_t OrDefault(uint64_t value, uint64_t def) {
+  if (value != 0)
+    return value;
+  return def;
+}
+
+std::string DbgFmt(const std::vector<std::string>& values) {
+  if (values.empty())
+    return "";
+
+  std::string result;
+  for (auto it = values.cbegin(); it != values.cend() - 1; ++it)
+    result += *it + ",";
+
+  result += values.back();
+  return result;
+}
+
+std::map<std::string, std::vector<std::string>> BuildMountpointMapping(
+    const DataSourceConfig& source_config) {
+  std::map<std::string, std::vector<std::string>> m;
+  for (const auto& map_entry :
+       source_config.inode_file_config().mount_point_mapping())
+    m.emplace(map_entry.mountpoint(), map_entry.scan_roots());
+
+  return m;
+}
 
 class StaticMapDelegate : public FileScanner::Delegate {
  public:
@@ -57,7 +86,8 @@
   void OnInodeScanDone() {}
   std::map<BlockDeviceID, std::unordered_map<Inode, InodeMapValue>>* map_;
 };
-}
+
+}  // namespace
 
 void CreateStaticDeviceToInodeMap(
     const std::string& root_directory,
@@ -79,13 +109,19 @@
 }
 
 InodeFileDataSource::InodeFileDataSource(
+    DataSourceConfig source_config,
     base::TaskRunner* task_runner,
     TracingSessionID id,
     std::map<BlockDeviceID, std::unordered_map<Inode, InodeMapValue>>*
         static_file_map,
     LRUInodeCache* cache,
     std::unique_ptr<TraceWriter> writer)
-    : task_runner_(task_runner),
+    : source_config_(std::move(source_config)),
+      scan_mount_points_(
+          source_config_.inode_file_config().scan_mount_points().cbegin(),
+          source_config_.inode_file_config().scan_mount_points().cend()),
+      mount_point_mapping_(BuildMountpointMapping(source_config_)),
+      task_runner_(task_runner),
       session_id_(id),
       static_file_map_(static_file_map),
       cache_(cache),
@@ -163,7 +199,25 @@
     // paths/type
     AddInodesFromStaticMap(block_device_id, &inode_numbers);
     AddInodesFromLRUCache(block_device_id, &inode_numbers);
-    // TODO(azappone): Make root directory a mount point
+
+    if (source_config_.inode_file_config().do_not_scan())
+      inode_numbers.clear();
+
+    // If we defined mount points we want to scan in the config,
+    // skip inodes on other mount points.
+    if (!scan_mount_points_.empty()) {
+      bool process = true;
+      auto range = mount_points_.equal_range(block_device_id);
+      for (auto it = range.first; it != range.second; ++it) {
+        if (scan_mount_points_.count(it->second) == 0) {
+          process = false;
+          break;
+        }
+      }
+      if (!process)
+        continue;
+    }
+
     if (!inode_numbers.empty()) {
       // Try to piggy back the current scan.
       auto it = missing_inodes_.find(block_device_id);
@@ -174,7 +228,6 @@
                                                    inode_numbers.cend());
       if (!scan_running_) {
         scan_running_ = true;
-        PERFETTO_DLOG("Posting to scan filesystem in %d ms", kScanIntervalMs);
         auto weak_this = GetWeakPtr();
         task_runner_->PostDelayedTask(
             [weak_this] {
@@ -184,7 +237,7 @@
               }
               weak_this.get()->FindMissingInodes();
             },
-            kScanIntervalMs);
+            GetScanDelayMs());
       }
     }
   }
@@ -216,12 +269,10 @@
     Inode inode_number,
     const std::string& path,
     protos::pbzero::InodeFileMap_Entry_Type type) {
-  PERFETTO_DLOG("Saw %s %lu", path.c_str(), block_device_id);
   auto it = missing_inodes_.find(block_device_id);
   if (it == missing_inodes_.end())
     return true;
 
-  PERFETTO_DLOG("Missing %lu / %lu", missing_inodes_.size(), it->second.size());
   size_t n = it->second.erase(inode_number);
   if (n == 0)
     return true;
@@ -266,15 +317,25 @@
           }
           weak_this->FindMissingInodes();
         },
-        kScanIntervalMs);
+        GetScanDelayMs());
   }
 }
 
 void InodeFileDataSource::AddRootsForBlockDevice(
     BlockDeviceID block_device_id,
     std::vector<std::string>* roots) {
-  auto p = mount_points_.equal_range(block_device_id);
-  for (auto it = p.first; it != p.second; ++it)
+  auto range = mount_points_.equal_range(block_device_id);
+  for (auto it = range.first; it != range.second; ++it) {
+    PERFETTO_DLOG("Trying to replace %s", it->second.c_str());
+    auto replace_it = mount_point_mapping_.find(it->second);
+    if (replace_it != mount_point_mapping_.end()) {
+      roots->insert(roots->end(), replace_it->second.cbegin(),
+                    replace_it->second.cend());
+      return;
+    }
+  }
+
+  for (auto it = range.first; it != range.second; ++it)
     roots->emplace_back(it->second);
 }
 
@@ -286,12 +347,28 @@
 
   PERFETTO_DCHECK(file_scanner_.get() == nullptr);
   auto weak_this = GetWeakPtr();
-  file_scanner_ = std::unique_ptr<FileScanner>(
-      new FileScanner(std::move(roots), this, kScanIntervalMs, kScanBatchSize));
+  PERFETTO_DLOG("Starting scan of %s", DbgFmt(roots).c_str());
+  file_scanner_ = std::unique_ptr<FileScanner>(new FileScanner(
+      std::move(roots), this, GetScanIntervalMs(), GetScanBatchSize()));
 
   file_scanner_->Scan(task_runner_);
 }
 
+uint64_t InodeFileDataSource::GetScanIntervalMs() {
+  return OrDefault(source_config_.inode_file_config().scan_interval_ms(),
+                   kScanIntervalMs);
+}
+
+uint64_t InodeFileDataSource::GetScanDelayMs() {
+  return OrDefault(source_config_.inode_file_config().scan_delay_ms(),
+                   kScanDelayMs);
+}
+
+uint64_t InodeFileDataSource::GetScanBatchSize() {
+  return OrDefault(source_config_.inode_file_config().scan_batch_size(),
+                   kScanBatchSize);
+}
+
 base::WeakPtr<InodeFileDataSource> InodeFileDataSource::GetWeakPtr() const {
   return weak_factory_.GetWeakPtr();
 }
diff --git a/src/traced/probes/filesystem/inode_file_data_source.h b/src/traced/probes/filesystem/inode_file_data_source.h
index e7ce1ed..1f4197f 100644
--- a/src/traced/probes/filesystem/inode_file_data_source.h
+++ b/src/traced/probes/filesystem/inode_file_data_source.h
@@ -29,6 +29,7 @@
 #include "perfetto/base/weak_ptr.h"
 #include "perfetto/traced/data_source_types.h"
 #include "perfetto/tracing/core/basic_types.h"
+#include "perfetto/tracing/core/data_source_config.h"
 #include "perfetto/tracing/core/trace_writer.h"
 #include "src/traced/probes/filesystem/file_scanner.h"
 #include "src/traced/probes/filesystem/fs_mount.h"
@@ -61,6 +62,7 @@
 class InodeFileDataSource : public FileScanner::Delegate {
  public:
   InodeFileDataSource(
+      DataSourceConfig,
       base::TaskRunner*,
       TracingSessionID,
       std::map<BlockDeviceID, std::unordered_map<Inode, InodeMapValue>>*
@@ -95,6 +97,14 @@
   void AddRootsForBlockDevice(BlockDeviceID block_device_id,
                               std::vector<std::string>* roots);
 
+  uint64_t GetScanIntervalMs();
+  uint64_t GetScanDelayMs();
+  uint64_t GetScanBatchSize();
+
+  const DataSourceConfig source_config_;
+  std::set<std::string> scan_mount_points_;
+  std::map<std::string, std::vector<std::string>> mount_point_mapping_;
+
   base::TaskRunner* task_runner_;
   const TracingSessionID session_id_;
   std::map<BlockDeviceID, std::unordered_map<Inode, InodeMapValue>>*
diff --git a/src/traced/probes/probes_producer.cc b/src/traced/probes/probes_producer.cc
index a18181d..c6ea68a 100644
--- a/src/traced/probes/probes_producer.cc
+++ b/src/traced/probes/probes_producer.cc
@@ -180,16 +180,17 @@
 void ProbesProducer::CreateInodeFileDataSourceInstance(
     TracingSessionID session_id,
     DataSourceInstanceID id,
-    const DataSourceConfig& source_config) {
+    DataSourceConfig source_config) {
   PERFETTO_LOG("Inode file map start (id=%" PRIu64 ", target_buf=%" PRIu32 ")",
                id, source_config.target_buffer());
   auto trace_writer = endpoint_->CreateTraceWriter(
       static_cast<BufferID>(source_config.target_buffer()));
   if (system_inodes_.empty())
     CreateStaticDeviceToInodeMap("/system", &system_inodes_);
-  auto file_map_source = std::unique_ptr<InodeFileDataSource>(
-      new InodeFileDataSource(task_runner_, session_id, &system_inodes_,
-                              &cache_, std::move(trace_writer)));
+  auto file_map_source =
+      std::unique_ptr<InodeFileDataSource>(new InodeFileDataSource(
+          std::move(source_config), task_runner_, session_id, &system_inodes_,
+          &cache_, std::move(trace_writer)));
   file_map_sources_.emplace(id, std::move(file_map_source));
   AddWatchdogsTimer(id, source_config);
 }
@@ -205,6 +206,13 @@
       new ProcessStatsDataSource(session_id, std::move(trace_writer)));
   auto it_and_inserted = process_stats_sources_.emplace(id, std::move(source));
   PERFETTO_DCHECK(it_and_inserted.second);
+  if (std::find(config.process_stats_config().quirks().begin(),
+                config.process_stats_config().quirks().end(),
+                ProcessStatsConfig::DISABLE_INITIAL_DUMP) !=
+      config.process_stats_config().quirks().end()) {
+    PERFETTO_DLOG("Initial process tree dump is disabled.");
+    return;
+  }
   it_and_inserted.first->second->WriteAllProcesses();
 }
 
diff --git a/src/traced/probes/probes_producer.h b/src/traced/probes/probes_producer.h
index bd550c7..eb45935 100644
--- a/src/traced/probes/probes_producer.h
+++ b/src/traced/probes/probes_producer.h
@@ -60,7 +60,7 @@
                                             const DataSourceConfig& config);
   void CreateInodeFileDataSourceInstance(TracingSessionID session_id,
                                          DataSourceInstanceID id,
-                                         const DataSourceConfig& config);
+                                         DataSourceConfig config);
 
   void OnMetadata(const FtraceMetadata& metadata);
 
diff --git a/src/tracing/BUILD.gn b/src/tracing/BUILD.gn
index 80aedb4..68eee89 100644
--- a/src/tracing/BUILD.gn
+++ b/src/tracing/BUILD.gn
@@ -37,11 +37,13 @@
     "core/ftrace_config.cc",
     "core/id_allocator.cc",
     "core/id_allocator.h",
+    "core/inode_file_config.cc",
     "core/null_trace_writer.cc",
     "core/null_trace_writer.h",
     "core/packet_stream_validator.cc",
     "core/packet_stream_validator.h",
     "core/patch_list.h",
+    "core/process_stats_config.cc",
     "core/service_impl.cc",
     "core/service_impl.h",
     "core/shared_memory_abi.cc",
diff --git a/src/tracing/core/data_source_config.cc b/src/tracing/core/data_source_config.cc
index d4f0fc1..56192e8 100644
--- a/src/tracing/core/data_source_config.cc
+++ b/src/tracing/core/data_source_config.cc
@@ -30,6 +30,8 @@
 #include "perfetto/config/chrome/chrome_config.pb.h"
 #include "perfetto/config/data_source_config.pb.h"
 #include "perfetto/config/ftrace/ftrace_config.pb.h"
+#include "perfetto/config/inode_file/inode_file_config.pb.h"
+#include "perfetto/config/process_stats/process_stats_config.pb.h"
 #include "perfetto/config/test_config.pb.h"
 
 namespace perfetto {
@@ -60,6 +62,10 @@
 
   chrome_config_.FromProto(proto.chrome_config());
 
+  inode_file_config_.FromProto(proto.inode_file_config());
+
+  process_stats_config_.FromProto(proto.process_stats_config());
+
   static_assert(sizeof(legacy_config_) == sizeof(proto.legacy_config()),
                 "size mismatch");
   legacy_config_ = static_cast<decltype(legacy_config_)>(proto.legacy_config());
@@ -90,6 +96,10 @@
 
   chrome_config_.ToProto(proto->mutable_chrome_config());
 
+  inode_file_config_.ToProto(proto->mutable_inode_file_config());
+
+  process_stats_config_.ToProto(proto->mutable_process_stats_config());
+
   static_assert(sizeof(legacy_config_) == sizeof(proto->legacy_config()),
                 "size mismatch");
   proto->set_legacy_config(
diff --git a/src/tracing/core/ftrace_config.cc b/src/tracing/core/ftrace_config.cc
index 34d8ef4..cf0891f 100644
--- a/src/tracing/core/ftrace_config.cc
+++ b/src/tracing/core/ftrace_config.cc
@@ -84,19 +84,21 @@
   proto->Clear();
 
   for (const auto& it : ftrace_events_) {
-    proto->add_ftrace_events(it);
+    proto->add_ftrace_events(
+        static_cast<decltype(proto->ftrace_events(0))>(it));
     static_assert(sizeof(it) == sizeof(proto->ftrace_events(0)),
                   "size mismatch");
   }
 
   for (const auto& it : atrace_categories_) {
-    proto->add_atrace_categories(it);
+    proto->add_atrace_categories(
+        static_cast<decltype(proto->atrace_categories(0))>(it));
     static_assert(sizeof(it) == sizeof(proto->atrace_categories(0)),
                   "size mismatch");
   }
 
   for (const auto& it : atrace_apps_) {
-    proto->add_atrace_apps(it);
+    proto->add_atrace_apps(static_cast<decltype(proto->atrace_apps(0))>(it));
     static_assert(sizeof(it) == sizeof(proto->atrace_apps(0)), "size mismatch");
   }
 
diff --git a/src/tracing/core/inode_file_config.cc b/src/tracing/core/inode_file_config.cc
new file mode 100644
index 0000000..bd831bc
--- /dev/null
+++ b/src/tracing/core/inode_file_config.cc
@@ -0,0 +1,161 @@
+/*
+ * 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/inode_file/inode_file_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/inode_file_config.h"
+
+#include "perfetto/config/inode_file/inode_file_config.pb.h"
+
+namespace perfetto {
+
+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;
+
+void InodeFileConfig::FromProto(
+    const perfetto::protos::InodeFileConfig& proto) {
+  static_assert(sizeof(scan_interval_ms_) == sizeof(proto.scan_interval_ms()),
+                "size mismatch");
+  scan_interval_ms_ =
+      static_cast<decltype(scan_interval_ms_)>(proto.scan_interval_ms());
+
+  static_assert(sizeof(scan_delay_ms_) == sizeof(proto.scan_delay_ms()),
+                "size mismatch");
+  scan_delay_ms_ = static_cast<decltype(scan_delay_ms_)>(proto.scan_delay_ms());
+
+  static_assert(sizeof(scan_batch_size_) == sizeof(proto.scan_batch_size()),
+                "size mismatch");
+  scan_batch_size_ =
+      static_cast<decltype(scan_batch_size_)>(proto.scan_batch_size());
+
+  static_assert(sizeof(do_not_scan_) == sizeof(proto.do_not_scan()),
+                "size mismatch");
+  do_not_scan_ = static_cast<decltype(do_not_scan_)>(proto.do_not_scan());
+
+  scan_mount_points_.clear();
+  for (const auto& field : proto.scan_mount_points()) {
+    scan_mount_points_.emplace_back();
+    static_assert(
+        sizeof(scan_mount_points_.back()) == sizeof(proto.scan_mount_points(0)),
+        "size mismatch");
+    scan_mount_points_.back() =
+        static_cast<decltype(scan_mount_points_)::value_type>(field);
+  }
+
+  mount_point_mapping_.clear();
+  for (const auto& field : proto.mount_point_mapping()) {
+    mount_point_mapping_.emplace_back();
+    mount_point_mapping_.back().FromProto(field);
+  }
+  unknown_fields_ = proto.unknown_fields();
+}
+
+void InodeFileConfig::ToProto(perfetto::protos::InodeFileConfig* proto) const {
+  proto->Clear();
+
+  static_assert(sizeof(scan_interval_ms_) == sizeof(proto->scan_interval_ms()),
+                "size mismatch");
+  proto->set_scan_interval_ms(
+      static_cast<decltype(proto->scan_interval_ms())>(scan_interval_ms_));
+
+  static_assert(sizeof(scan_delay_ms_) == sizeof(proto->scan_delay_ms()),
+                "size mismatch");
+  proto->set_scan_delay_ms(
+      static_cast<decltype(proto->scan_delay_ms())>(scan_delay_ms_));
+
+  static_assert(sizeof(scan_batch_size_) == sizeof(proto->scan_batch_size()),
+                "size mismatch");
+  proto->set_scan_batch_size(
+      static_cast<decltype(proto->scan_batch_size())>(scan_batch_size_));
+
+  static_assert(sizeof(do_not_scan_) == sizeof(proto->do_not_scan()),
+                "size mismatch");
+  proto->set_do_not_scan(
+      static_cast<decltype(proto->do_not_scan())>(do_not_scan_));
+
+  for (const auto& it : scan_mount_points_) {
+    proto->add_scan_mount_points(
+        static_cast<decltype(proto->scan_mount_points(0))>(it));
+    static_assert(sizeof(it) == sizeof(proto->scan_mount_points(0)),
+                  "size mismatch");
+  }
+
+  for (const auto& it : mount_point_mapping_) {
+    auto* entry = proto->add_mount_point_mapping();
+    it.ToProto(entry);
+  }
+  *(proto->mutable_unknown_fields()) = unknown_fields_;
+}
+
+InodeFileConfig::MountPointMappingEntry::MountPointMappingEntry() = default;
+InodeFileConfig::MountPointMappingEntry::~MountPointMappingEntry() = default;
+InodeFileConfig::MountPointMappingEntry::MountPointMappingEntry(
+    const InodeFileConfig::MountPointMappingEntry&) = default;
+InodeFileConfig::MountPointMappingEntry&
+InodeFileConfig::MountPointMappingEntry::operator=(
+    const InodeFileConfig::MountPointMappingEntry&) = default;
+InodeFileConfig::MountPointMappingEntry::MountPointMappingEntry(
+    InodeFileConfig::MountPointMappingEntry&&) noexcept = default;
+InodeFileConfig::MountPointMappingEntry&
+InodeFileConfig::MountPointMappingEntry::operator=(
+    InodeFileConfig::MountPointMappingEntry&&) = default;
+
+void InodeFileConfig::MountPointMappingEntry::FromProto(
+    const perfetto::protos::InodeFileConfig_MountPointMappingEntry& proto) {
+  static_assert(sizeof(mountpoint_) == sizeof(proto.mountpoint()),
+                "size mismatch");
+  mountpoint_ = static_cast<decltype(mountpoint_)>(proto.mountpoint());
+
+  scan_roots_.clear();
+  for (const auto& field : proto.scan_roots()) {
+    scan_roots_.emplace_back();
+    static_assert(sizeof(scan_roots_.back()) == sizeof(proto.scan_roots(0)),
+                  "size mismatch");
+    scan_roots_.back() = static_cast<decltype(scan_roots_)::value_type>(field);
+  }
+  unknown_fields_ = proto.unknown_fields();
+}
+
+void InodeFileConfig::MountPointMappingEntry::ToProto(
+    perfetto::protos::InodeFileConfig_MountPointMappingEntry* proto) const {
+  proto->Clear();
+
+  static_assert(sizeof(mountpoint_) == sizeof(proto->mountpoint()),
+                "size mismatch");
+  proto->set_mountpoint(
+      static_cast<decltype(proto->mountpoint())>(mountpoint_));
+
+  for (const auto& it : scan_roots_) {
+    proto->add_scan_roots(static_cast<decltype(proto->scan_roots(0))>(it));
+    static_assert(sizeof(it) == sizeof(proto->scan_roots(0)), "size mismatch");
+  }
+  *(proto->mutable_unknown_fields()) = unknown_fields_;
+}
+
+}  // namespace perfetto
diff --git a/src/tracing/core/process_stats_config.cc b/src/tracing/core/process_stats_config.cc
new file mode 100644
index 0000000..fabf7d6
--- /dev/null
+++ b/src/tracing/core/process_stats_config.cc
@@ -0,0 +1,66 @@
+/*
+ * 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/process_stats/process_stats_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/process_stats_config.h"
+
+#include "perfetto/config/process_stats/process_stats_config.pb.h"
+
+namespace perfetto {
+
+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;
+
+void ProcessStatsConfig::FromProto(
+    const perfetto::protos::ProcessStatsConfig& proto) {
+  quirks_.clear();
+  for (const auto& field : proto.quirks()) {
+    quirks_.emplace_back();
+    static_assert(sizeof(quirks_.back()) == sizeof(proto.quirks(0)),
+                  "size mismatch");
+    quirks_.back() = static_cast<decltype(quirks_)::value_type>(field);
+  }
+  unknown_fields_ = proto.unknown_fields();
+}
+
+void ProcessStatsConfig::ToProto(
+    perfetto::protos::ProcessStatsConfig* proto) const {
+  proto->Clear();
+
+  for (const auto& it : quirks_) {
+    proto->add_quirks(static_cast<decltype(proto->quirks(0))>(it));
+    static_assert(sizeof(it) == sizeof(proto->quirks(0)), "size mismatch");
+  }
+  *(proto->mutable_unknown_fields()) = unknown_fields_;
+}
+
+}  // namespace perfetto
diff --git a/src/tracing/core/trace_config.cc b/src/tracing/core/trace_config.cc
index 68d371b..f3bfca5 100644
--- a/src/tracing/core/trace_config.cc
+++ b/src/tracing/core/trace_config.cc
@@ -220,7 +220,8 @@
   config_.ToProto(proto->mutable_config());
 
   for (const auto& it : producer_name_filter_) {
-    proto->add_producer_name_filter(it);
+    proto->add_producer_name_filter(
+        static_cast<decltype(proto->producer_name_filter(0))>(it));
     static_assert(sizeof(it) == sizeof(proto->producer_name_filter(0)),
                   "size mismatch");
   }
diff --git a/test/configs/ftrace.cfg b/test/configs/ftrace.cfg
index 65ea849..4fbc0a5 100644
--- a/test/configs/ftrace.cfg
+++ b/test/configs/ftrace.cfg
@@ -254,6 +254,16 @@
   config {
     name: "linux.inode_file_map"
     target_buffer: 0
+    inode_file_config {
+      scan_delay_ms: 1000
+      scan_interval_ms: 1000
+      scan_batch_size: 100000
+      mount_point_mapping: {
+        mountpoint: "/data"
+        scan_roots: "/data/app"
+        scan_roots: "/data/dalvik-cache"
+      }
+    }
   }
 }
 
diff --git a/tools/gen_merged_trace_config b/tools/gen_merged_trace_config
index 9a7abba..135fd02 100755
--- a/tools/gen_merged_trace_config
+++ b/tools/gen_merged_trace_config
@@ -20,6 +20,8 @@
 
 PROTOS = (
   'protos/perfetto/config/chrome/chrome_config.proto',
+  'protos/perfetto/config/inode_file/inode_file_config.proto',
+  'protos/perfetto/config/process_stats/process_stats_config.proto',
   'protos/perfetto/config/data_source_config.proto',
   'protos/perfetto/config/ftrace/ftrace_config.proto',
   'protos/perfetto/config/test_config.proto',
diff --git a/tools/gen_tracing_cpp_headers_from_protos.py b/tools/gen_tracing_cpp_headers_from_protos.py
index 350c5ad..ce7fdb6 100755
--- a/tools/gen_tracing_cpp_headers_from_protos.py
+++ b/tools/gen_tracing_cpp_headers_from_protos.py
@@ -20,6 +20,8 @@
 PROTOS = (
   'perfetto/config/chrome/chrome_config.proto',
   'perfetto/config/data_source_config.proto',
+  'perfetto/config/inode_file/inode_file_config.proto',
+  'perfetto/config/process_stats/process_stats_config.proto',
   'perfetto/config/data_source_descriptor.proto',
   'perfetto/config/ftrace/ftrace_config.proto',
   'perfetto/config/trace_config.proto',
diff --git a/tools/proto_to_cpp/proto_to_cpp.cc b/tools/proto_to_cpp/proto_to_cpp.cc
index 82fe8c0..6696c57 100644
--- a/tools/proto_to_cpp/proto_to_cpp.cc
+++ b/tools/proto_to_cpp/proto_to_cpp.cc
@@ -451,7 +451,9 @@
         p->Print("  auto* entry = proto->add_$n$();\n", "n", field->name());
         p->Print("  it.ToProto(entry);\n");
       } else {
-        p->Print("  proto->add_$n$(it);\n", "n", field->name());
+        p->Print(
+            "  proto->add_$n$(static_cast<decltype(proto->$n$(0))>(it));\n",
+            "n", field->name());
         p->Print(
             "static_assert(sizeof(it) == sizeof(proto->$n$(0)), \"size "
             "mismatch\");\n",