object_manager.cc revision 2a99a7e74a7f215066514fe81d2bfa6639d9eddd
12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2013 The Chromium Authors. All rights reserved.
22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file.
42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "dbus/object_manager.h"
62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/bind.h"
82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/logging.h"
92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "dbus/bus.h"
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "dbus/message.h"
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "dbus/object_proxy.h"
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "dbus/property.h"
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace dbus {
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ObjectManager::Object::Object()
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  : object_proxy(NULL) {
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ObjectManager::Object::~Object() {
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ObjectManager::ObjectManager(Bus* bus,
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                             const std::string& service_name,
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                             const ObjectPath& object_path)
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : bus_(bus),
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      service_name_(service_name),
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      object_path_(object_path),
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      weak_ptr_factory_(this) {
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DVLOG(1) << "Creating ObjectManager for " << service_name_
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)           << " " << object_path_.value();
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(bus_);
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  object_proxy_ = bus_->GetObjectProxy(service_name_, object_path_);
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  object_proxy_->ConnectToSignal(
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      kObjectManagerInterface,
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      kObjectManagerInterfacesAdded,
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(&ObjectManager::InterfacesAddedReceived,
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 weak_ptr_factory_.GetWeakPtr()),
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(&ObjectManager::InterfacesAddedConnected,
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 weak_ptr_factory_.GetWeakPtr()));
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  object_proxy_->ConnectToSignal(
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      kObjectManagerInterface,
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      kObjectManagerInterfacesRemoved,
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(&ObjectManager::InterfacesRemovedReceived,
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 weak_ptr_factory_.GetWeakPtr()),
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(&ObjectManager::InterfacesRemovedConnected,
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 weak_ptr_factory_.GetWeakPtr()));
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  GetManagedObjects();
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ObjectManager::~ObjectManager() {
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Clean up Object structures
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (ObjectMap::iterator iter = object_map_.begin();
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       iter != object_map_.end(); ++iter) {
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Object* object = iter->second;
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    for (Object::PropertiesMap::iterator piter = object->properties_map.begin();
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)         piter != object->properties_map.end(); ++piter) {
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      PropertySet* properties = piter->second;
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      delete properties;
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    delete object;
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ObjectManager::RegisterInterface(const std::string& interface_name,
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                      Interface* interface) {
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  interface_map_[interface_name] = interface;
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ObjectManager::UnregisterInterface(const std::string& interface_name) {
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  InterfaceMap::iterator iter = interface_map_.find(interface_name);
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (iter != interface_map_.end())
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    interface_map_.erase(iter);
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)std::vector<ObjectPath> ObjectManager::GetObjects() {
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::vector<ObjectPath> object_paths;
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (ObjectMap::iterator iter = object_map_.begin();
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       iter != object_map_.end(); ++iter)
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    object_paths.push_back(iter->first);
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return object_paths;
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)std::vector<ObjectPath> ObjectManager::GetObjectsWithInterface(
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const std::string& interface_name) {
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::vector<ObjectPath> object_paths;
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (ObjectMap::iterator oiter = object_map_.begin();
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       oiter != object_map_.end(); ++oiter) {
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Object* object = oiter->second;
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Object::PropertiesMap::iterator piter =
1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        object->properties_map.find(interface_name);
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (piter != object->properties_map.end())
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      object_paths.push_back(oiter->first);
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return object_paths;
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ObjectProxy* ObjectManager::GetObjectProxy(const ObjectPath& object_path) {
1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ObjectMap::iterator iter = object_map_.find(object_path);
1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (iter == object_map_.end())
1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return NULL;
1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Object* object = iter->second;
1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return object->object_proxy;
1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)PropertySet* ObjectManager::GetProperties(const ObjectPath& object_path,
1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                          const std::string& interface_name) {
1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ObjectMap::iterator iter = object_map_.find(object_path);
1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (iter == object_map_.end())
1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return NULL;
1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Object* object = iter->second;
1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Object::PropertiesMap::iterator piter =
1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      object->properties_map.find(interface_name);
1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (piter == object->properties_map.end())
1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return NULL;
1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return piter->second;
1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ObjectManager::GetManagedObjects() {
1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MethodCall method_call(kObjectManagerInterface,
1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                         kObjectManagerGetManagedObjects);
1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  object_proxy_->CallMethod(
1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      &method_call,
1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ObjectProxy::TIMEOUT_USE_DEFAULT,
1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(&ObjectManager::OnGetManagedObjects,
1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 weak_ptr_factory_.GetWeakPtr()));
1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ObjectManager::OnGetManagedObjects(Response* response) {
1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (response != NULL) {
1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MessageReader reader(response);
1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MessageReader array_reader(NULL);
1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!reader.PopArray(&array_reader))
1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return;
1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    while (array_reader.HasMoreData()) {
1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      MessageReader dict_entry_reader(NULL);
1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ObjectPath object_path;
1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      if (!array_reader.PopDictEntry(&dict_entry_reader) ||
1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          !dict_entry_reader.PopObjectPath(&object_path))
1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        continue;
1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      UpdateObject(object_path, &dict_entry_reader);
1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else {
1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    LOG(WARNING) << service_name_ << " " << object_path_.value()
1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 << ": Failed to get managed objects";
1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ObjectManager::InterfacesAddedReceived(Signal* signal) {
1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(signal);
1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MessageReader reader(signal);
1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ObjectPath object_path;
1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!reader.PopObjectPath(&object_path)) {
1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    LOG(WARNING) << service_name_ << " " << object_path_.value()
1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 << ": InterfacesAdded signal has incorrect parameters: "
1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 << signal->ToString();
1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UpdateObject(object_path, &reader);
1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ObjectManager::InterfacesAddedConnected(const std::string& interface_name,
1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                             const std::string& signal_name,
1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                             bool success) {
1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LOG_IF(WARNING, !success) << service_name_ << " " << object_path_.value()
1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                            << ": Failed to connect to InterfacesAdded signal.";
1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ObjectManager::InterfacesRemovedReceived(Signal* signal) {
1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(signal);
1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MessageReader reader(signal);
1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ObjectPath object_path;
1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::vector<std::string> interface_names;
1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!reader.PopObjectPath(&object_path) ||
1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      !reader.PopArrayOfStrings(&interface_names)) {
1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    LOG(WARNING) << service_name_ << " " << object_path_.value()
1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 << ": InterfacesRemoved signal has incorrect parameters: "
1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 << signal->ToString();
1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (size_t i = 0; i < interface_names.size(); ++i)
2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    RemoveInterface(object_path, interface_names[i]);
2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ObjectManager::InterfacesRemovedConnected(
2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& interface_name,
2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& signal_name,
2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    bool success) {
2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  LOG_IF(WARNING, !success) << service_name_ << " " << object_path_.value()
2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                            << ": Failed to connect to "
2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                            << "InterfacesRemoved signal.";
2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ObjectManager::UpdateObject(const ObjectPath& object_path,
2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 MessageReader* reader) {
2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(reader);
2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MessageReader array_reader(NULL);
2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!reader->PopArray(&array_reader))
2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  while (array_reader.HasMoreData()) {
2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MessageReader dict_entry_reader(NULL);
2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    std::string interface_name;
2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!array_reader.PopDictEntry(&dict_entry_reader) ||
2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        !dict_entry_reader.PopString(&interface_name))
2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      continue;
2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    AddInterface(object_path, interface_name, &dict_entry_reader);
2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ObjectManager::AddInterface(const ObjectPath& object_path,
2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 const std::string& interface_name,
2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 MessageReader* reader) {
2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  InterfaceMap::iterator iiter = interface_map_.find(interface_name);
2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (iiter == interface_map_.end())
2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Interface* interface = iiter->second;
2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ObjectMap::iterator oiter = object_map_.find(object_path);
2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Object* object;
2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (oiter == object_map_.end()) {
2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    object = object_map_[object_path] = new Object;
2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    object->object_proxy = bus_->GetObjectProxy(service_name_, object_path);
2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else
2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    object = oiter->second;
2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Object::PropertiesMap::iterator piter =
2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      object->properties_map.find(interface_name);
2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PropertySet* property_set;
2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const bool interface_added = (piter == object->properties_map.end());
2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (interface_added) {
2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    property_set = object->properties_map[interface_name] =
2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        interface->CreateProperties(object->object_proxy,
2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                    object_path, interface_name);
2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    property_set->ConnectSignals();
2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else
2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    property_set = piter->second;
2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  property_set->UpdatePropertiesFromReader(reader);
2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (interface_added)
2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    interface->ObjectAdded(object_path, interface_name);
2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ObjectManager::RemoveInterface(const ObjectPath& object_path,
2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                    const std::string& interface_name) {
2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ObjectMap::iterator oiter = object_map_.find(object_path);
2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (oiter == object_map_.end())
2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Object* object = oiter->second;
2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Object::PropertiesMap::iterator piter =
2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      object->properties_map.find(interface_name);
2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (piter == object->properties_map.end())
2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Inform the interface before removing the properties structure or object
2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // in case it needs details from them to make its own decisions.
2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  InterfaceMap::iterator iiter = interface_map_.find(interface_name);
2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (iiter != interface_map_.end()) {
2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Interface* interface = iiter->second;
2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    interface->ObjectRemoved(object_path, interface_name);
2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  object->properties_map.erase(piter);
2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (object->properties_map.empty()) {
2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    object_map_.erase(oiter);
2912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    delete object;
2922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace dbus
296