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