dbus: add signal support for removable media 51/9051/5
authorMatt Ranostay <matt.ranostay@konsulko.com>
Thu, 30 Mar 2017 22:05:03 +0000 (15:05 -0700)
committerMatt Ranostay <matt.ranostay@konsulko.com>
Fri, 14 Apr 2017 17:56:21 +0000 (10:56 -0700)
Detect media insertation and removal from lightmediascanner
and update the playlist accordingly. This makes some assumptions
that only one media device will available at a time.

Bug-AGL: SPEC-484
Change-Id: I8300abce3ac09c9cd0327c9d90892e3c5171d8d2
Signed-off-by: Matt Ranostay <matt.ranostay@konsulko.com>
app/MediaPlayer.qml
app/app.pri
app/dbus.cpp [new file with mode: 0644]
app/dbus.h [new file with mode: 0644]
app/lightmediascanner.cpp
app/lightmediascanner.h
app/main.cpp

index 37c2ab1..dae74a0 100644 (file)
@@ -24,6 +24,32 @@ import MediaPlayer 1.0
 ApplicationWindow {
     id: root
 
+    function clearMetadata() {
+        title.text = ''
+        artist.text = ''
+        duration.text = player.time2str(0)
+        albumart.visible = false
+    }
+
+    Connections {
+        target: dbus
+        onProcessPlaylistUpdate: {
+            playlist.clear()
+            playlist.addItems(mediaFiles)
+
+            playlistmodel.setSource(playlist)
+            playlistview.visible = true
+            albumart.visible = true
+        }
+
+        onProcessPlaylistHide: {
+            player.stop()
+            playlistview.visible = false
+            clearMetadata()
+        }
+
+    }
+
     MediaPlayer {
         id: player
         audioRole: MediaPlayer.MusicRole
@@ -53,6 +79,7 @@ ApplicationWindow {
             Layout.preferredHeight: 1080
             clip: true
             Image {
+                id: albumart
                 anchors.left: parent.left
                 anchors.right: parent.right
                 anchors.bottom: parent.bottom
@@ -178,17 +205,22 @@ ApplicationWindow {
             Layout.fillWidth: true
             Layout.fillHeight: true
             Layout.preferredHeight: 407
+
+           PlaylistWithMetadata {
+               id: playlistmodel
+                source: playlist
+            }
+
             ListView {
                 anchors.fill: parent
+                id: playlistview
                 clip: true
                 header: Label {
                     x: 50
                     text: 'PLAYLIST'
                     opacity: 0.5
                 }
-                model: PlaylistWithMetadata {
-                    source: playlist
-                }
+                model: playlistmodel
                 currentIndex: playlist.currentIndex
 
                 delegate: MouseArea {
index f2329c6..82f5a74 100644 (file)
@@ -16,4 +16,11 @@ packagesExist(sqlite3 lightmediascanner) {
     QT += sql
 }
 
+packagesExist(dbus-1) {
+    HEADERS += dbus.h
+    SOURCES += dbus.cpp
+    DEFINES += HAVE_DBUS
+    QT += dbus
+}
+
 DESTDIR = $${OUT_PWD}/../package/root/bin
diff --git a/app/dbus.cpp b/app/dbus.cpp
new file mode 100644 (file)
index 0000000..c6d0897
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2017 Konsulko Group
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "dbus.h"
+
+
+DbusService::DbusService(QObject *parent) : QObject(parent)
+{
+}
+
+/*
+ * Light Media Scanner
+ */
+
+bool DbusService::enableLMS()
+{
+    QDBusConnection session_bus = QDBusConnection::sessionBus();
+
+    if (!session_bus.isConnected())
+        return false;
+
+    return session_bus.connect(QString("org.lightmediascanner"), QString("/org/lightmediascanner/Scanner1"), "org.freedesktop.DBus.Properties", "PropertiesChanged", this, SLOT(lmsUpdate(QString,QVariantMap,QStringList)));
+}
+
+void DbusService::lmsUpdate(const QString&, const QVariantMap& map, const QStringList&)
+{
+    QVariantList mediaFiles;
+    QString music;
+
+    if (!map.contains("IsScanning") && !map.contains("WriteLocked"))
+        return;
+
+    if (map["IsScanning"].toBool() || map["WriteLocked"].toBool())
+        return;
+
+    mediaFiles = LightMediaScanner::processLightMediaScanner();
+
+    if (!mediaFiles.isEmpty())
+        emit processPlaylistUpdate(mediaFiles);
+    else
+        emit processPlaylistHide();
+}
diff --git a/app/dbus.h b/app/dbus.h
new file mode 100644 (file)
index 0000000..d533143
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2017 Konsulko Group
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef DBUS_H
+#define DBUS_H
+
+#include <QtCore/QDebug>
+#include <QtCore/QObject>
+#include <QtCore/QString>
+#include <QtCore/QVariant>
+#include <QtCore/QVariantList>
+#include <QtDBus/QDBusPendingCall>
+#include <QtDBus/QDBusPendingReply>
+#include <QtDBus/QDBusInterface>
+#include <QtDBus/QDBusConnection>
+
+#include "lightmediascanner.h"
+
+class DbusService : public QObject {
+    Q_OBJECT
+public:
+    explicit DbusService(QObject *parent = 0);
+    bool enableLMS();
+
+signals:
+    void processPlaylistUpdate(const QVariantList& mediaFiles);
+    void processPlaylistHide();
+
+private slots:
+    void lmsUpdate(const QString&, const QVariantMap&, const QStringList&);
+};
+
+#endif
index aa8c362..c17e0dc 100644 (file)
@@ -40,3 +40,18 @@ bool LightMediaScanner::next(QString& item)
 
     return true;
 }
+
+QVariantList LightMediaScanner::processLightMediaScanner()
+{
+    QVariantList mediaFiles;
+    QString music;
+    LightMediaScanner scanner(QDir::homePath() + "/.config/lightmediascannerd/db.sqlite3");
+    while (scanner.next(music)) {
+        QFileInfo fileInfo(music);
+        // Possible for stale entries due to removable media
+        if (!fileInfo.exists())
+            continue;
+        mediaFiles.append(QUrl::fromLocalFile(music));
+    }
+    return mediaFiles;
+}
index f5c5f90..c1c688b 100644 (file)
 #ifndef LIGHTMEDIASCANNER_H
 #define LIGHTMEDIASCANNER_H
 
+#include <QtCore/QDir>
+#include <QtCore/QUrl>
+#include <QtCore/QFileInfo>
 #include <QtCore/QDebug>
+#include <QtCore/QStandardPaths>
 #include <QtCore/QString>
 #include <QtSql/QSqlDatabase>
 #include <QtSql/QSqlRecord>
@@ -27,6 +31,7 @@ class LightMediaScanner {
 public:
     LightMediaScanner(const QString& path);
     bool next(QString& item);
+    static QVariantList processLightMediaScanner();
 private:
     QSqlDatabase lms;
     QSqlQuery query;
index 74ebad3..e8d4082 100644 (file)
 #include "lightmediascanner.h"
 #endif
 
+#ifdef HAVE_DBUS
+#include "dbus.h"
+#endif
+
 #include "playlistwithmetadata.h"
 
 #ifndef HAVE_LIGHTMEDIASCANNER
@@ -68,18 +72,12 @@ int main(int argc, char *argv[])
     qmlRegisterType<PlaylistWithMetadata>("MediaPlayer", 1, 0, "PlaylistWithMetadata");
 
     QVariantList mediaFiles;
-    QString music;
 
 #ifdef HAVE_LIGHTMEDIASCANNER
-    LightMediaScanner scanner(QDir::homePath() + "/.config/lightmediascannerd/db.sqlite3");
-    while (scanner.next(music)) {
-        QFileInfo fileInfo(music);
-        // Possible for stale entries due to removable media
-        if (!fileInfo.exists())
-            continue;
-        mediaFiles.append(QUrl::fromLocalFile(music));
-    }
+    mediaFiles = LightMediaScanner::processLightMediaScanner();
 #else
+    QString music;
+
     for (const auto &music : QStandardPaths::standardLocations(QStandardPaths::MusicLocation)) {
         mediaFiles.append(readMusicFile(music));
     }
@@ -88,8 +86,14 @@ int main(int argc, char *argv[])
     QQmlApplicationEngine engine;
     QQmlContext *context = engine.rootContext();
     context->setContextProperty("mediaFiles", mediaFiles);
+
+#if defined(HAVE_DBUS) && defined(HAVE_LIGHTMEDIASCANNER)
+    DbusService dbus_service;
+    context->setContextProperty("dbus", &dbus_service);
+    if (!dbus_service.enableLMS())
+       qWarning() << "Cannot run enableLMS";
+#endif
     engine.load(QUrl(QStringLiteral("qrc:/MediaPlayer.qml")));
 
     return app.exec();
 }
-