Bind the slider volume to the 4a active role 81/19081/2
authorLoïc Collignon <loic.collignon@iot.bzh>
Wed, 19 Dec 2018 14:30:09 +0000 (15:30 +0100)
committerLoïc Collignon [ IoT.bzh ] <loic.collignon@iot.bzh>
Wed, 19 Dec 2018 15:50:33 +0000 (15:50 +0000)
4a now expose an active role, which is the opened role with the higher
priority. This binds the slider to the active role.

Bug: 1313

Change-Id: I73766163fc0b8ef1e6b70e9c13e28d3642be858a
Signed-off-by: Loïc Collignon <loic.collignon@iot.bzh>
.gitmodules [new file with mode: 0644]
homescreen/helpers [new submodule]
homescreen/homescreen.pro
homescreen/qml/MediaAreaBlank.qml
homescreen/src/main.cpp
homescreen/src/mastervolume.cpp
homescreen/src/mastervolume.h
package/config.xml

diff --git a/.gitmodules b/.gitmodules
new file mode 100644 (file)
index 0000000..7a441d4
--- /dev/null
@@ -0,0 +1,3 @@
+[submodule "homescreen/helpers"]
+       path = homescreen/helpers
+       url =  https://gerrit.automotivelinux.org/gerrit/apps/app-afb-helpers-submodule
diff --git a/homescreen/helpers b/homescreen/helpers
new file mode 160000 (submodule)
index 0000000..b3a54dd
--- /dev/null
@@ -0,0 +1 @@
+Subproject commit b3a54dd8653fa672650229dd2498308ffcc3e943
index 0e5bb58..3a25880 100644 (file)
@@ -30,14 +30,16 @@ SOURCES += \
     src/statusbarserver.cpp \
     src/applicationlauncher.cpp \
     src/mastervolume.cpp \
-    src/homescreenhandler.cpp
+    src/homescreenhandler.cpp \
+    helpers/qafbwebsocketclient.cpp
 
 HEADERS  += \
     src/statusbarmodel.h \
     src/statusbarserver.h \
     src/applicationlauncher.h \
     src/mastervolume.h \
-    src/homescreenhandler.h
+    src/homescreenhandler.h \
+    helpers/qafbwebsocketclient.h
 
 OTHER_FILES += \
     README.md
