Handle the volume_changed event
[apps/mixer.git] / app / mixer.cpp
1 /*
2  * Copyright (C) 2016 The Qt Company Ltd.
3  * Copyright (C) 2016,2017 Konsulko Group
4  * Copyright (C) 2018 IoT.bzh
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  *      http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */
18
19 #include <QJsonArray>
20 #include <QJsonObject>
21 #include <QTimer>
22 #include <QtDebug>
23 #include "mixer.h"
24
25 Mixer::Mixer(QObject* parent)
26     : QObject(parent)
27 {
28         connect(&m_client, SIGNAL(connected()), this, SLOT(onClientConnected()));
29         connect(&m_client, SIGNAL(disconnected()), this, SLOT(onClientDisconnected()));
30         connect(&m_client, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(onClientError(QAbstractSocket::SocketError)));
31         connect(&m_client, SIGNAL(eventReceived(QString, const QJsonValue&)), this, SLOT(onClientEventReceived(QString, const QJsonValue&)));
32
33         m_roles.append("Multimedia");
34         m_roles.append("Navigation");
35         m_roles.append("Emergency");
36 }
37
38 QStringList Mixer::roles() const
39 {
40         return m_roles;
41 }
42
43 void Mixer::open(const QUrl& url)
44 {
45         m_url = url;
46         m_client.open(m_url);
47 }
48
49 void Mixer::onClientConnected()
50 {
51         // Subscribe to 4a events
52         m_client.call("ahl-4a", "subscribe", QJsonValue(), [this](bool r, const QJsonValue& val) {
53                 if (r)
54                         qDebug() << "Mixer::onClientConnected - subscribed to 4a events!";
55                 else
56                         qCritical () << "Mixer::onClientConnected - Failed to subscribe to 4a events!";
57         });
58
59         // Call HAL to populate list
60         m_client.call("ahl-4a", "get_roles", QJsonValue(), [this](bool r, const QJsonValue& val) {
61                 if (r)
62                 {
63                         m_roles.clear();
64                         //BUG: should be able to add this, but not handled right now: m_roles.append("playback");
65                         QJsonArray cards = val.toObject()["response"].toArray();
66                         foreach (const QJsonValue& card, cards)
67                         {
68                                 m_roles.append(card.toString());
69                                 qDebug() << "Mixer::onClientConnected - added this HAL: " << card.toString();
70                         }
71                         emit rolesChanged();
72                 }
73         });
74 }
75
76 void Mixer::onClientDisconnected()
77 {
78         qDebug() << "Mixer::onClientDisconnected";
79         QTimer::singleShot(1000, this, SLOT(onRetryOpen()));
80 }
81
82 void Mixer::onClientError(QAbstractSocket::SocketError se)
83 {
84         qDebug() << "Mixer::onClientError: " << se;
85 }
86
87 void Mixer::onRetryOpen()
88 {
89         m_client.open(m_url);
90 }
91
92 void Mixer::onClientEventReceived(QString eventName, const QJsonValue& data)
93 {
94         qDebug() << "Mixer::onClientEventReceived[" << eventName << "]: " << data;
95         if (eventName == "ahl-4a/volume_changed")
96         {
97                 QString role = data["role"].toString();
98                 int volume = data["volume"].toInt();
99                 m_volumes[role] = volume;
100                 emit volumeChanged(role, volume);
101         }
102 }
103
104 void Mixer::setVolume(const QString& name, int value)
105 {
106         auto currentVolume = m_volumes.find(name);
107         if (currentVolume != m_volumes.end() && *currentVolume == value)
108         return;
109
110         QJsonObject arg;
111         arg.insert("action", "volume");
112         arg.insert("value", QJsonValue(value));
113         m_client.call("ahl-4a", name, arg, [name](bool r, const QJsonValue& v) {
114                 /* Nothing to do, events will update sliders*/
115         });
116 }
117
118 void Mixer::getVolume(const QString& name)
119 {
120         QJsonObject arg;
121         arg.insert("action", "volume");
122         arg.insert("value", QJsonValue("+0")); // FIXME: Hack to get volume: ask for a relative change with a delta of zero
123         m_client.call("ahl-4a", name, arg, [this, name](bool r, const QJsonValue& v) {
124                 if (r && v.isObject())
125                 {
126                         // TODO: Success, update the slider
127                         qDebug() << "Volume changed: " << v;
128                         int newVolume = v.toObject()["response"].toObject()["volnew"].toInt();
129                         auto currentVolume = m_volumes.find(name);
130                         if (currentVolume != m_volumes.end() && *currentVolume == newVolume)
131                                 return;
132
133                         m_volumes[name] = newVolume;
134                         emit volumeChanged(name, newVolume);
135                 }
136         });
137 }