xref: /aosp_15_r20/external/perfetto/src/perfetto_cmd/trigger_perfetto.cc (revision 6dbdd20afdafa5e3ca9b8809fa73465d530080dc)
1*6dbdd20aSAndroid Build Coastguard Worker /*
2*6dbdd20aSAndroid Build Coastguard Worker  * Copyright (C) 2019 The Android Open Source Project
3*6dbdd20aSAndroid Build Coastguard Worker  *
4*6dbdd20aSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*6dbdd20aSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*6dbdd20aSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*6dbdd20aSAndroid Build Coastguard Worker  *
8*6dbdd20aSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*6dbdd20aSAndroid Build Coastguard Worker  *
10*6dbdd20aSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*6dbdd20aSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*6dbdd20aSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*6dbdd20aSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*6dbdd20aSAndroid Build Coastguard Worker  * limitations under the License.
15*6dbdd20aSAndroid Build Coastguard Worker  */
16*6dbdd20aSAndroid Build Coastguard Worker 
17*6dbdd20aSAndroid Build Coastguard Worker #include <string>
18*6dbdd20aSAndroid Build Coastguard Worker #include <vector>
19*6dbdd20aSAndroid Build Coastguard Worker 
20*6dbdd20aSAndroid Build Coastguard Worker #include "perfetto/base/logging.h"
21*6dbdd20aSAndroid Build Coastguard Worker #include "perfetto/ext/base/getopt.h"
22*6dbdd20aSAndroid Build Coastguard Worker #include "perfetto/ext/base/unix_task_runner.h"
23*6dbdd20aSAndroid Build Coastguard Worker #include "perfetto/ext/traced/traced.h"
24*6dbdd20aSAndroid Build Coastguard Worker #include "src/android_stats/statsd_logging_helper.h"
25*6dbdd20aSAndroid Build Coastguard Worker #include "src/perfetto_cmd/trigger_producer.h"
26*6dbdd20aSAndroid Build Coastguard Worker 
27*6dbdd20aSAndroid Build Coastguard Worker namespace perfetto {
28*6dbdd20aSAndroid Build Coastguard Worker namespace {
29*6dbdd20aSAndroid Build Coastguard Worker 
PrintUsage(const char * argv0)30*6dbdd20aSAndroid Build Coastguard Worker int PrintUsage(const char* argv0) {
31*6dbdd20aSAndroid Build Coastguard Worker   PERFETTO_ELOG(R"(
32*6dbdd20aSAndroid Build Coastguard Worker Usage: %s TRIGGER...
33*6dbdd20aSAndroid Build Coastguard Worker   -h|--help  Show this message
34*6dbdd20aSAndroid Build Coastguard Worker )",
35*6dbdd20aSAndroid Build Coastguard Worker                 argv0);
36*6dbdd20aSAndroid Build Coastguard Worker   return 1;
37*6dbdd20aSAndroid Build Coastguard Worker }
38*6dbdd20aSAndroid Build Coastguard Worker 
39*6dbdd20aSAndroid Build Coastguard Worker }  // namespace
40*6dbdd20aSAndroid Build Coastguard Worker 
TriggerPerfettoMain(int argc,char ** argv)41*6dbdd20aSAndroid Build Coastguard Worker int PERFETTO_EXPORT_ENTRYPOINT TriggerPerfettoMain(int argc, char** argv) {
42*6dbdd20aSAndroid Build Coastguard Worker   static const option long_options[] = {{"help", no_argument, nullptr, 'h'},
43*6dbdd20aSAndroid Build Coastguard Worker                                         {nullptr, 0, nullptr, 0}};
44*6dbdd20aSAndroid Build Coastguard Worker 
45*6dbdd20aSAndroid Build Coastguard Worker   // Set opterror to zero to disable |getopt_long| from printing an error and
46*6dbdd20aSAndroid Build Coastguard Worker   // exiting when it encounters an unknown option. Instead, |getopt_long|
47*6dbdd20aSAndroid Build Coastguard Worker   // will return '?' which we silently ignore.
48*6dbdd20aSAndroid Build Coastguard Worker   //
49*6dbdd20aSAndroid Build Coastguard Worker   // We prefer ths behaviour rather than erroring on unknown options because
50*6dbdd20aSAndroid Build Coastguard Worker   // trigger_perfetto can be called by apps so it's command line API needs to
51*6dbdd20aSAndroid Build Coastguard Worker   // be backward and forward compatible. If we introduce an option here which
52*6dbdd20aSAndroid Build Coastguard Worker   // apps will use in the future, we don't want to cause errors on older
53*6dbdd20aSAndroid Build Coastguard Worker   // platforms where the command line flag did not exist.
54*6dbdd20aSAndroid Build Coastguard Worker   //
55*6dbdd20aSAndroid Build Coastguard Worker   // This behaviour was introduced in Android S.
56*6dbdd20aSAndroid Build Coastguard Worker   opterr = 0;
57*6dbdd20aSAndroid Build Coastguard Worker 
58*6dbdd20aSAndroid Build Coastguard Worker   std::vector<std::string> triggers_to_activate;
59*6dbdd20aSAndroid Build Coastguard Worker   bool seen_unknown_arg = false;
60*6dbdd20aSAndroid Build Coastguard Worker 
61*6dbdd20aSAndroid Build Coastguard Worker   for (;;) {
62*6dbdd20aSAndroid Build Coastguard Worker     int option = getopt_long(argc, argv, "h", long_options, nullptr);
63*6dbdd20aSAndroid Build Coastguard Worker 
64*6dbdd20aSAndroid Build Coastguard Worker     if (option == 'h')
65*6dbdd20aSAndroid Build Coastguard Worker       return PrintUsage(argv[0]);
66*6dbdd20aSAndroid Build Coastguard Worker 
67*6dbdd20aSAndroid Build Coastguard Worker     if (option == '?') {
68*6dbdd20aSAndroid Build Coastguard Worker       seen_unknown_arg = true;
69*6dbdd20aSAndroid Build Coastguard Worker     }
70*6dbdd20aSAndroid Build Coastguard Worker 
71*6dbdd20aSAndroid Build Coastguard Worker     if (option == -1)
72*6dbdd20aSAndroid Build Coastguard Worker       break;  // EOF.
73*6dbdd20aSAndroid Build Coastguard Worker   }
74*6dbdd20aSAndroid Build Coastguard Worker 
75*6dbdd20aSAndroid Build Coastguard Worker   // See above for rationale on why we just ignore unknown args instead of
76*6dbdd20aSAndroid Build Coastguard Worker   // exiting.
77*6dbdd20aSAndroid Build Coastguard Worker   if (seen_unknown_arg) {
78*6dbdd20aSAndroid Build Coastguard Worker     PERFETTO_ELOG("Ignoring unknown arguments. See --help for usage.");
79*6dbdd20aSAndroid Build Coastguard Worker   }
80*6dbdd20aSAndroid Build Coastguard Worker 
81*6dbdd20aSAndroid Build Coastguard Worker   for (int i = optind; i < argc; i++)
82*6dbdd20aSAndroid Build Coastguard Worker     triggers_to_activate.push_back(std::string(argv[i]));
83*6dbdd20aSAndroid Build Coastguard Worker 
84*6dbdd20aSAndroid Build Coastguard Worker   if (triggers_to_activate.empty()) {
85*6dbdd20aSAndroid Build Coastguard Worker     PERFETTO_ELOG("At least one trigger must the specified.");
86*6dbdd20aSAndroid Build Coastguard Worker     return PrintUsage(argv[0]);
87*6dbdd20aSAndroid Build Coastguard Worker   }
88*6dbdd20aSAndroid Build Coastguard Worker 
89*6dbdd20aSAndroid Build Coastguard Worker   bool finished_with_success = false;
90*6dbdd20aSAndroid Build Coastguard Worker   base::UnixTaskRunner task_runner;
91*6dbdd20aSAndroid Build Coastguard Worker   TriggerProducer producer(
92*6dbdd20aSAndroid Build Coastguard Worker       &task_runner,
93*6dbdd20aSAndroid Build Coastguard Worker       [&task_runner, &finished_with_success](bool success) {
94*6dbdd20aSAndroid Build Coastguard Worker         finished_with_success = success;
95*6dbdd20aSAndroid Build Coastguard Worker         task_runner.Quit();
96*6dbdd20aSAndroid Build Coastguard Worker       },
97*6dbdd20aSAndroid Build Coastguard Worker       &triggers_to_activate);
98*6dbdd20aSAndroid Build Coastguard Worker   task_runner.Run();
99*6dbdd20aSAndroid Build Coastguard Worker 
100*6dbdd20aSAndroid Build Coastguard Worker   if (!finished_with_success) {
101*6dbdd20aSAndroid Build Coastguard Worker     return 1;
102*6dbdd20aSAndroid Build Coastguard Worker   }
103*6dbdd20aSAndroid Build Coastguard Worker   return 0;
104*6dbdd20aSAndroid Build Coastguard Worker }
105*6dbdd20aSAndroid Build Coastguard Worker 
106*6dbdd20aSAndroid Build Coastguard Worker }  // namespace perfetto
107