1 /*
2 * Copyright (C) 2024 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_args_parser.h"
18 #include "perfetto/ext/base/string_utils.h"
19 #include "perfetto/ext/base/string_view.h"
20 #include "protos/perfetto/trace/interned_data/interned_data.pbzero.h"
21 #include "protos/perfetto/trace/profiling/profile_common.pbzero.h"
22 #include "src/trace_processor/importers/proto/packet_sequence_state_generation.h"
23
24 namespace perfetto {
25 namespace trace_processor {
26
ViewCaptureArgsParser(int64_t packet_timestamp,ArgsTracker::BoundInserter & inserter,TraceStorage & storage,PacketSequenceStateGeneration * sequence_state)27 ViewCaptureArgsParser::ViewCaptureArgsParser(
28 int64_t packet_timestamp,
29 ArgsTracker::BoundInserter& inserter,
30 TraceStorage& storage,
31 PacketSequenceStateGeneration* sequence_state)
32 : ArgsParser(packet_timestamp, inserter, storage, sequence_state),
33 storage_{storage} {}
34
AddInteger(const Key & key,int64_t value)35 void ViewCaptureArgsParser::AddInteger(const Key& key, int64_t value) {
36 if (TryAddDeinternedString(key, static_cast<uint64_t>(value))) {
37 return;
38 }
39 ArgsParser::AddInteger(key, value);
40 }
41
AddUnsignedInteger(const Key & key,uint64_t value)42 void ViewCaptureArgsParser::AddUnsignedInteger(const Key& key, uint64_t value) {
43 if (TryAddDeinternedString(key, value)) {
44 return;
45 }
46 ArgsParser::AddUnsignedInteger(key, value);
47 }
48
TryAddDeinternedString(const Key & key,uint64_t iid)49 bool ViewCaptureArgsParser::TryAddDeinternedString(const Key& key,
50 uint64_t iid) {
51 bool is_interned_field = base::EndsWith(key.key, "_iid");
52 if (!is_interned_field) {
53 return false;
54 }
55
56 const auto deintern_key = key.key.substr(0, key.key.size() - 4);
57 const auto deintern_flat_key =
58 key.flat_key.substr(0, key.flat_key.size() - 4);
59 const auto deintern_key_combined = Key{deintern_flat_key, deintern_key};
60 const auto deintern_val = TryDeinternString(key, iid);
61
62 if (!deintern_val) {
63 ArgsParser::AddString(
64 deintern_key_combined,
65 protozero::ConstChars{ERROR_MSG.data(), ERROR_MSG.size()});
66 storage_.IncrementStats(
67 stats::winscope_viewcapture_missing_interned_string_parse_errors);
68 return false;
69 }
70
71 ArgsParser::AddString(deintern_key_combined, *deintern_val);
72
73 IidToStringMap& iid_args =
74 flat_key_to_iid_args[storage_.InternString(key.flat_key)];
75 iid_args.Insert(iid, storage_.InternString(*deintern_val));
76
77 return true;
78 }
79
TryDeinternString(const Key & key,uint64_t iid)80 std::optional<protozero::ConstChars> ViewCaptureArgsParser::TryDeinternString(
81 const Key& key,
82 uint64_t iid) {
83 if (base::EndsWith(key.key, "class_name_iid")) {
84 auto* decoder =
85 seq_state()
86 ->LookupInternedMessage<
87 protos::pbzero::InternedData::kViewcaptureClassNameFieldNumber,
88 protos::pbzero::InternedString>(iid);
89 if (decoder) {
90 return protozero::ConstChars{
91 reinterpret_cast<const char*>(decoder->str().data),
92 decoder->str().size};
93 }
94 } else if (base::EndsWith(key.key, "package_name_iid")) {
95 auto* decoder =
96 seq_state()
97 ->LookupInternedMessage<protos::pbzero::InternedData::
98 kViewcapturePackageNameFieldNumber,
99 protos::pbzero::InternedString>(iid);
100 if (decoder) {
101 return protozero::ConstChars{
102 reinterpret_cast<const char*>(decoder->str().data),
103 decoder->str().size};
104 }
105 } else if (base::EndsWith(key.key, "view_id_iid")) {
106 auto* decoder =
107 seq_state()
108 ->LookupInternedMessage<
109 protos::pbzero::InternedData::kViewcaptureViewIdFieldNumber,
110 protos::pbzero::InternedString>(iid);
111 if (decoder) {
112 return protozero::ConstChars{
113 reinterpret_cast<const char*>(decoder->str().data),
114 decoder->str().size};
115 }
116 } else if (base::EndsWith(key.key, "window_name_iid")) {
117 auto* decoder =
118 seq_state()
119 ->LookupInternedMessage<
120 protos::pbzero::InternedData::kViewcaptureWindowNameFieldNumber,
121 protos::pbzero::InternedString>(iid);
122 if (decoder) {
123 return protozero::ConstChars{
124 reinterpret_cast<const char*>(decoder->str().data),
125 decoder->str().size};
126 }
127 }
128
129 return std::nullopt;
130 }
131
132 } // namespace trace_processor
133 } // namespace perfetto
134