This source file includes following definitions.
- EmptyStopSystemTracingCallbackBody
- weak_ptr_factory_
- GetDebugLogs
- SetDebugMode
- GetRoutes
- GetNetworkStatus
- GetModemStatus
- GetWiMaxStatus
- GetNetworkInterfaces
- GetPerfData
- GetScrubbedLogs
- GetAllLogs
- GetUserLogFiles
- StartSystemTracing
- RequestStopSystemTracing
- TestICMP
- TestICMPWithOptions
- UploadCrashes
- Init
- CheckValidity
- OnCheckValidityGetDebugLogs
- OnGetDebugLogs
- OnSetDebugMode
- OnGetRoutes
- OnGetNetworkStatus
- OnGetModemStatus
- OnGetWiMaxStatus
- OnGetNetworkInterfaces
- OnGetPerfData
- OnGetAllLogs
- OnGetUserLogFiles
- OnStartMethod
- OnCheckValidityRequestStopSystem
- OnRequestStopSystemTracing
- OnTestICMP
- OnIOComplete
- EmptyStopSystemTracingCallback
- Create
#include "chromeos/dbus/debug_daemon_client.h"
#include <fcntl.h>
#include <unistd.h>
#include <string>
#include <vector>
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/callback.h"
#include "base/location.h"
#include "base/memory/ref_counted_memory.h"
#include "base/message_loop/message_loop.h"
#include "base/platform_file.h"
#include "base/posix/eintr_wrapper.h"
#include "base/strings/string_util.h"
#include "base/threading/worker_pool.h"
#include "chromeos/dbus/pipe_reader.h"
#include "dbus/bus.h"
#include "dbus/message.h"
#include "dbus/object_path.h"
#include "dbus/object_proxy.h"
#include "third_party/cros_system_api/dbus/service_constants.h"
namespace {
void EmptyStopSystemTracingCallbackBody(
const scoped_refptr<base::RefCountedString>& unused_result) {
}
}
namespace chromeos {
class DebugDaemonClientImpl : public DebugDaemonClient {
public:
DebugDaemonClientImpl() : debugdaemon_proxy_(NULL), weak_ptr_factory_(this) {}
virtual ~DebugDaemonClientImpl() {}
virtual void GetDebugLogs(base::PlatformFile file,
const GetDebugLogsCallback& callback) OVERRIDE {
dbus::FileDescriptor* file_descriptor = new dbus::FileDescriptor(file);
base::WorkerPool::PostTaskAndReply(
FROM_HERE,
base::Bind(&DebugDaemonClientImpl::CheckValidity,
file_descriptor),
base::Bind(&DebugDaemonClientImpl::OnCheckValidityGetDebugLogs,
weak_ptr_factory_.GetWeakPtr(),
base::Owned(file_descriptor),
callback),
false);
}
virtual void SetDebugMode(const std::string& subsystem,
const SetDebugModeCallback& callback) OVERRIDE {
dbus::MethodCall method_call(debugd::kDebugdInterface,
debugd::kSetDebugMode);
dbus::MessageWriter writer(&method_call);
writer.AppendString(subsystem);
debugdaemon_proxy_->CallMethod(
&method_call,
dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
base::Bind(&DebugDaemonClientImpl::OnSetDebugMode,
weak_ptr_factory_.GetWeakPtr(),
callback));
}
virtual void GetRoutes(bool numeric, bool ipv6,
const GetRoutesCallback& callback) OVERRIDE {
dbus::MethodCall method_call(debugd::kDebugdInterface,
debugd::kGetRoutes);
dbus::MessageWriter writer(&method_call);
dbus::MessageWriter sub_writer(NULL);
writer.OpenArray("{sv}", &sub_writer);
dbus::MessageWriter elem_writer(NULL);
sub_writer.OpenDictEntry(&elem_writer);
elem_writer.AppendString("numeric");
elem_writer.AppendVariantOfBool(numeric);
sub_writer.CloseContainer(&elem_writer);
sub_writer.OpenDictEntry(&elem_writer);
elem_writer.AppendString("v6");
elem_writer.AppendVariantOfBool(ipv6);
sub_writer.CloseContainer(&elem_writer);
writer.CloseContainer(&sub_writer);
debugdaemon_proxy_->CallMethod(
&method_call,
dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
base::Bind(&DebugDaemonClientImpl::OnGetRoutes,
weak_ptr_factory_.GetWeakPtr(),
callback));
}
virtual void GetNetworkStatus(const GetNetworkStatusCallback& callback)
OVERRIDE {
dbus::MethodCall method_call(debugd::kDebugdInterface,
debugd::kGetNetworkStatus);
debugdaemon_proxy_->CallMethod(
&method_call,
dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
base::Bind(&DebugDaemonClientImpl::OnGetNetworkStatus,
weak_ptr_factory_.GetWeakPtr(),
callback));
}
virtual void GetModemStatus(const GetModemStatusCallback& callback)
OVERRIDE {
dbus::MethodCall method_call(debugd::kDebugdInterface,
debugd::kGetModemStatus);
debugdaemon_proxy_->CallMethod(
&method_call,
dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
base::Bind(&DebugDaemonClientImpl::OnGetModemStatus,
weak_ptr_factory_.GetWeakPtr(),
callback));
}
virtual void GetWiMaxStatus(const GetWiMaxStatusCallback& callback)
OVERRIDE {
dbus::MethodCall method_call(debugd::kDebugdInterface,
debugd::kGetWiMaxStatus);
debugdaemon_proxy_->CallMethod(
&method_call,
dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
base::Bind(&DebugDaemonClientImpl::OnGetWiMaxStatus,
weak_ptr_factory_.GetWeakPtr(),
callback));
}
virtual void GetNetworkInterfaces(
const GetNetworkInterfacesCallback& callback) OVERRIDE {
dbus::MethodCall method_call(debugd::kDebugdInterface,
debugd::kGetInterfaces);
debugdaemon_proxy_->CallMethod(
&method_call,
dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
base::Bind(&DebugDaemonClientImpl::OnGetNetworkInterfaces,
weak_ptr_factory_.GetWeakPtr(),
callback));
}
virtual void GetPerfData(uint32_t duration,
const GetPerfDataCallback& callback) OVERRIDE {
dbus::MethodCall method_call(debugd::kDebugdInterface,
debugd::kGetRichPerfData);
dbus::MessageWriter writer(&method_call);
writer.AppendUint32(duration);
debugdaemon_proxy_->CallMethod(
&method_call,
dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
base::Bind(&DebugDaemonClientImpl::OnGetPerfData,
weak_ptr_factory_.GetWeakPtr(),
callback));
}
virtual void GetScrubbedLogs(const GetLogsCallback& callback) OVERRIDE {
dbus::MethodCall method_call(debugd::kDebugdInterface,
debugd::kGetFeedbackLogs);
debugdaemon_proxy_->CallMethod(
&method_call,
dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
base::Bind(&DebugDaemonClientImpl::OnGetAllLogs,
weak_ptr_factory_.GetWeakPtr(),
callback));
}
virtual void GetAllLogs(const GetLogsCallback& callback)
OVERRIDE {
dbus::MethodCall method_call(debugd::kDebugdInterface,
debugd::kGetAllLogs);
debugdaemon_proxy_->CallMethod(
&method_call,
dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
base::Bind(&DebugDaemonClientImpl::OnGetAllLogs,
weak_ptr_factory_.GetWeakPtr(),
callback));
}
virtual void GetUserLogFiles(
const GetLogsCallback& callback) OVERRIDE {
dbus::MethodCall method_call(debugd::kDebugdInterface,
debugd::kGetUserLogFiles);
debugdaemon_proxy_->CallMethod(
&method_call,
dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
base::Bind(&DebugDaemonClientImpl::OnGetUserLogFiles,
weak_ptr_factory_.GetWeakPtr(),
callback));
}
virtual void StartSystemTracing() OVERRIDE {
dbus::MethodCall method_call(
debugd::kDebugdInterface,
debugd::kSystraceStart);
dbus::MessageWriter writer(&method_call);
writer.AppendString("all");
DVLOG(1) << "Requesting a systrace start";
debugdaemon_proxy_->CallMethod(
&method_call,
dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
base::Bind(&DebugDaemonClientImpl::OnStartMethod,
weak_ptr_factory_.GetWeakPtr()));
}
virtual bool RequestStopSystemTracing(const StopSystemTracingCallback&
callback) OVERRIDE {
if (pipe_reader_ != NULL) {
LOG(ERROR) << "Busy doing StopSystemTracing";
return false;
}
pipe_reader_.reset(new PipeReaderForString(
base::Bind(&DebugDaemonClientImpl::OnIOComplete,
weak_ptr_factory_.GetWeakPtr())));
int write_fd = -1;
if (!pipe_reader_->StartIO()) {
LOG(ERROR) << "Cannot create pipe reader";
write_fd = HANDLE_EINTR(open("/dev/null", O_WRONLY));
} else {
write_fd = pipe_reader_->write_fd();
}
dbus::FileDescriptor* file_descriptor = new dbus::FileDescriptor(write_fd);
base::WorkerPool::PostTaskAndReply(
FROM_HERE,
base::Bind(&DebugDaemonClientImpl::CheckValidity,
file_descriptor),
base::Bind(&DebugDaemonClientImpl::OnCheckValidityRequestStopSystem,
weak_ptr_factory_.GetWeakPtr(),
base::Owned(file_descriptor),
callback),
false);
return true;
}
virtual void TestICMP(const std::string& ip_address,
const TestICMPCallback& callback) OVERRIDE {
dbus::MethodCall method_call(debugd::kDebugdInterface,
debugd::kTestICMP);
dbus::MessageWriter writer(&method_call);
writer.AppendString(ip_address);
debugdaemon_proxy_->CallMethod(
&method_call,
dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
base::Bind(&DebugDaemonClientImpl::OnTestICMP,
weak_ptr_factory_.GetWeakPtr(),
callback));
}
virtual void TestICMPWithOptions(
const std::string& ip_address,
const std::map<std::string, std::string>& options,
const TestICMPCallback& callback) OVERRIDE {
dbus::MethodCall method_call(debugd::kDebugdInterface,
debugd::kTestICMPWithOptions);
dbus::MessageWriter writer(&method_call);
dbus::MessageWriter sub_writer(NULL);
dbus::MessageWriter elem_writer(NULL);
writer.AppendString(ip_address);
writer.OpenArray("{ss}", &sub_writer);
std::map<std::string, std::string>::const_iterator it;
for (it = options.begin(); it != options.end(); ++it) {
sub_writer.OpenDictEntry(&elem_writer);
elem_writer.AppendString(it->first);
elem_writer.AppendString(it->second);
sub_writer.CloseContainer(&elem_writer);
}
writer.CloseContainer(&sub_writer);
debugdaemon_proxy_->CallMethod(
&method_call,
dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
base::Bind(&DebugDaemonClientImpl::OnTestICMP,
weak_ptr_factory_.GetWeakPtr(),
callback));
}
virtual void UploadCrashes() OVERRIDE {
dbus::MethodCall method_call(debugd::kDebugdInterface,
debugd::kUploadCrashes);
debugdaemon_proxy_->CallMethod(
&method_call,
dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
base::Bind(&DebugDaemonClientImpl::OnStartMethod,
weak_ptr_factory_.GetWeakPtr()));
}
protected:
virtual void Init(dbus::Bus* bus) OVERRIDE {
debugdaemon_proxy_ =
bus->GetObjectProxy(debugd::kDebugdServiceName,
dbus::ObjectPath(debugd::kDebugdServicePath));
}
private:
static void CheckValidity(dbus::FileDescriptor* file_descriptor) {
file_descriptor->CheckValidity();
}
void OnCheckValidityGetDebugLogs(dbus::FileDescriptor* file_descriptor,
const GetDebugLogsCallback& callback) {
dbus::MethodCall method_call(
debugd::kDebugdInterface,
debugd::kGetDebugLogs);
dbus::MessageWriter writer(&method_call);
writer.AppendFileDescriptor(*file_descriptor);
debugdaemon_proxy_->CallMethod(
&method_call,
dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
base::Bind(&DebugDaemonClientImpl::OnGetDebugLogs,
weak_ptr_factory_.GetWeakPtr(),
callback));
}
void OnGetDebugLogs(const GetDebugLogsCallback& callback,
dbus::Response* response) {
if (!response) {
LOG(ERROR) << "Failed to get debug logs";
callback.Run(false);
return;
}
callback.Run(true);
}
void OnSetDebugMode(const SetDebugModeCallback& callback,
dbus::Response* response) {
if (!response) {
LOG(ERROR) << "Failed to change debug mode";
callback.Run(false);
} else {
callback.Run(true);
}
}
void OnGetRoutes(const GetRoutesCallback& callback,
dbus::Response* response) {
std::vector<std::string> routes;
if (response) {
dbus::MessageReader reader(response);
if (reader.PopArrayOfStrings(&routes)) {
callback.Run(true, routes);
} else {
LOG(ERROR) << "Got non-array response from GetRoutes";
callback.Run(false, routes);
}
} else {
callback.Run(false, routes);
}
}
void OnGetNetworkStatus(const GetNetworkStatusCallback& callback,
dbus::Response* response) {
std::string status;
if (response && dbus::MessageReader(response).PopString(&status))
callback.Run(true, status);
else
callback.Run(false, "");
}
void OnGetModemStatus(const GetModemStatusCallback& callback,
dbus::Response* response) {
std::string status;
if (response && dbus::MessageReader(response).PopString(&status))
callback.Run(true, status);
else
callback.Run(false, "");
}
void OnGetWiMaxStatus(const GetWiMaxStatusCallback& callback,
dbus::Response* response) {
std::string status;
if (response && dbus::MessageReader(response).PopString(&status))
callback.Run(true, status);
else
callback.Run(false, "");
}
void OnGetNetworkInterfaces(const GetNetworkInterfacesCallback& callback,
dbus::Response* response) {
std::string status;
if (response && dbus::MessageReader(response).PopString(&status))
callback.Run(true, status);
else
callback.Run(false, "");
}
void OnGetPerfData(const GetPerfDataCallback& callback,
dbus::Response* response) {
std::vector<uint8> data;
if (!response) {
return;
}
dbus::MessageReader reader(response);
const uint8* buffer = NULL;
size_t buf_size = 0;
if (!reader.PopArrayOfBytes(&buffer, &buf_size))
return;
data.insert(data.end(), buffer, buffer + buf_size);
callback.Run(data);
}
void OnGetAllLogs(const GetLogsCallback& callback,
dbus::Response* response) {
std::map<std::string, std::string> logs;
bool broken = false;
dbus::MessageReader sub_reader(NULL);
if (!response || !dbus::MessageReader(response).PopArray(&sub_reader)) {
callback.Run(false, logs);
return;
}
while (sub_reader.HasMoreData()) {
dbus::MessageReader sub_sub_reader(NULL);
std::string key, value;
if (!sub_reader.PopDictEntry(&sub_sub_reader)
|| !sub_sub_reader.PopString(&key)
|| !sub_sub_reader.PopString(&value)) {
broken = true;
break;
}
logs[key] = value;
}
callback.Run(!sub_reader.HasMoreData() && !broken, logs);
}
void OnGetUserLogFiles(const GetLogsCallback& callback,
dbus::Response* response) {
return OnGetAllLogs(callback, response);
}
void OnStartMethod(dbus::Response* response) {
if (!response) {
LOG(ERROR) << "Failed to request start";
return;
}
}
void OnCheckValidityRequestStopSystem(
dbus::FileDescriptor* file_descriptor,
const StopSystemTracingCallback& callback) {
dbus::MethodCall method_call(
debugd::kDebugdInterface,
debugd::kSystraceStop);
dbus::MessageWriter writer(&method_call);
writer.AppendFileDescriptor(*file_descriptor);
callback_ = callback;
DVLOG(1) << "Requesting a systrace stop";
debugdaemon_proxy_->CallMethod(
&method_call,
dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
base::Bind(&DebugDaemonClientImpl::OnRequestStopSystemTracing,
weak_ptr_factory_.GetWeakPtr()));
pipe_reader_->CloseWriteFD();
}
void OnRequestStopSystemTracing(dbus::Response* response) {
if (!response) {
LOG(ERROR) << "Failed to request systrace stop";
if (pipe_reader_.get())
pipe_reader_->OnDataReady(-1);
}
}
void OnTestICMP(const TestICMPCallback& callback, dbus::Response* response) {
std::string status;
if (response && dbus::MessageReader(response).PopString(&status))
callback.Run(true, status);
else
callback.Run(false, "");
}
void OnIOComplete() {
std::string pipe_data;
pipe_reader_->GetData(&pipe_data);
callback_.Run(base::RefCountedString::TakeString(&pipe_data));
pipe_reader_.reset();
}
dbus::ObjectProxy* debugdaemon_proxy_;
scoped_ptr<PipeReaderForString> pipe_reader_;
StopSystemTracingCallback callback_;
base::WeakPtrFactory<DebugDaemonClientImpl> weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(DebugDaemonClientImpl);
};
DebugDaemonClient::DebugDaemonClient() {
}
DebugDaemonClient::~DebugDaemonClient() {
}
DebugDaemonClient::StopSystemTracingCallback
DebugDaemonClient::EmptyStopSystemTracingCallback() {
return base::Bind(&EmptyStopSystemTracingCallbackBody);
}
DebugDaemonClient* DebugDaemonClient::Create() {
return new DebugDaemonClientImpl();
}
}