metrics: Refactor RAIL Mode power queries

Adds a templated _by_category metric for each of the existing ones and
convert the corresponding rail mode query to use it.

Also fixes modified_rail_slices query to add an id column so that it's
consumable by the by_category metrics.

Bug: 173002394
Change-Id: Iec70f40bf05b64a82d9d388e15e087e878fafff0
diff --git a/Android.bp b/Android.bp
index 68c4084..291ce78 100644
--- a/Android.bp
+++ b/Android.bp
@@ -7146,10 +7146,13 @@
     "src/trace_processor/metrics/android/process_unagg_mem_view.sql",
     "src/trace_processor/metrics/android/span_view_stats.sql",
     "src/trace_processor/metrics/android/unsymbolized_frames.sql",
+    "src/trace_processor/metrics/chrome/actual_power_by_category.sql",
     "src/trace_processor/metrics/chrome/actual_power_by_rail_mode.sql",
     "src/trace_processor/metrics/chrome/chrome_processes.sql",
     "src/trace_processor/metrics/chrome/chrome_thread_slice_with_cpu_time.sql",
+    "src/trace_processor/metrics/chrome/cpu_time_by_category.sql",
     "src/trace_processor/metrics/chrome/cpu_time_by_rail_mode.sql",
+    "src/trace_processor/metrics/chrome/estimated_power_by_category.sql",
     "src/trace_processor/metrics/chrome/estimated_power_by_rail_mode.sql",
     "src/trace_processor/metrics/chrome/rail_modes.sql",
     "src/trace_processor/metrics/chrome/scroll_flow_event.sql",
diff --git a/BUILD b/BUILD
index cd7447d..3c723f5 100644
--- a/BUILD
+++ b/BUILD
@@ -822,10 +822,13 @@
         "src/trace_processor/metrics/android/process_unagg_mem_view.sql",
         "src/trace_processor/metrics/android/span_view_stats.sql",
         "src/trace_processor/metrics/android/unsymbolized_frames.sql",
+        "src/trace_processor/metrics/chrome/actual_power_by_category.sql",
         "src/trace_processor/metrics/chrome/actual_power_by_rail_mode.sql",
         "src/trace_processor/metrics/chrome/chrome_processes.sql",
         "src/trace_processor/metrics/chrome/chrome_thread_slice_with_cpu_time.sql",
+        "src/trace_processor/metrics/chrome/cpu_time_by_category.sql",
         "src/trace_processor/metrics/chrome/cpu_time_by_rail_mode.sql",
+        "src/trace_processor/metrics/chrome/estimated_power_by_category.sql",
         "src/trace_processor/metrics/chrome/estimated_power_by_rail_mode.sql",
         "src/trace_processor/metrics/chrome/rail_modes.sql",
         "src/trace_processor/metrics/chrome/scroll_flow_event.sql",
diff --git a/src/trace_processor/metrics/BUILD.gn b/src/trace_processor/metrics/BUILD.gn
index 6c844b6..7afc75b 100644
--- a/src/trace_processor/metrics/BUILD.gn
+++ b/src/trace_processor/metrics/BUILD.gn
@@ -56,10 +56,13 @@
   "android/process_counter_span_view.sql",
   "android/global_counter_span_view.sql",
   "android/unsymbolized_frames.sql",
+  "chrome/actual_power_by_category.sql",
   "chrome/actual_power_by_rail_mode.sql",
   "chrome/chrome_processes.sql",
   "chrome/chrome_thread_slice_with_cpu_time.sql",
+  "chrome/cpu_time_by_category.sql",
   "chrome/cpu_time_by_rail_mode.sql",
+  "chrome/estimated_power_by_category.sql",
   "chrome/estimated_power_by_rail_mode.sql",
   "chrome/rail_modes.sql",
   "chrome/scroll_jank.sql",
