1 /* 2 * libjingle 3 * Copyright 2004--2011, Google Inc. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright notice, 9 * this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright notice, 11 * this list of conditions and the following disclaimer in the documentation 12 * and/or other materials provided with the distribution. 13 * 3. The name of the author may not be used to endorse or promote products 14 * derived from this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO 19 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 20 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 22 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 23 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 */ 27 28 #ifndef TALK_BASE_DBUS_H_ 29 #define TALK_BASE_DBUS_H_ 30 31 #ifdef HAVE_DBUS_GLIB 32 33 #include <dbus/dbus.h> 34 35 #include <string> 36 #include <vector> 37 38 #include "talk/base/libdbusglibsymboltable.h" 39 #include "talk/base/messagehandler.h" 40 #include "talk/base/thread.h" 41 42 namespace talk_base { 43 44 #define DBUS_TYPE "type" 45 #define DBUS_SIGNAL "signal" 46 #define DBUS_PATH "path" 47 #define DBUS_INTERFACE "interface" 48 #define DBUS_MEMBER "member" 49 50 #ifdef CHROMEOS 51 #define CROS_PM_PATH "/" 52 #define CROS_PM_INTERFACE "org.chromium.PowerManager" 53 #define CROS_SIG_POWERCHANGED "PowerStateChanged" 54 #define CROS_VALUE_SLEEP "mem" 55 #define CROS_VALUE_RESUME "on" 56 #else 57 #define UP_PATH "/org/freedesktop/UPower" 58 #define UP_INTERFACE "org.freedesktop.UPower" 59 #define UP_SIG_SLEEPING "Sleeping" 60 #define UP_SIG_RESUMING "Resuming" 61 #endif // CHROMEOS 62 63 // Wraps a DBus messages. 64 class DBusSigMessageData : public TypedMessageData<DBusMessage *> { 65 public: 66 explicit DBusSigMessageData(DBusMessage *message); 67 ~DBusSigMessageData(); 68 }; 69 70 // DBusSigFilter is an abstract class that defines the interface of DBus 71 // signal handling. 72 // The subclasses implement ProcessSignal() for various purposes. 73 // When a DBus signal comes, a DSM_SIGNAL message is posted to the caller thread 74 // which will then invokes ProcessSignal(). 75 class DBusSigFilter : protected MessageHandler { 76 public: 77 enum DBusSigMessage { DSM_SIGNAL }; 78 79 // This filter string should ususally come from BuildFilterString() 80 explicit DBusSigFilter(const std::string &filter) 81 : caller_thread_(Thread::Current()), filter_(filter) { 82 } 83 84 // Builds a DBus monitor filter string from given DBus path, interface, and 85 // member. 86 // See http://dbus.freedesktop.org/doc/api/html/group__DBusConnection.html 87 static std::string BuildFilterString(const std::string &path, 88 const std::string &interface, 89 const std::string &member); 90 91 // Handles callback on DBus messages by DBus system. 92 static DBusHandlerResult DBusCallback(DBusConnection *dbus_conn, 93 DBusMessage *message, 94 void *instance); 95 96 // Handles callback on DBus messages to each DBusSigFilter instance. 97 DBusHandlerResult Callback(DBusMessage *message); 98 99 // From MessageHandler. 100 virtual void OnMessage(Message *message); 101 102 // Returns the DBus monitor filter string. 103 const std::string &filter() const { return filter_; } 104 105 private: 106 // On caller thread. 107 virtual void ProcessSignal(DBusMessage *message) = 0; 108 109 Thread *caller_thread_; 110 const std::string filter_; 111 }; 112 113 // DBusMonitor is a class for DBus signal monitoring. 114 // 115 // The caller-thread calls AddFilter() first to add the signals that it wants to 116 // monitor and then calls StartMonitoring() to start the monitoring. 117 // This will create a worker-thread which listens on DBus connection and sends 118 // DBus signals back through the callback. 119 // The worker-thread will be running forever until either StopMonitoring() is 120 // called from the caller-thread or the worker-thread hit some error. 121 // 122 // Programming model: 123 // 1. Caller-thread: Creates an object of DBusMonitor. 124 // 2. Caller-thread: Calls DBusMonitor::AddFilter() one or several times. 125 // 3. Caller-thread: StartMonitoring(). 126 // ... 127 // 4. Worker-thread: DBus signal recieved. Post a message to caller-thread. 128 // 5. Caller-thread: DBusFilterBase::ProcessSignal() is invoked. 129 // ... 130 // 6. Caller-thread: StopMonitoring(). 131 // 132 // Assumption: 133 // AddFilter(), StartMonitoring(), and StopMonitoring() methods are called by 134 // a single thread. Hence, there is no need to make them thread safe. 135 class DBusMonitor { 136 public: 137 // Status of DBus monitoring. 138 enum DBusMonitorStatus { 139 DMS_NOT_INITIALIZED, // Not initialized. 140 DMS_INITIALIZING, // Initializing the monitoring thread. 141 DMS_RUNNING, // Monitoring. 142 DMS_STOPPED, // Not monitoring. Stopped normally. 143 DMS_FAILED, // Not monitoring. Failed. 144 }; 145 146 // Returns the DBus-Glib symbol table. 147 // We should only use this function to access DBus-Glib symbols. 148 static LibDBusGlibSymbolTable *GetDBusGlibSymbolTable(); 149 150 // Creates an instance of DBusMonitor. 151 static DBusMonitor *Create(DBusBusType type); 152 ~DBusMonitor(); 153 154 // Adds a filter to DBusMonitor. 155 bool AddFilter(DBusSigFilter *filter); 156 157 // Starts DBus message monitoring. 158 bool StartMonitoring(); 159 160 // Stops DBus message monitoring. 161 bool StopMonitoring(); 162 163 // Gets the status of DBus monitoring. 164 DBusMonitorStatus GetStatus(); 165 166 private: 167 // Forward declaration. Defined in the .cc file. 168 class DBusMonitoringThread; 169 170 explicit DBusMonitor(DBusBusType type); 171 172 // Updates status_ when monitoring status has changed. 173 void OnMonitoringStatusChanged(DBusMonitorStatus status); 174 175 DBusBusType type_; 176 DBusMonitorStatus status_; 177 DBusMonitoringThread *monitoring_thread_; 178 std::vector<DBusSigFilter *> filter_list_; 179 }; 180 181 } // namespace talk_base 182 183 #endif // HAVE_DBUS_GLIB 184 185 #endif // TALK_BASE_DBUS_H_ 186