From 9495545c38d5e72014cba05f8ea79c98ed3321a1 Mon Sep 17 00:00:00 2001 From: Arnaud Ferraris Date: Fri, 10 Dec 2021 12:44:27 +0100 Subject: launcher: rely on applaunchd for application startup 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 Change-Id: Ie2f55a5acb64ed90aa6aafb687c927d87f6cc0aa --- launcher/launcher.pro | 4 ++- launcher/qml/IconItem.qml | 2 +- launcher/qml/Launcher.qml | 3 +- launcher/src/applicationmodel.cpp | 19 ++++++----- launcher/src/homescreenhandler.cpp | 67 +++++++++++++++++++++++++++++++------- launcher/src/homescreenhandler.h | 7 +++- 6 files changed, 76 insertions(+), 26 deletions(-) diff --git a/launcher/launcher.pro b/launcher/launcher.pro index d99b09c..929960f 100644 --- a/launcher/launcher.pro +++ b/launcher/launcher.pro @@ -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 \ diff --git a/launcher/qml/IconItem.qml b/launcher/qml/IconItem.qml index 5adbe81..5207196 100644 --- a/launcher/qml/IconItem.qml +++ b/launcher/qml/IconItem.qml @@ -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() diff --git a/launcher/qml/Launcher.qml b/launcher/qml/Launcher.qml index befce07..3c948dd 100644 --- a/launcher/qml/Launcher.qml +++ b/launcher/qml/Launcher.qml @@ -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 = '' } diff --git a/launcher/src/applicationmodel.cpp b/launcher/src/applicationmodel.cpp index 42982d5..1af4366 100644 --- a/launcher/src/applicationmodel.cpp +++ b/launcher/src/applicationmodel.cpp @@ -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"; } diff --git a/launcher/src/homescreenhandler.cpp b/launcher/src/homescreenhandler.cpp index 811daa0..9cf7e61 100644 --- a/launcher/src/homescreenhandler.cpp +++ b/launcher/src/homescreenhandler.cpp @@ -15,33 +15,76 @@ * limitations under the License. */ +#include +#include #include "homescreenhandler.h" #include "hmi-debug.h" +#include + +#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 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(); + + 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!"); + } } diff --git a/launcher/src/homescreenhandler.h b/launcher/src/homescreenhandler.h index c5d46b4..616f816 100644 --- a/launcher/src/homescreenhandler.h +++ b/launcher/src/homescreenhandler.h @@ -25,6 +25,8 @@ #include +#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 -- cgit 1.2.3-korg