diff --git a/src/trace_processor/metrics/chrome/actual_power_by_category.sql b/src/trace_processor/metrics/chrome/actual_power_by_category.sql
new file mode 100644
index 0000000..36257c1
--- /dev/null
+++ b/src/trace_processor/metrics/chrome/actual_power_by_category.sql
@@ -0,0 +1,56 @@
+--
+-- Copyright 2020 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.
+--
+
+-- This is a templated metric that takes 3 parameters:
+-- input: name of a table/view which must have columns: id, ts, dur and a
+--   "category" column
+-- output: name of the view that will be created
+-- category: name of the category column in the input table, which will be
+--   preserved in the output
+
+SELECT RUN_METRIC('chrome/chrome_processes.sql');
+SELECT RUN_METRIC('android/power_drain_in_watts.sql');
+
+DROP TABLE IF EXISTS real_{{input}}_power;
+CREATE VIRTUAL TABLE real_{{input}}_power USING SPAN_JOIN(
+    {{input}},
+    drain_in_watts
+);
+
+-- Actual power usage for chrome across the categorised slices contained in the
+-- input table broken down by subsystem.
+DROP VIEW IF EXISTS {{output}};
+CREATE VIEW {{output}} AS
+SELECT s.id,
+  ts,
+  dur,
+  {{category}},
+  subsystem,
+  joules,
+  joules / dur * 1e9 AS drain_w
+FROM (
+    SELECT id,
+      subsystem,
+      SUM(drain_w * dur / 1e9) AS joules
+    FROM real_{{input}}_power
+      JOIN power_counters
+    WHERE real_{{input}}_power.name = power_counters.name
+    GROUP BY id,
+      subsystem
+  ) p
+  JOIN {{input}} s
+WHERE s.id = p.id
+ORDER BY s.id;
diff --git a/src/trace_processor/metrics/chrome/actual_power_by_rail_mode.sql b/src/trace_processor/metrics/chrome/actual_power_by_rail_mode.sql
index 6a63e4a..901a07b 100644
--- a/src/trace_processor/metrics/chrome/actual_power_by_rail_mode.sql
+++ b/src/trace_processor/metrics/chrome/actual_power_by_rail_mode.sql
@@ -15,36 +15,12 @@
 --
 
 SELECT RUN_METRIC('chrome/rail_modes.sql');
-SELECT RUN_METRIC('chrome/chrome_processes.sql');
-SELECT RUN_METRIC('android/power_drain_in_watts.sql');
 
-DROP TABLE IF EXISTS real_rail_power;
-CREATE VIRTUAL TABLE real_rail_power USING SPAN_JOIN(
-    combined_overall_rail_slices,
-    drain_in_watts
-);
-
--- Actual power usage for chrome across the RAIL mode slices contained in
--- combined_overall_rail_slices broken down by subsystem.
-DROP VIEW IF EXISTS real_power_by_rail_mode;
-CREATE VIEW real_power_by_rail_mode AS
-SELECT s.id,
-  ts,
-  dur,
-  rail_mode,
-  subsystem,
-  joules,
-  joules / dur * 1e9 AS drain_w
-FROM (
-    SELECT id,
-      subsystem,
-      SUM(drain_w * dur / 1e9) AS joules
-    FROM real_rail_power
-      JOIN power_counters
-    WHERE real_rail_power.name = power_counters.name
-    GROUP BY id,
-      subsystem
-  ) p
-  JOIN combined_overall_rail_slices s
-WHERE s.id = p.id
-ORDER BY s.id;
+-- Creates a view called real_power_by_rail_mode, containing the actual power
+-- usage for chrome broken down by RAIL Mode (subdivided by subsystem).
+SELECT RUN_METRIC(
+    'chrome/actual_power_by_category.sql',
+    'input', 'combined_overall_rail_slices',
+    'output', 'real_power_by_rail_mode',
+    'category', 'rail_mode'
+  );
diff --git a/src/trace_processor/metrics/chrome/cpu_time_by_category.sql b/src/trace_processor/metrics/chrome/cpu_time_by_category.sql
new file mode 100644
index 0000000..2981ebd
--- /dev/null
+++ b/src/trace_processor/metrics/chrome/cpu_time_by_category.sql
@@ -0,0 +1,71 @@
+--
+-- Copyright 2020 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.
+--
+
+-- This is a templated metric that takes 3 parameters:
+-- input: name of a table/view which must have columns: id, ts, dur and a
+--   "category" column
+-- output: name of the view that will be created
+-- category: name of the category column in the input table, which will be
+--   preserved in the output
+
+SELECT RUN_METRIC('chrome/chrome_processes.sql') ;
+
+-- CPU time slices for Chrome threads.
+DROP VIEW IF EXISTS chrome_cpu_slices;
+CREATE VIEW chrome_cpu_slices AS
+SELECT counters.id AS counter_id,
+  track_id,
+  ts,
+  lead(ts) OVER (
+    PARTITION BY track_id
+    ORDER BY ts
+  ) - ts AS dur,
+  CAST(
+    lead(value) OVER (
+      PARTITION BY track_id
+      ORDER BY ts
+    ) - value AS "INT64"
+  ) AS cpu_dur
+FROM counters,
+  (
+    SELECT thread_counter_track.id
+    FROM chrome_thread
+      JOIN thread_counter_track ON chrome_thread.utid = thread_counter_track.utid
+  ) AS t
+WHERE t.id = track_id;
+
+DROP TABLE IF EXISTS {{input}}_cpu_time;
+CREATE VIRTUAL TABLE {{input}}_cpu_time USING SPAN_JOIN(
+  {{input}},
+  chrome_cpu_slices PARTITIONED track_id
+);
+
+-- View containing the CPU time used (across all cores) for each category slice
+-- from input.
+-- This will slightly overestimate the CPU time for some category slices as the
+-- cpu time slices don't always line up with the category slices. However the
+-- CPU slices are small enough this makes very little difference.
+DROP VIEW IF EXISTS {{output}};
+CREATE VIEW {{output}} AS
+SELECT s.id,
+  s.ts,
+  s.dur,
+  s.{{category}},
+  SUM(cpu_dur) AS cpu_dur
+FROM {{input}}_cpu_time r
+  JOIN {{input}} s
+WHERE r.id = s.id
+GROUP BY r.id;
diff --git a/src/trace_processor/metrics/chrome/cpu_time_by_rail_mode.sql b/src/trace_processor/metrics/chrome/cpu_time_by_rail_mode.sql
index a57fcda..426bd25 100644
--- a/src/trace_processor/metrics/chrome/cpu_time_by_rail_mode.sql
+++ b/src/trace_processor/metrics/chrome/cpu_time_by_rail_mode.sql
@@ -14,52 +14,12 @@
 -- limitations under the License.
 --
 
