Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 #include "tools/battor_agent/battor_agent.h" | 4 #include "tools/battor_agent/battor_agent.h" |
| 5 | 5 |
| 6 #include <iomanip> | 6 #include <iomanip> |
| 7 | 7 |
| 8 #include "base/bind.h" | 8 #include "base/bind.h" |
| 9 #include "base/threading/thread_task_runner_handle.h" | 9 #include "base/threading/thread_task_runner_handle.h" |
| 10 #include "tools/battor_agent/battor_connection_impl.h" | 10 #include "tools/battor_agent/battor_connection_impl.h" |
| 11 #include "tools/battor_agent/battor_sample_converter.h" | 11 #include "tools/battor_agent/battor_sample_converter.h" |
| 12 | 12 |
| 13 using std::vector; | 13 using std::vector; |
| 14 | 14 |
| 15 namespace battor { | 15 namespace battor { |
| 16 | 16 |
| 17 namespace { | 17 namespace { |
| 18 | 18 |
| 19 // The maximum number of times to retry when initializing a BattOr. | 19 // The maximum number of times to retry a command. |
| 20 const uint8_t kMaxInitAttempts = 20; | 20 const uint8_t kMaxCommandAttempts = 10; |
| 21 | |
| 22 // The maximum number of times to retry the StartTracing command. | |
| 23 const uint8_t kMaxStartTracingAttempts = 5; | |
| 24 | |
| 25 // The number of milliseconds to wait before retrying initialization. | |
| 26 const uint16_t kInitRetryDelayMilliseconds = 100; | |
| 27 | |
| 28 // The maximum number of times to retry when reading a message. | |
| 29 const uint8_t kMaxReadAttempts = 20; | |
| 30 | |
| 31 // The number of milliseconds to wait before trying to read a message again. | |
| 32 const uint8_t kReadRetryDelayMilliseconds = 1; | |
| 33 | 21 |
| 34 // The amount of time we need to wait after recording a clock sync marker in | 22 // The amount of time we need to wait after recording a clock sync marker in |
| 35 // order to ensure that the sample we synced to doesn't get thrown out. | 23 // order to ensure that the sample we synced to doesn't get thrown out. |
| 36 const uint8_t kStopTracingClockSyncDelayMilliseconds = 100; | 24 const uint8_t kStopTracingClockSyncDelayMilliseconds = 100; |
| 37 | 25 |
| 38 // The number of seconds allowed for a given action before timing out. | 26 // The number of seconds to wait before retrying a command. |
| 39 const uint8_t kBattOrTimeoutSeconds = 4; | 27 const uint16_t kCommandRetryDelaySeconds = 2; |
| 28 | |
| 29 // The number of seconds allowed for a control message before timing out. | |
| 30 const uint8_t kBattOrControlMessageTimeoutSeconds = 2; | |
| 31 | |
| 32 // The number of seconds allowed for connection to open before timing out. | |
| 33 const uint8_t kBattOrConnectionTimeoutSeconds = 4; | |
| 40 | 34 |
| 41 // Returns true if the specified vector of bytes decodes to a message that is an | 35 // Returns true if the specified vector of bytes decodes to a message that is an |
| 42 // ack for the specified control message type. | 36 // ack for the specified control message type. |
| 43 bool IsAckOfControlCommand(BattOrMessageType message_type, | 37 bool IsAckOfControlCommand(BattOrMessageType message_type, |
| 44 BattOrControlMessageType control_message_type, | 38 BattOrControlMessageType control_message_type, |
| 45 const vector<char>& msg) { | 39 const vector<char>& msg) { |
| 46 if (message_type != BATTOR_MESSAGE_TYPE_CONTROL_ACK) | 40 if (message_type != BATTOR_MESSAGE_TYPE_CONTROL_ACK) |
| 47 return false; | 41 return false; |
| 48 | 42 |
| 49 if (msg.size() != sizeof(BattOrControlMessageAck)) | 43 if (msg.size() != sizeof(BattOrControlMessageAck)) |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 116 Listener* listener, | 110 Listener* listener, |
| 117 scoped_refptr<base::SingleThreadTaskRunner> file_thread_task_runner, | 111 scoped_refptr<base::SingleThreadTaskRunner> file_thread_task_runner, |
| 118 scoped_refptr<base::SingleThreadTaskRunner> ui_thread_task_runner) | 112 scoped_refptr<base::SingleThreadTaskRunner> ui_thread_task_runner) |
| 119 : connection_(new BattOrConnectionImpl(path, | 113 : connection_(new BattOrConnectionImpl(path, |
| 120 this, | 114 this, |
| 121 file_thread_task_runner, | 115 file_thread_task_runner, |
| 122 ui_thread_task_runner)), | 116 ui_thread_task_runner)), |
| 123 listener_(listener), | 117 listener_(listener), |
| 124 last_action_(Action::INVALID), | 118 last_action_(Action::INVALID), |
| 125 command_(Command::INVALID), | 119 command_(Command::INVALID), |
| 126 num_init_attempts_(0), | 120 num_command_attempts_(0) { |
| 127 num_start_tracing_attempts_(0), | |
| 128 num_read_attempts_(0) { | |
| 129 // We don't care what thread the constructor is called on - we only care that | 121 // We don't care what thread the constructor is called on - we only care that |
| 130 // all of the other method invocations happen on the same thread. | 122 // all of the other method invocations happen on the same thread. |
| 131 thread_checker_.DetachFromThread(); | 123 thread_checker_.DetachFromThread(); |
| 132 } | 124 } |
| 133 | 125 |
| 134 BattOrAgent::~BattOrAgent() { | 126 BattOrAgent::~BattOrAgent() { |
| 135 DCHECK(thread_checker_.CalledOnValidThread()); | 127 DCHECK(thread_checker_.CalledOnValidThread()); |
| 136 } | 128 } |
| 137 | 129 |
| 138 void BattOrAgent::StartTracing() { | 130 void BattOrAgent::StartTracing() { |
| 139 DCHECK(thread_checker_.CalledOnValidThread()); | 131 DCHECK(thread_checker_.CalledOnValidThread()); |
| 140 | 132 |
| 141 // When tracing is restarted, all previous clock sync markers are invalid. | 133 // When tracing is restarted, all previous clock sync markers are invalid. |
| 142 clock_sync_markers_.clear(); | 134 clock_sync_markers_.clear(); |
| 143 last_clock_sync_time_ = base::TimeTicks(); | 135 last_clock_sync_time_ = base::TimeTicks(); |
| 144 | 136 |
| 145 num_start_tracing_attempts_ = 1; | |
| 146 command_ = Command::START_TRACING; | 137 command_ = Command::START_TRACING; |
| 147 PerformAction(Action::REQUEST_CONNECTION); | 138 PerformAction(Action::REQUEST_CONNECTION); |
| 148 } | 139 } |
| 149 | 140 |
| 150 void BattOrAgent::StopTracing() { | 141 void BattOrAgent::StopTracing() { |
| 151 DCHECK(thread_checker_.CalledOnValidThread()); | 142 DCHECK(thread_checker_.CalledOnValidThread()); |
| 152 | 143 |
| 153 command_ = Command::STOP_TRACING; | 144 command_ = Command::STOP_TRACING; |
| 154 PerformAction(Action::REQUEST_CONNECTION); | 145 PerformAction(Action::REQUEST_CONNECTION); |
| 155 } | 146 } |
| 156 | 147 |
| 157 void BattOrAgent::RecordClockSyncMarker(const std::string& marker) { | 148 void BattOrAgent::RecordClockSyncMarker(const std::string& marker) { |
| 158 DCHECK(thread_checker_.CalledOnValidThread()); | 149 DCHECK(thread_checker_.CalledOnValidThread()); |
| 159 | 150 |
| 160 command_ = Command::RECORD_CLOCK_SYNC_MARKER; | 151 command_ = Command::RECORD_CLOCK_SYNC_MARKER; |
| 161 pending_clock_sync_marker_ = marker; | 152 pending_clock_sync_marker_ = marker; |
| 162 PerformAction(Action::REQUEST_CONNECTION); | 153 PerformAction(Action::REQUEST_CONNECTION); |
| 163 } | 154 } |
| 164 | 155 |
| 165 void BattOrAgent::GetFirmwareGitHash() { | 156 void BattOrAgent::GetFirmwareGitHash() { |
| 166 DCHECK(thread_checker_.CalledOnValidThread()); | 157 DCHECK(thread_checker_.CalledOnValidThread()); |
| 167 | 158 |
| 168 command_ = Command::GET_FIRMWARE_GIT_HASH; | 159 command_ = Command::GET_FIRMWARE_GIT_HASH; |
| 169 PerformAction(Action::REQUEST_CONNECTION); | 160 PerformAction(Action::REQUEST_CONNECTION); |
| 170 } | 161 } |
| 171 | 162 |
| 172 void BattOrAgent::BeginConnect() { | 163 void BattOrAgent::BeginConnect() { |
| 173 DCHECK(thread_checker_.CalledOnValidThread()); | 164 DCHECK(thread_checker_.CalledOnValidThread()); |
| 174 | 165 |
| 166 SetActionTimeout(kBattOrConnectionTimeoutSeconds); | |
| 167 | |
| 175 connection_->Open(); | 168 connection_->Open(); |
| 176 } | 169 } |
| 177 | 170 |
| 178 void BattOrAgent::OnConnectionOpened(bool success) { | 171 void BattOrAgent::OnConnectionOpened(bool success) { |
| 179 // Return immediately if opening the connection already timed out. | 172 // Cancel timeout because the connection was opened in time. |
| 180 if (timeout_callback_.IsCancelled()) | |
| 181 return; | |
| 182 timeout_callback_.Cancel(); | 173 timeout_callback_.Cancel(); |
| 183 | 174 |
| 184 if (!success) { | 175 if (!success) { |
| 185 CompleteCommand(BATTOR_ERROR_CONNECTION_FAILED); | 176 CompleteCommand(BATTOR_ERROR_CONNECTION_FAILED); |
| 186 return; | 177 return; |
| 187 } | 178 } |
| 188 | 179 |
| 189 switch (command_) { | 180 switch (command_) { |
| 190 case Command::START_TRACING: | 181 case Command::START_TRACING: |
| 191 num_init_attempts_ = 1; | |
| 192 PerformAction(Action::SEND_INIT); | 182 PerformAction(Action::SEND_INIT); |
| 193 return; | 183 return; |
| 194 case Command::STOP_TRACING: | 184 case Command::STOP_TRACING: |
| 195 PerformAction(Action::SEND_EEPROM_REQUEST); | 185 PerformAction(Action::SEND_EEPROM_REQUEST); |
| 196 return; | 186 return; |
| 197 case Command::RECORD_CLOCK_SYNC_MARKER: | 187 case Command::RECORD_CLOCK_SYNC_MARKER: |
| 198 PerformAction(Action::SEND_CURRENT_SAMPLE_REQUEST); | 188 PerformAction(Action::SEND_CURRENT_SAMPLE_REQUEST); |
| 199 return; | 189 return; |
| 200 case Command::GET_FIRMWARE_GIT_HASH: | 190 case Command::GET_FIRMWARE_GIT_HASH: |
| 201 num_init_attempts_ = 1; | |
| 202 PerformAction(Action::SEND_INIT); | 191 PerformAction(Action::SEND_INIT); |
| 203 return; | 192 return; |
| 204 case Command::INVALID: | 193 case Command::INVALID: |
| 205 NOTREACHED(); | 194 NOTREACHED(); |
| 195 return; | |
| 206 } | 196 } |
| 207 } | 197 } |
| 208 | 198 |
| 209 void BattOrAgent::OnBytesSent(bool success) { | 199 void BattOrAgent::OnBytesSent(bool success) { |
| 210 DCHECK(thread_checker_.CalledOnValidThread()); | 200 DCHECK(thread_checker_.CalledOnValidThread()); |
| 211 | 201 |
| 212 // Return immediately if whatever action we were trying to perform already | |
| 213 // timed out. | |
| 214 if (timeout_callback_.IsCancelled()) | |
| 215 return; | |
| 216 timeout_callback_.Cancel(); | |
| 217 | |
| 218 if (!success) { | 202 if (!success) { |
| 219 CompleteCommand(BATTOR_ERROR_SEND_ERROR); | 203 CompleteCommand(BATTOR_ERROR_SEND_ERROR); |
| 220 return; | 204 return; |
| 221 } | 205 } |
| 222 | 206 |
| 223 switch (last_action_) { | 207 switch (last_action_) { |
| 224 case Action::SEND_INIT: | 208 case Action::SEND_INIT: |
| 225 PerformAction(Action::READ_INIT_ACK); | 209 PerformAction(Action::READ_INIT_ACK); |
| 226 return; | 210 return; |
| 227 case Action::SEND_SET_GAIN: | 211 case Action::SEND_SET_GAIN: |
| 228 PerformAction(Action::READ_SET_GAIN_ACK); | 212 PerformAction(Action::READ_SET_GAIN_ACK); |
| 229 return; | 213 return; |
| 230 case Action::SEND_START_TRACING: | 214 case Action::SEND_START_TRACING: |
| 231 PerformAction(Action::READ_START_TRACING_ACK); | 215 PerformAction(Action::READ_START_TRACING_ACK); |
| 232 return; | 216 return; |
| 233 case Action::SEND_EEPROM_REQUEST: | 217 case Action::SEND_EEPROM_REQUEST: |
| 234 num_read_attempts_ = 1; | |
| 235 PerformAction(Action::READ_EEPROM); | 218 PerformAction(Action::READ_EEPROM); |
| 236 return; | 219 return; |
| 237 case Action::SEND_SAMPLES_REQUEST: | 220 case Action::SEND_SAMPLES_REQUEST: |
| 238 num_read_attempts_ = 1; | |
| 239 PerformAction(Action::READ_CALIBRATION_FRAME); | 221 PerformAction(Action::READ_CALIBRATION_FRAME); |
| 240 return; | 222 return; |
| 241 case Action::SEND_CURRENT_SAMPLE_REQUEST: | 223 case Action::SEND_CURRENT_SAMPLE_REQUEST: |
| 242 num_read_attempts_ = 1; | |
| 243 PerformAction(Action::READ_CURRENT_SAMPLE); | 224 PerformAction(Action::READ_CURRENT_SAMPLE); |
| 244 return; | 225 return; |
| 245 case Action::SEND_GIT_HASH_REQUEST: | 226 case Action::SEND_GIT_HASH_REQUEST: |
| 246 num_read_attempts_ = 1; | |
| 247 PerformAction(Action::READ_GIT_HASH); | 227 PerformAction(Action::READ_GIT_HASH); |
| 248 return; | 228 return; |
| 249 default: | 229 default: |
| 250 CompleteCommand(BATTOR_ERROR_UNEXPECTED_MESSAGE); | 230 NOTREACHED(); |
| 231 return; | |
| 251 } | 232 } |
| 252 } | 233 } |
| 253 | 234 |
| 254 void BattOrAgent::OnMessageRead(bool success, | 235 void BattOrAgent::OnMessageRead(bool success, |
| 255 BattOrMessageType type, | 236 BattOrMessageType type, |
| 256 std::unique_ptr<vector<char>> bytes) { | 237 std::unique_ptr<vector<char>> bytes) { |
| 257 // Return immediately if whatever action we were trying to perform already | |
| 258 // timed out. | |
| 259 if (timeout_callback_.IsCancelled()) | |
| 260 return; | |
| 261 timeout_callback_.Cancel(); | |
| 262 | |
| 263 if (!success) { | 238 if (!success) { |
| 264 switch (last_action_) { | 239 switch (last_action_) { |
| 265 case Action::READ_GIT_HASH: | 240 case Action::READ_GIT_HASH: |
| 241 case Action::READ_INIT_ACK: | |
| 242 case Action::READ_SET_GAIN_ACK: | |
| 243 case Action::READ_START_TRACING_ACK: | |
| 266 case Action::READ_EEPROM: | 244 case Action::READ_EEPROM: |
| 267 case Action::READ_CALIBRATION_FRAME: | 245 case Action::READ_CALIBRATION_FRAME: |
| 268 case Action::READ_DATA_FRAME: | 246 case Action::READ_DATA_FRAME: |
| 269 case Action::READ_CURRENT_SAMPLE: | 247 RetryCommand(); |
| 270 if (num_read_attempts_++ > kMaxReadAttempts) { | |
| 271 CompleteCommand(BATTOR_ERROR_RECEIVE_ERROR); | |
| 272 return; | |
| 273 } | |
| 274 | |
| 275 PerformDelayedAction(last_action_, base::TimeDelta::FromMilliseconds( | |
| 276 kReadRetryDelayMilliseconds)); | |
| 277 return; | 248 return; |
| 278 | 249 |
| 279 // Retry sending an INIT if it an ACK is not received. | 250 case Action::READ_CURRENT_SAMPLE: |
| 280 case Action::SEND_INIT: | 251 CompleteCommand(BATTOR_ERROR_RECEIVE_ERROR); |
| 281 case Action::READ_INIT_ACK: | |
| 282 if (num_init_attempts_++ < kMaxInitAttempts) { | |
| 283 PerformDelayedAction(Action::SEND_INIT, | |
| 284 base::TimeDelta::FromMilliseconds(kInitRetryDelayMilliseconds)); | |
| 285 } else { | |
| 286 CompleteCommand(BATTOR_ERROR_TOO_MANY_INIT_RETRIES); | |
| 287 } | |
| 288 | |
| 289 return; | |
| 290 | |
| 291 case Action::READ_START_TRACING_ACK: | |
| 292 if (num_start_tracing_attempts_++ < kMaxStartTracingAttempts) { | |
| 293 num_init_attempts_ = 1; | |
| 294 PerformAction(Action::SEND_INIT); | |
| 295 } else { | |
| 296 CompleteCommand(BATTOR_ERROR_TOO_MANY_START_TRACING_RETRIES); | |
| 297 } | |
| 298 | |
| 299 return; | 252 return; |
| 300 | 253 |
| 301 default: | 254 default: |
| 302 CompleteCommand(BATTOR_ERROR_RECEIVE_ERROR); | 255 NOTREACHED(); |
| 303 return; | 256 return; |
| 304 } | 257 } |
| 305 } | 258 } |
| 306 | 259 |
| 260 // Successfully read a message, cancel any timeouts. | |
| 261 timeout_callback_.Cancel(); | |
| 262 | |
| 307 switch (last_action_) { | 263 switch (last_action_) { |
| 308 case Action::READ_INIT_ACK: | 264 case Action::READ_INIT_ACK: |
| 309 if (!IsAckOfControlCommand(type, BATTOR_CONTROL_MESSAGE_TYPE_INIT, | 265 if (!IsAckOfControlCommand(type, BATTOR_CONTROL_MESSAGE_TYPE_INIT, |
| 310 *bytes)) { | 266 *bytes)) { |
| 311 if (num_init_attempts_++ < kMaxInitAttempts) { | 267 RetryCommand(); |
| 312 PerformDelayedAction(Action::SEND_INIT, | |
| 313 base::TimeDelta::FromMilliseconds(kInitRetryDelayMilliseconds)); | |
| 314 } else { | |
| 315 CompleteCommand(BATTOR_ERROR_TOO_MANY_INIT_RETRIES); | |
| 316 } | |
| 317 | |
| 318 return; | 268 return; |
| 319 } | 269 } |
| 320 | 270 |
| 321 switch (command_) { | 271 switch (command_) { |
| 322 case Command::START_TRACING: | 272 case Command::START_TRACING: |
| 323 PerformAction(Action::SEND_SET_GAIN); | 273 PerformAction(Action::SEND_SET_GAIN); |
| 324 return; | 274 return; |
| 325 case Command::GET_FIRMWARE_GIT_HASH: | 275 case Command::GET_FIRMWARE_GIT_HASH: |
| 326 PerformAction(Action::SEND_GIT_HASH_REQUEST); | 276 PerformAction(Action::SEND_GIT_HASH_REQUEST); |
| 327 return; | 277 return; |
| 328 default: | 278 default: |
| 329 CompleteCommand(BATTOR_ERROR_UNEXPECTED_MESSAGE); | 279 NOTREACHED(); |
| 330 return; | 280 return; |
| 331 } | 281 } |
| 332 | 282 |
| 333 case Action::READ_SET_GAIN_ACK: | 283 case Action::READ_SET_GAIN_ACK: |
| 334 if (!IsAckOfControlCommand(type, BATTOR_CONTROL_MESSAGE_TYPE_SET_GAIN, | 284 if (!IsAckOfControlCommand(type, BATTOR_CONTROL_MESSAGE_TYPE_SET_GAIN, |
| 335 *bytes)) { | 285 *bytes)) { |
| 336 CompleteCommand(BATTOR_ERROR_UNEXPECTED_MESSAGE); | 286 RetryCommand(); |
| 337 return; | 287 return; |
| 338 } | 288 } |
| 339 | 289 |
| 340 PerformAction(Action::SEND_START_TRACING); | 290 PerformAction(Action::SEND_START_TRACING); |
| 341 return; | 291 return; |
| 342 | 292 |
| 343 case Action::READ_START_TRACING_ACK: | 293 case Action::READ_START_TRACING_ACK: |
| 344 if (!IsAckOfControlCommand( | 294 if (!IsAckOfControlCommand( |
| 345 type, BATTOR_CONTROL_MESSAGE_TYPE_START_SAMPLING_SD, *bytes)) { | 295 type, BATTOR_CONTROL_MESSAGE_TYPE_START_SAMPLING_SD, *bytes)) { |
| 346 if (num_start_tracing_attempts_++ < kMaxStartTracingAttempts) { | 296 RetryCommand(); |
| 347 num_init_attempts_ = 1; | |
| 348 PerformAction(Action::SEND_INIT); | |
| 349 } else { | |
| 350 CompleteCommand(BATTOR_ERROR_TOO_MANY_START_TRACING_RETRIES); | |
| 351 } | |
| 352 | |
| 353 return; | 297 return; |
| 354 } | 298 } |
| 355 | 299 |
| 356 CompleteCommand(BATTOR_ERROR_NONE); | 300 CompleteCommand(BATTOR_ERROR_NONE); |
| 357 return; | 301 return; |
| 358 | 302 |
| 359 case Action::READ_EEPROM: { | 303 case Action::READ_EEPROM: { |
| 360 battor_eeprom_ = ParseEEPROM(type, *bytes); | 304 battor_eeprom_ = ParseEEPROM(type, *bytes); |
| 361 if (!battor_eeprom_) { | 305 if (!battor_eeprom_) { |
| 362 CompleteCommand(BATTOR_ERROR_UNEXPECTED_MESSAGE); | 306 RetryCommand(); |
| 363 return; | 307 return; |
| 364 } | 308 } |
| 365 | 309 |
| 366 // Make sure that we don't request samples until a safe amount of time has | 310 // Make sure that we don't request samples until a safe amount of time has |
| 367 // elapsed since recording the last clock sync marker: we need to ensure | 311 // elapsed since recording the last clock sync marker: we need to ensure |
| 368 // that the sample we synced to doesn't get thrown out. | 312 // that the sample we synced to doesn't get thrown out. |
| 369 base::TimeTicks min_request_samples_time = | 313 base::TimeTicks min_request_samples_time = |
| 370 last_clock_sync_time_ + base::TimeDelta::FromMilliseconds( | 314 last_clock_sync_time_ + base::TimeDelta::FromMilliseconds( |
| 371 kStopTracingClockSyncDelayMilliseconds); | 315 kStopTracingClockSyncDelayMilliseconds); |
| 372 base::TimeDelta request_samples_delay = std::max( | 316 base::TimeDelta request_samples_delay = std::max( |
| 373 min_request_samples_time - base::TimeTicks::Now(), base::TimeDelta()); | 317 min_request_samples_time - base::TimeTicks::Now(), base::TimeDelta()); |
| 374 | 318 |
| 375 PerformDelayedAction(Action::SEND_SAMPLES_REQUEST, request_samples_delay); | 319 PerformDelayedAction(Action::SEND_SAMPLES_REQUEST, request_samples_delay); |
| 376 return; | 320 return; |
| 377 } | 321 } |
| 378 case Action::READ_CALIBRATION_FRAME: { | 322 case Action::READ_CALIBRATION_FRAME: { |
| 379 BattOrFrameHeader frame_header; | 323 BattOrFrameHeader frame_header; |
| 380 if (!ParseSampleFrame(type, *bytes, next_sequence_number_++, | 324 if (!ParseSampleFrame(type, *bytes, next_sequence_number_++, |
| 381 &frame_header, &calibration_frame_)) { | 325 &frame_header, &calibration_frame_)) { |
| 382 CompleteCommand(BATTOR_ERROR_UNEXPECTED_MESSAGE); | 326 RetryCommand(); |
| 383 return; | 327 return; |
| 384 } | 328 } |
| 385 | 329 |
| 386 // Make sure that the calibration frame has actual samples in it. | 330 // Make sure that the calibration frame has actual samples in it. |
| 387 if (calibration_frame_.empty()) { | 331 if (calibration_frame_.empty()) { |
| 388 CompleteCommand(BATTOR_ERROR_UNEXPECTED_MESSAGE); | 332 RetryCommand(); |
| 389 return; | 333 return; |
| 390 } | 334 } |
| 391 | 335 |
| 392 num_read_attempts_ = 1; | |
| 393 PerformAction(Action::READ_DATA_FRAME); | 336 PerformAction(Action::READ_DATA_FRAME); |
| 394 return; | 337 return; |
| 395 } | 338 } |
| 396 | 339 |
| 397 case Action::READ_DATA_FRAME: { | 340 case Action::READ_DATA_FRAME: { |
| 398 BattOrFrameHeader frame_header; | 341 BattOrFrameHeader frame_header; |
| 399 vector<RawBattOrSample> frame; | 342 vector<RawBattOrSample> frame; |
| 400 if (!ParseSampleFrame(type, *bytes, next_sequence_number_++, | 343 if (!ParseSampleFrame(type, *bytes, next_sequence_number_++, |
| 401 &frame_header, &frame)) { | 344 &frame_header, &frame)) { |
| 402 CompleteCommand(BATTOR_ERROR_UNEXPECTED_MESSAGE); | 345 RetryCommand(); |
| 403 return; | 346 return; |
| 404 } | 347 } |
| 405 | 348 |
| 406 // Check for the empty frame the BattOr uses to indicate it's done | 349 // Check for the empty frame the BattOr uses to indicate it's done |
| 407 // streaming samples. | 350 // streaming samples. |
| 408 if (frame.empty()) { | 351 if (frame.empty()) { |
| 352 // Cancel the next data frame timeout. | |
| 353 timeout_callback_.Cancel(); | |
| 409 CompleteCommand(BATTOR_ERROR_NONE); | 354 CompleteCommand(BATTOR_ERROR_NONE); |
| 410 return; | 355 return; |
| 411 } | 356 } |
| 412 | 357 |
| 413 samples_.insert(samples_.end(), frame.begin(), frame.end()); | 358 samples_.insert(samples_.end(), frame.begin(), frame.end()); |
| 414 | 359 |
| 415 num_read_attempts_ = 1; | |
| 416 PerformAction(Action::READ_DATA_FRAME); | 360 PerformAction(Action::READ_DATA_FRAME); |
| 417 return; | 361 return; |
| 418 } | 362 } |
| 419 | 363 |
| 420 case Action::READ_CURRENT_SAMPLE: | 364 case Action::READ_CURRENT_SAMPLE: |
| 421 if (type != BATTOR_MESSAGE_TYPE_CONTROL_ACK || | 365 if (type != BATTOR_MESSAGE_TYPE_CONTROL_ACK || |
| 422 bytes->size() != sizeof(uint32_t)) { | 366 bytes->size() != sizeof(uint32_t)) { |
| 423 CompleteCommand(BATTOR_ERROR_UNEXPECTED_MESSAGE); | 367 CompleteCommand(BATTOR_ERROR_UNEXPECTED_MESSAGE); |
| 424 return; | 368 return; |
| 425 } | 369 } |
| 426 | 370 |
| 427 uint32_t sample_num; | 371 uint32_t sample_num; |
| 428 memcpy(&sample_num, bytes->data(), sizeof(uint32_t)); | 372 memcpy(&sample_num, bytes->data(), sizeof(uint32_t)); |
| 429 clock_sync_markers_[sample_num] = pending_clock_sync_marker_; | 373 clock_sync_markers_[sample_num] = pending_clock_sync_marker_; |
| 430 last_clock_sync_time_ = base::TimeTicks::Now(); | 374 last_clock_sync_time_ = base::TimeTicks::Now(); |
| 431 CompleteCommand(BATTOR_ERROR_NONE); | 375 CompleteCommand(BATTOR_ERROR_NONE); |
| 432 return; | 376 return; |
| 433 | 377 |
| 434 case Action::READ_GIT_HASH: | 378 case Action::READ_GIT_HASH: |
| 435 if (type != BATTOR_MESSAGE_TYPE_CONTROL_ACK ){ | 379 if (type != BATTOR_MESSAGE_TYPE_CONTROL_ACK) { |
| 436 CompleteCommand(BATTOR_ERROR_UNEXPECTED_MESSAGE); | 380 RetryCommand(); |
| 437 return; | 381 return; |
| 438 } | 382 } |
| 383 | |
| 439 firmware_git_hash_ = std::string(bytes->begin(), bytes->end()); | 384 firmware_git_hash_ = std::string(bytes->begin(), bytes->end()); |
| 440 CompleteCommand(BATTOR_ERROR_NONE); | 385 CompleteCommand(BATTOR_ERROR_NONE); |
| 441 return; | 386 return; |
| 442 | 387 |
| 443 default: | 388 default: |
| 444 CompleteCommand(BATTOR_ERROR_UNEXPECTED_MESSAGE); | 389 NOTREACHED(); |
| 390 return; | |
| 445 } | 391 } |
| 446 } | 392 } |
| 447 | 393 |
| 448 void BattOrAgent::PerformAction(Action action) { | 394 void BattOrAgent::PerformAction(Action action) { |
| 449 DCHECK(thread_checker_.CalledOnValidThread()); | 395 DCHECK(thread_checker_.CalledOnValidThread()); |
| 450 | 396 |
| 451 timeout_callback_.Reset( | |
| 452 base::Bind(&BattOrAgent::OnActionTimeout, AsWeakPtr())); | |
| 453 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( | |
| 454 FROM_HERE, timeout_callback_.callback(), | |
| 455 base::TimeDelta::FromSeconds(kBattOrTimeoutSeconds)); | |
| 456 | |
| 457 last_action_ = action; | 397 last_action_ = action; |
| 458 | 398 |
| 459 switch (action) { | 399 switch (action) { |
| 460 case Action::REQUEST_CONNECTION: | 400 case Action::REQUEST_CONNECTION: |
| 461 BeginConnect(); | 401 BeginConnect(); |
| 462 return; | 402 return; |
| 463 | |
| 464 // The following actions are required for StartTracing: | 403 // The following actions are required for StartTracing: |
| 465 case Action::SEND_INIT: | 404 case Action::SEND_INIT: |
| 466 // Clear out the serial data that may exist from prior init attempts. | |
| 467 connection_->Flush(); | |
| 468 | |
| 469 SendControlMessage(BATTOR_CONTROL_MESSAGE_TYPE_INIT, 0, 0); | 405 SendControlMessage(BATTOR_CONTROL_MESSAGE_TYPE_INIT, 0, 0); |
| 470 return; | 406 return; |
| 471 case Action::READ_INIT_ACK: | 407 case Action::READ_INIT_ACK: |
| 472 connection_->ReadMessage(BATTOR_MESSAGE_TYPE_CONTROL_ACK); | 408 connection_->ReadMessage(BATTOR_MESSAGE_TYPE_CONTROL_ACK); |
| 473 return; | 409 return; |
| 474 case Action::SEND_SET_GAIN: | 410 case Action::SEND_SET_GAIN: |
| 475 // Set the BattOr's gain. Setting the gain tells the BattOr the range of | 411 // Set the BattOr's gain. Setting the gain tells the BattOr the range of |
| 476 // power measurements that we expect to see. | 412 // power measurements that we expect to see. |
| 477 SendControlMessage(BATTOR_CONTROL_MESSAGE_TYPE_SET_GAIN, BATTOR_GAIN_LOW, | 413 SendControlMessage(BATTOR_CONTROL_MESSAGE_TYPE_SET_GAIN, BATTOR_GAIN_LOW, |
| 478 0); | 414 0); |
| 479 return; | 415 return; |
| 480 case Action::READ_SET_GAIN_ACK: | 416 case Action::READ_SET_GAIN_ACK: |
| 481 connection_->ReadMessage(BATTOR_MESSAGE_TYPE_CONTROL_ACK); | 417 connection_->ReadMessage(BATTOR_MESSAGE_TYPE_CONTROL_ACK); |
| 482 return; | 418 return; |
| 483 case Action::SEND_START_TRACING: | 419 case Action::SEND_START_TRACING: |
| 484 SendControlMessage(BATTOR_CONTROL_MESSAGE_TYPE_START_SAMPLING_SD, 0, 0); | 420 SendControlMessage(BATTOR_CONTROL_MESSAGE_TYPE_START_SAMPLING_SD, 0, 0); |
| 485 return; | 421 return; |
| 486 case Action::READ_START_TRACING_ACK: | 422 case Action::READ_START_TRACING_ACK: |
| 487 connection_->ReadMessage(BATTOR_MESSAGE_TYPE_CONTROL_ACK); | 423 connection_->ReadMessage(BATTOR_MESSAGE_TYPE_CONTROL_ACK); |
| 488 return; | 424 return; |
| 489 | |
| 490 // The following actions are required for StopTracing: | 425 // The following actions are required for StopTracing: |
| 491 case Action::SEND_EEPROM_REQUEST: | 426 case Action::SEND_EEPROM_REQUEST: |
| 492 // Read the BattOr's EEPROM to get calibration information that's required | 427 // Read the BattOr's EEPROM to get calibration information that's required |
| 493 // to convert the raw samples to accurate ones. | 428 // to convert the raw samples to accurate ones. |
| 494 SendControlMessage(BATTOR_CONTROL_MESSAGE_TYPE_READ_EEPROM, | 429 SendControlMessage(BATTOR_CONTROL_MESSAGE_TYPE_READ_EEPROM, |
| 495 sizeof(BattOrEEPROM), 0); | 430 sizeof(BattOrEEPROM), 0); |
| 496 return; | 431 return; |
| 497 case Action::READ_EEPROM: | 432 case Action::READ_EEPROM: |
| 498 connection_->ReadMessage(BATTOR_MESSAGE_TYPE_CONTROL_ACK); | 433 connection_->ReadMessage(BATTOR_MESSAGE_TYPE_CONTROL_ACK); |
| 499 return; | 434 return; |
| 500 case Action::SEND_SAMPLES_REQUEST: | 435 case Action::SEND_SAMPLES_REQUEST: |
| 501 // Send a request to the BattOr to tell it to start streaming the samples | 436 // Send a request to the BattOr to tell it to start streaming the samples |
| 502 // that it's stored on its SD card over the serial connection. | 437 // that it's stored on its SD card over the serial connection. |
| 503 SendControlMessage(BATTOR_CONTROL_MESSAGE_TYPE_READ_SD_UART, 0, 0); | 438 SendControlMessage(BATTOR_CONTROL_MESSAGE_TYPE_READ_SD_UART, 0, 0); |
| 504 return; | 439 return; |
| 505 case Action::READ_CALIBRATION_FRAME: | 440 case Action::READ_CALIBRATION_FRAME: |
| 506 // Data frames are numbered starting at zero and counting up by one each | 441 // Data frames are numbered starting at zero and counting up by one each |
| 507 // data frame. We keep track of the next frame sequence number we expect | 442 // data frame. We keep track of the next frame sequence number we expect |
| 508 // to see to ensure we don't miss any data. | 443 // to see to ensure we don't miss any data. |
| 509 next_sequence_number_ = 0; | 444 next_sequence_number_ = 0; |
| 445 | |
| 446 // Clear stored samples from prior attempts to read sample frames. | |
| 447 samples_.clear(); | |
| 448 calibration_frame_.clear(); | |
| 510 case Action::READ_DATA_FRAME: | 449 case Action::READ_DATA_FRAME: |
| 511 // The first frame sent back from the BattOr contains voltage and current | 450 // The first frame sent back from the BattOr contains voltage and current |
| 512 // data that excludes whatever device is being measured from the | 451 // data that excludes whatever device is being measured from the |
| 513 // circuit. We use this first frame to establish a baseline voltage and | 452 // circuit. We use this first frame to establish a baseline voltage and |
| 514 // current. | 453 // current. |
| 515 // | 454 // |
| 516 // All further frames contain real (but uncalibrated) voltage and current | 455 // All further frames contain real (but uncalibrated) voltage and current |
| 517 // data. | 456 // data. |
| 457 SetActionTimeout(kBattOrControlMessageTimeoutSeconds); | |
| 518 connection_->ReadMessage(BATTOR_MESSAGE_TYPE_SAMPLES); | 458 connection_->ReadMessage(BATTOR_MESSAGE_TYPE_SAMPLES); |
| 519 return; | 459 return; |
| 520 | 460 |
| 521 // The following actions are required for RecordClockSyncMarker: | 461 // The following actions are required for RecordClockSyncMarker: |
| 522 case Action::SEND_CURRENT_SAMPLE_REQUEST: | 462 case Action::SEND_CURRENT_SAMPLE_REQUEST: |
| 523 SendControlMessage(BATTOR_CONTROL_MESSAGE_TYPE_READ_SAMPLE_COUNT, 0, 0); | 463 SendControlMessage(BATTOR_CONTROL_MESSAGE_TYPE_READ_SAMPLE_COUNT, 0, 0); |
| 524 return; | 464 return; |
| 525 case Action::READ_CURRENT_SAMPLE: | 465 case Action::READ_CURRENT_SAMPLE: |
| 526 connection_->ReadMessage(BATTOR_MESSAGE_TYPE_CONTROL_ACK); | 466 connection_->ReadMessage(BATTOR_MESSAGE_TYPE_CONTROL_ACK); |
| 527 return; | 467 return; |
| 528 | 468 |
| 529 case Action::SEND_GIT_HASH_REQUEST: | 469 case Action::SEND_GIT_HASH_REQUEST: |
| 530 connection_->Flush(); | |
| 531 SendControlMessage( | 470 SendControlMessage( |
| 532 BATTOR_CONTROL_MESSAGE_TYPE_GET_FIRMWARE_GIT_HASH, 0, 0); | 471 BATTOR_CONTROL_MESSAGE_TYPE_GET_FIRMWARE_GIT_HASH, 0, 0); |
| 533 return; | 472 return; |
| 534 | 473 |
| 535 case Action::READ_GIT_HASH: | 474 case Action::READ_GIT_HASH: |
| 536 connection_->ReadMessage(BATTOR_MESSAGE_TYPE_CONTROL_ACK); | 475 connection_->ReadMessage(BATTOR_MESSAGE_TYPE_CONTROL_ACK); |
| 537 return; | 476 return; |
| 538 | 477 |
| 539 case Action::INVALID: | 478 case Action::INVALID: |
| 540 NOTREACHED(); | 479 NOTREACHED(); |
| 480 return; | |
| 541 } | 481 } |
| 542 } | 482 } |
| 543 | 483 |
| 544 void BattOrAgent::PerformDelayedAction(Action action, base::TimeDelta delay) { | 484 void BattOrAgent::PerformDelayedAction(Action action, base::TimeDelta delay) { |
| 545 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( | 485 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( |
| 546 FROM_HERE, base::Bind(&BattOrAgent::PerformAction, AsWeakPtr(), action), | 486 FROM_HERE, base::Bind(&BattOrAgent::PerformAction, AsWeakPtr(), action), |
| 547 delay); | 487 delay); |
| 548 } | 488 } |
| 549 | 489 |
| 550 void BattOrAgent::OnActionTimeout() { | 490 void BattOrAgent::OnActionTimeout() { |
| 551 switch (last_action_) { | 491 switch (last_action_) { |
| 552 case Action::READ_INIT_ACK: | 492 case Action::READ_INIT_ACK: |
| 553 if (num_init_attempts_++ < kMaxInitAttempts) { | 493 case Action::READ_SET_GAIN_ACK: |
| 554 // OnMessageRead() will fail and retry SEND_INIT. | |
| 555 connection_->CancelReadMessage(); | |
| 556 } else { | |
| 557 CompleteCommand(BATTOR_ERROR_TOO_MANY_INIT_RETRIES); | |
| 558 } | |
| 559 return; | |
| 560 | |
| 561 // TODO(crbug.com/672631): There's currently a BattOr firmware bug that's | |
| 562 // causing the BattOr to reset when it's sent the START_TRACING command. | |
| 563 // When the BattOr resets, it emits 0x00 to the serial connection. This 0x00 | |
| 564 // isn't long enough for the connection to consider it a full ack of the | |
| 565 // START_TRACING command, so it continues to wait for more data. We handle | |
| 566 // this case here by assuming any timeouts while waiting for the | |
| 567 // StartTracing ack are related to this bug and retrying the full | |
| 568 // initialization sequence. | |
| 569 case Action::READ_START_TRACING_ACK: | 494 case Action::READ_START_TRACING_ACK: |
| 570 if (num_start_tracing_attempts_ < kMaxStartTracingAttempts) { | 495 case Action::READ_EEPROM: |
| 571 // OnMessageRead() will fail and retry StartTracing. | 496 case Action::READ_CALIBRATION_FRAME: |
| 572 connection_->CancelReadMessage(); | 497 case Action::READ_DATA_FRAME: |
| 573 } else { | 498 case Action::READ_GIT_HASH: |
| 574 CompleteCommand(BATTOR_ERROR_TOO_MANY_START_TRACING_RETRIES); | 499 connection_->CancelReadMessage(); |
| 575 } | |
| 576 return; | 500 return; |
| 577 | 501 |
| 578 default: | 502 default: |
| 579 CompleteCommand(BATTOR_ERROR_TIMEOUT); | 503 CompleteCommand(BATTOR_ERROR_TIMEOUT); |
| 580 timeout_callback_.Cancel(); | 504 timeout_callback_.Cancel(); |
| 581 } | 505 } |
| 582 } | 506 } |
| 583 | 507 |
| 584 void BattOrAgent::SendControlMessage(BattOrControlMessageType type, | 508 void BattOrAgent::SendControlMessage(BattOrControlMessageType type, |
| 585 uint16_t param1, | 509 uint16_t param1, |
| 586 uint16_t param2) { | 510 uint16_t param2) { |
| 587 DCHECK(thread_checker_.CalledOnValidThread()); | 511 DCHECK(thread_checker_.CalledOnValidThread()); |
| 588 | 512 |
| 513 SetActionTimeout(kBattOrControlMessageTimeoutSeconds); | |
| 514 | |
| 589 BattOrControlMessage msg{type, param1, param2}; | 515 BattOrControlMessage msg{type, param1, param2}; |
| 590 connection_->SendBytes(BATTOR_MESSAGE_TYPE_CONTROL, &msg, sizeof(msg)); | 516 connection_->SendBytes(BATTOR_MESSAGE_TYPE_CONTROL, &msg, sizeof(msg)); |
| 591 } | 517 } |
| 592 | 518 |
| 519 void BattOrAgent::RetryCommand() { | |
| 520 if (++num_command_attempts_ >= kMaxCommandAttempts) { | |
| 521 CompleteCommand(BATTOR_ERROR_TOO_MANY_COMMAND_RETRIES); | |
| 522 return; | |
| 523 } | |
| 524 | |
| 525 // Failed to read response to message, retry current command. | |
| 526 base::Callback<void()> next_command; | |
| 527 switch (command_) { | |
| 528 case Command::START_TRACING: | |
| 529 next_command = base::Bind(&BattOrAgent::StartTracing, AsWeakPtr()); | |
| 530 return; | |
| 531 case Command::STOP_TRACING: | |
| 532 next_command = base::Bind(&BattOrAgent::StopTracing, AsWeakPtr()); | |
| 533 return; | |
| 534 case Command::GET_FIRMWARE_GIT_HASH: | |
| 535 next_command = base::Bind(&BattOrAgent::GetFirmwareGitHash, AsWeakPtr()); | |
| 536 return; | |
| 537 default: | |
| 538 NOTREACHED(); | |
| 539 return; | |
| 540 } | |
| 541 | |
| 542 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( | |
|
charliea (OOO until 10-5)
2017/05/16 16:13:08
Ah, looks like the presubmit caught a bug that I d
| |
| 543 FROM_HERE, next_command, | |
| 544 base::TimeDelta::FromSeconds(kCommandRetryDelaySeconds)); | |
| 545 } | |
| 546 | |
| 593 void BattOrAgent::CompleteCommand(BattOrError error) { | 547 void BattOrAgent::CompleteCommand(BattOrError error) { |
| 594 switch (command_) { | 548 switch (command_) { |
| 595 case Command::START_TRACING: | 549 case Command::START_TRACING: |
| 596 base::ThreadTaskRunnerHandle::Get()->PostTask( | 550 base::ThreadTaskRunnerHandle::Get()->PostTask( |
| 597 FROM_HERE, base::Bind(&Listener::OnStartTracingComplete, | 551 FROM_HERE, base::Bind(&Listener::OnStartTracingComplete, |
| 598 base::Unretained(listener_), error)); | 552 base::Unretained(listener_), error)); |
| 599 break; | 553 break; |
| 600 case Command::STOP_TRACING: | 554 case Command::STOP_TRACING: |
| 601 base::ThreadTaskRunnerHandle::Get()->PostTask( | 555 base::ThreadTaskRunnerHandle::Get()->PostTask( |
| 602 FROM_HERE, | 556 FROM_HERE, |
| 603 base::Bind(&Listener::OnStopTracingComplete, | 557 base::Bind(&Listener::OnStopTracingComplete, |
| 604 base::Unretained(listener_), SamplesToString(), error)); | 558 base::Unretained(listener_), SamplesToString(), error)); |
| 605 break; | 559 break; |
| 606 case Command::RECORD_CLOCK_SYNC_MARKER: | 560 case Command::RECORD_CLOCK_SYNC_MARKER: |
| 607 base::ThreadTaskRunnerHandle::Get()->PostTask( | 561 base::ThreadTaskRunnerHandle::Get()->PostTask( |
| 608 FROM_HERE, base::Bind(&Listener::OnRecordClockSyncMarkerComplete, | 562 FROM_HERE, base::Bind(&Listener::OnRecordClockSyncMarkerComplete, |
| 609 base::Unretained(listener_), error)); | 563 base::Unretained(listener_), error)); |
| 610 break; | 564 break; |
| 611 case Command::GET_FIRMWARE_GIT_HASH: | 565 case Command::GET_FIRMWARE_GIT_HASH: |
| 612 base::ThreadTaskRunnerHandle::Get()->PostTask( | 566 base::ThreadTaskRunnerHandle::Get()->PostTask( |
| 613 FROM_HERE, base::Bind(&Listener::OnGetFirmwareGitHashComplete, | 567 FROM_HERE, base::Bind(&Listener::OnGetFirmwareGitHashComplete, |
| 614 base::Unretained(listener_), | 568 base::Unretained(listener_), |
| 615 firmware_git_hash_, error)); | 569 firmware_git_hash_, error)); |
| 616 break; | 570 break; |
| 617 case Command::INVALID: | 571 case Command::INVALID: |
| 618 NOTREACHED(); | 572 NOTREACHED(); |
| 573 return; | |
| 619 } | 574 } |
| 620 | 575 |
| 621 last_action_ = Action::INVALID; | 576 last_action_ = Action::INVALID; |
| 622 command_ = Command::INVALID; | 577 command_ = Command::INVALID; |
| 623 pending_clock_sync_marker_.clear(); | 578 pending_clock_sync_marker_.clear(); |
| 624 battor_eeprom_.reset(); | 579 battor_eeprom_.reset(); |
| 625 calibration_frame_.clear(); | 580 calibration_frame_.clear(); |
| 626 samples_.clear(); | 581 samples_.clear(); |
| 627 next_sequence_number_ = 0; | 582 next_sequence_number_ = 0; |
| 583 num_command_attempts_ = 0; | |
| 628 } | 584 } |
| 629 | 585 |
| 630 std::string BattOrAgent::SamplesToString() { | 586 std::string BattOrAgent::SamplesToString() { |
| 631 if (calibration_frame_.empty() || samples_.empty() || !battor_eeprom_) | 587 if (calibration_frame_.empty() || samples_.empty() || !battor_eeprom_) |
| 632 return ""; | 588 return ""; |
| 633 | 589 |
| 634 BattOrSampleConverter converter(*battor_eeprom_, calibration_frame_); | 590 BattOrSampleConverter converter(*battor_eeprom_, calibration_frame_); |
| 635 | 591 |
| 636 std::stringstream trace_stream; | 592 std::stringstream trace_stream; |
| 637 trace_stream << std::fixed; | 593 trace_stream << std::fixed; |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 660 static_cast<uint32_t>(calibration_frame_.size() + i)); | 616 static_cast<uint32_t>(calibration_frame_.size() + i)); |
| 661 if (clock_sync_marker != clock_sync_markers_.end()) | 617 if (clock_sync_marker != clock_sync_markers_.end()) |
| 662 trace_stream << " <" << clock_sync_marker->second << ">"; | 618 trace_stream << " <" << clock_sync_marker->second << ">"; |
| 663 | 619 |
| 664 trace_stream << std::endl; | 620 trace_stream << std::endl; |
| 665 } | 621 } |
| 666 | 622 |
| 667 return trace_stream.str(); | 623 return trace_stream.str(); |
| 668 } | 624 } |
| 669 | 625 |
| 626 void BattOrAgent::SetActionTimeout(uint16_t timeout_seconds) { | |
| 627 timeout_callback_.Reset( | |
| 628 base::Bind(&BattOrAgent::OnActionTimeout, AsWeakPtr())); | |
| 629 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( | |
| 630 FROM_HERE, timeout_callback_.callback(), | |
| 631 base::TimeDelta::FromSeconds(timeout_seconds)); | |
| 632 } | |
| 633 | |
| 670 } // namespace battor | 634 } // namespace battor |
| OLD | NEW |