1 // Copyright (C) 2019 The Android Open Source Project
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #include "common/debug.h"
16 #include "compiler/compiler.h"
17 #include "maintenance/controller.h"
18 #include "db/clean_up.h"
19
20 #include <android-base/parseint.h>
21 #include <android-base/properties.h>
22 #include <android-base/logging.h>
23
24 #include <iostream>
25 #include <optional>
26
27 #if defined(IORAP_MAINTENANCE_MAIN)
28
29 namespace iorap::maintenance {
30
Usage(char ** argv)31 void Usage(char** argv) {
32 std::cerr << "Usage: " << argv[0] << " <path of sqlite db>" << std::endl;
33 std::cerr << "" << std::endl;
34 std::cerr << " Compile the perfetto trace for an package and activity." << std::endl;
35 std::cerr << " The info of perfetto trace is stored in the sqlite db." << std::endl;
36 std::cerr << "" << std::endl;
37 std::cerr << " Optional flags:" << std::endl;
38 std::cerr << " --package $,-p $ Package name." << std::endl;
39 std::cerr << " --version $,-ve $ Package version." << std::endl;
40 std::cerr << " --activity $,-a $ Activity name." << std::endl;
41 std::cerr << " --inode-textcache $,-it $ Resolve inode->filename from textcache." << std::endl;
42 std::cerr << " --help,-h Print this Usage." << std::endl;
43 std::cerr << " --recompile,-r Force re-compilation, which replace the existing compiled trace ." << std::endl;
44 std::cerr << " --purge-package,-pp Purge all files associated with a package." << std::endl;
45 std::cerr << " --verbose,-v Set verbosity (default off)." << std::endl;
46 std::cerr << " --output-text,-ot Output ascii text instead of protobuf (default off)." << std::endl;
47 std::cerr << " --min_traces,-mt The min number of perfetto traces needed for compilation (default 1)."
48 << std::endl;
49 exit(1);
50 }
51
52
Main(int argc,char ** argv)53 int Main(int argc, char** argv){
54 android::base::InitLogging(argv);
55 android::base::SetLogger(android::base::StderrLogger);
56
57 if (argc == 1) {
58 // Need at least 1 input file to do anything.
59 Usage(argv);
60 }
61
62 std::vector<std::string> arg_input_filenames;
63 std::optional<std::string> arg_package;
64 std::optional<std::string> arg_purge_package;
65 int arg_version = -1;
66 std::optional<std::string> arg_activity;
67 std::optional<std::string> arg_inode_textcache;
68 bool recompile = false;
69 bool enable_verbose = false;
70 bool arg_output_text = false;
71 uint64_t arg_min_traces = 1;
72
73 for (int arg = 1; arg < argc; ++arg) {
74 std::string argstr = argv[arg];
75 bool has_arg_next = (arg+1)<argc;
76 std::string arg_next = has_arg_next ? argv[arg+1] : "";
77
78 if (argstr == "--help" || argstr == "-h") {
79 Usage(argv);
80 } else if (argstr == "--package" || argstr == "-p") {
81 if (!has_arg_next) {
82 std::cerr << "Missing --package <value>" << std::endl;
83 return 1;
84 }
85 arg_package = arg_next;
86 ++arg;
87 } else if (argstr == "--version" || argstr == "-ve") {
88 if (!has_arg_next) {
89 std::cerr << "Missing --version <value>" << std::endl;
90 return 1;
91 }
92 int version;
93 if (!android::base::ParseInt<int>(arg_next, &version)) {
94 std::cerr << "Invalid --version " << arg_next << std::endl;
95 return 1;
96 }
97 arg_version = version;
98 ++arg;
99 } else if (argstr == "--activity" || argstr == "-a") {
100 if (!has_arg_next) {
101 std::cerr << "Missing --activity <value>" << std::endl;
102 return 1;
103 }
104 arg_activity = arg_next;
105 ++arg;
106 } else if (argstr == "--inode-textcache" || argstr == "-it") {
107 if (!has_arg_next) {
108 std::cerr << "Missing --inode-textcache <value>" << std::endl;
109 return 1;
110 }
111 arg_inode_textcache = arg_next;
112 ++arg;
113 } else if (argstr == "--purge-package" || argstr == "-pp") {
114 if (!has_arg_next) {
115 std::cerr << "Missing --purge-package <value>" << std::endl;
116 return 1;
117 }
118 arg_purge_package = arg_next;
119 ++arg;
120 }
121 else if (argstr == "--verbose" || argstr == "-v") {
122 enable_verbose = true;
123 } else if (argstr == "--recompile" || argstr == "-r") {
124 recompile = true;
125 } else if (argstr == "--output-text" || argstr == "-ot") {
126 arg_output_text = true;
127 } else if (argstr == "--min_traces" || argstr == "-mt") {
128 if (!has_arg_next) {
129 std::cerr << "Missing --min_traces <value>" << std::endl;
130 return 1;
131 }
132 arg_min_traces = std::stoul(arg_next);
133 ++arg;
134 } else {
135 arg_input_filenames.push_back(argstr);
136 }
137 }
138
139 if (arg_input_filenames.empty()) {
140 LOG(ERROR) << "Missing filename to a sqlite database.";
141 Usage(argv);
142 } else if (arg_input_filenames.size() > 1) {
143 LOG(ERROR) << "More than one filename to a sqlite database.";
144 Usage(argv);
145 }
146
147 std::string db_path = arg_input_filenames[0];
148
149 if (enable_verbose) {
150 android::base::SetMinimumLogSeverity(android::base::VERBOSE);
151
152 LOG(VERBOSE) << "Verbose check";
153 LOG(VERBOSE) << "Debug check: " << ::iorap::kIsDebugBuild;
154 } else {
155 android::base::SetMinimumLogSeverity(android::base::DEBUG);
156 }
157
158 if (arg_purge_package) {
159 db::CleanUpFilesForPackage(db_path, *arg_purge_package);
160 return 0;
161 // Don't do any more work because SchemaModel can only be created once.
162 }
163
164 maintenance::ControllerParameters params{
165 arg_output_text,
166 arg_inode_textcache,
167 enable_verbose,
168 recompile,
169 arg_min_traces,
170 std::make_shared<Exec>()};
171
172 int ret_code = 0;
173 if (arg_package && arg_activity) {
174 ret_code = !Compile(std::move(db_path),
175 std::move(*arg_package),
176 std::move(*arg_activity),
177 arg_version,
178 params);
179 } else if (arg_package) {
180 ret_code = !Compile(std::move(db_path), std::move(*arg_package), arg_version, params);
181 } else {
182 ret_code = !Compile(std::move(db_path), params);
183 }
184 return ret_code;
185 }
186
187 } // iorap::maintenance
188
main(int argc,char ** argv)189 int main(int argc, char** argv) {
190 return ::iorap::maintenance::Main(argc, argv);
191 }
192
193
194 #endif // IORAP_MAINTENANCE_MAIN
195