metrics: Add Wattson atrace apps estimate

Estimate power for any number of arbitrary windows as defined by atrace
apps. For example, the SysUI CUJs define time windows for which power
estimates can be made.

Test: tools/diff_test_trace_processor.py out/linux/trace_processor_shell --name-filter '.*wattson.*'
Bug: 381153639
Change-Id: I1ce7569cb62b5bd16dc8235a0b8bfe0e13143cbe
Signed-off-by: Samuel Wu <wusamuel@google.com>
diff --git a/Android.bp b/Android.bp
index 5a23a79..21f6817 100644
--- a/Android.bp
+++ b/Android.bp
@@ -13216,6 +13216,7 @@
         "src/trace_processor/metrics/sql/android/sysui_update_notif_on_ui_mode_changed_metric.sql",
         "src/trace_processor/metrics/sql/android/unsymbolized_frames.sql",
         "src/trace_processor/metrics/sql/android/wattson_app_startup_rails.sql",
+        "src/trace_processor/metrics/sql/android/wattson_atrace_apps_rails.sql",
         "src/trace_processor/metrics/sql/android/wattson_markers_rails.sql",
         "src/trace_processor/metrics/sql/android/wattson_markers_threads.sql",
         "src/trace_processor/metrics/sql/android/wattson_rail_relations.sql",
diff --git a/BUILD b/BUILD
index e97c280..3280a73 100644
--- a/BUILD
+++ b/BUILD
@@ -2513,6 +2513,7 @@
         "src/trace_processor/metrics/sql/android/sysui_update_notif_on_ui_mode_changed_metric.sql",
         "src/trace_processor/metrics/sql/android/unsymbolized_frames.sql",
         "src/trace_processor/metrics/sql/android/wattson_app_startup_rails.sql",
+        "src/trace_processor/metrics/sql/android/wattson_atrace_apps_rails.sql",
         "src/trace_processor/metrics/sql/android/wattson_markers_rails.sql",
         "src/trace_processor/metrics/sql/android/wattson_markers_threads.sql",
         "src/trace_processor/metrics/sql/android/wattson_rail_relations.sql",
diff --git a/protos/perfetto/metrics/metrics.proto b/protos/perfetto/metrics/metrics.proto
index 9ab7eda..360713b 100644
--- a/protos/perfetto/metrics/metrics.proto
+++ b/protos/perfetto/metrics/metrics.proto
@@ -128,7 +128,7 @@
 
 // Root message for all Perfetto-based metrics.
 //
