2 * Copyright (C) 2017 Konsulko Group
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
20 DbusService::DbusService(QObject *parent) : QObject(parent)
28 void DbusService::setBluezPath(const QString& path)
30 this->bluezPath = path;
33 QString DbusService::getBluezPath() const
35 return this->bluezPath;
38 bool DbusService::enableBluetooth()
40 QDBusConnection system_bus = QDBusConnection::systemBus();
41 QString interface = "org.freedesktop.DBus.ObjectManager";
44 if (!system_bus.isConnected())
47 if (deviceConnected(system_bus))
48 initialBluetoothData(system_bus);
50 ret = system_bus.connect(QString("org.bluez"), QString("/"), interface, "InterfacesAdded", this, SLOT(newBluetoothDevice(QDBusObjectPath,QVariantMap)));
55 ret = system_bus.connect(QString("org.bluez"), QString("/"), interface, "InterfacesRemoved", this, SLOT(removeBluetoothDevice(QDBusObjectPath,QStringList)));
58 * Unregister InterfacesAdded on error condition
61 system_bus.disconnect(QString("org.bluez"), QString("/"), interface, "InterfacesAdded", this, SLOT(newBluetoothDevice(QString,QVariantMap)));
66 bool DbusService::checkIfPlayer(const QString& path) const
68 QRegExp regex("^.*/player\\d$");
69 if (regex.exactMatch(path))
75 bool DbusService::deviceConnected(const QDBusConnection& system_bus)
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>();
82 if (argument.currentType() != QDBusArgument::MapType)
87 while (!argument.atEnd()) {
90 argument.beginMapEntry();
92 argument.endMapEntry();
94 ret = checkIfPlayer(key);
97 newBluetoothDevice(QDBusObjectPath(key), QVariantMap());
107 void DbusService::initialBluetoothData(const QDBusConnection& system_bus)
109 QDBusInterface interface("org.bluez", getBluezPath(), "org.freedesktop.DBus.Properties", system_bus);
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;
116 if (argument.currentType() != QDBusArgument::MapType)
121 while (!argument.atEnd()) {
125 argument.beginMapEntry();
126 argument >> key >> value;
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);
137 argument1.beginMap();
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();
152 argument.endMapEntry();
156 emit processPlaylistHide();
157 emit displayBluetoothMetadata(artist, title, duration);
158 emit updatePlayerStatus(status);
159 emit updatePosition(position);
162 void DbusService::newBluetoothDevice(const QDBusObjectPath& item, const QVariantMap&)
164 QString path = item.path();
165 if (!checkIfPlayer(path))
168 if (!getBluezPath().isEmpty()) {
169 qWarning() << "Another Bluetooth Player already connected";
173 emit processPlaylistHide();
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)));
181 void DbusService::removeBluetoothDevice(const QDBusObjectPath& item, const QStringList&)
183 QString path = item.path();
184 if (!checkIfPlayer(path))
187 if (getBluezPath().isEmpty()) {
188 qWarning() << "No Bluetooth Player connected";
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)));
195 setBluezPath(QString());
196 emit processPlaylistShow();
199 void DbusService::processBluetoothEvent(const QString&, const QVariantMap& map, const QStringList&)
201 if (map.contains("Track")) {
203 map["Track"].value<QDBusArgument>() >> track;
204 emit displayBluetoothMetadata(track["Artist"].toString(), track["Title"].toString(), track["Duration"].toInt());
207 if (map.contains("Position"))
208 emit updatePosition(map["Position"].toInt());
210 if (map.contains("Status"))
211 emit updatePlayerStatus(map["Status"].toString());
214 void DbusService::processQMLEvent(const QString& state)
216 QDBusInterface interface("org.bluez", getBluezPath(), "org.bluez.MediaPlayer1", QDBusConnection::systemBus());
217 interface.call(state);
220 long DbusService::getCurrentPosition()
222 QDBusInterface interface("org.bluez", getBluezPath(), "org.bluez.MediaPlayer1", QDBusConnection::systemBus());
223 return interface.property("Position").toInt();