Monitor pulse audio state and reconnect when it dies and gets re-spawned again
authorMohammed Sameer <msameer@foolab.org>
Sun, 23 Dec 2012 21:13:48 +0000 (23:13 +0200)
committerMohammed Sameer <msameer@foolab.org>
Sun, 23 Dec 2012 21:13:48 +0000 (23:13 +0200)
imports/imports.pro
imports/sounds.cpp
imports/sounds.h

index 097fa5f..be4a105 100644 (file)
@@ -8,7 +8,7 @@ CONFIG += link_pkgconfig debug
 PKGCONFIG = gstreamer-0.10 gstreamer-interfaces-0.10 gstreamer-video-0.10 gstreamer-tag-0.10 \
             gstreamer-pbutils-0.10 meego-gstreamer-interfaces-0.10 libcanberra
 
-QT += declarative
+QT += declarative dbus
 
 HEADERS += plugin.h previewprovider.h camera.h mode.h imagemode.h videomode.h \
            zoom.h flash.h scene.h evcomp.h videotorch.h whitebalance.h \
index 46b9984..fdf559f 100644 (file)
@@ -23,6 +23,8 @@
 #include "qtcamconfig.h"
 #include <QMutex>
 #include <QWaitCondition>
+#include <QDBusServiceWatcher>
+#include <QDBusConnection>
 
 #define CAMERA_IMAGE_START_SOUND_ID  "camera-image-start"
 #define CAMERA_IMAGE_END_SOUND_ID    "camera-image-end"
 // Odd, volume has to be a char *
 #define CANBERRA_FULL_VOLUME "0.0"
 
-// TODO: monitor pulse audio death and re-upload our samples
 // TODO: if we are using headphones then sound volume might be loud. Detect and lower it.
 
 Sounds::Sounds(QObject *parent) :
   QObject(parent),
   m_muted(false),
   m_ctx(0),
-  m_conf(0) {
+  m_conf(0),
+  m_watcher(new QDBusServiceWatcher("org.pulseaudio.Server",
+                                   QDBusConnection::systemBus(),
+                                   QDBusServiceWatcher::WatchForOwnerChange)) {
+
+  QObject::connect(m_watcher,
+                  SIGNAL(serviceOwnerChanged(const QString&, const QString&, const QString&)),
+                  this,
+                  SLOT(serviceOwnerChanged(const QString&, const QString&, const QString&)));
 
   // No idea why but canberra will not cache without that!!!
   setenv("CANBERRA_EVENT_LOOKUP", "1", 1);
@@ -57,6 +66,23 @@ void Sounds::setConfig(QtCamConfig *conf) {
   m_conf = conf;
 }
 
+void Sounds::serviceOwnerChanged(const QString& serviceName, const QString& oldOwner,
+                                const QString& newOwner) {
+  Q_UNUSED(serviceName);
+  Q_UNUSED(oldOwner);
+
+  if (newOwner.isEmpty()) {
+    // pulse died:
+    if (m_ctx) {
+      ca_context_destroy(m_ctx);
+      m_ctx = 0;
+    }
+  }
+  else if (!newOwner.isEmpty()) {
+    reload();
+  }
+}
+
 void Sounds::imageCaptureStarted() {
   if (isMuted() || !m_ctx) {
     return;
@@ -165,6 +191,11 @@ void Sounds::cache(const QString& path, const char *id) {
 }
 
 void Sounds::play(const char *id) {
+  if (!m_ctx) {
+    qWarning() << "Not connected to pulse audio";
+    return;
+  }
+
   int code = ca_context_play(m_ctx, 0,
                             CA_PROP_CANBERRA_VOLUME, CANBERRA_FULL_VOLUME,
                             CA_PROP_EVENT_ID, id,
index dfa56db..f6016b3 100644 (file)
@@ -28,6 +28,7 @@
 #include <canberra.h>
 
 class QtCamConfig;
+class QDBusServiceWatcher;
 
 class Sounds : public QObject, public Notifications {
   Q_OBJECT
@@ -54,6 +55,10 @@ public:
 signals:
   void muteChanged();
 
+private slots:
+  void serviceOwnerChanged(const QString& serviceName, const QString& oldOwner,
+                          const QString& newOwner);
+
 private:
   void cache(const QString& path, const char *id);
   void play(const char *id);
@@ -62,6 +67,7 @@ private:
   bool m_muted;
   ca_context *m_ctx;
   QtCamConfig *m_conf;
+  QDBusServiceWatcher *m_watcher;
 };
 
 #endif /* SOUNDS_H */