15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "dbus/bus.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h" 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 99ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#include "base/message_loop/message_loop.h" 10868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/message_loop/message_loop_proxy.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/stl_util.h" 12eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/strings/stringprintf.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/threading/thread.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/threading/thread_restrictions.h" 15eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/time/time.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "dbus/exported_object.h" 17868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "dbus/message.h" 182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "dbus/object_manager.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "dbus/object_path.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "dbus/object_proxy.h" 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "dbus/scoped_dbus_error.h" 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace dbus { 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kDisconnectedSignal[] = "Disconnected"; 282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kDisconnectedMatchRule[] = 292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "type='signal', path='/org/freedesktop/DBus/Local'," 302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "interface='org.freedesktop.DBus.Local', member='Disconnected'"; 312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 32868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// The NameOwnerChanged member in org.freedesktop.DBus 33868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)const char kNameOwnerChangedSignal[] = "NameOwnerChanged"; 34868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 35868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// The match rule used to filter for changes to a given service name owner. 36868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)const char kServiceNameOwnerChangeMatchRule[] = 37868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) "type='signal',interface='org.freedesktop.DBus'," 38868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) "member='NameOwnerChanged',path='/org/freedesktop/DBus'," 39868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) "sender='org.freedesktop.DBus',arg0='%s'"; 40868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The class is used for watching the file descriptor used for D-Bus 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// communication. 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class Watch : public base::MessagePumpLibevent::Watcher { 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) explicit Watch(DBusWatch* watch) 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : raw_watch_(watch) { 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dbus_watch_set_data(raw_watch_, this, NULL); 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~Watch() { 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dbus_watch_set_data(raw_watch_, NULL, NULL); 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns true if the underlying file descriptor is ready to be watched. 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool IsReadyToBeWatched() { 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return dbus_watch_get_enabled(raw_watch_); 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Starts watching the underlying file descriptor. 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void StartWatching() { 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int file_descriptor = dbus_watch_get_unix_fd(raw_watch_); 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int flags = dbus_watch_get_flags(raw_watch_); 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 64c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::MessageLoopForIO::Mode mode = base::MessageLoopForIO::WATCH_READ; 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((flags & DBUS_WATCH_READABLE) && (flags & DBUS_WATCH_WRITABLE)) 66c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) mode = base::MessageLoopForIO::WATCH_READ_WRITE; 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if (flags & DBUS_WATCH_READABLE) 68c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) mode = base::MessageLoopForIO::WATCH_READ; 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if (flags & DBUS_WATCH_WRITABLE) 70c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) mode = base::MessageLoopForIO::WATCH_WRITE; 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const bool persistent = true; // Watch persistently. 75c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const bool success = base::MessageLoopForIO::current()->WatchFileDescriptor( 76c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) file_descriptor, persistent, mode, &file_descriptor_watcher_, this); 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(success) << "Unable to allocate memory"; 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Stops watching the underlying file descriptor. 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void StopWatching() { 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file_descriptor_watcher_.StopWatchingFileDescriptor(); 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Implement MessagePumpLibevent::Watcher. 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void OnFileCanReadWithoutBlocking(int file_descriptor) OVERRIDE { 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const bool success = dbus_watch_handle(raw_watch_, DBUS_WATCH_READABLE); 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(success) << "Unable to allocate memory"; 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Implement MessagePumpLibevent::Watcher. 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void OnFileCanWriteWithoutBlocking(int file_descriptor) OVERRIDE { 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const bool success = dbus_watch_handle(raw_watch_, DBUS_WATCH_WRITABLE); 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(success) << "Unable to allocate memory"; 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DBusWatch* raw_watch_; 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::MessagePumpLibevent::FileDescriptorWatcher file_descriptor_watcher_; 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The class is used for monitoring the timeout used for D-Bus method 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// calls. 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Unlike Watch, Timeout is a ref counted object, to ensure that |this| of 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the object is is alive when HandleTimeout() is called. It's unlikely 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// but it may be possible that HandleTimeout() is called after 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Bus::OnRemoveTimeout(). That's why we don't simply delete the object in 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Bus::OnRemoveTimeout(). 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class Timeout : public base::RefCountedThreadSafe<Timeout> { 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) explicit Timeout(DBusTimeout* timeout) 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : raw_timeout_(timeout), 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) monitoring_is_active_(false), 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) is_completed(false) { 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dbus_timeout_set_data(raw_timeout_, this, NULL); 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddRef(); // Balanced on Complete(). 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns true if the timeout is ready to be monitored. 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool IsReadyToBeMonitored() { 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return dbus_timeout_get_enabled(raw_timeout_); 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Starts monitoring the timeout. 1267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) void StartMonitoring(Bus* bus) { 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bus->PostDelayedTaskToDBusThread(FROM_HERE, 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&Timeout::HandleTimeout, 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this), 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetInterval()); 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) monitoring_is_active_ = true; 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Stops monitoring the timeout. 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void StopMonitoring() { 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We cannot take back the delayed task we posted in 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // StartMonitoring(), so we just mark the monitoring is inactive now. 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) monitoring_is_active_ = false; 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns the interval. 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeDelta GetInterval() { 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return base::TimeDelta::FromMilliseconds( 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dbus_timeout_get_interval(raw_timeout_)); 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Cleans up the raw_timeout and marks that timeout is completed. 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // See the class comment above for why we are doing this. 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void Complete() { 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dbus_timeout_set_data(raw_timeout_, NULL, NULL); 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) is_completed = true; 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Release(); 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) friend class base::RefCountedThreadSafe<Timeout>; 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ~Timeout() { 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Handles the timeout. 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void HandleTimeout() { 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If the timeout is marked completed, we should do nothing. This can 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // occur if this function is called after Bus::OnRemoveTimeout(). 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (is_completed) 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Skip if monitoring is canceled. 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!monitoring_is_active_) 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const bool success = dbus_timeout_handle(raw_timeout_); 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(success) << "Unable to allocate memory"; 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DBusTimeout* raw_timeout_; 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool monitoring_is_active_; 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool is_completed; 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Bus::Options::Options() 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : bus_type(SESSION), 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) connection_type(PRIVATE) { 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Bus::Options::~Options() { 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Bus::Bus(const Options& options) 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : bus_type_(options.bus_type), 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) connection_type_(options.connection_type), 1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) dbus_task_runner_(options.dbus_task_runner), 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) on_shutdown_(false /* manual_reset */, false /* initially_signaled */), 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) connection_(NULL), 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) origin_thread_id_(base::PlatformThread::CurrentId()), 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) async_operations_set_up_(false), 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shutdown_completed_(false), 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) num_pending_watches_(0), 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) num_pending_timeouts_(0), 2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) address_(options.address), 2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) on_disconnected_closure_(options.disconnected_callback) { 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This is safe to call multiple times. 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dbus_threads_init_default(); 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The origin message loop is unnecessary if the client uses synchronous 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // functions only. 206c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (base::MessageLoop::current()) 207c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) origin_task_runner_ = base::MessageLoop::current()->message_loop_proxy(); 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Bus::~Bus() { 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!connection_); 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(owned_service_names_.empty()); 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(match_rules_added_.empty()); 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(filter_functions_added_.empty()); 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(registered_object_paths_.empty()); 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(0, num_pending_watches_); 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(satorux): This check fails occasionally in browser_tests for tests 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // that run very quickly. Perhaps something does not have time to clean up. 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Despite the check failing, the tests seem to run fine. crosbug.com/23416 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // DCHECK_EQ(0, num_pending_timeouts_); 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ObjectProxy* Bus::GetObjectProxy(const std::string& service_name, 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ObjectPath& object_path) { 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return GetObjectProxyWithOptions(service_name, object_path, 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ObjectProxy::DEFAULT_OPTIONS); 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ObjectProxy* Bus::GetObjectProxyWithOptions(const std::string& service_name, 2307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const ObjectPath& object_path, 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int options) { 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AssertOnOriginThread(); 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Check if we already have the requested object proxy. 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ObjectProxyTable::key_type key(service_name + object_path.value(), 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) options); 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ObjectProxyTable::iterator iter = object_proxy_table_.find(key); 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (iter != object_proxy_table_.end()) { 239868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return iter->second.get(); 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<ObjectProxy> object_proxy = 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new ObjectProxy(this, service_name, object_path, options); 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) object_proxy_table_[key] = object_proxy; 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return object_proxy.get(); 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool Bus::RemoveObjectProxy(const std::string& service_name, 2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const ObjectPath& object_path, 2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::Closure& callback) { 2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return RemoveObjectProxyWithOptions(service_name, object_path, 2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ObjectProxy::DEFAULT_OPTIONS, 2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) callback); 2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool Bus::RemoveObjectProxyWithOptions(const std::string& service_name, 2587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const ObjectPath& object_path, 2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int options, 2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::Closure& callback) { 2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) AssertOnOriginThread(); 2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Check if we have the requested object proxy. 2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const ObjectProxyTable::key_type key(service_name + object_path.value(), 2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) options); 2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ObjectProxyTable::iterator iter = object_proxy_table_.find(key); 2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (iter != object_proxy_table_.end()) { 2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Object is present. Remove it now and Detach in the DBus thread. 2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PostTaskToDBusThread(FROM_HERE, base::Bind( 2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &Bus::RemoveObjectProxyInternal, 2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) this, iter->second, callback)); 2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) object_proxy_table_.erase(iter); 2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void Bus::RemoveObjectProxyInternal(scoped_refptr<ObjectProxy> object_proxy, 2807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const base::Closure& callback) { 2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) AssertOnDBusThread(); 2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) object_proxy.get()->Detach(); 2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PostTaskToOriginThread(FROM_HERE, callback); 2862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ExportedObject* Bus::GetExportedObject(const ObjectPath& object_path) { 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AssertOnOriginThread(); 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Check if we already have the requested exported object. 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExportedObjectTable::iterator iter = exported_object_table_.find(object_path); 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (iter != exported_object_table_.end()) { 294868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return iter->second.get(); 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<ExportedObject> exported_object = 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new ExportedObject(this, object_path); 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exported_object_table_[object_path] = exported_object; 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return exported_object.get(); 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Bus::UnregisterExportedObject(const ObjectPath& object_path) { 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AssertOnOriginThread(); 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Remove the registered object from the table first, to allow a new 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // GetExportedObject() call to return a new object, rather than this one. 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExportedObjectTable::iterator iter = exported_object_table_.find(object_path); 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (iter == exported_object_table_.end()) 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<ExportedObject> exported_object = iter->second; 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exported_object_table_.erase(iter); 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Post the task to perform the final unregistration to the D-Bus thread. 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Since the registration also happens on the D-Bus thread in 3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // TryRegisterObjectPath(), and the task runner we post to is a 3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // SequencedTaskRunner, there is a guarantee that this will happen before any 3202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // future registration call. 3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PostTaskToDBusThread(FROM_HERE, 3222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&Bus::UnregisterExportedObjectInternal, 3232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) this, exported_object)); 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Bus::UnregisterExportedObjectInternal( 3277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_refptr<ExportedObject> exported_object) { 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AssertOnDBusThread(); 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exported_object->Unregister(); 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ObjectManager* Bus::GetObjectManager(const std::string& service_name, 3342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const ObjectPath& object_path) { 3352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) AssertOnOriginThread(); 3362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Check if we already have the requested object manager. 3382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const ObjectManagerTable::key_type key(service_name + object_path.value()); 3392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ObjectManagerTable::iterator iter = object_manager_table_.find(key); 3402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (iter != object_manager_table_.end()) { 341868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return iter->second.get(); 3422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_refptr<ObjectManager> object_manager = 3452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) new ObjectManager(this, service_name, object_path); 3462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) object_manager_table_[key] = object_manager; 3472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return object_manager.get(); 3492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void Bus::RemoveObjectManager(const std::string& service_name, 3522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const ObjectPath& object_path) { 3532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) AssertOnOriginThread(); 3542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const ObjectManagerTable::key_type key(service_name + object_path.value()); 3562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ObjectManagerTable::iterator iter = object_manager_table_.find(key); 3572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (iter == object_manager_table_.end()) 3582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 3592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_refptr<ObjectManager> object_manager = iter->second; 3612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) object_manager_table_.erase(iter); 3622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void Bus::GetManagedObjects() { 3652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (ObjectManagerTable::iterator iter = object_manager_table_.begin(); 3662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) iter != object_manager_table_.end(); ++iter) { 3672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) iter->second->GetManagedObjects(); 3682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool Bus::Connect() { 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // dbus_bus_get_private() and dbus_bus_get() are blocking calls. 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AssertOnDBusThread(); 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Check if it's already initialized. 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (connection_) 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ScopedDBusError error; 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (bus_type_ == CUSTOM_ADDRESS) { 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (connection_type_ == PRIVATE) { 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) connection_ = dbus_connection_open_private(address_.c_str(), error.get()); 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) connection_ = dbus_connection_open(address_.c_str(), error.get()); 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const DBusBusType dbus_bus_type = static_cast<DBusBusType>(bus_type_); 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (connection_type_ == PRIVATE) { 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) connection_ = dbus_bus_get_private(dbus_bus_type, error.get()); 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) connection_ = dbus_bus_get(dbus_bus_type, error.get()); 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!connection_) { 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "Failed to connect to the bus: " 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << (error.is_set() ? error.message() : ""); 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (bus_type_ == CUSTOM_ADDRESS) { 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We should call dbus_bus_register here, otherwise unique name can not be 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // acquired. According to dbus specification, it is responsible to call 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // org.freedesktop.DBus.Hello method at the beging of bus connection to 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // acquire unique name. In the case of dbus_bus_get, dbus_bus_register is 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // called internally. 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!dbus_bus_register(connection_, error.get())) { 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "Failed to register the bus component: " 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << (error.is_set() ? error.message() : ""); 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We shouldn't exit on the disconnected signal. 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dbus_connection_set_exit_on_disconnect(connection_, false); 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Watch Disconnected signal. 4162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) AddFilterFunction(Bus::OnConnectionDisconnectedFilter, this); 4172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) AddMatch(kDisconnectedMatchRule, error.get()); 4182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void Bus::ClosePrivateConnection() { 4232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // dbus_connection_close is blocking call. 4242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) AssertOnDBusThread(); 4252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK_EQ(PRIVATE, connection_type_) 4262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) << "non-private connection should not be closed"; 4272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) dbus_connection_close(connection_); 4282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Bus::ShutdownAndBlock() { 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AssertOnDBusThread(); 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (shutdown_completed_) 4342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; // Already shutdowned, just return. 4352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Unregister the exported objects. 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (ExportedObjectTable::iterator iter = exported_object_table_.begin(); 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) iter != exported_object_table_.end(); ++iter) { 4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) iter->second->Unregister(); 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Release all service names. 4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (std::set<std::string>::iterator iter = owned_service_names_.begin(); 4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) iter != owned_service_names_.end();) { 4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This is a bit tricky but we should increment the iter here as 4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // ReleaseOwnership() may remove |service_name| from the set. 4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& service_name = *iter++; 4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReleaseOwnership(service_name); 4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!owned_service_names_.empty()) { 4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "Failed to release all service names. # of services left: " 4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << owned_service_names_.size(); 4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Detach from the remote objects. 4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (ObjectProxyTable::iterator iter = object_proxy_table_.begin(); 4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) iter != object_proxy_table_.end(); ++iter) { 4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) iter->second->Detach(); 4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Release object proxies and exported objects here. We should do this 4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // here rather than in the destructor to avoid memory leaks due to 4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // cyclic references. 4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) object_proxy_table_.clear(); 4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) exported_object_table_.clear(); 4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Private connection should be closed. 4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (connection_) { 4692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Remove Disconnected watcher. 4702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ScopedDBusError error; 4712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) RemoveFilterFunction(Bus::OnConnectionDisconnectedFilter, this); 4722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) RemoveMatch(kDisconnectedMatchRule, error.get()); 4732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (connection_type_ == PRIVATE) 4752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ClosePrivateConnection(); 4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // dbus_connection_close() won't unref. 4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dbus_connection_unref(connection_); 4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) connection_ = NULL; 4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shutdown_completed_ = true; 4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Bus::ShutdownOnDBusThreadAndBlock() { 4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AssertOnOriginThread(); 4862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(dbus_task_runner_.get()); 4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PostTaskToDBusThread(FROM_HERE, base::Bind( 4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &Bus::ShutdownOnDBusThreadAndBlockInternal, 4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this)); 4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // http://crbug.com/125222 4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::ThreadRestrictions::ScopedAllowWait allow_wait; 4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Wait until the shutdown is complete on the D-Bus thread. 4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The shutdown should not hang, but set timeout just in case. 4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int kTimeoutSecs = 3; 4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::TimeDelta timeout(base::TimeDelta::FromSeconds(kTimeoutSecs)); 4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const bool signaled = on_shutdown_.TimedWait(timeout); 5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG_IF(ERROR, !signaled) << "Failed to shutdown the bus"; 5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Bus::RequestOwnership(const std::string& service_name, 504a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ServiceOwnershipOptions options, 5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnOwnershipCallback on_ownership_callback) { 5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AssertOnOriginThread(); 5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PostTaskToDBusThread(FROM_HERE, base::Bind( 5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &Bus::RequestOwnershipInternal, 510a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) this, service_name, options, on_ownership_callback)); 5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Bus::RequestOwnershipInternal(const std::string& service_name, 514a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ServiceOwnershipOptions options, 5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnOwnershipCallback on_ownership_callback) { 5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AssertOnDBusThread(); 5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool success = Connect(); 5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (success) 520a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) success = RequestOwnershipAndBlock(service_name, options); 5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PostTaskToOriginThread(FROM_HERE, 5232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(on_ownership_callback, 5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) service_name, 5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) success)); 5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 528a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)bool Bus::RequestOwnershipAndBlock(const std::string& service_name, 529a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ServiceOwnershipOptions options) { 5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(connection_); 5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // dbus_bus_request_name() is a blocking call. 5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AssertOnDBusThread(); 5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Check if we already own the service name. 5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (owned_service_names_.find(service_name) != owned_service_names_.end()) { 5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ScopedDBusError error; 5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int result = dbus_bus_request_name(connection_, 5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) service_name.c_str(), 542a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) options, 5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) error.get()); 5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (result != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) { 5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "Failed to get the ownership of " << service_name << ": " 5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << (error.is_set() ? error.message() : ""); 5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) owned_service_names_.insert(service_name); 5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool Bus::ReleaseOwnership(const std::string& service_name) { 5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(connection_); 5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // dbus_bus_request_name() is a blocking call. 5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AssertOnDBusThread(); 5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Check if we already own the service name. 5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::set<std::string>::iterator found = 5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) owned_service_names_.find(service_name); 5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (found == owned_service_names_.end()) { 5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << service_name << " is not owned by the bus"; 5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ScopedDBusError error; 5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int result = dbus_bus_release_name(connection_, service_name.c_str(), 5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) error.get()); 5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (result == DBUS_RELEASE_NAME_REPLY_RELEASED) { 5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) owned_service_names_.erase(found); 5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "Failed to release the ownership of " << service_name << ": " 574a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) << (error.is_set() ? error.message() : "") 575a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) << ", result code: " << result; 5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool Bus::SetUpAsyncOperations() { 5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(connection_); 5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AssertOnDBusThread(); 5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (async_operations_set_up_) 5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Process all the incoming data if any, so that OnDispatchStatus() will 5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // be called when the incoming data is ready. 5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ProcessAllIncomingDataIfAny(); 5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool success = dbus_connection_set_watch_functions(connection_, 5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &Bus::OnAddWatchThunk, 5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &Bus::OnRemoveWatchThunk, 5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &Bus::OnToggleWatchThunk, 5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this, 5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NULL); 5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(success) << "Unable to allocate memory"; 5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) success = dbus_connection_set_timeout_functions(connection_, 6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &Bus::OnAddTimeoutThunk, 6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &Bus::OnRemoveTimeoutThunk, 6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &Bus::OnToggleTimeoutThunk, 6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this, 6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NULL); 6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(success) << "Unable to allocate memory"; 6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dbus_connection_set_dispatch_status_function( 6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) connection_, 6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &Bus::OnDispatchStatusChangedThunk, 6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this, 6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NULL); 6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) async_operations_set_up_ = true; 6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DBusMessage* Bus::SendWithReplyAndBlock(DBusMessage* request, 6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int timeout_ms, 6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DBusError* error) { 6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(connection_); 6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AssertOnDBusThread(); 6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return dbus_connection_send_with_reply_and_block( 6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) connection_, request, timeout_ms, error); 6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Bus::SendWithReply(DBusMessage* request, 6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DBusPendingCall** pending_call, 6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int timeout_ms) { 6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(connection_); 6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AssertOnDBusThread(); 6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const bool success = dbus_connection_send_with_reply( 6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) connection_, request, pending_call, timeout_ms); 6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(success) << "Unable to allocate memory"; 6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Bus::Send(DBusMessage* request, uint32* serial) { 6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(connection_); 6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AssertOnDBusThread(); 6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const bool success = dbus_connection_send(connection_, request, serial); 6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(success) << "Unable to allocate memory"; 6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool Bus::AddFilterFunction(DBusHandleMessageFunction filter_function, 6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void* user_data) { 6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(connection_); 6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AssertOnDBusThread(); 6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::pair<DBusHandleMessageFunction, void*> filter_data_pair = 6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::make_pair(filter_function, user_data); 6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (filter_functions_added_.find(filter_data_pair) != 6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) filter_functions_added_.end()) { 6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VLOG(1) << "Filter function already exists: " << filter_function 6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << " with associated data: " << user_data; 6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const bool success = dbus_connection_add_filter( 6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) connection_, filter_function, user_data, NULL); 6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(success) << "Unable to allocate memory"; 6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) filter_functions_added_.insert(filter_data_pair); 6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool Bus::RemoveFilterFunction(DBusHandleMessageFunction filter_function, 6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void* user_data) { 6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(connection_); 6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AssertOnDBusThread(); 6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::pair<DBusHandleMessageFunction, void*> filter_data_pair = 6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::make_pair(filter_function, user_data); 6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (filter_functions_added_.find(filter_data_pair) == 6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) filter_functions_added_.end()) { 6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VLOG(1) << "Requested to remove an unknown filter function: " 6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << filter_function 6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << " with associated data: " << user_data; 6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dbus_connection_remove_filter(connection_, filter_function, user_data); 6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) filter_functions_added_.erase(filter_data_pair); 6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Bus::AddMatch(const std::string& match_rule, DBusError* error) { 6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(connection_); 6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AssertOnDBusThread(); 6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::map<std::string, int>::iterator iter = 6932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) match_rules_added_.find(match_rule); 6942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (iter != match_rules_added_.end()) { 6952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // The already existing rule's counter is incremented. 6962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) iter->second++; 6972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VLOG(1) << "Match rule already exists: " << match_rule; 6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dbus_bus_add_match(connection_, match_rule.c_str(), error); 7032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) match_rules_added_[match_rule] = 1; 7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool Bus::RemoveMatch(const std::string& match_rule, DBusError* error) { 7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(connection_); 7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AssertOnDBusThread(); 7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::map<std::string, int>::iterator iter = 7112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) match_rules_added_.find(match_rule); 7122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (iter == match_rules_added_.end()) { 7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "Requested to remove an unknown match rule: " << match_rule; 7142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // The rule's counter is decremented and the rule is deleted when reachs 0. 7182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) iter->second--; 7192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (iter->second == 0) { 7202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) dbus_bus_remove_match(connection_, match_rule.c_str(), error); 7212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) match_rules_added_.erase(match_rule); 7222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 7232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool Bus::TryRegisterObjectPath(const ObjectPath& object_path, 7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const DBusObjectPathVTable* vtable, 7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void* user_data, 7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DBusError* error) { 7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(connection_); 7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AssertOnDBusThread(); 7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (registered_object_paths_.find(object_path) != 7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) registered_object_paths_.end()) { 7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "Object path already registered: " << object_path.value(); 7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const bool success = dbus_connection_try_register_object_path( 7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) connection_, 7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) object_path.value().c_str(), 7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) vtable, 7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) user_data, 7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) error); 7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (success) 7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) registered_object_paths_.insert(object_path); 7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return success; 7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Bus::UnregisterObjectPath(const ObjectPath& object_path) { 7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(connection_); 7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AssertOnDBusThread(); 7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (registered_object_paths_.find(object_path) == 7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) registered_object_paths_.end()) { 7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "Requested to unregister an unknown object path: " 7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << object_path.value(); 7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const bool success = dbus_connection_unregister_object_path( 7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) connection_, 7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) object_path.value().c_str()); 7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(success) << "Unable to allocate memory"; 7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) registered_object_paths_.erase(object_path); 7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Bus::ShutdownOnDBusThreadAndBlockInternal() { 7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AssertOnDBusThread(); 7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ShutdownAndBlock(); 7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) on_shutdown_.Signal(); 7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Bus::ProcessAllIncomingDataIfAny() { 7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AssertOnDBusThread(); 7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // As mentioned at the class comment in .h file, connection_ can be NULL. 7792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!connection_) 7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // It is safe and necessary to call dbus_connection_get_dispatch_status even 7832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // if the connection is lost. Otherwise we will miss "Disconnected" signal. 7842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // (crbug.com/174431) 7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (dbus_connection_get_dispatch_status(connection_) == 7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DBUS_DISPATCH_DATA_REMAINS) { 7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (dbus_connection_dispatch(connection_) == 7887d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) DBUS_DISPATCH_DATA_REMAINS) { 7897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) } 7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 793b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)void Bus::PostTaskToDBusThreadAndReply( 794b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) const tracked_objects::Location& from_here, 795b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) const base::Closure& task, 796b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) const base::Closure& reply) { 797b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) AssertOnOriginThread(); 798b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 799b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (dbus_task_runner_.get()) { 800b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (!dbus_task_runner_->PostTaskAndReply(from_here, task, reply)) { 801b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) LOG(WARNING) << "Failed to post a task to the D-Bus thread message loop"; 802b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) } 803b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) } else { 804b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) DCHECK(origin_task_runner_.get()); 805b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (!origin_task_runner_->PostTaskAndReply(from_here, task, reply)) { 806b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) LOG(WARNING) << "Failed to post a task to the origin message loop"; 807b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) } 808b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) } 809b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)} 810b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Bus::PostTaskToOriginThread(const tracked_objects::Location& from_here, 8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::Closure& task) { 8132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(origin_task_runner_.get()); 8142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!origin_task_runner_->PostTask(from_here, task)) { 8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(WARNING) << "Failed to post a task to the origin message loop"; 8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Bus::PostTaskToDBusThread(const tracked_objects::Location& from_here, 8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::Closure& task) { 8212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (dbus_task_runner_.get()) { 8222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!dbus_task_runner_->PostTask(from_here, task)) { 8235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(WARNING) << "Failed to post a task to the D-Bus thread message loop"; 8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 8262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(origin_task_runner_.get()); 8272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!origin_task_runner_->PostTask(from_here, task)) { 8285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(WARNING) << "Failed to post a task to the origin message loop"; 8295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Bus::PostDelayedTaskToDBusThread( 8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const tracked_objects::Location& from_here, 8355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::Closure& task, 8365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeDelta delay) { 8372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (dbus_task_runner_.get()) { 8382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!dbus_task_runner_->PostDelayedTask( 8395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) from_here, task, delay)) { 8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(WARNING) << "Failed to post a task to the D-Bus thread message loop"; 8415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 8432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(origin_task_runner_.get()); 8442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!origin_task_runner_->PostDelayedTask(from_here, task, delay)) { 8455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(WARNING) << "Failed to post a task to the origin message loop"; 8465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool Bus::HasDBusThread() { 8512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return dbus_task_runner_.get() != NULL; 8525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Bus::AssertOnOriginThread() { 8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(origin_thread_id_, base::PlatformThread::CurrentId()); 8565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Bus::AssertOnDBusThread() { 8595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::ThreadRestrictions::AssertIOAllowed(); 8605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (dbus_task_runner_.get()) { 8622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(dbus_task_runner_->RunsTasksOnCurrentThread()); 8635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 8645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AssertOnOriginThread(); 8655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 868c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)std::string Bus::GetServiceOwnerAndBlock(const std::string& service_name, 869c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GetServiceOwnerOption options) { 870c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) AssertOnDBusThread(); 871c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 872c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) MethodCall get_name_owner_call("org.freedesktop.DBus", "GetNameOwner"); 873c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) MessageWriter writer(&get_name_owner_call); 874c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) writer.AppendString(service_name); 875c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) VLOG(1) << "Method call: " << get_name_owner_call.ToString(); 876c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 877c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const ObjectPath obj_path("/org/freedesktop/DBus"); 878c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!get_name_owner_call.SetDestination("org.freedesktop.DBus") || 879c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) !get_name_owner_call.SetPath(obj_path)) { 880c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (options == REPORT_ERRORS) 881c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) LOG(ERROR) << "Failed to get name owner."; 882c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return ""; 883c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 884c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 885c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ScopedDBusError error; 886c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DBusMessage* response_message = 887c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SendWithReplyAndBlock(get_name_owner_call.raw_message(), 888c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ObjectProxy::TIMEOUT_USE_DEFAULT, 889c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) error.get()); 890c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!response_message) { 891c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (options == REPORT_ERRORS) { 892c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) LOG(ERROR) << "Failed to get name owner. Got " << error.name() << ": " 893c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) << error.message(); 894c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 895c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return ""; 896c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 897c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 898c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<Response> response(Response::FromRawMessage(response_message)); 899c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) MessageReader reader(response.get()); 900c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 901c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::string service_owner; 902c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!reader.PopString(&service_owner)) 903c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) service_owner.clear(); 904c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return service_owner; 905c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 906c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 907c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void Bus::GetServiceOwner(const std::string& service_name, 908c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const GetServiceOwnerCallback& callback) { 909c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) AssertOnOriginThread(); 910c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 911c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) PostTaskToDBusThread( 912c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) FROM_HERE, 913c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Bind(&Bus::GetServiceOwnerInternal, this, service_name, callback)); 914c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 915c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 916c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void Bus::GetServiceOwnerInternal(const std::string& service_name, 917c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const GetServiceOwnerCallback& callback) { 918c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) AssertOnDBusThread(); 919c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 920c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::string service_owner; 921c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (Connect()) 922b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) service_owner = GetServiceOwnerAndBlock(service_name, SUPPRESS_ERRORS); 923c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) PostTaskToOriginThread(FROM_HERE, base::Bind(callback, service_owner)); 924c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 925c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 926868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void Bus::ListenForServiceOwnerChange( 927868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const std::string& service_name, 928868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const GetServiceOwnerCallback& callback) { 929868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) AssertOnOriginThread(); 930868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(!service_name.empty()); 931868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(!callback.is_null()); 932868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 933868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) PostTaskToDBusThread(FROM_HERE, 934868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) base::Bind(&Bus::ListenForServiceOwnerChangeInternal, 935868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) this, service_name, callback)); 936868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 937868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 938868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void Bus::ListenForServiceOwnerChangeInternal( 939868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const std::string& service_name, 940868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const GetServiceOwnerCallback& callback) { 941868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) AssertOnDBusThread(); 942868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(!service_name.empty()); 943868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(!callback.is_null()); 944868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 945868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!Connect() || !SetUpAsyncOperations()) 946868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 947868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 948868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (service_owner_changed_listener_map_.empty()) { 949868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) bool filter_added = 950868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) AddFilterFunction(Bus::OnServiceOwnerChangedFilter, this); 951868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(filter_added); 952868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 953868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 954868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ServiceOwnerChangedListenerMap::iterator it = 955868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) service_owner_changed_listener_map_.find(service_name); 956868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (it == service_owner_changed_listener_map_.end()) { 957868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Add a match rule for the new service name. 958868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const std::string name_owner_changed_match_rule = 959868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) base::StringPrintf(kServiceNameOwnerChangeMatchRule, 960868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) service_name.c_str()); 961868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ScopedDBusError error; 962868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) AddMatch(name_owner_changed_match_rule, error.get()); 963868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (error.is_set()) { 964868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) LOG(ERROR) << "Failed to add match rule for " << service_name 965868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) << ". Got " << error.name() << ": " << error.message(); 966868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 967868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 968868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 969868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) service_owner_changed_listener_map_[service_name].push_back(callback); 970868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 971868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 972868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 973868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Check if the callback has already been added. 974868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) std::vector<GetServiceOwnerCallback>& callbacks = it->second; 975868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) for (size_t i = 0; i < callbacks.size(); ++i) { 976868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (callbacks[i].Equals(callback)) 977868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 978868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 979868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) callbacks.push_back(callback); 980868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 981868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 982868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void Bus::UnlistenForServiceOwnerChange( 983868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const std::string& service_name, 984868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const GetServiceOwnerCallback& callback) { 985868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) AssertOnOriginThread(); 986868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(!service_name.empty()); 987868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(!callback.is_null()); 988868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 989868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) PostTaskToDBusThread(FROM_HERE, 990868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) base::Bind(&Bus::UnlistenForServiceOwnerChangeInternal, 991868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) this, service_name, callback)); 992868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 993868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 994868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void Bus::UnlistenForServiceOwnerChangeInternal( 995868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const std::string& service_name, 996868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const GetServiceOwnerCallback& callback) { 997868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) AssertOnDBusThread(); 998868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(!service_name.empty()); 999868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(!callback.is_null()); 1000868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1001868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ServiceOwnerChangedListenerMap::iterator it = 1002868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) service_owner_changed_listener_map_.find(service_name); 1003868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (it == service_owner_changed_listener_map_.end()) 1004868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 1005868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1006868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) std::vector<GetServiceOwnerCallback>& callbacks = it->second; 1007868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) for (size_t i = 0; i < callbacks.size(); ++i) { 1008868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (callbacks[i].Equals(callback)) { 1009868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) callbacks.erase(callbacks.begin() + i); 1010868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) break; // There can be only one. 1011868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1012868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1013868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!callbacks.empty()) 1014868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 1015868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1016868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Last callback for |service_name| has been removed, remove match rule. 1017868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const std::string name_owner_changed_match_rule = 1018868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) base::StringPrintf(kServiceNameOwnerChangeMatchRule, 1019868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) service_name.c_str()); 1020868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ScopedDBusError error; 1021868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) RemoveMatch(name_owner_changed_match_rule, error.get()); 1022868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // And remove |service_owner_changed_listener_map_| entry. 1023868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) service_owner_changed_listener_map_.erase(it); 1024868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1025868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (service_owner_changed_listener_map_.empty()) { 1026868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) bool filter_removed = 1027868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) RemoveFilterFunction(Bus::OnServiceOwnerChangedFilter, this); 1028868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(filter_removed); 1029868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1030868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 1031868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 10325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)dbus_bool_t Bus::OnAddWatch(DBusWatch* raw_watch) { 10335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AssertOnDBusThread(); 10345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // watch will be deleted when raw_watch is removed in OnRemoveWatch(). 10365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Watch* watch = new Watch(raw_watch); 10375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (watch->IsReadyToBeWatched()) { 10385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) watch->StartWatching(); 10395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++num_pending_watches_; 10415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 10425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Bus::OnRemoveWatch(DBusWatch* raw_watch) { 10455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AssertOnDBusThread(); 10465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Watch* watch = static_cast<Watch*>(dbus_watch_get_data(raw_watch)); 10485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete watch; 10495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) --num_pending_watches_; 10505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Bus::OnToggleWatch(DBusWatch* raw_watch) { 10535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AssertOnDBusThread(); 10545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Watch* watch = static_cast<Watch*>(dbus_watch_get_data(raw_watch)); 10565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (watch->IsReadyToBeWatched()) { 10575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) watch->StartWatching(); 10585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 10595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // It's safe to call this if StartWatching() wasn't called, per 10605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // message_pump_libevent.h. 10615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) watch->StopWatching(); 10625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)dbus_bool_t Bus::OnAddTimeout(DBusTimeout* raw_timeout) { 10665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AssertOnDBusThread(); 10675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // timeout will be deleted when raw_timeout is removed in 10695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // OnRemoveTimeoutThunk(). 10705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Timeout* timeout = new Timeout(raw_timeout); 10715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (timeout->IsReadyToBeMonitored()) { 10725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) timeout->StartMonitoring(this); 10735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++num_pending_timeouts_; 10755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 10765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Bus::OnRemoveTimeout(DBusTimeout* raw_timeout) { 10795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AssertOnDBusThread(); 10805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Timeout* timeout = static_cast<Timeout*>(dbus_timeout_get_data(raw_timeout)); 10825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) timeout->Complete(); 10835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) --num_pending_timeouts_; 10845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Bus::OnToggleTimeout(DBusTimeout* raw_timeout) { 10875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AssertOnDBusThread(); 10885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Timeout* timeout = static_cast<Timeout*>(dbus_timeout_get_data(raw_timeout)); 10905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (timeout->IsReadyToBeMonitored()) { 10915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) timeout->StartMonitoring(this); 10925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 10935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) timeout->StopMonitoring(); 10945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Bus::OnDispatchStatusChanged(DBusConnection* connection, 10985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DBusDispatchStatus status) { 10995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(connection, connection_); 11005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AssertOnDBusThread(); 11015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We cannot call ProcessAllIncomingDataIfAny() here, as calling 11035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // dbus_connection_dispatch() inside DBusDispatchStatusFunction is 11045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // prohibited by the D-Bus library. Hence, we post a task here instead. 11055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // See comments for dbus_connection_set_dispatch_status_function(). 11065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PostTaskToDBusThread(FROM_HERE, 11075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&Bus::ProcessAllIncomingDataIfAny, 11085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this)); 11095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 11105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void Bus::OnConnectionDisconnected(DBusConnection* connection) { 11122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) AssertOnDBusThread(); 11132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 11142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!on_disconnected_closure_.is_null()) 11152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PostTaskToOriginThread(FROM_HERE, on_disconnected_closure_); 11162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 11172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!connection) 11182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 11192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!dbus_connection_get_is_connected(connection)); 11202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 11212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ShutdownAndBlock(); 11222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 11232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1124868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void Bus::OnServiceOwnerChanged(DBusMessage* message) { 1125868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(message); 1126868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) AssertOnDBusThread(); 1127868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1128868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // |message| will be unrefed on exit of the function. Increment the 1129868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // reference so we can use it in Signal::FromRawMessage() below. 1130868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) dbus_message_ref(message); 1131868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_ptr<Signal> signal(Signal::FromRawMessage(message)); 1132868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1133868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Confirm the validity of the NameOwnerChanged signal. 1134868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (signal->GetMember() != kNameOwnerChangedSignal || 1135868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) signal->GetInterface() != DBUS_INTERFACE_DBUS || 1136868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) signal->GetSender() != DBUS_SERVICE_DBUS) { 1137868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 1138868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1139868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1140868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) MessageReader reader(signal.get()); 1141868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) std::string service_name; 1142868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) std::string old_owner; 1143868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) std::string new_owner; 1144868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!reader.PopString(&service_name) || 1145868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) !reader.PopString(&old_owner) || 1146868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) !reader.PopString(&new_owner)) { 1147868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 1148868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1149868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1150868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ServiceOwnerChangedListenerMap::const_iterator it = 1151868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) service_owner_changed_listener_map_.find(service_name); 1152868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (it == service_owner_changed_listener_map_.end()) 1153868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 1154868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1155868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const std::vector<GetServiceOwnerCallback>& callbacks = it->second; 1156868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) for (size_t i = 0; i < callbacks.size(); ++i) { 1157868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) PostTaskToOriginThread(FROM_HERE, 1158868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) base::Bind(callbacks[i], new_owner)); 1159868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1160868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 1161868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1162868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// static 11635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)dbus_bool_t Bus::OnAddWatchThunk(DBusWatch* raw_watch, void* data) { 11645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Bus* self = static_cast<Bus*>(data); 11655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return self->OnAddWatch(raw_watch); 11665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 11675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1168868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// static 11695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Bus::OnRemoveWatchThunk(DBusWatch* raw_watch, void* data) { 11705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Bus* self = static_cast<Bus*>(data); 11715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self->OnRemoveWatch(raw_watch); 11725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 11735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1174868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// static 11755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Bus::OnToggleWatchThunk(DBusWatch* raw_watch, void* data) { 11765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Bus* self = static_cast<Bus*>(data); 11775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self->OnToggleWatch(raw_watch); 11785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 11795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1180868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// static 11815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)dbus_bool_t Bus::OnAddTimeoutThunk(DBusTimeout* raw_timeout, void* data) { 11825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Bus* self = static_cast<Bus*>(data); 11835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return self->OnAddTimeout(raw_timeout); 11845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 11855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1186868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// static 11875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Bus::OnRemoveTimeoutThunk(DBusTimeout* raw_timeout, void* data) { 11885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Bus* self = static_cast<Bus*>(data); 11895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self->OnRemoveTimeout(raw_timeout); 11905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 11915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1192868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// static 11935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Bus::OnToggleTimeoutThunk(DBusTimeout* raw_timeout, void* data) { 11945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Bus* self = static_cast<Bus*>(data); 11955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self->OnToggleTimeout(raw_timeout); 11965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 11975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1198868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// static 11995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Bus::OnDispatchStatusChangedThunk(DBusConnection* connection, 12005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DBusDispatchStatus status, 12015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void* data) { 12025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Bus* self = static_cast<Bus*>(data); 12035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self->OnDispatchStatusChanged(connection, status); 12045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 12055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1206868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// static 12072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)DBusHandlerResult Bus::OnConnectionDisconnectedFilter( 12082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DBusConnection* connection, 12092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DBusMessage* message, 12102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void* data) { 12112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (dbus_message_is_signal(message, 12122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DBUS_INTERFACE_LOCAL, 12132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) kDisconnectedSignal)) { 12142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Bus* self = static_cast<Bus*>(data); 12152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) self->OnConnectionDisconnected(connection); 12162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return DBUS_HANDLER_RESULT_HANDLED; 12172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 12182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; 12192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 12202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1221868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// static 1222868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)DBusHandlerResult Bus::OnServiceOwnerChangedFilter( 1223868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DBusConnection* connection, 1224868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DBusMessage* message, 1225868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) void* data) { 1226868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (dbus_message_is_signal(message, 1227868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DBUS_INTERFACE_DBUS, 1228868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) kNameOwnerChangedSignal)) { 1229868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) Bus* self = static_cast<Bus*>(data); 1230868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) self->OnServiceOwnerChanged(message); 1231868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 1232868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Always return unhandled to let others, e.g. ObjectProxies, handle the same 1233868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // signal. 1234868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; 1235868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 1236868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 12375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace dbus 1238