Add thermal events

Bug:160920914
Change-Id: I56faae158ef295eea293469a024586845d344e0b
diff --git a/Android.bp b/Android.bp
index 1bf9cf2..66ca9a7 100644
--- a/Android.bp
+++ b/Android.bp
@@ -3718,6 +3718,7 @@
     "protos/perfetto/trace/ftrace/systrace.proto",
     "protos/perfetto/trace/ftrace/task.proto",
     "protos/perfetto/trace/ftrace/test_bundle_wrapper.proto",
+    "protos/perfetto/trace/ftrace/thermal.proto",
     "protos/perfetto/trace/ftrace/vmscan.proto",
     "protos/perfetto/trace/ftrace/workqueue.proto",
   ],
@@ -3762,6 +3763,7 @@
     "external/perfetto/protos/perfetto/trace/ftrace/systrace.gen.cc",
     "external/perfetto/protos/perfetto/trace/ftrace/task.gen.cc",
     "external/perfetto/protos/perfetto/trace/ftrace/test_bundle_wrapper.gen.cc",
+    "external/perfetto/protos/perfetto/trace/ftrace/thermal.gen.cc",
     "external/perfetto/protos/perfetto/trace/ftrace/vmscan.gen.cc",
     "external/perfetto/protos/perfetto/trace/ftrace/workqueue.gen.cc",
   ],
@@ -3806,6 +3808,7 @@
     "protos/perfetto/trace/ftrace/systrace.proto",
     "protos/perfetto/trace/ftrace/task.proto",
     "protos/perfetto/trace/ftrace/test_bundle_wrapper.proto",
+    "protos/perfetto/trace/ftrace/thermal.proto",
     "protos/perfetto/trace/ftrace/vmscan.proto",
     "protos/perfetto/trace/ftrace/workqueue.proto",
   ],
@@ -3850,6 +3853,7 @@
     "external/perfetto/protos/perfetto/trace/ftrace/systrace.gen.h",
     "external/perfetto/protos/perfetto/trace/ftrace/task.gen.h",
     "external/perfetto/protos/perfetto/trace/ftrace/test_bundle_wrapper.gen.h",
+    "external/perfetto/protos/perfetto/trace/ftrace/thermal.gen.h",
     "external/perfetto/protos/perfetto/trace/ftrace/vmscan.gen.h",
     "external/perfetto/protos/perfetto/trace/ftrace/workqueue.gen.h",
   ],
@@ -3898,6 +3902,7 @@
     "protos/perfetto/trace/ftrace/systrace.proto",
     "protos/perfetto/trace/ftrace/task.proto",
     "protos/perfetto/trace/ftrace/test_bundle_wrapper.proto",
+    "protos/perfetto/trace/ftrace/thermal.proto",
     "protos/perfetto/trace/ftrace/vmscan.proto",
     "protos/perfetto/trace/ftrace/workqueue.proto",
   ],
@@ -3941,6 +3946,7 @@
     "external/perfetto/protos/perfetto/trace/ftrace/systrace.pb.cc",
     "external/perfetto/protos/perfetto/trace/ftrace/task.pb.cc",
     "external/perfetto/protos/perfetto/trace/ftrace/test_bundle_wrapper.pb.cc",
+    "external/perfetto/protos/perfetto/trace/ftrace/thermal.pb.cc",
     "external/perfetto/protos/perfetto/trace/ftrace/vmscan.pb.cc",
     "external/perfetto/protos/perfetto/trace/ftrace/workqueue.pb.cc",
   ],
@@ -3985,6 +3991,7 @@
     "protos/perfetto/trace/ftrace/systrace.proto",
     "protos/perfetto/trace/ftrace/task.proto",
     "protos/perfetto/trace/ftrace/test_bundle_wrapper.proto",
+    "protos/perfetto/trace/ftrace/thermal.proto",
     "protos/perfetto/trace/ftrace/vmscan.proto",
     "protos/perfetto/trace/ftrace/workqueue.proto",
   ],
@@ -4028,6 +4035,7 @@
     "external/perfetto/protos/perfetto/trace/ftrace/systrace.pb.h",
     "external/perfetto/protos/perfetto/trace/ftrace/task.pb.h",
     "external/perfetto/protos/perfetto/trace/ftrace/test_bundle_wrapper.pb.h",
