launcher: rely on applaunchd for application startup 58/26958/3 12.91.0 marlin/12.91.0 marlin_12.91.0
authorArnaud Ferraris <arnaud.ferraris@collabora.com>
Fri, 10 Dec 2021 11:44:27 +0000 (12:44 +0100)
committerArnaud Ferraris <arnaud.ferraris@collabora.com>
Mon, 20 Dec 2021 20:08:46 +0000 (21:08 +0100)
In the new App FW setup, `launcher` should only instruct `applaunchd` to
execute an application. In order to do so, it must first build a list of
available applications by looking for and parsing `.desktop` files in
relevant folders.

Then, when an application must be started, it has to call the
corresponding `applaunchd` method through D-Bus, which will then handle
the application startup using either command line execution or D-Bus
activation.

Bug-AGL: SPEC-4159 SPEC-4160
Signed-off-by: Arnaud Ferraris <arnaud.ferraris@collabora.com>
Change-Id: Ie2f55a5acb64ed90aa6aafb687c927d87f6cc0aa

launcher/launcher.pro
launcher/qml/IconItem.qml
launcher/qml/Launcher.qml
launcher/src/applicationmodel.cpp
launcher/src/homescreenhandler.cpp
launcher/src/homescreenhandler.h

index d99b09c..929960f 100644 (file)
@@ -15,7 +15,7 @@
 
 TEMPLATE = app
 TARGET = launcher
-QT = qml quick gui-private
+QT = qml quick gui-private dbus
 CONFIG += c++11 link_pkgconfig
 DESTDIR = $${OUT_PWD}
 PKGCONFIG += json-c
@@ -24,6 +24,8 @@ CONFIG(release, debug|release) {
     QMAKE_POST_LINK = $(STRIP) --strip-unneeded $(TARGET)
 }
 
+DBUS_INTERFACES = $$[QT_SYSROOT]/usr/share/dbus-1/interfaces/org.automotivelinux.AppLaunch.xml
+
 SOURCES += \
     src/main.cpp \
     src/applicationmodel.cpp \
