From 6d5e4c7d6f65d501ba259d5865d4e71fb654d0f4 Mon Sep 17 00:00:00 2001
From: Andreas Traczyk <andreas.traczyk@savoirfairelinux.com>
Date: Fri, 18 Jan 2019 15:39:56 -0500
Subject: [PATCH] audio: bind to audio metering api

Change-Id: I1b88605c4dd058babe98b323b5c247cb63b4a676
Reviewed-by: Philippe Gorley <philippe.gorley@savoirfairelinux.com>
---
 src/api/avmodel.h                         | 24 ++++++++++++++
 src/api/behaviorcontroller.h              |  4 +++
 src/avmodel.cpp                           | 38 +++++++++++++++++++++++
 src/callbackshandler.cpp                  | 11 +++++++
 src/callbackshandler.h                    | 16 ++++++++--
 src/newaccountmodel.cpp                   |  1 -
 src/qtwrapper/configurationmanager_wrap.h | 13 ++++++++
 src/qtwrapper/videomanager_wrap.h         | 10 ++++++
 test/mocks/configurationmanager_mock.h    |  5 +++
 test/mocks/videomanager_mock.h            |  8 +++++
 10 files changed, 126 insertions(+), 4 deletions(-)

diff --git a/src/api/avmodel.h b/src/api/avmodel.h
index d9988945..5fde4834 100644
--- a/src/api/avmodel.h
+++ b/src/api/avmodel.h
@@ -124,6 +124,24 @@ public:
      * @return current input device
      */
     std::string getInputDevice() const;
+    /**
+     * Get current state of the audio meter
+     * @return current state of the audio meter
+     */
+    bool isAudioMeterActive(const std::string& id="") const;
+    /**
+     * Turn on/off the audio metering feature
+     * @param the new state of the meter
+     */
+    void setAudioMeterState(bool active, const std::string& id="") const;
+    /**
+     * Starts audio device. Should only be invoked when outside of a call.
+     */
+    void startAudioDevice() const;
+    /**
+     * Stops audio device. Should only be invoked when outside of a call.
+     */
+    void stopAudioDevice() const;
     /**
      * Set current audio manager
      * @param name of the new audio manager
@@ -223,6 +241,12 @@ Q_SIGNALS:
      * Emitted when a device is plugged or unplugged
      */
     void deviceEvent();
+    /**
+     * Audio volume level
+     * @param id Ringbuffer id
+     * @param level Volume in range [0, 1]
+     */
+    void audioMeter(const std::string& id, float level);
 
 private:
     std::unique_ptr<AVModelPimpl> pimpl_;
diff --git a/src/api/behaviorcontroller.h b/src/api/behaviorcontroller.h
index a27e6970..1b2a41d7 100644
--- a/src/api/behaviorcontroller.h
+++ b/src/api/behaviorcontroller.h
@@ -95,6 +95,10 @@ Q_SIGNALS:
      * Emitted debugMessageReceived
      */
      void debugMessageReceived(const std::string& message);
+     /**
+     * Emitted audioMeter
+     */
+     void audioMeter(const std::string& id, float level);
 
 };
 
diff --git a/src/avmodel.cpp b/src/avmodel.cpp
index b0d0a09f..d0ffa4c9 100644
--- a/src/avmodel.cpp
+++ b/src/avmodel.cpp
@@ -114,6 +114,12 @@ public Q_SLOTS:
      * Detect when a device is plugged or unplugged
      */
     void slotDeviceEvent();
+    /**
+     * Audio volume level
+     * @param id Ringbuffer id
+     * @param level Volume in range [0, 1]
+     */
+    void slotAudioMeter(const std::string& id, float level);
 
 };
 
@@ -301,6 +307,30 @@ AVModel::getInputDevice() const
     return pimpl_->getDevice(INPUT_IDX);
 }
 
