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" 81320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/location.h" 92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/logging.h" 101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/metrics/histogram.h" 111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/strings/stringprintf.h" 121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/task_runner_util.h" 132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "dbus/bus.h" 141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "dbus/dbus_statistics.h" 152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "dbus/message.h" 162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "dbus/object_proxy.h" 172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "dbus/property.h" 181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "dbus/scoped_dbus_error.h" 191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "dbus/util.h" 202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace dbus { 222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ObjectManager::Object::Object() 242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : object_proxy(NULL) { 252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ObjectManager::Object::~Object() { 282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ObjectManager::ObjectManager(Bus* bus, 312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& service_name, 322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const ObjectPath& object_path) 332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : bus_(bus), 342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) service_name_(service_name), 352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) object_path_(object_path), 361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci setup_success_(false), 371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci cleanup_called_(false), 382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) weak_ptr_factory_(this) { 392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DVLOG(1) << "Creating ObjectManager for " << service_name_ 402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) << " " << object_path_.value(); 412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(bus_); 421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci bus_->AssertOnOriginThread(); 432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) object_proxy_ = bus_->GetObjectProxy(service_name_, object_path_); 44a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) object_proxy_->SetNameOwnerChangedCallback( 45a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::Bind(&ObjectManager::NameOwnerChanged, 46a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) weak_ptr_factory_.GetWeakPtr())); 472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Set up a match rule and a filter function to handle PropertiesChanged 491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // signals from the service. This is important to avoid any race conditions 501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // that might cause us to miss PropertiesChanged signals once all objects are 511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // initialized via GetManagedObjects. 521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::PostTaskAndReplyWithResult( 531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci bus_->GetDBusTaskRunner(), 541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci FROM_HERE, 551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::Bind(&ObjectManager::SetupMatchRuleAndFilter, this), 561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::Bind(&ObjectManager::OnSetupMatchRuleAndFilterComplete, this)); 572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ObjectManager::~ObjectManager() { 602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Clean up Object structures 612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (ObjectMap::iterator iter = object_map_.begin(); 622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) iter != object_map_.end(); ++iter) { 632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Object* object = iter->second; 642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (Object::PropertiesMap::iterator piter = object->properties_map.begin(); 662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) piter != object->properties_map.end(); ++piter) { 672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PropertySet* properties = piter->second; 682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) delete properties; 692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) delete object; 722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ObjectManager::RegisterInterface(const std::string& interface_name, 762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Interface* interface) { 772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) interface_map_[interface_name] = interface; 782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ObjectManager::UnregisterInterface(const std::string& interface_name) { 812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) InterfaceMap::iterator iter = interface_map_.find(interface_name); 822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (iter != interface_map_.end()) 832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) interface_map_.erase(iter); 842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)std::vector<ObjectPath> ObjectManager::GetObjects() { 872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::vector<ObjectPath> object_paths; 882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (ObjectMap::iterator iter = object_map_.begin(); 902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) iter != object_map_.end(); ++iter) 912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) object_paths.push_back(iter->first); 922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return object_paths; 942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)std::vector<ObjectPath> ObjectManager::GetObjectsWithInterface( 972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& interface_name) { 982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::vector<ObjectPath> object_paths; 992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (ObjectMap::iterator oiter = object_map_.begin(); 1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) oiter != object_map_.end(); ++oiter) { 1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Object* object = oiter->second; 1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Object::PropertiesMap::iterator piter = 1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) object->properties_map.find(interface_name); 1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (piter != object->properties_map.end()) 1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) object_paths.push_back(oiter->first); 1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return object_paths; 1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ObjectProxy* ObjectManager::GetObjectProxy(const ObjectPath& object_path) { 1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ObjectMap::iterator iter = object_map_.find(object_path); 1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (iter == object_map_.end()) 1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return NULL; 1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Object* object = iter->second; 1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return object->object_proxy; 1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)PropertySet* ObjectManager::GetProperties(const ObjectPath& object_path, 1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& interface_name) { 1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ObjectMap::iterator iter = object_map_.find(object_path); 1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (iter == object_map_.end()) 1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return NULL; 1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Object* object = iter->second; 1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Object::PropertiesMap::iterator piter = 1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) object->properties_map.find(interface_name); 1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (piter == object->properties_map.end()) 1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return NULL; 1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return piter->second; 1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ObjectManager::GetManagedObjects() { 1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MethodCall method_call(kObjectManagerInterface, 1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) kObjectManagerGetManagedObjects); 1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) object_proxy_->CallMethod( 1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &method_call, 1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ObjectProxy::TIMEOUT_USE_DEFAULT, 1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&ObjectManager::OnGetManagedObjects, 1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) weak_ptr_factory_.GetWeakPtr())); 1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid ObjectManager::CleanUp() { 1491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(bus_); 1501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci bus_->AssertOnDBusThread(); 1511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(!cleanup_called_); 1521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci cleanup_called_ = true; 1541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!setup_success_) 1561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return; 1571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!bus_->RemoveFilterFunction(&ObjectManager::HandleMessageThunk, this)) 1591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci LOG(ERROR) << "Failed to remove filter function"; 1601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ScopedDBusError error; 1621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci bus_->RemoveMatch(match_rule_, error.get()); 1631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (error.is_set()) 1641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci LOG(ERROR) << "Failed to remove match rule: " << match_rule_; 1651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci match_rule_.clear(); 1671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 1681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid ObjectManager::InitializeObjects() { 1701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(bus_); 1711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(object_proxy_); 1721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(setup_success_); 1731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // |object_proxy_| is no longer valid if the Bus was shut down before this 1751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // call. Don't initiate any other action from the origin thread. 1761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (cleanup_called_) 1771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return; 1781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci object_proxy_->ConnectToSignal( 1801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci kObjectManagerInterface, 1811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci kObjectManagerInterfacesAdded, 1821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::Bind(&ObjectManager::InterfacesAddedReceived, 1831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci weak_ptr_factory_.GetWeakPtr()), 1841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::Bind(&ObjectManager::InterfacesAddedConnected, 1851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci weak_ptr_factory_.GetWeakPtr())); 1861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci object_proxy_->ConnectToSignal( 1881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci kObjectManagerInterface, 1891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci kObjectManagerInterfacesRemoved, 1901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::Bind(&ObjectManager::InterfacesRemovedReceived, 1911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci weak_ptr_factory_.GetWeakPtr()), 1921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::Bind(&ObjectManager::InterfacesRemovedConnected, 1931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci weak_ptr_factory_.GetWeakPtr())); 1941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci GetManagedObjects(); 1961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 1971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccibool ObjectManager::SetupMatchRuleAndFilter() { 1991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(bus_); 2001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(!setup_success_); 2011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci bus_->AssertOnDBusThread(); 2021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 2031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (cleanup_called_) 2041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return false; 2051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 2061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!bus_->Connect() || !bus_->SetUpAsyncOperations()) 2071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return false; 2081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 2091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci service_name_owner_ = 2101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci bus_->GetServiceOwnerAndBlock(service_name_, Bus::SUPPRESS_ERRORS); 2111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 2121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const std::string match_rule = 2131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::StringPrintf( 2141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci "type='signal', sender='%s', interface='%s', member='%s'", 2151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci service_name_.c_str(), 2161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci kPropertiesInterface, 2171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci kPropertiesChanged); 2181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 2191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!bus_->AddFilterFunction(&ObjectManager::HandleMessageThunk, this)) { 2201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci LOG(ERROR) << "ObjectManager failed to add filter function"; 2211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return false; 2221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 2231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 2241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ScopedDBusError error; 2251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci bus_->AddMatch(match_rule, error.get()); 2261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (error.is_set()) { 2271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci LOG(ERROR) << "ObjectManager failed to add match rule \"" << match_rule 2281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci << "\". Got " << error.name() << ": " << error.message(); 2291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci bus_->RemoveFilterFunction(&ObjectManager::HandleMessageThunk, this); 2301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return false; 2311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 2321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 2331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci match_rule_ = match_rule; 2341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci setup_success_ = true; 2351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 2361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return true; 2371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 2381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 2391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid ObjectManager::OnSetupMatchRuleAndFilterComplete(bool success) { 2401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci LOG_IF(WARNING, !success) << service_name_ << " " << object_path_.value() 2411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci << ": Failed to set up match rule."; 2421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (success) 2431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci InitializeObjects(); 2441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 2451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 2461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// static 2471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciDBusHandlerResult ObjectManager::HandleMessageThunk(DBusConnection* connection, 2481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DBusMessage* raw_message, 2491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci void* user_data) { 2501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ObjectManager* self = reinterpret_cast<ObjectManager*>(user_data); 2511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return self->HandleMessage(connection, raw_message); 2521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 2531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 2541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciDBusHandlerResult ObjectManager::HandleMessage(DBusConnection* connection, 2551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DBusMessage* raw_message) { 2561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(bus_); 2571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci bus_->AssertOnDBusThread(); 2581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 2591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (dbus_message_get_type(raw_message) != DBUS_MESSAGE_TYPE_SIGNAL) 2601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; 2611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 2621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // raw_message will be unrefed on exit of the function. Increment the 2631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // reference so we can use it in Signal. 2641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci dbus_message_ref(raw_message); 2651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci scoped_ptr<Signal> signal( 2661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci Signal::FromRawMessage(raw_message)); 2671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 2681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const std::string interface = signal->GetInterface(); 2691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const std::string member = signal->GetMember(); 2701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 2711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci statistics::AddReceivedSignal(service_name_, interface, member); 2721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 2731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Only handle the PropertiesChanged signal. 2741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const std::string absolute_signal_name = 2751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci GetAbsoluteMemberName(interface, member); 2761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const std::string properties_changed_signal_name = 2771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci GetAbsoluteMemberName(kPropertiesInterface, kPropertiesChanged); 2781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (absolute_signal_name != properties_changed_signal_name) 2791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; 2801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 2811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci VLOG(1) << "Signal received: " << signal->ToString(); 2821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 2831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Make sure that the signal originated from the correct sender. 2841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci std::string sender = signal->GetSender(); 2851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (service_name_owner_ != sender) { 2861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci LOG(ERROR) << "Rejecting a message from a wrong sender."; 2871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci UMA_HISTOGRAM_COUNTS("DBus.RejectedSignalCount", 1); 2881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; 2891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 2901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 2911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const ObjectPath path = signal->GetPath(); 2921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 2931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (bus_->HasDBusThread()) { 2941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Post a task to run the method in the origin thread. Transfer ownership of 2951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // |signal| to NotifyPropertiesChanged, which will handle the clean up. 2961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci Signal* released_signal = signal.release(); 2971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci bus_->GetOriginTaskRunner()->PostTask( 2981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci FROM_HERE, 2991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::Bind(&ObjectManager::NotifyPropertiesChanged, 3001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci this, path, 3011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci released_signal)); 3021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } else { 3031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // If the D-Bus thread is not used, just call the callback on the 3041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // current thread. Transfer the ownership of |signal| to 3051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // NotifyPropertiesChanged. 3061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci NotifyPropertiesChanged(path, signal.release()); 3071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 3081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 3091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // We don't return DBUS_HANDLER_RESULT_HANDLED for signals because other 3101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // objects may be interested in them. (e.g. Signals from org.freedesktop.DBus) 3111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; 3121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 3131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 3141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid ObjectManager::NotifyPropertiesChanged( 3151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const dbus::ObjectPath object_path, 3161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci Signal* signal) { 3171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(bus_); 3181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci bus_->AssertOnOriginThread(); 3191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 3201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci NotifyPropertiesChangedHelper(object_path, signal); 3211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 3221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Delete the message on the D-Bus thread. See comments in HandleMessage. 3231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci bus_->GetDBusTaskRunner()->PostTask( 3241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci FROM_HERE, 3251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::Bind(&base::DeletePointer<Signal>, signal)); 3261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 3271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 3281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid ObjectManager::NotifyPropertiesChangedHelper( 3291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const dbus::ObjectPath object_path, 3301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci Signal* signal) { 3311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(bus_); 3321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci bus_->AssertOnOriginThread(); 3331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 3341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci MessageReader reader(signal); 3351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci std::string interface; 3361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!reader.PopString(&interface)) { 3371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci LOG(WARNING) << "Property changed signal has wrong parameters: " 3381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci << "expected interface name: " << signal->ToString(); 3391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return; 3401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 3411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 3421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci PropertySet* properties = GetProperties(object_path, interface); 3431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (properties) 3441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci properties->ChangedReceived(signal); 3451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 3461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 3472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ObjectManager::OnGetManagedObjects(Response* response) { 3482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (response != NULL) { 3492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MessageReader reader(response); 3502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MessageReader array_reader(NULL); 3512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!reader.PopArray(&array_reader)) 3522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 3532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) while (array_reader.HasMoreData()) { 3552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MessageReader dict_entry_reader(NULL); 3562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ObjectPath object_path; 3572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!array_reader.PopDictEntry(&dict_entry_reader) || 3582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) !dict_entry_reader.PopObjectPath(&object_path)) 3592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) continue; 3602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) UpdateObject(object_path, &dict_entry_reader); 3622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 3652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LOG(WARNING) << service_name_ << " " << object_path_.value() 3662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) << ": Failed to get managed objects"; 3672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ObjectManager::InterfacesAddedReceived(Signal* signal) { 3712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(signal); 3722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MessageReader reader(signal); 3732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ObjectPath object_path; 3742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!reader.PopObjectPath(&object_path)) { 3752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LOG(WARNING) << service_name_ << " " << object_path_.value() 3762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) << ": InterfacesAdded signal has incorrect parameters: " 3772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) << signal->ToString(); 3782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 3792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) UpdateObject(object_path, &reader); 3822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ObjectManager::InterfacesAddedConnected(const std::string& interface_name, 3852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& signal_name, 3862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool success) { 3872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LOG_IF(WARNING, !success) << service_name_ << " " << object_path_.value() 3882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) << ": Failed to connect to InterfacesAdded signal."; 3892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ObjectManager::InterfacesRemovedReceived(Signal* signal) { 3922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(signal); 3932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MessageReader reader(signal); 3942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ObjectPath object_path; 3952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::vector<std::string> interface_names; 3962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!reader.PopObjectPath(&object_path) || 3972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) !reader.PopArrayOfStrings(&interface_names)) { 3982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LOG(WARNING) << service_name_ << " " << object_path_.value() 3992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) << ": InterfacesRemoved signal has incorrect parameters: " 4002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) << signal->ToString(); 4012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 4022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (size_t i = 0; i < interface_names.size(); ++i) 4052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) RemoveInterface(object_path, interface_names[i]); 4062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ObjectManager::InterfacesRemovedConnected( 4092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& interface_name, 4102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& signal_name, 4112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool success) { 4122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LOG_IF(WARNING, !success) << service_name_ << " " << object_path_.value() 4132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) << ": Failed to connect to " 4142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) << "InterfacesRemoved signal."; 4152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ObjectManager::UpdateObject(const ObjectPath& object_path, 4182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MessageReader* reader) { 4192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(reader); 4202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MessageReader array_reader(NULL); 4212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!reader->PopArray(&array_reader)) 4222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 4232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) while (array_reader.HasMoreData()) { 4252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MessageReader dict_entry_reader(NULL); 4262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string interface_name; 4272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!array_reader.PopDictEntry(&dict_entry_reader) || 4282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) !dict_entry_reader.PopString(&interface_name)) 4292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) continue; 4302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) AddInterface(object_path, interface_name, &dict_entry_reader); 4322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ObjectManager::AddInterface(const ObjectPath& object_path, 4372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& interface_name, 4382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MessageReader* reader) { 4392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) InterfaceMap::iterator iiter = interface_map_.find(interface_name); 4402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (iiter == interface_map_.end()) 4412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 4422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Interface* interface = iiter->second; 4432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ObjectMap::iterator oiter = object_map_.find(object_path); 4452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Object* object; 4462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (oiter == object_map_.end()) { 4472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) object = object_map_[object_path] = new Object; 4482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) object->object_proxy = bus_->GetObjectProxy(service_name_, object_path); 4492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else 4502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) object = oiter->second; 4512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Object::PropertiesMap::iterator piter = 4532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) object->properties_map.find(interface_name); 4542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PropertySet* property_set; 4552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const bool interface_added = (piter == object->properties_map.end()); 4562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (interface_added) { 4572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) property_set = object->properties_map[interface_name] = 4582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) interface->CreateProperties(object->object_proxy, 4592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) object_path, interface_name); 4602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else 4612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) property_set = piter->second; 4622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) property_set->UpdatePropertiesFromReader(reader); 4642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (interface_added) 4662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) interface->ObjectAdded(object_path, interface_name); 4672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ObjectManager::RemoveInterface(const ObjectPath& object_path, 4702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& interface_name) { 4712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ObjectMap::iterator oiter = object_map_.find(object_path); 4722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (oiter == object_map_.end()) 4732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 4742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Object* object = oiter->second; 4752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Object::PropertiesMap::iterator piter = 4772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) object->properties_map.find(interface_name); 4782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (piter == object->properties_map.end()) 4792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 4802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Inform the interface before removing the properties structure or object 4822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // in case it needs details from them to make its own decisions. 4832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) InterfaceMap::iterator iiter = interface_map_.find(interface_name); 4842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (iiter != interface_map_.end()) { 4852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Interface* interface = iiter->second; 4862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) interface->ObjectRemoved(object_path, interface_name); 4872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) object->properties_map.erase(piter); 4902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (object->properties_map.empty()) { 4922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) object_map_.erase(oiter); 4932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) delete object; 4942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 497a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void ObjectManager::NameOwnerChanged(const std::string& old_owner, 498a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const std::string& new_owner) { 4991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci service_name_owner_ = new_owner; 5001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 501a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!old_owner.empty()) { 502a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ObjectMap::iterator iter = object_map_.begin(); 503a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) while (iter != object_map_.end()) { 504a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ObjectMap::iterator tmp = iter; 505a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ++iter; 506a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 507a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // PropertiesMap is mutated by RemoveInterface, and also Object is 508a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // destroyed; easier to collect the object path and interface names 509a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // and remove them safely. 510a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const dbus::ObjectPath object_path = tmp->first; 511a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) Object* object = tmp->second; 512a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) std::vector<std::string> interfaces; 513a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 514a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) for (Object::PropertiesMap::iterator piter = 515a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) object->properties_map.begin(); 516a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) piter != object->properties_map.end(); ++piter) 517a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) interfaces.push_back(piter->first); 518a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 519a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) for (std::vector<std::string>::iterator iiter = interfaces.begin(); 520a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) iiter != interfaces.end(); ++iiter) 521a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) RemoveInterface(object_path, *iiter); 522a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 523a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 524a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 525a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 526a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!new_owner.empty()) 527a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) GetManagedObjects(); 528a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 529a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 5302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace dbus 531