blob: c8a02524963ce4fd4de6dd9ab4b296fe3dd6a9cc [file] [log] [blame]
// Copyright 2017 The Chromium OS 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 "debugd/src/helpers/system_service_proxy.h"
#include <base/memory/ptr_util.h>
#include <dbus/values_util.h>
namespace debugd {
namespace {
const char kDBusPropertiesInterface[] = "org.freedesktop.DBus.Properties";
const char kDBusPropertiesGetAllMethod[] = "GetAll";
} // namespace
// static
std::unique_ptr<SystemServiceProxy> SystemServiceProxy::Create(
const std::string& service_name) {
scoped_refptr<dbus::Bus> bus = ConnectToSystemBus();
if (!bus)
return nullptr;
return std::unique_ptr<SystemServiceProxy>(
new SystemServiceProxy(bus, service_name));
}
SystemServiceProxy::SystemServiceProxy(scoped_refptr<dbus::Bus> bus,
const std::string& service_name)
: bus_(bus), service_name_(service_name) {}
// static
scoped_refptr<dbus::Bus> SystemServiceProxy::ConnectToSystemBus() {
dbus::Bus::Options options;
options.bus_type = dbus::Bus::SYSTEM;
scoped_refptr<dbus::Bus> bus(new dbus::Bus(options));
if (!bus->Connect())
return nullptr;
return bus;
}
std::unique_ptr<base::Value> SystemServiceProxy::CallMethodAndGetResponse(
const dbus::ObjectPath& object_path, dbus::MethodCall* method_call) {
dbus::ObjectProxy* object_proxy =
bus_->GetObjectProxy(service_name_, object_path);
std::unique_ptr<dbus::Response> response = object_proxy->CallMethodAndBlock(
method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT);
if (!response)
return nullptr;
dbus::MessageReader reader(response.get());
// TODO(benchan): Remove base::WrapUnique() once dbus::PopDataAsValue()
// returns std::unique_ptr<base::Value> instead of base::Value* when we
// update libchrome to a new revision.
return base::WrapUnique(dbus::PopDataAsValue(&reader));
}
std::unique_ptr<base::DictionaryValue> SystemServiceProxy::GetProperties(
const std::string& interface_name, const dbus::ObjectPath& object_path) {
dbus::MethodCall method_call(kDBusPropertiesInterface,
kDBusPropertiesGetAllMethod);
dbus::MessageWriter writer(&method_call);
writer.AppendString(interface_name);
return base::DictionaryValue::From(
CallMethodAndGetResponse(object_path, &method_call));
}
std::unique_ptr<base::DictionaryValue>
SystemServiceProxy::BuildObjectPropertiesMap(
const std::string& interface_name,
const std::vector<dbus::ObjectPath>& object_paths) {
auto result = std::make_unique<base::DictionaryValue>();
for (const auto& object_path : object_paths) {
result->SetWithoutPathExpansion(object_path.value(),
GetProperties(interface_name, object_path));
}
return result;
}
// static
std::vector<dbus::ObjectPath> SystemServiceProxy::GetObjectPaths(
const base::DictionaryValue& properties, const std::string& property_name) {
std::vector<dbus::ObjectPath> object_paths;
const base::ListValue* paths = nullptr;
if (properties.GetList(property_name, &paths)) {
for (size_t i = 0; i < paths->GetSize(); ++i) {
std::string path;
if (paths->GetString(i, &path)) {
object_paths.emplace_back(path);
}
}
}
return object_paths;
}
} // namespace debugd