+bool
+AVModel::isAudioMeterActive(const std::string& id) const
+{
+    return ConfigurationManager::instance().isAudioMeterActive(id.c_str());
+}
+
+void
+AVModel::setAudioMeterState(bool active, const std::string& id) const
+{
+    ConfigurationManager::instance().setAudioMeterState(id.c_str(), active);
+}
+
+void
+AVModel::startAudioDevice() const
+{
+    VideoManager::instance().startAudioDevice();
+}
+
+void
+AVModel::stopAudioDevice() const
+{
+    VideoManager::instance().stopAudioDevice();
+}
+
 bool
 AVModel::setAudioManager(const std::string& name)
 {
@@ -487,6 +517,8 @@ AVModelPimpl::init()
 #endif
     connect(&callbacksHandler, &CallbacksHandler::deviceEvent,
             this, &AVModelPimpl::slotDeviceEvent);
+    connect(&callbacksHandler, &CallbacksHandler::audioMeter,
+            this, &AVModelPimpl::slotAudioMeter);
     connect(&callbacksHandler, &CallbacksHandler::startedDecoding,
             this, &AVModelPimpl::startedDecoding);
     connect(&callbacksHandler, &CallbacksHandler::stoppedDecoding,
@@ -696,6 +728,12 @@ AVModelPimpl::slotDeviceEvent()
     emit linked_.deviceEvent();
 }
 
+void
+AVModelPimpl::slotAudioMeter(const std::string& id, float level)
+{
+    emit linked_.audioMeter(id, level);
+}
+
 } // namespace lrc
 
 #include "api/moc_avmodel.cpp"
diff --git a/src/callbackshandler.cpp b/src/callbackshandler.cpp
index ae7d68f2..dad2607e 100644
--- a/src/callbackshandler.cpp
+++ b/src/callbackshandler.cpp
@@ -206,6 +206,12 @@ CallbacksHandler::CallbacksHandler(const Lrc& parent)
             this,
             &CallbacksHandler::slotDeviceEvent,
             Qt::QueuedConnection);
+
+    connect(&ConfigurationManager::instance(),
+            &ConfigurationManagerInterface::audioMeter,
+            this,
+            &CallbacksHandler::slotAudioMeterReceived,
+            Qt::QueuedConnection);
 }
 
 CallbacksHandler::~CallbacksHandler()
@@ -493,5 +499,10 @@ CallbacksHandler::slotDeviceEvent()
     emit deviceEvent();
 }
 
+void
+CallbacksHandler::slotAudioMeterReceived(const QString& id, float level)
+{
+    emit audioMeter(id.toStdString(), level);
+}
 
 } // namespace lrc
diff --git a/src/callbackshandler.h b/src/callbackshandler.h
index c87c792e..098e7b9a 100644
--- a/src/callbackshandler.h
+++ b/src/callbackshandler.h
@@ -176,7 +176,6 @@ Q_SIGNALS:
     void transferStatusTimeoutExpired(long long dringId, api::datatransfer::Info info);
     void transferStatusUnjoinable(long long dringId, api::datatransfer::Info info);
 
-
     /**
      * Connect this signal to get when a device name changed or a device is added
      * @param accountId interaction receiver.
@@ -253,6 +252,13 @@ Q_SIGNALS:
      */
     void deviceEvent();
 
+    /**
+     * Emitted when an audio level is received
+     * @param id of the ringbuffer level
+     * @param level
+     */
+    void audioMeter(const std::string& id, float level);
+
 private Q_SLOTS:
     /**
      * Emit newAccountMessage
@@ -433,8 +439,6 @@ private Q_SLOTS:
     void slotDebugMessageReceived(const QString& message);
 #endif
 
-
-
     /**
      * Renderer is started
      * @param id
@@ -456,6 +460,12 @@ private Q_SLOTS:
      */
     void slotDeviceEvent();
 
+    /**
+     * Called when an audio meter level is received
+     * @param id of the ringbuffer level
+     * @param level
+     */
+    void slotAudioMeterReceived(const QString& id, float level);
 
 private:
     const api::Lrc& parent;
diff --git a/src/newaccountmodel.cpp b/src/newaccountmodel.cpp
index 12cf254c..cbc207c9 100644
--- a/src/newaccountmodel.cpp
+++ b/src/newaccountmodel.cpp
@@ -226,7 +226,6 @@ NewAccountModel::getAccountConfig(const std::string& accountId) const
     return accountInfo->second.confProperties;
 }
 
-
 void
 NewAccountModel::enableAccount(const std::string& accountId, bool enabled)
 {
diff --git a/src/qtwrapper/configurationmanager_wrap.h b/src/qtwrapper/configurationmanager_wrap.h
index 5223bc71..703bc068 100644
--- a/src/qtwrapper/configurationmanager_wrap.h
+++ b/src/qtwrapper/configurationmanager_wrap.h
@@ -152,6 +152,10 @@ public:
                 [this] () {
                     Q_EMIT this->audioDeviceEvent();
                 }),