-// Next id: 75
+// Next id: 76
 message TraceMetrics {
   reserved 4, 10, 13, 14, 16, 19;
 
@@ -343,6 +343,9 @@
   // Android Wattson estimate during markers time window.
   optional AndroidWattsonTimePeriodMetric wattson_markers_rails = 74;
 
+  // Android Wattson estimate during time windows defined by atrace apps.
+  optional AndroidWattsonTimePeriodMetric wattson_atrace_apps_rails = 75;
+
   // Android
   // Demo extensions.
   extensions 450 to 499;
diff --git a/protos/perfetto/metrics/perfetto_merged_metrics.proto b/protos/perfetto/metrics/perfetto_merged_metrics.proto
index 222d0e6..280bb88 100644
--- a/protos/perfetto/metrics/perfetto_merged_metrics.proto
+++ b/protos/perfetto/metrics/perfetto_merged_metrics.proto
@@ -3074,7 +3074,7 @@
 
 // Root message for all Perfetto-based metrics.
 //
-// Next id: 75
+// Next id: 76
 message TraceMetrics {
   reserved 4, 10, 13, 14, 16, 19;
 
@@ -3289,6 +3289,9 @@
   // Android Wattson estimate during markers time window.
   optional AndroidWattsonTimePeriodMetric wattson_markers_rails = 74;
 
+  // Android Wattson estimate during time windows defined by atrace apps.
+  optional AndroidWattsonTimePeriodMetric wattson_atrace_apps_rails = 75;
+
   // Android
   // Demo extensions.
   extensions 450 to 499;
diff --git a/python/perfetto/trace_processor/metrics.descriptor b/python/perfetto/trace_processor/metrics.descriptor
index 2866231..6e65539 100644
--- a/python/perfetto/trace_processor/metrics.descriptor
+++ b/python/perfetto/trace_processor/metrics.descriptor
Binary files differ
diff --git a/src/trace_processor/metrics/sql/android/BUILD.gn b/src/trace_processor/metrics/sql/android/BUILD.gn
index ae6fb83..e522e95 100644
--- a/src/trace_processor/metrics/sql/android/BUILD.gn
+++ b/src/trace_processor/metrics/sql/android/BUILD.gn
@@ -142,6 +142,7 @@
     "sysui_update_notif_on_ui_mode_changed_metric.sql",
     "unsymbolized_frames.sql",
     "wattson_app_startup_rails.sql",
+    "wattson_atrace_apps_rails.sql",
     "wattson_markers_rails.sql",
     "wattson_markers_threads.sql",
     "wattson_rail_relations.sql",
diff --git a/src/trace_processor/metrics/sql/android/wattson_atrace_apps_rails.sql b/src/trace_processor/metrics/sql/android/wattson_atrace_apps_rails.sql
new file mode 100644
index 0000000..7841c91
--- /dev/null
+++ b/src/trace_processor/metrics/sql/android/wattson_atrace_apps_rails.sql
@@ -0,0 +1,50 @@
+
+-- Copyright 2024 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
+--
+--     https://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.
+
+INCLUDE PERFETTO MODULE wattson.curves.estimates;
+
+-- Create the base table (`android_jank_cuj`) containing all completed CUJs
+-- found in the trace.
+SELECT RUN_METRIC('android/jank/cujs.sql');
+
+DROP VIEW IF EXISTS _wattson_cuj_windows;
+CREATE PERFETTO VIEW _wattson_cuj_windows AS
+SELECT
+  ts,
+  dur,
+  cuj_id as period_id
+FROM android_jank_cuj;
+
+SELECT RUN_METRIC(
+  'android/wattson_rail_relations.sql',
+  'window_table', '_wattson_cuj_windows'
+);
+
+DROP VIEW IF EXISTS wattson_atrace_apps_rails_output;
+CREATE PERFETTO VIEW wattson_atrace_apps_rails_output AS
+SELECT AndroidWattsonTimePeriodMetric(
+  'metric_version', 4,
+  'power_model_version', 1,
+  'period_info', (
+    SELECT RepeatedField(
+      AndroidWattsonEstimateInfo(
+        'period_id', period_id,
+        'period_dur', period_dur,
+        'cpu_subsystem', proto
+      )
+    )
+    FROM _estimate_cpu_subsystem_sum
+  )
+);
diff --git a/test/data/wattson_jank_cuj.pb.sha256 b/test/data/wattson_jank_cuj.pb.sha256
new file mode 100644
index 0000000..15cdf88
--- /dev/null
+++ b/test/data/wattson_jank_cuj.pb.sha256
@@ -0,0 +1 @@
+dc1a17d76931b24cf4e07a2f13f6072145e783215321457d31c7e74474b51d1a
\ No newline at end of file
diff --git a/test/trace_processor/diff_tests/metrics/android/tests.py b/test/trace_processor/diff_tests/metrics/android/tests.py
index 5f24e2e..769a81a 100644
--- a/test/trace_processor/diff_tests/metrics/android/tests.py
+++ b/test/trace_processor/diff_tests/metrics/android/tests.py
@@ -539,3 +539,9 @@
           }
         }
         """))
+
+  def test_wattson_atrace_apps_rails_output(self):
+    return DiffTestBlueprint(
+        trace=DataPath('wattson_jank_cuj.pb'),
+        query=Metric("wattson_atrace_apps_rails"),
+        out=Path('wattson_atrace_apps_rails.out'))
diff --git a/test/trace_processor/diff_tests/metrics/android/wattson_atrace_apps_rails.out b/test/trace_processor/diff_tests/metrics/android/wattson_atrace_apps_rails.out
new file mode 100644
index 0000000..aafb780
--- /dev/null
+++ b/test/trace_processor/diff_tests/metrics/android/wattson_atrace_apps_rails.out
@@ -0,0 +1,172 @@
+wattson_atrace_apps_rails {
+  metric_version: 4
+  power_model_version: 1
+  period_info {
+    period_id: 3
+    period_dur: 1033882989
+    cpu_subsystem {
+      estimated_mw: 588.551453
+      estimated_mws: 608.493347
+      policy0 {
+        estimated_mw: 206.885727
+        estimated_mws: 213.895630
+        cpu0 {
+          estimated_mw: 48.200874
+          estimated_mws: 49.834064
+        }
+        cpu1 {
+          estimated_mw: 52.758167
+          estimated_mws: 54.545773
+        }
+        cpu2 {
+          estimated_mw: 54.796875
+          estimated_mws: 56.653557
+        }
+        cpu3 {
+          estimated_mw: 51.129807
+          estimated_mws: 52.862240
+        }
+      }
+      policy4 {
+        estimated_mw: 238.698257
+        estimated_mws: 246.786057
+        cpu4 {
+          estimated_mw: 136.624969
+          estimated_mws: 141.254242
+        }
+        cpu5 {
+          estimated_mw: 102.073280
+          estimated_mws: 105.531822
+        }
+      }
+      policy6 {
+        estimated_mw: 124.599953
+        estimated_mws: 128.821777
+        cpu6 {
+          estimated_mw: 59.473373
+          estimated_mws: 61.488510
+        }
+        cpu7 {
+          estimated_mw: 65.126579
+          estimated_mws: 67.333260
+        }
+      }
+      dsu_scu {
+        estimated_mw: 18.367506
+        estimated_mws: 18.989853
+      }
+    }
+  }
+  period_info {
+    period_id: 4
+    period_dur: 1102956461
+    cpu_subsystem {
+      estimated_mw: 495.969849
+      estimated_mws: 547.033142
+      policy0 {
+        estimated_mw: 176.800064
+        estimated_mws: 195.002777
+        cpu0 {
+          estimated_mw: 46.978123
+          estimated_mws: 51.814823
+        }
+        cpu1 {
+          estimated_mw: 38.306576
+          estimated_mws: 42.250484
+        }
+        cpu2 {
+          estimated_mw: 42.787342
+          estimated_mws: 47.192577
+        }
+        cpu3 {
+          estimated_mw: 48.728027
+          estimated_mws: 53.744892
+        }
+      }
+      policy4 {
+        estimated_mw: 196.383987
+        estimated_mws: 216.602982
+        cpu4 {
+          estimated_mw: 97.974754
+          estimated_mws: 108.061882
+        }
+        cpu5 {
+          estimated_mw: 98.409233
+          estimated_mws: 108.541100
+        }
+      }
+      policy6 {
+        estimated_mw: 104.246399
+        estimated_mws: 114.979240
+        cpu6 {
+          estimated_mw: 45.691574
+          estimated_mws: 50.395817
+        }
+        cpu7 {
+          estimated_mw: 58.554829
+          estimated_mws: 64.583427
+        }
+      }
+      dsu_scu {
+        estimated_mw: 18.539404
+        estimated_mws: 20.448156
+      }
+    }
+  }
+  period_info {
+    period_id: 5
+    period_dur: 1102797607
+    cpu_subsystem {
+      estimated_mw: 495.587769
+      estimated_mws: 546.533020
+      policy0 {
+        estimated_mw: 176.701065
+        estimated_mws: 194.865509
+        cpu0 {
+          estimated_mw: 46.844067
+          estimated_mws: 51.659523
+        }
+        cpu1 {
+          estimated_mw: 38.327526
+          estimated_mws: 42.267502
+        }
+        cpu2 {
+          estimated_mw: 42.806507
+          estimated_mws: 47.206913
+        }
+        cpu3 {
+          estimated_mw: 48.722961
+          estimated_mws: 53.731564
+        }
+      }
+      policy4 {
+        estimated_mw: 196.306625
+        estimated_mws: 216.486481
+        cpu4 {
+          estimated_mw: 98.009254
+          estimated_mws: 108.084373
+        }
+        cpu5 {
+          estimated_mw: 98.297379
+          estimated_mws: 108.402115
+        }
+      }
+      policy6 {
+        estimated_mw: 104.057350
+        estimated_mws: 114.754196
+        cpu6 {
+          estimated_mw: 45.671753
+          estimated_mws: 50.366699
+        }
+        cpu7 {
+          estimated_mw: 58.385597
+          estimated_mws: 64.387497
+        }
+      }
+      dsu_scu {
+        estimated_mw: 18.522726
+        estimated_mws: 20.426819
+      }
+    }
+  }
+}