blob: 9e498e6df8e918358ed42e393500eac9e30eef61 [file] [log] [blame]
// Copyright 2018 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 "shill/dbus/dbus_properties_proxy.h"
#include <utility>
#include <base/memory/ptr_util.h>
#include "shill/dbus/fake_properties_proxy.h"
#include "shill/logging.h"
namespace shill {
using std::string;
using std::vector;
namespace Logging {
static auto kModuleLogScope = ScopeLogger::kDBus;
static string ObjectID(const dbus::ObjectPath* p) {
return p->value();
}
} // namespace Logging
namespace {
void RunSuccessCallback(
const base::Callback<void(const KeyValueStore&)>& success_callback,
const brillo::VariantDictionary& properties) {
success_callback.Run(KeyValueStore::ConvertFromVariantDictionary(properties));
}
void RunErrorCallback(const base::Callback<void(const Error&)>& error_callback,
brillo::Error* dbus_error) {
error_callback.Run(Error(Error::kOperationFailed, dbus_error->GetMessage()));
}
} // namespace
DBusPropertiesProxy::DBusPropertiesProxy(const scoped_refptr<dbus::Bus>& bus,
const RpcIdentifier& path,
const string& service)
: proxy_(new org::freedesktop::DBus::PropertiesProxy(
bus, service, dbus::ObjectPath(path))) {}
DBusPropertiesProxy::~DBusPropertiesProxy() = default;
// Test only private constructor.
DBusPropertiesProxy::DBusPropertiesProxy(
std::unique_ptr<org::freedesktop::DBus::PropertiesProxyInterface> proxy)
: proxy_(std::move(proxy)) {}
// static
std::unique_ptr<DBusPropertiesProxy>
DBusPropertiesProxy::CreateDBusPropertiesProxyForTesting() {
// Use WrapUnique to allow test constructor to be private.
return base::WrapUnique(
new DBusPropertiesProxy(std::make_unique<FakePropertiesProxy>()));
}
FakePropertiesProxy* DBusPropertiesProxy::GetFakePropertiesProxyForTesting() {
return static_cast<FakePropertiesProxy*>(proxy_.get());
}
KeyValueStore DBusPropertiesProxy::GetAll(const string& interface_name) {
SLOG(&proxy_->GetObjectPath(), 2) << __func__ << "(" << interface_name << ")";
brillo::VariantDictionary properties_dict;
brillo::ErrorPtr error;
if (!proxy_->GetAll(interface_name, &properties_dict, &error)) {
LOG(ERROR) << __func__ << " failed on " << interface_name << ": "
<< error->GetCode() << " " << error->GetMessage();
return KeyValueStore();
}
KeyValueStore properties_store =
KeyValueStore::ConvertFromVariantDictionary(properties_dict);
return properties_store;
}
void DBusPropertiesProxy::GetAllAsync(
const std::string& interface_name,
const base::Callback<void(const KeyValueStore&)>& success_callback,
const base::Callback<void(const Error&)>& error_callback) {
SLOG(&proxy_->GetObjectPath(), 2) << __func__ << "(" << interface_name << ")";
proxy_->GetAllAsync(interface_name,
base::Bind(RunSuccessCallback, success_callback),
base::Bind(RunErrorCallback, error_callback));
}
brillo::Any DBusPropertiesProxy::Get(const string& interface_name,
const string& property) {
SLOG(&proxy_->GetObjectPath(), 2)
<< __func__ << "(" << interface_name << ", " << property << ")";
brillo::Any value;
brillo::ErrorPtr error;
if (!proxy_->Get(interface_name, property, &value, &error)) {
LOG(ERROR) << __func__ << " failed for " << interface_name << " "
<< property << ": " << error->GetCode() << " "
<< error->GetMessage();
}
return value;
}
void DBusPropertiesProxy::GetAsync(
const std::string& interface_name,
const std::string& property,
const base::Callback<void(const brillo::Any&)>& success_callback,
const base::Callback<void(const Error&)>& error_callback) {
SLOG(&proxy_->GetObjectPath(), 2)
<< __func__ << "(" << interface_name << ", " << property << ")";
proxy_->GetAsync(interface_name, property, success_callback,
base::Bind(RunErrorCallback, error_callback));
}
void DBusPropertiesProxy::SetPropertiesChangedCallback(
const PropertiesChangedCallback& callback) {
CHECK(properties_changed_callback_.is_null());
properties_changed_callback_ = callback;
proxy_->RegisterPropertiesChangedSignalHandler(
base::Bind(&DBusPropertiesProxy::PropertiesChanged,
weak_factory_.GetWeakPtr()),
base::Bind(&DBusPropertiesProxy::OnSignalConnected,
weak_factory_.GetWeakPtr()));
}
void DBusPropertiesProxy::SetModemManagerPropertiesChangedCallback(
const ModemManagerPropertiesChangedCallback& callback) {
CHECK(mm_properties_changed_callback_.is_null());
mm_properties_changed_callback_ = callback;
proxy_->RegisterMmPropertiesChangedSignalHandler(
base::Bind(&DBusPropertiesProxy::MmPropertiesChanged,
weak_factory_.GetWeakPtr()),
base::Bind(&DBusPropertiesProxy::OnSignalConnected,
weak_factory_.GetWeakPtr()));
}
void DBusPropertiesProxy::MmPropertiesChanged(
const string& interface, const brillo::VariantDictionary& properties) {
SLOG(&proxy_->GetObjectPath(), 2) << __func__ << "(" << interface << ")";
KeyValueStore properties_store =
KeyValueStore::ConvertFromVariantDictionary(properties);
mm_properties_changed_callback_.Run(interface, properties_store);
}
void DBusPropertiesProxy::PropertiesChanged(
const string& interface,
const brillo::VariantDictionary& changed_properties,
const vector<string>& /*invalidated_properties*/) {
SLOG(&proxy_->GetObjectPath(), 2) << __func__ << "(" << interface << ")";
KeyValueStore properties_store =
KeyValueStore::ConvertFromVariantDictionary(changed_properties);
properties_changed_callback_.Run(interface, properties_store);
}
void DBusPropertiesProxy::OnSignalConnected(const string& interface_name,
const string& signal_name,
bool success) {
SLOG(&proxy_->GetObjectPath(), 2)
<< __func__ << "interface: " << interface_name
<< " signal: " << signal_name << "success: " << success;
if (!success) {
LOG(ERROR) << "Failed to connect signal " << signal_name << " to interface "
<< interface_name;
}
}
} // namespace shill