+    "external/perfetto/protos/perfetto/trace/ftrace/thermal.pb.h",
     "external/perfetto/protos/perfetto/trace/ftrace/vmscan.pb.h",
     "external/perfetto/protos/perfetto/trace/ftrace/workqueue.pb.h",
   ],
@@ -4076,6 +4084,7 @@
     "protos/perfetto/trace/ftrace/systrace.proto",
     "protos/perfetto/trace/ftrace/task.proto",
     "protos/perfetto/trace/ftrace/test_bundle_wrapper.proto",
+    "protos/perfetto/trace/ftrace/thermal.proto",
     "protos/perfetto/trace/ftrace/vmscan.proto",
     "protos/perfetto/trace/ftrace/workqueue.proto",
   ],
@@ -4120,6 +4129,7 @@
     "external/perfetto/protos/perfetto/trace/ftrace/systrace.pbzero.cc",
     "external/perfetto/protos/perfetto/trace/ftrace/task.pbzero.cc",
     "external/perfetto/protos/perfetto/trace/ftrace/test_bundle_wrapper.pbzero.cc",
+    "external/perfetto/protos/perfetto/trace/ftrace/thermal.pbzero.cc",
     "external/perfetto/protos/perfetto/trace/ftrace/vmscan.pbzero.cc",
     "external/perfetto/protos/perfetto/trace/ftrace/workqueue.pbzero.cc",
   ],
@@ -4164,6 +4174,7 @@
     "protos/perfetto/trace/ftrace/systrace.proto",
     "protos/perfetto/trace/ftrace/task.proto",
     "protos/perfetto/trace/ftrace/test_bundle_wrapper.proto",
+    "protos/perfetto/trace/ftrace/thermal.proto",
     "protos/perfetto/trace/ftrace/vmscan.proto",
     "protos/perfetto/trace/ftrace/workqueue.proto",
   ],
@@ -4208,6 +4219,7 @@
     "external/perfetto/protos/perfetto/trace/ftrace/systrace.pbzero.h",
     "external/perfetto/protos/perfetto/trace/ftrace/task.pbzero.h",
     "external/perfetto/protos/perfetto/trace/ftrace/test_bundle_wrapper.pbzero.h",
+    "external/perfetto/protos/perfetto/trace/ftrace/thermal.pbzero.h",
     "external/perfetto/protos/perfetto/trace/ftrace/vmscan.pbzero.h",
     "external/perfetto/protos/perfetto/trace/ftrace/workqueue.pbzero.h",
   ],
diff --git a/BUILD b/BUILD
index 8f1ad2c..1035a99 100644
--- a/BUILD
+++ b/BUILD
@@ -2210,6 +2210,7 @@
         "protos/perfetto/trace/ftrace/systrace.proto",
         "protos/perfetto/trace/ftrace/task.proto",
         "protos/perfetto/trace/ftrace/test_bundle_wrapper.proto",
+        "protos/perfetto/trace/ftrace/thermal.proto",
         "protos/perfetto/trace/ftrace/vmscan.proto",
         "protos/perfetto/trace/ftrace/workqueue.proto",
     ],
diff --git a/protos/perfetto/trace/ftrace/all_protos.gni b/protos/perfetto/trace/ftrace/all_protos.gni
index fc11e54..5eb1823 100644
--- a/protos/perfetto/trace/ftrace/all_protos.gni
+++ b/protos/perfetto/trace/ftrace/all_protos.gni
@@ -50,6 +50,7 @@
   "sync.proto",
   "systrace.proto",
   "task.proto",
+  "thermal.proto",
   "vmscan.proto",
   "workqueue.proto",
 ]
diff --git a/protos/perfetto/trace/ftrace/ftrace_event.proto b/protos/perfetto/trace/ftrace/ftrace_event.proto
index ba8db73..72b2f89 100644
--- a/protos/perfetto/trace/ftrace/ftrace_event.proto
+++ b/protos/perfetto/trace/ftrace/ftrace_event.proto
@@ -50,6 +50,7 @@
 import "protos/perfetto/trace/ftrace/sync.proto";
 import "protos/perfetto/trace/ftrace/systrace.proto";
 import "protos/perfetto/trace/ftrace/task.proto";
+import "protos/perfetto/trace/ftrace/thermal.proto";
 import "protos/perfetto/trace/ftrace/vmscan.proto";
 import "protos/perfetto/trace/ftrace/workqueue.proto";
 import "protos/perfetto/trace/ftrace/generic.proto";
