perfetto: Generate merged trace proto from white listed events

Change-Id: I0affeb6cfeb8df076303fdf2785f3d1af499ea37
diff --git a/PRESUBMIT.py b/PRESUBMIT.py
index 222d364..ad839c4 100644
--- a/PRESUBMIT.py
+++ b/PRESUBMIT.py
@@ -80,16 +80,16 @@
 
 
 def CheckMergedTraceConfigProto(input_api, output_api):
-    tool = 'tools/gen_merged_trace_config'
+    tool = 'tools/gen_merged_protos'
     build_file_filter = lambda x: input_api.FilterSourceFile(
           x,
-          white_list=('protos/perfetto/config/.*[.]proto$', tool))
+          white_list=('protos/perfetto/.*[.]proto$', tool))
     if not input_api.AffectedSourceFiles(build_file_filter):
         return []
     if subprocess.call([tool, '--check-only']):
         return [
             output_api.PresubmitError(
-                'perfetto_config.proto is out of date. Please run ' +
-                tool + ' to update it.')
+                'perfetto_config.proto or perfetto_trace.proto is out of ' +
+                'date. Please run ' + tool + ' to update it.')
         ]
     return []
diff --git a/protos/perfetto/config/perfetto_config.proto b/protos/perfetto/config/perfetto_config.proto
index 066df14..b3c275a 100644
--- a/protos/perfetto/config/perfetto_config.proto
+++ b/protos/perfetto/config/perfetto_config.proto
@@ -1,7 +1,7 @@
 // AUTOGENERATED - DO NOT EDIT
 // ---------------------------
 // This file has been generated by
-// AOSP://external/perfetto/tools/gen_merged_trace_config
+// AOSP://external/perfetto/tools/gen_merged_protos
 // merging the perfetto config protos.
 // This fused proto is intended to be copied in:
 //  - Android tree, for statsd.
diff --git a/protos/perfetto/trace/BUILD.gn b/protos/perfetto/trace/BUILD.gn
index 814de07..d58e354 100644
--- a/protos/perfetto/trace/BUILD.gn
+++ b/protos/perfetto/trace/BUILD.gn
@@ -70,3 +70,14 @@
   proto_in_dir = "$perfetto_root_path/protos"
   proto_out_dir = "$perfetto_root_path/protos"
 }
