summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRobert Griebl <robert.griebl@pelagicore.com>2017-05-23 11:21:27 +0200
committerDominik Holland <dominik.holland@pelagicore.com>2017-06-02 12:57:19 +0000
commit0fa1e466ee0043fccc76f5b71e1c4b80c28f1107 (patch)
treec1568f0192240d056d4c1b00f410454a809177b6
parent61d0099d3e46229963cfac348720817494cad37f (diff)
Refactor the src/manager dir into a sub-module
* the appman binary is now built from src/tools/appman * renamed all the main.cpp files to the names of their containing directories (avoids a lot of confusion) * all dependencies between the src modules and the tools are now handled centrally in src.pro * removed the Android deployment, since it doesn't work as-is on newer Android version anymore - we have to come up with a new plan on how to package up the AM plus a system-ui in one APK Change-Id: Ieb4536a7ab2a301488de09db61844da092620859 Reviewed-by: Dominik Holland <dominik.holland@pelagicore.com>
-rw-r--r--src/launchers/launchers.pro5
-rw-r--r--src/main-lib/.gitignore (renamed from src/manager/.gitignore)0
-rw-r--r--src/main-lib/configuration.cpp (renamed from src/manager/configuration.cpp)28
-rw-r--r--src/main-lib/configuration.h (renamed from src/manager/configuration.h)1
-rw-r--r--src/main-lib/defaultconfiguration.cpp (renamed from src/manager/defaultconfiguration.cpp)37
-rw-r--r--src/main-lib/defaultconfiguration.h (renamed from src/manager/defaultconfiguration.h)9
-rw-r--r--src/main-lib/main-lib.pro (renamed from src/manager/manager.pri)21
-rw-r--r--src/main-lib/main.cpp (renamed from src/manager/main.cpp)158
-rw-r--r--src/main-lib/main.h (renamed from src/manager/main.h)7
-rw-r--r--src/main-lib/qmllogger.cpp (renamed from src/manager/qmllogger.cpp)0
-rw-r--r--src/main-lib/qmllogger.h (renamed from src/manager/qmllogger.h)0
-rw-r--r--src/manager/android-deploy-dummy.qml60
-rw-r--r--src/manager/android/AndroidManifest.xml80
-rw-r--r--src/manager/android/build.gradle57
-rw-r--r--src/manager/android/res/drawable-hdpi/icon.pngbin2326 -> 0 bytes
-rw-r--r--src/manager/android/res/drawable-ldpi/icon.pngbin1166 -> 0 bytes
-rw-r--r--src/manager/android/res/drawable-mdpi/icon.pngbin1549 -> 0 bytes
-rw-r--r--src/manager/android/res/values/libs.xml25
-rw-r--r--src/manager/manager.pro25
-rw-r--r--src/manager/syms.txt23
-rw-r--r--src/src.pro110
-rw-r--r--src/tools/appman/appman.cpp141
-rw-r--r--src/tools/appman/appman.pro25
-rw-r--r--src/tools/controller/controller.cpp (renamed from src/tools/controller/main.cpp)0
-rw-r--r--src/tools/controller/controller.pro2
-rw-r--r--src/tools/dumpqmltypes/dumpqmltypes.cpp (renamed from src/tools/dumpqmltypes/main.cpp)0
-rw-r--r--src/tools/dumpqmltypes/dumpqmltypes.pro3
-rw-r--r--src/tools/packager/main.cpp233
-rw-r--r--src/tools/packager/packager.cpp411
-rw-r--r--src/tools/packager/packager.pro6
-rw-r--r--src/tools/packager/packagingjob.cpp310
-rw-r--r--src/tools/packager/packagingjob.h (renamed from src/tools/packager/packager.h)24
-rw-r--r--src/tools/testrunner/testrunner.pro5
-rw-r--r--src/tools/tools.pro18
-rw-r--r--src/window-lib/waylandcompositor.h6
-rw-r--r--sync.profile1
-rw-r--r--tests/packager-tool/packager-tool.pro2
-rw-r--r--tests/packager-tool/tst_packager-tool.cpp34
38 files changed, 858 insertions, 1009 deletions
diff --git a/src/launchers/launchers.pro b/src/launchers/launchers.pro
deleted file mode 100644
index c9b4c9e6..00000000
--- a/src/launchers/launchers.pro
+++ /dev/null
@@ -1,5 +0,0 @@
-TEMPLATE = subdirs
-
-load(am-config)
-
-multi-process:qtHaveModule(dbus):SUBDIRS = qml
diff --git a/src/manager/.gitignore b/src/main-lib/.gitignore
index 71cd379f..71cd379f 100644
--- a/src/manager/.gitignore
+++ b/src/main-lib/.gitignore
diff --git a/src/manager/configuration.cpp b/src/main-lib/configuration.cpp
index 0507d979..ba38e194 100644
--- a/src/manager/configuration.cpp
+++ b/src/main-lib/configuration.cpp
@@ -71,25 +71,34 @@ QT_BEGIN_NAMESPACE_AM
template<> bool Configuration::value(const char *clname, const QVector<const char *> &cfname) const
{
- return m_clp.isSet(qL1S(clname)) || findInConfigFile(cfname).toBool();
+ return (clname && m_clp.isSet(qL1S(clname))) || findInConfigFile(cfname).toBool();
}
template<> QString Configuration::value(const char *clname, const QVector<const char *> &cfname) const
{
- QString clval = m_clp.value(qL1S(clname));
+ QString clval;
+ if (clname)
+ clval = m_clp.value(qL1S(clname));
bool cffound;
QString cfval = findInConfigFile(cfname, &cffound).toString();
- return (m_clp.isSet(qL1S(clname)) || !cffound) ? clval : cfval;
+ return ((clname && m_clp.isSet(qL1S(clname))) || !cffound) ? clval : cfval;
}
template<> QStringList Configuration::value(const char *clname, const QVector<const char *> &cfname) const
{
- return m_clp.values(qL1S(clname)) + variantToStringList(findInConfigFile(cfname));
+ QStringList result;
+ if (clname)
+ result = m_clp.values(qL1S(clname));
+ if (!cfname.isEmpty())
+ result += variantToStringList(findInConfigFile(cfname));
+ return result;
}
template<> QVariant Configuration::value(const char *clname, const QVector<const char *> &cfname) const
{
- QString yaml = m_clp.value(qL1S(clname));
+ QString yaml;
+ if (clname)
+ yaml = m_clp.value(qL1S(clname));
if (!yaml.isEmpty()) {
auto docs = QtYaml::variantDocumentsFromYaml(yaml.toUtf8());
return docs.isEmpty() ? QVariant() : docs.constFirst();
@@ -158,6 +167,15 @@ Configuration::Configuration(const QString &defaultConfigFilePath, const QString
m_clp.addOption({ qSL("build-config"), qSL("dumps the build configuration and exits.") });
}
+QVariant Configuration::buildConfig() const
+{
+ QFile f(m_buildConfigFilePath);
+ if (f.open(QFile::ReadOnly))
+ return QtYaml::variantDocumentsFromYaml(f.readAll()).toList();
+ else
+ return QVariant();
+}
+
Configuration::~Configuration()
{
diff --git a/src/manager/configuration.h b/src/main-lib/configuration.h
index af937051..3cc633b6 100644
--- a/src/manager/configuration.h
+++ b/src/main-lib/configuration.h
@@ -54,6 +54,7 @@ class Configuration
public:
virtual ~Configuration();
virtual void parse();
+ QVariant buildConfig() const;
protected:
Configuration(const QString &defaultConfigFilePath, const QString &buildConfigFilePath);
diff --git a/src/manager/defaultconfiguration.cpp b/src/main-lib/defaultconfiguration.cpp
index 0beac426..cab61f0a 100644
--- a/src/manager/defaultconfiguration.cpp
+++ b/src/main-lib/defaultconfiguration.cpp
@@ -53,33 +53,28 @@
QT_BEGIN_NAMESPACE_AM
-DefaultConfiguration::DefaultConfiguration()
+DefaultConfiguration::DefaultConfiguration(const char *additionalDescription, bool onlyOnePositionalArgument)
: Configuration(qSL(AM_CONFIG_FILE), qSL(":/build-config.yaml"))
+ , m_onlyOnePositionalArgument(onlyOnePositionalArgument)
{
// using QStringLiteral for all strings here adds a few KB of ro-data, but will also improve
// startup times slightly: less allocations and copies. MSVC cannot cope with multi-line though
const char *description =
-#ifdef AM_TESTRUNNER
- "Pelagicore ApplicationManager QML Test Runner"
- "\n\n"
- "Additional testrunner commandline options can be set after the -- argument\n"
- "Use -- -help to show all available testrunner commandline options"
-#else
- "Pelagicore ApplicationManager"
-#endif
- "\n\n"
"In addition to the commandline options below, the following environment\n"
"variables can be set:\n\n"
" AM_STARTUP_TIMER if set to 1, a startup performance analysis will be printed\n"
" on the console. Anything other than 1 will be interpreted\n"
- " as the name of a file that is used instead of the console\n"
+ " as the name of a file that is used instead of the console.\n"
"\n"
" AM_FORCE_COLOR_OUTPUT can be set to 'on' to force color output to the console\n"
" and to 'off' to disable it. Any other value will result\n"
" in the default, auto-detection behavior.\n";
- m_clp.setApplicationDescription(description);
+ m_clp.setApplicationDescription(QCoreApplication::organizationName() + qL1C(' ')
+ + QCoreApplication::applicationName() + qSL("\n\n")
+ + (additionalDescription ? (qL1S(additionalDescription) + qSL("\n\n")) : QString())
+ + qL1S(description));
m_clp.addPositionalArgument(qSL("qml-file"), qSL("the main QML file."));
m_clp.addOption({ qSL("database"), qSL("application database."), qSL("file"), qSL("/opt/am/apps.db") });
@@ -122,12 +117,10 @@ void DefaultConfiguration::parse()
{
Configuration::parse();
-#ifndef AM_TESTRUNNER
- if (m_clp.positionalArguments().size() > 1) {
+ if (m_onlyOnePositionalArgument && (m_clp.positionalArguments().size() > 1)) {
showParserMessage(qL1S("Only one main qml file can be specified.\n"), ErrorMessage);
exit(1);
}
-#endif
}
QString DefaultConfiguration::mainQmlFile() const
@@ -146,7 +139,7 @@ QString DefaultConfiguration::database() const
bool DefaultConfiguration::recreateDatabase() const
{
- return m_clp.isSet("recreate-database");
+ return value<bool>("recreate-database");
}
QStringList DefaultConfiguration::builtinAppsManifestDirs() const
@@ -171,7 +164,7 @@ bool DefaultConfiguration::fullscreen() const
bool DefaultConfiguration::noFullscreen() const
{
- return m_clp.isSet("no-fullscreen");
+ return value<bool>("no-fullscreen");
}
QString DefaultConfiguration::windowIcon() const
@@ -298,16 +291,14 @@ QVariantMap DefaultConfiguration::runtimeConfigurations() const
return value<QVariant>(nullptr, { "runtimes" }).toMap();
}
-QVariantMap DefaultConfiguration::dbusPolicy(const QString &interfaceName) const
+QVariantMap DefaultConfiguration::dbusPolicy(const char *interfaceName) const
{
- QByteArray name = interfaceName.toLocal8Bit();
- return value<QVariant>(nullptr, { "dbus", name.constData(), "policy" }).toMap();
+ return value<QVariant>(nullptr, { "dbus", interfaceName, "policy" }).toMap();
}
-QString DefaultConfiguration::dbusRegistration(const QString &interfaceName) const
+QString DefaultConfiguration::dbusRegistration(const char *interfaceName) const
{
- QByteArray name = interfaceName.toLocal8Bit();
- QString dbus = value<QString>("dbus", { "dbus", name.constData(), "register" });
+ QString dbus = value<QString>("dbus", { "dbus", interfaceName, "register" });
if (dbus == qL1S("none"))
dbus.clear();
return dbus;
diff --git a/src/manager/defaultconfiguration.h b/src/main-lib/defaultconfiguration.h
index ed210837..66ec46ef 100644
--- a/src/manager/defaultconfiguration.h
+++ b/src/main-lib/defaultconfiguration.h
@@ -42,14 +42,14 @@
#pragma once
#include <QtAppManCommon/global.h>
-#include "configuration.h"
+#include <QtAppManMain/configuration.h>
QT_BEGIN_NAMESPACE_AM
class DefaultConfiguration : public Configuration
{
public:
- DefaultConfiguration();
+ DefaultConfiguration(const char *additionalDescription, bool onlyOnePositionalArgument);
~DefaultConfiguration();
void parse();
@@ -85,8 +85,8 @@ public:
QVariantMap containerConfigurations() const;
QVariantMap runtimeConfigurations() const;
- QVariantMap dbusPolicy(const QString &interfaceName) const;
- QString dbusRegistration(const QString &interfaceName) const;
+ QVariantMap dbusPolicy(const char *interfaceName) const;
+ QString dbusRegistration(const char *interfaceName) const;
int dbusRegistrationDelay() const;
bool dbusStartSessionBus() const;
@@ -114,6 +114,7 @@ public:
private:
QString m_mainQmlFile;
+ bool m_onlyOnePositionalArgument = false;
};
QT_END_NAMESPACE_AM
diff --git a/src/manager/manager.pri b/src/main-lib/main-lib.pro
index b3514fb0..824f8ce1 100644
--- a/src/manager/manager.pri
+++ b/src/main-lib/main-lib.pro
@@ -1,3 +1,7 @@
+TEMPLATE = lib
+TARGET = QtAppManMain
+MODULE = appman_main
+
load(am-config)
QT = core network qml core-private
@@ -15,7 +19,7 @@ QT *= \
appman_window-private \
appman_monitor-private \
-CONFIG *= console
+CONFIG *= static internal_module
win32:LIBS += -luser32
@@ -50,17 +54,4 @@ dbus-appman.header_flags = -l QtAM::ApplicationManager -i applicationmanager.h
DBUS_ADAPTORS += dbus-notifications dbus-appman
-load(qt_tool)
-
-load(install-prefix)
-
-OTHER_FILES = \
- syms.txt \
-
-load(build-config)
-
-unix:exists($$SOURCE_DIR/.git):GIT_VERSION=$$system(cd "$$SOURCE_DIR" && git describe --tags --always --dirty 2>/dev/null)
-isEmpty(GIT_VERSION):GIT_VERSION="unknown"
-
-createBuildConfig(_DATE_, VERSION, GIT_VERSION, SOURCE_DIR, BUILD_DIR, INSTALL_PREFIX, \
- QT_ARCH, QT_VERSION, QT, CONFIG, DEFINES, INCLUDEPATH, LIBS)
+load(qt_module)
diff --git a/src/manager/main.cpp b/src/main-lib/main.cpp
index 852d48bb..85a6dfad 100644
--- a/src/manager/main.cpp
+++ b/src/main-lib/main.cpp
@@ -135,69 +135,6 @@
#include "../plugin-interfaces/startupinterface.h"
-#if defined(AM_TESTRUNNER)
-# include "testrunner.h"
-# include "qtyaml.h"
-#endif
-
-
-QT_USE_NAMESPACE_AM
-
-Q_DECL_EXPORT int main(int argc, char *argv[])
-{
-#if defined(Q_OS_UNIX) && defined(AM_MULTI_PROCESS)
- // set a reasonable default for OSes/distros that do not set this by default
- setenv("XDG_RUNTIME_DIR", "/tmp", 0);
-#endif
-
- StartupTimer::instance()->checkpoint("entered main");
-
- QCoreApplication::setApplicationName(qSL("ApplicationManager"));
- QCoreApplication::setOrganizationName(qSL("Pelagicore AG"));
- QCoreApplication::setOrganizationDomain(qSL("pelagicore.com"));
- QCoreApplication::setApplicationVersion(qSL(AM_VERSION));
- for (int i = 1; i < argc; ++i) {
- if (strcmp("--no-dlt-logging", argv[i]) == 0) {
- Logging::setDltEnabled(false);
- break;
- }
- }
- Logging::initialize();
- StartupTimer::instance()->checkpoint("after basic initialization");
-
-#if !defined(AM_DISABLE_INSTALLER)
- Package::ensureCorrectLocale();
-
- QString error;
- if (Q_UNLIKELY(!forkSudoServer(DropPrivilegesPermanently, &error))) {
- qCCritical(LogSystem) << "ERROR:" << qPrintable(error);
- return 2;
- }
- StartupTimer::instance()->checkpoint("after sudo server fork");
-#endif
-
- DefaultConfiguration cfg;
- cfg.parse();
- StartupTimer::instance()->checkpoint("after command line parse");
-
- try {
-#if !defined(AM_HEADLESS)
- // this is needed for both WebEngine and Wayland Multi-screen rendering
- QCoreApplication::setAttribute(Qt::AA_ShareOpenGLContexts);
-# if !defined(QT_NO_SESSIONMANAGER)
- QGuiApplication::setFallbackSessionManagementEnabled(false);
-# endif
-#endif
- Main a(argc, argv);
-
- a.setup(&cfg);
- return a.exec();
-
- } catch (const std::exception &e) {
- qCCritical(LogSystem) << "ERROR:" << e.what();
- return 2;
- }
-}
QT_BEGIN_NAMESPACE_AM
@@ -215,13 +152,23 @@ Main::Main(int &argc, char **argv)
Main::~Main()
{
-#if defined(AM_TESTRUNNER)
- Q_UNUSED(m_notificationManager);
- Q_UNUSED(m_systemMonitor);
- Q_UNUSED(m_applicationIPCManager);
- Q_UNUSED(m_debuggingEnabler);
- delete m_engine;
-#else
+ // the eventloop stopped, so any pending "retakes" would not be executed
+ QObject *singletons[] = {
+ m_applicationManager,
+ m_applicationInstaller,
+ m_applicationIPCManager,
+ m_notificationManager,
+ m_windowManager,
+ m_systemMonitor
+ };
+ for (const auto &singleton : singletons)
+ retakeSingletonOwnershipFromQmlEngine(m_engine, singleton, true);
+
+#if defined(QT_PSSDP_LIB)
+ if (m_ssdpOk)
+ m_ssdp.setActive(false);
+#endif // QT_PSSDP_LIB
+
delete m_engine;
delete m_notificationManager;
@@ -234,7 +181,6 @@ Main::~Main()
delete m_systemMonitor;
delete m_applicationIPCManager;
delete m_debuggingEnabler;
-#endif // defined(AM_TESTRUNNER)
}
/*! \internal
@@ -253,10 +199,6 @@ void Main::setup(const DefaultConfiguration *cfg) Q_DECL_NOEXCEPT_EXPR(false)
setupQmlDebugging(cfg->qmlDebugging());
Logging::registerUnregisteredDltContexts();
-#if defined(AM_TESTRUNNER)
- TestRunner::initialize(cfg->testRunnerArguments());
-#endif
-
loadStartupPlugins(cfg->pluginFilePaths("startup"));
parseSystemProperties(cfg->rawSystemProperties());
@@ -289,35 +231,6 @@ void Main::setup(const DefaultConfiguration *cfg) Q_DECL_NOEXCEPT_EXPR(false)
setupSSDPService();
}
-int Main::exec() Q_DECL_NOEXCEPT_EXPR(false)
-{
- int res;
-#if defined(AM_TESTRUNNER)
- res = TestRunner::exec(m_engine);
-#else
- res = MainBase::exec();
-
- // the eventloop stopped, so any pending "retakes" would not be executed
- QObject *singletons[] = {
- m_applicationManager,
- m_applicationInstaller,
- m_applicationIPCManager,
- m_notificationManager,
- m_windowManager,
- m_systemMonitor
- };
- for (const auto &singleton : singletons)
- retakeSingletonOwnershipFromQmlEngine(m_engine, singleton, true);
-#endif // defined(AM_TESTRUNNER)
-
-#if defined(QT_PSSDP_LIB)
- if (m_ssdpOk)
- m_ssdp.setActive(false);
-#endif // QT_PSSDP_LIB
-
- return res;
-}
-
bool Main::isSingleProcessMode() const
{
return m_isSingleProcessMode;
@@ -358,6 +271,11 @@ void Main::shutDown()
}
}
+QQmlApplicationEngine *Main::qmlEngine() const
+{
+ return m_engine;
+}
+
void Main::setupQmlDebugging(bool qmlDebugging)
{
if (qmlDebugging) {
@@ -605,6 +523,11 @@ void Main::loadApplicationDatabase(const QString &databasePath, bool recreateDat
}
if (!m_applicationDatabase->isValid() || recreateDatabase) {
+ const QString dbDir = QFileInfo(databasePath).absolutePath();
+
+ if (Q_UNLIKELY(!QDir(dbDir).exists()) && Q_UNLIKELY(!QDir::root().mkpath(dbDir)))
+ throw Exception("could not create application database directory %1").arg(dbDir);
+
QVector<const Application *> apps;
if (!singleApp.isEmpty()) {
@@ -678,18 +601,9 @@ void Main::setupQmlEngine(const QStringList &importPaths, const QString &quickCo
new QmlLogger(m_engine);
m_engine->setOutputWarningsToStandardError(false);
m_engine->setImportPathList(m_engine->importPathList() + importPaths);
- m_engine->rootContext()->setContextProperty("StartupTimer", StartupTimer::instance());
+ m_engine->rootContext()->setContextProperty(qSL("StartupTimer"), StartupTimer::instance());
StartupTimer::instance()->checkpoint("after QML engine instantiation");
-
-#if defined(AM_TESTRUNNER)
- QFile f(qSL(":/build-config.yaml"));
- QVector<QVariant> docs;
- if (f.open(QFile::ReadOnly))
- docs = QtYaml::variantDocumentsFromYaml(f.readAll());
- f.close();
- m_engine->rootContext()->setContextProperty("buildConfig", docs.toList());
-#endif
}
void Main::setupWindowTitle(const QString &title, const QString &iconPath)
@@ -887,7 +801,7 @@ const char *Main::dbusInterfaceName(QObject *o) const Q_DECL_NOEXCEPT_EXPR(false
int idx = o->metaObject()->indexOfClassInfo("D-Bus Interface");
if (idx < 0) {
throw Exception("Could not get class-info \"D-Bus Interface\" for D-Bus adapter %1")
- .arg(o->metaObject()->className());
+ .arg(qL1S(o->metaObject()->className()));
}
return o->metaObject()->classInfo(idx).value();
#else
@@ -905,14 +819,14 @@ void Main::registerDBusObject(QDBusAbstractAdaptor *adaptor, const QString &dbus
if (dbusName.isEmpty()) {
return;
} else if (dbusName == qL1S("system")) {
- dbusAddress = qgetenv("DBUS_SYSTEM_BUS_ADDRESS");
+ dbusAddress = QString::fromLocal8Bit(qgetenv("DBUS_SYSTEM_BUS_ADDRESS"));
# if defined(Q_OS_LINUX)
if (dbusAddress.isEmpty())
dbusAddress = qL1S("unix:path=/var/run/dbus/system_bus_socket");
# endif
conn = QDBusConnection::systemBus();
} else if (dbusName == qL1S("session")) {
- dbusAddress = qgetenv("DBUS_SESSION_BUS_ADDRESS");
+ dbusAddress = QString::fromLocal8Bit(qgetenv("DBUS_SESSION_BUS_ADDRESS"));
conn = QDBusConnection::sessionBus();
} else {
dbusAddress = dbusName;
@@ -932,12 +846,12 @@ void Main::registerDBusObject(QDBusAbstractAdaptor *adaptor, const QString &dbus
if (!conn.registerObject(qL1S(path), adaptor->parent(), QDBusConnection::ExportAdaptors)) {
throw Exception("could not register object %1 on D-Bus (%2): %3")
- .arg(path).arg(dbusName).arg(conn.lastError().message());
+ .arg(qL1S(path)).arg(dbusName).arg(conn.lastError().message());
}
if (!conn.registerService(qL1S(serviceName))) {
throw Exception("could not register service %1 on D-Bus (%2): %3")
- .arg(serviceName).arg(dbusName).arg(conn.lastError().message());
+ .arg(qL1S(serviceName)).arg(dbusName).arg(conn.lastError().message());
}
qCDebug(LogSystem).nospace().noquote() << " * " << serviceName << path << " [on bus: " << dbusName << "]";
@@ -949,7 +863,7 @@ void Main::registerDBusObject(QDBusAbstractAdaptor *adaptor, const QString &dbus
QFile f(QDir::temp().absoluteFilePath(qL1S(interfaceName) + qSL(".dbus")));
QByteArray dbusUtf8 = dbusAddress.isEmpty() ? dbusName.toUtf8() : dbusAddress.toUtf8();
if (!f.open(QFile::WriteOnly | QFile::Truncate) || (f.write(dbusUtf8) != dbusUtf8.size()))
- throw Exception(f, "Could not write D-Bus address of interface %1").arg(interfaceName);
+ throw Exception(f, "Could not write D-Bus address of interface %1").arg(qL1S(interfaceName));
static QStringList filesToDelete;
if (filesToDelete.isEmpty())
@@ -963,8 +877,8 @@ void Main::registerDBusObject(QDBusAbstractAdaptor *adaptor, const QString &dbus
#endif // QT_DBUS_LIB
}
-void Main::registerDBusInterfaces(const std::function<QString(const QString &)> &busForInterface,
- const std::function<QVariantMap(const QString &)> &policyForInterface)
+void Main::registerDBusInterfaces(const std::function<QString(const char *)> &busForInterface,
+ const std::function<QVariantMap(const char *)> &policyForInterface)
{
#if defined(QT_DBUS_LIB)
registerDBusTypes();
diff --git a/src/manager/main.h b/src/main-lib/main.h
index d137cdb5..a9f3df4d 100644
--- a/src/manager/main.h
+++ b/src/main-lib/main.h
@@ -88,18 +88,19 @@ public:
bool isSingleProcessMode() const;
void setup(const DefaultConfiguration *cfg) Q_DECL_NOEXCEPT_EXPR(false);
- int exec() Q_DECL_NOEXCEPT_EXPR(false);
void shutDown();
+ QQmlApplicationEngine *qmlEngine() const;
+
protected:
void setupQmlDebugging(bool qmlDebugging);
void setupLoggingRules(bool verbose, const QStringList &loggingRules);
void loadStartupPlugins(const QStringList &startupPluginPaths) Q_DECL_NOEXCEPT_EXPR(false);
void parseSystemProperties(const QVariantMap &rawSystemProperties);
void setupDBus(bool startSessionBus) Q_DECL_NOEXCEPT_EXPR(false);
- void registerDBusInterfaces(const std::function<QString(const QString &)> &busForInterface,
- const std::function<QVariantMap(const QString &)> &policyForInterface);
+ void registerDBusInterfaces(const std::function<QString(const char *)> &busForInterface,
+ const std::function<QVariantMap(const char *)> &policyForInterface);
void setMainQmlFile(const QString &mainQml) Q_DECL_NOEXCEPT_EXPR(false);
void setupSingleOrMultiProcess(bool forceSingleProcess, bool forceMultiProcess) Q_DECL_NOEXCEPT_EXPR(false);
void setupRuntimesAndContainers(const QVariantMap &runtimeConfigurations, const QVariantMap &containerConfigurations,
diff --git a/src/manager/qmllogger.cpp b/src/main-lib/qmllogger.cpp
index 21889251..21889251 100644
--- a/src/manager/qmllogger.cpp
+++ b/src/main-lib/qmllogger.cpp
diff --git a/src/manager/qmllogger.h b/src/main-lib/qmllogger.h
index 7ea18cb5..7ea18cb5 100644
--- a/src/manager/qmllogger.h
+++ b/src/main-lib/qmllogger.h
diff --git a/src/manager/android-deploy-dummy.qml b/src/manager/android-deploy-dummy.qml
deleted file mode 100644
index be606e97..00000000
--- a/src/manager/android-deploy-dummy.qml
+++ /dev/null
@@ -1,60 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 Pelagicore AG
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the Pelagicore 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
-**
-****************************************************************************/
-
-import QtGraphicalEffects 1.0
-import Qt.labs.folderlistmodel 2.0
-import QtMultimedia 5.0
-import QtQuick 2.1
-import QtQuick.Controls 1.1
-import QtQuick.Controls.Styles 1.0
-import QtQuick.Layouts 1.1
-import QtQuick.Window 2.1
-import QtWebKit 3.0
-import QtQuick.LocalStorage 2.0
-import com.pelagicore.datasource 0.1
-import com.pelagicore.ScreenManager 0.1
-import com.theqtcompany.comtqci18ndemo 0.1
-
-Rectangle {
- width: 100
- height: 62
-}
-
diff --git a/src/manager/android/AndroidManifest.xml b/src/manager/android/AndroidManifest.xml
deleted file mode 100644
index 94356084..00000000
--- a/src/manager/android/AndroidManifest.xml
+++ /dev/null
@@ -1,80 +0,0 @@
-<?xml version="1.0"?>
-<manifest package="io.qt.ApplicationManager" xmlns:android="http://schemas.android.com/apk/res/android" android:versionName="1.1" android:versionCode="1" android:installLocation="auto">
- <application android:hardwareAccelerated="true" android:name="org.qtproject.qt5.android.bindings.QtApplication" android:label="Qt ApplicationManager" android:icon="@drawable/icon" android:theme="@android:style/Theme.Holo.NoActionBar">
- <activity android:configChanges="orientation|uiMode|screenLayout|screenSize|smallestScreenSize|layoutDirection|locale|fontScale|keyboard|keyboardHidden|navigation" android:name="org.qtproject.qt5.android.bindings.QtActivity" android:label="Qt ApplicationManager" android:screenOrientation="unspecified" android:launchMode="singleTop">
- <intent-filter>
- <action android:name="android.intent.action.MAIN"/>
- <category android:name="android.intent.category.LAUNCHER"/>
- </intent-filter>
-
- <!-- Application arguments -->
- <!-- meta-data android:name="android.app.arguments" android:value="arg1 arg2 arg3"/ -->
- <!-- Application arguments -->
-
- <meta-data android:name="android.app.lib_name" android:value="appman"/>
- <meta-data android:name="android.app.qt_sources_resource_id" android:resource="@array/qt_sources"/>
- <meta-data android:name="android.app.repository" android:value="default"/>
- <meta-data android:name="android.app.qt_libs_resource_id" android:resource="@array/qt_libs"/>
- <meta-data android:name="android.app.bundled_libs_resource_id" android:resource="@array/bundled_libs"/>
- <!-- Deploy Qt libs as part of package -->
- <meta-data android:name="android.app.bundle_local_qt_libs" android:value="-- %%BUNDLE_LOCAL_QT_LIBS%% --"/>
- <meta-data android:name="android.app.bundled_in_lib_resource_id" android:resource="@array/bundled_in_lib"/>
- <meta-data android:name="android.app.bundled_in_assets_resource_id" android:resource="@array/bundled_in_assets"/>
- <!-- Run with local libs -->
- <meta-data android:name="android.app.use_local_qt_libs" android:value="-- %%USE_LOCAL_QT_LIBS%% --"/>
- <meta-data android:name="android.app.libs_prefix" android:value="/data/local/tmp/qt/"/>
- <meta-data android:name="android.app.load_local_libs" android:value="-- %%INSERT_LOCAL_LIBS%% --"/>
- <meta-data android:name="android.app.load_local_jars" android:value="-- %%INSERT_LOCAL_JARS%% --"/>
- <meta-data android:name="android.app.static_init_classes" android:value="-- %%INSERT_INIT_CLASSES%% --"/>
- <!-- Messages maps -->
- <meta-data android:value="@string/ministro_not_found_msg" android:name="android.app.ministro_not_found_msg"/>
- <meta-data android:value="@string/ministro_needed_msg" android:name="android.app.ministro_needed_msg"/>
- <meta-data android:value="@string/fatal_error_msg" android:name="android.app.fatal_error_msg"/>
- <!-- Messages maps -->
-
- <!-- Splash screen -->
- <!-- meta-data android:name="android.app.splash_screen_drawable" android:resource="@drawable/logo"/ -->
- <!-- meta-data android:name="android.app.splash_screen_sticky" android:value="true"/ -->
- <!-- Splash screen -->
-
- <!-- Background running -->
- <!-- Warning: changing this value to true may cause unexpected crashes if the
- application still try to draw after
- "applicationStateChanged(Qt::ApplicationSuspended)"
- signal is sent! -->
- <meta-data android:name="android.app.background_running" android:value="false"/>
- <!-- Background running -->
-
- <!-- auto screen scale factor -->
- <meta-data android:name="android.app.auto_screen_scale_factor" android:value="false"/>
- <!-- auto screen scale factor -->
-
- <!-- extract android style -->
- <!-- available android:values :
- * full - useful QWidget & Quick Controls 1 apps
- * minimal - useful for Quick Controls 2 apps, it is much faster than "full"
- * none - useful for apps that don't use any of the above Qt modules
- -->
- <meta-data android:name="android.app.extract_android_style" android:value="full"/>
- <!-- extract android style -->
- </activity>
-
- <!-- For adding service(s) please check: https://wiki.qt.io/AndroidServices -->
-
- </application>
-
- <uses-sdk android:minSdkVersion="21" android:targetSdkVersion="21"/>
- <supports-screens android:largeScreens="true" android:normalScreens="true" android:anyDensity="true" android:smallScreens="true"/>
-
- <!-- The following comment will be replaced upon deployment with default permissions based on the dependencies of the application.
- Remove the comment if you do not require these default permissions. -->
- <!-- %%INSERT_PERMISSIONS -->
-
- <!-- The following comment will be replaced upon deployment with default features based on the dependencies of the application.
- Remove the comment if you do not require these default features. -->
- <!-- %%INSERT_FEATURES -->
-
- <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
- <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
-
-</manifest>
diff --git a/src/manager/android/build.gradle b/src/manager/android/build.gradle
deleted file mode 100644
index ef416b0b..00000000
--- a/src/manager/android/build.gradle
+++ /dev/null
@@ -1,57 +0,0 @@
-buildscript {
- repositories {
- jcenter()
- }
-
- dependencies {
- classpath 'com.android.tools.build:gradle:1.1.0'
- }
-}
-
-allprojects {
- repositories {
- jcenter()
- }
-}
-
-apply plugin: 'com.android.application'
-
-dependencies {
- compile fileTree(dir: 'libs', include: ['*.jar'])
-}
-
-android {
- /*******************************************************
- * The following variables:
- * - androidBuildToolsVersion,
- * - androidCompileSdkVersion
- * - qt5AndroidDir - holds the path to qt android files
- * needed to build any Qt application
- * on Android.
- *
- * are defined in gradle.properties file. This file is
- * updated by QtCreator and androiddeployqt tools.
- * Changing them manually might break the compilation!
- *******************************************************/
-
- compileSdkVersion androidCompileSdkVersion.toInteger()
-
- buildToolsVersion androidBuildToolsVersion
-
- sourceSets {
- main {
- manifest.srcFile 'AndroidManifest.xml'
- java.srcDirs = [qt5AndroidDir + '/src', 'src', 'java']
- aidl.srcDirs = [qt5AndroidDir + '/src', 'src', 'aidl']
- res.srcDirs = [qt5AndroidDir + '/res', 'res']
- resources.srcDirs = ['src']
- renderscript.srcDirs = ['src']
- assets.srcDirs = ['assets']
- jniLibs.srcDirs = ['libs']
- }
- }
-
- lintOptions {
- abortOnError false
- }
-}
diff --git a/src/manager/android/res/drawable-hdpi/icon.png b/src/manager/android/res/drawable-hdpi/icon.png
deleted file mode 100644
index f1c9743c..00000000
--- a/src/manager/android/res/drawable-hdpi/icon.png
+++ /dev/null
Binary files differ
diff --git a/src/manager/android/res/drawable-ldpi/icon.png b/src/manager/android/res/drawable-ldpi/icon.png
deleted file mode 100644
index ba86ab00..00000000
--- a/src/manager/android/res/drawable-ldpi/icon.png
+++ /dev/null
Binary files differ
diff --git a/src/manager/android/res/drawable-mdpi/icon.png b/src/manager/android/res/drawable-mdpi/icon.png
deleted file mode 100644
index 03b85478..00000000
--- a/src/manager/android/res/drawable-mdpi/icon.png
+++ /dev/null
Binary files differ
diff --git a/src/manager/android/res/values/libs.xml b/src/manager/android/res/values/libs.xml
deleted file mode 100644
index 77f422cf..00000000
--- a/src/manager/android/res/values/libs.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version='1.0' encoding='utf-8'?>
-<resources>
- <array name="qt_sources">
- <item>https://download.qt.io/ministro/android/qt5/qt-5.8</item>
- </array>
-
- <!-- The following is handled automatically by the deployment tool. It should
- not be edited manually. -->
-
- <array name="bundled_libs">
- <!-- %%INSERT_EXTRA_LIBS%% -->
- </array>
-
- <array name="qt_libs">
- <!-- %%INSERT_QT_LIBS%% -->
- </array>
-
- <array name="bundled_in_lib">
- <!-- %%INSERT_BUNDLED_IN_LIB%% -->
- </array>
- <array name="bundled_in_assets">
- <!-- %%INSERT_BUNDLED_IN_ASSETS%% -->
- </array>
-
-</resources>
diff --git a/src/manager/manager.pro b/src/manager/manager.pro
deleted file mode 100644
index 5a940a60..00000000
--- a/src/manager/manager.pro
+++ /dev/null
@@ -1,25 +0,0 @@
-TEMPLATE = app
-TARGET = appman
-
-include(manager.pri)
-
-android {
- QT *= androidextras
-
- ANDROID_PACKAGE_SOURCE_DIR = $$PWD/android
-
- DISTFILES += \
- android/gradle/wrapper/gradle-wrapper.jar \
- android/AndroidManifest.xml \
- android/gradlew.bat \
- android/res/values/libs.xml \
- android/build.gradle \
- android/gradle/wrapper/gradle-wrapper.properties \
- android/gradlew
-
- # hack for neptune to get the plugin deployed
-# ANDROID_EXTRA_LIBS = $$[QT_INSTALL_QML]/com/pelagicore/datasource/libqmldatasources.so
-
- # hack for neptune to get all relevant Qt modules deployed
-# DISTFILES += android-deploy-dummy.qml
-}
diff --git a/src/manager/syms.txt b/src/manager/syms.txt
deleted file mode 100644
index 90a495af..00000000
--- a/src/manager/syms.txt
+++ /dev/null
@@ -1,23 +0,0 @@
-{
- *AbstractRuntime;
- *RuntimeFactory;
- *Application;
- *ApplicationManager;
- *ApplicationInterface;
- *ExecutionContainer;
- *ExecutionContainerFactory;
- *ExecutionContainerProcess;
- *FakeApplicationManagerWindow;
- extern "C++" {
- AbstractRuntime::*;
- Application::*;
- ApplicationManager::*;
- ApplicationInterface::*;
- RuntimeFactory::*;
- ExecutionContainer::*;
- ExecutionContainerFactory::*;
- ExecutionContainerProcess::*;
- FakeApplicationManagerWindow::*;
- Log*;
- };
-};
diff --git a/src/src.pro b/src/src.pro
index 58aa7357..99fc2feb 100644
--- a/src/src.pro
+++ b/src/src.pro
@@ -3,45 +3,95 @@ TEMPLATE = subdirs
load(am-config)
+common_lib.subdir = common-lib
+
+plugin_interfaces.subdir = plugin-interfaces
+
+crypto_lib.subdir = crypto-lib
+crypto_lib.depends = common_lib
+
+application_lib.subdir = application-lib
+application_lib.depends = common_lib
+
+notification_lib.subdir = notification-lib
+notification_lib.depends = common_lib
+
+package_lib.subdir = package-lib
+package_lib.depends = crypto_lib application_lib
+
+manager_lib.subdir = manager-lib
+manager_lib.depends = application_lib notification_lib plugin_interfaces
+
+installer_lib.subdir = installer-lib
+installer_lib.depends = package_lib manager_lib
+
+window_lib.subdir = window-lib
+window_lib.depends = manager_lib
+
+monitor_lib.subdir = monitor-lib
+monitor_lib.depends = manager_lib window_lib
+
+launcher_lib.subdir = launcher-lib
+launcher_lib.depends = application_lib notification_lib
+
+main_lib.subdir = main-lib
+main_lib.depends = manager_lib installer_lib window_lib monitor_lib
+
+launchers_qml.subdir = launchers/qml
+launchers_qml.depends = launcher_lib plugin_interfaces
+
+tools_appman.subdir = tools/appman
+tools_appman.depends = main_lib
+
+tools_testrunner.subdir = tools/testrunner
+tools_testrunner.depends = main_lib
+
+tools_dumpqmltypes.subdir = tools/dumpqmltypes
+tools_dumpqmltypes.depends = manager_lib installer_lib window_lib monitor_lib launcher_lib
+
+tools_packager.subdir = tools/packager
+tools_packager.depends = package_lib
+
+tools_deployer.subdir = tools/deployer
+
+tools_controller.subdir = tools/controller
+tools_controller.depends = common_lib
+
SUBDIRS = \
- common-lib \
- crypto-lib \
- application-lib \
- package-lib \
-
-crypto-lib.depends = common-lib
-application-lib.depends = common-lib
-notification-lib.depends = common-lib
-package-lib.depends = crypto-lib application-lib
-manager-lib.depends = application-lib notification-lib plugin-interfaces
-installer-lib.depends = package-lib manager-lib
-window-lib.depends = manager-lib
-monitor-lib.depends = manager-lib window-lib
-launcher-lib.depends = application-lib notification-lib
-manager.depends = manager-lib installer-lib window-lib monitor-lib
-launchers.depends = launcher-lib
-tools.depends = package-lib
+ common_lib \
+ crypto_lib \
+ application_lib \
+ package_lib \
!tools-only {
SUBDIRS += \
- plugin-interfaces \
+ plugin_interfaces \
dbus \
qtHaveModule(qml):SUBDIRS += \
- notification-lib \
- manager-lib \
- installer-lib \
- window-lib \
- monitor-lib \
- manager \
+ notification_lib \
+ manager_lib \
+ installer_lib \
+ window_lib \
+ main_lib \
+ monitor_lib \
+ tools_appman \
+ # Although the testrunner is in tools we don't want to build it with tools-only
+ # because it is based on the manager binary
+ tools_testrunner \
qtHaveModule(qml):qtHaveModule(dbus):SUBDIRS += \
- launcher-lib \
- launchers
+ launcher_lib \
+ # This tool links against everything to extract the Qml type information
+ tools_dumpqmltypes \
- tools.depends *= manager-lib installer-lib window-lib monitor-lib
-
- qtHaveModule(qml):qtHaveModule(dbus):tools.depends *= launcher-lib
+ multi-process:qtHaveModule(qml):qtHaveModule(dbus):SUBDIRS += \
+ launchers_qml \
}
-SUBDIRS += tools
+!android:SUBDIRS += \
+ tools_packager \
+ tools_deployer \
+
+qtHaveModule(dbus):SUBDIRS += \
+ tools_controller \
diff --git a/src/tools/appman/appman.cpp b/src/tools/appman/appman.cpp
new file mode 100644
index 00000000..aba6e487
--- /dev/null
+++ b/src/tools/appman/appman.cpp
@@ -0,0 +1,141 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 Pelagicore AG
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Pelagicore 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 <QQmlApplicationEngine>
+#include <QQmlContext>
+
+#include "global.h"
+#include "logging.h"
+#include "main.h"
+#include "defaultconfiguration.h"
+#include "package.h"
+#if !defined(AM_DISABLE_INSTALLER)
+# include "sudo.h"
+#endif
+#include "startuptimer.h"
+
+#if defined(AM_TESTRUNNER)
+# include "testrunner.h"
+#endif
+
+
+QT_USE_NAMESPACE_AM
+
+Q_DECL_EXPORT int main(int argc, char *argv[])
+{
+#if defined(Q_OS_UNIX) && defined(AM_MULTI_PROCESS)
+ // set a reasonable default for OSes/distros that do not set this by default
+ setenv("XDG_RUNTIME_DIR", "/tmp", 0);
+#endif
+
+ StartupTimer::instance()->checkpoint("entered main");
+
+#if defined(AM_TESTRUNNER)
+ QCoreApplication::setApplicationName(qSL("ApplicationManager QML Test Runner"));
+#else
+ QCoreApplication::setApplicationName(qSL("ApplicationManager"));
+#endif
+ QCoreApplication::setOrganizationName(qSL("Pelagicore AG"));
+ QCoreApplication::setOrganizationDomain(qSL("pelagicore.com"));
+ QCoreApplication::setApplicationVersion(qSL(AM_VERSION));
+ for (int i = 1; i < argc; ++i) {
+ if (strcmp("--no-dlt-logging", argv[i]) == 0) {
+ Logging::setDltEnabled(false);
+ break;
+ }
+ }
+ Logging::initialize();
+ StartupTimer::instance()->checkpoint("after basic initialization");
+
+#if !defined(AM_DISABLE_INSTALLER)
+ Package::ensureCorrectLocale();
+
+ QString error;
+ if (Q_UNLIKELY(!forkSudoServer(DropPrivilegesPermanently, &error))) {
+ qCCritical(LogSystem) << "ERROR:" << qPrintable(error);
+ return 2;
+ }
+ StartupTimer::instance()->checkpoint("after sudo server fork");
+#endif
+
+ try {
+#if !defined(AM_HEADLESS)
+ // this is needed for both WebEngine and Wayland Multi-screen rendering
+ QCoreApplication::setAttribute(Qt::AA_ShareOpenGLContexts);
+# if !defined(QT_NO_SESSIONMANAGER)
+ QGuiApplication::setFallbackSessionManagementEnabled(false);
+# endif
+#endif
+
+ Main a(argc, argv);
+
+#if defined(AM_TESTRUNNER)
+ const char *additionalDescription =
+ "Additional testrunner commandline options can be set after the -- argument\n" \
+ "Use -- -help to show all available testrunner commandline options.";
+ bool onlyOnePositionalArgument = false;
+#else
+ const char *additionalDescription = nullptr;
+ bool onlyOnePositionalArgument = true;
+#endif
+
+ DefaultConfiguration cfg(additionalDescription, onlyOnePositionalArgument);
+ cfg.parse();
+
+ StartupTimer::instance()->checkpoint("after command line parse");
+#if defined(AM_TESTRUNNER)
+ TestRunner::initialize(cfg.testRunnerArguments());
+#endif
+ a.setup(&cfg);
+#if defined(AM_TESTRUNNER)
+ a.qmlEngine()->rootContext()->setContextProperty("buildConfig", cfg.buildConfig());
+#endif
+
+#if defined(AM_TESTRUNNER)
+ return TestRunner::exec(a.qmlEngine());
+#else
+ return MainBase::exec();
+#endif
+ } catch (const std::exception &e) {
+ qCCritical(LogSystem) << "ERROR:" << e.what();
+ return 2;
+ }
+}
diff --git a/src/tools/appman/appman.pro b/src/tools/appman/appman.pro
new file mode 100644
index 00000000..0b9e3e46
--- /dev/null
+++ b/src/tools/appman/appman.pro
@@ -0,0 +1,25 @@
+TEMPLATE = app
+TARGET = appman
+
+load(am-config)
+
+QT = appman_main-private
+
+CONFIG *= console
+
+#win32:LIBS += -luser32
+
+SOURCES += \
+ $$PWD/appman.cpp
+
+load(qt_tool)
+
+load(install-prefix)
+
+load(build-config)
+
+unix:exists($$SOURCE_DIR/.git):GIT_VERSION=$$system(cd "$$SOURCE_DIR" && git describe --tags --always --dirty 2>/dev/null)
+isEmpty(GIT_VERSION):GIT_VERSION="unknown"
+
+createBuildConfig(_DATE_, VERSION, GIT_VERSION, SOURCE_DIR, BUILD_DIR, INSTALL_PREFIX, \
+ QT_ARCH, QT_VERSION, QT, CONFIG, DEFINES, INCLUDEPATH, LIBS)
diff --git a/src/tools/controller/main.cpp b/src/tools/controller/controller.cpp
index 63df9897..63df9897 100644
--- a/src/tools/controller/main.cpp
+++ b/src/tools/controller/controller.cpp
diff --git a/src/tools/controller/controller.pro b/src/tools/controller/controller.pro
index 55eae1ed..465a8a4e 100644
--- a/src/tools/controller/controller.pro
+++ b/src/tools/controller/controller.pro
@@ -9,7 +9,7 @@ QT *= appman_common-private
CONFIG *= console
SOURCES += \
- main.cpp \
+ controller.cpp \
appmanif.files = ../../dbus/io.qt.applicationmanager.xml
appmanif.header_flags = -i dbus-utilities.h
diff --git a/src/tools/dumpqmltypes/main.cpp b/src/tools/dumpqmltypes/dumpqmltypes.cpp
index 2123ae9a..2123ae9a 100644
--- a/src/tools/dumpqmltypes/main.cpp
+++ b/src/tools/dumpqmltypes/dumpqmltypes.cpp
diff --git a/src/tools/dumpqmltypes/dumpqmltypes.pro b/src/tools/dumpqmltypes/dumpqmltypes.pro
index 73e23952..823626b9 100644
--- a/src/tools/dumpqmltypes/dumpqmltypes.pro
+++ b/src/tools/dumpqmltypes/dumpqmltypes.pro
@@ -15,7 +15,8 @@ QT *= \
CONFIG *= console
-SOURCES += main.cpp
+SOURCES += \
+ dumpqmltypes.cpp
load(qt_tool)
diff --git a/src/tools/packager/main.cpp b/src/tools/packager/main.cpp
deleted file mode 100644
index 39aefe38..00000000
--- a/src/tools/packager/main.cpp
+++ /dev/null
@@ -1,233 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2017 Pelagicore AG
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the Pelagicore Application Manager.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT-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 General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** 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-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QCoreApplication>
-#include <QCommandLineParser>
-#include <QStringList>
-#include <QDebug>
-
-#include <stdio.h>
-
-#include <QtAppManCommon/exception.h>
-#include <QtAppManPackage/package.h>
-#include "packager.h"
-
-QT_USE_NAMESPACE_AM
-
-enum Command {
- NoCommand,
- CreatePackage,
- DevSignPackage,
- DevVerifyPackage,
- StoreSignPackage,
- StoreVerifyPackage,
-};
-
-static struct {
- Command command;
- const char *name;
- const char *description;
-} commandTable[] = {
- { CreatePackage, "create-package", "Create a new package." },
- { DevSignPackage, "dev-sign-package", "Add developer signature to package." },
- { DevVerifyPackage, "dev-verify-package", "Verify developer signature on package." },
- { StoreSignPackage, "store-sign-package", "Add store signature to package." },
- { StoreVerifyPackage, "store-verify-package", "Verify store signature on package." }
-};
-
-static Command command(QCommandLineParser &clp)
-{
- if (!clp.positionalArguments().isEmpty()) {
- QByteArray cmd = clp.positionalArguments().at(0).toLatin1();
-
- for (uint i = 0; i < sizeof(commandTable) / sizeof(commandTable[0]); ++i) {
- if (cmd == commandTable[i].name) {
- clp.clearPositionalArguments();
- clp.addPositionalArgument(cmd, commandTable[i].description, cmd);
- return commandTable[i].command;
- }
- }
- }
- return NoCommand;
-}
-
-int main(int argc, char *argv[])
-{
- Package::ensureCorrectLocale();
-
- QCoreApplication::setApplicationName(qSL("ApplicationManager Packager"));
- QCoreApplication::setOrganizationName(qSL("Pelagicore AG"));
- QCoreApplication::setOrganizationDomain(qSL("pelagicore.com"));
- QCoreApplication::setApplicationVersion(qSL(AM_VERSION));
-
- QCoreApplication a(argc, argv);
-
- if (!Package::checkCorrectLocale()) {
- fprintf(stderr, "ERROR: the packager needs a UTF-8 locale to work correctly:\n"
- " even automatically switching to C.UTF-8 or en_US.UTF-8 failed.\n");
- exit(2);
- }
-
- QString desc = qSL("\nPelagicore ApplicationManager packaging tool\n\nAvailable commands are:\n");
- uint longestName = 0;
- for (uint i = 0; i < sizeof(commandTable) / sizeof(commandTable[0]); ++i)
- longestName = qMax(longestName, qstrlen(commandTable[i].name));
- for (uint i = 0; i < sizeof(commandTable) / sizeof(commandTable[0]); ++i) {
- desc += qSL(" %1%2 %3\n")
- .arg(qL1S(commandTable[i].name),
- QString(longestName - qstrlen(commandTable[i].name), qL1C(' ')),
- qL1S(commandTable[i].description));
- }
-
- desc += qSL("\nMore information about each command can be obtained by running\n appman-packager <command> --help");
-
- QCommandLineParser clp;
- clp.setApplicationDescription(desc);
-
- clp.addHelpOption();
- clp.addVersionOption();
-
- clp.addPositionalArgument(qSL("command"), qSL("The command to execute."));
-
- // ignore unknown options for now -- the sub-commands may need them later
- clp.setOptionsAfterPositionalArgumentsMode(QCommandLineParser::ParseAsPositionalArguments);
-
- if (!clp.parse(QCoreApplication::arguments())) {
- fprintf(stderr, "%s\n", qPrintable(clp.errorText()));
- exit(1);
- }
- clp.setOptionsAfterPositionalArgumentsMode(QCommandLineParser::ParseAsOptions);
-
- Packager *p = nullptr;
-
- switch (command(clp)) {
- default:
- case NoCommand:
- if (clp.isSet(qSL("version")))
- clp.showVersion();
- if (clp.isSet(qSL("help")))
- clp.showHelp();
- clp.showHelp(1);
- break;
-
- case CreatePackage:
- clp.addOption({ qSL("verbose"), qSL("Dump the package's meta-data header and footer information to stdout.") });
- clp.addOption({ qSL("json"), qSL("Output in JSON format instead of YAML.") });
- clp.addPositionalArgument(qSL("package"), qSL("The file name of the created package."));
- clp.addPositionalArgument(qSL("source-directory"), qSL("The package's content root directory."));
- clp.process(a);
-
- if (clp.positionalArguments().size() != 3)
- clp.showHelp(1);
-
- p = Packager::create(clp.positionalArguments().at(1),
- clp.positionalArguments().at(2),
- clp.isSet(qSL("json")));
- break;
-
- case DevSignPackage:
- clp.addOption({ qSL("verbose"), qSL("Dump the package's meta-data header and footer information to stdout.") });
- clp.addOption({ qSL("json"), qSL("Output in JSON format instead of YAML.") });
- clp.addPositionalArgument(qSL("package"), qSL("File name of the unsigned package (input)."));
- clp.addPositionalArgument(qSL("signed-package"), qSL("File name of the signed package (output)."));
- clp.addPositionalArgument(qSL("certificate"), qSL("PKCS#12 certificate file."));
- clp.addPositionalArgument(qSL("password"), qSL("Password for the PKCS#12 certificate."));
- clp.process(a);
-
- if (clp.positionalArguments().size() != 5)
- clp.showHelp(1);
-
- p = Packager::developerSign(clp.positionalArguments().at(1),
- clp.positionalArguments().at(2),
- clp.positionalArguments().at(3),
- clp.positionalArguments().at(4),
- clp.isSet(qSL("json")));
- break;
-
- case DevVerifyPackage:
- clp.addOption({ qSL("verbose"), qSL("Print details regarding the verification to stdout.") });
- clp.addPositionalArgument(qSL("package"), qSL("File name of the signed package (input)."));
- clp.addPositionalArgument(qSL("certificates"), qSL("The developer's CA certificate file(s)."), qSL("certificates..."));
- clp.process(a);
-
- if (clp.positionalArguments().size() < 3)
- clp.showHelp(1);
-
- p = Packager::developerVerify(clp.positionalArguments().at(1),
- clp.positionalArguments().mid(2));
- break;
-
- case StoreSignPackage:
- clp.addOption({ qSL("verbose"), qSL("Dump the package's meta-data header and footer information to stdout.") });
- clp.addOption({ qSL("json"), qSL("Output in JSON format instead of YAML.") });
- clp.addPositionalArgument(qSL("package"), qSL("File name of the unsigned package (input)."));
- clp.addPositionalArgument(qSL("signed-package"), qSL("File name of the signed package (output)."));
- clp.addPositionalArgument(qSL("certificate"), qSL("PKCS#12 certificate file."));
- clp.addPositionalArgument(qSL("password"), qSL("Password for the PKCS#12 certificate."));
- clp.addPositionalArgument(qSL("hardware-id"), qSL("Unique hardware id to which this package gets bound."));
- clp.process(a);
-
- if (clp.positionalArguments().size() != 6)
- clp.showHelp(1);
-
- p = Packager::storeSign(clp.positionalArguments().at(1),
- clp.positionalArguments().at(2),
- clp.positionalArguments().at(3),
- clp.positionalArguments().at(4),
- clp.positionalArguments().at(5),
- clp.isSet(qSL("json")));
- break;
-
- case StoreVerifyPackage:
- clp.addOption({ qSL("verbose"), qSL("Print details regarding the verification to stdout.") });
- clp.addPositionalArgument(qSL("package"), qSL("File name of the signed package (input)."));
- clp.addPositionalArgument(qSL("certificates"), qSL("Store CA certificate file(s)."), qSL("certificates..."));
- clp.addPositionalArgument(qSL("hardware-id"), qSL("Unique hardware id to which this package was bound."));
- clp.process(a);
-
- if (clp.positionalArguments().size() < 4)
- clp.showHelp(1);
-
- p = Packager::storeVerify(clp.positionalArguments().at(1),
- clp.positionalArguments().mid(2, clp.positionalArguments().size() - 2),
- *--clp.positionalArguments().cend());
- break;
- }
-
- if (!p)
- return 2;
- try {
- p->execute();
- if (clp.isSet(qSL("verbose")) && !p->output().isEmpty())
- fprintf(stdout, "%s\n", qPrintable(p->output()));
- return p->resultCode();
- } catch (const Exception &e) {
- fprintf(stderr, "ERROR: %s\n", qPrintable(e.errorString()));
- return 1;
- }
-}
diff --git a/src/tools/packager/packager.cpp b/src/tools/packager/packager.cpp
index b738f0c8..f595b595 100644
--- a/src/tools/packager/packager.cpp
+++ b/src/tools/packager/packager.cpp
@@ -26,285 +26,208 @@
**
****************************************************************************/
-#include <QFile>
-#include <QFileInfo>
-#include <QUrl>
-#include <QRegExp>
-#include <QDirIterator>
-#include <QMessageAuthenticationCode>
-#include <QJsonDocument>
-#include <QTemporaryDir>
+#include <QCoreApplication>
+#include <QCommandLineParser>
+#include <QStringList>
+#include <QDebug>
#include <stdio.h>
-#include <stdlib.h>
-#include "exception.h"
-#include "signature.h"
-#include "qtyaml.h"
-#include "application.h"
-#include "installationreport.h"
-#include "yamlapplicationscanner.h"
-#include "packageextractor.h"
-#include "packagecreator.h"
-
-#include "packager.h"
+#include <QtAppManCommon/exception.h>
+#include <QtAppManPackage/package.h>
+#include "packagingjob.h"
QT_USE_NAMESPACE_AM
-// this corresponds to the -b parameter for mkfs.ext2 in sudo.cpp
-static const int Ext2BlockSize = 1024;
-
-
-Packager *Packager::create(const QString &destinationName, const QString &sourceDir, bool asJson)
-{
- Packager *p = new Packager();
- p->m_mode = Create;
- p->m_asJson = asJson;
- p->m_destinationName = destinationName;
- p->m_sourceDir = sourceDir;
- return p;
-}
-
-Packager *Packager::developerSign(const QString &sourceName, const QString &destinationName,
- const QString &certificateFile, const QString &passPhrase,
- bool asJson)
-{
- Packager *p = new Packager();
- p->m_mode = DeveloperSign;
- p->m_asJson = asJson;
- p->m_sourceName = sourceName;
- p->m_destinationName = destinationName;
- p->m_passphrase = passPhrase;
- p->m_certificateFiles = QStringList { certificateFile };
- return p;
-}
-
-Packager *Packager::developerVerify(const QString &sourceName, const QStringList &certificateFiles)
-{
- Packager *p = new Packager();
- p->m_mode = DeveloperVerify;
- p->m_sourceName = sourceName;
- p->m_certificateFiles = certificateFiles;
- return p;
-}
-
-Packager *Packager::storeSign(const QString &sourceName, const QString &destinationName,
- const QString &certificateFile, const QString &passPhrase,
- const QString &hardwareId, bool asJson)
+enum Command {
+ NoCommand,
+ CreatePackage,
+ DevSignPackage,
+ DevVerifyPackage,
+ StoreSignPackage,
+ StoreVerifyPackage,
+};
+
+static struct {
+ Command command;
+ const char *name;
+ const char *description;
+} commandTable[] = {
+ { CreatePackage, "create-package", "Create a new package." },
+ { DevSignPackage, "dev-sign-package", "Add developer signature to package." },
+ { DevVerifyPackage, "dev-verify-package", "Verify developer signature on package." },
+ { StoreSignPackage, "store-sign-package", "Add store signature to package." },
+ { StoreVerifyPackage, "store-verify-package", "Verify store signature on package." }
+};
+
+static Command command(QCommandLineParser &clp)
{
- Packager *p = new Packager();
- p->m_mode = StoreSign;
- p->m_asJson = asJson;
- p->m_sourceName = sourceName;
- p->m_destinationName = destinationName;
- p->m_passphrase = passPhrase;
- p->m_certificateFiles = QStringList { certificateFile };
- p->m_hardwareId = hardwareId;
- return p;
-}
-
-Packager *Packager::storeVerify(const QString &sourceName, const QStringList &certificateFiles, const QString &hardwareId)
-{
- Packager *p = new Packager();
- p->m_mode = StoreVerify;
- p->m_sourceName = sourceName;
- p->m_certificateFiles = certificateFiles;
- p->m_hardwareId = hardwareId;
- return p;
-}
-
-QString Packager::output() const
-{
- return m_output;
-}
-
-int Packager::resultCode() const
-{
- return m_resultCode;
+ if (!clp.positionalArguments().isEmpty()) {
+ QByteArray cmd = clp.positionalArguments().at(0).toLatin1();
+
+ for (uint i = 0; i < sizeof(commandTable) / sizeof(commandTable[0]); ++i) {
+ if (cmd == commandTable[i].name) {
+ clp.clearPositionalArguments();
+ clp.addPositionalArgument(cmd, commandTable[i].description, cmd);
+ return commandTable[i].command;
+ }
+ }
+ }
+ return NoCommand;
}
-Packager::Packager()
-{ }
-
-void Packager::execute() Q_DECL_NOEXCEPT_EXPR(false)
+int main(int argc, char *argv[])
{
- switch (m_mode) {
- case Create: {
- if (m_destinationName.isEmpty())
- throw Exception(Error::Package, "no destination package name given");
-
- QFile destination(m_destinationName);
- if (!destination.open(QIODevice::WriteOnly | QIODevice::Truncate))
- throw Exception(destination, "could not create package file");
-
- QString canonicalDestination = QFileInfo(destination).canonicalFilePath();
-
- QDir source(m_sourceDir);
- if (!source.exists())
- throw Exception(Error::Package, "source %1 is not a directory").arg(m_sourceDir);
-
- // check metadata
- YamlApplicationScanner yas;
- QString infoName = yas.metaDataFileName();
- QScopedPointer<Application> app(yas.scan(source.absoluteFilePath(infoName)));
-
- // build report
- InstallationReport report(app->id());
- report.addFile(infoName);
+ Package::ensureCorrectLocale();
- if (!QFile::exists(source.absoluteFilePath(app->icon())))
- throw Exception(Error::Package, "missing the 'icon.png' file");
- report.addFile(qSL("icon.png"));
+ QCoreApplication::setApplicationName(qSL("ApplicationManager Packager"));
+ QCoreApplication::setOrganizationName(qSL("Pelagicore AG"));
+ QCoreApplication::setOrganizationDomain(qSL("pelagicore.com"));
+ QCoreApplication::setApplicationVersion(qSL(AM_VERSION));
- // check executable
- if (!QFile::exists(source.absoluteFilePath(app->codeFilePath())))
- throw Exception(Error::Package, "missing the file referenced by the 'code' field");
+ QCoreApplication a(argc, argv);
- quint64 estimatedImageSize = 0;
- QString canonicalSourcePath = source.canonicalPath();
- QDirIterator it(source.absolutePath(), QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot, QDirIterator::Subdirectories);
-
- while (it.hasNext()) {
- it.next();
- QFileInfo entryInfo = it.fileInfo();
- QString entryPath = entryInfo.canonicalFilePath();
+ if (!Package::checkCorrectLocale()) {
+ fprintf(stderr, "ERROR: the packager needs a UTF-8 locale to work correctly:\n"
+ " even automatically switching to C.UTF-8 or en_US.UTF-8 failed.\n");
+ exit(2);
+ }
- // do not package the package itself, in case someone builds the package within the source dir
- if (canonicalDestination == entryPath)
- continue;
+ QString desc = qSL("\nPelagicore ApplicationManager packaging tool\n\nAvailable commands are:\n");
+ uint longestName = 0;
+ for (uint i = 0; i < sizeof(commandTable) / sizeof(commandTable[0]); ++i)
+ longestName = qMax(longestName, qstrlen(commandTable[i].name));
+ for (uint i = 0; i < sizeof(commandTable) / sizeof(commandTable[0]); ++i) {
+ desc += qSL(" %1%2 %3\n")
+ .arg(qL1S(commandTable[i].name),
+ QString(longestName - qstrlen(commandTable[i].name), qL1C(' ')),
+ qL1S(commandTable[i].description));
+ }
- if (!entryPath.startsWith(canonicalSourcePath))
- throw Exception(Error::Package, "file %1 is not inside the source directory %2").arg(entryPath).arg(canonicalSourcePath);
+ desc += qSL("\nMore information about each command can be obtained by running\n appman-packager <command> --help");
- // QDirIterator::filePath() returns absolute paths, although the naming suggests otherwise
- entryPath = entryPath.mid(canonicalSourcePath.size() + 1);
+ QCommandLineParser clp;
+ clp.setApplicationDescription(desc);
- if (entryInfo.fileName().startsWith(qL1S("--PACKAGE-")))
- throw Exception(Error::Package, "file names starting with --PACKAGE- are reserved by the packager (found: %1)").arg(entryPath);
+ clp.addHelpOption();
+ clp.addVersionOption();
- estimatedImageSize += (entryInfo.size() + Ext2BlockSize - 1) / Ext2BlockSize;
+ clp.addPositionalArgument(qSL("command"), qSL("The command to execute."));
- if (entryPath != infoName && entryPath != qL1S("icon.png"))
- report.addFile(entryPath);
- }
+ // ignore unknown options for now -- the sub-commands may need them later
+ clp.setOptionsAfterPositionalArgumentsMode(QCommandLineParser::ParseAsPositionalArguments);
- // we have the estimatedImageSize for the raw content now, but we need to add the inode
- // overhead still. This algorithm comes from buildroot:
- // http://git.buildroot.net/buildroot/tree/package/mke2img/mke2img
- estimatedImageSize = (500 + (estimatedImageSize + report.files().count() + 400 / 8) * 11 / 10) * Ext2BlockSize;
- report.setDiskSpaceUsed(estimatedImageSize);
+ if (!clp.parse(QCoreApplication::arguments())) {
+ fprintf(stderr, "%s\n", qPrintable(clp.errorText()));
+ exit(1);
+ }
+ clp.setOptionsAfterPositionalArgumentsMode(QCommandLineParser::ParseAsOptions);
- // finally create the package
- PackageCreator creator(source, &destination, report);
- if (!creator.create())
- throw Exception(Error::Package, "could not create package %1: %2").arg(app->id()).arg(creator.errorString());
+ PackagingJob *p = nullptr;
- QVariantMap md = creator.metaData();
- m_output = m_asJson ? QJsonDocument::fromVariant(md).toJson().constData()
- : QtYaml::yamlFromVariantDocuments({ md }).constData();
+ switch (command(clp)) {
+ default:
+ case NoCommand:
+ if (clp.isSet(qSL("version")))
+ clp.showVersion();
+ if (clp.isSet(qSL("help")))
+ clp.showHelp();
+ clp.showHelp(1);
break;
- }
- case DeveloperSign:
- case DeveloperVerify:
- case StoreSign:
- case StoreVerify: {
- if (!QFile::exists(m_sourceName))
- throw Exception(Error::Package, "package file %1 does not exist").arg(m_sourceName);
-
- // read certificates
- QList<QByteArray> certificates;
- for (const QString &cert : qAsConst(m_certificateFiles)) {
- QFile cf(cert);
- if (!cf.open(QIODevice::ReadOnly))
- throw Exception(cf, "could not open certificate file");
- certificates << cf.readAll();
- }
- // create temporary dir for extraction
- QTemporaryDir tmp;
- if (!tmp.isValid())
- throw Exception(Error::Package, "could not create temporary directory %1").arg(tmp.path());
-
- // extract source
- PackageExtractor extractor(QUrl::fromLocalFile(m_sourceName), tmp.path());
- if (!extractor.extract())
- throw Exception(Error::Package, "could not extract package %1: %2").arg(m_sourceName).arg(extractor.errorString());
-
- InstallationReport report = extractor.installationReport();
-
- // check signatures
- if (m_mode == DeveloperVerify) {
- if (report.developerSignature().isEmpty()) {
- m_output = qSL("no developer signature");
- m_resultCode = 1;
- } else {
- Signature sig(report.digest());
- if (!sig.verify(report.developerSignature(), certificates)) {
- m_output = qSL("invalid developer signature (") + sig.errorString() + qSL(")");
- m_resultCode = 2;
- } else {
- m_output = qSL("valid developer signature");
- }
- }
- break; // done with DeveloperVerify
-
- } else if (m_mode == StoreVerify) {
- if (report.storeSignature().isEmpty()) {
- m_output = qSL("no store signature");
- m_resultCode = 1;
- } else {
- QByteArray digestPlusId = QMessageAuthenticationCode::hash(report.digest(), m_hardwareId.toUtf8(), QCryptographicHash::Sha256);
- Signature sig(digestPlusId);
- if (!sig.verify(report.storeSignature(), certificates)) {
- m_output = qSL("invalid store signature (") + sig.errorString() + qSL(")");
- m_resultCode = 2;
- } else {
- m_output = qSL("valid store signature");
- }
+ case CreatePackage:
+ clp.addOption({ qSL("verbose"), qSL("Dump the package's meta-data header and footer information to stdout.") });
+ clp.addOption({ qSL("json"), qSL("Output in JSON format instead of YAML.") });
+ clp.addPositionalArgument(qSL("package"), qSL("The file name of the created package."));
+ clp.addPositionalArgument(qSL("source-directory"), qSL("The package's content root directory."));
+ clp.process(a);
- }
- break; // done with StoreVerify
- }
+ if (clp.positionalArguments().size() != 3)
+ clp.showHelp(1);
- // create a signed package
- if (m_destinationName.isEmpty())
- throw Exception(Error::Package, "no destination package name given");
+ p = PackagingJob::create(clp.positionalArguments().at(1),
+ clp.positionalArguments().at(2),
+ clp.isSet(qSL("json")));
+ break;
- QFile destination(m_destinationName);
- if (!destination.open(QIODevice::WriteOnly | QIODevice::Truncate))
- throw Exception(destination, "could not create package file");
+ case DevSignPackage:
+ clp.addOption({ qSL("verbose"), qSL("Dump the package's meta-data header and footer information to stdout.") });
+ clp.addOption({ qSL("json"), qSL("Output in JSON format instead of YAML.") });
+ clp.addPositionalArgument(qSL("package"), qSL("File name of the unsigned package (input)."));
+ clp.addPositionalArgument(qSL("signed-package"), qSL("File name of the signed package (output)."));
+ clp.addPositionalArgument(qSL("certificate"), qSL("PKCS#12 certificate file."));
+ clp.addPositionalArgument(qSL("password"), qSL("Password for the PKCS#12 certificate."));
+ clp.process(a);
+
+ if (clp.positionalArguments().size() != 5)
+ clp.showHelp(1);
+
+ p = PackagingJob::developerSign(clp.positionalArguments().at(1),
+ clp.positionalArguments().at(2),
+ clp.positionalArguments().at(3),
+ clp.positionalArguments().at(4),
+ clp.isSet(qSL("json")));
+ break;
- PackageCreator creator(tmp.path(), &destination, report);
+ case DevVerifyPackage:
+ clp.addOption({ qSL("verbose"), qSL("Print details regarding the verification to stdout.") });
+ clp.addPositionalArgument(qSL("package"), qSL("File name of the signed package (input)."));
+ clp.addPositionalArgument(qSL("certificates"), qSL("The developer's CA certificate file(s)."), qSL("certificates..."));
+ clp.process(a);
- if (certificates.size() != 1)
- throw Exception(Error::Package, "cannot sign packages with more than one certificate");
+ if (clp.positionalArguments().size() < 3)
+ clp.showHelp(1);
- if (m_mode == DeveloperSign) {
- Signature sig(report.digest());
- QByteArray signature = sig.create(certificates.first(), m_passphrase.toUtf8());
+ p = PackagingJob::developerVerify(clp.positionalArguments().at(1),
+ clp.positionalArguments().mid(2));
+ break;
- if (signature.isEmpty())
- throw Exception(Error::Package, "could not create signature: %1").arg(sig.errorString());
- report.setDeveloperSignature(signature);
- } else if (m_mode == StoreSign) {
- QByteArray digestPlusId = QMessageAuthenticationCode::hash(report.digest(), m_hardwareId.toUtf8(), QCryptographicHash::Sha256);
- Signature sig(digestPlusId);
- QByteArray signature = sig.create(certificates.first(), m_passphrase.toUtf8());
+ case StoreSignPackage:
+ clp.addOption({ qSL("verbose"), qSL("Dump the package's meta-data header and footer information to stdout.") });
+ clp.addOption({ qSL("json"), qSL("Output in JSON format instead of YAML.") });
+ clp.addPositionalArgument(qSL("package"), qSL("File name of the unsigned package (input)."));
+ clp.addPositionalArgument(qSL("signed-package"), qSL("File name of the signed package (output)."));
+ clp.addPositionalArgument(qSL("certificate"), qSL("PKCS#12 certificate file."));
+ clp.addPositionalArgument(qSL("password"), qSL("Password for the PKCS#12 certificate."));
+ clp.addPositionalArgument(qSL("hardware-id"), qSL("Unique hardware id to which this package gets bound."));
+ clp.process(a);
+
+ if (clp.positionalArguments().size() != 6)
+ clp.showHelp(1);
+
+ p = PackagingJob::storeSign(clp.positionalArguments().at(1),
+ clp.positionalArguments().at(2),
+ clp.positionalArguments().at(3),
+ clp.positionalArguments().at(4),
+ clp.positionalArguments().at(5),
+ clp.isSet(qSL("json")));
+ break;
- if (signature.isEmpty())
- throw Exception(Error::Package, "could not create signature: %1").arg(sig.errorString());
- report.setStoreSignature(signature);
- }
+ case StoreVerifyPackage:
+ clp.addOption({ qSL("verbose"), qSL("Print details regarding the verification to stdout.") });
+ clp.addPositionalArgument(qSL("package"), qSL("File name of the signed package (input)."));
+ clp.addPositionalArgument(qSL("certificates"), qSL("Store CA certificate file(s)."), qSL("certificates..."));
+ clp.addPositionalArgument(qSL("hardware-id"), qSL("Unique hardware id to which this package was bound."));
+ clp.process(a);
- if (!creator.create())
- throw Exception(Error::Package, "could not create package %1: %2").arg(m_destinationName).arg(creator.errorString());
+ if (clp.positionalArguments().size() < 4)
+ clp.showHelp(1);
- QVariantMap md = creator.metaData();
- m_output = m_asJson ? QJsonDocument::fromVariant(md).toJson().constData()
- : QtYaml::yamlFromVariantDocuments({ md }).constData();
+ p = PackagingJob::storeVerify(clp.positionalArguments().at(1),
+ clp.positionalArguments().mid(2, clp.positionalArguments().size() - 2),
+ *--clp.positionalArguments().cend());
break;
}
- default:
- throw Exception("invalid mode");
+
+ if (!p)
+ return 2;
+ try {
+ p->execute();
+ if (clp.isSet(qSL("verbose")) && !p->output().isEmpty())
+ fprintf(stdout, "%s\n", qPrintable(p->output()));
+ return p->resultCode();
+ } catch (const Exception &e) {
+ fprintf(stderr, "ERROR: %s\n", qPrintable(e.errorString()));
+ return 1;
}
}
diff --git a/src/tools/packager/packager.pro b/src/tools/packager/packager.pro
index 2e6fab05..fba890af 100644
--- a/src/tools/packager/packager.pro
+++ b/src/tools/packager/packager.pro
@@ -13,11 +13,11 @@ QT *= \
CONFIG *= console
SOURCES += \
- main.cpp \
- packager.cpp
+ packager.cpp \
+ packagingjob.cpp \
HEADERS += \
- packager.h
+ packagingjob.h \
load(qt_tool)
diff --git a/src/tools/packager/packagingjob.cpp b/src/tools/packager/packagingjob.cpp
new file mode 100644
index 00000000..9551fe3e
--- /dev/null
+++ b/src/tools/packager/packagingjob.cpp
@@ -0,0 +1,310 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 Pelagicore AG
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Pelagicore Application Manager.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT-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 General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** 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-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QFile>
+#include <QFileInfo>
+#include <QUrl>
+#include <QRegExp>
+#include <QDirIterator>
+#include <QMessageAuthenticationCode>
+#include <QJsonDocument>
+#include <QTemporaryDir>
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "exception.h"
+#include "signature.h"
+#include "qtyaml.h"
+#include "application.h"
+#include "installationreport.h"
+#include "yamlapplicationscanner.h"
+#include "packageextractor.h"
+#include "packagecreator.h"
+
+#include "packagingjob.h"
+
+QT_USE_NAMESPACE_AM
+
+// this corresponds to the -b parameter for mkfs.ext2 in sudo.cpp
+static const int Ext2BlockSize = 1024;
+
+
+PackagingJob *PackagingJob::create(const QString &destinationName, const QString &sourceDir, bool asJson)
+{
+ PackagingJob *p = new PackagingJob();
+ p->m_mode = Create;
+ p->m_asJson = asJson;
+ p->m_destinationName = destinationName;
+ p->m_sourceDir = sourceDir;
+ return p;
+}
+
+PackagingJob *PackagingJob::developerSign(const QString &sourceName, const QString &destinationName,
+ const QString &certificateFile, const QString &passPhrase,
+ bool asJson)
+{
+ PackagingJob *p = new PackagingJob();
+ p->m_mode = DeveloperSign;
+ p->m_asJson = asJson;
+ p->m_sourceName = sourceName;
+ p->m_destinationName = destinationName;
+ p->m_passphrase = passPhrase;
+ p->m_certificateFiles = QStringList { certificateFile };
+ return p;
+}
+
+PackagingJob *PackagingJob::developerVerify(const QString &sourceName, const QStringList &certificateFiles)
+{
+ PackagingJob *p = new PackagingJob();
+ p->m_mode = DeveloperVerify;
+ p->m_sourceName = sourceName;
+ p->m_certificateFiles = certificateFiles;
+ return p;
+}
+
+PackagingJob *PackagingJob::storeSign(const QString &sourceName, const QString &destinationName,
+ const QString &certificateFile, const QString &passPhrase,
+ const QString &hardwareId, bool asJson)
+{
+ PackagingJob *p = new PackagingJob();
+ p->m_mode = StoreSign;
+ p->m_asJson = asJson;
+ p->m_sourceName = sourceName;
+ p->m_destinationName = destinationName;
+ p->m_passphrase = passPhrase;
+ p->m_certificateFiles = QStringList { certificateFile };
+ p->m_hardwareId = hardwareId;
+ return p;
+}
+
+PackagingJob *PackagingJob::storeVerify(const QString &sourceName, const QStringList &certificateFiles, const QString &hardwareId)
+{
+ PackagingJob *p = new PackagingJob();
+ p->m_mode = StoreVerify;
+ p->m_sourceName = sourceName;
+ p->m_certificateFiles = certificateFiles;
+ p->m_hardwareId = hardwareId;
+ return p;
+}
+
+QString PackagingJob::output() const
+{
+ return m_output;
+}
+
+int PackagingJob::resultCode() const
+{
+ return m_resultCode;
+}
+
+PackagingJob::PackagingJob()
+{ }
+
+void PackagingJob::execute() Q_DECL_NOEXCEPT_EXPR(false)
+{
+ switch (m_mode) {
+ case Create: {
+ if (m_destinationName.isEmpty())
+ throw Exception(Error::Package, "no destination package name given");
+
+ QFile destination(m_destinationName);
+ if (!destination.open(QIODevice::WriteOnly | QIODevice::Truncate))
+ throw Exception(destination, "could not create package file");
+
+ QString canonicalDestination = QFileInfo(destination).canonicalFilePath();
+
+ QDir source(m_sourceDir);
+ if (!source.exists())
+ throw Exception(Error::Package, "source %1 is not a directory").arg(m_sourceDir);
+
+ // check metadata
+ YamlApplicationScanner yas;
+ QString infoName = yas.metaDataFileName();
+ QScopedPointer<Application> app(yas.scan(source.absoluteFilePath(infoName)));
+
+ // build report
+ InstallationReport report(app->id());
+ report.addFile(infoName);
+
+ if (!QFile::exists(source.absoluteFilePath(app->icon())))
+ throw Exception(Error::Package, "missing the 'icon.png' file");
+ report.addFile(qSL("icon.png"));
+
+ // check executable
+ if (!QFile::exists(source.absoluteFilePath(app->codeFilePath())))
+ throw Exception(Error::Package, "missing the file referenced by the 'code' field");
+
+ quint64 estimatedImageSize = 0;
+ QString canonicalSourcePath = source.canonicalPath();
+ QDirIterator it(source.absolutePath(), QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot, QDirIterator::Subdirectories);
+
+ while (it.hasNext()) {
+ it.next();
+ QFileInfo entryInfo = it.fileInfo();
+ QString entryPath = entryInfo.canonicalFilePath();
+
+ // do not package the package itself, in case someone builds the package within the source dir
+ if (canonicalDestination == entryPath)
+ continue;
+
+ if (!entryPath.startsWith(canonicalSourcePath))
+ throw Exception(Error::Package, "file %1 is not inside the source directory %2").arg(entryPath).arg(canonicalSourcePath);
+
+ // QDirIterator::filePath() returns absolute paths, although the naming suggests otherwise
+ entryPath = entryPath.mid(canonicalSourcePath.size() + 1);
+
+ if (entryInfo.fileName().startsWith(qL1S("--PACKAGE-")))
+ throw Exception(Error::Package, "file names starting with --PACKAGE- are reserved by the packager (found: %1)").arg(entryPath);
+
+ estimatedImageSize += (entryInfo.size() + Ext2BlockSize - 1) / Ext2BlockSize;
+
+ if (entryPath != infoName && entryPath != qL1S("icon.png"))
+ report.addFile(entryPath);
+ }
+
+ // we have the estimatedImageSize for the raw content now, but we need to add the inode
+ // overhead still. This algorithm comes from buildroot:
+ // http://git.buildroot.net/buildroot/tree/package/mke2img/mke2img
+ estimatedImageSize = (500 + (estimatedImageSize + report.files().count() + 400 / 8) * 11 / 10) * Ext2BlockSize;
+ report.setDiskSpaceUsed(estimatedImageSize);
+
+ // finally create the package
+ PackageCreator creator(source, &destination, report);
+ if (!creator.create())
+ throw Exception(Error::Package, "could not create package %1: %2").arg(app->id()).arg(creator.errorString());
+
+ QVariantMap md = creator.metaData();
+ m_output = m_asJson ? QJsonDocument::fromVariant(md).toJson().constData()
+ : QtYaml::yamlFromVariantDocuments({ md }).constData();
+ break;
+ }
+ case DeveloperSign:
+ case DeveloperVerify:
+ case StoreSign:
+ case StoreVerify: {
+ if (!QFile::exists(m_sourceName))
+ throw Exception(Error::Package, "package file %1 does not exist").arg(m_sourceName);
+
+ // read certificates
+ QList<QByteArray> certificates;
+ for (const QString &cert : qAsConst(m_certificateFiles)) {
+ QFile cf(cert);
+ if (!cf.open(QIODevice::ReadOnly))
+ throw Exception(cf, "could not open certificate file");
+ certificates << cf.readAll();
+ }
+
+ // create temporary dir for extraction
+ QTemporaryDir tmp;
+ if (!tmp.isValid())
+ throw Exception(Error::Package, "could not create temporary directory %1").arg(tmp.path());
+
+ // extract source
+ PackageExtractor extractor(QUrl::fromLocalFile(m_sourceName), tmp.path());
+ if (!extractor.extract())
+ throw Exception(Error::Package, "could not extract package %1: %2").arg(m_sourceName).arg(extractor.errorString());
+
+ InstallationReport report = extractor.installationReport();
+
+ // check signatures
+ if (m_mode == DeveloperVerify) {
+ if (report.developerSignature().isEmpty()) {
+ m_output = qSL("no developer signature");
+ m_resultCode = 1;
+ } else {
+ Signature sig(report.digest());
+ if (!sig.verify(report.developerSignature(), certificates)) {
+ m_output = qSL("invalid developer signature (") + sig.errorString() + qSL(")");
+ m_resultCode = 2;
+ } else {
+ m_output = qSL("valid developer signature");
+ }
+ }
+ break; // done with DeveloperVerify
+
+ } else if (m_mode == StoreVerify) {
+ if (report.storeSignature().isEmpty()) {
+ m_output = qSL("no store signature");
+ m_resultCode = 1;
+ } else {
+ QByteArray digestPlusId = QMessageAuthenticationCode::hash(report.digest(), m_hardwareId.toUtf8(), QCryptographicHash::Sha256);
+ Signature sig(digestPlusId);
+ if (!sig.verify(report.storeSignature(), certificates)) {
+ m_output = qSL("invalid store signature (") + sig.errorString() + qSL(")");
+ m_resultCode = 2;
+ } else {
+ m_output = qSL("valid store signature");
+ }
+
+ }
+ break; // done with StoreVerify
+ }
+
+ // create a signed package
+ if (m_destinationName.isEmpty())
+ throw Exception(Error::Package, "no destination package name given");
+
+ QFile destination(m_destinationName);
+ if (!destination.open(QIODevice::WriteOnly | QIODevice::Truncate))
+ throw Exception(destination, "could not create package file");
+
+ PackageCreator creator(tmp.path(), &destination, report);
+
+ if (certificates.size() != 1)
+ throw Exception(Error::Package, "cannot sign packages with more than one certificate");
+
+ if (m_mode == DeveloperSign) {
+ Signature sig(report.digest());
+ QByteArray signature = sig.create(certificates.first(), m_passphrase.toUtf8());
+
+ if (signature.isEmpty())
+ throw Exception(Error::Package, "could not create signature: %1").arg(sig.errorString());
+ report.setDeveloperSignature(signature);
+ } else if (m_mode == StoreSign) {
+ QByteArray digestPlusId = QMessageAuthenticationCode::hash(report.digest(), m_hardwareId.toUtf8(), QCryptographicHash::Sha256);
+ Signature sig(digestPlusId);
+ QByteArray signature = sig.create(certificates.first(), m_passphrase.toUtf8());
+
+ if (signature.isEmpty())
+ throw Exception(Error::Package, "could not create signature: %1").arg(sig.errorString());
+ report.setStoreSignature(signature);
+ }
+
+ if (!creator.create())
+ throw Exception(Error::Package, "could not create package %1: %2").arg(m_destinationName).arg(creator.errorString());
+
+ QVariantMap md = creator.metaData();
+ m_output = m_asJson ? QJsonDocument::fromVariant(md).toJson().constData()
+ : QtYaml::yamlFromVariantDocuments({ md }).constData();
+ break;
+ }
+ default:
+ throw Exception("invalid mode");
+ }
+}
diff --git a/src/tools/packager/packager.h b/src/tools/packager/packagingjob.h
index 22e5376f..9b22c90a 100644
--- a/src/tools/packager/packager.h
+++ b/src/tools/packager/packagingjob.h
@@ -32,21 +32,21 @@
#include <QByteArray>
#include <QString>
-class Packager
+class PackagingJob
{
public:
- static Packager *create(const QString &destinationName, const QString &sourceDir, bool asJson = false);
+ static PackagingJob *create(const QString &destinationName, const QString &sourceDir, bool asJson = false);
- static Packager *developerSign(const QString &sourceName, const QString &destinationName,
- const QString &certificateFile, const QString &passPhrase,
- bool asJson = false);
- static Packager *developerVerify(const QString &sourceName, const QStringList &certificateFiles);
+ static PackagingJob *developerSign(const QString &sourceName, const QString &destinationName,
+ const QString &certificateFile, const QString &passPhrase,
+ bool asJson = false);
+ static PackagingJob *developerVerify(const QString &sourceName, const QStringList &certificateFiles);
- static Packager *storeSign(const QString &sourceName, const QString &destinationName,
- const QString &certificateFile, const QString &passPhrase,
- const QString &hardwareId, bool asJson = false);
- static Packager *storeVerify(const QString &sourceName, const QStringList &certificateFiles,
- const QString &hardwareId);
+ static PackagingJob *storeSign(const QString &sourceName, const QString &destinationName,
+ const QString &certificateFile, const QString &passPhrase,
+ const QString &hardwareId, bool asJson = false);
+ static PackagingJob *storeVerify(const QString &sourceName, const QStringList &certificateFiles,
+ const QString &hardwareId);
void execute() Q_DECL_NOEXCEPT_EXPR(false);
@@ -54,7 +54,7 @@ public:
int resultCode() const;
private:
- Packager();
+ PackagingJob();
enum Mode {
Create,
diff --git a/src/tools/testrunner/testrunner.pro b/src/tools/testrunner/testrunner.pro
index 432e2409..02825d1f 100644
--- a/src/tools/testrunner/testrunner.pro
+++ b/src/tools/testrunner/testrunner.pro
@@ -1,9 +1,10 @@
-TEMPLATE = app
+include(../appman/appman.pro)
+
TARGET = appman-qmltestrunner
DEFINES += AM_TESTRUNNER
-include($$PWD/../../manager/manager.pri)
+CONFIG *= console
QT += qmltest qmltest-private
diff --git a/src/tools/tools.pro b/src/tools/tools.pro
deleted file mode 100644
index 181ebdc1..00000000
--- a/src/tools/tools.pro
+++ /dev/null
@@ -1,18 +0,0 @@
-
-TEMPLATE = subdirs
-
-!tools-only {
- # Although the testrunner is in tools we don't want to build it with tools-only
- # because it is based on the manager binary
- SUBDIRS += testrunner
-
- # This tool links against everything to extract the Qml type information
- qtHaveModule(qml):qtHaveModule(dbus):SUBDIRS += dumpqmltypes
-}
-
-!android:SUBDIRS += \
- packager \
- deployer \
-
-qtHaveModule(dbus):SUBDIRS += \
- controller \
diff --git a/src/window-lib/waylandcompositor.h b/src/window-lib/waylandcompositor.h
index 9cc77ddb..79f863e1 100644
--- a/src/window-lib/waylandcompositor.h
+++ b/src/window-lib/waylandcompositor.h
@@ -42,6 +42,10 @@
#pragma once
+#include <QtAppManCommon/global.h>
+
+#if defined(AM_MULTI_PROCESS)
+
#include <QWaylandQuickCompositor>
#include <QtAppManWindow/windowmanager.h>
@@ -155,3 +159,5 @@ private:
};
QT_END_NAMESPACE_AM
+
+#endif // AM_MULTIPROCESS
diff --git a/sync.profile b/sync.profile
index 01485f1b..4f5281ab 100644
--- a/sync.profile
+++ b/sync.profile
@@ -5,6 +5,7 @@
"QtAppManPackage" => "$basedir/src/package-lib",
"QtAppManNotification" => "$basedir/src/notification-lib",
"QtAppManManager" => "$basedir/src/manager-lib",
+ "QtAppManMain" => "$basedir/src/main-lib",
"QtAppManWindow" => "$basedir/src/window-lib",
"QtAppManInstaller" => "$basedir/src/installer-lib",
"QtAppManLauncher" => "$basedir/src/launcher-lib",
diff --git a/tests/packager-tool/packager-tool.pro b/tests/packager-tool/packager-tool.pro
index a7b8d472..214995bb 100644
--- a/tests/packager-tool/packager-tool.pro
+++ b/tests/packager-tool/packager-tool.pro
@@ -13,6 +13,6 @@ QT *= \
appman_installer-private \
INCLUDEPATH += ../../src/tools/packager
-SOURCES += ../../src/tools/packager/packager.cpp
+SOURCES += ../../src/tools/packager/packagingjob.cpp
SOURCES += tst_packager-tool.cpp
diff --git a/tests/packager-tool/tst_packager-tool.cpp b/tests/packager-tool/tst_packager-tool.cpp
index 5d4404d8..652f453d 100644
--- a/tests/packager-tool/tst_packager-tool.cpp
+++ b/tests/packager-tool/tst_packager-tool.cpp
@@ -35,7 +35,7 @@
#include "application.h"
#include "qtyaml.h"
#include "exception.h"
-#include "packager.h"
+#include "packagingjob.h"
#include "applicationinstaller.h"
#include "qmlinprocessruntime.h"
#include "runtimefactory.h"
@@ -135,7 +135,7 @@ void tst_PackagerTool::initTestCase()
// exceptions are nice -- just not for unit testing :)
-static bool packagerCheck(Packager *p, QString &errorString)
+static bool packagerCheck(PackagingJob *p, QString &errorString)
{
bool result = false;
try {
@@ -156,39 +156,39 @@ void tst_PackagerTool::test()
QString hardwareId = "foobar";
// no valid destination
- QVERIFY(!packagerCheck(Packager::create(pathTo("test.appkg"), pathTo("test.appkg")), errorString));
+ QVERIFY(!packagerCheck(PackagingJob::create(pathTo("test.appkg"), pathTo("test.appkg")), errorString));
QVERIFY2(errorString.contains(qL1S("not a directory")), qPrintable(errorString));
// no valid info.yaml
- QVERIFY(!packagerCheck(Packager::create(pathTo("test.appkg"), tmp.path()), errorString));
+ QVERIFY(!packagerCheck(PackagingJob::create(pathTo("test.appkg"), tmp.path()), errorString));
QVERIFY2(errorString.contains(qL1S("could not open file for reading")), qPrintable(errorString));
// add an info.yaml file
createInfoYaml(tmp);
// no icon
- QVERIFY(!packagerCheck(Packager::create(pathTo("test.appkg"), tmp.path()), errorString));
+ QVERIFY(!packagerCheck(PackagingJob::create(pathTo("test.appkg"), tmp.path()), errorString));
QVERIFY2(errorString.contains(qL1S("missing the 'icon.png' file")), qPrintable(errorString));
// add an icon
createIconPng(tmp);
// no valid code
- QVERIFY(!packagerCheck(Packager::create(pathTo("test.appkg"), tmp.path()), errorString));
+ QVERIFY(!packagerCheck(PackagingJob::create(pathTo("test.appkg"), tmp.path()), errorString));
QVERIFY2(errorString.contains(qL1S("missing the file referenced by the 'code' field")), qPrintable(errorString));
// add a code file
createCode(tmp);
// invalid destination
- QVERIFY(!packagerCheck(Packager::create(tmp.path(), tmp.path()), errorString));
+ QVERIFY(!packagerCheck(PackagingJob::create(tmp.path(), tmp.path()), errorString));
QVERIFY2(errorString.contains(qL1S("could not create package file")), qPrintable(errorString));
// now everything is correct - try again
- QVERIFY2(packagerCheck(Packager::create(pathTo("test.appkg"), tmp.path()), errorString), qPrintable(errorString));
+ QVERIFY2(packagerCheck(PackagingJob::create(pathTo("test.appkg"), tmp.path()), errorString), qPrintable(errorString));
// invalid source package
- QVERIFY(!packagerCheck(Packager::developerSign(
+ QVERIFY(!packagerCheck(PackagingJob::developerSign(
pathTo("no-such-file"),
pathTo("test.dev-signed.appkg"),
m_devCertificate,
@@ -196,7 +196,7 @@ void tst_PackagerTool::test()
QVERIFY2(errorString.contains(qL1S("does not exist")), qPrintable(errorString));
// invalid destination package
- QVERIFY(!packagerCheck(Packager::developerSign(
+ QVERIFY(!packagerCheck(PackagingJob::developerSign(
pathTo("test.appkg"),
pathTo("."),
m_devCertificate,
@@ -205,7 +205,7 @@ void tst_PackagerTool::test()
// invalid dev key
- QVERIFY(!packagerCheck(Packager::developerSign(
+ QVERIFY(!packagerCheck(PackagingJob::developerSign(
pathTo("test.appkg"),
pathTo("test.dev-signed.appkg"),
m_devCertificate,
@@ -213,7 +213,7 @@ void tst_PackagerTool::test()
QVERIFY2(errorString.contains(qL1S("could not create signature")), qPrintable(errorString));
// invalid store key
- QVERIFY(!packagerCheck(Packager::storeSign(
+ QVERIFY(!packagerCheck(PackagingJob::storeSign(
pathTo("test.appkg"),
pathTo("test.store-signed.appkg"),
m_storeCertificate,
@@ -222,13 +222,13 @@ void tst_PackagerTool::test()
QVERIFY2(errorString.contains(qL1S("could not create signature")), qPrintable(errorString));
// sign
- QVERIFY2(packagerCheck(Packager::developerSign(
+ QVERIFY2(packagerCheck(PackagingJob::developerSign(
pathTo("test.appkg"),
pathTo("test.dev-signed.appkg"),
m_devCertificate,
m_devPassword), errorString), qPrintable(errorString));
- QVERIFY2(packagerCheck(Packager::storeSign(
+ QVERIFY2(packagerCheck(PackagingJob::storeSign(
pathTo("test.appkg"),
pathTo("test.store-signed.appkg"),
m_storeCertificate,
@@ -236,11 +236,11 @@ void tst_PackagerTool::test()
hardwareId), errorString), qPrintable(errorString));
// verify
- QVERIFY2(packagerCheck(Packager::developerVerify(
+ QVERIFY2(packagerCheck(PackagingJob::developerVerify(
pathTo("test.dev-signed.appkg"),
m_caFiles), errorString), qPrintable(errorString));
- QVERIFY2(packagerCheck(Packager::storeVerify(
+ QVERIFY2(packagerCheck(PackagingJob::storeVerify(
pathTo("test.store-signed.appkg"),
m_caFiles,
hardwareId), errorString), qPrintable(errorString));
@@ -299,7 +299,7 @@ void tst_PackagerTool::brokenMetadata()
// check if packaging actually fails with the expected error
QString error;
- QVERIFY(!packagerCheck(Packager::create(pathTo("test.appkg"), tmp.path()), error));
+ QVERIFY(!packagerCheck(PackagingJob::create(pathTo("test.appkg"), tmp.path()), error));
AM_CHECK_ERRORSTRING(error, errorString);
}