@@ -422,5 +423,7 @@
     ScmCallStartFtraceEvent scm_call_start = 338;
     ScmCallEndFtraceEvent scm_call_end = 339;
     GpuMemTotalFtraceEvent gpu_mem_total = 340;
+    ThermalTemperatureFtraceEvent thermal_temperature = 341;
+    CdevUpdateFtraceEvent cdev_update = 342;
   }
 }
diff --git a/protos/perfetto/trace/ftrace/thermal.proto b/protos/perfetto/trace/ftrace/thermal.proto
new file mode 100644
index 0000000..3aa78d3
--- /dev/null
+++ b/protos/perfetto/trace/ftrace/thermal.proto
@@ -0,0 +1,17 @@
+// Autogenerated by:
+// ../../tools/ftrace_proto_gen/ftrace_proto_gen.cc
+// Do not edit.
+
+syntax = "proto2";
+package perfetto.protos;
+
+message ThermalTemperatureFtraceEvent {
+  optional int32 id = 1;
+  optional int32 temp = 2;
+  optional int32 temp_prev = 3;
+  optional string thermal_zone = 4;
+}
+message CdevUpdateFtraceEvent {
+  optional uint64 target = 1;
+  optional string type = 2;
+}
diff --git a/protos/perfetto/trace/perfetto_trace.proto b/protos/perfetto/trace/perfetto_trace.proto
index 1b54d20..c143295 100644
--- a/protos/perfetto/trace/perfetto_trace.proto
+++ b/protos/perfetto/trace/perfetto_trace.proto
@@ -4349,6 +4349,21 @@
 
 // End of protos/perfetto/trace/ftrace/task.proto
 
+// Begin of protos/perfetto/trace/ftrace/thermal.proto
+
+message ThermalTemperatureFtraceEvent {
+  optional int32 id = 1;
+  optional int32 temp = 2;
+  optional int32 temp_prev = 3;
+  optional string thermal_zone = 4;
+}
+message CdevUpdateFtraceEvent {
+  optional uint64 target = 1;
+  optional string type = 2;
+}
+
+// End of protos/perfetto/trace/ftrace/thermal.proto
+
 // Begin of protos/perfetto/trace/ftrace/vmscan.proto
 
 message MmVmscanDirectReclaimBeginFtraceEvent {
@@ -4759,6 +4774,8 @@
     ScmCallStartFtraceEvent scm_call_start = 338;
     ScmCallEndFtraceEvent scm_call_end = 339;
     GpuMemTotalFtraceEvent gpu_mem_total = 340;
+    ThermalTemperatureFtraceEvent thermal_temperature = 341;
+    CdevUpdateFtraceEvent cdev_update = 342;
   }
 }
 