+
+# This target is not used in the tree and is built only to guarantee that the
+# autogenerated merged proto has a valid syntax.
+proto_library("merged_trace") {
+  generate_python = false
+  proto_in_dir = "$perfetto_root_path/protos"
+  proto_out_dir = "$perfetto_root_path/protos"
+  sources = [
+    "perfetto_trace.proto",
+  ]
+}
diff --git a/protos/perfetto/trace/perfetto_trace.proto b/protos/perfetto/trace/perfetto_trace.proto
new file mode 100644
index 0000000..8ef1530
--- /dev/null
+++ b/protos/perfetto/trace/perfetto_trace.proto
@@ -0,0 +1,897 @@
+// AUTOGENERATED - DO NOT EDIT
+// ---------------------------
+// This file has been generated by
+// AOSP://external/perfetto/tools/gen_merged_protos
+// merging the perfetto config protos.
+// This fused proto is intended to be copied in:
+//  - Android tree, for statsd.
+//  - Google internal repos.
+
+syntax = "proto2";
+
+package perfetto.protos;
+
+// Begin of protos/perfetto/trace/trace.proto
+
+message Trace {
+  repeated TracePacket packet = 1;
+
+  // Do NOT add any other field here. This is just a convenience wrapper for
+  // the use case of a trace being saved to a file. There are other cases
+  // (streaming) where TracePacket are directly streamed without being wrapped
+  // in a Trace proto. Nothing should ever rely on the full trace, all the
+  // logic should be based on TracePacket(s).
+}
+
+// End of protos/perfetto/trace/trace.proto
+
+// Begin of protos/perfetto/trace/trace_packet.proto
+
+// The root object emitted by Perfetto. A perfetto trace is just a stream of
+// TracePacket(s).
+//
+// Next id: 7.
+message TracePacket {
+  oneof data {
+    FtraceEventBundle ftrace_events = 1;
+    ProcessTree process_tree = 2;
+    // removed field with id 4
+    // removed field with id 5
+    // removed field with id 6
+
+    // IDs up to 32 are reserved for events that are quite frequent because they
+    // take only one byte to encode their preamble.
+    // removed field with id 33
+
+    // This field is only used for testing.
+    // removed field with id 536870911  // 2^29 - 1, max field id for protos.
+  }
+  // Trusted user id of the producer which generated this packet. Keep in sync
+  // with TrustedPacket.trusted_uid.
+  oneof optional_trusted_uid { int32 trusted_uid = 3; };
+}
+
+// End of protos/perfetto/trace/trace_packet.proto
+
+// Begin of protos/perfetto/trace/ftrace/ftrace_event_bundle.proto
+
+message FtraceEventBundle {
+  optional uint32 cpu = 1;
+  repeated FtraceEvent event = 2;
+  // Total of all overwrite fields from the headers of all kernel
+  // ftrace pages we parsed into this FtraceEventBundle. Zero if
+  // no overwriting occurred, a number larger than zero if some overwriting
+  // occurred.
+  optional uint32 overwrite_count = 3;
+}
+
+// End of protos/perfetto/trace/ftrace/ftrace_event_bundle.proto
+
+// Begin of protos/perfetto/trace/ftrace/ftrace_event.proto
+
+message FtraceEvent {
+  // Nanoseconds since an epoch.
+  // Epoch is configurable by writing into trace_clock.
+  // By default this timestamp is CPU local.
+  // TODO: Figure out a story for reconciling the various clocks.
+  optional uint64 timestamp = 1;
+
+  optional uint32 pid = 2;
+
+  oneof event {
+    // removed field with id 3
+    SchedSwitchFtraceEvent sched_switch = 4;
+    CpufreqInteractiveAlreadyFtraceEvent cpufreq_interactive_already = 5;
+    CpufreqInteractiveBoostFtraceEvent cpufreq_interactive_boost = 6;
+    CpufreqInteractiveNotyetFtraceEvent cpufreq_interactive_notyet = 7;
+    CpufreqInteractiveSetspeedFtraceEvent cpufreq_interactive_setspeed = 8;
+    CpufreqInteractiveTargetFtraceEvent cpufreq_interactive_target = 9;
+    CpufreqInteractiveUnboostFtraceEvent cpufreq_interactive_unboost = 10;
+    CpuFrequencyFtraceEvent cpu_frequency = 11;
+    CpuFrequencyLimitsFtraceEvent cpu_frequency_limits = 12;
+    CpuIdleFtraceEvent cpu_idle = 13;
+    // removed field with id 14
+    // removed field with id 15
+    ClockSetRateFtraceEvent clock_set_rate = 16;
+    SchedWakeupFtraceEvent sched_wakeup = 17;
+    SchedBlockedReasonFtraceEvent sched_blocked_reason = 18;
+    SchedCpuHotplugFtraceEvent sched_cpu_hotplug = 19;
+    // removed field with id 20
+    // removed field with id 21
+    // removed field with id 22
+    // removed field with id 23
+    // removed field with id 24
+    // removed field with id 25
+    // removed field with id 26
+    // removed field with id 27
+    // removed field with id 28
+    // removed field with id 29
+    // removed field with id 30
+    // removed field with id 31
+    // removed field with id 32
+    // removed field with id 33
+    // removed field with id 34
+    LowmemoryKillFtraceEvent lowmemory_kill = 35;
+    // removed field with id 36
+    // removed field with id 37
+    // removed field with id 38
+    // removed field with id 39
+    // removed field with id 40
+    Ext4DaWriteBeginFtraceEvent ext4_da_write_begin = 41;
+    Ext4DaWriteEndFtraceEvent ext4_da_write_end = 42;
+    Ext4SyncFileEnterFtraceEvent ext4_sync_file_enter = 43;
+    Ext4SyncFileExitFtraceEvent ext4_sync_file_exit = 44;
+    BlockRqIssueFtraceEvent block_rq_issue = 45;
+    MmVmscanDirectReclaimBeginFtraceEvent mm_vmscan_direct_reclaim_begin = 46;
+    MmVmscanDirectReclaimEndFtraceEvent mm_vmscan_direct_reclaim_end = 47;
+    MmVmscanKswapdWakeFtraceEvent mm_vmscan_kswapd_wake = 48;
+    MmVmscanKswapdSleepFtraceEvent mm_vmscan_kswapd_sleep = 49;
+    BinderTransactionFtraceEvent binder_transaction = 50;
+    BinderTransactionReceivedFtraceEvent binder_transaction_received = 51;
+    // removed field with id 52
+    BinderLockFtraceEvent binder_lock = 53;
+    BinderLockedFtraceEvent binder_locked = 54;
+    BinderUnlockFtraceEvent binder_unlock = 55;
+    // removed field with id 56
+    // removed field with id 57
+    // removed field with id 58
+    // removed field with id 59
+    // removed field with id 60
+    // removed field with id 61
+    // removed field with id 62
+    // removed field with id 63
+    // removed field with id 64
+    // removed field with id 65
+    // removed field with id 66
+    CgroupAttachTaskFtraceEvent cgroup_attach_task = 67;
+    CgroupMkdirFtraceEvent cgroup_mkdir = 68;
+    CgroupRemountFtraceEvent cgroup_remount = 69;
+    CgroupRmdirFtraceEvent cgroup_rmdir = 70;
+    CgroupTransferTasksFtraceEvent cgroup_transfer_tasks = 71;
+    CgroupDestroyRootFtraceEvent cgroup_destroy_root = 72;
+    CgroupReleaseFtraceEvent cgroup_release = 73;
+    CgroupRenameFtraceEvent cgroup_rename = 74;
+    CgroupSetupRootFtraceEvent cgroup_setup_root = 75;
+    // removed field with id 76
+    // removed field with id 77
+    // removed field with id 78
+    // removed field with id 79
+    // removed field with id 80
+    // removed field with id 81
+    // removed field with id 82
+    // removed field with id 83
+    // removed field with id 84
+    // removed field with id 85
+    // removed field with id 86
+    // removed field with id 87
+    // removed field with id 88
+    // removed field with id 89
+    // removed field with id 90
+    // removed field with id 91
+    // removed field with id 92
+    // removed field with id 93
+    // removed field with id 94
+    // removed field with id 95
+    // removed field with id 96
+    // removed field with id 97
+    // removed field with id 98
+    // removed field with id 99
+    // removed field with id 100
+    // removed field with id 101
+    // removed field with id 102
+    // removed field with id 103
+    // removed field with id 104
+    // removed field with id 105
+    // removed field with id 106
+    // removed field with id 107
+    // removed field with id 108
+    // removed field with id 109
+    // removed field with id 110
+    // removed field with id 111
+    // removed field with id 112
+    // removed field with id 113
+    // removed field with id 114
+    // removed field with id 115
+    // removed field with id 116
+    // removed field with id 117
+    // removed field with id 118
+    // removed field with id 119
+    // removed field with id 120
+    // removed field with id 121
+    // removed field with id 122
+    // removed field with id 123
+    // removed field with id 124
+    BlockRqCompleteFtraceEvent block_rq_complete = 125;
+    // removed field with id 126
+    // removed field with id 128
+    // removed field with id 129
+    // removed field with id 130
+    // removed field with id 131
+    // removed field with id 132
+    // removed field with id 133
+    // removed field with id 134
+    // removed field with id 135
+    // removed field with id 136
+    // removed field with id 137
+    // removed field with id 138
+    // removed field with id 139
+    // removed field with id 140
+    // removed field with id 141
+    // removed field with id 142
+    // removed field with id 143
+    // removed field with id 144
+    // removed field with id 145
+    // removed field with id 146
+    // removed field with id 147
+    // removed field with id 148
+    // removed field with id 149
+    // removed field with id 150
+    // removed field with id 151
+    // removed field with id 152
+    Ext4EsLookupExtentEnterFtraceEvent ext4_es_lookup_extent_enter = 153;
+    Ext4EsLookupExtentExitFtraceEvent ext4_es_lookup_extent_exit = 154;
+    // removed field with id 155
+    // removed field with id 156
+    // removed field with id 157
+    // removed field with id 158
+    // removed field with id 159
+    // removed field with id 160
+    // removed field with id 161
+    // removed field with id 162
+    // removed field with id 163
+    // removed field with id 164
+    // removed field with id 165
+    // removed field with id 166
+    // removed field with id 167
+    // removed field with id 168
+    // removed field with id 169
+    // removed field with id 170
+    // removed field with id 171
+    // removed field with id 172
+    // removed field with id 173
+    // removed field with id 174
+    // removed field with id 175
+    // removed field with id 176
+    // removed field with id 177
+    // removed field with id 178
+    // removed field with id 179
+    // removed field with id 180
+    // removed field with id 181
+    // removed field with id 182
+    // removed field with id 183
+    // removed field with id 184
+    // removed field with id 185
+    // removed field with id 186
+    // removed field with id 187
+    // removed field with id 188
+    // removed field with id 189
+    Ext4LoadInodeFtraceEvent ext4_load_inode = 190;
+    // removed field with id 191
+    // removed field with id 192
+    // removed field with id 193
+    // removed field with id 194
+    // removed field with id 195
+    // removed field with id 196
+    // removed field with id 197
+    // removed field with id 198
+    // removed field with id 199
+    // removed field with id 200
+    // removed field with id 201
+    // removed field with id 202
+    // removed field with id 203
+    // removed field with id 204
+    // removed field with id 205
+    // removed field with id 206
+    // removed field with id 207
+    // removed field with id 208
+    // removed field with id 209
+    // removed field with id 210
+    // removed field with id 211
+    // removed field with id 212
+    // removed field with id 213
+    // removed field with id 214
+    // removed field with id 215
+    // removed field with id 216
+    // removed field with id 217
+    // removed field with id 218
+    // removed field with id 219
+    // removed field with id 230
+    // removed field with id 231
+    // removed field with id 232
+    // removed field with id 233
+    // removed field with id 234
+    // removed field with id 235
+    // removed field with id 236
+    // removed field with id 237
+    // removed field with id 238
+    // removed field with id 239
+    // removed field with id 240
+    // removed field with id 241
+    // removed field with id 242
+    // removed field with id 243
+    // removed field with id 244
+    // removed field with id 245
+    F2fsGetDataBlockFtraceEvent f2fs_get_data_block = 246;
+    // removed field with id 247
+    F2fsIgetFtraceEvent f2fs_iget = 248;
+    // removed field with id 249
+    // removed field with id 250
+    // removed field with id 251
+    // removed field with id 252
+    // removed field with id 253
+    // removed field with id 254
+    F2fsSyncFileEnterFtraceEvent f2fs_sync_file_enter = 255;
+    F2fsSyncFileExitFtraceEvent f2fs_sync_file_exit = 256;
+    // removed field with id 257
+    // removed field with id 258
+    // removed field with id 259
+    // removed field with id 260
+    // removed field with id 261
+    // removed field with id 262
+    // removed field with id 263
+    // removed field with id 264
+    // removed field with id 265
+    // removed field with id 266
+    // removed field with id 267
+    // removed field with id 268
+    // removed field with id 269
+    // removed field with id 270
+    F2fsWriteBeginFtraceEvent f2fs_write_begin = 271;
+    // removed field with id 272
+    F2fsWriteEndFtraceEvent f2fs_write_end = 273;
+  }
+}
+
+// End of protos/perfetto/trace/ftrace/ftrace_event.proto
+
+// Begin of protos/perfetto/trace/ps/process_tree.proto
+
+message ProcessTree {
+  // Representation of a thread
+  message Thread {
+    // The thread id (as per gettid())
+    optional int32 tid = 1;
+
+    // The name of the thread.
+    optional string name = 2;
+  }
+
+  // Representation of a process.
+  message Process {
+    // The UNIX process ID, aka thread group ID (as per getpid()).
+    optional int32 pid = 1;
+
+    // The parent process ID, as per getppid().
+    optional int32 ppid = 2;
+
+    // The command line for the process, as per /proc/pid/cmdline.
+    // If it is a kernel thread there will only be one cmdline field
+    // and it will contain /proc/pid/comm.
+    repeated string cmdline = 3;
+
+    // The list of all threads in the process.
+    repeated Thread threads = 4;
+  }
+
+  // List of all processes in the client.
+  repeated Process processes = 1;
+}
+
+// End of protos/perfetto/trace/ps/process_tree.proto
+
+// Begin of protos/perfetto/trace/ftrace/binder_locked.proto
+
+message BinderLockedFtraceEvent {
+  optional string tag = 1;
+}
+
+// End of protos/perfetto/trace/ftrace/binder_locked.proto
+
+// Begin of protos/perfetto/trace/ftrace/binder_lock.proto
+
+message BinderLockFtraceEvent {
+  optional string tag = 1;
+}
+
+// End of protos/perfetto/trace/ftrace/binder_lock.proto
+
+// Begin of protos/perfetto/trace/ftrace/binder_transaction.proto
+
+message BinderTransactionFtraceEvent {
+  optional int32 debug_id = 1;
+  optional int32 target_node = 2;
+  optional int32 to_proc = 3;
+  optional int32 to_thread = 4;
+  optional int32 reply = 5;
+  optional uint32 code = 6;
+  optional uint32 flags = 7;
+}
+
+// End of protos/perfetto/trace/ftrace/binder_transaction.proto
+
+// Begin of protos/perfetto/trace/ftrace/binder_transaction_received.proto
+
+message BinderTransactionReceivedFtraceEvent {
+  optional int32 debug_id = 1;
+}
+
+// End of protos/perfetto/trace/ftrace/binder_transaction_received.proto
+
+// Begin of protos/perfetto/trace/ftrace/binder_unlock.proto
+
+message BinderUnlockFtraceEvent {
+  optional string tag = 1;
+}
+
+// End of protos/perfetto/trace/ftrace/binder_unlock.proto
+
+// Begin of protos/perfetto/trace/ftrace/block_rq_complete.proto
+
+message BlockRqCompleteFtraceEvent {
+  optional uint64 dev = 1;
+  optional uint64 sector = 2;
+  optional uint32 nr_sector = 3;
+  optional int32 errors = 4;
+  optional string rwbs = 5;
+  optional string cmd = 6;
+}
+
+// End of protos/perfetto/trace/ftrace/block_rq_complete.proto
+
+// Begin of protos/perfetto/trace/ftrace/block_rq_issue.proto
+
+message BlockRqIssueFtraceEvent {
+  optional uint64 dev = 1;
+  optional uint64 sector = 2;
+  optional uint32 nr_sector = 3;
+  optional uint32 bytes = 4;
+  optional string rwbs = 5;
+  optional string comm = 6;
+  optional string cmd = 7;
+}
+
+// End of protos/perfetto/trace/ftrace/block_rq_issue.proto
+
+// Begin of protos/perfetto/trace/ftrace/cgroup_attach_task.proto
+
+message CgroupAttachTaskFtraceEvent {
+  optional int32 dst_root = 1;
+  optional int32 dst_id = 2;
+  optional int32 pid = 3;
+  optional string comm = 4;
+  optional string cname = 5;
+}
+
+// End of protos/perfetto/trace/ftrace/cgroup_attach_task.proto
+
+// Begin of protos/perfetto/trace/ftrace/cgroup_destroy_root.proto
+
+message CgroupDestroyRootFtraceEvent {
+  optional int32 root = 1;
+  optional uint32 ss_mask = 2;
+  optional string name = 3;
+}
+
+// End of protos/perfetto/trace/ftrace/cgroup_destroy_root.proto
+
+// Begin of protos/perfetto/trace/ftrace/cgroup_mkdir.proto
+
+message CgroupMkdirFtraceEvent {
+  optional int32 root = 1;
+  optional int32 id = 2;
+  optional string cname = 3;
+}
+
+// End of protos/perfetto/trace/ftrace/cgroup_mkdir.proto
+
+// Begin of protos/perfetto/trace/ftrace/cgroup_release.proto
+
+message CgroupReleaseFtraceEvent {
+  optional int32 root = 1;
+  optional int32 id = 2;
+  optional string cname = 3;
+}
+
+// End of protos/perfetto/trace/ftrace/cgroup_release.proto
+
+// Begin of protos/perfetto/trace/ftrace/cgroup_remount.proto
+
+message CgroupRemountFtraceEvent {
+  optional int32 root = 1;
+  optional uint32 ss_mask = 2;
+  optional string name = 3;
+}
+
+// End of protos/perfetto/trace/ftrace/cgroup_remount.proto
+
+// Begin of protos/perfetto/trace/ftrace/cgroup_rename.proto
+
+message CgroupRenameFtraceEvent {
+  optional int32 root = 1;
+  optional int32 id = 2;
+  optional string cname = 3;
+}
+
+// End of protos/perfetto/trace/ftrace/cgroup_rename.proto
+
+// Begin of protos/perfetto/trace/ftrace/cgroup_rmdir.proto
+
+message CgroupRmdirFtraceEvent {
+  optional int32 root = 1;
+  optional int32 id = 2;
+  optional string cname = 3;
+}
+
+// End of protos/perfetto/trace/ftrace/cgroup_rmdir.proto
+
+// Begin of protos/perfetto/trace/ftrace/cgroup_setup_root.proto
+
+message CgroupSetupRootFtraceEvent {
+  optional int32 root = 1;
+  optional uint32 ss_mask = 2;
+  optional string name = 3;
+}
+
+// End of protos/perfetto/trace/ftrace/cgroup_setup_root.proto
+
+// Begin of protos/perfetto/trace/ftrace/cgroup_transfer_tasks.proto
+
+message CgroupTransferTasksFtraceEvent {
+  optional int32 dst_root = 1;
+  optional int32 dst_id = 2;
+  optional int32 pid = 3;
+  optional string comm = 4;
+  optional string cname = 5;
+}
+
+// End of protos/perfetto/trace/ftrace/cgroup_transfer_tasks.proto
+
+// Begin of protos/perfetto/trace/ftrace/clock_set_rate.proto
+
+message ClockSetRateFtraceEvent {
+  optional string name = 1;
+  optional uint64 state = 2;
+  optional uint64 cpu_id = 3;
+}
+
+// End of protos/perfetto/trace/ftrace/clock_set_rate.proto
+
+// Begin of protos/perfetto/trace/ftrace/cpufreq_interactive_already.proto
+
+message CpufreqInteractiveAlreadyFtraceEvent {
+  optional uint64 cpu_id = 1;
+  optional uint64 load = 2;
+  optional uint64 curtarg = 3;
+  optional uint64 curactual = 4;
+  optional uint64 newtarg = 5;
+}
+
+// End of protos/perfetto/trace/ftrace/cpufreq_interactive_already.proto
+
+// Begin of protos/perfetto/trace/ftrace/cpufreq_interactive_boost.proto
+
+message CpufreqInteractiveBoostFtraceEvent {
+  optional string s = 1;
+}
+
+// End of protos/perfetto/trace/ftrace/cpufreq_interactive_boost.proto
+
+// Begin of protos/perfetto/trace/ftrace/cpufreq_interactive_notyet.proto
+
+message CpufreqInteractiveNotyetFtraceEvent {
+  optional uint64 cpu_id = 1;
+  optional uint64 load = 2;
+  optional uint64 curtarg = 3;
+  optional uint64 curactual = 4;
+  optional uint64 newtarg = 5;
+}
+
+// End of protos/perfetto/trace/ftrace/cpufreq_interactive_notyet.proto
+
+// Begin of protos/perfetto/trace/ftrace/cpufreq_interactive_setspeed.proto
+
+message CpufreqInteractiveSetspeedFtraceEvent {
+  optional uint32 cpu_id = 1;
+  optional uint64 targfreq = 2;
+  optional uint64 actualfreq = 3;
+}
+
+// End of protos/perfetto/trace/ftrace/cpufreq_interactive_setspeed.proto
+
+// Begin of protos/perfetto/trace/ftrace/cpufreq_interactive_target.proto
+
+message CpufreqInteractiveTargetFtraceEvent {
+  optional uint64 cpu_id = 1;
+  optional uint64 load = 2;
+  optional uint64 curtarg = 3;
+  optional uint64 curactual = 4;
+  optional uint64 newtarg = 5;
+}
+
+// End of protos/perfetto/trace/ftrace/cpufreq_interactive_target.proto
+
+// Begin of protos/perfetto/trace/ftrace/cpufreq_interactive_unboost.proto
+
+message CpufreqInteractiveUnboostFtraceEvent {
+  optional string s = 1;
+}
+
+// End of protos/perfetto/trace/ftrace/cpufreq_interactive_unboost.proto
+
+// Begin of protos/perfetto/trace/ftrace/cpu_frequency_limits.proto
+
+message CpuFrequencyLimitsFtraceEvent {
+  optional uint32 min_freq = 1;
+  optional uint32 max_freq = 2;
+  optional uint32 cpu_id = 3;
+}
+
+// End of protos/perfetto/trace/ftrace/cpu_frequency_limits.proto
+
+// Begin of protos/perfetto/trace/ftrace/cpu_frequency.proto
+
+message CpuFrequencyFtraceEvent {
+  optional uint32 state = 1;
+  optional uint32 cpu_id = 2;
+}
+
+// End of protos/perfetto/trace/ftrace/cpu_frequency.proto
+
+// Begin of protos/perfetto/trace/ftrace/cpu_idle.proto
+
+message CpuIdleFtraceEvent {
+  optional uint32 state = 1;
+  optional uint32 cpu_id = 2;
+}
+
+// End of protos/perfetto/trace/ftrace/cpu_idle.proto
+
+// Begin of protos/perfetto/trace/ftrace/ext4_da_write_begin.proto
+
+message Ext4DaWriteBeginFtraceEvent {
+  optional uint64 dev = 1;
+  optional uint64 ino = 2;
+  optional int64 pos = 3;
+  optional uint32 len = 4;
+  optional uint32 flags = 5;
+}
+
+// End of protos/perfetto/trace/ftrace/ext4_da_write_begin.proto
+
+// Begin of protos/perfetto/trace/ftrace/ext4_da_write_end.proto
+
+message Ext4DaWriteEndFtraceEvent {
+  optional uint64 dev = 1;
+  optional uint64 ino = 2;
+  optional int64 pos = 3;
+  optional uint32 len = 4;
+  optional uint32 copied = 5;
+}
+
+// End of protos/perfetto/trace/ftrace/ext4_da_write_end.proto
+
+// Begin of protos/perfetto/trace/ftrace/ext4_es_lookup_extent_enter.proto
+
+message Ext4EsLookupExtentEnterFtraceEvent {
+  optional uint64 dev = 1;
+  optional uint64 ino = 2;
+  optional uint32 lblk = 3;
+}
+
+// End of protos/perfetto/trace/ftrace/ext4_es_lookup_extent_enter.proto
+
+// Begin of protos/perfetto/trace/ftrace/ext4_es_lookup_extent_exit.proto
+
+message Ext4EsLookupExtentExitFtraceEvent {
+  optional uint64 dev = 1;
+  optional uint64 ino = 2;
+  optional uint32 lblk = 3;
+  optional uint32 len = 4;
+  optional uint64 pblk = 5;
+  optional uint32 status = 6;
+  optional int32 found = 7;
+}
+
+// End of protos/perfetto/trace/ftrace/ext4_es_lookup_extent_exit.proto
+
+// Begin of protos/perfetto/trace/ftrace/ext4_load_inode.proto
+
+message Ext4LoadInodeFtraceEvent {
+  optional uint64 dev = 1;
+  optional uint64 ino = 2;
+}
+
+// End of protos/perfetto/trace/ftrace/ext4_load_inode.proto
+
+// Begin of protos/perfetto/trace/ftrace/ext4_sync_file_enter.proto
+
+message Ext4SyncFileEnterFtraceEvent {
+  optional uint64 dev = 1;
+  optional uint64 ino = 2;
+  optional uint64 parent = 3;
+  optional int32 datasync = 4;
+}
+
+// End of protos/perfetto/trace/ftrace/ext4_sync_file_enter.proto
+
+// Begin of protos/perfetto/trace/ftrace/ext4_sync_file_exit.proto
+
+message Ext4SyncFileExitFtraceEvent {
+  optional uint64 dev = 1;
+  optional uint64 ino = 2;
+  optional int32 ret = 3;
+}
+
+// End of protos/perfetto/trace/ftrace/ext4_sync_file_exit.proto
+
+// Begin of protos/perfetto/trace/ftrace/f2fs_get_data_block.proto
+
+message F2fsGetDataBlockFtraceEvent {
+  optional uint64 dev = 1;
+  optional uint64 ino = 2;
+  optional uint64 iblock = 3;
+  optional uint64 bh_start = 4;
+  optional uint64 bh_size = 5;
+  optional int32 ret = 6;
+}
+
+// End of protos/perfetto/trace/ftrace/f2fs_get_data_block.proto
+
+// Begin of protos/perfetto/trace/ftrace/f2fs_iget.proto
+
+message F2fsIgetFtraceEvent {
+  optional uint64 dev = 1;
+  optional uint64 ino = 2;
+  optional uint64 pino = 3;
+  optional uint32 mode = 4;
+  optional int64 size = 5;
+  optional uint32 nlink = 6;
+  optional uint64 blocks = 7;
+  optional uint32 advise = 8;
+}
+
+// End of protos/perfetto/trace/ftrace/f2fs_iget.proto
+
+// Begin of protos/perfetto/trace/ftrace/f2fs_sync_file_enter.proto
+
+message F2fsSyncFileEnterFtraceEvent {
+  optional uint64 dev = 1;
+  optional uint64 ino = 2;
+  optional uint64 pino = 3;
+  optional uint32 mode = 4;
+  optional int64 size = 5;
+  optional uint32 nlink = 6;
+  optional uint64 blocks = 7;
+  optional uint32 advise = 8;
+}
+
+// End of protos/perfetto/trace/ftrace/f2fs_sync_file_enter.proto
+
+// Begin of protos/perfetto/trace/ftrace/f2fs_sync_file_exit.proto
+
+message F2fsSyncFileExitFtraceEvent {
+  optional uint64 dev = 1;
+  optional uint64 ino = 2;
+  optional uint32 need_cp = 3;
+  optional int32 datasync = 4;
+  optional int32 ret = 5;
+}
+
+// End of protos/perfetto/trace/ftrace/f2fs_sync_file_exit.proto
+
+// Begin of protos/perfetto/trace/ftrace/f2fs_write_begin.proto
+
+message F2fsWriteBeginFtraceEvent {
+  optional uint64 dev = 1;
+  optional uint64 ino = 2;
+  optional int64 pos = 3;
+  optional uint32 len = 4;
+  optional uint32 flags = 5;
+}
+
+// End of protos/perfetto/trace/ftrace/f2fs_write_begin.proto
+
+// Begin of protos/perfetto/trace/ftrace/f2fs_write_end.proto
+
+message F2fsWriteEndFtraceEvent {
+  optional uint64 dev = 1;
+  optional uint64 ino = 2;
+  optional int64 pos = 3;
+  optional uint32 len = 4;
+  optional uint32 copied = 5;
+}
+
+// End of protos/perfetto/trace/ftrace/f2fs_write_end.proto
+
+// Begin of protos/perfetto/trace/ftrace/lowmemory_kill.proto
+
+message LowmemoryKillFtraceEvent {
+  optional string comm = 1;
+  optional int32 pid = 2;
+  optional int64 pagecache_size = 3;
+  optional int64 pagecache_limit = 4;
+  optional int64 free = 5;
+}
+
+// End of protos/perfetto/trace/ftrace/lowmemory_kill.proto
+
+// Begin of protos/perfetto/trace/ftrace/mm_vmscan_direct_reclaim_begin.proto
+
+message MmVmscanDirectReclaimBeginFtraceEvent {
+  optional int32 order = 1;
+  optional int32 may_writepage = 2;
+  optional uint32 gfp_flags = 3;
+}
+
+// End of protos/perfetto/trace/ftrace/mm_vmscan_direct_reclaim_begin.proto
+
+// Begin of protos/perfetto/trace/ftrace/mm_vmscan_direct_reclaim_end.proto
+
+message MmVmscanDirectReclaimEndFtraceEvent {
+  optional uint64 nr_reclaimed = 1;
+}
+
+// End of protos/perfetto/trace/ftrace/mm_vmscan_direct_reclaim_end.proto
+
+// Begin of protos/perfetto/trace/ftrace/mm_vmscan_kswapd_sleep.proto
+
+message MmVmscanKswapdSleepFtraceEvent {
+  optional int32 nid = 1;
+}
+
+// End of protos/perfetto/trace/ftrace/mm_vmscan_kswapd_sleep.proto
+
+// Begin of protos/perfetto/trace/ftrace/mm_vmscan_kswapd_wake.proto
+
+message MmVmscanKswapdWakeFtraceEvent {
+  optional int32 nid = 1;
+  optional int32 order = 2;
+}
+
+// End of protos/perfetto/trace/ftrace/mm_vmscan_kswapd_wake.proto
+
+// Begin of protos/perfetto/trace/ftrace/sched_blocked_reason.proto
+
+message SchedBlockedReasonFtraceEvent {
+  optional int32 pid = 1;
+  optional uint64 caller = 2;
+  optional uint32 io_wait = 3;
+}
+
+// End of protos/perfetto/trace/ftrace/sched_blocked_reason.proto
+
+// Begin of protos/perfetto/trace/ftrace/sched_cpu_hotplug.proto
+
+message SchedCpuHotplugFtraceEvent {
+  optional int32 affected_cpu = 1;
+  optional int32 error = 2;
+  optional int32 status = 3;
+}
+
+// End of protos/perfetto/trace/ftrace/sched_cpu_hotplug.proto
+
+// Begin of protos/perfetto/trace/ftrace/sched_switch.proto
+
+message SchedSwitchFtraceEvent {
+  optional string prev_comm = 1;
+  optional int32 prev_pid = 2;
+  optional int32 prev_prio = 3;
+  optional int64 prev_state = 4;
+  optional string next_comm = 5;
+  optional int32 next_pid = 6;
+  optional int32 next_prio = 7;
+}
+
+// End of protos/perfetto/trace/ftrace/sched_switch.proto
+
+// Begin of protos/perfetto/trace/ftrace/sched_wakeup.proto
+
+message SchedWakeupFtraceEvent {
+  optional string comm = 1;
+  optional int32 pid = 2;
+  optional int32 prio = 3;
+  optional int32 success = 4;
+  optional int32 target_cpu = 5;
+}
+
+// End of protos/perfetto/trace/ftrace/sched_wakeup.proto
diff --git a/tools/gen_merged_protos b/tools/gen_merged_protos
new file mode 100755
index 0000000..3588720
--- /dev/null
+++ b/tools/gen_merged_protos
@@ -0,0 +1,178 @@
+#!/usr/bin/env python
+# 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.
+
+from __future__ import absolute_import
+from __future__ import division
+from __future__ import print_function
+import os
+import re
+import subprocess
+import sys
+
+CONFIG_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',
+  'protos/perfetto/config/trace_config.proto',
+)
+
+MERGED_CONFIG_PROTO = 'protos/perfetto/config/perfetto_config.proto'
+
+TRACE_PROTOS = (
+  'protos/perfetto/trace/trace.proto',
+  'protos/perfetto/trace/trace_packet.proto',
+  'protos/perfetto/trace/ftrace/ftrace_event_bundle.proto',
+  'protos/perfetto/trace/ftrace/ftrace_event.proto',
+  'protos/perfetto/trace/ps/process_tree.proto',
+
+  # FTrace events
+  # Generated by tools/protos_from_genfs_contexts.sh.
+  # MISSING cpufreq_interactive_load_change
+  'protos/perfetto/trace/ftrace/binder_locked.proto',
+  'protos/perfetto/trace/ftrace/binder_lock.proto',
+  'protos/perfetto/trace/ftrace/binder_transaction.proto',
+  'protos/perfetto/trace/ftrace/binder_transaction_received.proto',
+  'protos/perfetto/trace/ftrace/binder_unlock.proto',
+  'protos/perfetto/trace/ftrace/block_rq_complete.proto',
+  'protos/perfetto/trace/ftrace/block_rq_issue.proto',
+  'protos/perfetto/trace/ftrace/cgroup_attach_task.proto',
+  'protos/perfetto/trace/ftrace/cgroup_destroy_root.proto',
+  'protos/perfetto/trace/ftrace/cgroup_mkdir.proto',
+  'protos/perfetto/trace/ftrace/cgroup_release.proto',
+  'protos/perfetto/trace/ftrace/cgroup_remount.proto',
+  'protos/perfetto/trace/ftrace/cgroup_rename.proto',
+  'protos/perfetto/trace/ftrace/cgroup_rmdir.proto',
+  'protos/perfetto/trace/ftrace/cgroup_setup_root.proto',
+  'protos/perfetto/trace/ftrace/cgroup_transfer_tasks.proto',
+  'protos/perfetto/trace/ftrace/clock_set_rate.proto',
+  'protos/perfetto/trace/ftrace/cpufreq_interactive_already.proto',
+  'protos/perfetto/trace/ftrace/cpufreq_interactive_boost.proto',
+  'protos/perfetto/trace/ftrace/cpufreq_interactive_notyet.proto',
+  'protos/perfetto/trace/ftrace/cpufreq_interactive_setspeed.proto',
+  'protos/perfetto/trace/ftrace/cpufreq_interactive_target.proto',
+  'protos/perfetto/trace/ftrace/cpufreq_interactive_unboost.proto',
+  'protos/perfetto/trace/ftrace/cpu_frequency_limits.proto',
+  'protos/perfetto/trace/ftrace/cpu_frequency.proto',
+  'protos/perfetto/trace/ftrace/cpu_idle.proto',
+  'protos/perfetto/trace/ftrace/ext4_da_write_begin.proto',
+  'protos/perfetto/trace/ftrace/ext4_da_write_end.proto',
+  'protos/perfetto/trace/ftrace/ext4_es_lookup_extent_enter.proto',
+  'protos/perfetto/trace/ftrace/ext4_es_lookup_extent_exit.proto',
+  'protos/perfetto/trace/ftrace/ext4_load_inode.proto',
+  'protos/perfetto/trace/ftrace/ext4_sync_file_enter.proto',
+  'protos/perfetto/trace/ftrace/ext4_sync_file_exit.proto',
+  'protos/perfetto/trace/ftrace/f2fs_get_data_block.proto',
+  'protos/perfetto/trace/ftrace/f2fs_iget.proto',
+  'protos/perfetto/trace/ftrace/f2fs_sync_file_enter.proto',
+  'protos/perfetto/trace/ftrace/f2fs_sync_file_exit.proto',
+  'protos/perfetto/trace/ftrace/f2fs_write_begin.proto',
+  'protos/perfetto/trace/ftrace/f2fs_write_end.proto',
+  'protos/perfetto/trace/ftrace/lowmemory_kill.proto',
+  'protos/perfetto/trace/ftrace/mm_vmscan_direct_reclaim_begin.proto',
+  'protos/perfetto/trace/ftrace/mm_vmscan_direct_reclaim_end.proto',
+  'protos/perfetto/trace/ftrace/mm_vmscan_kswapd_sleep.proto',
+  'protos/perfetto/trace/ftrace/mm_vmscan_kswapd_wake.proto',
+  'protos/perfetto/trace/ftrace/sched_blocked_reason.proto',
+  'protos/perfetto/trace/ftrace/sched_cpu_hotplug.proto',
+  'protos/perfetto/trace/ftrace/sched_switch.proto',
+  'protos/perfetto/trace/ftrace/sched_wakeup.proto',
+)
+
+MERGED_TRACE_PROTO = 'protos/perfetto/trace/perfetto_trace.proto'
+
+REPLACEMENT_HEADER = '''
+// AUTOGENERATED - DO NOT EDIT
+// ---------------------------
+// This file has been generated by
+// AOSP://external/perfetto/%s
+// merging the perfetto config protos.
+// This fused proto is intended to be copied in:
+//  - Android tree, for statsd.
+//  - Google internal repos.
+
+syntax = "proto2";
+
+package perfetto.protos;
+'''
+
+def merge_protos(proto_paths, output_path):
+  root_dir = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
+  merged_content = ''
+  for proto in proto_paths:
+    path = os.path.join(root_dir, proto)
+    with open(path) as f:
+      content = f.read()
+
+    # Remove header
+    header = re.match(r'\/(\*|\/)(?:.|\s)*?package.*;\n', content)
+    header = header.group(0)
+    content = content[len(header):]
+    if merged_content == '':
+      merged_content += REPLACEMENT_HEADER.lstrip() % __file__
+    content = re.sub(r'^import.*?\n', '', content, flags=re.MULTILINE)
+    content = re.sub(r'TODO\([^)]*\):', 'TODO:', content)
+    merged_content += '\n// Begin of %s\n' % proto
+    merged_content += content
+    merged_content += '\n// End of %s\n' % proto
+
+  definitions_re = r'^ *(?:message|enum) ([A-Z][A-Za-z0-9].*) {'
+  definitions = re.finditer(definitions_re, merged_content, re.MULTILINE)
+  types = set((match.group(1) for match in definitions))
+
+  uses_re = r'^( +)(?:repeated)?\s?([A-Z]\w+.*)\s+[a-z]\w+\s*=\s*(\d+);'
+  uses = re.finditer(uses_re, merged_content, re.MULTILINE)
+  substitutions = []
+  for use in uses:
+    everything = use.group(0)
+    indentation = use.group(1)
+    used_type = use.group(2)
+    field_number = use.group(3)
+    if used_type not in types:
+      # replacement = '{}reserved {};'.format(indentation, field_number)
+      replacement = '{}// removed field with id {}'.format(
+          indentation, field_number)
+      substitutions.append((everything, replacement))
+
+  for before, after in substitutions:
+    merged_content = merged_content.replace(before, after)
+
+  out_path = os.path.join(root_dir, output_path)
+
+  prev_content = None
+  if os.path.exists(out_path):
+    with open(out_path, 'rb') as fprev:
+      prev_content = fprev.read()
+
+  if prev_content == merged_content:
+    return True
+
+  if '--check-only' in sys.argv:
+    return False
+
+  print('Updating {}'.format(output_path))
+  with open(out_path, 'wb') as fout:
+    fout.write(merged_content)
+  return True
+
+def main():
+  config_result = merge_protos(CONFIG_PROTOS, MERGED_CONFIG_PROTO)
+  trace_result = merge_protos(TRACE_PROTOS, MERGED_TRACE_PROTO)
+  return 0 if config_result and trace_result else 1
+
+if __name__ == '__main__':
+  sys.exit(main())
diff --git a/tools/gen_merged_trace_config b/tools/gen_merged_trace_config
deleted file mode 100755
index 135fd02..0000000
--- a/tools/gen_merged_trace_config
+++ /dev/null
@@ -1,87 +0,0 @@
-#!/usr/bin/env python
-# 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.
-
-import os
-import re
-import subprocess
-import sys
-
-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',
-  'protos/perfetto/config/trace_config.proto',
-)
-
-MERGED_OUT_PROTO = 'protos/perfetto/config/perfetto_config.proto'
-
-REPLACEMENT_HEADER = '''
-// AUTOGENERATED - DO NOT EDIT
-// ---------------------------
-// This file has been generated by
-// AOSP://external/perfetto/%s
-// merging the perfetto config protos.
-// This fused proto is intended to be copied in:
-//  - Android tree, for statsd.
-//  - Google internal repos.
-
-syntax = "proto2";
-
-package perfetto.protos;
-'''
-
-def main():
-  root_dir = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
-  merged_content = ''
-  for proto in PROTOS:
-    path = os.path.join(root_dir, proto)
-    with open(path) as f:
-      content = f.read()
-
-    # Remove header
-    header = re.match(r'\/\*(?:.|\s)*?package.*;\n', content)
-    header = header.group(0)
-    content = content[len(header):]
-    if merged_content == '':
-      merged_content += REPLACEMENT_HEADER.lstrip() % __file__
-    content = re.sub(r'^import.*?\n', '', content, flags=re.MULTILINE)
-    content = re.sub(r'TODO\([^)]*\):', 'TODO:', content)
-    merged_content += '\n// Begin of %s\n' % proto
-    merged_content += content
-    merged_content += '\n// End of %s\n' % proto
-
-  out_path = os.path.join(root_dir, MERGED_OUT_PROTO)
-
-  prev_content = None
-  if os.path.exists(out_path):
-    with open(out_path, 'rb') as fprev:
-      prev_content = fprev.read()
-
-  if prev_content == merged_content:
-    return 0
-
-  if '--check-only' in sys.argv:
-    return 1
-
-  print 'Updating %s' % MERGED_OUT_PROTO
-  with open(out_path, 'wb') as fout:
-    fout.write(merged_content)
-  return 0
-
-if __name__ == '__main__':
-  sys.exit(main())
diff --git a/tools/protos_from_genfs_contexts.sh b/tools/protos_from_genfs_contexts.sh
new file mode 100644
index 0000000..e2e00d9
--- /dev/null
+++ b/tools/protos_from_genfs_contexts.sh
@@ -0,0 +1,30 @@
+#!/bin/bash
+# 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.
+
+for f in $(cat $1 | grep u:object_r:debugfs_tracing:s0 | grep tracing/events | awk '{ print $3 }' | xargs -n1 basename);do
+  if [ -f "protos/perfetto/trace/ftrace/$f.proto" ]; then
+    echo "'protos/perfetto/trace/ftrace/$f.proto',";
+  else
+    for x in $(find src/ftrace_reader/test/data/*/events -wholename '*/'"$f"'/format' -or -wholename '*/'"$f"'/*/format'); do
+      event=$(echo $x | awk -F / '{print $(NF - 1)}')
+      n="protos/perfetto/trace/ftrace/$event.proto";
+      if [ -f $n ]; then
+        echo "'$n',"
+      else
+          echo "# MISSING $event"
+      fi
+    done
+  fi
+done | sort