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)));
57 connect(applaunch_iface, SIGNAL(splited(QString, uint32_t)), this, SLOT(appSplit(QString, uint32_t)));
61 static struct wl_output *
62 getWlOutput(QPlatformNativeInterface *native, QScreen *screen)
64 void *output = native->nativeResourceForScreen("output", screen);
65 return static_cast<struct ::wl_output*>(output);
68 void HomescreenHandler::tapShortcut(QString application_id)
70 QDBusPendingReply<> reply;
71 HMI_DEBUG("HomeScreen","tapShortcut %s", application_id.toStdString().c_str());
73 if (application_id == LAUNCHER_APP_ID)
76 reply = applaunch_iface->start(application_id);
77 reply.waitForFinished();
79 if (reply.isError()) {
80 HMI_ERROR("HomeScreen","Unable to start application '%s': %s",
81 application_id.toStdString().c_str(),
82 reply.error().message().toStdString().c_str());
88 mp_launcher->setCurrent(application_id);
90 appStarted(application_id);
94 * Keep track of currently running apps and the order in which
95 * they were activated. That way, when an app is closed, we can
96 * switch back to the previously active one.
98 void HomescreenHandler::addAppToStack(const QString& application_id)
100 if (application_id == "homescreen")
103 if (!apps_stack.contains(application_id)) {
104 apps_stack << application_id;
106 int current_pos = apps_stack.indexOf(application_id);
107 int last_pos = apps_stack.size() - 1;
109 if (current_pos != last_pos)
110 apps_stack.move(current_pos, last_pos);
114 void HomescreenHandler::appSplit(const QString& application_id, uint32_t orientation)
116 struct agl_shell *agl_shell = aglShell->shell.get();
117 QPlatformNativeInterface *native = qApp->platformNativeInterface();
118 struct wl_output *output = getWlOutput(native, qApp->screens().first());
120 HMI_DEBUG("HomeScreen", "Split application %s", application_id.toStdString().c_str());
122 fprintf(stderr, "homescreen: doing a split for app %s with orientation passed %d\n",
123 application_id.toStdString().c_str(), orientation);
124 agl_shell_set_app_split(agl_shell, application_id.toStdString().c_str(),
125 orientation, output);
128 void HomescreenHandler::appStarted(const QString& application_id)
130 struct agl_shell *agl_shell = aglShell->shell.get();
131 QPlatformNativeInterface *native = qApp->platformNativeInterface();
132 struct wl_output *output = getWlOutput(native, qApp->screens().first());
134 HMI_DEBUG("HomeScreen", "Activating application %s", application_id.toStdString().c_str());
135 agl_shell_activate_app(agl_shell, application_id.toStdString().c_str(), output);
136 addAppToStack(application_id);
139 void HomescreenHandler::appTerminated(const QString& application_id)
141 HMI_DEBUG("HomeScreen", "Application %s terminated, activating last app", application_id.toStdString().c_str());
142 if (apps_stack.contains(application_id)) {
143 apps_stack.removeOne(application_id);
144 if (!apps_stack.isEmpty())
145 appStarted(apps_stack.last());