diff --git a/src/trace_processor/importers/ftrace/ftrace_descriptors.cc b/src/trace_processor/importers/ftrace/ftrace_descriptors.cc
index 477c086..e46321b 100644
--- a/src/trace_processor/importers/ftrace/ftrace_descriptors.cc
+++ b/src/trace_processor/importers/ftrace/ftrace_descriptors.cc
@@ -24,7 +24,7 @@
 namespace trace_processor {
 namespace {
 
-std::array<MessageDescriptor, 338> descriptors{{
+std::array<MessageDescriptor, 343> descriptors{{
     {nullptr, 0, {}},
     {nullptr, 0, {}},
     {nullptr, 0, {}},
@@ -3603,6 +3603,53 @@
             {"len", ProtoSchemaType::kUint64},
         },
     },
+    {
+        "scm_call_start",
+        3,
+        {
+            {},
+            {"arginfo", ProtoSchemaType::kUint32},
+            {"x0", ProtoSchemaType::kUint64},
+            {"x5", ProtoSchemaType::kUint64},
+        },
+    },
+    {
+        "scm_call_end",
+        0,
+        {
+            {},
+        },
+    },
+    {
+        "gpu_mem_total",
+        3,
+        {
+            {},
+            {"gpu_id", ProtoSchemaType::kUint32},
+            {"pid", ProtoSchemaType::kUint32},
+            {"size", ProtoSchemaType::kUint64},
+        },
+    },
+    {
+        "thermal_temperature",
+        4,
+        {
+            {},
+            {"id", ProtoSchemaType::kInt32},
+            {"temp", ProtoSchemaType::kInt32},
+            {"temp_prev", ProtoSchemaType::kInt32},
+            {"thermal_zone", ProtoSchemaType::kString},
+        },
+    },
+    {
+        "cdev_update",
+        2,
+        {
+            {},
+            {"target", ProtoSchemaType::kUint64},
+            {"type", ProtoSchemaType::kString},
+        },
+    },
 }};
 
 }  // namespace
diff --git a/src/trace_processor/importers/ftrace/ftrace_parser.cc b/src/trace_processor/importers/ftrace/ftrace_parser.cc
index 25cd058..644b77f 100644
--- a/src/trace_processor/importers/ftrace/ftrace_parser.cc
+++ b/src/trace_processor/importers/ftrace/ftrace_parser.cc
@@ -47,6 +47,7 @@
 #include "protos/perfetto/trace/ftrace/signal.pbzero.h"
 #include "protos/perfetto/trace/ftrace/systrace.pbzero.h"
 #include "protos/perfetto/trace/ftrace/task.pbzero.h"
+#include "protos/perfetto/trace/ftrace/thermal.pbzero.h"
 #include "protos/perfetto/trace/ftrace/workqueue.pbzero.h"
 
 namespace perfetto {
@@ -441,6 +442,14 @@
         ParseGpuMemTotal(ts, data);
         break;
       }
+      case FtraceEvent::kThermalTemperatureFieldNumber: {
+        ParseThermalTemperature(ts, data);
+        break;
+      }
+      case FtraceEvent::kCdevUpdateFieldNumber: {
+        ParseCdevUpdate(ts, data);
+        break;
+      }
       default:
         break;
     }
@@ -1110,5 +1119,31 @@
   }
 }
 
+void FtraceParser::ParseThermalTemperature(int64_t timestamp,
+                                           protozero::ConstBytes blob) {
+  protos::pbzero::ThermalTemperatureFtraceEvent::Decoder evt(blob.data,
+                                                             blob.size);
+  char counter_name[255];
+  base::StringView thermal_zone = evt.thermal_zone();
+  snprintf(counter_name, sizeof(counter_name), "%.*s Temperature",
+           int(thermal_zone.size()), thermal_zone.data());
+  StringId name = context_->storage->InternString(counter_name);
+  TrackId track = context_->track_tracker->InternGlobalCounterTrack(name);
+  context_->event_tracker->PushCounter(timestamp, evt.temp(), track);
+}
+
+void FtraceParser::ParseCdevUpdate(int64_t timestamp,
+                                   protozero::ConstBytes blob) {
+  protos::pbzero::CdevUpdateFtraceEvent::Decoder evt(blob.data, blob.size);
+  char counter_name[255];
+  base::StringView type = evt.type();
+  snprintf(counter_name, sizeof(counter_name), "%.*s Cooling Device",
+           int(type.size()), type.data());
+  StringId name = context_->storage->InternString(counter_name);
+  TrackId track = context_->track_tracker->InternGlobalCounterTrack(name);
+  context_->event_tracker->PushCounter(
+      timestamp, static_cast<double>(evt.target()), track);
+}
+
 }  // namespace trace_processor
 }  // namespace perfetto
diff --git a/src/trace_processor/importers/ftrace/ftrace_parser.h b/src/trace_processor/importers/ftrace/ftrace_parser.h
index 199e377..85663f3 100644
--- a/src/trace_processor/importers/ftrace/ftrace_parser.h
+++ b/src/trace_processor/importers/ftrace/ftrace_parser.h
@@ -122,6 +122,8 @@
                          protozero::ConstBytes);
   void ParseSoftIrqExit(uint32_t cpu, int64_t timestamp, protozero::ConstBytes);
   void ParseGpuMemTotal(int64_t timestamp, protozero::ConstBytes);
+  void ParseThermalTemperature(int64_t timestamp, protozero::ConstBytes);
+  void ParseCdevUpdate(int64_t timestamp, protozero::ConstBytes);
   TraceProcessorContext* context_;
   RssStatTracker rss_stat_tracker_;
 
