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 25 namespace 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. 47 class 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(). 58 class DBusSigFilter : protected MessageHandler { 59 public: 60 enum DBusSigMessage { DSM_SIGNAL }; 61 62 // This filter string should ususally come from BuildFilterString() DBusSigFilter(const std::string & filter)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. filter()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. 118 class 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