Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(121)

Side by Side Diff: tools/battor_agent/battor_agent_bin.cc

Issue 1732943002: tools/battor_agent: Changes the BattOr Agent binary to be interactive (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Documented usage Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 // This file provides a thin binary wrapper around the BattOr Agent 5 // This file provides a thin binary wrapper around the BattOr Agent
6 // library. This binary wrapper provides a means for non-C++ tracing 6 // library. This binary wrapper provides a means for non-C++ tracing
7 // controllers, such as Telemetry and Android Systrace, to issue high-level 7 // controllers, such as Telemetry and Android Systrace, to issue high-level
8 // tracing commands to the BattOr.. 8 // tracing commands to the BattOr through an interactive shell.
9 //
10 // Example usage of how an external trace controller might use this binary:
11 //
12 // 1) Telemetry's PowerTracingAgent is told to start recording power samples
13 // 2) PowerTracingAgent opens up a BattOr agent binary subprocess
14 // 3) PowerTracingAgent sends the subprocess the StartTracing message via
15 // STDIN
16 // 4) PowerTracingAgent waits for the subprocess to write a line to STDOUT
17 // ('Done.' if successful, some error message otherwise)
18 // 5) If the last command was successful, PowerTracingAgent waits for the
19 // duration of the trace
20 // 6) When the tracing should end, PowerTracingAgent records the clock sync
21 // start timestamp and sends the subprocess the RecordClockSyncMark <marker>'
22 // message via STDIN.
23 // 7) PowerTracingAgent waits for the subprocess to write a line to STDOUT
24 // ('Done.' if successful, some error message otherwise)
25 // 8) If the last command was successful, PowerTracingAgent records the clock
26 // sync end timestamp and sends the subprocess the StopTracing message via
27 // STDIN
28 // 9) PowerTracingAgent continues to read trace output lines from STDOUT until
29 // the binary exits with an exit code of 1 (indicating failure) or the
30 // 'Done.' line is printed to STDOUT, signaling the last line of the trace
31 // 10) PowerTracingAgent returns the battery trace to the Telemetry trace
32 // controller
9 33
10 #include <stdint.h> 34 #include <stdint.h>
11 35
12 #include <iostream> 36 #include <iostream>
13 37
14 #include "base/at_exit.h" 38 #include "base/at_exit.h"
15 #include "base/bind.h" 39 #include "base/bind.h"
16 #include "base/bind_helpers.h" 40 #include "base/bind_helpers.h"
17 #include "base/command_line.h" 41 #include "base/command_line.h"
18 #include "base/location.h" 42 #include "base/location.h"
19 #include "base/logging.h" 43 #include "base/logging.h"
20 #include "base/strings/utf_string_conversions.h" 44 #include "base/strings/utf_string_conversions.h"
21 #include "base/threading/thread.h" 45 #include "base/threading/thread.h"
22 #include "tools/battor_agent/battor_agent.h" 46 #include "tools/battor_agent/battor_agent.h"
23 #include "tools/battor_agent/battor_error.h" 47 #include "tools/battor_agent/battor_error.h"
24 #include "tools/battor_agent/battor_finder.h" 48 #include "tools/battor_agent/battor_finder.h"
25 49
26 using std::cout;
27 using std::endl; 50 using std::endl;
28 51
29 namespace { 52 namespace {
30 53
31 const char kIoThreadName[] = "BattOr IO Thread"; 54 const char kIoThreadName[] = "BattOr IO Thread";
32 const char kFileThreadName[] = "BattOr File Thread"; 55 const char kFileThreadName[] = "BattOr File Thread";
33 const char kUiThreadName[] = "BattOr UI Thread"; 56 const char kUiThreadName[] = "BattOr UI Thread";
34 const int32_t kBattOrCommandTimeoutSeconds = 10; 57 const int32_t kBattOrCommandTimeoutSeconds = 10;
35 58
36 void PrintUsage() { 59 const char kUsage[] =
37 cout << "Usage: battor_agent <command> <arguments> <switches>" << endl 60 "Start the battor_agent shell with:\n"
38 << endl 61 "\n"
39 << "Commands:" << endl 62 " battor_agent <switches>\n"
40 << endl 63 "\n"
41 << " StartTracing" << endl 64 "Switches: \n"
42 << " StopTracing" << endl 65 " --battor-path=<path> Uses the specified BattOr path.\n"
43 << " SupportsExplicitClockSync" << endl 66 "\n"
44 << " RecordClockSyncMarker <marker>" << endl 67 "Once in the shell, you can issue the following commands:\n"
45 << " IssueClockSyncMarker" << endl 68 "\n"
46 << " Help" << endl 69 " StartTracing\n"
47 << endl 70 " StopTracing\n"
48 << "Switches:" << endl 71 " SupportsExplicitClockSync\n"
49 << endl 72 " RecordClockSyncMarker <marker>\n"
50 << " --battor-path=<path> Uses the specified BattOr path." << endl; 73 " Exit\n"
51 } 74 " Help\n"
75 "\n";
52 76
53 void PrintSupportsExplicitClockSync() { 77 void PrintSupportsExplicitClockSync() {
54 cout << battor::BattOrAgent::SupportsExplicitClockSync() << endl; 78 std::cout << battor::BattOrAgent::SupportsExplicitClockSync() << endl;
55 }
56
57 // Retrieves argument argnum from the argument list, or an empty string if the
58 // argument doesn't exist.
59 std::string GetArg(size_t argnum, base::CommandLine::StringVector args) {
60 if (argnum >= args.size()) {
61 return std::string();
62 }
63
64 #if defined(OS_WIN)
65 return base::WideToUTF8(args[argnum]);
66 #else
67 return args[argnum];
68 #endif
69 } 79 }
70 80
71 // Checks if an error occurred and, if it did, prints the error and exits 81 // Checks if an error occurred and, if it did, prints the error and exits
72 // with an error code. 82 // with an error code.
73 void CheckError(battor::BattOrError error) { 83 void CheckError(battor::BattOrError error) {
74 if (error != battor::BATTOR_ERROR_NONE) 84 if (error != battor::BATTOR_ERROR_NONE)
75 LOG(FATAL) << "Fatal error when communicating with the BattOr: " << error; 85 LOG(FATAL) << "Fatal error when communicating with the BattOr: " << error;
76 } 86 }
77 87
78 // Prints an error message and exits due to a required thread failing to start. 88 // Prints an error message and exits due to a required thread failing to start.
(...skipping 10 matching lines...) Expand all
89 class BattOrAgentBin : public BattOrAgent::Listener { 99 class BattOrAgentBin : public BattOrAgent::Listener {
90 public: 100 public:
91 BattOrAgentBin() 101 BattOrAgentBin()
92 : done_(false, false), 102 : done_(false, false),
93 io_thread_(kIoThreadName), 103 io_thread_(kIoThreadName),
94 file_thread_(kFileThreadName), 104 file_thread_(kFileThreadName),
95 ui_thread_(kUiThreadName) {} 105 ui_thread_(kUiThreadName) {}
96 106
97 ~BattOrAgentBin() { DCHECK(!agent_); } 107 ~BattOrAgentBin() { DCHECK(!agent_); }
98 108
99 // Runs the BattOr binary and returns the exit code. 109 // Starts the interactive BattOr agent shell and eventually returns an exit
110 // code.
100 int Run(int argc, char* argv[]) { 111 int Run(int argc, char* argv[]) {
101 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
102 std::string cmd = GetArg(0, command_line->GetArgs());
103 if (cmd.empty()) {
104 PrintUsage();
105 exit(1);
106 }
107
108 // SupportsExplicitClockSync doesn't need to use the serial connection, so
109 // handle it separately.
110 if (cmd == "SupportsExplicitClockSync") {
111 PrintSupportsExplicitClockSync();
112 return 0;
113 }
114
115 // If we don't have any BattOr to use, exit. 112 // If we don't have any BattOr to use, exit.
116 std::string path = BattOrFinder::FindBattOr(); 113 std::string path = BattOrFinder::FindBattOr();
117 if (path.empty()) { 114 if (path.empty()) {
118 cout << "Unable to find a BattOr." << endl; 115 std::cout << "Unable to find a BattOr." << endl;
119 exit(1); 116 exit(1);
120 } 117 }
121 118
122 SetUp(path); 119 SetUp(path);
123 120
124 if (cmd == "StartTracing") { 121 std::string cmd;
125 StartTracing(); 122 for (;;) {
126 } else if (cmd == "StopTracing") { 123 std::getline(std::cin, cmd);
127 StopTracing(); 124
128 } else if (cmd == "RecordClockSyncMarker") { 125 if (cmd == "StartTracing") {
129 // TODO(charliea): Write RecordClockSyncMarker. 126 StartTracing();
130 } else if (cmd == "IssueClockSyncMarker") { 127 } else if (cmd == "StopTracing") {
131 // TODO(charliea): Write IssueClockSyncMarker. 128 StopTracing();
132 } else { 129 break;
133 TearDown(); 130 } else if (cmd == "SupportsExplicitClockSync") {
134 PrintUsage(); 131 PrintSupportsExplicitClockSync();
135 return 1; 132 } else if (cmd == "RecordClockSyncMarker") {
133 // TODO(charliea): Write RecordClockSyncMarker.
134 } else if (cmd == "Exit") {
135 break;
136 } else {
137 std::cout << kUsage << endl;
138 }
136 } 139 }
137 140
138 TearDown(); 141 TearDown();
139 return 0; 142 return 0;
140 } 143 }
141 144
142 // Performs any setup necessary for the BattOr binary to run. 145 // Performs any setup necessary for the BattOr binary to run.
143 void SetUp(const std::string& path) { 146 void SetUp(const std::string& path) {
144 // TODO(charliea): Investigate whether it's possible to replace this 147 // TODO(charliea): Investigate whether it's possible to replace this
145 // separate thread with a combination of MessageLoopForIO and RunLoop. 148 // separate thread with a combination of MessageLoopForIO and RunLoop.
(...skipping 19 matching lines...) Expand all
165 168
166 void StartTracing() { 169 void StartTracing() {
167 io_thread_.task_runner()->PostTask( 170 io_thread_.task_runner()->PostTask(
168 FROM_HERE, 171 FROM_HERE,
169 base::Bind(&BattOrAgent::StartTracing, base::Unretained(agent_.get()))); 172 base::Bind(&BattOrAgent::StartTracing, base::Unretained(agent_.get())));
170 CheckError(AwaitResult()); 173 CheckError(AwaitResult());
171 } 174 }
172 175
173 void OnStartTracingComplete(BattOrError error) override { 176 void OnStartTracingComplete(BattOrError error) override {
174 error_ = error; 177 error_ = error;
178 std::cout << "Done." << endl;
175 done_.Signal(); 179 done_.Signal();
176 } 180 }
177 181
178 void StopTracing() { 182 void StopTracing() {
179 io_thread_.task_runner()->PostTask( 183 io_thread_.task_runner()->PostTask(
180 FROM_HERE, 184 FROM_HERE,
181 base::Bind(&BattOrAgent::StopTracing, base::Unretained(agent_.get()))); 185 base::Bind(&BattOrAgent::StopTracing, base::Unretained(agent_.get())));
182 CheckError(AwaitResult()); 186 CheckError(AwaitResult());
183 } 187 }
184 188
185 void OnStopTracingComplete(const std::string& trace, 189 void OnStopTracingComplete(const std::string& trace,
186 BattOrError error) override { 190 BattOrError error) override {
187 error_ = error; 191 error_ = error;
188 192
189 if (error == BATTOR_ERROR_NONE) 193 if (error == BATTOR_ERROR_NONE)
190 cout << trace << endl; 194 std::cout << trace;
195
196 std::cout << "Done." << endl;
191 197
192 done_.Signal(); 198 done_.Signal();
193 } 199 }
194 200
195 void OnRecordClockSyncMarkerComplete(BattOrError error) override { 201 void OnRecordClockSyncMarkerComplete(BattOrError error) override {
196 // TODO(charliea): Implement RecordClockSyncMarker for this binary. This 202 // TODO(charliea): Implement RecordClockSyncMarker for this binary. This
197 // will probably involve reading an external file for the actual sample 203 // will probably involve reading an external file for the actual sample
198 // number to clock sync ID map. 204 // number to clock sync ID map.
199 NOTREACHED(); 205 NOTREACHED();
200 } 206 }
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
255 }; 261 };
256 262
257 } // namespace battor 263 } // namespace battor
258 264
259 int main(int argc, char* argv[]) { 265 int main(int argc, char* argv[]) {
260 base::AtExitManager exit_manager; 266 base::AtExitManager exit_manager;
261 base::CommandLine::Init(argc, argv); 267 base::CommandLine::Init(argc, argv);
262 battor::BattOrAgentBin bin; 268 battor::BattOrAgentBin bin;
263 return bin.Run(argc, argv); 269 return bin.Run(argc, argv);
264 } 270 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698