binding: remove non-binding lightmediascanner detection
[apps/mediaplayer.git] / app / dbus.cpp
1 /*
2  * Copyright (C) 2017 Konsulko Group
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include "dbus.h"
18
19
20 DbusService::DbusService(QObject *parent) : QObject(parent)
21 {
22 }
23
24 /*
25  * Bluetooth
26  */
27
28 void DbusService::setBluezPath(const QString& path)
29 {
30     this->bluezPath = path;
31 }
32
33 QString DbusService::getBluezPath() const
34 {
35     return this->bluezPath;
36 }
37
38 bool DbusService::enableBluetooth()
39 {
40     QDBusConnection system_bus = QDBusConnection::systemBus();
41     QString interface = "org.freedesktop.DBus.ObjectManager";
42     bool ret;
43
44     if (!system_bus.isConnected())
45         return false;
46
47     if (deviceConnected(system_bus))
48         initialBluetoothData(system_bus);
49
50     ret = system_bus.connect(QString("org.bluez"), QString("/"), interface, "InterfacesAdded", this, SLOT(newBluetoothDevice(QDBusObjectPath,QVariantMap)));
51
52     if (!ret)
53         return false;
54
55     ret = system_bus.connect(QString("org.bluez"), QString("/"), interface, "InterfacesRemoved", this, SLOT(removeBluetoothDevice(QDBusObjectPath,QStringList)));
56
57     /*
58      * Unregister InterfacesAdded on error condition
59      */
60     if (!ret)
61         system_bus.disconnect(QString("org.bluez"), QString("/"), interface, "InterfacesAdded", this, SLOT(newBluetoothDevice(QString,QVariantMap)));
62
63     return ret;
64 }
65
66 bool DbusService::checkIfPlayer(const QString& path) const
67 {
68     QRegExp regex("^.*/player\\d$");
69     if (regex.exactMatch(path))
70         return true;
71
72     return false;
73 }
74
75 bool DbusService::deviceConnected(const QDBusConnection& system_bus)
76 {
77     QDBusInterface interface("org.bluez", "/", "org.freedesktop.DBus.ObjectManager", system_bus);
78     QDBusMessage result = interface.call("GetManagedObjects");
79     const QDBusArgument argument = result.arguments().at(0).value<QDBusArgument>();
80     bool ret = false;
81
82     if (argument.currentType() != QDBusArgument::MapType)
83         return false;
84
85     argument.beginMap();
86
87     while (!argument.atEnd()) {
88         QString key;
89
90         argument.beginMapEntry();
91         argument >> key;
92         argument.endMapEntry();
93
94         ret = checkIfPlayer(key);
95
96         if (ret) {
97             newBluetoothDevice(QDBusObjectPath(key), QVariantMap());
98             break;
99         }
100     }
101
102     argument.endMap();
103
104     return ret;
105 }
106
107 void DbusService::initialBluetoothData(const QDBusConnection& system_bus)
108 {
109     QDBusInterface interface("org.bluez", getBluezPath(), "org.freedesktop.DBus.Properties", system_bus);
110
111     QDBusMessage result = interface.call("GetAll", "org.bluez.MediaPlayer1");
112     const QDBusArgument argument = result.arguments().at(0).value<QDBusArgument>();
113     QString status, artist, title;
114     int position = 0, duration = 0;
115
116     if (argument.currentType() != QDBusArgument::MapType)
117         return;
118
119     argument.beginMap();
120
121     while (!argument.atEnd()) {
122         QString key;
123         QVariant value;
124
125         argument.beginMapEntry();
126         argument >> key >> value;
127
128         if (key == "Position") {
129             position = value.toInt();
130         } else if (key == "Status") {
131             status = value.toString();
132         } else if (key == "Track") {
133             const QDBusArgument argument1 = qvariant_cast<QDBusArgument>(value);
134             QString key1;
135             QVariant value1;
136
137             argument1.beginMap();
138
139             while (!argument1.atEnd()) {
140                 argument1.beginMapEntry();
141                 argument1 >> key1 >> value1;
142                 if (key1 == "Artist")
143                     artist = value1.toString();
144                 else if (key1 == "Title")
145                     title = value1.toString();
146                 else if (key1 == "Duration")
147                     duration = value1.toInt();
148                 argument1.endMapEntry();
149             }
150             argument1.endMap();
151         }
152         argument.endMapEntry();
153     }
154     argument.endMap();
155
156     emit processPlaylistHide();
157     emit displayBluetoothMetadata(artist, title, duration);
158     emit updatePlayerStatus(status);
159     emit updatePosition(position);
160 }
161
162 void DbusService::newBluetoothDevice(const QDBusObjectPath& item, const QVariantMap&)
163 {
164     QString path = item.path();
165     if (!checkIfPlayer(path))
166         return;
167
168     if (!getBluezPath().isEmpty()) {
169         qWarning() << "Another Bluetooth Player already connected";
170         return;
171     }
172
173     emit processPlaylistHide();
174
175     QDBusConnection system_bus = QDBusConnection::systemBus();
176     system_bus.connect(QString("org.bluez"), path, "org.freedesktop.DBus.Properties", "PropertiesChanged", this, SLOT(processBluetoothEvent(QString,QVariantMap,QStringList)));
177
178     setBluezPath(path);
179 }
180
181 void DbusService::removeBluetoothDevice(const QDBusObjectPath& item, const QStringList&)
182 {
183     QString path = item.path();
184     if (!checkIfPlayer(path))
185         return;
186
187     if (getBluezPath().isEmpty()) {
188         qWarning() << "No Bluetooth Player connected";
189         return;
190     }
191
192     QDBusConnection system_bus = QDBusConnection::systemBus();
193     system_bus.disconnect(QString("org.bluez"), path, "org.freedesktop.DBus.Properties", "PropertiesChanged", this, SLOT(processBluetoothEvent(QString,QVariantMap,QStringList)));
194
195     setBluezPath(QString());
196     emit processPlaylistShow();
197 }
198
199 void DbusService::processBluetoothEvent(const QString&, const QVariantMap& map, const QStringList&)
200 {
201     if (map.contains("Track")) {
202         QVariantMap track;
203         map["Track"].value<QDBusArgument>() >> track;
204         emit displayBluetoothMetadata(track["Artist"].toString(), track["Title"].toString(), track["Duration"].toInt());
205     }
206
207     if (map.contains("Position"))
208         emit updatePosition(map["Position"].toInt());
209
210     if (map.contains("Status"))
211         emit updatePlayerStatus(map["Status"].toString());
212 }
213
214 void DbusService::processQMLEvent(const QString& state)
215 {
216     QDBusInterface interface("org.bluez", getBluezPath(), "org.bluez.MediaPlayer1", QDBusConnection::systemBus());
217     interface.call(state);
218 }
219
220 long DbusService::getCurrentPosition()
221 {
222     QDBusInterface interface("org.bluez", getBluezPath(), "org.bluez.MediaPlayer1", QDBusConnection::systemBus());
223     return interface.property("Position").toInt();
224 }