tp: add viewcapture parsing
Bug: 323166383
Change-Id: Ifa70b3008463ba4542c5716b953644bce988fe3c
diff --git a/Android.bp b/Android.bp
index c27bfd8..c750262 100644
--- a/Android.bp
+++ b/Android.bp
@@ -12502,6 +12502,7 @@
"src/trace_processor/importers/proto/winscope/shell_transitions_tracker.cc",
"src/trace_processor/importers/proto/winscope/surfaceflinger_layers_parser.cc",
"src/trace_processor/importers/proto/winscope/surfaceflinger_transactions_parser.cc",
+ "src/trace_processor/importers/proto/winscope/viewcapture_args_parser.cc",
"src/trace_processor/importers/proto/winscope/winscope_module.cc",
],
}
@@ -13094,6 +13095,7 @@
"src/trace_processor/perfetto_sql/stdlib/android/suspend.sql",
"src/trace_processor/perfetto_sql/stdlib/android/thread.sql",
"src/trace_processor/perfetto_sql/stdlib/android/winscope/inputmethod.sql",
+ "src/trace_processor/perfetto_sql/stdlib/android/winscope/viewcapture.sql",
"src/trace_processor/perfetto_sql/stdlib/chrome/**/*.sql",
"src/trace_processor/perfetto_sql/stdlib/common/args.sql",
"src/trace_processor/perfetto_sql/stdlib/common/counters.sql",
diff --git a/BUILD b/BUILD
index 5d12e4c..78c6af4 100644
--- a/BUILD
+++ b/BUILD
@@ -1777,6 +1777,8 @@
"src/trace_processor/importers/proto/winscope/surfaceflinger_layers_parser.h",
"src/trace_processor/importers/proto/winscope/surfaceflinger_transactions_parser.cc",
"src/trace_processor/importers/proto/winscope/surfaceflinger_transactions_parser.h",
+ "src/trace_processor/importers/proto/winscope/viewcapture_args_parser.cc",
+ "src/trace_processor/importers/proto/winscope/viewcapture_args_parser.h",
"src/trace_processor/importers/proto/winscope/winscope_module.cc",
"src/trace_processor/importers/proto/winscope/winscope_module.h",
],
@@ -2509,6 +2511,7 @@
name = "src_trace_processor_perfetto_sql_stdlib_android_winscope_winscope",
srcs = [
"src/trace_processor/perfetto_sql/stdlib/android/winscope/inputmethod.sql",
+ "src/trace_processor/perfetto_sql/stdlib/android/winscope/viewcapture.sql",
],
)
diff --git a/protos/perfetto/trace/android/winscope.proto b/protos/perfetto/trace/android/winscope.proto
index d7927d8..50723ee 100644
--- a/protos/perfetto/trace/android/winscope.proto
+++ b/protos/perfetto/trace/android/winscope.proto
@@ -22,6 +22,7 @@
import "protos/perfetto/trace/android/shell_transition.proto";
import "protos/perfetto/trace/android/surfaceflinger_layers.proto";
import "protos/perfetto/trace/android/surfaceflinger_transactions.proto";
+import "protos/perfetto/trace/android/viewcapture.proto";
import "protos/perfetto/trace/android/winscope_extensions_impl.proto";
// This file is used to generated descriptors for all the winscope protos.
@@ -32,4 +33,5 @@
optional ShellTransition shell_transition = 3;
optional ProtoLogMessage protolog_message = 4;
optional WinscopeExtensionsImpl winscope_extensions = 5;
+ optional ViewCapture viewcapture = 6;
}
diff --git a/src/trace_processor/importers/common/args_tracker.h b/src/trace_processor/importers/common/args_tracker.h
index 964a6ad..8b8d35c 100644
--- a/src/trace_processor/importers/common/args_tracker.h
+++ b/src/trace_processor/importers/common/args_tracker.h
@@ -154,6 +154,10 @@
context_->storage->mutable_surfaceflinger_transactions_table(), id);
}
+ BoundInserter AddArgsTo(tables::ViewCaptureTable::Id id) {
+ return AddArgsTo(context_->storage->mutable_viewcapture_table(), id);
+ }
+
BoundInserter AddArgsTo(tables::WindowManagerShellTransitionsTable::Id id) {
return AddArgsTo(
context_->storage->mutable_window_manager_shell_transitions_table(),
diff --git a/src/trace_processor/importers/proto/winscope/BUILD.gn b/src/trace_processor/importers/proto/winscope/BUILD.gn
index 593b749..d22dee0 100644
--- a/src/trace_processor/importers/proto/winscope/BUILD.gn
+++ b/src/trace_processor/importers/proto/winscope/BUILD.gn
@@ -16,6 +16,8 @@
source_set("full") {
sources = [
+ "viewcapture_args_parser.cc",
+ "viewcapture_args_parser.h",
"protolog_messages_tracker.cc",
"protolog_messages_tracker.h",
"protolog_parser.cc",
diff --git a/src/trace_processor/importers/proto/winscope/viewcapture_args_parser.cc b/src/trace_processor/importers/proto/winscope/viewcapture_args_parser.cc
new file mode 100644
index 0000000..ed88163
--- /dev/null
+++ b/src/trace_processor/importers/proto/winscope/viewcapture_args_parser.cc
@@ -0,0 +1,128 @@
+/*
+ * 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.
+ */
+
+#include "src/trace_processor/importers/proto/winscope/viewcapture_args_parser.h"
+#include "perfetto/ext/base/string_utils.h"
+#include "perfetto/ext/base/string_view.h"
+#include "protos/perfetto/trace/interned_data/interned_data.pbzero.h"
+#include "protos/perfetto/trace/profiling/profile_common.pbzero.h"
+#include "src/trace_processor/importers/proto/packet_sequence_state_generation.h"
+
+namespace perfetto {
+namespace trace_processor {
+
+ViewCaptureArgsParser::ViewCaptureArgsParser(
+ int64_t packet_timestamp,
+ ArgsTracker::BoundInserter& inserter,
+ TraceStorage& storage,
+ PacketSequenceStateGeneration* sequence_state)
+ : ArgsParser(packet_timestamp, inserter, storage, sequence_state),
+ storage_{storage} {}
+
+void ViewCaptureArgsParser::AddInteger(const Key& key, int64_t value) {
+ if (TryAddDeinternedString(key, static_cast<uint64_t>(value))) {
+ return;
+ }
+ ArgsParser::AddInteger(key, value);
+}
+
+void ViewCaptureArgsParser::AddUnsignedInteger(const Key& key, uint64_t value) {
+ if (TryAddDeinternedString(key, value)) {
+ return;
+ }
+ ArgsParser::AddUnsignedInteger(key, value);
+}
+
+bool ViewCaptureArgsParser::TryAddDeinternedString(const Key& key,
+ uint64_t iid) {
+ bool is_interned_field = base::EndsWith(key.key, "_iid");
+ if (!is_interned_field) {
+ return false;
+ }
+
+ const auto deintern_key = key.key.substr(0, key.key.size() - 4);
+ const auto deintern_flat_key =
+ key.flat_key.substr(0, key.flat_key.size() - 4);
+ const auto deintern_key_combined = Key{deintern_flat_key, deintern_key};
+ const auto deintern_val = TryDeinternString(key, iid);
+
+ if (!deintern_val) {
+ ArgsParser::AddString(
+ deintern_key_combined,
+ protozero::ConstChars{ERROR_MSG.data(), ERROR_MSG.size()});
+ storage_.IncrementStats(
+ stats::winscope_viewcapture_missing_interned_string_parse_errors);
+ return false;
+ }
+
+ ArgsParser::AddString(deintern_key_combined, *deintern_val);
+ return true;
+}
+
+std::optional<protozero::ConstChars> ViewCaptureArgsParser::TryDeinternString(
+ const Key& key,
+ uint64_t iid) {
+ if (base::EndsWith(key.key, "class_name_iid")) {
+ auto* decoder =
+ seq_state()
+ ->LookupInternedMessage<
+ protos::pbzero::InternedData::kViewcaptureClassNameFieldNumber,
+ protos::pbzero::InternedString>(iid);
+ if (decoder) {
+ return protozero::ConstChars{
+ reinterpret_cast<const char*>(decoder->str().data),
+ decoder->str().size};
+ }
+ } else if (base::EndsWith(key.key, "package_name_iid")) {
+ auto* decoder =
+ seq_state()
+ ->LookupInternedMessage<protos::pbzero::InternedData::
+ kViewcapturePackageNameFieldNumber,
+ protos::pbzero::InternedString>(iid);
+ if (decoder) {
+ return protozero::ConstChars{
+ reinterpret_cast<const char*>(decoder->str().data),
+ decoder->str().size};
+ }
+ } else if (base::EndsWith(key.key, "view_id_iid")) {
+ auto* decoder =
+ seq_state()
+ ->LookupInternedMessage<
+ protos::pbzero::InternedData::kViewcaptureViewIdFieldNumber,
+ protos::pbzero::InternedString>(iid);
+ if (decoder) {
+ return protozero::ConstChars{
+ reinterpret_cast<const char*>(decoder->str().data),
+ decoder->str().size};
+ }
+ } else if (base::EndsWith(key.key, "window_name_iid")) {
+ auto* decoder =
+ seq_state()
+ ->LookupInternedMessage<
+ protos::pbzero::InternedData::kViewcaptureWindowNameFieldNumber,
+ protos::pbzero::InternedString>(iid);
+ if (decoder) {
+ return protozero::ConstChars{
+ reinterpret_cast<const char*>(decoder->str().data),
+ decoder->str().size};
+ }
+ }
+
+ return std::nullopt;
+}
+
+} // namespace trace_processor
+} // namespace perfetto
diff --git a/src/trace_processor/importers/proto/winscope/viewcapture_args_parser.h b/src/trace_processor/importers/proto/winscope/viewcapture_args_parser.h
new file mode 100644
index 0000000..32b76b6
--- /dev/null
+++ b/src/trace_processor/importers/proto/winscope/viewcapture_args_parser.h
@@ -0,0 +1,50 @@
+/*
+ * 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.
+ */
+
+#ifndef SRC_TRACE_PROCESSOR_IMPORTERS_PROTO_WINSCOPE_VIEWCAPTURE_ARGS_PARSER_H_
+#define SRC_TRACE_PROCESSOR_IMPORTERS_PROTO_WINSCOPE_VIEWCAPTURE_ARGS_PARSER_H_
+
+#include <optional>
+
+#include "src/trace_processor/importers/proto/args_parser.h"
+
+namespace perfetto {
+namespace trace_processor {
+
+// Specialized args parser to de-intern ViewCapture strings
+class ViewCaptureArgsParser : public ArgsParser {
+ public:
+ using Key = ArgsParser::Key;
+
+ ViewCaptureArgsParser(int64_t packet_timestamp,
+ ArgsTracker::BoundInserter& inserter,
+ TraceStorage& storage,
+ PacketSequenceStateGeneration* sequence_state);
+ void AddInteger(const Key&, int64_t) override;
+ void AddUnsignedInteger(const Key&, uint64_t) override;
+
+ private:
+ bool TryAddDeinternedString(const Key&, uint64_t);
+ std::optional<protozero::ConstChars> TryDeinternString(const Key&, uint64_t);
+
+ const base::StringView ERROR_MSG{"STRING DE-INTERNING ERROR"};
+ TraceStorage& storage_;
+};
+
+} // namespace trace_processor
+} // namespace perfetto
+
+#endif // SRC_TRACE_PROCESSOR_IMPORTERS_PROTO_WINSCOPE_VIEWCAPTURE_ARGS_PARSER_H_
diff --git a/src/trace_processor/importers/proto/winscope/winscope_module.cc b/src/trace_processor/importers/proto/winscope/winscope_module.cc
index 4bf2723..81c7a59 100644
--- a/src/trace_processor/importers/proto/winscope/winscope_module.cc
+++ b/src/trace_processor/importers/proto/winscope/winscope_module.cc
@@ -18,6 +18,7 @@
#include "protos/perfetto/trace/android/winscope_extensions.pbzero.h"
#include "protos/perfetto/trace/android/winscope_extensions_impl.pbzero.h"
#include "src/trace_processor/importers/proto/args_parser.h"
+#include "src/trace_processor/importers/proto/winscope/viewcapture_args_parser.h"
#include "src/trace_processor/importers/proto/winscope/winscope.descriptor.h"
namespace perfetto {
@@ -76,13 +77,15 @@
decoder.protolog_viewer_config());
return;
case TracePacket::kWinscopeExtensionsFieldNumber:
- ParseWinscopeExtensionsData(decoder.winscope_extensions(), timestamp);
+ ParseWinscopeExtensionsData(decoder.winscope_extensions(), timestamp,
+ data);
return;
}
}
void WinscopeModule::ParseWinscopeExtensionsData(protozero::ConstBytes blob,
- int64_t timestamp) {
+ int64_t timestamp,
+ const TracePacketData& data) {
WinscopeExtensionsImpl::Decoder decoder(blob.data, blob.size);
if (auto field =
@@ -97,6 +100,11 @@
WinscopeExtensionsImpl::kInputmethodServiceFieldNumber);
field.valid()) {
ParseInputMethodServiceData(timestamp, field.as_bytes());
+ } else if (field =
+ decoder.Get(WinscopeExtensionsImpl::kViewcaptureFieldNumber);
+ field.valid()) {
+ ParseViewCaptureData(timestamp, field.as_bytes(),
+ data.sequence_state.get());
}
}
@@ -159,5 +167,24 @@
}
}
+void WinscopeModule::ParseViewCaptureData(
+ int64_t timestamp,
+ protozero::ConstBytes blob,
+ PacketSequenceStateGeneration* sequence_state) {
+ tables::ViewCaptureTable::Row row;
+ row.ts = timestamp;
+ auto rowId = context_->storage->mutable_viewcapture_table()->Insert(row).id;
+
+ ArgsTracker tracker(context_);
+ auto inserter = tracker.AddArgsTo(rowId);
+ ViewCaptureArgsParser writer(timestamp, inserter, *context_->storage.get(),
+ sequence_state);
+ base::Status status = args_parser_.ParseMessage(
+ blob, kViewCaptureProtoName, nullptr /* parse all fields */, writer);
+ if (!status.ok()) {
+ context_->storage->IncrementStats(stats::winscope_viewcapture_parse_errors);
+ }
+}
+
} // namespace trace_processor
} // namespace perfetto
diff --git a/src/trace_processor/importers/proto/winscope/winscope_module.h b/src/trace_processor/importers/proto/winscope/winscope_module.h
index c77fcb4..7f6ae08 100644
--- a/src/trace_processor/importers/proto/winscope/winscope_module.h
+++ b/src/trace_processor/importers/proto/winscope/winscope_module.h
@@ -42,21 +42,25 @@
private:
void ParseWinscopeExtensionsData(protozero::ConstBytes blob,
- int64_t timestamp);
+ int64_t timestamp,
+ const TracePacketData&);
void ParseInputMethodClientsData(int64_t timestamp,
protozero::ConstBytes blob);
void ParseInputMethodManagerServiceData(int64_t timestamp,
protozero::ConstBytes blob);
void ParseInputMethodServiceData(int64_t timestamp,
protozero::ConstBytes blob);
+ void ParseViewCaptureData(int64_t timestamp,
+ protozero::ConstBytes blob,
+ PacketSequenceStateGeneration* sequence_state);
static constexpr auto* kInputMethodClientsProtoName =
".perfetto.protos.InputMethodClientsTraceProto";
static constexpr auto* kInputMethodManagerServiceProtoName =
".perfetto.protos.InputMethodManagerServiceTraceProto";
-
static constexpr auto* kInputMethodServiceProtoName =
".perfetto.protos.InputMethodServiceTraceProto";
+ static constexpr auto* kViewCaptureProtoName = ".perfetto.protos.ViewCapture";
TraceProcessorContext* const context_;
DescriptorPool pool_;
diff --git a/src/trace_processor/perfetto_sql/stdlib/android/winscope/BUILD.gn b/src/trace_processor/perfetto_sql/stdlib/android/winscope/BUILD.gn
index 93abe35..ff7e3ef 100644
--- a/src/trace_processor/perfetto_sql/stdlib/android/winscope/BUILD.gn
+++ b/src/trace_processor/perfetto_sql/stdlib/android/winscope/BUILD.gn
@@ -17,5 +17,6 @@
perfetto_sql_source_set("winscope") {
sources = [
"inputmethod.sql",
+ "viewcapture.sql",
]
}
diff --git a/src/trace_processor/perfetto_sql/stdlib/android/winscope/viewcapture.sql b/src/trace_processor/perfetto_sql/stdlib/android/winscope/viewcapture.sql
new file mode 100644
index 0000000..77e68b5
--- /dev/null
+++ b/src/trace_processor/perfetto_sql/stdlib/android/winscope/viewcapture.sql
@@ -0,0 +1,29 @@
+--
+-- 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.
+
+-- Android viewcapture (from android.viewcapture data source).
+CREATE PERFETTO VIEW android_viewcapture(
+ -- Snapshot id
+ id INT,
+ -- Timestamp when the snapshot was triggered
+ ts INT,
+ -- Extra args parsed from the proto message
+ arg_set_id INT
+) AS
+SELECT
+ id,
+ ts,
+ arg_set_id
+FROM __intrinsic_viewcapture;
diff --git a/src/trace_processor/storage/stats.h b/src/trace_processor/storage/stats.h
index c8d58ca..6238455 100644
--- a/src/trace_processor/storage/stats.h
+++ b/src/trace_processor/storage/stats.h
@@ -349,6 +349,14 @@
F(winscope_protolog_missing_interned_stacktrace_parse_errors, \
kSingle, kInfo, kAnalysis, \
"Failed to find interned ProtoLog stacktrace."), \
+ F(winscope_viewcapture_parse_errors, \
+ kSingle, kInfo, kAnalysis, \
+ "ViewCapture packet has unknown fields, which results in some " \
+ "arguments missing. You may need a newer version of trace processor " \
+ "to parse them."), \
+ F(winscope_viewcapture_missing_interned_string_parse_errors, \
+ kSingle, kInfo, kAnalysis, \
+ "Failed to find interned ViewCapture string."), \
F(jit_unknown_frame, kSingle, kDataLoss, kTrace, \
"Indicates that we were unable to determine the function for a frame in "\
"a jitted memory region"), \
diff --git a/src/trace_processor/storage/trace_storage.h b/src/trace_processor/storage/trace_storage.h
index ff280e1..efc667e 100644
--- a/src/trace_processor/storage/trace_storage.h
+++ b/src/trace_processor/storage/trace_storage.h
@@ -845,6 +845,13 @@
return &surfaceflinger_transactions_table_;
}
+ const tables::ViewCaptureTable& viewcapture_table() const {
+ return viewcapture_table_;
+ }
+ tables::ViewCaptureTable* mutable_viewcapture_table() {
+ return &viewcapture_table_;
+ }
+
const tables::WindowManagerShellTransitionsTable&
window_manager_shell_transitions_table() const {
return window_manager_shell_transitions_table_;
@@ -1147,6 +1154,7 @@
tables::SurfaceFlingerLayerTable surfaceflinger_layer_table_{&string_pool_};
tables::SurfaceFlingerTransactionsTable surfaceflinger_transactions_table_{
&string_pool_};
+ tables::ViewCaptureTable viewcapture_table_{&string_pool_};
tables::WindowManagerShellTransitionsTable
window_manager_shell_transitions_table_{&string_pool_};
tables::WindowManagerShellTransitionHandlersTable
diff --git a/src/trace_processor/tables/table_destructors.cc b/src/trace_processor/tables/table_destructors.cc
index 6093c83..2902edc 100644
--- a/src/trace_processor/tables/table_destructors.cc
+++ b/src/trace_processor/tables/table_destructors.cc
@@ -139,15 +139,16 @@
InputMethodClientsTable::~InputMethodClientsTable() = default;
InputMethodManagerServiceTable::~InputMethodManagerServiceTable() = default;
InputMethodServiceTable::~InputMethodServiceTable() = default;
+ProtoLogTable::~ProtoLogTable() = default;
SurfaceFlingerLayersSnapshotTable::~SurfaceFlingerLayersSnapshotTable() =
default;
SurfaceFlingerLayerTable::~SurfaceFlingerLayerTable() = default;
SurfaceFlingerTransactionsTable::~SurfaceFlingerTransactionsTable() = default;
+ViewCaptureTable::~ViewCaptureTable() = default;
WindowManagerShellTransitionsTable::~WindowManagerShellTransitionsTable() =
default;
WindowManagerShellTransitionHandlersTable::
~WindowManagerShellTransitionHandlersTable() = default;
-ProtoLogTable::~ProtoLogTable() = default;
} // namespace tables
diff --git a/src/trace_processor/tables/winscope_tables.py b/src/trace_processor/tables/winscope_tables.py
index 8c058aa..15b93bb 100644
--- a/src/trace_processor/tables/winscope_tables.py
+++ b/src/trace_processor/tables/winscope_tables.py
@@ -117,6 +117,22 @@
'arg_set_id': 'Extra args parsed from the proto message',
}))
+VIEWCAPTURE_TABLE = Table(
+ python_module=__file__,
+ class_name='ViewCaptureTable',
+ sql_name='__intrinsic_viewcapture',
+ columns=[
+ C('ts', CppInt64()),
+ C('arg_set_id', CppUint32()),
+ ],
+ tabledoc=TableDoc(
+ doc='ViewCapture',
+ group='Winscope',
+ columns={
+ 'ts': 'The timestamp the views were captured',
+ 'arg_set_id': 'Extra args parsed from the proto message',
+ }))
+
WINDOW_MANAGER_SHELL_TRANSITIONS_TABLE = Table(
python_module=__file__,
class_name='WindowManagerShellTransitionsTable',
@@ -182,6 +198,7 @@
SURFACE_FLINGER_LAYERS_SNAPSHOT_TABLE,
SURFACE_FLINGER_LAYER_TABLE,
SURFACE_FLINGER_TRANSACTIONS_TABLE,
+ VIEWCAPTURE_TABLE,
WINDOW_MANAGER_SHELL_TRANSITIONS_TABLE,
WINDOW_MANAGER_SHELL_TRANSITION_HANDLERS_TABLE,
]
diff --git a/src/trace_processor/trace_processor_impl.cc b/src/trace_processor/trace_processor_impl.cc
index 117a737..fe25faf 100644
--- a/src/trace_processor/trace_processor_impl.cc
+++ b/src/trace_processor/trace_processor_impl.cc
@@ -891,6 +891,8 @@
RegisterStaticTable(storage->surfaceflinger_layer_table());
RegisterStaticTable(storage->surfaceflinger_transactions_table());
+ RegisterStaticTable(storage->viewcapture_table());
+
RegisterStaticTable(storage->window_manager_shell_transitions_table());
RegisterStaticTable(
storage->window_manager_shell_transition_handlers_table());
diff --git a/test/trace_processor/diff_tests/include_index.py b/test/trace_processor/diff_tests/include_index.py
index e70dfa3..2434d26 100644
--- a/test/trace_processor/diff_tests/include_index.py
+++ b/test/trace_processor/diff_tests/include_index.py
@@ -57,6 +57,7 @@
from diff_tests.parser.android.tests_shell_transitions import ShellTransitions
from diff_tests.parser.android.tests_surfaceflinger_layers import SurfaceFlingerLayers
from diff_tests.parser.android.tests_surfaceflinger_transactions import SurfaceFlingerTransactions
+from diff_tests.parser.android.tests_viewcapture import ViewCapture
from diff_tests.parser.atrace.tests import Atrace
from diff_tests.parser.atrace.tests_error_handling import AtraceErrorHandling
from diff_tests.parser.chrome.tests import ChromeParser
@@ -206,6 +207,7 @@
*ShellTransitions(index_path, 'parser/android',
'ShellTransitions').fetch(),
*ProtoLog(index_path, 'parser/android', 'ProtoLog').fetch(),
+ *ViewCapture(index_path, 'parser/android', 'ViewCapture').fetch(),
*TrackEvent(index_path, 'parser/track_event', 'TrackEvent').fetch(),
*TranslatedArgs(index_path, 'parser/translated_args',
'TranslatedArgs').fetch(),
diff --git a/test/trace_processor/diff_tests/parser/android/tests_viewcapture.py b/test/trace_processor/diff_tests/parser/android/tests_viewcapture.py
new file mode 100644
index 0000000..e089ecb
--- /dev/null
+++ b/test/trace_processor/diff_tests/parser/android/tests_viewcapture.py
@@ -0,0 +1,81 @@
+#!/usr/bin/env python3
+# 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 a
+#
+# 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 python.generators.diff_tests.testing import Path
+from python.generators.diff_tests.testing import Csv
+from python.generators.diff_tests.testing import DiffTestBlueprint
+from python.generators.diff_tests.testing import TestSuite
+
+
+class ViewCapture(TestSuite):
+
+ def test_has_expected_rows(self):
+ return DiffTestBlueprint(
+ trace=Path('viewcapture.textproto'),
+ query="""
+ INCLUDE PERFETTO MODULE android.winscope.viewcapture;
+ SELECT
+ id, ts
+ FROM
+ android_viewcapture;
+ """,
+ out=Csv("""
+ "id","ts"
+ 0,448881087865
+ 1,448883575576
+ """))
+
+ def test_has_expected_args(self):
+ return DiffTestBlueprint(
+ trace=Path('viewcapture.textproto'),
+ query="""
+ INCLUDE PERFETTO MODULE android.winscope.viewcapture;
+ SELECT
+ args.key, args.display_value
+ FROM
+ android_viewcapture AS vc JOIN args ON vc.arg_set_id = args.arg_set_id
+ WHERE vc.id = 0
+ ORDER BY args.key
+ LIMIT 10;
+ """,
+ out=Csv("""
+ "key","display_value"
+ "package_name","com.google.android.apps.nexuslauncher"
+ "views[0].alpha","1.0"
+ "views[0].class_name","com.android.internal.policy.PhoneWindow@6cec234"
+ "views[0].hashcode","182652084"
+ "views[0].height","2400"
+ "views[0].parent_id","-1"
+ "views[0].scale_x","1.0"
+ "views[0].scale_y","1.0"
+ "views[0].view_id","NO_ID"
+ "views[0].width","1080"
+ """))
+
+ def test_handle_string_deinterning_errors(self):
+ return DiffTestBlueprint(
+ trace=Path('viewcapture.textproto'),
+ query="""
+ INCLUDE PERFETTO MODULE android.winscope.viewcapture;
+ SELECT
+ args.key, args.display_value
+ FROM
+ android_viewcapture AS vc JOIN args ON vc.arg_set_id = args.arg_set_id
+ WHERE vc.id = 1 and args.key = 'views[1].class_name';
+ """,
+ out=Csv("""
+ "key","display_value"
+ "views[1].class_name","STRING DE-INTERNING ERROR"
+ """))
diff --git a/test/trace_processor/diff_tests/parser/android/viewcapture.textproto b/test/trace_processor/diff_tests/parser/android/viewcapture.textproto
new file mode 100644
index 0000000..7f484b8
--- /dev/null
+++ b/test/trace_processor/diff_tests/parser/android/viewcapture.textproto
@@ -0,0 +1,128 @@
+packet {
+ clock_snapshot {
+ primary_trace_clock: BUILTIN_CLOCK_BOOTTIME
+ clocks {
+ clock_id: 6
+ timestamp: 448243204726
+ }
+ clocks {
+ clock_id: 2
+ timestamp: 1716366701256000218
+ }
+ clocks {
+ clock_id: 4
+ timestamp: 448237110366
+ }
+ clocks {
+ clock_id: 1
+ timestamp: 1716366701262094741
+ }
+ clocks {
+ clock_id: 3
+ timestamp: 448243204971
+ }
+ clocks {
+ clock_id: 5
+ timestamp: 448243205052
+ }
+ }
+ trusted_uid: 9999
+ trusted_packet_sequence_id: 1
+}
+
+packet {
+ first_packet_on_sequence: true
+ timestamp: 448881087865
+ winscope_extensions {
+ [perfetto.protos.WinscopeExtensionsImpl.viewcapture] {
+ package_name_iid: 1
+ window_name_iid: 1
+ views {
+ parent_id: -1
+ hashcode: 182652084
+ view_id_iid: 1
+ class_name_iid: 1
+ width: 1080
+ height: 2400
+ scale_x: 1.000000
+ scale_y: 1.000000
+ alpha: 1.000000
+ will_not_draw: true
+ }
+ views {
+ id: 1
+ hashcode: 130248925
+ view_id_iid: 3
+ class_name_iid: 2
+ width: 1080
+ height: 2400
+ scale_x: 1.000000
+ scale_y: 1.000000
+ alpha: 1.000000
+ will_not_draw: true
+ }
+ }
+ }
+ sequence_flags: 3
+ interned_data {
+ viewcapture_class_name {
+ iid: 1
+ str: "com.android.internal.policy.PhoneWindow@6cec234"
+ }
+ viewcapture_class_name {
+ iid: 2
+ str: "com.android.internal.policy.DecorView"
+ }
+ viewcapture_package_name {
+ iid: 1
+ str: "com.google.android.apps.nexuslauncher"
+ }
+ viewcapture_view_id {
+ iid: 1
+ str: "NO_ID"
+ }
+ }
+ trusted_uid: 10230
+ trusted_packet_sequence_id: 2
+ trusted_pid: 2688
+ previous_packet_dropped: true
+}
+
+packet {
+ timestamp: 448883575576
+ winscope_extensions {
+ [perfetto.protos.WinscopeExtensionsImpl.viewcapture] {
+ package_name_iid: 1
+ window_name_iid: 1
+ views {
+ parent_id: -1
+ hashcode: 182652084
+ view_id_iid: 1
+ class_name_iid: 1
+ width: 1080
+ height: 2400
+ scale_x: 1.000000
+ scale_y: 1.000000
+ alpha: 1.000000
+ will_not_draw: true
+ }
+ views {
+ id: 1
+ hashcode: 130248925
+ view_id_iid: 1
+ # triggers de-interning error because of unavailable iid-to-string mapping
+ class_name_iid: 3
+ width: 1080
+ height: 2400
+ scale_x: 1.000000
+ scale_y: 1.000000
+ alpha: 1.000000
+ will_not_draw: true
+ }
+ }
+ }
+ sequence_flags: 2
+ trusted_uid: 10230
+ trusted_packet_sequence_id: 2
+ trusted_pid: 2688
+}