You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
755 lines
29 KiB
755 lines
29 KiB
// Copyright (c) 2012 The Chromium Authors. All rights reserved. |
|
// Use of this source code is governed by a BSD-style license that can be |
|
// found in the LICENSE file. |
|
|
|
#ifndef DBUS_BUS_H_ |
|
#define DBUS_BUS_H_ |
|
|
|
#include <dbus/dbus.h> |
|
#include <stdint.h> |
|
|
|
#include <map> |
|
#include <set> |
|
#include <string> |
|
#include <utility> |
|
#include <vector> |
|
|
|
#include "base/callback.h" |
|
#include "base/macros.h" |
|
#include "base/memory/ref_counted.h" |
|
#include "base/synchronization/waitable_event.h" |
|
#include "base/threading/platform_thread.h" |
|
#include "dbus/dbus_export.h" |
|
#include "dbus/object_path.h" |
|
|
|
namespace base { |
|
class SequencedTaskRunner; |
|
class SingleThreadTaskRunner; |
|
class TaskRunner; |
|
} |
|
|
|
namespace dbus { |
|
|
|
class ExportedObject; |
|
class ObjectManager; |
|
class ObjectProxy; |
|
|
|
// Bus is used to establish a connection with D-Bus, create object |
|
// proxies, and export objects. |
|
// |
|
// For asynchronous operations such as an asynchronous method call, the |
|
// bus object will use a task runner to monitor the underlying file |
|
// descriptor used for D-Bus communication. By default, the bus will use |
|
// the current thread's task runner. If |dbus_task_runner| option is |
|
// specified, the bus will use that task runner instead. |
|
// |
|
// THREADING |
|
// |
|
// In the D-Bus library, we use the two threads: |
|
// |
|
// - The origin thread: the thread that created the Bus object. |
|
// - The D-Bus thread: the thread servicing |dbus_task_runner|. |
|
// |
|
// The origin thread is usually Chrome's UI thread. The D-Bus thread is |
|
// usually a dedicated thread for the D-Bus library. |
|
// |
|
// BLOCKING CALLS |
|
// |
|
// Functions that issue blocking calls are marked "BLOCKING CALL" and |
|
// these functions should be called in the D-Bus thread (if |
|
// supplied). AssertOnDBusThread() is placed in these functions. |
|
// |
|
// Note that it's hard to tell if a libdbus function is actually blocking |
|
// or not (ex. dbus_bus_request_name() internally calls |
|
// dbus_connection_send_with_reply_and_block(), which is a blocking |
|
// call). To err on the safe side, we consider all libdbus functions that |
|
// deal with the connection to dbus-daemon to be blocking. |
|
// |
|
// SHUTDOWN |
|
// |
|
// The Bus object must be shut down manually by ShutdownAndBlock() and |
|
// friends. We require the manual shutdown to make the operation explicit |
|
// rather than doing it silently in the destructor. |
|
// |
|
// EXAMPLE USAGE: |
|
// |
|
// Synchronous method call: |
|
// |
|
// dbus::Bus::Options options; |
|
// // Set up the bus options here. |
|
// ... |
|
// dbus::Bus bus(options); |
|
// |
|
// dbus::ObjectProxy* object_proxy = |
|
// bus.GetObjectProxy(service_name, object_path); |
|
// |
|
// dbus::MethodCall method_call(interface_name, method_name); |
|
// std::unique_ptr<dbus::Response> response( |
|
// object_proxy.CallMethodAndBlock(&method_call, timeout_ms)); |
|
// if (response.get() != nullptr) { // Success. |
|
// ... |
|
// } |
|
// |
|
// Asynchronous method call: |
|
// |
|
// void OnResponse(dbus::Response* response) { |
|
// // response is NULL if the method call failed. |
|
// if (!response) |
|
// return; |
|
// } |
|
// |
|
// ... |
|
// object_proxy.CallMethod(&method_call, timeout_ms, |
|
// base::Bind(&OnResponse)); |
|
// |
|
// Exporting a method: |
|
// |
|
// void Echo(dbus::MethodCall* method_call, |
|
// dbus::ExportedObject::ResponseSender response_sender) { |
|
// // Do something with method_call. |
|
// Response* response = Response::FromMethodCall(method_call); |
|
// // Build response here. |
|
// // Can send an immediate response here to implement a synchronous service |
|
// // or store the response_sender and send a response later to implement an |
|
// // asynchronous service. |
|
// response_sender.Run(response); |
|
// } |
|
// |
|
// void OnExported(const std::string& interface_name, |
|
// const ObjectPath& object_path, |
|
// bool success) { |
|
// // success is true if the method was exported successfully. |
|
// } |
|
// |
|
// ... |
|
// dbus::ExportedObject* exported_object = |
|
// bus.GetExportedObject(service_name, object_path); |
|
// exported_object.ExportMethod(interface_name, method_name, |
|
// base::Bind(&Echo), |
|
// base::Bind(&OnExported)); |
|
// |
|
// WHY IS THIS A REF COUNTED OBJECT? |
|
// |
|
// Bus is a ref counted object, to ensure that |this| of the object is |
|
// alive when callbacks referencing |this| are called. However, after the |
|
// bus is shut down, |connection_| can be NULL. Hence, callbacks should |
|
// not rely on that |connection_| is alive. |
|
class CHROME_DBUS_EXPORT Bus : public base::RefCountedThreadSafe<Bus> { |
|
public: |
|
// Specifies the bus type. SESSION is used to communicate with per-user |
|
// services like GNOME applications. SYSTEM is used to communicate with |
|
// system-wide services like NetworkManager. CUSTOM_ADDRESS is used to |
|
// communicate with an user specified address. |
|
enum BusType { |
|
SESSION = DBUS_BUS_SESSION, |
|
SYSTEM = DBUS_BUS_SYSTEM, |
|
CUSTOM_ADDRESS, |
|
}; |
|
|
|
// Specifies the connection type. PRIVATE should usually be used unless |
|
// you are sure that SHARED is safe for you, which is unlikely the case |
|
// in Chrome. |
|
// |
|
// PRIVATE gives you a private connection, that won't be shared with |
|
// other Bus objects. |
|
// |
|
// SHARED gives you a connection shared among other Bus objects, which |
|
// is unsafe if the connection is shared with multiple threads. |
|
enum ConnectionType { |
|
PRIVATE, |
|
SHARED, |
|
}; |
|
|
|
// Specifies whether the GetServiceOwnerAndBlock call should report or |
|
// suppress errors. |
|
enum GetServiceOwnerOption { |
|
REPORT_ERRORS, |
|
SUPPRESS_ERRORS, |
|
}; |
|
|
|
// Specifies service ownership options. |
|
// |
|
// REQUIRE_PRIMARY indicates that you require primary ownership of the |
|
// service name. |
|
// |
|
// ALLOW_REPLACEMENT indicates that you'll allow another connection to |
|
// steal ownership of this service name from you. |
|
// |
|
// REQUIRE_PRIMARY_ALLOW_REPLACEMENT does the obvious. |
|
enum ServiceOwnershipOptions { |
|
REQUIRE_PRIMARY = (DBUS_NAME_FLAG_DO_NOT_QUEUE | |
|
DBUS_NAME_FLAG_REPLACE_EXISTING), |
|
REQUIRE_PRIMARY_ALLOW_REPLACEMENT = (REQUIRE_PRIMARY | |
|
DBUS_NAME_FLAG_ALLOW_REPLACEMENT), |
|
}; |
|
|
|
// Options used to create a Bus object. |
|
struct CHROME_DBUS_EXPORT Options { |
|
Options(); |
|
~Options(); |
|
|
|
BusType bus_type; // SESSION by default. |
|
ConnectionType connection_type; // PRIVATE by default. |
|
// If dbus_task_runner is set, the bus object will use that |
|
// task runner to process asynchronous operations. |
|
// |
|
// The thread servicing the task runner should meet the following |
|
// requirements: |
|
// 1) Already running. |
|
// 2) Has a MessageLoopForIO. |
|
scoped_refptr<base::SequencedTaskRunner> dbus_task_runner; |
|
|
|
// Specifies the server addresses to be connected. If you want to |
|
// communicate with non dbus-daemon such as ibus-daemon, set |bus_type| to |
|
// CUSTOM_ADDRESS, and |address| to the D-Bus server address you want to |
|
// connect to. The format of this address value is the dbus address style |
|
// which is described in |
|
// http://dbus.freedesktop.org/doc/dbus-specification.html#addresses |
|
// |
|
// EXAMPLE USAGE: |
|
// dbus::Bus::Options options; |
|
// options.bus_type = CUSTOM_ADDRESS; |
|
// options.address.assign("unix:path=/tmp/dbus-XXXXXXX"); |
|
// // Set up other options |
|
// dbus::Bus bus(options); |
|
// |
|
// // Do something. |
|
// |
|
std::string address; |
|
}; |
|
|
|
// Creates a Bus object. The actual connection will be established when |
|
// Connect() is called. |
|
explicit Bus(const Options& options); |
|
|
|
// Called when an ownership request is complete. |
|
// Parameters: |
|
// - the requested service name. |
|
// - whether ownership has been obtained or not. |
|
typedef base::Callback<void (const std::string&, bool)> OnOwnershipCallback; |
|
|
|
// Called when GetServiceOwner() completes. |
|
// |service_owner| is the return value from GetServiceOwnerAndBlock(). |
|
typedef base::Callback<void (const std::string& service_owner)> |
|
GetServiceOwnerCallback; |
|
|
|
// TODO(satorux): Remove the service name parameter as the caller of |
|
// RequestOwnership() knows the service name. |
|
|
|
// Gets the object proxy for the given service name and the object path. |
|
// The caller must not delete the returned object. |
|
// |
|
// Returns an existing object proxy if the bus object already owns the |
|
// object proxy for the given service name and the object path. |
|
// Never returns NULL. |
|
// |
|
// The bus will own all object proxies created by the bus, to ensure |
|
// that the object proxies are detached from remote objects at the |
|
// shutdown time of the bus. |
|
// |
|
// The object proxy is used to call methods of remote objects, and |
|
// receive signals from them. |
|
// |
|
// |service_name| looks like "org.freedesktop.NetworkManager", and |
|
// |object_path| looks like "/org/freedesktop/NetworkManager/Devices/0". |
|
// |
|
// Must be called in the origin thread. |
|
virtual ObjectProxy* GetObjectProxy(const std::string& service_name, |
|
const ObjectPath& object_path); |
|
|
|
// Same as above, but also takes a bitfield of ObjectProxy::Options. |
|
// See object_proxy.h for available options. |
|
virtual ObjectProxy* GetObjectProxyWithOptions( |
|
const std::string& service_name, |
|
const ObjectPath& object_path, |
|
int options); |
|
|
|
// Removes the previously created object proxy for the given service |
|
// name and the object path and releases its memory. |
|
// |
|
// If and object proxy for the given service name and object was |
|
// created with GetObjectProxy, this function removes it from the |
|
// bus object and detaches the ObjectProxy, invalidating any pointer |
|
// previously acquired for it with GetObjectProxy. A subsequent call |
|
// to GetObjectProxy will return a new object. |
|
// |
|
// All the object proxies are detached from remote objects at the |
|
// shutdown time of the bus, but they can be detached early to reduce |
|
// memory footprint and used match rules for the bus connection. |
|
// |
|
// |service_name| looks like "org.freedesktop.NetworkManager", and |
|
// |object_path| looks like "/org/freedesktop/NetworkManager/Devices/0". |
|
// |callback| is called when the object proxy is successfully removed and |
|
// detached. |
|
// |
|
// The function returns true when there is an object proxy matching the |
|
// |service_name| and |object_path| to remove, and calls |callback| when it |
|
// is removed. Otherwise, it returns false and the |callback| function is |
|
// never called. The |callback| argument must not be null. |
|
// |
|
// Must be called in the origin thread. |
|
virtual bool RemoveObjectProxy(const std::string& service_name, |
|
const ObjectPath& object_path, |
|
const base::Closure& callback); |
|
|
|
// Same as above, but also takes a bitfield of ObjectProxy::Options. |
|
// See object_proxy.h for available options. |
|
virtual bool RemoveObjectProxyWithOptions( |
|
const std::string& service_name, |
|
const ObjectPath& object_path, |
|
int options, |
|
const base::Closure& callback); |
|
|
|
// Gets the exported object for the given object path. |
|
// The caller must not delete the returned object. |
|
// |
|
// Returns an existing exported object if the bus object already owns |
|
// the exported object for the given object path. Never returns NULL. |
|
// |
|
// The bus will own all exported objects created by the bus, to ensure |
|
// that the exported objects are unregistered at the shutdown time of |
|
// the bus. |
|
// |
|
// The exported object is used to export methods of local objects, and |
|
// send signal from them. |
|
// |
|
// Must be called in the origin thread. |
|
virtual ExportedObject* GetExportedObject(const ObjectPath& object_path); |
|
|
|
// Unregisters the exported object for the given object path |object_path|. |
|
// |
|
// Getting an exported object for the same object path after this call |
|
// will return a new object, method calls on any remaining copies of the |
|
// previous object will not be called. |
|
// |
|
// Must be called in the origin thread. |
|
virtual void UnregisterExportedObject(const ObjectPath& object_path); |
|
|
|
|
|
// Gets an object manager for the given remote object path |object_path| |
|
// exported by the service |service_name|. |
|
// |
|
// Returns an existing object manager if the bus object already owns a |
|
// matching object manager, never returns NULL. |
|
// |
|
// The caller must not delete the returned object, the bus retains ownership |
|
// of all object managers. |
|
// |
|
// Must be called in the origin thread. |
|
virtual ObjectManager* GetObjectManager(const std::string& service_name, |
|
const ObjectPath& object_path); |
|
|
|
// Unregisters the object manager for the given remote object path |
|
// |object_path| exported by the srevice |service_name|. |
|
// |
|
// Getting an object manager for the same remote object after this call |
|
// will return a new object, method calls on any remaining copies of the |
|
// previous object are not permitted. |
|
// |
|
// This method will asynchronously clean up any match rules that have been |
|
// added for the object manager and invoke |callback| when the operation is |
|
// complete. If this method returns false, then |callback| is never called. |
|
// The |callback| argument must not be null. |
|
// |
|
// Must be called in the origin thread. |
|
virtual bool RemoveObjectManager(const std::string& service_name, |
|
const ObjectPath& object_path, |
|
const base::Closure& callback); |
|
|
|
// Shuts down the bus and blocks until it's done. More specifically, this |
|
// function does the following: |
|
// |
|
// - Unregisters the object paths |
|
// - Releases the service names |
|
// - Closes the connection to dbus-daemon. |
|
// |
|
// This function can be called multiple times and it is no-op for the 2nd time |
|
// calling. |
|
// |
|
// BLOCKING CALL. |
|
virtual void ShutdownAndBlock(); |
|
|
|
// Similar to ShutdownAndBlock(), but this function is used to |
|
// synchronously shut down the bus that uses the D-Bus thread. This |
|
// function is intended to be used at the very end of the browser |
|
// shutdown, where it makes more sense to shut down the bus |
|
// synchronously, than trying to make it asynchronous. |
|
// |
|
// BLOCKING CALL, but must be called in the origin thread. |
|
virtual void ShutdownOnDBusThreadAndBlock(); |
|
|
|
// Returns true if the shutdown has been completed. |
|
bool shutdown_completed() { return shutdown_completed_; } |
|
|
|
// |
|
// The public functions below are not intended to be used in client |
|
// code. These are used to implement ObjectProxy and ExportedObject. |
|
// |
|
|
|
// Connects the bus to the dbus-daemon. |
|
// Returns true on success, or the bus is already connected. |
|
// |
|
// BLOCKING CALL. |
|
virtual bool Connect(); |
|
|
|
// Disconnects the bus from the dbus-daemon. |
|
// Safe to call multiple times and no operation after the first call. |
|
// Do not call for shared connection it will be released by libdbus. |
|
// |
|
// BLOCKING CALL. |
|
virtual void ClosePrivateConnection(); |
|
|
|
// Requests the ownership of the service name given by |service_name|. |
|
// See also RequestOwnershipAndBlock(). |
|
// |
|
// |on_ownership_callback| is called when the service name is obtained |
|
// or failed to be obtained, in the origin thread. |
|
// |
|
// Must be called in the origin thread. |
|
virtual void RequestOwnership(const std::string& service_name, |
|
ServiceOwnershipOptions options, |
|
OnOwnershipCallback on_ownership_callback); |
|
|
|
// Requests the ownership of the given service name. |
|
// Returns true on success, or the the service name is already obtained. |
|
// |
|
// Note that it's important to expose methods before requesting a service |
|
// name with this method. See also ExportedObject::ExportMethodAndBlock() |
|
// for details. |
|
// |
|
// BLOCKING CALL. |
|
virtual bool RequestOwnershipAndBlock(const std::string& service_name, |
|
ServiceOwnershipOptions options); |
|
|
|
// Releases the ownership of the given service name. |
|
// Returns true on success. |
|
// |
|
// BLOCKING CALL. |
|
virtual bool ReleaseOwnership(const std::string& service_name); |
|
|
|
// Sets up async operations. |
|
// Returns true on success, or it's already set up. |
|
// This function needs to be called before starting async operations. |
|
// |
|
// BLOCKING CALL. |
|
virtual bool SetUpAsyncOperations(); |
|
|
|
// Sends a message to the bus and blocks until the response is |
|
// received. Used to implement synchronous method calls. |
|
// |
|
// BLOCKING CALL. |
|
virtual DBusMessage* SendWithReplyAndBlock(DBusMessage* request, |
|
int timeout_ms, |
|
DBusError* error); |
|
|
|
// Requests to send a message to the bus. The reply is handled with |
|
// |pending_call| at a later time. |
|
// |
|
// BLOCKING CALL. |
|
virtual void SendWithReply(DBusMessage* request, |
|
DBusPendingCall** pending_call, |
|
int timeout_ms); |
|
|
|
// Requests to send a message to the bus. The message serial number will |
|
// be stored in |serial|. |
|
// |
|
// BLOCKING CALL. |
|
virtual void Send(DBusMessage* request, uint32_t* serial); |
|
|
|
// Adds the message filter function. |filter_function| will be called |
|
// when incoming messages are received. |
|
// |
|
// When a new incoming message arrives, filter functions are called in |
|
// the order that they were added until the the incoming message is |
|
// handled by a filter function. |
|
// |
|
// The same filter function associated with the same user data cannot be |
|
// added more than once. |
|
// |
|
// BLOCKING CALL. |
|
virtual void AddFilterFunction(DBusHandleMessageFunction filter_function, |
|
void* user_data); |
|
|
|
// Removes the message filter previously added by AddFilterFunction(). |
|
// |
|
// BLOCKING CALL. |
|
virtual void RemoveFilterFunction(DBusHandleMessageFunction filter_function, |
|
void* user_data); |
|
|
|
// Adds the match rule. Messages that match the rule will be processed |
|
// by the filter functions added by AddFilterFunction(). |
|
// |
|
// You cannot specify which filter function to use for a match rule. |
|
// Instead, you should check if an incoming message is what you are |
|
// interested in, in the filter functions. |
|
// |
|
// The same match rule can be added more than once and should be removed |
|
// as many times as it was added. |
|
// |
|
// The match rule looks like: |
|
// "type='signal', interface='org.chromium.SomeInterface'". |
|
// |
|
// See "Message Bus Message Routing" section in the D-Bus specification |
|
// for details about match rules: |
|
// http://dbus.freedesktop.org/doc/dbus-specification.html#message-bus-routing |
|
// |
|
// BLOCKING CALL. |
|
virtual void AddMatch(const std::string& match_rule, DBusError* error); |
|
|
|
// Removes the match rule previously added by AddMatch(). |
|
// Returns false if the requested match rule is unknown or has already been |
|
// removed. Otherwise, returns true and sets |error| accordingly. |
|
// |
|
// BLOCKING CALL. |
|
virtual bool RemoveMatch(const std::string& match_rule, DBusError* error); |
|
|
|
// Tries to register the object path. Returns true on success. |
|
// Returns false if the object path is already registered. |
|
// |
|
// |message_function| in |vtable| will be called every time when a new |
|
// |message sent to the object path arrives. |
|
// |
|
// The same object path must not be added more than once. |
|
// |
|
// See also documentation of |dbus_connection_try_register_object_path| at |
|
// http://dbus.freedesktop.org/doc/api/html/group__DBusConnection.html |
|
// |
|
// BLOCKING CALL. |
|
virtual bool TryRegisterObjectPath(const ObjectPath& object_path, |
|
const DBusObjectPathVTable* vtable, |
|
void* user_data, |
|
DBusError* error); |
|
|
|
// Unregister the object path. |
|
// |
|
// BLOCKING CALL. |
|
virtual void UnregisterObjectPath(const ObjectPath& object_path); |
|
|
|
// Returns the task runner of the D-Bus thread. |
|
virtual base::TaskRunner* GetDBusTaskRunner(); |
|
|
|
// Returns the task runner of the thread that created the bus. |
|
virtual base::TaskRunner* GetOriginTaskRunner(); |
|
|
|
// Returns true if the bus has the D-Bus thread. |
|
virtual bool HasDBusThread(); |
|
|
|
// Check whether the current thread is on the origin thread (the thread |
|
// that created the bus). If not, DCHECK will fail. |
|
virtual void AssertOnOriginThread(); |
|
|
|
// Check whether the current thread is on the D-Bus thread. If not, |
|
// DCHECK will fail. If the D-Bus thread is not supplied, it calls |
|
// AssertOnOriginThread(). |
|
virtual void AssertOnDBusThread(); |
|
|
|
// Gets the owner for |service_name| via org.freedesktop.DBus.GetNameOwner. |
|
// Returns the owner name, if any, or an empty string on failure. |
|
// |options| specifies where to printing error messages or not. |
|
// |
|
// BLOCKING CALL. |
|
virtual std::string GetServiceOwnerAndBlock(const std::string& service_name, |
|
GetServiceOwnerOption options); |
|
|
|
// A non-blocking version of GetServiceOwnerAndBlock(). |
|
// Must be called in the origin thread. |
|
virtual void GetServiceOwner(const std::string& service_name, |
|
const GetServiceOwnerCallback& callback); |
|
|
|
// Whenever the owner for |service_name| changes, run |callback| with the |
|
// name of the new owner. If the owner goes away, then |callback| receives |
|
// an empty string. |
|
// |
|
// Any unique (service_name, callback) can be used. Duplicate are ignored. |
|
// |service_name| must not be empty and |callback| must not be null. |
|
// |
|
// Must be called in the origin thread. |
|
virtual void ListenForServiceOwnerChange( |
|
const std::string& service_name, |
|
const GetServiceOwnerCallback& callback); |
|
|
|
// Stop listening for |service_name| owner changes for |callback|. |
|
// Any unique (service_name, callback) can be used. Non-registered callbacks |
|
// for a given service name are ignored. |
|
// |service_name| must not be empty and |callback| must not be null. |
|
// |
|
// Must be called in the origin thread. |
|
virtual void UnlistenForServiceOwnerChange( |
|
const std::string& service_name, |
|
const GetServiceOwnerCallback& callback); |
|
|
|
// Return the unique name of the bus connnection if it is connected to |
|
// D-BUS. Otherwise, return an empty string. |
|
std::string GetConnectionName(); |
|
|
|
// Returns true if the bus is connected to D-Bus. |
|
bool is_connected() { return connection_ != nullptr; } |
|
|
|
protected: |
|
// This is protected, so we can define sub classes. |
|
virtual ~Bus(); |
|
|
|
private: |
|
friend class base::RefCountedThreadSafe<Bus>; |
|
|
|
// Helper function used for RemoveObjectProxy(). |
|
void RemoveObjectProxyInternal(scoped_refptr<dbus::ObjectProxy> object_proxy, |
|
const base::Closure& callback); |
|
|
|
// Helper functions used for RemoveObjectManager(). |
|
void RemoveObjectManagerInternal( |
|
scoped_refptr<dbus::ObjectManager> object_manager, |
|
const base::Closure& callback); |
|
void RemoveObjectManagerInternalHelper( |
|
scoped_refptr<dbus::ObjectManager> object_manager, |
|
const base::Closure& callback); |
|
|
|
// Helper function used for UnregisterExportedObject(). |
|
void UnregisterExportedObjectInternal( |
|
scoped_refptr<dbus::ExportedObject> exported_object); |
|
|
|
// Helper function used for ShutdownOnDBusThreadAndBlock(). |
|
void ShutdownOnDBusThreadAndBlockInternal(); |
|
|
|
// Helper function used for RequestOwnership(). |
|
void RequestOwnershipInternal(const std::string& service_name, |
|
ServiceOwnershipOptions options, |
|
OnOwnershipCallback on_ownership_callback); |
|
|
|
// Helper function used for GetServiceOwner(). |
|
void GetServiceOwnerInternal(const std::string& service_name, |
|
const GetServiceOwnerCallback& callback); |
|
|
|
// Helper function used for ListenForServiceOwnerChange(). |
|
void ListenForServiceOwnerChangeInternal( |
|
const std::string& service_name, |
|
const GetServiceOwnerCallback& callback); |
|
|
|
// Helper function used for UnListenForServiceOwnerChange(). |
|
void UnlistenForServiceOwnerChangeInternal( |
|
const std::string& service_name, |
|
const GetServiceOwnerCallback& callback); |
|
|
|
// Processes the all incoming data to the connection, if any. |
|
// |
|
// BLOCKING CALL. |
|
void ProcessAllIncomingDataIfAny(); |
|
|
|
// Called when a watch object is added. Used to start monitoring the |
|
// file descriptor used for D-Bus communication. |
|
dbus_bool_t OnAddWatch(DBusWatch* raw_watch); |
|
|
|
// Called when a watch object is removed. |
|
void OnRemoveWatch(DBusWatch* raw_watch); |
|
|
|
// Called when the "enabled" status of |raw_watch| is toggled. |
|
void OnToggleWatch(DBusWatch* raw_watch); |
|
|
|
// Called when a timeout object is added. Used to start monitoring |
|
// timeout for method calls. |
|
dbus_bool_t OnAddTimeout(DBusTimeout* raw_timeout); |
|
|
|
// Called when a timeout object is removed. |
|
void OnRemoveTimeout(DBusTimeout* raw_timeout); |
|
|
|
// Called when the "enabled" status of |raw_timeout| is toggled. |
|
void OnToggleTimeout(DBusTimeout* raw_timeout); |
|
|
|
// Called when the dispatch status (i.e. if any incoming data is |
|
// available) is changed. |
|
void OnDispatchStatusChanged(DBusConnection* connection, |
|
DBusDispatchStatus status); |
|
|
|
// Called when a service owner change occurs. |
|
void OnServiceOwnerChanged(DBusMessage* message); |
|
|
|
// Callback helper functions. Redirects to the corresponding member function. |
|
static dbus_bool_t OnAddWatchThunk(DBusWatch* raw_watch, void* data); |
|
static void OnRemoveWatchThunk(DBusWatch* raw_watch, void* data); |
|
static void OnToggleWatchThunk(DBusWatch* raw_watch, void* data); |
|
static dbus_bool_t OnAddTimeoutThunk(DBusTimeout* raw_timeout, void* data); |
|
static void OnRemoveTimeoutThunk(DBusTimeout* raw_timeout, void* data); |
|
static void OnToggleTimeoutThunk(DBusTimeout* raw_timeout, void* data); |
|
static void OnDispatchStatusChangedThunk(DBusConnection* connection, |
|
DBusDispatchStatus status, |
|
void* data); |
|
|
|
// Calls OnConnectionDisconnected if the Disconnected signal is received. |
|
static DBusHandlerResult OnConnectionDisconnectedFilter( |
|
DBusConnection* connection, |
|
DBusMessage* message, |
|
void* user_data); |
|
|
|
// Calls OnServiceOwnerChanged for a NameOwnerChanged signal. |
|
static DBusHandlerResult OnServiceOwnerChangedFilter( |
|
DBusConnection* connection, |
|
DBusMessage* message, |
|
void* user_data); |
|
|
|
const BusType bus_type_; |
|
const ConnectionType connection_type_; |
|
scoped_refptr<base::SequencedTaskRunner> dbus_task_runner_; |
|
base::WaitableEvent on_shutdown_; |
|
DBusConnection* connection_; |
|
|
|
scoped_refptr<base::SingleThreadTaskRunner> origin_task_runner_; |
|
base::PlatformThreadId origin_thread_id_; |
|
|
|
std::set<std::string> owned_service_names_; |
|
// The following sets are used to check if rules/object_paths/filters |
|
// are properly cleaned up before destruction of the bus object. |
|
// Since it's not an error to add the same match rule twice, the repeated |
|
// match rules are counted in a map. |
|
std::map<std::string, int> match_rules_added_; |
|
std::set<ObjectPath> registered_object_paths_; |
|
std::set<std::pair<DBusHandleMessageFunction, void*>> filter_functions_added_; |
|
|
|
// ObjectProxyTable is used to hold the object proxies created by the |
|
// bus object. Key is a pair; the first part is a concatenated string of |
|
// service name + object path, like |
|
// "org.chromium.TestService/org/chromium/TestObject". |
|
// The second part is the ObjectProxy::Options for the proxy. |
|
typedef std::map<std::pair<std::string, int>, |
|
scoped_refptr<dbus::ObjectProxy>> ObjectProxyTable; |
|
ObjectProxyTable object_proxy_table_; |
|
|
|
// ExportedObjectTable is used to hold the exported objects created by |
|
// the bus object. Key is a concatenated string of service name + |
|
// object path, like "org.chromium.TestService/org/chromium/TestObject". |
|
typedef std::map<const dbus::ObjectPath, |
|
scoped_refptr<dbus::ExportedObject>> ExportedObjectTable; |
|
ExportedObjectTable exported_object_table_; |
|
|
|
// ObjectManagerTable is used to hold the object managers created by the |
|
// bus object. Key is a concatenated string of service name + object path, |
|
// like "org.chromium.TestService/org/chromium/TestObject". |
|
typedef std::map<std::string, |
|
scoped_refptr<dbus::ObjectManager>> ObjectManagerTable; |
|
ObjectManagerTable object_manager_table_; |
|
|
|
// A map of NameOwnerChanged signals to listen for and the callbacks to run |
|
// on the origin thread when the owner changes. |
|
// Only accessed on the DBus thread. |
|
// Key: Service name |
|
// Value: Vector of callbacks. Unique and expected to be small. Not using |
|
// std::set here because base::Callbacks don't have a '<' operator. |
|
typedef std::map<std::string, std::vector<GetServiceOwnerCallback>> |
|
ServiceOwnerChangedListenerMap; |
|
ServiceOwnerChangedListenerMap service_owner_changed_listener_map_; |
|
|
|
bool async_operations_set_up_; |
|
bool shutdown_completed_; |
|
|
|
// Counters to make sure that OnAddWatch()/OnRemoveWatch() and |
|
// OnAddTimeout()/OnRemoveTimeou() are balanced. |
|
int num_pending_watches_; |
|
int num_pending_timeouts_; |
|
|
|
std::string address_; |
|
|
|
DISALLOW_COPY_AND_ASSIGN(Bus); |
|
}; |
|
|
|
} // namespace dbus |
|
|
|
#endif // DBUS_BUS_H_
|
|
|