aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorScott Murray <scott.murray@konsulko.com>2022-09-10 12:59:02 -0400
committerJan-Simon Moeller <jsmoeller@linuxfoundation.org>2022-09-16 14:19:01 +0000
commit20f629dd6d8628611d950073c4f7a0446c40365a (patch)
treef5918ebce7ec2cbcaad8588290ae55e7c3fea3ae
parentd1347bf236f84908fea96ba929e0e8376c2b1d78 (diff)
Rework to use launcher wrapper from libqtappfw
Changes: - Switch to using the new app launcher API wrapper from libqtappfw in order to migrate to the new gRPC based API implementation. - The appStarted and appTerminated methods in HomescreenHandler have been renamed to activateApp and deactivateApp, respectively, to better reflect what they do. A new processAppStatusEvent method had been added that calls them as appropriate based on the event from the AppLauncherClient status update signal. - The copyright headers in the source files have been tweaked to remove the Apache license boilerplate in favour of a SPDX license tag. - The code in main.cpp that was not formatted with Linux-style has been reformatted to match the rest of the file. Bug-AGL: SPEC-4559 Signed-off-by: Scott Murray <scott.murray@konsulko.com> Change-Id: I236cb6a412945a6df7d35652c55f664264964f9c
-rw-r--r--homescreen/homescreen.pro7
-rw-r--r--homescreen/src/homescreenhandler.cpp147
-rw-r--r--homescreen/src/homescreenhandler.h59
-rw-r--r--homescreen/src/main.cpp144
4 files changed, 157 insertions, 200 deletions
diff --git a/homescreen/homescreen.pro b/homescreen/homescreen.pro
index 00ed5e7..c713c76 100644
--- a/homescreen/homescreen.pro
+++ b/homescreen/homescreen.pro
@@ -15,11 +15,10 @@
TEMPLATE = app
TARGET = homescreen
-QT = qml quick gui-private dbus
+QT = qml quick gui-private
CONFIG += c++11 link_pkgconfig wayland-scanner
-PKGCONFIG += wayland-client qtappfw-weather qtappfw-network qtappfw-bt qtappfw-vehicle-signals
-
-DBUS_INTERFACES = $$[QT_SYSROOT]/usr/share/dbus-1/interfaces/org.automotivelinux.AppLaunch.xml
+PKGCONFIG += wayland-client
+PKGCONFIG += qtappfw-weather qtappfw-network qtappfw-bt qtappfw-vehicle-signals qtappfw-applauncher
SOURCES += \
src/main.cpp \
diff --git a/homescreen/src/homescreenhandler.cpp b/homescreen/src/homescreenhandler.cpp
index c44cbb9..16d65fb 100644
--- a/homescreen/src/homescreenhandler.cpp
+++ b/homescreen/src/homescreenhandler.cpp
@@ -1,60 +1,43 @@
+// SPDX-License-Identifier: Apache-2.0
/*
* Copyright (c) 2017, 2018, 2019 TOYOTA MOTOR CORPORATION
- *
- * 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.
+ * Copyright (c) 2022 Konsulko Group
*/
#include <QGuiApplication>
#include <QFileInfo>
-#include "homescreenhandler.h"
#include <functional>
+
+#include "homescreenhandler.h"
#include "hmi-debug.h"
#include <qpa/qplatformnativeinterface.h>
-#define APPLAUNCH_DBUS_IFACE "org.automotivelinux.AppLaunch"
-#define APPLAUNCH_DBUS_OBJECT "/org/automotivelinux/AppLaunch"
-/* LAUNCHER_APP_ID shouldn't be started by applaunchd as it is started as a
- * user session by systemd */
+// LAUNCHER_APP_ID shouldn't be started by applaunchd as it is started as
+// a user session by systemd
#define LAUNCHER_APP_ID "launcher"
-void* HomescreenHandler::myThis = 0;
-
HomescreenHandler::HomescreenHandler(Shell *_aglShell, ApplicationLauncher *launcher, QObject *parent) :
- QObject(parent),
- aglShell(_aglShell)
+ QObject(parent),
+ aglShell(_aglShell)
{
- mp_launcher = launcher;
- applaunch_iface = new org::automotivelinux::AppLaunch(APPLAUNCH_DBUS_IFACE, APPLAUNCH_DBUS_OBJECT,
- QDBusConnection::sessionBus(), this);
+ mp_launcher = launcher;
+ mp_applauncher_client = new AppLauncherClient();
+
+ //
+ // The "started" event is received any time a start request is made to applaunchd,
+ // and the application either starts successfully or is already running. This
+ // effectively acts as a "switch to app X" action.
+ //
+ connect(mp_applauncher_client,
+ &AppLauncherClient::appStatusEvent,
+ this,
+ &HomescreenHandler::processAppStatusEvent);
}
HomescreenHandler::~HomescreenHandler()
{
-}
-
-void HomescreenHandler::init(void)
-{
- myThis = this;
-
- /*
- * The "started" signal is received any time a start request is made to applaunchd,
- * and the application either starts successfully or is already running. This
- * effectively acts as a "switch to app X" action.
- */
- connect(applaunch_iface, SIGNAL(started(QString)), this, SLOT(appStarted(QString)));
- connect(applaunch_iface, SIGNAL(terminated(QString)), this, SLOT(appTerminated(QString)));
-
+ delete mp_applauncher_client;
}
static struct wl_output *
@@ -64,29 +47,24 @@ getWlOutput(QPlatformNativeInterface *native, QScreen *screen)
return static_cast<struct ::wl_output*>(output);
}
-void HomescreenHandler::tapShortcut(QString application_id)
+void HomescreenHandler::tapShortcut(QString app_id)
{
- QDBusPendingReply<> reply;
- HMI_DEBUG("HomeScreen","tapShortcut %s", application_id.toStdString().c_str());
-
- if (application_id == LAUNCHER_APP_ID)
- goto activate_app;
+ HMI_DEBUG("HomeScreen","tapShortcut %s", app_id.toStdString().c_str());
- reply = applaunch_iface->start(application_id);
- reply.waitForFinished();
+ if (app_id == LAUNCHER_APP_ID)
+ goto activate_app;
- if (reply.isError()) {
- HMI_ERROR("HomeScreen","Unable to start application '%s': %s",
- application_id.toStdString().c_str(),
- reply.error().message().toStdString().c_str());
- return;
- }
+ if (!mp_applauncher_client->startApplication(app_id)) {
+ HMI_ERROR("HomeScreen","Unable to start application '%s'",
+ app_id.toStdString().c_str());
+ return;
+ }
activate_app:
- if (mp_launcher) {
- mp_launcher->setCurrent(application_id);
- }
- appStarted(application_id);
+ if (mp_launcher) {
+ mp_launcher->setCurrent(app_id);
+ }
+ activateApp(app_id);
}
/*
@@ -94,39 +72,48 @@ activate_app:
* they were activated. That way, when an app is closed, we can
* switch back to the previously active one.
*/
-void HomescreenHandler::addAppToStack(const QString& application_id)
+void HomescreenHandler::addAppToStack(const QString& app_id)
{
- if (application_id == "homescreen")
- return;
-
- if (!apps_stack.contains(application_id)) {
- apps_stack << application_id;
- } else {
- int current_pos = apps_stack.indexOf(application_id);
- int last_pos = apps_stack.size() - 1;
-
- if (current_pos != last_pos)
- apps_stack.move(current_pos, last_pos);
- }
+ if (app_id == "homescreen")
+ return;
+
+ if (!apps_stack.contains(app_id)) {
+ apps_stack << app_id;
+ } else {
+ int current_pos = apps_stack.indexOf(app_id);
+ int last_pos = apps_stack.size() - 1;
+
+ if (current_pos != last_pos)
+ apps_stack.move(current_pos, last_pos);
+ }
}
-void HomescreenHandler::appStarted(const QString& application_id)
+void HomescreenHandler::activateApp(const QString& app_id)
{
struct agl_shell *agl_shell = aglShell->shell.get();
QPlatformNativeInterface *native = qApp->platformNativeInterface();
struct wl_output *output = getWlOutput(native, qApp->screens().first());
- HMI_DEBUG("HomeScreen", "Activating application %s", application_id.toStdString().c_str());
- agl_shell_activate_app(agl_shell, application_id.toStdString().c_str(), output);
- addAppToStack(application_id);
+ HMI_DEBUG("HomeScreen", "Activating application %s", app_id.toStdString().c_str());
+ agl_shell_activate_app(agl_shell, app_id.toStdString().c_str(), output);
+ addAppToStack(app_id);
+}
+
+void HomescreenHandler::deactivateApp(const QString& app_id)
+{
+ if (apps_stack.contains(app_id)) {
+ apps_stack.removeOne(app_id);
+ if (!apps_stack.isEmpty())
+ activateApp(apps_stack.last());
+ }
}
-void HomescreenHandler::appTerminated(const QString& application_id)
+void HomescreenHandler::processAppStatusEvent(const QString &app_id, const QString &status)
{
- HMI_DEBUG("HomeScreen", "Application %s terminated, activating last app", application_id.toStdString().c_str());
- if (apps_stack.contains(application_id)) {
- apps_stack.removeOne(application_id);
- if (!apps_stack.isEmpty())
- appStarted(apps_stack.last());
- }
+ if (status == "started") {
+ activateApp(app_id);
+ } else if (status == "terminated") {
+ HMI_DEBUG("HomeScreen", "Application %s terminated, activating last app", app_id.toStdString().c_str());
+ deactivateApp(app_id);
+ }
}
diff --git a/homescreen/src/homescreenhandler.h b/homescreen/src/homescreenhandler.h
index 503221a..a2baeb2 100644
--- a/homescreen/src/homescreenhandler.h
+++ b/homescreen/src/homescreenhandler.h
@@ -1,68 +1,49 @@
+// SPDX-License-Identifier: Apache-2.0
/*
* Copyright (c) 2017 TOYOTA MOTOR CORPORATION
- *
- * 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.
+ * Copyright (c) 2022 Konsulko Group
*/
#ifndef HOMESCREENHANDLER_H
#define HOMESCREENHANDLER_H
#include <QObject>
+#include <string>
#include "applicationlauncher.h"
-#include "applaunch_interface.h"
+#include "AppLauncherClient.h"
#include "shell.h"
-#include <string>
using namespace std;
class HomescreenHandler : public QObject
{
- Q_OBJECT
+ Q_OBJECT
public:
- explicit HomescreenHandler(Shell *aglShell, ApplicationLauncher *launcher = 0, QObject *parent = 0);
- ~HomescreenHandler();
-
- void init(void);
+ explicit HomescreenHandler(Shell *aglShell, ApplicationLauncher *launcher = 0, QObject *parent = 0);
+ ~HomescreenHandler();
- Q_INVOKABLE void tapShortcut(QString application_id);
+ Q_INVOKABLE void tapShortcut(QString application_id);
-#if 0
- void onRep(struct json_object* reply_contents);
- void onEv(const string& event, struct json_object* event_contents);
-#endif
- static void* myThis;
-#if 0
- static void onRep_static(struct json_object* reply_contents);
- static void onEv_static(const string& event, struct json_object* event_contents);
-#endif
-
- void addAppToStack(const QString& application_id);
+ void addAppToStack(const QString& application_id);
+ void activateApp(const QString& app_id);
+ void deactivateApp(const QString& app_id);
signals:
- void showNotification(QString application_id, QString icon_path, QString text);
- void showInformation(QString info);
+ void showNotification(QString application_id, QString icon_path, QString text);
+ void showInformation(QString info);
public slots:
- void appStarted(const QString& application_id);
- void appTerminated(const QString& application_id);
+ void processAppStatusEvent(const QString &id, const QString &status);
private:
- ApplicationLauncher *mp_launcher;
- Shell *aglShell;
- org::automotivelinux::AppLaunch *applaunch_iface;
- QStringList apps_stack;
+ ApplicationLauncher *mp_launcher;
+ AppLauncherClient *mp_applauncher_client;
+
+ Shell *aglShell;
+
+ QStringList apps_stack;
};
#endif // HOMESCREENHANDLER_H
diff --git a/homescreen/src/main.cpp b/homescreen/src/main.cpp
index e9a5817..2c2f7c0 100644
--- a/homescreen/src/main.cpp
+++ b/homescreen/src/main.cpp
@@ -1,18 +1,8 @@
+// SPDX-License-Identifier: Apache-2.0
/*
* Copyright (C) 2016, 2017 Mentor Graphics Development (Deutschland) GmbH
* Copyright (c) 2017, 2018 TOYOTA MOTOR CORPORATION
- *
- * 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.
+ * Copyright (c) 2022 Konsulko Group
*/
#include <QGuiApplication>
@@ -69,7 +59,7 @@ agl_shell_desktop_state_app(void *data,
HomescreenHandler *homescreenHandler = static_cast<HomescreenHandler *>(data);
if (homescreenHandler && state == AGL_SHELL_DESKTOP_APP_STATE_DESTROYED)
- homescreenHandler->appTerminated(app_id);
+ homescreenHandler->deactivateApp(app_id);
}
static const struct agl_shell_desktop_listener shell_desktop_listener = {
@@ -252,68 +242,68 @@ load_agl_shell_app(QPlatformNativeInterface *native,
int main(int argc, char *argv[])
{
- setenv("QT_QPA_PLATFORM", "wayland", 1);
- setenv("QT_QUICK_CONTROLS_STYLE", "AGL", 1);
- QGuiApplication a(argc, argv);
- const char *screen_name;
- bool is_demo_val = false;
- struct shell_data shell_data = { nullptr, nullptr };
-
- QPlatformNativeInterface *native = qApp->platformNativeInterface();
- screen_name = getenv("HOMESCREEN_START_SCREEN");
-
- const char *is_demo = getenv("HOMESCREEN_DEMO_CI");
- if (is_demo && strcmp(is_demo, "1") == 0)
- is_demo_val = true;
-
- QCoreApplication::setOrganizationDomain("LinuxFoundation");
- QCoreApplication::setOrganizationName("AutomotiveGradeLinux");
- QCoreApplication::setApplicationName("HomeScreen");
- QCoreApplication::setApplicationVersion("0.7.0");
- /* we need to have an app_id */
- a.setDesktopFileName("homescreen");
-
- register_agl_shell(native, &shell_data);
- if (!shell_data.shell) {
- fprintf(stderr, "agl_shell extension is not advertised. "
- "Are you sure that agl-compositor is running?\n");
- exit(EXIT_FAILURE);
- }
- if (!shell_data.shell_desktop) {
- fprintf(stderr, "agl_shell_desktop extension is not advertised. "
- "Are you sure that agl-compositor is running?\n");
- exit(EXIT_FAILURE);
- }
-
- std::shared_ptr<struct agl_shell> agl_shell{shell_data.shell, agl_shell_destroy};
- Shell *aglShell = new Shell(agl_shell, &a);
-
- // import C++ class to QML
- qmlRegisterType<StatusBarModel>("HomeScreen", 1, 0, "StatusBarModel");
- qmlRegisterType<MasterVolume>("MasterVolume", 1, 0, "MasterVolume");
-
- ApplicationLauncher *launcher = new ApplicationLauncher();
- launcher->setCurrent(QStringLiteral("launcher"));
- HomescreenHandler* homescreenHandler = new HomescreenHandler(aglShell, launcher);
- homescreenHandler->init();
-
- agl_shell_desktop_add_listener(shell_data.shell_desktop, &shell_desktop_listener, homescreenHandler);
-
- QQmlApplicationEngine engine;
- QQmlContext *context = engine.rootContext();
-
- context->setContextProperty("homescreenHandler", homescreenHandler);
- context->setContextProperty("launcher", launcher);
- context->setContextProperty("weather", new Weather());
- context->setContextProperty("bluetooth", new Bluetooth(false, context));
-
- // we add it here even if we don't use it
- context->setContextProperty("shell", aglShell);
-
- /* instead of loading main.qml we load one-by-one each of the QMLs,
- * divided now between several surfaces: panels, background.
- */
- load_agl_shell_app(native, &engine, shell_data.shell, screen_name, is_demo_val);
-
- return a.exec();
+ setenv("QT_QPA_PLATFORM", "wayland", 1);
+ setenv("QT_QUICK_CONTROLS_STYLE", "AGL", 1);
+
+ QGuiApplication app(argc, argv);
+ const char *screen_name;
+ bool is_demo_val = false;
+ struct shell_data shell_data = { nullptr, nullptr };
+
+ QPlatformNativeInterface *native = qApp->platformNativeInterface();
+ screen_name = getenv("HOMESCREEN_START_SCREEN");
+
+ const char *is_demo = getenv("HOMESCREEN_DEMO_CI");
+ if (is_demo && strcmp(is_demo, "1") == 0)
+ is_demo_val = true;
+
+ QCoreApplication::setOrganizationDomain("LinuxFoundation");
+ QCoreApplication::setOrganizationName("AutomotiveGradeLinux");
+ QCoreApplication::setApplicationName("HomeScreen");
+ QCoreApplication::setApplicationVersion("0.7.0");
+
+ // we need to have an app_id
+ app.setDesktopFileName("homescreen");
+
+ register_agl_shell(native, &shell_data);
+ if (!shell_data.shell) {
+ fprintf(stderr, "agl_shell extension is not advertised. "
+ "Are you sure that agl-compositor is running?\n");
+ exit(EXIT_FAILURE);
+ }
+ if (!shell_data.shell_desktop) {
+ fprintf(stderr, "agl_shell_desktop extension is not advertised. "
+ "Are you sure that agl-compositor is running?\n");
+ exit(EXIT_FAILURE);
+ }
+
+ std::shared_ptr<struct agl_shell> agl_shell{shell_data.shell, agl_shell_destroy};
+ Shell *aglShell = new Shell(agl_shell, &app);
+
+ // Import C++ class to QML
+ qmlRegisterType<StatusBarModel>("HomeScreen", 1, 0, "StatusBarModel");
+ qmlRegisterType<MasterVolume>("MasterVolume", 1, 0, "MasterVolume");
+
+ ApplicationLauncher *launcher = new ApplicationLauncher();
+ launcher->setCurrent(QStringLiteral("launcher"));
+ HomescreenHandler* homescreenHandler = new HomescreenHandler(aglShell, launcher);
+
+ agl_shell_desktop_add_listener(shell_data.shell_desktop, &shell_desktop_listener, homescreenHandler);
+
+ QQmlApplicationEngine engine;
+ QQmlContext *context = engine.rootContext();
+
+ context->setContextProperty("homescreenHandler", homescreenHandler);
+ context->setContextProperty("launcher", launcher);
+ context->setContextProperty("weather", new Weather());
+ context->setContextProperty("bluetooth", new Bluetooth(false, context));
+
+ // We add it here even if we don't use it
+ context->setContextProperty("shell", aglShell);
+
+ // Instead of loading main.qml we load one-by-one each of the QMLs,
+ // divided now between several surfaces: panels, background.
+ load_agl_shell_app(native, &engine, shell_data.shell, screen_name, is_demo_val);
+
+ return app.exec();
}