From 3229c695fc52e22e773cef89a835915c0bb6d90b Mon Sep 17 00:00:00 2001
From: Loïc Collignon <loic.collignon@iot.bzh>
Date: Wed, 19 Dec 2018 15:30:09 +0100
Subject: Bind the slider volume to the 4a active role
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

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                       |  3 ++
 homescreen/helpers                |  1 +
 homescreen/homescreen.pro         |  6 ++-
 homescreen/qml/MediaAreaBlank.qml |  9 +++--
 homescreen/src/main.cpp           |  1 +
 homescreen/src/mastervolume.cpp   | 83 +++++++++++++++++++++++++++++++++++----
 homescreen/src/mastervolume.h     | 51 +++++++++++++-----------
 package/config.xml                |  2 +
 8 files changed, 120 insertions(+), 36 deletions(-)
 create mode 100644 .gitmodules
 create mode 160000 homescreen/helpers

diff --git a/.gitmodules b/.gitmodules
new file mode 100644
index 0000000..7a441d4
--- /dev/null
+++ b/.gitmodules
@@ -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
index 0000000..b3a54dd
--- /dev/null
+++ b/homescreen/helpers
@@ -0,0 +1 @@
+Subproject commit b3a54dd8653fa672650229dd2498308ffcc3e943
diff --git a/homescreen/homescreen.pro b/homescreen/homescreen.pro
index 0e5bb58..3a25880 100644
--- a/homescreen/homescreen.pro
+++ b/homescreen/homescreen.pro
@@ -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
diff --git a/homescreen/qml/MediaAreaBlank.qml b/homescreen/qml/MediaAreaBlank.qml
index c3a5f89..347c26a 100644
--- a/homescreen/qml/MediaAreaBlank.qml
+++ b/homescreen/qml/MediaAreaBlank.qml
@@ -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
diff --git a/homescreen/src/main.cpp b/homescreen/src/main.cpp
index 8ecfd68..939577f 100644
--- a/homescreen/src/main.cpp
+++ b/homescreen/src/main.cpp
@@ -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);
diff --git a/homescreen/src/mastervolume.cpp b/homescreen/src/mastervolume.cpp
index 9fb92a9..35b47fc 100644
--- a/homescreen/src/mastervolume.cpp
+++ b/homescreen/src/mastervolume.cpp
@@ -15,17 +15,86 @@
  */
 
 #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);
 }
diff --git a/homescreen/src/mastervolume.h b/homescreen/src/mastervolume.h
index bca6356..e23e8d1 100644
--- a/homescreen/src/mastervolume.h
+++ b/homescreen/src/mastervolume.h
@@ -16,31 +16,34 @@
 
 #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();
 };
diff --git a/package/config.xml b/package/config.xml
index 32d19fd..a15baee 100644
--- a/package/config.xml
+++ b/package/config.xml
@@ -12,10 +12,12 @@
     <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>
-- 
cgit