aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIvan Kozlov <ivankozlov@google.com>2024-05-03 20:22:05 +0000
committerGerrit Code Review <noreply-gerritcodereview@google.com>2024-05-03 20:22:05 +0000
commitbfd465a5e6d77db584464a27dc7861842659a798 (patch)
tree9c3b31ce9eb4f8f5e08af54248b5ea96982e8cef
parent8a68054a08c17aaf430848acd458ef882b812954 (diff)
parent9e6623cebdcf3ff6defd29c6973834ce20dbed09 (diff)
downloadperfetto-bfd465a5e6d77db584464a27dc7861842659a798.tar.gz
Merge "Update auto multiuser metric;" into main
-rw-r--r--Android.bp4
-rw-r--r--BUILD10
-rw-r--r--protos/perfetto/metrics/android/BUILD.gn1
-rw-r--r--protos/perfetto/metrics/android/auto_metric.proto51
-rw-r--r--protos/perfetto/metrics/metrics.proto3
-rw-r--r--protos/perfetto/metrics/perfetto_merged_metrics.proto38
-rw-r--r--python/perfetto/trace_processor/metrics.descriptor27
-rw-r--r--src/trace_processor/metrics/sql/android/android_auto_multiuser.sql59
-rw-r--r--src/trace_processor/perfetto_sql/stdlib/android/BUILD.gn1
-rw-r--r--src/trace_processor/perfetto_sql/stdlib/android/auto/BUILD.gn21
-rw-r--r--src/trace_processor/perfetto_sql/stdlib/android/auto/multiuser.sql173
-rw-r--r--test/trace_processor/diff_tests/metrics/android/android_auto_multiuser.textproto127
-rw-r--r--test/trace_processor/diff_tests/metrics/android/tests.py28
13 files changed, 493 insertions, 50 deletions
diff --git a/Android.bp b/Android.bp
index 438f7d687..4fe5a6a97 100644
--- a/Android.bp
+++ b/Android.bp
@@ -5237,6 +5237,7 @@ genrule {
"protos/perfetto/metrics/android/android_trusty_workqueues.proto",
"protos/perfetto/metrics/android/anr_metric.proto",
"protos/perfetto/metrics/android/app_process_starts_metric.proto",
+ "protos/perfetto/metrics/android/auto_metric.proto",
"protos/perfetto/metrics/android/batt_metric.proto",
"protos/perfetto/metrics/android/binder_metric.proto",
"protos/perfetto/metrics/android/camera_metric.proto",
@@ -5328,6 +5329,7 @@ genrule {
"protos/perfetto/metrics/android/android_trusty_workqueues.proto",
"protos/perfetto/metrics/android/anr_metric.proto",
"protos/perfetto/metrics/android/app_process_starts_metric.proto",
+ "protos/perfetto/metrics/android/auto_metric.proto",
"protos/perfetto/metrics/android/batt_metric.proto",
"protos/perfetto/metrics/android/binder_metric.proto",
"protos/perfetto/metrics/android/camera_metric.proto",
@@ -5403,6 +5405,7 @@ genrule {
"protos/perfetto/metrics/android/android_trusty_workqueues.proto",
"protos/perfetto/metrics/android/anr_metric.proto",
"protos/perfetto/metrics/android/app_process_starts_metric.proto",
+ "protos/perfetto/metrics/android/auto_metric.proto",
"protos/perfetto/metrics/android/batt_metric.proto",
"protos/perfetto/metrics/android/binder_metric.proto",
"protos/perfetto/metrics/android/camera_metric.proto",
@@ -12961,6 +12964,7 @@ genrule {
srcs: [
"src/trace_processor/perfetto_sql/stdlib/android/anrs.sql",
"src/trace_processor/perfetto_sql/stdlib/android/app_process_starts.sql",
+ "src/trace_processor/perfetto_sql/stdlib/android/auto/multiuser.sql",
"src/trace_processor/perfetto_sql/stdlib/android/battery.sql",
"src/trace_processor/perfetto_sql/stdlib/android/battery_stats.sql",
"src/trace_processor/perfetto_sql/stdlib/android/binder.sql",
diff --git a/BUILD b/BUILD
index 2f53ea54e..5d1e5bec6 100644
--- a/BUILD
+++ b/BUILD
@@ -2412,6 +2412,14 @@ perfetto_filegroup(
],
)
+# GN target: //src/trace_processor/perfetto_sql/stdlib/android/auto:auto
+perfetto_filegroup(
+ name = "src_trace_processor_perfetto_sql_stdlib_android_auto_auto",
+ srcs = [
+ "src/trace_processor/perfetto_sql/stdlib/android/auto/multiuser.sql",
+ ],
+)
+
# GN target: //src/trace_processor/perfetto_sql/stdlib/android/frames:frames
perfetto_filegroup(
name = "src_trace_processor_perfetto_sql_stdlib_android_frames_frames",
@@ -2662,6 +2670,7 @@ perfetto_cc_amalgamated_sql(
name = "src_trace_processor_perfetto_sql_stdlib_stdlib",
deps = [
":src_trace_processor_perfetto_sql_stdlib_android_android",
+ ":src_trace_processor_perfetto_sql_stdlib_android_auto_auto",
":src_trace_processor_perfetto_sql_stdlib_android_frames_frames",
":src_trace_processor_perfetto_sql_stdlib_android_startup_startup",
":src_trace_processor_perfetto_sql_stdlib_chrome_chrome_sql",
@@ -4462,6 +4471,7 @@ perfetto_proto_library(
"protos/perfetto/metrics/android/android_trusty_workqueues.proto",
"protos/perfetto/metrics/android/anr_metric.proto",
"protos/perfetto/metrics/android/app_process_starts_metric.proto",
+ "protos/perfetto/metrics/android/auto_metric.proto",
"protos/perfetto/metrics/android/batt_metric.proto",
"protos/perfetto/metrics/android/binder_metric.proto",
"protos/perfetto/metrics/android/camera_metric.proto",
diff --git a/protos/perfetto/metrics/android/BUILD.gn b/protos/perfetto/metrics/android/BUILD.gn
index 2bb8c0e18..af7aa8f5c 100644
--- a/protos/perfetto/metrics/android/BUILD.gn
+++ b/protos/perfetto/metrics/android/BUILD.gn
@@ -33,6 +33,7 @@ perfetto_proto_library("@TYPE@") {
"android_trusty_workqueues.proto",
"anr_metric.proto",
"app_process_starts_metric.proto",
+ "auto_metric.proto",
"batt_metric.proto",
"binder_metric.proto",
"camera_metric.proto",
diff --git a/protos/perfetto/metrics/android/auto_metric.proto b/protos/perfetto/metrics/android/auto_metric.proto
new file mode 100644
index 000000000..d7043fe89
--- /dev/null
+++ b/protos/perfetto/metrics/android/auto_metric.proto
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 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
+ *
+ * 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;
+
+// Metrics for Multiuser events, such as switching users.
+message AndroidAutoMultiuserMetric {
+ message EventData {
+ // Id of the user the system has been switched to
+ optional int32 user_id = 1;
+
+ // The end event name for which the duration_ms is measured
+ optional string start_event = 2;
+
+ // The end event name for which the duration_ms is measured
+ optional string end_event = 3;
+
+ // Duration of the event (in milliseconds).
+ optional int64 duration_ms = 4;
+
+ // Previous user resource usage info during user switch
+ message UserData {
+ // Id of the user the system has been switched from
+ optional int32 user_id = 1;
+
+ optional int64 total_cpu_time_ms = 2;
+
+ optional int64 total_memory_usage_kb = 3;
+ }
+
+ optional UserData previous_user_info = 5;
+ }
+
+ // Metrics for a user switch.
+ repeated EventData user_switch = 1;
+}
diff --git a/protos/perfetto/metrics/metrics.proto b/protos/perfetto/metrics/metrics.proto
index e5a9553fd..434818796 100644
--- a/protos/perfetto/metrics/metrics.proto
+++ b/protos/perfetto/metrics/metrics.proto
@@ -22,6 +22,7 @@ import "protos/perfetto/metrics/android/ad_services_metric.proto";
import "protos/perfetto/metrics/android/android_boot.proto";
import "protos/perfetto/metrics/android/android_boot_unagg.proto";
import "protos/perfetto/metrics/android/android_garbage_collection_unagg_metric.proto";
+import "protos/perfetto/metrics/android/auto_metric.proto";
import "protos/perfetto/metrics/android/sysui_notif_shade_list_builder_metric.proto";
import "protos/perfetto/metrics/android/sysui_update_notif_on_ui_mode_changed_metric.proto";
import "protos/perfetto/metrics/android/android_frame_timeline_metric.proto";
@@ -298,7 +299,7 @@ message TraceMetrics {
// Multiuser - metrics for switching users.
// Specific for Android Auto
- optional AndroidMultiuserMetric android_auto_multiuser = 64;
+ optional AndroidAutoMultiuserMetric android_auto_multiuser = 64;
// All blocking calls (e.g. binder calls) for a trace.
optional AndroidBlockingCallsUnagg android_blocking_calls_unagg = 65;
diff --git a/protos/perfetto/metrics/perfetto_merged_metrics.proto b/protos/perfetto/metrics/perfetto_merged_metrics.proto
index a4da77818..8f736b36a 100644
--- a/protos/perfetto/metrics/perfetto_merged_metrics.proto
+++ b/protos/perfetto/metrics/perfetto_merged_metrics.proto
@@ -474,6 +474,42 @@ message AndroidTrustyWorkqueues {}
}
// End of protos/perfetto/metrics/android/anr_metric.proto
+// Begin of protos/perfetto/metrics/android/auto_metric.proto
+
+// Metrics for Multiuser events, such as switching users.
+message AndroidAutoMultiuserMetric {
+ message EventData {
+ // Id of the user the system has been switched to
+ optional int32 user_id = 1;
+
+ // The end event name for which the duration_ms is measured
+ optional string start_event = 2;
+
+ // The end event name for which the duration_ms is measured
+ optional string end_event = 3;
+
+ // Duration of the event (in milliseconds).
+ optional int64 duration_ms = 4;
+
+ // Previous user resource usage info during user switch
+ message UserData {
+ // Id of the user the system has been switched from
+ optional int32 user_id = 1;
+
+ optional int64 total_cpu_time_ms = 2;
+
+ optional int64 total_memory_usage_kb = 3;
+ }
+
+ optional UserData previous_user_info = 5;
+ }
+
+ // Metrics for a user switch.
+ repeated EventData user_switch = 1;
+}
+
+// End of protos/perfetto/metrics/android/auto_metric.proto
+
// Begin of protos/perfetto/metrics/android/batt_metric.proto
message AndroidBatteryMetric {
@@ -2822,7 +2858,7 @@ message TraceMetrics {
// Multiuser - metrics for switching users.
// Specific for Android Auto
- optional AndroidMultiuserMetric android_auto_multiuser = 64;
+ optional AndroidAutoMultiuserMetric android_auto_multiuser = 64;
// All blocking calls (e.g. binder calls) for a trace.
optional AndroidBlockingCallsUnagg android_blocking_calls_unagg = 65;
diff --git a/python/perfetto/trace_processor/metrics.descriptor b/python/perfetto/trace_processor/metrics.descriptor
index 59b0f2a97..9c1dfa01f 100644
--- a/python/perfetto/trace_processor/metrics.descriptor
+++ b/python/perfetto/trace_processor/metrics.descriptor
@@ -132,6 +132,23 @@ gc_int_dur (RgcIntDur
AndroidBootUnaggv
android_app_process_start_metric ( 2..perfetto.protos.AndroidAppProcessStartsMetricRandroidAppProcessStartMetricr
android_post_boot_gc_metric ( 24.perfetto.protos.AndroidGarbageCollectionUnaggMetricRandroidPostBootGcMetric
+
+1protos/perfetto/metrics/android/auto_metric.protoperfetto.protos"
+AndroidAutoMultiuserMetricV
+ user_switch ( 25.perfetto.protos.AndroidAutoMultiuserMetric.EventDataR
+userSwitch
+ EventData
+user_id (RuserId
+ start_event ( R
+startEvent
+ end_event ( RendEvent
+ duration_ms (R
+durationMsl
+previous_user_info ( 2>.perfetto.protos.AndroidAutoMultiuserMetric.EventData.UserDataRpreviousUserInfo
+UserData
+user_id (RuserId)
+total_cpu_time_ms (RtotalCpuTimeMs1
+total_memory_usage_kb (RtotalMemoryUsageKb

Nprotos/perfetto/metrics/android/sysui_slice_performance_statistical_data.protoperfetto.protos"
$SysUiSlicePerformanceStatisticalData
@@ -1278,8 +1295,8 @@ destBucket
avg_oom_adj_dur (R avgOomAdjDur-
oom_adj_event_count (RoomAdjEventCount$
oom_adj_reason ( R oomAdjReason
-I
-%protos/perfetto/metrics/metrics.protoperfetto.protos8protos/perfetto/metrics/android/ad_services_metric.proto2protos/perfetto/metrics/android/android_boot.proto8protos/perfetto/metrics/android/android_boot_unagg.protoMprotos/perfetto/metrics/android/android_garbage_collection_unagg_metric.protoKprotos/perfetto/metrics/android/sysui_notif_shade_list_builder_metric.protoRprotos/perfetto/metrics/android/sysui_update_notif_on_ui_mode_changed_metric.protoCprotos/perfetto/metrics/android/android_frame_timeline_metric.proto0protos/perfetto/metrics/android/anr_metric.proto1protos/perfetto/metrics/android/batt_metric.protoWprotos/perfetto/metrics/android/android_sysui_notifications_blocking_calls_metric.protoGprotos/perfetto/metrics/android/android_blocking_calls_cuj_metric.protoBprotos/perfetto/metrics/android/android_blocking_calls_unagg.proto3protos/perfetto/metrics/android/codec_metrics.proto0protos/perfetto/metrics/android/cpu_metric.proto3protos/perfetto/metrics/android/camera_metric.proto9protos/perfetto/metrics/android/camera_unagg_metric.proto5protos/perfetto/metrics/android/display_metrics.proto5protos/perfetto/metrics/android/dma_heap_metric.proto1protos/perfetto/metrics/android/dvfs_metric.proto4protos/perfetto/metrics/android/fastrpc_metric.proto0protos/perfetto/metrics/android/g2d_metric.proto0protos/perfetto/metrics/android/gpu_metric.proto0protos/perfetto/metrics/android/hwcomposer.proto1protos/perfetto/metrics/android/hwui_metric.proto/protos/perfetto/metrics/android/io_metric.proto5protos/perfetto/metrics/android/io_unagg_metric.proto0protos/perfetto/metrics/android/ion_metric.proto8protos/perfetto/metrics/android/irq_runtime_metric.proto5protos/perfetto/metrics/android/jank_cuj_metric.proto9protos/perfetto/metrics/android/java_heap_histogram.proto;protos/perfetto/metrics/android/java_heap_class_stats.proto5protos/perfetto/metrics/android/java_heap_stats.proto0protos/perfetto/metrics/android/lmk_metric.proto7protos/perfetto/metrics/android/lmk_reason_metric.proto0protos/perfetto/metrics/android/mem_metric.proto6protos/perfetto/metrics/android/mem_unagg_metric.proto6protos/perfetto/metrics/android/multiuser_metric.proto4protos/perfetto/metrics/android/network_metric.proto2protos/perfetto/metrics/android/other_traces.proto2protos/perfetto/metrics/android/package_list.proto5protos/perfetto/metrics/android/powrails_metric.proto4protos/perfetto/metrics/android/profiler_smaps.proto7protos/perfetto/metrics/android/rt_runtime_metric.proto0protos/perfetto/metrics/android/simpleperf.proto4protos/perfetto/metrics/android/startup_metric.proto4protos/perfetto/metrics/android/surfaceflinger.proto0protos/perfetto/metrics/android/task_names.proto3protos/perfetto/metrics/android/trace_quality.proto?protos/perfetto/metrics/android/android_trusty_workqueues.proto9protos/perfetto/metrics/android/unsymbolized_frames.proto3protos/perfetto/metrics/android/binder_metric.proto?protos/perfetto/metrics/android/monitor_contention_metric.protoCprotos/perfetto/metrics/android/monitor_contention_agg_metric.proto?protos/perfetto/metrics/android/app_process_starts_metric.protoAprotos/perfetto/metrics/android/android_oom_adjuster_metric.proto"
+J
+%protos/perfetto/metrics/metrics.protoperfetto.protos8protos/perfetto/metrics/android/ad_services_metric.proto2protos/perfetto/metrics/android/android_boot.proto8protos/perfetto/metrics/android/android_boot_unagg.protoMprotos/perfetto/metrics/android/android_garbage_collection_unagg_metric.proto1protos/perfetto/metrics/android/auto_metric.protoKprotos/perfetto/metrics/android/sysui_notif_shade_list_builder_metric.protoRprotos/perfetto/metrics/android/sysui_update_notif_on_ui_mode_changed_metric.protoCprotos/perfetto/metrics/android/android_frame_timeline_metric.proto0protos/perfetto/metrics/android/anr_metric.proto1protos/perfetto/metrics/android/batt_metric.protoWprotos/perfetto/metrics/android/android_sysui_notifications_blocking_calls_metric.protoGprotos/perfetto/metrics/android/android_blocking_calls_cuj_metric.protoBprotos/perfetto/metrics/android/android_blocking_calls_unagg.proto3protos/perfetto/metrics/android/codec_metrics.proto0protos/perfetto/metrics/android/cpu_metric.proto3protos/perfetto/metrics/android/camera_metric.proto9protos/perfetto/metrics/android/camera_unagg_metric.proto5protos/perfetto/metrics/android/display_metrics.proto5protos/perfetto/metrics/android/dma_heap_metric.proto1protos/perfetto/metrics/android/dvfs_metric.proto4protos/perfetto/metrics/android/fastrpc_metric.proto0protos/perfetto/metrics/android/g2d_metric.proto0protos/perfetto/metrics/android/gpu_metric.proto0protos/perfetto/metrics/android/hwcomposer.proto1protos/perfetto/metrics/android/hwui_metric.proto/protos/perfetto/metrics/android/io_metric.proto5protos/perfetto/metrics/android/io_unagg_metric.proto0protos/perfetto/metrics/android/ion_metric.proto8protos/perfetto/metrics/android/irq_runtime_metric.proto5protos/perfetto/metrics/android/jank_cuj_metric.proto9protos/perfetto/metrics/android/java_heap_histogram.proto;protos/perfetto/metrics/android/java_heap_class_stats.proto5protos/perfetto/metrics/android/java_heap_stats.proto0protos/perfetto/metrics/android/lmk_metric.proto7protos/perfetto/metrics/android/lmk_reason_metric.proto0protos/perfetto/metrics/android/mem_metric.proto6protos/perfetto/metrics/android/mem_unagg_metric.proto6protos/perfetto/metrics/android/multiuser_metric.proto4protos/perfetto/metrics/android/network_metric.proto2protos/perfetto/metrics/android/other_traces.proto2protos/perfetto/metrics/android/package_list.proto5protos/perfetto/metrics/android/powrails_metric.proto4protos/perfetto/metrics/android/profiler_smaps.proto7protos/perfetto/metrics/android/rt_runtime_metric.proto0protos/perfetto/metrics/android/simpleperf.proto4protos/perfetto/metrics/android/startup_metric.proto4protos/perfetto/metrics/android/surfaceflinger.proto0protos/perfetto/metrics/android/task_names.proto3protos/perfetto/metrics/android/trace_quality.proto?protos/perfetto/metrics/android/android_trusty_workqueues.proto9protos/perfetto/metrics/android/unsymbolized_frames.proto3protos/perfetto/metrics/android/binder_metric.proto?protos/perfetto/metrics/android/monitor_contention_metric.protoCprotos/perfetto/metrics/android/monitor_contention_agg_metric.proto?protos/perfetto/metrics/android/app_process_starts_metric.protoAprotos/perfetto/metrics/android/android_oom_adjuster_metric.proto"
TraceMetadata*
trace_duration_ns (RtraceDurationNs
@@ -1309,7 +1326,7 @@ trace_uuid ( R traceUuid:
Source
SOURCE_UNKNOWN
SOURCE_TRACE
-SOURCE_ANALYSIS"(
+SOURCE_ANALYSIS"(
TraceMetricsH
android_batt ( 2%.perfetto.protos.AndroidBatteryMetricR androidBattB
android_cpu ( 2!.perfetto.protos.AndroidCpuMetricR
@@ -1373,8 +1390,8 @@ androidAnrw
,sysui_update_notif_on_ui_mode_changed_metric< ( 26.perfetto.protos.SysuiUpdateNotifOnUiModeChangedMetricR%sysuiUpdateNotifOnUiModeChangedMetrick
android_app_process_starts= ( 2..perfetto.protos.AndroidAppProcessStartsMetricRandroidAppProcessStartsO
android_boot_unagg> ( 2!.perfetto.protos.AndroidBootUnaggRandroidBootUnagg}
- android_garbage_collection_unagg? ( 24.perfetto.protos.AndroidGarbageCollectionUnaggMetricRandroidGarbageCollectionUnagg]
-android_auto_multiuser@ ( 2'.perfetto.protos.AndroidMultiuserMetricRandroidAutoMultiuserk
+ android_garbage_collection_unagg? ( 24.perfetto.protos.AndroidGarbageCollectionUnaggMetricRandroidGarbageCollectionUnagga
+android_auto_multiuser@ ( 2+.perfetto.protos.AndroidAutoMultiuserMetricRandroidAutoMultiuserk
android_blocking_calls_unaggA ( 2*.perfetto.protos.AndroidBlockingCallsUnaggRandroidBlockingCallsUnagg[
android_oom_adjusterB ( 2).perfetto.protos.AndroidOomAdjusterMetricRandroidOomAdjuster****JJ
 J JJJJJJ \ No newline at end of file
diff --git a/src/trace_processor/metrics/sql/android/android_auto_multiuser.sql b/src/trace_processor/metrics/sql/android/android_auto_multiuser.sql
index 3b1230515..2be5ef0de 100644
--- a/src/trace_processor/metrics/sql/android/android_auto_multiuser.sql
+++ b/src/trace_processor/metrics/sql/android/android_auto_multiuser.sql
@@ -14,51 +14,26 @@
-- limitations under the License.
--
-INCLUDE PERFETTO MODULE android.startup.startups;
-
--- Collect the last ts for user switch event.
--- The metric should represent time elapsed between
--- the latest user start and the latest carlauncher startup.
-DROP VIEW IF EXISTS auto_multiuser_events;
-CREATE PERFETTO VIEW auto_multiuser_events AS
-SELECT
- user_start_time_ns AS event_start_time_ns,
- launcher_end_time_ns AS event_end_time_ns
-FROM
- (
- SELECT MAX(slice.ts) as user_start_time_ns
- FROM slice
- WHERE (
- slice.name GLOB "UserController.startUser*"
- AND slice.name NOT GLOB "UserController.startUser-10*"
- )
- ),
- (
- SELECT ts_end AS launcher_end_time_ns
- FROM android_startups
- WHERE (package = 'com.android.car.carlauncher')
- );
-
--- Precompute user switch duration time.
--- Take only positive duration values(user start ts < carlauncher start ts)
--- If there are potential duplicates in carlauncher startup,
--- take the smallest value. It represents the closest carlaucnher startup
-DROP TABLE IF EXISTS android_auto_multiuser_timing;
-CREATE PERFETTO TABLE android_auto_multiuser_timing AS
-SELECT
- cast_int!((event_end_time_ns - event_start_time_ns) / 1e6 + 0.5) as duration_ms
-FROM
- auto_multiuser_events
-WHERE duration_ms > 0
-ORDER BY duration_ms ASC
-LIMIT 1;
+INCLUDE PERFETTO MODULE android.auto.multiuser;
+INCLUDE PERFETTO MODULE time.conversion;
DROP VIEW IF EXISTS android_auto_multiuser_output;
CREATE PERFETTO VIEW android_auto_multiuser_output AS
-SELECT AndroidMultiuserMetric (
- 'user_switch', AndroidMultiuserMetric_EventData(
- 'duration_ms', (
- SELECT duration_ms FROM android_auto_multiuser_timing
+SELECT AndroidAutoMultiuserMetric(
+ 'user_switch', (
+ SELECT RepeatedField(
+ AndroidAutoMultiuserMetric_EventData(
+ 'user_id', cast_int!(event_start_user_id),
+ 'start_event', event_start_name,
+ 'end_event', event_end_name,
+ 'duration_ms', time_to_ms(duration),
+ 'previous_user_info', AndroidAutoMultiuserMetric_EventData_UserData(
+ 'user_id', user_id,
+ 'total_cpu_time_ms', time_to_ms(total_cpu_time),
+ 'total_memory_usage_kb', total_memory_usage_kb
+ )
+ )
)
+ FROM android_auto_multiuser_timing_with_previous_user_resource_usage
)
); \ No newline at end of file
diff --git a/src/trace_processor/perfetto_sql/stdlib/android/BUILD.gn b/src/trace_processor/perfetto_sql/stdlib/android/BUILD.gn
index 786882eb3..bd2f18d9d 100644
--- a/src/trace_processor/perfetto_sql/stdlib/android/BUILD.gn
+++ b/src/trace_processor/perfetto_sql/stdlib/android/BUILD.gn
@@ -16,6 +16,7 @@ import("../../../../../gn/perfetto_sql.gni")
perfetto_sql_source_set("android") {
deps = [
+ "auto",
"frames",
"startup",
]
diff --git a/src/trace_processor/perfetto_sql/stdlib/android/auto/BUILD.gn b/src/trace_processor/perfetto_sql/stdlib/android/auto/BUILD.gn
new file mode 100644
index 000000000..bf52d69d5
--- /dev/null
+++ b/src/trace_processor/perfetto_sql/stdlib/android/auto/BUILD.gn
@@ -0,0 +1,21 @@
+# Copyright (C) 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
+#
+# 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.
+
+import("../../../../../../gn/perfetto_sql.gni")
+
+perfetto_sql_source_set("auto") {
+ sources = [
+ "multiuser.sql",
+ ]
+}
diff --git a/src/trace_processor/perfetto_sql/stdlib/android/auto/multiuser.sql b/src/trace_processor/perfetto_sql/stdlib/android/auto/multiuser.sql
new file mode 100644
index 000000000..ea95dcc4e
--- /dev/null
+++ b/src/trace_processor/perfetto_sql/stdlib/android/auto/multiuser.sql
@@ -0,0 +1,173 @@
+--
+-- 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 android.startup.startups;
+
+-- Time elapsed between the latest user start
+-- and the specific end event
+-- like package startup(ex carlauncher) or previous user stop.
+CREATE PERFETTO TABLE android_auto_multiuser_timing(
+ -- Id of the started android user
+ event_start_user_id STRING,
+ -- Start event time
+ event_start_time INT,
+ -- End event time
+ event_end_time INT,
+ -- End event name
+ event_end_name STRING,
+ -- Start event name
+ event_start_name STRING,
+ -- User switch duration from start event
+ -- to end event
+ duration LONG
+) AS
+-- The last ts for user switch event.
+WITH auto_multiuser_user_start AS (
+ SELECT
+ slice.name as event_start_name,
+ slice.ts AS user_start_time,
+ -- Ex.: UserController.startUser-11-fg-start-mode-1
+ -- User is enclosed in dashes and will be at most 2 characters(10, 11, etc.)
+ SUBSTR(name, INSTR(name, '-') + 1, 2) as started_user_id
+ FROM slice
+ WHERE (
+ slice.name GLOB "UserController.startUser*"
+ AND slice.name NOT GLOB "UserController.startUser-10*"
+ )
+ ORDER BY ts DESC
+ LIMIT 1
+)
+SELECT
+ started_user_id AS event_start_user_id,
+ user_start_time AS event_start_time,
+ event_end_time,
+ event_end_name,
+ event_start_name,
+ (event_end_time - user_start_time) as duration
+FROM (
+ SELECT
+ ts_end AS event_end_time,
+ package as event_end_name
+ FROM android_startups
+ UNION
+ SELECT
+ slice.ts as event_end_time,
+ slice.name as event_end_name
+ FROM slice
+ WHERE slice.name GLOB "finishUserStopped-10*"
+) as a
+JOIN auto_multiuser_user_start as b
+ON a.event_end_time > b.user_start_time;
+
+-- Previous user(user 10) total CPU time
+CREATE PERFETTO VIEW _android_auto_user_10_total_cpu_time AS
+SELECT
+ SUM(dur) as total_cpu_time,
+ (uid - android_appid) / 100000 as user_id,
+ event_end_name
+FROM sched_slice
+ JOIN thread USING (utid)
+ JOIN process USING (upid),
+ android_auto_multiuser_timing
+WHERE
+ user_id = 10
+ AND ts >= android_auto_multiuser_timing.event_start_time
+ AND ts <= android_auto_multiuser_timing.event_end_time
+GROUP BY event_end_name;
+
+-- Previous user(user 10) total memory usage
+CREATE PERFETTO VIEW _android_auto_user_10_total_memory AS
+WITH filtered_process AS (
+ SELECT
+ c.ts,
+ c.value,
+ p.name AS proc_name,
+ (uid - android_appid) / 100000 as user_id,
+ event_end_name
+ FROM counter AS c
+ LEFT JOIN process_counter_track AS t
+ ON c.track_id = t.id
+ LEFT JOIN process AS p USING (upid),
+ android_auto_multiuser_timing
+ WHERE
+ t.name GLOB "mem.rss"
+ AND user_id = 10
+ AND c.ts >= android_auto_multiuser_timing.event_start_time
+ AND c.ts <= android_auto_multiuser_timing.event_end_time
+),
+process_rss AS (
+ SELECT
+ *,
+ ifnull(
+ lag(value) OVER (PARTITION BY proc_name, event_end_name ORDER BY ts), value
+ ) AS prev_value
+ FROM filtered_process
+),
+per_process_allocations AS (
+ SELECT
+ proc_name,
+ SUM(value - prev_value) / 1e3 AS alloc_value_kb,
+ user_id,
+ event_end_name
+ FROM process_rss
+ WHERE value - prev_value > 0
+ GROUP BY proc_name, event_end_name
+ ORDER BY alloc_value_kb DESC
+)
+SELECT
+ cast_int!(SUM(alloc_value_kb)) AS total_memory_usage_kb,
+ user_id,
+ event_end_name
+FROM per_process_allocations
+GROUP BY event_end_name;
+
+-- This table extends `android_auto_multiuser_timing` table with previous user resource usage.
+CREATE PERFETTO VIEW android_auto_multiuser_timing_with_previous_user_resource_usage(
+ -- Start user id
+ event_start_user_id STRING,
+ -- Start event time
+ event_start_time INT,
+ -- End event time
+ event_end_time INT,
+ -- End event name
+ event_end_name STRING,
+ -- Start event name
+ event_start_name STRING,
+ -- User switch duration from start event
+ -- to end event
+ duration LONG,
+ -- User id
+ user_id INT,
+ -- Total CPU time for a user
+ total_cpu_time LONG,
+ -- Total memory user for a user
+ total_memory_usage_kb LONG
+) AS
+SELECT
+ a.event_start_user_id,
+ a.event_start_time,
+ a.event_end_time,
+ a.event_end_name,
+ a.event_start_name,
+ a.duration,
+ b.user_id,
+ b.total_cpu_time,
+ c.total_memory_usage_kb
+FROM android_auto_multiuser_timing as a
+LEFT JOIN _android_auto_user_10_total_cpu_time as b
+ ON a.event_end_name = b.event_end_name
+LEFT JOIN _android_auto_user_10_total_memory as c
+ ON a.event_end_name = c.event_end_name; \ No newline at end of file
diff --git a/test/trace_processor/diff_tests/metrics/android/android_auto_multiuser.textproto b/test/trace_processor/diff_tests/metrics/android/android_auto_multiuser.textproto
new file mode 100644
index 000000000..c33839e22
--- /dev/null
+++ b/test/trace_processor/diff_tests/metrics/android/android_auto_multiuser.textproto
@@ -0,0 +1,127 @@
+packet {
+ timestamp: 1
+ process_tree {
+ processes {
+ pid: 10
+ uid: 1000010
+ cmdline: "dummy:1"
+ }
+ processes {
+ pid: 11
+ uid: 1000010
+ cmdline: "dummy:2"
+ }
+ }
+}
+packet {
+ ftrace_events {
+ event {
+ timestamp: 1000000000
+ print {
+ buf: "S|5993|UserController.startUser-10-fg-start-mode-1|0\n"
+ }
+ }
+ }
+}
+packet {
+ ftrace_events {
+ event {
+ timestamp: 2000000000
+ print {
+ buf: "S|2608|launching: com.android.car.carlauncher|0\n"
+ }
+ }
+ }
+}
+packet {
+ ftrace_events {
+ cpu: 1
+ event {
+ timestamp: 3000000001
+ pid: 10
+ sched_switch {
+ prev_comm: "dummy:1"
+ prev_pid: 10
+ prev_state: 2
+ next_comm: "dummy:2"
+ next_pid: 11
+ }
+ }
+ }
+}
+packet {
+ ftrace_events {
+ cpu: 1
+ event {
+ timestamp: 3010000000
+ pid: 11
+ sched_switch {
+ prev_comm: "dummy:2"
+ prev_pid: 11
+ prev_state: 2
+ next_comm: "dummy:1"
+ next_pid: 10
+ }
+ }
+ }
+}
+packet {
+ timestamp: 3000000001
+ process_stats {
+ processes {
+ pid: 10
+ vm_rss_kb: 1000
+ }
+ }
+}
+packet {
+ timestamp: 3000000002
+ process_stats {
+ processes {
+ pid: 10
+ vm_rss_kb: 2000
+ }
+ }
+}
+packet {
+ timestamp: 3000000001
+ process_stats {
+ processes {
+ pid: 11
+ vm_rss_kb: 1000
+ }
+ }
+}
+packet {
+ timestamp: 3000000002
+ process_stats {
+ processes {
+ pid: 11
+ vm_rss_kb: 2000
+ }
+ }
+}
+packet {
+ ftrace_events {
+ cpu: 1
+ event {
+ timestamp: 3000000000
+ pid: 1
+ print {
+ buf: "S|5993|UserController.startUser-11-fg-start-mode-1|0\n"
+ }
+ }
+ }
+}
+packet {
+ ftrace_events {
+ cpu: 1
+ event {
+ timestamp: 4000000000
+ pid: 1
+ print {
+ buf: "S|2609|launching: com.android.car.carlauncher|0\n"
+ }
+ }
+ }
+} \ 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 da5559ea3..a1c244843 100644
--- a/test/trace_processor/diff_tests/metrics/android/tests.py
+++ b/test/trace_processor/diff_tests/metrics/android/tests.py
@@ -299,10 +299,36 @@ class AndroidMetrics(TestSuite):
out=TextProto(r"""
android_auto_multiuser {
user_switch {
- duration_ms: 3878
+ user_id: 11
+ start_event: "UserController.startUser-11-fg-start-mode-1"
+ end_event: "com.android.car.carlauncher"
+ duration_ms: 3877
+ previous_user_info {
+ }
+ }
+ }
+ """))
+
+ def test_android_auto_multiuser_switch_with_previous_user_data(self):
+ return DiffTestBlueprint(
+ trace=Path("android_auto_multiuser.textproto"),
+ query=Metric('android_auto_multiuser'),
+ out=TextProto(r"""
+ android_auto_multiuser {
+ user_switch {
+ user_id: 11
+ start_event: "UserController.startUser-11-fg-start-mode-1"
+ end_event: "com.android.car.carlauncher"
+ duration_ms: 999
+ previous_user_info {
+ user_id: 10
+ total_cpu_time_ms: 9
+ total_memory_usage_kb: 2048
+ }
}
}
"""))
+
def test_android_oom_adjuster(self):
return DiffTestBlueprint(
trace=DataPath('android_postboot_unlock.pftrace'),