index c3a5f89..347c26a 100644 (file)
@@ -72,6 +72,9 @@ Image {
         id: mv
         objectName: "mv"
         onVolumeChanged: slider.value = volume
+        Component.onCompleted: {
+            mv.open(bindingAddress);
+        }
     }
 
     Item {
@@ -84,7 +87,7 @@ Image {
             font.pixelSize: 36
             anchors.horizontalCenter: parent.horizontalCenter
             color: "white"
-            text: qsTr("Master Volume")
+            text: qsTr("Active Volume")
         }
 
         RowLayout {
@@ -101,8 +104,8 @@ Image {
                 id: slider
                 Layout.fillWidth: true
                 from: 0
-                to: 65536
-                stepSize: 256
+                to: 100
+                stepSize: 1
                 snapMode: Slider.SnapOnRelease
                 onValueChanged: mv.volume = value
                 Component.onCompleted: value = mv.volume
index 8ecfd68..939577f 100644 (file)
@@ -134,6 +134,7 @@ int main(int argc, char *argv[])
 
     // mail.qml loading
     QQmlApplicationEngine engine;
+    engine.rootContext()->setContextProperty("bindingAddress", bindingAddress);
     engine.rootContext()->setContextProperty("layoutHandler", layoutHandler);
     engine.rootContext()->setContextProperty("homescreenHandler", homescreenHandler);
     engine.rootContext()->setContextProperty("launcher", launcher);
index 9fb92a9..35b47fc 100644 (file)
  */
 
 #include "mastervolume.h"
+#include <QJsonObject>
+#include <QTimer>
+#include <QtDebug>
 
-void MasterVolume::setVolume(int volume)
+MasterVolume::MasterVolume(QObject* parent)
+       : QObject(parent)
+       , m_volume{50}
 {
-       int volume_delta = volume - m_volume;
-       m_volume = volume;
-       emit sliderVolumeChanged(volume_delta);
+       connect(&m_client, SIGNAL(connected()), this, SLOT(onClientConnected()));
+       connect(&m_client, SIGNAL(disconnected()), this, SLOT(onClientDisconnected()));
+       connect(&m_client, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(onClientError(QAbstractSocket::SocketError)));
+       connect(&m_client, SIGNAL(eventReceived(QString, const QJsonValue&)), this, SLOT(onClientEventReceived(QString, const QJsonValue&)));
+}
+
+void MasterVolume::open(const QUrl& url)
+{
+       m_url = url;
+       TryOpen();
+}
+
+qint32 MasterVolume::getVolume() const
+{
+       return m_volume;
+}
+
+void MasterVolume::setVolume(qint32 volume)
+{
+       if (m_volume != volume)
+       {
+               m_volume = volume;
+               QJsonObject arg;
+               arg.insert("action", "volume");
+               arg.insert("value", volume);
+               m_client.call("ahl-4a", "activerole", arg, [](bool, const QJsonValue&) {
+                       // Nothing to do, events will update sliders
+               });
+       }
+}
 
+void MasterVolume::onClientConnected()
+{
+       // Subscribe to 4a events
+       m_client.call("ahl-4a", "subscribe", QJsonValue(), [this](bool r, const QJsonValue&) {
+               if (r) qDebug() << "MasterVolume::onClientConnected - subscribed to 4a events!";
+               else qCritical () << "MasterVolume::onClientConnected - Failed to subscribe to 4a events!";
+       });
+}
+
+void MasterVolume::onClientDisconnected()
+{
+       qDebug() << "MasterVolume::onClientDisconnected!";
+       QTimer::singleShot(1000, this, SLOT(TryOpen()));
+}
+
+void MasterVolume::onClientError(QAbstractSocket::SocketError se)
+{
+       qDebug() << "MasterVolume::onClientError: " << se;
+}
+
+void MasterVolume::onClientEventReceived(QString name, const QJsonValue& data)
+{
+       qDebug() << "MasterVolume::onClientEventReceived[" << name << "]: " << data;
+       if (name == "ahl-4a/volume_changed")
+       {
+               QJsonObject arg = data.toObject();
+               bool active = arg["active"].toBool();
+               if (active)
+               {
+                       // QString role = arg["role"].toString();
+                       int volume = arg["volume"].toInt();
+                       if (m_volume != volume)
+                       {
+                               m_volume = volume;
+                               emit VolumeChanged();
+                       }
+               }
+       }
 }
 
-void MasterVolume::changeExternalVolume(int volume)
+void MasterVolume::TryOpen()
 {
-       m_volume = volume;
-       emit volumeChanged();
+       m_client.open(m_url);
 }
index bca6356..e23e8d1 100644 (file)
 
 #include <QtCore/QObject>
 #include <QQmlEngine>
+#include "../helpers/qafbwebsocketclient.h"
 
-class MasterVolume : public QObject
+class MasterVolume
+       : public QObject
 {
        Q_OBJECT
-               Q_PROPERTY (uint32_t volume READ getVolume WRITE setVolume NOTIFY volumeChanged)
-
-       public:
-               MasterVolume(QObject *parent = 0)
-                       : QObject(parent), m_volume(32768)
-               {
-               }
-
-               ~MasterVolume() {}
-
-               uint32_t getVolume() const { return m_volume; }
-               void setVolume(int volume);
-
-       public slots:
-               void changeExternalVolume(int volume);
-
-       signals:
-               void volumeChanged(void);
-               void sliderVolumeChanged(int volume_delta);
-               void externalVolumeChanged(uint32_t volume);
-
-       private:
-               uint32_t m_volume;
+       Q_PROPERTY (uint32_t volume READ getVolume WRITE setVolume NOTIFY VolumeChanged)
+
+private:
+       QAfbWebsocketClient m_client;
+       QUrl m_url;
+       qint32 m_volume;
+
+public:
+       MasterVolume(QObject* parent = nullptr);
+       ~MasterVolume() = default;
+
+       Q_INVOKABLE void open(const QUrl& url);
+       Q_INVOKABLE qint32 getVolume() const;
+       Q_INVOKABLE void setVolume(qint32 val);
+
+private slots:
+       void onClientConnected();
+       void onClientDisconnected();
+       void onClientError(QAbstractSocket::SocketError se);
+       void onClientEventReceived(QString name, const QJsonValue& data);
+       void TryOpen();
+
+signals:
+       void VolumeChanged();
 };
index 32d19fd..a15baee 100644 (file)
     <param name="weather" value="ws" />
     <param name="Bluetooth-Manager" value="ws" />
     <param name="windowmanager" value="ws" />
+    <param name="ahl-4a" value="ws" />
   </feature>
   <feature name="urn:AGL:widget:required-permission">
     <param name="urn:AGL:permission::public:no-htdocs" value="required" />
     <param name="urn:AGL:permission::system:run-by-default" value="required" />
     <param name="http://tizen.org/privilege/internal/dbus" value="required" />
+    <param name="urn:AGL:permission::public:4a-audio-mixer" value="required" />
   </feature>
 </widget>