Commit 32d25453 authored by dtapuska's avatar dtapuska Committed by Commit bot

Enhance the DBus interface for peerd

Add ability to query properties of
 - Manager
 - Peer
 - Service
Add Observer to peerd so we are told when things change.

BUG=453873

Review URL: https://codereview.chromium.org/893663002

Cr-Commit-Position: refs/heads/master@{#315311}
parent b2e3ecec
...@@ -15,6 +15,32 @@ FakePeerDaemonManagerClient::~FakePeerDaemonManagerClient() { ...@@ -15,6 +15,32 @@ FakePeerDaemonManagerClient::~FakePeerDaemonManagerClient() {
void FakePeerDaemonManagerClient::Init(dbus::Bus* bus) { void FakePeerDaemonManagerClient::Init(dbus::Bus* bus) {
} }
void FakePeerDaemonManagerClient::AddObserver(Observer* observer) {
}
void FakePeerDaemonManagerClient::RemoveObserver(Observer* observer) {
}
std::vector<dbus::ObjectPath> FakePeerDaemonManagerClient::GetPeers() {
return std::vector<dbus::ObjectPath>();
}
std::vector<dbus::ObjectPath> FakePeerDaemonManagerClient::GetServices() {
return std::vector<dbus::ObjectPath>();
}
PeerDaemonManagerClient::PeerProperties*
FakePeerDaemonManagerClient::GetPeerProperties(
const dbus::ObjectPath& object_path) {
return nullptr;
}
PeerDaemonManagerClient::ServiceProperties*
FakePeerDaemonManagerClient::GetServiceProperties(
const dbus::ObjectPath& object_path) {
return nullptr;
}
void FakePeerDaemonManagerClient::StartMonitoring( void FakePeerDaemonManagerClient::StartMonitoring(
const std::vector<std::string>& requested_technologies, const std::vector<std::string>& requested_technologies,
const base::DictionaryValue& options, const base::DictionaryValue& options,
......
...@@ -24,6 +24,14 @@ class FakePeerDaemonManagerClient : public PeerDaemonManagerClient { ...@@ -24,6 +24,14 @@ class FakePeerDaemonManagerClient : public PeerDaemonManagerClient {
void Init(dbus::Bus* bus) override; void Init(dbus::Bus* bus) override;
// PeerDaemonManagerClient overrides: // PeerDaemonManagerClient overrides:
void AddObserver(Observer* observer) override;
void RemoveObserver(Observer* observer) override;
std::vector<dbus::ObjectPath> GetPeers() override;
std::vector<dbus::ObjectPath> GetServices() override;
PeerProperties* GetPeerProperties(
const dbus::ObjectPath& object_path) override;
ServiceProperties* GetServiceProperties(
const dbus::ObjectPath& object_path) override;
void StartMonitoring(const std::vector<std::string>& requested_technologies, void StartMonitoring(const std::vector<std::string>& requested_technologies,
const base::DictionaryValue& options, const base::DictionaryValue& options,
const StringDBusMethodCallback& callback) override; const StringDBusMethodCallback& callback) override;
......
...@@ -8,8 +8,11 @@ ...@@ -8,8 +8,11 @@
#include "base/callback.h" #include "base/callback.h"
#include "base/logging.h" #include "base/logging.h"
#include "base/memory/weak_ptr.h" #include "base/memory/weak_ptr.h"
#include "base/message_loop/message_loop.h"
#include "base/observer_list.h"
#include "dbus/bus.h" #include "dbus/bus.h"
#include "dbus/message.h" #include "dbus/message.h"
#include "dbus/object_manager.h"
#include "dbus/object_proxy.h" #include "dbus/object_proxy.h"
#include "dbus/values_util.h" #include "dbus/values_util.h"
...@@ -19,8 +22,11 @@ namespace { ...@@ -19,8 +22,11 @@ namespace {
// TODO(benchan): Move these constants to system_api. // TODO(benchan): Move these constants to system_api.
namespace peerd { namespace peerd {
const char kPeerdServiceName[] = "org.chromium.peerd"; const char kPeerdServiceName[] = "org.chromium.peerd";
const char kPeerdObjectManagerServicePath[] = "/org/chromium/peerd";
const char kPeerdManagerPath[] = "/org/chromium/peerd/Manager"; const char kPeerdManagerPath[] = "/org/chromium/peerd/Manager";
const char kManagerInterface[] = "org.chromium.peerd.Manager"; const char kManagerInterface[] = "org.chromium.peerd.Manager";
const char kServiceInterface[] = "org.chromium.peerd.Service";
const char kPeerInterface[] = "org.chromium.peerd.Peer";
const char kStartMonitoringMethod[] = "StartMonitoring"; const char kStartMonitoringMethod[] = "StartMonitoring";
const char kStopMonitoringMethod[] = "StopMonitoring"; const char kStopMonitoringMethod[] = "StopMonitoring";
const char kExposeServiceMethod[] = "ExposeService"; const char kExposeServiceMethod[] = "ExposeService";
...@@ -29,15 +35,24 @@ const char kPingMethod[] = "Ping"; ...@@ -29,15 +35,24 @@ const char kPingMethod[] = "Ping";
} // namespace peerd } // namespace peerd
// The PeerDaemonManagerClient implementation used in production. // The PeerDaemonManagerClient implementation used in production.
class PeerDaemonManagerClientImpl : public PeerDaemonManagerClient { class PeerDaemonManagerClientImpl : public PeerDaemonManagerClient,
public dbus::ObjectManager::Interface {
public: public:
PeerDaemonManagerClientImpl(); PeerDaemonManagerClientImpl();
~PeerDaemonManagerClientImpl() override; ~PeerDaemonManagerClientImpl() override;
// DBusClient overrides: // DBusClient overrides.
void Init(dbus::Bus* bus) override; void Init(dbus::Bus* bus) override;
// PeerDaemonManagerClient overrides: // PeerDaemonManagerClient overrides.
void AddObserver(Observer* observer) override;
void RemoveObserver(Observer* observer) override;
std::vector<dbus::ObjectPath> GetServices() override;
std::vector<dbus::ObjectPath> GetPeers() override;
ServiceProperties* GetServiceProperties(
const dbus::ObjectPath& object_path) override;
PeerProperties* GetPeerProperties(
const dbus::ObjectPath& object_path) override;
void StartMonitoring( void StartMonitoring(
const std::vector<std::string>& requested_technologies, const std::vector<std::string>& requested_technologies,
const base::DictionaryValue& options, const base::DictionaryValue& options,
...@@ -53,55 +68,126 @@ class PeerDaemonManagerClientImpl : public PeerDaemonManagerClient { ...@@ -53,55 +68,126 @@ class PeerDaemonManagerClientImpl : public PeerDaemonManagerClient {
const VoidDBusMethodCallback& callback) override; const VoidDBusMethodCallback& callback) override;
void Ping(const StringDBusMethodCallback& callback) override; void Ping(const StringDBusMethodCallback& callback) override;
// dbus::ObjectManager::Interface overrides.
dbus::PropertySet* CreateProperties(
dbus::ObjectProxy* object_proxy,
const dbus::ObjectPath& object_path,
const std::string& interface_name) override;
void ObjectAdded(const dbus::ObjectPath& object_path,
const std::string& interface_name) override;
void ObjectRemoved(const dbus::ObjectPath& object_path,
const std::string& interface_name) override;
private: private:
void OnStringDBusMethod(const StringDBusMethodCallback& callback, void OnStringDBusMethod(const StringDBusMethodCallback& callback,
dbus::Response* response); dbus::Response* response);
void OnVoidDBusMethod(const VoidDBusMethodCallback& callback, void OnVoidDBusMethod(const VoidDBusMethodCallback& callback,
dbus::Response* response); dbus::Response* response);
void OnManagerPropertyChanged(const std::string& property_name);
void OnServicePropertyChanged(const dbus::ObjectPath& object_path,
const std::string& property_name);
void OnPeerPropertyChanged(const dbus::ObjectPath& object_path,
const std::string& property_name);
// List of observers interested in event notifications from us.
ObserverList<Observer> observers_;
dbus::ObjectManager* object_manager_;
dbus::ObjectProxy* peer_daemon_proxy_;
base::WeakPtrFactory<PeerDaemonManagerClientImpl> weak_ptr_factory_; base::WeakPtrFactory<PeerDaemonManagerClientImpl> weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(PeerDaemonManagerClientImpl); DISALLOW_COPY_AND_ASSIGN(PeerDaemonManagerClientImpl);
}; };
PeerDaemonManagerClientImpl::PeerDaemonManagerClientImpl() PeerDaemonManagerClientImpl::PeerDaemonManagerClientImpl()
: peer_daemon_proxy_(nullptr), weak_ptr_factory_(this) { : object_manager_(nullptr), weak_ptr_factory_(this) {
} }
PeerDaemonManagerClientImpl::~PeerDaemonManagerClientImpl() { PeerDaemonManagerClientImpl::~PeerDaemonManagerClientImpl() {
if (object_manager_) {
object_manager_->UnregisterInterface(peerd::kManagerInterface);
object_manager_->UnregisterInterface(peerd::kServiceInterface);
object_manager_->UnregisterInterface(peerd::kPeerInterface);
}
}
void PeerDaemonManagerClientImpl::AddObserver(Observer* observer) {
DCHECK(observer);
observers_.AddObserver(observer);
}
void PeerDaemonManagerClientImpl::RemoveObserver(Observer* observer) {
DCHECK(observer);
observers_.RemoveObserver(observer);
}
std::vector<dbus::ObjectPath> PeerDaemonManagerClientImpl::GetServices() {
return object_manager_->GetObjectsWithInterface(peerd::kServiceInterface);
}
std::vector<dbus::ObjectPath> PeerDaemonManagerClientImpl::GetPeers() {
return object_manager_->GetObjectsWithInterface(peerd::kPeerInterface);
}
PeerDaemonManagerClient::ServiceProperties*
PeerDaemonManagerClientImpl::GetServiceProperties(
const dbus::ObjectPath& object_path) {
return static_cast<ServiceProperties*>(
object_manager_->GetProperties(object_path, peerd::kServiceInterface));
}
PeerDaemonManagerClient::PeerProperties*
PeerDaemonManagerClientImpl::GetPeerProperties(
const dbus::ObjectPath& object_path) {
return static_cast<PeerProperties*>(
object_manager_->GetProperties(object_path, peerd::kPeerInterface));
} }
void PeerDaemonManagerClientImpl::StartMonitoring( void PeerDaemonManagerClientImpl::StartMonitoring(
const std::vector<std::string>& requested_technologies, const std::vector<std::string>& requested_technologies,
const base::DictionaryValue& options, const base::DictionaryValue& options,
const StringDBusMethodCallback& callback) { const StringDBusMethodCallback& callback) {
dbus::ObjectProxy* object_proxy = object_manager_->GetObjectProxy(
dbus::ObjectPath(peerd::kPeerdManagerPath));
if (!object_proxy) {
base::MessageLoop::current()->PostTask(
FROM_HERE,
base::Bind(&PeerDaemonManagerClientImpl::OnStringDBusMethod,
weak_ptr_factory_.GetWeakPtr(), callback, nullptr));
return;
}
dbus::MethodCall method_call(peerd::kManagerInterface, dbus::MethodCall method_call(peerd::kManagerInterface,
peerd::kStartMonitoringMethod); peerd::kStartMonitoringMethod);
dbus::MessageWriter writer(&method_call); dbus::MessageWriter writer(&method_call);
writer.AppendArrayOfStrings(requested_technologies); writer.AppendArrayOfStrings(requested_technologies);
dbus::AppendValueData(&writer, options); dbus::AppendValueData(&writer, options);
peer_daemon_proxy_->CallMethod( object_proxy->CallMethod(
&method_call, &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
base::Bind(&PeerDaemonManagerClientImpl::OnStringDBusMethod, base::Bind(&PeerDaemonManagerClientImpl::OnStringDBusMethod,
weak_ptr_factory_.GetWeakPtr(), weak_ptr_factory_.GetWeakPtr(), callback));
callback));
} }
void PeerDaemonManagerClientImpl::StopMonitoring( void PeerDaemonManagerClientImpl::StopMonitoring(
const std::string& monitoring_token, const std::string& monitoring_token,
const VoidDBusMethodCallback& callback) { const VoidDBusMethodCallback& callback) {
dbus::ObjectProxy* object_proxy = object_manager_->GetObjectProxy(
dbus::ObjectPath(peerd::kPeerdManagerPath));
if (!object_proxy) {
base::MessageLoop::current()->PostTask(
FROM_HERE,
base::Bind(&PeerDaemonManagerClientImpl::OnVoidDBusMethod,
weak_ptr_factory_.GetWeakPtr(), callback, nullptr));
return;
}
dbus::MethodCall method_call(peerd::kManagerInterface, dbus::MethodCall method_call(peerd::kManagerInterface,
peerd::kStopMonitoringMethod); peerd::kStopMonitoringMethod);
dbus::MessageWriter writer(&method_call); dbus::MessageWriter writer(&method_call);
writer.AppendString(monitoring_token); writer.AppendString(monitoring_token);
peer_daemon_proxy_->CallMethod( object_proxy->CallMethod(
&method_call, &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
base::Bind(&PeerDaemonManagerClientImpl::OnVoidDBusMethod, base::Bind(&PeerDaemonManagerClientImpl::OnVoidDBusMethod,
weak_ptr_factory_.GetWeakPtr(), weak_ptr_factory_.GetWeakPtr(), callback));
callback));
} }
void PeerDaemonManagerClientImpl::ExposeService( void PeerDaemonManagerClientImpl::ExposeService(
...@@ -109,6 +195,16 @@ void PeerDaemonManagerClientImpl::ExposeService( ...@@ -109,6 +195,16 @@ void PeerDaemonManagerClientImpl::ExposeService(
const std::map<std::string, std::string>& service_info, const std::map<std::string, std::string>& service_info,
const base::DictionaryValue& options, const base::DictionaryValue& options,
const StringDBusMethodCallback& callback) { const StringDBusMethodCallback& callback) {
dbus::ObjectProxy* object_proxy = object_manager_->GetObjectProxy(
dbus::ObjectPath(peerd::kPeerdManagerPath));
if (!object_proxy) {
base::MessageLoop::current()->PostTask(
FROM_HERE,
base::Bind(&PeerDaemonManagerClientImpl::OnStringDBusMethod,
weak_ptr_factory_.GetWeakPtr(), callback, nullptr));
return;
}
dbus::MethodCall method_call(peerd::kManagerInterface, dbus::MethodCall method_call(peerd::kManagerInterface,
peerd::kExposeServiceMethod); peerd::kExposeServiceMethod);
dbus::MessageWriter writer(&method_call); dbus::MessageWriter writer(&method_call);
...@@ -126,12 +222,10 @@ void PeerDaemonManagerClientImpl::ExposeService( ...@@ -126,12 +222,10 @@ void PeerDaemonManagerClientImpl::ExposeService(
writer.CloseContainer(&array_writer); writer.CloseContainer(&array_writer);
dbus::AppendValueData(&writer, options); dbus::AppendValueData(&writer, options);
peer_daemon_proxy_->CallMethod( object_proxy->CallMethod(
&method_call, &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
base::Bind(&PeerDaemonManagerClientImpl::OnStringDBusMethod, base::Bind(&PeerDaemonManagerClientImpl::OnStringDBusMethod,
weak_ptr_factory_.GetWeakPtr(), weak_ptr_factory_.GetWeakPtr(), callback));
callback));
} }
void PeerDaemonManagerClientImpl::RemoveExposedService( void PeerDaemonManagerClientImpl::RemoveExposedService(
...@@ -139,27 +233,95 @@ void PeerDaemonManagerClientImpl::RemoveExposedService( ...@@ -139,27 +233,95 @@ void PeerDaemonManagerClientImpl::RemoveExposedService(
const VoidDBusMethodCallback& callback) { const VoidDBusMethodCallback& callback) {
dbus::MethodCall method_call(peerd::kManagerInterface, dbus::MethodCall method_call(peerd::kManagerInterface,
peerd::kRemoveExposedServiceMethod); peerd::kRemoveExposedServiceMethod);
dbus::ObjectProxy* object_proxy = object_manager_->GetObjectProxy(
dbus::ObjectPath(peerd::kPeerdManagerPath));
if (!object_proxy) {
base::MessageLoop::current()->PostTask(
FROM_HERE,
base::Bind(&PeerDaemonManagerClientImpl::OnVoidDBusMethod,
weak_ptr_factory_.GetWeakPtr(), callback, nullptr));
return;
}
dbus::MessageWriter writer(&method_call); dbus::MessageWriter writer(&method_call);
writer.AppendString(service_token); writer.AppendString(service_token);
peer_daemon_proxy_->CallMethod( object_proxy->CallMethod(
&method_call, &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
base::Bind(&PeerDaemonManagerClientImpl::OnVoidDBusMethod, base::Bind(&PeerDaemonManagerClientImpl::OnVoidDBusMethod,
weak_ptr_factory_.GetWeakPtr(), weak_ptr_factory_.GetWeakPtr(), callback));
callback));
} }
void PeerDaemonManagerClientImpl::Ping( void PeerDaemonManagerClientImpl::Ping(
const StringDBusMethodCallback& callback) { const StringDBusMethodCallback& callback) {
dbus::MethodCall method_call(peerd::kManagerInterface, dbus::MethodCall method_call(peerd::kManagerInterface,
peerd::kPingMethod); peerd::kPingMethod);
dbus::ObjectProxy* object_proxy = object_manager_->GetObjectProxy(
dbus::ObjectPath(peerd::kPeerdManagerPath));
if (!object_proxy) {
base::MessageLoop::current()->PostTask(
FROM_HERE,
base::Bind(&PeerDaemonManagerClientImpl::OnStringDBusMethod,
weak_ptr_factory_.GetWeakPtr(), callback, nullptr));
return;
}
dbus::MessageWriter writer(&method_call); dbus::MessageWriter writer(&method_call);
peer_daemon_proxy_->CallMethod( object_proxy->CallMethod(
&method_call, &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
base::Bind(&PeerDaemonManagerClientImpl::OnStringDBusMethod, base::Bind(&PeerDaemonManagerClientImpl::OnStringDBusMethod,
weak_ptr_factory_.GetWeakPtr(), weak_ptr_factory_.GetWeakPtr(), callback));
callback)); }
dbus::PropertySet* PeerDaemonManagerClientImpl::CreateProperties(
dbus::ObjectProxy* object_proxy,
const dbus::ObjectPath& object_path,
const std::string& interface_name) {
dbus::PropertySet* properties = nullptr;
if (interface_name == peerd::kManagerInterface) {
properties = new ManagerProperties(
object_proxy,
base::Bind(&PeerDaemonManagerClientImpl::OnManagerPropertyChanged,
weak_ptr_factory_.GetWeakPtr()));
} else if (interface_name == peerd::kServiceInterface) {
properties = new ServiceProperties(
object_proxy,
base::Bind(&PeerDaemonManagerClientImpl::OnServicePropertyChanged,
weak_ptr_factory_.GetWeakPtr(), object_path));
} else if (interface_name == peerd::kPeerInterface) {
properties = new PeerProperties(
object_proxy,
base::Bind(&PeerDaemonManagerClientImpl::OnPeerPropertyChanged,
weak_ptr_factory_.GetWeakPtr(), object_path));
} else {
NOTREACHED() << "Unhandled interface name " << interface_name;
}
return properties;
}
void PeerDaemonManagerClientImpl::ObjectAdded(
const dbus::ObjectPath& object_path,
const std::string& interface_name) {
if (interface_name == peerd::kManagerInterface) {
FOR_EACH_OBSERVER(Observer, observers_, ManagerAdded());
} else if (interface_name == peerd::kServiceInterface) {
FOR_EACH_OBSERVER(Observer, observers_, ServiceAdded(object_path));
} else if (interface_name == peerd::kPeerInterface) {
FOR_EACH_OBSERVER(Observer, observers_, PeerAdded(object_path));
} else {
NOTREACHED() << "Unhandled interface name " << interface_name;
}
}
void PeerDaemonManagerClientImpl::ObjectRemoved(
const dbus::ObjectPath& object_path,
const std::string& interface_name) {
if (interface_name == peerd::kManagerInterface) {
FOR_EACH_OBSERVER(Observer, observers_, ManagerRemoved());
} else if (interface_name == peerd::kServiceInterface) {
FOR_EACH_OBSERVER(Observer, observers_, ServiceRemoved(object_path));
} else if (interface_name == peerd::kPeerInterface) {
FOR_EACH_OBSERVER(Observer, observers_, PeerRemoved(object_path));
} else {
NOTREACHED() << "Unhandled interface name " << interface_name;
}
} }
void PeerDaemonManagerClientImpl::OnStringDBusMethod( void PeerDaemonManagerClientImpl::OnStringDBusMethod(
...@@ -187,13 +349,68 @@ void PeerDaemonManagerClientImpl::OnVoidDBusMethod( ...@@ -187,13 +349,68 @@ void PeerDaemonManagerClientImpl::OnVoidDBusMethod(
} }
void PeerDaemonManagerClientImpl::Init(dbus::Bus* bus) { void PeerDaemonManagerClientImpl::Init(dbus::Bus* bus) {
peer_daemon_proxy_ = object_manager_ = bus->GetObjectManager(
bus->GetObjectProxy(peerd::kPeerdServiceName, peerd::kPeerdServiceName,
dbus::ObjectPath(peerd::kPeerdManagerPath)); dbus::ObjectPath(peerd::kPeerdObjectManagerServicePath));
object_manager_->RegisterInterface(peerd::kManagerInterface, this);
object_manager_->RegisterInterface(peerd::kServiceInterface, this);
object_manager_->RegisterInterface(peerd::kPeerInterface, this);
}
void PeerDaemonManagerClientImpl::OnManagerPropertyChanged(
const std::string& property_name) {
FOR_EACH_OBSERVER(Observer, observers_,
ManagerPropertyChanged(property_name));
}
void PeerDaemonManagerClientImpl::OnServicePropertyChanged(
const dbus::ObjectPath& object_path,
const std::string& property_name) {
FOR_EACH_OBSERVER(Observer, observers_,
ServicePropertyChanged(object_path, property_name));
}
void PeerDaemonManagerClientImpl::OnPeerPropertyChanged(
const dbus::ObjectPath& object_path,
const std::string& property_name) {
FOR_EACH_OBSERVER(Observer, observers_,
PeerPropertyChanged(object_path, property_name));
} }
} // namespace } // namespace
PeerDaemonManagerClient::ManagerProperties::ManagerProperties(
dbus::ObjectProxy* object_proxy,
const PropertyChangedCallback& callback)
: dbus::PropertySet{object_proxy, peerd::kManagerInterface, callback} {
RegisterProperty("MonitoredTechnologies", &monitored_technologies_);
}
PeerDaemonManagerClient::ManagerProperties::~ManagerProperties() {
}
PeerDaemonManagerClient::ServiceProperties::ServiceProperties(
dbus::ObjectProxy* object_proxy,
const PropertyChangedCallback& callback)
: dbus::PropertySet{object_proxy, peerd::kServiceInterface, callback} {
RegisterProperty("ServiceId", &service_id_);
RegisterProperty("ServiceInfo", &service_info_);
RegisterProperty("IpInfos", &ip_infos_);
}
PeerDaemonManagerClient::ServiceProperties::~ServiceProperties() {
}
PeerDaemonManagerClient::PeerProperties::PeerProperties(
dbus::ObjectProxy* object_proxy,
const PropertyChangedCallback& callback)
: dbus::PropertySet{object_proxy, peerd::kPeerInterface, callback} {
RegisterProperty("UUID", &uuid_);
RegisterProperty("LastSeen", &last_seen_);
}
PeerDaemonManagerClient::PeerProperties::~PeerProperties() {
}
PeerDaemonManagerClient::PeerDaemonManagerClient() { PeerDaemonManagerClient::PeerDaemonManagerClient() {
} }
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#include <map> #include <map>
#include <string> #include <string>
#include <utility>
#include <vector> #include <vector>
#include "base/macros.h" #include "base/macros.h"
...@@ -14,6 +15,7 @@ ...@@ -14,6 +15,7 @@
#include "chromeos/chromeos_export.h" #include "chromeos/chromeos_export.h"
#include "chromeos/dbus/dbus_client.h" #include "chromeos/dbus/dbus_client.h"
#include "chromeos/dbus/dbus_method_call_status.h" #include "chromeos/dbus/dbus_method_call_status.h"
#include "dbus/property.h"
namespace chromeos { namespace chromeos {
...@@ -22,12 +24,130 @@ namespace chromeos { ...@@ -22,12 +24,130 @@ namespace chromeos {
// initializes the DBusThreadManager instance. // initializes the DBusThreadManager instance.
class CHROMEOS_EXPORT PeerDaemonManagerClient : public DBusClient { class CHROMEOS_EXPORT PeerDaemonManagerClient : public DBusClient {
public: public:
class ManagerProperties : public dbus::PropertySet {
public:
ManagerProperties(dbus::ObjectProxy* object_proxy,
const PropertyChangedCallback& callback);
~ManagerProperties() override;
const std::vector<std::string>& monitored_technologies() const {
return monitored_technologies_.value();
}
private:
dbus::Property<std::vector<std::string>> monitored_technologies_;
DISALLOW_COPY_AND_ASSIGN(ManagerProperties);
};
class ServiceProperties : public dbus::PropertySet {
public:
ServiceProperties(dbus::ObjectProxy* object_proxy,
const PropertyChangedCallback& callback);
~ServiceProperties() override;
const std::string& service_id() const { return service_id_.value(); }
const std::map<std::string, std::string>& service_info() const {
return service_info_.value();
}
const std::vector<std::pair<std::vector<uint8_t>, uint16_t>>& ip_infos()
const {
return ip_infos_.value();
}
private:
dbus::Property<std::string> service_id_;
dbus::Property<std::map<std::string, std::string>> service_info_;
dbus::Property<std::vector<std::pair<std::vector<uint8_t>, uint16_t>>>
ip_infos_;
DISALLOW_COPY_AND_ASSIGN(ServiceProperties);
};
class PeerProperties : public dbus::PropertySet {
public:
PeerProperties(dbus::ObjectProxy* object_proxy,
const PropertyChangedCallback& callback);
~PeerProperties() override;
const std::string& uuid() const { return uuid_.value(); }
uint64_t last_seen() const { return last_seen_.value(); }
private:
dbus::Property<std::string> uuid_;
dbus::Property<uint64_t> last_seen_;
DISALLOW_COPY_AND_ASSIGN(PeerProperties);
};
// Interface for observing changes from a leadership daemon.
class Observer {
public:
virtual ~Observer() {}
// Called when the peer daemon manager is added.
virtual void ManagerAdded() {}
// Called when the peer daemon manager is removed; perhaps on a process
// crash of the peer daemon.
virtual void ManagerRemoved() {}
// Called when the manager changes a property value.
virtual void ManagerPropertyChanged(const std::string& property_name) {}
// Called when the service with object path |object_path| is added to the
// system.
virtual void ServiceAdded(const dbus::ObjectPath& object_path) {}
// Called when the service with object path |object_path| is removed from
// the system.
virtual void ServiceRemoved(const dbus::ObjectPath& object_path) {}
// Called when the service with object path |object_path| changes a
// property value.
virtual void ServicePropertyChanged(const dbus::ObjectPath& object_path,
const std::string& property_name) {}
// Called when the peer with object path |object_path| is added to the
// system.
virtual void PeerAdded(const dbus::ObjectPath& object_path) {}
// Called when the peer with object path |object_path| is removed from
// the system.
virtual void PeerRemoved(const dbus::ObjectPath& object_path) {}
// Called when the peer with object path |object_path| changes a
// property value.
virtual void PeerPropertyChanged(const dbus::ObjectPath& object_path,
const std::string& property_name) {}
};
~PeerDaemonManagerClient() override; ~PeerDaemonManagerClient() override;
// Factory function, creates a new instance which is owned by the caller. // Factory function, creates a new instance which is owned by the caller.
// For normal usage, access the singleton via DBusThreadManager::Get(). // For normal usage, access the singleton via DBusThreadManager::Get().
static PeerDaemonManagerClient* Create(); static PeerDaemonManagerClient* Create();
// Adds and removes observers for events on all peer events.
virtual void AddObserver(Observer* observer) = 0;
virtual void RemoveObserver(Observer* observer) = 0;
// Retrieves a list of all the services.
virtual std::vector<dbus::ObjectPath> GetServices() = 0;
// Retrieves a list of all the peers.
virtual std::vector<dbus::ObjectPath> GetPeers() = 0;
// Obtains the properties for the service with object path |object_path|,
// any values should be copied if needed.
virtual ServiceProperties* GetServiceProperties(
const dbus::ObjectPath& object_path) = 0;
// Obtains the properties for the peer with object path |object_path|,
// any values should be copied if needed.
virtual PeerProperties* GetPeerProperties(
const dbus::ObjectPath& object_path) = 0;
// Calls StartMonitoring method. // Calls StartMonitoring method.
// |callback| is called with its |call_status| argument set to // |callback| is called with its |call_status| argument set to
// DBUS_METHOD_CALL_SUCCESS if the method call succeeds. Otherwise, // DBUS_METHOD_CALL_SUCCESS if the method call succeeds. Otherwise,
......
...@@ -478,6 +478,103 @@ void Property<std::vector<uint8> >::AppendSetValueToWriter( ...@@ -478,6 +478,103 @@ void Property<std::vector<uint8> >::AppendSetValueToWriter(
writer->CloseContainer(&variant_writer); writer->CloseContainer(&variant_writer);
} }
//
// Property<std::map<std::string, std::string>> specialization.
//
template <>
bool Property<std::map<std::string, std::string>>::PopValueFromReader(
MessageReader* reader) {
MessageReader variant_reader(NULL);
MessageReader array_reader(NULL);
if (!reader->PopVariant(&variant_reader) ||
!variant_reader.PopArray(&array_reader))
return false;
value_.clear();
while (array_reader.HasMoreData()) {
dbus::MessageReader dict_entry_reader(NULL);
if (!array_reader.PopDictEntry(&dict_entry_reader))
return false;
std::string key;
std::string value;
if (!dict_entry_reader.PopString(&key) ||
!dict_entry_reader.PopString(&value))
return false;
value_[key] = value;
}
return true;
}
template <>
void Property<std::map<std::string, std::string>>::AppendSetValueToWriter(
MessageWriter* writer) {
MessageWriter variant_writer(NULL);
MessageWriter dict_writer(NULL);
writer->OpenVariant("a{ss}", &variant_writer);
variant_writer.OpenArray("{ss}", &dict_writer);
for (const auto& pair : set_value_) {
dbus::MessageWriter entry_writer(NULL);
dict_writer.OpenDictEntry(&entry_writer);
entry_writer.AppendString(pair.first);
entry_writer.AppendString(pair.second);
dict_writer.CloseContainer(&entry_writer);
}
variant_writer.CloseContainer(&dict_writer);
writer->CloseContainer(&variant_writer);
}
//
// Property<std::vector<std::pair<std::vector<uint8_t>, uint16_t>>>
// specialization.
//
template <>
bool Property<std::vector<std::pair<std::vector<uint8_t>, uint16_t>>>::
PopValueFromReader(MessageReader* reader) {
MessageReader variant_reader(NULL);
MessageReader array_reader(NULL);
if (!reader->PopVariant(&variant_reader) ||
!variant_reader.PopArray(&array_reader))
return false;
value_.clear();
while (array_reader.HasMoreData()) {
dbus::MessageReader struct_reader(NULL);
if (!array_reader.PopStruct(&struct_reader))
return false;
std::pair<std::vector<uint8_t>, uint16_t> entry;
const uint8* bytes = NULL;
size_t length = 0;
if (!struct_reader.PopArrayOfBytes(&bytes, &length))
return false;
entry.first.assign(bytes, bytes + length);
if (!struct_reader.PopUint16(&entry.second))
return false;
value_.push_back(entry);
}
return true;
}
template <>
void Property<std::vector<std::pair<std::vector<uint8_t>, uint16_t>>>::
AppendSetValueToWriter(MessageWriter* writer) {
MessageWriter variant_writer(NULL);
MessageWriter array_writer(NULL);
writer->OpenVariant("a(ayq)", &variant_writer);
variant_writer.OpenArray("(ayq)", &array_writer);
for (const auto& pair : set_value_) {
dbus::MessageWriter struct_writer(nullptr);
array_writer.OpenStruct(&struct_writer);
struct_writer.AppendArrayOfBytes(std::get<0>(pair).data(),
std::get<0>(pair).size());
struct_writer.AppendUint16(std::get<1>(pair));
array_writer.CloseContainer(&struct_writer);
}
variant_writer.CloseContainer(&array_writer);
writer->CloseContainer(&variant_writer);
}
template class Property<uint8>; template class Property<uint8>;
template class Property<bool>; template class Property<bool>;
template class Property<int16>; template class Property<int16>;
...@@ -492,5 +589,7 @@ template class Property<ObjectPath>; ...@@ -492,5 +589,7 @@ template class Property<ObjectPath>;
template class Property<std::vector<std::string> >; template class Property<std::vector<std::string> >;
template class Property<std::vector<ObjectPath> >; template class Property<std::vector<ObjectPath> >;
template class Property<std::vector<uint8> >; template class Property<std::vector<uint8> >;
template class Property<std::map<std::string, std::string>>;
template class Property<std::vector<std::pair<std::vector<uint8_t>, uint16_t>>>;
} // namespace dbus } // namespace dbus
...@@ -7,6 +7,8 @@ ...@@ -7,6 +7,8 @@
#include <map> #include <map>
#include <string> #include <string>
#include <utility>
#include <vector>
#include "base/basictypes.h" #include "base/basictypes.h"
#include "base/bind.h" #include "base/bind.h"
...@@ -158,7 +160,7 @@ class PropertyBase { ...@@ -158,7 +160,7 @@ class PropertyBase {
// no knowledge of the contained type is required, this method returns // no knowledge of the contained type is required, this method returns
// true if its expected type was found, false if not. // true if its expected type was found, false if not.
// Implementation provided by specialization. // Implementation provided by specialization.
virtual bool PopValueFromReader(MessageReader*) = 0; virtual bool PopValueFromReader(MessageReader* reader) = 0;
// Method used by PropertySet to append the set value to a MessageWriter, // Method used by PropertySet to append the set value to a MessageWriter,
// no knowledge of the contained type is required. // no knowledge of the contained type is required.
...@@ -229,7 +231,7 @@ class CHROME_DBUS_EXPORT PropertySet { ...@@ -229,7 +231,7 @@ class CHROME_DBUS_EXPORT PropertySet {
// Methods connected by ConnectSignals() and called by dbus:: when // Methods connected by ConnectSignals() and called by dbus:: when
// a property is changed. Sub-classes may override if the property // a property is changed. Sub-classes may override if the property
// changed signal provides different arguments. // changed signal provides different arguments.
virtual void ChangedReceived(Signal*); virtual void ChangedReceived(Signal* signal);
virtual void ChangedConnected(const std::string& interface_name, virtual void ChangedConnected(const std::string& interface_name,
const std::string& signal_name, const std::string& signal_name,
bool success); bool success);
...@@ -376,7 +378,7 @@ class CHROME_DBUS_EXPORT Property : public PropertyBase { ...@@ -376,7 +378,7 @@ class CHROME_DBUS_EXPORT Property : public PropertyBase {
// Method used by PropertySet to retrieve the value from a MessageReader, // Method used by PropertySet to retrieve the value from a MessageReader,
// no knowledge of the contained type is required, this method returns // no knowledge of the contained type is required, this method returns
// true if its expected type was found, false if not. // true if its expected type was found, false if not.
bool PopValueFromReader(MessageReader*) override; bool PopValueFromReader(MessageReader* reader) override;
// Method used by PropertySet to append the set value to a MessageWriter, // Method used by PropertySet to append the set value to a MessageWriter,
// no knowledge of the contained type is required. // no knowledge of the contained type is required.
...@@ -398,6 +400,10 @@ class CHROME_DBUS_EXPORT Property : public PropertyBase { ...@@ -398,6 +400,10 @@ class CHROME_DBUS_EXPORT Property : public PropertyBase {
property_set()->NotifyPropertyChanged(name()); property_set()->NotifyPropertyChanged(name());
} }
// Method used by test and stub implementations to directly set the
// |set_value_| of a property.
void ReplaceSetValueForTesting(const T& value) { set_value_ = value; }
private: private:
// Current cached value of the property. // Current cached value of the property.
T value_; T value_;
...@@ -485,6 +491,23 @@ template <> void Property<std::vector<uint8> >::AppendSetValueToWriter( ...@@ -485,6 +491,23 @@ template <> void Property<std::vector<uint8> >::AppendSetValueToWriter(
MessageWriter* writer); MessageWriter* writer);
extern template class Property<std::vector<uint8> >; extern template class Property<std::vector<uint8> >;
template <>
bool Property<std::map<std::string, std::string>>::PopValueFromReader(
MessageReader* reader);
template <>
void Property<std::map<std::string, std::string>>::AppendSetValueToWriter(
MessageWriter* writer);
extern template class Property<std::map<std::string, std::string>>;
template <>
bool Property<std::vector<std::pair<std::vector<uint8_t>, uint16_t>>>::
PopValueFromReader(MessageReader* reader);
template <>
void Property<std::vector<std::pair<std::vector<uint8_t>, uint16_t>>>::
AppendSetValueToWriter(MessageWriter* writer);
extern template class Property<
std::vector<std::pair<std::vector<uint8_t>, uint16_t>>>;
} // namespace dbus } // namespace dbus
#endif // DBUS_PROPERTY_H_ #endif // DBUS_PROPERTY_H_
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#include "base/logging.h" #include "base/logging.h"
#include "base/message_loop/message_loop.h" #include "base/message_loop/message_loop.h"
#include "base/run_loop.h" #include "base/run_loop.h"
#include "base/strings/string_number_conversions.h"
#include "base/threading/thread.h" #include "base/threading/thread.h"
#include "base/threading/thread_restrictions.h" #include "base/threading/thread_restrictions.h"
#include "dbus/bus.h" #include "dbus/bus.h"
...@@ -277,4 +278,108 @@ TEST_F(PropertyTest, Set) { ...@@ -277,4 +278,108 @@ TEST_F(PropertyTest, Set) {
EXPECT_EQ("NewService", properties_->name.value()); EXPECT_EQ("NewService", properties_->name.value());
} }
TEST(PropertyTestStatic, ReadWriteStringMap) {
scoped_ptr<Response> message(Response::CreateEmpty());
MessageWriter writer(message.get());
MessageWriter variant_writer(NULL);
MessageWriter variant_array_writer(NULL);
MessageWriter struct_entry_writer(NULL);
writer.OpenVariant("a{ss}", &variant_writer);
variant_writer.OpenArray("{ss}", &variant_array_writer);
const char* items[] = {"One", "Two", "Three", "Four"};
for (unsigned i = 0; i < arraysize(items); ++i) {
variant_array_writer.OpenDictEntry(&struct_entry_writer);
struct_entry_writer.AppendString(items[i]);
struct_entry_writer.AppendString(base::UintToString(i + 1));
variant_array_writer.CloseContainer(&struct_entry_writer);
}
variant_writer.CloseContainer(&variant_array_writer);
writer.CloseContainer(&variant_writer);
MessageReader reader(message.get());
Property<std::map<std::string, std::string>> string_map;
EXPECT_TRUE(string_map.PopValueFromReader(&reader));
ASSERT_EQ(4U, string_map.value().size());
EXPECT_EQ("1", string_map.value().at("One"));
EXPECT_EQ("2", string_map.value().at("Two"));
EXPECT_EQ("3", string_map.value().at("Three"));
EXPECT_EQ("4", string_map.value().at("Four"));
}
TEST(PropertyTestStatic, SerializeStringMap) {
std::map<std::string, std::string> test_map;
test_map["Hi"] = "There";
test_map["Map"] = "Test";
test_map["Random"] = "Text";
scoped_ptr<Response> message(Response::CreateEmpty());
MessageWriter writer(message.get());
Property<std::map<std::string, std::string>> string_map;
string_map.ReplaceSetValueForTesting(test_map);
string_map.AppendSetValueToWriter(&writer);
MessageReader reader(message.get());
EXPECT_TRUE(string_map.PopValueFromReader(&reader));
EXPECT_EQ(test_map, string_map.value());
}
TEST(PropertyTestStatic, ReadWriteNetAddressArray) {
scoped_ptr<Response> message(Response::CreateEmpty());
MessageWriter writer(message.get());
MessageWriter variant_writer(NULL);
MessageWriter variant_array_writer(NULL);
MessageWriter struct_entry_writer(NULL);
writer.OpenVariant("a(ayq)", &variant_writer);
variant_writer.OpenArray("(ayq)", &variant_array_writer);
uint8 ip_bytes[] = {0x54, 0x65, 0x73, 0x74, 0x30};
for (uint16 i = 0; i < 5; ++i) {
variant_array_writer.OpenStruct(&struct_entry_writer);
ip_bytes[4] = 0x30 + i;
struct_entry_writer.AppendArrayOfBytes(ip_bytes, arraysize(ip_bytes));
struct_entry_writer.AppendUint16(i);
variant_array_writer.CloseContainer(&struct_entry_writer);
}
variant_writer.CloseContainer(&variant_array_writer);
writer.CloseContainer(&variant_writer);
MessageReader reader(message.get());
Property<std::vector<std::pair<std::vector<uint8>, uint16>>> ip_list;
EXPECT_TRUE(ip_list.PopValueFromReader(&reader));
ASSERT_EQ(5U, ip_list.value().size());
size_t item_index = 0;
for (auto& item : ip_list.value()) {
ASSERT_EQ(5U, item.first.size());
ip_bytes[4] = 0x30 + item_index;
EXPECT_EQ(0, memcmp(ip_bytes, item.first.data(), 5U));
EXPECT_EQ(item_index, item.second);
++item_index;
}
}
TEST(PropertyTestStatic, SerializeNetAddressArray) {
std::vector<std::pair<std::vector<uint8>, uint16>> test_list;
uint8 ip_bytes[] = {0x54, 0x65, 0x73, 0x74, 0x30};
for (uint16 i = 0; i < 5; ++i) {
ip_bytes[4] = 0x30 + i;
std::vector<uint8> bytes(ip_bytes, ip_bytes + arraysize(ip_bytes));
test_list.push_back(make_pair(bytes, 16));
}
scoped_ptr<Response> message(Response::CreateEmpty());
MessageWriter writer(message.get());
Property<std::vector<std::pair<std::vector<uint8>, uint16>>> ip_list;
ip_list.ReplaceSetValueForTesting(test_list);
ip_list.AppendSetValueToWriter(&writer);
MessageReader reader(message.get());
EXPECT_TRUE(ip_list.PopValueFromReader(&reader));
EXPECT_EQ(test_list, ip_list.value());
}
} // namespace dbus } // namespace dbus
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment