Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(604)

Unified Diff: dbus/object_manager.cc

Issue 12491014: Support D-Bus Object Manager (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Review comments Created 7 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: dbus/object_manager.cc
diff --git a/dbus/object_manager.cc b/dbus/object_manager.cc
new file mode 100644
index 0000000000000000000000000000000000000000..4b96d8317f9ca1cb440d391be42ccb8437348577
--- /dev/null
+++ b/dbus/object_manager.cc
@@ -0,0 +1,288 @@
+// Copyright (c) 2013 The Chromium 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 "dbus/object_manager.h"
+
+#include "base/bind.h"
+#include "base/logging.h"
+#include "dbus/bus.h"
+#include "dbus/message.h"
+#include "dbus/object_proxy.h"
+#include "dbus/property.h"
+
+namespace dbus {
+
+ObjectManager::ObjectManager(Bus* bus,
+ const std::string& service_name,
+ const ObjectPath& object_path)
+ : bus_(bus),
+ service_name_(service_name),
+ object_path_(object_path),
+ weak_ptr_factory_(this) {
+ DVLOG(1) << "Creating ObjectManager for " << service_name_
+ << " " << object_path_.value();
+
+ DCHECK(bus_);
+ object_proxy_ = bus_->GetObjectProxy(service_name_, object_path_);
+
+ object_proxy_->ConnectToSignal(
+ kObjectManagerInterface,
+ kObjectManagerInterfacesAdded,
+ base::Bind(&ObjectManager::InterfacesAddedReceived,
+ weak_ptr_factory_.GetWeakPtr()),
+ base::Bind(&ObjectManager::InterfacesAddedConnected,
+ weak_ptr_factory_.GetWeakPtr()));
+
+ object_proxy_->ConnectToSignal(
+ kObjectManagerInterface,
+ kObjectManagerInterfacesRemoved,
+ base::Bind(&ObjectManager::InterfacesRemovedReceived,
+ weak_ptr_factory_.GetWeakPtr()),
+ base::Bind(&ObjectManager::InterfacesRemovedConnected,
+ weak_ptr_factory_.GetWeakPtr()));
+
+ GetManagedObjects();
+}
+
+ObjectManager::~ObjectManager() {
+ // Clean up Object structures
+ for (ObjectMap::iterator iter = object_map_.begin();
+ iter != object_map_.end(); ++iter) {
+ Object* object = iter->second;
+
+ for (Object::PropertiesMap::iterator piter = object->properties_map.begin();
+ piter != object->properties_map.end(); ++piter) {
+ PropertySet* properties = piter->second;
+ delete properties;
+ }
+
+ delete object;
+ }
+}
+
+void ObjectManager::RegisterInterface(const std::string& interface_name,
+ Interface* interface) {
+ interface_map_[interface_name] = interface;
+}
+
+void ObjectManager::UnregisterInterface(const std::string& interface_name) {
+ InterfaceMap::iterator iter = interface_map_.find(interface_name);
+ if (iter != interface_map_.end())
+ interface_map_.erase(iter);
+}
+
+std::vector<ObjectPath> ObjectManager::GetObjects() {
+ std::vector<ObjectPath> object_paths;
+
+ for (ObjectMap::iterator iter = object_map_.begin();
+ iter != object_map_.end(); ++iter)
+ object_paths.push_back(iter->first);
+
+ return object_paths;
+}
+
+std::vector<ObjectPath> ObjectManager::GetObjectsWithInterface(
+ const std::string& interface_name) {
+ std::vector<ObjectPath> object_paths;
+
+ for (ObjectMap::iterator oiter = object_map_.begin();
+ oiter != object_map_.end(); ++oiter) {
+ Object* object = oiter->second;
+
+ Object::PropertiesMap::iterator piter =
+ object->properties_map.find(interface_name);
+ if (piter != object->properties_map.end())
+ object_paths.push_back(oiter->first);
+ }
+
+ return object_paths;
+}
+
+ObjectProxy* ObjectManager::GetObjectProxy(const ObjectPath& object_path) {
+ ObjectMap::iterator iter = object_map_.find(object_path);
+ if (iter == object_map_.end())
+ return NULL;
+
+ Object* object = iter->second;
+ return object->object_proxy;
+}
+
+PropertySet* ObjectManager::GetProperties(const ObjectPath& object_path,
+ const std::string& interface_name) {
+ ObjectMap::iterator iter = object_map_.find(object_path);
+ if (iter == object_map_.end())
+ return NULL;
+
+ Object* object = iter->second;
+ Object::PropertiesMap::iterator piter =
+ object->properties_map.find(interface_name);
+ if (piter == object->properties_map.end())
+ return NULL;
+
+ return piter->second;
+}
+
+void ObjectManager::GetManagedObjects() {
+ MethodCall method_call(kObjectManagerInterface,
+ kObjectManagerGetManagedObjects);
+
+ object_proxy_->CallMethod(
+ &method_call,
+ ObjectProxy::TIMEOUT_USE_DEFAULT,
+ base::Bind(&ObjectManager::OnGetManagedObjects,
+ weak_ptr_factory_.GetWeakPtr()));
+}
+
+void ObjectManager::OnGetManagedObjects(Response* response) {
+ if (response != NULL) {
+ MessageReader reader(response);
+ MessageReader array_reader(NULL);
+ if (!reader.PopArray(&array_reader))
+ return;
+
+ while (array_reader.HasMoreData()) {
+ MessageReader dict_entry_reader(NULL);
+ ObjectPath object_path;
+ if (!array_reader.PopDictEntry(&dict_entry_reader) ||
+ !dict_entry_reader.PopObjectPath(&object_path))
+ continue;
+
+ UpdateObject(object_path, &dict_entry_reader);
+ }
+
+ } else {
+ LOG(WARNING) << service_name_ << " " << object_path_.value()
+ << ": Failed to get managed objects";
+ }
+}
+
+void ObjectManager::InterfacesAddedReceived(Signal* signal) {
+ DCHECK(signal);
+ MessageReader reader(signal);
+ ObjectPath object_path;
+ if (!reader.PopObjectPath(&object_path)) {
+ LOG(WARNING) << service_name_ << " " << object_path_.value()
+ << ": InterfacesAdded signal has incorrect parameters: "
+ << signal->ToString();
+ return;
+ }
+
+ UpdateObject(object_path, &reader);
+}
+
+void ObjectManager::InterfacesAddedConnected(const std::string& interface_name,
+ const std::string& signal_name,
+ bool success) {
+ LOG_IF(WARNING, !success) << service_name_ << " " << object_path_.value()
+ << ": Failed to connect to InterfacesAdded signal.";
+}
+
+void ObjectManager::InterfacesRemovedReceived(Signal* signal) {
+ DCHECK(signal);
+ MessageReader reader(signal);
+ ObjectPath object_path;
+ std::vector<std::string> interface_names;
+ if (!reader.PopObjectPath(&object_path) ||
+ !reader.PopArrayOfStrings(&interface_names)) {
+ LOG(WARNING) << service_name_ << " " << object_path_.value()
+ << ": InterfacesRemoved signal has incorrect parameters: "
+ << signal->ToString();
+ return;
+ }
+
+ for (size_t i = 0; i < interface_names.size(); ++i)
+ RemoveInterface(object_path, interface_names[i]);
+}
+
+void ObjectManager::InterfacesRemovedConnected(
+ const std::string& interface_name,
+ const std::string& signal_name,
+ bool success) {
+ LOG_IF(WARNING, !success) << service_name_ << " " << object_path_.value()
+ << ": Failed to connect to "
+ << "InterfacesRemoved signal.";
+}
+
+void ObjectManager::UpdateObject(const ObjectPath& object_path,
+ MessageReader* reader) {
+ DCHECK(reader);
+ MessageReader array_reader(NULL);
+ if (!reader->PopArray(&array_reader))
+ return;
+
+ while (array_reader.HasMoreData()) {
+ MessageReader dict_entry_reader(NULL);
+ std::string interface_name;
+ if (!array_reader.PopDictEntry(&dict_entry_reader) ||
+ !dict_entry_reader.PopString(&interface_name))
+ continue;
+
+ AddInterface(object_path, interface_name, &dict_entry_reader);
+ }
+}
+
+
+void ObjectManager::AddInterface(const ObjectPath& object_path,
+ const std::string& interface_name,
+ MessageReader* reader) {
+ InterfaceMap::iterator iiter = interface_map_.find(interface_name);
+ if (iiter == interface_map_.end())
+ return;
+ Interface* interface = iiter->second;
+
+ ObjectMap::iterator oiter = object_map_.find(object_path);
+ Object* object;
+ if (oiter == object_map_.end()) {
+ object = object_map_[object_path] = new Object;
+ object->object_proxy = bus_->GetObjectProxy(service_name_, object_path);
+ } else
+ object = oiter->second;
+
+ Object::PropertiesMap::iterator piter =
+ object->properties_map.find(interface_name);
+ PropertySet* property_set;
+ const bool interface_added = (piter == object->properties_map.end());
+ if (interface_added) {
+ property_set = object->properties_map[interface_name] =
+ interface->CreateProperties(object->object_proxy,
+ object_path, interface_name);
+ property_set->ConnectSignals();
+ } else
+ property_set = piter->second;
+
+ property_set->UpdatePropertiesFromReader(reader);
+
+ if (interface_added)
+ interface->ObjectAdded(object_path, interface_name);
+}
+
+void ObjectManager::RemoveInterface(const ObjectPath& object_path,
+ const std::string& interface_name) {
+ ObjectMap::iterator oiter = object_map_.find(object_path);
+ if (oiter == object_map_.end())
+ return;
+ Object* object = oiter->second;
+
+ Object::PropertiesMap::iterator piter =
+ object->properties_map.find(interface_name);
+ if (piter == object->properties_map.end())
+ return;
+
+ // Inform the interface before removing the properties structure or object
+ // in case it needs details from them to make its own decisions.
+ InterfaceMap::iterator iiter = interface_map_.find(interface_name);
+ if (iiter != interface_map_.end()) {
+ Interface* interface = iiter->second;
+ interface->ObjectRemoved(object_path, interface_name);
+ }
+
+ object->properties_map.erase(piter);
+
+ if (object->properties_map.empty()) {
+ object_map_.erase(oiter);
+ delete object;
+ }
+}
+
+} // namespace dbus

Powered by Google App Engine
This is Rietveld 408576698