diff --git a/src/trace_processor/importers/systrace/systrace_line_parser.cc b/src/trace_processor/importers/systrace/systrace_line_parser.cc
index b27b402..8654eef 100644
--- a/src/trace_processor/importers/systrace/systrace_line_parser.cc
+++ b/src/trace_processor/importers/systrace/systrace_line_parser.cc
@@ -196,6 +196,28 @@
   } else if (line.event_name == "workqueue_execute_end") {
     TrackId track = context_->track_tracker->InternThreadTrack(utid);
     context_->slice_tracker->End(line.ts, track, workqueue_name_id_);
+  } else if (line.event_name == "thermal_temperature") {
+    std::string thermal_zone = args["thermal_zone"] + " Temperature";
+    StringId track_name =
+        context_->storage->InternString(base::StringView(thermal_zone));
+    TrackId track =
+        context_->track_tracker->InternGlobalCounterTrack(track_name);
+    auto temp = base::StringToInt32(args["temp"]);
+    if (!temp.has_value()) {
+      return util::Status("Could not convert temp");
+    }
+    context_->event_tracker->PushCounter(line.ts, temp.value(), track);
+  } else if (line.event_name == "cdev_update") {
+    std::string type = args["type"] + " Cooling Device";
+    StringId track_name =
+        context_->storage->InternString(base::StringView(type));
+    TrackId track =
+        context_->track_tracker->InternGlobalCounterTrack(track_name);
+    auto target = base::StringToDouble(args["target"]);
+    if (!target.has_value()) {
+      return util::Status("Could not convert target");
+    }
+    context_->event_tracker->PushCounter(line.ts, target.value(), track);
   }
 
   return util::OkStatus();
diff --git a/src/traced/probes/ftrace/event_info.cc b/src/traced/probes/ftrace/event_info.cc
index 3449084..a90eca9 100644
--- a/src/traced/probes/ftrace/event_info.cc
+++ b/src/traced/probes/ftrace/event_info.cc
@@ -6165,6 +6165,38 @@
        kUnsetFtraceId,
        236,
        kUnsetSize},
+      {"thermal_temperature",
+       "thermal",
+       {
+           {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+            "id", 1, ProtoSchemaType::kInt32,
+            TranslationStrategy::kInvalidTranslationStrategy},
+           {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+            "temp", 2, ProtoSchemaType::kInt32,
+            TranslationStrategy::kInvalidTranslationStrategy},
+           {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+            "temp_prev", 3, ProtoSchemaType::kInt32,
+            TranslationStrategy::kInvalidTranslationStrategy},
+           {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+            "thermal_zone", 4, ProtoSchemaType::kString,
+            TranslationStrategy::kInvalidTranslationStrategy},
+       },
+       kUnsetFtraceId,
+       341,
+       kUnsetSize},
+      {"cdev_update",
+       "thermal",
+       {
+           {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+            "target", 1, ProtoSchemaType::kUint64,
+            TranslationStrategy::kInvalidTranslationStrategy},
+           {kUnsetOffset, kUnsetSize, FtraceFieldType::kInvalidFtraceFieldType,
+            "type", 2, ProtoSchemaType::kString,
+            TranslationStrategy::kInvalidTranslationStrategy},
+       },
+       kUnsetFtraceId,
+       342,
+       kUnsetSize},
       {"mm_vmscan_direct_reclaim_begin",
        "vmscan",
        {
diff --git a/test/configs/thermal.cfg b/test/configs/thermal.cfg
new file mode 100644
index 0000000..214dfe4
--- /dev/null
+++ b/test/configs/thermal.cfg
@@ -0,0 +1,21 @@
+buffers: {
+    size_kb: 8960
+    fill_policy: DISCARD
+}
+buffers: {
+    size_kb: 1280
+    fill_policy: DISCARD
+}
+data_sources: {
+    config {
+        name: "linux.ftrace"
+        ftrace_config {
+            ftrace_events: "thermal/thermal_temperature"
+            ftrace_events: "thermal/cdev_update"
+            buffer_size_kb: 2048
+            drain_period_ms: 250
+        }
+    }
+}
+duration_ms: 10000
+
diff --git a/tools/ftrace_proto_gen/event_whitelist b/tools/ftrace_proto_gen/event_whitelist
index 0f38e2a..e89131a 100644
--- a/tools/ftrace_proto_gen/event_whitelist
+++ b/tools/ftrace_proto_gen/event_whitelist
@@ -335,3 +335,5 @@
 scm/scm_call_start
 scm/scm_call_end
 gpu_mem/gpu_mem_total
+thermal/thermal_temperature
+thermal/cdev_update