Chromium Code Reviews| Index: chromeos/dbus/arc_trace_agent.cc |
| diff --git a/chromeos/dbus/arc_trace_agent.cc b/chromeos/dbus/arc_trace_agent.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..863a10b222f985e73cf3205c91279cc112655f47 |
| --- /dev/null |
| +++ b/chromeos/dbus/arc_trace_agent.cc |
| @@ -0,0 +1,145 @@ |
| +// Copyright 2016 The Chromium Authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +#include "chromeos/dbus/arc_trace_agent.h" |
| + |
| +#include <utility> |
| + |
| +#include "base/logging.h" |
| +#include "base/threading/thread_task_runner_handle.h" |
| +#include "chromeos/dbus/dbus_thread_manager.h" |
| +#include "dbus/bus.h" |
| +#include "dbus/message.h" |
| +#include "dbus/object_path.h" |
| +#include "third_party/cros_system_api/dbus/service_constants.h" |
| + |
| +namespace chromeos { |
| + |
| +namespace { |
| + |
| +constexpr char kArcTracingAgentName[] = "arc"; |
| +constexpr char kArcTraceLabel[] = "ArcTraceEvents"; |
| + |
| +} // namespace |
| + |
| +std::string ArcTraceAgent::GetTracingAgentName() { |
| + return kArcTracingAgentName; |
| +} |
| + |
| +std::string ArcTraceAgent::GetTraceEventLabel() { |
| + return kArcTraceLabel; |
| +} |
| + |
| +void ArcTraceAgent::SetArcTraceBridge(ArcTraceAgent::ArcTraceBridge* bridge) { |
| + arc_trace_bridge_ = bridge; |
| +} |
| + |
| +void ArcTraceAgent::StartAgentTracing( |
| + const base::trace_event::TraceConfig& trace_config, |
| + const StartAgentTracingCallback& callback) { |
| + |
| + // arc_trace_brigde_ may be null if ARC is not enabled on the system. In such |
|
Luis Héctor Chávez
2016/12/27 19:15:59
s/arc_trace_brigde_/arc_trace_bridge_/
shunhsingou
2016/12/28 09:15:16
Done.
|
| + // case, simply do nothing. |
| + if (arc_trace_bridge_) { |
| + arc_trace_bridge_->StartTracing(trace_config); |
| + |
| + dbus::MethodCall method_call( |
| + debugd::kDebugdInterface, |
| + "ArcTraceStart"); |
| + debugdaemon_proxy_->CallMethod( |
| + &method_call, |
| + dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, |
| + base::Bind(&ArcTraceAgent::OnStartMethod, |
|
Luis Héctor Chávez
2016/12/27 19:15:59
Shouldn't you run |callback| in OnStartMethod inst
shunhsingou
2016/12/28 09:15:16
Done.
|
| + weak_ptr_factory_.GetWeakPtr())); |
| + } |
| + |
| + base::ThreadTaskRunnerHandle::Get()->PostTask( |
|
Luis Héctor Chávez
2016/12/27 19:15:59
Why can't you just do
callback.Run(GetTracingAgen
shunhsingou
2016/12/28 09:15:16
I forget to change. Move it to OnStartMethod.
|
| + FROM_HERE, |
| + base::Bind(callback, GetTracingAgentName(), true /* success */)); |
| +} |
| + |
| +// Called when a response for a simple start is received. |
| +void ArcTraceAgent::OnStartMethod(dbus::Response* response) { |
|
Luis Héctor Chávez
2016/12/27 19:16:00
This can be a standalone function in the anonymous
shunhsingou
2016/12/28 09:15:16
Moved callback call to here. So this function need
|
| + if (!response) { |
| + LOG(ERROR) << "Failed to request start"; |
| + return; |
| + } |
| +} |
| + |
| +void ArcTraceAgent::StopAgentTracing(const StopAgentTracingCallback& callback) { |
| + DCHECK(stop_agent_tracing_task_runner_); |
| + if (pipe_reader_ != NULL) { |
|
Luis Héctor Chávez
2016/12/27 19:15:59
Maybe it's better to check if |callback_.is_null()
shunhsingou
2016/12/28 09:15:15
Done.
|
| + LOG(ERROR) << "Busy doing StopAgentTracing"; |
| + return; |
| + } |
| + |
| + if (arc_trace_bridge_) { |
|
Luis Héctor Chávez
2016/12/27 19:15:59
if (!arc_trace_bridge_)
return;
// rest of the
shunhsingou
2016/12/28 09:15:16
Done. Just return empty report here.
|
| + arc_trace_bridge_->StopTracing(); |
| + |
| + pipe_reader_.reset( |
|
Luis Héctor Chávez
2016/12/27 19:15:59
nit: pipe_reader_ = base::MakeUnique<PipeReaderFor
shunhsingou
2016/12/28 09:15:16
Done.
|
| + new PipeReaderForString(stop_agent_tracing_task_runner_, |
| + base::Bind(&ArcTraceAgent::OnIOComplete, |
| + weak_ptr_factory_.GetWeakPtr()))); |
| + |
| + base::ScopedFD pipe_write_end = pipe_reader_->StartIO(); |
|
Luis Héctor Chávez
2016/12/27 19:15:59
What thread is this supposed to be run on? Is I/O
shunhsingou
2016/12/28 09:15:15
It's running on 'stop_agent_tracing_task_runner_',
Luis Héctor Chávez
2016/12/28 17:21:58
Can you add comments about which methods run on wh
shunhsingou
2016/12/29 09:40:29
Done.
|
| + DCHECK(pipe_write_end.is_valid()); |
| + // Issue the dbus request to stop system tracing |
| + dbus::MethodCall method_call(debugd::kDebugdInterface, |
| + "ArcTraceStop"); |
| + dbus::MessageWriter writer(&method_call); |
| + writer.AppendFileDescriptor(pipe_write_end.get()); |
| + |
| + callback_ = callback; |
| + |
| + debugdaemon_proxy_->CallMethod( |
| + &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, |
| + base::Bind(&ArcTraceAgent::OnStopAgentTracing, |
| + weak_ptr_factory_.GetWeakPtr())); |
| + } |
| +} |
| + |
| +// Called when pipe i/o completes; pass data on and delete the instance. |
|
Luis Héctor Chávez
2016/12/27 19:16:00
nit: be consistent and use I/O all across the boar
shunhsingou
2016/12/28 09:15:15
Done.
|
| +void ArcTraceAgent::OnIOComplete() { |
| + std::string pipe_data; |
| + pipe_reader_->GetData(&pipe_data); |
| + callback_.Run(GetTracingAgentName(), GetTraceEventLabel(), |
|
Luis Héctor Chávez
2016/12/27 19:15:59
nit: base::ResetAndReturn(&callback_).Run(...);
shunhsingou
2016/12/28 09:15:16
Done.
|
| + base::RefCountedString::TakeString(&pipe_data)); |
| + pipe_reader_.reset(); |
|
Luis Héctor Chávez
2016/12/27 19:16:00
maybe reset the pipe_reader_ before calling the ca
shunhsingou
2016/12/28 09:15:16
Done.
|
| +} |
| + |
| +void ArcTraceAgent::OnStopAgentTracing(dbus::Response* response) { |
| + if (!response) { |
| + LOG(ERROR) << "Failed to request arc stop"; |
| + // If debugd crashes or completes I/O before this message is processed |
| + // then pipe_reader_ can be NULL, see OnIOComplete(). |
| + if (pipe_reader_.get()) |
| + pipe_reader_->OnDataReady(-1); // terminate data stream |
| + } |
| + // NB: requester is signaled when i/o completes |
| +} |
| + |
| +void ArcTraceAgent::SetStopAgentTracingTaskRunner( |
| + scoped_refptr<base::TaskRunner> task_runner) { |
| + stop_agent_tracing_task_runner_ = task_runner; |
|
Luis Héctor Chávez
2016/12/27 19:15:59
alignment. please run `git cl format` and `git cl
shunhsingou
2016/12/28 09:15:16
Done.
|
| +} |
| + |
| +ArcTraceAgent* ArcTraceAgent::Create() { |
|
Luis Héctor Chávez
2016/12/27 19:15:59
nit: // static
shunhsingou
2016/12/28 09:15:16
Done.
|
| + return new ArcTraceAgent(); |
| +} |
| + |
| +void ArcTraceAgent::Init(dbus::Bus* bus) { |
| + debugdaemon_proxy_ = |
| + bus->GetObjectProxy(debugd::kDebugdServiceName, |
| + dbus::ObjectPath(debugd::kDebugdServicePath)); |
| +} |
| + |
| +ArcTraceAgent::ArcTraceAgent() |
| + : arc_trace_bridge_(NULL), |
|
Luis Héctor Chávez
2016/12/27 19:15:59
nit: s/NULL/nullptr/ all across the change.
Also,
shunhsingou
2016/12/28 09:15:16
Done.
|
| + debugdaemon_proxy_(NULL), |
| + weak_ptr_factory_(this) {} |
| + |
| +ArcTraceAgent::~ArcTraceAgent() { |
|
Luis Héctor Chávez
2016/12/27 19:15:59
nit: = default;
shunhsingou
2016/12/28 09:15:16
Done.
|
| +} |
| + |
| +} // namespace chromeos |