blob: 12621d30936e4428186f0a6b9b3b6165f305bbfe [file] [log] [blame]
Torne (Richard Coles)58218062012-11-14 11:43:16 +00001// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef DBUS_BUS_H_
6#define DBUS_BUS_H_
7
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00008#include <dbus/dbus.h>
9
Torne (Richard Coles)58218062012-11-14 11:43:16 +000010#include <map>
11#include <set>
12#include <string>
13#include <utility>
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +010014#include <vector>
Torne (Richard Coles)58218062012-11-14 11:43:16 +000015
16#include "base/callback.h"
17#include "base/memory/ref_counted.h"
18#include "base/synchronization/waitable_event.h"
19#include "base/threading/platform_thread.h"
Torne (Richard Coles)58218062012-11-14 11:43:16 +000020#include "dbus/dbus_export.h"
21#include "dbus/object_path.h"
22
Torne (Richard Coles)58218062012-11-14 11:43:16 +000023namespace base {
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000024class SequencedTaskRunner;
25class SingleThreadTaskRunner;
Torne (Richard Coles)68043e12013-09-26 13:24:57 +010026class TaskRunner;
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000027}
28
29namespace tracked_objects {
30class Location;
Torne (Richard Coles)58218062012-11-14 11:43:16 +000031}
32
33namespace dbus {
34
35class ExportedObject;
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000036class ObjectManager;
Torne (Richard Coles)58218062012-11-14 11:43:16 +000037class ObjectProxy;
38
39// Bus is used to establish a connection with D-Bus, create object
40// proxies, and export objects.
41//
42// For asynchronous operations such as an asynchronous method call, the
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000043// bus object will use a task runner to monitor the underlying file
Torne (Richard Coles)58218062012-11-14 11:43:16 +000044// descriptor used for D-Bus communication. By default, the bus will use
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000045// the current thread's task runner. If |dbus_task_runner| option is
46// specified, the bus will use that task runner instead.
Torne (Richard Coles)58218062012-11-14 11:43:16 +000047//
48// THREADING
49//
50// In the D-Bus library, we use the two threads:
51//
52// - The origin thread: the thread that created the Bus object.
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000053// - The D-Bus thread: the thread servicing |dbus_task_runner|.
Torne (Richard Coles)58218062012-11-14 11:43:16 +000054//
55// The origin thread is usually Chrome's UI thread. The D-Bus thread is
56// usually a dedicated thread for the D-Bus library.
57//
58// BLOCKING CALLS
59//
60// Functions that issue blocking calls are marked "BLOCKING CALL" and
61// these functions should be called in the D-Bus thread (if
62// supplied). AssertOnDBusThread() is placed in these functions.
63//
64// Note that it's hard to tell if a libdbus function is actually blocking
65// or not (ex. dbus_bus_request_name() internally calls
66// dbus_connection_send_with_reply_and_block(), which is a blocking
67// call). To err on the safe side, we consider all libdbus functions that
68// deal with the connection to dbus-daemon to be blocking.
69//
70// SHUTDOWN
71//
72// The Bus object must be shut down manually by ShutdownAndBlock() and
73// friends. We require the manual shutdown to make the operation explicit
74// rather than doing it silently in the destructor.
75//
76// EXAMPLE USAGE:
77//
78// Synchronous method call:
79//
80// dbus::Bus::Options options;
81// // Set up the bus options here.
82// ...
83// dbus::Bus bus(options);
84//
85// dbus::ObjectProxy* object_proxy =
86// bus.GetObjectProxy(service_name, object_path);
87//
88// dbus::MethodCall method_call(interface_name, method_name);
89// scoped_ptr<dbus::Response> response(
90// object_proxy.CallMethodAndBlock(&method_call, timeout_ms));
91// if (response.get() != NULL) { // Success.
92// ...
93// }
94//
95// Asynchronous method call:
96//
97// void OnResponse(dbus::Response* response) {
98// // response is NULL if the method call failed.
99// if (!response)
100// return;
101// }
102//
103// ...
104// object_proxy.CallMethod(&method_call, timeout_ms,
105// base::Bind(&OnResponse));
106//
107// Exporting a method:
108//
109// void Echo(dbus::MethodCall* method_call,
110// dbus::ExportedObject::ResponseSender response_sender) {
111// // Do something with method_call.
112// Response* response = Response::FromMethodCall(method_call);
113// // Build response here.
114// // Can send an immediate response here to implement a synchronous service
115// // or store the response_sender and send a response later to implement an
116// // asynchronous service.
117// response_sender.Run(response);
118// }
119//
120// void OnExported(const std::string& interface_name,
121// const ObjectPath& object_path,
122// bool success) {
123// // success is true if the method was exported successfully.
124// }
125//
126// ...
127// dbus::ExportedObject* exported_object =
128// bus.GetExportedObject(service_name, object_path);
129// exported_object.ExportMethod(interface_name, method_name,
130// base::Bind(&Echo),
131// base::Bind(&OnExported));
132//
133// WHY IS THIS A REF COUNTED OBJECT?
134//
135// Bus is a ref counted object, to ensure that |this| of the object is
136// alive when callbacks referencing |this| are called. However, after the
137// bus is shut down, |connection_| can be NULL. Hence, callbacks should
138// not rely on that |connection_| is alive.
139class CHROME_DBUS_EXPORT Bus : public base::RefCountedThreadSafe<Bus> {
140 public:
141 // Specifies the bus type. SESSION is used to communicate with per-user
142 // services like GNOME applications. SYSTEM is used to communicate with
143 // system-wide services like NetworkManager. CUSTOM_ADDRESS is used to
144 // communicate with an user specified address.
145 enum BusType {
146 SESSION = DBUS_BUS_SESSION,
147 SYSTEM = DBUS_BUS_SYSTEM,
148 CUSTOM_ADDRESS,
149 };
150
151 // Specifies the connection type. PRIVATE should usually be used unless
152 // you are sure that SHARED is safe for you, which is unlikely the case
153 // in Chrome.
154 //
155 // PRIVATE gives you a private connection, that won't be shared with
156 // other Bus objects.
157 //
158 // SHARED gives you a connection shared among other Bus objects, which
159 // is unsafe if the connection is shared with multiple threads.
160 enum ConnectionType {
161 PRIVATE,
162 SHARED,
163 };
164
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100165 // Specifies whether the GetServiceOwnerAndBlock call should report or
166 // suppress errors.
167 enum GetServiceOwnerOption {
168 REPORT_ERRORS,
169 SUPPRESS_ERRORS,
170 };
171
Torne (Richard Coles)a36e5922013-08-05 13:57:33 +0100172 // Specifies service ownership options.
173 //
174 // REQUIRE_PRIMARY indicates that you require primary ownership of the
175 // service name.
176 //
177 // ALLOW_REPLACEMENT indicates that you'll allow another connection to
178 // steal ownership of this service name from you.
179 //
180 // REQUIRE_PRIMARY_ALLOW_REPLACEMENT does the obvious.
181 enum ServiceOwnershipOptions {
182 REQUIRE_PRIMARY = (DBUS_NAME_FLAG_DO_NOT_QUEUE |
183 DBUS_NAME_FLAG_REPLACE_EXISTING),
184 REQUIRE_PRIMARY_ALLOW_REPLACEMENT = (REQUIRE_PRIMARY |
185 DBUS_NAME_FLAG_ALLOW_REPLACEMENT),
186 };
187
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000188 // Options used to create a Bus object.
189 struct CHROME_DBUS_EXPORT Options {
190 Options();
191 ~Options();
192
193 BusType bus_type; // SESSION by default.
194 ConnectionType connection_type; // PRIVATE by default.
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000195 // If dbus_task_runner is set, the bus object will use that
196 // task runner to process asynchronous operations.
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000197 //
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000198 // The thread servicing the task runner should meet the following
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000199 // requirements:
200 // 1) Already running.
201 // 2) Has a MessageLoopForIO.
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000202 scoped_refptr<base::SequencedTaskRunner> dbus_task_runner;
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000203
204 // Specifies the server addresses to be connected. If you want to
205 // communicate with non dbus-daemon such as ibus-daemon, set |bus_type| to
206 // CUSTOM_ADDRESS, and |address| to the D-Bus server address you want to
207 // connect to. The format of this address value is the dbus address style
208 // which is described in
209 // http://dbus.freedesktop.org/doc/dbus-specification.html#addresses
210 //
211 // EXAMPLE USAGE:
212 // dbus::Bus::Options options;
213 // options.bus_type = CUSTOM_ADDRESS;
214 // options.address.assign("unix:path=/tmp/dbus-XXXXXXX");
215 // // Set up other options
216 // dbus::Bus bus(options);
217 //
218 // // Do something.
219 //
220 std::string address;
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000221
222 // If the connection with dbus-daemon is closed, |disconnected_callback|
223 // will be called on the origin thread. This is also called when the
224 // disonnection by ShutdownAndBlock. |disconnected_callback| can be null
225 // callback
226 base::Closure disconnected_callback;
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000227 };
228
229 // Creates a Bus object. The actual connection will be established when
230 // Connect() is called.
231 explicit Bus(const Options& options);
232
233 // Called when an ownership request is complete.
234 // Parameters:
235 // - the requested service name.
236 // - whether ownership has been obtained or not.
237 typedef base::Callback<void (const std::string&, bool)> OnOwnershipCallback;
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100238
239 // Called when GetServiceOwner() completes.
240 // |service_owner| is the return value from GetServiceOwnerAndBlock().
241 typedef base::Callback<void (const std::string& service_owner)>
242 GetServiceOwnerCallback;
243
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000244 // TODO(satorux): Remove the service name parameter as the caller of
245 // RequestOwnership() knows the service name.
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000246
247 // Gets the object proxy for the given service name and the object path.
248 // The caller must not delete the returned object.
249 //
250 // Returns an existing object proxy if the bus object already owns the
251 // object proxy for the given service name and the object path.
252 // Never returns NULL.
253 //
254 // The bus will own all object proxies created by the bus, to ensure
255 // that the object proxies are detached from remote objects at the
256 // shutdown time of the bus.
257 //
258 // The object proxy is used to call methods of remote objects, and
259 // receive signals from them.
260 //
261 // |service_name| looks like "org.freedesktop.NetworkManager", and
262 // |object_path| looks like "/org/freedesktop/NetworkManager/Devices/0".
263 //
264 // Must be called in the origin thread.
265 virtual ObjectProxy* GetObjectProxy(const std::string& service_name,
266 const ObjectPath& object_path);
267
268 // Same as above, but also takes a bitfield of ObjectProxy::Options.
269 // See object_proxy.h for available options.
270 virtual ObjectProxy* GetObjectProxyWithOptions(
271 const std::string& service_name,
272 const ObjectPath& object_path,
273 int options);
274
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000275 // Removes the previously created object proxy for the given service
276 // name and the object path and releases its memory.
277 //
278 // If and object proxy for the given service name and object was
279 // created with GetObjectProxy, this function removes it from the
280 // bus object and detaches the ObjectProxy, invalidating any pointer
281 // previously acquired for it with GetObjectProxy. A subsequent call
282 // to GetObjectProxy will return a new object.
283 //
284 // All the object proxies are detached from remote objects at the
285 // shutdown time of the bus, but they can be detached early to reduce
286 // memory footprint and used match rules for the bus connection.
287 //
288 // |service_name| looks like "org.freedesktop.NetworkManager", and
289 // |object_path| looks like "/org/freedesktop/NetworkManager/Devices/0".
290 // |callback| is called when the object proxy is successfully removed and
291 // detached.
292 //
293 // The function returns true when there is an object proxy matching the
294 // |service_name| and |object_path| to remove, and calls |callback| when it
295 // is removed. Otherwise, it returns false and the |callback| function is
296 // never called. The |callback| argument must not be null.
297 //
298 // Must be called in the origin thread.
299 virtual bool RemoveObjectProxy(const std::string& service_name,
300 const ObjectPath& object_path,
301 const base::Closure& callback);
302
303 // Same as above, but also takes a bitfield of ObjectProxy::Options.
304 // See object_proxy.h for available options.
305 virtual bool RemoveObjectProxyWithOptions(
306 const std::string& service_name,
307 const ObjectPath& object_path,
308 int options,
309 const base::Closure& callback);
310
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000311 // Gets the exported object for the given object path.
312 // The caller must not delete the returned object.
313 //
314 // Returns an existing exported object if the bus object already owns
315 // the exported object for the given object path. Never returns NULL.
316 //
317 // The bus will own all exported objects created by the bus, to ensure
318 // that the exported objects are unregistered at the shutdown time of
319 // the bus.
320 //
321 // The exported object is used to export methods of local objects, and
322 // send signal from them.
323 //
324 // Must be called in the origin thread.
325 virtual ExportedObject* GetExportedObject(const ObjectPath& object_path);
326
327 // Unregisters the exported object for the given object path |object_path|.
328 //
329 // Getting an exported object for the same object path after this call
330 // will return a new object, method calls on any remaining copies of the
331 // previous object will not be called.
332 //
333 // Must be called in the origin thread.
334 virtual void UnregisterExportedObject(const ObjectPath& object_path);
335
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000336
337 // Gets an object manager for the given remote object path |object_path|
338 // exported by the service |service_name|.
339 //
340 // Returns an existing object manager if the bus object already owns a
341 // matching object manager, never returns NULL.
342 //
343 // The caller must not delete the returned object, the bus retains ownership
344 // of all object managers.
345 //
346 // Must be called in the origin thread.
347 virtual ObjectManager* GetObjectManager(const std::string& service_name,
348 const ObjectPath& object_path);
349
350 // Unregisters the object manager for the given remote object path
351 // |object_path| exported by the srevice |service_name|.
352 //
353 // Getting an object manager for the same remote object after this call
354 // will return a new object, method calls on any remaining copies of the
355 // previous object are not permitted.
356 //
357 // Must be called in the origin thread.
358 virtual void RemoveObjectManager(const std::string& service_name,
359 const ObjectPath& object_path);
360
361 // Instructs all registered object managers to retrieve their set of managed
362 // objects from their respective remote objects. There is no need to call this
363 // manually, this is called automatically by the D-Bus thread manager once
364 // implementation classes are registered.
365 virtual void GetManagedObjects();
366
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000367 // Shuts down the bus and blocks until it's done. More specifically, this
368 // function does the following:
369 //
370 // - Unregisters the object paths
371 // - Releases the service names
372 // - Closes the connection to dbus-daemon.
373 //
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000374 // This function can be called multiple times and it is no-op for the 2nd time
375 // calling.
376 //
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000377 // BLOCKING CALL.
378 virtual void ShutdownAndBlock();
379
380 // Similar to ShutdownAndBlock(), but this function is used to
381 // synchronously shut down the bus that uses the D-Bus thread. This
382 // function is intended to be used at the very end of the browser
383 // shutdown, where it makes more sense to shut down the bus
384 // synchronously, than trying to make it asynchronous.
385 //
386 // BLOCKING CALL, but must be called in the origin thread.
387 virtual void ShutdownOnDBusThreadAndBlock();
388
389 // Returns true if the shutdown has been completed.
390 bool shutdown_completed() { return shutdown_completed_; }
391
392 //
393 // The public functions below are not intended to be used in client
394 // code. These are used to implement ObjectProxy and ExportedObject.
395 //
396
397 // Connects the bus to the dbus-daemon.
398 // Returns true on success, or the bus is already connected.
399 //
400 // BLOCKING CALL.
401 virtual bool Connect();
402
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000403 // Disconnects the bus from the dbus-daemon.
404 // Safe to call multiple times and no operation after the first call.
405 // Do not call for shared connection it will be released by libdbus.
406 //
407 // BLOCKING CALL.
408 virtual void ClosePrivateConnection();
409
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000410 // Requests the ownership of the service name given by |service_name|.
411 // See also RequestOwnershipAndBlock().
412 //
413 // |on_ownership_callback| is called when the service name is obtained
414 // or failed to be obtained, in the origin thread.
415 //
416 // Must be called in the origin thread.
417 virtual void RequestOwnership(const std::string& service_name,
Torne (Richard Coles)a36e5922013-08-05 13:57:33 +0100418 ServiceOwnershipOptions options,
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000419 OnOwnershipCallback on_ownership_callback);
420
421 // Requests the ownership of the given service name.
422 // Returns true on success, or the the service name is already obtained.
423 //
424 // BLOCKING CALL.
Torne (Richard Coles)a36e5922013-08-05 13:57:33 +0100425 virtual bool RequestOwnershipAndBlock(const std::string& service_name,
426 ServiceOwnershipOptions options);
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000427
428 // Releases the ownership of the given service name.
429 // Returns true on success.
430 //
431 // BLOCKING CALL.
432 virtual bool ReleaseOwnership(const std::string& service_name);
433
434 // Sets up async operations.
435 // Returns true on success, or it's already set up.
436 // This function needs to be called before starting async operations.
437 //
438 // BLOCKING CALL.
439 virtual bool SetUpAsyncOperations();
440
441 // Sends a message to the bus and blocks until the response is
442 // received. Used to implement synchronous method calls.
443 //
444 // BLOCKING CALL.
445 virtual DBusMessage* SendWithReplyAndBlock(DBusMessage* request,
446 int timeout_ms,
447 DBusError* error);
448
449 // Requests to send a message to the bus. The reply is handled with
450 // |pending_call| at a later time.
451 //
452 // BLOCKING CALL.
453 virtual void SendWithReply(DBusMessage* request,
454 DBusPendingCall** pending_call,
455 int timeout_ms);
456
457 // Requests to send a message to the bus. The message serial number will
458 // be stored in |serial|.
459 //
460 // BLOCKING CALL.
461 virtual void Send(DBusMessage* request, uint32* serial);
462
463 // Adds the message filter function. |filter_function| will be called
464 // when incoming messages are received. Returns true on success.
465 //
466 // When a new incoming message arrives, filter functions are called in
467 // the order that they were added until the the incoming message is
468 // handled by a filter function.
469 //
470 // The same filter function associated with the same user data cannot be
471 // added more than once. Returns false for this case.
472 //
473 // BLOCKING CALL.
474 virtual bool AddFilterFunction(DBusHandleMessageFunction filter_function,
475 void* user_data);
476
477 // Removes the message filter previously added by AddFilterFunction().
478 // Returns true on success.
479 //
480 // BLOCKING CALL.
481 virtual bool RemoveFilterFunction(DBusHandleMessageFunction filter_function,
482 void* user_data);
483
484 // Adds the match rule. Messages that match the rule will be processed
485 // by the filter functions added by AddFilterFunction().
486 //
487 // You cannot specify which filter function to use for a match rule.
488 // Instead, you should check if an incoming message is what you are
489 // interested in, in the filter functions.
490 //
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000491 // The same match rule can be added more than once and should be removed
492 // as many times as it was added.
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000493 //
494 // The match rule looks like:
495 // "type='signal', interface='org.chromium.SomeInterface'".
496 //
497 // See "Message Bus Message Routing" section in the D-Bus specification
498 // for details about match rules:
499 // http://dbus.freedesktop.org/doc/dbus-specification.html#message-bus-routing
500 //
501 // BLOCKING CALL.
502 virtual void AddMatch(const std::string& match_rule, DBusError* error);
503
504 // Removes the match rule previously added by AddMatch().
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000505 // Returns false if the requested match rule is unknown or has already been
506 // removed. Otherwise, returns true and sets |error| accordingly.
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000507 //
508 // BLOCKING CALL.
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000509 virtual bool RemoveMatch(const std::string& match_rule, DBusError* error);
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000510
511 // Tries to register the object path. Returns true on success.
512 // Returns false if the object path is already registered.
513 //
514 // |message_function| in |vtable| will be called every time when a new
515 // |message sent to the object path arrives.
516 //
517 // The same object path must not be added more than once.
518 //
519 // See also documentation of |dbus_connection_try_register_object_path| at
520 // http://dbus.freedesktop.org/doc/api/html/group__DBusConnection.html
521 //
522 // BLOCKING CALL.
523 virtual bool TryRegisterObjectPath(const ObjectPath& object_path,
524 const DBusObjectPathVTable* vtable,
525 void* user_data,
526 DBusError* error);
527
528 // Unregister the object path.
529 //
530 // BLOCKING CALL.
531 virtual void UnregisterObjectPath(const ObjectPath& object_path);
532
Torne (Richard Coles)68043e12013-09-26 13:24:57 +0100533 // Returns the task runner of the D-Bus thread.
534 virtual base::TaskRunner* GetDBusTaskRunner();
Torne (Richard Coles)b2df76e2013-05-13 16:52:09 +0100535
Torne (Richard Coles)68043e12013-09-26 13:24:57 +0100536 // Returns the task runner of the thread that created the bus.
537 virtual base::TaskRunner* GetOriginTaskRunner();
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000538
539 // Returns true if the bus has the D-Bus thread.
540 virtual bool HasDBusThread();
541
542 // Check whether the current thread is on the origin thread (the thread
543 // that created the bus). If not, DCHECK will fail.
544 virtual void AssertOnOriginThread();
545
546 // Check whether the current thread is on the D-Bus thread. If not,
547 // DCHECK will fail. If the D-Bus thread is not supplied, it calls
548 // AssertOnOriginThread().
549 virtual void AssertOnDBusThread();
550
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100551 // Gets the owner for |service_name| via org.freedesktop.DBus.GetNameOwner.
552 // Returns the owner name, if any, or an empty string on failure.
553 // |options| specifies where to printing error messages or not.
554 //
555 // BLOCKING CALL.
556 virtual std::string GetServiceOwnerAndBlock(const std::string& service_name,
557 GetServiceOwnerOption options);
558
559 // A non-blocking version of GetServiceOwnerAndBlock().
560 // Must be called in the origin thread.
561 virtual void GetServiceOwner(const std::string& service_name,
562 const GetServiceOwnerCallback& callback);
563
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +0100564 // Whenever the owner for |service_name| changes, run |callback| with the
565 // name of the new owner. If the owner goes away, then |callback| receives
566 // an empty string.
567 //
568 // Any unique (service_name, callback) can be used. Duplicate are ignored.
569 // |service_name| must not be empty and |callback| must not be null.
570 //
571 // Must be called in the origin thread.
572 virtual void ListenForServiceOwnerChange(
573 const std::string& service_name,
574 const GetServiceOwnerCallback& callback);
575
576 // Stop listening for |service_name| owner changes for |callback|.
577 // Any unique (service_name, callback) can be used. Non-registered callbacks
578 // for a given service name are ignored.
579 // |service_name| must not be empty and |callback| must not be null.
580 //
581 // Must be called in the origin thread.
582 virtual void UnlistenForServiceOwnerChange(
583 const std::string& service_name,
584 const GetServiceOwnerCallback& callback);
585
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000586 // Returns true if the bus is connected to D-Bus.
587 bool is_connected() { return connection_ != NULL; }
588
589 protected:
590 // This is protected, so we can define sub classes.
591 virtual ~Bus();
592
593 private:
594 friend class base::RefCountedThreadSafe<Bus>;
595
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000596 // Helper function used for RemoveObjectProxy().
597 void RemoveObjectProxyInternal(scoped_refptr<dbus::ObjectProxy> object_proxy,
598 const base::Closure& callback);
599
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000600 // Helper function used for UnregisterExportedObject().
601 void UnregisterExportedObjectInternal(
602 scoped_refptr<dbus::ExportedObject> exported_object);
603
604 // Helper function used for ShutdownOnDBusThreadAndBlock().
605 void ShutdownOnDBusThreadAndBlockInternal();
606
607 // Helper function used for RequestOwnership().
608 void RequestOwnershipInternal(const std::string& service_name,
Torne (Richard Coles)a36e5922013-08-05 13:57:33 +0100609 ServiceOwnershipOptions options,
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000610 OnOwnershipCallback on_ownership_callback);
611
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100612 // Helper function used for GetServiceOwner().
613 void GetServiceOwnerInternal(const std::string& service_name,
614 const GetServiceOwnerCallback& callback);
615
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +0100616 // Helper function used for ListenForServiceOwnerChange().
617 void ListenForServiceOwnerChangeInternal(
618 const std::string& service_name,
619 const GetServiceOwnerCallback& callback);
620
621 // Helper function used for UnListenForServiceOwnerChange().
622 void UnlistenForServiceOwnerChangeInternal(
623 const std::string& service_name,
624 const GetServiceOwnerCallback& callback);
625
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000626 // Processes the all incoming data to the connection, if any.
627 //
628 // BLOCKING CALL.
629 void ProcessAllIncomingDataIfAny();
630
631 // Called when a watch object is added. Used to start monitoring the
632 // file descriptor used for D-Bus communication.
633 dbus_bool_t OnAddWatch(DBusWatch* raw_watch);
634
635 // Called when a watch object is removed.
636 void OnRemoveWatch(DBusWatch* raw_watch);
637
638 // Called when the "enabled" status of |raw_watch| is toggled.
639 void OnToggleWatch(DBusWatch* raw_watch);
640
641 // Called when a timeout object is added. Used to start monitoring
642 // timeout for method calls.
643 dbus_bool_t OnAddTimeout(DBusTimeout* raw_timeout);
644
645 // Called when a timeout object is removed.
646 void OnRemoveTimeout(DBusTimeout* raw_timeout);
647
648 // Called when the "enabled" status of |raw_timeout| is toggled.
649 void OnToggleTimeout(DBusTimeout* raw_timeout);
650
651 // Called when the dispatch status (i.e. if any incoming data is
652 // available) is changed.
653 void OnDispatchStatusChanged(DBusConnection* connection,
654 DBusDispatchStatus status);
655
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000656 // Called when the connection is diconnected.
657 void OnConnectionDisconnected(DBusConnection* connection);
658
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +0100659 // Called when a service owner change occurs.
660 void OnServiceOwnerChanged(DBusMessage* message);
661
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000662 // Callback helper functions. Redirects to the corresponding member function.
663 static dbus_bool_t OnAddWatchThunk(DBusWatch* raw_watch, void* data);
664 static void OnRemoveWatchThunk(DBusWatch* raw_watch, void* data);
665 static void OnToggleWatchThunk(DBusWatch* raw_watch, void* data);
666 static dbus_bool_t OnAddTimeoutThunk(DBusTimeout* raw_timeout, void* data);
667 static void OnRemoveTimeoutThunk(DBusTimeout* raw_timeout, void* data);
668 static void OnToggleTimeoutThunk(DBusTimeout* raw_timeout, void* data);
669 static void OnDispatchStatusChangedThunk(DBusConnection* connection,
670 DBusDispatchStatus status,
671 void* data);
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000672
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +0100673 // Calls OnConnectionDisconnected if the Disconnected signal is received.
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000674 static DBusHandlerResult OnConnectionDisconnectedFilter(
675 DBusConnection* connection,
676 DBusMessage* message,
677 void* user_data);
678
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +0100679 // Calls OnServiceOwnerChanged for a NameOwnerChanged signal.
680 static DBusHandlerResult OnServiceOwnerChangedFilter(
681 DBusConnection* connection,
682 DBusMessage* message,
683 void* user_data);
684
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000685 const BusType bus_type_;
686 const ConnectionType connection_type_;
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000687 scoped_refptr<base::SequencedTaskRunner> dbus_task_runner_;
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000688 base::WaitableEvent on_shutdown_;
689 DBusConnection* connection_;
690
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000691 scoped_refptr<base::SingleThreadTaskRunner> origin_task_runner_;
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000692 base::PlatformThreadId origin_thread_id_;
693
694 std::set<std::string> owned_service_names_;
695 // The following sets are used to check if rules/object_paths/filters
696 // are properly cleaned up before destruction of the bus object.
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000697 // Since it's not an error to add the same match rule twice, the repeated
698 // match rules are counted in a map.
699 std::map<std::string, int> match_rules_added_;
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000700 std::set<ObjectPath> registered_object_paths_;
701 std::set<std::pair<DBusHandleMessageFunction, void*> >
702 filter_functions_added_;
703
704 // ObjectProxyTable is used to hold the object proxies created by the
705 // bus object. Key is a pair; the first part is a concatenated string of
706 // service name + object path, like
707 // "org.chromium.TestService/org/chromium/TestObject".
708 // The second part is the ObjectProxy::Options for the proxy.
709 typedef std::map<std::pair<std::string, int>,
710 scoped_refptr<dbus::ObjectProxy> > ObjectProxyTable;
711 ObjectProxyTable object_proxy_table_;
712
713 // ExportedObjectTable is used to hold the exported objects created by
714 // the bus object. Key is a concatenated string of service name +
715 // object path, like "org.chromium.TestService/org/chromium/TestObject".
716 typedef std::map<const dbus::ObjectPath,
717 scoped_refptr<dbus::ExportedObject> > ExportedObjectTable;
718 ExportedObjectTable exported_object_table_;
719
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000720 // ObjectManagerTable is used to hold the object managers created by the
721 // bus object. Key is a concatenated string of service name + object path,
722 // like "org.chromium.TestService/org/chromium/TestObject".
723 typedef std::map<std::string,
724 scoped_refptr<dbus::ObjectManager> > ObjectManagerTable;
725 ObjectManagerTable object_manager_table_;
726
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +0100727 // A map of NameOwnerChanged signals to listen for and the callbacks to run
728 // on the origin thread when the owner changes.
729 // Only accessed on the DBus thread.
730 // Key: Service name
731 // Value: Vector of callbacks. Unique and expected to be small. Not using
732 // std::set here because base::Callbacks don't have a '<' operator.
733 typedef std::map<std::string, std::vector<GetServiceOwnerCallback> >
734 ServiceOwnerChangedListenerMap;
735 ServiceOwnerChangedListenerMap service_owner_changed_listener_map_;
736
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000737 bool async_operations_set_up_;
738 bool shutdown_completed_;
739
740 // Counters to make sure that OnAddWatch()/OnRemoveWatch() and
741 // OnAddTimeout()/OnRemoveTimeou() are balanced.
742 int num_pending_watches_;
743 int num_pending_timeouts_;
744
745 std::string address_;
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000746 base::Closure on_disconnected_closure_;
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000747
748 DISALLOW_COPY_AND_ASSIGN(Bus);
749};
750
751} // namespace dbus
752
753#endif // DBUS_BUS_H_