metrics: Force modified_rail_slices to be empty if not valid

The modified_rail_slices view uses data from the VSync event to divide
RAIL_MODE_ANIMATION slices into foreground_idle and animation. Since
this event is only emitted on Android, the modified_rail_slices will
have no animation and only foreground_idle on other platforms which may
given a misleading pictures.

To that end, this adds chrome/chrome_trace_metadata.sql which extracts
trace metadata currently restricted to trace categories and OS, which
are then used to force the modified_rail_slices view to be empty if its
value would not be valid.

Bug: 173094735
Change-Id: I7d630c15de56fd656e86f6d744a49a30357e8f03
diff --git a/Android.bp b/Android.bp
index 291ce78..1756f7b 100644
--- a/Android.bp
+++ b/Android.bp
@@ -7148,6 +7148,7 @@
     "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_event_metadata.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",
diff --git a/BUILD b/BUILD
index 3c723f5..0b6c279 100644
--- a/BUILD
+++ b/BUILD
@@ -824,6 +824,7 @@
         "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_event_metadata.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",
diff --git a/src/trace_processor/metrics/BUILD.gn b/src/trace_processor/metrics/BUILD.gn
index 7afc75b..0017914 100644
--- a/src/trace_processor/metrics/BUILD.gn
+++ b/src/trace_processor/metrics/BUILD.gn
@@ -58,6 +58,7 @@
   "android/unsymbolized_frames.sql",
   "chrome/actual_power_by_category.sql",
   "chrome/actual_power_by_rail_mode.sql",
+  "chrome/chrome_event_metadata.sql",
   "chrome/chrome_processes.sql",
   "chrome/chrome_thread_slice_with_cpu_time.sql",
   "chrome/cpu_time_by_category.sql",
diff --git a/src/trace_processor/metrics/chrome/chrome_event_metadata.sql b/src/trace_processor/metrics/chrome/chrome_event_metadata.sql
new file mode 100644
index 0000000..cc23004
--- /dev/null
+++ b/src/trace_processor/metrics/chrome/chrome_event_metadata.sql
@@ -0,0 +1,39 @@
+--
+-- 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.
+--
+
+-- Creates a view containing name-value pairs extracted from
+-- chrome_event.metadata. Some names can have multiple values:
+-- e.g. trace-category
+DROP VIEW IF EXISTS chrome_event_metadata;
+CREATE VIEW chrome_event_metadata AS
+WITH metadata (arg_set_id) AS (
+  SELECT arg_set_id
+  FROM raw
+  WHERE name = "chrome_event.metadata"
+)
+-- TODO(b/173201788): Once this is fixed, extract all the fields.
+SELECT 'os-name' AS name,
+  EXTRACT_ARG(metadata.arg_set_id, 'os-name') AS value
+FROM metadata
+UNION
+SELECT "trace-category" AS name,
+  value AS category
+FROM metadata, json_each(
+    json_extract(
+      EXTRACT_ARG(metadata.arg_set_id, "trace-config"),
+      '$.included_categories'
+    )
+  );
diff --git a/src/trace_processor/metrics/chrome/rail_modes.sql b/src/trace_processor/metrics/chrome/rail_modes.sql
index 0abb7b1..eefc7a5 100644
--- a/src/trace_processor/metrics/chrome/rail_modes.sql
+++ b/src/trace_processor/metrics/chrome/rail_modes.sql
@@ -13,6 +13,9 @@
 -- See the License for the specific language governing permissions and
 -- limitations under the License.
 --
+
+SELECT RUN_METRIC('chrome/chrome_event_metadata.sql');
+
 -- Priority order for RAIL modes where response has the highest priority and
 -- idle has the lowest.
 CREATE TABLE IF NOT EXISTS rail_modes (
@@ -186,6 +189,14 @@
 CREATE VIRTUAL TABLE temp_rail_mode_join_animation
 USING SPAN_LEFT_JOIN(rail_mode_animation_slices, not_animating_slices);
 
+DROP VIEW IF EXISTS has_modified_rail_slices;
+CREATE VIEW has_modified_rail_slices AS
+SELECT (
+    SELECT value
+    FROM chrome_event_metadata
+    WHERE name == "os-name"
+  ) == "Android" AS value;
+
 -- When the RAIL mode is animation, but there is no actual animation (according
 -- to vsync data), then record the mode as foreground_idle instead.
 DROP VIEW IF EXISTS modified_rail_slices;
@@ -209,4 +220,9 @@
     dur,
     rail_mode AS mode
   FROM combined_overall_rail_slices
-  WHERE rail_mode <> "animation");
+  WHERE rail_mode <> "animation")
+-- Since VSync events are only emitted on Android (and this the concept of a
+-- unified RAIL mode only makes sense if there's just a single Chrome window),
+-- don't output anything on other platforms. This will result in all the power
+-- and cpu time tables being empty rather than containing bogus results.
+WHERE (SELECT value FROM has_modified_rail_slices);
\ No newline at end of file