147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org/*
247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org *  Copyright 2004 The WebRTC Project Authors. All rights reserved.
347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org *
447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org *  Use of this source code is governed by a BSD-style license
547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org *  that can be found in the LICENSE file in the root of the source
647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org *  tree. An additional intellectual property rights grant can be found
747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org *  in the file PATENTS.  All contributing project authors may
847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org *  be found in the AUTHORS file in the root of the source tree.
947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org */
1047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
1147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#ifndef WEBRTC_BASE_DBUS_H_
1247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#define WEBRTC_BASE_DBUS_H_
1347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
1447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#ifdef HAVE_DBUS_GLIB
1547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
1647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include <dbus/dbus.h>
1747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
1847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include <string>
1947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include <vector>
2047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
2147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include "webrtc/base/libdbusglibsymboltable.h"
2247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include "webrtc/base/messagehandler.h"
2347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#include "webrtc/base/thread.h"
2447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
2547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgnamespace rtc {
2647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
2747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#define DBUS_TYPE                   "type"
2847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#define DBUS_SIGNAL                 "signal"
2947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#define DBUS_PATH                   "path"
3047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#define DBUS_INTERFACE              "interface"
3147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#define DBUS_MEMBER                 "member"
3247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
3347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#ifdef CHROMEOS
3447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#define CROS_PM_PATH                "/"
3547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#define CROS_PM_INTERFACE           "org.chromium.PowerManager"
3647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#define CROS_SIG_POWERCHANGED       "PowerStateChanged"
3747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#define CROS_VALUE_SLEEP            "mem"
3847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#define CROS_VALUE_RESUME           "on"
3947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#else
4047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#define UP_PATH                     "/org/freedesktop/UPower"
4147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#define UP_INTERFACE                "org.freedesktop.UPower"
4247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#define UP_SIG_SLEEPING             "Sleeping"
4347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#define UP_SIG_RESUMING             "Resuming"
4447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#endif  // CHROMEOS
4547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
4647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// Wraps a DBus messages.
4747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgclass DBusSigMessageData : public TypedMessageData<DBusMessage *> {
4847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org public:
4947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  explicit DBusSigMessageData(DBusMessage *message);
5047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  ~DBusSigMessageData();
5147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org};
5247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
5347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// DBusSigFilter is an abstract class that defines the interface of DBus
5447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// signal handling.
5547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// The subclasses implement ProcessSignal() for various purposes.
5647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// When a DBus signal comes, a DSM_SIGNAL message is posted to the caller thread
5747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// which will then invokes ProcessSignal().
5847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgclass DBusSigFilter : protected MessageHandler {
5947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org public:
6047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  enum DBusSigMessage { DSM_SIGNAL };
6147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
6247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // This filter string should ususally come from BuildFilterString()
6347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  explicit DBusSigFilter(const std::string &filter)
6447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org      : caller_thread_(Thread::Current()), filter_(filter) {
6547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  }
6647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
6747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Builds a DBus monitor filter string from given DBus path, interface, and
6847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // member.
6947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // See http://dbus.freedesktop.org/doc/api/html/group__DBusConnection.html
7047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  static std::string BuildFilterString(const std::string &path,
7147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                                       const std::string &interface,
7247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                                       const std::string &member);
7347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
7447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Handles callback on DBus messages by DBus system.
7547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  static DBusHandlerResult DBusCallback(DBusConnection *dbus_conn,
7647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                                        DBusMessage *message,
7747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org                                        void *instance);
7847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
7947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Handles callback on DBus messages to each DBusSigFilter instance.
8047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  DBusHandlerResult Callback(DBusMessage *message);
8147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
8247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // From MessageHandler.
8347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  virtual void OnMessage(Message *message);
8447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
8547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Returns the DBus monitor filter string.
8647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  const std::string &filter() const { return filter_; }
8747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
8847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org private:
8947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // On caller thread.
9047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  virtual void ProcessSignal(DBusMessage *message) = 0;
9147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
9247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  Thread *caller_thread_;
9347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  const std::string filter_;
9447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org};
9547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
9647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// DBusMonitor is a class for DBus signal monitoring.
9747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org//
9847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// The caller-thread calls AddFilter() first to add the signals that it wants to
9947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// monitor and then calls StartMonitoring() to start the monitoring.
10047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// This will create a worker-thread which listens on DBus connection and sends
10147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// DBus signals back through the callback.
10247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// The worker-thread will be running forever until either StopMonitoring() is
10347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// called from the caller-thread or the worker-thread hit some error.
10447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org//
10547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// Programming model:
10647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org//   1. Caller-thread: Creates an object of DBusMonitor.
10747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org//   2. Caller-thread: Calls DBusMonitor::AddFilter() one or several times.
10847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org//   3. Caller-thread: StartMonitoring().
10947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org//      ...
11047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org//   4. Worker-thread: DBus signal recieved. Post a message to caller-thread.
11147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org//   5. Caller-thread: DBusFilterBase::ProcessSignal() is invoked.
11247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org//      ...
11347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org//   6. Caller-thread: StopMonitoring().
11447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org//
11547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org// Assumption:
11647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org//   AddFilter(), StartMonitoring(), and StopMonitoring() methods are called by
11747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org//   a single thread. Hence, there is no need to make them thread safe.
11847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.orgclass DBusMonitor {
11947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org public:
12047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Status of DBus monitoring.
12147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  enum DBusMonitorStatus {
12247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    DMS_NOT_INITIALIZED,  // Not initialized.
12347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    DMS_INITIALIZING,     // Initializing the monitoring thread.
12447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    DMS_RUNNING,          // Monitoring.
12547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    DMS_STOPPED,          // Not monitoring. Stopped normally.
12647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org    DMS_FAILED,           // Not monitoring. Failed.
12747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  };
12847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
12947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Returns the DBus-Glib symbol table.
13047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // We should only use this function to access DBus-Glib symbols.
13147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  static LibDBusGlibSymbolTable *GetDBusGlibSymbolTable();
13247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
13347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Creates an instance of DBusMonitor.
13447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  static DBusMonitor *Create(DBusBusType type);
13547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  ~DBusMonitor();
13647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
13747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Adds a filter to DBusMonitor.
13847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  bool AddFilter(DBusSigFilter *filter);
13947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
14047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Starts DBus message monitoring.
14147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  bool StartMonitoring();
14247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
14347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Stops DBus message monitoring.
14447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  bool StopMonitoring();
14547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
14647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Gets the status of DBus monitoring.
14747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  DBusMonitorStatus GetStatus();
14847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
14947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org private:
15047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Forward declaration. Defined in the .cc file.
15147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  class DBusMonitoringThread;
15247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
15347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  explicit DBusMonitor(DBusBusType type);
15447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
15547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  // Updates status_ when monitoring status has changed.
15647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  void OnMonitoringStatusChanged(DBusMonitorStatus status);
15747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
15847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  DBusBusType type_;
15947be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  DBusMonitorStatus status_;
16047be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  DBusMonitoringThread *monitoring_thread_;
16147be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org  std::vector<DBusSigFilter *> filter_list_;
16247be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org};
16347be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
16447be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org}  // namespace rtc
16547be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
16647be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#endif  // HAVE_DBUS_GLIB
16747be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org
16847be73b8629244d6bb63a28198f97f040ce53d21henrike@webrtc.org#endif  // WEBRTC_BASE_DBUS_H_
169