+            exportable_callback<AudioSignal::AudioMeter>(
+                [this](const std::string& id, float level) {
+                    Q_EMIT this->audioMeter(QString(id.c_str()), level);
+                }),
             exportable_callback<ConfigurationSignal::MigrationEnded>(
                 [this] (const std::string& account_id, const std::string& result) {
                     Q_EMIT this->migrationEnded(QString(account_id.c_str()), QString(result.c_str()));
@@ -509,6 +513,14 @@ public Q_SLOTS: // METHODS
         DRing::setNoiseSuppressState(state);
     }
 
+    bool isAudioMeterActive(const std::string& id) {
+        return DRing::isAudioMeterActive(id);
+    }
+
+    void setAudioMeterState(const std::string& id, bool state) {
+        DRing::setAudioMeterState(id, state);
+    }
+
     void setRecordPath(const QString& rec) {
         DRing::setRecordPath(rec.toStdString());
     }
@@ -697,6 +709,7 @@ Q_SIGNALS: // SIGNALS
     void incomingAccountMessage(const QString& accountId, const QString& from, const MapStringString& payloads);
     void mediaParametersChanged(const QString& accountId);
     void audioDeviceEvent();
+    void audioMeter(const QString& id, float level);
     void accountMessageStatusChanged(const QString& accountId, const uint64_t id, const QString& to, int status);
     void nameRegistrationEnded(const QString& accountId, int status, const QString& name);
     void registeredNameFound(const QString& accountId, int status, const QString& address, const QString& name);
diff --git a/src/qtwrapper/videomanager_wrap.h b/src/qtwrapper/videomanager_wrap.h
index 72ea6e59..e773d6c2 100644
--- a/src/qtwrapper/videomanager_wrap.h
+++ b/src/qtwrapper/videomanager_wrap.h
@@ -189,6 +189,16 @@ public Q_SLOTS: // METHODS
 #endif
     }
 
+    void startAudioDevice()
+    {
+        DRing::startAudioDevice();
+    }
+
+    void stopAudioDevice()
+    {
+        DRing::stopAudioDevice();
+    }
+
     bool switchInput(const QString &resource)
     {
 #ifdef ENABLE_VIDEO
diff --git a/test/mocks/configurationmanager_mock.h b/test/mocks/configurationmanager_mock.h
index 6373b971..cb3679b4 100644
--- a/test/mocks/configurationmanager_mock.h
+++ b/test/mocks/configurationmanager_mock.h
@@ -819,6 +819,10 @@ public Q_SLOTS: // METHODS
 
     void stopProxyClient(const std::string& /*accountID*/) { }
 
+    bool isAudioMeterActive(const std::string& /*id*/) { return false; }
+
+    void setAudioMeterState(const std::string& /*id*/, bool /*state*/) { }
+
 Q_SIGNALS: // SIGNALS
     void volumeChanged(const QString& device, double value);
     void accountsChanged();
@@ -839,6 +843,7 @@ Q_SIGNALS: // SIGNALS
     void incomingAccountMessage(const QString& accountId, const QString& from, const MapStringString& payloads);
     void mediaParametersChanged(const QString& accountId);
     void audioDeviceEvent();
+    void audioMeter(const QString& id, float level);
     void accountMessageStatusChanged(const QString& accountId, const uint64_t id, const QString& to, int status);
     void nameRegistrationEnded(const QString& accountId, int status, const QString& name);
     void registeredNameFound(const QString& accountId, int status, const QString& address, const QString& name); // used by conversationModel
diff --git a/test/mocks/videomanager_mock.h b/test/mocks/videomanager_mock.h
index e1afb3aa..569d4640 100644
--- a/test/mocks/videomanager_mock.h
+++ b/test/mocks/videomanager_mock.h
@@ -155,6 +155,14 @@ public Q_SLOTS: // METHODS
     {
     }
 
+    void startAudioDevice()
+    {
+    }
+
+    void stopAudioDevice()
+    {
+    }
+
     bool switchInput(const QString &resource)
     {
         Q_UNUSED(resource)
-- 
GitLab