binding: remove non-binding lightmediascanner detection
[apps/mediaplayer.git] / app / dbus.cpp
index c6d0897..a562989 100644 (file)
@@ -22,34 +22,203 @@ DbusService::DbusService(QObject *parent) : QObject(parent)
 }
 
 /*
- * Light Media Scanner
+ * Bluetooth
  */
 
-bool DbusService::enableLMS()
+void DbusService::setBluezPath(const QString& path)
 {
-    QDBusConnection session_bus = QDBusConnection::sessionBus();
+    this->bluezPath = path;
+}
+
+QString DbusService::getBluezPath() const
+{
+    return this->bluezPath;
+}
+
+bool DbusService::enableBluetooth()
+{
+    QDBusConnection system_bus = QDBusConnection::systemBus();
+    QString interface = "org.freedesktop.DBus.ObjectManager";
+    bool ret;
+
+    if (!system_bus.isConnected())
+        return false;
+
+    if (deviceConnected(system_bus))
+        initialBluetoothData(system_bus);
+
+    ret = system_bus.connect(QString("org.bluez"), QString("/"), interface, "InterfacesAdded", this, SLOT(newBluetoothDevice(QDBusObjectPath,QVariantMap)));
+
+    if (!ret)
+        return false;
+
+    ret = system_bus.connect(QString("org.bluez"), QString("/"), interface, "InterfacesRemoved", this, SLOT(removeBluetoothDevice(QDBusObjectPath,QStringList)));
+
+    /*
+     * Unregister InterfacesAdded on error condition
+     */
+    if (!ret)
+        system_bus.disconnect(QString("org.bluez"), QString("/"), interface, "InterfacesAdded", this, SLOT(newBluetoothDevice(QString,QVariantMap)));
+
+    return ret;
+}
+
+bool DbusService::checkIfPlayer(const QString& path) const
+{
+    QRegExp regex("^.*/player\\d$");
+    if (regex.exactMatch(path))
+        return true;
+
+    return false;
+}
+
+bool DbusService::deviceConnected(const QDBusConnection& system_bus)
+{
+    QDBusInterface interface("org.bluez", "/", "org.freedesktop.DBus.ObjectManager", system_bus);
+    QDBusMessage result = interface.call("GetManagedObjects");
+    const QDBusArgument argument = result.arguments().at(0).value<QDBusArgument>();
+    bool ret = false;
 
-    if (!session_bus.isConnected())
+    if (argument.currentType() != QDBusArgument::MapType)
         return false;
 
-    return session_bus.connect(QString("org.lightmediascanner"), QString("/org/lightmediascanner/Scanner1"), "org.freedesktop.DBus.Properties", "PropertiesChanged", this, SLOT(lmsUpdate(QString,QVariantMap,QStringList)));
+    argument.beginMap();
+
+    while (!argument.atEnd()) {
+        QString key;
+
+        argument.beginMapEntry();
+        argument >> key;
+        argument.endMapEntry();
+
+        ret = checkIfPlayer(key);
+
+        if (ret) {
+            newBluetoothDevice(QDBusObjectPath(key), QVariantMap());
+            break;
+        }
+    }
+
+    argument.endMap();
+
+    return ret;
+}
+
+void DbusService::initialBluetoothData(const QDBusConnection& system_bus)
+{
+    QDBusInterface interface("org.bluez", getBluezPath(), "org.freedesktop.DBus.Properties", system_bus);
+
+    QDBusMessage result = interface.call("GetAll", "org.bluez.MediaPlayer1");
+    const QDBusArgument argument = result.arguments().at(0).value<QDBusArgument>();
+    QString status, artist, title;
+    int position = 0, duration = 0;
+
+    if (argument.currentType() != QDBusArgument::MapType)
+        return;
+
+    argument.beginMap();
+
+    while (!argument.atEnd()) {
+        QString key;
+        QVariant value;
+
+        argument.beginMapEntry();
+        argument >> key >> value;
+
+        if (key == "Position") {
+            position = value.toInt();
+        } else if (key == "Status") {
+            status = value.toString();
+        } else if (key == "Track") {
+            const QDBusArgument argument1 = qvariant_cast<QDBusArgument>(value);
+            QString key1;
+            QVariant value1;
+
+            argument1.beginMap();
+
+            while (!argument1.atEnd()) {
+                argument1.beginMapEntry();
+                argument1 >> key1 >> value1;
+                if (key1 == "Artist")
+                    artist = value1.toString();
+                else if (key1 == "Title")
+                    title = value1.toString();
+                else if (key1 == "Duration")
+                    duration = value1.toInt();
+                argument1.endMapEntry();
+            }
+            argument1.endMap();
+        }
+        argument.endMapEntry();
+    }
+    argument.endMap();
+
+    emit processPlaylistHide();
+    emit displayBluetoothMetadata(artist, title, duration);
+    emit updatePlayerStatus(status);
+    emit updatePosition(position);
 }
 
