1/* 2 * Copyright 2004 The WebRTC Project Authors. All rights reserved. 3 * 4 * Use of this source code is governed by a BSD-style license 5 * that can be found in the LICENSE file in the root of the source 6 * tree. An additional intellectual property rights grant can be found 7 * in the file PATENTS. All contributing project authors may 8 * be found in the AUTHORS file in the root of the source tree. 9 */ 10 11#ifndef WEBRTC_BASE_DBUS_H_ 12#define WEBRTC_BASE_DBUS_H_ 13 14#ifdef HAVE_DBUS_GLIB 15 16#include <dbus/dbus.h> 17 18#include <string> 19#include <vector> 20 21#include "webrtc/base/libdbusglibsymboltable.h" 22#include "webrtc/base/messagehandler.h" 23#include "webrtc/base/thread.h" 24 25namespace rtc { 26 27#define DBUS_TYPE "type" 28#define DBUS_SIGNAL "signal" 29#define DBUS_PATH "path" 30#define DBUS_INTERFACE "interface" 31#define DBUS_MEMBER "member" 32 33#ifdef CHROMEOS 34#define CROS_PM_PATH "/" 35#define CROS_PM_INTERFACE "org.chromium.PowerManager" 36#define CROS_SIG_POWERCHANGED "PowerStateChanged" 37#define CROS_VALUE_SLEEP "mem" 38#define CROS_VALUE_RESUME "on" 39#else 40#define UP_PATH "/org/freedesktop/UPower" 41#define UP_INTERFACE "org.freedesktop.UPower" 42#define UP_SIG_SLEEPING "Sleeping" 43#define UP_SIG_RESUMING "Resuming" 44#endif // CHROMEOS 45 46// Wraps a DBus messages. 47class DBusSigMessageData : public TypedMessageData<DBusMessage *> { 48 public: 49 explicit DBusSigMessageData(DBusMessage *message); 50 ~DBusSigMessageData(); 51}; 52 53// DBusSigFilter is an abstract class that defines the interface of DBus 54// signal handling. 55// The subclasses implement ProcessSignal() for various purposes. 56// When a DBus signal comes, a DSM_SIGNAL message is posted to the caller thread 57// which will then invokes ProcessSignal(). 58class DBusSigFilter : protected MessageHandler { 59 public: 60 enum DBusSigMessage { DSM_SIGNAL }; 61 62 // This filter string should ususally come from BuildFilterString() 63 explicit DBusSigFilter(const std::string &filter) 64 : caller_thread_(Thread::Current()), filter_(filter) { 65 } 66 67 // Builds a DBus monitor filter string from given DBus path, interface, and 68 // member. 69 // See http://dbus.freedesktop.org/doc/api/html/group__DBusConnection.html 70 static std::string BuildFilterString(const std::string &path, 71 const std::string &interface, 72 const std::string &member); 73 74 // Handles callback on DBus messages by DBus system. 75 static DBusHandlerResult DBusCallback(DBusConnection *dbus_conn, 76 DBusMessage *message, 77 void *instance); 78 79 // Handles callback on DBus messages to each DBusSigFilter instance. 80 DBusHandlerResult Callback(DBusMessage *message); 81 82 // From MessageHandler. 83 virtual void OnMessage(Message *message); 84 85 // Returns the DBus monitor filter string. 86 const std::string &filter() const { return filter_; } 87 88 private: 89 // On caller thread. 90 virtual void ProcessSignal(DBusMessage *message) = 0; 91 92 Thread *caller_thread_; 93 const std::string filter_; 94}; 95 96// DBusMonitor is a class for DBus signal monitoring. 97// 98// The caller-thread calls AddFilter() first to add the signals that it wants to 99// monitor and then calls StartMonitoring() to start the monitoring. 100// This will create a worker-thread which listens on DBus connection and sends 101// DBus signals back through the callback. 102// The worker-thread will be running forever until either StopMonitoring() is 103// called from the caller-thread or the worker-thread hit some error. 104// 105// Programming model: 106// 1. Caller-thread: Creates an object of DBusMonitor. 107// 2. Caller-thread: Calls DBusMonitor::AddFilter() one or several times. 108// 3. Caller-thread: StartMonitoring(). 109// ... 110// 4. Worker-thread: DBus signal recieved. Post a message to caller-thread. 111// 5. Caller-thread: DBusFilterBase::ProcessSignal() is invoked. 112// ... 113// 6. Caller-thread: StopMonitoring(). 114// 115// Assumption: 116// AddFilter(), StartMonitoring(), and StopMonitoring() methods are called by 117// a single thread. Hence, there is no need to make them thread safe. 118class DBusMonitor { 119 public: 120 // Status of DBus monitoring. 121 enum DBusMonitorStatus { 122 DMS_NOT_INITIALIZED, // Not initialized. 123 DMS_INITIALIZING, // Initializing the monitoring thread. 124 DMS_RUNNING, // Monitoring. 125 DMS_STOPPED, // Not monitoring. Stopped normally. 126 DMS_FAILED, // Not monitoring. Failed. 127 }; 128 129 // Returns the DBus-Glib symbol table. 130 // We should only use this function to access DBus-Glib symbols. 131 static LibDBusGlibSymbolTable *GetDBusGlibSymbolTable(); 132 133 // Creates an instance of DBusMonitor. 134 static DBusMonitor *Create(DBusBusType type); 135 ~DBusMonitor(); 136 137 // Adds a filter to DBusMonitor. 138 bool AddFilter(DBusSigFilter *filter); 139 140 // Starts DBus message monitoring. 141 bool StartMonitoring(); 142 143 // Stops DBus message monitoring. 144 bool StopMonitoring(); 145 146 // Gets the status of DBus monitoring. 147 DBusMonitorStatus GetStatus(); 148 149 private: 150 // Forward declaration. Defined in the .cc file. 151 class DBusMonitoringThread; 152 153 explicit DBusMonitor(DBusBusType type); 154 155 // Updates status_ when monitoring status has changed. 156 void OnMonitoringStatusChanged(DBusMonitorStatus status); 157 158 DBusBusType type_; 159 DBusMonitorStatus status_; 160 DBusMonitoringThread *monitoring_thread_; 161 std::vector<DBusSigFilter *> filter_list_; 162}; 163 164} // namespace rtc 165 166#endif // HAVE_DBUS_GLIB 167 168#endif // WEBRTC_BASE_DBUS_H_ 169