index 5adbe81..5207196 100644 (file)
@@ -39,7 +39,7 @@ Item {
             anchors.horizontalCenter: parent.horizontalCenter
             width: 220
             height: width
-            source: './images/%1_%2.svg'.arg(model.icon).arg(loc.pressed && (loc.index === model.index || loc.currentId === model.id) ? 'active' : 'inactive')
+            source: main.icon
             antialiasing: item.state !== ''
 
             property string initial: model.name.substring(0,1).toUpperCase()
index befce07..3c948dd 100644 (file)
@@ -82,7 +82,6 @@ ApplicationWindow {
             property string currentId: ''
             property int newIndex: -1
             property int index: grid.indexAt(loc.mouseX, loc.mouseY)
-           property string output_screen: ''
             x: 62
             y: 264
             onPressAndHold: currentId = applicationModel.id(newIndex = index)
@@ -96,7 +95,7 @@ ApplicationWindow {
                //      output_screen = 'Virtual-1'
                //}
                 if (currentId === '') {
-                    homescreenHandler.tapShortcut(applicationModel.appid(loc.index), output_screen)
+                    homescreenHandler.tapShortcut(applicationModel.appid(loc.index))
                 } else {
                     currentId = ''
                 }
index 42982d5..1af4366 100644 (file)
@@ -40,13 +40,10 @@ public:
 namespace {
     QString get_icon_name(QJsonObject const &i)
     {
-        QString icon = i["name"].toString().toLower();
-
-        if ( !QFile::exists(QString(":/images/%1_active.svg").arg(icon)) ||
-             !QFile::exists(QString(":/images/%1_inactive.svg").arg(icon)) )
-        {
+        QString icon = i["icon"].toString();
+        fprintf(stderr, "Looking for icon %s\n", icon.toLocal8Bit().data());
+        if ( !QFile::exists(icon) )
             icon = "blank";
-        }
         return icon;
     }
 }
@@ -63,9 +60,13 @@ void ApplicationModel::Private::addApp(QString icon, QString name, QString id)
             return;
     }
 
-    QString _icon = name.toLower();
-    if ( !QFile::exists(QString(":/images/%1_active.svg").arg(_icon)) ||
-         !QFile::exists(QString(":/images/%1_inactive.svg").arg(_icon)) )
+    QString _icon;
+    if ( QFile::exists(icon) )
+    {
+        _icon = QString("file:%1").arg(icon);
+        fprintf(stderr, "using icon '%s'\n", _icon.toLocal8Bit().data());
+    }
+    else
     {
         _icon = "blank";
     }
index 811daa0..9cf7e61 100644 (file)
  * limitations under the License.
  */
 
+#include <QDBusMessage>
+#include <QDBusConnection>
 #include "homescreenhandler.h"
 #include "hmi-debug.h"
 
+#include <json.h>
+
+#define APPLAUNCH_DBUS_IFACE     "org.automotivelinux.AppLaunch"
+#define APPLAUNCH_DBUS_OBJECT    "/org/automotivelinux/AppLaunch"
+
 HomescreenHandler::HomescreenHandler(QObject *parent) : QObject(parent)
 {
+    applaunch_iface = new org::automotivelinux::AppLaunch(APPLAUNCH_DBUS_IFACE, APPLAUNCH_DBUS_OBJECT, QDBusConnection::sessionBus(), this);
 }
 
 HomescreenHandler::~HomescreenHandler()
 {
 }
 
-void HomescreenHandler::tapShortcut(QString application_id, QString output_name)
+void HomescreenHandler::tapShortcut(QString application_id)
 {
-       HMI_DEBUG("Launcher","tapShortcut %s", application_id.toStdString().c_str());
-}
+    HMI_DEBUG("Launcher","tapShortcut %s", application_id.toStdString().c_str());
 
-void HomescreenHandler::onRep(struct json_object* reply_contents)
-{
-       if (reply_contents) {
-               QString data = json_object_to_json_string(reply_contents);
-               HMI_DEBUG("Launcher", "doing an emit initAppList()");
-               emit initAppList(data);
-       } else {
-               HMI_DEBUG("Launcher", "reply contents is invalid!");
-       }
+    QDBusPendingReply<> reply = applaunch_iface->start(application_id);
+    reply.waitForFinished();
+    if (reply.isError()) {
+        HMI_ERROR("Launcher","Unable to start application '%s': %s",
+                  application_id.toStdString().c_str(),
+                  reply.error().message().toStdString().c_str());
+    }
 }
 
 void HomescreenHandler::getRunnables(void)
 {
+       struct json_object *json_applist;
+       QString applist;
+    QStringList apps;
+
+    QDBusPendingReply<QVariantList> reply = applaunch_iface->listApplications(true);
+    reply.waitForFinished();
+    if (reply.isError()) {
+        HMI_ERROR("Launcher","Unable to retrieve application list: %s",
+                  reply.error().message().toStdString().c_str());
+        return;
+    } else {
+        QVariantList applist_variant = reply.value();
+        for (auto &v: applist_variant) {
+            QString app_id;
+            QString name;
+            QString icon_path;
+            const QDBusArgument &dbus_arg = v.value<QDBusArgument>();
+
+            dbus_arg.beginStructure();
+            dbus_arg >> app_id >> name >> icon_path;
+
+            apps << QString("{ \"name\":\"%1\", \"id\":\"%2\", \"icon\":\"%3\" }")
+                        .arg(name)
+                        .arg(app_id)
+                        .arg(icon_path);
+            dbus_arg.endStructure();
+        }
+    }
+
+    applist = QString("[ %1 ]").arg(apps.join(", "));
+    json_applist = json_tokener_parse(applist.toLocal8Bit().data());
+    if (json_applist) {
+        QString data = json_object_to_json_string(json_applist);
+        HMI_DEBUG("Launcher", "doing an emit initAppList()");
+        emit initAppList(data);
+    } else {
+        HMI_DEBUG("Launcher", "app list is invalid!");
+    }
 }
index c5d46b4..616f816 100644 (file)
@@ -25,6 +25,8 @@
 
 #include <json.h>
 
+#include "applaunch_interface.h"
+
 using namespace std;
 
 class HomescreenHandler : public QObject
@@ -34,7 +36,7 @@ public:
     explicit HomescreenHandler(QObject *parent = 0);
     ~HomescreenHandler();
 
-    Q_INVOKABLE void tapShortcut(QString application_id, QString output_name);
+    Q_INVOKABLE void tapShortcut(QString application_id);
     Q_INVOKABLE void getRunnables(void);
 
     void onRep(struct json_object* reply_contents);
@@ -42,6 +44,9 @@ public:
 signals:
     void initAppList(QString data);
     void appListUpdate(QStringList info);
+
+private:
+    org::automotivelinux::AppLaunch *applaunch_iface;
 };
 
 #endif // HOMESCREENHANDLER_H