xref: /aosp_15_r20/external/libchrome/dbus/bus.cc (revision 635a864187cb8b6c713ff48b7e790a6b21769273)
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