diff options
Diffstat (limited to 'src/manager-lib')
28 files changed, 269 insertions, 1109 deletions
diff --git a/src/manager-lib/abstractcontainer.cpp b/src/manager-lib/abstractcontainer.cpp index 8827c788..e09e8aa4 100644 --- a/src/manager-lib/abstractcontainer.cpp +++ b/src/manager-lib/abstractcontainer.cpp @@ -118,7 +118,7 @@ AbstractContainerProcess *AbstractContainer::process() const return m_process; } -void AbstractContainer::setApplication(AbstractApplication *app) +void AbstractContainer::setApplication(Application *app) { if (app != m_app) { m_app = app; @@ -126,12 +126,12 @@ void AbstractContainer::setApplication(AbstractApplication *app) } } -AbstractApplication *AbstractContainer::application() const +Application *AbstractContainer::application() const { return m_app; } -AbstractContainer::AbstractContainer(AbstractContainerManager *manager, AbstractApplication *app) +AbstractContainer::AbstractContainer(AbstractContainerManager *manager, Application *app) : QObject(manager) , m_manager(manager) , m_app(app) diff --git a/src/manager-lib/abstractcontainer.h b/src/manager-lib/abstractcontainer.h index 15e7d1f1..538a0f36 100644 --- a/src/manager-lib/abstractcontainer.h +++ b/src/manager-lib/abstractcontainer.h @@ -52,7 +52,7 @@ QT_BEGIN_NAMESPACE_AM -class AbstractApplication; +class Application; class AbstractContainer; class AbstractContainerManager : public QObject @@ -66,7 +66,7 @@ public: QString identifier() const; virtual bool supportsQuickLaunch() const; - virtual AbstractContainer *create(AbstractApplication *app, const QVector<int> &stdioRedirections, + virtual AbstractContainer *create(Application *app, const QVector<int> &stdioRedirections, const QMap<QString, QString> &debugWrapperEnvironment, const QStringList &debugWrapperCommand) = 0; @@ -124,17 +124,17 @@ public: AbstractContainerProcess *process() const; - void setApplication(AbstractApplication *app); - AbstractApplication *application() const; + void setApplication(Application *app); + Application *application() const; signals: void ready(); void memoryLowWarning(); void memoryCriticalWarning(); - void applicationChanged(AbstractApplication *newApplication); + void applicationChanged(Application *newApplication); protected: - explicit AbstractContainer(AbstractContainerManager *manager, AbstractApplication *app); + explicit AbstractContainer(AbstractContainerManager *manager, Application *app); QVariantMap configuration() const; @@ -142,7 +142,7 @@ protected: QString m_baseDirectory; AbstractContainerManager *m_manager; AbstractContainerProcess *m_process = nullptr; - AbstractApplication *m_app; + Application *m_app; }; QT_END_NAMESPACE_AM diff --git a/src/manager-lib/application.cpp b/src/manager-lib/application.cpp index bc2c7e4f..bfb59fce 100644 --- a/src/manager-lib/application.cpp +++ b/src/manager-lib/application.cpp @@ -43,6 +43,7 @@ #include "application.h" #include "abstractruntime.h" #include "applicationinfo.h" +#include "package.h" #include "exception.h" #include "logging.h" @@ -90,9 +91,12 @@ /*! \qmlproperty string ApplicationObject::documentUrl \readonly + \obsolete - This property always returns the default \c documentUrl specified in the manifest file, even if - a different URL was used to start the application. + This was used to distinguish between application aliases, which have been replaced by the + intents mechanism. + + Always returns an empty string. */ /*! \qmlproperty bool ApplicationObject::builtIn @@ -104,22 +108,22 @@ /*! \qmlproperty bool ApplicationObject::alias \readonly + \obsolete - Will return \c true if this ApplicationObject object is an alias to another one. + This was used to distinguish between application aliases, which have been replaced by the + intents mechanism. - \sa nonAliased + Always returns \c false. */ /*! \qmlproperty ApplicationObject ApplicationObject::nonAliased \readonly + \obsolete - If this ApplicationObject is an alias, then you can access the non-alias, base ApplicationObject - via this property, otherwise it contains a reference to itself. This means that if you're interested - in accessing the base application regardless of whether the object at hand is just an alias, you - can always safely refer to this property. + This was used to distinguish between application aliases, which have been replaced by the + intents mechanism. - If you want to know whether this object is an alias or a base ApplicationObject, use - ApplicationObject::alias instead. + Always returns the object itself. */ /*! \qmlproperty list<string> ApplicationObject::capabilities @@ -272,222 +276,143 @@ QT_BEGIN_NAMESPACE_AM + /////////////////////////////////////////////////////////////////////////////////////////////////// -// AbstractApplication +// Application /////////////////////////////////////////////////////////////////////////////////////////////////// -AbstractApplication::AbstractApplication(AbstractApplicationInfo *info) +Application::Application(ApplicationInfo *info, Package *package) : m_info(info) + , m_package(package) { + Q_ASSERT(info); + Q_ASSERT(package); } -QString AbstractApplication::id() const +bool Application::start(const QString &documentUrl) { - return m_info->id(); + if (requests.startRequested) + return requests.startRequested(documentUrl); + else + return false; } -QUrl AbstractApplication::icon() const +bool Application::debug(const QString &debugWrapper, const QString &documentUrl) { - if (info()->icon().isEmpty()) - return QUrl(); - - auto appInfo = this->nonAliasedInfo(); - QDir dir; - switch (state()) { - default: - case Installed: - dir.setPath(appInfo->manifestDir()); - break; - case BeingInstalled: - case BeingUpdated: - dir.setPath(appInfo->codeDir().absolutePath() + QLatin1Char('+')); - break; - case BeingRemoved: - dir.setPath(appInfo->codeDir().absolutePath() + QLatin1Char('-')); - break; - } - return QUrl::fromLocalFile(dir.absoluteFilePath(info()->icon())); + if (requests.debugRequested) + return requests.debugRequested(debugWrapper, documentUrl); + else + return false; } -QString AbstractApplication::documentUrl() const +void Application::stop(bool forceKill) { - return info()->documentUrl(); + if (requests.stopRequested) + requests.stopRequested(forceKill); } -bool AbstractApplication::isBuiltIn() const +ApplicationInfo *Application::info() const { - return nonAliasedInfo()->isBuiltIn(); + return m_info.data(); } -bool AbstractApplication::isAlias() const +PackageInfo *Application::packageInfo() const { - return info()->isAlias(); + return m_info->packageInfo(); } -QStringList AbstractApplication::capabilities() const +Package *Application::package() const { - return nonAliasedInfo()->capabilities(); + return m_package; } -QStringList AbstractApplication::supportedMimeTypes() const +QString Application::id() const { - return nonAliasedInfo()->supportedMimeTypes(); + return m_info->id(); } -QStringList AbstractApplication::categories() const +bool Application::isBuiltIn() const { - return nonAliasedInfo()->categories(); + return packageInfo()->isBuiltIn(); } -QVariantMap AbstractApplication::applicationProperties() const +QString Application::runtimeName() const { - return info()->applicationProperties(); + return m_info->runtimeName(); } -bool AbstractApplication::supportsApplicationInterface() const +QVariantMap Application::runtimeParameters() const { - return nonAliasedInfo()->supportsApplicationInterface(); + return m_info->runtimeParameters(); } -QString AbstractApplication::version() const +QStringList Application::capabilities() const { - return nonAliasedInfo()->version(); + return m_info->capabilities(); } -QString AbstractApplication::codeDir() const +QStringList Application::categories() const { - switch (state()) { - default: - case Installed: - return nonAliasedInfo()->codeDir().absolutePath(); - case BeingInstalled: - case BeingUpdated: - return nonAliasedInfo()->codeDir().absolutePath() + QLatin1Char('+'); - case BeingRemoved: - return nonAliasedInfo()->codeDir().absolutePath() + QLatin1Char('-'); - } + return package()->categories(); } -QString AbstractApplication::name(const QString &language) const +QUrl Application::icon() const { - return info()->name(language); + return package()->icon(); } -bool AbstractApplication::start(const QString &documentUrl) +QStringList Application::supportedMimeTypes() const { - if (requests.startRequested) - return requests.startRequested(documentUrl); - else - return false; + return info()->supportedMimeTypes(); } -bool AbstractApplication::debug(const QString &debugWrapper, const QString &documentUrl) +QString Application::name() const { - if (requests.debugRequested) - return requests.debugRequested(debugWrapper, documentUrl); - else - return false; + return package()->name(); } -void AbstractApplication::stop(bool forceKill) +QString Application::name(const QString &language) const { - if (requests.stopRequested) - requests.stopRequested(forceKill); + return package()->names().value(language).toString(); } -QVector<AbstractApplication *> AbstractApplication::fromApplicationInfoVector( - QVector<AbstractApplicationInfo *> &appInfoVector) +QVariantMap Application::applicationProperties() const { - QVector<AbstractApplication *> apps; - - auto findAppWithId = [&apps] (const QString &id) -> AbstractApplication* - { - for (AbstractApplication *app : apps) { - if (app->id() == id) - return app; - } - return nullptr; - }; - - auto extractBaseId = [] (const QString &id) -> QString - { - return id.section(qL1C('@'), 0, 0); - }; - - for (auto *appInfo : appInfoVector) { - QScopedPointer<AbstractApplication> app; - if (appInfo->isAlias()) { - auto *originalApp = findAppWithId(extractBaseId(appInfo->id())); - if (!originalApp) - throw Exception(Error::Parse, "Could not find base app for alias id %2").arg(appInfo->id()); - Q_ASSERT(!originalApp->isAlias()); - app.reset(new ApplicationAlias(static_cast<Application*>(originalApp), - static_cast<ApplicationAliasInfo*>(appInfo))); - } else { - AbstractApplication *otherAbsApp = findAppWithId(appInfo->id()); - if (otherAbsApp) { - // There's already another ApplicationInfo with the same id. It's probably an update for a - // built-in app, in which case we use the same Application instance to hold both - // ApplicationInfo instances. - bool merged = false; - - if (!otherAbsApp->isAlias()) { - auto otherApp = static_cast<Application*>(otherAbsApp); - auto fullAppInfo = static_cast<ApplicationInfo*>(appInfo); - if (otherApp->isBuiltIn() && !fullAppInfo->isBuiltIn() && !otherApp->updatedInfo()) { - otherApp->setUpdatedInfo(static_cast<ApplicationInfo*>(appInfo)); - merged = true; - } else if (!otherApp->isBuiltIn() && fullAppInfo->isBuiltIn() && !otherApp->updatedInfo()) { - auto currentBaseInfo = otherApp->takeBaseInfo(); - otherApp->setBaseInfo(static_cast<ApplicationInfo*>(appInfo)); - otherApp->setUpdatedInfo(currentBaseInfo); - merged = true; - } - } - - if (!merged) - qCWarning(LogSystem).nospace() << "Found a second application with id " - << appInfo->id() << " which is not an update for a built-in one. Ignoring it."; - } else { - app.reset(new Application(static_cast<ApplicationInfo*>(appInfo))); - } - } - - if (!app.isNull()) - apps << app.take(); - } - - return apps; + return info()->applicationProperties(); } -/////////////////////////////////////////////////////////////////////////////////////////////////// -// Application -/////////////////////////////////////////////////////////////////////////////////////////////////// - -Application::Application(ApplicationInfo *info, State initialState) - : AbstractApplication(info) - , m_state(initialState) +bool Application::supportsApplicationInterface() const { + return info()->supportsApplicationInterface(); } -void Application::setCurrentRuntime(AbstractRuntime *rt) +QString Application::codeDir() const { - if (m_runtime == rt) - return; + switch (package()->state()) { + default: + case Package::Installed: + return packageInfo()->baseDir().absolutePath(); + case Package::BeingInstalled: + case Package::BeingUpdated: + return packageInfo()->baseDir().absolutePath() + QLatin1Char('+'); + case Package::BeingRemoved: + return packageInfo()->baseDir().absolutePath() + QLatin1Char('-'); + } +} - if (m_runtime) - disconnect(m_runtime, nullptr, this, nullptr); +QString Application::version() const +{ + return packageInfo()->version(); +} - m_runtime = rt; - emit runtimeChanged(); +Application::State Application::state() const +{ + return static_cast<State>(package()->state()); +} - if (m_runtime) { - connect(m_runtime, &AbstractRuntime::finished, this, &Application::setLastExitCodeAndStatus); - connect(m_runtime, &QObject::destroyed, this, [this]() { - this->setCurrentRuntime(nullptr); - }); - } else - setRunState(Am::NotRunning); +qreal Application::progress() const +{ + return package()->progress(); } bool Application::isBlocked() const @@ -513,24 +438,25 @@ void Application::setRunState(Am::RunState runState) } } -QString Application::runtimeName() const +void Application::setCurrentRuntime(AbstractRuntime *runtime) { - return Application::nonAliasedInfo()->runtimeName(); -} + if (m_runtime == runtime) + return; -QVariantMap Application::runtimeParameters() const -{ - return Application::nonAliasedInfo()->runtimeParameters(); -} + if (m_runtime) + disconnect(m_runtime, nullptr, this, nullptr); -AbstractApplicationInfo *Application::info() const -{ - return m_updatedInfo ? m_updatedInfo.data() : m_info.data(); -} + m_runtime = runtime; + emit runtimeChanged(); -ApplicationInfo *Application::nonAliasedInfo() const -{ - return static_cast<ApplicationInfo*>(Application::info()); + if (m_runtime) { + connect(m_runtime, &AbstractRuntime::finished, this, &Application::setLastExitCodeAndStatus); + connect(m_runtime, &QObject::destroyed, this, [this]() { + this->setCurrentRuntime(nullptr); + }); + } else { + setRunState(Am::NotRunning); + } } void Application::setLastExitCodeAndStatus(int exitCode, Am::ExitStatus exitStatus) @@ -557,71 +483,9 @@ void Application::setLastExitCodeAndStatus(int exitCode, Am::ExitStatus exitStat } } -void Application::setBaseInfo(ApplicationInfo *info) -{ - m_info.reset(info); - emit bulkChange(); -} - -ApplicationInfo *Application::takeBaseInfo() -{ - return static_cast<ApplicationInfo*>(m_info.take()); -} - -void Application::setUpdatedInfo(ApplicationInfo* info) -{ - Q_ASSERT(!info || (m_info && info->id() == m_info->id())); - - m_updatedInfo.reset(info); - emit bulkChange(); -} - -void Application::setState(State state) -{ - if (m_state != state) { - m_state = state; - emit stateChanged(m_state); - } -} - -void Application::setProgress(qreal value) -{ - m_progress = value; -} - -/////////////////////////////////////////////////////////////////////////////////////////////////// -// ApplicationAlias -/////////////////////////////////////////////////////////////////////////////////////////////////// - -ApplicationAlias::ApplicationAlias(Application* app, ApplicationAliasInfo* info) - : AbstractApplication(info) - , m_application(app) -{ - connect(m_application, &AbstractApplication::runtimeChanged, this, &AbstractApplication::runtimeChanged); - connect(m_application, &AbstractApplication::lastExitCodeChanged, this, &AbstractApplication::lastExitCodeChanged); - connect(m_application, &AbstractApplication::lastExitStatusChanged, this, &AbstractApplication::lastExitStatusChanged); - connect(m_application, &AbstractApplication::stateChanged, this, &AbstractApplication::stateChanged); - connect(m_application, &AbstractApplication::runStateChanged, this, &AbstractApplication::runStateChanged); -} - -QString ApplicationAlias::runtimeName() const -{ - return m_application->runtimeName(); -} - -QVariantMap ApplicationAlias::runtimeParameters() const -{ - return m_application->runtimeParameters(); -} - -ApplicationInfo *ApplicationAlias::nonAliasedInfo() const -{ - return m_application->nonAliasedInfo(); -} - QT_END_NAMESPACE_AM -QDebug operator<<(QDebug debug, const QT_PREPEND_NAMESPACE_AM(AbstractApplication) *app) +QDebug operator<<(QDebug debug, const QT_PREPEND_NAMESPACE_AM(Application) *app) { debug << "Application Object:"; if (app) diff --git a/src/manager-lib/application.h b/src/manager-lib/application.h index 0b081329..9e3bcc16 100644 --- a/src/manager-lib/application.h +++ b/src/manager-lib/application.h @@ -44,15 +44,16 @@ #include <QObject> #include <QScopedPointer> +#include <QVariantMap> #include <QUrl> #include <QtAppManApplication/applicationinfo.h> +#include <QtAppManApplication/packageinfo.h> #include <QtAppManManager/amnamespace.h> #include <QtAppManCommon/global.h> QT_BEGIN_NAMESPACE_AM class AbstractRuntime; -class Application; // A place to collect functions used internally by appman without polluting // Application's public QML API. @@ -64,7 +65,9 @@ public: std::function<void(bool forceKill)> stopRequested; }; -class AbstractApplication : public QObject +class Package; + +class Application : public QObject { Q_OBJECT Q_CLASSINFO("AM-QmlType", "QtApplicationManager.SystemUI/ApplicationObject 2.0 UNCREATABLE") @@ -73,12 +76,12 @@ class AbstractApplication : public QObject Q_PROPERTY(QString runtimeName READ runtimeName NOTIFY bulkChange) Q_PROPERTY(QVariantMap runtimeParameters READ runtimeParameters NOTIFY bulkChange) Q_PROPERTY(QUrl icon READ icon NOTIFY bulkChange) - Q_PROPERTY(QString documentUrl READ documentUrl NOTIFY bulkChange) - Q_PROPERTY(bool builtIn READ isBuiltIn CONSTANT) - Q_PROPERTY(bool alias READ isAlias CONSTANT) - Q_PROPERTY(Application* nonAliased READ nonAliased CONSTANT) + Q_PROPERTY(QString documentUrl READ documentUrl NOTIFY bulkChange) // REMOVE + Q_PROPERTY(bool builtIn READ isBuiltIn NOTIFY bulkChange) + Q_PROPERTY(bool alias READ isAlias CONSTANT) // REMOVE + Q_PROPERTY(Application *nonAliased READ nonAliased CONSTANT) // REMOVE Q_PROPERTY(QStringList capabilities READ capabilities NOTIFY bulkChange) - Q_PROPERTY(QStringList supportedMimeTypes READ supportedMimeTypes NOTIFY bulkChange) + Q_PROPERTY(QStringList supportedMimeTypes READ supportedMimeTypes NOTIFY bulkChange) // REMOVE Q_PROPERTY(QStringList categories READ categories NOTIFY bulkChange) Q_PROPERTY(QVariantMap applicationProperties READ applicationProperties NOTIFY bulkChange) Q_PROPERTY(AbstractRuntime *runtime READ currentRuntime NOTIFY runtimeChanged) @@ -91,7 +94,7 @@ class AbstractApplication : public QObject Q_PROPERTY(QT_PREPEND_NAMESPACE_AM(Am::RunState) runState READ runState NOTIFY runStateChanged) public: - enum State { + enum State { // kept for compatibility ... in reality moved to class Package Installed, BeingInstalled, BeingUpdated, @@ -100,62 +103,53 @@ public: }; Q_ENUM(State) - AbstractApplication(AbstractApplicationInfo *info); + Application(ApplicationInfo *info, Package *package); Q_INVOKABLE bool start(const QString &documentUrl = QString()); Q_INVOKABLE bool debug(const QString &debugWrapper, const QString &documentUrl = QString()); Q_INVOKABLE void stop(bool forceKill = false); - virtual Application *nonAliased() = 0; - - /* - Returns information about this application, which can either - be a full-fledged one (ApplicationInfo) or just an alias - (ApplicationAliasInfo). - - Use info()->isAlias() to check and cast as appropriate. - */ - virtual AbstractApplicationInfo *info() const = 0; + ApplicationInfo *info() const; + PackageInfo *packageInfo() const; + Package *package() const; - /* - Always returns information about the "concrete", non-aliased, application. - This is the same as static_cast<ApplicationInfo*>(nonAliased()->info()) - */ - virtual ApplicationInfo *nonAliasedInfo() const = 0; + // legacy compatibility + bool isAlias() const { return false; } + Application *nonAliased() { return this; } + QStringList categories() const; + QUrl icon() const; + QString documentUrl() const { return QString {}; } + QStringList supportedMimeTypes() const; + QString name() const; + Q_INVOKABLE QString name(const QString &language) const; // Properties that mainly forward content from ApplicationInfo QString id() const; - virtual QString runtimeName() const = 0; - virtual QVariantMap runtimeParameters() const = 0; - QUrl icon() const; - QString documentUrl() const; bool isBuiltIn() const; - bool isAlias() const; + QString runtimeName() const; + QVariantMap runtimeParameters() const; QStringList capabilities() const; - QStringList supportedMimeTypes() const; - QStringList categories() const; QVariantMap applicationProperties() const; bool supportsApplicationInterface() const; + QString codeDir() const; QString version() const; - Q_INVOKABLE QString name(const QString &language) const; // Properties present only in Application (not coming from ApplicationInfo) - virtual AbstractRuntime *currentRuntime() const = 0; - virtual State state() const = 0; - QString codeDir() const; - virtual bool isBlocked() const = 0; - virtual bool block() = 0; - virtual bool unblock() = 0; - virtual qreal progress() const = 0; - virtual Am::RunState runState() const = 0; - virtual int lastExitCode() const = 0; - virtual Am::ExitStatus lastExitStatus() const = 0; + + AbstractRuntime *currentRuntime() const { return m_runtime; } + State state() const; + qreal progress() const; + Am::RunState runState() const { return m_runState; } + bool isBlocked() const; + bool block(); + bool unblock(); + int lastExitCode() const { return m_lastExitCode; } + Am::ExitStatus lastExitStatus() const { return m_lastExitStatus; } ApplicationRequests requests; - // Creates a list of Applications from a list of ApplicationInfo objects. - // Ownership of the given ApplicationInfo objects is passed to the returned Applications. - static QVector<AbstractApplication *> fromApplicationInfoVector(QVector<AbstractApplicationInfo *> &); + void setRunState(Am::RunState runState); + void setCurrentRuntime(AbstractRuntime *runtime); signals: void bulkChange(); @@ -166,107 +160,24 @@ signals: void stateChanged(State state); void runStateChanged(Am::RunState state); -protected: - QScopedPointer<AbstractApplicationInfo> m_info; -}; - -class Application : public AbstractApplication -{ - Q_OBJECT -public: - Application(ApplicationInfo *info, State initialState = Installed); - - - // Returns the updated info, if there's one. Otherwise - // returns the base info. - AbstractApplicationInfo *info() const override; - - // same as info() - ApplicationInfo *nonAliasedInfo() const override; - - - /* - All applications have a base info. - - Built-in applications, when updated, also get an updated info. - The updated info then overlays the base one. Subsequent updates - just replace the updated info. When requested to be removed, a - built-in application only loses its updated info, returning to - expose the base one. - - Regular applications (ie, non-built-in) only have a base info. When - updated their base info gets replaced and thus there's no way to go - back to a previous version. Regular applications get completely - removed when requested. - */ - void setBaseInfo(ApplicationInfo*); - void setUpdatedInfo(ApplicationInfo*); - ApplicationInfo *updatedInfo() const { return m_updatedInfo.data(); } - ApplicationInfo *takeBaseInfo(); - - void setState(State); - void setProgress(qreal); - void setRunState(Am::RunState); - void setCurrentRuntime(AbstractRuntime *rt); - - Application *nonAliased() override { return this; } - QString runtimeName() const override; - QVariantMap runtimeParameters() const override; - AbstractRuntime *currentRuntime() const override { return m_runtime; } - State state() const override { return m_state; } - bool isBlocked() const override; - bool block() override; - bool unblock() override; - qreal progress() const override { return m_progress; } - Am::RunState runState() const override { return m_runState; } - int lastExitCode() const override { return m_lastExitCode; } - Am::ExitStatus lastExitStatus() const override { return m_lastExitStatus; } - private: void setLastExitCodeAndStatus(int exitCode, Am::ExitStatus exitStatus); + QScopedPointer<ApplicationInfo> m_info; + Package *m_package = nullptr; AbstractRuntime *m_runtime = nullptr; QAtomicInt m_blocked; QAtomicInt m_mounted; - State m_state = Installed; Am::RunState m_runState = Am::NotRunning; - qreal m_progress = 0; int m_lastExitCode = 0; Am::ExitStatus m_lastExitStatus = Am::NormalExit; - QScopedPointer<ApplicationInfo> m_updatedInfo; -}; - -class ApplicationAlias : public AbstractApplication -{ - Q_OBJECT -public: - ApplicationAlias(Application*, ApplicationAliasInfo*); - - AbstractApplicationInfo *info() const override { return m_info.data(); } - Application *nonAliased() override { return m_application; } - QString runtimeName() const override; - QVariantMap runtimeParameters() const override; - AbstractRuntime *currentRuntime() const override { return m_application->currentRuntime(); } - State state() const override { return m_application->state(); } - bool isBlocked() const override { return m_application->isBlocked(); } - bool block() override { return m_application->block(); } - bool unblock() override { return m_application->unblock(); } - qreal progress() const override { return m_application->progress(); } - Am::RunState runState() const override { return m_application->runState(); } - int lastExitCode() const override { return m_application->lastExitCode(); } - Am::ExitStatus lastExitStatus() const override { return m_application->lastExitStatus(); } -protected: - // Returns info() from the application being aliased - ApplicationInfo *nonAliasedInfo() const override; -private: - Application *m_application; }; QT_END_NAMESPACE_AM -Q_DECLARE_METATYPE(const QT_PREPEND_NAMESPACE_AM(AbstractApplication *)) +Q_DECLARE_METATYPE(const QT_PREPEND_NAMESPACE_AM(Application *)) -QDebug operator<<(QDebug debug, const QT_PREPEND_NAMESPACE_AM(AbstractApplication) *app); +QDebug operator<<(QDebug debug, const QT_PREPEND_NAMESPACE_AM(Application) *app); diff --git a/src/manager-lib/applicationdatabase.cpp b/src/manager-lib/applicationdatabase.cpp deleted file mode 100644 index a6fb8ef3..00000000 --- a/src/manager-lib/applicationdatabase.cpp +++ /dev/null @@ -1,184 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2019 Luxoft Sweden AB -** Copyright (C) 2018 Pelagicore AG -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Luxoft Application Manager. -** -** $QT_BEGIN_LICENSE:LGPL-QTAS$ -** Commercial License Usage -** Licensees holding valid commercial Qt Automotive Suite licenses may use -** this file in accordance with the commercial license agreement provided -** with the Software or, alternatively, in accordance with the terms -** contained in a written agreement between you and The Qt Company. For -** licensing terms and conditions see https://www.qt.io/terms-conditions. -** For further information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -** SPDX-License-Identifier: LGPL-3.0 -** -****************************************************************************/ - -#include <QFile> -#include <QDataStream> -#include <QTemporaryFile> -#include <QScopedPointer> - -#include "application.h" -#include "applicationdatabase.h" -#include "exception.h" -#include "logging.h" - -QT_BEGIN_NAMESPACE_AM - -class ApplicationDatabasePrivate -{ -public: - void validateWritableFile() - { - if (!file || !file->isOpen() || !file->isWritable()) - throw Exception("application database %1 is not opened for writing").arg(file ? file->fileName() : qSL("<null>")); - if (!file->seek(0)) - throw Exception(*file, "could not not seek to position 0 in the application database"); - if (!file->resize(0)) - throw Exception(*file, "could not truncate the application database"); - } - - QFile *file = nullptr; - - ApplicationDatabasePrivate() - { } - ~ApplicationDatabasePrivate() - { delete file; } -}; - -ApplicationDatabase::ApplicationDatabase(const QString &fileName) - : d(new ApplicationDatabasePrivate()) -{ - d->file = new QFile(fileName); - d->file->open(QFile::ReadWrite); -} - -ApplicationDatabase::ApplicationDatabase() - : d(new ApplicationDatabasePrivate()) -{ - d->file = new QTemporaryFile(qSL("am-apps-db")); - d->file->open(QFile::ReadWrite); -} - -ApplicationDatabase::~ApplicationDatabase() -{ - delete d; -} - -bool ApplicationDatabase::isValid() const -{ - return d->file && d->file->isOpen(); -} - -bool ApplicationDatabase::isTemporary() const -{ - return qobject_cast<QTemporaryFile *>(d->file); -} - -QString ApplicationDatabase::errorString() const -{ - return d->file->errorString(); -} - -QString ApplicationDatabase::name() const -{ - return d->file->fileName(); -} - -QVector<AbstractApplication *> ApplicationDatabase::read() Q_DECL_NOEXCEPT_EXPR(false) -{ - if (!d->file || !d->file->isOpen() || !d->file->isReadable()) - throw Exception("application database %1 is not opened for reading").arg(d->file ? d->file->fileName() : qSL("<null>")); - - QVector<AbstractApplicationInfo *> appInfoVector; - - if (d->file->seek(0)) { - QDataStream ds(d->file); - forever { - QScopedPointer<AbstractApplicationInfo> appInfo(AbstractApplicationInfo::readFromDataStream(ds)); - - if (ds.status() != QDataStream::Ok) { - if (ds.status() != QDataStream::ReadPastEnd) { - qDeleteAll(appInfoVector); - throw Exception("could not read from application database %1").arg(d->file->fileName()); - } - break; - } - - appInfoVector.append(appInfo.take()); - } - } - - return AbstractApplication::fromApplicationInfoVector(appInfoVector); -} - -void ApplicationDatabase::write(const QVector<AbstractApplicationInfo *> &apps) Q_DECL_NOEXCEPT_EXPR(false) -{ - d->validateWritableFile(); - - QDataStream ds(d->file); - for (auto *app : apps) - app->writeToDataStream(ds); - - if (ds.status() != QDataStream::Ok) - throw Exception(*d->file, "could not write to application database"); -} - -void ApplicationDatabase::write(const QVector<AbstractApplication *> &apps) Q_DECL_NOEXCEPT_EXPR(false) -{ - d->validateWritableFile(); - - QDataStream ds(d->file); - for (auto *app : apps) { - app->info()->writeToDataStream(ds); - if (!app->isAlias()) { - auto fullApp = static_cast<Application*>(app); - if (fullApp->updatedInfo()) - fullApp->updatedInfo()->writeToDataStream(ds); - } - } - - if (ds.status() != QDataStream::Ok) - throw Exception(*d->file, "could not write to application database"); - - d->file->flush(); -} - -void ApplicationDatabase::invalidate() -{ - if (d->file) { - if (d->file->isOpen()) - d->file->close(); - d->file->remove(); - d->file = nullptr; - } -} - -QT_END_NAMESPACE_AM diff --git a/src/manager-lib/applicationdatabase.h b/src/manager-lib/applicationdatabase.h deleted file mode 100644 index 7d11f4a9..00000000 --- a/src/manager-lib/applicationdatabase.h +++ /dev/null @@ -1,78 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2019 Luxoft Sweden AB -** Copyright (C) 2018 Pelagicore AG -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Luxoft Application Manager. -** -** $QT_BEGIN_LICENSE:LGPL-QTAS$ -** Commercial License Usage -** Licensees holding valid commercial Qt Automotive Suite licenses may use -** this file in accordance with the commercial license agreement provided -** with the Software or, alternatively, in accordance with the terms -** contained in a written agreement between you and The Qt Company. For -** licensing terms and conditions see https://www.qt.io/terms-conditions. -** For further information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -** SPDX-License-Identifier: LGPL-3.0 -** -****************************************************************************/ - -#pragma once - -#include <QtAppManCommon/global.h> -#include <QList> -#include <QString> - -QT_BEGIN_NAMESPACE_AM - -class Application; -class AbstractApplication; -class ApplicationDatabasePrivate; - -class ApplicationDatabase -{ -public: - explicit ApplicationDatabase(); - explicit ApplicationDatabase(const QString &fileName); - ~ApplicationDatabase(); - - bool isValid() const; - bool isTemporary() const; - QString errorString() const; - QString name() const; - - QVector<AbstractApplication *> read() Q_DECL_NOEXCEPT_EXPR(false); - void write(const QVector<AbstractApplication *> &apps) Q_DECL_NOEXCEPT_EXPR(false); - void write(const QVector<AbstractApplicationInfo *> &apps) Q_DECL_NOEXCEPT_EXPR(false); - - void invalidate(); - -private: - ApplicationDatabasePrivate *d; - Q_DISABLE_COPY(ApplicationDatabase) -}; - -QT_END_NAMESPACE_AM diff --git a/src/manager-lib/applicationipcinterface.cpp b/src/manager-lib/applicationipcinterface.cpp index 9b9ec477..54be78d5 100644 --- a/src/manager-lib/applicationipcinterface.cpp +++ b/src/manager-lib/applicationipcinterface.cpp @@ -100,7 +100,7 @@ QString ApplicationIPCInterface::pathName() const return m_ipcProxy ? m_ipcProxy->pathName() : QString(); } -bool ApplicationIPCInterface::isValidForApplication(AbstractApplication *app) const +bool ApplicationIPCInterface::isValidForApplication(Application *app) const { return m_ipcProxy ? m_ipcProxy->isValidForApplication(app) : false; } @@ -126,7 +126,7 @@ void ApplicationIPCInterface::setServiceObject(QObject *serviceObject) } #if defined(QT_DBUS_LIB) -bool ApplicationIPCInterface::dbusRegister(AbstractApplication *app, QDBusConnection connection, const QString &debugPathPrefix) +bool ApplicationIPCInterface::dbusRegister(Application *app, QDBusConnection connection, const QString &debugPathPrefix) { return m_ipcProxy ? m_ipcProxy->dbusRegister(app, connection, debugPathPrefix) : false; } @@ -432,7 +432,7 @@ QStringList IpcProxyObject::connectionNames() const return m_connectionNamesToApplicationIds.keys(); } -bool IpcProxyObject::isValidForApplication(AbstractApplication *app) const +bool IpcProxyObject::isValidForApplication(Application *app) const { if (!app) return false; @@ -454,7 +454,7 @@ bool IpcProxyObject::isValidForApplication(AbstractApplication *app) const #if defined(QT_DBUS_LIB) -bool IpcProxyObject::dbusRegister(AbstractApplication *app, QDBusConnection connection, const QString &debugPathPrefix) +bool IpcProxyObject::dbusRegister(Application *app, QDBusConnection connection, const QString &debugPathPrefix) { if (m_connectionNamesToApplicationIds.contains(connection.name())) return false; diff --git a/src/manager-lib/applicationipcinterface.h b/src/manager-lib/applicationipcinterface.h index 3a1f8aad..b4478f3d 100644 --- a/src/manager-lib/applicationipcinterface.h +++ b/src/manager-lib/applicationipcinterface.h @@ -53,7 +53,7 @@ QT_BEGIN_NAMESPACE_AM -class AbstractApplication; +class Application; class ApplicationIPCInterfaceAttached; class IpcProxyObject; @@ -70,12 +70,12 @@ public: QString interfaceName() const; QString pathName() const; - bool isValidForApplication(AbstractApplication *app) const; + bool isValidForApplication(Application *app) const; QObject *serviceObject() const; void setServiceObject(QObject *serviceObject); #if defined(QT_DBUS_LIB) - bool dbusRegister(AbstractApplication *app, QDBusConnection connection, const QString &debugPathPrefix = QString()); + bool dbusRegister(Application *app, QDBusConnection connection, const QString &debugPathPrefix = QString()); bool dbusUnregister(QDBusConnection connection); #endif diff --git a/src/manager-lib/applicationipcinterface_p.h b/src/manager-lib/applicationipcinterface_p.h index e4828adb..9ea30121 100644 --- a/src/manager-lib/applicationipcinterface_p.h +++ b/src/manager-lib/applicationipcinterface_p.h @@ -54,7 +54,7 @@ QT_BEGIN_NAMESPACE_AM -class AbstractApplication; +class Application; class IpcProxySignalRelay; class IpcProxyObject // clazy:exclude=missing-qobject-macro @@ -75,10 +75,10 @@ public: QString interfaceName() const; QStringList connectionNames() const; - bool isValidForApplication(AbstractApplication *app) const; + bool isValidForApplication(Application *app) const; #if defined(QT_DBUS_LIB) - bool dbusRegister(AbstractApplication *app, QDBusConnection connection, const QString &debugPathPrefix = QString()); + bool dbusRegister(Application *app, QDBusConnection connection, const QString &debugPathPrefix = QString()); bool dbusUnregister(QDBusConnection connection); QString introspect(const QString &path) const override; diff --git a/src/manager-lib/applicationmanager.cpp b/src/manager-lib/applicationmanager.cpp index 734198bc..eaa8e205 100644 --- a/src/manager-lib/applicationmanager.cpp +++ b/src/manager-lib/applicationmanager.cpp @@ -58,6 +58,7 @@ #include "global.h" #include "applicationinfo.h" +#include "installationreport.h" #include "logging.h" #include "exception.h" #include "applicationmanager.h" @@ -386,9 +387,9 @@ ApplicationManager *ApplicationManager::createInstance(bool singleProcess) qmlRegisterSingletonType<ApplicationManager>("QtApplicationManager.SystemUI", 2, 0, "ApplicationManager", &ApplicationManager::instanceForQml); qmlRegisterType<ApplicationModel>("QtApplicationManager.SystemUI", 2, 0, "ApplicationModel"); - qmlRegisterUncreatableType<AbstractApplication>("QtApplicationManager.SystemUI", 2, 0, "ApplicationObject", - qSL("Cannot create objects of type ApplicationObject")); - qRegisterMetaType<AbstractApplication*>("AbstractApplication*"); + qmlRegisterUncreatableType<Application>("QtApplicationManager.SystemUI", 2, 0, "ApplicationObject", + qSL("Cannot create objects of type ApplicationObject")); + qRegisterMetaType<Application*>("Application*"); qmlRegisterUncreatableType<AbstractRuntime>("QtApplicationManager.SystemUI", 2, 0, "Runtime", qSL("Cannot create objects of type Runtime")); qRegisterMetaType<AbstractRuntime*>("AbstractRuntime*"); @@ -497,27 +498,27 @@ void ApplicationManager::setWindowManagerCompositorReady(bool ready) } } -QVector<AbstractApplication *> ApplicationManager::applications() const +QVector<Application *> ApplicationManager::applications() const { return d->apps; } -AbstractApplication *ApplicationManager::fromId(const QString &id) const +Application *ApplicationManager::fromId(const QString &id) const { - for (AbstractApplication *app : d->apps) { + for (Application *app : d->apps) { if (app->id() == id) return app; } return nullptr; } -AbstractApplication *ApplicationManager::fromProcessId(qint64 pid) const +Application *ApplicationManager::fromProcessId(qint64 pid) const { // pid could be an indirect child (e.g. when started via gdbserver) qint64 appmanPid = QCoreApplication::applicationPid(); while ((pid > 1) && (pid != appmanPid)) { - for (AbstractApplication *app : d->apps) { + for (Application *app : d->apps) { if (app->currentRuntime() && (app->currentRuntime()->applicationProcessId() == pid)) return app; } @@ -526,26 +527,23 @@ AbstractApplication *ApplicationManager::fromProcessId(qint64 pid) const return nullptr; } -AbstractApplication *ApplicationManager::fromSecurityToken(const QByteArray &securityToken) const +Application *ApplicationManager::fromSecurityToken(const QByteArray &securityToken) const { if (securityToken.size() != AbstractRuntime::SecurityTokenSize) return nullptr; - for (AbstractApplication *app : d->apps) { + for (Application *app : d->apps) { if (app->currentRuntime() && app->currentRuntime()->securityToken() == securityToken) return app; } return nullptr; } -QVector<AbstractApplication *> ApplicationManager::schemeHandlers(const QString &scheme) const +QVector<Application *> ApplicationManager::schemeHandlers(const QString &scheme) const { - QVector<AbstractApplication *> handlers; - - for (AbstractApplication *app : d->apps) { - if (app->isAlias()) - continue; + QVector<Application *> handlers; + for (Application *app : d->apps) { const auto mimeTypes = app->supportedMimeTypes(); for (const QString &mime : mimeTypes) { int pos = mime.indexOf(QLatin1Char('/')); @@ -560,14 +558,11 @@ QVector<AbstractApplication *> ApplicationManager::schemeHandlers(const QString return handlers; } -QVector<AbstractApplication *> ApplicationManager::mimeTypeHandlers(const QString &mimeType) const +QVector<Application *> ApplicationManager::mimeTypeHandlers(const QString &mimeType) const { - QVector<AbstractApplication *> handlers; - - for (AbstractApplication *app : d->apps) { - if (app->isAlias()) - continue; + QVector<Application *> handlers; + for (Application *app : d->apps) { if (app->supportedMimeTypes().contains(mimeType)) handlers << app; } @@ -580,7 +575,7 @@ void ApplicationManager::registerMimeTypes() QSet<QString> schemes; schemes << qSL("file") << qSL("http") << qSL("https"); - for (AbstractApplication *app : qAsConst(d->apps)) { + for (Application *app : qAsConst(d->apps)) { if (app->isAlias()) continue; @@ -613,14 +608,12 @@ bool ApplicationManager::startApplicationInternal(const QString &appId, const QS { if (d->shuttingDown) throw Exception("Cannot start applications during shutdown"); - AbstractApplication *app = fromId(appId); + Application *app = fromId(appId); if (!app) throw Exception("Cannot start application: id '%1' is not known").arg(appId); if (app->isBlocked()) throw Exception("Application %1 is blocked - cannot start").arg( app->id()); - Application* realApp = app->nonAliased(); - AbstractRuntime *runtime = app->currentRuntime(); auto runtimeManager = runtime ? runtime->manager() : RuntimeFactory::instance()->manager(app->runtimeName()); if (!runtimeManager) @@ -668,7 +661,6 @@ bool ApplicationManager::startApplicationInternal(const QString &appId, const QS throw Exception("Application %1 is already running - cannot start with debug-wrapper: %2") .arg(app->id(), debugWrapperSpecification); } - if (!documentUrl.isNull()) runtime->openDocument(documentUrl, documentMimeType); else if (!app->documentUrl().isNull()) @@ -732,7 +724,7 @@ bool ApplicationManager::startApplicationInternal(const QString &appId, const QS cannotUseQuickLaunch = "standard I/O is redirected"; else if (!app->runtimeParameters().value(qSL("environmentVariables")).toMap().isEmpty()) cannotUseQuickLaunch = "the app requests customs environment variables"; - else if (app->nonAliasedInfo()->openGLConfiguration() != runtimeManager->systemOpenGLConfiguration()) + else if (app->info()->openGLConfiguration() != runtimeManager->systemOpenGLConfiguration()) cannotUseQuickLaunch = "the app requests a custom OpenGL configuration"; if (cannotUseQuickLaunch) { @@ -741,12 +733,12 @@ bool ApplicationManager::startApplicationInternal(const QString &appId, const QS } else { // check quicklaunch pool QPair<AbstractContainer *, AbstractRuntime *> quickLaunch = - QuickLauncher::instance()->take(containerId, app->nonAliasedInfo()->runtimeName()); + QuickLauncher::instance()->take(containerId, app->info()->runtimeName()); container = quickLaunch.first; runtime = quickLaunch.second; qCDebug(LogSystem) << "Found a quick-launch entry for container" << containerId - << "and runtime" << app->nonAliasedInfo()->runtimeName() << "->" << container << runtime; + << "and runtime" << app->info()->runtimeName() << "->" << container << runtime; if (!container && runtime) { runtime->deleteLater(); @@ -769,7 +761,7 @@ bool ApplicationManager::startApplicationInternal(const QString &appId, const QS attachRuntime = true; } if (!runtime) - runtime = RuntimeFactory::instance()->create(container, realApp); + runtime = RuntimeFactory::instance()->create(container, app); if (runtime) emit internalSignals.newRuntimeCreated(runtime); @@ -781,27 +773,9 @@ bool ApplicationManager::startApplicationInternal(const QString &appId, const QS } connect(runtime, &AbstractRuntime::stateChanged, this, [this, app](Am::RunState newRuntimeState) { - QVector<AbstractApplication *> apps; - //Always emit the actual starting app/alias first - apps.append(app); - - //Add the original app and all aliases - AbstractApplication *nonAliasedApp = app->nonAliased(); - - if (!apps.contains(nonAliasedApp)) - apps.append(nonAliasedApp); - - for (AbstractApplication *alias : qAsConst(d->apps)) { - if (!apps.contains(alias) && alias->isAlias() && alias->nonAliased() == nonAliasedApp) - apps.append(alias); - } - - static_cast<Application*>(nonAliasedApp)->setRunState(newRuntimeState); - - for (AbstractApplication *app : qAsConst(apps)) { - emit applicationRunStateChanged(app->id(), newRuntimeState); - emitDataChanged(app, QVector<int> { IsRunning, IsStartingUp, IsShuttingDown }); - } + app->setRunState(newRuntimeState); + emit applicationRunStateChanged(app->id(), newRuntimeState); + emitDataChanged(app, QVector<int> { IsRunning, IsStartingUp, IsShuttingDown }); }); if (!documentUrl.isNull()) @@ -826,11 +800,11 @@ bool ApplicationManager::startApplicationInternal(const QString &appId, const QS // Using a state-machine would be one option, but then we would need that state-machine // object plus the per-app state. Relying on 2 lambdas is the easier choice for now. - auto doStartInContainer = [realApp, attachRuntime, runtime]() -> bool { - bool successfullyStarted = attachRuntime ? runtime->attachApplicationToQuickLauncher(realApp) + auto doStartInContainer = [app, attachRuntime, runtime]() -> bool { + bool successfullyStarted = attachRuntime ? runtime->attachApplicationToQuickLauncher(app) : runtime->start(); if (!successfullyStarted) - runtime->deleteLater(); // ~Runtime() will clean realApp->m_runtime + runtime->deleteLater(); // ~Runtime() will clean app->m_runtime return successfullyStarted; }; @@ -866,7 +840,7 @@ bool ApplicationManager::startApplicationInternal(const QString &appId, const QS } } -void ApplicationManager::stopApplicationInternal(AbstractApplication *app, bool forceKill) +void ApplicationManager::stopApplicationInternal(Application *app, bool forceKill) { if (!app) return; @@ -950,12 +924,10 @@ void ApplicationManager::stopApplication(const QString &id, bool forceKill) */ void ApplicationManager::stopAllApplications(bool forceKill) { - for (AbstractApplication *app : qAsConst(d->apps)) { - if (!app->isAlias()) { - AbstractRuntime *rt = app->currentRuntime(); - if (rt) - rt->stop(forceKill); - } + for (Application *app : qAsConst(d->apps)) { + AbstractRuntime *rt = app->currentRuntime(); + if (rt) + rt->stop(forceKill); } } @@ -1000,6 +972,8 @@ void ApplicationManager::stopAllApplications(bool forceKill) */ bool ApplicationManager::openUrl(const QString &urlStr) { + //TODO: relay to a well-known Intent call + // QDesktopServices::openUrl has a special behavior when called recursively, which makes sense // on the desktop, but is completely counter-productive for the AM. static bool recursionGuard = false; @@ -1011,28 +985,13 @@ bool ApplicationManager::openUrl(const QString &urlStr) QUrl url(urlStr); QString mimeTypeName; - QVector<AbstractApplication *> apps; + QVector<Application *> apps; if (url.isValid()) { QString scheme = url.scheme(); - if (scheme != qL1S("file")) { + if (scheme != qL1S("file")) apps = schemeHandlers(scheme); - for (auto it = apps.begin(); it != apps.end(); ++it) { - AbstractApplication *&app = *it; - - // try to find a better matching alias, if available - for (AbstractApplication *alias : d->apps) { - if (alias->isAlias() && alias->nonAliased() == app) { - if (url.toString(QUrl::PrettyDecoded) == alias->documentUrl()) { - app = alias; - break; - } - } - } - } - } - if (apps.isEmpty()) { QMimeDatabase mdb; QMimeType mt = mdb.mimeTypeForUrl(url); @@ -1054,9 +1013,9 @@ bool ApplicationManager::openUrl(const QString &urlStr) } else { ApplicationManagerPrivate::OpenUrlRequest req { QUuid::createUuid().toString(), - urlStr, - mimeTypeName, - QStringList() + urlStr, + mimeTypeName, + QStringList() }; for (const auto &app : qAsConst(apps)) req.possibleAppIds << app->id(); @@ -1149,7 +1108,7 @@ void ApplicationManager::rejectOpenUrlRequest(const QString &requestId) */ QStringList ApplicationManager::capabilities(const QString &id) const { - AbstractApplication *app = fromId(id); + Application *app = fromId(id); return app ? app->capabilities() : QStringList(); } @@ -1163,13 +1122,13 @@ QStringList ApplicationManager::capabilities(const QString &id) const */ QString ApplicationManager::identifyApplication(qint64 pid) const { - AbstractApplication *app = fromProcessId(pid); + Application *app = fromProcessId(pid); return app ? app->id() : QString(); } bool ApplicationManager::blockApplication(const QString &id) { - AbstractApplication *app = fromId(id); + Application *app = fromId(id); if (!app) return false; if (!app->block()) @@ -1182,7 +1141,7 @@ bool ApplicationManager::blockApplication(const QString &id) bool ApplicationManager::unblockApplication(const QString &id) { - AbstractApplication *app = fromId(id); + Application *app = fromId(id); if (!app) return false; if (!app->unblock()) @@ -1191,217 +1150,6 @@ bool ApplicationManager::unblockApplication(const QString &id) return true; } -bool ApplicationManager::startingApplicationInstallation(ApplicationInfo *info) -{ - // ownership of info is transferred to ApplicationManager - QScopedPointer<ApplicationInfo> newInfo(info); - - if (!newInfo || newInfo->id().isEmpty()) - return false; - AbstractApplication *absApp = fromId(newInfo->id()); - if (!RuntimeFactory::instance()->manager(newInfo->runtimeName())) - return false; - - if (absApp) { // update - Q_ASSERT(!absApp->isAlias()); - Application *app = static_cast<Application*>(absApp); - - if (!blockApplication(app->id())) - return false; - - if (app->isBuiltIn()) { - // overlay the existing base info - // we will rollback to the base one if this update is removed. - app->setUpdatedInfo(newInfo.take()); - } else { - // overwrite the existing base info - // we're not keeping track of the original. so removing the updated base version removes the - // application entirely. - app->setBaseInfo(newInfo.take()); - } - app->setState(Application::BeingUpdated); - app->setProgress(0); - emitDataChanged(app); - } else { // installation - Application *app = new Application(newInfo.take(), Application::BeingInstalled); - - app->block(); - - beginInsertRows(QModelIndex(), d->apps.count(), d->apps.count()); - addApplication(app); - endInsertRows(); - - emitDataChanged(app); - - emit applicationAdded(app->id()); - } - return true; -} - -bool ApplicationManager::startingApplicationRemoval(const QString &id) -{ - AbstractApplication *absApp = fromId(id); - if (!absApp) - return false; - - Q_ASSERT(!absApp->isAlias()); - - Application *app = static_cast<Application*>(absApp); - if (app->isBlocked() || (app->state() != Application::Installed)) - return false; - - if (app->isBuiltIn() && !app->updatedInfo()) - return false; - - if (!blockApplication(id)) - return false; - - if (app->updatedInfo()) - app->setState(Application::BeingDowngraded); - else - app->setState(Application::BeingRemoved); - - app->setProgress(0); - emitDataChanged(app, QVector<int> { IsUpdating }); - return true; -} - -void ApplicationManager::progressingApplicationInstall(const QString &id, qreal progress) -{ - AbstractApplication *absApp = fromId(id); - if (!absApp) - return; - - Q_ASSERT(!absApp->isAlias()); - Application *app = static_cast<Application*>(absApp); - - if (app->state() == Application::Installed) - return; - app->setProgress(progress); - // Icon will be in a "+" suffixed directory during installation. So notify about a change on its - // location as well. - emitDataChanged(app, QVector<int> { Icon, UpdateProgress }); -} - -bool ApplicationManager::finishedApplicationInstall(const QString &id) -{ - AbstractApplication *absApp = fromId(id); - if (!absApp) - return false; - - Q_ASSERT(!absApp->isAlias()); - Application *app = static_cast<Application*>(absApp); - - switch (app->state()) { - case Application::Installed: - return false; - - case Application::BeingInstalled: - case Application::BeingUpdated: { - // The Application object has been updated right at the start of the installation/update. - // Now's the time to update the InstallationReport that was written by the installer. - QFile irfile(QDir(app->nonAliasedInfo()->manifestDir()).absoluteFilePath(qSL("installation-report.yaml"))); - QScopedPointer<InstallationReport> ir(new InstallationReport(app->id())); - if (!irfile.open(QFile::ReadOnly) || !ir->deserialize(&irfile)) { - qCCritical(LogInstaller) << "Could not read the new installation-report for application" - << app->id() << "at" << irfile.fileName(); - return false; - } - app->nonAliasedInfo()->setInstallationReport(ir.take()); - registerMimeTypes(); - app->setState(Application::Installed); - app->setProgress(0); - - emitDataChanged(app); - - unblockApplication(id); - emit app->bulkChange(); // not ideal, but icon and codeDir have changed - break; - } - case Application::BeingDowngraded: - app->setUpdatedInfo(nullptr); - app->setState(Application::Installed); - registerMimeTypes(); - break; - case Application::BeingRemoved: { - int row = d->apps.indexOf(app); - if (row >= 0) { - emit applicationAboutToBeRemoved(app->id()); - beginRemoveRows(QModelIndex(), row, row); - d->apps.removeAt(row); - endRemoveRows(); - } - delete app; - registerMimeTypes(); - break; - } - } - - emit internalSignals.applicationsChanged(); - - return true; -} - -bool ApplicationManager::canceledApplicationInstall(const QString &id) -{ - AbstractApplication *absApp = fromId(id); - if (!absApp) - return false; - - Q_ASSERT(!absApp->isAlias()); - Application *app = static_cast<Application*>(absApp); - - switch (app->state()) { - case Application::Installed: - return false; - - case Application::BeingInstalled: { - int row = d->apps.indexOf(app); - if (row >= 0) { - emit applicationAboutToBeRemoved(app->id()); - beginRemoveRows(QModelIndex(), row, row); - d->apps.removeAt(row); - endRemoveRows(); - } - delete app; - break; - } - case Application::BeingUpdated: - case Application::BeingDowngraded: - case Application::BeingRemoved: - app->setState(Application::Installed); - app->setProgress(0); - emitDataChanged(app, QVector<int> { IsUpdating }); - - unblockApplication(id); - break; - } - return true; -} - -void ApplicationManager::enableSingleAppMode() -{ - QMetaObject::invokeMethod(this, &ApplicationManager::startSingleAppAndQuitWhenStopped, Qt::QueuedConnection); -} - -void ApplicationManager::startSingleAppAndQuitWhenStopped() -{ - Q_ASSERT(d->apps.count() == 1); - - AbstractApplication *app = d->apps[0]; - - if (!startApplication(app->id())) { - QMetaObject::invokeMethod(qApp, "shutDown", Qt::DirectConnection, Q_ARG(int, 1)); - } else { - connect(this, &ApplicationManager::applicationRunStateChanged, [app](const QString &id, Am::RunState runState) { - if ((id == app->id()) && (runState == Am::NotRunning)) { - QMetaObject::invokeMethod(qApp, "shutDown", Qt::DirectConnection, - Q_ARG(int, app->lastExitCode())); - } - }); - } -} - void ApplicationManager::shutDown() { d->shuttingDown = true; @@ -1409,7 +1157,7 @@ void ApplicationManager::shutDown() auto shutdownHelper = [this]() { bool activeRuntime = false; - for (AbstractApplication *app : qAsConst(d->apps)) { + for (Application *app : qAsConst(d->apps)) { AbstractRuntime *rt = app->currentRuntime(); if (rt) { activeRuntime = true; @@ -1420,7 +1168,7 @@ void ApplicationManager::shutDown() emit shutDownFinished(); }; - for (AbstractApplication *app : qAsConst(d->apps)) { + for (Application *app : qAsConst(d->apps)) { AbstractRuntime *rt = app->currentRuntime(); if (rt) { connect(rt, &AbstractRuntime::destroyed, @@ -1440,7 +1188,7 @@ void ApplicationManager::openUrlRelay(const QUrl &url) openUrl(url.toString()); } -void ApplicationManager::emitDataChanged(AbstractApplication *app, const QVector<int> &roles) +void ApplicationManager::emitDataChanged(Application *app, const QVector<int> &roles) { int row = d->apps.indexOf(app); if (row >= 0) { @@ -1456,9 +1204,9 @@ void ApplicationManager::emitDataChanged(AbstractApplication *app, const QVector } } -void ApplicationManager::emitActivated(AbstractApplication *app) +void ApplicationManager::emitActivated(Application *app) { - emit applicationWasActivated(app->isAlias() ? app->nonAliased()->id() : app->id(), app->id()); + emit applicationWasActivated(app->id(), app->id()); emit app->activated(); } @@ -1476,29 +1224,15 @@ QVariant ApplicationManager::data(const QModelIndex &index, int role) const if (index.parent().isValid() || !index.isValid()) return QVariant(); - AbstractApplication *app = d->apps.at(index.row()); + Application *app = d->apps.at(index.row()); switch (role) { case Id: return app->id(); - case Name: { - QString name; - if (!app->info()->names().isEmpty()) { - name = app->info()->name(d->currentLocale); - if (name.isEmpty()) - name = app->info()->name(qSL("en")); - if (name.isEmpty()) - name = app->info()->name(qSL("en_US")); - if (name.isEmpty()) - name = *app->info()->names().constBegin(); - } else { - name = app->id(); - } - return name; - } + case Name: + return app->name(); case Icon: return app->icon(); - case IsRunning: return app->currentRuntime() ? (app->currentRuntime()->state() == Am::Running) : false; case IsStartingUp: @@ -1513,9 +1247,8 @@ QVariant ApplicationManager::data(const QModelIndex &index, int role) const return app->progress(); case IsRemovable: return !app->isBuiltIn(); - case CodeFilePath: - return app->nonAliasedInfo()->absoluteCodeFilePath(); + return app->info()->absoluteCodeFilePath(); case RuntimeName: return app->runtimeName(); case RuntimeParameters: @@ -1582,7 +1315,7 @@ QVariantMap ApplicationManager::get(int index) const signals or the applicationAboutToBeRemoved signal to get notified if the object is about to be deleted on the C++ side. */ -AbstractApplication *ApplicationManager::application(int index) const +Application *ApplicationManager::application(int index) const { if (index < 0 || index >= count()) { qCWarning(LogSystem) << "ApplicationManager::application(index): invalid index:" << index; @@ -1602,7 +1335,7 @@ AbstractApplication *ApplicationManager::application(int index) const signals or the applicationAboutToBeRemoved signal to get notified if the object is about to be deleted on the C++ side. */ -AbstractApplication *ApplicationManager::application(const QString &id) const +Application *ApplicationManager::application(const QString &id) const { auto index = indexOfApplication(id); return (index < 0) ? nullptr : application(index); @@ -1659,7 +1392,7 @@ Am::RunState ApplicationManager::applicationRunState(const QString &id) const return (index < 0) ? Am::NotRunning : d->apps.at(index)->runState(); } -void ApplicationManager::setApplications(const QVector<AbstractApplication *> &apps) +void ApplicationManager::setApplications(const QVector<Application *> &apps) { Q_ASSERT(d->apps.count() == 0); for (auto app : apps) @@ -1667,7 +1400,7 @@ void ApplicationManager::setApplications(const QVector<AbstractApplication *> &a registerMimeTypes(); } -void ApplicationManager::addApplication(AbstractApplication *app) +void ApplicationManager::addApplication(Application *app) { QQmlEngine::setObjectOwnership(app, QQmlEngine::CppOwnership); diff --git a/src/manager-lib/applicationmanager.h b/src/manager-lib/applicationmanager.h index 60b133dd..3e98038c 100644 --- a/src/manager-lib/applicationmanager.h +++ b/src/manager-lib/applicationmanager.h @@ -101,21 +101,21 @@ public: // Set the initial application list // To be used only during startup (ie, before exposing ApplicationManager to QML) as // no model update signals are emitted. - void setApplications(const QVector<AbstractApplication *> &apps); + void setApplications(const QVector<Application *> &apps); - QVector<AbstractApplication *> applications() const; + QVector<Application *> applications() const; - AbstractApplication *fromId(const QString &id) const; - AbstractApplication *fromProcessId(qint64 pid) const; - AbstractApplication *fromSecurityToken(const QByteArray &securityToken) const; - QVector<AbstractApplication *> schemeHandlers(const QString &scheme) const; - QVector<AbstractApplication *> mimeTypeHandlers(const QString &mimeType) const; + Application *fromId(const QString &id) const; + Application *fromProcessId(qint64 pid) const; + Application *fromSecurityToken(const QByteArray &securityToken) const; + QVector<Application *> schemeHandlers(const QString &scheme) const; + QVector<Application *> mimeTypeHandlers(const QString &mimeType) const; bool startApplicationInternal(const QString &appId, const QString &documentUrl = QString(), const QString &documentMimeType = QString(), const QString &debugWrapperSpecification = QString(), const QVector<int> &stdioRedirections = QVector<int>()) Q_DECL_NOEXCEPT_EXPR(false); - void stopApplicationInternal(AbstractApplication *app, bool forceKill = false); + void stopApplicationInternal(Application *app, bool forceKill = false); // only use these two functions for development! bool securityChecksEnabled() const; @@ -137,8 +137,8 @@ public: int count() const; Q_INVOKABLE QVariantMap get(int index) const; - Q_INVOKABLE AbstractApplication *application(int index) const; - Q_INVOKABLE AbstractApplication *application(const QString &id) const; + Q_INVOKABLE Application *application(int index) const; + Q_INVOKABLE Application *application(const QString &id) const; Q_INVOKABLE int indexOfApplication(const QString &id) const; Q_INVOKABLE void acknowledgeOpenUrlRequest(const QString &requestId, const QString &appId); @@ -158,8 +158,6 @@ public: ApplicationManagerInternalSignals internalSignals; - void enableSingleAppMode(); - public slots: void shutDown(); @@ -183,29 +181,15 @@ signals: void windowManagerCompositorReadyChanged(bool ready); private slots: - void startSingleAppAndQuitWhenStopped(); void openUrlRelay(const QUrl &url); - void addApplication(AbstractApplication *app); + void addApplication(Application *app); - // Interface for the installer - //TODO: Find something nicer than private slots with 3 friend classes. - // This is hard though, since the senders live in different threads and - // need to use BlockingQueuedConnections bool blockApplication(const QString &id); bool unblockApplication(const QString &id); - bool startingApplicationInstallation(QT_PREPEND_NAMESPACE_AM(ApplicationInfo*) installApp); - bool startingApplicationRemoval(const QString &id); - void progressingApplicationInstall(const QString &id, qreal progress); - bool finishedApplicationInstall(const QString &id); - bool canceledApplicationInstall(const QString &id); - - friend class ApplicationInstaller; - friend class InstallationTask; - friend class DeinstallationTask; private: - void emitDataChanged(AbstractApplication *app, const QVector<int> &roles = QVector<int>()); - void emitActivated(AbstractApplication *app); + void emitDataChanged(Application *app, const QVector<int> &roles = QVector<int>()); + void emitActivated(Application *app); void registerMimeTypes(); ApplicationManager(bool singleProcess, QObject *parent = nullptr); diff --git a/src/manager-lib/applicationmanager_p.h b/src/manager-lib/applicationmanager_p.h index c9d1ad6b..5fc052c8 100644 --- a/src/manager-lib/applicationmanager_p.h +++ b/src/manager-lib/applicationmanager_p.h @@ -60,7 +60,8 @@ public: bool windowManagerCompositorReady = false; QVariantMap systemProperties; - QVector<AbstractApplication *> apps; + QVector<PackageInfo> packages; + QVector<Application *> apps; QString currentLocale; QHash<int, QByteArray> roleNames; diff --git a/src/manager-lib/containerfactory.cpp b/src/manager-lib/containerfactory.cpp index fbeb2e49..69564e7c 100644 --- a/src/manager-lib/containerfactory.cpp +++ b/src/manager-lib/containerfactory.cpp @@ -83,7 +83,7 @@ AbstractContainerManager *ContainerFactory::manager(const QString &id) return m_containers.value(id); } -AbstractContainer *ContainerFactory::create(const QString &id, AbstractApplication *app, +AbstractContainer *ContainerFactory::create(const QString &id, Application *app, const QVector<int> &stdioRedirections, const QMap<QString, QString> &debugWrapperEnvironment, const QStringList &debugWrapperCommand) diff --git a/src/manager-lib/containerfactory.h b/src/manager-lib/containerfactory.h index 020100d8..39d1f0e1 100644 --- a/src/manager-lib/containerfactory.h +++ b/src/manager-lib/containerfactory.h @@ -49,7 +49,7 @@ QT_BEGIN_NAMESPACE_AM -class AbstractApplication; +class Application; class AbstractContainer; class AbstractContainerManager; @@ -64,7 +64,7 @@ public: QStringList containerIds() const; AbstractContainerManager *manager(const QString &id); - AbstractContainer *create(const QString &id, AbstractApplication *app, + AbstractContainer *create(const QString &id, Application *app, const QVector<int> &stdioRedirections = QVector<int>(), const QMap<QString, QString> &debugWrapperEnvironment = QMap<QString, QString>(), const QStringList &debugWrapperCommand = QStringList()); diff --git a/src/manager-lib/intentaminterface.cpp b/src/manager-lib/intentaminterface.cpp index 713b2039..be94b0e7 100644 --- a/src/manager-lib/intentaminterface.cpp +++ b/src/manager-lib/intentaminterface.cpp @@ -68,6 +68,7 @@ #include "qmlinprocessruntime.h" #include "application.h" #include "applicationmanager.h" +#include "applicationinfo.h" QT_BEGIN_NAMESPACE_AM @@ -115,75 +116,6 @@ IntentServer *IntentAMImplementation::createIntentServerAndClientInstance(const return intentServer; } -void IntentAMImplementation::addApplicationIntents(AbstractApplication *app, IntentServer *intentServer) -{ - if (app->isAlias()) - return; - - QSet<QString> intentIds; - const auto intents = app->nonAliasedInfo()->intents(); - - if (!intents.isEmpty()) - intentServer->addApplication(app->id()); - - for (const auto &intent : intents) { - /* example: - id: io.qt.shareImage - handledBy: main - visibility: public*|private - requiredCapabilities: [ a, b ] - parameterMatch: - mimeType: "^image/.*\.png$" - */ - const QVariantMap map = intent.toMap(); - const QString id = map[qSL("id")].toString(); - Intent::Visibility visibility = Intent::Public; - const QString visibilityStr = map[qSL("visibility")].toString(); - QString handledBy = map[qSL("handledBy")].toString(); - const QStringList capabilities = map[qSL("requiredCapabilities")].toStringList(); - const QVariantMap parameterMatch = map[qSL("parameterMatch")].toMap(); // do we really need that? - - if (id.isEmpty()) - throw Exception(Error::Intents, "intents need to have an id (app %1)").arg(app->id()); - if (intentIds.contains(id)) - throw Exception(Error::Intents, "found two intent handlers for %2 (app %1)").arg(app->id()).arg(id); - intentIds << id; - - if (visibilityStr == qL1S("private")) - visibility = Intent::Private; - else if (!visibilityStr.isEmpty() && (visibilityStr != qL1S("public"))) { - throw Exception(Error::Intents, "intent visibilty %3 is invalid (intent %2, app %1)") - .arg(app->id()).arg(id).arg(visibilityStr); - } - - if (handledBy == qL1S("main")) - handledBy.clear(); - // we do not support bg services yet - if (!handledBy.isEmpty()) { - throw Exception(Error::Intents, "service background handlers for intent are not supported yet (intent %2, app %1)") - .arg(app->id()).arg(id).arg(visibilityStr); - } - - qCDebug(LogSystem).nospace().noquote() << " * " << id << " [app: " << app->id() << "]"; - - if (!intentServer->addIntent(id, app->id(), handledBy, capabilities, - visibility, parameterMatch)) { - throw Exception(Error::Intents, "could not add intent %2 for app %1").arg(app->id()).arg(id); - } - } -} - -void IntentAMImplementation::removeApplicationIntents(AbstractApplication *app, IntentServer *intentServer) -{ - if (app->isAlias()) - return; - auto intents = intentServer->filterByHandlingApplicationId(intentServer->all(), app->id()); - for (const auto &intent : intents) - intentServer->removeIntent(intent); - - intentServer->removeApplication(app->id()); -} - // ^^^ IntentAMImplementation ^^^ ////////////////////////////////////////////////////////////////////////// // vvv IntentServerAMImplementation vvv diff --git a/src/manager-lib/intentaminterface.h b/src/manager-lib/intentaminterface.h index c2db4a44..be4eda1e 100644 --- a/src/manager-lib/intentaminterface.h +++ b/src/manager-lib/intentaminterface.h @@ -60,13 +60,11 @@ class IntentInterfaceAdaptor; QT_BEGIN_NAMESPACE_AM class Application; -class AbstractApplication; +class PackageInfo; class IntentServerRequest; namespace IntentAMImplementation { IntentServer *createIntentServerAndClientInstance(const QMap<QString, int> &timeouts); -void addApplicationIntents(AbstractApplication *app, IntentServer *intentServer); -void removeApplicationIntents(AbstractApplication *app, IntentServer *intentServer); } // the server side diff --git a/src/manager-lib/manager-lib.pro b/src/manager-lib/manager-lib.pro index 170792bd..9ae1ee90 100644 --- a/src/manager-lib/manager-lib.pro +++ b/src/manager-lib/manager-lib.pro @@ -13,6 +13,7 @@ QT_FOR_PRIVATE *= \ appman_plugininterfaces-private \ appman_intent_server-private \ appman_intent_client-private \ + appman_installer-private \ appman_monitor-private \ CONFIG *= static internal_module @@ -41,7 +42,6 @@ HEADERS += \ application.h \ applicationmanager.h \ applicationmodel.h \ - applicationdatabase.h \ notificationmanager.h \ abstractcontainer.h \ containerfactory.h \ @@ -70,7 +70,6 @@ SOURCES += \ application.cpp \ applicationmanager.cpp \ applicationmodel.cpp \ - applicationdatabase.cpp \ notificationmanager.cpp \ abstractcontainer.cpp \ containerfactory.cpp \ diff --git a/src/manager-lib/nativeruntime.cpp b/src/manager-lib/nativeruntime.cpp index 3c1865b6..7fffb626 100644 --- a/src/manager-lib/nativeruntime.cpp +++ b/src/manager-lib/nativeruntime.cpp @@ -215,7 +215,7 @@ bool NativeRuntime::initialize() if (!m_app) return false; - m_container->setProgram(m_app->nonAliasedInfo()->absoluteCodeFilePath()); + m_container->setProgram(m_app->info()->absoluteCodeFilePath()); m_container->setBaseDirectory(m_app->codeDir()); return true; } @@ -271,7 +271,7 @@ bool NativeRuntime::start() QVariantMap openGLConfig; if (m_app) - openGLConfig = m_app->nonAliasedInfo()->openGLConfiguration(); + openGLConfig = m_app->info()->openGLConfiguration(); if (openGLConfig.isEmpty()) openGLConfig = manager()->systemOpenGLConfiguration(); if (!openGLConfig.isEmpty()) @@ -392,8 +392,10 @@ void NativeRuntime::stop(bool forceKill) void NativeRuntime::onProcessStarted() { - if (!m_startedViaLauncher && !application()->nonAliasedInfo()->supportsApplicationInterface()) + if (!m_startedViaLauncher + && !(application()->info()->supportsApplicationInterface() || manager()->supportsQuickLaunch())) { setState(Am::Running); + } } void NativeRuntime::onProcessError(Am::ProcessError error) @@ -467,7 +469,7 @@ bool NativeRuntime::startApplicationViaLauncher() return false; QString baseDir = m_container->mapHostPathToContainer(m_app->codeDir()); - QString pathInContainer = m_container->mapHostPathToContainer(m_app->nonAliasedInfo()->absoluteCodeFilePath()); + QString pathInContainer = m_container->mapHostPathToContainer(m_app->info()->absoluteCodeFilePath()); emit m_runtimeInterface->startApplication(baseDir, pathInContainer, m_document, m_mimeType, convertFromJSVariant(QVariant(m_app->info()->toVariantMap())).toMap(), diff --git a/src/manager-lib/notificationmanager.cpp b/src/manager-lib/notificationmanager.cpp index 26c804fc..68b86386 100644 --- a/src/manager-lib/notificationmanager.cpp +++ b/src/manager-lib/notificationmanager.cpp @@ -207,7 +207,7 @@ enum Roles struct NotificationData { uint id; - AbstractApplication *application; + Application *application; uint priority; QString summary; QString body; @@ -353,7 +353,7 @@ QVariant NotificationManager::data(const QModelIndex &index, int role) const case Icon: if (!n->iconUrl.isEmpty()) return n->iconUrl; - return n->application ? n->application->icon() : QString(); + return n->application ? n->application->info()->packageInfo()->icon() : QString(); case Image: return n->imageUrl; case ShowActionsAsIcons: @@ -580,7 +580,7 @@ uint NotificationManager::notifyHelper(const QString &app_name, uint id, bool re qCDebug(LogNotifications) << " -> adding new notification with id" << id; } - AbstractApplication *app = ApplicationManager::instance()->fromId(app_name); + Application *app = ApplicationManager::instance()->fromId(app_name); if (replaces && app != n->application) { // no hijacking allowed diff --git a/src/manager-lib/plugincontainer.cpp b/src/manager-lib/plugincontainer.cpp index 2150f8d4..c5e5696c 100644 --- a/src/manager-lib/plugincontainer.cpp +++ b/src/manager-lib/plugincontainer.cpp @@ -61,7 +61,7 @@ bool PluginContainerManager::supportsQuickLaunch() const return m_interface->supportsQuickLaunch(); } -AbstractContainer *PluginContainerManager::create(AbstractApplication *app, const QVector<int> &stdioRedirections, +AbstractContainer *PluginContainerManager::create(Application *app, const QVector<int> &stdioRedirections, const QMap<QString, QString> &debugWrapperEnvironment, const QStringList &debugWrapperCommand) { @@ -133,7 +133,7 @@ AbstractContainerProcess *PluginContainer::start(const QStringList &arguments, c return nullptr; } -PluginContainer::PluginContainer(AbstractContainerManager *manager, AbstractApplication *app, ContainerInterface *containerInterface) +PluginContainer::PluginContainer(AbstractContainerManager *manager, Application *app, ContainerInterface *containerInterface) : AbstractContainer(manager, app) , m_interface(containerInterface) , m_process(new PluginContainerProcess(this)) diff --git a/src/manager-lib/plugincontainer.h b/src/manager-lib/plugincontainer.h index acf250da..3dc1b613 100644 --- a/src/manager-lib/plugincontainer.h +++ b/src/manager-lib/plugincontainer.h @@ -56,7 +56,7 @@ public: static QString defaultIdentifier(); bool supportsQuickLaunch() const override; - AbstractContainer *create(AbstractApplication *app, const QVector<int> &stdioRedirections, + AbstractContainer *create(Application *app, const QVector<int> &stdioRedirections, const QMap<QString, QString> &debugWrapperEnvironment, const QStringList &debugWrapperCommand) override; @@ -108,7 +108,7 @@ public: const QVariantMap &amConfig) override; protected: - explicit PluginContainer(AbstractContainerManager *manager, AbstractApplication *app, ContainerInterface *containerInterface); + explicit PluginContainer(AbstractContainerManager *manager, Application *app, ContainerInterface *containerInterface); ContainerInterface *m_interface; PluginContainerProcess *m_process; bool m_startCalled = false; diff --git a/src/manager-lib/processcontainer.cpp b/src/manager-lib/processcontainer.cpp index 23113239..a9586e8f 100644 --- a/src/manager-lib/processcontainer.cpp +++ b/src/manager-lib/processcontainer.cpp @@ -183,7 +183,7 @@ void HostProcess::setStopBeforeExec(bool stopBeforeExec) } -ProcessContainer::ProcessContainer(ProcessContainerManager *manager, AbstractApplication *app, +ProcessContainer::ProcessContainer(ProcessContainerManager *manager, Application *app, const QVector<int> &stdioRedirections, const QMap<QString, QString> &debugWrapperEnvironment, const QStringList &debugWrapperCommand) @@ -323,7 +323,7 @@ bool ProcessContainerManager::supportsQuickLaunch() const return true; } -AbstractContainer *ProcessContainerManager::create(AbstractApplication *app, const QVector<int> &stdioRedirections, +AbstractContainer *ProcessContainerManager::create(Application *app, const QVector<int> &stdioRedirections, const QMap<QString, QString> &debugWrapperEnvironment, const QStringList &debugWrapperCommand) { diff --git a/src/manager-lib/processcontainer.h b/src/manager-lib/processcontainer.h index 65d11acb..a57689b2 100644 --- a/src/manager-lib/processcontainer.h +++ b/src/manager-lib/processcontainer.h @@ -60,7 +60,7 @@ public: static QString defaultIdentifier(); bool supportsQuickLaunch() const override; - AbstractContainer *create(AbstractApplication *app, const QVector<int> &stdioRedirections, + AbstractContainer *create(Application *app, const QVector<int> &stdioRedirections, const QMap<QString, QString> &debugWrapperEnvironment, const QStringList &debugWrapperCommand) override; }; @@ -100,7 +100,7 @@ class ProcessContainer : public AbstractContainer Q_OBJECT public: - explicit ProcessContainer(ProcessContainerManager *manager, AbstractApplication *app, + explicit ProcessContainer(ProcessContainerManager *manager, Application *app, const QVector<int> &stdioRedirections, const QMap<QString, QString> &debugWrapperEnvironment, const QStringList &debugWrapperCommand); diff --git a/src/manager-lib/processstatus.cpp b/src/manager-lib/processstatus.cpp index 8d6e88c4..f1d5dd35 100644 --- a/src/manager-lib/processstatus.cpp +++ b/src/manager-lib/processstatus.cpp @@ -190,7 +190,7 @@ void ProcessStatus::setApplicationId(const QString &appId) qmlWarning(this) << "Invalid application ID:" << appId; } else { m_application = ApplicationManager::instance()->application(appIndex); - connect(m_application, &AbstractApplication::runStateChanged, this, &ProcessStatus::onRunStateChanged); + connect(m_application, &Application::runStateChanged, this, &ProcessStatus::onRunStateChanged); } } determinePid(); diff --git a/src/manager-lib/processstatus.h b/src/manager-lib/processstatus.h index b233aced..7d022ffe 100644 --- a/src/manager-lib/processstatus.h +++ b/src/manager-lib/processstatus.h @@ -105,7 +105,7 @@ private: QVariantMap m_memoryRss; QVariantMap m_memoryPss; - QPointer<AbstractApplication> m_application; + QPointer<Application> m_application; bool m_pendingUpdate = false; QScopedPointer<ProcessReader> m_reader; diff --git a/src/manager-lib/qmlinprocessapplicationinterface.cpp b/src/manager-lib/qmlinprocessapplicationinterface.cpp index a24651b4..7372e9f0 100644 --- a/src/manager-lib/qmlinprocessapplicationinterface.cpp +++ b/src/manager-lib/qmlinprocessapplicationinterface.cpp @@ -78,7 +78,7 @@ QVariantMap QmlInProcessApplicationInterface::name() const { QVariantMap names; if (m_runtime && m_runtime->application()) { - const QMap<QString, QString> &sm = m_runtime->application()->info()->names(); + const QMap<QString, QString> &sm = m_runtime->application()->packageInfo()->names(); for (auto it = sm.cbegin(); it != sm.cend(); ++it) names.insert(it.key(), it.value()); } @@ -88,7 +88,7 @@ QVariantMap QmlInProcessApplicationInterface::name() const QUrl QmlInProcessApplicationInterface::icon() const { if (m_runtime && m_runtime->application()) - return m_runtime->application()->icon(); + return m_runtime->application()->packageInfo()->icon(); return QUrl(); } diff --git a/src/manager-lib/qmlinprocessapplicationmanagerwindow.cpp b/src/manager-lib/qmlinprocessapplicationmanagerwindow.cpp index 8bf809aa..4edab126 100644 --- a/src/manager-lib/qmlinprocessapplicationmanagerwindow.cpp +++ b/src/manager-lib/qmlinprocessapplicationmanagerwindow.cpp @@ -182,8 +182,6 @@ void QmlInProcessApplicationManagerWindow::data_clear(QQmlListProperty<QObject> void QmlInProcessApplicationManagerWindow::componentComplete() { - qCDebug(LogSystem) << "QmlInProcessApplicationManagerWindow componentComplete() this:" << this; - if (!m_runtime) m_runtime = QmlInProcessRuntime::determineRuntime(this); diff --git a/src/manager-lib/qmlinprocessruntime.cpp b/src/manager-lib/qmlinprocessruntime.cpp index 3929a58f..ef5c1391 100644 --- a/src/manager-lib/qmlinprocessruntime.cpp +++ b/src/manager-lib/qmlinprocessruntime.cpp @@ -107,7 +107,7 @@ bool QmlInProcessRuntime::start() if (m_app->runtimeParameters().value(qSL("loadDummyData")).toBool()) { qCDebug(LogSystem) << "Loading dummy-data"; - loadQmlDummyDataFiles(m_inProcessQmlEngine, QFileInfo(m_app->nonAliasedInfo()->absoluteCodeFilePath()).path()); + loadQmlDummyDataFiles(m_inProcessQmlEngine, QFileInfo(m_app->info()->absoluteCodeFilePath()).path()); } const QStringList importPaths = variantToStringList(configuration().value(qSL("importPaths"))) @@ -120,10 +120,10 @@ bool QmlInProcessRuntime::start() qCDebug(LogSystem) << "Updated Qml import paths:" << m_inProcessQmlEngine->importPathList(); } - QQmlComponent *component = new QQmlComponent(m_inProcessQmlEngine, m_app->nonAliasedInfo()->absoluteCodeFilePath()); + QQmlComponent *component = new QQmlComponent(m_inProcessQmlEngine, m_app->info()->absoluteCodeFilePath()); if (!component->isReady()) { - qCDebug(LogSystem) << "qml-file (" << m_app->nonAliasedInfo()->absoluteCodeFilePath() << "): component not ready:\n" << component->errorString(); + qCDebug(LogSystem) << "qml-file (" << m_app->info()->absoluteCodeFilePath() << "): component not ready:\n" << component->errorString(); return false; } @@ -143,7 +143,7 @@ bool QmlInProcessRuntime::start() QMetaObject::invokeMethod(this, [component, appContext, obj, this]() { component->completeCreate(); if (!obj) { - qCCritical(LogSystem) << "could not load" << m_app->nonAliasedInfo()->absoluteCodeFilePath() << ": no root object"; + qCCritical(LogSystem) << "could not load" << m_app->info()->absoluteCodeFilePath() << ": no root object"; delete obj; delete appContext; delete m_applicationIf; |