2
* Copyright (C) 2014-2016 Canonical, Ltd.
4
* This program is free software: you can redistribute it and/or modify it under
5
* the terms of the GNU Lesser General Public License version 3, as published by
6
* the Free Software Foundation.
8
* This program is distributed in the hope that it will be useful, but WITHOUT
9
* ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
10
* SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11
* Lesser General Public License for more details.
13
* You should have received a copy of the GNU Lesser General Public License
14
* along with this program. If not, see <http://www.gnu.org/licenses/>.
18
#include "applicationinfo.h"
19
#include "taskcontroller.h"
25
#include <QStandardPaths>
29
#include "ubuntu-app-launch.h"
31
#include <ubuntu-app-launch/registry.h>
33
namespace ual = ubuntu::app_launch;
40
struct TaskController::Private
42
std::shared_ptr<ual::Registry> registry;
43
UbuntuAppLaunchAppObserver preStartCallback = nullptr;
44
UbuntuAppLaunchAppObserver startedCallback = nullptr;
45
UbuntuAppLaunchAppObserver stopCallback = nullptr;
46
UbuntuAppLaunchAppObserver focusCallback = nullptr;
47
UbuntuAppLaunchAppObserver resumeCallback = nullptr;
48
UbuntuAppLaunchAppPausedResumedObserver pausedCallback = nullptr;
49
UbuntuAppLaunchAppFailedObserver failureCallback = nullptr;
54
* @brief toShortAppIdIfPossible
55
* @param appId - any string that you think is an appId
56
* @return if a valid appId was input, a shortened appId is returned, else returns the input string unaltered
58
QString toShortAppIdIfPossible(const QString &appId) {
59
gchar *package, *application;
60
if (ubuntu_app_launch_app_id_parse(appId.toLatin1().constData(), &package, &application, nullptr)) {
61
// is long appId, so assemble its short appId
62
QString shortAppId = QStringLiteral("%1_%2").arg(package, application);
71
std::shared_ptr<ual::Application> createApp(const QString &inputAppId, std::shared_ptr<ual::Registry> registry)
73
auto appId = ual::AppID::find(inputAppId.toStdString());
75
qCDebug(QTMIR_APPLICATIONS) << "ApplicationController::createApp could not find appId" << inputAppId;
80
return ual::Application::create(appId, registry);
81
} catch (std::runtime_error e) {
82
qCDebug(QTMIR_APPLICATIONS) << "ApplicationController::createApp - UAL failed to create app for appId"
83
<< inputAppId << ":" << e.what();
90
TaskController::TaskController()
91
: qtmir::TaskController(),
94
impl->registry = std::make_shared<ual::Registry>();
96
impl->preStartCallback = [](const gchar * appId, gpointer userData) {
97
auto thiz = static_cast<TaskController*>(userData);
98
Q_EMIT(thiz->processStarting(toShortAppIdIfPossible(appId)));
101
impl->startedCallback = [](const gchar * appId, gpointer userData) {
102
auto thiz = static_cast<TaskController*>(userData);
103
Q_EMIT(thiz->applicationStarted(toShortAppIdIfPossible(appId)));
106
impl->stopCallback = [](const gchar * appId, gpointer userData) {
107
auto thiz = static_cast<TaskController*>(userData);
108
Q_EMIT(thiz->processStopped(toShortAppIdIfPossible(appId)));
111
impl->focusCallback = [](const gchar * appId, gpointer userData) {
112
auto thiz = static_cast<TaskController*>(userData);
113
Q_EMIT(thiz->focusRequested(toShortAppIdIfPossible(appId)));
116
impl->resumeCallback = [](const gchar * appId, gpointer userData) {
117
auto thiz = static_cast<TaskController*>(userData);
118
Q_EMIT(thiz->resumeRequested(toShortAppIdIfPossible(appId)));
121
impl->pausedCallback = [](const gchar * appId, GPid *, gpointer userData) {
122
auto thiz = static_cast<TaskController*>(userData);
123
Q_EMIT(thiz->processSuspended(toShortAppIdIfPossible(appId)));
126
impl->failureCallback = [](const gchar * appId, UbuntuAppLaunchAppFailed failureType, gpointer userData) {
127
TaskController::Error error;
130
case UBUNTU_APP_LAUNCH_APP_FAILED_CRASH: error = TaskController::Error::APPLICATION_CRASHED; break;
131
case UBUNTU_APP_LAUNCH_APP_FAILED_START_FAILURE: error = TaskController::Error::APPLICATION_FAILED_TO_START; break;
134
auto thiz = static_cast<TaskController*>(userData);
135
Q_EMIT(thiz->processFailed(toShortAppIdIfPossible(appId), error));
138
ubuntu_app_launch_observer_add_app_starting(impl->preStartCallback, this);
139
ubuntu_app_launch_observer_add_app_started(impl->startedCallback, this);
140
ubuntu_app_launch_observer_add_app_stop(impl->stopCallback, this);
141
ubuntu_app_launch_observer_add_app_focus(impl->focusCallback, this);
142
ubuntu_app_launch_observer_add_app_resume(impl->resumeCallback, this);
143
ubuntu_app_launch_observer_add_app_paused(impl->pausedCallback, this);
144
ubuntu_app_launch_observer_add_app_failed(impl->failureCallback, this);
147
TaskController::~TaskController()
149
ubuntu_app_launch_observer_delete_app_starting(impl->preStartCallback, this);
150
ubuntu_app_launch_observer_delete_app_started(impl->startedCallback, this);
151
ubuntu_app_launch_observer_delete_app_stop(impl->stopCallback, this);
152
ubuntu_app_launch_observer_delete_app_focus(impl->focusCallback, this);
153
ubuntu_app_launch_observer_delete_app_resume(impl->resumeCallback, this);
154
ubuntu_app_launch_observer_delete_app_paused(impl->pausedCallback, this);
155
ubuntu_app_launch_observer_delete_app_failed(impl->failureCallback, this);
158
bool TaskController::appIdHasProcessId(const QString& appId, pid_t pid)
160
auto app = createApp(appId, impl->registry);
165
for (auto &instance: app->instances()) {
166
if (instance->hasPid(pid)) {
174
bool TaskController::stop(const QString& appId)
176
auto app = createApp(appId, impl->registry);
181
for (auto &instance: app->instances()) {
188
bool TaskController::start(const QString& appId, const QStringList& arguments)
190
auto app = createApp(appId, impl->registry);
195
// Convert arguments QStringList into format suitable for ubuntu-app-launch
196
std::vector<ual::Application::URL> urls;
197
for (auto &arg: arguments) {
198
urls.emplace_back(ual::Application::URL::from_raw(arg.toStdString()));
206
bool TaskController::suspend(const QString& appId)
208
auto app = createApp(appId, impl->registry);
213
for (auto &instance: app->instances()) {
220
bool TaskController::resume(const QString& appId)
222
auto app = createApp(appId, impl->registry);
227
for (auto &instance: app->instances()) {
234
QSharedPointer<qtmir::ApplicationInfo> TaskController::getInfoForApp(const QString &appId) const
236
auto app = createApp(appId, impl->registry);
237
if (!app || !app->info()) {
238
return QSharedPointer<qtmir::ApplicationInfo>();
241
QString shortAppId = toShortAppIdIfPossible(QString::fromStdString(std::string(app->appId())));
242
auto appInfo = new qtmir::upstart::ApplicationInfo(shortAppId, app->info());
243
return QSharedPointer<qtmir::ApplicationInfo>(appInfo);
246
} // namespace upstart