-SELECT RUN_METRIC('chrome/rail_modes.sql');
-SELECT RUN_METRIC('chrome/chrome_processes.sql');
+SELECT RUN_METRIC('chrome/rail_modes.sql') AS suppress_query_output;
 
--- CPU time slices for Chrome threads.
-DROP VIEW IF EXISTS chrome_cpu_slices;
-CREATE VIEW chrome_cpu_slices AS
-SELECT counters.id AS counter_id,
-  track_id,
-  ts,
-  lead(ts) OVER (
-    PARTITION BY track_id
-    ORDER BY ts
-  ) - ts AS dur,
-  CAST(
-    lead(value) OVER (
-      PARTITION BY track_id
-      ORDER BY ts
-    ) - value AS "INT64"
-  ) AS cpu_dur
-FROM counters,
-  (
-    SELECT thread_counter_track.id
-    FROM chrome_thread
-      JOIN thread_counter_track ON chrome_thread.utid = thread_counter_track.utid
-  ) AS t
-WHERE t.id = track_id;
-
-DROP TABLE IF EXISTS rail_cpu_time;
-CREATE VIRTUAL TABLE rail_cpu_time USING SPAN_JOIN(
-  combined_overall_rail_slices,
-  chrome_cpu_slices PARTITIONED track_id
-);
-
--- View containing the CPU time used (across all cores) for each RAIL mode slice
--- from combined_overall_rail_slices.
--- This will slightly overestimate the CPU time for some RAIL mode slices as the
--- cpu time slices don't always line up with the RAIL mode slices. However the
--- CPU slices are small enough this makes very little difference.
-DROP VIEW IF EXISTS cpu_time_by_rail_mode;
-CREATE VIEW cpu_time_by_rail_mode AS
-SELECT s.id,
-  s.ts,
-  s.dur,
-  s.rail_mode,
-  SUM(cpu_dur) AS cpu_dur
-FROM rail_cpu_time r
-  JOIN combined_overall_rail_slices s
-WHERE r.id = s.id
-GROUP BY r.id;
+-- Creates a view cpu_time_by_rail_mode containing the CPU time used (across all
+-- cores) for each RAIL Mode slice in combined_overall_rail_slices.
+SELECT RUN_METRIC('chrome/cpu_time_by_category.sql',
+    'input', 'combined_overall_rail_slices',
+    'output', 'cpu_time_by_rail_mode',
+    'category', 'rail_mode'
+  );
diff --git a/src/trace_processor/metrics/chrome/estimated_power_by_category.sql b/src/trace_processor/metrics/chrome/estimated_power_by_category.sql
new file mode 100644
index 0000000..62190d4
--- /dev/null
+++ b/src/trace_processor/metrics/chrome/estimated_power_by_category.sql
@@ -0,0 +1,71 @@
+--
+-- Copyright 2020 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.
+--
+
+-- This is a templated metric that takes 3 parameters:
+-- input: name of a table/view which must have columns: id, ts, dur and a
+--   "category" column
+-- output: name of the view that will be created
+-- category: name of the category column in the input table, which will be
+--   preserved in the output
+
+SELECT RUN_METRIC('chrome/chrome_processes.sql');
+SELECT RUN_METRIC('android/android_proxy_power.sql');
+
+-- View containing estimated power slices broken down by cpu.
+DROP VIEW IF EXISTS power_per_chrome_thread;
+CREATE VIEW power_per_chrome_thread AS
+SELECT ts,
+  dur,
+  cpu,
+  power_per_thread.utid,
+  end_state,
+  priority,
+  power_ma,
+  power_per_thread.type,
+  name AS thread_name,
+  upid,
+  is_main_thread
+FROM power_per_thread
+  JOIN chrome_thread
+WHERE power_per_thread.utid = chrome_thread.utid;
+
+DROP TABLE IF EXISTS {{input}}_power;
+CREATE VIRTUAL TABLE {{input}}_power USING SPAN_JOIN(
+  {{input}},
+  power_per_chrome_thread
+);
+
+-- Estimated power usage for chrome across the categroy slices contained in
+-- input.
+DROP VIEW IF EXISTS {{output}};
+CREATE VIEW {{output}} AS
+SELECT id,
+  ts,
+  dur,
+  {{category}},
+  mas,
+  mas / dur * 1e9 AS ma
+FROM (
+    SELECT s.id,
+      s.ts,
+      s.dur,
+      s.{{category}},
+      SUM(r.power_ma * r.dur) / 1e9 AS mas
+    FROM {{input}}_power r
+      JOIN {{input}} s
+    WHERE r.id == s.id
+    GROUP BY s.id
+  );
diff --git a/src/trace_processor/metrics/chrome/estimated_power_by_rail_mode.sql b/src/trace_processor/metrics/chrome/estimated_power_by_rail_mode.sql
index 627e049..a0b9b22 100644
--- a/src/trace_processor/metrics/chrome/estimated_power_by_rail_mode.sql
+++ b/src/trace_processor/metrics/chrome/estimated_power_by_rail_mode.sql
@@ -15,51 +15,12 @@
 --
 
 SELECT RUN_METRIC('chrome/rail_modes.sql');