-void DbusService::lmsUpdate(const QString&, const QVariantMap& map, const QStringList&)
+void DbusService::newBluetoothDevice(const QDBusObjectPath& item, const QVariantMap&)
 {
-    QVariantList mediaFiles;
-    QString music;
+    QString path = item.path();
+    if (!checkIfPlayer(path))
+        return;
+
+    if (!getBluezPath().isEmpty()) {
+        qWarning() << "Another Bluetooth Player already connected";
+        return;
+    }
+
+    emit processPlaylistHide();
 
-    if (!map.contains("IsScanning") && !map.contains("WriteLocked"))
+    QDBusConnection system_bus = QDBusConnection::systemBus();
+    system_bus.connect(QString("org.bluez"), path, "org.freedesktop.DBus.Properties", "PropertiesChanged", this, SLOT(processBluetoothEvent(QString,QVariantMap,QStringList)));
+
+    setBluezPath(path);
+}
+
+void DbusService::removeBluetoothDevice(const QDBusObjectPath& item, const QStringList&)
+{
+    QString path = item.path();
+    if (!checkIfPlayer(path))
         return;
 
-    if (map["IsScanning"].toBool() || map["WriteLocked"].toBool())
+    if (getBluezPath().isEmpty()) {
+        qWarning() << "No Bluetooth Player connected";
         return;
+    }
 
-    mediaFiles = LightMediaScanner::processLightMediaScanner();
+    QDBusConnection system_bus = QDBusConnection::systemBus();
+    system_bus.disconnect(QString("org.bluez"), path, "org.freedesktop.DBus.Properties", "PropertiesChanged", this, SLOT(processBluetoothEvent(QString,QVariantMap,QStringList)));
+
+    setBluezPath(QString());
+    emit processPlaylistShow();
+}
+
+void DbusService::processBluetoothEvent(const QString&, const QVariantMap& map, const QStringList&)
+{
+    if (map.contains("Track")) {
+        QVariantMap track;
+        map["Track"].value<QDBusArgument>() >> track;
+        emit displayBluetoothMetadata(track["Artist"].toString(), track["Title"].toString(), track["Duration"].toInt());
+    }
 
-    if (!mediaFiles.isEmpty())
-        emit processPlaylistUpdate(mediaFiles);
-    else
-        emit processPlaylistHide();
+    if (map.contains("Position"))
+        emit updatePosition(map["Position"].toInt());
+
+    if (map.contains("Status"))
+        emit updatePlayerStatus(map["Status"].toString());
+}
+
+void DbusService::processQMLEvent(const QString& state)
+{
+    QDBusInterface interface("org.bluez", getBluezPath(), "org.bluez.MediaPlayer1", QDBusConnection::systemBus());
+    interface.call(state);
+}
+
+long DbusService::getCurrentPosition()
+{
+    QDBusInterface interface("org.bluez", getBluezPath(), "org.bluez.MediaPlayer1", QDBusConnection::systemBus());
+    return interface.property("Position").toInt();
 }