chromeos-dbus-bindings: Add support for ObjectManager/Properties
When generating D-Bus object proxy classes, add support for D-Bus
Object Manager proxy and properties on D-Bus objects.
BUG=chromium:431737
TEST=FEATURES=test emerge-link chromeos-dbus-bindings
Change-Id: I4d399fc5ed9613e7c51a7b489383fada184e498f
Reviewed-on: https://chromium-review.googlesource.com/232532
Tested-by: Alex Vakulenko <avakulenko@chromium.org>
Reviewed-by: Vitaly Buka <vitalybuka@chromium.org>
Commit-Queue: Alex Vakulenko <avakulenko@chromium.org>
diff --git a/chromeos-dbus-bindings/proxy_generator_unittest.cc b/chromeos-dbus-bindings/proxy_generator_unittest.cc
index e4f596e..d3ebaad 100644
--- a/chromeos-dbus-bindings/proxy_generator_unittest.cc
+++ b/chromeos-dbus-bindings/proxy_generator_unittest.cc
@@ -45,6 +45,7 @@
const char kSignal2Argument1[] = "as";
const char kSignal2Argument2[] = "y";
const char kExpectedContent[] = R"literal_string(
+#include <memory>
#include <string>
#include <vector>
@@ -55,11 +56,13 @@
#include <base/memory/ref_counted.h>
#include <chromeos/any.h>
#include <chromeos/dbus/dbus_method_invoker.h>
+#include <chromeos/dbus/dbus_property.h>
#include <chromeos/dbus/dbus_signal_handler.h>
#include <chromeos/errors/error.h>
#include <chromeos/variant_dictionary.h>
#include <dbus/bus.h>
#include <dbus/message.h>
+#include <dbus/object_manager.h>
#include <dbus/object_path.h>
#include <dbus/object_proxy.h>
@@ -80,10 +83,10 @@
TestInterfaceProxy(
const scoped_refptr<dbus::Bus>& bus,
const std::string& service_name) :
- bus_(bus),
- service_name_(service_name),
- dbus_object_proxy_(
- bus_->GetObjectProxy(service_name_, object_path_)) {
+ bus_{bus},
+ service_name_{service_name},
+ dbus_object_proxy_{
+ bus_->GetObjectProxy(service_name_, object_path_)} {
}
TestInterfaceProxy(
@@ -120,6 +123,12 @@
bus_->RemoveObjectProxy(service_name_, object_path_, callback);
}
+ const dbus::ObjectPath& GetObjectPath() const {
+ return object_path_;
+ }
+
+ dbus::ObjectProxy* GetObjectProxy() const { return dbus_object_proxy_; }
+
void OnDBusSignalConnected(
const std::string& interface,
const std::string& signal,
@@ -207,12 +216,12 @@
TestInterface2Proxy(
const scoped_refptr<dbus::Bus>& bus,
const std::string& service_name,
- const std::string& object_path) :
- bus_(bus),
- service_name_(service_name),
- object_path_(object_path),
- dbus_object_proxy_(
- bus_->GetObjectProxy(service_name_, object_path_)) {
+ const dbus::ObjectPath& object_path) :
+ bus_{bus},
+ service_name_{service_name},
+ object_path_{object_path},
+ dbus_object_proxy_{
+ bus_->GetObjectProxy(service_name_, object_path_)} {
}
~TestInterface2Proxy() {
@@ -222,6 +231,12 @@
bus_->RemoveObjectProxy(service_name_, object_path_, callback);
}
+ const dbus::ObjectPath& GetObjectPath() const {
+ return object_path_;
+ }
+
+ dbus::ObjectProxy* GetObjectProxy() const { return dbus_object_proxy_; }
+
bool GetPersonInfo(
std::string* out_name,
int32_t* out_age,
@@ -246,10 +261,10 @@
} // namespace chromium
} // namespace org
-
)literal_string";
const char kExpectedContentWithService[] = R"literal_string(
+#include <memory>
#include <string>
#include <vector>
@@ -260,11 +275,13 @@
#include <base/memory/ref_counted.h>
#include <chromeos/any.h>
#include <chromeos/dbus/dbus_method_invoker.h>
+#include <chromeos/dbus/dbus_property.h>
#include <chromeos/dbus/dbus_signal_handler.h>
#include <chromeos/errors/error.h>
#include <chromeos/variant_dictionary.h>
#include <dbus/bus.h>
#include <dbus/message.h>
+#include <dbus/object_manager.h>
#include <dbus/object_path.h>
#include <dbus/object_proxy.h>
@@ -280,9 +297,9 @@
};
TestInterfaceProxy(const scoped_refptr<dbus::Bus>& bus) :
- bus_(bus),
- dbus_object_proxy_(
- bus_->GetObjectProxy(service_name_, object_path_)) {
+ bus_{bus},
+ dbus_object_proxy_{
+ bus_->GetObjectProxy(service_name_, object_path_)} {
}
TestInterfaceProxy(
@@ -308,6 +325,12 @@
bus_->RemoveObjectProxy(service_name_, object_path_, callback);
}
+ const dbus::ObjectPath& GetObjectPath() const {
+ return object_path_;
+ }
+
+ dbus::ObjectProxy* GetObjectProxy() const { return dbus_object_proxy_; }
+
void OnDBusSignalConnected(
const std::string& interface,
const std::string& signal,
@@ -340,11 +363,11 @@
public:
TestInterface2Proxy(
const scoped_refptr<dbus::Bus>& bus,
- const std::string& object_path) :
- bus_(bus),
- object_path_(object_path),
- dbus_object_proxy_(
- bus_->GetObjectProxy(service_name_, object_path_)) {
+ const dbus::ObjectPath& object_path) :
+ bus_{bus},
+ object_path_{object_path},
+ dbus_object_proxy_{
+ bus_->GetObjectProxy(service_name_, object_path_)} {
}
~TestInterface2Proxy() {
@@ -354,6 +377,12 @@
bus_->RemoveObjectProxy(service_name_, object_path_, callback);
}
+ const dbus::ObjectPath& GetObjectPath() const {
+ return object_path_;
+ }
+
+ dbus::ObjectProxy* GetObjectProxy() const { return dbus_object_proxy_; }
+
private:
scoped_refptr<dbus::Bus> bus_;
const std::string service_name_{"org.chromium.Test"};
@@ -365,9 +394,705 @@
} // namespace chromium
} // namespace org
-
)literal_string";
+const char kExpectedContentWithObjectManager[] = R"literal_string(
+#include <memory>
+#include <string>
+#include <vector>
+
+#include <base/bind.h>
+#include <base/callback.h>
+#include <base/logging.h>
+#include <base/macros.h>
+#include <base/memory/ref_counted.h>
+#include <chromeos/any.h>
+#include <chromeos/dbus/dbus_method_invoker.h>
+#include <chromeos/dbus/dbus_property.h>
+#include <chromeos/dbus/dbus_signal_handler.h>
+#include <chromeos/errors/error.h>
+#include <chromeos/variant_dictionary.h>
+#include <dbus/bus.h>
+#include <dbus/message.h>
+#include <dbus/object_manager.h>
+#include <dbus/object_path.h>
+#include <dbus/object_proxy.h>
+
+namespace org {
+namespace chromium {
+class ObjectManagerProxy;
+} // namespace chromium
+} // namespace org
+
+namespace org {
+namespace chromium {
+
+// Interface proxy for org::chromium::Itf1.
+class Itf1Proxy final {
+ public:
+ class SignalReceiver {
+ public:
+ virtual void OnCloserSignal() {}
+ };
+
+ class PropertySet : public dbus::PropertySet {
+ public:
+ PropertySet(dbus::ObjectProxy* object_proxy,
+ const PropertyChangedCallback& callback)
+ : dbus::PropertySet{object_proxy,
+ "org.chromium.Itf1",
+ callback} {
+ RegisterProperty("data", &data);
+ }
+
+ chromeos::dbus_utils::Property<std::string> data;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(PropertySet);
+ };
+
+ Itf1Proxy(
+ const scoped_refptr<dbus::Bus>& bus,
+ const std::string& service_name,
+ PropertySet* property_set) :
+ bus_{bus},
+ service_name_{service_name},
+ property_set_{property_set},
+ dbus_object_proxy_{
+ bus_->GetObjectProxy(service_name_, object_path_)} {
+ }
+
+ Itf1Proxy(
+ const scoped_refptr<dbus::Bus>& bus,
+ const std::string& service_name,
+ PropertySet* property_set,
+ SignalReceiver* signal_receiver) :
+ Itf1Proxy(bus, service_name, property_set) {
+ chromeos::dbus_utils::ConnectToSignal(
+ dbus_object_proxy_,
+ "org.chromium.Itf1",
+ "Closer",
+ base::Bind(
+ &SignalReceiver::OnCloserSignal,
+ base::Unretained(signal_receiver)),
+ base::Bind(
+ &Itf1Proxy::OnDBusSignalConnected,
+ base::Unretained(this)));
+ }
+
+ ~Itf1Proxy() {
+ }
+
+ void ReleaseObjectProxy(const base::Closure& callback) {
+ bus_->RemoveObjectProxy(service_name_, object_path_, callback);
+ }
+
+ const dbus::ObjectPath& GetObjectPath() const {
+ return object_path_;
+ }
+
+ dbus::ObjectProxy* GetObjectProxy() const { return dbus_object_proxy_; }
+
+ void SetPropertyChangedCallback(
+ const base::Callback<void(Itf1Proxy*, const std::string&)>& callback) {
+ on_property_changed_ = callback;
+ }
+
+ const PropertySet* GetProperties() const { return property_set_; }
+ PropertySet* GetProperties() { return property_set_; }
+
+ void OnDBusSignalConnected(
+ const std::string& interface,
+ const std::string& signal,
+ bool success) {
+ if (!success) {
+ LOG(ERROR)
+ << "Failed to connect to " << interface << "." << signal
+ << " for " << service_name_ << " at "
+ << object_path_.value();
+ }
+ }
+
+ const std::string& data() const {
+ return property_set_->data.value();
+ }
+
+ private:
+ void OnPropertyChanged(const std::string& property_name) {
+ if (!on_property_changed_.is_null())
+ on_property_changed_.Run(this, property_name);
+ }
+
+ scoped_refptr<dbus::Bus> bus_;
+ std::string service_name_;
+ const dbus::ObjectPath object_path_{"/org/chromium/Test/Object"};
+ PropertySet* property_set_;
+ base::Callback<void(Itf1Proxy*, const std::string&)> on_property_changed_;
+ dbus::ObjectProxy* dbus_object_proxy_;
+
+ friend class org::chromium::ObjectManagerProxy;
+ DISALLOW_COPY_AND_ASSIGN(Itf1Proxy);
+};
+
+} // namespace chromium
+} // namespace org
+
+namespace org {
+namespace chromium {
+
+// Interface proxy for org::chromium::Itf2.
+class Itf2Proxy final {
+ public:
+ class PropertySet : public dbus::PropertySet {
+ public:
+ PropertySet(dbus::ObjectProxy* object_proxy,
+ const PropertyChangedCallback& callback)
+ : dbus::PropertySet{object_proxy,
+ "org.chromium.Itf2",
+ callback} {
+ }
+
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(PropertySet);
+ };
+
+ Itf2Proxy(
+ const scoped_refptr<dbus::Bus>& bus,
+ const std::string& service_name,
+ const dbus::ObjectPath& object_path) :
+ bus_{bus},
+ service_name_{service_name},
+ object_path_{object_path},
+ dbus_object_proxy_{
+ bus_->GetObjectProxy(service_name_, object_path_)} {
+ }
+
+ ~Itf2Proxy() {
+ }
+
+ void ReleaseObjectProxy(const base::Closure& callback) {
+ bus_->RemoveObjectProxy(service_name_, object_path_, callback);
+ }
+
+ const dbus::ObjectPath& GetObjectPath() const {
+ return object_path_;
+ }
+
+ dbus::ObjectProxy* GetObjectProxy() const { return dbus_object_proxy_; }
+
+ private:
+ scoped_refptr<dbus::Bus> bus_;
+ std::string service_name_;
+ dbus::ObjectPath object_path_;
+ dbus::ObjectProxy* dbus_object_proxy_;
+
+ DISALLOW_COPY_AND_ASSIGN(Itf2Proxy);
+};
+
+} // namespace chromium
+} // namespace org
+
+namespace org {
+namespace chromium {
+
+class ObjectManagerProxy : public dbus::ObjectManager::Interface {
+ public:
+ ObjectManagerProxy(const scoped_refptr<dbus::Bus>& bus,
+ const std::string& service_name)
+ : bus_{bus},
+ dbus_object_manager_{bus->GetObjectManager(
+ service_name,
+ dbus::ObjectPath{"/org/chromium/Test"})} {
+ dbus_object_manager_->RegisterInterface("org.chromium.Itf1", this);
+ dbus_object_manager_->RegisterInterface("org.chromium.Itf2", this);
+ }
+
+ dbus::ObjectManager* GetObjectManagerProxy() const {
+ return dbus_object_manager_;
+ }
+
+ org::chromium::Itf1Proxy* GetItf1Proxy(
+ const dbus::ObjectPath& object_path) {
+ auto p = itf1_instances_.find(object_path);
+ if (p != itf1_instances_.end())
+ return p->second.get();
+ return nullptr;
+ }
+ std::vector<org::chromium::Itf1Proxy*> GetItf1Instances() const {
+ std::vector<org::chromium::Itf1Proxy*> values;
+ values.reserve(itf1_instances_.size());
+ for (const auto& pair : itf1_instances_)
+ values.push_back(pair.second.get());
+ return values;
+ }
+ void SetItf1AddedCallback(
+ const base::Callback<void(org::chromium::Itf1Proxy*)>& callback) {
+ on_itf1_added_ = callback;
+ }
+ void SetItf1RemovedCallback(
+ const base::Callback<void(const dbus::ObjectPath&)>& callback) {
+ on_itf1_removed_ = callback;
+ }
+
+ org::chromium::Itf2Proxy* GetItf2Proxy(
+ const dbus::ObjectPath& object_path) {
+ auto p = itf2_instances_.find(object_path);
+ if (p != itf2_instances_.end())
+ return p->second.get();
+ return nullptr;
+ }
+ std::vector<org::chromium::Itf2Proxy*> GetItf2Instances() const {
+ std::vector<org::chromium::Itf2Proxy*> values;
+ values.reserve(itf2_instances_.size());
+ for (const auto& pair : itf2_instances_)
+ values.push_back(pair.second.get());
+ return values;
+ }
+ void SetItf2AddedCallback(
+ const base::Callback<void(org::chromium::Itf2Proxy*)>& callback) {
+ on_itf2_added_ = callback;
+ }
+ void SetItf2RemovedCallback(
+ const base::Callback<void(const dbus::ObjectPath&)>& callback) {
+ on_itf2_removed_ = callback;
+ }
+
+ private:
+ void OnPropertyChanged(const dbus::ObjectPath& object_path,
+ const std::string& interface_name,
+ const std::string& property_name) {
+ if (interface_name == "org.chromium.Itf1") {
+ auto p = itf1_instances_.find(object_path);
+ if (p == itf1_instances_.end())
+ return;
+ p->second->OnPropertyChanged(property_name);
+ return;
+ }
+ }
+
+ void ObjectAdded(
+ const dbus::ObjectPath& object_path,
+ const std::string& interface_name) override {
+ if (interface_name == "org.chromium.Itf1") {
+ auto property_set =
+ static_cast<org::chromium::Itf1Proxy::PropertySet*>(
+ dbus_object_manager_->GetProperties(object_path, interface_name));
+ std::unique_ptr<org::chromium::Itf1Proxy> itf1_proxy{
+ new org::chromium::Itf1Proxy{bus_, property_set}
+ };
+ auto p = itf1_instances_.emplace(object_path, std::move(itf1_proxy));
+ if (!on_itf1_added_.is_null())
+ on_itf1_added_.Run(p.first->second.get());
+ return;
+ }
+ if (interface_name == "org.chromium.Itf2") {
+ std::unique_ptr<org::chromium::Itf2Proxy> itf2_proxy{
+ new org::chromium::Itf2Proxy{bus_, object_path}
+ };
+ auto p = itf2_instances_.emplace(object_path, std::move(itf2_proxy));
+ if (!on_itf2_added_.is_null())
+ on_itf2_added_.Run(p.first->second.get());
+ return;
+ }
+ }
+
+ void ObjectRemoved(
+ const dbus::ObjectPath& object_path,
+ const std::string& interface_name) override {
+ if (interface_name == "org.chromium.Itf1") {
+ auto p = itf1_instances_.find(object_path);
+ if (p != itf1_instances_.end()) {
+ if (!on_itf1_removed_.is_null())
+ on_itf1_removed_.Run(object_path);
+ itf1_instances_.erase(p);
+ }
+ return;
+ }
+ if (interface_name == "org.chromium.Itf2") {
+ auto p = itf2_instances_.find(object_path);
+ if (p != itf2_instances_.end()) {
+ if (!on_itf2_removed_.is_null())
+ on_itf2_removed_.Run(object_path);
+ itf2_instances_.erase(p);
+ }
+ return;
+ }
+ }
+
+ dbus::PropertySet* CreateProperties(
+ dbus::ObjectProxy* object_proxy,
+ const dbus::ObjectPath& object_path,
+ const std::string& interface_name) override {
+ if (interface_name == "org.chromium.Itf1") {
+ return new org::chromium::Itf1Proxy::PropertySet{
+ object_proxy,
+ base::Bind(&ObjectManagerProxy::OnPropertyChanged,
+ weak_ptr_factory_.GetWeakPtr(),
+ object_path,
+ interface_name)
+ };
+ }
+ if (interface_name == "org.chromium.Itf2") {
+ return new org::chromium::Itf2Proxy::PropertySet{
+ object_proxy,
+ base::Bind(&ObjectManagerProxy::OnPropertyChanged,
+ weak_ptr_factory_.GetWeakPtr(),
+ object_path,
+ interface_name)
+ };
+ }
+ LOG(FATAL) << "Creating properties for unsupported interface "
+ << interface_name;
+ return nullptr;
+ }
+
+ scoped_refptr<dbus::Bus> bus_;
+ dbus::ObjectManager* dbus_object_manager_;
+ std::map<dbus::ObjectPath,
+ std::unique_ptr<org::chromium::Itf1Proxy>> itf1_instances_;
+ base::Callback<void(org::chromium::Itf1Proxy*)> on_itf1_added_;
+ base::Callback<void(const dbus::ObjectPath&)> on_itf1_removed_;
+ std::map<dbus::ObjectPath,
+ std::unique_ptr<org::chromium::Itf2Proxy>> itf2_instances_;
+ base::Callback<void(org::chromium::Itf2Proxy*)> on_itf2_added_;
+ base::Callback<void(const dbus::ObjectPath&)> on_itf2_removed_;
+ base::WeakPtrFactory<ObjectManagerProxy> weak_ptr_factory_{this};
+
+ DISALLOW_COPY_AND_ASSIGN(ObjectManagerProxy);
+};
+
+} // namespace chromium
+} // namespace org
+)literal_string";
+
+const char kExpectedContentWithObjectManagerAndServiceName[] = R"literal_string(
+#include <memory>
+#include <string>
+#include <vector>
+
+#include <base/bind.h>
+#include <base/callback.h>
+#include <base/logging.h>
+#include <base/macros.h>
+#include <base/memory/ref_counted.h>
+#include <chromeos/any.h>
+#include <chromeos/dbus/dbus_method_invoker.h>
+#include <chromeos/dbus/dbus_property.h>
+#include <chromeos/dbus/dbus_signal_handler.h>
+#include <chromeos/errors/error.h>
+#include <chromeos/variant_dictionary.h>
+#include <dbus/bus.h>
+#include <dbus/message.h>
+#include <dbus/object_manager.h>
+#include <dbus/object_path.h>
+#include <dbus/object_proxy.h>
+
+namespace org {
+namespace chromium {
+class ObjectManagerProxy;
+} // namespace chromium
+} // namespace org
+
+namespace org {
+namespace chromium {
+
+// Interface proxy for org::chromium::Itf1.
+class Itf1Proxy final {
+ public:
+ class SignalReceiver {
+ public:
+ virtual void OnCloserSignal() {}
+ };
+
+ class PropertySet : public dbus::PropertySet {
+ public:
+ PropertySet(dbus::ObjectProxy* object_proxy,
+ const PropertyChangedCallback& callback)
+ : dbus::PropertySet{object_proxy,
+ "org.chromium.Itf1",
+ callback} {
+ }
+
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(PropertySet);
+ };
+
+ Itf1Proxy(const scoped_refptr<dbus::Bus>& bus) :
+ bus_{bus},
+ dbus_object_proxy_{
+ bus_->GetObjectProxy(service_name_, object_path_)} {
+ }
+
+ Itf1Proxy(
+ const scoped_refptr<dbus::Bus>& bus,
+ SignalReceiver* signal_receiver) :
+ Itf1Proxy(bus) {
+ chromeos::dbus_utils::ConnectToSignal(
+ dbus_object_proxy_,
+ "org.chromium.Itf1",
+ "Closer",
+ base::Bind(
+ &SignalReceiver::OnCloserSignal,
+ base::Unretained(signal_receiver)),
+ base::Bind(
+ &Itf1Proxy::OnDBusSignalConnected,
+ base::Unretained(this)));
+ }
+
+ ~Itf1Proxy() {
+ }
+
+ void ReleaseObjectProxy(const base::Closure& callback) {
+ bus_->RemoveObjectProxy(service_name_, object_path_, callback);
+ }
+
+ const dbus::ObjectPath& GetObjectPath() const {
+ return object_path_;
+ }
+
+ dbus::ObjectProxy* GetObjectProxy() const { return dbus_object_proxy_; }
+
+ void OnDBusSignalConnected(
+ const std::string& interface,
+ const std::string& signal,
+ bool success) {
+ if (!success) {
+ LOG(ERROR)
+ << "Failed to connect to " << interface << "." << signal
+ << " for " << service_name_ << " at "
+ << object_path_.value();
+ }
+ }
+
+ private:
+ scoped_refptr<dbus::Bus> bus_;
+ const std::string service_name_{"org.chromium.Test"};
+ const dbus::ObjectPath object_path_{"/org/chromium/Test/Object"};
+ dbus::ObjectProxy* dbus_object_proxy_;
+
+ DISALLOW_COPY_AND_ASSIGN(Itf1Proxy);
+};
+
+} // namespace chromium
+} // namespace org
+
+namespace org {
+namespace chromium {
+
+// Interface proxy for org::chromium::Itf2.
+class Itf2Proxy final {
+ public:
+ class PropertySet : public dbus::PropertySet {
+ public:
+ PropertySet(dbus::ObjectProxy* object_proxy,
+ const PropertyChangedCallback& callback)
+ : dbus::PropertySet{object_proxy,
+ "org.chromium.Itf2",
+ callback} {
+ }
+
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(PropertySet);
+ };
+
+ Itf2Proxy(
+ const scoped_refptr<dbus::Bus>& bus,
+ const dbus::ObjectPath& object_path) :
+ bus_{bus},
+ object_path_{object_path},
+ dbus_object_proxy_{
+ bus_->GetObjectProxy(service_name_, object_path_)} {
+ }
+
+ ~Itf2Proxy() {
+ }
+
+ void ReleaseObjectProxy(const base::Closure& callback) {
+ bus_->RemoveObjectProxy(service_name_, object_path_, callback);
+ }
+
+ const dbus::ObjectPath& GetObjectPath() const {
+ return object_path_;
+ }
+
+ dbus::ObjectProxy* GetObjectProxy() const { return dbus_object_proxy_; }
+
+ private:
+ scoped_refptr<dbus::Bus> bus_;
+ const std::string service_name_{"org.chromium.Test"};
+ dbus::ObjectPath object_path_;
+ dbus::ObjectProxy* dbus_object_proxy_;
+
+ DISALLOW_COPY_AND_ASSIGN(Itf2Proxy);
+};
+
+} // namespace chromium
+} // namespace org
+
+namespace org {
+namespace chromium {
+
+class ObjectManagerProxy : public dbus::ObjectManager::Interface {
+ public:
+ ObjectManagerProxy(const scoped_refptr<dbus::Bus>& bus)
+ : bus_{bus},
+ dbus_object_manager_{bus->GetObjectManager(
+ "org.chromium.Test",
+ dbus::ObjectPath{"/org/chromium/Test"})} {
+ dbus_object_manager_->RegisterInterface("org.chromium.Itf1", this);
+ dbus_object_manager_->RegisterInterface("org.chromium.Itf2", this);
+ }
+
+ dbus::ObjectManager* GetObjectManagerProxy() const {
+ return dbus_object_manager_;
+ }
+
+ org::chromium::Itf1Proxy* GetItf1Proxy(
+ const dbus::ObjectPath& object_path) {
+ auto p = itf1_instances_.find(object_path);
+ if (p != itf1_instances_.end())
+ return p->second.get();
+ return nullptr;
+ }
+ std::vector<org::chromium::Itf1Proxy*> GetItf1Instances() const {
+ std::vector<org::chromium::Itf1Proxy*> values;
+ values.reserve(itf1_instances_.size());
+ for (const auto& pair : itf1_instances_)
+ values.push_back(pair.second.get());
+ return values;
+ }
+ void SetItf1AddedCallback(
+ const base::Callback<void(org::chromium::Itf1Proxy*)>& callback) {
+ on_itf1_added_ = callback;
+ }
+ void SetItf1RemovedCallback(
+ const base::Callback<void(const dbus::ObjectPath&)>& callback) {
+ on_itf1_removed_ = callback;
+ }
+
+ org::chromium::Itf2Proxy* GetItf2Proxy(
+ const dbus::ObjectPath& object_path) {
+ auto p = itf2_instances_.find(object_path);
+ if (p != itf2_instances_.end())
+ return p->second.get();
+ return nullptr;
+ }
+ std::vector<org::chromium::Itf2Proxy*> GetItf2Instances() const {
+ std::vector<org::chromium::Itf2Proxy*> values;
+ values.reserve(itf2_instances_.size());
+ for (const auto& pair : itf2_instances_)
+ values.push_back(pair.second.get());
+ return values;
+ }
+ void SetItf2AddedCallback(
+ const base::Callback<void(org::chromium::Itf2Proxy*)>& callback) {
+ on_itf2_added_ = callback;
+ }
+ void SetItf2RemovedCallback(
+ const base::Callback<void(const dbus::ObjectPath&)>& callback) {
+ on_itf2_removed_ = callback;
+ }
+
+ private:
+ void OnPropertyChanged(const dbus::ObjectPath& object_path,
+ const std::string& interface_name,
+ const std::string& property_name) {
+ }
+
+ void ObjectAdded(
+ const dbus::ObjectPath& object_path,
+ const std::string& interface_name) override {
+ if (interface_name == "org.chromium.Itf1") {
+ std::unique_ptr<org::chromium::Itf1Proxy> itf1_proxy{
+ new org::chromium::Itf1Proxy{bus_}
+ };
+ auto p = itf1_instances_.emplace(object_path, std::move(itf1_proxy));
+ if (!on_itf1_added_.is_null())
+ on_itf1_added_.Run(p.first->second.get());
+ return;
+ }
+ if (interface_name == "org.chromium.Itf2") {
+ std::unique_ptr<org::chromium::Itf2Proxy> itf2_proxy{
+ new org::chromium::Itf2Proxy{bus_, object_path}
+ };
+ auto p = itf2_instances_.emplace(object_path, std::move(itf2_proxy));
+ if (!on_itf2_added_.is_null())
+ on_itf2_added_.Run(p.first->second.get());
+ return;
+ }
+ }
+
+ void ObjectRemoved(
+ const dbus::ObjectPath& object_path,
+ const std::string& interface_name) override {
+ if (interface_name == "org.chromium.Itf1") {
+ auto p = itf1_instances_.find(object_path);
+ if (p != itf1_instances_.end()) {
+ if (!on_itf1_removed_.is_null())
+ on_itf1_removed_.Run(object_path);
+ itf1_instances_.erase(p);
+ }
+ return;
+ }
+ if (interface_name == "org.chromium.Itf2") {
+ auto p = itf2_instances_.find(object_path);
+ if (p != itf2_instances_.end()) {
+ if (!on_itf2_removed_.is_null())
+ on_itf2_removed_.Run(object_path);
+ itf2_instances_.erase(p);
+ }
+ return;
+ }
+ }
+
+ dbus::PropertySet* CreateProperties(
+ dbus::ObjectProxy* object_proxy,
+ const dbus::ObjectPath& object_path,
+ const std::string& interface_name) override {
+ if (interface_name == "org.chromium.Itf1") {
+ return new org::chromium::Itf1Proxy::PropertySet{
+ object_proxy,
+ base::Bind(&ObjectManagerProxy::OnPropertyChanged,
+ weak_ptr_factory_.GetWeakPtr(),
+ object_path,
+ interface_name)
+ };
+ }
+ if (interface_name == "org.chromium.Itf2") {
+ return new org::chromium::Itf2Proxy::PropertySet{
+ object_proxy,
+ base::Bind(&ObjectManagerProxy::OnPropertyChanged,
+ weak_ptr_factory_.GetWeakPtr(),
+ object_path,
+ interface_name)
+ };
+ }
+ LOG(FATAL) << "Creating properties for unsupported interface "
+ << interface_name;
+ return nullptr;
+ }
+
+ scoped_refptr<dbus::Bus> bus_;
+ dbus::ObjectManager* dbus_object_manager_;
+ std::map<dbus::ObjectPath,
+ std::unique_ptr<org::chromium::Itf1Proxy>> itf1_instances_;
+ base::Callback<void(org::chromium::Itf1Proxy*)> on_itf1_added_;
+ base::Callback<void(const dbus::ObjectPath&)> on_itf1_removed_;
+ std::map<dbus::ObjectPath,
+ std::unique_ptr<org::chromium::Itf2Proxy>> itf2_instances_;
+ base::Callback<void(org::chromium::Itf2Proxy*)> on_itf2_added_;
+ base::Callback<void(const dbus::ObjectPath&)> on_itf2_removed_;
+ base::WeakPtrFactory<ObjectManagerProxy> weak_ptr_factory_{this};
+
+ DISALLOW_COPY_AND_ASSIGN(ObjectManagerProxy);
+};
+
+} // namespace chromium
+} // namespace org
+)literal_string";
} // namespace
class ProxyGeneratorTest : public Test {
@@ -456,4 +1181,53 @@
<< kExpectedContentWithService << "...within content...\n" << contents;
}
+TEST_F(ProxyGeneratorTest, GenerateAdaptorsWithObjectManager) {
+ Interface interface;
+ interface.name = "org.chromium.Itf1";
+ interface.path = "/org/chromium/Test/Object";
+ interface.signals.emplace_back(kSignal1Name);
+ interface.properties.emplace_back("data", "s", "read");
+ Interface interface2;
+ interface2.name = "org.chromium.Itf2";
+ vector<Interface> interfaces{interface, interface2};
+ base::FilePath output_path = temp_dir_.path().Append("output3.h");
+ ServiceConfig config;
+ config.object_manager.name = "org.chromium.ObjectManager";
+ config.object_manager.object_path = "/org/chromium/Test";
+ EXPECT_TRUE(ProxyGenerator::GenerateProxies(config, interfaces, output_path));
+ string contents;
+ EXPECT_TRUE(base::ReadFileToString(output_path, &contents));
+ // The header guards contain the (temporary) filename, so we search for
+ // the content we need within the string.
+ EXPECT_NE(string::npos, contents.find(kExpectedContentWithObjectManager))
+ << "Expected to find the following content...\n"
+ << kExpectedContentWithObjectManager << "...within content...\n"
+ << contents;
+}
+
+TEST_F(ProxyGeneratorTest, GenerateAdaptorsWithObjectManagerAndServiceName) {
+ Interface interface;
+ interface.name = "org.chromium.Itf1";
+ interface.path = "/org/chromium/Test/Object";
+ interface.signals.emplace_back(kSignal1Name);
+ Interface interface2;
+ interface2.name = "org.chromium.Itf2";
+ vector<Interface> interfaces{interface, interface2};
+ base::FilePath output_path = temp_dir_.path().Append("output4.h");
+ ServiceConfig config;
+ config.service_name = "org.chromium.Test";
+ config.object_manager.name = "org.chromium.ObjectManager";
+ config.object_manager.object_path = "/org/chromium/Test";
+ EXPECT_TRUE(ProxyGenerator::GenerateProxies(config, interfaces, output_path));
+ string contents;
+ EXPECT_TRUE(base::ReadFileToString(output_path, &contents));
+ // The header guards contain the (temporary) filename, so we search for
+ // the content we need within the string.
+ EXPECT_NE(string::npos,
+ contents.find(kExpectedContentWithObjectManagerAndServiceName))
+ << "Expected to find the following content...\n"
+ << kExpectedContentWithObjectManagerAndServiceName
+ << "...within content...\n" << contents;
+}
+
} // namespace chromeos_dbus_bindings