Add app deadline missed metrics

Collect App Deadline Missed count as metrics.

Bug: 216246509
Test: <trace_processor_shell> --run-metrics android_frame_timeline_metric <perfetto_trace>
Test: tools/diff_test_trace_processor.py <trace_processor_shell> --query-metric-filter='android_frame_timeline_metric'
Change-Id: I5c79825aa7142856be7bdea2187a131ee8e81894
diff --git a/Android.bp b/Android.bp
index 9d933ea..6824626 100644
--- a/Android.bp
+++ b/Android.bp
@@ -3723,6 +3723,7 @@
 genrule {
     name: "perfetto_protos_perfetto_metrics_chrome_descriptor",
     srcs: [
+        "protos/perfetto/metrics/android/android_frame_timeline_metric.proto",
         "protos/perfetto/metrics/android/android_trusty_workqueues.proto",
         "protos/perfetto/metrics/android/batt_metric.proto",
         "protos/perfetto/metrics/android/binder_metric.proto",
@@ -3792,6 +3793,7 @@
 genrule {
     name: "perfetto_protos_perfetto_metrics_descriptor",
     srcs: [
+        "protos/perfetto/metrics/android/android_frame_timeline_metric.proto",
         "protos/perfetto/metrics/android/android_trusty_workqueues.proto",
         "protos/perfetto/metrics/android/batt_metric.proto",
         "protos/perfetto/metrics/android/binder_metric.proto",
@@ -8475,6 +8477,7 @@
         "src/trace_processor/metrics/sql/android/android_dma_heap.sql",
         "src/trace_processor/metrics/sql/android/android_dvfs.sql",
         "src/trace_processor/metrics/sql/android/android_fastrpc.sql",
+        "src/trace_processor/metrics/sql/android/android_frame_timeline_metric.sql",
         "src/trace_processor/metrics/sql/android/android_gpu.sql",
         "src/trace_processor/metrics/sql/android/android_hwcomposer.sql",
         "src/trace_processor/metrics/sql/android/android_hwui_metric.sql",
diff --git a/BUILD b/BUILD
index 08bc590..77289f5 100644
--- a/BUILD
+++ b/BUILD
@@ -1103,6 +1103,7 @@
         "src/trace_processor/metrics/sql/android/android_dma_heap.sql",
         "src/trace_processor/metrics/sql/android/android_dvfs.sql",
         "src/trace_processor/metrics/sql/android/android_fastrpc.sql",
+        "src/trace_processor/metrics/sql/android/android_frame_timeline_metric.sql",
         "src/trace_processor/metrics/sql/android/android_gpu.sql",
         "src/trace_processor/metrics/sql/android/android_hwcomposer.sql",
         "src/trace_processor/metrics/sql/android/android_hwui_metric.sql",
@@ -2796,6 +2797,7 @@
 perfetto_proto_library(
     name = "protos_perfetto_metrics_android_protos",
     srcs = [
+        "protos/perfetto/metrics/android/android_frame_timeline_metric.proto",
         "protos/perfetto/metrics/android/android_trusty_workqueues.proto",
         "protos/perfetto/metrics/android/batt_metric.proto",
         "protos/perfetto/metrics/android/binder_metric.proto",
diff --git a/protos/perfetto/metrics/android/BUILD.gn b/protos/perfetto/metrics/android/BUILD.gn
index 8091fb7..467fcd7 100644
--- a/protos/perfetto/metrics/android/BUILD.gn
+++ b/protos/perfetto/metrics/android/BUILD.gn
@@ -20,6 +20,7 @@
     "source_set",
   ]
   sources = [
+    "android_frame_timeline_metric.proto",
     "android_trusty_workqueues.proto",
     "batt_metric.proto",
     "binder_metric.proto",
diff --git a/protos/perfetto/metrics/android/android_frame_timeline_metric.proto b/protos/perfetto/metrics/android/android_frame_timeline_metric.proto
new file mode 100644
index 0000000..2e71fc0
--- /dev/null
+++ b/protos/perfetto/metrics/android/android_frame_timeline_metric.proto
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2022 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
+ *
+ *      http://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.
+ */
+
+syntax = "proto2";
+
+package perfetto.protos;
+
+// Measure app deadline missed.
+message AndroidFrameTimelineMetric {
+  message ProcessBreakdown {
+    // Process name
+    optional string process_name = 1;
+    // Count of app deadline missed in the process
+    optional int64 app_deadline_missed_count = 2;
+  }
+
+  // Total count for app deadline missed
+  optional int64 app_deadline_missed_total_count = 1;
+
+  // Process name and app deadline missed metrics
+  repeated ProcessBreakdown process = 2;
+}
+
diff --git a/protos/perfetto/metrics/metrics.proto b/protos/perfetto/metrics/metrics.proto
index 55571c4..b2d248a 100644
--- a/protos/perfetto/metrics/metrics.proto
+++ b/protos/perfetto/metrics/metrics.proto
@@ -18,6 +18,7 @@
 
 package perfetto.protos;
 
+import "protos/perfetto/metrics/android/android_frame_timeline_metric.proto";
 import "protos/perfetto/metrics/android/batt_metric.proto";
 import "protos/perfetto/metrics/android/cpu_metric.proto";
 import "protos/perfetto/metrics/android/camera_metric.proto";
@@ -100,7 +101,7 @@
 
 // Root message for all Perfetto-based metrics.
 //
-// Next id: 47
+// Next id: 48
 message TraceMetrics {
   reserved 4, 10, 13, 14, 16, 19;
 
@@ -226,6 +227,9 @@
   // Per-process Binder transaction metrics.
   optional AndroidBinderMetric android_binder = 46;
 
+  // Metrics for app deadline missed.
+  optional AndroidFrameTimelineMetric android_frame_timeline_metric = 47;
+
   // 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 3c0933b..78426cd 100644
--- a/protos/perfetto/metrics/perfetto_merged_metrics.proto
+++ b/protos/perfetto/metrics/perfetto_merged_metrics.proto
@@ -13,6 +13,27 @@
 
 option go_package = "github.com/google/perfetto/perfetto_proto";
 
+// Begin of protos/perfetto/metrics/android/android_frame_timeline_metric.proto
+
+// Measure app deadline missed.
+message AndroidFrameTimelineMetric {
+  message ProcessBreakdown {
+    // Process name
+    optional string process_name = 1;
+    // Count of app deadline missed in the process
+    optional int64 app_deadline_missed_count = 2;
+  }
+
+  // Total count for app deadline missed
+  optional int64 app_deadline_missed_total_count = 1;
+
+  // Process name and app deadline missed metrics
+  repeated ProcessBreakdown process = 2;
+}
+
+
+// End of protos/perfetto/metrics/android/android_frame_timeline_metric.proto
+
 // Begin of protos/perfetto/metrics/android/android_trusty_workqueues.proto
 
 // Metric used to generate a simplified view of the Trusty kworker events.
@@ -1544,7 +1565,7 @@
 
 // Root message for all Perfetto-based metrics.
 //
-// Next id: 47
+// Next id: 48
 message TraceMetrics {
   reserved 4, 10, 13, 14, 16, 19;
 
@@ -1670,6 +1691,9 @@
   // Per-process Binder transaction metrics.
   optional AndroidBinderMetric android_binder = 46;
 
+  // Metrics for app deadline missed.
+  optional AndroidFrameTimelineMetric android_frame_timeline_metric = 47;
+
   // Demo extensions.
   extensions 450 to 499;
 
diff --git a/python/perfetto/trace_processor/metrics.descriptor b/python/perfetto/trace_processor/metrics.descriptor
index 850b6df..585c274 100644
--- a/python/perfetto/trace_processor/metrics.descriptor
+++ b/python/perfetto/trace_processor/metrics.descriptor
Binary files differ
diff --git a/python/perfetto/trace_processor/metrics.descriptor.sha1 b/python/perfetto/trace_processor/metrics.descriptor.sha1
index 8d1166a..0789b59 100644
--- a/python/perfetto/trace_processor/metrics.descriptor.sha1
+++ b/python/perfetto/trace_processor/metrics.descriptor.sha1
@@ -2,5 +2,5 @@
 // SHA1(tools/gen_binary_descriptors)
 // c4a38769074f8a8c2ffbf514b267919b5f2d47df
 // SHA1(protos/perfetto/metrics/metrics.proto)
-// 1555061bf1527fce27559876acaf3c31f82bf1d2
+// 6a6df998653b26dabf7ae6591e2f8a8677669b77
   
\ No newline at end of file
diff --git a/src/trace_processor/metrics/sql/BUILD.gn b/src/trace_processor/metrics/sql/BUILD.gn
index b0efb56..a6bf204 100644
--- a/src/trace_processor/metrics/sql/BUILD.gn
+++ b/src/trace_processor/metrics/sql/BUILD.gn
@@ -63,6 +63,7 @@
   "android/process_metadata.sql",
   "android/process_oom_score.sql",
   "android/profiler_smaps.sql",
+  "android/android_frame_timeline_metric.sql",
   "android/android_rt_runtime.sql",
   "android/android_irq_runtime.sql",
   "android/mem_stats_priority_breakdown.sql",
diff --git a/src/trace_processor/metrics/sql/android/android_frame_timeline_metric.sql b/src/trace_processor/metrics/sql/android/android_frame_timeline_metric.sql
new file mode 100644
index 0000000..72ef920
--- /dev/null
+++ b/src/trace_processor/metrics/sql/android/android_frame_timeline_metric.sql
@@ -0,0 +1,45 @@
+--
+-- Copyright 2022 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.
+
+DROP VIEW IF EXISTS app_deadline_missed_view;
+
+CREATE VIEW app_deadline_missed_view
+AS
+SELECT p.name AS process, COUNT(jank_type) AS 'jank_count'
+FROM actual_frame_timeline_slice
+LEFT JOIN process AS p
+  USING (upid)
+WHERE jank_type LIKE '%App Deadline Missed%'
+GROUP BY process;
+
+DROP VIEW IF EXISTS android_frame_timeline_metric_output;
+
+CREATE VIEW android_frame_timeline_metric_output
+AS
+SELECT
+    AndroidFrameTimelineMetric(
+    'app_deadline_missed_total_count',
+    (SELECT SUM(jank_count) FROM app_deadline_missed_view),
+    'process',
+    (
+      SELECT
+        RepeatedField(
+            AndroidFrameTimelineMetric_ProcessBreakdown(
+            'process_name',
+            process,
+            'app_deadline_missed_count',
+            jank_count))
+      FROM app_deadline_missed_view
+    ));
diff --git a/test/trace_processor/performance/frame_timeline_metric.out b/test/trace_processor/performance/frame_timeline_metric.out
new file mode 100644
index 0000000..b2797c2
--- /dev/null
+++ b/test/trace_processor/performance/frame_timeline_metric.out
@@ -0,0 +1,12 @@
+android_frame_timeline_metric {
+  app_deadline_missed_total_count: 3
+  process {
+    process_name: "process1"
+    app_deadline_missed_count: 2
+  }
+  process {
+    process_name: "process2"
+    app_deadline_missed_count: 1
+  }
+}
+
diff --git a/test/trace_processor/performance/frame_timeline_metric.py b/test/trace_processor/performance/frame_timeline_metric.py
new file mode 100755
index 0000000..ab563fc
--- /dev/null
+++ b/test/trace_processor/performance/frame_timeline_metric.py
@@ -0,0 +1,69 @@
+#!/usr/bin/env python3
+# Copyright (C) 2022 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
+#
+#      http://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.
+
+from os import sys, path
+
+import synth_common
+
+class JankType:
+  JANK_UNSPECIFIED = 0;
+  JANK_NONE = 1;
+  JANK_SF_SCHEDULING = 2;
+  JANK_PREDICTION_ERROR = 4;
+  JANK_DISPLAY_HAL = 8;
+  JANK_SF_CPU_DEADLINE_MISSED = 16;
+  JANK_SF_GPU_DEADLINE_MISSED = 32;
+  JANK_APP_DEADLINE_MISSED = 64;
+  JANK_BUFFER_STUFFING = 128;
+  JANK_UNKNOWN = 256;
+  JANK_SF_STUFFING = 512;
+
+class PresentType:
+  PRESENT_UNSPECIFIED = 0;
+  PRESENT_ON_TIME = 1;
+  PRESENT_LATE = 2;
+  PRESENT_EARLY = 3;
+  PRESENT_DROPPED = 4;
+  PRESENT_UNKNOWN = 5;
+
+class PredictionType:
+  PREDICTION_UNSPECIFIED = 0;
+  PREDICTION_VALID = 1;
+  PREDICTION_EXPIRED = 2;
+  PREDICTION_UNKNOWN = 3;
+
+trace = synth_common.create_trace()
+
+trace.add_packet(ts=5)
+trace.add_process(1001, 0, "process1")
+trace.add_process(1002, 0, "process2")
+trace.add_process(1003, 0, "process3")
+
+trace.add_actual_surface_frame_start_event(ts=21, cookie=6, token=1, display_frame_token=4, pid=1002, layer_name="Layer1", present_type=PresentType.PRESENT_ON_TIME, on_time_finish=1, gpu_composition=0, jank_type=JankType.JANK_NONE, prediction_type=PredictionType.PREDICTION_VALID)
+trace.add_frame_end_event(ts=37, cookie=6)
+
+trace.add_actual_surface_frame_start_event(ts=31, cookie=7, token=1, display_frame_token=4, pid=1002, layer_name="Layer1", present_type=PresentType.PRESENT_ON_TIME, on_time_finish=1, gpu_composition=0, jank_type=JankType.JANK_APP_DEADLINE_MISSED, prediction_type=PredictionType.PREDICTION_VALID)
+trace.add_frame_end_event(ts=47, cookie=7)
+
+
+# DisplayFrame with a janky SurfaceFrame
+trace.add_actual_surface_frame_start_event(ts=41, cookie=10, token=5, display_frame_token=6, pid=1001, layer_name="Layer1", present_type=PresentType.PRESENT_LATE, on_time_finish=0, gpu_composition=0, jank_type=JankType.JANK_APP_DEADLINE_MISSED, prediction_type=PredictionType.PREDICTION_VALID)
+trace.add_frame_end_event(ts=74, cookie=10)
+trace.add_actual_surface_frame_start_event(ts=41, cookie=11, token=5, display_frame_token=6, pid=1001, layer_name="Layer1", present_type=PresentType.PRESENT_LATE, on_time_finish=0, gpu_composition=0, jank_type=JankType.JANK_APP_DEADLINE_MISSED|JankType.JANK_BUFFER_STUFFING, prediction_type=PredictionType.PREDICTION_VALID)
+trace.add_frame_end_event(ts=75, cookie=11)
+
+trace.add_actual_surface_frame_start_event(ts=81, cookie=15, token=8, display_frame_token=9, pid=1003, layer_name="Layer1", present_type=PresentType.PRESENT_LATE, on_time_finish=0, gpu_composition=0, jank_type=JankType.JANK_SF_CPU_DEADLINE_MISSED, prediction_type=PredictionType.PREDICTION_VALID)
+trace.add_frame_end_event(ts=85, cookie=15)
+sys.stdout.buffer.write(trace.trace.SerializeToString())
diff --git a/test/trace_processor/performance/index b/test/trace_processor/performance/index
index 484f717..6f1a80d 100644
--- a/test/trace_processor/performance/index
+++ b/test/trace_processor/performance/index
@@ -2,3 +2,5 @@
 irq_runtime_metric.textproto android_irq_runtime irq_runtime_metric.out
 # CPU frequency maximum & minimum limits change
 cpu_frequency_limits.textproto cpu_frequency_limits.sql cpu_frequency_limits.out
+# frame_timeline_metric collects App_Deadline_Missed metrics
+frame_timeline_metric.py android_frame_timeline_metric frame_timeline_metric.out