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