trace_processor: Add sysstats gpufreq tracks

Introduce SysStats gpu frequency track as gpufreq.

Bug: 337135744
Test: build trace_processor locally, run a trace with `gpufreq_period_ms` enabled and check counters
Test: diff tests

Change-Id: Ibfc13ba4e8b81ab549a49f9597bea46bb19d0b4b
diff --git a/src/trace_processor/importers/proto/proto_trace_parser_impl_unittest.cc b/src/trace_processor/importers/proto/proto_trace_parser_impl_unittest.cc
index cbff477..9e4a854 100644
--- a/src/trace_processor/importers/proto/proto_trace_parser_impl_unittest.cc
+++ b/src/trace_processor/importers/proto/proto_trace_parser_impl_unittest.cc
@@ -691,6 +691,20 @@
   EXPECT_EQ(context_.storage->track_table().row_count(), 1u);
 }
 
+TEST_F(ProtoTraceParserTest, LoadGpuFreqStats) {
+  auto* packet = trace_->add_packet();
+  uint64_t ts = 1000;
+  packet->set_timestamp(ts);
+  auto* bundle = packet->set_sys_stats();
+  bundle->add_gpufreq_mhz(300);
+  EXPECT_CALL(*event_, PushCounter(static_cast<int64_t>(ts),
+                                   static_cast<double>(300), TrackId{1u}));
+  Tokenize();
+  context_.sorter->ExtractEventsForced();
+
+  EXPECT_EQ(context_.storage->track_table().row_count(), 2u);
+}
+
 TEST_F(ProtoTraceParserTest, LoadMemInfo) {
   auto* packet = trace_->add_packet();
   uint64_t ts = 1000;
diff --git a/src/trace_processor/importers/proto/system_probes_parser.cc b/src/trace_processor/importers/proto/system_probes_parser.cc
index 24e2a69..ad153aa 100644
--- a/src/trace_processor/importers/proto/system_probes_parser.cc
+++ b/src/trace_processor/importers/proto/system_probes_parser.cc
@@ -134,7 +134,9 @@
       num_softirq_total_name_id_(
           context->storage->InternString("num_softirq_total")),
       oom_score_adj_id_(context->storage->InternString("oom_score_adj")),
-      thermal_unit_id_(context->storage->InternString("C")) {
+      thermal_unit_id_(context->storage->InternString("C")),
+      gpufreq_id(context->storage->InternString("gpufreq")),
+      gpufreq_unit_id(context->storage->InternString("MHz")) {
   for (const auto& name : BuildMeminfoCounterNames()) {
     meminfo_strs_id_.emplace_back(context->storage->InternString(name));
   }
@@ -475,6 +477,12 @@
   for (auto it = sys_stats.cpuidle_state(); it; ++it) {
     ParseCpuIdleStats(ts, *it);
   }
+
+  for (auto it = sys_stats.gpufreq_mhz(); it; ++it, ++c) {
+    TrackId track = context_->track_tracker->InternGlobalCounterTrack(
+        TrackTracker::Group::kPower, gpufreq_id, {}, gpufreq_unit_id);
+    context_->event_tracker->PushCounter(ts, static_cast<double>(*it), track);
+  }
 }
 
 void SystemProbesParser::ParseCpuIdleStats(int64_t ts, ConstBytes blob) {
diff --git a/src/trace_processor/importers/proto/system_probes_parser.h b/src/trace_processor/importers/proto/system_probes_parser.h
index faf1b98..2c879c8 100644
--- a/src/trace_processor/importers/proto/system_probes_parser.h
+++ b/src/trace_processor/importers/proto/system_probes_parser.h
@@ -60,6 +60,8 @@
   const StringId num_softirq_total_name_id_;
   const StringId oom_score_adj_id_;
   const StringId thermal_unit_id_;
+  const StringId gpufreq_id;
+  const StringId gpufreq_unit_id;
   std::vector<StringId> meminfo_strs_id_;
   std::vector<StringId> vmstat_strs_id_;
 
diff --git a/test/trace_processor/diff_tests/parser/parsing/tests_sys_stats.py b/test/trace_processor/diff_tests/parser/parsing/tests_sys_stats.py
index 8e00929..56e2959 100644
--- a/test/trace_processor/diff_tests/parser/parsing/tests_sys_stats.py
+++ b/test/trace_processor/diff_tests/parser/parsing/tests_sys_stats.py
@@ -13,12 +13,10 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-from python.generators.diff_tests.testing import Path, DataPath, Metric
-from python.generators.diff_tests.testing import Csv, Json, TextProto
+from python.generators.diff_tests.testing import Csv, TextProto
 from python.generators.diff_tests.testing import DiffTestBlueprint
 from python.generators.diff_tests.testing import TestSuite
 
-
 class ParsingSysStats(TestSuite):
 
   def test_cpuidle_stats(self):
@@ -101,3 +99,34 @@
         71625871363623,"x86_pkg_temp",29.000000
         71626000387166,"x86_pkg_temp",31.000000
         """))
+
+  def test_gpufreq(self):
+    return DiffTestBlueprint(
+        trace=TextProto(r"""
+    packet {
+      sys_stats {
+        gpufreq_mhz: 300
+      }
+      timestamp: 115835063108
+      trusted_packet_sequence_id: 2
+    }
+    packet {
+      sys_stats {
+        gpufreq_mhz: 350
+      }
+      timestamp: 115900182490
+      trusted_packet_sequence_id: 2
+    }
+    """),
+        query="""
+    SELECT c.ts,
+            t.name,
+            c.value
+    FROM counter_track t
+    JOIN counter c ON t.id = c.track_id
+    """,
+        out=Csv("""
+    "ts","name","value"
+    115835063108,"gpufreq",300.000000
+    115900182490,"gpufreq",350.000000
+    """))