diff options
author | Robert Griebl <robert.griebl@pelagicore.com> | 2019-08-09 00:11:25 +0200 |
---|---|---|
committer | Robert Griebl <robert.griebl@pelagicore.com> | 2019-08-09 00:11:25 +0200 |
commit | cb5b9a50187d3680ca949f1af6be11013c8e4282 (patch) | |
tree | da226495606a6d31b5455cebfbda9ad03bf1f599 | |
parent | 21db103f4de134c0c1141839551cace1610912ed (diff) | |
parent | 1968c30f07c4ed8e682829bb4264364d3bdf9341 (diff) |
Merge remote-tracking branch 'gerrit/5.13' into dev
* gerrit/5.13:
Bump version to 5.13.1
Ignore $WAYLAND_DISPLAY when starting on Wayland desktop environments
Cleanup application lifecycle in single-process mode
Bump version to 5.12.4
Fix app start/stop in single-process mode
Destroy QDBusServer instance when an application quits
Fix applications reusing a runtime object that is about to be destructed
Fix broken Wayland socket name detection
Fix crashes when trying to start blocked apps
Wait for apps to stop before actually uninstalling them
Make sure the app-db is flushed after writing
Fix possibly crashing qml/simple tests
Only calculate the hardwareId once
[intents] add intents list to read/write of ApplicationInfo to stream
Fix headless compilation
Change-Id: Iaa7026852e5d3ab48140aae09b4159ad9939eba2
-rw-r--r-- | application-manager.pro | 2 | ||||
-rw-r--r-- | qmake-features/am-config.prf | 4 | ||||
-rw-r--r-- | src/main-lib/defaultconfiguration.cpp | 23 | ||||
-rw-r--r-- | src/manager-lib/qmlinprocessruntime.cpp | 2 | ||||
-rw-r--r-- | src/monitor-lib/systemreader.cpp | 2 | ||||
-rw-r--r-- | src/tools/testrunner/testrunner.cpp | 12 | ||||
-rw-r--r-- | src/tools/testrunner/testrunner_p.h | 4 | ||||
-rw-r--r-- | tests/qml/lifecycle/am-config.yaml | 17 | ||||
-rw-r--r-- | tests/qml/lifecycle/apps/tld.test.lifecycle/app.qml | 50 | ||||
-rw-r--r-- | tests/qml/lifecycle/apps/tld.test.lifecycle/icon.png | bin | 0 -> 1486 bytes | |||
-rw-r--r-- | tests/qml/lifecycle/apps/tld.test.lifecycle/info.yaml | 9 | ||||
-rw-r--r-- | tests/qml/lifecycle/lifecycle.pro | 5 | ||||
-rw-r--r-- | tests/qml/lifecycle/tst_lifecycle.qml | 144 | ||||
-rw-r--r-- | tests/qml/qml.pro | 3 |
14 files changed, 266 insertions, 11 deletions
diff --git a/application-manager.pro b/application-manager.pro index 53e6c99e..7fd99d16 100644 --- a/application-manager.pro +++ b/application-manager.pro @@ -25,7 +25,7 @@ else:contains(QT_BUILD_PARTS, "examples"):CONFIG += enable-examples !headless:qtHaveModule(gui):qtCompileTest(touchemulation) } -qtHaveModule(waylandcompositor):CONFIG += am_compatible_compositor +qtHaveModule(waylandcompositor):qtHaveModule(quick):qtConfig(opengl):CONFIG += am_compatible_compositor load(am-config) diff --git a/qmake-features/am-config.prf b/qmake-features/am-config.prf index 113013e7..d115eb63 100644 --- a/qmake-features/am-config.prf +++ b/qmake-features/am-config.prf @@ -5,7 +5,9 @@ CONFIG *= no_private_qt_headers_warning hide_symbols CONFIG -= app_bundle qml_debug CONFIG += exceptions -!qtHaveModule(gui):CONFIG *= headless +!qtHaveModule(gui)|!qtHaveModule(quick)|!qtConfig(opengl) { + CONFIG *= headless +} DEFINES += QT_MESSAGELOGCONTEXT diff --git a/src/main-lib/defaultconfiguration.cpp b/src/main-lib/defaultconfiguration.cpp index a91b417a..a0e5f930 100644 --- a/src/main-lib/defaultconfiguration.cpp +++ b/src/main-lib/defaultconfiguration.cpp @@ -49,6 +49,10 @@ # include <sys/file.h> #endif +#if !defined(AM_HEADLESS) +# include <QGuiApplication> +#endif + #include <QtAppManCommon/logging.h> #include "defaultconfiguration.h" @@ -480,22 +484,26 @@ int DefaultConfiguration::quickLaunchRuntimesPerContainer() const QString DefaultConfiguration::waylandSocketName() const { - const QString socket = m_clp.value(qSL("wayland-socket-name")); // get the default value - if (!socket.isEmpty()) - return socket; +#if !defined(AM_HEADLESS) + QString socketName = m_clp.value(qSL("wayland-socket-name")); // get the default value + if (!socketName.isEmpty()) + return socketName; const char *envName = "WAYLAND_DISPLAY"; - if (qEnvironmentVariableIsSet(envName)) - return qEnvironmentVariable(envName); + if (qEnvironmentVariableIsSet(envName)) { + socketName = qEnvironmentVariable(envName); + if (!QGuiApplication::platformName().startsWith(qSL("wayland")) || (socketName != qSL("wayland-0"))) + return socketName; + } -#if defined(Q_OS_LINUX) +# if defined(Q_OS_LINUX) // modelled after wl_socket_lock() in wayland_server.c const QString xdgDir = qEnvironmentVariable("XDG_RUNTIME_DIR") + qSL("/"); const QString pattern = qSL("qtam-wayland-%1"); const QString lockSuffix = qSL(".lock"); for (int i = 0; i < 32; ++i) { - const QString socketName = pattern.arg(i); + socketName = pattern.arg(i); QFile lock(xdgDir + socketName + lockSuffix); if (lock.open(QIODevice::ReadWrite)) { if (::flock(lock.handle(), LOCK_EX | LOCK_NB) == 0) { @@ -505,6 +513,7 @@ QString DefaultConfiguration::waylandSocketName() const } } } +# endif #endif return QString(); } diff --git a/src/manager-lib/qmlinprocessruntime.cpp b/src/manager-lib/qmlinprocessruntime.cpp index 0cfd93ee..7f769b7d 100644 --- a/src/manager-lib/qmlinprocessruntime.cpp +++ b/src/manager-lib/qmlinprocessruntime.cpp @@ -215,6 +215,8 @@ void QmlInProcessRuntime::finish(int exitCode, Am::ExitStatus status) qCDebug(LogSystem) << "QmlInProcessRuntime (id:" << (m_app ? m_app->id() : qSL("(none)")) << ") exited with code:" << exitCode << "status:" << status; emit finished(exitCode, status); + if (m_app) + m_app->setCurrentRuntime(nullptr); setState(Am::NotRunning); #if !defined(AM_HEADLESS) if (m_surfaces.isEmpty()) diff --git a/src/monitor-lib/systemreader.cpp b/src/monitor-lib/systemreader.cpp index 4f2d180c..bc1c8514 100644 --- a/src/monitor-lib/systemreader.cpp +++ b/src/monitor-lib/systemreader.cpp @@ -71,11 +71,11 @@ QT_END_NAMESPACE_AM # include <QSocketNotifier> # include <QProcess> # include <QCoreApplication> +# include <QAtomicInteger> # if !defined(AM_HEADLESS) # include <QOffscreenSurface> # include <QOpenGLContext> # include <QOpenGLFunctions> -# include <QAtomicInteger> # endif # include <sys/eventfd.h> diff --git a/src/tools/testrunner/testrunner.cpp b/src/tools/testrunner/testrunner.cpp index 59d8d072..ce10cefd 100644 --- a/src/tools/testrunner/testrunner.cpp +++ b/src/tools/testrunner/testrunner.cpp @@ -118,6 +118,18 @@ void AmTest::ignoreMessage(MsgType type, const QRegExp &expression) #endif } +int AmTest::observeObjectDestroyed(QObject *obj) +{ + static int idx = 0; + int index = idx++; + + connect(obj, &QObject::destroyed, [this, index] () { + emit objectDestroyed(index); + }); + + return index; +} + QTestRootObject::QTestRootObject(QObject *parent) : QObject(parent) diff --git a/src/tools/testrunner/testrunner_p.h b/src/tools/testrunner/testrunner_p.h index 93b93ee0..bc29c250 100644 --- a/src/tools/testrunner/testrunner_p.h +++ b/src/tools/testrunner/testrunner_p.h @@ -105,6 +105,10 @@ public: Q_INVOKABLE void ignoreMessage(MsgType type, const char* msg); Q_INVOKABLE void ignoreMessage(MsgType type, const QRegExp &expression); + Q_INVOKABLE int observeObjectDestroyed(QObject *obj); + +Q_SIGNALS: + void objectDestroyed(int index); }; QT_END_NAMESPACE_AM diff --git a/tests/qml/lifecycle/am-config.yaml b/tests/qml/lifecycle/am-config.yaml new file mode 100644 index 00000000..b9c17b5e --- /dev/null +++ b/tests/qml/lifecycle/am-config.yaml @@ -0,0 +1,17 @@ +formatVersion: 1 +formatType: am-configuration +--- +applications: + builtinAppsManifestDir: "${CONFIG_PWD}/apps" + installedAppsManifestDir: "/tmp/am-crash-test/manifests" + appImageMountDir: "/tmp/am-crash-test/image-mounts" + database: "/tmp/am-crash-test/apps.db" + +installationLocations: +- id: "internal-0" + installationPath: "/tmp/am/apps" + documentPath: "/tmp/am/docs" + mountPoint: "/tmp" + +flags: + noUiWatchdog: yes diff --git a/tests/qml/lifecycle/apps/tld.test.lifecycle/app.qml b/tests/qml/lifecycle/apps/tld.test.lifecycle/app.qml new file mode 100644 index 00000000..a994adf4 --- /dev/null +++ b/tests/qml/lifecycle/apps/tld.test.lifecycle/app.qml @@ -0,0 +1,50 @@ +/**************************************************************************** +** +** 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 QtQuick 2.11 +import QtApplicationManager.Application 2.0 + +ApplicationManagerWindow { + Image { + anchors.centerIn: parent + source: ApplicationInterface.icon + } +} diff --git a/tests/qml/lifecycle/apps/tld.test.lifecycle/icon.png b/tests/qml/lifecycle/apps/tld.test.lifecycle/icon.png Binary files differnew file mode 100644 index 00000000..c1397153 --- /dev/null +++ b/tests/qml/lifecycle/apps/tld.test.lifecycle/icon.png diff --git a/tests/qml/lifecycle/apps/tld.test.lifecycle/info.yaml b/tests/qml/lifecycle/apps/tld.test.lifecycle/info.yaml new file mode 100644 index 00000000..198cbe51 --- /dev/null +++ b/tests/qml/lifecycle/apps/tld.test.lifecycle/info.yaml @@ -0,0 +1,9 @@ +formatVersion: 1 +formatType: am-application +--- +id: 'tld.test.lifecycle' +name: + en: 'Lifecycle Tests' +icon: 'icon.png' +code: 'app.qml' +runtime: 'qml' diff --git a/tests/qml/lifecycle/lifecycle.pro b/tests/qml/lifecycle/lifecycle.pro new file mode 100644 index 00000000..98ab9709 --- /dev/null +++ b/tests/qml/lifecycle/lifecycle.pro @@ -0,0 +1,5 @@ +AM_CONFIG = am-config.yaml +TEST_FILES = tst_lifecycle.qml +TEST_APPS = tld.test.lifecycle + +load(am-qml-testcase) diff --git a/tests/qml/lifecycle/tst_lifecycle.qml b/tests/qml/lifecycle/tst_lifecycle.qml new file mode 100644 index 00000000..641ab7e1 --- /dev/null +++ b/tests/qml/lifecycle/tst_lifecycle.qml @@ -0,0 +1,144 @@ +/**************************************************************************** +** +** 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 QtQuick 2.11 +import QtTest 1.0 +import QtApplicationManager 2.0 +import QtApplicationManager.SystemUI 2.0 + +TestCase { + id: testCase + when: windowShown + name: "LifeCycleTest" + visible: true + + property var app: ApplicationManager.application("tld.test.lifecycle"); + + + WindowItem { + id: chrome + anchors.fill: parent + } + + Connections { + target: WindowManager + onWindowAdded: chrome.window = window; + } + + Connections { + target: chrome.window + onContentStateChanged: { + if (chrome.window.contentState === WindowObject.NoSurface) + chrome.window = null; + } + } + + + SignalSpy { + id: runStateChangedSpy + target: ApplicationManager + signalName: "applicationRunStateChanged" + } + + SignalSpy { + id: objectDestroyedSpy + target: AmTest + signalName: "objectDestroyed" + } + + Timer { + id: stopTimer + interval: 1 + onTriggered: app.stop(); + } + + + function cleanup() { + objectDestroyedSpy.clear(); + var index = AmTest.observeObjectDestroyed(app.runtime); + app.stop(); + while (app.runState !== ApplicationObject.NotRunning) + runStateChangedSpy.wait(); + objectDestroyedSpy.wait(); + compare(objectDestroyedSpy.signalArguments[0][0], index); + } + + + // Start followed by quick stop/start in single-porcess mode caused an abort in the past + function test_fast_stop_start() { + app.start(); + runStateChangedSpy.wait(); + compare(app.runState, ApplicationObject.StartingUp); + runStateChangedSpy.wait(); + compare(app.runState, ApplicationObject.Running); + + objectDestroyedSpy.clear(); + var index = AmTest.observeObjectDestroyed(app.runtime); + + app.stop(); + runStateChangedSpy.wait(); + compare(app.runState, ApplicationObject.ShuttingDown); + runStateChangedSpy.wait(); + compare(app.runState, ApplicationObject.NotRunning); + + app.start(); + runStateChangedSpy.wait(); + compare(app.runState, ApplicationObject.StartingUp); + runStateChangedSpy.wait(); + compare(app.runState, ApplicationObject.Running); + + objectDestroyedSpy.wait(); + compare(objectDestroyedSpy.signalArguments[0][0], index); + } + + // Quick start/stop followd by start in single-process mode caused an abort in the past + function test_fast_start_stop() { + app.start(); + stopTimer.start(); + + while (app.runState !== ApplicationObject.NotRunning) + runStateChangedSpy.wait(); + + app.start(); + while (app.runState !== ApplicationObject.Running) + runStateChangedSpy.wait(); + } +} diff --git a/tests/qml/qml.pro b/tests/qml/qml.pro index 8a0cd59f..d6a064f6 100644 --- a/tests/qml/qml.pro +++ b/tests/qml/qml.pro @@ -14,4 +14,5 @@ SUBDIRS = \ intents \ crash/apps/tld.test.crash/terminator2 \ crash \ - configs + configs \ + lifecycle |