Home | History | Annotate | Download | only in base
      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()
     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.
    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