diff options
author | Robert Griebl <robert.griebl@qt.io> | 2020-01-21 16:01:44 +0100 |
---|---|---|
committer | Robert Griebl <robert.griebl@qt.io> | 2020-01-21 16:13:18 +0100 |
commit | 6393474dc5f8de581c5d2c07946d22990ff0f004 (patch) | |
tree | 624cd1e393b2ef5e3f6507523aeb00a10d98bcfd | |
parent | ea1421e218e330e27e1f059e55a6d6babb1f7c69 (diff) | |
parent | 0c69e083ac5f5e97c9da09bdf1bd979dbe87ea93 (diff) | |
download | qtapplicationmanager-6393474dc5f8de581c5d2c07946d22990ff0f004.tar.gz |
Merge remote-tracking branch 'gerrit/5.13' into 5.14
Change-Id: I3e8a149be99266ad6438759fda9acb1c9dd12448
26 files changed, 318 insertions, 70 deletions
diff --git a/doc/applicationmanager-project.qdocconf b/doc/applicationmanager-project.qdocconf index 9db69b01..0e70d0d8 100644 --- a/doc/applicationmanager-project.qdocconf +++ b/doc/applicationmanager-project.qdocconf @@ -9,7 +9,7 @@ includepaths = -I . sources.fileextensions = "*.cpp *.qdoc *.mm *.qml" headers.fileextensions = "*.h *.ch *.h++ *.hh *.hpp *.hxx" -examples.fileextensions = "*.qml *.yaml" +examples.fileextensions = "*.cpp *.h *.qml *.yaml" examples.imageextensions = "*.png *.jpg *.gif" include(config/exampleurl-qtapplicationmanager.qdocconf) @@ -21,7 +21,6 @@ headerdirs += \ ../src/manager-lib \ ../src/application-lib \ ../src/package-lib \ - ../src/installer-lib \ ../src/intent-client-lib \ ../src/intent-server-lib \ ../src/notification-lib \ @@ -39,7 +38,6 @@ sourcedirs += \ ../src/manager-lib \ ../src/application-lib \ ../src/package-lib \ - ../src/installer-lib \ ../src/intent-client-lib \ ../src/intent-server-lib \ ../src/notification-lib \ diff --git a/qmake-features/am-app.prf b/qmake-features/am-app.prf index fe2f590a..0ca6d1fd 100644 --- a/qmake-features/am-app.prf +++ b/qmake-features/am-app.prf @@ -11,6 +11,10 @@ AM_MANIFEST_PATH = $$absolute_path($$AM_MANIFEST, $$_PRO_FILE_PWD_) # Call the appman-packager to convert the yaml to JSON to parse it here qtPrepareTool(APPMAN_PACKAGER, appman-packager, , system) +!exists($$APPMAN_PACKAGER): { + warning("Couldn't add the 'package' step, due to the missing appman-packager binary") + return() +} JSON = $$system($$APPMAN_PACKAGER yaml-to-json -i1 $$system_quote($$AM_MANIFEST_PATH)) parseJson(JSON, INFO)| error("Failed to parse appman-packager output.") diff --git a/src/common-lib/crashhandler.cpp b/src/common-lib/crashhandler.cpp index 95ec9b9f..fd196dff 100644 --- a/src/common-lib/crashhandler.cpp +++ b/src/common-lib/crashhandler.cpp @@ -145,7 +145,7 @@ static void initBacktrace() getOutputInformation(&useAnsiColor, nullptr, nullptr); - demangleBufferSize = 512; + demangleBufferSize = 768; demangleBuffer = static_cast<char *>(malloc(demangleBufferSize)); UnixSignalHandler::instance()->install(UnixSignalHandler::RawSignalHandler, @@ -171,7 +171,7 @@ static void initBacktrace() const char *typeName = type->name(); if (typeName) { int status; - abi::__cxa_demangle(typeName, demangleBuffer, &demangleBufferSize, &status); + demangleBuffer = abi::__cxa_demangle(typeName, demangleBuffer, &demangleBufferSize, &status); if (status == 0 && *demangleBuffer) { typeName = demangleBuffer; } @@ -271,7 +271,7 @@ static void printCrashInfo(PrintDestination dest, const char *why, int stackFram int level = static_cast<btData *>(data)->level; if (symname) { int status; - abi::__cxa_demangle(symname, demangleBuffer, &demangleBufferSize, &status); + demangleBuffer = abi::__cxa_demangle(symname, demangleBuffer, &demangleBufferSize, &status); if (status == 0 && *demangleBuffer) printBacktraceLine(level, demangleBuffer, pc); @@ -286,7 +286,7 @@ static void printCrashInfo(PrintDestination dest, const char *why, int stackFram const char *function) -> int { if (function) { int status; - abi::__cxa_demangle(function, demangleBuffer, &demangleBufferSize, &status); + demangleBuffer = abi::__cxa_demangle(function, demangleBuffer, &demangleBufferSize, &status); printBacktraceLine(static_cast<btData *>(data)->level, (status == 0 && *demangleBuffer) ? demangleBuffer : function, @@ -344,7 +344,7 @@ static void printCrashInfo(PrintDestination dest, const char *why, int stackFram *end = 0; int status; - abi::__cxa_demangle(function, demangleBuffer, &demangleBufferSize, &status); + demangleBuffer = abi::__cxa_demangle(function, demangleBuffer, &demangleBufferSize, &status); if (status == 0 && *demangleBuffer) { printMsg(" %3d: %s [+%s]", i, demangleBuffer, offset + 1); diff --git a/src/common-lib/logging.cpp b/src/common-lib/logging.cpp index bce03e6d..74d9a7c6 100644 --- a/src/common-lib/logging.cpp +++ b/src/common-lib/logging.cpp @@ -387,11 +387,10 @@ void Logging::setFilterRules(const QStringList &rules) void Logging::setMessagePattern(const QString &pattern) { - if (!pattern.isEmpty()) { - if (!s_messagePatternDefined) { - qputenv("QT_MESSAGE_PATTERN", pattern.toLocal8Bit()); - s_messagePatternDefined = true; - } + if (!pattern.isEmpty() && !s_messagePatternDefined) { + qputenv("QT_MESSAGE_PATTERN", pattern.toLocal8Bit()); // pass on to application processes, however for the + qSetMessagePattern(pattern); // System UI this might be too late, so set pattern explicitly here. + s_messagePatternDefined = true; } } diff --git a/src/manager-lib/nativeruntime.cpp b/src/manager-lib/nativeruntime.cpp index aee5ad7f..5313a3b3 100644 --- a/src/manager-lib/nativeruntime.cpp +++ b/src/manager-lib/nativeruntime.cpp @@ -106,8 +106,9 @@ NativeRuntime::NativeRuntime(AbstractContainer *container, Application *app, Nat , m_isQuickLauncher(app == nullptr) , m_startedViaLauncher(manager->identifier() != qL1S("native")) { + QDir().mkdir(qSL("/tmp/dbus-qtam")); QString dbusAddress = QUuid::createUuid().toString().mid(1,36); - m_applicationInterfaceServer = new QDBusServer(qSL("unix:path=/tmp/dbus-qtam-") + dbusAddress, this); + m_applicationInterfaceServer = new QDBusServer(qSL("unix:path=/tmp/dbus-qtam/dbus-qtam-") + dbusAddress, this); connect(m_applicationInterfaceServer, &QDBusServer::newConnection, this, [this](const QDBusConnection &connection) { diff --git a/src/manager-lib/package.cpp b/src/manager-lib/package.cpp index 7ad4b1cf..e180fc7b 100644 --- a/src/manager-lib/package.cpp +++ b/src/manager-lib/package.cpp @@ -208,6 +208,7 @@ bool Package::block() bool blockedNow = (m_blocked.fetchAndAddOrdered(1) == 0); if (blockedNow) { m_blockedApps = info()->applications(); + m_blockedAppsCount = m_blockedApps.count(); emit blockedChanged(true); } return blockedNow; @@ -218,6 +219,7 @@ bool Package::unblock() bool unblockedNow = (m_blocked.fetchAndSubOrdered(1) == 1); if (unblockedNow) { m_blockedApps.clear(); + m_blockedAppsCount = 0; emit blockedChanged(false); } return unblockedNow; @@ -234,11 +236,12 @@ void Package::applicationStoppedDueToBlock(const QString &appId) }); if (it != m_blockedApps.cend()) m_blockedApps.removeOne(*it); + m_blockedAppsCount = m_blockedApps.count(); } bool Package::areAllApplicationsStoppedDueToBlock() const { - return isBlocked() && m_blockedApps.isEmpty(); + return isBlocked() && !m_blockedAppsCount; } QT_END_NAMESPACE_AM diff --git a/src/manager-lib/package.h b/src/manager-lib/package.h index 690059f0..d8513bb1 100644 --- a/src/manager-lib/package.h +++ b/src/manager-lib/package.h @@ -142,6 +142,7 @@ private: State m_state = Installed; qreal m_progress = 0; QAtomicInt m_blocked; + QAtomicInt m_blockedAppsCount; QVector<ApplicationInfo *> m_blockedApps; }; diff --git a/src/manager-lib/processstatus.cpp b/src/manager-lib/processstatus.cpp index 2445b030..3f1ee50c 100644 --- a/src/manager-lib/processstatus.cpp +++ b/src/manager-lib/processstatus.cpp @@ -125,25 +125,53 @@ \endtable */ +/*! + \qmlsignal ProcessStatus::memoryReportingChanged(memoryVirtual, memoryRss, memoryPss) + + This signal is emitted after \l{ProcessStatus::update()}{update()} has been called and the + memory usage values have been refreshed. The arguments are key-value pairs with the keys listed + in the table \l{supported-keys}{above}. +*/ + + QT_USE_NAMESPACE_AM QThread *ProcessStatus::m_workerThread = nullptr; +int ProcessStatus::m_instanceCount = 0; ProcessStatus::ProcessStatus(QObject *parent) : QObject(parent) { - if (!m_workerThread) { + if (m_instanceCount == 0) { m_workerThread = new QThread; m_workerThread->start(); } + ++m_instanceCount; + + m_reader = new ProcessReader; + m_reader->moveToThread(m_workerThread); - m_reader.reset(new ProcessReader); - connect(m_reader.data(), &ProcessReader::updated, this, [this]() { + connect(m_reader, &ProcessReader::updated, this, [this]() { emit cpuLoadChanged(); fetchMemoryReadings(); + emit memoryReportingChanged(m_memoryVirtual, m_memoryRss, m_memoryPss); m_pendingUpdate = false; }); - connect(this, &ProcessStatus::processIdChanged, m_reader.data(), &ProcessReader::setProcessId); + connect(this, &ProcessStatus::processIdChanged, m_reader, &ProcessReader::setProcessId); + connect(this, &ProcessStatus::memoryReportingEnabledChanged, m_reader, &ProcessReader::enableMemoryReporting); +} + +ProcessStatus::~ProcessStatus() +{ + m_reader->deleteLater(); + + --m_instanceCount; + if (m_instanceCount == 0) { + m_workerThread->quit(); + m_workerThread->wait(); + delete m_workerThread; + m_workerThread = nullptr; + } } /*! @@ -155,7 +183,7 @@ void ProcessStatus::update() { if (!m_pendingUpdate) { m_pendingUpdate = true; - QMetaObject::invokeMethod(m_reader.data(), &ProcessReader::update); + QMetaObject::invokeMethod(m_reader, &ProcessReader::update); } } @@ -250,8 +278,7 @@ qint64 ProcessStatus::processId() const */ qreal ProcessStatus::cpuLoad() { - quint32 value = m_reader->cpuLoad.load(); - return ((qreal)value) / ((qreal)std::numeric_limits<quint32>::max()); + return m_reader->cpuLoad.load() / ProcessReader::cpuLoadFactor; } void ProcessStatus::fetchMemoryReadings() @@ -266,8 +293,6 @@ void ProcessStatus::fetchMemoryReadings() m_memoryPss[qSL("total")] = quint64(m_reader->totalPss.load()) << 10; m_memoryPss[qSL("text")] = quint64(m_reader->textPss.load()) << 10; m_memoryPss[qSL("heap")] = quint64(m_reader->heapPss.load()) << 10; - - emit memoryReportingChanged(m_memoryVirtual, m_memoryRss, m_memoryPss); } /*! @@ -325,6 +350,29 @@ QVariantMap ProcessStatus::memoryPss() const } /*! + \qmlproperty bool ProcessStatus::memoryReportingEnabled + + A boolean value that determines whether the memory properties are refreshed each time + \l{ProcessStatus::update()}{update()} is called. The default value is \c true. In your System + UI, the process of determining memory consumption adds additional load to the CPU, affecting + the \c cpuLoad value. If \c cpuLoad needs to be kept accurate, consider disabling memory + reporting. +*/ + +bool ProcessStatus::isMemoryReportingEnabled() const +{ + return m_memoryReportingEnabled; +} + +void ProcessStatus::setMemoryReportingEnabled(bool enabled) +{ + if (enabled != m_memoryReportingEnabled) { + m_memoryReportingEnabled = enabled; + emit memoryReportingEnabledChanged(m_memoryReportingEnabled); + } +} + +/*! \qmlproperty list<string> ProcessStatus::roleNames \readonly diff --git a/src/manager-lib/processstatus.h b/src/manager-lib/processstatus.h index 612bb23c..839f1d65 100644 --- a/src/manager-lib/processstatus.h +++ b/src/manager-lib/processstatus.h @@ -66,9 +66,12 @@ class ProcessStatus : public QObject Q_PROPERTY(QVariantMap memoryVirtual READ memoryVirtual NOTIFY memoryReportingChanged) Q_PROPERTY(QVariantMap memoryRss READ memoryRss NOTIFY memoryReportingChanged) Q_PROPERTY(QVariantMap memoryPss READ memoryPss NOTIFY memoryReportingChanged) + Q_PROPERTY(bool memoryReportingEnabled READ isMemoryReportingEnabled WRITE setMemoryReportingEnabled + NOTIFY memoryReportingEnabledChanged) Q_PROPERTY(QStringList roleNames READ roleNames CONSTANT) public: ProcessStatus(QObject *parent = nullptr); + ~ProcessStatus(); QStringList roleNames() const; @@ -84,12 +87,16 @@ public: QVariantMap memoryRss() const; QVariantMap memoryPss() const; + bool isMemoryReportingEnabled() const; + void setMemoryReportingEnabled(bool enabled); + signals: void applicationIdChanged(const QString &applicationId); void processIdChanged(qint64 processId); void cpuLoadChanged(); void memoryReportingChanged(const QVariantMap &memoryVirtual, const QVariantMap &memoryRss, const QVariantMap &memoryPss); + void memoryReportingEnabledChanged(bool enabled); private slots: void onRunStateChanged(Am::RunState state); @@ -104,12 +111,14 @@ private: QVariantMap m_memoryVirtual; QVariantMap m_memoryRss; QVariantMap m_memoryPss; + bool m_memoryReportingEnabled = true; QPointer<Application> m_application; bool m_pendingUpdate = false; - QScopedPointer<ProcessReader> m_reader; + ProcessReader *m_reader; static QThread *m_workerThread; + static int m_instanceCount; }; QT_END_NAMESPACE_AM diff --git a/src/manager-lib/sudo.cpp b/src/manager-lib/sudo.cpp index ab497d89..729c4665 100644 --- a/src/manager-lib/sudo.cpp +++ b/src/manager-lib/sudo.cpp @@ -349,8 +349,11 @@ QByteArray SudoClient::call(const QByteArray &msg) { QMutexLocker locker(&m_mutex); - if (m_shortCircuit) - return m_shortCircuit->receive(msg); + if (m_shortCircuit) { + const QByteArray res = m_shortCircuit->receive(msg); + m_errorString = m_shortCircuit->lastError(); + return res; + } #ifdef Q_OS_LINUX if (m_socket >= 0) { diff --git a/src/monitor-lib/processreader.cpp b/src/monitor-lib/processreader.cpp index aacde41f..30ca5c38 100644 --- a/src/monitor-lib/processreader.cpp +++ b/src/monitor-lib/processreader.cpp @@ -50,7 +50,6 @@ # include <unistd.h> #endif - QT_USE_NAMESPACE_AM void ProcessReader::setProcessId(qint64 pid) @@ -60,39 +59,38 @@ void ProcessReader::setProcessId(qint64 pid) openCpuLoad(); } +void ProcessReader::enableMemoryReporting(bool enabled) +{ + m_memoryReportingEnabled = enabled; + if (!m_memoryReportingEnabled) + zeroMemory(); +} + void ProcessReader::update() { - // read cpu - { - quint32 value = quint32(readCpuLoad() * std::numeric_limits<quint32>::max()); - cpuLoad.store(value); - } + cpuLoad.store(static_cast<quint32>(cpuLoadFactor * readCpuLoad())); - { - if (!readMemory()) { - totalVm.store(0); - totalRss.store(0); - totalPss.store(0); - textVm.store(0); - textRss.store(0); - textPss.store(0); - heapVm.store(0); - heapRss.store(0); - heapPss.store(0); - } - } + if (m_memoryReportingEnabled && !readMemory()) + zeroMemory(); emit updated(); } -#if defined(Q_OS_LINUX) - -static uint parseValue(const char *pl) { - while (*pl && (*pl < '0' || *pl > '9')) - pl++; - return static_cast<uint>(strtoul(pl, nullptr, 10)); +void ProcessReader::zeroMemory() +{ + totalVm.store(0); + totalRss.store(0); + totalPss.store(0); + textVm.store(0); + textRss.store(0); + textPss.store(0); + heapVm.store(0); + heapRss.store(0); + heapPss.store(0); } +#if defined(Q_OS_LINUX) + void ProcessReader::openCpuLoad() { const QByteArray fileName = "/proc/" + QByteArray::number(m_pid) + "/stat"; @@ -142,6 +140,12 @@ bool ProcessReader::readMemory() return readSmaps(smapsFile); } +static uint parseValue(const char *pl) { + while (*pl && (*pl < '0' || *pl > '9')) + pl++; + return static_cast<uint>(strtoul(pl, nullptr, 10)); +} + bool ProcessReader::readSmaps(const QByteArray &smapsFile) { quint32 _totalVm = 0; diff --git a/src/monitor-lib/processreader.h b/src/monitor-lib/processreader.h index cfef25b6..a6c6bc35 100644 --- a/src/monitor-lib/processreader.h +++ b/src/monitor-lib/processreader.h @@ -60,6 +60,7 @@ class ProcessReader : public QObject { public slots: void update(); void setProcessId(qint64 pid); + void enableMemoryReporting(bool enabled); signals: void updated(); @@ -81,11 +82,13 @@ public: // it's public solely for testing purposes bool readSmaps(const QByteArray &smapsFile); #endif + static constexpr qreal cpuLoadFactor = 1000000.0; private: void openCpuLoad(); qreal readCpuLoad(); bool readMemory(); + void zeroMemory(); #if defined(Q_OS_LINUX) QScopedPointer<SysFsReader> m_statReader; @@ -94,6 +97,7 @@ private: quint64 m_lastCpuUsage = 0.0; qint64 m_pid = 0; + bool m_memoryReportingEnabled = true; }; QT_END_NAMESPACE_AM diff --git a/src/src.pro b/src/src.pro index 17746233..5b6867bd 100644 --- a/src/src.pro +++ b/src/src.pro @@ -110,7 +110,7 @@ SUBDIRS = \ tools_launcher_qml \ } -!android { +!cross_compile | tools-only { !disable-installer:SUBDIRS += \ tools_packager diff --git a/sync.profile b/sync.profile index 142d3f44..3a6983dd 100644 --- a/sync.profile +++ b/sync.profile @@ -8,7 +8,6 @@ "QtAppManSharedMain" => "$basedir/src/shared-main-lib", "QtAppManMain" => "$basedir/src/main-lib", "QtAppManWindow" => "$basedir/src/window-lib", - "QtAppManInstaller" => "$basedir/src/installer-lib", "QtAppManLauncher" => "$basedir/src/launcher-lib", "QtAppManPluginInterfaces" => "$basedir/src/plugin-interfaces", "QtAppManMonitor" => "$basedir/src/monitor-lib", diff --git a/tests/data/create-test-packages.sh b/tests/data/create-test-packages.sh index eab20672..3bc17175 100755 --- a/tests/data/create-test-packages.sh +++ b/tests/data/create-test-packages.sh @@ -155,6 +155,7 @@ packager create-package "$dst/hello-world.red.appkg" hello-world.red ### v2 packages for testing updates echo "test update" >"$src/test" +sed -i 's/version: 1.0/version: 2.0/' "$src/info.yaml" info "Create update package" packager create-package "$dst/test-update.appkg" "$src" @@ -163,6 +164,7 @@ info "Dev-sign update package" packager dev-sign-package "$dst/test-update.appkg" "$dst/test-update-dev-signed.appkg" certificates/dev2.p12 password echo "test" >"$src/test" +sed -i 's/version: 2.0/version: 1.0/' "$src/info.yaml" ### big packages diff --git a/tests/data/hello-world.red/info.yaml b/tests/data/hello-world.red/info.yaml index af6a9f70..77980428 100644 --- a/tests/data/hello-world.red/info.yaml +++ b/tests/data/hello-world.red/info.yaml @@ -7,3 +7,4 @@ code: 'main.qml' runtime: 'qml' name: en: 'Hello Updated Red' +version: red diff --git a/tests/data/manifests/com.pelagicore.test/info.yaml b/tests/data/manifests/com.pelagicore.test/info.yaml index f7fc13a3..0c4b3fd0 100644 --- a/tests/data/manifests/com.pelagicore.test/info.yaml +++ b/tests/data/manifests/com.pelagicore.test/info.yaml @@ -11,6 +11,8 @@ name: en: 'english' de: 'deutsch' +version: v1 + mimeTypes: - "x-scheme-handler/mailto" - "text/plain" diff --git a/tests/main/tst_main.cpp b/tests/main/tst_main.cpp index 090df7b7..d87f1b88 100644 --- a/tests/main/tst_main.cpp +++ b/tests/main/tst_main.cpp @@ -180,7 +180,7 @@ void tst_Main::installPackage(const QString &pkgPath) connect(packageManager, &PackageManager::taskRequestingInstallationAcknowledge, this, [packageManager](const QString &taskId, const QVariantMap &, - const QVariantMap &, const QVariantMap &) { + const QVariantMap &, const QVariantMap &) { packageManager->acknowledgePackageInstallation(taskId); }); @@ -201,8 +201,9 @@ void tst_Main::removePackage(const QString &id) bool removalFinished = false; connect(packageManager, &PackageManager::taskFinished, - this, [&removalFinished](const QString &) { - removalFinished = true; + this, [this, &removalFinished](const QString &) { + Q_UNUSED(this); // gcc 9.2 bug: without capturing 'this', broken code will be generated + removalFinished = true; }); packageManager->removePackage(id, false /* keepDocuments */); diff --git a/tests/qml/crash/apps/tld.test.crash/terminator2/qmlterminator2.cpp b/tests/qml/crash/apps/tld.test.crash/terminator2/qmlterminator2.cpp index ae03e600..0ed12064 100644 --- a/tests/qml/crash/apps/tld.test.crash/terminator2/qmlterminator2.cpp +++ b/tests/qml/crash/apps/tld.test.crash/terminator2/qmlterminator2.cpp @@ -47,6 +47,11 @@ void TerminatorPlugin::registerTypes(const char *uri) } +static void abortWithVeryLongSymbolNameOnTheStack800CharactersLong_CallMeIshmaelSomeYearsAgoNeverMindHowLongPreciselyHavingLittleOrNoMoneyInMyPurseAndNothingParticularToInterestMeOnShoreIThoughIWouldSailAboutALittlAndSeeTheWateryPartOfTheWorldItIsAWayIHaveOfDrivingOffTheSpleenAndRegulatingTheCirculationWhenenverIFindMyselfGrowingGrimAboutTheMouthWheneverItIsADampDrizzlyNovemberInMySoulWheneverIFindMyselfInvoluntarilyPausingBeforeCoffinWarehousesAndBringingUpTheRearOfEveryFuneralIMeetAndEspeciallyWheneverMyHyposGetSuchAnUpperHandOfMeThatItRequiresAStrongMoralPrincipleToPreventMeFromDeliberatelySteppingIntoTheStreetAndMethodicallyKnockingPeoplesHatsOffThenIAccountItHighTimeToGetToSeaAsSoonAsICanThisIsMySubstituteForPistolAndBallWithAPhilosophicalFlourishCatoThrowsHimselfUponHisSwordIQuietlyTakeToTheShip() +{ + ::abort(); +} + void Terminator::accessIllegalMemory() const { *(int*)1 = 42; @@ -76,7 +81,7 @@ void Terminator::divideByZero() const void Terminator::abort() const { - ::abort(); + abortWithVeryLongSymbolNameOnTheStack800CharactersLong_CallMeIshmaelSomeYearsAgoNeverMindHowLongPreciselyHavingLittleOrNoMoneyInMyPurseAndNothingParticularToInterestMeOnShoreIThoughIWouldSailAboutALittlAndSeeTheWateryPartOfTheWorldItIsAWayIHaveOfDrivingOffTheSpleenAndRegulatingTheCirculationWhenenverIFindMyselfGrowingGrimAboutTheMouthWheneverItIsADampDrizzlyNovemberInMySoulWheneverIFindMyselfInvoluntarilyPausingBeforeCoffinWarehousesAndBringingUpTheRearOfEveryFuneralIMeetAndEspeciallyWheneverMyHyposGetSuchAnUpperHandOfMeThatItRequiresAStrongMoralPrincipleToPreventMeFromDeliberatelySteppingIntoTheStreetAndMethodicallyKnockingPeoplesHatsOffThenIAccountItHighTimeToGetToSeaAsSoonAsICanThisIsMySubstituteForPistolAndBallWithAPhilosophicalFlourishCatoThrowsHimselfUponHisSwordIQuietlyTakeToTheShip(); } void Terminator::raise(int sig) const diff --git a/tests/qml/crash/tst_crash.qml b/tests/qml/crash/tst_crash.qml index 29ebd011..eacc66b3 100644 --- a/tests/qml/crash/tst_crash.qml +++ b/tests/qml/crash/tst_crash.qml @@ -66,10 +66,10 @@ TestCase { return [ { tag: "gracefully" }, { tag: "illegalMemory" }, { tag: "illegalMemoryInThread" }, - { tag: "unhandledException" } ]; + { tag: "unhandledException" }, + { tag: "abort" } ]; //{ tag: "stackOverflow" }, //{ tag: "divideByZero" }, - //{ tag: "abort" }, //{ tag: "raise" } ]; } diff --git a/tests/qml/installer/apps/hello-world.red/app1.qml b/tests/qml/installer/apps/hello-world.red/app1.qml new file mode 100644 index 00000000..a3c4b30f --- /dev/null +++ b/tests/qml/installer/apps/hello-world.red/app1.qml @@ -0,0 +1,46 @@ +/**************************************************************************** +** +** Copyright (C) 2019 Luxoft Sweden AB +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt 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 QtApplicationManager.Application 2.0 + +ApplicationManagerWindow { + color: "green" +} diff --git a/tests/qml/installer/apps/hello-world.red/icon1.png b/tests/qml/installer/apps/hello-world.red/icon1.png Binary files differnew file mode 100644 index 00000000..c1397153 --- /dev/null +++ b/tests/qml/installer/apps/hello-world.red/icon1.png diff --git a/tests/qml/installer/apps/hello-world.red/info.yaml b/tests/qml/installer/apps/hello-world.red/info.yaml new file mode 100644 index 00000000..1b628d1e --- /dev/null +++ b/tests/qml/installer/apps/hello-world.red/info.yaml @@ -0,0 +1,10 @@ +formatVersion: 1 +formatType: am-application +--- +id: 'hello-world.red' +version: 'v1' +icon: 'icon1.png' +code: 'app1.qml' +runtime: 'qml' +name: + en: 'Builtin Installation Test App v1' diff --git a/tests/qml/installer/tst_installer.qml b/tests/qml/installer/tst_installer.qml index a51a26b8..dced0938 100644 --- a/tests/qml/installer/tst_installer.qml +++ b/tests/qml/installer/tst_installer.qml @@ -50,6 +50,9 @@ TestCase { name: "Installer" when: windowShown + property var stateList: [] + property int spyTimeout: 5000 * AmTest.timeoutFactor + SignalSpy { id: taskFinishedSpy target: PackageManager @@ -57,6 +60,12 @@ TestCase { } SignalSpy { + id: taskFailedSpy + target: PackageManager + signalName: "taskFailed" + } + + SignalSpy { id: taskStateChangedSpy target: PackageManager signalName: "taskStateChanged" @@ -68,17 +77,26 @@ TestCase { signalName: "taskRequestingInstallationAcknowledge" } - property var stateList: [] - property int spyTimeout: 5000 * AmTest.timeoutFactor + SignalSpy { + id: applicationChangedSpy + target: ApplicationManager + signalName: "applicationChanged" + } - function test_states() { - // App could potentially be installed already. Remove it. - if (PackageManager.removePackage("com.pelagicore.test", false, true)) { - taskFinishedSpy.wait(spyTimeout); - compare(taskFinishedSpy.count, 1); - taskFinishedSpy.clear(); + + function init() { + // Remove previous installations + + for (var pkg of [ "hello-world.red", "com.pelagicore.test" ]) { + if (PackageManager.removePackage(pkg, false, true)) { + taskFinishedSpy.wait(spyTimeout); + compare(taskFinishedSpy.count, 1); + taskFinishedSpy.clear(); + } } + } + function test_1states() { PackageManager.packageAdded.connect(function(pkgId) { var pkg = PackageManager.package(pkgId); stateList.push(pkg.state) @@ -88,6 +106,7 @@ TestCase { }) }) + taskStateChangedSpy.clear(); var id = PackageManager.startPackageInstallation(ApplicationManager.systemProperties.AM_TESTDATA_DIR + "/packages/test-dev-signed.appkg") taskRequestingInstallationAcknowledgeSpy.wait(spyTimeout); @@ -112,6 +131,7 @@ TestCase { taskRequestingInstallationAcknowledgeSpy.wait(spyTimeout); compare(taskRequestingInstallationAcknowledgeSpy.count, 1); compare(taskRequestingInstallationAcknowledgeSpy.signalArguments[0][0], id); + taskRequestingInstallationAcknowledgeSpy.clear(); PackageManager.acknowledgePackageInstallation(id); taskFinishedSpy.wait(spyTimeout); @@ -147,4 +167,92 @@ TestCase { for (var i = 0; i < taskStates.length; i++) compare(taskStateChangedSpy.signalArguments[i][1], taskStates[i], "- index: " + i); } + + function test_2cancel_update() { + var id = PackageManager.startPackageInstallation(ApplicationManager.systemProperties.AM_TESTDATA_DIR + + "/packages/test-dev-signed.appkg") + taskRequestingInstallationAcknowledgeSpy.wait(spyTimeout); + compare(taskRequestingInstallationAcknowledgeSpy.count, 1); + compare(taskRequestingInstallationAcknowledgeSpy.signalArguments[0][0], id); + var pkgId = taskRequestingInstallationAcknowledgeSpy.signalArguments[0][1].id + compare(pkgId, "com.pelagicore.test"); + taskRequestingInstallationAcknowledgeSpy.clear(); + PackageManager.acknowledgePackageInstallation(id); + + taskFinishedSpy.wait(spyTimeout); + taskFinishedSpy.clear(); + + var pkg = PackageManager.package(pkgId); + compare(pkg.version, "1.0"); + + id = PackageManager.startPackageInstallation(ApplicationManager.systemProperties.AM_TESTDATA_DIR + + "/packages/test-update-dev-signed.appkg") + taskRequestingInstallationAcknowledgeSpy.wait(spyTimeout); + pkgId = taskRequestingInstallationAcknowledgeSpy.signalArguments[0][1].id + compare(pkgId, "com.pelagicore.test"); + taskRequestingInstallationAcknowledgeSpy.clear(); + PackageManager.cancelTask(id); + + taskFailedSpy.wait(spyTimeout); + taskFailedSpy.clear(); + + compare(pkg.version, "1.0"); + } + + function test_3cancel_builtin_update() { + taskStateChangedSpy.clear() + var pkg = PackageManager.package("hello-world.red"); + verify(pkg.builtIn); + compare(pkg.icon.toString().slice(-9), "icon1.png") + compare(pkg.version, "v1"); + + var id = PackageManager.startPackageInstallation(ApplicationManager.systemProperties.AM_TESTDATA_DIR + + "/packages/hello-world.red.appkg") + taskRequestingInstallationAcknowledgeSpy.wait(spyTimeout); + compare(taskRequestingInstallationAcknowledgeSpy.count, 1); + compare(taskRequestingInstallationAcknowledgeSpy.signalArguments[0][0], id); + taskRequestingInstallationAcknowledgeSpy.clear(); + PackageManager.cancelTask(id); + + taskFailedSpy.wait(spyTimeout); + taskFailedSpy.clear(); + + verify(pkg.builtIn); + compare(pkg.icon.toString().slice(-9), "icon1.png") + compare(pkg.version, "v1"); + } + + function test_4builtin_update_downgrade() { + taskStateChangedSpy.clear() + + var id = PackageManager.startPackageInstallation(ApplicationManager.systemProperties.AM_TESTDATA_DIR + + "/packages/hello-world.red.appkg") + taskRequestingInstallationAcknowledgeSpy.wait(spyTimeout); + compare(taskRequestingInstallationAcknowledgeSpy.count, 1); + compare(taskRequestingInstallationAcknowledgeSpy.signalArguments[0][0], id); + taskRequestingInstallationAcknowledgeSpy.clear(); + PackageManager.acknowledgePackageInstallation(id); + + taskFinishedSpy.wait(spyTimeout); + var pkg = PackageManager.package("hello-world.red") + compare(pkg.version, "red"); + taskFinishedSpy.clear(); + applicationChangedSpy.clear(); + + // remvove is a downgrade + verify(pkg.builtIn) + verify(pkg.builtInHasRemovableUpdate) + verify(PackageManager.removePackage("hello-world.red", false, true)); + taskFinishedSpy.wait(spyTimeout); + compare(taskFinishedSpy.count, 1); + taskFinishedSpy.clear(); + + compare(applicationChangedSpy.count, 3); + compare(applicationChangedSpy.signalArguments[0][0], "hello-world.red"); + compare(applicationChangedSpy.signalArguments[0][1], ["isBlocked"]); + compare(applicationChangedSpy.signalArguments[2][1], []); + + verify(!pkg.blocked) + compare(pkg.version, "v1"); + } } diff --git a/tests/qml/resources/appcommon/Quicklaunch.qml b/tests/qml/resources/appcommon/Quicklaunch.qml index 39d7b8c1..a8998d0e 100644 --- a/tests/qml/resources/appcommon/Quicklaunch.qml +++ b/tests/qml/resources/appcommon/Quicklaunch.qml @@ -3,7 +3,7 @@ ** Copyright (C) 2019 Luxoft Sweden AB ** Contact: https://www.qt.io/licensing/ ** -** This file is part of the Luxoft Application Manager. +** This file is part of the Qt Application Manager. ** ** $QT_BEGIN_LICENSE:LGPL-QTAS$ ** Commercial License Usage diff --git a/tests/qml/resources/appcommon/qml/common/CommonObj.qml b/tests/qml/resources/appcommon/qml/common/CommonObj.qml index 2ee42a0b..ff1fdcf7 100644 --- a/tests/qml/resources/appcommon/qml/common/CommonObj.qml +++ b/tests/qml/resources/appcommon/qml/common/CommonObj.qml @@ -3,7 +3,7 @@ ** Copyright (C) 2019 Luxoft Sweden AB ** Contact: https://www.qt.io/licensing/ ** -** This file is part of the Luxoft Application Manager. +** This file is part of the Qt Application Manager. ** ** $QT_BEGIN_LICENSE:LGPL-QTAS$ ** Commercial License Usage |