-SELECT RUN_METRIC('chrome/chrome_processes.sql');
-SELECT RUN_METRIC('android/android_proxy_power.sql');
 
--- View containing estimated power slices broken down by cpu.
-DROP VIEW IF EXISTS power_per_chrome_thread;
-CREATE VIEW power_per_chrome_thread AS
-SELECT ts,
-  dur,
-  cpu,
-  power_per_thread.utid,
-  end_state,
-  priority,
-  power_ma,
-  power_per_thread.type,
-  name AS thread_name,
-  upid,
-  is_main_thread
-FROM power_per_thread
-  JOIN chrome_thread
-WHERE power_per_thread.utid = chrome_thread.utid;
-
-DROP TABLE IF EXISTS rail_power;
-CREATE VIRTUAL TABLE rail_power USING SPAN_JOIN(
-  combined_overall_rail_slices,
-  power_per_chrome_thread
-);
-
--- Estimated power usage for chrome across the RAIL mode slices contained in
--- combined_overall_rail_slices.
-DROP VIEW IF EXISTS power_by_rail_mode;
-CREATE VIEW power_by_rail_mode AS
-SELECT id,
-  ts,
-  dur,
-  rail_mode,
-  mas,
-  mas / dur * 1e9 AS ma
-FROM (
-    SELECT s.id,
-      s.ts,
-      s.dur,
-      s.rail_mode,
-      SUM(r.power_ma * r.dur) / 1e9 AS mas
-    FROM rail_power r
-      JOIN combined_overall_rail_slices s
-    WHERE r.id == s.id
-    GROUP BY s.id
+-- Creates a view called power_by_rail_mode, containing the estimated CPU power
+-- usage for chrome broken down by RAIL Mode.
+SELECT RUN_METRIC(
+    'chrome/estimated_power_by_category.sql',
+    'input', 'combined_overall_rail_slices',
+    'output', 'power_by_rail_mode',
+    'category', 'rail_mode'
   );
diff --git a/src/trace_processor/metrics/chrome/rail_modes.sql b/src/trace_processor/metrics/chrome/rail_modes.sql
index 40a7344..0abb7b1 100644
--- a/src/trace_processor/metrics/chrome/rail_modes.sql
+++ b/src/trace_processor/metrics/chrome/rail_modes.sql
@@ -190,17 +190,23 @@
 -- to vsync data), then record the mode as foreground_idle instead.
 DROP VIEW IF EXISTS modified_rail_slices;
 CREATE VIEW modified_rail_slices AS
-SELECT ts,
+SELECT ROW_NUMBER() OVER () AS id,
+  ts,
   dur,
-  IIF(
-    present IS NULL,
-    "animation",
-    "foreground_idle"
-  ) AS mode
-FROM temp_rail_mode_join_animation
-UNION
-SELECT ts,
-  dur,
-  rail_mode AS mode
-FROM combined_overall_rail_slices
-WHERE rail_mode <> "animation";
\ No newline at end of file
+  mode
+FROM (
+  SELECT
+    ts,
+    dur,
+    IIF(
+      present IS NULL,
+      "animation",
+      "foreground_idle"
+    ) AS mode
+  FROM temp_rail_mode_join_animation
+  UNION
+  SELECT ts,
+    dur,
+    rail_mode AS mode
+  FROM combined_overall_rail_slices
+  WHERE rail_mode <> "animation");