1 /*
2 * Copyright (C) 2020 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/traced/probes/packages_list/packages_list_parser.h"
18
19 #include "perfetto/ext/base/scoped_file.h"
20 #include "perfetto/ext/base/string_splitter.h"
21
22 namespace perfetto {
23
ReadPackagesListLine(char * line,Package * package)24 bool ReadPackagesListLine(char* line, Package* package) {
25 size_t idx = 0;
26 for (base::StringSplitter ss(line, ' '); ss.Next();) {
27 switch (idx) {
28 case 0:
29 package->name = std::string(ss.cur_token(), ss.cur_token_size());
30 break;
31 case 1: {
32 char* end;
33 long long uid = strtoll(ss.cur_token(), &end, 10);
34 if ((*end != '\0' && *end != '\n') || *ss.cur_token() == '\0') {
35 PERFETTO_ELOG("Failed to parse packages.list uid.");
36 return false;
37 }
38 package->uid = static_cast<uint64_t>(uid);
39 break;
40 }
41 case 2: {
42 char* end;
43 long long debuggable = strtoll(ss.cur_token(), &end, 10);
44 if ((*end != '\0' && *end != '\n') || *ss.cur_token() == '\0') {
45 PERFETTO_ELOG("Failed to parse packages.list debuggable.");
46 return false;
47 }
48 package->debuggable = debuggable != 0;
49 break;
50 }
51 case 6: {
52 char* end;
53 long long profilable_from_shell = strtoll(ss.cur_token(), &end, 10);
54 if ((*end != '\0' && *end != '\n') || *ss.cur_token() == '\0') {
55 PERFETTO_ELOG("Failed to parse packages.list profilable_from_shell.");
56 return false;
57 }
58 package->profileable_from_shell = profilable_from_shell != 0;
59 break;
60 }
61 case 7: {
62 char* end;
63 long long version_code = strtoll(ss.cur_token(), &end, 10);
64 if ((*end != '\0' && *end != '\n') || *ss.cur_token() == '\0') {
65 PERFETTO_ELOG("Failed to parse packages.list version_code: %s.",
66 ss.cur_token());
67 return false;
68 }
69 package->version_code = version_code;
70 break;
71 }
72 case 8: {
73 char* end;
74 long long profileable = strtoll(ss.cur_token(), &end, 10);
75 if ((*end != '\0' && *end != '\n') || *ss.cur_token() == '\0') {
76 PERFETTO_ELOG("Failed to parse packages.list profileable.");
77 return false;
78 }
79 package->profileable = profileable != 0;
80 break;
81 }
82 case 9:
83 package->installed_by =
84 std::string(ss.cur_token(), ss.cur_token_size());
85 break;
86 }
87 ++idx;
88 }
89 return true;
90 }
91
92 } // namespace perfetto
93