• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2025 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include "src/trace_processor/importers/proto/winscope/viewcapture_parser.h"
18 
19 #include "perfetto/ext/base/base64.h"
20 #include "protos/perfetto/trace/android/viewcapture.pbzero.h"
21 #include "src/trace_processor/importers/common/args_tracker.h"
22 #include "src/trace_processor/tables/winscope_tables_py.h"
23 #include "src/trace_processor/types/trace_processor_context.h"
24 #include "src/trace_processor/util/winscope_proto_mapping.h"
25 
26 namespace perfetto {
27 namespace trace_processor {
28 
ViewCaptureParser(TraceProcessorContext * context)29 ViewCaptureParser::ViewCaptureParser(TraceProcessorContext* context)
30     : context_{context}, args_parser_{*context->descriptor_pool_} {}
31 
Parse(int64_t timestamp,protozero::ConstBytes blob,PacketSequenceStateGeneration * seq_state)32 void ViewCaptureParser::Parse(int64_t timestamp,
33                               protozero::ConstBytes blob,
34                               PacketSequenceStateGeneration* seq_state) {
35   protos::pbzero::ViewCapture::Decoder snapshot_decoder(blob);
36   tables::ViewCaptureTable::Row row;
37   row.ts = timestamp;
38   row.base64_proto_id = context_->storage->mutable_string_pool()
39                             ->InternString(base::StringView(
40                                 base::Base64Encode(blob.data, blob.size)))
41                             .raw_id();
42   auto snapshot_id =
43       context_->storage->mutable_viewcapture_table()->Insert(row).id;
44 
45   auto inserter = context_->args_tracker->AddArgsTo(snapshot_id);
46   ViewCaptureArgsParser writer(timestamp, inserter, *context_->storage,
47                                seq_state);
48   const auto table_name = tables::ViewCaptureTable::Name();
49   auto allowed_fields =
50       util::winscope_proto_mapping::GetAllowedFields(table_name);
51   base::Status status = args_parser_.ParseMessage(
52       blob, *util::winscope_proto_mapping::GetProtoName(table_name),
53       &allowed_fields.value(), writer);
54 
55   AddDeinternedData(writer, row.base64_proto_id.value());
56   if (!status.ok()) {
57     context_->storage->IncrementStats(stats::winscope_viewcapture_parse_errors);
58   }
59   for (auto it = snapshot_decoder.views(); it; ++it) {
60     ParseView(timestamp, *it, snapshot_id, seq_state);
61   }
62 }
63 
ParseView(int64_t timestamp,protozero::ConstBytes blob,tables::ViewCaptureTable::Id snapshot_id,PacketSequenceStateGeneration * seq_state)64 void ViewCaptureParser::ParseView(int64_t timestamp,
65                                   protozero::ConstBytes blob,
66                                   tables::ViewCaptureTable::Id snapshot_id,
67                                   PacketSequenceStateGeneration* seq_state) {
68   tables::ViewCaptureViewTable::Row view;
69   view.snapshot_id = snapshot_id;
70   view.base64_proto_id = context_->storage->mutable_string_pool()
71                              ->InternString(base::StringView(
72                                  base::Base64Encode(blob.data, blob.size)))
73                              .raw_id();
74   auto layer_id =
75       context_->storage->mutable_viewcapture_view_table()->Insert(view).id;
76 
77   ArgsTracker tracker(context_);
78   auto inserter = tracker.AddArgsTo(layer_id);
79   ViewCaptureArgsParser writer(timestamp, inserter, *context_->storage,
80                                seq_state);
81   base::Status status =
82       args_parser_.ParseMessage(blob,
83                                 *util::winscope_proto_mapping::GetProtoName(
84                                     tables::ViewCaptureViewTable::Name()),
85                                 nullptr /* parse all fields */, writer);
86 
87   AddDeinternedData(writer, view.base64_proto_id.value());
88   if (!status.ok()) {
89     context_->storage->IncrementStats(stats::winscope_viewcapture_parse_errors);
90   }
91 }
92 
AddDeinternedData(const ViewCaptureArgsParser & writer,uint32_t base64_proto_id)93 void ViewCaptureParser::AddDeinternedData(const ViewCaptureArgsParser& writer,
94                                           uint32_t base64_proto_id) {
95   auto* deinterned_data_table =
96       context_->storage->mutable_viewcapture_interned_data_table();
97   for (auto i = writer.flat_key_to_iid_args.GetIterator(); i; ++i) {
98     const auto& flat_key = i.key();
99     ViewCaptureArgsParser::IidToStringMap& iids_to_add = i.value();
100 
101     for (auto j = iids_to_add.GetIterator(); j; ++j) {
102       const auto iid = j.key();
103       const auto& deinterned_value = j.value();
104 
105       tables::ViewCaptureInternedDataTable::Row interned_data_row;
106       interned_data_row.base64_proto_id = base64_proto_id;
107       interned_data_row.flat_key = flat_key;
108       interned_data_row.iid = static_cast<int64_t>(iid);
109       interned_data_row.deinterned_value = deinterned_value;
110       deinterned_data_table->Insert(interned_data_row);
111     }
112   }
113 }
114 
115 }  // namespace trace_processor
116 }  // namespace perfetto
117