• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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