1*635a8641SAndroid Build Coastguard Worker // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2*635a8641SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*635a8641SAndroid Build Coastguard Worker // found in the LICENSE file.
4*635a8641SAndroid Build Coastguard Worker
5*635a8641SAndroid Build Coastguard Worker #include "dbus/bus.h"
6*635a8641SAndroid Build Coastguard Worker
7*635a8641SAndroid Build Coastguard Worker #include <stddef.h>
8*635a8641SAndroid Build Coastguard Worker
9*635a8641SAndroid Build Coastguard Worker #include <memory>
10*635a8641SAndroid Build Coastguard Worker
11*635a8641SAndroid Build Coastguard Worker #include "base/bind.h"
12*635a8641SAndroid Build Coastguard Worker #include "base/files/file_descriptor_watcher_posix.h"
13*635a8641SAndroid Build Coastguard Worker #include "base/logging.h"
14*635a8641SAndroid Build Coastguard Worker #include "base/memory/weak_ptr.h"
15*635a8641SAndroid Build Coastguard Worker #include "base/stl_util.h"
16*635a8641SAndroid Build Coastguard Worker #include "base/strings/stringprintf.h"
17*635a8641SAndroid Build Coastguard Worker #include "base/threading/thread.h"
18*635a8641SAndroid Build Coastguard Worker #include "base/threading/thread_restrictions.h"
19*635a8641SAndroid Build Coastguard Worker #include "base/threading/thread_task_runner_handle.h"
20*635a8641SAndroid Build Coastguard Worker #include "base/time/time.h"
21*635a8641SAndroid Build Coastguard Worker #include "dbus/exported_object.h"
22*635a8641SAndroid Build Coastguard Worker #include "dbus/message.h"
23*635a8641SAndroid Build Coastguard Worker #include "dbus/object_manager.h"
24*635a8641SAndroid Build Coastguard Worker #include "dbus/object_path.h"
25*635a8641SAndroid Build Coastguard Worker #include "dbus/object_proxy.h"
26*635a8641SAndroid Build Coastguard Worker #include "dbus/scoped_dbus_error.h"
27*635a8641SAndroid Build Coastguard Worker
28*635a8641SAndroid Build Coastguard Worker namespace dbus {
29*635a8641SAndroid Build Coastguard Worker
30*635a8641SAndroid Build Coastguard Worker namespace {
31*635a8641SAndroid Build Coastguard Worker
32*635a8641SAndroid Build Coastguard Worker const char kDisconnectedSignal[] = "Disconnected";
33*635a8641SAndroid Build Coastguard Worker const char kDisconnectedMatchRule[] =
34*635a8641SAndroid Build Coastguard Worker "type='signal', path='/org/freedesktop/DBus/Local',"
35*635a8641SAndroid Build Coastguard Worker "interface='org.freedesktop.DBus.Local', member='Disconnected'";
36*635a8641SAndroid Build Coastguard Worker
37*635a8641SAndroid Build Coastguard Worker // The NameOwnerChanged member in org.freedesktop.DBus
38*635a8641SAndroid Build Coastguard Worker const char kNameOwnerChangedSignal[] = "NameOwnerChanged";
39*635a8641SAndroid Build Coastguard Worker
40*635a8641SAndroid Build Coastguard Worker // The match rule used to filter for changes to a given service name owner.
41*635a8641SAndroid Build Coastguard Worker const char kServiceNameOwnerChangeMatchRule[] =
42*635a8641SAndroid Build Coastguard Worker "type='signal',interface='org.freedesktop.DBus',"
43*635a8641SAndroid Build Coastguard Worker "member='NameOwnerChanged',path='/org/freedesktop/DBus',"
44*635a8641SAndroid Build Coastguard Worker "sender='org.freedesktop.DBus',arg0='%s'";
45*635a8641SAndroid Build Coastguard Worker
46*635a8641SAndroid Build Coastguard Worker // The class is used for watching the file descriptor used for D-Bus
47*635a8641SAndroid Build Coastguard Worker // communication.
48*635a8641SAndroid Build Coastguard Worker class Watch {
49*635a8641SAndroid Build Coastguard Worker public:
Watch(DBusWatch * watch)50*635a8641SAndroid Build Coastguard Worker explicit Watch(DBusWatch* watch) : raw_watch_(watch) {
51*635a8641SAndroid Build Coastguard Worker dbus_watch_set_data(raw_watch_, this, nullptr);
52*635a8641SAndroid Build Coastguard Worker }
53*635a8641SAndroid Build Coastguard Worker
~Watch()54*635a8641SAndroid Build Coastguard Worker ~Watch() { dbus_watch_set_data(raw_watch_, nullptr, nullptr); }
55*635a8641SAndroid Build Coastguard Worker
56*635a8641SAndroid Build Coastguard Worker // Returns true if the underlying file descriptor is ready to be watched.
IsReadyToBeWatched()57*635a8641SAndroid Build Coastguard Worker bool IsReadyToBeWatched() {
58*635a8641SAndroid Build Coastguard Worker return dbus_watch_get_enabled(raw_watch_);
59*635a8641SAndroid Build Coastguard Worker }
60*635a8641SAndroid Build Coastguard Worker
61*635a8641SAndroid Build Coastguard Worker // Starts watching the underlying file descriptor.
StartWatching()62*635a8641SAndroid Build Coastguard Worker void StartWatching() {
63*635a8641SAndroid Build Coastguard Worker const int file_descriptor = dbus_watch_get_unix_fd(raw_watch_);
64*635a8641SAndroid Build Coastguard Worker const unsigned int flags = dbus_watch_get_flags(raw_watch_);
65*635a8641SAndroid Build Coastguard Worker
66*635a8641SAndroid Build Coastguard Worker // Using base::Unretained(this) is safe because watches are automatically
67*635a8641SAndroid Build Coastguard Worker // canceled when |read_watcher_| and |write_watcher_| are destroyed.
68*635a8641SAndroid Build Coastguard Worker if (flags & DBUS_WATCH_READABLE) {
69*635a8641SAndroid Build Coastguard Worker read_watcher_ = base::FileDescriptorWatcher::WatchReadable(
70*635a8641SAndroid Build Coastguard Worker file_descriptor,
71*635a8641SAndroid Build Coastguard Worker base::Bind(&Watch::OnFileReady, base::Unretained(this),
72*635a8641SAndroid Build Coastguard Worker DBUS_WATCH_READABLE));
73*635a8641SAndroid Build Coastguard Worker }
74*635a8641SAndroid Build Coastguard Worker if (flags & DBUS_WATCH_WRITABLE) {
75*635a8641SAndroid Build Coastguard Worker write_watcher_ = base::FileDescriptorWatcher::WatchWritable(
76*635a8641SAndroid Build Coastguard Worker file_descriptor,
77*635a8641SAndroid Build Coastguard Worker base::Bind(&Watch::OnFileReady, base::Unretained(this),
78*635a8641SAndroid Build Coastguard Worker DBUS_WATCH_WRITABLE));
79*635a8641SAndroid Build Coastguard Worker }
80*635a8641SAndroid Build Coastguard Worker }
81*635a8641SAndroid Build Coastguard Worker
82*635a8641SAndroid Build Coastguard Worker // Stops watching the underlying file descriptor.
StopWatching()83*635a8641SAndroid Build Coastguard Worker void StopWatching() {
84*635a8641SAndroid Build Coastguard Worker read_watcher_.reset();
85*635a8641SAndroid Build Coastguard Worker write_watcher_.reset();
86*635a8641SAndroid Build Coastguard Worker }
87*635a8641SAndroid Build Coastguard Worker
88*635a8641SAndroid Build Coastguard Worker private:
OnFileReady(unsigned int flags)89*635a8641SAndroid Build Coastguard Worker void OnFileReady(unsigned int flags) {
90*635a8641SAndroid Build Coastguard Worker CHECK(dbus_watch_handle(raw_watch_, flags)) << "Unable to allocate memory";
91*635a8641SAndroid Build Coastguard Worker }
92*635a8641SAndroid Build Coastguard Worker
93*635a8641SAndroid Build Coastguard Worker DBusWatch* raw_watch_;
94*635a8641SAndroid Build Coastguard Worker std::unique_ptr<base::FileDescriptorWatcher::Controller> read_watcher_;
95*635a8641SAndroid Build Coastguard Worker std::unique_ptr<base::FileDescriptorWatcher::Controller> write_watcher_;
96*635a8641SAndroid Build Coastguard Worker
97*635a8641SAndroid Build Coastguard Worker DISALLOW_COPY_AND_ASSIGN(Watch);
98*635a8641SAndroid Build Coastguard Worker };
99*635a8641SAndroid Build Coastguard Worker
100*635a8641SAndroid Build Coastguard Worker // The class is used for monitoring the timeout used for D-Bus method
101*635a8641SAndroid Build Coastguard Worker // calls.
102*635a8641SAndroid Build Coastguard Worker class Timeout {
103*635a8641SAndroid Build Coastguard Worker public:
Timeout(DBusTimeout * timeout)104*635a8641SAndroid Build Coastguard Worker explicit Timeout(DBusTimeout* timeout)
105*635a8641SAndroid Build Coastguard Worker : raw_timeout_(timeout), weak_ptr_factory_(this) {
106*635a8641SAndroid Build Coastguard Worker // Associated |this| with the underlying DBusTimeout.
107*635a8641SAndroid Build Coastguard Worker dbus_timeout_set_data(raw_timeout_, this, nullptr);
108*635a8641SAndroid Build Coastguard Worker }
109*635a8641SAndroid Build Coastguard Worker
~Timeout()110*635a8641SAndroid Build Coastguard Worker ~Timeout() {
111*635a8641SAndroid Build Coastguard Worker // Remove the association between |this| and the |raw_timeout_|.
112*635a8641SAndroid Build Coastguard Worker dbus_timeout_set_data(raw_timeout_, nullptr, nullptr);
113*635a8641SAndroid Build Coastguard Worker }
114*635a8641SAndroid Build Coastguard Worker
115*635a8641SAndroid Build Coastguard Worker // Returns true if the timeout is ready to be monitored.
IsReadyToBeMonitored()116*635a8641SAndroid Build Coastguard Worker bool IsReadyToBeMonitored() {
117*635a8641SAndroid Build Coastguard Worker return dbus_timeout_get_enabled(raw_timeout_);
118*635a8641SAndroid Build Coastguard Worker }
119*635a8641SAndroid Build Coastguard Worker
120*635a8641SAndroid Build Coastguard Worker // Starts monitoring the timeout.
StartMonitoring(Bus * bus)121*635a8641SAndroid Build Coastguard Worker void StartMonitoring(Bus* bus) {
122*635a8641SAndroid Build Coastguard Worker bus->GetDBusTaskRunner()->PostDelayedTask(
123*635a8641SAndroid Build Coastguard Worker FROM_HERE,
124*635a8641SAndroid Build Coastguard Worker base::Bind(&Timeout::HandleTimeout, weak_ptr_factory_.GetWeakPtr()),
125*635a8641SAndroid Build Coastguard Worker GetInterval());
126*635a8641SAndroid Build Coastguard Worker }
127*635a8641SAndroid Build Coastguard Worker
128*635a8641SAndroid Build Coastguard Worker // Stops monitoring the timeout.
StopMonitoring()129*635a8641SAndroid Build Coastguard Worker void StopMonitoring() { weak_ptr_factory_.InvalidateWeakPtrs(); }
130*635a8641SAndroid Build Coastguard Worker
GetInterval()131*635a8641SAndroid Build Coastguard Worker base::TimeDelta GetInterval() {
132*635a8641SAndroid Build Coastguard Worker return base::TimeDelta::FromMilliseconds(
133*635a8641SAndroid Build Coastguard Worker dbus_timeout_get_interval(raw_timeout_));
134*635a8641SAndroid Build Coastguard Worker }
135*635a8641SAndroid Build Coastguard Worker
136*635a8641SAndroid Build Coastguard Worker private:
137*635a8641SAndroid Build Coastguard Worker // Calls DBus to handle the timeout.
HandleTimeout()138*635a8641SAndroid Build Coastguard Worker void HandleTimeout() { CHECK(dbus_timeout_handle(raw_timeout_)); }
139*635a8641SAndroid Build Coastguard Worker
140*635a8641SAndroid Build Coastguard Worker DBusTimeout* raw_timeout_;
141*635a8641SAndroid Build Coastguard Worker
142*635a8641SAndroid Build Coastguard Worker base::WeakPtrFactory<Timeout> weak_ptr_factory_;
143*635a8641SAndroid Build Coastguard Worker
144*635a8641SAndroid Build Coastguard Worker DISALLOW_COPY_AND_ASSIGN(Timeout);
145*635a8641SAndroid Build Coastguard Worker };
146*635a8641SAndroid Build Coastguard Worker
147*635a8641SAndroid Build Coastguard Worker } // namespace
148*635a8641SAndroid Build Coastguard Worker
Options()149*635a8641SAndroid Build Coastguard Worker Bus::Options::Options()
150*635a8641SAndroid Build Coastguard Worker : bus_type(SESSION),
151*635a8641SAndroid Build Coastguard Worker connection_type(PRIVATE) {
152*635a8641SAndroid Build Coastguard Worker }
153*635a8641SAndroid Build Coastguard Worker
154*635a8641SAndroid Build Coastguard Worker Bus::Options::~Options() = default;
155*635a8641SAndroid Build Coastguard Worker
Bus(const Options & options)156*635a8641SAndroid Build Coastguard Worker Bus::Bus(const Options& options)
157*635a8641SAndroid Build Coastguard Worker : bus_type_(options.bus_type),
158*635a8641SAndroid Build Coastguard Worker connection_type_(options.connection_type),
159*635a8641SAndroid Build Coastguard Worker dbus_task_runner_(options.dbus_task_runner),
160*635a8641SAndroid Build Coastguard Worker on_shutdown_(base::WaitableEvent::ResetPolicy::AUTOMATIC,
161*635a8641SAndroid Build Coastguard Worker base::WaitableEvent::InitialState::NOT_SIGNALED),
162*635a8641SAndroid Build Coastguard Worker connection_(nullptr),
163*635a8641SAndroid Build Coastguard Worker origin_thread_id_(base::PlatformThread::CurrentId()),
164*635a8641SAndroid Build Coastguard Worker async_operations_set_up_(false),
165*635a8641SAndroid Build Coastguard Worker shutdown_completed_(false),
166*635a8641SAndroid Build Coastguard Worker num_pending_watches_(0),
167*635a8641SAndroid Build Coastguard Worker num_pending_timeouts_(0),
168*635a8641SAndroid Build Coastguard Worker address_(options.address) {
169*635a8641SAndroid Build Coastguard Worker // This is safe to call multiple times.
170*635a8641SAndroid Build Coastguard Worker dbus_threads_init_default();
171*635a8641SAndroid Build Coastguard Worker // The origin message loop is unnecessary if the client uses synchronous
172*635a8641SAndroid Build Coastguard Worker // functions only.
173*635a8641SAndroid Build Coastguard Worker if (base::ThreadTaskRunnerHandle::IsSet())
174*635a8641SAndroid Build Coastguard Worker origin_task_runner_ = base::ThreadTaskRunnerHandle::Get();
175*635a8641SAndroid Build Coastguard Worker }
176*635a8641SAndroid Build Coastguard Worker
~Bus()177*635a8641SAndroid Build Coastguard Worker Bus::~Bus() {
178*635a8641SAndroid Build Coastguard Worker DCHECK(!connection_);
179*635a8641SAndroid Build Coastguard Worker DCHECK(owned_service_names_.empty());
180*635a8641SAndroid Build Coastguard Worker DCHECK(match_rules_added_.empty());
181*635a8641SAndroid Build Coastguard Worker DCHECK(filter_functions_added_.empty());
182*635a8641SAndroid Build Coastguard Worker DCHECK(registered_object_paths_.empty());
183*635a8641SAndroid Build Coastguard Worker DCHECK_EQ(0, num_pending_watches_);
184*635a8641SAndroid Build Coastguard Worker // TODO(satorux): This check fails occasionally in browser_tests for tests
185*635a8641SAndroid Build Coastguard Worker // that run very quickly. Perhaps something does not have time to clean up.
186*635a8641SAndroid Build Coastguard Worker // Despite the check failing, the tests seem to run fine. crosbug.com/23416
187*635a8641SAndroid Build Coastguard Worker // DCHECK_EQ(0, num_pending_timeouts_);
188*635a8641SAndroid Build Coastguard Worker }
189*635a8641SAndroid Build Coastguard Worker
GetObjectProxy(const std::string & service_name,const ObjectPath & object_path)190*635a8641SAndroid Build Coastguard Worker ObjectProxy* Bus::GetObjectProxy(const std::string& service_name,
191*635a8641SAndroid Build Coastguard Worker const ObjectPath& object_path) {
192*635a8641SAndroid Build Coastguard Worker return GetObjectProxyWithOptions(service_name, object_path,
193*635a8641SAndroid Build Coastguard Worker ObjectProxy::DEFAULT_OPTIONS);
194*635a8641SAndroid Build Coastguard Worker }
195*635a8641SAndroid Build Coastguard Worker
GetObjectProxyWithOptions(const std::string & service_name,const ObjectPath & object_path,int options)196*635a8641SAndroid Build Coastguard Worker ObjectProxy* Bus::GetObjectProxyWithOptions(const std::string& service_name,
197*635a8641SAndroid Build Coastguard Worker const ObjectPath& object_path,
198*635a8641SAndroid Build Coastguard Worker int options) {
199*635a8641SAndroid Build Coastguard Worker AssertOnOriginThread();
200*635a8641SAndroid Build Coastguard Worker
201*635a8641SAndroid Build Coastguard Worker // Check if we already have the requested object proxy.
202*635a8641SAndroid Build Coastguard Worker const ObjectProxyTable::key_type key(service_name + object_path.value(),
203*635a8641SAndroid Build Coastguard Worker options);
204*635a8641SAndroid Build Coastguard Worker ObjectProxyTable::iterator iter = object_proxy_table_.find(key);
205*635a8641SAndroid Build Coastguard Worker if (iter != object_proxy_table_.end()) {
206*635a8641SAndroid Build Coastguard Worker return iter->second.get();
207*635a8641SAndroid Build Coastguard Worker }
208*635a8641SAndroid Build Coastguard Worker
209*635a8641SAndroid Build Coastguard Worker scoped_refptr<ObjectProxy> object_proxy =
210*635a8641SAndroid Build Coastguard Worker new ObjectProxy(this, service_name, object_path, options);
211*635a8641SAndroid Build Coastguard Worker object_proxy_table_[key] = object_proxy;
212*635a8641SAndroid Build Coastguard Worker
213*635a8641SAndroid Build Coastguard Worker return object_proxy.get();
214*635a8641SAndroid Build Coastguard Worker }
215*635a8641SAndroid Build Coastguard Worker
RemoveObjectProxy(const std::string & service_name,const ObjectPath & object_path,const base::Closure & callback)216*635a8641SAndroid Build Coastguard Worker bool Bus::RemoveObjectProxy(const std::string& service_name,
217*635a8641SAndroid Build Coastguard Worker const ObjectPath& object_path,
218*635a8641SAndroid Build Coastguard Worker const base::Closure& callback) {
219*635a8641SAndroid Build Coastguard Worker return RemoveObjectProxyWithOptions(service_name, object_path,
220*635a8641SAndroid Build Coastguard Worker ObjectProxy::DEFAULT_OPTIONS,
221*635a8641SAndroid Build Coastguard Worker callback);
222*635a8641SAndroid Build Coastguard Worker }
223*635a8641SAndroid Build Coastguard Worker
RemoveObjectProxyWithOptions(const std::string & service_name,const ObjectPath & object_path,int options,const base::Closure & callback)224*635a8641SAndroid Build Coastguard Worker bool Bus::RemoveObjectProxyWithOptions(const std::string& service_name,
225*635a8641SAndroid Build Coastguard Worker const ObjectPath& object_path,
226*635a8641SAndroid Build Coastguard Worker int options,
227*635a8641SAndroid Build Coastguard Worker const base::Closure& callback) {
228*635a8641SAndroid Build Coastguard Worker AssertOnOriginThread();
229*635a8641SAndroid Build Coastguard Worker
230*635a8641SAndroid Build Coastguard Worker // Check if we have the requested object proxy.
231*635a8641SAndroid Build Coastguard Worker const ObjectProxyTable::key_type key(service_name + object_path.value(),
232*635a8641SAndroid Build Coastguard Worker options);
233*635a8641SAndroid Build Coastguard Worker ObjectProxyTable::iterator iter = object_proxy_table_.find(key);
234*635a8641SAndroid Build Coastguard Worker if (iter != object_proxy_table_.end()) {
235*635a8641SAndroid Build Coastguard Worker scoped_refptr<ObjectProxy> object_proxy = iter->second;
236*635a8641SAndroid Build Coastguard Worker object_proxy_table_.erase(iter);
237*635a8641SAndroid Build Coastguard Worker // Object is present. Remove it now and Detach on the DBus thread.
238*635a8641SAndroid Build Coastguard Worker GetDBusTaskRunner()->PostTask(
239*635a8641SAndroid Build Coastguard Worker FROM_HERE,
240*635a8641SAndroid Build Coastguard Worker base::Bind(&Bus::RemoveObjectProxyInternal,
241*635a8641SAndroid Build Coastguard Worker this, object_proxy, callback));
242*635a8641SAndroid Build Coastguard Worker return true;
243*635a8641SAndroid Build Coastguard Worker }
244*635a8641SAndroid Build Coastguard Worker return false;
245*635a8641SAndroid Build Coastguard Worker }
246*635a8641SAndroid Build Coastguard Worker
RemoveObjectProxyInternal(scoped_refptr<ObjectProxy> object_proxy,const base::Closure & callback)247*635a8641SAndroid Build Coastguard Worker void Bus::RemoveObjectProxyInternal(scoped_refptr<ObjectProxy> object_proxy,
248*635a8641SAndroid Build Coastguard Worker const base::Closure& callback) {
249*635a8641SAndroid Build Coastguard Worker AssertOnDBusThread();
250*635a8641SAndroid Build Coastguard Worker
251*635a8641SAndroid Build Coastguard Worker object_proxy->Detach();
252*635a8641SAndroid Build Coastguard Worker
253*635a8641SAndroid Build Coastguard Worker GetOriginTaskRunner()->PostTask(FROM_HERE, callback);
254*635a8641SAndroid Build Coastguard Worker }
255*635a8641SAndroid Build Coastguard Worker
GetExportedObject(const ObjectPath & object_path)256*635a8641SAndroid Build Coastguard Worker ExportedObject* Bus::GetExportedObject(const ObjectPath& object_path) {
257*635a8641SAndroid Build Coastguard Worker AssertOnOriginThread();
258*635a8641SAndroid Build Coastguard Worker
259*635a8641SAndroid Build Coastguard Worker // Check if we already have the requested exported object.
260*635a8641SAndroid Build Coastguard Worker ExportedObjectTable::iterator iter = exported_object_table_.find(object_path);
261*635a8641SAndroid Build Coastguard Worker if (iter != exported_object_table_.end()) {
262*635a8641SAndroid Build Coastguard Worker return iter->second.get();
263*635a8641SAndroid Build Coastguard Worker }
264*635a8641SAndroid Build Coastguard Worker
265*635a8641SAndroid Build Coastguard Worker scoped_refptr<ExportedObject> exported_object =
266*635a8641SAndroid Build Coastguard Worker new ExportedObject(this, object_path);
267*635a8641SAndroid Build Coastguard Worker exported_object_table_[object_path] = exported_object;
268*635a8641SAndroid Build Coastguard Worker
269*635a8641SAndroid Build Coastguard Worker return exported_object.get();
270*635a8641SAndroid Build Coastguard Worker }
271*635a8641SAndroid Build Coastguard Worker
UnregisterExportedObject(const ObjectPath & object_path)272*635a8641SAndroid Build Coastguard Worker void Bus::UnregisterExportedObject(const ObjectPath& object_path) {
273*635a8641SAndroid Build Coastguard Worker AssertOnOriginThread();
274*635a8641SAndroid Build Coastguard Worker
275*635a8641SAndroid Build Coastguard Worker // Remove the registered object from the table first, to allow a new
276*635a8641SAndroid Build Coastguard Worker // GetExportedObject() call to return a new object, rather than this one.
277*635a8641SAndroid Build Coastguard Worker ExportedObjectTable::iterator iter = exported_object_table_.find(object_path);
278*635a8641SAndroid Build Coastguard Worker if (iter == exported_object_table_.end())
279*635a8641SAndroid Build Coastguard Worker return;
280*635a8641SAndroid Build Coastguard Worker
281*635a8641SAndroid Build Coastguard Worker scoped_refptr<ExportedObject> exported_object = iter->second;
282*635a8641SAndroid Build Coastguard Worker exported_object_table_.erase(iter);
283*635a8641SAndroid Build Coastguard Worker
284*635a8641SAndroid Build Coastguard Worker // Post the task to perform the final unregistration to the D-Bus thread.
285*635a8641SAndroid Build Coastguard Worker // Since the registration also happens on the D-Bus thread in
286*635a8641SAndroid Build Coastguard Worker // TryRegisterObjectPath(), and the task runner we post to is a
287*635a8641SAndroid Build Coastguard Worker // SequencedTaskRunner, there is a guarantee that this will happen before any
288*635a8641SAndroid Build Coastguard Worker // future registration call.
289*635a8641SAndroid Build Coastguard Worker GetDBusTaskRunner()->PostTask(
290*635a8641SAndroid Build Coastguard Worker FROM_HERE,
291*635a8641SAndroid Build Coastguard Worker base::Bind(&Bus::UnregisterExportedObjectInternal,
292*635a8641SAndroid Build Coastguard Worker this, exported_object));
293*635a8641SAndroid Build Coastguard Worker }
294*635a8641SAndroid Build Coastguard Worker
UnregisterExportedObjectInternal(scoped_refptr<ExportedObject> exported_object)295*635a8641SAndroid Build Coastguard Worker void Bus::UnregisterExportedObjectInternal(
296*635a8641SAndroid Build Coastguard Worker scoped_refptr<ExportedObject> exported_object) {
297*635a8641SAndroid Build Coastguard Worker AssertOnDBusThread();
298*635a8641SAndroid Build Coastguard Worker
299*635a8641SAndroid Build Coastguard Worker exported_object->Unregister();
300*635a8641SAndroid Build Coastguard Worker }
301*635a8641SAndroid Build Coastguard Worker
GetObjectManager(const std::string & service_name,const ObjectPath & object_path)302*635a8641SAndroid Build Coastguard Worker ObjectManager* Bus::GetObjectManager(const std::string& service_name,
303*635a8641SAndroid Build Coastguard Worker const ObjectPath& object_path) {
304*635a8641SAndroid Build Coastguard Worker AssertOnOriginThread();
305*635a8641SAndroid Build Coastguard Worker
306*635a8641SAndroid Build Coastguard Worker // Check if we already have the requested object manager.
307*635a8641SAndroid Build Coastguard Worker const ObjectManagerTable::key_type key(service_name + object_path.value());
308*635a8641SAndroid Build Coastguard Worker ObjectManagerTable::iterator iter = object_manager_table_.find(key);
309*635a8641SAndroid Build Coastguard Worker if (iter != object_manager_table_.end()) {
310*635a8641SAndroid Build Coastguard Worker return iter->second.get();
311*635a8641SAndroid Build Coastguard Worker }
312*635a8641SAndroid Build Coastguard Worker
313*635a8641SAndroid Build Coastguard Worker scoped_refptr<ObjectManager> object_manager =
314*635a8641SAndroid Build Coastguard Worker new ObjectManager(this, service_name, object_path);
315*635a8641SAndroid Build Coastguard Worker object_manager_table_[key] = object_manager;
316*635a8641SAndroid Build Coastguard Worker
317*635a8641SAndroid Build Coastguard Worker return object_manager.get();
318*635a8641SAndroid Build Coastguard Worker }
319*635a8641SAndroid Build Coastguard Worker
RemoveObjectManager(const std::string & service_name,const ObjectPath & object_path,const base::Closure & callback)320*635a8641SAndroid Build Coastguard Worker bool Bus::RemoveObjectManager(const std::string& service_name,
321*635a8641SAndroid Build Coastguard Worker const ObjectPath& object_path,
322*635a8641SAndroid Build Coastguard Worker const base::Closure& callback) {
323*635a8641SAndroid Build Coastguard Worker AssertOnOriginThread();
324*635a8641SAndroid Build Coastguard Worker DCHECK(!callback.is_null());
325*635a8641SAndroid Build Coastguard Worker
326*635a8641SAndroid Build Coastguard Worker const ObjectManagerTable::key_type key(service_name + object_path.value());
327*635a8641SAndroid Build Coastguard Worker ObjectManagerTable::iterator iter = object_manager_table_.find(key);
328*635a8641SAndroid Build Coastguard Worker if (iter == object_manager_table_.end())
329*635a8641SAndroid Build Coastguard Worker return false;
330*635a8641SAndroid Build Coastguard Worker
331*635a8641SAndroid Build Coastguard Worker // ObjectManager is present. Remove it now and CleanUp on the DBus thread.
332*635a8641SAndroid Build Coastguard Worker scoped_refptr<ObjectManager> object_manager = iter->second;
333*635a8641SAndroid Build Coastguard Worker object_manager_table_.erase(iter);
334*635a8641SAndroid Build Coastguard Worker
335*635a8641SAndroid Build Coastguard Worker GetDBusTaskRunner()->PostTask(
336*635a8641SAndroid Build Coastguard Worker FROM_HERE,
337*635a8641SAndroid Build Coastguard Worker base::Bind(&Bus::RemoveObjectManagerInternal,
338*635a8641SAndroid Build Coastguard Worker this, object_manager, callback));
339*635a8641SAndroid Build Coastguard Worker
340*635a8641SAndroid Build Coastguard Worker return true;
341*635a8641SAndroid Build Coastguard Worker }
342*635a8641SAndroid Build Coastguard Worker
RemoveObjectManagerInternal(scoped_refptr<dbus::ObjectManager> object_manager,const base::Closure & callback)343*635a8641SAndroid Build Coastguard Worker void Bus::RemoveObjectManagerInternal(
344*635a8641SAndroid Build Coastguard Worker scoped_refptr<dbus::ObjectManager> object_manager,
345*635a8641SAndroid Build Coastguard Worker const base::Closure& callback) {
346*635a8641SAndroid Build Coastguard Worker AssertOnDBusThread();
347*635a8641SAndroid Build Coastguard Worker DCHECK(object_manager.get());
348*635a8641SAndroid Build Coastguard Worker
349*635a8641SAndroid Build Coastguard Worker object_manager->CleanUp();
350*635a8641SAndroid Build Coastguard Worker
351*635a8641SAndroid Build Coastguard Worker // The ObjectManager has to be deleted on the origin thread since it was
352*635a8641SAndroid Build Coastguard Worker // created there.
353*635a8641SAndroid Build Coastguard Worker GetOriginTaskRunner()->PostTask(
354*635a8641SAndroid Build Coastguard Worker FROM_HERE,
355*635a8641SAndroid Build Coastguard Worker base::Bind(&Bus::RemoveObjectManagerInternalHelper,
356*635a8641SAndroid Build Coastguard Worker this, object_manager, callback));
357*635a8641SAndroid Build Coastguard Worker }
358*635a8641SAndroid Build Coastguard Worker
RemoveObjectManagerInternalHelper(scoped_refptr<dbus::ObjectManager> object_manager,const base::Closure & callback)359*635a8641SAndroid Build Coastguard Worker void Bus::RemoveObjectManagerInternalHelper(
360*635a8641SAndroid Build Coastguard Worker scoped_refptr<dbus::ObjectManager> object_manager,
361*635a8641SAndroid Build Coastguard Worker const base::Closure& callback) {
362*635a8641SAndroid Build Coastguard Worker AssertOnOriginThread();
363*635a8641SAndroid Build Coastguard Worker DCHECK(object_manager);
364*635a8641SAndroid Build Coastguard Worker
365*635a8641SAndroid Build Coastguard Worker // Release the object manager and run the callback.
366*635a8641SAndroid Build Coastguard Worker object_manager = nullptr;
367*635a8641SAndroid Build Coastguard Worker callback.Run();
368*635a8641SAndroid Build Coastguard Worker }
369*635a8641SAndroid Build Coastguard Worker
Connect()370*635a8641SAndroid Build Coastguard Worker bool Bus::Connect() {
371*635a8641SAndroid Build Coastguard Worker // dbus_bus_get_private() and dbus_bus_get() are blocking calls.
372*635a8641SAndroid Build Coastguard Worker AssertOnDBusThread();
373*635a8641SAndroid Build Coastguard Worker
374*635a8641SAndroid Build Coastguard Worker // Check if it's already initialized.
375*635a8641SAndroid Build Coastguard Worker if (connection_)
376*635a8641SAndroid Build Coastguard Worker return true;
377*635a8641SAndroid Build Coastguard Worker
378*635a8641SAndroid Build Coastguard Worker ScopedDBusError error;
379*635a8641SAndroid Build Coastguard Worker if (bus_type_ == CUSTOM_ADDRESS) {
380*635a8641SAndroid Build Coastguard Worker if (connection_type_ == PRIVATE) {
381*635a8641SAndroid Build Coastguard Worker connection_ = dbus_connection_open_private(address_.c_str(), error.get());
382*635a8641SAndroid Build Coastguard Worker } else {
383*635a8641SAndroid Build Coastguard Worker connection_ = dbus_connection_open(address_.c_str(), error.get());
384*635a8641SAndroid Build Coastguard Worker }
385*635a8641SAndroid Build Coastguard Worker } else {
386*635a8641SAndroid Build Coastguard Worker const DBusBusType dbus_bus_type = static_cast<DBusBusType>(bus_type_);
387*635a8641SAndroid Build Coastguard Worker if (connection_type_ == PRIVATE) {
388*635a8641SAndroid Build Coastguard Worker connection_ = dbus_bus_get_private(dbus_bus_type, error.get());
389*635a8641SAndroid Build Coastguard Worker } else {
390*635a8641SAndroid Build Coastguard Worker connection_ = dbus_bus_get(dbus_bus_type, error.get());
391*635a8641SAndroid Build Coastguard Worker }
392*635a8641SAndroid Build Coastguard Worker }
393*635a8641SAndroid Build Coastguard Worker if (!connection_) {
394*635a8641SAndroid Build Coastguard Worker LOG(ERROR) << "Failed to connect to the bus: "
395*635a8641SAndroid Build Coastguard Worker << (error.is_set() ? error.message() : "");
396*635a8641SAndroid Build Coastguard Worker return false;
397*635a8641SAndroid Build Coastguard Worker }
398*635a8641SAndroid Build Coastguard Worker
399*635a8641SAndroid Build Coastguard Worker if (bus_type_ == CUSTOM_ADDRESS) {
400*635a8641SAndroid Build Coastguard Worker // We should call dbus_bus_register here, otherwise unique name can not be
401*635a8641SAndroid Build Coastguard Worker // acquired. According to dbus specification, it is responsible to call
402*635a8641SAndroid Build Coastguard Worker // org.freedesktop.DBus.Hello method at the beging of bus connection to
403*635a8641SAndroid Build Coastguard Worker // acquire unique name. In the case of dbus_bus_get, dbus_bus_register is
404*635a8641SAndroid Build Coastguard Worker // called internally.
405*635a8641SAndroid Build Coastguard Worker if (!dbus_bus_register(connection_, error.get())) {
406*635a8641SAndroid Build Coastguard Worker LOG(ERROR) << "Failed to register the bus component: "
407*635a8641SAndroid Build Coastguard Worker << (error.is_set() ? error.message() : "");
408*635a8641SAndroid Build Coastguard Worker return false;
409*635a8641SAndroid Build Coastguard Worker }
410*635a8641SAndroid Build Coastguard Worker }
411*635a8641SAndroid Build Coastguard Worker // We shouldn't exit on the disconnected signal.
412*635a8641SAndroid Build Coastguard Worker dbus_connection_set_exit_on_disconnect(connection_, false);
413*635a8641SAndroid Build Coastguard Worker
414*635a8641SAndroid Build Coastguard Worker // Watch Disconnected signal.
415*635a8641SAndroid Build Coastguard Worker AddFilterFunction(Bus::OnConnectionDisconnectedFilter, this);
416*635a8641SAndroid Build Coastguard Worker AddMatch(kDisconnectedMatchRule, error.get());
417*635a8641SAndroid Build Coastguard Worker
418*635a8641SAndroid Build Coastguard Worker return true;
419*635a8641SAndroid Build Coastguard Worker }
420*635a8641SAndroid Build Coastguard Worker
ClosePrivateConnection()421*635a8641SAndroid Build Coastguard Worker void Bus::ClosePrivateConnection() {
422*635a8641SAndroid Build Coastguard Worker // dbus_connection_close is blocking call.
423*635a8641SAndroid Build Coastguard Worker AssertOnDBusThread();
424*635a8641SAndroid Build Coastguard Worker DCHECK_EQ(PRIVATE, connection_type_)
425*635a8641SAndroid Build Coastguard Worker << "non-private connection should not be closed";
426*635a8641SAndroid Build Coastguard Worker dbus_connection_close(connection_);
427*635a8641SAndroid Build Coastguard Worker }
428*635a8641SAndroid Build Coastguard Worker
ShutdownAndBlock()429*635a8641SAndroid Build Coastguard Worker void Bus::ShutdownAndBlock() {
430*635a8641SAndroid Build Coastguard Worker AssertOnDBusThread();
431*635a8641SAndroid Build Coastguard Worker
432*635a8641SAndroid Build Coastguard Worker if (shutdown_completed_)
433*635a8641SAndroid Build Coastguard Worker return; // Already shutdowned, just return.
434*635a8641SAndroid Build Coastguard Worker
435*635a8641SAndroid Build Coastguard Worker // Unregister the exported objects.
436*635a8641SAndroid Build Coastguard Worker for (ExportedObjectTable::iterator iter = exported_object_table_.begin();
437*635a8641SAndroid Build Coastguard Worker iter != exported_object_table_.end(); ++iter) {
438*635a8641SAndroid Build Coastguard Worker iter->second->Unregister();
439*635a8641SAndroid Build Coastguard Worker }
440*635a8641SAndroid Build Coastguard Worker
441*635a8641SAndroid Build Coastguard Worker // Release all service names.
442*635a8641SAndroid Build Coastguard Worker for (std::set<std::string>::iterator iter = owned_service_names_.begin();
443*635a8641SAndroid Build Coastguard Worker iter != owned_service_names_.end();) {
444*635a8641SAndroid Build Coastguard Worker // This is a bit tricky but we should increment the iter here as
445*635a8641SAndroid Build Coastguard Worker // ReleaseOwnership() may remove |service_name| from the set.
446*635a8641SAndroid Build Coastguard Worker const std::string& service_name = *iter++;
447*635a8641SAndroid Build Coastguard Worker ReleaseOwnership(service_name);
448*635a8641SAndroid Build Coastguard Worker }
449*635a8641SAndroid Build Coastguard Worker if (!owned_service_names_.empty()) {
450*635a8641SAndroid Build Coastguard Worker LOG(ERROR) << "Failed to release all service names. # of services left: "
451*635a8641SAndroid Build Coastguard Worker << owned_service_names_.size();
452*635a8641SAndroid Build Coastguard Worker }
453*635a8641SAndroid Build Coastguard Worker
454*635a8641SAndroid Build Coastguard Worker // Detach from the remote objects.
455*635a8641SAndroid Build Coastguard Worker for (ObjectProxyTable::iterator iter = object_proxy_table_.begin();
456*635a8641SAndroid Build Coastguard Worker iter != object_proxy_table_.end(); ++iter) {
457*635a8641SAndroid Build Coastguard Worker iter->second->Detach();
458*635a8641SAndroid Build Coastguard Worker }
459*635a8641SAndroid Build Coastguard Worker
460*635a8641SAndroid Build Coastguard Worker // Clean up the object managers.
461*635a8641SAndroid Build Coastguard Worker for (ObjectManagerTable::iterator iter = object_manager_table_.begin();
462*635a8641SAndroid Build Coastguard Worker iter != object_manager_table_.end(); ++iter) {
463*635a8641SAndroid Build Coastguard Worker iter->second->CleanUp();
464*635a8641SAndroid Build Coastguard Worker }
465*635a8641SAndroid Build Coastguard Worker
466*635a8641SAndroid Build Coastguard Worker // Release object proxies and exported objects here. We should do this
467*635a8641SAndroid Build Coastguard Worker // here rather than in the destructor to avoid memory leaks due to
468*635a8641SAndroid Build Coastguard Worker // cyclic references.
469*635a8641SAndroid Build Coastguard Worker object_proxy_table_.clear();
470*635a8641SAndroid Build Coastguard Worker exported_object_table_.clear();
471*635a8641SAndroid Build Coastguard Worker
472*635a8641SAndroid Build Coastguard Worker // Private connection should be closed.
473*635a8641SAndroid Build Coastguard Worker if (connection_) {
474*635a8641SAndroid Build Coastguard Worker // Remove Disconnected watcher.
475*635a8641SAndroid Build Coastguard Worker ScopedDBusError error;
476*635a8641SAndroid Build Coastguard Worker RemoveFilterFunction(Bus::OnConnectionDisconnectedFilter, this);
477*635a8641SAndroid Build Coastguard Worker RemoveMatch(kDisconnectedMatchRule, error.get());
478*635a8641SAndroid Build Coastguard Worker
479*635a8641SAndroid Build Coastguard Worker if (connection_type_ == PRIVATE)
480*635a8641SAndroid Build Coastguard Worker ClosePrivateConnection();
481*635a8641SAndroid Build Coastguard Worker // dbus_connection_close() won't unref.
482*635a8641SAndroid Build Coastguard Worker dbus_connection_unref(connection_);
483*635a8641SAndroid Build Coastguard Worker }
484*635a8641SAndroid Build Coastguard Worker
485*635a8641SAndroid Build Coastguard Worker connection_ = nullptr;
486*635a8641SAndroid Build Coastguard Worker shutdown_completed_ = true;
487*635a8641SAndroid Build Coastguard Worker }
488*635a8641SAndroid Build Coastguard Worker
ShutdownOnDBusThreadAndBlock()489*635a8641SAndroid Build Coastguard Worker void Bus::ShutdownOnDBusThreadAndBlock() {
490*635a8641SAndroid Build Coastguard Worker AssertOnOriginThread();
491*635a8641SAndroid Build Coastguard Worker DCHECK(dbus_task_runner_);
492*635a8641SAndroid Build Coastguard Worker
493*635a8641SAndroid Build Coastguard Worker GetDBusTaskRunner()->PostTask(
494*635a8641SAndroid Build Coastguard Worker FROM_HERE,
495*635a8641SAndroid Build Coastguard Worker base::Bind(&Bus::ShutdownOnDBusThreadAndBlockInternal, this));
496*635a8641SAndroid Build Coastguard Worker
497*635a8641SAndroid Build Coastguard Worker // http://crbug.com/125222
498*635a8641SAndroid Build Coastguard Worker base::ThreadRestrictions::ScopedAllowWait allow_wait;
499*635a8641SAndroid Build Coastguard Worker
500*635a8641SAndroid Build Coastguard Worker // Wait until the shutdown is complete on the D-Bus thread.
501*635a8641SAndroid Build Coastguard Worker // The shutdown should not hang, but set timeout just in case.
502*635a8641SAndroid Build Coastguard Worker const int kTimeoutSecs = 3;
503*635a8641SAndroid Build Coastguard Worker const base::TimeDelta timeout(base::TimeDelta::FromSeconds(kTimeoutSecs));
504*635a8641SAndroid Build Coastguard Worker const bool signaled = on_shutdown_.TimedWait(timeout);
505*635a8641SAndroid Build Coastguard Worker LOG_IF(ERROR, !signaled) << "Failed to shutdown the bus";
506*635a8641SAndroid Build Coastguard Worker }
507*635a8641SAndroid Build Coastguard Worker
RequestOwnership(const std::string & service_name,ServiceOwnershipOptions options,OnOwnershipCallback on_ownership_callback)508*635a8641SAndroid Build Coastguard Worker void Bus::RequestOwnership(const std::string& service_name,
509*635a8641SAndroid Build Coastguard Worker ServiceOwnershipOptions options,
510*635a8641SAndroid Build Coastguard Worker OnOwnershipCallback on_ownership_callback) {
511*635a8641SAndroid Build Coastguard Worker AssertOnOriginThread();
512*635a8641SAndroid Build Coastguard Worker
513*635a8641SAndroid Build Coastguard Worker GetDBusTaskRunner()->PostTask(
514*635a8641SAndroid Build Coastguard Worker FROM_HERE,
515*635a8641SAndroid Build Coastguard Worker base::Bind(&Bus::RequestOwnershipInternal,
516*635a8641SAndroid Build Coastguard Worker this, service_name, options, on_ownership_callback));
517*635a8641SAndroid Build Coastguard Worker }
518*635a8641SAndroid Build Coastguard Worker
RequestOwnershipInternal(const std::string & service_name,ServiceOwnershipOptions options,OnOwnershipCallback on_ownership_callback)519*635a8641SAndroid Build Coastguard Worker void Bus::RequestOwnershipInternal(const std::string& service_name,
520*635a8641SAndroid Build Coastguard Worker ServiceOwnershipOptions options,
521*635a8641SAndroid Build Coastguard Worker OnOwnershipCallback on_ownership_callback) {
522*635a8641SAndroid Build Coastguard Worker AssertOnDBusThread();
523*635a8641SAndroid Build Coastguard Worker
524*635a8641SAndroid Build Coastguard Worker bool success = Connect();
525*635a8641SAndroid Build Coastguard Worker if (success)
526*635a8641SAndroid Build Coastguard Worker success = RequestOwnershipAndBlock(service_name, options);
527*635a8641SAndroid Build Coastguard Worker
528*635a8641SAndroid Build Coastguard Worker GetOriginTaskRunner()->PostTask(FROM_HERE,
529*635a8641SAndroid Build Coastguard Worker base::Bind(on_ownership_callback,
530*635a8641SAndroid Build Coastguard Worker service_name,
531*635a8641SAndroid Build Coastguard Worker success));
532*635a8641SAndroid Build Coastguard Worker }
533*635a8641SAndroid Build Coastguard Worker
RequestOwnershipAndBlock(const std::string & service_name,ServiceOwnershipOptions options)534*635a8641SAndroid Build Coastguard Worker bool Bus::RequestOwnershipAndBlock(const std::string& service_name,
535*635a8641SAndroid Build Coastguard Worker ServiceOwnershipOptions options) {
536*635a8641SAndroid Build Coastguard Worker DCHECK(connection_);
537*635a8641SAndroid Build Coastguard Worker // dbus_bus_request_name() is a blocking call.
538*635a8641SAndroid Build Coastguard Worker AssertOnDBusThread();
539*635a8641SAndroid Build Coastguard Worker
540*635a8641SAndroid Build Coastguard Worker // Check if we already own the service name.
541*635a8641SAndroid Build Coastguard Worker if (owned_service_names_.find(service_name) != owned_service_names_.end()) {
542*635a8641SAndroid Build Coastguard Worker return true;
543*635a8641SAndroid Build Coastguard Worker }
544*635a8641SAndroid Build Coastguard Worker
545*635a8641SAndroid Build Coastguard Worker ScopedDBusError error;
546*635a8641SAndroid Build Coastguard Worker const int result = dbus_bus_request_name(connection_,
547*635a8641SAndroid Build Coastguard Worker service_name.c_str(),
548*635a8641SAndroid Build Coastguard Worker options,
549*635a8641SAndroid Build Coastguard Worker error.get());
550*635a8641SAndroid Build Coastguard Worker if (result != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) {
551*635a8641SAndroid Build Coastguard Worker LOG(ERROR) << "Failed to get the ownership of " << service_name << ": "
552*635a8641SAndroid Build Coastguard Worker << (error.is_set() ? error.message() : "");
553*635a8641SAndroid Build Coastguard Worker return false;
554*635a8641SAndroid Build Coastguard Worker }
555*635a8641SAndroid Build Coastguard Worker owned_service_names_.insert(service_name);
556*635a8641SAndroid Build Coastguard Worker return true;
557*635a8641SAndroid Build Coastguard Worker }
558*635a8641SAndroid Build Coastguard Worker
ReleaseOwnership(const std::string & service_name)559*635a8641SAndroid Build Coastguard Worker bool Bus::ReleaseOwnership(const std::string& service_name) {
560*635a8641SAndroid Build Coastguard Worker DCHECK(connection_);
561*635a8641SAndroid Build Coastguard Worker // dbus_bus_request_name() is a blocking call.
562*635a8641SAndroid Build Coastguard Worker AssertOnDBusThread();
563*635a8641SAndroid Build Coastguard Worker
564*635a8641SAndroid Build Coastguard Worker // Check if we already own the service name.
565*635a8641SAndroid Build Coastguard Worker std::set<std::string>::iterator found =
566*635a8641SAndroid Build Coastguard Worker owned_service_names_.find(service_name);
567*635a8641SAndroid Build Coastguard Worker if (found == owned_service_names_.end()) {
568*635a8641SAndroid Build Coastguard Worker LOG(ERROR) << service_name << " is not owned by the bus";
569*635a8641SAndroid Build Coastguard Worker return false;
570*635a8641SAndroid Build Coastguard Worker }
571*635a8641SAndroid Build Coastguard Worker
572*635a8641SAndroid Build Coastguard Worker ScopedDBusError error;
573*635a8641SAndroid Build Coastguard Worker const int result = dbus_bus_release_name(connection_, service_name.c_str(),
574*635a8641SAndroid Build Coastguard Worker error.get());
575*635a8641SAndroid Build Coastguard Worker if (result == DBUS_RELEASE_NAME_REPLY_RELEASED) {
576*635a8641SAndroid Build Coastguard Worker owned_service_names_.erase(found);
577*635a8641SAndroid Build Coastguard Worker return true;
578*635a8641SAndroid Build Coastguard Worker } else {
579*635a8641SAndroid Build Coastguard Worker LOG(ERROR) << "Failed to release the ownership of " << service_name << ": "
580*635a8641SAndroid Build Coastguard Worker << (error.is_set() ? error.message() : "")
581*635a8641SAndroid Build Coastguard Worker << ", result code: " << result;
582*635a8641SAndroid Build Coastguard Worker return false;
583*635a8641SAndroid Build Coastguard Worker }
584*635a8641SAndroid Build Coastguard Worker }
585*635a8641SAndroid Build Coastguard Worker
SetUpAsyncOperations()586*635a8641SAndroid Build Coastguard Worker bool Bus::SetUpAsyncOperations() {
587*635a8641SAndroid Build Coastguard Worker DCHECK(connection_);
588*635a8641SAndroid Build Coastguard Worker AssertOnDBusThread();
589*635a8641SAndroid Build Coastguard Worker
590*635a8641SAndroid Build Coastguard Worker if (async_operations_set_up_)
591*635a8641SAndroid Build Coastguard Worker return true;
592*635a8641SAndroid Build Coastguard Worker
593*635a8641SAndroid Build Coastguard Worker // Process all the incoming data if any, so that OnDispatchStatus() will
594*635a8641SAndroid Build Coastguard Worker // be called when the incoming data is ready.
595*635a8641SAndroid Build Coastguard Worker ProcessAllIncomingDataIfAny();
596*635a8641SAndroid Build Coastguard Worker
597*635a8641SAndroid Build Coastguard Worker bool success = dbus_connection_set_watch_functions(
598*635a8641SAndroid Build Coastguard Worker connection_, &Bus::OnAddWatchThunk, &Bus::OnRemoveWatchThunk,
599*635a8641SAndroid Build Coastguard Worker &Bus::OnToggleWatchThunk, this, nullptr);
600*635a8641SAndroid Build Coastguard Worker CHECK(success) << "Unable to allocate memory";
601*635a8641SAndroid Build Coastguard Worker
602*635a8641SAndroid Build Coastguard Worker success = dbus_connection_set_timeout_functions(
603*635a8641SAndroid Build Coastguard Worker connection_, &Bus::OnAddTimeoutThunk, &Bus::OnRemoveTimeoutThunk,
604*635a8641SAndroid Build Coastguard Worker &Bus::OnToggleTimeoutThunk, this, nullptr);
605*635a8641SAndroid Build Coastguard Worker CHECK(success) << "Unable to allocate memory";
606*635a8641SAndroid Build Coastguard Worker
607*635a8641SAndroid Build Coastguard Worker dbus_connection_set_dispatch_status_function(
608*635a8641SAndroid Build Coastguard Worker connection_, &Bus::OnDispatchStatusChangedThunk, this, nullptr);
609*635a8641SAndroid Build Coastguard Worker
610*635a8641SAndroid Build Coastguard Worker async_operations_set_up_ = true;
611*635a8641SAndroid Build Coastguard Worker
612*635a8641SAndroid Build Coastguard Worker return true;
613*635a8641SAndroid Build Coastguard Worker }
614*635a8641SAndroid Build Coastguard Worker
SendWithReplyAndBlock(DBusMessage * request,int timeout_ms,DBusError * error)615*635a8641SAndroid Build Coastguard Worker DBusMessage* Bus::SendWithReplyAndBlock(DBusMessage* request,
616*635a8641SAndroid Build Coastguard Worker int timeout_ms,
617*635a8641SAndroid Build Coastguard Worker DBusError* error) {
618*635a8641SAndroid Build Coastguard Worker DCHECK(connection_);
619*635a8641SAndroid Build Coastguard Worker AssertOnDBusThread();
620*635a8641SAndroid Build Coastguard Worker
621*635a8641SAndroid Build Coastguard Worker return dbus_connection_send_with_reply_and_block(
622*635a8641SAndroid Build Coastguard Worker connection_, request, timeout_ms, error);
623*635a8641SAndroid Build Coastguard Worker }
624*635a8641SAndroid Build Coastguard Worker
SendWithReply(DBusMessage * request,DBusPendingCall ** pending_call,int timeout_ms)625*635a8641SAndroid Build Coastguard Worker void Bus::SendWithReply(DBusMessage* request,
626*635a8641SAndroid Build Coastguard Worker DBusPendingCall** pending_call,
627*635a8641SAndroid Build Coastguard Worker int timeout_ms) {
628*635a8641SAndroid Build Coastguard Worker DCHECK(connection_);
629*635a8641SAndroid Build Coastguard Worker AssertOnDBusThread();
630*635a8641SAndroid Build Coastguard Worker
631*635a8641SAndroid Build Coastguard Worker const bool success = dbus_connection_send_with_reply(
632*635a8641SAndroid Build Coastguard Worker connection_, request, pending_call, timeout_ms);
633*635a8641SAndroid Build Coastguard Worker CHECK(success) << "Unable to allocate memory";
634*635a8641SAndroid Build Coastguard Worker }
635*635a8641SAndroid Build Coastguard Worker
Send(DBusMessage * request,uint32_t * serial)636*635a8641SAndroid Build Coastguard Worker void Bus::Send(DBusMessage* request, uint32_t* serial) {
637*635a8641SAndroid Build Coastguard Worker DCHECK(connection_);
638*635a8641SAndroid Build Coastguard Worker AssertOnDBusThread();
639*635a8641SAndroid Build Coastguard Worker
640*635a8641SAndroid Build Coastguard Worker const bool success = dbus_connection_send(connection_, request, serial);
641*635a8641SAndroid Build Coastguard Worker CHECK(success) << "Unable to allocate memory";
642*635a8641SAndroid Build Coastguard Worker }
643*635a8641SAndroid Build Coastguard Worker
AddFilterFunction(DBusHandleMessageFunction filter_function,void * user_data)644*635a8641SAndroid Build Coastguard Worker void Bus::AddFilterFunction(DBusHandleMessageFunction filter_function,
645*635a8641SAndroid Build Coastguard Worker void* user_data) {
646*635a8641SAndroid Build Coastguard Worker DCHECK(connection_);
647*635a8641SAndroid Build Coastguard Worker AssertOnDBusThread();
648*635a8641SAndroid Build Coastguard Worker
649*635a8641SAndroid Build Coastguard Worker std::pair<DBusHandleMessageFunction, void*> filter_data_pair =
650*635a8641SAndroid Build Coastguard Worker std::make_pair(filter_function, user_data);
651*635a8641SAndroid Build Coastguard Worker if (filter_functions_added_.find(filter_data_pair) !=
652*635a8641SAndroid Build Coastguard Worker filter_functions_added_.end()) {
653*635a8641SAndroid Build Coastguard Worker VLOG(1) << "Filter function already exists: " << filter_function
654*635a8641SAndroid Build Coastguard Worker << " with associated data: " << user_data;
655*635a8641SAndroid Build Coastguard Worker return;
656*635a8641SAndroid Build Coastguard Worker }
657*635a8641SAndroid Build Coastguard Worker
658*635a8641SAndroid Build Coastguard Worker const bool success = dbus_connection_add_filter(connection_, filter_function,
659*635a8641SAndroid Build Coastguard Worker user_data, nullptr);
660*635a8641SAndroid Build Coastguard Worker CHECK(success) << "Unable to allocate memory";
661*635a8641SAndroid Build Coastguard Worker filter_functions_added_.insert(filter_data_pair);
662*635a8641SAndroid Build Coastguard Worker }
663*635a8641SAndroid Build Coastguard Worker
RemoveFilterFunction(DBusHandleMessageFunction filter_function,void * user_data)664*635a8641SAndroid Build Coastguard Worker void Bus::RemoveFilterFunction(DBusHandleMessageFunction filter_function,
665*635a8641SAndroid Build Coastguard Worker void* user_data) {
666*635a8641SAndroid Build Coastguard Worker DCHECK(connection_);
667*635a8641SAndroid Build Coastguard Worker AssertOnDBusThread();
668*635a8641SAndroid Build Coastguard Worker
669*635a8641SAndroid Build Coastguard Worker std::pair<DBusHandleMessageFunction, void*> filter_data_pair =
670*635a8641SAndroid Build Coastguard Worker std::make_pair(filter_function, user_data);
671*635a8641SAndroid Build Coastguard Worker if (filter_functions_added_.find(filter_data_pair) ==
672*635a8641SAndroid Build Coastguard Worker filter_functions_added_.end()) {
673*635a8641SAndroid Build Coastguard Worker VLOG(1) << "Requested to remove an unknown filter function: "
674*635a8641SAndroid Build Coastguard Worker << filter_function
675*635a8641SAndroid Build Coastguard Worker << " with associated data: " << user_data;
676*635a8641SAndroid Build Coastguard Worker return;
677*635a8641SAndroid Build Coastguard Worker }
678*635a8641SAndroid Build Coastguard Worker
679*635a8641SAndroid Build Coastguard Worker dbus_connection_remove_filter(connection_, filter_function, user_data);
680*635a8641SAndroid Build Coastguard Worker filter_functions_added_.erase(filter_data_pair);
681*635a8641SAndroid Build Coastguard Worker }
682*635a8641SAndroid Build Coastguard Worker
AddMatch(const std::string & match_rule,DBusError * error)683*635a8641SAndroid Build Coastguard Worker void Bus::AddMatch(const std::string& match_rule, DBusError* error) {
684*635a8641SAndroid Build Coastguard Worker DCHECK(connection_);
685*635a8641SAndroid Build Coastguard Worker AssertOnDBusThread();
686*635a8641SAndroid Build Coastguard Worker
687*635a8641SAndroid Build Coastguard Worker std::map<std::string, int>::iterator iter =
688*635a8641SAndroid Build Coastguard Worker match_rules_added_.find(match_rule);
689*635a8641SAndroid Build Coastguard Worker if (iter != match_rules_added_.end()) {
690*635a8641SAndroid Build Coastguard Worker // The already existing rule's counter is incremented.
691*635a8641SAndroid Build Coastguard Worker iter->second++;
692*635a8641SAndroid Build Coastguard Worker
693*635a8641SAndroid Build Coastguard Worker VLOG(1) << "Match rule already exists: " << match_rule;
694*635a8641SAndroid Build Coastguard Worker return;
695*635a8641SAndroid Build Coastguard Worker }
696*635a8641SAndroid Build Coastguard Worker
697*635a8641SAndroid Build Coastguard Worker dbus_bus_add_match(connection_, match_rule.c_str(), error);
698*635a8641SAndroid Build Coastguard Worker match_rules_added_[match_rule] = 1;
699*635a8641SAndroid Build Coastguard Worker }
700*635a8641SAndroid Build Coastguard Worker
RemoveMatch(const std::string & match_rule,DBusError * error)701*635a8641SAndroid Build Coastguard Worker bool Bus::RemoveMatch(const std::string& match_rule, DBusError* error) {
702*635a8641SAndroid Build Coastguard Worker DCHECK(connection_);
703*635a8641SAndroid Build Coastguard Worker AssertOnDBusThread();
704*635a8641SAndroid Build Coastguard Worker
705*635a8641SAndroid Build Coastguard Worker std::map<std::string, int>::iterator iter =
706*635a8641SAndroid Build Coastguard Worker match_rules_added_.find(match_rule);
707*635a8641SAndroid Build Coastguard Worker if (iter == match_rules_added_.end()) {
708*635a8641SAndroid Build Coastguard Worker LOG(ERROR) << "Requested to remove an unknown match rule: " << match_rule;
709*635a8641SAndroid Build Coastguard Worker return false;
710*635a8641SAndroid Build Coastguard Worker }
711*635a8641SAndroid Build Coastguard Worker
712*635a8641SAndroid Build Coastguard Worker // The rule's counter is decremented and the rule is deleted when reachs 0.
713*635a8641SAndroid Build Coastguard Worker iter->second--;
714*635a8641SAndroid Build Coastguard Worker if (iter->second == 0) {
715*635a8641SAndroid Build Coastguard Worker dbus_bus_remove_match(connection_, match_rule.c_str(), error);
716*635a8641SAndroid Build Coastguard Worker match_rules_added_.erase(match_rule);
717*635a8641SAndroid Build Coastguard Worker }
718*635a8641SAndroid Build Coastguard Worker return true;
719*635a8641SAndroid Build Coastguard Worker }
720*635a8641SAndroid Build Coastguard Worker
TryRegisterObjectPath(const ObjectPath & object_path,const DBusObjectPathVTable * vtable,void * user_data,DBusError * error)721*635a8641SAndroid Build Coastguard Worker bool Bus::TryRegisterObjectPath(const ObjectPath& object_path,
722*635a8641SAndroid Build Coastguard Worker const DBusObjectPathVTable* vtable,
723*635a8641SAndroid Build Coastguard Worker void* user_data,
724*635a8641SAndroid Build Coastguard Worker DBusError* error) {
725*635a8641SAndroid Build Coastguard Worker DCHECK(connection_);
726*635a8641SAndroid Build Coastguard Worker AssertOnDBusThread();
727*635a8641SAndroid Build Coastguard Worker
728*635a8641SAndroid Build Coastguard Worker if (registered_object_paths_.find(object_path) !=
729*635a8641SAndroid Build Coastguard Worker registered_object_paths_.end()) {
730*635a8641SAndroid Build Coastguard Worker LOG(ERROR) << "Object path already registered: " << object_path.value();
731*635a8641SAndroid Build Coastguard Worker return false;
732*635a8641SAndroid Build Coastguard Worker }
733*635a8641SAndroid Build Coastguard Worker
734*635a8641SAndroid Build Coastguard Worker const bool success = dbus_connection_try_register_object_path(
735*635a8641SAndroid Build Coastguard Worker connection_,
736*635a8641SAndroid Build Coastguard Worker object_path.value().c_str(),
737*635a8641SAndroid Build Coastguard Worker vtable,
738*635a8641SAndroid Build Coastguard Worker user_data,
739*635a8641SAndroid Build Coastguard Worker error);
740*635a8641SAndroid Build Coastguard Worker if (success)
741*635a8641SAndroid Build Coastguard Worker registered_object_paths_.insert(object_path);
742*635a8641SAndroid Build Coastguard Worker return success;
743*635a8641SAndroid Build Coastguard Worker }
744*635a8641SAndroid Build Coastguard Worker
UnregisterObjectPath(const ObjectPath & object_path)745*635a8641SAndroid Build Coastguard Worker void Bus::UnregisterObjectPath(const ObjectPath& object_path) {
746*635a8641SAndroid Build Coastguard Worker DCHECK(connection_);
747*635a8641SAndroid Build Coastguard Worker AssertOnDBusThread();
748*635a8641SAndroid Build Coastguard Worker
749*635a8641SAndroid Build Coastguard Worker if (registered_object_paths_.find(object_path) ==
750*635a8641SAndroid Build Coastguard Worker registered_object_paths_.end()) {
751*635a8641SAndroid Build Coastguard Worker LOG(ERROR) << "Requested to unregister an unknown object path: "
752*635a8641SAndroid Build Coastguard Worker << object_path.value();
753*635a8641SAndroid Build Coastguard Worker return;
754*635a8641SAndroid Build Coastguard Worker }
755*635a8641SAndroid Build Coastguard Worker
756*635a8641SAndroid Build Coastguard Worker const bool success = dbus_connection_unregister_object_path(
757*635a8641SAndroid Build Coastguard Worker connection_,
758*635a8641SAndroid Build Coastguard Worker object_path.value().c_str());
759*635a8641SAndroid Build Coastguard Worker CHECK(success) << "Unable to allocate memory";
760*635a8641SAndroid Build Coastguard Worker registered_object_paths_.erase(object_path);
761*635a8641SAndroid Build Coastguard Worker }
762*635a8641SAndroid Build Coastguard Worker
ShutdownOnDBusThreadAndBlockInternal()763*635a8641SAndroid Build Coastguard Worker void Bus::ShutdownOnDBusThreadAndBlockInternal() {
764*635a8641SAndroid Build Coastguard Worker AssertOnDBusThread();
765*635a8641SAndroid Build Coastguard Worker
766*635a8641SAndroid Build Coastguard Worker ShutdownAndBlock();
767*635a8641SAndroid Build Coastguard Worker on_shutdown_.Signal();
768*635a8641SAndroid Build Coastguard Worker }
769*635a8641SAndroid Build Coastguard Worker
ProcessAllIncomingDataIfAny()770*635a8641SAndroid Build Coastguard Worker void Bus::ProcessAllIncomingDataIfAny() {
771*635a8641SAndroid Build Coastguard Worker AssertOnDBusThread();
772*635a8641SAndroid Build Coastguard Worker
773*635a8641SAndroid Build Coastguard Worker // As mentioned at the class comment in .h file, connection_ can be NULL.
774*635a8641SAndroid Build Coastguard Worker if (!connection_)
775*635a8641SAndroid Build Coastguard Worker return;
776*635a8641SAndroid Build Coastguard Worker
777*635a8641SAndroid Build Coastguard Worker // It is safe and necessary to call dbus_connection_get_dispatch_status even
778*635a8641SAndroid Build Coastguard Worker // if the connection is lost.
779*635a8641SAndroid Build Coastguard Worker if (dbus_connection_get_dispatch_status(connection_) ==
780*635a8641SAndroid Build Coastguard Worker DBUS_DISPATCH_DATA_REMAINS) {
781*635a8641SAndroid Build Coastguard Worker while (dbus_connection_dispatch(connection_) ==
782*635a8641SAndroid Build Coastguard Worker DBUS_DISPATCH_DATA_REMAINS) {
783*635a8641SAndroid Build Coastguard Worker }
784*635a8641SAndroid Build Coastguard Worker }
785*635a8641SAndroid Build Coastguard Worker }
786*635a8641SAndroid Build Coastguard Worker
GetDBusTaskRunner()787*635a8641SAndroid Build Coastguard Worker base::TaskRunner* Bus::GetDBusTaskRunner() {
788*635a8641SAndroid Build Coastguard Worker if (dbus_task_runner_)
789*635a8641SAndroid Build Coastguard Worker return dbus_task_runner_.get();
790*635a8641SAndroid Build Coastguard Worker else
791*635a8641SAndroid Build Coastguard Worker return GetOriginTaskRunner();
792*635a8641SAndroid Build Coastguard Worker }
793*635a8641SAndroid Build Coastguard Worker
GetOriginTaskRunner()794*635a8641SAndroid Build Coastguard Worker base::TaskRunner* Bus::GetOriginTaskRunner() {
795*635a8641SAndroid Build Coastguard Worker DCHECK(origin_task_runner_);
796*635a8641SAndroid Build Coastguard Worker return origin_task_runner_.get();
797*635a8641SAndroid Build Coastguard Worker }
798*635a8641SAndroid Build Coastguard Worker
HasDBusThread()799*635a8641SAndroid Build Coastguard Worker bool Bus::HasDBusThread() {
800*635a8641SAndroid Build Coastguard Worker return dbus_task_runner_ != nullptr;
801*635a8641SAndroid Build Coastguard Worker }
802*635a8641SAndroid Build Coastguard Worker
AssertOnOriginThread()803*635a8641SAndroid Build Coastguard Worker void Bus::AssertOnOriginThread() {
804*635a8641SAndroid Build Coastguard Worker DCHECK_EQ(origin_thread_id_, base::PlatformThread::CurrentId());
805*635a8641SAndroid Build Coastguard Worker }
806*635a8641SAndroid Build Coastguard Worker
AssertOnDBusThread()807*635a8641SAndroid Build Coastguard Worker void Bus::AssertOnDBusThread() {
808*635a8641SAndroid Build Coastguard Worker base::AssertBlockingAllowed();
809*635a8641SAndroid Build Coastguard Worker
810*635a8641SAndroid Build Coastguard Worker if (dbus_task_runner_) {
811*635a8641SAndroid Build Coastguard Worker DCHECK(dbus_task_runner_->RunsTasksInCurrentSequence());
812*635a8641SAndroid Build Coastguard Worker } else {
813*635a8641SAndroid Build Coastguard Worker AssertOnOriginThread();
814*635a8641SAndroid Build Coastguard Worker }
815*635a8641SAndroid Build Coastguard Worker }
816*635a8641SAndroid Build Coastguard Worker
GetServiceOwnerAndBlock(const std::string & service_name,GetServiceOwnerOption options)817*635a8641SAndroid Build Coastguard Worker std::string Bus::GetServiceOwnerAndBlock(const std::string& service_name,
818*635a8641SAndroid Build Coastguard Worker GetServiceOwnerOption options) {
819*635a8641SAndroid Build Coastguard Worker AssertOnDBusThread();
820*635a8641SAndroid Build Coastguard Worker
821*635a8641SAndroid Build Coastguard Worker MethodCall get_name_owner_call("org.freedesktop.DBus", "GetNameOwner");
822*635a8641SAndroid Build Coastguard Worker MessageWriter writer(&get_name_owner_call);
823*635a8641SAndroid Build Coastguard Worker writer.AppendString(service_name);
824*635a8641SAndroid Build Coastguard Worker VLOG(1) << "Method call: " << get_name_owner_call.ToString();
825*635a8641SAndroid Build Coastguard Worker
826*635a8641SAndroid Build Coastguard Worker const ObjectPath obj_path("/org/freedesktop/DBus");
827*635a8641SAndroid Build Coastguard Worker if (!get_name_owner_call.SetDestination("org.freedesktop.DBus") ||
828*635a8641SAndroid Build Coastguard Worker !get_name_owner_call.SetPath(obj_path)) {
829*635a8641SAndroid Build Coastguard Worker if (options == REPORT_ERRORS)
830*635a8641SAndroid Build Coastguard Worker LOG(ERROR) << "Failed to get name owner.";
831*635a8641SAndroid Build Coastguard Worker return "";
832*635a8641SAndroid Build Coastguard Worker }
833*635a8641SAndroid Build Coastguard Worker
834*635a8641SAndroid Build Coastguard Worker ScopedDBusError error;
835*635a8641SAndroid Build Coastguard Worker DBusMessage* response_message =
836*635a8641SAndroid Build Coastguard Worker SendWithReplyAndBlock(get_name_owner_call.raw_message(),
837*635a8641SAndroid Build Coastguard Worker ObjectProxy::TIMEOUT_USE_DEFAULT,
838*635a8641SAndroid Build Coastguard Worker error.get());
839*635a8641SAndroid Build Coastguard Worker if (!response_message) {
840*635a8641SAndroid Build Coastguard Worker if (options == REPORT_ERRORS) {
841*635a8641SAndroid Build Coastguard Worker LOG(ERROR) << "Failed to get name owner. Got " << error.name() << ": "
842*635a8641SAndroid Build Coastguard Worker << error.message();
843*635a8641SAndroid Build Coastguard Worker }
844*635a8641SAndroid Build Coastguard Worker return "";
845*635a8641SAndroid Build Coastguard Worker }
846*635a8641SAndroid Build Coastguard Worker
847*635a8641SAndroid Build Coastguard Worker std::unique_ptr<Response> response(
848*635a8641SAndroid Build Coastguard Worker Response::FromRawMessage(response_message));
849*635a8641SAndroid Build Coastguard Worker MessageReader reader(response.get());
850*635a8641SAndroid Build Coastguard Worker
851*635a8641SAndroid Build Coastguard Worker std::string service_owner;
852*635a8641SAndroid Build Coastguard Worker if (!reader.PopString(&service_owner))
853*635a8641SAndroid Build Coastguard Worker service_owner.clear();
854*635a8641SAndroid Build Coastguard Worker return service_owner;
855*635a8641SAndroid Build Coastguard Worker }
856*635a8641SAndroid Build Coastguard Worker
GetServiceOwner(const std::string & service_name,const GetServiceOwnerCallback & callback)857*635a8641SAndroid Build Coastguard Worker void Bus::GetServiceOwner(const std::string& service_name,
858*635a8641SAndroid Build Coastguard Worker const GetServiceOwnerCallback& callback) {
859*635a8641SAndroid Build Coastguard Worker AssertOnOriginThread();
860*635a8641SAndroid Build Coastguard Worker
861*635a8641SAndroid Build Coastguard Worker GetDBusTaskRunner()->PostTask(
862*635a8641SAndroid Build Coastguard Worker FROM_HERE,
863*635a8641SAndroid Build Coastguard Worker base::Bind(&Bus::GetServiceOwnerInternal, this, service_name, callback));
864*635a8641SAndroid Build Coastguard Worker }
865*635a8641SAndroid Build Coastguard Worker
GetServiceOwnerInternal(const std::string & service_name,const GetServiceOwnerCallback & callback)866*635a8641SAndroid Build Coastguard Worker void Bus::GetServiceOwnerInternal(const std::string& service_name,
867*635a8641SAndroid Build Coastguard Worker const GetServiceOwnerCallback& callback) {
868*635a8641SAndroid Build Coastguard Worker AssertOnDBusThread();
869*635a8641SAndroid Build Coastguard Worker
870*635a8641SAndroid Build Coastguard Worker std::string service_owner;
871*635a8641SAndroid Build Coastguard Worker if (Connect())
872*635a8641SAndroid Build Coastguard Worker service_owner = GetServiceOwnerAndBlock(service_name, SUPPRESS_ERRORS);
873*635a8641SAndroid Build Coastguard Worker GetOriginTaskRunner()->PostTask(FROM_HERE,
874*635a8641SAndroid Build Coastguard Worker base::Bind(callback, service_owner));
875*635a8641SAndroid Build Coastguard Worker }
876*635a8641SAndroid Build Coastguard Worker
ListenForServiceOwnerChange(const std::string & service_name,const GetServiceOwnerCallback & callback)877*635a8641SAndroid Build Coastguard Worker void Bus::ListenForServiceOwnerChange(
878*635a8641SAndroid Build Coastguard Worker const std::string& service_name,
879*635a8641SAndroid Build Coastguard Worker const GetServiceOwnerCallback& callback) {
880*635a8641SAndroid Build Coastguard Worker AssertOnOriginThread();
881*635a8641SAndroid Build Coastguard Worker DCHECK(!service_name.empty());
882*635a8641SAndroid Build Coastguard Worker DCHECK(!callback.is_null());
883*635a8641SAndroid Build Coastguard Worker
884*635a8641SAndroid Build Coastguard Worker GetDBusTaskRunner()->PostTask(
885*635a8641SAndroid Build Coastguard Worker FROM_HERE,
886*635a8641SAndroid Build Coastguard Worker base::Bind(&Bus::ListenForServiceOwnerChangeInternal,
887*635a8641SAndroid Build Coastguard Worker this, service_name, callback));
888*635a8641SAndroid Build Coastguard Worker }
889*635a8641SAndroid Build Coastguard Worker
ListenForServiceOwnerChangeInternal(const std::string & service_name,const GetServiceOwnerCallback & callback)890*635a8641SAndroid Build Coastguard Worker void Bus::ListenForServiceOwnerChangeInternal(
891*635a8641SAndroid Build Coastguard Worker const std::string& service_name,
892*635a8641SAndroid Build Coastguard Worker const GetServiceOwnerCallback& callback) {
893*635a8641SAndroid Build Coastguard Worker AssertOnDBusThread();
894*635a8641SAndroid Build Coastguard Worker DCHECK(!service_name.empty());
895*635a8641SAndroid Build Coastguard Worker DCHECK(!callback.is_null());
896*635a8641SAndroid Build Coastguard Worker
897*635a8641SAndroid Build Coastguard Worker if (!Connect() || !SetUpAsyncOperations())
898*635a8641SAndroid Build Coastguard Worker return;
899*635a8641SAndroid Build Coastguard Worker
900*635a8641SAndroid Build Coastguard Worker if (service_owner_changed_listener_map_.empty())
901*635a8641SAndroid Build Coastguard Worker AddFilterFunction(Bus::OnServiceOwnerChangedFilter, this);
902*635a8641SAndroid Build Coastguard Worker
903*635a8641SAndroid Build Coastguard Worker ServiceOwnerChangedListenerMap::iterator it =
904*635a8641SAndroid Build Coastguard Worker service_owner_changed_listener_map_.find(service_name);
905*635a8641SAndroid Build Coastguard Worker if (it == service_owner_changed_listener_map_.end()) {
906*635a8641SAndroid Build Coastguard Worker // Add a match rule for the new service name.
907*635a8641SAndroid Build Coastguard Worker const std::string name_owner_changed_match_rule =
908*635a8641SAndroid Build Coastguard Worker base::StringPrintf(kServiceNameOwnerChangeMatchRule,
909*635a8641SAndroid Build Coastguard Worker service_name.c_str());
910*635a8641SAndroid Build Coastguard Worker ScopedDBusError error;
911*635a8641SAndroid Build Coastguard Worker AddMatch(name_owner_changed_match_rule, error.get());
912*635a8641SAndroid Build Coastguard Worker if (error.is_set()) {
913*635a8641SAndroid Build Coastguard Worker LOG(ERROR) << "Failed to add match rule for " << service_name
914*635a8641SAndroid Build Coastguard Worker << ". Got " << error.name() << ": " << error.message();
915*635a8641SAndroid Build Coastguard Worker return;
916*635a8641SAndroid Build Coastguard Worker }
917*635a8641SAndroid Build Coastguard Worker
918*635a8641SAndroid Build Coastguard Worker service_owner_changed_listener_map_[service_name].push_back(callback);
919*635a8641SAndroid Build Coastguard Worker return;
920*635a8641SAndroid Build Coastguard Worker }
921*635a8641SAndroid Build Coastguard Worker
922*635a8641SAndroid Build Coastguard Worker // Check if the callback has already been added.
923*635a8641SAndroid Build Coastguard Worker std::vector<GetServiceOwnerCallback>& callbacks = it->second;
924*635a8641SAndroid Build Coastguard Worker for (size_t i = 0; i < callbacks.size(); ++i) {
925*635a8641SAndroid Build Coastguard Worker if (callbacks[i].Equals(callback))
926*635a8641SAndroid Build Coastguard Worker return;
927*635a8641SAndroid Build Coastguard Worker }
928*635a8641SAndroid Build Coastguard Worker callbacks.push_back(callback);
929*635a8641SAndroid Build Coastguard Worker }
930*635a8641SAndroid Build Coastguard Worker
UnlistenForServiceOwnerChange(const std::string & service_name,const GetServiceOwnerCallback & callback)931*635a8641SAndroid Build Coastguard Worker void Bus::UnlistenForServiceOwnerChange(
932*635a8641SAndroid Build Coastguard Worker const std::string& service_name,
933*635a8641SAndroid Build Coastguard Worker const GetServiceOwnerCallback& callback) {
934*635a8641SAndroid Build Coastguard Worker AssertOnOriginThread();
935*635a8641SAndroid Build Coastguard Worker DCHECK(!service_name.empty());
936*635a8641SAndroid Build Coastguard Worker DCHECK(!callback.is_null());
937*635a8641SAndroid Build Coastguard Worker
938*635a8641SAndroid Build Coastguard Worker GetDBusTaskRunner()->PostTask(
939*635a8641SAndroid Build Coastguard Worker FROM_HERE,
940*635a8641SAndroid Build Coastguard Worker base::Bind(&Bus::UnlistenForServiceOwnerChangeInternal,
941*635a8641SAndroid Build Coastguard Worker this, service_name, callback));
942*635a8641SAndroid Build Coastguard Worker }
943*635a8641SAndroid Build Coastguard Worker
UnlistenForServiceOwnerChangeInternal(const std::string & service_name,const GetServiceOwnerCallback & callback)944*635a8641SAndroid Build Coastguard Worker void Bus::UnlistenForServiceOwnerChangeInternal(
945*635a8641SAndroid Build Coastguard Worker const std::string& service_name,
946*635a8641SAndroid Build Coastguard Worker const GetServiceOwnerCallback& callback) {
947*635a8641SAndroid Build Coastguard Worker AssertOnDBusThread();
948*635a8641SAndroid Build Coastguard Worker DCHECK(!service_name.empty());
949*635a8641SAndroid Build Coastguard Worker DCHECK(!callback.is_null());
950*635a8641SAndroid Build Coastguard Worker
951*635a8641SAndroid Build Coastguard Worker ServiceOwnerChangedListenerMap::iterator it =
952*635a8641SAndroid Build Coastguard Worker service_owner_changed_listener_map_.find(service_name);
953*635a8641SAndroid Build Coastguard Worker if (it == service_owner_changed_listener_map_.end())
954*635a8641SAndroid Build Coastguard Worker return;
955*635a8641SAndroid Build Coastguard Worker
956*635a8641SAndroid Build Coastguard Worker std::vector<GetServiceOwnerCallback>& callbacks = it->second;
957*635a8641SAndroid Build Coastguard Worker for (size_t i = 0; i < callbacks.size(); ++i) {
958*635a8641SAndroid Build Coastguard Worker if (callbacks[i].Equals(callback)) {
959*635a8641SAndroid Build Coastguard Worker callbacks.erase(callbacks.begin() + i);
960*635a8641SAndroid Build Coastguard Worker break; // There can be only one.
961*635a8641SAndroid Build Coastguard Worker }
962*635a8641SAndroid Build Coastguard Worker }
963*635a8641SAndroid Build Coastguard Worker if (!callbacks.empty())
964*635a8641SAndroid Build Coastguard Worker return;
965*635a8641SAndroid Build Coastguard Worker
966*635a8641SAndroid Build Coastguard Worker // Last callback for |service_name| has been removed, remove match rule.
967*635a8641SAndroid Build Coastguard Worker const std::string name_owner_changed_match_rule =
968*635a8641SAndroid Build Coastguard Worker base::StringPrintf(kServiceNameOwnerChangeMatchRule,
969*635a8641SAndroid Build Coastguard Worker service_name.c_str());
970*635a8641SAndroid Build Coastguard Worker ScopedDBusError error;
971*635a8641SAndroid Build Coastguard Worker RemoveMatch(name_owner_changed_match_rule, error.get());
972*635a8641SAndroid Build Coastguard Worker // And remove |service_owner_changed_listener_map_| entry.
973*635a8641SAndroid Build Coastguard Worker service_owner_changed_listener_map_.erase(it);
974*635a8641SAndroid Build Coastguard Worker
975*635a8641SAndroid Build Coastguard Worker if (service_owner_changed_listener_map_.empty())
976*635a8641SAndroid Build Coastguard Worker RemoveFilterFunction(Bus::OnServiceOwnerChangedFilter, this);
977*635a8641SAndroid Build Coastguard Worker }
978*635a8641SAndroid Build Coastguard Worker
GetConnectionName()979*635a8641SAndroid Build Coastguard Worker std::string Bus::GetConnectionName() {
980*635a8641SAndroid Build Coastguard Worker if (!connection_)
981*635a8641SAndroid Build Coastguard Worker return "";
982*635a8641SAndroid Build Coastguard Worker return dbus_bus_get_unique_name(connection_);
983*635a8641SAndroid Build Coastguard Worker }
984*635a8641SAndroid Build Coastguard Worker
OnAddWatch(DBusWatch * raw_watch)985*635a8641SAndroid Build Coastguard Worker dbus_bool_t Bus::OnAddWatch(DBusWatch* raw_watch) {
986*635a8641SAndroid Build Coastguard Worker AssertOnDBusThread();
987*635a8641SAndroid Build Coastguard Worker
988*635a8641SAndroid Build Coastguard Worker // watch will be deleted when raw_watch is removed in OnRemoveWatch().
989*635a8641SAndroid Build Coastguard Worker Watch* watch = new Watch(raw_watch);
990*635a8641SAndroid Build Coastguard Worker if (watch->IsReadyToBeWatched()) {
991*635a8641SAndroid Build Coastguard Worker watch->StartWatching();
992*635a8641SAndroid Build Coastguard Worker }
993*635a8641SAndroid Build Coastguard Worker ++num_pending_watches_;
994*635a8641SAndroid Build Coastguard Worker return true;
995*635a8641SAndroid Build Coastguard Worker }
996*635a8641SAndroid Build Coastguard Worker
OnRemoveWatch(DBusWatch * raw_watch)997*635a8641SAndroid Build Coastguard Worker void Bus::OnRemoveWatch(DBusWatch* raw_watch) {
998*635a8641SAndroid Build Coastguard Worker AssertOnDBusThread();
999*635a8641SAndroid Build Coastguard Worker
1000*635a8641SAndroid Build Coastguard Worker Watch* watch = static_cast<Watch*>(dbus_watch_get_data(raw_watch));
1001*635a8641SAndroid Build Coastguard Worker delete watch;
1002*635a8641SAndroid Build Coastguard Worker --num_pending_watches_;
1003*635a8641SAndroid Build Coastguard Worker }
1004*635a8641SAndroid Build Coastguard Worker
OnToggleWatch(DBusWatch * raw_watch)1005*635a8641SAndroid Build Coastguard Worker void Bus::OnToggleWatch(DBusWatch* raw_watch) {
1006*635a8641SAndroid Build Coastguard Worker AssertOnDBusThread();
1007*635a8641SAndroid Build Coastguard Worker
1008*635a8641SAndroid Build Coastguard Worker Watch* watch = static_cast<Watch*>(dbus_watch_get_data(raw_watch));
1009*635a8641SAndroid Build Coastguard Worker if (watch->IsReadyToBeWatched())
1010*635a8641SAndroid Build Coastguard Worker watch->StartWatching();
1011*635a8641SAndroid Build Coastguard Worker else
1012*635a8641SAndroid Build Coastguard Worker watch->StopWatching();
1013*635a8641SAndroid Build Coastguard Worker }
1014*635a8641SAndroid Build Coastguard Worker
OnAddTimeout(DBusTimeout * raw_timeout)1015*635a8641SAndroid Build Coastguard Worker dbus_bool_t Bus::OnAddTimeout(DBusTimeout* raw_timeout) {
1016*635a8641SAndroid Build Coastguard Worker AssertOnDBusThread();
1017*635a8641SAndroid Build Coastguard Worker
1018*635a8641SAndroid Build Coastguard Worker // |timeout| will be deleted by OnRemoveTimeoutThunk().
1019*635a8641SAndroid Build Coastguard Worker Timeout* timeout = new Timeout(raw_timeout);
1020*635a8641SAndroid Build Coastguard Worker if (timeout->IsReadyToBeMonitored()) {
1021*635a8641SAndroid Build Coastguard Worker timeout->StartMonitoring(this);
1022*635a8641SAndroid Build Coastguard Worker }
1023*635a8641SAndroid Build Coastguard Worker ++num_pending_timeouts_;
1024*635a8641SAndroid Build Coastguard Worker return true;
1025*635a8641SAndroid Build Coastguard Worker }
1026*635a8641SAndroid Build Coastguard Worker
OnRemoveTimeout(DBusTimeout * raw_timeout)1027*635a8641SAndroid Build Coastguard Worker void Bus::OnRemoveTimeout(DBusTimeout* raw_timeout) {
1028*635a8641SAndroid Build Coastguard Worker AssertOnDBusThread();
1029*635a8641SAndroid Build Coastguard Worker
1030*635a8641SAndroid Build Coastguard Worker Timeout* timeout = static_cast<Timeout*>(dbus_timeout_get_data(raw_timeout));
1031*635a8641SAndroid Build Coastguard Worker delete timeout;
1032*635a8641SAndroid Build Coastguard Worker --num_pending_timeouts_;
1033*635a8641SAndroid Build Coastguard Worker }
1034*635a8641SAndroid Build Coastguard Worker
OnToggleTimeout(DBusTimeout * raw_timeout)1035*635a8641SAndroid Build Coastguard Worker void Bus::OnToggleTimeout(DBusTimeout* raw_timeout) {
1036*635a8641SAndroid Build Coastguard Worker AssertOnDBusThread();
1037*635a8641SAndroid Build Coastguard Worker
1038*635a8641SAndroid Build Coastguard Worker Timeout* timeout = static_cast<Timeout*>(dbus_timeout_get_data(raw_timeout));
1039*635a8641SAndroid Build Coastguard Worker if (timeout->IsReadyToBeMonitored()) {
1040*635a8641SAndroid Build Coastguard Worker timeout->StartMonitoring(this);
1041*635a8641SAndroid Build Coastguard Worker } else {
1042*635a8641SAndroid Build Coastguard Worker timeout->StopMonitoring();
1043*635a8641SAndroid Build Coastguard Worker }
1044*635a8641SAndroid Build Coastguard Worker }
1045*635a8641SAndroid Build Coastguard Worker
OnDispatchStatusChanged(DBusConnection * connection,DBusDispatchStatus status)1046*635a8641SAndroid Build Coastguard Worker void Bus::OnDispatchStatusChanged(DBusConnection* connection,
1047*635a8641SAndroid Build Coastguard Worker DBusDispatchStatus status) {
1048*635a8641SAndroid Build Coastguard Worker DCHECK_EQ(connection, connection_);
1049*635a8641SAndroid Build Coastguard Worker AssertOnDBusThread();
1050*635a8641SAndroid Build Coastguard Worker
1051*635a8641SAndroid Build Coastguard Worker // We cannot call ProcessAllIncomingDataIfAny() here, as calling
1052*635a8641SAndroid Build Coastguard Worker // dbus_connection_dispatch() inside DBusDispatchStatusFunction is
1053*635a8641SAndroid Build Coastguard Worker // prohibited by the D-Bus library. Hence, we post a task here instead.
1054*635a8641SAndroid Build Coastguard Worker // See comments for dbus_connection_set_dispatch_status_function().
1055*635a8641SAndroid Build Coastguard Worker GetDBusTaskRunner()->PostTask(FROM_HERE,
1056*635a8641SAndroid Build Coastguard Worker base::Bind(&Bus::ProcessAllIncomingDataIfAny,
1057*635a8641SAndroid Build Coastguard Worker this));
1058*635a8641SAndroid Build Coastguard Worker }
1059*635a8641SAndroid Build Coastguard Worker
OnServiceOwnerChanged(DBusMessage * message)1060*635a8641SAndroid Build Coastguard Worker void Bus::OnServiceOwnerChanged(DBusMessage* message) {
1061*635a8641SAndroid Build Coastguard Worker DCHECK(message);
1062*635a8641SAndroid Build Coastguard Worker AssertOnDBusThread();
1063*635a8641SAndroid Build Coastguard Worker
1064*635a8641SAndroid Build Coastguard Worker // |message| will be unrefed on exit of the function. Increment the
1065*635a8641SAndroid Build Coastguard Worker // reference so we can use it in Signal::FromRawMessage() below.
1066*635a8641SAndroid Build Coastguard Worker dbus_message_ref(message);
1067*635a8641SAndroid Build Coastguard Worker std::unique_ptr<Signal> signal(Signal::FromRawMessage(message));
1068*635a8641SAndroid Build Coastguard Worker
1069*635a8641SAndroid Build Coastguard Worker // Confirm the validity of the NameOwnerChanged signal.
1070*635a8641SAndroid Build Coastguard Worker if (signal->GetMember() != kNameOwnerChangedSignal ||
1071*635a8641SAndroid Build Coastguard Worker signal->GetInterface() != DBUS_INTERFACE_DBUS ||
1072*635a8641SAndroid Build Coastguard Worker signal->GetSender() != DBUS_SERVICE_DBUS) {
1073*635a8641SAndroid Build Coastguard Worker return;
1074*635a8641SAndroid Build Coastguard Worker }
1075*635a8641SAndroid Build Coastguard Worker
1076*635a8641SAndroid Build Coastguard Worker MessageReader reader(signal.get());
1077*635a8641SAndroid Build Coastguard Worker std::string service_name;
1078*635a8641SAndroid Build Coastguard Worker std::string old_owner;
1079*635a8641SAndroid Build Coastguard Worker std::string new_owner;
1080*635a8641SAndroid Build Coastguard Worker if (!reader.PopString(&service_name) ||
1081*635a8641SAndroid Build Coastguard Worker !reader.PopString(&old_owner) ||
1082*635a8641SAndroid Build Coastguard Worker !reader.PopString(&new_owner)) {
1083*635a8641SAndroid Build Coastguard Worker return;
1084*635a8641SAndroid Build Coastguard Worker }
1085*635a8641SAndroid Build Coastguard Worker
1086*635a8641SAndroid Build Coastguard Worker ServiceOwnerChangedListenerMap::const_iterator it =
1087*635a8641SAndroid Build Coastguard Worker service_owner_changed_listener_map_.find(service_name);
1088*635a8641SAndroid Build Coastguard Worker if (it == service_owner_changed_listener_map_.end())
1089*635a8641SAndroid Build Coastguard Worker return;
1090*635a8641SAndroid Build Coastguard Worker
1091*635a8641SAndroid Build Coastguard Worker const std::vector<GetServiceOwnerCallback>& callbacks = it->second;
1092*635a8641SAndroid Build Coastguard Worker for (size_t i = 0; i < callbacks.size(); ++i) {
1093*635a8641SAndroid Build Coastguard Worker GetOriginTaskRunner()->PostTask(FROM_HERE,
1094*635a8641SAndroid Build Coastguard Worker base::Bind(callbacks[i], new_owner));
1095*635a8641SAndroid Build Coastguard Worker }
1096*635a8641SAndroid Build Coastguard Worker }
1097*635a8641SAndroid Build Coastguard Worker
1098*635a8641SAndroid Build Coastguard Worker // static
OnAddWatchThunk(DBusWatch * raw_watch,void * data)1099*635a8641SAndroid Build Coastguard Worker dbus_bool_t Bus::OnAddWatchThunk(DBusWatch* raw_watch, void* data) {
1100*635a8641SAndroid Build Coastguard Worker Bus* self = static_cast<Bus*>(data);
1101*635a8641SAndroid Build Coastguard Worker return self->OnAddWatch(raw_watch);
1102*635a8641SAndroid Build Coastguard Worker }
1103*635a8641SAndroid Build Coastguard Worker
1104*635a8641SAndroid Build Coastguard Worker // static
OnRemoveWatchThunk(DBusWatch * raw_watch,void * data)1105*635a8641SAndroid Build Coastguard Worker void Bus::OnRemoveWatchThunk(DBusWatch* raw_watch, void* data) {
1106*635a8641SAndroid Build Coastguard Worker Bus* self = static_cast<Bus*>(data);
1107*635a8641SAndroid Build Coastguard Worker self->OnRemoveWatch(raw_watch);
1108*635a8641SAndroid Build Coastguard Worker }
1109*635a8641SAndroid Build Coastguard Worker
1110*635a8641SAndroid Build Coastguard Worker // static
OnToggleWatchThunk(DBusWatch * raw_watch,void * data)1111*635a8641SAndroid Build Coastguard Worker void Bus::OnToggleWatchThunk(DBusWatch* raw_watch, void* data) {
1112*635a8641SAndroid Build Coastguard Worker Bus* self = static_cast<Bus*>(data);
1113*635a8641SAndroid Build Coastguard Worker self->OnToggleWatch(raw_watch);
1114*635a8641SAndroid Build Coastguard Worker }
1115*635a8641SAndroid Build Coastguard Worker
1116*635a8641SAndroid Build Coastguard Worker // static
OnAddTimeoutThunk(DBusTimeout * raw_timeout,void * data)1117*635a8641SAndroid Build Coastguard Worker dbus_bool_t Bus::OnAddTimeoutThunk(DBusTimeout* raw_timeout, void* data) {
1118*635a8641SAndroid Build Coastguard Worker Bus* self = static_cast<Bus*>(data);
1119*635a8641SAndroid Build Coastguard Worker return self->OnAddTimeout(raw_timeout);
1120*635a8641SAndroid Build Coastguard Worker }
1121*635a8641SAndroid Build Coastguard Worker
1122*635a8641SAndroid Build Coastguard Worker // static
OnRemoveTimeoutThunk(DBusTimeout * raw_timeout,void * data)1123*635a8641SAndroid Build Coastguard Worker void Bus::OnRemoveTimeoutThunk(DBusTimeout* raw_timeout, void* data) {
1124*635a8641SAndroid Build Coastguard Worker Bus* self = static_cast<Bus*>(data);
1125*635a8641SAndroid Build Coastguard Worker self->OnRemoveTimeout(raw_timeout);
1126*635a8641SAndroid Build Coastguard Worker }
1127*635a8641SAndroid Build Coastguard Worker
1128*635a8641SAndroid Build Coastguard Worker // static
OnToggleTimeoutThunk(DBusTimeout * raw_timeout,void * data)1129*635a8641SAndroid Build Coastguard Worker void Bus::OnToggleTimeoutThunk(DBusTimeout* raw_timeout, void* data) {
1130*635a8641SAndroid Build Coastguard Worker Bus* self = static_cast<Bus*>(data);
1131*635a8641SAndroid Build Coastguard Worker self->OnToggleTimeout(raw_timeout);
1132*635a8641SAndroid Build Coastguard Worker }
1133*635a8641SAndroid Build Coastguard Worker
1134*635a8641SAndroid Build Coastguard Worker // static
OnDispatchStatusChangedThunk(DBusConnection * connection,DBusDispatchStatus status,void * data)1135*635a8641SAndroid Build Coastguard Worker void Bus::OnDispatchStatusChangedThunk(DBusConnection* connection,
1136*635a8641SAndroid Build Coastguard Worker DBusDispatchStatus status,
1137*635a8641SAndroid Build Coastguard Worker void* data) {
1138*635a8641SAndroid Build Coastguard Worker Bus* self = static_cast<Bus*>(data);
1139*635a8641SAndroid Build Coastguard Worker self->OnDispatchStatusChanged(connection, status);
1140*635a8641SAndroid Build Coastguard Worker }
1141*635a8641SAndroid Build Coastguard Worker
1142*635a8641SAndroid Build Coastguard Worker // static
OnConnectionDisconnectedFilter(DBusConnection * connection,DBusMessage * message,void * data)1143*635a8641SAndroid Build Coastguard Worker DBusHandlerResult Bus::OnConnectionDisconnectedFilter(
1144*635a8641SAndroid Build Coastguard Worker DBusConnection* connection,
1145*635a8641SAndroid Build Coastguard Worker DBusMessage* message,
1146*635a8641SAndroid Build Coastguard Worker void* data) {
1147*635a8641SAndroid Build Coastguard Worker if (dbus_message_is_signal(message,
1148*635a8641SAndroid Build Coastguard Worker DBUS_INTERFACE_LOCAL,
1149*635a8641SAndroid Build Coastguard Worker kDisconnectedSignal)) {
1150*635a8641SAndroid Build Coastguard Worker // Abort when the connection is lost.
1151*635a8641SAndroid Build Coastguard Worker LOG(FATAL) << "D-Bus connection was disconnected. Aborting.";
1152*635a8641SAndroid Build Coastguard Worker }
1153*635a8641SAndroid Build Coastguard Worker return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
1154*635a8641SAndroid Build Coastguard Worker }
1155*635a8641SAndroid Build Coastguard Worker
1156*635a8641SAndroid Build Coastguard Worker // static
OnServiceOwnerChangedFilter(DBusConnection * connection,DBusMessage * message,void * data)1157*635a8641SAndroid Build Coastguard Worker DBusHandlerResult Bus::OnServiceOwnerChangedFilter(
1158*635a8641SAndroid Build Coastguard Worker DBusConnection* connection,
1159*635a8641SAndroid Build Coastguard Worker DBusMessage* message,
1160*635a8641SAndroid Build Coastguard Worker void* data) {
1161*635a8641SAndroid Build Coastguard Worker if (dbus_message_is_signal(message,
1162*635a8641SAndroid Build Coastguard Worker DBUS_INTERFACE_DBUS,
1163*635a8641SAndroid Build Coastguard Worker kNameOwnerChangedSignal)) {
1164*635a8641SAndroid Build Coastguard Worker Bus* self = static_cast<Bus*>(data);
1165*635a8641SAndroid Build Coastguard Worker self->OnServiceOwnerChanged(message);
1166*635a8641SAndroid Build Coastguard Worker }
1167*635a8641SAndroid Build Coastguard Worker // Always return unhandled to let others, e.g. ObjectProxies, handle the same
1168*635a8641SAndroid Build Coastguard Worker // signal.
1169*635a8641SAndroid Build Coastguard Worker return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
1170*635a8641SAndroid Build Coastguard Worker }
1171*635a8641SAndroid Build Coastguard Worker
1172*635a8641SAndroid Build Coastguard Worker } // namespace dbus
1173