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() {
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(
const std::vector<std::string>& requested_technologies,
const base::DictionaryValue& options,
......
......@@ -24,6 +24,14 @@ class FakePeerDaemonManagerClient : public PeerDaemonManagerClient {
void Init(dbus::Bus* bus) override;
// 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,
const base::DictionaryValue& options,
const StringDBusMethodCallback& callback) override;
......
This diff is collapsed.
......@@ -7,6 +7,7 @@
#include <map>
#include <string>
#include <utility>
#include <vector>
#include "base/macros.h"
......@@ -14,6 +15,7 @@
#include "chromeos/chromeos_export.h"
#include "chromeos/dbus/dbus_client.h"
#include "chromeos/dbus/dbus_method_call_status.h"
#include "dbus/property.h"
namespace chromeos {
......@@ -22,12 +24,130 @@ namespace chromeos {
// initializes the DBusThreadManager instance.
class CHROMEOS_EXPORT PeerDaemonManagerClient : public DBusClient {
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;
// Factory function, creates a new instance which is owned by the caller.
// For normal usage, access the singleton via DBusThreadManager::Get().
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.
// |callback| is called with its |call_status| argument set to
// DBUS_METHOD_CALL_SUCCESS if the method call succeeds. Otherwise,
......
......@@ -478,6 +478,103 @@ void Property<std::vector<uint8> >::AppendSetValueToWriter(
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<bool>;
template class Property<int16>;
......@@ -492,5 +589,7 @@ template class Property<ObjectPath>;
template class Property<std::vector<std::string> >;
template class Property<std::vector<ObjectPath> >;
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
......@@ -7,6 +7,8 @@
#include <map>
#include <string>
#include <utility>
#include <vector>
#include "base/basictypes.h"
#include "base/bind.h"
......@@ -158,7 +160,7 @@ class PropertyBase {
// no knowledge of the contained type is required, this method returns
// true if its expected type was found, false if not.
// 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,
// no knowledge of the contained type is required.
......@@ -229,7 +231,7 @@ class CHROME_DBUS_EXPORT PropertySet {
// Methods connected by ConnectSignals() and called by dbus:: when
// a property is changed. Sub-classes may override if the property
// changed signal provides different arguments.
virtual void ChangedReceived(Signal*);
virtual void ChangedReceived(Signal* signal);
virtual void ChangedConnected(const std::string& interface_name,
const std::string& signal_name,
bool success);
......@@ -376,7 +378,7 @@ class CHROME_DBUS_EXPORT Property : public PropertyBase {
// Method used by PropertySet to retrieve the value from a MessageReader,
// no knowledge of the contained type is required, this method returns
// 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,
// no knowledge of the contained type is required.
......@@ -398,6 +400,10 @@ class CHROME_DBUS_EXPORT Property : public PropertyBase {
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:
// Current cached value of the property.
T value_;
......@@ -485,6 +491,23 @@ template <> void Property<std::vector<uint8> >::AppendSetValueToWriter(
MessageWriter* writer);
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
#endif // DBUS_PROPERTY_H_
......@@ -12,6 +12,7 @@
#include "base/logging.h"
#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "base/strings/string_number_conversions.h"
#include "base/threading/thread.h"
#include "base/threading/thread_restrictions.h"
#include "dbus/bus.h"
......@@ -277,4 +278,108 @@ TEST_F(PropertyTest, Set) {
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
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