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