2 * Copyright (c) 2017, 2018, 2019 TOYOTA MOTOR CORPORATION
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 #include <QGuiApplication>
19 #include "homescreenhandler.h"
21 #include "hmi-debug.h"
23 #include <qpa/qplatformnativeinterface.h>
25 #define APPLAUNCH_DBUS_IFACE "org.automotivelinux.AppLaunch"
26 #define APPLAUNCH_DBUS_OBJECT "/org/automotivelinux/AppLaunch"
27 /* LAUNCHER_APP_ID shouldn't be started by applaunchd as it is started as a
28 * user session by systemd */
29 #define LAUNCHER_APP_ID "launcher"
31 void* HomescreenHandler::myThis = 0;
33 HomescreenHandler::HomescreenHandler(Shell *_aglShell, ApplicationLauncher *launcher, QObject *parent) :
37 mp_launcher = launcher;
38 applaunch_iface = new org::automotivelinux::AppLaunch(APPLAUNCH_DBUS_IFACE, APPLAUNCH_DBUS_OBJECT,
39 QDBusConnection::sessionBus(), this);
42 HomescreenHandler::~HomescreenHandler()
46 void HomescreenHandler::init(void)
51 * The "started" signal is received any time a start request is made to applaunchd,
52 * and the application either starts successfully or is already running. This
53 * effectively acts as a "switch to app X" action.
55 connect(applaunch_iface, SIGNAL(started(QString)), this, SLOT(appStarted(QString)));
56 connect(applaunch_iface, SIGNAL(terminated(QString)), this, SLOT(appTerminated(QString)));
60 static struct wl_output *
61 getWlOutput(QPlatformNativeInterface *native, QScreen *screen)
63 void *output = native->nativeResourceForScreen("output", screen);
64 return static_cast<struct ::wl_output*>(output);
67 void HomescreenHandler::tapShortcut(QString application_id)
69 QDBusPendingReply<> reply;
70 HMI_DEBUG("HomeScreen","tapShortcut %s", application_id.toStdString().c_str());
72 if (application_id == LAUNCHER_APP_ID)
75 reply = applaunch_iface->start(application_id);
76 reply.waitForFinished();
78 if (reply.isError()) {
79 HMI_ERROR("HomeScreen","Unable to start application '%s': %s",
80 application_id.toStdString().c_str(),
81 reply.error().message().toStdString().c_str());
87 mp_launcher->setCurrent(application_id);
89 appStarted(application_id);
93 * Keep track of currently running apps and the order in which
94 * they were activated. That way, when an app is closed, we can
95 * switch back to the previously active one.
97 void HomescreenHandler::addAppToStack(const QString& application_id)
99 if (application_id == "homescreen")
102 if (!apps_stack.contains(application_id)) {
103 apps_stack << application_id;
105 int current_pos = apps_stack.indexOf(application_id);
106 int last_pos = apps_stack.size() - 1;
108 if (current_pos != last_pos)
109 apps_stack.move(current_pos, last_pos);
113 void HomescreenHandler::appStarted(const QString& application_id)
115 struct agl_shell *agl_shell = aglShell->shell.get();
116 QPlatformNativeInterface *native = qApp->platformNativeInterface();
117 struct wl_output *output = getWlOutput(native, qApp->screens().first());
119 HMI_DEBUG("HomeScreen", "Activating application %s", application_id.toStdString().c_str());
120 agl_shell_activate_app(agl_shell, application_id.toStdString().c_str(), output);
121 addAppToStack(application_id);
124 void HomescreenHandler::appTerminated(const QString& application_id)
126 HMI_DEBUG("HomeScreen", "Application %s terminated, activating last app", application_id.toStdString().c_str());
127 if (apps_stack.contains(application_id)) {
128 apps_stack.removeOne(application_id);
129 appStarted(apps_stack.last());