Add static table function to return args with defaults based on proto schema.
Bug: 311643446
Test: npm run test:unit:ci
Change-Id: Idc5f19370ef448167db4ca136ed1a55d17236283
diff --git a/Android.bp b/Android.bp
index 2e4aaa2..6d90b84 100644
--- a/Android.bp
+++ b/Android.bp
@@ -13407,6 +13407,7 @@
"src/trace_processor/perfetto_sql/intrinsics/table_functions/experimental_slice_layout.cc",
"src/trace_processor/perfetto_sql/intrinsics/table_functions/flamegraph_construction_algorithms.cc",
"src/trace_processor/perfetto_sql/intrinsics/table_functions/table_info.cc",
+ "src/trace_processor/perfetto_sql/intrinsics/table_functions/winscope_proto_to_args_with_defaults.cc",
],
}
diff --git a/BUILD b/BUILD
index f1cb6bb..84c3a3b 100644
--- a/BUILD
+++ b/BUILD
@@ -2651,6 +2651,8 @@
"src/trace_processor/perfetto_sql/intrinsics/table_functions/flamegraph_construction_algorithms.h",
"src/trace_processor/perfetto_sql/intrinsics/table_functions/table_info.cc",
"src/trace_processor/perfetto_sql/intrinsics/table_functions/table_info.h",
+ "src/trace_processor/perfetto_sql/intrinsics/table_functions/winscope_proto_to_args_with_defaults.cc",
+ "src/trace_processor/perfetto_sql/intrinsics/table_functions/winscope_proto_to_args_with_defaults.h",
],
)
diff --git a/src/trace_processor/perfetto_sql/intrinsics/table_functions/BUILD.gn b/src/trace_processor/perfetto_sql/intrinsics/table_functions/BUILD.gn
index 7be5b26..a73c7d9 100644
--- a/src/trace_processor/perfetto_sql/intrinsics/table_functions/BUILD.gn
+++ b/src/trace_processor/perfetto_sql/intrinsics/table_functions/BUILD.gn
@@ -41,6 +41,8 @@
"experimental_slice_layout.h",
"flamegraph_construction_algorithms.cc",
"flamegraph_construction_algorithms.h",
+ "winscope_proto_to_args_with_defaults.cc",
+ "winscope_proto_to_args_with_defaults.h",
"table_info.cc",
"table_info.h",
]
@@ -62,6 +64,9 @@
"../../../tables",
"../../../types",
"../../../util",
+ "../../../util:descriptors",
+ "../../../util:proto_to_args_parser",
+ "../../../util:winscope_proto_mapping",
"../../engine",
]
public_deps = [ ":interface" ]
diff --git a/src/trace_processor/perfetto_sql/intrinsics/table_functions/tables.py b/src/trace_processor/perfetto_sql/intrinsics/table_functions/tables.py
index aa882dd..22999ee 100644
--- a/src/trace_processor/perfetto_sql/intrinsics/table_functions/tables.py
+++ b/src/trace_processor/perfetto_sql/intrinsics/table_functions/tables.py
@@ -80,6 +80,21 @@
],
parent=FLOW_TABLE)
+ARGS_WITH_DEFAULTS_TABLE = Table(
+ python_module=__file__,
+ class_name='WinscopeArgsWithDefaultsTable',
+ sql_name='__intrinsic_winscope_proto_to_args_with_defaults',
+ columns=[
+ C("table_name", CppString(), flags=ColumnFlag.HIDDEN),
+ C('base64_proto_id', CppUint32()),
+ C('flat_key', CppString()),
+ C('key', CppString()),
+ C('int_value', CppOptional(CppInt64())),
+ C('string_value', CppOptional(CppString())),
+ C('real_value', CppOptional(CppDouble())),
+ C('value_type', CppString()),
+ ])
+
DESCENDANT_SLICE_TABLE = Table(
python_module=__file__,
class_name="DescendantSliceTable",
@@ -169,6 +184,7 @@
ANCESTOR_SLICE_TABLE,
ANCESTOR_STACK_PROFILE_CALLSITE_TABLE,
CONNECTED_FLOW_TABLE,
+ ARGS_WITH_DEFAULTS_TABLE,
DESCENDANT_SLICE_BY_STACK_TABLE,
DESCENDANT_SLICE_TABLE,
DFS_WEIGHT_BOUNDED_TABLE,
diff --git a/src/trace_processor/perfetto_sql/intrinsics/table_functions/winscope_proto_to_args_with_defaults.cc b/src/trace_processor/perfetto_sql/intrinsics/table_functions/winscope_proto_to_args_with_defaults.cc
new file mode 100644
index 0000000..ee8e600
--- /dev/null
+++ b/src/trace_processor/perfetto_sql/intrinsics/table_functions/winscope_proto_to_args_with_defaults.cc
@@ -0,0 +1,201 @@
+/*
+ * 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/perfetto_sql/intrinsics/table_functions/winscope_proto_to_args_with_defaults.h"
+
+#include "perfetto/base/status.h"
+#include "perfetto/ext/base/base64.h"
+#include "perfetto/ext/base/status_or.h"
+#include "src/trace_processor/containers/string_pool.h"
+#include "src/trace_processor/db/table.h"
+#include "src/trace_processor/perfetto_sql/engine/perfetto_sql_engine.h"
+#include "src/trace_processor/perfetto_sql/intrinsics/table_functions/tables_py.h"
+#include "src/trace_processor/types/trace_processor_context.h"
+#include "src/trace_processor/util/descriptors.h"
+#include "src/trace_processor/util/proto_to_args_parser.h"
+#include "src/trace_processor/util/status_macros.h"
+#include "src/trace_processor/util/winscope_proto_mapping.h"
+
+namespace perfetto::trace_processor {
+namespace tables {
+WinscopeArgsWithDefaultsTable::~WinscopeArgsWithDefaultsTable() = default;
+} // namespace tables
+
+namespace {
+using Row = tables::WinscopeArgsWithDefaultsTable::Row;
+
+class Delegate : public util::ProtoToArgsParser::Delegate {
+ public:
+ using Key = util::ProtoToArgsParser::Key;
+ explicit Delegate(StringPool* pool,
+ const uint32_t base64_proto_id,
+ tables::WinscopeArgsWithDefaultsTable* table)
+ : pool_(pool), base64_proto_id_(base64_proto_id), table_(table) {}
+
+ void AddInteger(const Key& key, int64_t res) override {
+ Row r;
+ r.int_value = res;
+ SetColumnsAndInsertRow(key, r);
+ }
+ void AddUnsignedInteger(const Key& key, uint64_t res) override {
+ Row r;
+ r.int_value = res;
+ SetColumnsAndInsertRow(key, r);
+ }
+ void AddString(const Key& key, const protozero::ConstChars& res) override {
+ Row r;
+ r.string_value = pool_->InternString(base::StringView((res.ToStdString())));
+ SetColumnsAndInsertRow(key, r);
+ }
+ void AddString(const Key& key, const std::string& res) override {
+ Row r;
+ r.string_value = pool_->InternString(base::StringView(res));
+ SetColumnsAndInsertRow(key, r);
+ }
+ void AddDouble(const Key& key, double res) override {
+ Row r;
+ r.real_value = res;
+ SetColumnsAndInsertRow(key, r);
+ }
+ void AddBoolean(const Key& key, bool res) override {
+ Row r;
+ r.int_value = res;
+ SetColumnsAndInsertRow(key, r);
+ }
+ void AddBytes(const Key& key, const protozero::ConstBytes& res) override {
+ Row r;
+ r.string_value = pool_->InternString(base::StringView((res.ToStdString())));
+ SetColumnsAndInsertRow(key, r);
+ }
+ void AddNull(const Key& key) override {
+ Row r;
+ SetColumnsAndInsertRow(key, r);
+ }
+ void AddPointer(const Key&, const void*) override {
+ PERFETTO_FATAL("Unsupported");
+ }
+ bool AddJson(const Key&, const protozero::ConstChars&) override {
+ PERFETTO_FATAL("Unsupported");
+ }
+ size_t GetArrayEntryIndex(const std::string&) override {
+ PERFETTO_FATAL("Unsupported");
+ }
+ size_t IncrementArrayEntryIndex(const std::string&) override {
+ PERFETTO_FATAL("Unsupported");
+ }
+ PacketSequenceStateGeneration* seq_state() override { return nullptr; }
+
+ private:
+ InternedMessageView* GetInternedMessageView(uint32_t, uint64_t) override {
+ return nullptr;
+ }
+
+ void SetColumnsAndInsertRow(const Key& key, Row& row) {
+ row.key = pool_->InternString(base::StringView(key.key));
+ row.flat_key = pool_->InternString(base::StringView(key.flat_key));
+ row.base64_proto_id = base64_proto_id_;
+ table_->Insert(row);
+ }
+
+ StringPool* pool_;
+ const uint32_t base64_proto_id_;
+ tables::WinscopeArgsWithDefaultsTable* table_;
+};
+
+base::Status InsertRows(
+ const Table& static_table,
+ tables::WinscopeArgsWithDefaultsTable* inflated_args_table,
+ const std::string& proto_name,
+ const std::vector<uint32_t>* allowed_fields,
+ DescriptorPool& descriptor_pool,
+ StringPool* string_pool) {
+ util::ProtoToArgsParser args_parser{descriptor_pool};
+ const auto base64_proto_id_col_idx =
+ static_table.ColumnIdxFromName("base64_proto_id").value();
+ const auto base_64_proto_col_idx =
+ static_table.ColumnIdxFromName("base64_proto").value();
+
+ std::unordered_set<uint32_t> inflated_protos;
+ for (auto it = static_table.IterateRows(); it; ++it) {
+ const auto base64_proto_id =
+ static_cast<uint32_t>(it.Get(base64_proto_id_col_idx).AsLong());
+ if (inflated_protos.count(base64_proto_id) > 0) {
+ continue;
+ }
+ inflated_protos.insert(base64_proto_id);
+ const auto* raw_proto = it.Get(base_64_proto_col_idx).AsString();
+ const auto blob = *base::Base64Decode(raw_proto);
+ const auto cb = protozero::ConstBytes{
+ reinterpret_cast<const uint8_t*>(blob.data()), blob.size()};
+ Delegate delegate(string_pool, base64_proto_id, inflated_args_table);
+ RETURN_IF_ERROR(args_parser.ParseMessage(cb, proto_name, allowed_fields,
+ delegate, nullptr, true));
+ }
+ return base::OkStatus();
+}
+} // namespace
+
+WinscopeProtoToArgsWithDefaults::WinscopeProtoToArgsWithDefaults(
+ StringPool* string_pool,
+ PerfettoSqlEngine* engine,
+ TraceProcessorContext* context)
+ : string_pool_(string_pool), engine_(engine), context_(context) {}
+
+base::StatusOr<std::unique_ptr<Table>>
+WinscopeProtoToArgsWithDefaults::ComputeTable(
+ const std::vector<SqlValue>& arguments) {
+ PERFETTO_CHECK(arguments.size() == 1);
+ if (arguments[0].type != SqlValue::kString) {
+ return base::ErrStatus(
+ "__intrinsic_winscope_proto_to_args_with_defaults takes table name as "
+ "a string.");
+ }
+ std::string table_name = arguments[0].AsString();
+
+ const Table* static_table = engine_->GetStaticTableOrNull(table_name);
+ if (!static_table) {
+ return base::ErrStatus("Failed to find %s table.", table_name.c_str());
+ }
+
+ std::string proto_name;
+ ASSIGN_OR_RETURN(proto_name,
+ util::winscope_proto_mapping::GetProtoName(table_name));
+
+ auto table =
+ std::make_unique<tables::WinscopeArgsWithDefaultsTable>(string_pool_);
+
+ auto allowed_fields =
+ util::winscope_proto_mapping::GetAllowedFields(table_name);
+ RETURN_IF_ERROR(InsertRows(*static_table, table.get(), proto_name,
+ allowed_fields ? &allowed_fields.value() : nullptr,
+ *context_->descriptor_pool_, string_pool_));
+
+ return std::unique_ptr<Table>(std::move(table));
+}
+
+Table::Schema WinscopeProtoToArgsWithDefaults::CreateSchema() {
+ return tables::WinscopeArgsWithDefaultsTable::ComputeStaticSchema();
+}
+
+std::string WinscopeProtoToArgsWithDefaults::TableName() {
+ return tables::WinscopeArgsWithDefaultsTable::Name();
+}
+
+uint32_t WinscopeProtoToArgsWithDefaults::EstimateRowCount() {
+ // 100 inflated args per 100 elements per 100 entries
+ return 1000000;
+}
+} // namespace perfetto::trace_processor
diff --git a/src/trace_processor/perfetto_sql/intrinsics/table_functions/winscope_proto_to_args_with_defaults.h b/src/trace_processor/perfetto_sql/intrinsics/table_functions/winscope_proto_to_args_with_defaults.h
new file mode 100644
index 0000000..91ab8c8
--- /dev/null
+++ b/src/trace_processor/perfetto_sql/intrinsics/table_functions/winscope_proto_to_args_with_defaults.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_PERFETTO_SQL_INTRINSICS_TABLE_FUNCTIONS_WINSCOPE_PROTO_TO_ARGS_WITH_DEFAULTS_H_
+#define SRC_TRACE_PROCESSOR_PERFETTO_SQL_INTRINSICS_TABLE_FUNCTIONS_WINSCOPE_PROTO_TO_ARGS_WITH_DEFAULTS_H_
+
+#include "perfetto/ext/base/status_or.h"
+#include "src/trace_processor/containers/string_pool.h"
+#include "src/trace_processor/db/table.h"
+#include "src/trace_processor/perfetto_sql/engine/perfetto_sql_engine.h"
+#include "src/trace_processor/perfetto_sql/intrinsics/table_functions/static_table_function.h"
+
+namespace perfetto::trace_processor {
+
+class TraceProcessorContext;
+
+class WinscopeProtoToArgsWithDefaults : public StaticTableFunction {
+ public:
+ explicit WinscopeProtoToArgsWithDefaults(StringPool*,
+ PerfettoSqlEngine*,
+ TraceProcessorContext* context);
+
+ Table::Schema CreateSchema() override;
+ std::string TableName() override;
+ uint32_t EstimateRowCount() override;
+ base::StatusOr<std::unique_ptr<Table>> ComputeTable(
+ const std::vector<SqlValue>& arguments) override;
+
+ private:
+ StringPool* string_pool_ = nullptr;
+ PerfettoSqlEngine* engine_ = nullptr;
+ TraceProcessorContext* context_ = nullptr;
+};
+
+} // namespace perfetto::trace_processor
+
+#endif // SRC_TRACE_PROCESSOR_PERFETTO_SQL_INTRINSICS_TABLE_FUNCTIONS_WINSCOPE_PROTO_TO_ARGS_WITH_DEFAULTS_H_
diff --git a/src/trace_processor/trace_processor_impl.cc b/src/trace_processor/trace_processor_impl.cc
index 296dc99..2459c75 100644
--- a/src/trace_processor/trace_processor_impl.cc
+++ b/src/trace_processor/trace_processor_impl.cc
@@ -115,6 +115,7 @@
#include "src/trace_processor/perfetto_sql/intrinsics/table_functions/experimental_sched_upid.h"
#include "src/trace_processor/perfetto_sql/intrinsics/table_functions/experimental_slice_layout.h"
#include "src/trace_processor/perfetto_sql/intrinsics/table_functions/table_info.h"
+#include "src/trace_processor/perfetto_sql/intrinsics/table_functions/winscope_proto_to_args_with_defaults.h"
#include "src/trace_processor/perfetto_sql/stdlib/stdlib.h"
#include "src/trace_processor/sqlite/bindings/sqlite_aggregate_function.h"
#include "src/trace_processor/sqlite/bindings/sqlite_result.h"
@@ -1061,6 +1062,9 @@
std::make_unique<ExperimentalFlatSlice>(&context_));
engine_->RegisterStaticTableFunction(std::make_unique<DfsWeightBounded>(
context_.storage->mutable_string_pool()));
+ engine_->RegisterStaticTableFunction(
+ std::make_unique<WinscopeProtoToArgsWithDefaults>(
+ context_.storage->mutable_string_pool(), engine_.get(), &context_));
// Value table aggregate functions.
engine_->RegisterSqliteAggregateFunction<DominatorTree>(
diff --git a/src/trace_processor/trace_processor_storage_impl.cc b/src/trace_processor/trace_processor_storage_impl.cc
index bdd04a3..d409320 100644
--- a/src/trace_processor/trace_processor_storage_impl.cc
+++ b/src/trace_processor/trace_processor_storage_impl.cc
@@ -153,7 +153,8 @@
// kernel version (inside system_info_tracker) to know how to textualise
// sched_switch.prev_state bitflags.
context.system_info_tracker = std::move(context_.system_info_tracker);
- // "proto_to_args_with_defaults" requires proto descriptors.
+ // "__intrinsic_winscope_proto_to_args_with_defaults" requires proto
+ // descriptors.
context.descriptor_pool_ = std::move(context_.descriptor_pool_);
context_ = std::move(context);
diff --git a/test/trace_processor/diff_tests/parser/android/surfaceflinger_layers.textproto b/test/trace_processor/diff_tests/parser/android/surfaceflinger_layers.textproto
index 7afbb6a..c8da434 100644
--- a/test/trace_processor/diff_tests/parser/android/surfaceflinger_layers.textproto
+++ b/test/trace_processor/diff_tests/parser/android/surfaceflinger_layers.textproto
@@ -48,12 +48,9 @@
children: 44
children: 77
children: 87
- type: "Layer"
layer_stack: 0
z: 0
crop {
- left: 0
- top: 0
right: -1
bottom: -1
}
@@ -393,6 +390,18 @@
}
is_virtual: false
}
+ displays {
+ id: 4619827677550801153
+ name: "Common Panel"
+ size {
+ w: 1080
+ h: 2400
+ }
+ layer_stack_space_rect {
+ right: 1080
+ bottom: 2400
+ }
+ }
vsync_id: 24767
}
trusted_uid: 1000
diff --git a/test/trace_processor/diff_tests/syntax/table_tests.py b/test/trace_processor/diff_tests/syntax/table_tests.py
index a90e71c..fb2cbc2 100644
--- a/test/trace_processor/diff_tests/syntax/table_tests.py
+++ b/test/trace_processor/diff_tests/syntax/table_tests.py
@@ -412,3 +412,159 @@
"MAX(id)"
20745
"""))
+
+ def test_winscope_proto_to_args_with_defaults_with_nested_fields(self):
+ return DiffTestBlueprint(
+ trace=Path('../parser/android/surfaceflinger_layers.textproto'),
+ query="""
+ SELECT flat_key, key, int_value, string_value, real_value FROM __intrinsic_winscope_proto_to_args_with_defaults('surfaceflinger_layer') AS sfl
+ ORDER BY sfl.base64_proto_id, key
+ LIMIT 95
+ """,
+ out=Csv("""
+ "flat_key","key","int_value","string_value","real_value"
+ "active_buffer","active_buffer","[NULL]","[NULL]","[NULL]"
+ "app_id","app_id",0,"[NULL]","[NULL]"
+ "background_blur_radius","background_blur_radius",0,"[NULL]","[NULL]"
+ "barrier_layer","barrier_layer","[NULL]","[NULL]","[NULL]"
+ "blur_regions","blur_regions","[NULL]","[NULL]","[NULL]"
+ "bounds.bottom","bounds.bottom","[NULL]","[NULL]",24000.000000
+ "bounds.left","bounds.left","[NULL]","[NULL]",-10800.000000
+ "bounds.right","bounds.right","[NULL]","[NULL]",10800.000000
+ "bounds.top","bounds.top","[NULL]","[NULL]",-24000.000000
+ "buffer_transform","buffer_transform","[NULL]","[NULL]","[NULL]"
+ "children","children[0]",4,"[NULL]","[NULL]"
+ "children","children[1]",35,"[NULL]","[NULL]"
+ "children","children[2]",43,"[NULL]","[NULL]"
+ "children","children[3]",45,"[NULL]","[NULL]"
+ "children","children[4]",44,"[NULL]","[NULL]"
+ "children","children[5]",77,"[NULL]","[NULL]"
+ "children","children[6]",87,"[NULL]","[NULL]"
+ "color.a","color.a","[NULL]","[NULL]",1.000000
+ "color.b","color.b","[NULL]","[NULL]",-1.000000
+ "color.g","color.g","[NULL]","[NULL]",-1.000000
+ "color.r","color.r","[NULL]","[NULL]",-1.000000
+ "color_transform","color_transform","[NULL]","[NULL]","[NULL]"
+ "corner_radius","corner_radius","[NULL]","[NULL]",0.000000
+ "corner_radius_crop","corner_radius_crop","[NULL]","[NULL]","[NULL]"
+ "crop.bottom","crop.bottom",-1,"[NULL]","[NULL]"
+ "crop.left","crop.left",0,"[NULL]","[NULL]"
+ "crop.right","crop.right",-1,"[NULL]","[NULL]"
+ "crop.top","crop.top",0,"[NULL]","[NULL]"
+ "curr_frame","curr_frame",0,"[NULL]","[NULL]"
+ "damage_region","damage_region","[NULL]","[NULL]","[NULL]"
+ "dataspace","dataspace","[NULL]","BT709 sRGB Full range","[NULL]"
+ "destination_frame.bottom","destination_frame.bottom",-1,"[NULL]","[NULL]"
+ "destination_frame.left","destination_frame.left",0,"[NULL]","[NULL]"
+ "destination_frame.right","destination_frame.right",-1,"[NULL]","[NULL]"
+ "destination_frame.top","destination_frame.top",0,"[NULL]","[NULL]"
+ "effective_scaling_mode","effective_scaling_mode",0,"[NULL]","[NULL]"
+ "effective_transform","effective_transform","[NULL]","[NULL]","[NULL]"
+ "final_crop","final_crop","[NULL]","[NULL]","[NULL]"
+ "flags","flags",2,"[NULL]","[NULL]"
+ "hwc_composition_type","hwc_composition_type","[NULL]","HWC_TYPE_UNSPECIFIED","[NULL]"
+ "hwc_crop","hwc_crop","[NULL]","[NULL]","[NULL]"
+ "hwc_frame","hwc_frame","[NULL]","[NULL]","[NULL]"
+ "hwc_transform","hwc_transform",0,"[NULL]","[NULL]"
+ "id","id",3,"[NULL]","[NULL]"
+ "input_window_info","input_window_info","[NULL]","[NULL]","[NULL]"
+ "invalidate","invalidate",1,"[NULL]","[NULL]"
+ "is_opaque","is_opaque",0,"[NULL]","[NULL]"
+ "is_protected","is_protected",0,"[NULL]","[NULL]"
+ "is_relative_of","is_relative_of",0,"[NULL]","[NULL]"
+ "is_trusted_overlay","is_trusted_overlay",0,"[NULL]","[NULL]"
+ "layer_stack","layer_stack",0,"[NULL]","[NULL]"
+ "metadata","metadata","[NULL]","[NULL]","[NULL]"
+ "name","name","[NULL]","Display 0 name=\"Built-in Screen\"#3","[NULL]"
+ "original_id","original_id",0,"[NULL]","[NULL]"
+ "owner_uid","owner_uid",1000,"[NULL]","[NULL]"
+ "parent","parent",0,"[NULL]","[NULL]"
+ "pixel_format","pixel_format","[NULL]","Unknown/None","[NULL]"
+ "position","position","[NULL]","[NULL]","[NULL]"
+ "queued_frames","queued_frames",0,"[NULL]","[NULL]"
+ "refresh_pending","refresh_pending",0,"[NULL]","[NULL]"
+ "relatives","relatives","[NULL]","[NULL]","[NULL]"
+ "requested_color.a","requested_color.a","[NULL]","[NULL]",1.000000
+ "requested_color.b","requested_color.b","[NULL]","[NULL]",-1.000000
+ "requested_color.g","requested_color.g","[NULL]","[NULL]",-1.000000
+ "requested_color.r","requested_color.r","[NULL]","[NULL]",-1.000000
+ "requested_corner_radius","requested_corner_radius","[NULL]","[NULL]",0.000000
+ "requested_position","requested_position","[NULL]","[NULL]","[NULL]"
+ "requested_transform.dsdx","requested_transform.dsdx","[NULL]","[NULL]",0.000000
+ "requested_transform.dsdy","requested_transform.dsdy","[NULL]","[NULL]",0.000000
+ "requested_transform.dtdx","requested_transform.dtdx","[NULL]","[NULL]",0.000000
+ "requested_transform.dtdy","requested_transform.dtdy","[NULL]","[NULL]",0.000000
+ "requested_transform.type","requested_transform.type",0,"[NULL]","[NULL]"
+ "screen_bounds.bottom","screen_bounds.bottom","[NULL]","[NULL]",24000.000000
+ "screen_bounds.left","screen_bounds.left","[NULL]","[NULL]",-10800.000000
+ "screen_bounds.right","screen_bounds.right","[NULL]","[NULL]",10800.000000
+ "screen_bounds.top","screen_bounds.top","[NULL]","[NULL]",-24000.000000
+ "shadow_radius","shadow_radius","[NULL]","[NULL]",0.000000
+ "size","size","[NULL]","[NULL]","[NULL]"
+ "source_bounds.bottom","source_bounds.bottom","[NULL]","[NULL]",24000.000000
+ "source_bounds.left","source_bounds.left","[NULL]","[NULL]",-10800.000000
+ "source_bounds.right","source_bounds.right","[NULL]","[NULL]",10800.000000
+ "source_bounds.top","source_bounds.top","[NULL]","[NULL]",-24000.000000
+ "transform.dsdx","transform.dsdx","[NULL]","[NULL]",0.000000
+ "transform.dsdy","transform.dsdy","[NULL]","[NULL]",0.000000
+ "transform.dtdx","transform.dtdx","[NULL]","[NULL]",0.000000
+ "transform.dtdy","transform.dtdy","[NULL]","[NULL]",0.000000
+ "transform.type","transform.type",0,"[NULL]","[NULL]"
+ "transparent_region","transparent_region","[NULL]","[NULL]","[NULL]"
+ "trusted_overlay","trusted_overlay","[NULL]","UNSET","[NULL]"
+ "type","type","[NULL]","[NULL]","[NULL]"
+ "visible_region","visible_region","[NULL]","[NULL]","[NULL]"
+ "window_type","window_type",0,"[NULL]","[NULL]"
+ "z","z",0,"[NULL]","[NULL]"
+ "z_order_relative_of","z_order_relative_of",0,"[NULL]","[NULL]"
+ "active_buffer","active_buffer","[NULL]","[NULL]","[NULL]"
+ """))
+
+ def test_winscope_proto_to_args_with_defaults_with_repeated_fields(self):
+ return DiffTestBlueprint(
+ trace=Path('../parser/android/surfaceflinger_layers.textproto'),
+ query="""
+ SELECT flat_key, key, int_value, string_value, real_value FROM __intrinsic_winscope_proto_to_args_with_defaults('surfaceflinger_layers_snapshot') AS sfs
+ WHERE key != "hwc_blob"
+ ORDER BY sfs.base64_proto_id DESC, key ASC
+ LIMIT 36
+ """,
+ out=Csv("""
+ "flat_key","key","int_value","string_value","real_value"
+ "displays.dpi_x","displays[0].dpi_x","[NULL]","[NULL]",0.000000
+ "displays.dpi_y","displays[0].dpi_y","[NULL]","[NULL]",0.000000
+ "displays.id","displays[0].id",4619827677550801152,"[NULL]","[NULL]"
+ "displays.is_virtual","displays[0].is_virtual",0,"[NULL]","[NULL]"
+ "displays.layer_stack","displays[0].layer_stack",0,"[NULL]","[NULL]"
+ "displays.layer_stack_space_rect.bottom","displays[0].layer_stack_space_rect.bottom",2400,"[NULL]","[NULL]"
+ "displays.layer_stack_space_rect.left","displays[0].layer_stack_space_rect.left",0,"[NULL]","[NULL]"
+ "displays.layer_stack_space_rect.right","displays[0].layer_stack_space_rect.right",1080,"[NULL]","[NULL]"
+ "displays.layer_stack_space_rect.top","displays[0].layer_stack_space_rect.top",0,"[NULL]","[NULL]"
+ "displays.name","displays[0].name","[NULL]","Common Panel","[NULL]"
+ "displays.size.h","displays[0].size.h",2400,"[NULL]","[NULL]"
+ "displays.size.w","displays[0].size.w",1080,"[NULL]","[NULL]"
+ "displays.transform.dsdx","displays[0].transform.dsdx","[NULL]","[NULL]",0.000000
+ "displays.transform.dsdy","displays[0].transform.dsdy","[NULL]","[NULL]",0.000000
+ "displays.transform.dtdx","displays[0].transform.dtdx","[NULL]","[NULL]",0.000000
+ "displays.transform.dtdy","displays[0].transform.dtdy","[NULL]","[NULL]",0.000000
+ "displays.transform.type","displays[0].transform.type",0,"[NULL]","[NULL]"
+ "displays.dpi_x","displays[1].dpi_x","[NULL]","[NULL]",0.000000
+ "displays.dpi_y","displays[1].dpi_y","[NULL]","[NULL]",0.000000
+ "displays.id","displays[1].id",4619827677550801153,"[NULL]","[NULL]"
+ "displays.is_virtual","displays[1].is_virtual",0,"[NULL]","[NULL]"
+ "displays.layer_stack","displays[1].layer_stack",0,"[NULL]","[NULL]"
+ "displays.layer_stack_space_rect.bottom","displays[1].layer_stack_space_rect.bottom",2400,"[NULL]","[NULL]"
+ "displays.layer_stack_space_rect.left","displays[1].layer_stack_space_rect.left",0,"[NULL]","[NULL]"
+ "displays.layer_stack_space_rect.right","displays[1].layer_stack_space_rect.right",1080,"[NULL]","[NULL]"
+ "displays.layer_stack_space_rect.top","displays[1].layer_stack_space_rect.top",0,"[NULL]","[NULL]"
+ "displays.name","displays[1].name","[NULL]","Common Panel","[NULL]"
+ "displays.size.h","displays[1].size.h",2400,"[NULL]","[NULL]"
+ "displays.size.w","displays[1].size.w",1080,"[NULL]","[NULL]"
+ "displays.transform","displays[1].transform","[NULL]","[NULL]","[NULL]"
+ "elapsed_realtime_nanos","elapsed_realtime_nanos",2749500341063,"[NULL]","[NULL]"
+ "excludes_composition_state","excludes_composition_state",0,"[NULL]","[NULL]"
+ "missed_entries","missed_entries",0,"[NULL]","[NULL]"
+ "vsync_id","vsync_id",24767,"[NULL]","[NULL]"
+ "where","where","[NULL]","bufferLatched","[NULL]"
+ "displays.dpi_x","displays[0].dpi_x","[NULL]","[NULL]",0.000000
+ """))