summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.qmake.conf2
-rw-r--r--application-manager.pro1
-rwxr-xr-xbenchmarks/appman-bench/run.sh2
-rw-r--r--benchmarks/appman-bench/system-ui/main.qml2
-rw-r--r--benchmarks/appman-bench/templates/appman-qml/main.qml2
-rw-r--r--benchmarks/appman-bench/templates/qmlscene/main.qml2
-rw-r--r--benchmarks/appman-bench/tests/controls2.qml2
-rw-r--r--benchmarks/appman-bench/tests/rect.qml2
-rw-r--r--benchmarks/appman-bench/tests/repeater.qml2
-rw-r--r--benchmarks/appman-bench/tests/shader.qml2
-rw-r--r--config.tests/libarchive/main.cpp2
-rw-r--r--config.tests/libyaml/main.cpp2
-rw-r--r--config.tests/touchemulation/main.cpp2
-rw-r--r--doc/QtApplicationManagerDoc1
-rw-r--r--doc/apps.qdoc2
-rw-r--r--doc/configuration.qdoc69
-rw-r--r--doc/container.qdoc2
-rw-r--r--doc/controller.qdoc5
-rw-r--r--doc/debugging.qdoc2
-rw-r--r--doc/elements-apps.qdoc2
-rw-r--r--doc/elements-common.qdoc2
-rw-r--r--doc/elements-systemui.qdoc2
-rw-r--r--doc/index.qdoc2
-rw-r--r--doc/installation.qdoc2
-rw-r--r--doc/installer.qdoc2
-rw-r--r--doc/introduction.qdoc2
-rw-r--r--doc/manifest.qdoc2
-rw-r--r--doc/migration-guide-5.12.qdoc2
-rw-r--r--doc/package-format.qdoc2
-rw-r--r--doc/packager.qdoc2
-rw-r--r--doc/qmlmodule.qdoc2
-rw-r--r--doc/singlevsmultiprocess.qdoc2
-rw-r--r--doc/systemui.qdoc2
-rw-r--r--doc/troubleshooting.qdoc2
-rw-r--r--doc/yaml.qdoc2
-rw-r--r--examples/applicationmanager/animated-windows/apps/animated-windows.fish/fish.qml2
-rw-r--r--examples/applicationmanager/animated-windows/apps/animated-windows.rabbit/rabbit.qml2
-rw-r--r--examples/applicationmanager/animated-windows/doc/src/animated-windows.qdoc2
-rw-r--r--examples/applicationmanager/animated-windows/system-ui/main.qml2
-rw-r--r--examples/applicationmanager/custom-appman/custom-appman.cpp8
-rw-r--r--examples/applicationmanager/custom-appman/doc/src/custom-appman.qdoc2
-rw-r--r--examples/applicationmanager/frame-timer/apps/frame-timer.fish/fish.qml2
-rw-r--r--examples/applicationmanager/frame-timer/apps/frame-timer.rabbit/rabbit.qml2
-rw-r--r--examples/applicationmanager/frame-timer/doc/src/frame-timer-example.qdoc2
-rw-r--r--examples/applicationmanager/frame-timer/system-ui/main.qml2
-rw-r--r--examples/applicationmanager/hello-world/apps/hello-world.blue/main.qml2
-rw-r--r--examples/applicationmanager/hello-world/apps/hello-world.green/main.qml2
-rw-r--r--examples/applicationmanager/hello-world/apps/hello-world.red/main.qml2
-rw-r--r--examples/applicationmanager/hello-world/doc/src/hello-world.qdoc2
-rw-r--r--examples/applicationmanager/hello-world/system-ui.qml2
-rw-r--r--examples/applicationmanager/intents/apps/intents.blue/main.qml2
-rw-r--r--examples/applicationmanager/intents/apps/intents.green/main.qml2
-rw-r--r--examples/applicationmanager/intents/apps/intents.red/main.qml2
-rw-r--r--examples/applicationmanager/intents/doc/src/intents.qdoc2
-rw-r--r--examples/applicationmanager/intents/shared/IntentsApplicationWindow.qml2
-rw-r--r--examples/applicationmanager/intents/shared/IntentsUIPage.qml2
-rw-r--r--examples/applicationmanager/intents/system-ui.qml2
-rw-r--r--examples/applicationmanager/minidesk/apps/tld.minidesk.app1/app1.qml8
-rw-r--r--examples/applicationmanager/minidesk/apps/tld.minidesk.app1/icon.pngbin5138 -> 4804 bytes
-rw-r--r--examples/applicationmanager/minidesk/apps/tld.minidesk.app1/info.yaml12
-rw-r--r--examples/applicationmanager/minidesk/apps/tld.minidesk.app2/app2.qml4
-rw-r--r--examples/applicationmanager/minidesk/apps/tld.minidesk.app2/icon.pngbin5597 -> 4399 bytes
-rw-r--r--examples/applicationmanager/minidesk/apps/tld.minidesk.app2/info.yaml12
-rw-r--r--examples/applicationmanager/minidesk/doc/images/minidesk.pngbin103040 -> 84974 bytes
-rw-r--r--examples/applicationmanager/minidesk/doc/src/minidesk.qdoc20
-rw-r--r--examples/applicationmanager/minidesk/system-ui/Readme.qml2
-rw-r--r--examples/applicationmanager/minidesk/system-ui/chrome-bg.pngbin0 -> 488 bytes
-rw-r--r--examples/applicationmanager/minidesk/system-ui/main.qml15
-rw-r--r--examples/applicationmanager/multi-views/apps/tld.multi-views.app/app1.qml2
-rw-r--r--examples/applicationmanager/multi-views/doc/src/multi-views.qdoc2
-rw-r--r--examples/applicationmanager/multi-views/multi-views.pro2
-rw-r--r--examples/applicationmanager/multi-views/system-ui/Readme.qml2
-rw-r--r--examples/applicationmanager/multi-views/system-ui/main.qml2
-rw-r--r--examples/applicationmanager/process-status/apps/process-status.cpu-hog/main.qml2
-rw-r--r--examples/applicationmanager/process-status/apps/process-status.mem-hog/main.qml2
-rw-r--r--examples/applicationmanager/process-status/apps/process-status.slim/main.qml2
-rw-r--r--examples/applicationmanager/process-status/doc/src/process-status-example.qdoc2
-rw-r--r--examples/applicationmanager/process-status/system-ui/ApplicationDisplay.qml2
-rw-r--r--examples/applicationmanager/process-status/system-ui/CpuGraph.qml2
-rw-r--r--examples/applicationmanager/process-status/system-ui/MemoryText.qml2
-rw-r--r--examples/applicationmanager/process-status/system-ui/Stats.qml2
-rw-r--r--examples/applicationmanager/process-status/system-ui/main.qml2
-rw-r--r--examples/applicationmanager/softwarecontainer-plugin/README.md3
-rw-r--r--examples/applicationmanager/softwarecontainer-plugin/softwarecontainer.cpp2
-rw-r--r--examples/applicationmanager/softwarecontainer-plugin/softwarecontainer.h2
-rw-r--r--examples/applicationmanager/startup-plugin/startup-plugin.cpp2
-rw-r--r--examples/applicationmanager/startup-plugin/startup-plugin.h2
-rw-r--r--header.BSD-QTAS3
-rw-r--r--header.FDL-QTAS3
-rw-r--r--header.GPL-EXCEPT-QTAS3
-rw-r--r--header.LGPL-QTAS3
-rw-r--r--qmake-features/am-qml-testcase.prf3
-rw-r--r--src/application-lib/application-lib.pro12
-rw-r--r--src/application-lib/applicationinfo.cpp353
-rw-r--r--src/application-lib/applicationinfo.h115
-rw-r--r--src/application-lib/applicationinterface.cpp2
-rw-r--r--src/application-lib/applicationinterface.h2
-rw-r--r--src/application-lib/installationreport.cpp50
-rw-r--r--src/application-lib/installationreport.h14
-rw-r--r--src/application-lib/intentinfo.cpp (renamed from src/package-lib/package_p.cpp)124
-rw-r--r--src/application-lib/intentinfo.h (renamed from src/installer-lib/installationlocation.h)66
-rw-r--r--src/application-lib/packagedatabase.cpp221
-rw-r--r--src/application-lib/packagedatabase.h (renamed from src/manager-lib/applicationdatabase.h)59
-rw-r--r--src/application-lib/packageinfo.cpp283
-rw-r--r--src/application-lib/packageinfo.h122
-rw-r--r--src/application-lib/packagescanner.h (renamed from src/application-lib/applicationscanner.h)16
-rw-r--r--src/application-lib/yamlapplicationscanner.cpp229
-rw-r--r--src/application-lib/yamlpackagescanner.cpp383
-rw-r--r--src/application-lib/yamlpackagescanner.h (renamed from src/application-lib/yamlapplicationscanner.h)18
-rw-r--r--src/common-lib/crashhandler.cpp2
-rw-r--r--src/common-lib/crashhandler.h2
-rw-r--r--src/common-lib/dbus-utilities.cpp2
-rw-r--r--src/common-lib/dbus-utilities.h2
-rw-r--r--src/common-lib/error.h2
-rw-r--r--src/common-lib/exception.cpp2
-rw-r--r--src/common-lib/exception.h2
-rw-r--r--src/common-lib/global.h2
-rw-r--r--src/common-lib/logging.cpp6
-rw-r--r--src/common-lib/logging.h2
-rw-r--r--src/common-lib/processtitle.cpp2
-rw-r--r--src/common-lib/processtitle.h2
-rw-r--r--src/common-lib/qml-utilities.cpp2
-rw-r--r--src/common-lib/qml-utilities.h2
-rw-r--r--src/common-lib/qtyaml.cpp2
-rw-r--r--src/common-lib/qtyaml.h2
-rw-r--r--src/common-lib/startuptimer.cpp2
-rw-r--r--src/common-lib/startuptimer.h2
-rw-r--r--src/common-lib/unixsignalhandler.cpp2
-rw-r--r--src/common-lib/unixsignalhandler.h2
-rw-r--r--src/common-lib/utilities.cpp6
-rw-r--r--src/common-lib/utilities.h2
-rw-r--r--src/crypto-lib/cryptography.cpp2
-rw-r--r--src/crypto-lib/cryptography.h2
-rw-r--r--src/crypto-lib/libcryptofunction.cpp2
-rw-r--r--src/crypto-lib/libcryptofunction.h2
-rw-r--r--src/crypto-lib/signature.cpp2
-rw-r--r--src/crypto-lib/signature.h2
-rw-r--r--src/crypto-lib/signature_macos.cpp2
-rw-r--r--src/crypto-lib/signature_openssl.cpp2
-rw-r--r--src/crypto-lib/signature_p.h2
-rw-r--r--src/crypto-lib/signature_win.cpp2
-rw-r--r--src/dbus-lib/abstractdbuscontextadaptor.cpp2
-rw-r--r--src/dbus-lib/abstractdbuscontextadaptor.h2
-rw-r--r--src/dbus-lib/applicationinstallerdbuscontextadaptor.cpp204
-rw-r--r--src/dbus-lib/applicationmanagerdbuscontextadaptor.cpp2
-rw-r--r--src/dbus-lib/applicationmanagerdbuscontextadaptor.h2
-rw-r--r--src/dbus-lib/dbus-lib.pro15
-rw-r--r--src/dbus-lib/dbusdaemon.cpp2
-rw-r--r--src/dbus-lib/dbusdaemon.h2
-rw-r--r--src/dbus-lib/dbuspolicy.cpp2
-rw-r--r--src/dbus-lib/dbuspolicy.h2
-rw-r--r--src/dbus-lib/io.qt.packagemanager.xml (renamed from src/dbus-lib/io.qt.applicationinstaller.xml)29
-rw-r--r--src/dbus-lib/notificationmanagerdbuscontextadaptor.cpp2
-rw-r--r--src/dbus-lib/notificationmanagerdbuscontextadaptor.h2
-rw-r--r--src/dbus-lib/packagemanagerdbuscontextadaptor.cpp210
-rw-r--r--src/dbus-lib/packagemanagerdbuscontextadaptor.h (renamed from src/dbus-lib/applicationinstallerdbuscontextadaptor.h)8
-rw-r--r--src/dbus-lib/windowmanagerdbuscontextadaptor.cpp2
-rw-r--r--src/dbus-lib/windowmanagerdbuscontextadaptor.h2
-rw-r--r--src/installer-lib/applicationinstaller.cpp1042
-rw-r--r--src/installer-lib/installationlocation.cpp229
-rw-r--r--src/installer-lib/installer-lib.pro40
-rw-r--r--src/intent-client-lib/intentclient.cpp2
-rw-r--r--src/intent-client-lib/intentclient.h2
-rw-r--r--src/intent-client-lib/intentclientrequest.cpp2
-rw-r--r--src/intent-client-lib/intentclientrequest.h2
-rw-r--r--src/intent-client-lib/intentclientsysteminterface.cpp2
-rw-r--r--src/intent-client-lib/intentclientsysteminterface.h2
-rw-r--r--src/intent-client-lib/intenthandler.cpp2
-rw-r--r--src/intent-client-lib/intenthandler.h2
-rw-r--r--src/intent-server-lib/intent.cpp2
-rw-r--r--src/intent-server-lib/intent.h2
-rw-r--r--src/intent-server-lib/intentserver.cpp5
-rw-r--r--src/intent-server-lib/intentserver.h2
-rw-r--r--src/intent-server-lib/intentserverrequest.cpp2
-rw-r--r--src/intent-server-lib/intentserverrequest.h2
-rw-r--r--src/intent-server-lib/intentserversysteminterface.cpp2
-rw-r--r--src/intent-server-lib/intentserversysteminterface.h2
-rw-r--r--src/launcher-lib/applicationmanagerwindow.cpp2
-rw-r--r--src/launcher-lib/applicationmanagerwindow_p.h2
-rw-r--r--src/launcher-lib/intentclientdbusimplementation.cpp2
-rw-r--r--src/launcher-lib/intentclientdbusimplementation.h2
-rw-r--r--src/launcher-lib/ipcwrapperobject.cpp2
-rw-r--r--src/launcher-lib/ipcwrapperobject.h2
-rw-r--r--src/launcher-lib/ipcwrapperobject_p.h2
-rw-r--r--src/launcher-lib/launchermain.cpp2
-rw-r--r--src/launcher-lib/launchermain.h2
-rw-r--r--src/launcher-lib/qmlapplicationinterface.cpp2
-rw-r--r--src/launcher-lib/qmlapplicationinterface.h2
-rw-r--r--src/launcher-lib/qmlapplicationinterfaceextension.cpp2
-rw-r--r--src/launcher-lib/qmlapplicationinterfaceextension.h2
-rw-r--r--src/launcher-lib/qmlnotification.cpp2
-rw-r--r--src/launcher-lib/qmlnotification.h2
-rw-r--r--src/launcher-lib/waylandqtamclientextension.cpp2
-rw-r--r--src/launcher-lib/waylandqtamclientextension_p.h2
-rw-r--r--src/main-lib/applicationinstaller.cpp461
-rw-r--r--src/main-lib/applicationinstaller.h202
-rw-r--r--src/main-lib/configuration.cpp2
-rw-r--r--src/main-lib/configuration.h2
-rw-r--r--src/main-lib/defaultconfiguration.cpp54
-rw-r--r--src/main-lib/defaultconfiguration.h11
-rw-r--r--src/main-lib/main-lib.pro3
-rw-r--r--src/main-lib/main.cpp375
-rw-r--r--src/main-lib/main.h31
-rw-r--r--src/main-lib/windowframetimer.cpp2
-rw-r--r--src/main-lib/windowframetimer.h2
-rw-r--r--src/manager-lib/abstractcontainer.cpp8
-rw-r--r--src/manager-lib/abstractcontainer.h16
-rw-r--r--src/manager-lib/abstractruntime.cpp2
-rw-r--r--src/manager-lib/abstractruntime.h2
-rw-r--r--src/manager-lib/amnamespace.h2
-rw-r--r--src/manager-lib/application.cpp385
-rw-r--r--src/manager-lib/application.h179
-rw-r--r--src/manager-lib/applicationdatabase.cpp184
-rw-r--r--src/manager-lib/applicationipcinterface.cpp10
-rw-r--r--src/manager-lib/applicationipcinterface.h8
-rw-r--r--src/manager-lib/applicationipcinterface_p.h8
-rw-r--r--src/manager-lib/applicationipcmanager.cpp2
-rw-r--r--src/manager-lib/applicationipcmanager.h2
-rw-r--r--src/manager-lib/applicationmanager.cpp413
-rw-r--r--src/manager-lib/applicationmanager.h47
-rw-r--r--src/manager-lib/applicationmanager_p.h5
-rw-r--r--src/manager-lib/applicationmodel.cpp2
-rw-r--r--src/manager-lib/applicationmodel.h2
-rw-r--r--src/manager-lib/asynchronoustask.cpp (renamed from src/installer-lib/asynchronoustask.cpp)16
-rw-r--r--src/manager-lib/asynchronoustask.h (renamed from src/installer-lib/asynchronoustask.h)10
-rw-r--r--src/manager-lib/containerfactory.cpp4
-rw-r--r--src/manager-lib/containerfactory.h6
-rw-r--r--src/manager-lib/debugwrapper.cpp2
-rw-r--r--src/manager-lib/debugwrapper.h2
-rw-r--r--src/manager-lib/deinstallationtask.cpp (renamed from src/installer-lib/deinstallationtask.cpp)90
-rw-r--r--src/manager-lib/deinstallationtask.h (renamed from src/installer-lib/deinstallationtask.h)13
-rw-r--r--src/manager-lib/inprocesssurfaceitem.cpp2
-rw-r--r--src/manager-lib/inprocesssurfaceitem.h2
-rw-r--r--src/manager-lib/installationtask.cpp (renamed from src/installer-lib/installationtask.cpp)187
-rw-r--r--src/manager-lib/installationtask.h (renamed from src/installer-lib/installationtask.h)23
-rw-r--r--src/manager-lib/intentaminterface.cpp72
-rw-r--r--src/manager-lib/intentaminterface.h6
-rw-r--r--src/manager-lib/manager-lib.pro29
-rw-r--r--src/manager-lib/nativeruntime.cpp17
-rw-r--r--src/manager-lib/nativeruntime.h2
-rw-r--r--src/manager-lib/nativeruntime_p.h2
-rw-r--r--src/manager-lib/notificationmanager.cpp8
-rw-r--r--src/manager-lib/notificationmanager.h2
-rw-r--r--src/manager-lib/package.cpp237
-rw-r--r--src/manager-lib/package.h151
-rw-r--r--src/manager-lib/packagemanager.cpp1192
-rw-r--r--src/manager-lib/packagemanager.h (renamed from src/installer-lib/applicationinstaller.h)142
-rw-r--r--src/manager-lib/packagemanager_p.h (renamed from src/installer-lib/applicationinstaller_p.h)17
-rw-r--r--src/manager-lib/plugincontainer.cpp6
-rw-r--r--src/manager-lib/plugincontainer.h6
-rw-r--r--src/manager-lib/processcontainer.cpp6
-rw-r--r--src/manager-lib/processcontainer.h6
-rw-r--r--src/manager-lib/processstatus.cpp4
-rw-r--r--src/manager-lib/processstatus.h4
-rw-r--r--src/manager-lib/qmlinprocessapplicationinterface.cpp6
-rw-r--r--src/manager-lib/qmlinprocessapplicationinterface.h2
-rw-r--r--src/manager-lib/qmlinprocessapplicationmanagerwindow.cpp4
-rw-r--r--src/manager-lib/qmlinprocessapplicationmanagerwindow.h2
-rw-r--r--src/manager-lib/qmlinprocessruntime.cpp17
-rw-r--r--src/manager-lib/qmlinprocessruntime.h3
-rw-r--r--src/manager-lib/quicklauncher.cpp2
-rw-r--r--src/manager-lib/quicklauncher.h2
-rw-r--r--src/manager-lib/runtimefactory.cpp2
-rw-r--r--src/manager-lib/runtimefactory.h2
-rw-r--r--src/manager-lib/scopeutilities.cpp (renamed from src/installer-lib/scopeutilities.cpp)5
-rw-r--r--src/manager-lib/scopeutilities.h (renamed from src/installer-lib/scopeutilities.h)2
-rw-r--r--src/manager-lib/sudo.cpp (renamed from src/installer-lib/sudo.cpp)2
-rw-r--r--src/manager-lib/sudo.h (renamed from src/installer-lib/sudo.h)2
-rw-r--r--src/monitor-lib/processreader.cpp2
-rw-r--r--src/monitor-lib/processreader.h2
-rw-r--r--src/monitor-lib/sysfsreader.cpp2
-rw-r--r--src/monitor-lib/sysfsreader.h2
-rw-r--r--src/monitor-lib/systemreader.cpp2
-rw-r--r--src/monitor-lib/systemreader.h2
-rw-r--r--src/notification-lib/notification.cpp2
-rw-r--r--src/notification-lib/notification.h2
-rw-r--r--src/package-lib/package-lib.pro7
-rw-r--r--src/package-lib/packagecreator.cpp12
-rw-r--r--src/package-lib/packagecreator.h2
-rw-r--r--src/package-lib/packagecreator_p.h2
-rw-r--r--src/package-lib/packageextractor.cpp16
-rw-r--r--src/package-lib/packageextractor.h2
-rw-r--r--src/package-lib/packageextractor_p.h2
-rw-r--r--src/package-lib/packageutilities.cpp (renamed from src/package-lib/package.cpp)53
-rw-r--r--src/package-lib/packageutilities.h (renamed from src/package-lib/package.h)4
-rw-r--r--src/package-lib/packageutilities_p.h (renamed from src/package-lib/package_p.h)13
-rw-r--r--src/plugin-interfaces/containerinterface.cpp6
-rw-r--r--src/plugin-interfaces/containerinterface.h2
-rw-r--r--src/plugin-interfaces/startupinterface.cpp2
-rw-r--r--src/plugin-interfaces/startupinterface.h2
-rw-r--r--src/shared-main-lib/cpustatus.cpp2
-rw-r--r--src/shared-main-lib/cpustatus.h2
-rw-r--r--src/shared-main-lib/frametimer.cpp2
-rw-r--r--src/shared-main-lib/frametimer.h2
-rw-r--r--src/shared-main-lib/gpustatus.cpp2
-rw-r--r--src/shared-main-lib/gpustatus.h2
-rw-r--r--src/shared-main-lib/iostatus.cpp2
-rw-r--r--src/shared-main-lib/iostatus.h2
-rw-r--r--src/shared-main-lib/memorystatus.cpp2
-rw-r--r--src/shared-main-lib/memorystatus.h2
-rw-r--r--src/shared-main-lib/monitormodel.cpp2
-rw-r--r--src/shared-main-lib/monitormodel.h2
-rw-r--r--src/shared-main-lib/qmllogger.cpp2
-rw-r--r--src/shared-main-lib/qmllogger.h2
-rw-r--r--src/shared-main-lib/sharedmain.cpp2
-rw-r--r--src/shared-main-lib/sharedmain.h2
-rw-r--r--src/src.pro25
-rw-r--r--src/tools/appman/appman.cpp14
-rw-r--r--src/tools/controller/controller.cpp164
-rw-r--r--src/tools/controller/controller.pro2
-rw-r--r--src/tools/controller/interrupthandler.cpp2
-rw-r--r--src/tools/controller/interrupthandler.h2
-rw-r--r--src/tools/dumpqmltypes/dumpqmltypes.cpp12
-rw-r--r--src/tools/dumpqmltypes/dumpqmltypes.pro2
-rw-r--r--src/tools/launcher-qml/launcher-qml.cpp17
-rw-r--r--src/tools/launcher-qml/launcher-qml_p.h2
-rw-r--r--src/tools/packager/packager.cpp12
-rw-r--r--src/tools/packager/packagingjob.cpp56
-rw-r--r--src/tools/packager/packagingjob.h2
-rw-r--r--src/tools/testrunner/testrunner.cpp17
-rw-r--r--src/tools/testrunner/testrunner.h4
-rw-r--r--src/tools/testrunner/testrunner_p.h2
-rw-r--r--src/tools/uploader/uploader.cpp6
-rw-r--r--src/wayland-extensions/qtam-extension.xml2
-rw-r--r--src/window-lib/inprocesswindow.cpp4
-rw-r--r--src/window-lib/inprocesswindow.h4
-rw-r--r--src/window-lib/touchemulation.cpp2
-rw-r--r--src/window-lib/touchemulation.h2
-rw-r--r--src/window-lib/touchemulation_x11.cpp2
-rw-r--r--src/window-lib/touchemulation_x11_p.h2
-rw-r--r--src/window-lib/waylandcompositor.cpp2
-rw-r--r--src/window-lib/waylandcompositor.h2
-rw-r--r--src/window-lib/waylandqtamserverextension.cpp2
-rw-r--r--src/window-lib/waylandqtamserverextension_p.h2
-rw-r--r--src/window-lib/waylandwindow.cpp4
-rw-r--r--src/window-lib/waylandwindow.h4
-rw-r--r--src/window-lib/window-lib.pro2
-rw-r--r--src/window-lib/window.cpp6
-rw-r--r--src/window-lib/window.h10
-rw-r--r--src/window-lib/windowitem.cpp2
-rw-r--r--src/window-lib/windowitem.h2
-rw-r--r--src/window-lib/windowmanager.cpp57
-rw-r--r--src/window-lib/windowmanager.h9
-rw-r--r--src/window-lib/windowmanager_p.h4
-rw-r--r--template-opt/am/config-windows.yaml13
-rw-r--r--template-opt/am/config.yaml18
-rw-r--r--tests/application/tst_application.cpp15
-rw-r--r--tests/applicationinfo/tst_applicationinfo.cpp194
-rw-r--r--tests/applicationinstaller/applicationinstaller.pro1
-rw-r--r--tests/applicationinstaller/tst_applicationinstaller.cpp389
-rw-r--r--tests/cryptography/tst_cryptography.cpp2
-rwxr-xr-xtests/data/certificates/create-test-certificates.sh2
-rwxr-xr-xtests/data/create-test-packages.sh10
-rwxr-xr-xtests/data/utilities.sh2
-rw-r--r--tests/debugwrapper/tst_debugwrapper.cpp2
-rw-r--r--tests/error-checking.h2
-rw-r--r--tests/installationreport/tst_installationreport.cpp9
-rw-r--r--tests/main/am-config.yaml11
-rw-r--r--tests/main/dummy.qml0
-rw-r--r--tests/main/main.pro2
-rw-r--r--tests/main/main.qrc5
-rw-r--r--tests/main/tst_main.cpp89
-rw-r--r--tests/manual/manual.pro6
-rw-r--r--tests/manual/monitormodel/PropertyField.qml2
-rw-r--r--tests/manual/monitormodel/SystemMonitorChart.qml2
-rw-r--r--tests/manual/monitormodel/main.qml4
-rw-r--r--tests/manual/monitormodel/monitormodel.pro5
-rw-r--r--tests/packagecreator/tst_packagecreator.cpp8
-rw-r--r--tests/packageextractor/tst_packageextractor.cpp8
-rw-r--r--tests/packager-tool/packager-tool.pro5
-rw-r--r--tests/packager-tool/tst_packager-tool.cpp61
-rw-r--r--tests/processreader/tst_processreader.cpp2
-rw-r--r--tests/qml/configs/apps/test.configs.app/app.qml2
-rw-r--r--tests/qml/configs/configs.pro1
-rw-r--r--tests/qml/configs/tst_configs.qml2
-rw-r--r--tests/qml/crash/apps/tld.test.crash/app.qml2
-rw-r--r--tests/qml/crash/apps/tld.test.crash/terminator2/qmlterminator2.cpp2
-rw-r--r--tests/qml/crash/apps/tld.test.crash/terminator2/qmlterminator2.h2
-rw-r--r--tests/qml/crash/crash.pro2
-rw-r--r--tests/qml/crash/tst_crash.qml2
-rw-r--r--tests/qml/installer/tst_installer.qml2
-rw-r--r--tests/qml/intents/apps/intents1/intents1.qml2
-rw-r--r--tests/qml/intents/apps/intents2/intents2.qml2
-rw-r--r--tests/qml/intents/intents.pro4
-rw-r--r--tests/qml/intents/tst_intents.qml2
-rw-r--r--tests/qml/quicklaunch/apps/tld.test.quicklaunch/app.qml2
-rw-r--r--tests/qml/quicklaunch/quicklaunch.pro1
-rw-r--r--tests/qml/quicklaunch/tst_quicklaunch.qml2
-rw-r--r--tests/qml/simple/apps/tld.test.simple1/app1.qml2
-rw-r--r--tests/qml/simple/apps/tld.test.simple2/app.qml2
-rw-r--r--tests/qml/simple/simple.pro1
-rw-r--r--tests/qml/simple/tst_applicationmanager.qml2
-rw-r--r--tests/qml/windowitem/apps/test.windowitem.app/main.qml2
-rw-r--r--tests/qml/windowitem/apps/test.windowitem.multiwin/main.qml2
-rw-r--r--tests/qml/windowitem/tst_windowitem.qml2
-rw-r--r--tests/qml/windowitem/windowitem.pro1
-rw-r--r--tests/qml/windowitem2/apps/test.windowitem2.app/main.qml2
-rw-r--r--tests/qml/windowitem2/tst_windowitem2.qml2
-rw-r--r--tests/qml/windowitem2/windowitem2.pro1
-rw-r--r--tests/qml/windowmanager/IviApplicationExtension.qml2
-rw-r--r--tests/qml/windowmanager/tst_windowmanager.qml2
-rw-r--r--tests/qml/windowmanager/windowmanager.pro2
-rw-r--r--tests/qml/windowmapping/apps/test.winmap.amwin/amwin.qml2
-rw-r--r--tests/qml/windowmapping/apps/test.winmap.amwin2/amwin2.qml2
-rw-r--r--tests/qml/windowmapping/apps/test.winmap.loader/SubWin.qml2
-rw-r--r--tests/qml/windowmapping/apps/test.winmap.loader/loader.qml2
-rw-r--r--tests/qml/windowmapping/apps/test.winmap.ping/ping.qml2
-rw-r--r--tests/qml/windowmapping/apps/test.winmap.qtobject/qtobject.qml2
-rw-r--r--tests/qml/windowmapping/apps/test.winmap.rectangle/rectangle.qml2
-rw-r--r--tests/qml/windowmapping/apps/test.winmap.window/window.qml2
-rw-r--r--tests/qml/windowmapping/tst_windowmapping.qml2
-rw-r--r--tests/qml/windowmapping/windowmapping.pro8
-rw-r--r--tests/runtime/tst_runtime.cpp16
-rwxr-xr-xtests/signature/create-test-data.sh2
-rw-r--r--tests/signature/signature.pro2
-rw-r--r--tests/signature/tst_signature.cpp2
-rw-r--r--tests/sudo/sudo.pro2
-rw-r--r--tests/sudo/tst_sudo.cpp2
-rw-r--r--tests/systemreader/tst_systemreader.cpp2
-rw-r--r--tests/tests.pro2
-rw-r--r--tests/utilities/tst_utilities.cpp2
-rw-r--r--util/bash/appman-prompt4
422 files changed, 5645 insertions, 5050 deletions
diff --git a/.qmake.conf b/.qmake.conf
index 8257f184..4a22cc51 100644
--- a/.qmake.conf
+++ b/.qmake.conf
@@ -1,6 +1,6 @@
load(qt_build_config)
-MODULE_VERSION = 5.13.1
+MODULE_VERSION = 5.14.0
SOURCE_DIR=$$PWD
BUILD_DIR=$$shadowed($$PWD)
diff --git a/application-manager.pro b/application-manager.pro
index 62771a35..7fd99d16 100644
--- a/application-manager.pro
+++ b/application-manager.pro
@@ -116,6 +116,7 @@ OTHER_FILES += \
LICENSE.*[^~] \
config.tests/libarchive/* \
config.tests/libyaml/* \
+ config.tests/touchemulation/* \
util/bash/appman-prompt \
util/bash/README \
diff --git a/benchmarks/appman-bench/run.sh b/benchmarks/appman-bench/run.sh
index eb5b894c..2cb1ddd9 100755
--- a/benchmarks/appman-bench/run.sh
+++ b/benchmarks/appman-bench/run.sh
@@ -5,7 +5,7 @@
## Copyright (C) 2018 Pelagicore AG
## 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:BSD-QTAS$
## Commercial License Usage
diff --git a/benchmarks/appman-bench/system-ui/main.qml b/benchmarks/appman-bench/system-ui/main.qml
index 762303ac..fa7de877 100644
--- a/benchmarks/appman-bench/system-ui/main.qml
+++ b/benchmarks/appman-bench/system-ui/main.qml
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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:BSD-QTAS$
** Commercial License Usage
diff --git a/benchmarks/appman-bench/templates/appman-qml/main.qml b/benchmarks/appman-bench/templates/appman-qml/main.qml
index b15ea8aa..87b4597c 100644
--- a/benchmarks/appman-bench/templates/appman-qml/main.qml
+++ b/benchmarks/appman-bench/templates/appman-qml/main.qml
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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:BSD-QTAS$
** Commercial License Usage
diff --git a/benchmarks/appman-bench/templates/qmlscene/main.qml b/benchmarks/appman-bench/templates/qmlscene/main.qml
index f31cc6a2..2d1dcf6e 100644
--- a/benchmarks/appman-bench/templates/qmlscene/main.qml
+++ b/benchmarks/appman-bench/templates/qmlscene/main.qml
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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:BSD-QTAS$
** Commercial License Usage
diff --git a/benchmarks/appman-bench/tests/controls2.qml b/benchmarks/appman-bench/tests/controls2.qml
index 169d6163..f34db8a2 100644
--- a/benchmarks/appman-bench/tests/controls2.qml
+++ b/benchmarks/appman-bench/tests/controls2.qml
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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:BSD-QTAS$
** Commercial License Usage
diff --git a/benchmarks/appman-bench/tests/rect.qml b/benchmarks/appman-bench/tests/rect.qml
index c033e910..f5fbec06 100644
--- a/benchmarks/appman-bench/tests/rect.qml
+++ b/benchmarks/appman-bench/tests/rect.qml
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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:BSD-QTAS$
** Commercial License Usage
diff --git a/benchmarks/appman-bench/tests/repeater.qml b/benchmarks/appman-bench/tests/repeater.qml
index 2866e50d..fb759ceb 100644
--- a/benchmarks/appman-bench/tests/repeater.qml
+++ b/benchmarks/appman-bench/tests/repeater.qml
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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:BSD-QTAS$
** Commercial License Usage
diff --git a/benchmarks/appman-bench/tests/shader.qml b/benchmarks/appman-bench/tests/shader.qml
index e69d0a55..3aad12a1 100644
--- a/benchmarks/appman-bench/tests/shader.qml
+++ b/benchmarks/appman-bench/tests/shader.qml
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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:BSD-QTAS$
** Commercial License Usage
diff --git a/config.tests/libarchive/main.cpp b/config.tests/libarchive/main.cpp
index 53515610..58b21a4d 100644
--- a/config.tests/libarchive/main.cpp
+++ b/config.tests/libarchive/main.cpp
@@ -5,7 +5,7 @@
** Copyright (C) 2016 The Qt Company Ltd.
** 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/config.tests/libyaml/main.cpp b/config.tests/libyaml/main.cpp
index 546b2634..f6c5442c 100644
--- a/config.tests/libyaml/main.cpp
+++ b/config.tests/libyaml/main.cpp
@@ -5,7 +5,7 @@
** Copyright (C) 2016 The Qt Company Ltd.
** 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/config.tests/touchemulation/main.cpp b/config.tests/touchemulation/main.cpp
index 1b012d8f..92ed9484 100644
--- a/config.tests/touchemulation/main.cpp
+++ b/config.tests/touchemulation/main.cpp
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/doc/QtApplicationManagerDoc b/doc/QtApplicationManagerDoc
index 333bf5a6..ccd77195 100644
--- a/doc/QtApplicationManagerDoc
+++ b/doc/QtApplicationManagerDoc
@@ -4,7 +4,6 @@
#include <QtAppManCommon/QtAppManCommon>
#include <QtAppManCrypto/QtAppManCrypto>
#include <QtAppManDBus/QtAppManDBus>
-#include <QtAppManInstaller/QtAppManInstaller>
#include <QtAppManIntentClient/QtAppManIntentClient>
#include <QtAppManIntentServer/QtAppManIntentServer>
#include <QtAppManLauncher/QtAppManLauncher>
diff --git a/doc/apps.qdoc b/doc/apps.qdoc
index f73aab20..49d5f708 100644
--- a/doc/apps.qdoc
+++ b/doc/apps.qdoc
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** Contact: https://www.qt.io/licensing/
**
-** This file is part of the documentation of the Luxoft Application Manager.
+** This file is part of the documentation of the Qt Application Manager.
**
** $QT_BEGIN_LICENSE:FDL-QTAS$
** Commercial License Usage
diff --git a/doc/configuration.qdoc b/doc/configuration.qdoc
index 9ef3d870..98bc8c46 100644
--- a/doc/configuration.qdoc
+++ b/doc/configuration.qdoc
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** Contact: https://www.qt.io/licensing/
**
-** This file is part of the documentation of the Luxoft Application Manager.
+** This file is part of the documentation of the Qt Application Manager.
**
** $QT_BEGIN_LICENSE:FDL-QTAS$
** Commercial License Usage
@@ -160,18 +160,18 @@ or across multiple config files, the final value is resolved based on these rule
\li The base directory for built-in application manifests; you can also specify multiple
directories as a list.
\row
- \li \b --installed-apps-manifest-dir
- \br [\c applications/installedAppsManifestDir]
+ \li \b --installation-dir
+ \br [\c applications/installationDir]
\li string
- \li The base directory for installed application manifests. This option must be specified
- if you want to install new applications; otherwise only the built-in ones are
+ \li The base directory for package installations. This option must be specified
+ if you want to install new package; otherwise only the built-in ones are
available. (default: empty/disabled)
\row
- \li \b --app-image-mount-dir
- \br [\c applications/appImageMountDir]
+ \li \b --document-dir
+ \br [\c applications/documentDir]
\li string
- \li The base directory where application images are mounted to.
- (defaults: \c /opt/am/image-mounts)
+ \li The base directory for per-package document storage directories.
+ (default: empty/disabled)
\row
\li \b --dbus
\li string
@@ -353,8 +353,9 @@ or across multiple config files, the final value is resolved based on these rule
\row
\li [\c installationLocations]
\li array<object>
- \li The definition of installation locations available on the system; an array of
- \l {Installation Locations} objects.
+ \li The definition of installation locations available on the system. This is deprecated,
+ since only a single installation location is supported now, defined by \c
+ --installationDir or \c{applications/installationDir}.
\row
\li [\c runtimes]
\li map<object>
@@ -495,52 +496,6 @@ of these available interfaces are as follows:
\l {freedesktop.org specification}
\endtable
-\section1 Installation Locations
-
-The \c installationLocations YAML field is a list of YAML objects, very similar to
-ApplicationInstaller::getInstallationLocation.
-
-\table
- \header
- \li Config Key
- \li Type
- \li Description
- \row
- \li \c id
- \li string
- \li The installation location ID that is used as the handle for all other
- ApplicationInstaller function calls. The \c id consists of a \c type and \c index
- field, concatenated with a single dash. For example, \c removable-0.
-
- Valid values for \c type are \c internal and \c removable.
-
- In case there is more than one installation location for the same type of device, this
- zero-based index is used for disambiguation. For example, two SD card slots will result
- in the IDs \c removable-0 and \c removable-1. Otherwise, the index is always \c 0.
- \row
- \li \c isDefault
- \li bool
- \li Only one installation location can be the default location, which must be mounted and
- accessible at all times. This location can be used by a UI application to get a
- sensible default for the installation location that it needs to pass to
- \l{ApplicationInstaller::startPackageInstallation()}{startPackageInstallation()}.
- \row
- \li \c installationPath
- \li string
- \li The absolute file system path to the base directory where applications are installed.
- \row
- \li \c documentPath
- \li string
- \li The absolute file system path to the base directory where per-user document directories
- are created. This entry can either be located on this device, or it can be the same as
- the \c documentPath of the master installation location.
- \row
- \li \c mountPoint
- \li string
- \li Only required for \c removable installation location: The absolute file system path to
- the mount-point of the device, where \c installationPath is located.
-\endtable
-
\section1 Runtime Configuration
The runtime configuration sub-objects are specific to the actual runtimes, so the table below has
diff --git a/doc/container.qdoc b/doc/container.qdoc
index 246fc82c..fd7070e4 100644
--- a/doc/container.qdoc
+++ b/doc/container.qdoc
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** Contact: https://www.qt.io/licensing/
**
-** This file is part of the documentation of the Luxoft Application Manager.
+** This file is part of the documentation of the Qt Application Manager.
**
** $QT_BEGIN_LICENSE:FDL-QTAS$
** Commercial License Usage
diff --git a/doc/controller.qdoc b/doc/controller.qdoc
index 6b6511c9..42af67c9 100644
--- a/doc/controller.qdoc
+++ b/doc/controller.qdoc
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** Contact: https://www.qt.io/licensing/
**
-** This file is part of the documentation of the Luxoft Application Manager.
+** This file is part of the documentation of the Qt Application Manager.
**
** $QT_BEGIN_LICENSE:FDL-QTAS$
** Commercial License Usage
@@ -85,9 +85,6 @@ The following commands are available:
\li Installs the package given on the command-line. If the package file is specified as \c{-},
the tool tries to read the package from \c stdin. The following options are supported:
- \c{-l, --location}: Install to a specific installation location
- (see \c show-installation-location).
-
\c{-a, --acknowledge}: Automatically acknowledge the installation, instead of relying on
the System UI's logic.
\row
diff --git a/doc/debugging.qdoc b/doc/debugging.qdoc
index c1ecfe05..687e1fa7 100644
--- a/doc/debugging.qdoc
+++ b/doc/debugging.qdoc
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** Contact: https://www.qt.io/licensing/
**
-** This file is part of the documentation of the Luxoft Application Manager.
+** This file is part of the documentation of the Qt Application Manager.
**
** $QT_BEGIN_LICENSE:FDL-QTAS$
** Commercial License Usage
diff --git a/doc/elements-apps.qdoc b/doc/elements-apps.qdoc
index fc62c2d3..31658aea 100644
--- a/doc/elements-apps.qdoc
+++ b/doc/elements-apps.qdoc
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** Contact: https://www.qt.io/licensing/
**
-** This file is part of the documentation of the Luxoft Application Manager.
+** This file is part of the documentation of the Qt Application Manager.
**
** $QT_BEGIN_LICENSE:FDL-QTAS$
** Commercial License Usage
diff --git a/doc/elements-common.qdoc b/doc/elements-common.qdoc
index bcd505c4..d1f445a2 100644
--- a/doc/elements-common.qdoc
+++ b/doc/elements-common.qdoc
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** Contact: https://www.qt.io/licensing/
**
-** This file is part of the documentation of the Luxoft Application Manager.
+** This file is part of the documentation of the Qt Application Manager.
**
** $QT_BEGIN_LICENSE:FDL-QTAS$
** Commercial License Usage
diff --git a/doc/elements-systemui.qdoc b/doc/elements-systemui.qdoc
index df5df122..0db9ac7a 100644
--- a/doc/elements-systemui.qdoc
+++ b/doc/elements-systemui.qdoc
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** Contact: https://www.qt.io/licensing/
**
-** This file is part of the documentation of the Luxoft Application Manager.
+** This file is part of the documentation of the Qt Application Manager.
**
** $QT_BEGIN_LICENSE:FDL-QTAS$
** Commercial License Usage
diff --git a/doc/index.qdoc b/doc/index.qdoc
index 64f5a0d1..47e33165 100644
--- a/doc/index.qdoc
+++ b/doc/index.qdoc
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** Contact: https://www.qt.io/licensing/
**
-** This file is part of the documentation of the Luxoft Application Manager.
+** This file is part of the documentation of the Qt Application Manager.
**
** $QT_BEGIN_LICENSE:FDL-QTAS$
** Commercial License Usage
diff --git a/doc/installation.qdoc b/doc/installation.qdoc
index c7b59c14..dbc02466 100644
--- a/doc/installation.qdoc
+++ b/doc/installation.qdoc
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** Contact: https://www.qt.io/licensing/
**
-** This file is part of the documentation of the Luxoft Application Manager.
+** This file is part of the documentation of the Qt Application Manager.
**
** $QT_BEGIN_LICENSE:FDL-QTAS$
** Commercial License Usage
diff --git a/doc/installer.qdoc b/doc/installer.qdoc
index 74016e6a..54989990 100644
--- a/doc/installer.qdoc
+++ b/doc/installer.qdoc
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** Contact: https://www.qt.io/licensing/
**
-** This file is part of the documentation of the Luxoft Application Manager.
+** This file is part of the documentation of the Qt Application Manager.
**
** $QT_BEGIN_LICENSE:FDL-QTAS$
** Commercial License Usage
diff --git a/doc/introduction.qdoc b/doc/introduction.qdoc
index abf4610e..53eefb33 100644
--- a/doc/introduction.qdoc
+++ b/doc/introduction.qdoc
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** Contact: https://www.qt.io/licensing/
**
-** This file is part of the documentation of the Luxoft Application Manager.
+** This file is part of the documentation of the Qt Application Manager.
**
** $QT_BEGIN_LICENSE:FDL-QTAS$
** Commercial License Usage
diff --git a/doc/manifest.qdoc b/doc/manifest.qdoc
index bd7a465a..17f6e2bc 100644
--- a/doc/manifest.qdoc
+++ b/doc/manifest.qdoc
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** Contact: https://www.qt.io/licensing/
**
-** This file is part of the documentation of the Luxoft Application Manager.
+** This file is part of the documentation of the Qt Application Manager.
**
** $QT_BEGIN_LICENSE:FDL-QTAS$
** Commercial License Usage
diff --git a/doc/migration-guide-5.12.qdoc b/doc/migration-guide-5.12.qdoc
index 52ab19ff..f25b4f03 100644
--- a/doc/migration-guide-5.12.qdoc
+++ b/doc/migration-guide-5.12.qdoc
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** Contact: https://www.qt.io/licensing/
**
-** This file is part of the documentation of the Luxoft Application Manager.
+** This file is part of the documentation of the Qt Application Manager.
**
** $QT_BEGIN_LICENSE:FDL-QTAS$
** Commercial License Usage
diff --git a/doc/package-format.qdoc b/doc/package-format.qdoc
index 68d47ccc..8e49492d 100644
--- a/doc/package-format.qdoc
+++ b/doc/package-format.qdoc
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** Contact: https://www.qt.io/licensing/
**
-** This file is part of the documentation of the Luxoft Application Manager.
+** This file is part of the documentation of the Qt Application Manager.
**
** $QT_BEGIN_LICENSE:FDL-QTAS$
** Commercial License Usage
diff --git a/doc/packager.qdoc b/doc/packager.qdoc
index aba3fdd9..87bef980 100644
--- a/doc/packager.qdoc
+++ b/doc/packager.qdoc
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** Contact: https://www.qt.io/licensing/
**
-** This file is part of the documentation of the Luxoft Application Manager.
+** This file is part of the documentation of the Qt Application Manager.
**
** $QT_BEGIN_LICENSE:FDL-QTAS$
** Commercial License Usage
diff --git a/doc/qmlmodule.qdoc b/doc/qmlmodule.qdoc
index a297eb65..16181370 100644
--- a/doc/qmlmodule.qdoc
+++ b/doc/qmlmodule.qdoc
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** Contact: https://www.qt.io/licensing/
**
-** This file is part of the documentation of the Luxoft Application Manager.
+** This file is part of the documentation of the Qt Application Manager.
**
** $QT_BEGIN_LICENSE:FDL-QTAS$
** Commercial License Usage
diff --git a/doc/singlevsmultiprocess.qdoc b/doc/singlevsmultiprocess.qdoc
index 04748c05..f4000092 100644
--- a/doc/singlevsmultiprocess.qdoc
+++ b/doc/singlevsmultiprocess.qdoc
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** Contact: https://www.qt.io/licensing/
**
-** This file is part of the documentation of the Luxoft Application Manager.
+** This file is part of the documentation of the Qt Application Manager.
**
** $QT_BEGIN_LICENSE:FDL-QTAS$
** Commercial License Usage
diff --git a/doc/systemui.qdoc b/doc/systemui.qdoc
index 23732991..334e940c 100644
--- a/doc/systemui.qdoc
+++ b/doc/systemui.qdoc
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** Contact: https://www.qt.io/licensing/
**
-** This file is part of the documentation of the Luxoft Application Manager.
+** This file is part of the documentation of the Qt Application Manager.
**
** $QT_BEGIN_LICENSE:FDL-QTAS$
** Commercial License Usage
diff --git a/doc/troubleshooting.qdoc b/doc/troubleshooting.qdoc
index 48610b96..fd05bfc0 100644
--- a/doc/troubleshooting.qdoc
+++ b/doc/troubleshooting.qdoc
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** Contact: https://www.qt.io/licensing/
**
-** This file is part of the documentation of the Luxoft Application Manager.
+** This file is part of the documentation of the Qt Application Manager.
**
** $QT_BEGIN_LICENSE:FDL-QTAS$
** Commercial License Usage
diff --git a/doc/yaml.qdoc b/doc/yaml.qdoc
index b87c5eaf..8ee10d4b 100644
--- a/doc/yaml.qdoc
+++ b/doc/yaml.qdoc
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** Contact: https://www.qt.io/licensing/
**
-** This file is part of the documentation of the Luxoft Application Manager.
+** This file is part of the documentation of the Qt Application Manager.
**
** $QT_BEGIN_LICENSE:FDL-QTAS$
** Commercial License Usage
diff --git a/examples/applicationmanager/animated-windows/apps/animated-windows.fish/fish.qml b/examples/applicationmanager/animated-windows/apps/animated-windows.fish/fish.qml
index 1c6a56e5..60e64926 100644
--- a/examples/applicationmanager/animated-windows/apps/animated-windows.fish/fish.qml
+++ b/examples/applicationmanager/animated-windows/apps/animated-windows.fish/fish.qml
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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:BSD-QTAS$
** Commercial License Usage
diff --git a/examples/applicationmanager/animated-windows/apps/animated-windows.rabbit/rabbit.qml b/examples/applicationmanager/animated-windows/apps/animated-windows.rabbit/rabbit.qml
index 4b5892b0..42a2cfab 100644
--- a/examples/applicationmanager/animated-windows/apps/animated-windows.rabbit/rabbit.qml
+++ b/examples/applicationmanager/animated-windows/apps/animated-windows.rabbit/rabbit.qml
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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:BSD-QTAS$
** Commercial License Usage
diff --git a/examples/applicationmanager/animated-windows/doc/src/animated-windows.qdoc b/examples/applicationmanager/animated-windows/doc/src/animated-windows.qdoc
index d412054c..efdb3157 100644
--- a/examples/applicationmanager/animated-windows/doc/src/animated-windows.qdoc
+++ b/examples/applicationmanager/animated-windows/doc/src/animated-windows.qdoc
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** Contact: https://www.qt.io/licensing/
**
-** This file is part of the documentation of the Luxoft Application Manager.
+** This file is part of the documentation of the Qt Application Manager.
**
** $QT_BEGIN_LICENSE:FDL-QTAS$
** Commercial License Usage
diff --git a/examples/applicationmanager/animated-windows/system-ui/main.qml b/examples/applicationmanager/animated-windows/system-ui/main.qml
index cab98951..fd64b494 100644
--- a/examples/applicationmanager/animated-windows/system-ui/main.qml
+++ b/examples/applicationmanager/animated-windows/system-ui/main.qml
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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:BSD-QTAS$
** Commercial License Usage
diff --git a/examples/applicationmanager/custom-appman/custom-appman.cpp b/examples/applicationmanager/custom-appman/custom-appman.cpp
index 85f5d87a..45591130 100644
--- a/examples/applicationmanager/custom-appman/custom-appman.cpp
+++ b/examples/applicationmanager/custom-appman/custom-appman.cpp
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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:BSD-QTAS$
** Commercial License Usage
@@ -55,8 +55,8 @@
#include <QtAppManCommon/logging.h>
#include <QtAppManMain/main.h>
#include <QtAppManMain/defaultconfiguration.h>
-#include <QtAppManPackage/package.h>
-#include <QtAppManInstaller/sudo.h>
+#include <QtAppManPackage/packageutilities.h>
+#include <QtAppManManager/sudo.h>
QT_USE_NAMESPACE_AM
@@ -67,7 +67,7 @@ Q_DECL_EXPORT int main(int argc, char *argv[])
QCoreApplication::setApplicationVersion("0.1");
Logging::initialize(argc, argv);
- Package::ensureCorrectLocale();
+ PackageUtilities::ensureCorrectLocale();
Sudo::forkServer(Sudo::DropPrivilegesPermanently);
try {
diff --git a/examples/applicationmanager/custom-appman/doc/src/custom-appman.qdoc b/examples/applicationmanager/custom-appman/doc/src/custom-appman.qdoc
index 2f819c32..7aed03bb 100644
--- a/examples/applicationmanager/custom-appman/doc/src/custom-appman.qdoc
+++ b/examples/applicationmanager/custom-appman/doc/src/custom-appman.qdoc
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** Contact: https://www.qt.io/licensing/
**
-** This file is part of the documentation of the Luxoft Application Manager.
+** This file is part of the documentation of the Qt Application Manager.
**
** $QT_BEGIN_LICENSE:FDL-QTAS$
** Commercial License Usage
diff --git a/examples/applicationmanager/frame-timer/apps/frame-timer.fish/fish.qml b/examples/applicationmanager/frame-timer/apps/frame-timer.fish/fish.qml
index 823ce505..9d3c6107 100644
--- a/examples/applicationmanager/frame-timer/apps/frame-timer.fish/fish.qml
+++ b/examples/applicationmanager/frame-timer/apps/frame-timer.fish/fish.qml
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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:BSD-QTAS$
** Commercial License Usage
diff --git a/examples/applicationmanager/frame-timer/apps/frame-timer.rabbit/rabbit.qml b/examples/applicationmanager/frame-timer/apps/frame-timer.rabbit/rabbit.qml
index 4b5892b0..42a2cfab 100644
--- a/examples/applicationmanager/frame-timer/apps/frame-timer.rabbit/rabbit.qml
+++ b/examples/applicationmanager/frame-timer/apps/frame-timer.rabbit/rabbit.qml
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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:BSD-QTAS$
** Commercial License Usage
diff --git a/examples/applicationmanager/frame-timer/doc/src/frame-timer-example.qdoc b/examples/applicationmanager/frame-timer/doc/src/frame-timer-example.qdoc
index 2397f508..e0939058 100644
--- a/examples/applicationmanager/frame-timer/doc/src/frame-timer-example.qdoc
+++ b/examples/applicationmanager/frame-timer/doc/src/frame-timer-example.qdoc
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** Contact: https://www.qt.io/licensing/
**
-** This file is part of the documentation of the Luxoft Application Manager.
+** This file is part of the documentation of the Qt Application Manager.
**
** $QT_BEGIN_LICENSE:FDL-QTAS$
** Commercial License Usage
diff --git a/examples/applicationmanager/frame-timer/system-ui/main.qml b/examples/applicationmanager/frame-timer/system-ui/main.qml
index 1055843d..b95cec1d 100644
--- a/examples/applicationmanager/frame-timer/system-ui/main.qml
+++ b/examples/applicationmanager/frame-timer/system-ui/main.qml
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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:BSD-QTAS$
** Commercial License Usage
diff --git a/examples/applicationmanager/hello-world/apps/hello-world.blue/main.qml b/examples/applicationmanager/hello-world/apps/hello-world.blue/main.qml
index 8dd0a2a4..a2ba7929 100644
--- a/examples/applicationmanager/hello-world/apps/hello-world.blue/main.qml
+++ b/examples/applicationmanager/hello-world/apps/hello-world.blue/main.qml
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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:BSD-QTAS$
** Commercial License Usage
diff --git a/examples/applicationmanager/hello-world/apps/hello-world.green/main.qml b/examples/applicationmanager/hello-world/apps/hello-world.green/main.qml
index e2bbfd41..6fda63f7 100644
--- a/examples/applicationmanager/hello-world/apps/hello-world.green/main.qml
+++ b/examples/applicationmanager/hello-world/apps/hello-world.green/main.qml
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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:BSD-QTAS$
** Commercial License Usage
diff --git a/examples/applicationmanager/hello-world/apps/hello-world.red/main.qml b/examples/applicationmanager/hello-world/apps/hello-world.red/main.qml
index 944ee7db..fd04b159 100644
--- a/examples/applicationmanager/hello-world/apps/hello-world.red/main.qml
+++ b/examples/applicationmanager/hello-world/apps/hello-world.red/main.qml
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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:BSD-QTAS$
** Commercial License Usage
diff --git a/examples/applicationmanager/hello-world/doc/src/hello-world.qdoc b/examples/applicationmanager/hello-world/doc/src/hello-world.qdoc
index e3978de5..71d94a65 100644
--- a/examples/applicationmanager/hello-world/doc/src/hello-world.qdoc
+++ b/examples/applicationmanager/hello-world/doc/src/hello-world.qdoc
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** Contact: https://www.qt.io/licensing/
**
-** This file is part of the documentation of the Luxoft Application Manager.
+** This file is part of the documentation of the Qt Application Manager.
**
** $QT_BEGIN_LICENSE:FDL-QTAS$
** Commercial License Usage
diff --git a/examples/applicationmanager/hello-world/system-ui.qml b/examples/applicationmanager/hello-world/system-ui.qml
index 2d5aaa11..95f3edb8 100644
--- a/examples/applicationmanager/hello-world/system-ui.qml
+++ b/examples/applicationmanager/hello-world/system-ui.qml
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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:BSD-QTAS$
** Commercial License Usage
diff --git a/examples/applicationmanager/intents/apps/intents.blue/main.qml b/examples/applicationmanager/intents/apps/intents.blue/main.qml
index fe549f88..89321457 100644
--- a/examples/applicationmanager/intents/apps/intents.blue/main.qml
+++ b/examples/applicationmanager/intents/apps/intents.blue/main.qml
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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:BSD-QTAS$
** Commercial License Usage
diff --git a/examples/applicationmanager/intents/apps/intents.green/main.qml b/examples/applicationmanager/intents/apps/intents.green/main.qml
index fe549f88..89321457 100644
--- a/examples/applicationmanager/intents/apps/intents.green/main.qml
+++ b/examples/applicationmanager/intents/apps/intents.green/main.qml
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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:BSD-QTAS$
** Commercial License Usage
diff --git a/examples/applicationmanager/intents/apps/intents.red/main.qml b/examples/applicationmanager/intents/apps/intents.red/main.qml
index 3d6b070d..f9c3998a 100644
--- a/examples/applicationmanager/intents/apps/intents.red/main.qml
+++ b/examples/applicationmanager/intents/apps/intents.red/main.qml
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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:BSD-QTAS$
** Commercial License Usage
diff --git a/examples/applicationmanager/intents/doc/src/intents.qdoc b/examples/applicationmanager/intents/doc/src/intents.qdoc
index 07c062b3..f1da854a 100644
--- a/examples/applicationmanager/intents/doc/src/intents.qdoc
+++ b/examples/applicationmanager/intents/doc/src/intents.qdoc
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** Contact: https://www.qt.io/licensing/
**
-** This file is part of the documentation of the Luxoft Application Manager.
+** This file is part of the documentation of the Qt Application Manager.
**
** $QT_BEGIN_LICENSE:FDL-QTAS$
** Commercial License Usage
diff --git a/examples/applicationmanager/intents/shared/IntentsApplicationWindow.qml b/examples/applicationmanager/intents/shared/IntentsApplicationWindow.qml
index 4f56b576..ee58b1c2 100644
--- a/examples/applicationmanager/intents/shared/IntentsApplicationWindow.qml
+++ b/examples/applicationmanager/intents/shared/IntentsApplicationWindow.qml
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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:BSD-QTAS$
** Commercial License Usage
diff --git a/examples/applicationmanager/intents/shared/IntentsUIPage.qml b/examples/applicationmanager/intents/shared/IntentsUIPage.qml
index ccf5534f..0420a089 100644
--- a/examples/applicationmanager/intents/shared/IntentsUIPage.qml
+++ b/examples/applicationmanager/intents/shared/IntentsUIPage.qml
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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:BSD-QTAS$
** Commercial License Usage
diff --git a/examples/applicationmanager/intents/system-ui.qml b/examples/applicationmanager/intents/system-ui.qml
index 07efbcf2..328eb63b 100644
--- a/examples/applicationmanager/intents/system-ui.qml
+++ b/examples/applicationmanager/intents/system-ui.qml
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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:BSD-QTAS$
** Commercial License Usage
diff --git a/examples/applicationmanager/minidesk/apps/tld.minidesk.app1/app1.qml b/examples/applicationmanager/minidesk/apps/tld.minidesk.app1/app1.qml
index ae005f47..62aa661a 100644
--- a/examples/applicationmanager/minidesk/apps/tld.minidesk.app1/app1.qml
+++ b/examples/applicationmanager/minidesk/apps/tld.minidesk.app1/app1.qml
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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:BSD-QTAS$
** Commercial License Usage
@@ -56,12 +56,12 @@ import QtApplicationManager.Application 2.0
ApplicationManagerWindow {
id: root
- color: "peachpuff"
+ color: "lightgrey"
Rectangle {
anchors.centerIn: parent
width: 180; height: 180; radius: width/4
- color: "peru"
+ color: "lightsteelblue"
Image {
source: ApplicationInterface.icon
@@ -90,7 +90,7 @@ ApplicationManagerWindow {
ApplicationManagerWindow {
id: popUp
visible: false
- color: "lightcoral"
+ color: "orangered"
Text {
anchors.centerIn: parent
diff --git a/examples/applicationmanager/minidesk/apps/tld.minidesk.app1/icon.png b/examples/applicationmanager/minidesk/apps/tld.minidesk.app1/icon.png
index adb840ce..35a54600 100644
--- a/examples/applicationmanager/minidesk/apps/tld.minidesk.app1/icon.png
+++ b/examples/applicationmanager/minidesk/apps/tld.minidesk.app1/icon.png
Binary files differ
diff --git a/examples/applicationmanager/minidesk/apps/tld.minidesk.app1/info.yaml b/examples/applicationmanager/minidesk/apps/tld.minidesk.app1/info.yaml
index 953e852f..6b2efc9b 100644
--- a/examples/applicationmanager/minidesk/apps/tld.minidesk.app1/info.yaml
+++ b/examples/applicationmanager/minidesk/apps/tld.minidesk.app1/info.yaml
@@ -1,9 +1,11 @@
formatVersion: 1
-formatType: am-application
+formatType: am-package
---
-id: 'tld.minidesk.app1'
-icon: 'icon.png'
-code: 'app1.qml'
-runtime: 'qml'
+id: 'tld.minidesk.app1'
+icon: 'icon.png'
name:
en: 'App1'
+applications:
+ - id: 'tld.minidesk.app1'
+ code: 'app1.qml'
+ runtime: 'qml'
diff --git a/examples/applicationmanager/minidesk/apps/tld.minidesk.app2/app2.qml b/examples/applicationmanager/minidesk/apps/tld.minidesk.app2/app2.qml
index ae4db3a3..c4bef427 100644
--- a/examples/applicationmanager/minidesk/apps/tld.minidesk.app2/app2.qml
+++ b/examples/applicationmanager/minidesk/apps/tld.minidesk.app2/app2.qml
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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:BSD-QTAS$
** Commercial License Usage
@@ -55,7 +55,7 @@ import QtQuick 2.4
import QtApplicationManager.Application 2.0
ApplicationManagerWindow {
- color: ApplicationInterface.systemProperties.light ? "peachpuff" : "black"
+ color: ApplicationInterface.systemProperties.light ? "#B0808080" : "black"
Image {
anchors.centerIn: parent
diff --git a/examples/applicationmanager/minidesk/apps/tld.minidesk.app2/icon.png b/examples/applicationmanager/minidesk/apps/tld.minidesk.app2/icon.png
index 3f8caa42..9c1d6cf2 100644
--- a/examples/applicationmanager/minidesk/apps/tld.minidesk.app2/icon.png
+++ b/examples/applicationmanager/minidesk/apps/tld.minidesk.app2/icon.png
Binary files differ
diff --git a/examples/applicationmanager/minidesk/apps/tld.minidesk.app2/info.yaml b/examples/applicationmanager/minidesk/apps/tld.minidesk.app2/info.yaml
index 65759aa8..140955eb 100644
--- a/examples/applicationmanager/minidesk/apps/tld.minidesk.app2/info.yaml
+++ b/examples/applicationmanager/minidesk/apps/tld.minidesk.app2/info.yaml
@@ -1,9 +1,11 @@
formatVersion: 1
-formatType: am-application
+formatType: am-package
---
-id: 'tld.minidesk.app2'
-icon: 'icon.png'
-code: 'app2.qml'
-runtime: 'qml'
+id: 'tld.minidesk.app2'
+icon: 'icon.png'
name:
en: 'App2'
+applications:
+ - id: 'tld.minidesk.app2'
+ code: 'app2.qml'
+ runtime: 'qml'
diff --git a/examples/applicationmanager/minidesk/doc/images/minidesk.png b/examples/applicationmanager/minidesk/doc/images/minidesk.png
index 66a545c9..edbe0783 100644
--- a/examples/applicationmanager/minidesk/doc/images/minidesk.png
+++ b/examples/applicationmanager/minidesk/doc/images/minidesk.png
Binary files differ
diff --git a/examples/applicationmanager/minidesk/doc/src/minidesk.qdoc b/examples/applicationmanager/minidesk/doc/src/minidesk.qdoc
index e44e5854..867448e8 100644
--- a/examples/applicationmanager/minidesk/doc/src/minidesk.qdoc
+++ b/examples/applicationmanager/minidesk/doc/src/minidesk.qdoc
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** Contact: https://www.qt.io/licensing/
**
-** This file is part of the documentation of the Luxoft Application Manager.
+** This file is part of the documentation of the Qt Application Manager.
**
** $QT_BEGIN_LICENSE:FDL-QTAS$
** Commercial License Usage
@@ -81,11 +81,11 @@ The \c appman binary (executable file) is usually located in the Qt installation
\dots
The \l{QtApplicationManager.SystemUI} module has to be imported to access the application manager
-APIs. The System UI window has a fixed size and linen background color. Instead of a \l{Rectangle},
-the root element could also be a \l{Window}. On top of the background, we display a
-\c Readme element with information on the
-features available. At the bottom left there is a textual indication for whether the
-application manager runs in single-process or multi-process mode.
+APIs. The System UI window has a fixed size and "whitesmoke" background color. Instead of a
+\l{Window}, the root element could also be a regular item, like a \l{Rectangle}. The application
+manager would wrap it in a window for you. On top of the background, we display a \c Readme element
+with information on the features available. At the bottom left there is a textual indication for
+whether the application manager runs in single-process or multi-process mode.
\section2 Launcher
@@ -114,8 +114,8 @@ WindowManager. The code that populates the window role of this ListModel is show
now let's focus on what this Repeater's delegate consists of:
\list
- \li A fixed size window container \l{Rectangle} in "tan" color. The location depends on the
- \c model.index, hence each application window has a different initial location.
+ \li A mostly transparent background \l{Image}. The location depends on the \c model.index,
+ hence each application window has a different initial location.
\li The name of the application that created that window, prefixed with "Decoration" on top.
This name is from the related ApplicationObject, defined in the application's
\l{Manifest Definition}{info.yaml} file.
@@ -205,7 +205,7 @@ the \l {WindowManager::windowAdded}{onWindowAdded} handler is invoked.
Only App1's "pop-up" ApplicationManagerWindow has the user-defined \c type property set. Such a
window is placed in the \c popUpContainer WindowItem. All other windows don't have a \c type
-property; they are added to the \c topLevelWindowsModel. This model is used in the SystemUI chrome
+property; they are added to the \c topLevelWindowsModel. This model is used in the System UI chrome
Repeater above. Consequently, the \l {WindowObject}{window} object passed as an argument to
\l {WindowManager::windowAdded}{onWindowAdded} is set as the
\l{WindowItem::window}{window} property of the WindowItem (within the Repeater's delegate).
@@ -215,7 +215,7 @@ will also be displayed since in the configuration file, "\c flags/noSecurity: \c
instance in KDE's Calculator:
\badcode
-$ QT_WAYLAND_DISABLE_WINDOWDECORATION=1 QT_WAYLAND_SHELL_INTEGRATION=xdg-shell-v5 kcalc -platform wayland
+$ QT_WAYLAND_DISABLE_WINDOWDECORATION=1 WAYLAND_DISPLAY=qtam-wayland-0 kcalc -platform wayland
\endcode
\section2 Inter-Process Communication (IPC) Extension
diff --git a/examples/applicationmanager/minidesk/system-ui/Readme.qml b/examples/applicationmanager/minidesk/system-ui/Readme.qml
index 6565df71..65643913 100644
--- a/examples/applicationmanager/minidesk/system-ui/Readme.qml
+++ b/examples/applicationmanager/minidesk/system-ui/Readme.qml
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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:BSD-QTAS$
** Commercial License Usage
diff --git a/examples/applicationmanager/minidesk/system-ui/chrome-bg.png b/examples/applicationmanager/minidesk/system-ui/chrome-bg.png
new file mode 100644
index 00000000..0a6618c4
--- /dev/null
+++ b/examples/applicationmanager/minidesk/system-ui/chrome-bg.png
Binary files differ
diff --git a/examples/applicationmanager/minidesk/system-ui/main.qml b/examples/applicationmanager/minidesk/system-ui/main.qml
index 43265237..577599a2 100644
--- a/examples/applicationmanager/minidesk/system-ui/main.qml
+++ b/examples/applicationmanager/minidesk/system-ui/main.qml
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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:BSD-QTAS$
** Commercial License Usage
@@ -51,13 +51,15 @@
**
****************************************************************************/
-import QtQuick 2.4
+import QtQuick 2.11
+import QtQuick.Window 2.11
import QtApplicationManager.SystemUI 2.0
-Rectangle {
+Window {
+ title: "Minidesk - QtApplicationManager Example"
width: 1024
height: 640
- color: "linen"
+ color: "whitesmoke"
Readme {}
@@ -87,10 +89,9 @@ Rectangle {
Repeater {
model: ListModel { id: topLevelWindowsModel }
- delegate: Rectangle {
- width: 400; height: 320
+ delegate: Image {
+ source: "chrome-bg.png"
z: model.index
- color: "tan"
Text {
anchors.horizontalCenter: parent.horizontalCenter
diff --git a/examples/applicationmanager/multi-views/apps/tld.multi-views.app/app1.qml b/examples/applicationmanager/multi-views/apps/tld.multi-views.app/app1.qml
index e5e3f6e8..dd8c7bbd 100644
--- a/examples/applicationmanager/multi-views/apps/tld.multi-views.app/app1.qml
+++ b/examples/applicationmanager/multi-views/apps/tld.multi-views.app/app1.qml
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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:BSD-QTAS$
** Commercial License Usage
diff --git a/examples/applicationmanager/multi-views/doc/src/multi-views.qdoc b/examples/applicationmanager/multi-views/doc/src/multi-views.qdoc
index 959b3dd7..7e5c6d9e 100644
--- a/examples/applicationmanager/multi-views/doc/src/multi-views.qdoc
+++ b/examples/applicationmanager/multi-views/doc/src/multi-views.qdoc
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** Contact: https://www.qt.io/licensing/
**
-** This file is part of the documentation of the Luxoft Application Manager.
+** This file is part of the documentation of the Qt Application Manager.
**
** $QT_BEGIN_LICENSE:FDL-QTAS$
** Commercial License Usage
diff --git a/examples/applicationmanager/multi-views/multi-views.pro b/examples/applicationmanager/multi-views/multi-views.pro
index 2cff5f66..e7e041b9 100644
--- a/examples/applicationmanager/multi-views/multi-views.pro
+++ b/examples/applicationmanager/multi-views/multi-views.pro
@@ -4,6 +4,8 @@ CONFIG += am-systemui
OTHER_FILES += \
am-config.yaml \
system-ui/*.qml \
+ doc/src/*.qdoc \
+ doc/images/*.png \
apps/tld.multi-views.app/*.yaml \
apps/tld.multi-views.app/*.qml \
apps/tld.multi-views.app/*.png \
diff --git a/examples/applicationmanager/multi-views/system-ui/Readme.qml b/examples/applicationmanager/multi-views/system-ui/Readme.qml
index 23a7fb0b..ab201033 100644
--- a/examples/applicationmanager/multi-views/system-ui/Readme.qml
+++ b/examples/applicationmanager/multi-views/system-ui/Readme.qml
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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:BSD-QTAS$
** Commercial License Usage
diff --git a/examples/applicationmanager/multi-views/system-ui/main.qml b/examples/applicationmanager/multi-views/system-ui/main.qml
index 55f48188..b3ee5309 100644
--- a/examples/applicationmanager/multi-views/system-ui/main.qml
+++ b/examples/applicationmanager/multi-views/system-ui/main.qml
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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:BSD-QTAS$
** Commercial License Usage
diff --git a/examples/applicationmanager/process-status/apps/process-status.cpu-hog/main.qml b/examples/applicationmanager/process-status/apps/process-status.cpu-hog/main.qml
index baed4f24..4aa746bd 100644
--- a/examples/applicationmanager/process-status/apps/process-status.cpu-hog/main.qml
+++ b/examples/applicationmanager/process-status/apps/process-status.cpu-hog/main.qml
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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:BSD-QTAS$
** Commercial License Usage
diff --git a/examples/applicationmanager/process-status/apps/process-status.mem-hog/main.qml b/examples/applicationmanager/process-status/apps/process-status.mem-hog/main.qml
index 9a77bcd4..b899ea96 100644
--- a/examples/applicationmanager/process-status/apps/process-status.mem-hog/main.qml
+++ b/examples/applicationmanager/process-status/apps/process-status.mem-hog/main.qml
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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:BSD-QTAS$
** Commercial License Usage
diff --git a/examples/applicationmanager/process-status/apps/process-status.slim/main.qml b/examples/applicationmanager/process-status/apps/process-status.slim/main.qml
index 82de9abe..89a51cd8 100644
--- a/examples/applicationmanager/process-status/apps/process-status.slim/main.qml
+++ b/examples/applicationmanager/process-status/apps/process-status.slim/main.qml
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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:BSD-QTAS$
** Commercial License Usage
diff --git a/examples/applicationmanager/process-status/doc/src/process-status-example.qdoc b/examples/applicationmanager/process-status/doc/src/process-status-example.qdoc
index 5d012ac2..1bafdbf5 100644
--- a/examples/applicationmanager/process-status/doc/src/process-status-example.qdoc
+++ b/examples/applicationmanager/process-status/doc/src/process-status-example.qdoc
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** Contact: https://www.qt.io/licensing/
**
-** This file is part of the documentation of the Luxoft Application Manager.
+** This file is part of the documentation of the Qt Application Manager.
**
** $QT_BEGIN_LICENSE:FDL-QTAS$
** Commercial License Usage
diff --git a/examples/applicationmanager/process-status/system-ui/ApplicationDisplay.qml b/examples/applicationmanager/process-status/system-ui/ApplicationDisplay.qml
index 89fccd9e..3dabe63b 100644
--- a/examples/applicationmanager/process-status/system-ui/ApplicationDisplay.qml
+++ b/examples/applicationmanager/process-status/system-ui/ApplicationDisplay.qml
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/examples/applicationmanager/process-status/system-ui/CpuGraph.qml b/examples/applicationmanager/process-status/system-ui/CpuGraph.qml
index 4ba1edd8..8cd59c72 100644
--- a/examples/applicationmanager/process-status/system-ui/CpuGraph.qml
+++ b/examples/applicationmanager/process-status/system-ui/CpuGraph.qml
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/examples/applicationmanager/process-status/system-ui/MemoryText.qml b/examples/applicationmanager/process-status/system-ui/MemoryText.qml
index 6b999da1..14eaf0b1 100644
--- a/examples/applicationmanager/process-status/system-ui/MemoryText.qml
+++ b/examples/applicationmanager/process-status/system-ui/MemoryText.qml
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/examples/applicationmanager/process-status/system-ui/Stats.qml b/examples/applicationmanager/process-status/system-ui/Stats.qml
index 90983804..a62b6888 100644
--- a/examples/applicationmanager/process-status/system-ui/Stats.qml
+++ b/examples/applicationmanager/process-status/system-ui/Stats.qml
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/examples/applicationmanager/process-status/system-ui/main.qml b/examples/applicationmanager/process-status/system-ui/main.qml
index b342939e..57bfb463 100644
--- a/examples/applicationmanager/process-status/system-ui/main.qml
+++ b/examples/applicationmanager/process-status/system-ui/main.qml
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/examples/applicationmanager/softwarecontainer-plugin/README.md b/examples/applicationmanager/softwarecontainer-plugin/README.md
index 57d7eb3b..d599c854 100644
--- a/examples/applicationmanager/softwarecontainer-plugin/README.md
+++ b/examples/applicationmanager/softwarecontainer-plugin/README.md
@@ -35,7 +35,8 @@ that the application-manager is using, if you intend on forwarding this
bus. This is a bit tricky if the agent is run as root and the application-
manager as non-root user, since the default session-bus policy in most
distros disallows root to access user session-busses: the workaround is to
-add a `<allow user="root"/>` policy in `/etc/dbus-1/session.conf`.
+add a `<allow user="root"/>` policy within the `<policy context="default">`
+element in `/etc/dbus-1/session.conf`.
Please do also not forget to tell the agent about your environment, when
running it via sudo:
diff --git a/examples/applicationmanager/softwarecontainer-plugin/softwarecontainer.cpp b/examples/applicationmanager/softwarecontainer-plugin/softwarecontainer.cpp
index dd27b4a3..2598f6aa 100644
--- a/examples/applicationmanager/softwarecontainer-plugin/softwarecontainer.cpp
+++ b/examples/applicationmanager/softwarecontainer-plugin/softwarecontainer.cpp
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/examples/applicationmanager/softwarecontainer-plugin/softwarecontainer.h b/examples/applicationmanager/softwarecontainer-plugin/softwarecontainer.h
index e951c55d..63ba2614 100644
--- a/examples/applicationmanager/softwarecontainer-plugin/softwarecontainer.h
+++ b/examples/applicationmanager/softwarecontainer-plugin/softwarecontainer.h
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/examples/applicationmanager/startup-plugin/startup-plugin.cpp b/examples/applicationmanager/startup-plugin/startup-plugin.cpp
index 0a1a9a25..3ec57bf6 100644
--- a/examples/applicationmanager/startup-plugin/startup-plugin.cpp
+++ b/examples/applicationmanager/startup-plugin/startup-plugin.cpp
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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:BSD-QTAS$
** Commercial License Usage
diff --git a/examples/applicationmanager/startup-plugin/startup-plugin.h b/examples/applicationmanager/startup-plugin/startup-plugin.h
index fa62b702..f7540e96 100644
--- a/examples/applicationmanager/startup-plugin/startup-plugin.h
+++ b/examples/applicationmanager/startup-plugin/startup-plugin.h
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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:BSD-QTAS$
** Commercial License Usage
diff --git a/header.BSD-QTAS b/header.BSD-QTAS
index b436e34f..00ec0076 100644
--- a/header.BSD-QTAS
+++ b/header.BSD-QTAS
@@ -1,10 +1,9 @@
/****************************************************************************
**
** Copyright (C) 2019 Luxoft Sweden AB
-** Copyright (C) 2018 Pelagicore AG
** Contact: https://www.qt.io/licensing/
**
-** This file is part of the Luxoft Application Manager.
+** This file is part of the Qt Application Manager.
**
** $QT_BEGIN_LICENSE:BSD-QTAS$
** Commercial License Usage
diff --git a/header.FDL-QTAS b/header.FDL-QTAS
index b3064965..40ff9176 100644
--- a/header.FDL-QTAS
+++ b/header.FDL-QTAS
@@ -1,10 +1,9 @@
/****************************************************************************
**
** Copyright (C) 2019 Luxoft Sweden AB
-** Copyright (C) 2018 Pelagicore AG
** Contact: https://www.qt.io/licensing/
**
-** This file is part of the documentation of the Luxoft Application Manager.
+** This file is part of the documentation of the Qt Application Manager.
**
** $QT_BEGIN_LICENSE:FDL-QTAS$
** Commercial License Usage
diff --git a/header.GPL-EXCEPT-QTAS b/header.GPL-EXCEPT-QTAS
index 3ead040d..905efde0 100644
--- a/header.GPL-EXCEPT-QTAS
+++ b/header.GPL-EXCEPT-QTAS
@@ -1,10 +1,9 @@
/****************************************************************************
**
** Copyright (C) 2019 Luxoft Sweden AB
-** Copyright (C) 2018 Pelagicore AG
** Contact: https://www.qt.io/licensing/
**
-** This file is part of the Luxoft Application Manager.
+** This file is part of the Qt Application Manager.
**
** $QT_BEGIN_LICENSE:GPL-EXCEPT-QTAS$
** Commercial License Usage
diff --git a/header.LGPL-QTAS b/header.LGPL-QTAS
index 98265f2c..31af987d 100644
--- a/header.LGPL-QTAS
+++ b/header.LGPL-QTAS
@@ -1,10 +1,9 @@
/****************************************************************************
**
** Copyright (C) 2019 Luxoft Sweden AB
-** Copyright (C) 2018 Pelagicore AG
** Contact: https://www.qt.io/licensing/
**
-** This file is part of the Luxoft Application Manager.
+** This file is part of the Qt Application Manager.
**
** $QT_BEGIN_LICENSE:LGPL-QTAS$
** Commercial License Usage
diff --git a/qmake-features/am-qml-testcase.prf b/qmake-features/am-qml-testcase.prf
index c7f2396a..b475deed 100644
--- a/qmake-features/am-qml-testcase.prf
+++ b/qmake-features/am-qml-testcase.prf
@@ -93,3 +93,6 @@ for (f , FILES) {
check.depends = do_copydata
QMAKE_EXTRA_TARGETS += do_copydata
}
+
+# Make sure that possible apps are in OTHER_FILES
+for (app, TEST_APPS): OTHER_FILES += apps/$${app}/*.yaml apps/$${app}/*.qml apps/$${app}/*.png
diff --git a/src/application-lib/application-lib.pro b/src/application-lib/application-lib.pro
index 1f75472d..7363acc1 100644
--- a/src/application-lib/application-lib.pro
+++ b/src/application-lib/application-lib.pro
@@ -13,15 +13,21 @@ CONFIG -= create_cmake
HEADERS += \
applicationinfo.h \
- applicationscanner.h \
- yamlapplicationscanner.h \
+ packagescanner.h \
+ yamlpackagescanner.h \
installationreport.h \
applicationinterface.h \
+ intentinfo.h \
+ packageinfo.h \
+ packagedatabase.h \
SOURCES += \
applicationinfo.cpp \
- yamlapplicationscanner.cpp \
+ yamlpackagescanner.cpp \
installationreport.cpp \
applicationinterface.cpp \
+ intentinfo.cpp \
+ packageinfo.cpp \
+ packagedatabase.cpp \
load(qt_module)
diff --git a/src/application-lib/applicationinfo.cpp b/src/application-lib/applicationinfo.cpp
index f746f849..ca9130be 100644
--- a/src/application-lib/applicationinfo.cpp
+++ b/src/application-lib/applicationinfo.cpp
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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
@@ -40,82 +40,16 @@
**
****************************************************************************/
-#include <QDebug>
+#include <QDataStream>
#include <QBuffer>
#include "applicationinfo.h"
#include "exception.h"
#include "installationreport.h"
+#include "packageinfo.h"
QT_BEGIN_NAMESPACE_AM
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// AbstractApplicationInfo
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-bool AbstractApplicationInfo::isValidApplicationId(const QString &appId, bool isAliasName, QString *errorString)
-{
- static const int maxLength = 150;
-
- try {
- if (appId.isEmpty())
- throw Exception(Error::Parse, "must not be empty");
-
- // we need to make sure that we can use the name as directory on a FAT formatted SD-card,
- // which has a 255 character path length restriction
- if (appId.length() > maxLength)
- throw Exception(Error::Parse, "the maximum length is %1 characters (found %2 characters)").arg(maxLength, appId.length());
-
- int aliasPos = -1;
-
- // aliases need to have the '@' marker
- if (isAliasName) {
- aliasPos = appId.indexOf(qL1C('@'));
- if (aliasPos < 0 || aliasPos == (appId.size() - 1))
- throw Exception(Error::Parse, "missing alias-id tag '@'");
- }
-
- // all characters need to be ASCII minus '@' and any filesystem special characters:
- bool spaceOnly = true;
- static const char forbiddenChars[] = "@<>:\"/\\|?*";
- for (int pos = 0; pos < appId.length(); ++pos) {
- if (pos == aliasPos)
- continue;
- ushort ch = appId.at(pos).unicode();
- if ((ch < 0x20) || (ch > 0x7f) || strchr(forbiddenChars, ch & 0xff)) {
- throw Exception(Error::Parse, "must consist of printable ASCII characters only, except any of \'%1'")
- .arg(QString::fromLatin1(forbiddenChars));
- }
- if (spaceOnly)
- spaceOnly = QChar(ch).isSpace();
- }
- if (spaceOnly)
- throw Exception(Error::Parse, "must not consist of only white-space characters");
-
- return true;
- } catch (const Exception &e) {
- if (errorString)
- *errorString = e.errorString();
- return false;
- }
-}
-
-bool AbstractApplicationInfo::isValidIcon(const QString &icon, QString &errorString)
-{
- if (icon.isEmpty()) {
- errorString = qSL("it's empty");
- return false;
- }
-
- QFileInfo fileInfo(icon);
-
- if (fileInfo.fileName() != icon) {
- errorString = QString(qSL("'%1' is not a valid file name")).arg(icon);
- return false;
- }
-
- return true;
-}
//TODO Make this really unique
static int uniqueCounter = 0;
@@ -127,163 +61,114 @@ static int nextUniqueNumber() {
return uniqueCounter;
}
-AbstractApplicationInfo::AbstractApplicationInfo()
- : m_uniqueNumber(nextUniqueNumber())
+ApplicationInfo::ApplicationInfo(PackageInfo *packageInfo)
+ : m_packageInfo(packageInfo)
+ , m_uniqueNumber(nextUniqueNumber())
+{ }
+
+PackageInfo *ApplicationInfo::packageInfo() const
{
+ return m_packageInfo;
}
-QString AbstractApplicationInfo::id() const
+QString ApplicationInfo::id() const
{
return m_id;
}
-int AbstractApplicationInfo::uniqueNumber() const
+int ApplicationInfo::uniqueNumber() const
{
return m_uniqueNumber;
}
-QMap<QString, QString> AbstractApplicationInfo::names() const
-{
- return m_name;
-}
-
-QString AbstractApplicationInfo::name(const QString &language) const
-{
- return m_name.value(language);
-}
-
-QString AbstractApplicationInfo::icon() const
-{
- return m_icon;
-}
-
-QString AbstractApplicationInfo::documentUrl() const
-{
- return m_documentUrl;
-}
-
-QVariantMap AbstractApplicationInfo::applicationProperties() const
+QVariantMap ApplicationInfo::applicationProperties() const
{
return m_sysAppProperties;
}
-QVariantMap AbstractApplicationInfo::allAppProperties() const
+QVariantMap ApplicationInfo::allAppProperties() const
{
return m_allAppProperties;
}
-void AbstractApplicationInfo::validate() const Q_DECL_NOEXCEPT_EXPR(false)
-{
- QString errorMsg;
- if (!isValidApplicationId(id(), isAlias(), &errorMsg))
- throw Exception(Error::Parse, "the identifier (%1) is not a valid application-id: %2").arg(id()).arg(errorMsg);
-
- if (!isValidIcon(icon(), errorMsg))
- throw Exception(Error::Parse, "Invalid 'icon' field: %1").arg(errorMsg);
-
- if (names().isEmpty())
- throw Exception(Error::Parse, "the 'name' field must not be empty");
-
- // This check won't work during installations, since the icon file is extracted after info.json
- // if (!QFile::exists(displayIcon()))
- // throw Exception("the 'icon' field refers to a non-existent file");
-
- //TODO: check for valid capabilities
-}
-
-void AbstractApplicationInfo::read(QDataStream &ds)
-{
- ds >> m_id
- >> m_uniqueNumber
- >> m_name
- >> m_icon
- >> m_documentUrl
- >> m_sysAppProperties
- >> m_allAppProperties;
-
- uniqueCounter = qMax(uniqueCounter, m_uniqueNumber);
-}
-
-void AbstractApplicationInfo::writeToDataStream(QDataStream &ds) const
+void ApplicationInfo::writeToDataStream(QDataStream &ds) const
{
- ds << isAlias()
- << m_id
+ ds << m_id
<< m_uniqueNumber
- << m_name
- << m_icon
- << m_documentUrl
<< m_sysAppProperties
- << m_allAppProperties;
+ << m_allAppProperties
+ << m_codeFilePath
+ << m_runtimeName
+ << m_runtimeParameters
+ << m_supportsApplicationInterface
+ << m_capabilities
+ << m_openGLConfiguration;
}
-AbstractApplicationInfo *AbstractApplicationInfo::readFromDataStream(QDataStream &ds)
+ApplicationInfo *ApplicationInfo::readFromDataStream(PackageInfo *pkg, QDataStream &ds)
{
- bool isAlias;
- ds >> isAlias;
+ QScopedPointer<ApplicationInfo> app(new ApplicationInfo(pkg));
- QScopedPointer<AbstractApplicationInfo> app;
+ ds >> app->m_id
+ >> app->m_uniqueNumber
+ >> app->m_sysAppProperties
+ >> app->m_allAppProperties
+ >> app->m_codeFilePath
+ >> app->m_runtimeName
+ >> app->m_runtimeParameters
+ >> app->m_supportsApplicationInterface
+ >> app->m_capabilities
+ >> app->m_openGLConfiguration;
- if (isAlias)
- app.reset(new ApplicationAliasInfo);
- else
- app.reset(new ApplicationInfo);
-
- app->read(ds);
+ uniqueCounter = qMax(uniqueCounter, app->m_uniqueNumber);
+ app->m_capabilities.sort();
return app.take();
}
-void AbstractApplicationInfo::toVariantMapHelper(QVariantMap &map) const
+
+QVariantMap ApplicationInfo::toVariantMap() const
{
+ QVariantMap map;
//TODO: check if we can find a better method to keep this as similar as possible to
// ApplicationManager::get().
- // This is used for RuntimeInterface::startApplication(), ContainerInterface and
- // ApplicationInstaller::taskRequestingInstallationAcknowledge.
+ // This is used for RuntimeInterface::startApplication() and the ContainerInterface
map[qSL("id")] = m_id;
map[qSL("uniqueNumber")] = m_uniqueNumber;
{
QVariantMap displayName;
- auto names = m_name;
+ auto names = packageInfo()->names();
for (auto it = names.constBegin(); it != names.constEnd(); ++it)
displayName.insert(it.key(), it.value());
map[qSL("displayName")] = displayName;
}
- map[qSL("displayIcon")] = m_icon;
+ map[qSL("displayIcon")] = packageInfo()->icon();
map[qSL("applicationProperties")] = m_allAppProperties;
-}
+ map[qSL("codeFilePath")] = m_codeFilePath;
+ map[qSL("runtimeName")] = m_runtimeName;
+ map[qSL("runtimeParameters")] = m_runtimeParameters;
+ map[qSL("capabilities")] = m_capabilities;
+ map[qSL("mimeTypes")] = m_supportedMimeTypes;
+
+ map[qSL("categories")] = packageInfo()->categories();
+ map[qSL("version")] = packageInfo()->version();
+ map[qSL("baseDir")] = packageInfo()->baseDir().absolutePath();
+ map[qSL("codeDir")] = map[qSL("baseDir")]; // 5.12 backward compatibility
+ map[qSL("manifestDir")] = map[qSL("baseDir")]; // 5.12 backward compatibility
+ map[qSL("installationLocationId")] = packageInfo()->installationReport() ? qSL("internal-0") : QString();
+ map[qSL("supportsApplicationInterface")] = m_supportsApplicationInterface;
+ map[qSL("dlt")] = packageInfo()->dltConfiguration();
-QVariantMap AbstractApplicationInfo::toVariantMap() const
-{
- QVariantMap map;
- toVariantMapHelper(map);
return map;
}
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// ApplicationInfo
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-ApplicationInfo::ApplicationInfo()
-{ }
-
-void ApplicationInfo::validate() const Q_DECL_NOEXCEPT_EXPR(false)
-{
- AbstractApplicationInfo::validate();
-
- if (absoluteCodeFilePath().isEmpty())
- throw Exception(Error::Parse, "the 'code' field must not be empty");
-
- if (runtimeName().isEmpty())
- throw Exception(Error::Parse, "the 'runtimeName' field must not be empty");
-}
-
QString ApplicationInfo::absoluteCodeFilePath() const
{
QString code = m_codeFilePath;
- return code.isEmpty() ? QString() : QDir(codeDir()).absoluteFilePath(code);
+ return code.isEmpty() ? QString() : QDir(packageInfo()->baseDir()).absoluteFilePath(code);
}
QString ApplicationInfo::codeFilePath() const
@@ -301,11 +186,6 @@ QVariantMap ApplicationInfo::runtimeParameters() const
return m_runtimeParameters;
}
-bool ApplicationInfo::isBuiltIn() const
-{
- return m_builtIn;
-}
-
QStringList ApplicationInfo::capabilities() const
{
return m_capabilities;
@@ -313,17 +193,7 @@ QStringList ApplicationInfo::capabilities() const
QStringList ApplicationInfo::supportedMimeTypes() const
{
- return m_mimeTypes;
-}
-
-QStringList ApplicationInfo::categories() const
-{
- return m_categories;
-}
-
-QString ApplicationInfo::version() const
-{
- return m_version;
+ return m_supportedMimeTypes;
}
QVariantMap ApplicationInfo::openGLConfiguration() const
@@ -331,114 +201,9 @@ QVariantMap ApplicationInfo::openGLConfiguration() const
return m_openGLConfiguration;
}
-QVariantList ApplicationInfo::intents() const
-{
- return m_intents;
-}
-
-void ApplicationInfo::setBuiltIn(bool builtIn)
-{
- m_builtIn = builtIn;
-}
-
-void ApplicationInfo::setSupportsApplicationInterface(bool supportsAppInterface)
-{
- m_supportsApplicationInterface = supportsAppInterface;
-}
-
-void ApplicationInfo::writeToDataStream(QDataStream &ds) const
-{
- AbstractApplicationInfo::writeToDataStream(ds);
-
- QByteArray serializedReport;
-
- if (auto report = installationReport()) {
- QBuffer buffer(&serializedReport);
- buffer.open(QBuffer::WriteOnly);
- report->serialize(&buffer);
- }
-
- ds << m_codeFilePath
- << m_runtimeName
- << m_runtimeParameters
- << m_supportsApplicationInterface
- << m_builtIn
- << m_capabilities
- << m_categories
- << m_mimeTypes
- << m_version
- << m_openGLConfiguration
- << serializedReport
- << m_manifestDir.absolutePath()
- << m_codeDir.absolutePath()
- << m_uid
- << m_dlt
- << m_intents;
-}
-
bool ApplicationInfo::supportsApplicationInterface() const
{
return m_supportsApplicationInterface;
}
-void ApplicationInfo::read(QDataStream &ds)
-{
- AbstractApplicationInfo::read(ds);
-
- QString codeDir;
- QString manifestDir;
- QByteArray installationReport;
-
- ds >> m_codeFilePath
- >> m_runtimeName
- >> m_runtimeParameters
- >> m_supportsApplicationInterface
- >> m_builtIn
- >> m_capabilities
- >> m_categories
- >> m_mimeTypes
- >> m_version
- >> m_openGLConfiguration
- >> installationReport
- >> manifestDir
- >> codeDir
- >> m_uid
- >> m_dlt
- >> m_intents;
-
- m_capabilities.sort();
- m_categories.sort();
- m_mimeTypes.sort();
-
- m_codeDir.setPath(codeDir);
- m_manifestDir.setPath(manifestDir);
- if (!installationReport.isEmpty()) {
- QBuffer buffer(&installationReport);
- buffer.open(QBuffer::ReadOnly);
- m_installationReport.reset(new InstallationReport(m_id));
- if (!m_installationReport->deserialize(&buffer))
- m_installationReport.reset();
- }
-}
-
-void ApplicationInfo::toVariantMapHelper(QVariantMap &map) const
-{
- AbstractApplicationInfo::toVariantMapHelper(map);
-
- map[qSL("codeFilePath")] = m_codeFilePath;
- map[qSL("runtimeName")] = m_runtimeName;
- map[qSL("runtimeParameters")] = m_runtimeParameters;
- map[qSL("capabilities")] = m_capabilities;
- map[qSL("mimeTypes")] = m_mimeTypes;
- map[qSL("categories")] = m_categories;
- map[qSL("version")] = m_version;
- map[qSL("codeDir")] = m_codeDir.absolutePath();
- map[qSL("manifestDir")] = m_manifestDir.absolutePath();
- map[qSL("installationLocationId")] = installationReport() ? installationReport()->installationLocationId()
- : QString();
- map[qSL("supportsApplicationInterface")] = m_supportsApplicationInterface;
- map[qSL("dlt")] = m_dlt;
- map[qSL("intents")] = m_intents;
-}
-
QT_END_NAMESPACE_AM
diff --git a/src/application-lib/applicationinfo.h b/src/application-lib/applicationinfo.h
index aefce00c..6dd9afa5 100644
--- a/src/application-lib/applicationinfo.h
+++ b/src/application-lib/applicationinfo.h
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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
@@ -42,137 +42,70 @@
#pragma once
-#include <QDataStream>
#include <QDir>
#include <QMap>
#include <QString>
#include <QStringList>
#include <QVariantMap>
+#include <QVector>
#include <QtAppManCommon/global.h>
-#include <QtAppManApplication/installationreport.h>
+
+QT_FORWARD_DECLARE_CLASS(QDataStream)
QT_BEGIN_NAMESPACE_AM
-class ApplicationManager;
-class InstallationReport;
+class PackageInfo;
-class AbstractApplicationInfo
+class ApplicationInfo
{
public:
- AbstractApplicationInfo();
- virtual ~AbstractApplicationInfo() {}
+ ApplicationInfo(PackageInfo *packageInfo);
+
+ PackageInfo *packageInfo() const;
+ QVariantMap toVariantMap() const;
QString id() const;
int uniqueNumber() const;
- QMap<QString, QString> names() const;
- QString name(const QString &language) const;
- QString icon() const;
- QString documentUrl() const;
QVariantMap applicationProperties() const;
QVariantMap allAppProperties() const;
-
- QVariantMap toVariantMap() const;
- virtual void toVariantMapHelper(QVariantMap &map) const;
-
- virtual bool isAlias() const = 0;
- virtual void writeToDataStream(QDataStream &ds) const;
- virtual void validate() const Q_DECL_NOEXCEPT_EXPR(false);
-
- static bool isValidApplicationId(const QString &appId, bool isAliasName = false, QString *errorString = nullptr);
- static bool isValidIcon(const QString &icon, QString &errorString);
- static AbstractApplicationInfo *readFromDataStream(QDataStream &ds);
-
-protected:
- virtual void read(QDataStream &ds);
-
- // static part from info.json
- QString m_id;
- int m_uniqueNumber;
-
- QMap<QString, QString> m_name; // language -> name
- QString m_icon; // relative to info.json location
- QString m_documentUrl;
- QVariantMap m_sysAppProperties;
- QVariantMap m_allAppProperties;
-
- friend class YamlApplicationScanner;
-};
-
-class ApplicationAliasInfo : public AbstractApplicationInfo
-{
-public:
- bool isAlias() const override { return true; }
-};
-
-class ApplicationInfo : public AbstractApplicationInfo
-{
-public:
- ApplicationInfo();
-
- bool isAlias() const override { return false; }
- void writeToDataStream(QDataStream &ds) const override;
- void validate() const Q_DECL_NOEXCEPT_EXPR(false) override;
-
- const QDir &codeDir() const { return m_codeDir; }
QString absoluteCodeFilePath() const;
QString codeFilePath() const;
QString runtimeName() const;
QVariantMap runtimeParameters() const;
- QVariantMap environmentVariables() const { return m_environmentVariables; }
- bool isBuiltIn() const;
QStringList capabilities() const;
QStringList supportedMimeTypes() const;
- QStringList categories() const;
- QString version() const;
QVariantMap openGLConfiguration() const;
- QVariantList intents() const;
bool supportsApplicationInterface() const;
- void setSupportsApplicationInterface(bool supportsAppInterface);
- void setBuiltIn(bool builtIn);
+ void writeToDataStream(QDataStream &ds) const;
+ static ApplicationInfo *readFromDataStream(PackageInfo *pkg, QDataStream &ds);
- const InstallationReport *installationReport() const { return m_installationReport.data(); }
- void setInstallationReport(InstallationReport *report) { m_installationReport.reset(report); }
- QString manifestDir() const { return m_manifestDir.absolutePath(); }
- uint uid() const { return m_uid; }
- void setManifestDir(const QString &path) { m_manifestDir.setPath(path); }
- void setCodeDir(const QString &path) { m_codeDir.setPath(path); }
+private:
+ void read(QDataStream &ds);
- void toVariantMapHelper(QVariantMap &map) const override;
+ // static part from info.json
+ PackageInfo *m_packageInfo;
-private:
- void read(QDataStream &ds) override;
+ QString m_id;
+ int m_uniqueNumber;
+
+ QVariantMap m_sysAppProperties;
+ QVariantMap m_allAppProperties;
QString m_codeFilePath; // relative to info.json location
QString m_runtimeName;
QVariantMap m_runtimeParameters;
- QVariantMap m_environmentVariables;
bool m_supportsApplicationInterface = false;
-
- bool m_builtIn = false; // system app - not removable
-
QStringList m_capabilities;
- QStringList m_categories;
- QStringList m_mimeTypes;
-
- QString m_version;
-
QVariantMap m_openGLConfiguration;
- QVariantList m_intents;
- QVariantMap m_dlt;
-
- // added by installer
- QScopedPointer<InstallationReport> m_installationReport;
- QDir m_manifestDir;
- QDir m_codeDir;
- uint m_uid = uint(-1); // unix user id - move to installationReport
+ QStringList m_supportedMimeTypes; // deprecated
- friend class YamlApplicationScanner;
friend class ApplicationManager; // needed to update installation status
- friend class ApplicationDatabase; // needed to create ApplicationInfo objects
+ friend class PackageDatabase; // needed to create ApplicationInfo objects
friend class InstallationTask; // needed to set m_uid and m_builtin during the installation
+ friend class YamlPackageScanner;
Q_DISABLE_COPY(ApplicationInfo)
};
diff --git a/src/application-lib/applicationinterface.cpp b/src/application-lib/applicationinterface.cpp
index ca13eaf3..1ba0ea75 100644
--- a/src/application-lib/applicationinterface.cpp
+++ b/src/application-lib/applicationinterface.cpp
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/src/application-lib/applicationinterface.h b/src/application-lib/applicationinterface.h
index 5150546e..61e05118 100644
--- a/src/application-lib/applicationinterface.h
+++ b/src/application-lib/applicationinterface.h
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/src/application-lib/installationreport.cpp b/src/application-lib/installationreport.cpp
index 0b4e5c67..b52d772c 100644
--- a/src/application-lib/installationreport.cpp
+++ b/src/application-lib/installationreport.cpp
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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
@@ -50,7 +50,7 @@
#include "global.h"
#include "qtyaml.h"
-#include "applicationinfo.h"
+#include "packageinfo.h"
#include "utilities.h"
#include "exception.h"
#include "installationreport.h"
@@ -69,28 +69,18 @@ static const unsigned char privateHmacKeyData[64] = {
};
-InstallationReport::InstallationReport(const QString &applicationId)
- : m_applicationId(applicationId)
+InstallationReport::InstallationReport(const QString &packageId)
+ : m_packageId(packageId)
{ }
-QString InstallationReport::applicationId() const
+QString InstallationReport::packageId() const
{
- return m_applicationId;
+ return m_packageId;
}
-void InstallationReport::setApplicationId(const QString &applicationId)
+void InstallationReport::setPackageId(const QString &packageId)
{
- m_applicationId = applicationId;
-}
-
-QString InstallationReport::installationLocationId() const
-{
- return m_installationLocationId;
-}
-
-void InstallationReport::setInstallationLocationId(const QString &installationLocationId)
-{
- m_installationLocationId = installationLocationId;
+ m_packageId = packageId;
}
QVariantMap InstallationReport::extraMetaData() const
@@ -170,7 +160,7 @@ void InstallationReport::addFiles(const QStringList &files)
bool InstallationReport::isValid() const
{
- return AbstractApplicationInfo::isValidApplicationId(m_applicationId) && !m_digest.isEmpty() && !m_files.isEmpty();
+ return PackageInfo::isValidApplicationId(m_packageId) && !m_digest.isEmpty() && !m_files.isEmpty();
}
bool InstallationReport::deserialize(QIODevice *from)
@@ -188,7 +178,7 @@ bool InstallationReport::deserialize(QIODevice *from)
return false;
try {
- checkYamlFormat(docs, 3 /*number of expected docs*/, { "am-installation-report" }, 1);
+ checkYamlFormat(docs, 3 /*number of expected docs*/, { "am-installation-report" }, 3 /*version*/);
} catch (const Exception &) {
return false;
}
@@ -196,15 +186,14 @@ bool InstallationReport::deserialize(QIODevice *from)
const QVariantMap &root = docs.at(1).toMap();
try {
- if (m_applicationId.isEmpty()) {
- m_applicationId = root[qSL("applicationId")].toString();
- if (m_applicationId.isEmpty())
+ if (m_packageId.isEmpty()) {
+ m_packageId = root[qSL("packageId")].toString();
+ if (m_packageId.isEmpty())
throw false;
- } else if (root[qSL("applicationId")].toString() != m_applicationId) {
+ } else if (root[qSL("packageId")].toString() != m_packageId) {
throw false;
}
- m_installationLocationId = root[qSL("installationLocationId")].toString();
m_diskSpaceUsed = root[qSL("diskSpaceUsed")].toULongLong();
m_digest = QByteArray::fromHex(root[qSL("digest")].toString().toLatin1());
if (m_digest.isEmpty())
@@ -240,7 +229,8 @@ bool InstallationReport::deserialize(QIODevice *from)
// see if the file has been tampered with by checking the hmac
QByteArray hmacFile = QByteArray::fromHex(docs[2].toMap().value(qSL("hmac")).toString().toLatin1());
- QByteArray hmacKey = QByteArray::fromRawData((const char *) privateHmacKeyData, sizeof(privateHmacKeyData));
+ QByteArray hmacKey = QByteArray::fromRawData(reinterpret_cast<const char *>(privateHmacKeyData),
+ sizeof(privateHmacKeyData));
QByteArray hmacCalc= QMessageAuthenticationCode::hash(QtYaml::yamlFromVariantDocuments({ docs[0], docs[1] }, QtYaml::BlockStyle),
hmacKey,
QCryptographicHash::Sha256);
@@ -264,12 +254,11 @@ bool InstallationReport::serialize(QIODevice *to) const
return false;
QVariantMap header {
- { "formatVersion", 1 },
+ { "formatVersion", 3 },
{ "formatType", "am-installation-report" }
};
QVariantMap root {
- { qSL("applicationId"), applicationId() },
- { qSL("installationLocationId"), installationLocationId() },
+ { qSL("packageId"), packageId() },
{ qSL("diskSpaceUsed"), diskSpaceUsed() },
{ qSL("digest"), QLatin1String(digest().toHex()) }
};
@@ -289,7 +278,8 @@ bool InstallationReport::serialize(QIODevice *to) const
docs << root;
// generate hmac to prevent tampering
- QByteArray hmacKey = QByteArray::fromRawData((const char *) privateHmacKeyData, sizeof(privateHmacKeyData));
+ QByteArray hmacKey = QByteArray::fromRawData(reinterpret_cast<const char *>(privateHmacKeyData),
+ sizeof(privateHmacKeyData));
QByteArray hmacCalc= QMessageAuthenticationCode::hash(QtYaml::yamlFromVariantDocuments({ docs[0], docs[1] }, QtYaml::BlockStyle),
hmacKey,
QCryptographicHash::Sha256);
diff --git a/src/application-lib/installationreport.h b/src/application-lib/installationreport.h
index a619c80a..87fa56c1 100644
--- a/src/application-lib/installationreport.h
+++ b/src/application-lib/installationreport.h
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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
@@ -55,13 +55,10 @@ QT_BEGIN_NAMESPACE_AM
class InstallationReport
{
public:
- InstallationReport(const QString &applicationId = QString());
+ InstallationReport(const QString &packageId = QString());
- QString applicationId() const;
- void setApplicationId(const QString &applicationId);
-
- QString installationLocationId() const;
- void setInstallationLocationId(const QString &installationLocationId);
+ QString packageId() const;
+ void setPackageId(const QString &packageId);
QVariantMap extraMetaData() const;
void setExtraMetaData(const QVariantMap &extraMetaData);
@@ -90,8 +87,7 @@ public:
bool serialize(QIODevice *to) const;
private:
- QString m_applicationId;
- QString m_installationLocationId;
+ QString m_packageId;
QByteArray m_digest;
quint64 m_diskSpaceUsed = 0;
QStringList m_files;
diff --git a/src/package-lib/package_p.cpp b/src/application-lib/intentinfo.cpp
index 702b94a2..ef53ce7e 100644
--- a/src/package-lib/package_p.cpp
+++ b/src/application-lib/intentinfo.cpp
@@ -1,10 +1,9 @@
/****************************************************************************
**
** Copyright (C) 2019 Luxoft Sweden AB
-** Copyright (C) 2018 Pelagicore AG
** Contact: https://www.qt.io/licensing/
**
-** This file is part of the Luxoft Application Manager.
+** This file is part of the Qt Application Manager.
**
** $QT_BEGIN_LICENSE:LGPL-QTAS$
** Commercial License Usage
@@ -40,51 +39,108 @@
**
****************************************************************************/
-
-#include <QFileInfo>
#include <QDataStream>
-#include <QCryptographicHash>
-
-#include <archive.h>
-#include "package_p.h"
+#include "intentinfo.h"
+#include "packageinfo.h"
QT_BEGIN_NAMESPACE_AM
-ArchiveException::ArchiveException(struct ::archive *ar, const char *errorString)
- : Exception(Error::Archive, qSL("[libarchive] ") + qL1S(errorString) + qSL(": ") + QString::fromLocal8Bit(::archive_error_string(ar)))
+
+IntentInfo::IntentInfo(PackageInfo *packageInfo)
+ : m_packageInfo(packageInfo)
+{ }
+
+IntentInfo::~IntentInfo()
{ }
+QString IntentInfo::id() const
+{
+ return m_id;
+}
+
+IntentInfo::Visibility IntentInfo::visibility() const
+{
+ return m_visibility;
+}
+
+QStringList IntentInfo::requiredCapabilities() const
+{
+ return m_requiredCapabilities;
+}
+
+QVariantMap IntentInfo::parameterMatch() const
+{
+ return m_parameterMatch;
+}
-QVariantMap PackageUtilities::headerDataForDigest = QVariantMap {
- { "extraSigned", QVariantMap() }
-};
+QString IntentInfo::handlingApplicationId() const
+{
+ return m_handlingApplicationId;
+}
-void PackageUtilities::addFileMetadataToDigest(const QString &entryFilePath, const QFileInfo &fi, QCryptographicHash &digest)
+QStringList IntentInfo::categories() const
{
- // (using QDataStream would be more readable, but it would make the algorithm Qt dependent)
- QByteArray addToDigest = ((fi.isDir()) ? "D/" : "F/")
- + QByteArray::number(fi.isDir() ? 0 : fi.size())
- + '/' + entryFilePath.toUtf8();
- digest.addData(addToDigest);
+ return m_categories;
}
-void PackageUtilities::addHeaderDataToDigest(const QVariantMap &header, QCryptographicHash &digest) Q_DECL_NOEXCEPT_EXPR(false)
+QMap<QString, QString> IntentInfo::names() const
{
- for (auto it = headerDataForDigest.constBegin(); it != headerDataForDigest.constEnd(); ++it) {
- if (header.contains(it.key())) {
- QByteArray ba;
- QDataStream ds(&ba, QIODevice::WriteOnly);
-
- QVariant v = header.value(it.key());
- if (!v.convert(int(it.value().type())))
- throw Exception(Error::Package, "metadata field %1 has invalid type for digest calculation (cannot convert %2 to %3)")
- .arg(it.key()).arg(header.value(it.key()).type()).arg(it.value().type());
- ds << v;
-
- digest.addData(ba);
- }
- }
+ return m_name;
+}
+
+QString IntentInfo::name(const QString &language) const
+{
+ return m_name.value(language);
+}
+
+QMap<QString, QString> IntentInfo::descriptions() const
+{
+ return m_description;
+}
+
+QString IntentInfo::description(const QString &language) const
+{
+ return m_description.value(language);
+}
+
+QString IntentInfo::icon() const
+{
+ return m_icon;
+}
+
+void IntentInfo::writeToDataStream(QDataStream &ds) const
+{
+ ds << m_id
+ << (m_visibility == Public ? qSL("public") : qSL("private"))
+ << m_requiredCapabilities
+ << m_parameterMatch
+ << m_handlingApplicationId
+ << m_categories
+ << m_name
+ << m_description
+ << m_icon;
+}
+
+IntentInfo *IntentInfo::readFromDataStream(PackageInfo *pkg, QDataStream &ds)
+{
+ QScopedPointer<IntentInfo> intent(new IntentInfo(pkg));
+ QString visibilityStr;
+
+ ds >> intent->m_id
+ >> visibilityStr
+ >> intent->m_requiredCapabilities
+ >> intent->m_parameterMatch
+ >> intent->m_handlingApplicationId
+ >> intent->m_categories
+ >> intent->m_name
+ >> intent->m_description
+ >> intent->m_icon;
+
+ intent->m_visibility = (visibilityStr == qSL("public")) ? Public : Private;
+ intent->m_categories.sort();
+
+ return intent.take();
}
QT_END_NAMESPACE_AM
diff --git a/src/installer-lib/installationlocation.h b/src/application-lib/intentinfo.h
index 43e921ab..aee5b8ab 100644
--- a/src/installer-lib/installationlocation.h
+++ b/src/application-lib/intentinfo.h
@@ -1,10 +1,9 @@
/****************************************************************************
**
** Copyright (C) 2019 Luxoft Sweden AB
-** Copyright (C) 2018 Pelagicore AG
** Contact: https://www.qt.io/licensing/
**
-** This file is part of the Luxoft Application Manager.
+** This file is part of the Qt Application Manager.
**
** $QT_BEGIN_LICENSE:LGPL-QTAS$
** Commercial License Usage
@@ -42,43 +41,64 @@
#pragma once
-#include <QtAppManCommon/global.h>
+#include <QMap>
#include <QString>
+#include <QStringList>
#include <QVariantMap>
+#include <QVector>
+
+#include <QtAppManCommon/global.h>
+
+QT_FORWARD_DECLARE_CLASS(QDataStream)
QT_BEGIN_NAMESPACE_AM
-class InstallationLocation
+class YamlPackageScanner;
+class PackageInfo;
+
+class IntentInfo
{
public:
- static const InstallationLocation invalid;
+ IntentInfo(PackageInfo *packageInfo);
+ ~IntentInfo();
- bool operator==(const InstallationLocation &other) const;
- inline bool operator!=(const InstallationLocation &other) const { return !((*this) == other); }
+ enum Visibility {
+ Public,
+ Private
+ };
QString id() const;
- int index() const;
+ Visibility visibility() const;
+ QStringList requiredCapabilities() const;
+ QVariantMap parameterMatch() const;
+ QString handlingApplicationId() const;
- QString installationPath() const;
- QString documentPath() const;
+ QStringList categories() const;
- bool installationDeviceFreeSpace(quint64 *bytesTotal, quint64 *bytesFree) const;
- bool documentDeviceFreeSpace(quint64 *bytesTotal, quint64 *bytesFree) const;
+ QMap<QString, QString> names() const;
+ QString name(const QString &language) const;
+ QMap<QString, QString> descriptions() const;
+ QString description(const QString &language) const;
+ QString icon() const;
- bool isValid() const;
- bool isDefault() const;
+ void writeToDataStream(QDataStream &ds) const;
+ static IntentInfo *readFromDataStream(PackageInfo *pkg, QDataStream &ds);
- QVariantMap toVariantMap() const;
+private:
+ PackageInfo *m_packageInfo;
+ QString m_id;
+ Visibility m_visibility = Public;
+ QStringList m_requiredCapabilities;
+ QVariantMap m_parameterMatch;
- static QVector<InstallationLocation> parseInstallationLocations(const QVariantList &list,
- const QString &hardwareId) Q_DECL_NOEXCEPT_EXPR(false);
+ QString m_handlingApplicationId;
+ QStringList m_categories;
+ QMap<QString, QString> m_name; // language -> name
+ QMap<QString, QString> m_description; // language -> description
+ QString m_icon; // relative to info.json location
-private:
- bool m_valid = false;
- int m_index = 0;
- bool m_isDefault = false;
- QString m_installationPath;
- QString m_documentPath;
+ friend class YamlPackageScanner;
+ Q_DISABLE_COPY(IntentInfo)
};
QT_END_NAMESPACE_AM
diff --git a/src/application-lib/packagedatabase.cpp b/src/application-lib/packagedatabase.cpp
new file mode 100644
index 00000000..3496faa7
--- /dev/null
+++ b/src/application-lib/packagedatabase.cpp
@@ -0,0 +1,221 @@
+/****************************************************************************
+**
+** 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
+**
+****************************************************************************/
+
+#include <QDir>
+#include <QFile>
+#include <QScopedPointer>
+
+#include "packagedatabase.h"
+#include "packageinfo.h"
+#include "yamlpackagescanner.h"
+#include "applicationinfo.h"
+#include "installationreport.h"
+#include "exception.h"
+#include "logging.h"
+
+QT_BEGIN_NAMESPACE_AM
+
+PackageDatabase::PackageDatabase(const QStringList &builtInPackagesDirs,
+ const QString &installedPackagesDir)
+ : m_builtInPackagesDirs(builtInPackagesDirs)
+ , m_installedPackagesDir(installedPackagesDir)
+{ }
+
+PackageDatabase::PackageDatabase(const QString &singlePackagePath)
+ : m_singlePackagePath(singlePackagePath)
+{
+ Q_ASSERT(!singlePackagePath.isEmpty());
+}
+
+QString PackageDatabase::installedPackagesDir() const
+{
+ return m_installedPackagesDir;
+}
+
+void PackageDatabase::enableLoadFromCache()
+{
+ if (m_parsed)
+ qCWarning(LogSystem) << "PackageDatabase cannot change the caching mode after the initial load";
+ m_loadFromCache = true;
+}
+
+void PackageDatabase::enableSaveToCache()
+{
+ if (m_parsed)
+ qCWarning(LogSystem) << "PackageDatabase cannot change the caching mode after the initial load";
+ m_saveToCache = true;
+}
+
+bool PackageDatabase::loadFromCache()
+{
+ return false;
+ //TODO: read cache file
+}
+
+void PackageDatabase::saveToCache()
+{
+ //TODO: write cache file
+}
+
+bool PackageDatabase::canBeRevertedToBuiltIn(PackageInfo *pi)
+{
+ if (!pi || pi->isBuiltIn() || !m_installedPackages.contains(pi))
+ return false;
+ for (auto it = m_builtInPackages.cbegin(); it != m_builtInPackages.cend(); ++it) {
+ if (it.key()->id() == pi->id())
+ return true;
+ }
+ return false;
+}
+
+
+QMap<PackageInfo *, QString> PackageDatabase::loadManifestsFromDir(YamlPackageScanner *yps, const QString &manifestDir, bool scanningBuiltInApps)
+{
+ QMap<PackageInfo *, QString> result;
+
+ auto flags = scanningBuiltInApps ? QDir::Dirs | QDir::NoDotAndDotDot
+ : QDir::Dirs | QDir::NoDotAndDotDot | QDir::NoSymLinks;
+ const QDir baseDir(manifestDir);
+ const QStringList pkgDirNames = baseDir.entryList(flags);
+
+ for (const QString &pkgDirName : pkgDirNames) {
+ try {
+ // ignore left-overs from the installer
+ if (pkgDirName.endsWith('+') || pkgDirName.endsWith('-'))
+ continue;
+
+ // ignore filesystem problems
+ QDir pkgDir = baseDir.absoluteFilePath(pkgDirName);
+ if (!pkgDir.exists())
+ continue;
+
+ // ignore directory names with weird/forbidden characters
+ QString pkgIdError;
+ if (!PackageInfo::isValidApplicationId(pkgDirName, &pkgIdError))
+ throw Exception("directory name is not a valid package-id: %1").arg(pkgIdError);
+
+ if (!pkgDir.exists(qSL("info.yaml")))
+ throw Exception("couldn't find an info.yaml manifest");
+ if (!scanningBuiltInApps && !pkgDir.exists(qSL(".installation-report.yaml")))
+ throw Exception("found a non-built-in package without an installation report");
+
+ QString manifestPath = pkgDir.absoluteFilePath(yps->metaDataFileName());
+ QScopedPointer<PackageInfo> pkg(loadManifest(yps, manifestPath));
+
+ if (pkg->id() != pkgDir.dirName()) {
+ throw Exception("an info.yaml must be in a directory that has"
+ " the same name as the package's id: found '%1'").arg(pkg->id());
+ }
+ if (scanningBuiltInApps) {
+ pkg->setBuiltIn(true);
+ } else { // 3rd-party apps
+ QFile f(pkgDir.absoluteFilePath(qSL(".installation-report.yaml")));
+ if (!f.open(QFile::ReadOnly))
+ throw Exception(f, "failed to open the installation report");
+
+ QScopedPointer<InstallationReport> report(new InstallationReport(pkg->id()));
+ if (!report->deserialize(&f))
+ throw Exception(f, "failed to deserialize the installation report");
+
+ pkg->setInstallationReport(report.take());
+ pkg->setBaseDir(QDir(m_installedPackagesDir).filePath(pkg->id()));
+ }
+ result.insert(pkg.take(), manifestPath);
+ } catch (const Exception &e) {
+ qCDebug(LogSystem) << "Ignoring package" << pkgDirName << ":" << e.what();
+ }
+ }
+ return result;
+}
+
+PackageInfo *PackageDatabase::loadManifest(YamlPackageScanner *yps, const QString &manifestPath)
+{
+ QScopedPointer<PackageInfo> pkg(yps->scan(manifestPath));
+ Q_ASSERT(pkg);
+
+ if (pkg->applications().isEmpty())
+ throw Exception("package contains no applications");
+
+ return pkg.take();
+}
+
+void PackageDatabase::parse()
+{
+ if (m_parsed)
+ throw Exception("PackageDatabase::parse() has been called multiple times");
+ m_parsed = true;
+
+ if (m_loadFromCache) {
+ if (loadFromCache())
+ return;
+ }
+
+ YamlPackageScanner yps;
+
+ if (!m_singlePackagePath.isEmpty()) {
+ try {
+ m_builtInPackages.insert(loadManifest(&yps, m_singlePackagePath), m_singlePackagePath);
+ } catch (const Exception &e) {
+ throw Exception("Failed to load manifest for package: %1").arg(e.errorString());
+ }
+ } else {
+ for (const QString &dir : m_builtInPackagesDirs)
+ m_builtInPackages.unite(loadManifestsFromDir(&yps, dir, true));
+
+ if (!m_installedPackagesDir.isEmpty())
+ m_installedPackages = loadManifestsFromDir(&yps, m_installedPackagesDir, false);
+ }
+
+ if (m_saveToCache)
+ saveToCache();
+}
+
+QVector<PackageInfo *> PackageDatabase::installedPackages() const
+{
+ return m_installedPackages.keys().toVector();
+}
+
+QVector<PackageInfo *> PackageDatabase::builtInPackages() const
+{
+ return m_builtInPackages.keys().toVector();
+}
+
+QT_END_NAMESPACE_AM
diff --git a/src/manager-lib/applicationdatabase.h b/src/application-lib/packagedatabase.h
index 7d11f4a9..ce1610db 100644
--- a/src/manager-lib/applicationdatabase.h
+++ b/src/application-lib/packagedatabase.h
@@ -1,10 +1,9 @@
/****************************************************************************
**
** Copyright (C) 2019 Luxoft Sweden AB
-** Copyright (C) 2018 Pelagicore AG
** Contact: https://www.qt.io/licensing/
**
-** This file is part of the Luxoft Application Manager.
+** This file is part of the Qt Application Manager.
**
** $QT_BEGIN_LICENSE:LGPL-QTAS$
** Commercial License Usage
@@ -43,36 +42,56 @@
#pragma once
#include <QtAppManCommon/global.h>
-#include <QList>
+#include <QVector>
#include <QString>
+#include <QtAppManApplication/packageinfo.h>
+
QT_BEGIN_NAMESPACE_AM
-class Application;
-class AbstractApplication;
-class ApplicationDatabasePrivate;
+class PackageInfo;
+class YamlPackageScanner;
+
-class ApplicationDatabase
+class PackageDatabase
{
public:
- explicit ApplicationDatabase();
- explicit ApplicationDatabase(const QString &fileName);
- ~ApplicationDatabase();
+ PackageDatabase(const QStringList &builtInPackagesDirs, const QString &installedPackagesDir = QString());
+ PackageDatabase(const QString &singlePackagePath);
+
+ QString installedPackagesDir() const;
+
+ void enableLoadFromCache();
+ void enableSaveToCache();
- bool isValid() const;
- bool isTemporary() const;
- QString errorString() const;
- QString name() const;
+ void parse();
- QVector<AbstractApplication *> read() Q_DECL_NOEXCEPT_EXPR(false);
- void write(const QVector<AbstractApplication *> &apps) Q_DECL_NOEXCEPT_EXPR(false);
- void write(const QVector<AbstractApplicationInfo *> &apps) Q_DECL_NOEXCEPT_EXPR(false);
+ QVector<PackageInfo *> builtInPackages() const;
+ QVector<PackageInfo *> installedPackages() const;
- void invalidate();
+ //TODO: runtime installations
+ //void addPackage(PackageInfo *package);
+ //void removePackage(PackageInfo *package);
+ //void updatePackage(PackageInfo *oldPackage, PackageInfo *newPackage);
private:
- ApplicationDatabasePrivate *d;
- Q_DISABLE_COPY(ApplicationDatabase)
+ PackageInfo *loadManifest(YamlPackageScanner *yps, const QString &manifestPath);
+ QMap<PackageInfo *, QString> loadManifestsFromDir(YamlPackageScanner *yps, const QString &manifestDir, bool scanningBuiltInApps);
+
+ bool loadFromCache();
+ void saveToCache();
+
+ bool m_loadFromCache = false;
+ bool m_saveToCache = false;
+ bool m_parsed = false;
+ QStringList m_builtInPackagesDirs;
+ QString m_installedPackagesDir;
+ QString m_singlePackagePath;
+
+ QMap<PackageInfo *, QString> m_builtInPackages;
+ QMap<PackageInfo *, QString> m_installedPackages;
+
+ bool canBeRevertedToBuiltIn(PackageInfo *pi);
};
QT_END_NAMESPACE_AM
diff --git a/src/application-lib/packageinfo.cpp b/src/application-lib/packageinfo.cpp
new file mode 100644
index 00000000..ee306431
--- /dev/null
+++ b/src/application-lib/packageinfo.cpp
@@ -0,0 +1,283 @@
+/****************************************************************************
+**
+** 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
+**
+****************************************************************************/
+
+#include <QDataStream>
+#include <QBuffer>
+
+#include "packageinfo.h"
+#include "applicationinfo.h"
+#include "intentinfo.h"
+#include "exception.h"
+#include "installationreport.h"
+
+
+QT_BEGIN_NAMESPACE_AM
+
+PackageInfo::PackageInfo()
+{ }
+
+PackageInfo::~PackageInfo()
+{ }
+
+void PackageInfo::validate() const Q_DECL_NOEXCEPT_EXPR(false)
+{
+ QString errorMsg;
+ if (!isValidApplicationId(id(), &errorMsg))
+ throw Exception(Error::Parse, "the identifier (%1) is not a valid package-id: %2").arg(id()).arg(errorMsg);
+
+ for (const auto &app : m_applications) {
+ if (!isValidApplicationId(app->id(), &errorMsg))
+ throw Exception(Error::Parse, "the identifier (%1) is not a valid application-id: %2").arg(app->id()).arg(errorMsg);
+
+ if (app->absoluteCodeFilePath().isEmpty())
+ throw Exception(Error::Parse, "the 'code' field must not be empty on application %1").arg(app->id());
+
+ if (app->runtimeName().isEmpty())
+ throw Exception(Error::Parse, "the 'runtimeName' field must not be empty on application %1").arg(app->id());
+ }
+}
+
+QString PackageInfo::id() const
+{
+ return m_id;
+}
+
+QMap<QString, QString> PackageInfo::names() const
+{
+ return m_name;
+}
+
+QString PackageInfo::name(const QString &language) const
+{
+ return m_name.value(language);
+}
+
+QMap<QString, QString> PackageInfo::descriptions() const
+{
+ return m_description;
+}
+
+QString PackageInfo::description(const QString &language) const
+{
+ return m_description.value(language);
+}
+
+QString PackageInfo::icon() const
+{
+ return m_icon;
+}
+
+QStringList PackageInfo::categories() const
+{
+ return m_categories;
+}
+
+bool PackageInfo::isBuiltIn() const
+{
+ return m_builtIn;
+}
+
+void PackageInfo::setBuiltIn(bool builtIn)
+{
+ m_builtIn = builtIn;
+}
+
+QString PackageInfo::version() const
+{
+ return m_version;
+}
+
+QVariantMap PackageInfo::dltConfiguration() const
+{
+ return m_dltConfiguration;
+}
+
+const QDir &PackageInfo::baseDir() const
+{
+ return m_baseDir;
+}
+
+void PackageInfo::setBaseDir(const QDir &dir)
+{
+ m_baseDir = dir;
+}
+
+QVector<ApplicationInfo *> PackageInfo::applications() const
+{
+ return m_applications;
+}
+
+QVector<IntentInfo *> PackageInfo::intents() const
+{
+ return m_intents;
+}
+
+const InstallationReport *PackageInfo::installationReport() const
+{
+ return m_installationReport.data();
+}
+
+void PackageInfo::setInstallationReport(InstallationReport *report)
+{
+ m_installationReport.reset(report);
+}
+
+void PackageInfo::writeToDataStream(QDataStream &ds) const
+{
+ QByteArray serializedReport;
+
+ if (auto report = installationReport()) {
+ QBuffer buffer(&serializedReport);
+ buffer.open(QBuffer::WriteOnly);
+ report->serialize(&buffer);
+ }
+
+ ds << m_id
+ << m_name
+ << m_icon
+ << m_description
+ << m_categories
+ << m_version
+ << m_builtIn
+ << m_uid
+ << m_dltConfiguration
+ << m_baseDir.absolutePath()
+ << serializedReport;
+
+ ds << m_applications.size();
+ for (const auto &app : m_applications)
+ app->writeToDataStream(ds);
+
+ ds << m_intents.size();
+ for (const auto &intent : m_intents)
+ intent->writeToDataStream(ds);
+}
+
+PackageInfo *PackageInfo::readFromDataStream(QDataStream &ds)
+{
+ QScopedPointer<PackageInfo> pkg(new PackageInfo);
+
+ QString baseDir;
+ QByteArray installationReport;
+
+ ds >> pkg->m_id
+ >> pkg->m_name
+ >> pkg->m_icon
+ >> pkg->m_description
+ >> pkg->m_categories
+ >> pkg->m_version
+ >> pkg->m_builtIn
+ >> pkg->m_uid
+ >> pkg->m_dltConfiguration
+ >> baseDir
+ >> installationReport;
+
+ pkg->m_baseDir.setPath(baseDir);
+
+ if (!installationReport.isEmpty()) {
+ QBuffer buffer(&installationReport);
+ buffer.open(QBuffer::ReadOnly);
+ pkg->m_installationReport.reset(new InstallationReport(pkg->id()));
+ if (!pkg->m_installationReport->deserialize(&buffer))
+ pkg->m_installationReport.reset();
+ }
+
+ return pkg.take();
+}
+
+bool PackageInfo::isValidApplicationId(const QString &appId, QString *errorString)
+{
+ // we need to make sure that we can use the name as directory in a filesystem and inode names
+ // are limited to 255 characters in Linux. We need to subtract a safety margin for prefixes
+ // or suffixes though:
+ static const int maxLength = 150;
+
+ try {
+ if (appId.isEmpty())
+ throw Exception(Error::Parse, "must not be empty");
+
+ if (appId.length() > maxLength)
+ throw Exception(Error::Parse, "the maximum length is %1 characters (found %2 characters)").arg(maxLength, appId.length());
+
+ // all characters need to be ASCII minus any filesystem special characters:
+ bool spaceOnly = true;
+ static const char forbiddenChars[] = "<>:\"/\\|?*";
+ for (int pos = 0; pos < appId.length(); ++pos) {
+ ushort ch = appId.at(pos).unicode();
+ if ((ch < 0x20) || (ch > 0x7f) || strchr(forbiddenChars, ch & 0xff)) {
+ throw Exception(Error::Parse, "must consist of printable ASCII characters only, except any of \'%1'")
+ .arg(QString::fromLatin1(forbiddenChars));
+ }
+ if (spaceOnly)
+ spaceOnly = QChar(ch).isSpace();
+ }
+ if (spaceOnly)
+ throw Exception(Error::Parse, "must not consist of only white-space characters");
+
+ return true;
+ } catch (const Exception &e) {
+ if (errorString)
+ *errorString = e.errorString();
+ return false;
+ }
+}
+
+bool PackageInfo::isValidIcon(const QString &icon, QString *errorString)
+{
+ try {
+ if (icon.isEmpty())
+ throw Exception("empty path");
+
+ QFileInfo fileInfo(icon);
+
+ if (fileInfo.fileName() != icon)
+ throw Exception("'%1' is not a valid file name").arg(icon);
+
+ return true;
+ } catch (const Exception &e) {
+ if (errorString)
+ *errorString = e.errorString();
+ return false;
+ }
+}
+
+
+QT_END_NAMESPACE_AM
diff --git a/src/application-lib/packageinfo.h b/src/application-lib/packageinfo.h
new file mode 100644
index 00000000..777526f6
--- /dev/null
+++ b/src/application-lib/packageinfo.h
@@ -0,0 +1,122 @@
+/****************************************************************************
+**
+** 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
+**
+****************************************************************************/
+
+#pragma once
+
+#include <QDir>
+#include <QMap>
+#include <QString>
+#include <QStringList>
+#include <QVariantMap>
+#include <QVector>
+
+#include <QtAppManCommon/global.h>
+
+QT_FORWARD_DECLARE_CLASS(QDataStream)
+
+QT_BEGIN_NAMESPACE_AM
+
+class InstallationReport;
+class IntentInfo;
+class ApplicationInfo;
+class YamlPackageScanner;
+
+class PackageInfo
+{
+public:
+ PackageInfo();
+ ~PackageInfo();
+
+ void validate() const Q_DECL_NOEXCEPT_EXPR(false);
+
+ QString id() const;
+
+ QMap<QString, QString> names() const;
+ QString name(const QString &language) const;
+ QMap<QString, QString> descriptions() const;
+ QString description(const QString &language) const;
+ QString icon() const;
+ QStringList categories() const;
+
+ bool isBuiltIn() const;
+ void setBuiltIn(bool builtIn);
+ QString version() const;
+ QVariantMap dltConfiguration() const;
+ uint uid() const { return m_uid; }
+
+ const QDir &baseDir() const;
+ void setBaseDir(const QDir &dir);
+
+ QVector<ApplicationInfo *> applications() const;
+ QVector<IntentInfo *> intents() const;
+
+ const InstallationReport *installationReport() const;
+ void setInstallationReport(InstallationReport *report);
+
+ void writeToDataStream(QDataStream &ds) const;
+ static PackageInfo *readFromDataStream(QDataStream &ds);
+
+ static bool isValidApplicationId(const QString &appId, QString *errorString = nullptr);
+ static bool isValidIcon(const QString &icon, QString *errorString = nullptr);
+
+private:
+ QString m_id;
+ QMap<QString, QString> m_name; // language -> name
+ QMap<QString, QString> m_description; // language -> description
+ QStringList m_categories;
+ QString m_icon; // relative to info.json location
+ QString m_version;
+ bool m_builtIn = false; // system package - not removable
+ uint m_uid = uint(-1); // unix user id - move to installationReport
+ QVariantMap m_dltConfiguration;
+ QVector<ApplicationInfo *> m_applications;
+ QVector<IntentInfo *> m_intents;
+
+ // added by installer
+ QScopedPointer<InstallationReport> m_installationReport;
+ QDir m_baseDir;
+
+ friend class YamlPackageScanner;
+ friend class InstallationTask;
+ Q_DISABLE_COPY(PackageInfo)
+};
+
+QT_END_NAMESPACE_AM
diff --git a/src/application-lib/applicationscanner.h b/src/application-lib/packagescanner.h
index 5124d5c7..55e9ff3a 100644
--- a/src/application-lib/applicationscanner.h
+++ b/src/application-lib/packagescanner.h
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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
@@ -46,24 +46,22 @@
QT_BEGIN_NAMESPACE_AM
-class ApplicationInfo;
-class ApplicationAliasInfo;
+class PackageInfo;
-class ApplicationScanner
+class PackageScanner
{
public:
- virtual ~ApplicationScanner() = default;
+ virtual ~PackageScanner() = default;
- virtual ApplicationInfo *scan(const QString &filePath) Q_DECL_NOEXCEPT_EXPR(false) = 0;
- virtual ApplicationAliasInfo *scanAlias(const QString &filePath, const ApplicationInfo *application) Q_DECL_NOEXCEPT_EXPR(false) = 0;
+ virtual PackageInfo *scan(const QString &filePath) Q_DECL_NOEXCEPT_EXPR(false) = 0;
virtual QString metaDataFileName() const = 0;
protected:
- ApplicationScanner() = default;
+ PackageScanner() = default;
private:
- Q_DISABLE_COPY(ApplicationScanner)
+ Q_DISABLE_COPY(PackageScanner)
};
QT_END_NAMESPACE_AM
diff --git a/src/application-lib/yamlapplicationscanner.cpp b/src/application-lib/yamlapplicationscanner.cpp
deleted file mode 100644
index c3fd8e02..00000000
--- a/src/application-lib/yamlapplicationscanner.cpp
+++ /dev/null
@@ -1,229 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2019 Luxoft Sweden AB
-** Copyright (C) 2018 Pelagicore AG
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the Luxoft Application Manager.
-**
-** $QT_BEGIN_LICENSE:LGPL-QTAS$
-** Commercial License Usage
-** Licensees holding valid commercial Qt Automotive Suite licenses may use
-** this file in accordance with the commercial license agreement provided
-** with the Software or, alternatively, in accordance with the terms
-** contained in a written agreement between you and The Qt Company. For
-** licensing terms and conditions see https://www.qt.io/terms-conditions.
-** For further information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-** SPDX-License-Identifier: LGPL-3.0
-**
-****************************************************************************/
-
-#include <QJsonDocument>
-#include <QJsonParseError>
-#include <QJsonObject>
-#include <QJsonArray>
-#include <QFile>
-#include <QFileInfo>
-#include <QScopedPointer>
-
-#include "global.h"
-#include "qtyaml.h"
-#include "exception.h"
-#include "applicationinfo.h"
-#include "yamlapplicationscanner.h"
-#include "utilities.h"
-
-QT_BEGIN_NAMESPACE_AM
-
-YamlApplicationScanner::YamlApplicationScanner()
-{ }
-
-ApplicationInfo *YamlApplicationScanner::scan(const QString &filePath) Q_DECL_NOEXCEPT_EXPR(false)
-{
- return static_cast<ApplicationInfo*>(scanInternal(filePath, false, nullptr));
-}
-
-ApplicationAliasInfo *YamlApplicationScanner::scanAlias(const QString &filePath,
- const ApplicationInfo *application) Q_DECL_NOEXCEPT_EXPR(false)
-{
- return static_cast<ApplicationAliasInfo*>(scanInternal(filePath, true, application));
-}
-
-AbstractApplicationInfo *YamlApplicationScanner::scanInternal(const QString &filePath, bool scanAlias,
- const ApplicationInfo *application) Q_DECL_NOEXCEPT_EXPR(false)
-{
- try {
- if (scanAlias && !application)
- throw Exception("cannot scan an alias without a valid base application");
-
- QFile f(filePath);
- if (!f.open(QIODevice::ReadOnly))
- throw Exception(f, "could not open file for reading");
-
- QtYaml::ParseError parseError;
- QVector<QVariant> docs = QtYaml::variantDocumentsFromYaml(f.readAll(), &parseError);
-
- if (parseError.error != QJsonParseError::NoError) {
- throw Exception(Error::IO, "YAML parse error at line %1, column %2: %3")
- .arg(parseError.line).arg(parseError.column).arg(parseError.errorString());
- }
-
- try {
- checkYamlFormat(docs, 2 /*number of expected docs*/, { "am-application", "am-application-alias" }, 1);
- } catch (const Exception &e) {
- throw Exception(Error::Parse, "not a valid YAML application meta-data file: %1").arg(e.errorString());
- }
-
- const auto header = docs.constFirst().toMap();
- bool isApp = (header.value(qSL("formatType")).toString() == qL1S("am-application"));
- bool isAlias = (header.value(qSL("formatType")).toString() == qL1S("am-application-alias"));
-
- if (!isApp && !isAlias)
- throw Exception(Error::Parse, "not a valid YAML application manifest");
- if (isAlias && !scanAlias)
- throw Exception(Error::Parse, "is an alias, but expected a normal manifest");
- if (!isAlias && scanAlias)
- throw Exception(Error::Parse, "is an not alias, although expected such a manifest");
-
- QScopedPointer<AbstractApplicationInfo> app;
- if (isAlias)
- app.reset(new ApplicationAliasInfo);
- else {
- app.reset(new ApplicationInfo);
- auto *appInfo = static_cast<ApplicationInfo*>(app.data());
- appInfo->m_manifestDir = QFileInfo(f).absoluteDir();
- appInfo->m_codeDir.setPath(appInfo->manifestDir());
- }
-
- QVariantMap yaml = docs.at(1).toMap();
- for (auto it = yaml.constBegin(); it != yaml.constEnd(); ++it) {
- QByteArray field = it.key().toLatin1();
- bool unknownField = false;
- const QVariant &v = it.value();
-
- if ((!isAlias && (field == "id"))
- || (isAlias && (field == "aliasId"))) {
- app->m_id = v.toString();
- if (isAlias) {
- int sepPos = app->m_id.indexOf(qL1C('@'));
- if (sepPos < 0 || sepPos == (app->m_id.size() - 1))
- throw Exception(Error::Parse, "malformed aliasId '%1'").arg(app->m_id);
- QString realId = app->m_id.left(sepPos);
- if (application->id() != realId) {
- throw Exception(Error::Parse, "aliasId '%1' does not match base application id '%2'")
- .arg(app->m_id, application->id());
- }
- }
- } else if (field == "icon") {
- app->m_icon = v.toString();
- } else if (field == "name") {
- auto nameMap = v.toMap();
- for (auto it = nameMap.constBegin(); it != nameMap.constEnd(); ++it)
- app->m_name.insert(it.key(), it.value().toString());
- } else if (field == "documentUrl") {
- app->m_documentUrl = v.toString();
- } else if (!isAlias) {
- auto *appInfo = static_cast<ApplicationInfo*>(app.data());
- if (field == "code") {
- appInfo->m_codeFilePath = v.toString();
- } else if (field == "runtime") {
- appInfo->m_runtimeName = v.toString();
- } else if (field == "runtimeParameters") {
- appInfo->m_runtimeParameters = v.toMap();
- } else if (field == "supportsApplicationInterface") {
- appInfo->m_supportsApplicationInterface = v.toBool();
- } else if (field == "capabilities") {
- appInfo->m_capabilities = variantToStringList(v);
- appInfo->m_capabilities.sort();
- } else if (field == "categories") {
- appInfo->m_categories = variantToStringList(v);
- appInfo->m_categories.sort();
- } else if (field == "mimeTypes") {
- appInfo->m_mimeTypes = variantToStringList(v);
- appInfo->m_mimeTypes.sort();
- } else if (field == "applicationProperties") {
- const QVariantMap rawMap = v.toMap();
- appInfo->m_sysAppProperties = rawMap.value(qSL("protected")).toMap();
- appInfo->m_allAppProperties = appInfo->m_sysAppProperties;
- const QVariantMap pri = rawMap.value(qSL("private")).toMap();
- for (auto it = pri.cbegin(); it != pri.cend(); ++it)
- appInfo->m_allAppProperties.insert(it.key(), it.value());
- } else if (field == "version") {
- appInfo->m_version = v.toString();
- } else if (field == "opengl") {
- appInfo->m_openGLConfiguration = v.toMap();
-
- // sanity check
- static QStringList validKeys = {
- qSL("desktopProfile"),
- qSL("esMajorVersion"),
- qSL("esMinorVersion")
- };
- for (auto it = appInfo->m_openGLConfiguration.cbegin();
- it != appInfo->m_openGLConfiguration.cend(); ++it) {
- if (!validKeys.contains(it.key())) {
- throw Exception(Error::Parse, "the 'opengl' object contains the unsupported key '%1'")
- .arg(it.key());
- }
- }
- } else if (field == "logging") {
- const QVariantMap logging = v.toMap();
- if (!logging.isEmpty()) {
- if (logging.size() > 1 || logging.firstKey() != qSL("dlt"))
- throw Exception(Error::Parse, "'logging' only supports the 'dlt' key");
- appInfo->m_dlt = logging.value(qSL("dlt")).toMap();
-
- // sanity check
- for (auto it = appInfo->m_dlt.cbegin(); it != appInfo->m_dlt.cend(); ++it) {
- if (it.key() != qSL("id") && it.key() != qSL("description"))
- throw Exception(Error::Parse, "unsupported key in 'logging/dlt'");
- }
- }
- } else if (field == "intents") {
- appInfo->m_intents = v.toList();
- } else {
- unknownField = true;
- }
- } else {
- unknownField = true;
- }
- if (unknownField)
- throw Exception(Error::Parse, "contains unsupported field: '%1'").arg(field);
- }
-
- app->validate();
- return app.take();
- } catch (const Exception &e) {
- throw Exception(e.errorCode(), "Failed to parse manifest file %1: %2").arg(filePath, e.errorString());
- }
-}
-
-
-QString YamlApplicationScanner::metaDataFileName() const
-{
- return qSL("info.yaml");
-}
-
-QT_END_NAMESPACE_AM
diff --git a/src/application-lib/yamlpackagescanner.cpp b/src/application-lib/yamlpackagescanner.cpp
new file mode 100644
index 00000000..9adbd627
--- /dev/null
+++ b/src/application-lib/yamlpackagescanner.cpp
@@ -0,0 +1,383 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 Luxoft Sweden AB
+** Copyright (C) 2018 Pelagicore AG
+** 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
+**
+****************************************************************************/
+
+#include <QJsonDocument>
+#include <QJsonParseError>
+#include <QJsonObject>
+#include <QJsonArray>
+#include <QFile>
+#include <QFileInfo>
+#include <QScopedPointer>
+
+#include "global.h"
+#include "qtyaml.h"
+#include "exception.h"
+#include "logging.h"
+#include "packageinfo.h"
+#include "applicationinfo.h"
+#include "intentinfo.h"
+#include "yamlpackagescanner.h"
+#include "utilities.h"
+
+using Fields = std::vector<std::tuple<QByteArray, bool, const std::function<void(const QVariant &value)>>>;
+
+QT_BEGIN_NAMESPACE_AM
+
+
+YamlPackageScanner::YamlPackageScanner()
+{ }
+
+PackageInfo *YamlPackageScanner::scan(const QString &filePath) Q_DECL_NOEXCEPT_EXPR(false)
+{
+ auto parseMap = [](const QVariantMap &map, const Fields &fields) {
+ QStringList keys = map.keys();
+
+ for (const auto &field : fields) {
+ QString fieldName = qL1S(std::get<0>(field));
+
+ auto it = map.constFind(fieldName);
+ if (it != map.cend()) {
+ std::get<2>(field)(it.value());
+ } else if (std::get<1>(field)) { // missing, but required
+ throw Exception("required field missing in YAML: %1").arg(fieldName);
+ }
+ keys.removeOne(fieldName);
+ }
+ if (!keys.isEmpty())
+ throw Exception("unsupported fields found in YAML: %1").arg(keys.join(qSL(", ")));
+ };
+
+
+ try {
+ QFile f(filePath);
+ if (!f.open(QIODevice::ReadOnly))
+ throw Exception(f, "could not open file for reading");
+
+ QtYaml::ParseError parseError;
+ QVector<QVariant> docs = QtYaml::variantDocumentsFromYaml(f.readAll(), &parseError);
+
+ if (parseError.error != QJsonParseError::NoError) {
+ throw Exception(Error::IO, "YAML parse error at line %1, column %2: %3")
+ .arg(parseError.line).arg(parseError.column).arg(parseError.errorString());
+ }
+
+ bool legacy = false;
+ try {
+ checkYamlFormat(docs, 2 /*number of expected docs*/, { "am-package" }, 1);
+ } catch (const Exception &e) {
+ try {
+ checkYamlFormat(docs, 2 /*number of expected docs*/, { "am-application" }, 1);
+ qCDebug(LogSystem) << "Manifest file" << f.fileName() << "is still using the legacy 'am-application' format";
+ legacy = true;
+ } catch (const Exception &) {
+ throw Exception(Error::Parse, "not a valid YAML application meta-data file: %1").arg(e.errorString());
+ }
+ }
+
+ QStringList appIds; // duplicate check
+ QScopedPointer<PackageInfo> pkgInfo(new PackageInfo);
+ pkgInfo->setBaseDir(QFileInfo(f).absoluteDir());
+
+ QScopedPointer<ApplicationInfo> legacyAppInfo(legacy ? new ApplicationInfo(pkgInfo.data()) : nullptr);
+
+ // ----------------- package -----------------
+
+ Fields fields;
+ fields.emplace_back("id", true, [&pkgInfo, &legacyAppInfo](const QVariant &v) {
+ QString id = v.toString();
+ if (id.isEmpty())
+ throw Exception(Error::Parse, "packages need to have an id");
+ pkgInfo->m_id = id;
+ if (legacyAppInfo)
+ legacyAppInfo->m_id = pkgInfo->id();
+ });
+ fields.emplace_back("icon", true, [&pkgInfo](const QVariant &v) {
+ pkgInfo->m_icon = v.toString();
+ });
+ fields.emplace_back("name", true, [&pkgInfo](const QVariant &v) {
+ auto nameMap = v.toMap();
+ for (auto it = nameMap.constBegin(); it != nameMap.constEnd(); ++it)
+ pkgInfo->m_name.insert(it.key(), it.value().toString());
+
+ if (pkgInfo->m_name.isEmpty())
+ throw Exception(Error::Parse, "the 'name' field must not be empty");
+ });
+ if (!legacy) {
+ fields.emplace_back("description", false, [&pkgInfo](const QVariant &v) {
+ auto descriptionMap = v.toMap();
+ for (auto it = descriptionMap.constBegin(); it != descriptionMap.constEnd(); ++it)
+ pkgInfo->m_description.insert(it.key(), it.value().toString());
+ });
+ }
+ fields.emplace_back("categories", false, [&pkgInfo](const QVariant &v) {
+ pkgInfo->m_categories = variantToStringList(v);
+ pkgInfo->m_categories.sort();
+ });
+ fields.emplace_back("version", false, [&pkgInfo](const QVariant &v) {
+ pkgInfo->m_version = v.toString();
+ });
+ fields.emplace_back("logging", false, [&pkgInfo](const QVariant &v) {
+ const QVariantMap logging = v.toMap();
+ if (!logging.isEmpty()) {
+ if (logging.size() > 1 || logging.firstKey() != qSL("dlt"))
+ throw Exception(Error::Parse, "'logging' only supports the 'dlt' key");
+ pkgInfo->m_dltConfiguration = logging.value(qSL("dlt")).toMap();
+
+ // sanity check
+ for (auto it = pkgInfo->m_dltConfiguration.cbegin(); it != pkgInfo->m_dltConfiguration.cend(); ++it) {
+ if (it.key() != qSL("id") && it.key() != qSL("description"))
+ throw Exception(Error::Parse, "unsupported key in 'logging/dlt'");
+ }
+ }
+ });
+ if (legacy) {
+ fields.emplace_back("code", true, [&legacyAppInfo](const QVariant &v) {
+ legacyAppInfo->m_codeFilePath = v.toString();
+ });
+ fields.emplace_back("runtime", true, [&legacyAppInfo](const QVariant &v) {
+ legacyAppInfo->m_runtimeName = v.toString();
+ });
+ fields.emplace_back("runtimeParameters", false, [&legacyAppInfo](const QVariant &v) {
+ legacyAppInfo->m_runtimeParameters = v.toMap();
+ });
+ fields.emplace_back("supportsApplicationInterface", false, [&legacyAppInfo](const QVariant &v) {
+ legacyAppInfo->m_supportsApplicationInterface = v.toBool();
+ });
+ fields.emplace_back("capabilities", false, [&legacyAppInfo](const QVariant &v) {
+ legacyAppInfo->m_capabilities = variantToStringList(v);
+ legacyAppInfo->m_capabilities.sort();
+ });
+ fields.emplace_back("opengl", false, [&legacyAppInfo](const QVariant &v) {
+ legacyAppInfo->m_openGLConfiguration = v.toMap();
+
+ // sanity check - could be rewritten using the "fields" mechanism
+ static QStringList validKeys = {
+ qSL("desktopProfile"),
+ qSL("esMajorVersion"),
+ qSL("esMinorVersion")
+ };
+ for (auto it = legacyAppInfo->m_openGLConfiguration.cbegin();
+ it != legacyAppInfo->m_openGLConfiguration.cend(); ++it) {
+ if (!validKeys.contains(it.key())) {
+ throw Exception(Error::Parse, "the 'opengl' object contains the unsupported key '%1'")
+ .arg(it.key());
+ }
+ }
+ });
+ fields.emplace_back("applicationProperties", false, [&legacyAppInfo](const QVariant &v) {
+ const QVariantMap rawMap = v.toMap();
+ legacyAppInfo->m_sysAppProperties = rawMap.value(qSL("protected")).toMap();
+ legacyAppInfo->m_allAppProperties = legacyAppInfo->m_sysAppProperties;
+ const QVariantMap pri = rawMap.value(qSL("private")).toMap();
+ for (auto it = pri.cbegin(); it != pri.cend(); ++it)
+ legacyAppInfo->m_allAppProperties.insert(it.key(), it.value());
+ });
+ fields.emplace_back("documentUrl", false, [](const QVariant &) {
+ qCDebug(LogSystem) << " ignoring 'documentUrl'";
+ });
+ fields.emplace_back("mimeTypes", false, [&legacyAppInfo](const QVariant &v) {
+ legacyAppInfo->m_supportedMimeTypes = variantToStringList(v);
+ legacyAppInfo->m_supportedMimeTypes.sort();
+ });
+ }
+
+ // ----------------- applications -----------------
+
+ if (!legacy) {
+ fields.emplace_back("applications", true, [&pkgInfo, &appIds, &parseMap](const QVariant &v) {
+ QVariantList apps = v.toList();
+
+ for (auto appsIt = apps.constBegin(); appsIt != apps.constEnd(); ++appsIt) {
+ QScopedPointer<ApplicationInfo> appInfo(new ApplicationInfo(pkgInfo.data()));
+ Fields appFields;
+
+ appFields.emplace_back("id", true, [&appInfo, &appIds](const QVariant &v) {
+ QString id = v.toString();
+ if (id.isEmpty())
+ throw Exception(Error::Intents, "applications need to have an id");
+ if (appIds.contains(id))
+ throw Exception(Error::Intents, "found two applications with id %1").arg(id);
+ appInfo->m_id = id;
+ });
+ appFields.emplace_back("code", true, [&appInfo](const QVariant &v) {
+ appInfo->m_codeFilePath = v.toString();
+ });
+ appFields.emplace_back("runtime", true, [&appInfo](const QVariant &v) {
+ appInfo->m_runtimeName = v.toString();
+ });
+ appFields.emplace_back("runtimeParameters", false, [&appInfo](const QVariant &v) {
+ appInfo->m_runtimeParameters = v.toMap();
+ });
+ appFields.emplace_back("supportsApplicationInterface", false, [&appInfo](const QVariant &v) {
+ appInfo->m_supportsApplicationInterface = v.toBool();
+ });
+ appFields.emplace_back("capabilities", false, [&appInfo](const QVariant &v) {
+ appInfo->m_capabilities = variantToStringList(v);
+ appInfo->m_capabilities.sort();
+ });
+ appFields.emplace_back("opengl", false, [&appInfo](const QVariant &v) {
+ appInfo->m_openGLConfiguration = v.toMap();
+
+ // sanity check - could be rewritten using the "fields" mechanism
+ static QStringList validKeys = {
+ qSL("desktopProfile"),
+ qSL("esMajorVersion"),
+ qSL("esMinorVersion")
+ };
+ for (auto it = appInfo->m_openGLConfiguration.cbegin();
+ it != appInfo->m_openGLConfiguration.cend(); ++it) {
+ if (!validKeys.contains(it.key())) {
+ throw Exception(Error::Parse, "the 'opengl' object contains the unsupported key '%1'")
+ .arg(it.key());
+ }
+ }
+ });
+ appFields.emplace_back("applicationProperties", false, [&appInfo](const QVariant &v) {
+ const QVariantMap rawMap = v.toMap();
+ appInfo->m_sysAppProperties = rawMap.value(qSL("protected")).toMap();
+ appInfo->m_allAppProperties = appInfo->m_sysAppProperties;
+ const QVariantMap pri = rawMap.value(qSL("private")).toMap();
+ for (auto it = pri.cbegin(); it != pri.cend(); ++it)
+ appInfo->m_allAppProperties.insert(it.key(), it.value());
+ });
+
+ parseMap(appsIt->toMap(), appFields);
+ pkgInfo->m_applications << appInfo.take();
+ }
+ });
+ }
+
+ // ----------------- intents -----------------
+
+ fields.emplace_back("intents", false, [&pkgInfo, &parseMap, &appIds, legacy](const QVariant &v) {
+ QVariantList intents = v.toList();
+ QStringList intentIds; // duplicate check
+
+ for (auto intentsIt = intents.constBegin(); intentsIt != intents.constEnd(); ++intentsIt) {
+ QScopedPointer<IntentInfo> intentInfo(new IntentInfo(pkgInfo.data()));
+ Fields intentFields;
+
+ intentFields.emplace_back("id", true, [&intentInfo, &intentIds, &pkgInfo](const QVariant &v) {
+ QString id = v.toString();
+ if (id.isEmpty())
+ throw Exception(Error::Intents, "intents need to have an id (package %1)").arg(pkgInfo->id());
+ if (intentIds.contains(id))
+ throw Exception(Error::Intents, "found two intent handlers for intent %2 (package %1)").arg(pkgInfo->id()).arg(id);
+ intentInfo->m_id = id;
+ });
+ intentFields.emplace_back("visibility", false, [&intentInfo](const QVariant &v) {
+ const QString visibilityStr = v.toString();
+ if (visibilityStr == qL1S("private")) {
+ intentInfo->m_visibility = IntentInfo::Private;
+ } else if (visibilityStr != qL1S("public")) {
+ throw Exception(Error::Intents, "intent visibilty '%2' is invalid on intent %1 (valid values are either 'public' or 'private'")
+ .arg(intentInfo->m_id).arg(visibilityStr);
+ }
+ });
+ intentFields.emplace_back(legacy ? "handledBy" : "handlingApplicationId", legacy ? false : true, [&pkgInfo, &intentInfo, &appIds](const QVariant &v) {
+ QString appId = v.toString();
+
+ if (appId.isEmpty()) {
+ if (pkgInfo->m_applications.count() == 1) {
+ intentInfo->m_handlingApplicationId = pkgInfo->m_applications.constFirst()->id();
+ } else {
+ throw Exception(Error::Intents, "a 'handlingApplicationId' field on intent %1 is needed if more than one application is defined")
+ .arg(intentInfo->m_id);
+ }
+ } else {
+ if (appIds.contains(appId)) {
+ intentInfo->m_handlingApplicationId = appId;
+ } else {
+ throw Exception(Error::Intents, "the 'handlingApplicationId' field on intent %1 points to the unknown application id %2")
+ .arg(intentInfo->m_id).arg(appId);
+ }
+ }
+ });
+ intentFields.emplace_back("requiredCapabilities", false, [&intentInfo](const QVariant &v) {
+ intentInfo->m_requiredCapabilities = variantToStringList(v);
+ });
+ intentFields.emplace_back("parameterMatch", false, [&intentInfo](const QVariant &v) {
+ intentInfo->m_parameterMatch = v.toMap();
+ });
+ intentFields.emplace_back("icon", false, [&intentInfo](const QVariant &v) {
+ intentInfo->m_icon = v.toString();
+ });
+ intentFields.emplace_back("name", false, [&intentInfo](const QVariant &v) {
+ auto nameMap = v.toMap();
+ for (auto it = nameMap.constBegin(); it != nameMap.constEnd(); ++it)
+ intentInfo->m_name.insert(it.key(), it.value().toString());
+ });
+ intentFields.emplace_back("description", false, [&intentInfo](const QVariant &v) {
+ auto descriptionMap = v.toMap();
+ for (auto it = descriptionMap.constBegin(); it != descriptionMap.constEnd(); ++it)
+ intentInfo->m_description.insert(it.key(), it.value().toString());
+ });
+ intentFields.emplace_back("categories", false, [&intentInfo](const QVariant &v) {
+ intentInfo->m_categories = variantToStringList(v);
+ intentInfo->m_categories.sort();
+ });
+
+ parseMap(intentsIt->toMap(), intentFields);
+ pkgInfo->m_intents << intentInfo.take();
+ }
+ });
+
+ parseMap(docs.at(1).toMap(), fields);
+
+ if (legacy)
+ pkgInfo->m_applications << legacyAppInfo.take();
+
+ // validate the ids, runtime names and all referenced files
+ pkgInfo->validate();
+ return pkgInfo.take();
+ } catch (const Exception &e) {
+ throw Exception(e.errorCode(), "Failed to parse manifest file %1: %2").arg(QDir().relativeFilePath(filePath), e.errorString());
+ }
+}
+
+QString YamlPackageScanner::metaDataFileName() const
+{
+ return qSL("info.yaml");
+}
+
+
+QT_END_NAMESPACE_AM
diff --git a/src/application-lib/yamlapplicationscanner.h b/src/application-lib/yamlpackagescanner.h
index fd667182..d8eb4e22 100644
--- a/src/application-lib/yamlapplicationscanner.h
+++ b/src/application-lib/yamlpackagescanner.h
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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
@@ -42,26 +42,18 @@
#pragma once
-#include <QtAppManApplication/applicationscanner.h>
+#include <QtAppManApplication/packagescanner.h>
QT_BEGIN_NAMESPACE_AM
-class AbstractApplicationInfo;
-class YamlApplicationScanner : public ApplicationScanner
+class YamlPackageScanner : public PackageScanner
{
public:
- YamlApplicationScanner();
-
- ApplicationInfo *scan(const QString &filePath) Q_DECL_NOEXCEPT_EXPR(false) override;
- ApplicationAliasInfo *scanAlias(const QString &filePath,
- const ApplicationInfo *application) Q_DECL_NOEXCEPT_EXPR(false) override;
+ YamlPackageScanner();
+ PackageInfo *scan(const QString &filePath) Q_DECL_NOEXCEPT_EXPR(false) override;
QString metaDataFileName() const override;
-
-private:
- AbstractApplicationInfo *scanInternal(const QString &filePath, bool scanAlias,
- const ApplicationInfo *application) Q_DECL_NOEXCEPT_EXPR(false);
};
QT_END_NAMESPACE_AM
diff --git a/src/common-lib/crashhandler.cpp b/src/common-lib/crashhandler.cpp
index 1ec8a83f..95ec9b9f 100644
--- a/src/common-lib/crashhandler.cpp
+++ b/src/common-lib/crashhandler.cpp
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/src/common-lib/crashhandler.h b/src/common-lib/crashhandler.h
index 79b42730..b09104a8 100644
--- a/src/common-lib/crashhandler.h
+++ b/src/common-lib/crashhandler.h
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/src/common-lib/dbus-utilities.cpp b/src/common-lib/dbus-utilities.cpp
index ff74fb7f..1a8267b6 100644
--- a/src/common-lib/dbus-utilities.cpp
+++ b/src/common-lib/dbus-utilities.cpp
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/src/common-lib/dbus-utilities.h b/src/common-lib/dbus-utilities.h
index c135d142..fa3de40c 100644
--- a/src/common-lib/dbus-utilities.h
+++ b/src/common-lib/dbus-utilities.h
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/src/common-lib/error.h b/src/common-lib/error.h
index 1e1c16c8..6204783d 100644
--- a/src/common-lib/error.h
+++ b/src/common-lib/error.h
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/src/common-lib/exception.cpp b/src/common-lib/exception.cpp
index 11a54d89..ba3e8020 100644
--- a/src/common-lib/exception.cpp
+++ b/src/common-lib/exception.cpp
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/src/common-lib/exception.h b/src/common-lib/exception.h
index 3dcdc03a..92e41626 100644
--- a/src/common-lib/exception.h
+++ b/src/common-lib/exception.h
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/src/common-lib/global.h b/src/common-lib/global.h
index c1172b7b..72cec409 100644
--- a/src/common-lib/global.h
+++ b/src/common-lib/global.h
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/src/common-lib/logging.cpp b/src/common-lib/logging.cpp
index 3996d904..09a2b55f 100644
--- a/src/common-lib/logging.cpp
+++ b/src/common-lib/logging.cpp
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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
@@ -73,8 +73,8 @@ Q_CORE_EXPORT void qWinMsgHandler(QtMsgType t, const char* str);
QT_BEGIN_NAMESPACE_AM
#if defined(QT_GENIVIEXTRAS_LIB)
-static const char *s_defaultSystemUiDltId = "LXAM";
-static const char *s_defaultSystemUiDltDescription = "Luxoft Application-Manager";
+static const char *s_defaultSystemUiDltId = "QTAM";
+static const char *s_defaultSystemUiDltDescription = "Qt Application Manager";
#endif
/*
diff --git a/src/common-lib/logging.h b/src/common-lib/logging.h
index 7671a6cb..51b64909 100644
--- a/src/common-lib/logging.h
+++ b/src/common-lib/logging.h
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/src/common-lib/processtitle.cpp b/src/common-lib/processtitle.cpp
index c65cdb8f..e2b9401e 100644
--- a/src/common-lib/processtitle.cpp
+++ b/src/common-lib/processtitle.cpp
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/src/common-lib/processtitle.h b/src/common-lib/processtitle.h
index cecbc150..90c83af5 100644
--- a/src/common-lib/processtitle.h
+++ b/src/common-lib/processtitle.h
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/src/common-lib/qml-utilities.cpp b/src/common-lib/qml-utilities.cpp
index 7cf29393..f3d43965 100644
--- a/src/common-lib/qml-utilities.cpp
+++ b/src/common-lib/qml-utilities.cpp
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/src/common-lib/qml-utilities.h b/src/common-lib/qml-utilities.h
index 9c9f125d..e13a1f10 100644
--- a/src/common-lib/qml-utilities.h
+++ b/src/common-lib/qml-utilities.h
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/src/common-lib/qtyaml.cpp b/src/common-lib/qtyaml.cpp
index fbb75f50..c840550e 100644
--- a/src/common-lib/qtyaml.cpp
+++ b/src/common-lib/qtyaml.cpp
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/src/common-lib/qtyaml.h b/src/common-lib/qtyaml.h
index 11edb200..2130fae7 100644
--- a/src/common-lib/qtyaml.h
+++ b/src/common-lib/qtyaml.h
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/src/common-lib/startuptimer.cpp b/src/common-lib/startuptimer.cpp
index 861df663..f007166b 100644
--- a/src/common-lib/startuptimer.cpp
+++ b/src/common-lib/startuptimer.cpp
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/src/common-lib/startuptimer.h b/src/common-lib/startuptimer.h
index ab2ead55..89f9282e 100644
--- a/src/common-lib/startuptimer.h
+++ b/src/common-lib/startuptimer.h
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/src/common-lib/unixsignalhandler.cpp b/src/common-lib/unixsignalhandler.cpp
index 897a3103..cd51fae3 100644
--- a/src/common-lib/unixsignalhandler.cpp
+++ b/src/common-lib/unixsignalhandler.cpp
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/src/common-lib/unixsignalhandler.h b/src/common-lib/unixsignalhandler.h
index da2fd0d5..f1de44f1 100644
--- a/src/common-lib/unixsignalhandler.h
+++ b/src/common-lib/unixsignalhandler.h
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/src/common-lib/utilities.cpp b/src/common-lib/utilities.cpp
index b489fe56..392c78dd 100644
--- a/src/common-lib/utilities.cpp
+++ b/src/common-lib/utilities.cpp
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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
@@ -120,7 +120,7 @@ void checkYamlFormat(const QVector<QVariant> &docs, int numberOfDocuments,
}
if (numberOfDocuments < 0) {
- if (actualSize < numberOfDocuments) {
+ if (actualSize < -numberOfDocuments) {
throw Exception("wrong number of YAML documents: expected at least %1, got %2")
.arg(-numberOfDocuments).arg(actualSize);
}
@@ -131,7 +131,7 @@ void checkYamlFormat(const QVector<QVariant> &docs, int numberOfDocuments,
}
}
if (!formatTypes.contains(actualFormatType)) {
- throw Exception("wrong formatType header: expected %1, got %2")
+ throw Exception("wrong formatType header: expected '%1', got '%2'")
.arg(QString::fromUtf8(formatTypes.toList().join(", or ")), QString::fromUtf8(actualFormatType));
}
if (actualFormatVersion != formatVersion) {
diff --git a/src/common-lib/utilities.h b/src/common-lib/utilities.h
index 9910ce1c..ba8c7006 100644
--- a/src/common-lib/utilities.h
+++ b/src/common-lib/utilities.h
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/src/crypto-lib/cryptography.cpp b/src/crypto-lib/cryptography.cpp
index 17feaaa5..6e3fb327 100644
--- a/src/crypto-lib/cryptography.cpp
+++ b/src/crypto-lib/cryptography.cpp
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/src/crypto-lib/cryptography.h b/src/crypto-lib/cryptography.h
index e5b609b9..bc3c8a28 100644
--- a/src/crypto-lib/cryptography.h
+++ b/src/crypto-lib/cryptography.h
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/src/crypto-lib/libcryptofunction.cpp b/src/crypto-lib/libcryptofunction.cpp
index 943f9df0..362307cd 100644
--- a/src/crypto-lib/libcryptofunction.cpp
+++ b/src/crypto-lib/libcryptofunction.cpp
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/src/crypto-lib/libcryptofunction.h b/src/crypto-lib/libcryptofunction.h
index 5e8ff057..d60537d5 100644
--- a/src/crypto-lib/libcryptofunction.h
+++ b/src/crypto-lib/libcryptofunction.h
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/src/crypto-lib/signature.cpp b/src/crypto-lib/signature.cpp
index 34b33e29..320f17b0 100644
--- a/src/crypto-lib/signature.cpp
+++ b/src/crypto-lib/signature.cpp
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/src/crypto-lib/signature.h b/src/crypto-lib/signature.h
index 3b4dbd87..2e26d81c 100644
--- a/src/crypto-lib/signature.h
+++ b/src/crypto-lib/signature.h
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/src/crypto-lib/signature_macos.cpp b/src/crypto-lib/signature_macos.cpp
index fd565cd2..824474fc 100644
--- a/src/crypto-lib/signature_macos.cpp
+++ b/src/crypto-lib/signature_macos.cpp
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/src/crypto-lib/signature_openssl.cpp b/src/crypto-lib/signature_openssl.cpp
index 7fa38d54..27b999a9 100644
--- a/src/crypto-lib/signature_openssl.cpp
+++ b/src/crypto-lib/signature_openssl.cpp
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/src/crypto-lib/signature_p.h b/src/crypto-lib/signature_p.h
index e16896dc..1a8bee96 100644
--- a/src/crypto-lib/signature_p.h
+++ b/src/crypto-lib/signature_p.h
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/src/crypto-lib/signature_win.cpp b/src/crypto-lib/signature_win.cpp
index 1e05c013..31cc5fc3 100644
--- a/src/crypto-lib/signature_win.cpp
+++ b/src/crypto-lib/signature_win.cpp
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/src/dbus-lib/abstractdbuscontextadaptor.cpp b/src/dbus-lib/abstractdbuscontextadaptor.cpp
index 0716b3e4..aee9a521 100644
--- a/src/dbus-lib/abstractdbuscontextadaptor.cpp
+++ b/src/dbus-lib/abstractdbuscontextadaptor.cpp
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/src/dbus-lib/abstractdbuscontextadaptor.h b/src/dbus-lib/abstractdbuscontextadaptor.h
index 683dc04f..4753e636 100644
--- a/src/dbus-lib/abstractdbuscontextadaptor.h
+++ b/src/dbus-lib/abstractdbuscontextadaptor.h
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/src/dbus-lib/applicationinstallerdbuscontextadaptor.cpp b/src/dbus-lib/applicationinstallerdbuscontextadaptor.cpp
deleted file mode 100644
index de5097cd..00000000
--- a/src/dbus-lib/applicationinstallerdbuscontextadaptor.cpp
+++ /dev/null
@@ -1,204 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2019 Luxoft Sweden AB
-** Copyright (C) 2018 Pelagicore AG
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the Luxoft Application Manager.
-**
-** $QT_BEGIN_LICENSE:LGPL-QTAS$
-** Commercial License Usage
-** Licensees holding valid commercial Qt Automotive Suite licenses may use
-** this file in accordance with the commercial license agreement provided
-** with the Software or, alternatively, in accordance with the terms
-** contained in a written agreement between you and The Qt Company. For
-** licensing terms and conditions see https://www.qt.io/terms-conditions.
-** For further information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-** SPDX-License-Identifier: LGPL-3.0
-**
-****************************************************************************/
-
-#include "applicationinstallerdbuscontextadaptor.h"
-#include "applicationinstaller.h"
-#include "io.qt.applicationinstaller_adaptor.h"
-#include "dbuspolicy.h"
-#include "exception.h"
-#include "logging.h"
-
-
-QT_BEGIN_NAMESPACE_AM
-
-static QString taskStateToString(AsynchronousTask::TaskState state)
-{
- const char *cstr = QMetaEnum::fromType<AsynchronousTask::TaskState>().valueToKey(state);
- return QString::fromUtf8(cstr);
-}
-
-ApplicationInstallerDBusContextAdaptor::ApplicationInstallerDBusContextAdaptor(ApplicationInstaller *ai)
- : AbstractDBusContextAdaptor(ai)
-{
- m_adaptor = new ApplicationInstallerAdaptor(this);
-}
-
-QT_END_NAMESPACE_AM
-
-/////////////////////////////////////////////////////////////////////////////////////
-
-QT_USE_NAMESPACE_AM
-
-ApplicationInstallerAdaptor::ApplicationInstallerAdaptor(QObject *parent)
- : QDBusAbstractAdaptor(parent)
-{
- auto ai = ApplicationInstaller::instance();
-
- connect(ai, &ApplicationInstaller::taskBlockingUntilInstallationAcknowledge,
- this, &ApplicationInstallerAdaptor::taskBlockingUntilInstallationAcknowledge);
- connect(ai, &ApplicationInstaller::taskFailed,
- this, &ApplicationInstallerAdaptor::taskFailed);
- connect(ai, &ApplicationInstaller::taskFinished,
- this, &ApplicationInstallerAdaptor::taskFinished);
- connect(ai, &ApplicationInstaller::taskProgressChanged,
- this, &ApplicationInstallerAdaptor::taskProgressChanged);
- connect(ai, &ApplicationInstaller::taskRequestingInstallationAcknowledge,
- this, &ApplicationInstallerAdaptor::taskRequestingInstallationAcknowledge);
- connect(ai, &ApplicationInstaller::taskStarted,
- this, &ApplicationInstallerAdaptor::taskStarted);
- connect(ai, &ApplicationInstaller::taskStateChanged,
- [this](const QString &taskId, AsynchronousTask::TaskState newState) {
- emit taskStateChanged(taskId, taskStateToString(newState));
- });
-}
-
-ApplicationInstallerAdaptor::~ApplicationInstallerAdaptor()
-{ }
-
-bool ApplicationInstallerAdaptor::allowInstallationOfUnsignedPackages() const
-{
- return ApplicationInstaller::instance()->allowInstallationOfUnsignedPackages();
-}
-
-bool ApplicationInstallerAdaptor::applicationUserIdSeparation() const
-{
- return ApplicationInstaller::instance()->isApplicationUserIdSeparationEnabled();
-}
-
-uint ApplicationInstallerAdaptor::commonApplicationGroupId() const
-{
- return ApplicationInstaller::instance()->commonApplicationGroupId();
-}
-
-bool ApplicationInstallerAdaptor::developmentMode() const
-{
- return ApplicationInstaller::instance()->developmentMode();
-}
-
-void ApplicationInstallerAdaptor::acknowledgePackageInstallation(const QString &taskId)
-{
- AM_AUTHENTICATE_DBUS(void)
- return ApplicationInstaller::instance()->acknowledgePackageInstallation(taskId);
-}
-
-bool ApplicationInstallerAdaptor::cancelTask(const QString &taskId)
-{
- AM_AUTHENTICATE_DBUS(bool)
- return ApplicationInstaller::instance()->cancelTask(taskId);
-}
-
-int ApplicationInstallerAdaptor::compareVersions(const QString &version1, const QString &version2)
-{
- AM_AUTHENTICATE_DBUS(int)
- return ApplicationInstaller::instance()->compareVersions(version1, version2);
-}
-
-QVariantMap ApplicationInstallerAdaptor::getInstallationLocation(const QString &installationLocationId)
-{
- AM_AUTHENTICATE_DBUS(QVariantMap)
- return ApplicationInstaller::instance()->getInstallationLocation(installationLocationId);
-}
-
-QString ApplicationInstallerAdaptor::installationLocationIdFromApplication(const QString &id)
-{
- AM_AUTHENTICATE_DBUS(QString)
- return ApplicationInstaller::instance()->installationLocationIdFromApplication(id);
-}
-
-QStringList ApplicationInstallerAdaptor::installationLocationIds()
-{
- AM_AUTHENTICATE_DBUS(QStringList)
- return ApplicationInstaller::instance()->installationLocationIds();
-}
-
-qlonglong ApplicationInstallerAdaptor::installedApplicationSize(const QString &id)
-{
- AM_AUTHENTICATE_DBUS(qlonglong)
- return ApplicationInstaller::instance()->installedApplicationSize(id);
-}
-
-QVariantMap ApplicationInstallerAdaptor::installedApplicationExtraMetaData(const QString &id)
-{
- AM_AUTHENTICATE_DBUS(QVariantMap)
- return ApplicationInstaller::instance()->installedApplicationExtraMetaData(id);
-}
-
-QVariantMap ApplicationInstallerAdaptor::installedApplicationExtraSignedMetaData(const QString &id)
-{
- AM_AUTHENTICATE_DBUS(QVariantMap)
- return ApplicationInstaller::instance()->installedApplicationExtraSignedMetaData(id);
-}
-
-QString ApplicationInstallerAdaptor::removePackage(const QString &id, bool keepDocuments)
-{
- return removePackage(id, keepDocuments, false);
-}
-
-QString ApplicationInstallerAdaptor::removePackage(const QString &id, bool keepDocuments, bool force)
-{
- AM_AUTHENTICATE_DBUS(QString)
- return ApplicationInstaller::instance()->removePackage(id, keepDocuments, force);
-}
-
-QString ApplicationInstallerAdaptor::startPackageInstallation(const QString &installationLocationId, const QString &sourceUrl)
-{
- AM_AUTHENTICATE_DBUS(QString)
- return ApplicationInstaller::instance()->startPackageInstallation(installationLocationId, sourceUrl);
-}
-
-QString ApplicationInstallerAdaptor::taskState(const QString &taskId)
-{
- AM_AUTHENTICATE_DBUS(QString)
- return taskStateToString(ApplicationInstaller::instance()->taskState(taskId));
-}
-
-QString ApplicationInstallerAdaptor::taskApplicationId(const QString &taskId)
-{
- AM_AUTHENTICATE_DBUS(QString)
- return ApplicationInstaller::instance()->taskApplicationId(taskId);
-}
-
-QStringList ApplicationInstallerAdaptor::activeTaskIds()
-{
- AM_AUTHENTICATE_DBUS(QStringList)
- return ApplicationInstaller::instance()->activeTaskIds();
-}
diff --git a/src/dbus-lib/applicationmanagerdbuscontextadaptor.cpp b/src/dbus-lib/applicationmanagerdbuscontextadaptor.cpp
index 3ca02d65..5794e79a 100644
--- a/src/dbus-lib/applicationmanagerdbuscontextadaptor.cpp
+++ b/src/dbus-lib/applicationmanagerdbuscontextadaptor.cpp
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/src/dbus-lib/applicationmanagerdbuscontextadaptor.h b/src/dbus-lib/applicationmanagerdbuscontextadaptor.h
index 073697cd..02a2a805 100644
--- a/src/dbus-lib/applicationmanagerdbuscontextadaptor.h
+++ b/src/dbus-lib/applicationmanagerdbuscontextadaptor.h
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/src/dbus-lib/dbus-lib.pro b/src/dbus-lib/dbus-lib.pro
index 567fb0f3..5635fdf0 100644
--- a/src/dbus-lib/dbus-lib.pro
+++ b/src/dbus-lib/dbus-lib.pro
@@ -32,10 +32,9 @@ ADAPTORS_XML = \
org.freedesktop.notifications.xml \
!disable-installer {
- QT *= appman_installer-private
- HEADERS += applicationinstallerdbuscontextadaptor.h
- SOURCES += applicationinstallerdbuscontextadaptor.cpp
- ADAPTORS_XML += io.qt.applicationinstaller.xml
+ HEADERS += packagemanagerdbuscontextadaptor.h
+ SOURCES += packagemanagerdbuscontextadaptor.cpp
+ ADAPTORS_XML += io.qt.packagemanager.xml
}
!headless{
@@ -46,7 +45,7 @@ ADAPTORS_XML = \
}
OTHER_FILES = \
- io.qt.applicationinstaller.xml \
+ io.qt.packagemanager.xml \
io.qt.applicationmanager.applicationinterface.xml \
io.qt.applicationmanager.runtimeinterface.xml \
io.qt.applicationmanager.intentinterface.xml \
@@ -59,8 +58,8 @@ qtPrepareTool(QDBUSCPP2XML, qdbuscpp2xml)
recreate-applicationmanager-dbus-xml.CONFIG = phony
recreate-applicationmanager-dbus-xml.commands = $$QDBUSCPP2XML -a $$PWD/../manager-lib/applicationmanager.h -o $$PWD/io.qt.applicationmanager.xml
-recreate-applicationinstaller-dbus-xml.CONFIG = phony
-recreate-applicationinstaller-dbus-xml.commands = $$QDBUSCPP2XML -a $$PWD/../installer-lib/applicationinstaller.h -o $$PWD/io.qt.applicationinstaller.xml
+recreate-packagemanager-dbus-xml.CONFIG = phony
+recreate-packagemanager-dbus-xml.commands = $$QDBUSCPP2XML -a $$PWD/../installer-lib/packagemanager.h -o $$PWD/io.qt.packagemanager.xml
recreate-windowmanager-dbus-xml.CONFIG = phony
recreate-windowmanager-dbus-xml.commands = $$QDBUSCPP2XML -a $$PWD/../manager/windowmanager.h -o $$PWD/io.qt.windowmanager.xml
@@ -70,7 +69,7 @@ recreate-dbus-xml.depends = recreate-applicationmanager-dbus-xml recreate-applic
QMAKE_EXTRA_TARGETS += \
recreate-dbus-xml \
recreate-applicationmanager-dbus-xml \
- recreate-applicationinstaller-dbus-xml \
+ recreate-packagemanager-dbus-xml \
recreate-windowmanager-dbus-xml \
load(qt_module)
diff --git a/src/dbus-lib/dbusdaemon.cpp b/src/dbus-lib/dbusdaemon.cpp
index 94533c3e..0e0117f7 100644
--- a/src/dbus-lib/dbusdaemon.cpp
+++ b/src/dbus-lib/dbusdaemon.cpp
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/src/dbus-lib/dbusdaemon.h b/src/dbus-lib/dbusdaemon.h
index 34569bc3..ca3fdd4b 100644
--- a/src/dbus-lib/dbusdaemon.h
+++ b/src/dbus-lib/dbusdaemon.h
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/src/dbus-lib/dbuspolicy.cpp b/src/dbus-lib/dbuspolicy.cpp
index bf1a66b5..ef6214f6 100644
--- a/src/dbus-lib/dbuspolicy.cpp
+++ b/src/dbus-lib/dbuspolicy.cpp
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/src/dbus-lib/dbuspolicy.h b/src/dbus-lib/dbuspolicy.h
index fcdeed9c..e32c03d4 100644
--- a/src/dbus-lib/dbuspolicy.h
+++ b/src/dbus-lib/dbuspolicy.h
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/src/dbus-lib/io.qt.applicationinstaller.xml b/src/dbus-lib/io.qt.packagemanager.xml
index 913ce760..37e41b9d 100644
--- a/src/dbus-lib/io.qt.applicationinstaller.xml
+++ b/src/dbus-lib/io.qt.packagemanager.xml
@@ -1,10 +1,16 @@
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
<node>
- <interface name="io.qt.ApplicationInstaller">
+ <interface name="io.qt.PackageManager">
<property name="allowInstallationOfUnsignedPackages" type="b" access="read"/>
<property name="developmentMode" type="b" access="read"/>
<property name="applicationUserIdSeparation" type="b" access="read"/>
<property name="commonApplicationGroupId" type="u" access="read"/>
+ <property name="installationLocation" type="v" access="read">
+ <annotation name="org.qtproject.QtDBus.QtTypeName" value="QVariantMap"/>
+ </property>
+ <property name="documentLocation" type="v" access="read">
+ <annotation name="org.qtproject.QtDBus.QtTypeName" value="QVariantMap"/>
+ </property>
<signal name="taskStarted">
<arg name="taskId" type="s" direction="out"/>
</signal>
@@ -26,7 +32,7 @@
</signal>
<signal name="taskRequestingInstallationAcknowledge">
<arg name="taskId" type="s" direction="out"/>
- <arg name="applicationAsVariantMap" type="a{sv}" direction="out"/>
+ <arg name="packageAsVariantMap" type="a{sv}" direction="out"/>
<annotation name="org.qtproject.QtDBus.QtTypeName.Out1" value="QVariantMap"/>
<arg name="packageExtraMetaData" type="a{sv}" direction="out"/>
<annotation name="org.qtproject.QtDBus.QtTypeName.Out2" value="QVariantMap"/>
@@ -36,21 +42,16 @@
<signal name="taskBlockingUntilInstallationAcknowledge">
<arg name="taskId" type="s" direction="out"/>
</signal>
- <method name="installationLocationIds">
+ <method name="packageIds">
<arg type="as" direction="out"/>
</method>
- <method name="installationLocationIdFromApplication">
- <arg type="s" direction="out"/>
- <arg name="id" type="s" direction="in"/>
- </method>
- <method name="getInstallationLocation">
+ <method name="get">
<arg type="a{sv}" direction="out"/>
<annotation name="org.qtproject.QtDBus.QtTypeName.Out0" value="QVariantMap"/>
- <arg name="installationLocationId" type="s" direction="in"/>
+ <arg name="id" type="s" direction="in"/>
</method>
<method name="startPackageInstallation">
<arg type="s" direction="out"/>
- <arg name="installationLocationId" type="s" direction="in"/>
<arg name="sourceUrl" type="s" direction="in"/>
</method>
<method name="acknowledgePackageInstallation">
@@ -71,7 +72,7 @@
<arg type="s" direction="out"/>
<arg name="taskId" type="s" direction="in"/>
</method>
- <method name="taskApplicationId">
+ <method name="taskPackageId">
<arg type="s" direction="out"/>
<arg name="taskId" type="s" direction="in"/>
</method>
@@ -87,16 +88,16 @@
<arg name="version1" type="s" direction="in"/>
<arg name="version2" type="s" direction="in"/>
</method>
- <method name="installedApplicationSize">
+ <method name="installedPackageSize">
<arg type="x" direction="out"/>
<arg name="id" type="s" direction="in"/>
</method>
- <method name="installedApplicationExtraMetaData">
+ <method name="installedPackageExtraMetaData">
<arg type="a{sv}" direction="out"/>
<annotation name="org.qtproject.QtDBus.QtTypeName.Out0" value="QVariantMap"/>
<arg name="id" type="s" direction="in"/>
</method>
- <method name="installedApplicationExtraSignedMetaData">
+ <method name="installedPackageExtraSignedMetaData">
<arg type="a{sv}" direction="out"/>
<annotation name="org.qtproject.QtDBus.QtTypeName.Out0" value="QVariantMap"/>
<arg name="id" type="s" direction="in"/>
diff --git a/src/dbus-lib/notificationmanagerdbuscontextadaptor.cpp b/src/dbus-lib/notificationmanagerdbuscontextadaptor.cpp
index eeaefaff..ed80d6a5 100644
--- a/src/dbus-lib/notificationmanagerdbuscontextadaptor.cpp
+++ b/src/dbus-lib/notificationmanagerdbuscontextadaptor.cpp
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/src/dbus-lib/notificationmanagerdbuscontextadaptor.h b/src/dbus-lib/notificationmanagerdbuscontextadaptor.h
index bcced38f..6f71bdbe 100644
--- a/src/dbus-lib/notificationmanagerdbuscontextadaptor.h
+++ b/src/dbus-lib/notificationmanagerdbuscontextadaptor.h
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/src/dbus-lib/packagemanagerdbuscontextadaptor.cpp b/src/dbus-lib/packagemanagerdbuscontextadaptor.cpp
new file mode 100644
index 00000000..b423389c
--- /dev/null
+++ b/src/dbus-lib/packagemanagerdbuscontextadaptor.cpp
@@ -0,0 +1,210 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 Luxoft Sweden AB
+** Copyright (C) 2018 Pelagicore AG
+** 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
+**
+****************************************************************************/
+
+#include "packagemanagerdbuscontextadaptor.h"
+#include "packagemanager.h"
+#include "io.qt.packagemanager_adaptor.h"
+#include "dbuspolicy.h"
+#include "exception.h"
+#include "logging.h"
+
+
+QT_BEGIN_NAMESPACE_AM
+
+static QString taskStateToString(AsynchronousTask::TaskState state)
+{
+ const char *cstr = QMetaEnum::fromType<AsynchronousTask::TaskState>().valueToKey(state);
+ return QString::fromUtf8(cstr);
+}
+
+PackageManagerDBusContextAdaptor::PackageManagerDBusContextAdaptor(PackageManager *pm)
+ : AbstractDBusContextAdaptor(pm)
+{
+ m_adaptor = new PackageManagerAdaptor(this);
+}
+
+QT_END_NAMESPACE_AM
+
+/////////////////////////////////////////////////////////////////////////////////////
+
+QT_USE_NAMESPACE_AM
+
+PackageManagerAdaptor::PackageManagerAdaptor(QObject *parent)
+ : QDBusAbstractAdaptor(parent)
+{
+ auto ai = PackageManager::instance();
+
+ connect(ai, &PackageManager::taskBlockingUntilInstallationAcknowledge,
+ this, &PackageManagerAdaptor::taskBlockingUntilInstallationAcknowledge);
+ connect(ai, &PackageManager::taskFailed,
+ this, &PackageManagerAdaptor::taskFailed);
+ connect(ai, &PackageManager::taskFinished,
+ this, &PackageManagerAdaptor::taskFinished);
+ connect(ai, &PackageManager::taskProgressChanged,
+ this, &PackageManagerAdaptor::taskProgressChanged);
+ connect(ai, &PackageManager::taskRequestingInstallationAcknowledge,
+ this, &PackageManagerAdaptor::taskRequestingInstallationAcknowledge);
+ connect(ai, &PackageManager::taskStarted,
+ this, &PackageManagerAdaptor::taskStarted);
+ connect(ai, &PackageManager::taskStateChanged,
+ [this](const QString &taskId, AsynchronousTask::TaskState newState) {
+ emit taskStateChanged(taskId, taskStateToString(newState));
+ });
+}
+
+PackageManagerAdaptor::~PackageManagerAdaptor()
+{ }
+
+bool PackageManagerAdaptor::allowInstallationOfUnsignedPackages() const
+{
+ return PackageManager::instance()->allowInstallationOfUnsignedPackages();
+}
+
+bool PackageManagerAdaptor::applicationUserIdSeparation() const
+{
+ return PackageManager::instance()->isApplicationUserIdSeparationEnabled();
+}
+
+uint PackageManagerAdaptor::commonApplicationGroupId() const
+{
+ return PackageManager::instance()->commonApplicationGroupId();
+}
+
+bool PackageManagerAdaptor::developmentMode() const
+{
+ return PackageManager::instance()->developmentMode();
+}
+
+QDBusVariant PackageManagerAdaptor::installationLocation() const
+{
+ return QDBusVariant(PackageManager::instance()->installationLocation());
+}
+
+QDBusVariant PackageManagerAdaptor::documentLocation() const
+{
+ return QDBusVariant(PackageManager::instance()->documentLocation());
+}
+
+void PackageManagerAdaptor::acknowledgePackageInstallation(const QString &taskId)
+{
+ AM_AUTHENTICATE_DBUS(void)
+ return PackageManager::instance()->acknowledgePackageInstallation(taskId);
+}
+
+bool PackageManagerAdaptor::cancelTask(const QString &taskId)
+{
+ AM_AUTHENTICATE_DBUS(bool)
+ return PackageManager::instance()->cancelTask(taskId);
+}
+
+int PackageManagerAdaptor::compareVersions(const QString &version1, const QString &version2)
+{
+ AM_AUTHENTICATE_DBUS(int)
+ return PackageManager::instance()->compareVersions(version1, version2);
+}
+
+QStringList PackageManagerAdaptor::packageIds()
+{
+ AM_AUTHENTICATE_DBUS(QStringList)
+ return PackageManager::instance()->packageIds();
+}
+
+QVariantMap PackageManagerAdaptor::get(const QString &id)
+{
+ AM_AUTHENTICATE_DBUS(QVariantMap)
+ auto map = PackageManager::instance()->get(id);
+ map.remove(qSL("package")); // cannot marshall QObject *
+ return map;
+}
+
+qlonglong PackageManagerAdaptor::installedPackageSize(const QString &packageId)
+{
+ AM_AUTHENTICATE_DBUS(qlonglong)
+ return PackageManager::instance()->installedPackageSize(packageId);
+}
+
+QVariantMap PackageManagerAdaptor::installedPackageExtraMetaData(const QString &packageId)
+{
+ AM_AUTHENTICATE_DBUS(QVariantMap)
+ return PackageManager::instance()->installedPackageExtraMetaData(packageId);
+}
+
+QVariantMap PackageManagerAdaptor::installedPackageExtraSignedMetaData(const QString &packageId)
+{
+ AM_AUTHENTICATE_DBUS(QVariantMap)
+ return PackageManager::instance()->installedPackageExtraSignedMetaData(packageId);
+}
+
+QString PackageManagerAdaptor::removePackage(const QString &packageId, bool keepDocuments)
+{
+ return removePackage(packageId, keepDocuments, false);
+}
+
+QString PackageManagerAdaptor::removePackage(const QString &packageId, bool keepDocuments, bool force)
+{
+ AM_AUTHENTICATE_DBUS(QString)
+ return PackageManager::instance()->removePackage(packageId, keepDocuments, force);
+}
+
+QString PackageManagerAdaptor::startPackageInstallation(const QString &sourceUrl)
+{
+ AM_AUTHENTICATE_DBUS(QString)
+ return PackageManager::instance()->startPackageInstallation(sourceUrl);
+}
+
+QString PackageManagerAdaptor::taskState(const QString &taskId)
+{
+ AM_AUTHENTICATE_DBUS(QString)
+ return taskStateToString(PackageManager::instance()->taskState(taskId));
+}
+
+QString PackageManagerAdaptor::taskPackageId(const QString &taskId)
+{
+ AM_AUTHENTICATE_DBUS(QString)
+ return PackageManager::instance()->taskPackageId(taskId);
+}
+
+QStringList PackageManagerAdaptor::activeTaskIds()
+{
+ AM_AUTHENTICATE_DBUS(QStringList)
+ return PackageManager::instance()->activeTaskIds();
+}
diff --git a/src/dbus-lib/applicationinstallerdbuscontextadaptor.h b/src/dbus-lib/packagemanagerdbuscontextadaptor.h
index 98cac67d..8eb30e88 100644
--- a/src/dbus-lib/applicationinstallerdbuscontextadaptor.h
+++ b/src/dbus-lib/packagemanagerdbuscontextadaptor.h
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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
@@ -46,12 +46,12 @@
QT_BEGIN_NAMESPACE_AM
-class ApplicationInstaller;
+class PackageManager;
-class ApplicationInstallerDBusContextAdaptor : public AbstractDBusContextAdaptor
+class PackageManagerDBusContextAdaptor : public AbstractDBusContextAdaptor
{
public:
- explicit ApplicationInstallerDBusContextAdaptor(ApplicationInstaller *am);
+ explicit PackageManagerDBusContextAdaptor(PackageManager *pm);
};
QT_END_NAMESPACE_AM
diff --git a/src/dbus-lib/windowmanagerdbuscontextadaptor.cpp b/src/dbus-lib/windowmanagerdbuscontextadaptor.cpp
index cf18f049..b6b1b5a2 100644
--- a/src/dbus-lib/windowmanagerdbuscontextadaptor.cpp
+++ b/src/dbus-lib/windowmanagerdbuscontextadaptor.cpp
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/src/dbus-lib/windowmanagerdbuscontextadaptor.h b/src/dbus-lib/windowmanagerdbuscontextadaptor.h
index 8d749a3d..a78907bc 100644
--- a/src/dbus-lib/windowmanagerdbuscontextadaptor.h
+++ b/src/dbus-lib/windowmanagerdbuscontextadaptor.h
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/src/installer-lib/applicationinstaller.cpp b/src/installer-lib/applicationinstaller.cpp
deleted file mode 100644
index 10fae7ca..00000000
--- a/src/installer-lib/applicationinstaller.cpp
+++ /dev/null
@@ -1,1042 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2019 Luxoft Sweden AB
-** Copyright (C) 2018 Pelagicore AG
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the Luxoft Application Manager.
-**
-** $QT_BEGIN_LICENSE:LGPL-QTAS$
-** Commercial License Usage
-** Licensees holding valid commercial Qt Automotive Suite licenses may use
-** this file in accordance with the commercial license agreement provided
-** with the Software or, alternatively, in accordance with the terms
-** contained in a written agreement between you and The Qt Company. For
-** licensing terms and conditions see https://www.qt.io/terms-conditions.
-** For further information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-** SPDX-License-Identifier: LGPL-3.0
-**
-****************************************************************************/
-
-#include <QCoreApplication>
-#include <QDir>
-#include <QUuid>
-
-#include "logging.h"
-#include "application.h"
-#include "applicationinstaller.h"
-#include "applicationinstaller_p.h"
-#include "installationtask.h"
-#include "deinstallationtask.h"
-#include "sudo.h"
-#include "utilities.h"
-#include "exception.h"
-#include "global.h"
-#include "qml-utilities.h"
-#include "applicationmanager.h"
-
-
-/*!
- \qmltype ApplicationInstaller
- \inqmlmodule QtApplicationManager.SystemUI
- \ingroup system-ui-singletons
- \brief The package installation/removal/update part of the application-manager.
-
- The ApplicationInstaller singleton type handles the package installation
- part of the application manager. It provides both a DBus and QML APIs for
- all of its functionality.
-
- \note The ApplicationInstaller singleton and its corresponding DBus API are only available if you
- specify a base directory for installed application manifests. See \l{Configuration} for details.
-
- \target TaskStates
-
- The following table describes all possible states that a background task could be in:
-
- \table
- \header
- \li Task State
- \li Description
- \row
- \li \c Queued
- \li The task was created and is now queued up for execution.
- \row
- \li \c Executing
- \li The task is being executed.
- \row
- \li \c Finished
- \li The task was executed successfully.
- \row
- \li \c Failed
- \li The task failed to execute successfully.
- \row
- \li \c AwaitingAcknowledge
- \li \e{Installation tasks only!} The task is currently halted, waiting for either
- acknowledgePackageInstallation() or cancelTask() to continue. See startPackageInstallation()
- for more information on the installation workflow.
- \row
- \li \c Installing
- \li \e{Installation tasks only!} The installation was acknowledged via acknowledgePackageInstallation()
- and the final installation phase is now running.
- \row
- \li \c CleaningUp
- \li \e{Installation tasks only!} The installation has finished, and previous installations as
- well as temporary files are being cleaned up.
- \endtable
-
- The normal workflow for tasks is: \c Queued \unicode{0x2192} \c Executing \unicode{0x2192} \c
- Finished. The task can enter the \c Failed state at any point though - either by being canceled via
- cancelTask() or simply by failing due to an error.
-
- Installation tasks are a bit more complex due to the acknowledgment: \c Queued \unicode{0x2192}
- \c Executing \unicode{0x2192} \c AwaitingAcknowledge (this state may be skipped if
- acknowledgePackageInstallation() was called already) \unicode{0x2192} \c Installing
- \unicode{0x2192} \c Cleanup \unicode{0x2192} \c Finished. Again, the task can fail at any point.
-*/
-
-// THIS IS MISSING AN EXAMPLE!
-
-/*!
- \qmlsignal ApplicationInstaller::taskStateChanged(string taskId, string newState)
-
- This signal is emitted when the state of the task identified by \a taskId changes. The
- new state is supplied in the parameter \a newState.
-
- \sa taskState()
-*/
-
-/*!
- \qmlsignal ApplicationInstaller::taskStarted(string taskId)
-
- This signal is emitted when the task identified by \a taskId enters the \c Executing state.
-
- \sa taskStateChanged()
-*/
-
-/*!
- \qmlsignal ApplicationInstaller::taskFinished(string taskId)
-
- This signal is emitted when the task identified by \a taskId enters the \c Finished state.
-
- \sa taskStateChanged()
-*/
-
-/*!
- \qmlsignal ApplicationInstaller::taskFailed(string taskId)
-
- This signal is emitted when the task identified by \a taskId enters the \c Failed state.
-
- \sa taskStateChanged()
-*/
-
-/*!
- \qmlsignal ApplicationInstaller::taskRequestingInstallationAcknowledge(string taskId, object application, object packageExtraMetaData, object packageExtraSignedMetaData)
-
- This signal is emitted when the installation task identified by \a taskId has received enough
- meta-data to be able to emit this signal. The task may be in either \c Executing or \c
- AwaitingAcknowledge state.
-
- The contents of the package's manifest file are supplied via \a application as a JavaScript object.
- Please see the \l {ApplicationManager Roles}{role names} for the expected object fields.
-
- In addition, the package's extra meta-data (signed and unsinged) is also supplied via \a
- packageExtraMetaData and \a packageExtraSignedMetaData respectively as JavaScript objects.
- Both these objects are optional and need to be explicitly either populated during an
- application's packaging step or added by an intermediary app-store server.
- By default, both will just be empty.
-
- Following this signal, either cancelTask() or acknowledgePackageInstallation() has to be called
- for this \a taskId, to either cancel the installation or try to complete it.
-
- The ApplicationInstaller has two convenience functions to help the System-UI with verifying the
- meta-data: compareVersions() and, in case you are using reverse-DNS notation for application-ids,
- validateDnsName().
-
- \sa taskStateChanged(), startPackageInstallation()
-*/
-
-/*!
- \qmlsignal ApplicationInstaller::taskBlockingUntilInstallationAcknowledge(string taskId)
-
- This signal is emitted when the installation task identified by \a taskId cannot continue
- due to a missing acknowledgePackageInstallation() call for the task.
-
- \sa taskStateChanged(), acknowledgePackageInstallation()
-*/
-
-/*!
- \qmlsignal ApplicationInstaller::taskProgressChanged(string taskId, qreal progress)
-
- This signal is emitted whenever the task identified by \a taskId makes progress towards its
- completion. The \a progress is reported as a floating-point number ranging from \c 0.0 to \c 1.0.
-
- \sa taskStateChanged()
-*/
-
-QT_BEGIN_NAMESPACE_AM
-
-ApplicationInstaller *ApplicationInstaller::s_instance = nullptr;
-
-ApplicationInstaller::ApplicationInstaller(const QVector<InstallationLocation> &installationLocations,
- QDir *manifestDir, const QString &hardwareId,
- QObject *parent)
- : QObject(parent)
- , d(new ApplicationInstallerPrivate())
-{
- d->installationLocations = installationLocations;
- d->manifestDir.reset(manifestDir);
- d->hardwareId = hardwareId;
-}
-
-ApplicationInstaller::~ApplicationInstaller()
-{
- delete d;
- s_instance = nullptr;
-}
-
-ApplicationInstaller *ApplicationInstaller::createInstance(const QVector<InstallationLocation> &installationLocations,
- const QString &manifestDirPath,
- const QString &hardwareId, QString *error)
-{
- if (Q_UNLIKELY(s_instance))
- qFatal("ApplicationInstaller::createInstance() was called a second time.");
-
- qRegisterMetaType<AsynchronousTask *>();
- qRegisterMetaType<AsynchronousTask::TaskState>();
-
- QScopedPointer<QDir> manifestDir(new QDir(manifestDirPath));
-
- if (Q_UNLIKELY(!manifestDir->exists())) {
- if (error)
- *error = qL1S("ApplicationInstaller::createInstance() could not access the manifest directory ") + manifestDir->absolutePath();
- return nullptr;
- }
-
- qmlRegisterSingletonType<ApplicationInstaller>("QtApplicationManager.SystemUI", 2, 0, "ApplicationInstaller",
- &ApplicationInstaller::instanceForQml);
-
- return s_instance = new ApplicationInstaller(installationLocations, manifestDir.take(),
- hardwareId, QCoreApplication::instance());
-}
-
-ApplicationInstaller *ApplicationInstaller::instance()
-{
- if (!s_instance)
- qFatal("ApplicationInstaller::instance() was called before createInstance().");
- return s_instance;
-}
-
-QObject *ApplicationInstaller::instanceForQml(QQmlEngine *, QJSEngine *)
-{
- QQmlEngine::setObjectOwnership(instance(), QQmlEngine::CppOwnership);
- return instance();
-}
-
-bool ApplicationInstaller::developmentMode() const
-{
- return d->developmentMode;
-}
-
-void ApplicationInstaller::setDevelopmentMode(bool b)
-{
- d->developmentMode = b;
-}
-
-bool ApplicationInstaller::allowInstallationOfUnsignedPackages() const
-{
- return d->allowInstallationOfUnsignedPackages;
-}
-
-void ApplicationInstaller::setAllowInstallationOfUnsignedPackages(bool b)
-{
- d->allowInstallationOfUnsignedPackages = b;
-}
-
-QString ApplicationInstaller::hardwareId() const
-{
- return d->hardwareId;
-}
-
-bool ApplicationInstaller::isApplicationUserIdSeparationEnabled() const
-{
- return d->userIdSeparation;
-}
-
-uint ApplicationInstaller::commonApplicationGroupId() const
-{
- return d->commonGroupId;
-}
-
-bool ApplicationInstaller::enableApplicationUserIdSeparation(uint minUserId, uint maxUserId, uint commonGroupId)
-{
- if (minUserId >= maxUserId || minUserId == uint(-1) || maxUserId == uint(-1))
- return false;
- d->userIdSeparation = true;
- d->minUserId = minUserId;
- d->maxUserId = maxUserId;
- d->commonGroupId = commonGroupId;
- return true;
-}
-
-uint ApplicationInstaller::findUnusedUserId() const Q_DECL_NOEXCEPT_EXPR(false)
-{
- if (!isApplicationUserIdSeparationEnabled())
- return uint(-1);
-
- QVector<AbstractApplication *> apps = ApplicationManager::instance()->applications();
-
- for (uint uid = d->minUserId; uid <= d->maxUserId; ++uid) {
- bool match = false;
- for (AbstractApplication *app : qAsConst(apps)) {
- if (app->nonAliasedInfo()->uid() == uid) {
- match = true;
- break;
- }
- }
- if (!match)
- return uid;
- }
- throw Exception("could not find a free user-id for application separation in the range %1 to %2")
- .arg(d->minUserId).arg(d->maxUserId);
-}
-
-const QDir *ApplicationInstaller::manifestDirectory() const
-{
- return d->manifestDir.get();
-}
-
-QList<QByteArray> ApplicationInstaller::caCertificates() const
-{
- return d->chainOfTrust;
-}
-
-void ApplicationInstaller::setCACertificates(const QList<QByteArray> &chainOfTrust)
-{
- d->chainOfTrust = chainOfTrust;
-}
-
-void ApplicationInstaller::cleanupBrokenInstallations() const Q_DECL_NOEXCEPT_EXPR(false)
-{
- // Check that everything in the app-db is available
- // -> if not, remove from app-db
-
- ApplicationManager *am = ApplicationManager::instance();
-
- // key: baseDirPath, value: subDirName/ or fileName
- QMultiMap<QString, QString> validPaths {
- { manifestDirectory()->absolutePath(), QString() }
- };
- for (const InstallationLocation &il : qAsConst(d->installationLocations)) {
- validPaths.insert(il.documentPath(), QString());
- validPaths.insert(il.installationPath(), QString());
- }
-
- const auto allApps = am->applications();
- for (AbstractApplication *app : allApps) {
- const InstallationReport *ir = app->nonAliasedInfo()->installationReport();
- if (ir) {
- const InstallationLocation &il = installationLocationFromId(ir->installationLocationId());
-
- bool valid = il.isValid();
-
- if (!valid)
- qCDebug(LogInstaller) << "cleanup: uninstalling" << app->id() << "- installationLocation is invalid";
-
- if (valid) {
- QStringList checkDirs;
- QStringList checkFiles;
-
- checkDirs << manifestDirectory()->absoluteFilePath(app->id());
- checkFiles << manifestDirectory()->absoluteFilePath(app->id()) + qSL("/info.yaml");
- checkFiles << manifestDirectory()->absoluteFilePath(app->id()) + qSL("/installation-report.yaml");
- checkDirs << il.documentPath() + app->id();
- checkDirs << il.installationPath() + app->id();
-
- for (const QString &checkFile : qAsConst(checkFiles)) {
- QFileInfo fi(checkFile);
- if (!fi.exists() || !fi.isFile() || !fi.isReadable()) {
- valid = false;
- qCDebug(LogInstaller) << "cleanup: uninstalling" << app->id() << "- file missing:" << checkFile;
- break;
- }
- }
- for (const QString &checkDir : checkDirs) {
- QFileInfo fi(checkDir);
- if (!fi.exists() || !fi.isDir() || !fi.isReadable()) {
- valid = false;
- qCDebug(LogInstaller) << "cleanup: uninstalling" << app->id() << "- directory missing:" << checkDir;
- break;
- }
- }
-
- if (valid) {
- validPaths.insertMulti(il.installationPath(), app->id() + qL1C('/'));
- validPaths.insertMulti(il.documentPath(), app->id() + qL1C('/'));
- validPaths.insertMulti(manifestDirectory()->absolutePath(), app->id() + qL1C('/'));
- }
- }
- if (!valid) {
- if (am->startingApplicationRemoval(app->id())) {
- if (am->finishedApplicationInstall(app->id()))
- continue;
- }
- throw Exception(Error::Package, "could not remove broken installation of app %1 from database").arg(app->id());
- }
- }
- }
-
- // Remove everything that is not referenced from the app-db
-
- for (auto it = validPaths.cbegin(); it != validPaths.cend(); ) {
- const QString currentDir = it.key();
-
- // collect all values for the unique key currentDir
- QVector<QString> validNames;
- for ( ; it != validPaths.cend() && it.key() == currentDir; ++it)
- validNames << it.value();
-
- const QFileInfoList &dirEntries = QDir(currentDir).entryInfoList(QDir::AllEntries | QDir::NoDotAndDotDot);
-
- // check if there is anything in the filesystem that is NOT listed in the validNames
- for (const QFileInfo &fi : dirEntries) {
- QString name = fi.fileName();
- if (fi.isDir())
- name.append(qL1C('/'));
-
- if ((!fi.isDir() && !fi.isFile()) || !validNames.contains(name)) {
- qCDebug(LogInstaller) << "cleanup: removing unreferenced inode" << name;
-
- if (SudoClient::instance()) {
- if (!SudoClient::instance()->removeRecursive(fi.absoluteFilePath()))
- throw Exception(Error::IO, "could not remove broken installation leftover %1 : %2").arg(fi.absoluteFilePath()).arg(SudoClient::instance()->lastError());
- } else {
- if (!recursiveOperation(fi.absoluteFilePath(), safeRemove))
- throw Exception(Error::IO, "could not remove broken installation leftover %1 (maybe due to missing root privileges)").arg(fi.absoluteFilePath());
- }
- }
- }
- }
-}
-
-QVector<InstallationLocation> ApplicationInstaller::installationLocations() const
-{
- return d->installationLocations;
-}
-
-
-const InstallationLocation &ApplicationInstaller::defaultInstallationLocation() const
-{
- static bool once = false;
- static int defaultIndex = -1;
-
- if (!once) {
- for (int i = 0; i < d->installationLocations.size(); ++i) {
- if (d->installationLocations.at(i).isDefault()) {
- defaultIndex = i;
- break;
- }
- }
- once = true;
- }
- return (defaultIndex < 0) ? d->invalidInstallationLocation : d->installationLocations.at(defaultIndex);
-}
-
-const InstallationLocation &ApplicationInstaller::installationLocationFromId(const QString &installationLocationId) const
-{
- for (const InstallationLocation &il : d->installationLocations) {
- if (il.id() == installationLocationId)
- return il;
- }
- return d->invalidInstallationLocation;
-}
-
-const InstallationLocation &ApplicationInstaller::installationLocationFromApplication(const QString &id) const
-{
- if (AbstractApplication *a = ApplicationManager::instance()->fromId(id)) {
- if (const InstallationReport *report = a->nonAliasedInfo()->installationReport())
- return installationLocationFromId(report->installationLocationId());
- }
- return d->invalidInstallationLocation;
-}
-
-
-/*!
- \qmlmethod list<string> ApplicationInstaller::installationLocationIds()
-
- Retuns a list of all known installation location ids. Calling getInstallationLocation() on one of
- the returned identifiers will yield specific information about the individual installation locations.
-*/
-QStringList ApplicationInstaller::installationLocationIds() const
-{
- QStringList ids;
- ids.reserve(d->installationLocations.size());
- for (const InstallationLocation &il : d->installationLocations)
- ids << il.id();
- return ids;
-}
-
-/*!
- \qmlmethod string ApplicationInstaller::installationLocationIdFromApplication(string id)
-
- Returns the installation location id for the application identified by \a id. Returns
- an empty string in case the application is not installed.
-
- \sa installationLocationIds()
- */
-QString ApplicationInstaller::installationLocationIdFromApplication(const QString &id) const
-{
- const InstallationLocation &il = installationLocationFromApplication(id);
- return il.isValid() ? il.id() : QString();
-}
-
-/*!
- \qmlmethod object ApplicationInstaller::getInstallationLocation(string installationLocationId)
-
- Returns an object describing the installation location identified by \a installationLocationId in detail.
-
- The returned object has the following members:
-
- \table
- \header
- \li \c Name
- \li \c Type
- \li Description
- \row
- \li \c id
- \li \c string
- \li The installation location id that is used as the handle for all other ApplicationInstaller
- function calls. The \c id consists of the \c type and \c index field, concatenated by
- a single dash (for example, \c internal-0).
- \row
- \li \c type
- \li \c string
- \li The type of device this installation location is connected to. Valid values are \c
- internal (for any kind of built-in storage, e.g. flash), \c removable (for any kind of
- storage that is removable by the user, e.g. an SD card) and \c invalid.
- \row
- \li \c index
- \li \c int
- \li In case there is more than one installation location for the same type of device, this
- \c zero-based index is used for disambiguation. For example, two SD card slots will
- result in the ids \c removable-0 and \c removable-1. Otherwise, the index is always \c 0.
- \row
- \li \c isDefault
- \li \c bool
-
- \li Exactly one installation location is the default location which must be mounted and
- accessible at all times. This can be used by an UI application to get a sensible
- default for the installation location that it needs to pass to startPackageInstallation().
- \row
- \li \c isRemovable
- \li \c bool
- \li Indicates whether this installation location is on a removable media (for example, an SD
- card).
- \row
- \li \c isMounted
- \li \c bool
- \li The current mount status of this installation location: should always be \c true for
- non-removable media.
- \row
- \li \c installationPath
- \li \c string
- \li The absolute file-system path to the base directory under which applications are installed.
- \row
- \li \c installationDeviceSize
- \li \c int
- \li The size of the device holding \c installationPath in bytes. This field is only present if
- \c isMounted is \c true.
- \row
- \li \c installationDeviceFree
- \li \c int
- \li The amount of bytes available on the device holding \c installationPath. This field is only
- present if \c isMounted is \c true.
- \row
- \li \c documentPath
- \li \c string
- \li The absolute file-system path to the base directory under which per-user document
- directories are created.
- \row
- \li \c documentDeviceSize
- \li \c int
- \li The size of the device holding \c documentPath in bytes. This field is only present if
- \c isMounted is \c true.
- \row
- \li \c documentDeviceFree
- \li \c int
- \li The amount of bytes available on the device holding \c documentPath. This field is only
- present if \c isMounted is \c true.
- \endtable
-
- Returns an empty object in case the \a installationLocationId is not valid.
-*/
-QVariantMap ApplicationInstaller::getInstallationLocation(const QString &installationLocationId) const
-{
- const InstallationLocation &il = installationLocationFromId(installationLocationId);
- return il.isValid() ? il.toVariantMap() : QVariantMap();
-}
-
-/*!
- \qmlmethod int ApplicationInstaller::installedApplicationSize(string id)
-
- Returns the size in bytes that the application identified by \a id is occupying on the storage
- device.
-
- Returns \c -1 in case the application \a id is not valid, or the application is not installed.
-*/
-qint64 ApplicationInstaller::installedApplicationSize(const QString &id) const
-{
- if (AbstractApplication *a = ApplicationManager::instance()->fromId(id)) {
- if (const InstallationReport *report = a->nonAliasedInfo()->installationReport())
- return static_cast<qint64>(report->diskSpaceUsed());
- }
- return -1;
-}
-
-/*!
- \qmlmethod var ApplicationInstaller::installedApplicationExtraMetaData(string id)
-
- Returns a map of all extra metadata in the package header of the application identified by \a id.
-
- Returns an empty map in case the application \a id is not valid, or the application is not installed.
-*/
-QVariantMap ApplicationInstaller::installedApplicationExtraMetaData(const QString &id) const
-{
- if (AbstractApplication *a = ApplicationManager::instance()->fromId(id)) {
- if (const InstallationReport *report = a->nonAliasedInfo()->installationReport())
- return report->extraMetaData();
- }
- return QVariantMap();
-}
-
-/*!
- \qmlmethod var ApplicationInstaller::installedApplicationExtraSignedMetaData(string id)
-
- Returns a map of all signed extra metadata in the package header of the application identified
- by \a id.
-
- Returns an empty map in case the application \a id is not valid, or the application is not installed.
-*/
-QVariantMap ApplicationInstaller::installedApplicationExtraSignedMetaData(const QString &id) const
-{
- if (AbstractApplication *a = ApplicationManager::instance()->fromId(id)) {
- if (const InstallationReport *report = a->nonAliasedInfo()->installationReport())
- return report->extraSignedMetaData();
- }
- return QVariantMap();
-}
-
-/*! \internal
- Type safe convenience function, since DBus does not like QUrl
-*/
-QString ApplicationInstaller::startPackageInstallation(const QString &installationLocationId, const QUrl &sourceUrl)
-{
- AM_TRACE(LogInstaller, installationLocationId, sourceUrl);
-
- const InstallationLocation &il = installationLocationFromId(installationLocationId);
-
- return enqueueTask(new InstallationTask(il, sourceUrl));
-}
-
-/*!
- \qmlmethod string ApplicationInstaller::startPackageInstallation(string installationLocationId, string sourceUrl)
-
- Downloads an application package from \a sourceUrl and installs it to the installation location
- described by \a installationLocationId.
-
- The actual download and installation will happen asynchronously in the background. The
- ApplicationInstaller emits the signals \l taskStarted, \l taskProgressChanged, \l
- taskRequestingInstallationAcknowledge, \l taskFinished, \l taskFailed, and \l taskStateChanged
- for the returned taskId when applicable.
-
- \note Simply calling this function is not enough to complete a package installation: The
- taskRequestingInstallationAcknowledge() signal needs to be connected to a slot where the
- supplied application meta-data can be validated (either programmatically or by asking the user).
- If the validation is successful, the installation can be completed by calling
- acknowledgePackageInstallation() or, if the validation was unsuccessful, the installation should
- be canceled by calling cancelTask().
- Failing to do one or the other will leave an unfinished "zombie" installation.
-
- Returns a unique \c taskId. This can also be an empty string, if the task could not be
- created (in this case, no signals will be emitted).
-*/
-QString ApplicationInstaller::startPackageInstallation(const QString &installationLocationId, const QString &sourceUrl)
-{
- QUrl url(sourceUrl);
- if (url.scheme().isEmpty())
- url = QUrl::fromLocalFile(sourceUrl);
- return startPackageInstallation(installationLocationId, url);
-}
-
-/*!
- \qmlmethod void ApplicationInstaller::acknowledgePackageInstallation(string taskId)
-
- Calling this function enables the installer to complete the installation task identified by \a
- taskId. Normally, this function is called after receiving the taskRequestingInstallationAcknowledge()
- signal, and the user and/or the program logic decided to proceed with the installation.
-
- \sa startPackageInstallation()
- */
-void ApplicationInstaller::acknowledgePackageInstallation(const QString &taskId)
-{
- AM_TRACE(LogInstaller, taskId)
-
- const auto allTasks = d->allTasks();
-
- for (AsynchronousTask *task : allTasks) {
- if (qobject_cast<InstallationTask *>(task) && (task->id() == taskId)) {
- static_cast<InstallationTask *>(task)->acknowledge();
- break;
- }
- }
-}
-
-/*!
- \qmlmethod string ApplicationInstaller::removePackage(string id, bool keepDocuments, bool force)
-
- Uninstalls the application identified by \a id. Normally, the documents directory of the
- application is deleted on removal, but this can be prevented by setting \a keepDocuments to \c true.
-
- The actual removal will happen asynchronously in the background. The ApplicationInstaller will
- emit the signals \l taskStarted, \l taskProgressChanged, \l taskFinished, \l taskFailed and \l
- taskStateChanged for the returned \c taskId when applicable.
-
- Normally, \a force should only be set to \c true if a previous call to removePackage() failed.
- This may be necessary if the installation process was interrupted, or if an SD card got lost
- or has file-system issues.
-
- Returns a unique \c taskId. This can also be an empty string, if the task could not be created
- (in this case, no signals will be emitted).
-*/
-QString ApplicationInstaller::removePackage(const QString &id, bool keepDocuments, bool force)
-{
- AM_TRACE(LogInstaller, id, keepDocuments)
-
- if (AbstractApplication *a = ApplicationManager::instance()->fromId(id)) {
- if (const InstallationReport *report = a->nonAliasedInfo()->installationReport()) {
- const InstallationLocation &il = installationLocationFromId(report->installationLocationId());
-
- if (il.isValid() && (il.id() == report->installationLocationId()))
- return enqueueTask(new DeinstallationTask(a->nonAliasedInfo(), il, force, keepDocuments));
- }
- }
- return QString();
-}
-
-
-/*!
- \qmlmethod enumeration ApplicationInstaller::taskState(string taskId)
-
- Returns the current state of the installation task identified by \a taskId.
- \l {TaskStates}{See here} for a list of valid task states.
-
- Returns \c ApplicationInstaller.Invalid if the \a taskId is invalid.
-*/
-AsynchronousTask::TaskState ApplicationInstaller::taskState(const QString &taskId) const
-{
- const auto allTasks = d->allTasks();
-
- for (const AsynchronousTask *task : allTasks) {
- if (task && (task->id() == taskId))
- return task->state();
- }
- return AsynchronousTask::Invalid;
-}
-
-/*!
- \qmlmethod string ApplicationInstaller::taskApplicationId(string taskId)
-
- Returns the application id associated with the task identified by \a taskId. The task may not
- have a valid application id at all times though and in this case the function will return an
- empty string (this will be the case for installations before the taskRequestingInstallationAcknowledge
- signal has been emitted).
-
- Returns an empty string if the \a taskId is invalid.
-*/
-QString ApplicationInstaller::taskApplicationId(const QString &taskId) const
-{
- const auto allTasks = d->allTasks();
-
- for (const AsynchronousTask *task : allTasks) {
- if (task && (task->id() == taskId))
- return task->applicationId();
- }
- return QString();
-}
-
-/*!
- \qmlmethod list<string> ApplicationInstaller::activeTaskIds()
-
- Retuns a list of all currently active (as in not yet finished or failed) installation task ids.
-*/
-QStringList ApplicationInstaller::activeTaskIds() const
-{
- const auto allTasks = d->allTasks();
-
- QStringList result;
- for (const AsynchronousTask *task : allTasks)
- result << task->id();
- return result;
-}
-
-/*!
- \qmlmethod bool ApplicationInstaller::cancelTask(string taskId)
-
- Tries to cancel the installation task identified by \a taskId.
-
- Returns \c true if the task was canceled, \c false otherwise.
-*/
-bool ApplicationInstaller::cancelTask(const QString &taskId)
-{
- AM_TRACE(LogInstaller, taskId)
-
- // incoming tasks can be forcefully cancelled right away
- for (AsynchronousTask *task : qAsConst(d->incomingTaskList)) {
- if (task->id() == taskId) {
- task->forceCancel();
- task->deleteLater();
-
- handleFailure(task);
-
- d->incomingTaskList.removeOne(task);
- triggerExecuteNextTask();
- return true;
- }
- }
-
- // the active task and async tasks might be in a state where cancellation is not possible,
- // so we have to ask them nicely
- if (d->activeTask && d->activeTask->id() == taskId)
- return d->activeTask->cancel();
-
- for (AsynchronousTask *task : qAsConst(d->installationTaskList)) {
- if (task->id() == taskId)
- return task->cancel();
- }
- return false;
-}
-
-/*!
- \qmlmethod int ApplicationInstaller::compareVersions(string version1, string version2)
-
- Convenience method for app-store implementations or taskRequestingInstallationAcknowledge()
- callbacks for comparing version numbers, as the actual version comparison algorithm is not
- trivial.
-
- Returns \c -1, \c 0 or \c 1 if \a version1 is smaller than, equal to, or greater than \a
- version2 (similar to how \c strcmp() works).
-*/
-int ApplicationInstaller::compareVersions(const QString &version1, const QString &version2)
-{
- int pos1 = 0;
- int pos2 = 0;
- int len1 = version1.length();
- int len2 = version2.length();
-
- forever {
- if (pos1 == len1 && pos2 == len2)
- return 0;
- else if (pos1 >= len1)
- return -1;
- else if (pos2 >= len2)
- return +1;
-
- QString part1 = version1.mid(pos1++, 1);
- QString part2 = version2.mid(pos2++, 1);
-
- bool isDigit1 = part1.at(0).isDigit();
- bool isDigit2 = part2.at(0).isDigit();
-
- if (!isDigit1 || !isDigit2) {
- int cmp = part1.compare(part2);
- if (cmp)
- return (cmp > 0) ? 1 : -1;
- } else {
- while ((pos1 < len1) && version1.at(pos1).isDigit())
- part1.append(version1.at(pos1++));
- while ((pos2 < len2) && version2.at(pos2).isDigit())
- part2.append(version2.at(pos2++));
-
- int num1 = part1.toInt();
- int num2 = part2.toInt();
-
- if (num1 != num2)
- return (num1 > num2) ? 1 : -1;
- }
- }
-}
-
-/*!
- \qmlmethod int ApplicationInstaller::validateDnsName(string name, int minimalPartCount)
-
- Convenience method for app-store implementations or taskRequestingInstallationAcknowledge()
- callbacks for checking if the given \a name is a valid DNS (or reverse-DNS) name according to
- RFC 1035/1123. If the optional parameter \a minimalPartCount is specified, this function will
- also check if \a name contains at least this amount of parts/sub-domains.
-
- Returns \c true if the name is a valid DNS name or \c false otherwise.
-*/
-bool ApplicationInstaller::validateDnsName(const QString &name, int minimalPartCount)
-{
- try {
- // check if we have enough parts: e.g. "tld.company.app" would have 3 parts
- QStringList parts = name.split('.');
- if (parts.size() < minimalPartCount) {
- throw Exception(Error::Parse, "the minimum amount of parts (subdomains) is %1 (found %2)")
- .arg(minimalPartCount).arg(parts.size());
- }
-
- // standard RFC compliance tests (RFC 1035/1123)
-
- auto partCheck = [](const QString &part) {
- int len = part.length();
-
- if (len < 1 || len > 63)
- throw Exception(Error::Parse, "domain parts must consist of at least 1 and at most 63 characters (found %2 characters)").arg(len);
-
- for (int pos = 0; pos < len; ++pos) {
- ushort ch = part.at(pos).unicode();
- bool isFirst = (pos == 0);
- bool isLast = (pos == (len - 1));
- bool isDash = (ch == '-');
- bool isDigit = (ch >= '0' && ch <= '9');
- bool isLower = (ch >= 'a' && ch <= 'z');
-
- if ((isFirst || isLast || !isDash) && !isDigit && !isLower)
- throw Exception(Error::Parse, "domain parts must consist of only the characters '0-9', 'a-z', and '-' (which cannot be the first or last character)");
- }
- };
-
- for (const QString &part : parts)
- partCheck(part);
-
- return true;
- } catch (const Exception &e) {
- qCDebug(LogInstaller).noquote() << "validateDnsName failed:" << e.errorString();
- return false;
- }
-}
-
-QString ApplicationInstaller::enqueueTask(AsynchronousTask *task)
-{
- d->incomingTaskList.append(task);
- triggerExecuteNextTask();
- return task->id();
-}
-
-void ApplicationInstaller::triggerExecuteNextTask()
-{
- if (!QMetaObject::invokeMethod(this, "executeNextTask", Qt::QueuedConnection))
- qCCritical(LogSystem) << "ERROR: failed to invoke method checkQueue";
-}
-
-void ApplicationInstaller::executeNextTask()
-{
- if (d->activeTask || d->incomingTaskList.isEmpty())
- return;
-
- AsynchronousTask *task = d->incomingTaskList.takeFirst();
-
- if (task->hasFailed()) {
- task->setState(AsynchronousTask::Failed);
-
- handleFailure(task);
-
- task->deleteLater();
- triggerExecuteNextTask();
- return;
- }
-
- connect(task, &AsynchronousTask::started, this, [this, task]() {
- emit taskStarted(task->id());
- });
-
- connect(task, &AsynchronousTask::stateChanged, this, [this, task](AsynchronousTask::TaskState newState) {
- emit taskStateChanged(task->id(), newState);
- });
-
- connect(task, &AsynchronousTask::progress, this, [this, task](qreal p) {
- emit taskProgressChanged(task->id(), p);
- QMetaObject::invokeMethod(ApplicationManager::instance(),
- "progressingApplicationInstall",
- Qt::DirectConnection,
- Q_ARG(QString, task->applicationId()),
- Q_ARG(double, p));
- });
-
- connect(task, &AsynchronousTask::finished, this, [this, task]() {
- task->setState(task->hasFailed() ? AsynchronousTask::Failed : AsynchronousTask::Finished);
-
- if (task->hasFailed()) {
- handleFailure(task);
- } else {
- qCDebug(LogInstaller) << "emit finished" << task->id();
- emit taskFinished(task->id());
- }
-
- if (d->activeTask == task)
- d->activeTask = nullptr;
- d->installationTaskList.removeOne(task);
-
- delete task;
- triggerExecuteNextTask();
- });
-
- if (qobject_cast<InstallationTask *>(task)) {
- connect(static_cast<InstallationTask *>(task), &InstallationTask::finishedPackageExtraction, this, [this, task]() {
- qCDebug(LogInstaller) << "emit blockingUntilInstallationAcknowledge" << task->id();
- emit taskBlockingUntilInstallationAcknowledge(task->id());
-
- // we can now start the next download in parallel - the InstallationTask will take care
- // of serializing the final installation steps on its own as soon as it gets the
- // required acknowledge (or cancel).
- if (d->activeTask == task)
- d->activeTask = nullptr;
- d->installationTaskList.append(task);
- triggerExecuteNextTask();
- });
- }
-
-
- d->activeTask = task;
- task->setState(AsynchronousTask::Executing);
- task->start();
-}
-
-void ApplicationInstaller::handleFailure(AsynchronousTask *task)
-{
- qCDebug(LogInstaller) << "emit failed" << task->id() << task->errorCode() << task->errorString();
- emit taskFailed(task->id(), int(task->errorCode()), task->errorString());
-}
-
-
-bool removeRecursiveHelper(const QString &path)
-{
- if (ApplicationInstaller::instance()->isApplicationUserIdSeparationEnabled() && SudoClient::instance())
- return SudoClient::instance()->removeRecursive(path);
- else
- return recursiveOperation(path, safeRemove);
-}
-
-QT_END_NAMESPACE_AM
diff --git a/src/installer-lib/installationlocation.cpp b/src/installer-lib/installationlocation.cpp
deleted file mode 100644
index d87383f7..00000000
--- a/src/installer-lib/installationlocation.cpp
+++ /dev/null
@@ -1,229 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2019 Luxoft Sweden AB
-** Copyright (C) 2018 Pelagicore AG
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the Luxoft Application Manager.
-**
-** $QT_BEGIN_LICENSE:LGPL-QTAS$
-** Commercial License Usage
-** Licensees holding valid commercial Qt Automotive Suite licenses may use
-** this file in accordance with the commercial license agreement provided
-** with the Software or, alternatively, in accordance with the terms
-** contained in a written agreement between you and The Qt Company. For
-** licensing terms and conditions see https://www.qt.io/terms-conditions.
-** For further information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-** SPDX-License-Identifier: LGPL-3.0
-**
-****************************************************************************/
-
-#include <QDir>
-
-#include "installationlocation.h"
-#include "global.h"
-#include "utilities.h"
-#include "exception.h"
-
-#if defined(Q_OS_WIN)
-# include <windows.h>
-#else
-# include <sys/stat.h>
-# include <errno.h>
-# if defined(Q_OS_ANDROID)
-# include <sys/vfs.h>
-# define statvfs statfs
-# else
-# include <sys/statvfs.h>
-# endif
-#endif
-
-QT_BEGIN_NAMESPACE_AM
-
-static QString fixPath(const QString &path, const QString &hardwareId)
-{
- QString realPath = path;
- realPath.replace(qL1S("@HARDWARE-ID@"), hardwareId);
- QDir dir(realPath);
- return (dir.exists() ? dir.canonicalPath() : dir.absolutePath()) + qL1C('/');
-}
-
-static bool diskUsage(const QString &path, quint64 *bytesTotal, quint64 *bytesFree)
-{
- QString cpath = QFileInfo(path).canonicalPath();
-
-#if defined(Q_OS_WIN)
- return GetDiskFreeSpaceExW((LPCWSTR) cpath.utf16(), (ULARGE_INTEGER *) bytesFree,
- (ULARGE_INTEGER *) bytesTotal, nullptr);
-
-#else // Q_OS_UNIX
- int result;
- struct ::statvfs svfs;
-
- do {
- result = ::statvfs(cpath.toLocal8Bit(), &svfs);
- if (result == -1 && errno == EINTR)
- continue;
- } while (false);
-
- if (result == 0) {
- if (bytesTotal)
- *bytesTotal = quint64(svfs.f_frsize) * svfs.f_blocks;
- if (bytesFree)
- *bytesFree = quint64(svfs.f_frsize) * svfs.f_bavail;
- return true;
- }
- return false;
-#endif // Q_OS_WIN
-}
-
-
-bool InstallationLocation::operator==(const InstallationLocation &other) const
-{
- return (m_valid == other.m_valid)
- && (m_index == other.m_index)
- && (m_installationPath == other.m_installationPath)
- && (m_documentPath == other.m_documentPath);
-}
-
-QString InstallationLocation::id() const
-{
- QString name = m_valid ? qSL("internal") : qSL("invalid");
- if (m_valid)
- name = name + QLatin1Char('-') + QString::number(m_index);
- return name;
-}
-
-int InstallationLocation::index() const
-{
- return m_index;
-}
-
-bool InstallationLocation::isValid() const
-{
- return m_valid;
-}
-
-bool InstallationLocation::isDefault() const
-{
- return m_isDefault;
-}
-
-QString InstallationLocation::installationPath() const
-{
- return m_installationPath;
-}
-
-QString InstallationLocation::documentPath() const
-{
- return m_documentPath;
-}
-
-bool InstallationLocation::installationDeviceFreeSpace(quint64 *bytesTotal, quint64 *bytesFree) const
-{
- return diskUsage(installationPath(), bytesTotal, bytesFree);
-}
-
-bool InstallationLocation::documentDeviceFreeSpace(quint64 *bytesTotal, quint64 *bytesFree) const
-{
- return diskUsage(documentPath(), bytesTotal, bytesFree);
-}
-
-QVariantMap InstallationLocation::toVariantMap() const
-{
- QVariantMap map;
- map[qSL("id")] = id();
- map[qSL("type")] = m_valid ? qSL("internal") : qSL("invalid");
- map[qSL("index")] = index();
- map[qSL("installationPath")] = installationPath();
- map[qSL("documentPath")] = documentPath();
- map[qSL("isDefault")] = isDefault();
-
- quint64 total = 0, free = 0;
- installationDeviceFreeSpace(&total, &free);
-
- map[qSL("installationDeviceSize")] = total;
- map[qSL("installationDeviceFree")] = free;
-
- total = free = 0;
- documentDeviceFreeSpace(&total, &free);
-
- map[qSL("documentDeviceSize")] = total;
- map[qSL("documentDeviceFree")] = free;
-
- return map;
-}
-
-QVector<InstallationLocation> InstallationLocation::parseInstallationLocations(const QVariantList &list,
- const QString &hardwareId) Q_DECL_NOEXCEPT_EXPR(false)
-{
- QVector<InstallationLocation> locations;
- bool gotDefault = false;
-
- for (const QVariant &v : list) {
- QVariantMap map = v.toMap();
-
- QString id = map.value(qSL("id")).toString();
- QString instPath = map.value(qSL("installationPath")).toString();
- QString documentPath = map.value(qSL("documentPath")).toString();
- bool isDefault = map.value(qSL("isDefault")).toBool();
-
- if (isDefault) {
- if (!gotDefault)
- gotDefault = true;
- else
- throw Exception(Error::Parse, "multiple default installation locations defined");
- }
-
- QString type = id.section('-', 0, 0);
- bool ok = false;
- int index = id.section('-', 1).toInt(&ok);
-
- if ((type == qSL("internal")) && (index >= 0) && ok) {
- InstallationLocation il;
- il.m_valid = true;
- il.m_index = index;
- il.m_installationPath = fixPath(instPath, hardwareId);
- il.m_documentPath = fixPath(documentPath, hardwareId);
- il.m_isDefault = isDefault;
-
- if (!QDir::root().mkpath(instPath)) {
- throw Exception(Error::Parse, "the app directory %2 for the installation location %1 does not exist")
- .arg(id).arg(instPath);
- }
- if (!QDir::root().mkpath(documentPath)) {
- throw Exception(Error::Parse, "the doc directory %2 for the installation location %1 does not exist")
- .arg(id).arg(documentPath);
- }
-
- locations.append(il);
- } else {
- throw Exception(Error::Parse, "could not parse the installation location with id %1").arg(id);
- }
- }
- return locations;
-}
-
-QT_END_NAMESPACE_AM
diff --git a/src/installer-lib/installer-lib.pro b/src/installer-lib/installer-lib.pro
deleted file mode 100644
index c61ad7fd..00000000
--- a/src/installer-lib/installer-lib.pro
+++ /dev/null
@@ -1,40 +0,0 @@
-TEMPLATE = lib
-TARGET = QtAppManInstaller
-MODULE = appman_installer
-
-load(am-config)
-
-QT = core network qml
-QT_FOR_PRIVATE *= \
- appman_common-private \
- appman_crypto-private \
- appman_application-private \
- appman_package-private \
- appman_manager-private
-
-CONFIG *= static internal_module
-CONFIG -= create_cmake
-
-include($$SOURCE_DIR/3rdparty/libarchive.pri)
-include($$SOURCE_DIR/3rdparty/libz.pri)
-
-HEADERS += \
- installationlocation.h \
- asynchronoustask.h \
- deinstallationtask.h \
- installationtask.h \
- scopeutilities.h \
- applicationinstaller.h \
- applicationinstaller_p.h \
- sudo.h \
-
-SOURCES += \
- installationlocation.cpp \
- asynchronoustask.cpp \
- installationtask.cpp \
- deinstallationtask.cpp \
- scopeutilities.cpp \
- applicationinstaller.cpp \
- sudo.cpp \
-
-load(qt_module)
diff --git a/src/intent-client-lib/intentclient.cpp b/src/intent-client-lib/intentclient.cpp
index 0c5d5264..e88c7005 100644
--- a/src/intent-client-lib/intentclient.cpp
+++ b/src/intent-client-lib/intentclient.cpp
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/src/intent-client-lib/intentclient.h b/src/intent-client-lib/intentclient.h
index aa4ed95a..2ecccb31 100644
--- a/src/intent-client-lib/intentclient.h
+++ b/src/intent-client-lib/intentclient.h
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/src/intent-client-lib/intentclientrequest.cpp b/src/intent-client-lib/intentclientrequest.cpp
index bee28543..9c420e8c 100644
--- a/src/intent-client-lib/intentclientrequest.cpp
+++ b/src/intent-client-lib/intentclientrequest.cpp
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/src/intent-client-lib/intentclientrequest.h b/src/intent-client-lib/intentclientrequest.h
index ce004c97..8d898d32 100644
--- a/src/intent-client-lib/intentclientrequest.h
+++ b/src/intent-client-lib/intentclientrequest.h
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/src/intent-client-lib/intentclientsysteminterface.cpp b/src/intent-client-lib/intentclientsysteminterface.cpp
index 420ee92a..9be9a140 100644
--- a/src/intent-client-lib/intentclientsysteminterface.cpp
+++ b/src/intent-client-lib/intentclientsysteminterface.cpp
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/src/intent-client-lib/intentclientsysteminterface.h b/src/intent-client-lib/intentclientsysteminterface.h
index 4baa33d4..307aae8f 100644
--- a/src/intent-client-lib/intentclientsysteminterface.h
+++ b/src/intent-client-lib/intentclientsysteminterface.h
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/src/intent-client-lib/intenthandler.cpp b/src/intent-client-lib/intenthandler.cpp
index 24579aef..06b5fd15 100644
--- a/src/intent-client-lib/intenthandler.cpp
+++ b/src/intent-client-lib/intenthandler.cpp
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/src/intent-client-lib/intenthandler.h b/src/intent-client-lib/intenthandler.h
index 650ea539..95c73e41 100644
--- a/src/intent-client-lib/intenthandler.h
+++ b/src/intent-client-lib/intenthandler.h
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/src/intent-server-lib/intent.cpp b/src/intent-server-lib/intent.cpp
index b1151910..4ee207a8 100644
--- a/src/intent-server-lib/intent.cpp
+++ b/src/intent-server-lib/intent.cpp
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/src/intent-server-lib/intent.h b/src/intent-server-lib/intent.h
index 0de7f4f1..10f1c8c8 100644
--- a/src/intent-server-lib/intent.h
+++ b/src/intent-server-lib/intent.h
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/src/intent-server-lib/intentserver.cpp b/src/intent-server-lib/intentserver.cpp
index 0ba11e2f..e9afcbcd 100644
--- a/src/intent-server-lib/intentserver.cpp
+++ b/src/intent-server-lib/intentserver.cpp
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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
@@ -100,7 +100,8 @@ IntentServer *IntentServer::createInstance(IntentServerSystemInterface *systemIn
systemInterface->initialize(is.data());
qRegisterMetaType<Intent>("Intent");
- QMetaType::registerComparators<Intent>();
+ if (!QMetaType::hasRegisteredComparators<Intent>())
+ QMetaType::registerComparators<Intent>();
// Have a nicer name in the C++ API, since QML cannot cope with QList<Q_GADGET-type>
qRegisterMetaType<QVariantList>("IntentList");
diff --git a/src/intent-server-lib/intentserver.h b/src/intent-server-lib/intentserver.h
index 1bf62ade..9d658324 100644
--- a/src/intent-server-lib/intentserver.h
+++ b/src/intent-server-lib/intentserver.h
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/src/intent-server-lib/intentserverrequest.cpp b/src/intent-server-lib/intentserverrequest.cpp
index 52fd8280..8985cbe3 100644
--- a/src/intent-server-lib/intentserverrequest.cpp
+++ b/src/intent-server-lib/intentserverrequest.cpp
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/src/intent-server-lib/intentserverrequest.h b/src/intent-server-lib/intentserverrequest.h
index 1d3b2980..d008ac67 100644
--- a/src/intent-server-lib/intentserverrequest.h
+++ b/src/intent-server-lib/intentserverrequest.h
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/src/intent-server-lib/intentserversysteminterface.cpp b/src/intent-server-lib/intentserversysteminterface.cpp
index 84e54b02..96204582 100644
--- a/src/intent-server-lib/intentserversysteminterface.cpp
+++ b/src/intent-server-lib/intentserversysteminterface.cpp
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/src/intent-server-lib/intentserversysteminterface.h b/src/intent-server-lib/intentserversysteminterface.h
index 3e03806b..1a2d22e5 100644
--- a/src/intent-server-lib/intentserversysteminterface.h
+++ b/src/intent-server-lib/intentserversysteminterface.h
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/src/launcher-lib/applicationmanagerwindow.cpp b/src/launcher-lib/applicationmanagerwindow.cpp
index 766f4cbe..5bb1e645 100644
--- a/src/launcher-lib/applicationmanagerwindow.cpp
+++ b/src/launcher-lib/applicationmanagerwindow.cpp
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/src/launcher-lib/applicationmanagerwindow_p.h b/src/launcher-lib/applicationmanagerwindow_p.h
index 6a4ff5f1..825f44cb 100644
--- a/src/launcher-lib/applicationmanagerwindow_p.h
+++ b/src/launcher-lib/applicationmanagerwindow_p.h
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/src/launcher-lib/intentclientdbusimplementation.cpp b/src/launcher-lib/intentclientdbusimplementation.cpp
index 9b5b2a6f..5da608a6 100644
--- a/src/launcher-lib/intentclientdbusimplementation.cpp
+++ b/src/launcher-lib/intentclientdbusimplementation.cpp
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/src/launcher-lib/intentclientdbusimplementation.h b/src/launcher-lib/intentclientdbusimplementation.h
index 096634d2..06be71f2 100644
--- a/src/launcher-lib/intentclientdbusimplementation.h
+++ b/src/launcher-lib/intentclientdbusimplementation.h
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/src/launcher-lib/ipcwrapperobject.cpp b/src/launcher-lib/ipcwrapperobject.cpp
index 1a9bc0e6..0d3035f2 100644
--- a/src/launcher-lib/ipcwrapperobject.cpp
+++ b/src/launcher-lib/ipcwrapperobject.cpp
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/src/launcher-lib/ipcwrapperobject.h b/src/launcher-lib/ipcwrapperobject.h
index e7175faf..b36b4ed1 100644
--- a/src/launcher-lib/ipcwrapperobject.h
+++ b/src/launcher-lib/ipcwrapperobject.h
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/src/launcher-lib/ipcwrapperobject_p.h b/src/launcher-lib/ipcwrapperobject_p.h
index 95d3e3b8..9d980d75 100644
--- a/src/launcher-lib/ipcwrapperobject_p.h
+++ b/src/launcher-lib/ipcwrapperobject_p.h
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/src/launcher-lib/launchermain.cpp b/src/launcher-lib/launchermain.cpp
index 5b573c4e..c5147925 100644
--- a/src/launcher-lib/launchermain.cpp
+++ b/src/launcher-lib/launchermain.cpp
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/src/launcher-lib/launchermain.h b/src/launcher-lib/launchermain.h
index 7ff1dd31..4a9331ed 100644
--- a/src/launcher-lib/launchermain.h
+++ b/src/launcher-lib/launchermain.h
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/src/launcher-lib/qmlapplicationinterface.cpp b/src/launcher-lib/qmlapplicationinterface.cpp
index 07c914f1..4a7b95c8 100644
--- a/src/launcher-lib/qmlapplicationinterface.cpp
+++ b/src/launcher-lib/qmlapplicationinterface.cpp
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/src/launcher-lib/qmlapplicationinterface.h b/src/launcher-lib/qmlapplicationinterface.h
index 467c3069..296967d0 100644
--- a/src/launcher-lib/qmlapplicationinterface.h
+++ b/src/launcher-lib/qmlapplicationinterface.h
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/src/launcher-lib/qmlapplicationinterfaceextension.cpp b/src/launcher-lib/qmlapplicationinterfaceextension.cpp
index 97ee48d6..3b5067c0 100644
--- a/src/launcher-lib/qmlapplicationinterfaceextension.cpp
+++ b/src/launcher-lib/qmlapplicationinterfaceextension.cpp
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/src/launcher-lib/qmlapplicationinterfaceextension.h b/src/launcher-lib/qmlapplicationinterfaceextension.h
index 250c7b85..627f6899 100644
--- a/src/launcher-lib/qmlapplicationinterfaceextension.h
+++ b/src/launcher-lib/qmlapplicationinterfaceextension.h
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/src/launcher-lib/qmlnotification.cpp b/src/launcher-lib/qmlnotification.cpp
index a3de76f1..869f7bd2 100644
--- a/src/launcher-lib/qmlnotification.cpp
+++ b/src/launcher-lib/qmlnotification.cpp
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/src/launcher-lib/qmlnotification.h b/src/launcher-lib/qmlnotification.h
index b0c8826d..a358dd52 100644
--- a/src/launcher-lib/qmlnotification.h
+++ b/src/launcher-lib/qmlnotification.h
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/src/launcher-lib/waylandqtamclientextension.cpp b/src/launcher-lib/waylandqtamclientextension.cpp
index 5cf4e8ad..58c3955a 100644
--- a/src/launcher-lib/waylandqtamclientextension.cpp
+++ b/src/launcher-lib/waylandqtamclientextension.cpp
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/src/launcher-lib/waylandqtamclientextension_p.h b/src/launcher-lib/waylandqtamclientextension_p.h
index 5dfb7f50..f100fd0c 100644
--- a/src/launcher-lib/waylandqtamclientextension_p.h
+++ b/src/launcher-lib/waylandqtamclientextension_p.h
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/src/main-lib/applicationinstaller.cpp b/src/main-lib/applicationinstaller.cpp
new file mode 100644
index 00000000..7fa31479
--- /dev/null
+++ b/src/main-lib/applicationinstaller.cpp
@@ -0,0 +1,461 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 Luxoft Sweden AB
+** Copyright (C) 2018 Pelagicore AG
+** 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
+**
+****************************************************************************/
+
+#include <QCoreApplication>
+#include <qqml.h>
+#include <QQmlEngine>
+
+#include "applicationinstaller.h"
+
+
+/*!
+ \qmltype ApplicationInstaller
+ \inqmlmodule QtApplicationManager.SystemUI
+ \ingroup system-ui-singletons
+ \brief The package installation/removal/update part of the application-manager.
+
+ The ApplicationInstaller singleton type handles the package installation
+ part of the application manager. It provides both a DBus and QML APIs for
+ all of its functionality.
+
+ \note The ApplicationInstaller singleton and its corresponding DBus API are only available if you
+ specify a base directory for installed application manifests. See \l{Configuration} for details.
+
+ \target TaskStates
+
+ The following table describes all possible states that a background task could be in:
+
+ \table
+ \header
+ \li Task State
+ \li Description
+ \row
+ \li \c Queued
+ \li The task was created and is now queued up for execution.
+ \row
+ \li \c Executing
+ \li The task is being executed.
+ \row
+ \li \c Finished
+ \li The task was executed successfully.
+ \row
+ \li \c Failed
+ \li The task failed to execute successfully.
+ \row
+ \li \c AwaitingAcknowledge
+ \li \e{Installation tasks only!} The task is currently halted, waiting for either
+ acknowledgePackageInstallation() or cancelTask() to continue. See startPackageInstallation()
+ for more information on the installation workflow.
+ \row
+ \li \c Installing
+ \li \e{Installation tasks only!} The installation was acknowledged via acknowledgePackageInstallation()
+ and the final installation phase is now running.
+ \row
+ \li \c CleaningUp
+ \li \e{Installation tasks only!} The installation has finished, and previous installations as
+ well as temporary files are being cleaned up.
+ \endtable
+
+ The normal workflow for tasks is: \c Queued \unicode{0x2192} \c Executing \unicode{0x2192} \c
+ Finished. The task can enter the \c Failed state at any point though - either by being canceled via
+ cancelTask() or simply by failing due to an error.
+
+ Installation tasks are a bit more complex due to the acknowledgment: \c Queued \unicode{0x2192}
+ \c Executing \unicode{0x2192} \c AwaitingAcknowledge (this state may be skipped if
+ acknowledgePackageInstallation() was called already) \unicode{0x2192} \c Installing
+ \unicode{0x2192} \c Cleanup \unicode{0x2192} \c Finished. Again, the task can fail at any point.
+*/
+
+// THIS IS MISSING AN EXAMPLE!
+
+/*!
+ \qmlsignal ApplicationInstaller::taskStateChanged(string taskId, string newState)
+
+ This signal is emitted when the state of the task identified by \a taskId changes. The
+ new state is supplied in the parameter \a newState.
+
+ \sa taskState()
+*/
+
+/*!
+ \qmlsignal ApplicationInstaller::taskStarted(string taskId)
+
+ This signal is emitted when the task identified by \a taskId enters the \c Executing state.
+
+ \sa taskStateChanged()
+*/
+
+/*!
+ \qmlsignal ApplicationInstaller::taskFinished(string taskId)
+
+ This signal is emitted when the task identified by \a taskId enters the \c Finished state.
+
+ \sa taskStateChanged()
+*/
+
+/*!
+ \qmlsignal ApplicationInstaller::taskFailed(string taskId)
+
+ This signal is emitted when the task identified by \a taskId enters the \c Failed state.
+
+ \sa taskStateChanged()
+*/
+
+/*!
+ \qmlsignal ApplicationInstaller::taskRequestingInstallationAcknowledge(string taskId, object application, object packageExtraMetaData, object packageExtraSignedMetaData)
+
+ This signal is emitted when the installation task identified by \a taskId has received enough
+ meta-data to be able to emit this signal. The task may be in either \c Executing or \c
+ AwaitingAcknowledge state.
+
+ The contents of the package's manifest file are supplied via \a application as a JavaScript object.
+ Please see the \l {ApplicationManager Roles}{role names} for the expected object fields.
+
+ In addition, the package's extra meta-data (signed and unsinged) is also supplied via \a
+ packageExtraMetaData and \a packageExtraSignedMetaData respectively as JavaScript objects.
+ Both these objects are optional and need to be explicitly either populated during an
+ application's packaging step or added by an intermediary app-store server.
+ By default, both will just be empty.
+
+ Following this signal, either cancelTask() or acknowledgePackageInstallation() has to be called
+ for this \a taskId, to either cancel the installation or try to complete it.
+
+ The ApplicationInstaller has two convenience functions to help the System-UI with verifying the
+ meta-data: compareVersions() and, in case you are using reverse-DNS notation for application-ids,
+ validateDnsName().
+
+ \sa taskStateChanged(), startPackageInstallation()
+*/
+
+/*!
+ \qmlsignal ApplicationInstaller::taskBlockingUntilInstallationAcknowledge(string taskId)
+
+ This signal is emitted when the installation task identified by \a taskId cannot continue
+ due to a missing acknowledgePackageInstallation() call for the task.
+
+ \sa taskStateChanged(), acknowledgePackageInstallation()
+*/
+
+/*!
+ \qmlsignal ApplicationInstaller::taskProgressChanged(string taskId, qreal progress)
+
+ This signal is emitted whenever the task identified by \a taskId makes progress towards its
+ completion. The \a progress is reported as a floating-point number ranging from \c 0.0 to \c 1.0.
+
+ \sa taskStateChanged()
+*/
+
+QT_BEGIN_NAMESPACE_AM
+
+ApplicationInstaller *ApplicationInstaller::s_instance = nullptr;
+
+ApplicationInstaller::ApplicationInstaller(PackageManager *pm, QObject *parent)
+ : QObject(parent)
+ , m_pm(pm)
+{ }
+
+ApplicationInstaller::~ApplicationInstaller()
+{
+ s_instance = nullptr;
+}
+
+ApplicationInstaller *ApplicationInstaller::createInstance(PackageManager *pm)
+{
+ if (Q_UNLIKELY(s_instance))
+ qFatal("ApplicationInstaller::createInstance() was called a second time.");
+
+
+ qmlRegisterSingletonType<ApplicationInstaller>("QtApplicationManager.SystemUI", 2, 0, "ApplicationInstaller",
+ &ApplicationInstaller::instanceForQml);
+
+ return s_instance = new ApplicationInstaller(pm, QCoreApplication::instance());
+}
+
+ApplicationInstaller *ApplicationInstaller::instance()
+{
+ if (!s_instance)
+ qFatal("ApplicationInstaller::instance() was called before createInstance().");
+ return s_instance;
+}
+
+QObject *ApplicationInstaller::instanceForQml(QQmlEngine *, QJSEngine *)
+{
+ QQmlEngine::setObjectOwnership(instance(), QQmlEngine::CppOwnership);
+ return instance();
+}
+
+/*!
+ \qmlmethod list<string> ApplicationInstaller::installationLocationIds()
+
+ Retuns a list of all known installation location ids. Calling getInstallationLocation() on one of
+ the returned identifiers will yield specific information about the individual installation locations.
+*/
+
+/*!
+ \qmlmethod string ApplicationInstaller::installationLocationIdFromApplication(string id)
+
+ Returns the installation location id for the application identified by \a id. Returns
+ an empty string in case the application is not installed.
+
+ \sa installationLocationIds()
+*/
+
+/*!
+ \qmlmethod object ApplicationInstaller::getInstallationLocation(string installationLocationId)
+
+ Returns an object describing the installation location identified by \a installationLocationId in detail.
+
+ The returned object has the following members:
+
+ \table
+ \header
+ \li \c Name
+ \li \c Type
+ \li Description
+ \row
+ \li \c id
+ \li \c string
+ \li The installation location id that is used as the handle for all other ApplicationInstaller
+ function calls. The \c id consists of the \c type and \c index field, concatenated by
+ a single dash (for example, \c internal-0).
+ \row
+ \li \c type
+ \li \c string
+ \li The type of device this installation location is connected to. Valid values are \c
+ internal (for any kind of built-in storage, e.g. flash), \c removable (for any kind of
+ storage that is removable by the user, e.g. an SD card) and \c invalid.
+ \row
+ \li \c index
+ \li \c int
+ \li In case there is more than one installation location for the same type of device, this
+ \c zero-based index is used for disambiguation. For example, two SD card slots will
+ result in the ids \c removable-0 and \c removable-1. Otherwise, the index is always \c 0.
+ \row
+ \li \c isDefault
+ \li \c bool
+
+ \li Exactly one installation location is the default location which must be mounted and
+ accessible at all times. This can be used by an UI application to get a sensible
+ default for the installation location that it needs to pass to startPackageInstallation().
+ \row
+ \li \c isRemovable
+ \li \c bool
+ \li Indicates whether this installation location is on a removable media (for example, an SD
+ card).
+ \row
+ \li \c isMounted
+ \li \c bool
+ \li The current mount status of this installation location: should always be \c true for
+ non-removable media.
+ \row
+ \li \c installationPath
+ \li \c string
+ \li The absolute file-system path to the base directory under which applications are installed.
+ \row
+ \li \c installationDeviceSize
+ \li \c int
+ \li The size of the device holding \c installationPath in bytes. This field is only present if
+ \c isMounted is \c true.
+ \row
+ \li \c installationDeviceFree
+ \li \c int
+ \li The amount of bytes available on the device holding \c installationPath. This field is only
+ present if \c isMounted is \c true.
+ \row
+ \li \c documentPath
+ \li \c string
+ \li The absolute file-system path to the base directory under which per-user document
+ directories are created.
+ \row
+ \li \c documentDeviceSize
+ \li \c int
+ \li The size of the device holding \c documentPath in bytes. This field is only present if
+ \c isMounted is \c true.
+ \row
+ \li \c documentDeviceFree
+ \li \c int
+ \li The amount of bytes available on the device holding \c documentPath. This field is only
+ present if \c isMounted is \c true.
+ \endtable
+
+ Returns an empty object in case the \a installationLocationId is not valid.
+*/
+
+/*!
+ \qmlmethod int ApplicationInstaller::installedApplicationSize(string id)
+
+ Returns the size in bytes that the application identified by \a id is occupying on the storage
+ device.
+
+ Returns \c -1 in case the application \a id is not valid, or the application is not installed.
+*/
+
+/*!
+ \qmlmethod var ApplicationInstaller::installedApplicationExtraMetaData(string id)
+
+ Returns a map of all extra metadata in the package header of the application identified by \a id.
+
+ Returns an empty map in case the application \a id is not valid, or the application is not installed.
+*/
+
+/*!
+ \qmlmethod var ApplicationInstaller::installedApplicationExtraSignedMetaData(string id)
+
+ Returns a map of all signed extra metadata in the package header of the application identified
+ by \a id.
+
+ Returns an empty map in case the application \a id is not valid, or the application is not installed.
+*/
+
+/*! \internal
+ Type safe convenience function, since DBus does not like QUrl
+*/
+
+/*!
+ \qmlmethod string ApplicationInstaller::startPackageInstallation(string installationLocationId, string sourceUrl)
+
+ Downloads an application package from \a sourceUrl and installs it to the installation location
+ described by \a installationLocationId.
+
+ The actual download and installation will happen asynchronously in the background. The
+ ApplicationInstaller emits the signals \l taskStarted, \l taskProgressChanged, \l
+ taskRequestingInstallationAcknowledge, \l taskFinished, \l taskFailed, and \l taskStateChanged
+ for the returned taskId when applicable.
+
+ \note Simply calling this function is not enough to complete a package installation: The
+ taskRequestingInstallationAcknowledge() signal needs to be connected to a slot where the
+ supplied application meta-data can be validated (either programmatically or by asking the user).
+ If the validation is successful, the installation can be completed by calling
+ acknowledgePackageInstallation() or, if the validation was unsuccessful, the installation should
+ be canceled by calling cancelTask().
+ Failing to do one or the other will leave an unfinished "zombie" installation.
+
+ Returns a unique \c taskId. This can also be an empty string, if the task could not be
+ created (in this case, no signals will be emitted).
+*/
+
+/*!
+ \qmlmethod void ApplicationInstaller::acknowledgePackageInstallation(string taskId)
+
+ Calling this function enables the installer to complete the installation task identified by \a
+ taskId. Normally, this function is called after receiving the taskRequestingInstallationAcknowledge()
+ signal, and the user and/or the program logic decided to proceed with the installation.
+
+ \sa startPackageInstallation()
+ */
+
+/*!
+ \qmlmethod string ApplicationInstaller::removePackage(string id, bool keepDocuments, bool force)
+
+ Uninstalls the application identified by \a id. Normally, the documents directory of the
+ application is deleted on removal, but this can be prevented by setting \a keepDocuments to \c true.
+
+ The actual removal will happen asynchronously in the background. The ApplicationInstaller will
+ emit the signals \l taskStarted, \l taskProgressChanged, \l taskFinished, \l taskFailed and \l
+ taskStateChanged for the returned \c taskId when applicable.
+
+ Normally, \a force should only be set to \c true if a previous call to removePackage() failed.
+ This may be necessary if the installation process was interrupted, or if an SD card got lost
+ or has file-system issues.
+
+ Returns a unique \c taskId. This can also be an empty string, if the task could not be created
+ (in this case, no signals will be emitted).
+*/
+
+/*!
+ \qmlmethod enumeration ApplicationInstaller::taskState(string taskId)
+
+ Returns the current state of the installation task identified by \a taskId.
+ \l {TaskStates}{See here} for a list of valid task states.
+
+ Returns \c ApplicationInstaller.Invalid if the \a taskId is invalid.
+*/
+
+/*!
+ \qmlmethod string ApplicationInstaller::taskApplicationId(string taskId)
+
+ Returns the application id associated with the task identified by \a taskId. The task may not
+ have a valid application id at all times though and in this case the function will return an
+ empty string (this will be the case for installations before the taskRequestingInstallationAcknowledge
+ signal has been emitted).
+
+ Returns an empty string if the \a taskId is invalid.
+*/
+
+
+/*!
+ \qmlmethod list<string> ApplicationInstaller::activeTaskIds()
+
+ Retuns a list of all currently active (as in not yet finished or failed) installation task ids.
+*/
+
+/*!
+ \qmlmethod bool ApplicationInstaller::cancelTask(string taskId)
+
+ Tries to cancel the installation task identified by \a taskId.
+
+ Returns \c true if the task was canceled, \c false otherwise.
+*/
+
+/*!
+ \qmlmethod int ApplicationInstaller::compareVersions(string version1, string version2)
+
+ Convenience method for app-store implementations or taskRequestingInstallationAcknowledge()
+ callbacks for comparing version numbers, as the actual version comparison algorithm is not
+ trivial.
+
+ Returns \c -1, \c 0 or \c 1 if \a version1 is smaller than, equal to, or greater than \a
+ version2 (similar to how \c strcmp() works).
+*/
+
+/*!
+ \qmlmethod int ApplicationInstaller::validateDnsName(string name, int minimalPartCount)
+
+ Convenience method for app-store implementations or taskRequestingInstallationAcknowledge()
+ callbacks for checking if the given \a name is a valid DNS (or reverse-DNS) name according to
+ RFC 1035/1123. If the optional parameter \a minimalPartCount is specified, this function will
+ also check if \a name contains at least this amount of parts/sub-domains.
+
+ Returns \c true if the name is a valid DNS name or \c false otherwise.
+*/
+
+QT_END_NAMESPACE_AM
diff --git a/src/main-lib/applicationinstaller.h b/src/main-lib/applicationinstaller.h
new file mode 100644
index 00000000..978f6ce1
--- /dev/null
+++ b/src/main-lib/applicationinstaller.h
@@ -0,0 +1,202 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 Luxoft Sweden AB
+** Copyright (C) 2018 Pelagicore AG
+** 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
+**
+****************************************************************************/
+
+#pragma once
+
+#include <QObject>
+#include <QVariant>
+#include <QUrl>
+#include <QStringList>
+#include <QDir>
+#include <QDebug>
+#include <QtAppManCommon/error.h>
+#include <QtAppManCommon/logging.h>
+#include <QtAppManManager/applicationmanager.h>
+#include <QtAppManManager/packagemanager.h>
+#include <QtAppManManager/package.h>
+#include <QtAppManManager/asynchronoustask.h>
+
+QT_FORWARD_DECLARE_CLASS(QQmlEngine)
+QT_FORWARD_DECLARE_CLASS(QJSEngine)
+
+QT_BEGIN_NAMESPACE_AM
+
+
+class ApplicationInstaller : public QObject
+{
+ Q_OBJECT
+ Q_CLASSINFO("D-Bus Interface", "io.qt.ApplicationInstaller")
+ Q_CLASSINFO("AM-QmlType", "QtApplicationManager.SystemUI/ApplicationInstaller 2.0 SINGLETON")
+
+ // both are const on purpose - these should never change in a running system
+ Q_PROPERTY(bool allowInstallationOfUnsignedPackages READ allowInstallationOfUnsignedPackages CONSTANT)
+ Q_PROPERTY(bool developmentMode READ developmentMode CONSTANT)
+
+ Q_PROPERTY(bool applicationUserIdSeparation READ isApplicationUserIdSeparationEnabled)
+ Q_PROPERTY(uint commonApplicationGroupId READ commonApplicationGroupId)
+
+
+public:
+ Q_ENUMS(QT_PREPEND_NAMESPACE_AM(AsynchronousTask::TaskState))
+
+ ~ApplicationInstaller();
+ static ApplicationInstaller *createInstance(PackageManager *pm);
+ static ApplicationInstaller *instance();
+ static QObject *instanceForQml(QQmlEngine *qmlEngine, QJSEngine *);
+
+ bool developmentMode() const { return m_pm->developmentMode(); }
+ bool allowInstallationOfUnsignedPackages() const { return m_pm->allowInstallationOfUnsignedPackages(); }
+ QString hardwareId() const { return m_pm->hardwareId(); }
+
+ bool isApplicationUserIdSeparationEnabled() const { return m_pm->isApplicationUserIdSeparationEnabled(); }
+ uint commonApplicationGroupId() const { return m_pm->commonApplicationGroupId(); }
+
+ // Q_SCRIPTABLEs are available via both QML and D-Bus
+ Q_SCRIPTABLE QStringList installationLocationIds() const { return { qL1S("internal-0") }; }
+ Q_SCRIPTABLE QString installationLocationIdFromApplication(const QString &applicationId) const
+ {
+ auto app = ApplicationManager::instance()->fromId(applicationId);
+ if (app && ((!app->package()->isBuiltIn() || app->package()->canBeRevertedToBuiltIn())))
+ return qL1S("internal-0");
+ return QString();
+ }
+ Q_SCRIPTABLE QVariantMap getInstallationLocation(const QString &installationLocationId) const
+ {
+ if (installationLocationId != qL1S("internal-0"))
+ return QVariantMap { };
+
+ auto iloc = m_pm->installationLocation();
+ auto dloc = m_pm->documentLocation();
+
+ return QVariantMap {
+ { qSL("id"), qSL("internal-0") },
+ { qSL("type"), qSL("internal") },
+ { qSL("index"), 0 },
+ { qSL("isDefault"), true },
+ { qSL("installationPath"), iloc.value(qL1S("path")) },
+ { qSL("installationDeviceSize"), iloc.value(qL1S("size")) },
+ { qSL("installationDeviceFree"), iloc.value(qL1S("free")) },
+ { qSL("documentPath"), dloc.value(qL1S("path")) },
+ { qSL("documentDeviceSize"), dloc.value(qL1S("size")) },
+ { qSL("documentDeviceFree"), dloc.value(qL1S("free")) }
+ };
+ }
+
+ // all QString return values are task-ids
+ Q_SCRIPTABLE QString startPackageInstallation(const QString &installationLocationId, const QString &sourceUrl)
+ {
+ if (installationLocationId == qL1S("internal-0")) {
+ return m_pm->startPackageInstallation(sourceUrl);
+ } else {
+ qCWarning(LogInstaller) << "The only supported legacy installation location is 'internal-0', "
+ "but an installation was requested to:" << installationLocationId;
+ return QString();
+ }
+ }
+
+ Q_SCRIPTABLE void acknowledgePackageInstallation(const QString &taskId)
+ { return m_pm->acknowledgePackageInstallation(taskId); }
+ Q_SCRIPTABLE QString removePackage(const QString &packageId, bool keepDocuments, bool force = false)
+ { return m_pm->removePackage(packageId, keepDocuments, force); }
+
+ Q_SCRIPTABLE AsynchronousTask::TaskState taskState(const QString &taskId) const
+ { return m_pm->taskState(taskId); }
+ Q_SCRIPTABLE QString taskApplicationId(const QString &taskId) const
+ {
+ auto package = m_pm->fromId(m_pm->taskPackageId(taskId));
+ if (package && !package->info()->applications().isEmpty())
+ return package->info()->applications().constFirst()->id();
+ return QString();
+ }
+ Q_SCRIPTABLE QStringList activeTaskIds() const
+ { return m_pm->activeTaskIds(); }
+ Q_SCRIPTABLE bool cancelTask(const QString &taskId)
+ { return m_pm->cancelTask(taskId); }
+
+ // convenience function for app-store implementations
+ Q_SCRIPTABLE int compareVersions(const QString &version1, const QString &version2)
+ { return m_pm->compareVersions(version1, version2); }
+ Q_SCRIPTABLE bool validateDnsName(const QString &name, int minimumParts = 1)
+ { return m_pm->validateDnsName(name, minimumParts); }
+
+ Q_SCRIPTABLE qint64 installedApplicationSize(const QString &applicationId) const
+ {
+ auto app = ApplicationManager::instance()->fromId(applicationId);
+ return m_pm->installedPackageSize(app ? app->package()->id() : QString());
+ }
+ Q_SCRIPTABLE QVariantMap installedApplicationExtraMetaData(const QString &applicationId) const
+ {
+ auto app = ApplicationManager::instance()->fromId(applicationId);
+ return m_pm->installedPackageExtraMetaData(app ? app->package()->id() : QString());
+ }
+ Q_SCRIPTABLE QVariantMap installedApplicationExtraSignedMetaData(const QString &applicationId) const
+ {
+ auto app = ApplicationManager::instance()->fromId(applicationId);
+ return m_pm->installedPackageExtraSignedMetaData(app ? app->package()->id() : QString());
+ }
+
+signals:
+ Q_SCRIPTABLE void taskStarted(const QString &taskId);
+ Q_SCRIPTABLE void taskProgressChanged(const QString &taskId, qreal progress);
+ Q_SCRIPTABLE void taskFinished(const QString &taskId);
+ Q_SCRIPTABLE void taskFailed(const QString &taskId, int errorCode, const QString &errorString);
+ Q_SCRIPTABLE void taskStateChanged(const QString &taskId,
+ QT_PREPEND_NAMESPACE_AM(AsynchronousTask::TaskState) newState);
+
+ // installation only
+ Q_SCRIPTABLE void taskRequestingInstallationAcknowledge(const QString &taskId,
+ const QVariantMap &applicationAsVariantMap,
+ const QVariantMap &packageExtraMetaData,
+ const QVariantMap &packageExtraSignedMetaData);
+ Q_SCRIPTABLE void taskBlockingUntilInstallationAcknowledge(const QString &taskId);
+
+
+private:
+ PackageManager *m_pm;
+ ApplicationInstaller(PackageManager *pm, QObject *parent = nullptr);
+ ApplicationInstaller(const ApplicationInstaller &);
+ static ApplicationInstaller *s_instance;
+};
+
+QT_END_NAMESPACE_AM
+
+Q_DECLARE_METATYPE(QT_PREPEND_NAMESPACE_AM(AsynchronousTask::TaskState))
diff --git a/src/main-lib/configuration.cpp b/src/main-lib/configuration.cpp
index 313bc861..3dbe8f55 100644
--- a/src/main-lib/configuration.cpp
+++ b/src/main-lib/configuration.cpp
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/src/main-lib/configuration.h b/src/main-lib/configuration.h
index 85c91008..7d59d288 100644
--- a/src/main-lib/configuration.h
+++ b/src/main-lib/configuration.h
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/src/main-lib/defaultconfiguration.cpp b/src/main-lib/defaultconfiguration.cpp
index 6ba3bada..a0e5f930 100644
--- a/src/main-lib/defaultconfiguration.cpp
+++ b/src/main-lib/defaultconfiguration.cpp
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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
@@ -95,7 +95,9 @@ DefaultConfiguration::DefaultConfiguration(const QStringList &defaultConfigFileP
m_clp.addOption({ qSL("database"), qSL("filepath of the application database cache."), qSL("file") });
m_clp.addOption({ { qSL("r"), qSL("recreate-database") }, qSL("recreate the application database cache.") });
m_clp.addOption({ qSL("builtin-apps-manifest-dir"), qSL("base directory for built-in application manifests."), qSL("dir") });
- m_clp.addOption({ qSL("installed-apps-manifest-dir"), qSL("base directory for installed application manifests."), qSL("dir") });
+ m_clp.addOption({ qSL("installation-dir"), qSL("base directory for package installations."), qSL("dir") });
+ m_clp.addOption({ qSL("document-dir"), qSL("base directory for per-package document directories."), qSL("dir") });
+ m_clp.addOption({ qSL("installed-apps-manifest-dir"), qSL("deprecated (ignored)."), qSL("dir") });
m_clp.addOption({ qSL("app-image-mount-dir"), qSL("deprecated, not needed anymore."), qSL("dir") });
m_clp.addOption({ qSL("disable-installer"), qSL("disable the application installer sub-system.") });
m_clp.addOption({ qSL("disable-intents"), qSL("disable the intents sub-system.") });
@@ -143,10 +145,30 @@ void DefaultConfiguration::parseWithArguments(const QStringList &arguments, QStr
*deploymentWarnings << qL1S("No --database command line parameter or applications/database configuration"
" key specified. Database won't be cached to speed up subsequent System-UI startups.");
- if (installedAppsManifestDir().isEmpty())
- *deploymentWarnings << qL1S("No --installed-apps-manifest-dir command line parameter or"
- " applications/installedAppsManifestDir configuration key specified. It won't be possible to install,"
- " remove or access installable applications.");
+ if (installationDir().isEmpty()) {
+ const auto ilocs = value<QVariant>(nullptr, { "installationLocations" }).toList();
+ if (!ilocs.isEmpty()) {
+ *deploymentWarnings << qL1S("Support for \"installationLocations\" in the main config file has been removed:");
+
+ for (const auto iloc : ilocs) {
+ QVariantMap map = iloc.toMap();
+ QString id = map.value(qSL("id")).toString();
+ if (id == qSL("internal-0")) {
+ m_installationDir = map.value(qSL("installationPath")).toString();
+ m_documentDir = map.value(qSL("documentPath")).toString();
+ *deploymentWarnings << qL1S(" * still using installation location \"internal-0\" for backward compatibility");
+ } else {
+ *deploymentWarnings << qL1S(" * ignoring installation location ") + id;
+ }
+ }
+ }
+ }
+
+ if (installationDir().isEmpty()) {
+ *deploymentWarnings << qL1S("No --installation-dir command line parameter or"
+ " applications/installationDir configuration key specified. It won't be possible to install,"
+ " remove or access installable packages.");
+ }
if (value<bool>("start-session-dbus"))
*deploymentWarnings << qL1S("Option \"--start-session-dbus\" has been deprecated and will be ignored.");
@@ -154,7 +176,7 @@ void DefaultConfiguration::parseWithArguments(const QStringList &arguments, QStr
QString DefaultConfiguration::mainQmlFile() const
{
- if (!m_clp.positionalArguments().isEmpty() && m_clp.positionalArguments().at(0).endsWith(qL1S(".qml")))
+ if (!m_clp.positionalArguments().isEmpty())
return m_clp.positionalArguments().at(0);
else
return value<QString>(nullptr, { "ui", "mainQml" });
@@ -176,9 +198,18 @@ QStringList DefaultConfiguration::builtinAppsManifestDirs() const
return value<QStringList>("builtin-apps-manifest-dir", { "applications", "builtinAppsManifestDir" });
}
-QString DefaultConfiguration::installedAppsManifestDir() const
+QString DefaultConfiguration::installationDir() const
{
- return value<QString>("installed-apps-manifest-dir", { "applications", "installedAppsManifestDir" });
+ if (m_installationDir.isEmpty())
+ m_installationDir = value<QString>("installation-dir", { "applications", "installationDir" });
+ return m_installationDir;
+}
+
+QString DefaultConfiguration::documentDir() const
+{
+ if (m_documentDir.isEmpty())
+ m_documentDir = value<QString>("document-dir", { "applications", "documentDir" });
+ return m_documentDir;
}
bool DefaultConfiguration::disableInstaller() const
@@ -347,11 +378,6 @@ QVariantMap DefaultConfiguration::openGLConfiguration() const
return value<QVariant>(nullptr, { "ui", "opengl" }).toMap();
}
-QVariantList DefaultConfiguration::installationLocations() const
-{
- return value<QVariant>(nullptr, { "installationLocations" }).toList();
-}
-
QList<QPair<QString, QString>> DefaultConfiguration::containerSelectionConfiguration() const
{
QList<QPair<QString, QString>> config;
diff --git a/src/main-lib/defaultconfiguration.h b/src/main-lib/defaultconfiguration.h
index d253d420..b6317ba3 100644
--- a/src/main-lib/defaultconfiguration.h
+++ b/src/main-lib/defaultconfiguration.h
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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
@@ -65,7 +65,10 @@ public:
bool recreateDatabase() const;
QStringList builtinAppsManifestDirs() const;
- QString installedAppsManifestDir() const;
+
+ QString installationDir() const;
+ QString documentDir() const;
+
bool disableInstaller() const;
bool disableIntents() const;
QMap<QString, int> intentTimeouts() const;
@@ -98,8 +101,6 @@ public:
QVariantMap openGLConfiguration() const;
- QVariantList installationLocations() const;
-
QList<QPair<QString, QString>> containerSelectionConfiguration() const;
QVariantMap containerConfigurations() const;
QVariantMap runtimeConfigurations() const;
@@ -131,6 +132,8 @@ private:
QString m_mainQmlFile;
bool m_onlyOnePositionalArgument = false;
bool m_forceVerbose = false;
+ mutable QString m_installationDir; // cached value
+ mutable QString m_documentDir; // cached value
};
QT_END_NAMESPACE_AM
diff --git a/src/main-lib/main-lib.pro b/src/main-lib/main-lib.pro
index 73a972c3..721a54ce 100644
--- a/src/main-lib/main-lib.pro
+++ b/src/main-lib/main-lib.pro
@@ -14,7 +14,6 @@ QT *= \
appman_application-private \
appman_manager-private \
appman_package-private \
- appman_installer-private \
appman_notification-private \
appman_monitor-private \
appman_shared_main-private \
@@ -37,6 +36,7 @@ HEADERS += \
!headless:HEADERS += \
windowframetimer.h \
+ applicationinstaller.h \
SOURCES += \
main.cpp \
@@ -45,5 +45,6 @@ SOURCES += \
!headless:SOURCES += \
windowframetimer.cpp \
+ applicationinstaller.cpp \
load(qt_module)
diff --git a/src/main-lib/main.cpp b/src/main-lib/main.cpp
index 0ebc6211..5f7d6d67 100644
--- a/src/main-lib/main.cpp
+++ b/src/main-lib/main.cpp
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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
@@ -49,7 +49,7 @@
# include "dbusdaemon.h"
# include "dbuspolicy.h"
# include "applicationmanagerdbuscontextadaptor.h"
-# include "applicationinstallerdbuscontextadaptor.h"
+# include "packagemanagerdbuscontextadaptor.h"
# include "notificationmanagerdbuscontextadaptor.h"
#endif
@@ -95,13 +95,18 @@
#include "main.h"
#include "defaultconfiguration.h"
#include "applicationinfo.h"
+#include "intentinfo.h"
+#include "packageinfo.h"
#include "applicationmanager.h"
-#include "applicationdatabase.h"
+#include "packagemanager.h"
+#include "package.h"
+#include "packagedatabase.h"
#include "installationreport.h"
-#include "yamlapplicationscanner.h"
+#include "yamlpackagescanner.h"
#if !defined(AM_DISABLE_INSTALLER)
# include "applicationinstaller.h"
# include "sudo.h"
+# include "packageutilities.h"
#endif
#include "runtimefactory.h"
#include "containerfactory.h"
@@ -116,7 +121,6 @@
#include "qmlinprocessapplicationinterface.h"
#include "qml-utilities.h"
#include "dbus-utilities.h"
-#include "package.h"
#include "intentserver.h"
#include "intentaminterface.h"
@@ -186,6 +190,10 @@ Main::~Main()
delete m_view;
# endif
delete m_applicationManager;
+#if !defined(AM_DISABLE_INSTALLER)
+ delete m_applicationInstaller;
+#endif
+ delete m_packageManager;
delete m_quickLauncher;
delete m_applicationIPCManager;
@@ -204,7 +212,8 @@ void Main::setup(const DefaultConfiguration *cfg, const QStringList &deploymentW
m_noSecurity = cfg->noSecurity();
m_developmentMode = cfg->developmentMode();
m_builtinAppsManifestDirs = cfg->builtinAppsManifestDirs();
- m_installedAppsManifestDir = cfg->installedAppsManifestDir();
+ m_installationDir = cfg->installationDir();
+ m_documentDir = cfg->documentDir();
CrashHandler::setCrashActionConfiguration(cfg->managerCrashAction());
setupLogging(cfg->verbose(), cfg->loggingRules(), cfg->messagePattern(), cfg->useAMConsoleLogger());
@@ -228,16 +237,13 @@ void Main::setup(const DefaultConfiguration *cfg, const QStringList &deploymentW
setupRuntimesAndContainers(cfg->runtimeConfigurations(), cfg->openGLConfiguration(),
cfg->containerConfigurations(), cfg->pluginFilePaths("container"),
cfg->iconThemeSearchPaths(), cfg->iconThemeName());
- if (!cfg->disableInstaller())
- setupInstallationLocations(cfg->installationLocations());
- if (!cfg->database().isEmpty())
- loadApplicationDatabase(cfg->database(), cfg->recreateDatabase(), cfg->singleApp());
+ loadPackageDatabase(cfg->recreateDatabase(), cfg->singleApp());
setupSingletons(cfg->containerSelectionConfiguration(), cfg->quickLaunchRuntimesPerContainer(),
- cfg->quickLaunchIdleLoad(), cfg->singleApp());
+ cfg->quickLaunchIdleLoad());
- if (m_installedAppsManifestDir.isEmpty() || cfg->disableInstaller()) {
+ if (m_installationDir.isEmpty() || cfg->disableInstaller()) {
StartupTimer::instance()->checkpoint("skipping installer");
} else {
setupInstaller(cfg->caCertificates(),
@@ -349,11 +355,11 @@ void Main::parseSystemProperties(const QVariantMap &rawSystemProperties)
void Main::setMainQmlFile(const QString &mainQml) Q_DECL_NOEXCEPT_EXPR(false)
{
- // For some weird reason, QFile cannot cope with "qrc:/" and QUrl cannot cope with ":/" , so
- // we have to translate ourselves between those two "worlds".
+ // For some weird reason, QFile cannot cope with "qrc:/" and QUrl cannot cope with ":/",
+ // so we have to translate ourselves between those two "worlds".
if (mainQml.startsWith(qSL(":/")))
- m_mainQml = QUrl(qSL("qrc:") + mainQml.mid(1));
+ m_mainQml = QUrl(qSL("qrc") + mainQml);
else
m_mainQml = QUrl::fromUserInput(mainQml, QDir::currentPath(), QUrl::AssumeLocalFile);
@@ -362,8 +368,14 @@ void Main::setMainQmlFile(const QString &mainQml) Q_DECL_NOEXCEPT_EXPR(false)
else if (m_mainQml.scheme() == qSL("qrc"))
m_mainQmlLocalFile = qL1C(':') + m_mainQml.path();
- if (!m_mainQmlLocalFile.isEmpty() && !QFile::exists(m_mainQmlLocalFile))
- throw Exception("no/invalid main QML file specified: %1").arg(m_mainQmlLocalFile);
+ if (!QFileInfo(m_mainQmlLocalFile).isFile()) {
+ if (mainQml.isEmpty())
+ throw Exception("No main QML file specified");
+
+ // basically accept schemes other than file and qrc:
+ if (!m_mainQmlLocalFile.isEmpty())
+ throw Exception("Invalid main QML file specified: %1").arg(mainQml);
+ }
}
void Main::setupSingleOrMultiProcess(bool forceSingleProcess, bool forceMultiProcess) Q_DECL_NOEXCEPT_EXPR(false)
@@ -412,66 +424,33 @@ void Main::setupRuntimesAndContainers(const QVariantMap &runtimeConfigurations,
StartupTimer::instance()->checkpoint("after runtime registration");
}
-void Main::setupInstallationLocations(const QVariantList &installationLocations)
+void Main::loadPackageDatabase(bool recreateDatabase, const QString &singlePackage) Q_DECL_NOEXCEPT_EXPR(false)
{
- m_installationLocations = InstallationLocation::parseInstallationLocations(installationLocations,
- hardwareId());
- if (m_installationLocations.isEmpty())
- qCWarning(LogDeployment) << "No installation locations defined in config file";
-}
-
-void Main::loadApplicationDatabase(const QString &databasePath, bool recreateDatabase,
- const QString &singleApp) Q_DECL_NOEXCEPT_EXPR(false)
-{
- if (singleApp.isEmpty()) {
- if (!QFile::exists(databasePath)) // make sure to create a database on the first run
- recreateDatabase = true;
- if (QFileInfo(databasePath).size() == 0) // cope with Windows' 0-byte left-overs
- recreateDatabase = true;
-
- if (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);
- }
- m_applicationDatabase.reset(new ApplicationDatabase(databasePath));
+ if (!singlePackage.isEmpty()) {
+ m_packageDatabase = new PackageDatabase(singlePackage);
} else {
- m_applicationDatabase.reset(new ApplicationDatabase());
- recreateDatabase = true;
+ m_packageDatabase = new PackageDatabase(m_builtinAppsManifestDirs, m_installationDir);
+ if (!recreateDatabase)
+ m_packageDatabase->enableLoadFromCache();
+ m_packageDatabase->enableSaveToCache();
}
+ m_packageDatabase->parse();
- if (Q_UNLIKELY(!m_applicationDatabase->isValid() && !recreateDatabase)) {
- throw Exception("database file %1 is not a valid application database: %2")
- .arg(m_applicationDatabase->name(), m_applicationDatabase->errorString());
- }
+ const QVector<PackageInfo *> allPackages =
+ m_packageDatabase->builtInPackages()
+ + m_packageDatabase->installedPackages();
- if (!m_applicationDatabase->isValid() || recreateDatabase) {
- QVector<AbstractApplicationInfo *> apps;
+ for (auto package : allPackages) {
+ // check that the runtimes are supported in this instance of the AM
+ auto apps = package->applications();
- if (!singleApp.isEmpty()) {
- apps = scanForApplication(singleApp, m_builtinAppsManifestDirs);
- } else {
- apps = scanForApplications(m_builtinAppsManifestDirs,
- m_installedAppsManifestDir,
- m_installationLocations);
+ for (const auto app : apps) {
+ if (!RuntimeFactory::instance()->manager(app->runtimeName()))
+ qCWarning(LogSystem) << "Application" << app->id() << "uses an unknown runtime:" << app->runtimeName();
}
-
- if (LogSystem().isDebugEnabled()) {
- qCDebug(LogSystem) << "Registering applications:";
- for (auto *app : qAsConst(apps)) {
- if (app->isAlias())
- qCDebug(LogSystem).nospace().noquote() << " * " << app->id();
- else
- qCDebug(LogSystem).nospace().noquote() << " * " << app->id() << " [at: "
- << static_cast<const ApplicationInfo*>(app)->codeDir().path() << "]";
- }
- }
-
- m_applicationDatabase->write(apps);
- qDeleteAll(apps);
}
- StartupTimer::instance()->checkpoint("after application database loading");
+ StartupTimer::instance()->checkpoint("after package database loading");
}
void Main::setupIntents(const QMap<QString, int> &timeouts) Q_DECL_NOEXCEPT_EXPR(false)
@@ -480,38 +459,56 @@ void Main::setupIntents(const QMap<QString, int> &timeouts) Q_DECL_NOEXCEPT_EXPR
qCDebug(LogSystem) << "Registering intents:";
- const auto apps = m_applicationManager->applications();
- for (AbstractApplication *app : apps)
- IntentAMImplementation::addApplicationIntents(app, m_intentServer);
+ const auto packages = m_packageManager->packages();
+ for (const Package *package : packages) {
+ const auto intents = package->info()->intents();
+ if (!intents.isEmpty())
+ m_intentServer->addApplication(package->id());
+
+ for (const IntentInfo *intent : intents) {
+ if (!m_intentServer->addIntent(intent->id(), package->id(), intent->handlingApplicationId(),
+ intent->requiredCapabilities(),
+ intent->visibility() == IntentInfo::Public ? Intent::Public
+ : Intent::Private,
+ intent->parameterMatch())) {
+ throw Exception(Error::Intents, "could not add intent %1 for package %2")
+ .arg(intent->id()).arg(package->id());
+ }
+ qCDebug(LogSystem).nospace().noquote() << " * " << intent->id() << " [package: " << package->id() << "]";
+ }
+ }
StartupTimer::instance()->checkpoint("after Intents setup");
}
void Main::setupSingletons(const QList<QPair<QString, QString>> &containerSelectionConfiguration,
- int quickLaunchRuntimesPerContainer, qreal quickLaunchIdleLoad,
- const QString &singleApp) Q_DECL_NOEXCEPT_EXPR(false)
+ int quickLaunchRuntimesPerContainer,
+ qreal quickLaunchIdleLoad) Q_DECL_NOEXCEPT_EXPR(false)
{
- m_applicationManager = ApplicationManager::createInstance(m_isSingleProcessMode);
-
- if (m_applicationDatabase) {
- setupApplicationManagerWithDatabase();
- } else {
- QVector<AbstractApplicationInfo *> appInfoVector;
-
- if (!singleApp.isEmpty()) {
- appInfoVector = scanForApplication(singleApp, m_builtinAppsManifestDirs);
- } else {
- appInfoVector = scanForApplications(m_builtinAppsManifestDirs,
- m_installedAppsManifestDir,
- m_installationLocations);
+ m_packageManager = PackageManager::createInstance(m_packageDatabase, m_documentDir);
+
+ qCDebug(LogSystem) << "Registering packages:";
+
+ QVector<Application *> applications;
+ const auto allPackages = m_packageManager->packages();
+ for (auto package : allPackages) {
+ qCDebug(LogSystem).nospace().noquote() << " * " << package->id() << " [at: "
+ << QDir().relativeFilePath(package->info()->baseDir().path()) << "]";
+ const auto appInfos = package->info()->applications();
+ for (auto appInfo : appInfos) {
+ applications << new Application(appInfo, package);
+ qCDebug(LogSystem).nospace().noquote() << " * application:" << appInfo->id();
}
-
- QVector<AbstractApplication *> apps = AbstractApplication::fromApplicationInfoVector(appInfoVector);
- m_applicationManager->setApplications(apps);
}
- if (!singleApp.isEmpty())
- m_applicationManager->enableSingleAppMode();
+ m_applicationManager = ApplicationManager::createInstance(m_isSingleProcessMode);
+ m_applicationManager->setApplications(applications);
+
+ connect(&m_applicationManager->internalSignals, &ApplicationManagerInternalSignals::applicationsChanged,
+ this, [this]() {
+ //m_packageDatabase->saveToCache();
+ //TODO: this is wrong - we haven't update the info cache!
+ });
if (m_noSecurity)
m_applicationManager->setSecurityChecksEnabled(false);
@@ -534,27 +531,11 @@ void Main::setupSingletons(const QList<QPair<QString, QString>> &containerSelect
StartupTimer::instance()->checkpoint("after quick-launcher setup");
}
-void Main::setupApplicationManagerWithDatabase()
-{
- m_applicationManager->setApplications(m_applicationDatabase->read());
-
- connect(&m_applicationManager->internalSignals, &ApplicationManagerInternalSignals::applicationsChanged,
- this, [this]() {
- try {
- if (m_applicationDatabase)
- m_applicationDatabase->write(m_applicationManager->applications());
- } catch (const Exception &e) {
- qCCritical(LogInstaller) << "Failed to write the application database to disk:" << e.errorString();
- m_applicationDatabase->invalidate(); // make sure that the next AM start will rebuild the DB
- }
- });
-}
-
void Main::setupInstaller(const QStringList &caCertificatePaths,
const std::function<bool(uint *, uint *, uint *)> &userIdSeparation) Q_DECL_NOEXCEPT_EXPR(false)
{
#if !defined(AM_DISABLE_INSTALLER)
- if (!Package::checkCorrectLocale()) {
+ if (!PackageUtilities::checkCorrectLocale()) {
// we should really throw here, but so many embedded systems are badly set up
qCWarning(LogDeployment) << "The appman installer needs a UTF-8 locale to work correctly: "
"even automatically switching to C.UTF-8 or en_US.UTF-8 failed.";
@@ -563,24 +544,20 @@ void Main::setupInstaller(const QStringList &caCertificatePaths,
if (Q_UNLIKELY(hardwareId().isEmpty()))
throw Exception("the installer is enabled, but the device-id is empty");
- if (Q_UNLIKELY(!QDir::root().mkpath(m_installedAppsManifestDir)))
- throw Exception("could not create manifest directory for installed applications: \'%1\'").arg(m_installedAppsManifestDir);
+ if (!m_installationDir.isEmpty() && !QDir::root().mkpath(m_installationDir))
+ throw Exception("could not create package installation directory: \'%1\'").arg(m_installationDir);
+ if (!m_documentDir.isEmpty() && !QDir::root().mkpath(m_documentDir))
+ throw Exception("could not create document directory for packages: \'%1\'").arg(m_documentDir);
StartupTimer::instance()->checkpoint("after installer setup checks");
- QString error;
- m_applicationInstaller = ApplicationInstaller::createInstance(m_installationLocations,
- m_installedAppsManifestDir,
- hardwareId(),
- &error);
- if (Q_UNLIKELY(!m_applicationInstaller))
- throw Exception(Error::System, error);
+ m_applicationInstaller = ApplicationInstaller::createInstance(m_packageManager);
if (m_developmentMode)
- m_applicationInstaller->setDevelopmentMode(true);
+ m_packageManager->setDevelopmentMode(true);
if (m_noSecurity) {
- m_applicationInstaller->setAllowInstallationOfUnsignedPackages(true);
+ m_packageManager->setAllowInstallationOfUnsignedPackages(true);
} else {
QList<QByteArray> caCertificateList;
@@ -593,13 +570,13 @@ void Main::setupInstaller(const QStringList &caCertificatePaths,
throw Exception(f, "CA-certificate file is empty");
caCertificateList << cert;
}
- m_applicationInstaller->setCACertificates(caCertificateList);
+ m_packageManager->setCACertificates(caCertificateList);
}
uint minUserId, maxUserId, commonGroupId;
if (userIdSeparation && userIdSeparation(&minUserId, &maxUserId, &commonGroupId)) {
# if defined(Q_OS_LINUX)
- if (!m_applicationInstaller->enableApplicationUserIdSeparation(minUserId, maxUserId, commonGroupId))
+ if (!m_packageManager->enableApplicationUserIdSeparation(minUserId, maxUserId, commonGroupId))
throw Exception("could not enable application user-id separation in the installer.");
# else
qCCritical(LogSystem) << "WARNING: application user-id separation requested, but not possible on this platform.";
@@ -607,9 +584,12 @@ void Main::setupInstaller(const QStringList &caCertificatePaths,
}
//TODO: this could be delayed, but needs to have a lock on the app-db in this case
- m_applicationInstaller->cleanupBrokenInstallations();
+ m_packageManager->cleanupBrokenInstallations();
- StartupTimer::instance()->checkpoint("after ApplicationInstaller instantiation");
+ StartupTimer::instance()->checkpoint("after PackageManager instantiation");
+#else
+ Q_UNUSED(caCertificatePaths)
+ Q_UNUSED(userIdSeparation)
#endif // AM_DISABLE_INSTALLER
}
@@ -1002,9 +982,9 @@ void Main::setupDBus(const std::function<QString(const char *)> &busForInterface
};
# if !defined(AM_DISABLE_INSTALLER)
- if (m_applicationInstaller) {
- addInterface(new ApplicationInstallerDBusContextAdaptor(m_applicationInstaller),
- "io.qt.ApplicationManager", "/ApplicationInstaller");
+ if (m_packageManager) {
+ addInterface(new PackageManagerDBusContextAdaptor(m_packageManager),
+ "io.qt.ApplicationManager", "/PackageManager");
}
# endif
# if !defined(AM_HEADLESS)
@@ -1071,149 +1051,6 @@ void Main::setupDBus(const std::function<QString(const char *)> &busForInterface
#endif // defined(QT_DBUS_LIB) && !defined(AM_DISABLE_EXTERNAL_DBUS_INTERFACES)
}
-
-QVector<AbstractApplicationInfo *> Main::scanForApplication(const QString &singleAppInfoYaml,
- const QStringList &builtinAppsDirs) Q_DECL_NOEXCEPT_EXPR(false)
-{
- QVector<AbstractApplicationInfo *> result;
- YamlApplicationScanner yas;
-
- QDir appDir = QFileInfo(singleAppInfoYaml).dir();
-
- QScopedPointer<ApplicationInfo> a(yas.scan(singleAppInfoYaml));
- Q_ASSERT(a);
-
- if (!RuntimeFactory::instance()->manager(a->runtimeName())) {
- qCDebug(LogSystem) << "Ignoring application" << a->id() << ", because it uses an unknown runtime:" << a->runtimeName();
- return result;
- }
-
- QStringList aliasPaths = appDir.entryList(QStringList(qSL("info-*.yaml")));
- std::vector<std::unique_ptr<AbstractApplicationInfo>> aliases;
-
- for (int i = 0; i < aliasPaths.size(); ++i) {
- std::unique_ptr<AbstractApplicationInfo> alias(yas.scanAlias(appDir.absoluteFilePath(aliasPaths.at(i)), a.data()));
-
- Q_ASSERT(alias);
- Q_ASSERT(alias->isAlias());
-
- aliases.push_back(std::move(alias));
- }
-
- if (appDir.cdUp()) {
- for (const QString &dir : builtinAppsDirs) {
- if (appDir == QDir(dir)) {
- a->setBuiltIn(true);
- break;
- }
- }
- }
-
- result << a.take();
- for (auto &&alias : aliases)
- result << alias.release();
-
- return result;
-}
-
-QVector<AbstractApplicationInfo *> Main::scanForApplications(const QStringList &builtinAppsDirs, const QString &installedAppsDir,
- const QVector<InstallationLocation> &installationLocations) Q_DECL_NOEXCEPT_EXPR(false)
-{
- QVector<AbstractApplicationInfo *> result;
- YamlApplicationScanner yas;
-
- auto scan = [&result, &yas, &installationLocations](const QDir &baseDir, bool scanningBuiltinApps) {
- auto flags = scanningBuiltinApps ? QDir::Dirs | QDir::NoDotAndDotDot
- : QDir::Dirs | QDir::NoDotAndDotDot | QDir::NoSymLinks;
- const QStringList appDirNames = baseDir.entryList(flags);
-
- for (const QString &appDirName : appDirNames) {
- if (appDirName.endsWith('+') || appDirName.endsWith('-'))
- continue;
- QString appIdError;
- if (!AbstractApplicationInfo::isValidApplicationId(appDirName, false, &appIdError)) {
- qCDebug(LogSystem) << "Ignoring application directory" << appDirName
- << ": not a valid application-id:" << qPrintable(appIdError);
- continue;
- }
- QDir appDir = baseDir.absoluteFilePath(appDirName);
- if (!appDir.exists())
- continue;
- if (!appDir.exists(qSL("info.yaml"))) {
- qCDebug(LogSystem) << "Couldn't find a info.yaml in:" << appDir;
- continue;
- }
- if (!scanningBuiltinApps && !appDir.exists(qSL("installation-report.yaml")))
- continue;
-
- QScopedPointer<ApplicationInfo> a(yas.scan(appDir.absoluteFilePath(qSL("info.yaml"))));
- Q_ASSERT(a);
-
- AbstractRuntimeManager *runtimeManager = RuntimeFactory::instance()->manager(a->runtimeName());
- if (!runtimeManager) {
- qCDebug(LogSystem) << "Ignoring application" << a->id() << ", because it uses an unknown runtime:" << a->runtimeName();
- continue;
- }
- if (runtimeManager->supportsQuickLaunch()) {
- if (a->supportsApplicationInterface())
- qCDebug(LogSystem) << "Ignoring supportsApplicationInterface for application" << a->id() <<
- "as the runtime launcher supports it by default";
- a->setSupportsApplicationInterface(true);
- }
- if (a->id() != appDirName) {
- throw Exception(Error::Parse, "an info.yaml for built-in applications must be in a directory "
- "that has the same name as the application's id: found %1 in %2")
- .arg(a->id(), appDirName);
- }
- if (scanningBuiltinApps) {
- a->setBuiltIn(true);
- QStringList aliasPaths = appDir.entryList(QStringList(qSL("info-*.yaml")));
- std::vector<std::unique_ptr<AbstractApplicationInfo>> aliases;
-
- for (int i = 0; i < aliasPaths.size(); ++i) {
- std::unique_ptr<AbstractApplicationInfo> alias(yas.scanAlias(appDir.absoluteFilePath(aliasPaths.at(i)), a.data()));
-
- Q_ASSERT(alias);
- Q_ASSERT(alias->isAlias());
-
- aliases.push_back(std::move(alias));
- }
- result << a.take();
- for (auto &&alias : aliases)
- result << alias.release();
- } else { // 3rd-party apps
- QFile f(appDir.absoluteFilePath(qSL("installation-report.yaml")));
- if (!f.open(QFile::ReadOnly))
- continue;
-
- QScopedPointer<InstallationReport> report(new InstallationReport(a->id()));
- if (!report->deserialize(&f))
- continue;
-
-#if !defined(AM_DISABLE_INSTALLER)
- // fix the basedir of the application
- for (const InstallationLocation &il : installationLocations) {
- if (il.id() == report->installationLocationId()) {
- a->setCodeDir(il.installationPath() + a->id());
- break;
- }
- }
-#endif
- a->setInstallationReport(report.take());
- result << a.take();
- }
- }
- };
-
- for (const QString &dir : builtinAppsDirs)
- scan(dir, true);
-#if !defined(AM_DISABLE_INSTALLER)
- if (!installedAppsDir.isEmpty())
- scan(installedAppsDir, false);
-#endif
- return result;
-}
-
QString Main::hardwareId() const
{
static QString hardwareId;
diff --git a/src/main-lib/main.h b/src/main-lib/main.h
index 28838e6e..b7a38cee 100644
--- a/src/main-lib/main.h
+++ b/src/main-lib/main.h
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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
@@ -59,7 +59,6 @@ typedef QApplication MainBase;
typedef QGuiApplication MainBase;
#endif
-#include <QtAppManInstaller/installationlocation.h>
#include <QtAppManSharedMain/sharedmain.h>
#include <QVector>
@@ -71,10 +70,11 @@ class StartupInterface;
QT_BEGIN_NAMESPACE_AM
-class AbstractApplicationInfo;
+class ApplicationInfo;
class StartupTimer;
class ApplicationIPCManager;
-class ApplicationDatabase;
+class PackageDatabase;
+class PackageManager;
class ApplicationManager;
class ApplicationInstaller;
class NotificationManager;
@@ -114,13 +114,10 @@ protected:
void setupRuntimesAndContainers(const QVariantMap &runtimeConfigurations, const QVariantMap &openGLConfiguration,
const QVariantMap &containerConfigurations, const QStringList &containerPluginPaths,
const QStringList &iconThemeSearchPaths, const QString &iconThemeName);
- void setupInstallationLocations(const QVariantList &installationLocations);
- void loadApplicationDatabase(const QString &databasePath, bool recreateDatabase,
- const QString &singleApp) Q_DECL_NOEXCEPT_EXPR(false);
+ void loadPackageDatabase(bool recreateDatabase, const QString &singlePackage) Q_DECL_NOEXCEPT_EXPR(false);
void setupIntents(const QMap<QString, int> &timeouts) Q_DECL_NOEXCEPT_EXPR(false);
void setupSingletons(const QList<QPair<QString, QString>> &containerSelectionConfiguration,
- int quickLaunchRuntimesPerContainer, qreal quickLaunchIdleLoad,
- const QString &singleApp) Q_DECL_NOEXCEPT_EXPR(false);
+ int quickLaunchRuntimesPerContainer, qreal quickLaunchIdleLoad) Q_DECL_NOEXCEPT_EXPR(false);
void setupInstaller(const QStringList &caCertificatePaths,
const std::function<bool(uint *, uint *, uint *)> &userIdSeparation) Q_DECL_NOEXCEPT_EXPR(false);
@@ -145,16 +142,8 @@ private:
void registerDBusObject(QDBusAbstractAdaptor *adaptor, QString dbusName, const char *serviceName,
const char *interfaceName, const char *path) Q_DECL_NOEXCEPT_EXPR(false);
#endif
- static QVector<AbstractApplicationInfo *> scanForApplication(const QString &singleAppInfoYaml,
- const QStringList &builtinAppsDirs) Q_DECL_NOEXCEPT_EXPR(false);
- static QVector<AbstractApplicationInfo *> scanForApplications(const QStringList &builtinAppsDirs,
- const QString &installedAppsDir,
- const QVector<InstallationLocation> &installationLocations) Q_DECL_NOEXCEPT_EXPR(false);
-
- void setupApplicationManagerWithDatabase();
private:
- QVector<InstallationLocation> m_installationLocations;
bool m_isSingleProcessMode = false;
QUrl m_mainQml;
QString m_mainQmlLocalFile;
@@ -162,10 +151,13 @@ private:
QQmlApplicationEngine *m_engine = nullptr;
QQuickView *m_view = nullptr; // only set if we allocate the window ourselves
- QScopedPointer<ApplicationDatabase> m_applicationDatabase;
+ PackageDatabase *m_packageDatabase = nullptr;
+ PackageManager *m_packageManager = nullptr;
ApplicationManager *m_applicationManager = nullptr;
ApplicationIPCManager *m_applicationIPCManager = nullptr;
+#if !defined(AM_DISABLE_INSTALLER)
ApplicationInstaller *m_applicationInstaller = nullptr;
+#endif
NotificationManager *m_notificationManager = nullptr;
IntentServer *m_intentServer = nullptr;
WindowManager *m_windowManager = nullptr;
@@ -176,7 +168,8 @@ private:
bool m_noSecurity = false;
bool m_developmentMode = false;
QStringList m_builtinAppsManifestDirs;
- QString m_installedAppsManifestDir;
+ QString m_installationDir;
+ QString m_documentDir;
};
QT_END_NAMESPACE_AM
diff --git a/src/main-lib/windowframetimer.cpp b/src/main-lib/windowframetimer.cpp
index 11cc342e..c240023e 100644
--- a/src/main-lib/windowframetimer.cpp
+++ b/src/main-lib/windowframetimer.cpp
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/src/main-lib/windowframetimer.h b/src/main-lib/windowframetimer.h
index 098cacff..de9aefcf 100644
--- a/src/main-lib/windowframetimer.h
+++ b/src/main-lib/windowframetimer.h
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/src/manager-lib/abstractcontainer.cpp b/src/manager-lib/abstractcontainer.cpp
index 8827c788..aa444268 100644
--- a/src/manager-lib/abstractcontainer.cpp
+++ b/src/manager-lib/abstractcontainer.cpp
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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
@@ -118,7 +118,7 @@ AbstractContainerProcess *AbstractContainer::process() const
return m_process;
}
-void AbstractContainer::setApplication(AbstractApplication *app)
+void AbstractContainer::setApplication(Application *app)
{
if (app != m_app) {
m_app = app;
@@ -126,12 +126,12 @@ void AbstractContainer::setApplication(AbstractApplication *app)
}
}
-AbstractApplication *AbstractContainer::application() const
+Application *AbstractContainer::application() const
{
return m_app;
}
-AbstractContainer::AbstractContainer(AbstractContainerManager *manager, AbstractApplication *app)
+AbstractContainer::AbstractContainer(AbstractContainerManager *manager, Application *app)
: QObject(manager)
, m_manager(manager)
, m_app(app)
diff --git a/src/manager-lib/abstractcontainer.h b/src/manager-lib/abstractcontainer.h
index 15e7d1f1..435c9eba 100644
--- a/src/manager-lib/abstractcontainer.h
+++ b/src/manager-lib/abstractcontainer.h
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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
@@ -52,7 +52,7 @@
QT_BEGIN_NAMESPACE_AM
-class AbstractApplication;
+class Application;
class AbstractContainer;
class AbstractContainerManager : public QObject
@@ -66,7 +66,7 @@ public:
QString identifier() const;
virtual bool supportsQuickLaunch() const;
- virtual AbstractContainer *create(AbstractApplication *app, const QVector<int> &stdioRedirections,
+ virtual AbstractContainer *create(Application *app, const QVector<int> &stdioRedirections,
const QMap<QString, QString> &debugWrapperEnvironment,
const QStringList &debugWrapperCommand) = 0;
@@ -124,17 +124,17 @@ public:
AbstractContainerProcess *process() const;
- void setApplication(AbstractApplication *app);
- AbstractApplication *application() const;
+ void setApplication(Application *app);
+ Application *application() const;
signals:
void ready();
void memoryLowWarning();
void memoryCriticalWarning();
- void applicationChanged(AbstractApplication *newApplication);
+ void applicationChanged(Application *newApplication);
protected:
- explicit AbstractContainer(AbstractContainerManager *manager, AbstractApplication *app);
+ explicit AbstractContainer(AbstractContainerManager *manager, Application *app);
QVariantMap configuration() const;
@@ -142,7 +142,7 @@ protected:
QString m_baseDirectory;
AbstractContainerManager *m_manager;
AbstractContainerProcess *m_process = nullptr;
- AbstractApplication *m_app;
+ Application *m_app;
};
QT_END_NAMESPACE_AM
diff --git a/src/manager-lib/abstractruntime.cpp b/src/manager-lib/abstractruntime.cpp
index 1c4ba03f..ec34aabd 100644
--- a/src/manager-lib/abstractruntime.cpp
+++ b/src/manager-lib/abstractruntime.cpp
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/src/manager-lib/abstractruntime.h b/src/manager-lib/abstractruntime.h
index 8276be47..ef70120b 100644
--- a/src/manager-lib/abstractruntime.h
+++ b/src/manager-lib/abstractruntime.h
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/src/manager-lib/amnamespace.h b/src/manager-lib/amnamespace.h
index f407da90..c144f96b 100644
--- a/src/manager-lib/amnamespace.h
+++ b/src/manager-lib/amnamespace.h
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/src/manager-lib/application.cpp b/src/manager-lib/application.cpp
index bc2c7e4f..432cc86e 100644
--- a/src/manager-lib/application.cpp
+++ b/src/manager-lib/application.cpp
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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
@@ -43,14 +43,12 @@
#include "application.h"
#include "abstractruntime.h"
#include "applicationinfo.h"
+#include "package.h"
#include "exception.h"
#include "logging.h"
#include <QDebug>
-#if defined(Q_OS_UNIX)
-# include <signal.h>
-#endif
/*!
\qmltype ApplicationObject
@@ -90,9 +88,12 @@
/*!
\qmlproperty string ApplicationObject::documentUrl
\readonly
+ \obsolete
- This property always returns the default \c documentUrl specified in the manifest file, even if
- a different URL was used to start the application.
+ This was used to distinguish between application aliases, which have been replaced by the
+ intents mechanism.
+
+ Always returns an empty string.
*/
/*!
\qmlproperty bool ApplicationObject::builtIn
@@ -104,22 +105,22 @@
/*!
\qmlproperty bool ApplicationObject::alias
\readonly
+ \obsolete
- Will return \c true if this ApplicationObject object is an alias to another one.
+ This was used to distinguish between application aliases, which have been replaced by the
+ intents mechanism.
- \sa nonAliased
+ Always returns \c false.
*/
/*!
\qmlproperty ApplicationObject ApplicationObject::nonAliased
\readonly
+ \obsolete
- If this ApplicationObject is an alias, then you can access the non-alias, base ApplicationObject
- via this property, otherwise it contains a reference to itself. This means that if you're interested
- in accessing the base application regardless of whether the object at hand is just an alias, you
- can always safely refer to this property.
+ This was used to distinguish between application aliases, which have been replaced by the
+ intents mechanism.
- If you want to know whether this object is an alias or a base ApplicationObject, use
- ApplicationObject::alias instead.
+ Always returns the object itself.
*/
/*!
\qmlproperty list<string> ApplicationObject::capabilities
@@ -190,10 +191,7 @@
\qmlproperty string ApplicationObject::codeDir
\readonly
- The absolute path to the application's installation directory. Please note this directory might
- not always be available for applications that were installed onto removable media.
-
- \sa {Installation Locations}
+ The absolute path to the application's installation directory.
*/
/*!
\qmlproperty enumeration ApplicationObject::state
@@ -272,237 +270,162 @@
QT_BEGIN_NAMESPACE_AM
+
///////////////////////////////////////////////////////////////////////////////////////////////////
-// AbstractApplication
+// Application
///////////////////////////////////////////////////////////////////////////////////////////////////
-AbstractApplication::AbstractApplication(AbstractApplicationInfo *info)
+Application::Application(ApplicationInfo *info, Package *package)
: m_info(info)
+ , m_package(package)
{
+ Q_ASSERT(info);
+ Q_ASSERT(package);
+
+ // handle package blocking: all apps have to be stopped and the stop state has to be reported
+ // back to the package
+ connect(package, &Package::blockedChanged, this, [this](bool blocked) {
+ emit blockedChanged(blocked);
+ if (blocked && (runState() == Am::NotRunning))
+ this->package()->applicationStoppedDueToBlock(id());
+ else if (blocked)
+ stop(true);
+ });
+ connect(this, &Application::runStateChanged, this, [this](Am::RunState runState) {
+ if (isBlocked() && (runState == Am::NotRunning))
+ this->package()->applicationStoppedDueToBlock(id());
+ });
}
-QString AbstractApplication::id() const
+bool Application::start(const QString &documentUrl)
{
- return m_info->id();
+ if (requests.startRequested)
+ return requests.startRequested(documentUrl);
+ else
+ return false;
}
-QUrl AbstractApplication::icon() const
+bool Application::debug(const QString &debugWrapper, const QString &documentUrl)
{
- if (info()->icon().isEmpty())
- return QUrl();
-
- auto appInfo = this->nonAliasedInfo();
- QDir dir;
- switch (state()) {
- default:
- case Installed:
- dir.setPath(appInfo->manifestDir());
- break;
- case BeingInstalled:
- case BeingUpdated:
- dir.setPath(appInfo->codeDir().absolutePath() + QLatin1Char('+'));
- break;
- case BeingRemoved:
- dir.setPath(appInfo->codeDir().absolutePath() + QLatin1Char('-'));
- break;
- }
- return QUrl::fromLocalFile(dir.absoluteFilePath(info()->icon()));
+ if (requests.debugRequested)
+ return requests.debugRequested(debugWrapper, documentUrl);
+ else
+ return false;
}
-QString AbstractApplication::documentUrl() const
+void Application::stop(bool forceKill)
{
- return info()->documentUrl();
+ if (requests.stopRequested)
+ requests.stopRequested(forceKill);
}
-bool AbstractApplication::isBuiltIn() const
+ApplicationInfo *Application::info() const
{
- return nonAliasedInfo()->isBuiltIn();
+ return m_info.data();
}
-bool AbstractApplication::isAlias() const
+PackageInfo *Application::packageInfo() const
{
- return info()->isAlias();
+ return m_info->packageInfo();
}
-QStringList AbstractApplication::capabilities() const
+Package *Application::package() const
{
- return nonAliasedInfo()->capabilities();
+ return m_package;
}
-QStringList AbstractApplication::supportedMimeTypes() const
+QString Application::id() const
{
- return nonAliasedInfo()->supportedMimeTypes();
+ return m_info->id();
}
-QStringList AbstractApplication::categories() const
+bool Application::isBuiltIn() const
{
- return nonAliasedInfo()->categories();
+ return packageInfo()->isBuiltIn();
}
-QVariantMap AbstractApplication::applicationProperties() const
+QString Application::runtimeName() const
{
- return info()->applicationProperties();
+ return m_info->runtimeName();
}
-bool AbstractApplication::supportsApplicationInterface() const
+QVariantMap Application::runtimeParameters() const
{
- return nonAliasedInfo()->supportsApplicationInterface();
+ return m_info->runtimeParameters();
}
-QString AbstractApplication::version() const
+QStringList Application::capabilities() const
{
- return nonAliasedInfo()->version();
+ return m_info->capabilities();
}
-QString AbstractApplication::codeDir() const
+QStringList Application::categories() const
{
- switch (state()) {
- default:
- case Installed:
- return nonAliasedInfo()->codeDir().absolutePath();
- case BeingInstalled:
- case BeingUpdated:
- return nonAliasedInfo()->codeDir().absolutePath() + QLatin1Char('+');
- case BeingRemoved:
- return nonAliasedInfo()->codeDir().absolutePath() + QLatin1Char('-');
- }
+ return package()->categories();
}
-QString AbstractApplication::name(const QString &language) const
+QUrl Application::icon() const
{
- return info()->name(language);
+ return package()->icon();
}
-bool AbstractApplication::start(const QString &documentUrl)
+QStringList Application::supportedMimeTypes() const
{
- if (requests.startRequested)
- return requests.startRequested(documentUrl);
- else
- return false;
+ return info()->supportedMimeTypes();
}
-bool AbstractApplication::debug(const QString &debugWrapper, const QString &documentUrl)
+QString Application::name() const
{
- if (requests.debugRequested)
- return requests.debugRequested(debugWrapper, documentUrl);
- else
- return false;
+ return package()->name();
}
-void AbstractApplication::stop(bool forceKill)
+QString Application::name(const QString &language) const
{
- if (requests.stopRequested)
- requests.stopRequested(forceKill);
+ return package()->names().value(language).toString();
}
-QVector<AbstractApplication *> AbstractApplication::fromApplicationInfoVector(
- QVector<AbstractApplicationInfo *> &appInfoVector)
+bool Application::isBlocked() const
{
- QVector<AbstractApplication *> apps;
-
- auto findAppWithId = [&apps] (const QString &id) -> AbstractApplication*
- {
- for (AbstractApplication *app : apps) {
- if (app->id() == id)
- return app;
- }
- return nullptr;
- };
-
- auto extractBaseId = [] (const QString &id) -> QString
- {
- return id.section(qL1C('@'), 0, 0);
- };
-
- for (auto *appInfo : appInfoVector) {
- QScopedPointer<AbstractApplication> app;
- if (appInfo->isAlias()) {
- auto *originalApp = findAppWithId(extractBaseId(appInfo->id()));
- if (!originalApp)
- throw Exception(Error::Parse, "Could not find base app for alias id %2").arg(appInfo->id());
- Q_ASSERT(!originalApp->isAlias());
- app.reset(new ApplicationAlias(static_cast<Application*>(originalApp),
- static_cast<ApplicationAliasInfo*>(appInfo)));
- } else {
- AbstractApplication *otherAbsApp = findAppWithId(appInfo->id());
- if (otherAbsApp) {
- // There's already another ApplicationInfo with the same id. It's probably an update for a
- // built-in app, in which case we use the same Application instance to hold both
- // ApplicationInfo instances.
- bool merged = false;
-
- if (!otherAbsApp->isAlias()) {
- auto otherApp = static_cast<Application*>(otherAbsApp);
- auto fullAppInfo = static_cast<ApplicationInfo*>(appInfo);
- if (otherApp->isBuiltIn() && !fullAppInfo->isBuiltIn() && !otherApp->updatedInfo()) {
- otherApp->setUpdatedInfo(static_cast<ApplicationInfo*>(appInfo));
- merged = true;
- } else if (!otherApp->isBuiltIn() && fullAppInfo->isBuiltIn() && !otherApp->updatedInfo()) {
- auto currentBaseInfo = otherApp->takeBaseInfo();
- otherApp->setBaseInfo(static_cast<ApplicationInfo*>(appInfo));
- otherApp->setUpdatedInfo(currentBaseInfo);
- merged = true;
- }
- }
-
- if (!merged)
- qCWarning(LogSystem).nospace() << "Found a second application with id "
- << appInfo->id() << " which is not an update for a built-in one. Ignoring it.";
- } else {
- app.reset(new Application(static_cast<ApplicationInfo*>(appInfo)));
- }
- }
-
- if (!app.isNull())
- apps << app.take();
- }
-
- return apps;
+ return package()->isBlocked();
}
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// Application
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-Application::Application(ApplicationInfo *info, State initialState)
- : AbstractApplication(info)
- , m_state(initialState)
+QVariantMap Application::applicationProperties() const
{
+ return info()->applicationProperties();
}
-void Application::setCurrentRuntime(AbstractRuntime *rt)
+bool Application::supportsApplicationInterface() const
{
- if (m_runtime == rt)
- return;
-
- if (m_runtime)
- disconnect(m_runtime, nullptr, this, nullptr);
-
- m_runtime = rt;
- emit runtimeChanged();
+ return info()->supportsApplicationInterface();
+}
- if (m_runtime) {
- connect(m_runtime, &AbstractRuntime::finished, this, &Application::setLastExitCodeAndStatus);
- connect(m_runtime, &QObject::destroyed, this, [this]() {
- this->setCurrentRuntime(nullptr);
- });
- } else
- setRunState(Am::NotRunning);
+QString Application::codeDir() const
+{
+ switch (package()->state()) {
+ default:
+ case Package::Installed:
+ return packageInfo()->baseDir().absolutePath();
+ case Package::BeingInstalled:
+ case Package::BeingUpdated:
+ return packageInfo()->baseDir().absolutePath() + QLatin1Char('+');
+ case Package::BeingRemoved:
+ return packageInfo()->baseDir().absolutePath() + QLatin1Char('-');
+ }
}
-bool Application::isBlocked() const
+QString Application::version() const
{
- return m_blocked.load() == 1;
+ return packageInfo()->version();
}
-bool Application::block()
+Application::State Application::state() const
{
- return m_blocked.testAndSetOrdered(0, 1);
+ return static_cast<State>(package()->state());
}
-bool Application::unblock()
+qreal Application::progress() const
{
- return m_blocked.testAndSetOrdered(1, 0);
+ return package()->progress();
}
void Application::setRunState(Am::RunState runState)
@@ -513,24 +436,25 @@ void Application::setRunState(Am::RunState runState)
}
}
-QString Application::runtimeName() const
+void Application::setCurrentRuntime(AbstractRuntime *runtime)
{
- return Application::nonAliasedInfo()->runtimeName();
-}
+ if (m_runtime == runtime)
+ return;
-QVariantMap Application::runtimeParameters() const
-{
- return Application::nonAliasedInfo()->runtimeParameters();
-}
+ if (m_runtime)
+ disconnect(m_runtime, nullptr, this, nullptr);
-AbstractApplicationInfo *Application::info() const
-{
- return m_updatedInfo ? m_updatedInfo.data() : m_info.data();
-}
+ m_runtime = runtime;
+ emit runtimeChanged();
-ApplicationInfo *Application::nonAliasedInfo() const
-{
- return static_cast<ApplicationInfo*>(Application::info());
+ if (m_runtime) {
+ connect(m_runtime, &AbstractRuntime::finished, this, &Application::setLastExitCodeAndStatus);
+ connect(m_runtime, &QObject::destroyed, this, [this]() {
+ this->setCurrentRuntime(nullptr);
+ });
+ } else {
+ setRunState(Am::NotRunning);
+ }
}
void Application::setLastExitCodeAndStatus(int exitCode, Am::ExitStatus exitStatus)
@@ -540,88 +464,15 @@ void Application::setLastExitCodeAndStatus(int exitCode, Am::ExitStatus exitStat
emit lastExitCodeChanged();
}
- Am::ExitStatus newStatus;
- if (exitStatus == Am::CrashExit) {
-#if defined(Q_OS_UNIX)
- newStatus = (exitCode == SIGTERM || exitCode == SIGKILL) ? Am::ForcedExit : Am::CrashExit;
-#else
- newStatus = Am::CrashExit;
-#endif
- } else {
- newStatus = Am::NormalExit;
- }
-
- if (m_lastExitStatus != newStatus) {
- m_lastExitStatus = newStatus;
+ if (m_lastExitStatus != exitStatus) {
+ m_lastExitStatus = exitStatus;
emit lastExitStatusChanged();
}
}
-void Application::setBaseInfo(ApplicationInfo *info)
-{
- m_info.reset(info);
- emit bulkChange();
-}
-
-ApplicationInfo *Application::takeBaseInfo()
-{
- return static_cast<ApplicationInfo*>(m_info.take());
-}
-
-void Application::setUpdatedInfo(ApplicationInfo* info)
-{
- Q_ASSERT(!info || (m_info && info->id() == m_info->id()));
-
- m_updatedInfo.reset(info);
- emit bulkChange();
-}
-
-void Application::setState(State state)
-{
- if (m_state != state) {
- m_state = state;
- emit stateChanged(m_state);
- }
-}
-
-void Application::setProgress(qreal value)
-{
- m_progress = value;
-}
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// ApplicationAlias
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-ApplicationAlias::ApplicationAlias(Application* app, ApplicationAliasInfo* info)
- : AbstractApplication(info)
- , m_application(app)
-{
- connect(m_application, &AbstractApplication::runtimeChanged, this, &AbstractApplication::runtimeChanged);
- connect(m_application, &AbstractApplication::lastExitCodeChanged, this, &AbstractApplication::lastExitCodeChanged);
- connect(m_application, &AbstractApplication::lastExitStatusChanged, this, &AbstractApplication::lastExitStatusChanged);
- connect(m_application, &AbstractApplication::stateChanged, this, &AbstractApplication::stateChanged);
- connect(m_application, &AbstractApplication::runStateChanged, this, &AbstractApplication::runStateChanged);
-}
-
-QString ApplicationAlias::runtimeName() const
-{
- return m_application->runtimeName();
-}
-
-QVariantMap ApplicationAlias::runtimeParameters() const
-{
- return m_application->runtimeParameters();
-}
-
-ApplicationInfo *ApplicationAlias::nonAliasedInfo() const
-{
- return m_application->nonAliasedInfo();
-}
-
QT_END_NAMESPACE_AM
-QDebug operator<<(QDebug debug, const QT_PREPEND_NAMESPACE_AM(AbstractApplication) *app)
+QDebug operator<<(QDebug debug, const QT_PREPEND_NAMESPACE_AM(Application) *app)
{
debug << "Application Object:";
if (app)
diff --git a/src/manager-lib/application.h b/src/manager-lib/application.h
index 0b081329..9556cc3e 100644
--- a/src/manager-lib/application.h
+++ b/src/manager-lib/application.h
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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
@@ -44,15 +44,16 @@
#include <QObject>
#include <QScopedPointer>
+#include <QVariantMap>
#include <QUrl>
#include <QtAppManApplication/applicationinfo.h>
+#include <QtAppManApplication/packageinfo.h>
#include <QtAppManManager/amnamespace.h>
#include <QtAppManCommon/global.h>
QT_BEGIN_NAMESPACE_AM
class AbstractRuntime;
-class Application;
// A place to collect functions used internally by appman without polluting
// Application's public QML API.
@@ -64,7 +65,9 @@ public:
std::function<void(bool forceKill)> stopRequested;
};
-class AbstractApplication : public QObject
+class Package;
+
+class Application : public QObject
{
Q_OBJECT
Q_CLASSINFO("AM-QmlType", "QtApplicationManager.SystemUI/ApplicationObject 2.0 UNCREATABLE")
@@ -73,12 +76,12 @@ class AbstractApplication : public QObject
Q_PROPERTY(QString runtimeName READ runtimeName NOTIFY bulkChange)
Q_PROPERTY(QVariantMap runtimeParameters READ runtimeParameters NOTIFY bulkChange)
Q_PROPERTY(QUrl icon READ icon NOTIFY bulkChange)
- Q_PROPERTY(QString documentUrl READ documentUrl NOTIFY bulkChange)
- Q_PROPERTY(bool builtIn READ isBuiltIn CONSTANT)
- Q_PROPERTY(bool alias READ isAlias CONSTANT)
- Q_PROPERTY(Application* nonAliased READ nonAliased CONSTANT)
+ Q_PROPERTY(QString documentUrl READ documentUrl NOTIFY bulkChange) // REMOVE
+ Q_PROPERTY(bool builtIn READ isBuiltIn NOTIFY bulkChange)
+ Q_PROPERTY(bool alias READ isAlias CONSTANT) // REMOVE
+ Q_PROPERTY(Application *nonAliased READ nonAliased CONSTANT) // REMOVE
Q_PROPERTY(QStringList capabilities READ capabilities NOTIFY bulkChange)
- Q_PROPERTY(QStringList supportedMimeTypes READ supportedMimeTypes NOTIFY bulkChange)
+ Q_PROPERTY(QStringList supportedMimeTypes READ supportedMimeTypes NOTIFY bulkChange) // REMOVE
Q_PROPERTY(QStringList categories READ categories NOTIFY bulkChange)
Q_PROPERTY(QVariantMap applicationProperties READ applicationProperties NOTIFY bulkChange)
Q_PROPERTY(AbstractRuntime *runtime READ currentRuntime NOTIFY runtimeChanged)
@@ -89,9 +92,10 @@ class AbstractApplication : public QObject
Q_PROPERTY(QString codeDir READ codeDir NOTIFY bulkChange)
Q_PROPERTY(State state READ state NOTIFY stateChanged)
Q_PROPERTY(QT_PREPEND_NAMESPACE_AM(Am::RunState) runState READ runState NOTIFY runStateChanged)
+ Q_PROPERTY(bool blocked READ isBlocked NOTIFY blockedChanged)
public:
- enum State {
+ enum State { // kept for compatibility ... in reality moved to class Package
Installed,
BeingInstalled,
BeingUpdated,
@@ -100,62 +104,51 @@ public:
};
Q_ENUM(State)
- AbstractApplication(AbstractApplicationInfo *info);
+ Application(ApplicationInfo *info, Package *package);
Q_INVOKABLE bool start(const QString &documentUrl = QString());
Q_INVOKABLE bool debug(const QString &debugWrapper, const QString &documentUrl = QString());
Q_INVOKABLE void stop(bool forceKill = false);
- virtual Application *nonAliased() = 0;
-
- /*
- Returns information about this application, which can either
- be a full-fledged one (ApplicationInfo) or just an alias
- (ApplicationAliasInfo).
-
- Use info()->isAlias() to check and cast as appropriate.
- */
- virtual AbstractApplicationInfo *info() const = 0;
+ ApplicationInfo *info() const;
+ PackageInfo *packageInfo() const;
+ Package *package() const;
- /*
- Always returns information about the "concrete", non-aliased, application.
- This is the same as static_cast<ApplicationInfo*>(nonAliased()->info())
- */
- virtual ApplicationInfo *nonAliasedInfo() const = 0;
+ // legacy compatibility
+ bool isAlias() const { return false; }
+ Application *nonAliased() { return this; }
+ QStringList categories() const;
+ QUrl icon() const;
+ QString documentUrl() const { return QString {}; }
+ QStringList supportedMimeTypes() const;
+ QString name() const;
+ Q_INVOKABLE QString name(const QString &language) const;
+ bool isBlocked() const;
// Properties that mainly forward content from ApplicationInfo
QString id() const;
- virtual QString runtimeName() const = 0;
- virtual QVariantMap runtimeParameters() const = 0;
- QUrl icon() const;
- QString documentUrl() const;
bool isBuiltIn() const;
- bool isAlias() const;
+ QString runtimeName() const;
+ QVariantMap runtimeParameters() const;
QStringList capabilities() const;
- QStringList supportedMimeTypes() const;
- QStringList categories() const;
QVariantMap applicationProperties() const;
bool supportsApplicationInterface() const;
+ QString codeDir() const;
QString version() const;
- Q_INVOKABLE QString name(const QString &language) const;
// Properties present only in Application (not coming from ApplicationInfo)
- virtual AbstractRuntime *currentRuntime() const = 0;
- virtual State state() const = 0;
- QString codeDir() const;
- virtual bool isBlocked() const = 0;
- virtual bool block() = 0;
- virtual bool unblock() = 0;
- virtual qreal progress() const = 0;
- virtual Am::RunState runState() const = 0;
- virtual int lastExitCode() const = 0;
- virtual Am::ExitStatus lastExitStatus() const = 0;
+
+ AbstractRuntime *currentRuntime() const { return m_runtime; }
+ State state() const;
+ qreal progress() const;
+ Am::RunState runState() const { return m_runState; }
+ int lastExitCode() const { return m_lastExitCode; }
+ Am::ExitStatus lastExitStatus() const { return m_lastExitStatus; }
ApplicationRequests requests;
- // Creates a list of Applications from a list of ApplicationInfo objects.
- // Ownership of the given ApplicationInfo objects is passed to the returned Applications.
- static QVector<AbstractApplication *> fromApplicationInfoVector(QVector<AbstractApplicationInfo *> &);
+ void setRunState(Am::RunState runState);
+ void setCurrentRuntime(AbstractRuntime *runtime);
signals:
void bulkChange();
@@ -165,108 +158,24 @@ signals:
void activated();
void stateChanged(State state);
void runStateChanged(Am::RunState state);
-
-protected:
- QScopedPointer<AbstractApplicationInfo> m_info;
-};
-
-class Application : public AbstractApplication
-{
- Q_OBJECT
-public:
- Application(ApplicationInfo *info, State initialState = Installed);
-
-
- // Returns the updated info, if there's one. Otherwise
- // returns the base info.
- AbstractApplicationInfo *info() const override;
-
- // same as info()
- ApplicationInfo *nonAliasedInfo() const override;
-
-
- /*
- All applications have a base info.
-
- Built-in applications, when updated, also get an updated info.
- The updated info then overlays the base one. Subsequent updates
- just replace the updated info. When requested to be removed, a
- built-in application only loses its updated info, returning to
- expose the base one.
-
- Regular applications (ie, non-built-in) only have a base info. When
- updated their base info gets replaced and thus there's no way to go
- back to a previous version. Regular applications get completely
- removed when requested.
- */
- void setBaseInfo(ApplicationInfo*);
- void setUpdatedInfo(ApplicationInfo*);
- ApplicationInfo *updatedInfo() const { return m_updatedInfo.data(); }
- ApplicationInfo *takeBaseInfo();
-
- void setState(State);
- void setProgress(qreal);
- void setRunState(Am::RunState);
- void setCurrentRuntime(AbstractRuntime *rt);
-
- Application *nonAliased() override { return this; }
- QString runtimeName() const override;
- QVariantMap runtimeParameters() const override;
- AbstractRuntime *currentRuntime() const override { return m_runtime; }
- State state() const override { return m_state; }
- bool isBlocked() const override;
- bool block() override;
- bool unblock() override;
- qreal progress() const override { return m_progress; }
- Am::RunState runState() const override { return m_runState; }
- int lastExitCode() const override { return m_lastExitCode; }
- Am::ExitStatus lastExitStatus() const override { return m_lastExitStatus; }
+ void blockedChanged(bool blocked);
private:
void setLastExitCodeAndStatus(int exitCode, Am::ExitStatus exitStatus);
+ QScopedPointer<ApplicationInfo> m_info;
+ Package *m_package = nullptr;
AbstractRuntime *m_runtime = nullptr;
- QAtomicInt m_blocked;
- QAtomicInt m_mounted;
- State m_state = Installed;
Am::RunState m_runState = Am::NotRunning;
- qreal m_progress = 0;
int m_lastExitCode = 0;
Am::ExitStatus m_lastExitStatus = Am::NormalExit;
- QScopedPointer<ApplicationInfo> m_updatedInfo;
-};
-
-class ApplicationAlias : public AbstractApplication
-{
- Q_OBJECT
-public:
- ApplicationAlias(Application*, ApplicationAliasInfo*);
-
- AbstractApplicationInfo *info() const override { return m_info.data(); }
- Application *nonAliased() override { return m_application; }
- QString runtimeName() const override;
- QVariantMap runtimeParameters() const override;
- AbstractRuntime *currentRuntime() const override { return m_application->currentRuntime(); }
- State state() const override { return m_application->state(); }
- bool isBlocked() const override { return m_application->isBlocked(); }
- bool block() override { return m_application->block(); }
- bool unblock() override { return m_application->unblock(); }
- qreal progress() const override { return m_application->progress(); }
- Am::RunState runState() const override { return m_application->runState(); }
- int lastExitCode() const override { return m_application->lastExitCode(); }
- Am::ExitStatus lastExitStatus() const override { return m_application->lastExitStatus(); }
-protected:
- // Returns info() from the application being aliased
- ApplicationInfo *nonAliasedInfo() const override;
-private:
- Application *m_application;
};
QT_END_NAMESPACE_AM
-Q_DECLARE_METATYPE(const QT_PREPEND_NAMESPACE_AM(AbstractApplication *))
+Q_DECLARE_METATYPE(const QT_PREPEND_NAMESPACE_AM(Application *))
-QDebug operator<<(QDebug debug, const QT_PREPEND_NAMESPACE_AM(AbstractApplication) *app);
+QDebug operator<<(QDebug debug, const QT_PREPEND_NAMESPACE_AM(Application) *app);
diff --git a/src/manager-lib/applicationdatabase.cpp b/src/manager-lib/applicationdatabase.cpp
deleted file mode 100644
index a6fb8ef3..00000000
--- a/src/manager-lib/applicationdatabase.cpp
+++ /dev/null
@@ -1,184 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2019 Luxoft Sweden AB
-** Copyright (C) 2018 Pelagicore AG
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the Luxoft Application Manager.
-**
-** $QT_BEGIN_LICENSE:LGPL-QTAS$
-** Commercial License Usage
-** Licensees holding valid commercial Qt Automotive Suite licenses may use
-** this file in accordance with the commercial license agreement provided
-** with the Software or, alternatively, in accordance with the terms
-** contained in a written agreement between you and The Qt Company. For
-** licensing terms and conditions see https://www.qt.io/terms-conditions.
-** For further information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-** SPDX-License-Identifier: LGPL-3.0
-**
-****************************************************************************/
-
-#include <QFile>
-#include <QDataStream>
-#include <QTemporaryFile>
-#include <QScopedPointer>
-
-#include "application.h"
-#include "applicationdatabase.h"
-#include "exception.h"
-#include "logging.h"
-
-QT_BEGIN_NAMESPACE_AM
-
-class ApplicationDatabasePrivate
-{
-public:
- void validateWritableFile()
- {
- if (!file || !file->isOpen() || !file->isWritable())
- throw Exception("application database %1 is not opened for writing").arg(file ? file->fileName() : qSL("<null>"));
- if (!file->seek(0))
- throw Exception(*file, "could not not seek to position 0 in the application database");
- if (!file->resize(0))
- throw Exception(*file, "could not truncate the application database");
- }
-
- QFile *file = nullptr;
-
- ApplicationDatabasePrivate()
- { }
- ~ApplicationDatabasePrivate()
- { delete file; }
-};
-
-ApplicationDatabase::ApplicationDatabase(const QString &fileName)
- : d(new ApplicationDatabasePrivate())
-{
- d->file = new QFile(fileName);
- d->file->open(QFile::ReadWrite);
-}
-
-ApplicationDatabase::ApplicationDatabase()
- : d(new ApplicationDatabasePrivate())
-{
- d->file = new QTemporaryFile(qSL("am-apps-db"));
- d->file->open(QFile::ReadWrite);
-}
-
-ApplicationDatabase::~ApplicationDatabase()
-{
- delete d;
-}
-
-bool ApplicationDatabase::isValid() const
-{
- return d->file && d->file->isOpen();
-}
-
-bool ApplicationDatabase::isTemporary() const
-{
- return qobject_cast<QTemporaryFile *>(d->file);
-}
-
-QString ApplicationDatabase::errorString() const
-{
- return d->file->errorString();
-}
-
-QString ApplicationDatabase::name() const
-{
- return d->file->fileName();
-}
-
-QVector<AbstractApplication *> ApplicationDatabase::read() Q_DECL_NOEXCEPT_EXPR(false)
-{
- if (!d->file || !d->file->isOpen() || !d->file->isReadable())
- throw Exception("application database %1 is not opened for reading").arg(d->file ? d->file->fileName() : qSL("<null>"));
-
- QVector<AbstractApplicationInfo *> appInfoVector;
-
- if (d->file->seek(0)) {
- QDataStream ds(d->file);
- forever {
- QScopedPointer<AbstractApplicationInfo> appInfo(AbstractApplicationInfo::readFromDataStream(ds));
-
- if (ds.status() != QDataStream::Ok) {
- if (ds.status() != QDataStream::ReadPastEnd) {
- qDeleteAll(appInfoVector);
- throw Exception("could not read from application database %1").arg(d->file->fileName());
- }
- break;
- }
-
- appInfoVector.append(appInfo.take());
- }
- }
-
- return AbstractApplication::fromApplicationInfoVector(appInfoVector);
-}
-
-void ApplicationDatabase::write(const QVector<AbstractApplicationInfo *> &apps) Q_DECL_NOEXCEPT_EXPR(false)
-{
- d->validateWritableFile();
-
- QDataStream ds(d->file);
- for (auto *app : apps)
- app->writeToDataStream(ds);
-
- if (ds.status() != QDataStream::Ok)
- throw Exception(*d->file, "could not write to application database");
-}
-
-void ApplicationDatabase::write(const QVector<AbstractApplication *> &apps) Q_DECL_NOEXCEPT_EXPR(false)
-{
- d->validateWritableFile();
-
- QDataStream ds(d->file);
- for (auto *app : apps) {
- app->info()->writeToDataStream(ds);
- if (!app->isAlias()) {
- auto fullApp = static_cast<Application*>(app);
- if (fullApp->updatedInfo())
- fullApp->updatedInfo()->writeToDataStream(ds);
- }
- }
-
- if (ds.status() != QDataStream::Ok)
- throw Exception(*d->file, "could not write to application database");
-
- d->file->flush();
-}
-
-void ApplicationDatabase::invalidate()
-{
- if (d->file) {
- if (d->file->isOpen())
- d->file->close();
- d->file->remove();
- d->file = nullptr;
- }
-}
-
-QT_END_NAMESPACE_AM
diff --git a/src/manager-lib/applicationipcinterface.cpp b/src/manager-lib/applicationipcinterface.cpp
index 9b9ec477..aa08991d 100644
--- a/src/manager-lib/applicationipcinterface.cpp
+++ b/src/manager-lib/applicationipcinterface.cpp
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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
@@ -100,7 +100,7 @@ QString ApplicationIPCInterface::pathName() const
return m_ipcProxy ? m_ipcProxy->pathName() : QString();
}
-bool ApplicationIPCInterface::isValidForApplication(AbstractApplication *app) const
+bool ApplicationIPCInterface::isValidForApplication(Application *app) const
{
return m_ipcProxy ? m_ipcProxy->isValidForApplication(app) : false;
}
@@ -126,7 +126,7 @@ void ApplicationIPCInterface::setServiceObject(QObject *serviceObject)
}
#if defined(QT_DBUS_LIB)
-bool ApplicationIPCInterface::dbusRegister(AbstractApplication *app, QDBusConnection connection, const QString &debugPathPrefix)
+bool ApplicationIPCInterface::dbusRegister(Application *app, QDBusConnection connection, const QString &debugPathPrefix)
{
return m_ipcProxy ? m_ipcProxy->dbusRegister(app, connection, debugPathPrefix) : false;
}
@@ -432,7 +432,7 @@ QStringList IpcProxyObject::connectionNames() const
return m_connectionNamesToApplicationIds.keys();
}
-bool IpcProxyObject::isValidForApplication(AbstractApplication *app) const
+bool IpcProxyObject::isValidForApplication(Application *app) const
{
if (!app)
return false;
@@ -454,7 +454,7 @@ bool IpcProxyObject::isValidForApplication(AbstractApplication *app) const
#if defined(QT_DBUS_LIB)
-bool IpcProxyObject::dbusRegister(AbstractApplication *app, QDBusConnection connection, const QString &debugPathPrefix)
+bool IpcProxyObject::dbusRegister(Application *app, QDBusConnection connection, const QString &debugPathPrefix)
{
if (m_connectionNamesToApplicationIds.contains(connection.name()))
return false;
diff --git a/src/manager-lib/applicationipcinterface.h b/src/manager-lib/applicationipcinterface.h
index 3a1f8aad..bde98536 100644
--- a/src/manager-lib/applicationipcinterface.h
+++ b/src/manager-lib/applicationipcinterface.h
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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
@@ -53,7 +53,7 @@
QT_BEGIN_NAMESPACE_AM
-class AbstractApplication;
+class Application;
class ApplicationIPCInterfaceAttached;
class IpcProxyObject;
@@ -70,12 +70,12 @@ public:
QString interfaceName() const;
QString pathName() const;
- bool isValidForApplication(AbstractApplication *app) const;
+ bool isValidForApplication(Application *app) const;
QObject *serviceObject() const;
void setServiceObject(QObject *serviceObject);
#if defined(QT_DBUS_LIB)
- bool dbusRegister(AbstractApplication *app, QDBusConnection connection, const QString &debugPathPrefix = QString());
+ bool dbusRegister(Application *app, QDBusConnection connection, const QString &debugPathPrefix = QString());
bool dbusUnregister(QDBusConnection connection);
#endif
diff --git a/src/manager-lib/applicationipcinterface_p.h b/src/manager-lib/applicationipcinterface_p.h
index e4828adb..d47c9ec8 100644
--- a/src/manager-lib/applicationipcinterface_p.h
+++ b/src/manager-lib/applicationipcinterface_p.h
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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
@@ -54,7 +54,7 @@
QT_BEGIN_NAMESPACE_AM
-class AbstractApplication;
+class Application;
class IpcProxySignalRelay;
class IpcProxyObject // clazy:exclude=missing-qobject-macro
@@ -75,10 +75,10 @@ public:
QString interfaceName() const;
QStringList connectionNames() const;
- bool isValidForApplication(AbstractApplication *app) const;
+ bool isValidForApplication(Application *app) const;
#if defined(QT_DBUS_LIB)
- bool dbusRegister(AbstractApplication *app, QDBusConnection connection, const QString &debugPathPrefix = QString());
+ bool dbusRegister(Application *app, QDBusConnection connection, const QString &debugPathPrefix = QString());
bool dbusUnregister(QDBusConnection connection);
QString introspect(const QString &path) const override;
diff --git a/src/manager-lib/applicationipcmanager.cpp b/src/manager-lib/applicationipcmanager.cpp
index 2e0767f3..a4d375db 100644
--- a/src/manager-lib/applicationipcmanager.cpp
+++ b/src/manager-lib/applicationipcmanager.cpp
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/src/manager-lib/applicationipcmanager.h b/src/manager-lib/applicationipcmanager.h
index 427a6fef..856078b8 100644
--- a/src/manager-lib/applicationipcmanager.h
+++ b/src/manager-lib/applicationipcmanager.h
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/src/manager-lib/applicationmanager.cpp b/src/manager-lib/applicationmanager.cpp
index 734198bc..523211f3 100644
--- a/src/manager-lib/applicationmanager.cpp
+++ b/src/manager-lib/applicationmanager.cpp
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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
@@ -58,6 +58,7 @@
#include "global.h"
#include "applicationinfo.h"
+#include "installationreport.h"
#include "logging.h"
#include "exception.h"
#include "applicationmanager.h"
@@ -386,9 +387,9 @@ ApplicationManager *ApplicationManager::createInstance(bool singleProcess)
qmlRegisterSingletonType<ApplicationManager>("QtApplicationManager.SystemUI", 2, 0, "ApplicationManager",
&ApplicationManager::instanceForQml);
qmlRegisterType<ApplicationModel>("QtApplicationManager.SystemUI", 2, 0, "ApplicationModel");
- qmlRegisterUncreatableType<AbstractApplication>("QtApplicationManager.SystemUI", 2, 0, "ApplicationObject",
- qSL("Cannot create objects of type ApplicationObject"));
- qRegisterMetaType<AbstractApplication*>("AbstractApplication*");
+ qmlRegisterUncreatableType<Application>("QtApplicationManager.SystemUI", 2, 0, "ApplicationObject",
+ qSL("Cannot create objects of type ApplicationObject"));
+ qRegisterMetaType<Application*>("Application*");
qmlRegisterUncreatableType<AbstractRuntime>("QtApplicationManager.SystemUI", 2, 0, "Runtime",
qSL("Cannot create objects of type Runtime"));
qRegisterMetaType<AbstractRuntime*>("AbstractRuntime*");
@@ -497,27 +498,27 @@ void ApplicationManager::setWindowManagerCompositorReady(bool ready)
}
}
-QVector<AbstractApplication *> ApplicationManager::applications() const
+QVector<Application *> ApplicationManager::applications() const
{
return d->apps;
}
-AbstractApplication *ApplicationManager::fromId(const QString &id) const
+Application *ApplicationManager::fromId(const QString &id) const
{
- for (AbstractApplication *app : d->apps) {
+ for (Application *app : d->apps) {
if (app->id() == id)
return app;
}
return nullptr;
}
-AbstractApplication *ApplicationManager::fromProcessId(qint64 pid) const
+Application *ApplicationManager::fromProcessId(qint64 pid) const
{
// pid could be an indirect child (e.g. when started via gdbserver)
qint64 appmanPid = QCoreApplication::applicationPid();
while ((pid > 1) && (pid != appmanPid)) {
- for (AbstractApplication *app : d->apps) {
+ for (Application *app : d->apps) {
if (app->currentRuntime() && (app->currentRuntime()->applicationProcessId() == pid))
return app;
}
@@ -526,26 +527,23 @@ AbstractApplication *ApplicationManager::fromProcessId(qint64 pid) const
return nullptr;
}
-AbstractApplication *ApplicationManager::fromSecurityToken(const QByteArray &securityToken) const
+Application *ApplicationManager::fromSecurityToken(const QByteArray &securityToken) const
{
if (securityToken.size() != AbstractRuntime::SecurityTokenSize)
return nullptr;
- for (AbstractApplication *app : d->apps) {
+ for (Application *app : d->apps) {
if (app->currentRuntime() && app->currentRuntime()->securityToken() == securityToken)
return app;
}
return nullptr;
}
-QVector<AbstractApplication *> ApplicationManager::schemeHandlers(const QString &scheme) const
+QVector<Application *> ApplicationManager::schemeHandlers(const QString &scheme) const
{
- QVector<AbstractApplication *> handlers;
-
- for (AbstractApplication *app : d->apps) {
- if (app->isAlias())
- continue;
+ QVector<Application *> handlers;
+ for (Application *app : d->apps) {
const auto mimeTypes = app->supportedMimeTypes();
for (const QString &mime : mimeTypes) {
int pos = mime.indexOf(QLatin1Char('/'));
@@ -560,14 +558,11 @@ QVector<AbstractApplication *> ApplicationManager::schemeHandlers(const QString
return handlers;
}
-QVector<AbstractApplication *> ApplicationManager::mimeTypeHandlers(const QString &mimeType) const
+QVector<Application *> ApplicationManager::mimeTypeHandlers(const QString &mimeType) const
{
- QVector<AbstractApplication *> handlers;
-
- for (AbstractApplication *app : d->apps) {
- if (app->isAlias())
- continue;
+ QVector<Application *> handlers;
+ for (Application *app : d->apps) {
if (app->supportedMimeTypes().contains(mimeType))
handlers << app;
}
@@ -580,10 +575,7 @@ void ApplicationManager::registerMimeTypes()
QSet<QString> schemes;
schemes << qSL("file") << qSL("http") << qSL("https");
- for (AbstractApplication *app : qAsConst(d->apps)) {
- if (app->isAlias())
- continue;
-
+ for (Application *app : qAsConst(d->apps)) {
const auto mimeTypes = app->supportedMimeTypes();
for (const QString &mime : mimeTypes) {
int pos = mime.indexOf(QLatin1Char('/'));
@@ -613,14 +605,12 @@ bool ApplicationManager::startApplicationInternal(const QString &appId, const QS
{
if (d->shuttingDown)
throw Exception("Cannot start applications during shutdown");
- AbstractApplication *app = fromId(appId);
+ Application *app = fromId(appId);
if (!app)
throw Exception("Cannot start application: id '%1' is not known").arg(appId);
if (app->isBlocked())
throw Exception("Application %1 is blocked - cannot start").arg( app->id());
- Application* realApp = app->nonAliased();
-
AbstractRuntime *runtime = app->currentRuntime();
auto runtimeManager = runtime ? runtime->manager() : RuntimeFactory::instance()->manager(app->runtimeName());
if (!runtimeManager)
@@ -668,7 +658,6 @@ bool ApplicationManager::startApplicationInternal(const QString &appId, const QS
throw Exception("Application %1 is already running - cannot start with debug-wrapper: %2")
.arg(app->id(), debugWrapperSpecification);
}
-
if (!documentUrl.isNull())
runtime->openDocument(documentUrl, documentMimeType);
else if (!app->documentUrl().isNull())
@@ -732,7 +721,7 @@ bool ApplicationManager::startApplicationInternal(const QString &appId, const QS
cannotUseQuickLaunch = "standard I/O is redirected";
else if (!app->runtimeParameters().value(qSL("environmentVariables")).toMap().isEmpty())
cannotUseQuickLaunch = "the app requests customs environment variables";
- else if (app->nonAliasedInfo()->openGLConfiguration() != runtimeManager->systemOpenGLConfiguration())
+ else if (app->info()->openGLConfiguration() != runtimeManager->systemOpenGLConfiguration())
cannotUseQuickLaunch = "the app requests a custom OpenGL configuration";
if (cannotUseQuickLaunch) {
@@ -741,12 +730,12 @@ bool ApplicationManager::startApplicationInternal(const QString &appId, const QS
} else {
// check quicklaunch pool
QPair<AbstractContainer *, AbstractRuntime *> quickLaunch =
- QuickLauncher::instance()->take(containerId, app->nonAliasedInfo()->runtimeName());
+ QuickLauncher::instance()->take(containerId, app->info()->runtimeName());
container = quickLaunch.first;
runtime = quickLaunch.second;
qCDebug(LogSystem) << "Found a quick-launch entry for container" << containerId
- << "and runtime" << app->nonAliasedInfo()->runtimeName() << "->" << container << runtime;
+ << "and runtime" << app->info()->runtimeName() << "->" << container << runtime;
if (!container && runtime) {
runtime->deleteLater();
@@ -769,7 +758,7 @@ bool ApplicationManager::startApplicationInternal(const QString &appId, const QS
attachRuntime = true;
}
if (!runtime)
- runtime = RuntimeFactory::instance()->create(container, realApp);
+ runtime = RuntimeFactory::instance()->create(container, app);
if (runtime)
emit internalSignals.newRuntimeCreated(runtime);
@@ -781,27 +770,9 @@ bool ApplicationManager::startApplicationInternal(const QString &appId, const QS
}
connect(runtime, &AbstractRuntime::stateChanged, this, [this, app](Am::RunState newRuntimeState) {
- QVector<AbstractApplication *> apps;
- //Always emit the actual starting app/alias first
- apps.append(app);
-
- //Add the original app and all aliases
- AbstractApplication *nonAliasedApp = app->nonAliased();
-
- if (!apps.contains(nonAliasedApp))
- apps.append(nonAliasedApp);
-
- for (AbstractApplication *alias : qAsConst(d->apps)) {
- if (!apps.contains(alias) && alias->isAlias() && alias->nonAliased() == nonAliasedApp)
- apps.append(alias);
- }
-
- static_cast<Application*>(nonAliasedApp)->setRunState(newRuntimeState);
-
- for (AbstractApplication *app : qAsConst(apps)) {
- emit applicationRunStateChanged(app->id(), newRuntimeState);
- emitDataChanged(app, QVector<int> { IsRunning, IsStartingUp, IsShuttingDown });
- }
+ app->setRunState(newRuntimeState);
+ emit applicationRunStateChanged(app->id(), newRuntimeState);
+ emitDataChanged(app, QVector<int> { IsRunning, IsStartingUp, IsShuttingDown });
});
if (!documentUrl.isNull())
@@ -826,11 +797,11 @@ bool ApplicationManager::startApplicationInternal(const QString &appId, const QS
// Using a state-machine would be one option, but then we would need that state-machine
// object plus the per-app state. Relying on 2 lambdas is the easier choice for now.
- auto doStartInContainer = [realApp, attachRuntime, runtime]() -> bool {
- bool successfullyStarted = attachRuntime ? runtime->attachApplicationToQuickLauncher(realApp)
+ auto doStartInContainer = [app, attachRuntime, runtime]() -> bool {
+ bool successfullyStarted = attachRuntime ? runtime->attachApplicationToQuickLauncher(app)
: runtime->start();
if (!successfullyStarted)
- runtime->deleteLater(); // ~Runtime() will clean realApp->m_runtime
+ runtime->deleteLater(); // ~Runtime() will clean app->m_runtime
return successfullyStarted;
};
@@ -866,7 +837,7 @@ bool ApplicationManager::startApplicationInternal(const QString &appId, const QS
}
}
-void ApplicationManager::stopApplicationInternal(AbstractApplication *app, bool forceKill)
+void ApplicationManager::stopApplicationInternal(Application *app, bool forceKill)
{
if (!app)
return;
@@ -950,12 +921,10 @@ void ApplicationManager::stopApplication(const QString &id, bool forceKill)
*/
void ApplicationManager::stopAllApplications(bool forceKill)
{
- for (AbstractApplication *app : qAsConst(d->apps)) {
- if (!app->isAlias()) {
- AbstractRuntime *rt = app->currentRuntime();
- if (rt)
- rt->stop(forceKill);
- }
+ for (Application *app : qAsConst(d->apps)) {
+ AbstractRuntime *rt = app->currentRuntime();
+ if (rt)
+ rt->stop(forceKill);
}
}
@@ -1000,6 +969,8 @@ void ApplicationManager::stopAllApplications(bool forceKill)
*/
bool ApplicationManager::openUrl(const QString &urlStr)
{
+ //TODO: relay to a well-known Intent call
+
// QDesktopServices::openUrl has a special behavior when called recursively, which makes sense
// on the desktop, but is completely counter-productive for the AM.
static bool recursionGuard = false;
@@ -1011,28 +982,13 @@ bool ApplicationManager::openUrl(const QString &urlStr)
QUrl url(urlStr);
QString mimeTypeName;
- QVector<AbstractApplication *> apps;
+ QVector<Application *> apps;
if (url.isValid()) {
QString scheme = url.scheme();
- if (scheme != qL1S("file")) {
+ if (scheme != qL1S("file"))
apps = schemeHandlers(scheme);
- for (auto it = apps.begin(); it != apps.end(); ++it) {
- AbstractApplication *&app = *it;
-
- // try to find a better matching alias, if available
- for (AbstractApplication *alias : d->apps) {
- if (alias->isAlias() && alias->nonAliased() == app) {
- if (url.toString(QUrl::PrettyDecoded) == alias->documentUrl()) {
- app = alias;
- break;
- }
- }
- }
- }
- }
-
if (apps.isEmpty()) {
QMimeDatabase mdb;
QMimeType mt = mdb.mimeTypeForUrl(url);
@@ -1054,9 +1010,9 @@ bool ApplicationManager::openUrl(const QString &urlStr)
} else {
ApplicationManagerPrivate::OpenUrlRequest req {
QUuid::createUuid().toString(),
- urlStr,
- mimeTypeName,
- QStringList()
+ urlStr,
+ mimeTypeName,
+ QStringList()
};
for (const auto &app : qAsConst(apps))
req.possibleAppIds << app->id();
@@ -1149,7 +1105,7 @@ void ApplicationManager::rejectOpenUrlRequest(const QString &requestId)
*/
QStringList ApplicationManager::capabilities(const QString &id) const
{
- AbstractApplication *app = fromId(id);
+ Application *app = fromId(id);
return app ? app->capabilities() : QStringList();
}
@@ -1163,245 +1119,10 @@ QStringList ApplicationManager::capabilities(const QString &id) const
*/
QString ApplicationManager::identifyApplication(qint64 pid) const
{
- AbstractApplication *app = fromProcessId(pid);
+ Application *app = fromProcessId(pid);
return app ? app->id() : QString();
}
-bool ApplicationManager::blockApplication(const QString &id)
-{
- AbstractApplication *app = fromId(id);
- if (!app)
- return false;
- if (!app->block())
- return false;
- emitDataChanged(app, QVector<int> { IsBlocked });
- stopApplicationInternal(app, true);
- emitDataChanged(app, QVector<int> { IsRunning });
- return true;
-}
-
-bool ApplicationManager::unblockApplication(const QString &id)
-{
- AbstractApplication *app = fromId(id);
- if (!app)
- return false;
- if (!app->unblock())
- return false;
- emitDataChanged(app, QVector<int> { IsBlocked });
- return true;
-}
-
-bool ApplicationManager::startingApplicationInstallation(ApplicationInfo *info)
-{
- // ownership of info is transferred to ApplicationManager
- QScopedPointer<ApplicationInfo> newInfo(info);
-
- if (!newInfo || newInfo->id().isEmpty())
- return false;
- AbstractApplication *absApp = fromId(newInfo->id());
- if (!RuntimeFactory::instance()->manager(newInfo->runtimeName()))
- return false;
-
- if (absApp) { // update
- Q_ASSERT(!absApp->isAlias());
- Application *app = static_cast<Application*>(absApp);
-
- if (!blockApplication(app->id()))
- return false;
-
- if (app->isBuiltIn()) {
- // overlay the existing base info
- // we will rollback to the base one if this update is removed.
- app->setUpdatedInfo(newInfo.take());
- } else {
- // overwrite the existing base info
- // we're not keeping track of the original. so removing the updated base version removes the
- // application entirely.
- app->setBaseInfo(newInfo.take());
- }
- app->setState(Application::BeingUpdated);
- app->setProgress(0);
- emitDataChanged(app);
- } else { // installation
- Application *app = new Application(newInfo.take(), Application::BeingInstalled);
-
- app->block();
-
- beginInsertRows(QModelIndex(), d->apps.count(), d->apps.count());
- addApplication(app);
- endInsertRows();
-
- emitDataChanged(app);
-
- emit applicationAdded(app->id());
- }
- return true;
-}
-
-bool ApplicationManager::startingApplicationRemoval(const QString &id)
-{
- AbstractApplication *absApp = fromId(id);
- if (!absApp)
- return false;
-
- Q_ASSERT(!absApp->isAlias());
-
- Application *app = static_cast<Application*>(absApp);
- if (app->isBlocked() || (app->state() != Application::Installed))
- return false;
-
- if (app->isBuiltIn() && !app->updatedInfo())
- return false;
-
- if (!blockApplication(id))
- return false;
-
- if (app->updatedInfo())
- app->setState(Application::BeingDowngraded);
- else
- app->setState(Application::BeingRemoved);
-
- app->setProgress(0);
- emitDataChanged(app, QVector<int> { IsUpdating });
- return true;
-}
-
-void ApplicationManager::progressingApplicationInstall(const QString &id, qreal progress)
-{
- AbstractApplication *absApp = fromId(id);
- if (!absApp)
- return;
-
- Q_ASSERT(!absApp->isAlias());
- Application *app = static_cast<Application*>(absApp);
-
- if (app->state() == Application::Installed)
- return;
- app->setProgress(progress);
- // Icon will be in a "+" suffixed directory during installation. So notify about a change on its
- // location as well.
- emitDataChanged(app, QVector<int> { Icon, UpdateProgress });
-}
-
-bool ApplicationManager::finishedApplicationInstall(const QString &id)
-{
- AbstractApplication *absApp = fromId(id);
- if (!absApp)
- return false;
-
- Q_ASSERT(!absApp->isAlias());
- Application *app = static_cast<Application*>(absApp);
-
- switch (app->state()) {
- case Application::Installed:
- return false;
-
- case Application::BeingInstalled:
- case Application::BeingUpdated: {
- // The Application object has been updated right at the start of the installation/update.
- // Now's the time to update the InstallationReport that was written by the installer.
- QFile irfile(QDir(app->nonAliasedInfo()->manifestDir()).absoluteFilePath(qSL("installation-report.yaml")));
- QScopedPointer<InstallationReport> ir(new InstallationReport(app->id()));
- if (!irfile.open(QFile::ReadOnly) || !ir->deserialize(&irfile)) {
- qCCritical(LogInstaller) << "Could not read the new installation-report for application"
- << app->id() << "at" << irfile.fileName();
- return false;
- }
- app->nonAliasedInfo()->setInstallationReport(ir.take());
- registerMimeTypes();
- app->setState(Application::Installed);
- app->setProgress(0);
-
- emitDataChanged(app);
-
- unblockApplication(id);
- emit app->bulkChange(); // not ideal, but icon and codeDir have changed
- break;
- }
- case Application::BeingDowngraded:
- app->setUpdatedInfo(nullptr);
- app->setState(Application::Installed);
- registerMimeTypes();
- break;
- case Application::BeingRemoved: {
- int row = d->apps.indexOf(app);
- if (row >= 0) {
- emit applicationAboutToBeRemoved(app->id());
- beginRemoveRows(QModelIndex(), row, row);
- d->apps.removeAt(row);
- endRemoveRows();
- }
- delete app;
- registerMimeTypes();
- break;
- }
- }
-
- emit internalSignals.applicationsChanged();
-
- return true;
-}
-
-bool ApplicationManager::canceledApplicationInstall(const QString &id)
-{
- AbstractApplication *absApp = fromId(id);
- if (!absApp)
- return false;
-
- Q_ASSERT(!absApp->isAlias());
- Application *app = static_cast<Application*>(absApp);
-
- switch (app->state()) {
- case Application::Installed:
- return false;
-
- case Application::BeingInstalled: {
- int row = d->apps.indexOf(app);
- if (row >= 0) {
- emit applicationAboutToBeRemoved(app->id());
- beginRemoveRows(QModelIndex(), row, row);
- d->apps.removeAt(row);
- endRemoveRows();
- }
- delete app;
- break;
- }
- case Application::BeingUpdated:
- case Application::BeingDowngraded:
- case Application::BeingRemoved:
- app->setState(Application::Installed);
- app->setProgress(0);
- emitDataChanged(app, QVector<int> { IsUpdating });
-
- unblockApplication(id);
- break;
- }
- return true;
-}
-
-void ApplicationManager::enableSingleAppMode()
-{
- QMetaObject::invokeMethod(this, &ApplicationManager::startSingleAppAndQuitWhenStopped, Qt::QueuedConnection);
-}
-
-void ApplicationManager::startSingleAppAndQuitWhenStopped()
-{
- Q_ASSERT(d->apps.count() == 1);
-
- AbstractApplication *app = d->apps[0];
-
- if (!startApplication(app->id())) {
- QMetaObject::invokeMethod(qApp, "shutDown", Qt::DirectConnection, Q_ARG(int, 1));
- } else {
- connect(this, &ApplicationManager::applicationRunStateChanged, [app](const QString &id, Am::RunState runState) {
- if ((id == app->id()) && (runState == Am::NotRunning)) {
- QMetaObject::invokeMethod(qApp, "shutDown", Qt::DirectConnection,
- Q_ARG(int, app->lastExitCode()));
- }
- });
- }
-}
-
void ApplicationManager::shutDown()
{
d->shuttingDown = true;
@@ -1409,7 +1130,7 @@ void ApplicationManager::shutDown()
auto shutdownHelper = [this]() {
bool activeRuntime = false;
- for (AbstractApplication *app : qAsConst(d->apps)) {
+ for (Application *app : qAsConst(d->apps)) {
AbstractRuntime *rt = app->currentRuntime();
if (rt) {
activeRuntime = true;
@@ -1420,7 +1141,7 @@ void ApplicationManager::shutDown()
emit shutDownFinished();
};
- for (AbstractApplication *app : qAsConst(d->apps)) {
+ for (Application *app : qAsConst(d->apps)) {
AbstractRuntime *rt = app->currentRuntime();
if (rt) {
connect(rt, &AbstractRuntime::destroyed,
@@ -1440,7 +1161,7 @@ void ApplicationManager::openUrlRelay(const QUrl &url)
openUrl(url.toString());
}
-void ApplicationManager::emitDataChanged(AbstractApplication *app, const QVector<int> &roles)
+void ApplicationManager::emitDataChanged(Application *app, const QVector<int> &roles)
{
int row = d->apps.indexOf(app);
if (row >= 0) {
@@ -1456,9 +1177,9 @@ void ApplicationManager::emitDataChanged(AbstractApplication *app, const QVector
}
}
-void ApplicationManager::emitActivated(AbstractApplication *app)
+void ApplicationManager::emitActivated(Application *app)
{
- emit applicationWasActivated(app->isAlias() ? app->nonAliased()->id() : app->id(), app->id());
+ emit applicationWasActivated(app->id(), app->id());
emit app->activated();
}
@@ -1476,29 +1197,15 @@ QVariant ApplicationManager::data(const QModelIndex &index, int role) const
if (index.parent().isValid() || !index.isValid())
return QVariant();
- AbstractApplication *app = d->apps.at(index.row());
+ Application *app = d->apps.at(index.row());
switch (role) {
case Id:
return app->id();
- case Name: {
- QString name;
- if (!app->info()->names().isEmpty()) {
- name = app->info()->name(d->currentLocale);
- if (name.isEmpty())
- name = app->info()->name(qSL("en"));
- if (name.isEmpty())
- name = app->info()->name(qSL("en_US"));
- if (name.isEmpty())
- name = *app->info()->names().constBegin();
- } else {
- name = app->id();
- }
- return name;
- }
+ case Name:
+ return app->name();
case Icon:
return app->icon();
-
case IsRunning:
return app->currentRuntime() ? (app->currentRuntime()->state() == Am::Running) : false;
case IsStartingUp:
@@ -1513,9 +1220,8 @@ QVariant ApplicationManager::data(const QModelIndex &index, int role) const
return app->progress();
case IsRemovable:
return !app->isBuiltIn();
-
case CodeFilePath:
- return app->nonAliasedInfo()->absoluteCodeFilePath();
+ return app->info()->absoluteCodeFilePath();
case RuntimeName:
return app->runtimeName();
case RuntimeParameters:
@@ -1582,7 +1288,7 @@ QVariantMap ApplicationManager::get(int index) const
signals or the applicationAboutToBeRemoved signal to get notified if the object is about
to be deleted on the C++ side.
*/
-AbstractApplication *ApplicationManager::application(int index) const
+Application *ApplicationManager::application(int index) const
{
if (index < 0 || index >= count()) {
qCWarning(LogSystem) << "ApplicationManager::application(index): invalid index:" << index;
@@ -1602,7 +1308,7 @@ AbstractApplication *ApplicationManager::application(int index) const
signals or the applicationAboutToBeRemoved signal to get notified if the object is about
to be deleted on the C++ side.
*/
-AbstractApplication *ApplicationManager::application(const QString &id) const
+Application *ApplicationManager::application(const QString &id) const
{
auto index = indexOfApplication(id);
return (index < 0) ? nullptr : application(index);
@@ -1659,7 +1365,7 @@ Am::RunState ApplicationManager::applicationRunState(const QString &id) const
return (index < 0) ? Am::NotRunning : d->apps.at(index)->runState();
}
-void ApplicationManager::setApplications(const QVector<AbstractApplication *> &apps)
+void ApplicationManager::setApplications(const QVector<Application *> &apps)
{
Q_ASSERT(d->apps.count() == 0);
for (auto app : apps)
@@ -1667,7 +1373,7 @@ void ApplicationManager::setApplications(const QVector<AbstractApplication *> &a
registerMimeTypes();
}
-void ApplicationManager::addApplication(AbstractApplication *app)
+void ApplicationManager::addApplication(Application *app)
{
QQmlEngine::setObjectOwnership(app, QQmlEngine::CppOwnership);
@@ -1683,6 +1389,11 @@ void ApplicationManager::addApplication(AbstractApplication *app)
stopApplication(app->id(), forceKill);
};
+ connect(app, &Application::blockedChanged,
+ this, [this, app]() {
+ emitDataChanged(app, QVector<int> { IsBlocked });
+ });
+
d->apps << app;
}
diff --git a/src/manager-lib/applicationmanager.h b/src/manager-lib/applicationmanager.h
index 60b133dd..5513f119 100644
--- a/src/manager-lib/applicationmanager.h
+++ b/src/manager-lib/applicationmanager.h
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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
@@ -101,21 +101,21 @@ public:
// Set the initial application list
// To be used only during startup (ie, before exposing ApplicationManager to QML) as
// no model update signals are emitted.
- void setApplications(const QVector<AbstractApplication *> &apps);
+ void setApplications(const QVector<Application *> &apps);
- QVector<AbstractApplication *> applications() const;
+ QVector<Application *> applications() const;
- AbstractApplication *fromId(const QString &id) const;
- AbstractApplication *fromProcessId(qint64 pid) const;
- AbstractApplication *fromSecurityToken(const QByteArray &securityToken) const;
- QVector<AbstractApplication *> schemeHandlers(const QString &scheme) const;
- QVector<AbstractApplication *> mimeTypeHandlers(const QString &mimeType) const;
+ Application *fromId(const QString &id) const;
+ Application *fromProcessId(qint64 pid) const;
+ Application *fromSecurityToken(const QByteArray &securityToken) const;
+ QVector<Application *> schemeHandlers(const QString &scheme) const;
+ QVector<Application *> mimeTypeHandlers(const QString &mimeType) const;
bool startApplicationInternal(const QString &appId, const QString &documentUrl = QString(),
const QString &documentMimeType = QString(),
const QString &debugWrapperSpecification = QString(),
const QVector<int> &stdioRedirections = QVector<int>()) Q_DECL_NOEXCEPT_EXPR(false);
- void stopApplicationInternal(AbstractApplication *app, bool forceKill = false);
+ void stopApplicationInternal(Application *app, bool forceKill = false);
// only use these two functions for development!
bool securityChecksEnabled() const;
@@ -137,8 +137,8 @@ public:
int count() const;
Q_INVOKABLE QVariantMap get(int index) const;
- Q_INVOKABLE AbstractApplication *application(int index) const;
- Q_INVOKABLE AbstractApplication *application(const QString &id) const;
+ Q_INVOKABLE Application *application(int index) const;
+ Q_INVOKABLE Application *application(const QString &id) const;
Q_INVOKABLE int indexOfApplication(const QString &id) const;
Q_INVOKABLE void acknowledgeOpenUrlRequest(const QString &requestId, const QString &appId);
@@ -158,8 +158,6 @@ public:
ApplicationManagerInternalSignals internalSignals;
- void enableSingleAppMode();
-
public slots:
void shutDown();
@@ -183,29 +181,12 @@ signals:
void windowManagerCompositorReadyChanged(bool ready);
private slots:
- void startSingleAppAndQuitWhenStopped();
void openUrlRelay(const QUrl &url);
- void addApplication(AbstractApplication *app);
-
- // Interface for the installer
- //TODO: Find something nicer than private slots with 3 friend classes.
- // This is hard though, since the senders live in different threads and
- // need to use BlockingQueuedConnections
- bool blockApplication(const QString &id);
- bool unblockApplication(const QString &id);
- bool startingApplicationInstallation(QT_PREPEND_NAMESPACE_AM(ApplicationInfo*) installApp);
- bool startingApplicationRemoval(const QString &id);
- void progressingApplicationInstall(const QString &id, qreal progress);
- bool finishedApplicationInstall(const QString &id);
- bool canceledApplicationInstall(const QString &id);
-
- friend class ApplicationInstaller;
- friend class InstallationTask;
- friend class DeinstallationTask;
+ void addApplication(Application *app);
private:
- void emitDataChanged(AbstractApplication *app, const QVector<int> &roles = QVector<int>());
- void emitActivated(AbstractApplication *app);
+ void emitDataChanged(Application *app, const QVector<int> &roles = QVector<int>());
+ void emitActivated(Application *app);
void registerMimeTypes();
ApplicationManager(bool singleProcess, QObject *parent = nullptr);
diff --git a/src/manager-lib/applicationmanager_p.h b/src/manager-lib/applicationmanager_p.h
index c9d1ad6b..ad0ef7df 100644
--- a/src/manager-lib/applicationmanager_p.h
+++ b/src/manager-lib/applicationmanager_p.h
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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
@@ -60,7 +60,8 @@ public:
bool windowManagerCompositorReady = false;
QVariantMap systemProperties;
- QVector<AbstractApplication *> apps;
+ QVector<PackageInfo> packages;
+ QVector<Application *> apps;
QString currentLocale;
QHash<int, QByteArray> roleNames;
diff --git a/src/manager-lib/applicationmodel.cpp b/src/manager-lib/applicationmodel.cpp
index 5fd46ebd..c697087d 100644
--- a/src/manager-lib/applicationmodel.cpp
+++ b/src/manager-lib/applicationmodel.cpp
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/src/manager-lib/applicationmodel.h b/src/manager-lib/applicationmodel.h
index 5cedb69a..1ec1d503 100644
--- a/src/manager-lib/applicationmodel.h
+++ b/src/manager-lib/applicationmodel.h
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/src/installer-lib/asynchronoustask.cpp b/src/manager-lib/asynchronoustask.cpp
index 53406e0f..4b1b9e67 100644
--- a/src/installer-lib/asynchronoustask.cpp
+++ b/src/manager-lib/asynchronoustask.cpp
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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
@@ -103,9 +103,19 @@ bool AsynchronousTask::forceCancel()
return cancel();
}
-QString AsynchronousTask::applicationId() const
+QString AsynchronousTask::packageId() const
{
- return m_applicationId;
+ return m_packageId;
+}
+
+bool AsynchronousTask::preExecute()
+{
+ return true;
+}
+
+bool AsynchronousTask::postExecute()
+{
+ return true;
}
void AsynchronousTask::setError(Error errorCode, const QString &errorString)
diff --git a/src/installer-lib/asynchronoustask.h b/src/manager-lib/asynchronoustask.h
index 86b661c2..5ad8714f 100644
--- a/src/installer-lib/asynchronoustask.h
+++ b/src/manager-lib/asynchronoustask.h
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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
@@ -83,7 +83,10 @@ public:
virtual bool cancel();
bool forceCancel(); // will always work in Queued state
- QString applicationId() const; // convenience
+ QString packageId() const; // convenience
+
+ virtual bool preExecute();
+ virtual bool postExecute();
signals:
void stateChanged(QT_PREPEND_NAMESPACE_AM(AsynchronousTask::TaskState) newState);
@@ -98,10 +101,11 @@ protected:
QMutex m_mutex;
QString m_id;
- QString m_applicationId;
+ QString m_packageId;
TaskState m_state = Queued;
Error m_errorCode = Error::None;
QString m_errorString;
};
+
QT_END_NAMESPACE_AM
diff --git a/src/manager-lib/containerfactory.cpp b/src/manager-lib/containerfactory.cpp
index fbeb2e49..c8ff91c0 100644
--- a/src/manager-lib/containerfactory.cpp
+++ b/src/manager-lib/containerfactory.cpp
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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
@@ -83,7 +83,7 @@ AbstractContainerManager *ContainerFactory::manager(const QString &id)
return m_containers.value(id);
}
-AbstractContainer *ContainerFactory::create(const QString &id, AbstractApplication *app,
+AbstractContainer *ContainerFactory::create(const QString &id, Application *app,
const QVector<int> &stdioRedirections,
const QMap<QString, QString> &debugWrapperEnvironment,
const QStringList &debugWrapperCommand)
diff --git a/src/manager-lib/containerfactory.h b/src/manager-lib/containerfactory.h
index 020100d8..102c094c 100644
--- a/src/manager-lib/containerfactory.h
+++ b/src/manager-lib/containerfactory.h
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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
@@ -49,7 +49,7 @@
QT_BEGIN_NAMESPACE_AM
-class AbstractApplication;
+class Application;
class AbstractContainer;
class AbstractContainerManager;
@@ -64,7 +64,7 @@ public:
QStringList containerIds() const;
AbstractContainerManager *manager(const QString &id);
- AbstractContainer *create(const QString &id, AbstractApplication *app,
+ AbstractContainer *create(const QString &id, Application *app,
const QVector<int> &stdioRedirections = QVector<int>(),
const QMap<QString, QString> &debugWrapperEnvironment = QMap<QString, QString>(),
const QStringList &debugWrapperCommand = QStringList());
diff --git a/src/manager-lib/debugwrapper.cpp b/src/manager-lib/debugwrapper.cpp
index 59eb582e..bb1fc4c3 100644
--- a/src/manager-lib/debugwrapper.cpp
+++ b/src/manager-lib/debugwrapper.cpp
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/src/manager-lib/debugwrapper.h b/src/manager-lib/debugwrapper.h
index fdfd33f0..14060334 100644
--- a/src/manager-lib/debugwrapper.h
+++ b/src/manager-lib/debugwrapper.h
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/src/installer-lib/deinstallationtask.cpp b/src/manager-lib/deinstallationtask.cpp
index 8f31e3ee..4695add6 100644
--- a/src/installer-lib/deinstallationtask.cpp
+++ b/src/manager-lib/deinstallationtask.cpp
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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
@@ -41,26 +41,27 @@
****************************************************************************/
#include "logging.h"
-#include "applicationinstaller.h"
-#include "applicationinstaller_p.h"
-#include "applicationmanager.h"
+#include "packagemanager.h"
+#include "packagemanager_p.h"
#include "installationreport.h"
-#include "applicationinfo.h"
+#include "package.h"
#include "exception.h"
#include "scopeutilities.h"
#include "deinstallationtask.h"
QT_BEGIN_NAMESPACE_AM
-DeinstallationTask::DeinstallationTask(ApplicationInfo *app, const InstallationLocation &installationLocation,
- bool forceDeinstallation, bool keepDocuments, QObject *parent)
+DeinstallationTask::DeinstallationTask(Package *package, const QString &installationPath,
+ const QString &documentPath, bool forceDeinstallation,
+ bool keepDocuments, QObject *parent)
: AsynchronousTask(parent)
- , m_app(app)
- , m_installationLocation(installationLocation)
+ , m_package(package)
+ , m_installationPath(installationPath)
+ , m_documentPath(documentPath)
, m_forceDeinstallation(forceDeinstallation)
, m_keepDocuments(keepDocuments)
{
- m_applicationId = m_app->id(); // in base class
+ m_packageId = m_package->id(); // in base class
}
bool DeinstallationTask::cancel()
@@ -72,30 +73,28 @@ bool DeinstallationTask::cancel()
void DeinstallationTask::execute()
{
- // these have been checked in ApplicationInstaller::removePackage() already
- Q_ASSERT(m_app);
- Q_ASSERT(m_app->installationReport());
- Q_ASSERT(m_app->installationReport()->installationLocationId() == m_installationLocation.id());
- Q_ASSERT(m_installationLocation.isValid());
+ // these have been checked in PackageManager::removePackage() already
+ Q_ASSERT(m_package);
+ Q_ASSERT(m_package->info());
+ Q_ASSERT(m_package->info()->installationReport());
bool managerApproval = false;
try {
- // we need to call those ApplicationManager methods in the correct thread
- // this will also exclusively lock the application for us
- QMetaObject::invokeMethod(ApplicationManager::instance(),
- "startingApplicationRemoval",
- Qt::BlockingQueuedConnection,
- Q_RETURN_ARG(bool, managerApproval),
- Q_ARG(QString, m_app->id()));
+ // we need to call those PackageManager methods in the correct thread
+ // this will also exclusively lock the package for us
+ QMetaObject::invokeMethod(PackageManager::instance(), [this, &managerApproval]()
+ { managerApproval = PackageManager::instance()->startingPackageRemoval(m_package->id()); },
+ Qt::BlockingQueuedConnection);
+
if (!managerApproval)
- throw Exception("ApplicationManager rejected the removal of app %1").arg(m_app->id());
+ throw Exception("PackageManager rejected the removal of package %1").arg(m_package->id());
- // if the app was running before, we now need to wait until is has actually stopped
- while (!m_canceled &&
- (ApplicationManager::instance()->applicationRunState(m_app->id()) != Am::NotRunning)) {
+ // if any of the apps in the package were running before, we now need to wait until all of
+ // them have actually stopped
+ while (!m_canceled && !m_package->areAllApplicationsStoppedDueToBlock())
QThread::msleep(30);
- }
+
// there's a small race condition here, but not doing a planned cancellation isn't harmful
m_canBeCanceled = false;
if (m_canceled)
@@ -103,59 +102,50 @@ void DeinstallationTask::execute()
ScopedRenamer docDirRename;
ScopedRenamer appDirRename;
- ScopedRenamer manifestRename;
if (!m_keepDocuments) {
- if (!docDirRename.rename(QDir(m_installationLocation.documentPath()).absoluteFilePath(m_app->id()),
+ if (!docDirRename.rename(QDir(m_documentPath).absoluteFilePath(m_package->id()),
ScopedRenamer::NameToNameMinus)) {
throw Exception(Error::IO, "could not rename %1 to %1-").arg(docDirRename.baseName());
}
}
- if (!appDirRename.rename(QDir(m_installationLocation.installationPath()).absoluteFilePath(m_app->id()),
+ if (!appDirRename.rename(QDir(m_installationPath).absoluteFilePath(m_package->id()),
ScopedRenamer::NameToNameMinus)) {
throw Exception(Error::IO, "could not rename %1 to %1-").arg(appDirRename.baseName());
}
- if (!manifestRename.rename(ApplicationInstaller::instance()->manifestDirectory()->absoluteFilePath(m_app->id()),
- ScopedRenamer::NameToNameMinus)) {
- throw Exception(Error::IO, "could not rename %1 to %1-").arg(manifestRename.baseName());
- }
-
- manifestRename.take();
docDirRename.take();
appDirRename.take();
// point of no return
- for (ScopedRenamer *toDelete : { &manifestRename, &docDirRename, &appDirRename }) {
+ for (ScopedRenamer *toDelete : { &docDirRename, &appDirRename }) {
if (toDelete->isRenamed()) {
if (!removeRecursiveHelper(toDelete->baseName() + qL1C('-')))
qCCritical(LogInstaller) << "ERROR: could not remove" << (toDelete->baseName() + qL1C('-'));
}
}
- // we need to call those ApplicationManager methods in the correct thread
+ // we need to call those PackageManager methods in the correct thread
bool finishOk = false;
- QMetaObject::invokeMethod(ApplicationManager::instance(),
- "finishedApplicationInstall",
- Qt::BlockingQueuedConnection,
- Q_RETURN_ARG(bool, finishOk),
- Q_ARG(QString, m_applicationId));
+ QMetaObject::invokeMethod(PackageManager::instance(), [this, &finishOk]()
+ { finishOk = PackageManager::instance()->finishedPackageInstall(m_package->id()); },
+ Qt::BlockingQueuedConnection);
+
if (!finishOk)
- qCWarning(LogInstaller) << "ApplicationManager did not approve deinstallation of " << m_applicationId;
+ qCWarning(LogInstaller) << "PackageManager did not approve deinstallation of " << m_packageId;
} catch (const Exception &e) {
// we need to call those ApplicationManager methods in the correct thread
if (managerApproval) {
bool cancelOk = false;
- QMetaObject::invokeMethod(ApplicationManager::instance(),
- "canceledApplicationInstall",
- Qt::BlockingQueuedConnection,
- Q_RETURN_ARG(bool, cancelOk),
- Q_ARG(QString, m_applicationId));
+ QMetaObject::invokeMethod(PackageManager::instance(), [this, &cancelOk]()
+ { cancelOk = PackageManager::instance()->canceledPackageInstall(m_package->id()); },
+ Qt::BlockingQueuedConnection);
+
if (!cancelOk)
- qCWarning(LogInstaller) << "ApplicationManager could not re-enable app" << m_applicationId << "after a failed removal";
+ qCWarning(LogInstaller) << "PackageManager could not re-enable package" << m_packageId << "after a failed removal";
}
setError(e.errorCode(), e.errorString());
diff --git a/src/installer-lib/deinstallationtask.h b/src/manager-lib/deinstallationtask.h
index f990cee7..a7763d27 100644
--- a/src/installer-lib/deinstallationtask.h
+++ b/src/manager-lib/deinstallationtask.h
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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
@@ -42,11 +42,11 @@
#pragma once
-#include <QtAppManInstaller/asynchronoustask.h>
+#include <QtAppManManager/asynchronoustask.h>
QT_BEGIN_NAMESPACE_AM
-class ApplicationInfo;
+class Package;
class InstallationLocation;
class DeinstallationTask : public AsynchronousTask
@@ -54,7 +54,7 @@ class DeinstallationTask : public AsynchronousTask
Q_OBJECT
public:
- DeinstallationTask(ApplicationInfo *app, const InstallationLocation &installationLocation,
+ DeinstallationTask(Package *package, const QString &installationPath, const QString &documentPath,
bool forceDeinstallation, bool keepDocuments, QObject *parent = nullptr);
bool cancel() override;
@@ -63,8 +63,9 @@ protected:
void execute() override;
private:
- ApplicationInfo *m_app;
- const InstallationLocation &m_installationLocation;
+ Package *m_package;
+ QString m_installationPath;
+ QString m_documentPath;
bool m_forceDeinstallation;
bool m_keepDocuments;
bool m_canBeCanceled = true;
diff --git a/src/manager-lib/inprocesssurfaceitem.cpp b/src/manager-lib/inprocesssurfaceitem.cpp
index 9caa228a..7de480ad 100644
--- a/src/manager-lib/inprocesssurfaceitem.cpp
+++ b/src/manager-lib/inprocesssurfaceitem.cpp
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/src/manager-lib/inprocesssurfaceitem.h b/src/manager-lib/inprocesssurfaceitem.h
index a8c80c30..b9faa923 100644
--- a/src/manager-lib/inprocesssurfaceitem.h
+++ b/src/manager-lib/inprocesssurfaceitem.h
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/src/installer-lib/installationtask.cpp b/src/manager-lib/installationtask.cpp
index eb6186c7..30cbc74a 100644
--- a/src/installer-lib/installationtask.cpp
+++ b/src/manager-lib/installationtask.cpp
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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
@@ -44,12 +44,12 @@
#include <QMessageAuthenticationCode>
#include "logging.h"
-#include "applicationinstaller_p.h"
-#include "applicationinfo.h"
+#include "packagemanager_p.h"
+#include "packageinfo.h"
#include "packageextractor.h"
-#include "yamlapplicationscanner.h"
+#include "yamlpackagescanner.h"
#include "exception.h"
-#include "applicationmanager.h"
+#include "packagemanager.h"
#include "sudo.h"
#include "utilities.h"
#include "signature.h"
@@ -62,14 +62,12 @@
Step 1 -- startInstallation()
=============================
- delete <manifestdir>/<id>+
- delete <manifestdir>/<id>-
delete <location>/<id>+
- create dir <manifestdir>/<id>+
create dir <location>/<id>+
set <extractiondir> to <location>/<id>+
+
Step 2 -- unpack files
======================
@@ -81,23 +79,19 @@
if (exists <location>/<id>)
set <isupdate> to <true>
- create installation report at <manifestDir>/installation-report.yaml
+
+ create installation report at <extractiondir>/.installation-report.yaml
if (not <isupdate>)
create document directory
if (optional uid separation)
- chown/chmod recursively in <extractionDir> and document directory
-
- copy info.yaml and the icon file from <extractiondir> to <manifestdir>/<id>+
+ chown/chmod recursively in <extractiondir> and document directory
Step 3.1 -- final rename in finishInstallation()
==================================================
- rename <manifestdir>/<id> to <manifestdir>/<id>-
- rename <manifestdir>/<id>+ to <manifestdir>/<id>
-
if (<isupdate>)
rename <location>/<id> to <location>/<id>-
rename <location>/<id>+ to <location>/<id>
@@ -128,10 +122,12 @@ private:
QMutex InstallationTask::s_serializeFinishInstallation { };
-InstallationTask::InstallationTask(const InstallationLocation &installationLocation, const QUrl &sourceUrl, QObject *parent)
+InstallationTask::InstallationTask(const QString &installationPath, const QString &documentPath,
+ const QUrl &sourceUrl, QObject *parent)
: AsynchronousTask(parent)
- , m_ai(ApplicationInstaller::instance())
- , m_installationLocation(installationLocation)
+ , m_pm(PackageManager::instance())
+ , m_installationPath(installationPath)
+ , m_documentPath(documentPath)
, m_sourceUrl(sourceUrl)
{ }
@@ -167,8 +163,8 @@ void InstallationTask::acknowledge()
void InstallationTask::execute()
{
try {
- if (!m_installationLocation.isValid())
- throw Exception("invalid installation location");
+ if (m_installationPath.isEmpty())
+ throw Exception("no installation location was configured");
TemporaryDir extractionDir;
if (!extractionDir.isValid())
@@ -193,9 +189,9 @@ void InstallationTask::execute()
if (!m_foundInfo || !m_foundIcon)
throw Exception(Error::Package, "package did not contain a valid info.json and icon file");
- QList<QByteArray> chainOfTrust = m_ai->caCertificates();
+ QList<QByteArray> chainOfTrust = m_pm->caCertificates();
- if (ApplicationManager::instance()->securityChecksEnabled()) {
+ if (!m_pm->allowInstallationOfUnsignedPackages()) {
if (!m_extractor->installationReport().storeSignature().isEmpty()) {
// normal package from the store
QByteArray sigDigest = m_extractor->installationReport().digest();
@@ -203,9 +199,9 @@ void InstallationTask::execute()
if (Signature(sigDigest).verify(m_extractor->installationReport().storeSignature(), chainOfTrust)) {
sigOk = true;
- } else if (!m_ai->hardwareId().isEmpty()) {
+ } else if (!m_pm->hardwareId().isEmpty()) {
// did not verify - if we have a hardware-id, try to verify with it
- sigDigest = QMessageAuthenticationCode::hash(sigDigest, m_ai->hardwareId().toUtf8(), QCryptographicHash::Sha256);
+ sigDigest = QMessageAuthenticationCode::hash(sigDigest, m_pm->hardwareId().toUtf8(), QCryptographicHash::Sha256);
if (Signature(sigDigest).verify(m_extractor->installationReport().storeSignature(), chainOfTrust))
sigOk = true;
}
@@ -213,15 +209,14 @@ void InstallationTask::execute()
throw Exception(Error::Package, "could not verify the package's store signature");
} else if (!m_extractor->installationReport().developerSignature().isEmpty()) {
// developer package - needs a device in dev mode
- if (!m_ai->developmentMode())
+ if (!m_pm->developmentMode())
throw Exception(Error::Package, "cannot install development packages on consumer devices");
if (!Signature(m_extractor->installationReport().digest()).verify(m_extractor->installationReport().developerSignature(), chainOfTrust))
throw Exception(Error::Package, "could not verify the package's developer signature");
} else {
- if (!m_ai->allowInstallationOfUnsignedPackages())
- throw Exception(Error::Package, "cannot install unsigned packages");
+ throw Exception(Error::Package, "cannot install unsigned packages");
}
}
@@ -248,14 +243,14 @@ void InstallationTask::execute()
// At this point, the installation is done, so we cannot throw anymore.
- // we need to call those ApplicationManager methods in the correct thread
+ // we need to call those PackageManager methods in the correct thread
bool finishOk = false;
- QMetaObject::invokeMethod(ApplicationManager::instance(),
- "finishedApplicationInstall", Qt::BlockingQueuedConnection,
- Q_RETURN_ARG(bool, finishOk),
- Q_ARG(QString, m_applicationId));
+ QMetaObject::invokeMethod(PackageManager::instance(), [this, &finishOk]()
+ { finishOk = PackageManager::instance()->finishedPackageInstall(m_packageId); },
+ Qt::BlockingQueuedConnection);
+
if (!finishOk)
- qCWarning(LogInstaller) << "ApplicationManager rejected the installation of " << m_applicationId;
+ qCWarning(LogInstaller) << "PackageManager rejected the installation of " << m_packageId;
} catch (const Exception &e) {
setError(e.errorCode(), e.errorString());
@@ -263,13 +258,12 @@ void InstallationTask::execute()
if (m_managerApproval) {
// we need to call those ApplicationManager methods in the correct thread
bool cancelOk = false;
- QMetaObject::invokeMethod(ApplicationManager::instance(),
- "canceledApplicationInstall",
- Qt::BlockingQueuedConnection,
- Q_RETURN_ARG(bool, cancelOk),
- Q_ARG(QString, m_applicationId));
+ QMetaObject::invokeMethod(PackageManager::instance(), [this, &cancelOk]()
+ { cancelOk = PackageManager::instance()->canceledPackageInstall(m_packageId); },
+ Qt::BlockingQueuedConnection);
+
if (!cancelOk)
- qCWarning(LogInstaller) << "ApplicationManager could not remove app" << m_applicationId << "after a failed installation";
+ qCWarning(LogInstaller) << "PackageManager could not remove package" << m_packageId << "after a failed installation";
}
}
@@ -291,25 +285,17 @@ void InstallationTask::checkExtractedFile(const QString &file) Q_DECL_NOEXCEPT_E
throw Exception(Error::Package, "info.yaml must be the first file in the package. Got %1")
.arg(file);
- YamlApplicationScanner yas;
- m_app.reset(yas.scan(m_extractor->destinationDirectory().absoluteFilePath(file)));
- if (m_app->id() != m_extractor->installationReport().applicationId())
- throw Exception(Error::Package, "the application identifiers in --PACKAGE-HEADER--' and info.yaml do not match");
+ YamlPackageScanner yps;
+ m_package.reset(yps.scan(m_extractor->destinationDirectory().absoluteFilePath(file)));
+ if (m_package->id() != m_extractor->installationReport().packageId())
+ throw Exception(Error::Package, "the package identifiers in --PACKAGE-HEADER--' and info.yaml do not match");
- m_iconFileName = m_app->icon(); // store it separately as we will give away ApplicationInfo later on
+ m_iconFileName = m_package->icon(); // store it separately as we will give away ApplicationInfo later on
if (m_iconFileName.isEmpty())
throw Exception(Error::Package, "the 'icon' field in info.yaml cannot be empty or absent.");
- InstallationLocation existingLocation = m_ai->installationLocationFromApplication(m_app->id());
-
- if (existingLocation.isValid() && (existingLocation != m_installationLocation)) {
- throw Exception(Error::Package, "the application %1 cannot be installed to %2, since it is already installed to %3")
- .arg(m_app->id(), m_installationLocation.id(), existingLocation.id());
- }
-
- m_app->m_builtIn = false;
- m_applicationId = m_app->id();
+ m_packageId = m_package->id();
m_foundInfo = true;
} else if (m_extractedFileCount == 2) {
@@ -320,7 +306,7 @@ void InstallationTask::checkExtractedFile(const QString &file) Q_DECL_NOEXCEPT_E
if (file != m_iconFileName)
throw Exception(Error::Package,
- "The application icon (as stated in info.yaml) must be the second file in the package."
+ "The package icon (as stated in info.yaml) must be the second file in the package."
" Expected '%1', got '%2'").arg(m_iconFileName, file);
QFile icon(m_extractor->destinationDirectory().absoluteFilePath(file));
@@ -334,8 +320,26 @@ void InstallationTask::checkExtractedFile(const QString &file) Q_DECL_NOEXCEPT_E
}
if (m_foundIcon && m_foundInfo) {
- qCDebug(LogInstaller) << "emit taskRequestingInstallationAcknowledge" << id() << "for app" << m_app->id();
- emit m_ai->taskRequestingInstallationAcknowledge(id(), m_app->toVariantMap(),
+ qCDebug(LogInstaller) << "emit taskRequestingInstallationAcknowledge" << id() << "for package" << m_package->id();
+
+ QVariantMap nameMap;
+ auto names = m_package->names();
+ for (auto it = names.constBegin(); it != names.constEnd(); ++it)
+ nameMap.insert(it.key(), it.value());
+
+ QVariantMap applicationData {
+ { qSL("id"), m_package->id() },
+ { qSL("version"), m_package->version() },
+ { qSL("icon"), m_package->icon() },
+ { qSL("displayIcon"), m_package->icon() }, // legacy
+ { qSL("name"), nameMap },
+ { qSL("displayName"), nameMap }, // legacy
+ { qSL("baseDir"), m_package->baseDir().absolutePath() },
+ { qSL("codeDir"), m_package->baseDir().absolutePath() }, // 5.12 backward compatibility
+ { qSL("manifestDir"), m_package->baseDir().absolutePath() }, // 5.12 backward compatibility
+ { qSL("installationLocationId"), qSL("internal-0") } // 5.13 backward compatibility
+ };
+ emit m_pm->taskRequestingInstallationAcknowledge(id(), applicationData,
m_extractor->installationReport().extraMetaData(),
m_extractor->installationReport().extraSignedMetaData());
@@ -352,25 +356,22 @@ void InstallationTask::checkExtractedFile(const QString &file) Q_DECL_NOEXCEPT_E
QString path = m_extractionDir.absolutePath();
path.chop(1); // remove the '+'
- m_app->setManifestDir(m_manifestDir.absolutePath());
- m_app->setCodeDir(path);
+ m_package->setBaseDir(QDir(path));
}
// we need to find a free uid before we call startingApplicationInstallation
- m_app->m_uid = m_ai->findUnusedUserId();
- m_applicationUid = m_app->m_uid;
+ m_package->m_uid = m_pm->findUnusedUserId();
+ m_applicationUid = m_package->m_uid;
// we need to call those ApplicationManager methods in the correct thread
// this will also exclusively lock the application for us
- // m_app ownership is transferred to the ApplicationManager
- QString appId = m_app->id(); // m_app is gone after the invoke
- QMetaObject::invokeMethod(ApplicationManager::instance(),
- "startingApplicationInstallation",
- Qt::BlockingQueuedConnection,
- Q_RETURN_ARG(bool, m_managerApproval),
- // ugly, but Q_ARG chokes on QT_PREPEND_NAMESPACE_AM...
- QArgument<QT_PREPEND_NAMESPACE_AM(ApplicationInfo *)>(QT_STRINGIFY(QT_PREPEND_NAMESPACE_AM(ApplicationInfo *)), m_app.take()));
+ // m_package ownership is transferred to the ApplicationManager
+ QString packageId = m_package->id(); // m_package is gone after the invoke
+ QMetaObject::invokeMethod(PackageManager::instance(), [this]()
+ { m_managerApproval = PackageManager::instance()->startingPackageInstallation(m_package.take()); },
+ Qt::BlockingQueuedConnection);
+
if (!m_managerApproval)
- throw Exception("Application Manager declined the installation of %1").arg(appId);
+ throw Exception("PackageManager declined the installation of %1").arg(packageId);
// we're not interested in any other files from here on...
m_extractor->setFileExtractedCallback(nullptr);
@@ -379,36 +380,27 @@ void InstallationTask::checkExtractedFile(const QString &file) Q_DECL_NOEXCEPT_E
void InstallationTask::startInstallation() Q_DECL_NOEXCEPT_EXPR(false)
{
- // 1. delete $manifestDir+ and $manifestDir-
- m_manifestDir.setPath(m_ai->manifestDirectory()->absoluteFilePath(m_applicationId));
- removeRecursiveHelper(m_manifestDir.absolutePath() + qL1C('+'));
- removeRecursiveHelper(m_manifestDir.absolutePath() + qL1C('-'));
-
// 2. delete old, partial installation
- QDir installationDir = QString(m_installationLocation.installationPath() + qL1C('/'));
- QString installationTarget = m_applicationId + qL1C('+');
+ QDir installationDir = QString(m_installationPath + qL1C('/'));
+ QString installationTarget = m_packageId + qL1C('+');
if (installationDir.exists(installationTarget)) {
if (!removeRecursiveHelper(installationDir.absoluteFilePath(installationTarget)))
throw Exception("could not remove old, partial installation %1/%2").arg(installationDir).arg(installationTarget);
}
- // 3. create $manifestDir+
- if (!m_manifestDirPlusCreator.create(m_manifestDir.absolutePath() + qL1C('+')))
- throw Exception("could not create manifest sub-directory %1+").arg(m_manifestDir);
-
// 4. create new installation
if (!m_installationDirCreator.create(installationDir.absoluteFilePath(installationTarget)))
throw Exception("could not create installation directory %1/%2").arg(installationDir).arg(installationTarget);
m_extractionDir = installationDir;
if (!m_extractionDir.cd(installationTarget))
throw Exception("could not cd into installation directory %1/%2").arg(installationDir).arg(installationTarget);
- m_applicationDir.setPath(installationDir.absoluteFilePath(m_applicationId));
+ m_applicationDir.setPath(installationDir.absoluteFilePath(m_packageId));
}
void InstallationTask::finishInstallation() Q_DECL_NOEXCEPT_EXPR(false)
{
- QDir documentDirectory(m_installationLocation.documentPath());
+ QDir documentDirectory(m_documentPath);
ScopedDirectoryCreator documentDirCreator;
enum { Installation, Update } mode = Installation;
@@ -418,9 +410,8 @@ void InstallationTask::finishInstallation() Q_DECL_NOEXCEPT_EXPR(false)
// create the installation report
InstallationReport report = m_extractor->installationReport();
- report.setInstallationLocationId(m_installationLocation.id());
- QFile reportFile(m_manifestDirPlusCreator.dir().absoluteFilePath(qSL("installation-report.yaml")));
+ QFile reportFile(m_extractionDir.absoluteFilePath(qSL(".installation-report.yaml")));
if (!reportFile.open(QFile::WriteOnly) || !report.serialize(&reportFile))
throw Exception(reportFile, "could not write the installation report");
reportFile.close();
@@ -428,22 +419,22 @@ void InstallationTask::finishInstallation() Q_DECL_NOEXCEPT_EXPR(false)
// create the document directories when installing (not needed on updates)
if (mode == Installation) {
// this package may have been installed earlier and the document directory may not have been removed
- if (!documentDirectory.cd(m_applicationId)) {
- if (!documentDirCreator.create(documentDirectory.absoluteFilePath(m_applicationId)))
- throw Exception(Error::IO, "could not create the document directory %1").arg(documentDirectory.filePath(m_applicationId));
+ if (!documentDirectory.cd(m_packageId)) {
+ if (!documentDirCreator.create(documentDirectory.absoluteFilePath(m_packageId)))
+ throw Exception(Error::IO, "could not create the document directory %1").arg(documentDirectory.filePath(m_packageId));
}
}
#ifdef Q_OS_UNIX
// update the owner, group and permission bits on both the installation and document directories
SudoClient *root = SudoClient::instance();
- if (m_ai->isApplicationUserIdSeparationEnabled() && root) {
+ if (m_pm->isApplicationUserIdSeparationEnabled() && root) {
uid_t uid = m_applicationUid;
- gid_t gid = m_ai->commonApplicationGroupId();
+ gid_t gid = m_pm->commonApplicationGroupId();
- if (!root->setOwnerAndPermissionsRecursive(documentDirectory.filePath(m_applicationId), uid, gid, 02700)) {
+ if (!root->setOwnerAndPermissionsRecursive(documentDirectory.filePath(m_packageId), uid, gid, 02700)) {
throw Exception(Error::IO, "could not recursively change the owner to %1:%2 and the permission bits to %3 in %4")
- .arg(uid).arg(gid).arg(02700, 0, 8).arg(documentDirectory.filePath(m_applicationId));
+ .arg(uid).arg(gid).arg(02700, 0, 8).arg(documentDirectory.filePath(m_packageId));
}
if (!root->setOwnerAndPermissionsRecursive(m_extractionDir.path(), uid, gid, 0440)) {
@@ -453,26 +444,14 @@ void InstallationTask::finishInstallation() Q_DECL_NOEXCEPT_EXPR(false)
}
#endif
- // copy meta-data to manifest directory
- for (const QString &file : { qSL("info.yaml"), m_iconFileName })
- if (!QFile::copy(m_extractionDir.absoluteFilePath(file), m_manifestDirPlusCreator.dir().absoluteFilePath(file))) {
- throw Exception(Error::IO, "could not copy %1 from the application directory to the manifest directory").arg(file);
- }
- // in case we need persistent data in addition to info.yaml and the icon file,
- // we could copy these out of the image right now...
-
// final rename
// POSIX cannot atomically rename directories, if the destination directory exists
// and is non-empty. We need to do a double-rename in this case, which might fail!
// The image is a file, so this limitation does not apply!
- ScopedRenamer renameManifest;
ScopedRenamer renameApplication;
- if (!renameManifest.rename(m_manifestDir, (mode == Update ? ScopedRenamer::NameToNameMinus | ScopedRenamer::NamePlusToName : ScopedRenamer::NamePlusToName)))
- throw Exception(Error::IO, "could not rename manifest directory %1+ to %1 (including a backup to %1-)").arg(m_manifestDir);
-
if (mode == Update) {
if (!renameApplication.rename(m_applicationDir, ScopedRenamer::NamePlusToName | ScopedRenamer::NameToNameMinus))
throw Exception(Error::IO, "could not rename application directory %1+ to %1 (including a backup to %1-)").arg(m_applicationDir);
@@ -486,11 +465,9 @@ void InstallationTask::finishInstallation() Q_DECL_NOEXCEPT_EXPR(false)
setState(CleaningUp);
renameApplication.take();
- renameManifest.take();
documentDirCreator.take();
m_installationDirCreator.take();
- m_manifestDirPlusCreator.take();
// this should not be necessary, but it also won't hurt
if (mode == Update)
diff --git a/src/installer-lib/installationtask.h b/src/manager-lib/installationtask.h
index 5f5881b3..7d3163d2 100644
--- a/src/installer-lib/installationtask.h
+++ b/src/manager-lib/installationtask.h
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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
@@ -47,14 +47,14 @@
#include <QWaitCondition>
#include <QMutex>
-#include <QtAppManInstaller/applicationinstaller.h>
#include <QtAppManApplication/installationreport.h>
-#include <QtAppManInstaller/asynchronoustask.h>
-#include <QtAppManInstaller/scopeutilities.h>
+#include <QtAppManManager/asynchronoustask.h>
+#include <QtAppManManager/scopeutilities.h>
QT_BEGIN_NAMESPACE_AM
-class ApplicationInfo;
+class PackageInfo;
+class PackageManager;
class PackageExtractor;
@@ -62,8 +62,8 @@ class InstallationTask : public AsynchronousTask
{
Q_OBJECT
public:
- InstallationTask(const InstallationLocation &installationLocation, const QUrl &sourceUrl,
- QObject *parent = nullptr);
+ InstallationTask(const QString &installationPath, const QString &documentPath,
+ const QUrl &sourceUrl, QObject *parent = nullptr);
~InstallationTask() override;
void acknowledge();
@@ -81,8 +81,9 @@ private:
void checkExtractedFile(const QString &file) Q_DECL_NOEXCEPT_EXPR(false);
private:
- ApplicationInstaller *m_ai;
- const InstallationLocation &m_installationLocation;
+ PackageManager *m_pm;
+ QString m_installationPath;
+ QString m_documentPath;
QUrl m_sourceUrl;
bool m_foundInfo = false;
bool m_foundIcon = false;
@@ -90,7 +91,7 @@ private:
bool m_locked = false;
uint m_extractedFileCount = 0;
bool m_managerApproval = false;
- QScopedPointer<ApplicationInfo> m_app;
+ QScopedPointer<PackageInfo> m_package;
uint m_applicationUid = uint(-1);
// changes to these 4 member variables are protected by m_mutex
@@ -101,11 +102,9 @@ private:
static QMutex s_serializeFinishInstallation;
- QDir m_manifestDir;
QDir m_applicationDir;
QDir m_extractionDir;
- ScopedDirectoryCreator m_manifestDirPlusCreator;
ScopedDirectoryCreator m_installationDirCreator;
};
diff --git a/src/manager-lib/intentaminterface.cpp b/src/manager-lib/intentaminterface.cpp
index 713b2039..f787226a 100644
--- a/src/manager-lib/intentaminterface.cpp
+++ b/src/manager-lib/intentaminterface.cpp
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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
@@ -68,6 +68,7 @@
#include "qmlinprocessruntime.h"
#include "application.h"
#include "applicationmanager.h"
+#include "applicationinfo.h"
QT_BEGIN_NAMESPACE_AM
@@ -115,75 +116,6 @@ IntentServer *IntentAMImplementation::createIntentServerAndClientInstance(const
return intentServer;
}
-void IntentAMImplementation::addApplicationIntents(AbstractApplication *app, IntentServer *intentServer)
-{
- if (app->isAlias())
- return;
-
- QSet<QString> intentIds;
- const auto intents = app->nonAliasedInfo()->intents();
-
- if (!intents.isEmpty())
- intentServer->addApplication(app->id());
-
- for (const auto &intent : intents) {
- /* example:
- id: io.qt.shareImage
- handledBy: main
- visibility: public*|private
- requiredCapabilities: [ a, b ]
- parameterMatch:
- mimeType: "^image/.*\.png$"
- */
- const QVariantMap map = intent.toMap();
- const QString id = map[qSL("id")].toString();
- Intent::Visibility visibility = Intent::Public;
- const QString visibilityStr = map[qSL("visibility")].toString();
- QString handledBy = map[qSL("handledBy")].toString();
- const QStringList capabilities = map[qSL("requiredCapabilities")].toStringList();
- const QVariantMap parameterMatch = map[qSL("parameterMatch")].toMap(); // do we really need that?
-
- if (id.isEmpty())
- throw Exception(Error::Intents, "intents need to have an id (app %1)").arg(app->id());
- if (intentIds.contains(id))
- throw Exception(Error::Intents, "found two intent handlers for %2 (app %1)").arg(app->id()).arg(id);
- intentIds << id;
-
- if (visibilityStr == qL1S("private"))
- visibility = Intent::Private;
- else if (!visibilityStr.isEmpty() && (visibilityStr != qL1S("public"))) {
- throw Exception(Error::Intents, "intent visibilty %3 is invalid (intent %2, app %1)")
- .arg(app->id()).arg(id).arg(visibilityStr);
- }
-
- if (handledBy == qL1S("main"))
- handledBy.clear();
- // we do not support bg services yet
- if (!handledBy.isEmpty()) {
- throw Exception(Error::Intents, "service background handlers for intent are not supported yet (intent %2, app %1)")
- .arg(app->id()).arg(id).arg(visibilityStr);
- }
-
- qCDebug(LogSystem).nospace().noquote() << " * " << id << " [app: " << app->id() << "]";
-
- if (!intentServer->addIntent(id, app->id(), handledBy, capabilities,
- visibility, parameterMatch)) {
- throw Exception(Error::Intents, "could not add intent %2 for app %1").arg(app->id()).arg(id);
- }
- }
-}
-
-void IntentAMImplementation::removeApplicationIntents(AbstractApplication *app, IntentServer *intentServer)
-{
- if (app->isAlias())
- return;
- auto intents = intentServer->filterByHandlingApplicationId(intentServer->all(), app->id());
- for (const auto &intent : intents)
- intentServer->removeIntent(intent);
-
- intentServer->removeApplication(app->id());
-}
-
// ^^^ IntentAMImplementation ^^^
//////////////////////////////////////////////////////////////////////////
// vvv IntentServerAMImplementation vvv
diff --git a/src/manager-lib/intentaminterface.h b/src/manager-lib/intentaminterface.h
index c2db4a44..f026bbd4 100644
--- a/src/manager-lib/intentaminterface.h
+++ b/src/manager-lib/intentaminterface.h
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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
@@ -60,13 +60,11 @@ class IntentInterfaceAdaptor;
QT_BEGIN_NAMESPACE_AM
class Application;
-class AbstractApplication;
+class PackageInfo;
class IntentServerRequest;
namespace IntentAMImplementation {
IntentServer *createIntentServerAndClientInstance(const QMap<QString, int> &timeouts);
-void addApplicationIntents(AbstractApplication *app, IntentServer *intentServer);
-void removeApplicationIntents(AbstractApplication *app, IntentServer *intentServer);
}
// the server side
diff --git a/src/manager-lib/manager-lib.pro b/src/manager-lib/manager-lib.pro
index 170792bd..71fad983 100644
--- a/src/manager-lib/manager-lib.pro
+++ b/src/manager-lib/manager-lib.pro
@@ -41,7 +41,6 @@ HEADERS += \
application.h \
applicationmanager.h \
applicationmodel.h \
- applicationdatabase.h \
notificationmanager.h \
abstractcontainer.h \
containerfactory.h \
@@ -57,6 +56,9 @@ HEADERS += \
amnamespace.h \
intentaminterface.h \
processstatus.h \
+ package.h \
+ packagemanager.h \
+ packagemanager_p.h \
!headless:HEADERS += \
qmlinprocessapplicationmanagerwindow.h \
@@ -70,7 +72,6 @@ SOURCES += \
application.cpp \
applicationmanager.cpp \
applicationmodel.cpp \
- applicationdatabase.cpp \
notificationmanager.cpp \
abstractcontainer.cpp \
containerfactory.cpp \
@@ -83,6 +84,8 @@ SOURCES += \
debugwrapper.cpp \
intentaminterface.cpp \
processstatus.cpp \
+ packagemanager.cpp \
+ package.cpp \
!headless:SOURCES += \
qmlinprocessapplicationmanagerwindow.cpp \
@@ -96,4 +99,26 @@ qtHaveModule(qml):SOURCES += \
# compile the moc-data into the exporting binary (appman itself)
HEADERS += ../plugin-interfaces/containerinterface.h
+
+!disable-installer {
+
+ QT_FOR_PRIVATE *= \
+ appman_package-private \
+ appman_crypto-private \
+
+ HEADERS += \
+ asynchronoustask.h \
+ deinstallationtask.h \
+ installationtask.h \
+ scopeutilities.h \
+ sudo.h \
+
+ SOURCES += \
+ asynchronoustask.cpp \
+ installationtask.cpp \
+ deinstallationtask.cpp \
+ scopeutilities.cpp \
+ sudo.cpp \
+}
+
load(qt_module)
diff --git a/src/manager-lib/nativeruntime.cpp b/src/manager-lib/nativeruntime.cpp
index 3c1865b6..6adcc4d2 100644
--- a/src/manager-lib/nativeruntime.cpp
+++ b/src/manager-lib/nativeruntime.cpp
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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
@@ -75,6 +75,7 @@ QT_BEGIN_NAMESPACE_AM
QT_END_NAMESPACE_AM
# include <dlfcn.h>
# include <sys/socket.h>
+# include <signal.h>
QT_BEGIN_NAMESPACE_AM
static qint64 getDBusPeerPid(const QDBusConnection &conn)
@@ -215,7 +216,7 @@ bool NativeRuntime::initialize()
if (!m_app)
return false;
- m_container->setProgram(m_app->nonAliasedInfo()->absoluteCodeFilePath());
+ m_container->setProgram(m_app->info()->absoluteCodeFilePath());
m_container->setBaseDirectory(m_app->codeDir());
return true;
}
@@ -223,6 +224,10 @@ bool NativeRuntime::initialize()
void NativeRuntime::shutdown(int exitCode, Am::ExitStatus status)
{
+ // see NativeRuntime::stop() below
+ if ((status == Am::CrashExit) && (exitCode == SIGTERM || exitCode == SIGKILL))
+ status = Am::ForcedExit;
+
if (!m_isQuickLauncher || m_connectedToRuntimeInterface) {
qCDebug(LogSystem) << "NativeRuntime (id:" << (m_app ? m_app->id() : qSL("(none)"))
<< "pid:" << m_process->processId() << ") exited with code:" << exitCode
@@ -271,7 +276,7 @@ bool NativeRuntime::start()
QVariantMap openGLConfig;
if (m_app)
- openGLConfig = m_app->nonAliasedInfo()->openGLConfiguration();
+ openGLConfig = m_app->info()->openGLConfiguration();
if (openGLConfig.isEmpty())
openGLConfig = manager()->systemOpenGLConfiguration();
if (!openGLConfig.isEmpty())
@@ -392,8 +397,10 @@ void NativeRuntime::stop(bool forceKill)
void NativeRuntime::onProcessStarted()
{
- if (!m_startedViaLauncher && !application()->nonAliasedInfo()->supportsApplicationInterface())
+ if (!m_startedViaLauncher
+ && !(application()->info()->supportsApplicationInterface() || manager()->supportsQuickLaunch())) {
setState(Am::Running);
+ }
}
void NativeRuntime::onProcessError(Am::ProcessError error)
@@ -467,7 +474,7 @@ bool NativeRuntime::startApplicationViaLauncher()
return false;
QString baseDir = m_container->mapHostPathToContainer(m_app->codeDir());
- QString pathInContainer = m_container->mapHostPathToContainer(m_app->nonAliasedInfo()->absoluteCodeFilePath());
+ QString pathInContainer = m_container->mapHostPathToContainer(m_app->info()->absoluteCodeFilePath());
emit m_runtimeInterface->startApplication(baseDir, pathInContainer, m_document, m_mimeType,
convertFromJSVariant(QVariant(m_app->info()->toVariantMap())).toMap(),
diff --git a/src/manager-lib/nativeruntime.h b/src/manager-lib/nativeruntime.h
index 931d8e8b..1fa3638b 100644
--- a/src/manager-lib/nativeruntime.h
+++ b/src/manager-lib/nativeruntime.h
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/src/manager-lib/nativeruntime_p.h b/src/manager-lib/nativeruntime_p.h
index 82fff7bf..2c0e514d 100644
--- a/src/manager-lib/nativeruntime_p.h
+++ b/src/manager-lib/nativeruntime_p.h
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/src/manager-lib/notificationmanager.cpp b/src/manager-lib/notificationmanager.cpp
index 26c804fc..a959fb95 100644
--- a/src/manager-lib/notificationmanager.cpp
+++ b/src/manager-lib/notificationmanager.cpp
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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
@@ -207,7 +207,7 @@ enum Roles
struct NotificationData
{
uint id;
- AbstractApplication *application;
+ Application *application;
uint priority;
QString summary;
QString body;
@@ -353,7 +353,7 @@ QVariant NotificationManager::data(const QModelIndex &index, int role) const
case Icon:
if (!n->iconUrl.isEmpty())
return n->iconUrl;
- return n->application ? n->application->icon() : QString();
+ return n->application ? n->application->info()->packageInfo()->icon() : QString();
case Image:
return n->imageUrl;
case ShowActionsAsIcons:
@@ -580,7 +580,7 @@ uint NotificationManager::notifyHelper(const QString &app_name, uint id, bool re
qCDebug(LogNotifications) << " -> adding new notification with id" << id;
}
- AbstractApplication *app = ApplicationManager::instance()->fromId(app_name);
+ Application *app = ApplicationManager::instance()->fromId(app_name);
if (replaces && app != n->application) {
// no hijacking allowed
diff --git a/src/manager-lib/notificationmanager.h b/src/manager-lib/notificationmanager.h
index b97d4fa5..8a25a81b 100644
--- a/src/manager-lib/notificationmanager.h
+++ b/src/manager-lib/notificationmanager.h
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/src/manager-lib/package.cpp b/src/manager-lib/package.cpp
new file mode 100644
index 00000000..d51ed794
--- /dev/null
+++ b/src/manager-lib/package.cpp
@@ -0,0 +1,237 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 Luxoft Sweden AB
+** Copyright (C) 2018 Pelagicore AG
+** 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
+**
+****************************************************************************/
+
+#include <QLocale>
+
+#include "package.h"
+#include "packageinfo.h"
+#include "applicationinfo.h"
+
+QT_BEGIN_NAMESPACE_AM
+
+Package::Package(PackageInfo *packageInfo, State initialState)
+ : m_info(packageInfo)
+ , m_state(initialState)
+{ }
+
+QString Package::id() const
+{
+ return info()->id();
+}
+
+bool Package::isBuiltIn() const
+{
+ return info()->isBuiltIn();
+}
+
+QString Package::version() const
+{
+ return info()->version();
+}
+
+QString Package::name() const
+{
+ QString name;
+ if (!info()->names().isEmpty()) {
+ name = info()->name(QLocale::system().name()); //TODO: language changes
+ if (name.isEmpty())
+ name = info()->name(qSL("en"));
+ if (name.isEmpty())
+ name = info()->name(qSL("en_US"));
+ if (name.isEmpty())
+ name = *info()->names().constBegin();
+ } else {
+ name = id();
+ }
+ return name;
+}
+
+QVariantMap Package::names() const
+{
+ QVariantMap names;
+ for (auto it = info()->names().cbegin(); it != info()->names().cend(); ++it)
+ names.insert(it.key(), it.value());
+ return names;
+}
+
+QString Package::description() const
+{
+ QString description;
+ if (!info()->descriptions().isEmpty()) {
+ description = info()->description(QLocale::system().name()); //TODO: language changes
+ if (description.isEmpty())
+ description = info()->description(qSL("en"));
+ if (description.isEmpty())
+ description = info()->description(qSL("en_US"));
+ if (description.isEmpty())
+ description = *info()->descriptions().constBegin();
+ }
+ return description;
+}
+
+QVariantMap Package::descriptions() const
+{
+ QVariantMap descriptions;
+ for (auto it = info()->descriptions().cbegin(); it != info()->descriptions().cend(); ++it)
+ descriptions.insert(it.key(), it.value());
+ return descriptions;
+}
+
+QStringList Package::categories() const
+{
+ return info()->categories();
+}
+
+QUrl Package::icon() const
+{
+ if (info()->icon().isEmpty())
+ return QUrl();
+
+ QDir dir;
+ switch (state()) {
+ default:
+ case Installed:
+ dir = info()->baseDir();
+ break;
+ case BeingInstalled:
+ case BeingUpdated:
+ dir = QDir(info()->baseDir().absolutePath() + QLatin1Char('+'));
+ break;
+ case BeingRemoved:
+ dir = QDir(info()->baseDir().absolutePath() + QLatin1Char('-'));
+ break;
+ }
+ return QUrl::fromLocalFile(dir.absoluteFilePath(info()->icon()));
+}
+
+void Package::setState(State state)
+{
+ if (m_state != state) {
+ m_state = state;
+ emit stateChanged(m_state);
+ }
+}
+
+void Package::setProgress(qreal progress)
+{
+ m_progress = progress;
+}
+
+
+void Package::setBaseInfo(PackageInfo *info)
+{
+ m_info.reset(info);
+ emit bulkChange();
+}
+
+void Package::setUpdatedInfo(PackageInfo *info)
+{
+ Q_ASSERT(!info || (m_info && info->id() == m_info->id()));
+
+ m_updatedInfo.reset(info);
+ emit bulkChange();
+}
+
+PackageInfo *Package::info() const
+{
+ return m_updatedInfo ? m_updatedInfo.data() : m_info.data();
+}
+
+PackageInfo *Package::updatedInfo() const
+{
+ return m_updatedInfo.data();
+}
+
+PackageInfo *Package::takeBaseInfo()
+{
+ return m_info.take();
+}
+
+bool Package::canBeRevertedToBuiltIn() const
+{
+ return m_info && m_updatedInfo;
+}
+
+bool Package::isBlocked() const
+{
+ return m_blocked > 0;
+}
+
+bool Package::block()
+{
+ bool blockedNow = (m_blocked.fetchAndAddOrdered(1) == 0);
+ if (blockedNow) {
+ emit blockedChanged(true);
+ m_blockedApps = info()->applications();
+ }
+ return blockedNow;
+}
+
+bool Package::unblock()
+{
+ bool unblockedNow = (m_blocked.fetchAndSubOrdered(1) == 1);
+ if (unblockedNow) {
+ m_blockedApps.clear();
+ emit blockedChanged(false);
+ }
+ return unblockedNow;
+
+}
+
+void Package::applicationStoppedDueToBlock(const QString &appId)
+{
+ if (!isBlocked())
+ return;
+
+ auto it = std::find_if(m_blockedApps.cbegin(), m_blockedApps.cend(), [appId](const ApplicationInfo *appInfo) {
+ return appInfo->id() == appId;
+ });
+ if (it != m_blockedApps.cend())
+ m_blockedApps.removeOne(*it);
+}
+
+bool Package::areAllApplicationsStoppedDueToBlock() const
+{
+ return isBlocked() && m_blockedApps.isEmpty();
+}
+
+QT_END_NAMESPACE_AM
diff --git a/src/manager-lib/package.h b/src/manager-lib/package.h
new file mode 100644
index 00000000..bf5fd4c2
--- /dev/null
+++ b/src/manager-lib/package.h
@@ -0,0 +1,151 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 Luxoft Sweden AB
+** Copyright (C) 2018 Pelagicore AG
+** 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
+**
+****************************************************************************/
+
+#pragma once
+
+#include <QtAppManCommon/global.h>
+#include <QtAppManApplication/packageinfo.h>
+#include <QUrl>
+#include <QString>
+#include <QAtomicInt>
+#include <QObject>
+
+QT_BEGIN_NAMESPACE_AM
+
+
+class Package : public QObject
+{
+ Q_OBJECT
+ Q_CLASSINFO("AM-QmlType", "QtApplicationManager.SystemUI/PackageObject 2.0 UNCREATABLE")
+ Q_PROPERTY(QString id READ id CONSTANT)
+ Q_PROPERTY(bool builtIn READ isBuiltIn NOTIFY bulkChange)
+ Q_PROPERTY(QUrl icon READ icon NOTIFY bulkChange)
+ Q_PROPERTY(QString version READ version NOTIFY bulkChange)
+ Q_PROPERTY(QString name READ name NOTIFY bulkChange)
+ Q_PROPERTY(QVariantMap names READ names NOTIFY bulkChange)
+ Q_PROPERTY(QString description READ version NOTIFY bulkChange)
+ Q_PROPERTY(QVariantMap descriptions READ descriptions NOTIFY bulkChange)
+ Q_PROPERTY(QStringList categories READ categories NOTIFY bulkChange)
+ Q_PROPERTY(State state READ state NOTIFY stateChanged)
+ Q_PROPERTY(bool blocked READ isBlocked NOTIFY blockedChanged)
+
+public:
+ enum State {
+ Installed,
+ BeingInstalled,
+ BeingUpdated,
+ BeingDowngraded,
+ BeingRemoved
+ };
+ Q_ENUM(State)
+
+ Package(PackageInfo *packageInfo, State initialState = Installed);
+
+ QString id() const;
+ bool isBuiltIn() const;
+ QUrl icon() const;
+ QString version() const;
+ QString name() const;
+ QVariantMap names() const;
+ QString description() const;
+ QVariantMap descriptions() const;
+ QStringList categories() const;
+
+ State state() const { return m_state; }
+ qreal progress() const { return m_progress; }
+
+ void setState(State state);
+ void setProgress(qreal progress);
+
+ // Creates a list of Applications from a list of ApplicationInfo objects.
+ // Ownership of the given ApplicationInfo objects is passed to the returned Applications.
+ //static QVector<Application *> fromApplicationInfoVector(QVector<ApplicationInfo *> &);
+
+ /*
+ All packages have a base info.
+
+ Built-in packages, when updated, also get an updated info.
+ The updated info then overlays the base one. Subsequent updates
+ just replace the updated info. When requested to be removed, a
+ built-in packages only loses its updated info, returning to
+ expose the base one.
+
+ Regular packages (ie, non-built-in) only have a base info. When
+ updated, their base info gets replaced and thus there's no way to go
+ back to a previous version. Regular packages get completely
+ removed when requested.
+ */
+ void setBaseInfo(PackageInfo *info);
+ void setUpdatedInfo(PackageInfo *info);
+
+ // Returns the updated info, if there's one. Otherwise returns the base info.
+ PackageInfo *info() const;
+ PackageInfo *updatedInfo() const;
+ PackageInfo *takeBaseInfo();
+
+ bool canBeRevertedToBuiltIn() const;
+
+ bool isBlocked() const;
+ bool block();
+ bool unblock();
+
+ // function for Application to report it has stopped after getting a block request
+ void applicationStoppedDueToBlock(const QString &appId);
+ // query function for the installer to verify that it is safe to manipulate binaries
+ bool areAllApplicationsStoppedDueToBlock() const;
+
+signals:
+ void bulkChange();
+ void stateChanged(State state);
+ void blockedChanged(bool blocked);
+
+private:
+ QScopedPointer<PackageInfo> m_info;
+ QScopedPointer<PackageInfo> m_updatedInfo;
+
+ State m_state = Installed;
+ qreal m_progress = 0;
+ QAtomicInt m_blocked;
+ QVector<ApplicationInfo *> m_blockedApps;
+};
+
+QT_END_NAMESPACE_AM
diff --git a/src/manager-lib/packagemanager.cpp b/src/manager-lib/packagemanager.cpp
new file mode 100644
index 00000000..bd0d70f8
--- /dev/null
+++ b/src/manager-lib/packagemanager.cpp
@@ -0,0 +1,1192 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 Luxoft Sweden AB
+** Copyright (C) 2018 Pelagicore AG
+** 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
+**
+****************************************************************************/
+
+#include <QMetaMethod>
+#include <QQmlEngine>
+#include <QVersionNumber>
+#include "packagemanager.h"
+#include "packagedatabase.h"
+#include "packagemanager_p.h"
+#include "package.h"
+#include "logging.h"
+#include "installationreport.h"
+#include "exception.h"
+#include "sudo.h"
+#include "utilities.h"
+
+#if defined(Q_OS_WIN)
+# include <Windows.h>
+#else
+# include <sys/stat.h>
+# include <errno.h>
+# if defined(Q_OS_ANDROID)
+# include <sys/vfs.h>
+# define statvfs statfs
+# else
+# include <sys/statvfs.h>
+# endif
+#endif
+
+
+QT_BEGIN_NAMESPACE_AM
+
+enum Roles
+{
+ Id = Qt::UserRole,
+ Name,
+ Description,
+ Icon,
+
+ IsBlocked,
+ IsUpdating,
+ IsRemovable,
+
+ UpdateProgress,
+
+ Version,
+ PackageItem,
+};
+
+PackageManager *PackageManager::s_instance = nullptr;
+QHash<int, QByteArray> PackageManager::s_roleNames;
+
+PackageManager *PackageManager::createInstance(PackageDatabase *packageDatabase,
+ const QString &documentPath)
+{
+ if (Q_UNLIKELY(s_instance))
+ qFatal("PackageManager::createInstance() was called a second time.");
+
+ Q_ASSERT(packageDatabase);
+
+ QScopedPointer<PackageManager> pm(new PackageManager(packageDatabase, documentPath));
+ registerQmlTypes();
+
+ // map all the built-in packages first
+ const auto builtinPackages = packageDatabase->builtInPackages();
+ for (auto packageInfo : builtinPackages) {
+ auto *package = new Package(packageInfo);
+ QQmlEngine::setObjectOwnership(package, QQmlEngine::CppOwnership);
+ pm->d->packages << package;
+ }
+
+ // next, map all the installed packages, making sure to detect updates to built-in ones
+ const auto installedPackages = packageDatabase->installedPackages();
+ for (auto packageInfo : installedPackages) {
+ Package *builtInPackage = pm->fromId(packageInfo->id());
+
+ if (builtInPackage) { // update
+ if (builtInPackage->updatedInfo()) { // but there already is an update applied!?
+ throw Exception(Error::Package, "Found more than one update for the built-in package '%1'")
+ .arg(builtInPackage->id());
+ //TODO: can we get the paths to both info.yaml here?
+ }
+ builtInPackage->setUpdatedInfo(packageInfo);
+ } else {
+ auto *package = new Package(packageInfo);
+ QQmlEngine::setObjectOwnership(package, QQmlEngine::CppOwnership);
+ pm->d->packages << package;
+ }
+ }
+
+ return s_instance = pm.take();
+}
+
+PackageManager *PackageManager::instance()
+{
+ if (!s_instance)
+ qFatal("PackageManager::instance() was called before createInstance().");
+ return s_instance;
+}
+
+QObject *PackageManager::instanceForQml(QQmlEngine *, QJSEngine *)
+{
+ QQmlEngine::setObjectOwnership(instance(), QQmlEngine::CppOwnership);
+ return instance();
+}
+
+QVector<Package *> PackageManager::packages() const
+{
+ return d->packages;
+}
+
+void PackageManager::registerQmlTypes()
+{
+ qmlRegisterSingletonType<PackageManager>("QtApplicationManager.SystemUI", 2, 0, "PackageManager",
+ &PackageManager::instanceForQml);
+ qmlRegisterUncreatableType<Package>("QtApplicationManager.SystemUI", 2, 0, "PackageObject",
+ qSL("Cannot create objects of type PackageObject"));
+ qRegisterMetaType<Package *>("Package*");
+
+ s_roleNames.insert(Id, "packageId");
+ s_roleNames.insert(Name, "name");
+ s_roleNames.insert(Description, "description");
+ s_roleNames.insert(Icon, "icon");
+ s_roleNames.insert(IsBlocked, "isBlocked");
+ s_roleNames.insert(IsUpdating, "isUpdating");
+ s_roleNames.insert(IsRemovable, "isRemovable");
+ s_roleNames.insert(UpdateProgress, "updateProgress");
+ s_roleNames.insert(Version, "version");
+ s_roleNames.insert(PackageItem, "package");
+}
+
+PackageManager::PackageManager(PackageDatabase *packageDatabase,
+ const QString &documentPath)
+ : QAbstractListModel()
+ , d(new PackageManagerPrivate())
+{
+ d->database = packageDatabase;
+ d->installationPath = packageDatabase->installedPackagesDir();
+ d->documentPath = documentPath;
+}
+
+PackageManager::~PackageManager()
+{
+ delete d->database;
+ delete d;
+ s_instance = nullptr;
+}
+
+Package *PackageManager::fromId(const QString &id) const
+{
+ for (auto package : d->packages) {
+ if (package->id() == id)
+ return package;
+ }
+ return nullptr;
+}
+
+void PackageManager::emitDataChanged(Package *package, const QVector<int> &roles)
+{
+ int row = d->packages.indexOf(package);
+ if (row >= 0) {
+ emit dataChanged(index(row), index(row), roles);
+
+ static const auto pkgChanged = QMetaMethod::fromSignal(&PackageManager::packageChanged);
+ if (isSignalConnected(pkgChanged)) {
+ QStringList stringRoles;
+ for (auto role : roles)
+ stringRoles << qL1S(s_roleNames[role]);
+ emit packageChanged(package->id(), stringRoles);
+ }
+ }
+}
+
+// item model part
+
+int PackageManager::rowCount(const QModelIndex &parent) const
+{
+ if (parent.isValid())
+ return 0;
+ return d->packages.count();
+}
+
+QVariant PackageManager::data(const QModelIndex &index, int role) const
+{
+ if (index.parent().isValid() || !index.isValid())
+ return QVariant();
+
+ Package *package = d->packages.at(index.row());
+
+ switch (role) {
+ case Id:
+ return package->id();
+ case Name:
+ return package->name();
+ case Description:
+ return package->description();
+ case Icon:
+ return package->icon();
+ case IsBlocked:
+ return package->isBlocked();
+ case IsUpdating:
+ return package->state() != Package::Installed;
+ case UpdateProgress:
+ return package->progress();
+ case IsRemovable:
+ return !package->isBuiltIn();
+ case Version:
+ return package->version();
+ case PackageItem:
+ return QVariant::fromValue(package);
+ }
+ return QVariant();
+}
+
+QHash<int, QByteArray> PackageManager::roleNames() const
+{
+ return s_roleNames;
+}
+
+int PackageManager::count() const
+{
+ return rowCount();
+}
+
+/*!
+ \qmlmethod object PackageManager::get(int index)
+
+ Retrieves the model data at \a index as a JavaScript object. See the
+ \l {PackageManager Roles}{role names} for the expected object fields.
+
+ Returns an empty object if the specified \a index is invalid.
+
+ \note This is very inefficient if you only want to access a single property from QML; use
+ package() instead to access the Package object's properties directly.
+*/
+QVariantMap PackageManager::get(int index) const
+{
+ if (index < 0 || index >= count()) {
+ qCWarning(LogSystem) << "PackageManager::get(index): invalid index:" << index;
+ return QVariantMap();
+ }
+
+ QVariantMap map;
+ QHash<int, QByteArray> roles = roleNames();
+ for (auto it = roles.begin(); it != roles.end(); ++it)
+ map.insert(qL1S(it.value()), data(this->index(index), it.key()));
+ return map;
+}
+
+/*!
+ \qmlmethod PackageObject PackageManager::package(int index)
+
+ Returns the \l{PackageObject}{package} corresponding to the given \a index in the
+ model, or \c null if the index is invalid.
+
+ \note The object ownership of the returned Package object stays with the application-manager.
+ If you want to store this pointer, you can use the PackageManager's QAbstractListModel
+ signals or the packageAboutToBeRemoved signal to get notified if the object is about
+ to be deleted on the C++ side.
+*/
+Package *PackageManager::package(int index) const
+{
+ if (index < 0 || index >= count()) {
+ qCWarning(LogSystem) << "PackageManager::application(index): invalid index:" << index;
+ return nullptr;
+ }
+ return d->packages.at(index);
+}
+
+/*!
+ \qmlmethod PackageObject PackageManager::package(string id)
+
+ Returns the \l{PackageObject}{package} corresponding to the given package \a id,
+ or \c null if the id does not exist.
+
+ \note The object ownership of the returned Package object stays with the application-manager.
+ If you want to store this pointer, you can use the PackageManager's QAbstractListModel
+ signals or the packageAboutToBeRemoved signal to get notified if the object is about
+ to be deleted on the C++ side.
+*/
+Package *PackageManager::package(const QString &id) const
+{
+ auto index = indexOfPackage(id);
+ return (index < 0) ? nullptr : package(index);
+}
+
+/*!
+ \qmlmethod int PackageManager::indexOfPackage(string id)
+
+ Maps the package \a id to its position within the model.
+
+ Returns \c -1 if the specified \a id is invalid.
+*/
+int PackageManager::indexOfPackage(const QString &id) const
+{
+ for (int i = 0; i < d->packages.size(); ++i) {
+ if (d->packages.at(i)->id() == id)
+ return i;
+ }
+ return -1;
+}
+
+bool PackageManager::developmentMode() const
+{
+ return d->developmentMode;
+}
+
+void PackageManager::setDevelopmentMode(bool enable)
+{
+ d->developmentMode = enable;
+}
+
+bool PackageManager::allowInstallationOfUnsignedPackages() const
+{
+ return d->allowInstallationOfUnsignedPackages;
+}
+
+void PackageManager::setAllowInstallationOfUnsignedPackages(bool enable)
+{
+ d->allowInstallationOfUnsignedPackages = enable;
+}
+
+QString PackageManager::hardwareId() const
+{
+ return d->hardwareId;
+}
+
+void PackageManager::setHardwareId(const QString &hwId)
+{
+ d->hardwareId = hwId;
+}
+
+bool PackageManager::isApplicationUserIdSeparationEnabled() const
+{
+ return d->userIdSeparation;
+}
+
+uint PackageManager::commonApplicationGroupId() const
+{
+ return d->commonGroupId;
+}
+
+bool PackageManager::enableApplicationUserIdSeparation(uint minUserId, uint maxUserId, uint commonGroupId)
+{
+ if (minUserId >= maxUserId || minUserId == uint(-1) || maxUserId == uint(-1))
+ return false;
+ d->userIdSeparation = true;
+ d->minUserId = minUserId;
+ d->maxUserId = maxUserId;
+ d->commonGroupId = commonGroupId;
+ return true;
+}
+
+uint PackageManager::findUnusedUserId() const Q_DECL_NOEXCEPT_EXPR(false)
+{
+ if (!isApplicationUserIdSeparationEnabled())
+ return uint(-1);
+
+ for (uint uid = d->minUserId; uid <= d->maxUserId; ++uid) {
+ bool match = false;
+ for (Package *package : d->packages) {
+ if (package->info()->uid() == uid) {
+ match = true;
+ break;
+ }
+ }
+ if (!match)
+ return uid;
+ }
+ throw Exception("could not find a free user-id for application separation in the range %1 to %2")
+ .arg(d->minUserId).arg(d->maxUserId);
+}
+
+QList<QByteArray> PackageManager::caCertificates() const
+{
+ return d->chainOfTrust;
+}
+
+void PackageManager::setCACertificates(const QList<QByteArray> &chainOfTrust)
+{
+ d->chainOfTrust = chainOfTrust;
+}
+
+static QVariantMap locationMap(const QString &path)
+{
+ QString cpath = QFileInfo(path).canonicalPath();
+ quint64 bytesTotal = 0;
+ quint64 bytesFree = 0;
+
+#if defined(Q_OS_WIN)
+ GetDiskFreeSpaceExW((LPCWSTR) cpath.utf16(), (ULARGE_INTEGER *) &bytesFree,
+ (ULARGE_INTEGER *) &bytesTotal, nullptr);
+
+#else // Q_OS_UNIX
+ int result;
+ struct ::statvfs svfs;
+
+ do {
+ result = ::statvfs(cpath.toLocal8Bit(), &svfs);
+ if (result == -1 && errno == EINTR)
+ continue;
+ } while (false);
+
+ if (result == 0) {
+ bytesTotal = quint64(svfs.f_frsize) * svfs.f_blocks;
+ bytesFree = quint64(svfs.f_frsize) * svfs.f_bavail;
+ }
+#endif // Q_OS_WIN
+
+
+ return QVariantMap {
+ { qSL("path"), path },
+ { qSL("deviceSize"), bytesTotal },
+ { qSL("deviceFree"), bytesFree }
+ };
+}
+
+/*!
+ \qmlproperty object PackageManager::installationLocation
+
+ Returns an object describing the location under which applications are installed in detail.
+
+ The returned object has the following members:
+
+ \table
+ \header
+ \li \c Name
+ \li \c Type
+ \li Description
+ \row
+ \li \c path
+ \li \c string
+ \li The absolute file-system path to the base directory.
+ \row
+ \li \c deviceSize
+ \li \c int
+ \li The size of the device holding \c path in bytes.
+ \row
+ \li \c deviceFree
+ \li \c int
+ \li The amount of bytes available on the device holding \c path.
+ \endtable
+
+ Returns an empty object in case the installer component is disabled.
+*/
+QVariantMap PackageManager::installationLocation() const
+{
+ return locationMap(d->installationPath);
+}
+
+/*!
+ \qmlproperty object PackageManager::documentLocation
+
+ Returns an object describing the location under which per-user document
+ directories are created in detail.
+
+ The returned object has the same members as described in PackageManager::installationLocation.
+*/
+QVariantMap PackageManager::documentLocation() const
+{
+ return locationMap(d->documentPath);
+}
+
+void PackageManager::cleanupBrokenInstallations() Q_DECL_NOEXCEPT_EXPR(false)
+{
+ // Check that everything in the app-db is available
+ // -> if not, remove from app-db
+
+ // key: baseDirPath, value: subDirName/ or fileName
+ QMultiMap<QString, QString> validPaths;
+ if (!d->documentPath.isEmpty())
+ validPaths.insert(d->documentPath, QString());
+ if (!d->installationPath.isEmpty())
+ validPaths.insert(d->installationPath, QString());
+
+ for (Package *pkg : d->packages) { // we want to detach here!
+ const InstallationReport *ir = pkg->info()->installationReport();
+ if (ir) {
+ bool valid = true;
+
+ QString pkgDir = d->installationPath + pkg->id();
+ QStringList checkDirs;
+ QStringList checkFiles;
+
+ checkFiles << pkgDir + qSL("/info.yaml");
+ checkFiles << pkgDir + qSL("/.installation-report.yaml");
+ checkDirs << pkgDir;
+ checkDirs << d->installationPath + pkg->id();
+
+ for (const QString &checkFile : qAsConst(checkFiles)) {
+ QFileInfo fi(checkFile);
+ if (!fi.exists() || !fi.isFile() || !fi.isReadable()) {
+ valid = false;
+ qCDebug(LogInstaller) << "cleanup: uninstalling" << pkg->id() << "- file missing:" << checkFile;
+ break;
+ }
+ }
+ for (const QString &checkDir : checkDirs) {
+ QFileInfo fi(checkDir);
+ if (!fi.exists() || !fi.isDir() || !fi.isReadable()) {
+ valid = false;
+ qCDebug(LogInstaller) << "cleanup: uninstalling" << pkg->id() << "- directory missing:" << checkDir;
+ break;
+ }
+ }
+
+ if (valid) {
+ validPaths.insertMulti(d->installationPath, pkg->id() + qL1C('/'));
+ validPaths.insertMulti(d->documentPath, pkg->id() + qL1C('/'));
+ } else {
+ if (startingPackageRemoval(pkg->id())) {
+ if (finishedPackageInstall(pkg->id()))
+ continue;
+ }
+ throw Exception(Error::Package, "could not remove broken installation of package %1 from database").arg(pkg->id());
+ }
+ }
+ }
+
+ // Remove everything that is not referenced from the app-db
+
+ for (auto it = validPaths.cbegin(); it != validPaths.cend(); ) {
+ const QString currentDir = it.key();
+
+ // collect all values for the unique key currentDir
+ QVector<QString> validNames;
+ for ( ; it != validPaths.cend() && it.key() == currentDir; ++it)
+ validNames << it.value();
+
+ const QFileInfoList &dirEntries = QDir(currentDir).entryInfoList(QDir::AllEntries | QDir::NoDotAndDotDot);
+
+ // check if there is anything in the filesystem that is NOT listed in the validNames
+ for (const QFileInfo &fi : dirEntries) {
+ QString name = fi.fileName();
+ if (fi.isDir())
+ name.append(qL1C('/'));
+
+ if ((!fi.isDir() && !fi.isFile()) || !validNames.contains(name)) {
+ qCDebug(LogInstaller) << "cleanup: removing unreferenced inode" << name;
+
+ if (SudoClient::instance()) {
+ if (!SudoClient::instance()->removeRecursive(fi.absoluteFilePath())) {
+ throw Exception(Error::IO, "could not remove broken installation leftover %1: %2")
+ .arg(fi.absoluteFilePath()).arg(SudoClient::instance()->lastError());
+ }
+ } else {
+ if (!recursiveOperation(fi.absoluteFilePath(), safeRemove)) {
+ throw Exception(Error::IO, "could not remove broken installation leftover %1 (maybe due to missing root privileges)")
+ .arg(fi.absoluteFilePath());
+ }
+ }
+ }
+ }
+ }
+}
+
+/*!
+ \qmlmethod list<string> PackageManager::packageIds()
+
+ Returns a list of all available package ids. This can be used to further query for specific
+ information via get().
+*/
+QStringList PackageManager::packageIds() const
+{
+ QStringList ids;
+ ids.reserve(d->packages.size());
+ for (int i = 0; i < d->packages.size(); ++i)
+ ids << d->packages.at(i)->id();
+ return ids;
+}
+
+/*!
+ \qmlmethod object PackageManager::get(string id)
+
+ Retrieves the model data for the package identified by \a id as a JavaScript object.
+ See the \l {PackageManager Roles}{role names} for the expected object fields.
+
+ Returns an empty object if the specified \a id is invalid.
+*/
+QVariantMap PackageManager::get(const QString &id) const
+{
+ int index = indexOfPackage(id);
+ return (index < 0) ? QVariantMap{} : get(index);
+}
+
+/*!
+ \qmlmethod int PackageManager::installedPackageSize(string packageId)
+
+ Returns the size in bytes that the package identified by \a packageId is occupying on the storage
+ device.
+
+ Returns \c -1 in case the package \a packageId is not valid, or the package is not installed.
+*/
+qint64 PackageManager::installedPackageSize(const QString &packageId) const
+{
+ if (Package *package = fromId(packageId)) {
+ if (const InstallationReport *report = package->info()->installationReport())
+ return static_cast<qint64>(report->diskSpaceUsed());
+ }
+ return -1;
+}
+
+/*!
+ \qmlmethod var PackageManager::installedPackageExtraMetaData(string packageId)
+
+ Returns a map of all extra metadata in the package header of the package identified by \a packageId.
+
+ Returns an empty map in case the package \a packageId is not valid, or the package is not installed.
+*/
+QVariantMap PackageManager::installedPackageExtraMetaData(const QString &packageId) const
+{
+ if (Package *package = fromId(packageId)) {
+ if (const InstallationReport *report = package->info()->installationReport())
+ return report->extraMetaData();
+ }
+ return QVariantMap();
+}
+
+/*!
+ \qmlmethod var PackageManager::installedPackageExtraSignedMetaData(string packageId)
+
+ Returns a map of all signed extra metadata in the package header of the package identified
+ by \a packageId.
+
+ Returns an empty map in case the package \a packageId is not valid, or the package is not installed.
+*/
+QVariantMap PackageManager::installedPackageExtraSignedMetaData(const QString &packageId) const
+{
+ if (Package *package = fromId(packageId)) {
+ if (const InstallationReport *report = package->info()->installationReport())
+ return report->extraSignedMetaData();
+ }
+ return QVariantMap();
+}
+
+/*! \internal
+ Type safe convenience function, since DBus does not like QUrl
+*/
+QString PackageManager::startPackageInstallation(const QUrl &sourceUrl)
+{
+ AM_TRACE(LogInstaller, sourceUrl);
+
+ return enqueueTask(new InstallationTask(d->installationPath, d->documentPath, sourceUrl));
+}
+
+/*!
+ \qmlmethod string PackageManager::startPackageInstallation(string sourceUrl)
+
+ Downloads an application package from \a sourceUrl and installs it.
+
+ The actual download and installation will happen asynchronously in the background. The
+ PackageManager emits the signals \l taskStarted, \l taskProgressChanged, \l
+ taskRequestingInstallationAcknowledge, \l taskFinished, \l taskFailed, and \l taskStateChanged
+ for the returned taskId when applicable.
+
+ \note Simply calling this function is not enough to complete a package installation: The
+ taskRequestingInstallationAcknowledge() signal needs to be connected to a slot where the
+ supplied package meta-data can be validated (either programmatically or by asking the user).
+ If the validation is successful, the installation can be completed by calling
+ acknowledgePackageInstallation() or, if the validation was unsuccessful, the installation should
+ be canceled by calling cancelTask().
+ Failing to do one or the other will leave an unfinished "zombie" installation.
+
+ Returns a unique \c taskId. This can also be an empty string, if the task could not be
+ created (in this case, no signals will be emitted).
+*/
+QString PackageManager::startPackageInstallation(const QString &sourceUrl)
+{
+ QUrl url(sourceUrl);
+ if (url.scheme().isEmpty())
+ url = QUrl::fromLocalFile(sourceUrl);
+ return startPackageInstallation(url);
+}
+
+/*!
+ \qmlmethod void PackageManager::acknowledgePackageInstallation(string taskId)
+
+ Calling this function enables the installer to complete the installation task identified by \a
+ taskId. Normally, this function is called after receiving the taskRequestingInstallationAcknowledge()
+ signal, and the user and/or the program logic decided to proceed with the installation.
+
+ \sa startPackageInstallation()
+ */
+void PackageManager::acknowledgePackageInstallation(const QString &taskId)
+{
+ AM_TRACE(LogInstaller, taskId)
+
+ const auto allTasks = d->allTasks();
+
+ for (AsynchronousTask *task : allTasks) {
+ if (qobject_cast<InstallationTask *>(task) && (task->id() == taskId)) {
+ static_cast<InstallationTask *>(task)->acknowledge();
+ break;
+ }
+ }
+}
+
+/*!
+ \qmlmethod string PackageManager::removePackage(string packageId, bool keepDocuments, bool force)
+
+ Uninstalls the package identified by \a id. Normally, the documents directory of the
+ package is deleted on removal, but this can be prevented by setting \a keepDocuments to \c true.
+
+ The actual removal will happen asynchronously in the background. The PackageManager will
+ emit the signals \l taskStarted, \l taskProgressChanged, \l taskFinished, \l taskFailed and \l
+ taskStateChanged for the returned \c taskId when applicable.
+
+ Normally, \a force should only be set to \c true if a previous call to removePackage() failed.
+ This may be necessary if the installation process was interrupted, or or has file-system issues.
+
+ Returns a unique \c taskId. This can also be an empty string, if the task could not be created
+ (in this case, no signals will be emitted).
+*/
+QString PackageManager::removePackage(const QString &packageId, bool keepDocuments, bool force)
+{
+ AM_TRACE(LogInstaller, packageId, keepDocuments)
+
+ if (Package *package = fromId(packageId)) {
+ if (package->info()->installationReport()) {
+ return enqueueTask(new DeinstallationTask(package, d->installationPath,
+ d->documentPath, force, keepDocuments));
+ }
+ }
+ return QString();
+}
+
+
+/*!
+ \qmlmethod enumeration PackageManager::taskState(string taskId)
+
+ Returns the current state of the installation task identified by \a taskId.
+ \l {TaskStates}{See here} for a list of valid task states.
+
+ Returns \c PackageManager.Invalid if the \a taskId is invalid.
+*/
+AsynchronousTask::TaskState PackageManager::taskState(const QString &taskId) const
+{
+ const auto allTasks = d->allTasks();
+
+ for (const AsynchronousTask *task : allTasks) {
+ if (task && (task->id() == taskId))
+ return task->state();
+ }
+ return AsynchronousTask::Invalid;
+}
+
+/*!
+ \qmlmethod string PackageManager::taskPackageId(string taskId)
+
+ Returns the package id associated with the task identified by \a taskId. The task may not
+ have a valid package id at all times though and in this case the function will return an
+ empty string (this will be the case for installations before the taskRequestingInstallationAcknowledge
+ signal has been emitted).
+
+ Returns an empty string if the \a taskId is invalid.
+*/
+QString PackageManager::taskPackageId(const QString &taskId) const
+{
+ const auto allTasks = d->allTasks();
+
+ for (const AsynchronousTask *task : allTasks) {
+ if (task && (task->id() == taskId))
+ return task->packageId();
+ }
+ return QString();
+}
+
+/*!
+ \qmlmethod list<string> PackageManager::activeTaskIds()
+
+ Retuns a list of all currently active (as in not yet finished or failed) installation task ids.
+*/
+QStringList PackageManager::activeTaskIds() const
+{
+ const auto allTasks = d->allTasks();
+
+ QStringList result;
+ for (const AsynchronousTask *task : allTasks)
+ result << task->id();
+ return result;
+}
+
+/*!
+ \qmlmethod bool PackageManager::cancelTask(string taskId)
+
+ Tries to cancel the installation task identified by \a taskId.
+
+ Returns \c true if the task was canceled, \c false otherwise.
+*/
+bool PackageManager::cancelTask(const QString &taskId)
+{
+ AM_TRACE(LogInstaller, taskId)
+
+ // incoming tasks can be forcefully cancelled right away
+ for (AsynchronousTask *task : qAsConst(d->incomingTaskList)) {
+ if (task->id() == taskId) {
+ task->forceCancel();
+ task->deleteLater();
+
+ handleFailure(task);
+
+ d->incomingTaskList.removeOne(task);
+ triggerExecuteNextTask();
+ return true;
+ }
+ }
+
+ // the active task and async tasks might be in a state where cancellation is not possible,
+ // so we have to ask them nicely
+ if (d->activeTask && d->activeTask->id() == taskId)
+ return d->activeTask->cancel();
+
+ for (AsynchronousTask *task : qAsConst(d->installationTaskList)) {
+ if (task->id() == taskId)
+ return task->cancel();
+ }
+ return false;
+}
+
+/*!
+ \qmlmethod int PackageManager::compareVersions(string version1, string version2)
+
+ Convenience method for app-store implementations or taskRequestingInstallationAcknowledge()
+ callbacks for comparing version numbers, as the actual version comparison algorithm is not
+ trivial.
+
+ Returns \c -1, \c 0 or \c 1 if \a version1 is smaller than, equal to, or greater than \a
+ version2 (similar to how \c strcmp() works).
+*/
+int PackageManager::compareVersions(const QString &version1, const QString &version2)
+{
+ int vn1Suffix = -1;
+ int vn2Suffix = -1;
+ QVersionNumber vn1 = QVersionNumber::fromString(version1, &vn1Suffix);
+ QVersionNumber vn2 = QVersionNumber::fromString(version2, &vn2Suffix);
+
+ int d = QVersionNumber::compare(vn1, vn2);
+ return d < 0 ? -1 : (d > 0 ? 1 : version1.mid(vn1Suffix).compare(version2.mid(vn2Suffix)));
+}
+
+/*!
+ \qmlmethod int PackageManager::validateDnsName(string name, int minimalPartCount)
+
+ Convenience method for app-store implementations or taskRequestingInstallationAcknowledge()
+ callbacks for checking if the given \a name is a valid DNS (or reverse-DNS) name according to
+ RFC 1035/1123. If the optional parameter \a minimalPartCount is specified, this function will
+ also check if \a name contains at least this amount of parts/sub-domains.
+
+ Returns \c true if the name is a valid DNS name or \c false otherwise.
+*/
+bool PackageManager::validateDnsName(const QString &name, int minimalPartCount)
+{
+ try {
+ // check if we have enough parts: e.g. "tld.company.app" would have 3 parts
+ QStringList parts = name.split('.');
+ if (parts.size() < minimalPartCount) {
+ throw Exception(Error::Parse, "the minimum amount of parts (subdomains) is %1 (found %2)")
+ .arg(minimalPartCount).arg(parts.size());
+ }
+
+ // standard RFC compliance tests (RFC 1035/1123)
+
+ auto partCheck = [](const QString &part) {
+ int len = part.length();
+
+ if (len < 1 || len > 63)
+ throw Exception(Error::Parse, "domain parts must consist of at least 1 and at most 63 characters (found %2 characters)").arg(len);
+
+ for (int pos = 0; pos < len; ++pos) {
+ ushort ch = part.at(pos).unicode();
+ bool isFirst = (pos == 0);
+ bool isLast = (pos == (len - 1));
+ bool isDash = (ch == '-');
+ bool isDigit = (ch >= '0' && ch <= '9');
+ bool isLower = (ch >= 'a' && ch <= 'z');
+
+ if ((isFirst || isLast || !isDash) && !isDigit && !isLower)
+ throw Exception(Error::Parse, "domain parts must consist of only the characters '0-9', 'a-z', and '-' (which cannot be the first or last character)");
+ }
+ };
+
+ for (const QString &part : parts)
+ partCheck(part);
+
+ return true;
+ } catch (const Exception &e) {
+ qCDebug(LogInstaller).noquote() << "validateDnsName failed:" << e.errorString();
+ return false;
+ }
+}
+
+QString PackageManager::enqueueTask(AsynchronousTask *task)
+{
+ d->incomingTaskList.append(task);
+ triggerExecuteNextTask();
+ return task->id();
+}
+
+void PackageManager::triggerExecuteNextTask()
+{
+ if (!QMetaObject::invokeMethod(this, "executeNextTask", Qt::QueuedConnection))
+ qCCritical(LogSystem) << "ERROR: failed to invoke method checkQueue";
+}
+
+void PackageManager::executeNextTask()
+{
+ if (d->activeTask || d->incomingTaskList.isEmpty())
+ return;
+
+ AsynchronousTask *task = d->incomingTaskList.takeFirst();
+
+ if (task->hasFailed()) {
+ task->setState(AsynchronousTask::Failed);
+
+ handleFailure(task);
+
+ task->deleteLater();
+ triggerExecuteNextTask();
+ return;
+ }
+
+ connect(task, &AsynchronousTask::started, this, [this, task]() {
+ emit taskStarted(task->id());
+ });
+
+ connect(task, &AsynchronousTask::stateChanged, this, [this, task](AsynchronousTask::TaskState newState) {
+ emit taskStateChanged(task->id(), newState);
+ });
+
+ connect(task, &AsynchronousTask::progress, this, [this, task](qreal p) {
+ emit taskProgressChanged(task->id(), p);
+
+ Package *package = fromId(task->packageId());
+ if (package && (package->state() != Package::Installed)) {
+ package->setProgress(p);
+ // Icon will be in a "+" suffixed directory during installation. So notify about a change on its
+ // location as well.
+ emitDataChanged(package, QVector<int> { Icon, UpdateProgress });
+ }
+ });
+
+ connect(task, &AsynchronousTask::finished, this, [this, task]() {
+ task->setState(task->hasFailed() ? AsynchronousTask::Failed : AsynchronousTask::Finished);
+
+ if (task->hasFailed()) {
+ handleFailure(task);
+ } else {
+ qCDebug(LogInstaller) << "emit finished" << task->id();
+ emit taskFinished(task->id());
+ }
+
+ if (d->activeTask == task)
+ d->activeTask = nullptr;
+ d->installationTaskList.removeOne(task);
+
+ delete task;
+ triggerExecuteNextTask();
+ });
+
+ if (qobject_cast<InstallationTask *>(task)) {
+ connect(static_cast<InstallationTask *>(task), &InstallationTask::finishedPackageExtraction, this, [this, task]() {
+ qCDebug(LogInstaller) << "emit blockingUntilInstallationAcknowledge" << task->id();
+ emit taskBlockingUntilInstallationAcknowledge(task->id());
+
+ // we can now start the next download in parallel - the InstallationTask will take care
+ // of serializing the final installation steps on its own as soon as it gets the
+ // required acknowledge (or cancel).
+ if (d->activeTask == task)
+ d->activeTask = nullptr;
+ d->installationTaskList.append(task);
+ triggerExecuteNextTask();
+ });
+ }
+
+
+ d->activeTask = task;
+ task->setState(AsynchronousTask::Executing);
+ task->start();
+}
+
+void PackageManager::handleFailure(AsynchronousTask *task)
+{
+ qCDebug(LogInstaller) << "emit failed" << task->id() << task->errorCode() << task->errorString();
+ emit taskFailed(task->id(), int(task->errorCode()), task->errorString());
+}
+
+bool PackageManager::startingPackageInstallation(PackageInfo *info)
+{
+ // ownership of info is transferred to PackageManager
+ QScopedPointer<PackageInfo> newInfo(info);
+
+ if (!newInfo || newInfo->id().isEmpty())
+ return false;
+ Package *package = fromId(newInfo->id());
+// if (!RuntimeFactory::instance()->manager(newInfo->runtimeName()))
+// return false;
+
+ if (package) { // update
+ if (!package->block())
+ return false;
+
+ if (package->isBuiltIn()) {
+ // overlay the existing base info
+ // we will rollback to the base one if this update is removed.
+ package->setUpdatedInfo(newInfo.take());
+ } else {
+ // overwrite the existing base info
+ // we're not keeping track of the original. so removing the updated base version removes the
+ // application entirely.
+ package->setBaseInfo(newInfo.take());
+ }
+ package->setState(Package::BeingUpdated);
+ package->setProgress(0);
+ emitDataChanged(package);
+ } else { // installation
+ package = new Package(newInfo.take(), Package::BeingInstalled);
+
+ Q_ASSERT(package->block());
+
+ beginInsertRows(QModelIndex(), d->packages.count(), d->packages.count());
+
+ QQmlEngine::setObjectOwnership(package, QQmlEngine::CppOwnership);
+ d->packages << package;
+
+ endInsertRows();
+
+ emitDataChanged(package);
+
+ emit packageAdded(package->id());
+ }
+ return true;
+}
+
+bool PackageManager::startingPackageRemoval(const QString &id)
+{
+ Package *package = fromId(id);
+ if (!package)
+ return false;
+
+ if (package->isBlocked() || (package->state() != Package::Installed))
+ return false;
+
+ if (package->isBuiltIn() && !package->canBeRevertedToBuiltIn())
+ return false;
+
+ if (!package->block()) // this will implicitly stop all apps in this package (asynchronously)
+ return false;
+
+ package->setState(package->canBeRevertedToBuiltIn() ? Package::BeingDowngraded
+ : Package::BeingRemoved);
+
+ package->setProgress(0);
+ emitDataChanged(package, QVector<int> { IsUpdating });
+ return true;
+}
+
+bool PackageManager::finishedPackageInstall(const QString &id)
+{
+ Package *package = fromId(id);
+ if (!package)
+ return false;
+
+ switch (package->state()) {
+ case Package::Installed:
+ return false;
+
+ case Package::BeingInstalled:
+ case Package::BeingUpdated: {
+ // The Package object has been updated right at the start of the installation/update.
+ // Now's the time to update the InstallationReport that was written by the installer.
+ QFile irfile(QDir(package->info()->baseDir()).absoluteFilePath(qSL(".installation-report.yaml")));
+ QScopedPointer<InstallationReport> ir(new InstallationReport(package->id()));
+ if (!irfile.open(QFile::ReadOnly) || !ir->deserialize(&irfile)) {
+ qCCritical(LogInstaller) << "Could not read the new installation-report for package"
+ << package->id() << "at" << irfile.fileName();
+ return false;
+ }
+ package->info()->setInstallationReport(ir.take());
+ package->setState(Package::Installed);
+ package->setProgress(0);
+
+ emitDataChanged(package);
+
+ package->unblock();
+ emit package->bulkChange(); // not ideal, but icon and codeDir have changed
+ break;
+ }
+ case Package::BeingDowngraded:
+ package->setUpdatedInfo(nullptr);
+ package->setState(Package::Installed);
+ break;
+
+ case Package::BeingRemoved: {
+ int row = d->packages.indexOf(package);
+ if (row >= 0) {
+ emit packageAboutToBeRemoved(package->id());
+ beginRemoveRows(QModelIndex(), row, row);
+ d->packages.removeAt(row);
+ endRemoveRows();
+ }
+ delete package;
+ break;
+ }
+ }
+
+ //emit internalSignals.applicationsChanged();
+
+ return true;
+}
+
+bool PackageManager::canceledPackageInstall(const QString &id)
+{
+ Package *package = fromId(id);
+ if (!package)
+ return false;
+
+ switch (package->state()) {
+ case Package::Installed:
+ return false;
+
+ case Package::BeingInstalled: {
+ int row = d->packages.indexOf(package);
+ if (row >= 0) {
+ emit packageAboutToBeRemoved(package->id());
+ beginRemoveRows(QModelIndex(), row, row);
+ d->packages.removeAt(row);
+ endRemoveRows();
+ }
+ delete package;
+ break;
+ }
+ case Package::BeingUpdated:
+ case Package::BeingDowngraded:
+ case Package::BeingRemoved:
+ package->setState(Package::Installed);
+ package->setProgress(0);
+ emitDataChanged(package, QVector<int> { IsUpdating });
+
+ package->unblock();
+ break;
+ }
+ return true;
+}
+
+bool removeRecursiveHelper(const QString &path)
+{
+ if (PackageManager::instance()->isApplicationUserIdSeparationEnabled() && SudoClient::instance())
+ return SudoClient::instance()->removeRecursive(path);
+ else
+ return recursiveOperation(path, safeRemove);
+}
+
+QT_END_NAMESPACE_AM
diff --git a/src/installer-lib/applicationinstaller.h b/src/manager-lib/packagemanager.h
index 2afaeb85..fb1cb2ee 100644
--- a/src/installer-lib/applicationinstaller.h
+++ b/src/manager-lib/packagemanager.h
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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
@@ -43,87 +43,106 @@
#pragma once
#include <QObject>
-#include <QVariant>
-#include <QUrl>
-#include <QStringList>
-#include <QDir>
-#include <QtAppManCommon/error.h>
-#include <QtAppManInstaller/installationlocation.h>
-#include <QtAppManInstaller/asynchronoustask.h>
+#include <QAbstractListModel>
+#include <QtAppManCommon/global.h>
+#include <QtAppManApplication/packageinfo.h>
+#include <QtAppManManager/asynchronoustask.h>
+#include <QtAppManManager/installationtask.h>
+#include <QtAppManManager/deinstallationtask.h>
+
QT_FORWARD_DECLARE_CLASS(QQmlEngine)
QT_FORWARD_DECLARE_CLASS(QJSEngine)
QT_BEGIN_NAMESPACE_AM
-class ApplicationManager;
-class ApplicationInstallerPrivate;
-class SudoClient;
-
+class PackageDatabase;
+class Package;
+class PackageManagerPrivate;
-class ApplicationInstaller : public QObject
+class PackageManager : public QAbstractListModel
{
Q_OBJECT
- Q_CLASSINFO("D-Bus Interface", "io.qt.ApplicationInstaller")
- Q_CLASSINFO("AM-QmlType", "QtApplicationManager.SystemUI/ApplicationInstaller 2.0 SINGLETON")
+ Q_PROPERTY(int count READ count NOTIFY countChanged)
+ Q_CLASSINFO("D-Bus Interface", "io.qt.PackageManager")
+ Q_CLASSINFO("AM-QmlType", "QtApplicationManager.SystemUI/PackageManager 2.0 SINGLETON")
- // both are const on purpose - these should never change in a running system
+ // these are const on purpose - these should never change in a running system
Q_PROPERTY(bool allowInstallationOfUnsignedPackages READ allowInstallationOfUnsignedPackages CONSTANT)
Q_PROPERTY(bool developmentMode READ developmentMode CONSTANT)
+ Q_PROPERTY(QString hardwareId READ hardwareId CONSTANT)
+
+ Q_PROPERTY(QVariantMap installationLocation READ installationLocation CONSTANT)
+ Q_PROPERTY(QVariantMap documentLocation READ documentLocation CONSTANT)
Q_PROPERTY(bool applicationUserIdSeparation READ isApplicationUserIdSeparationEnabled)
Q_PROPERTY(uint commonApplicationGroupId READ commonApplicationGroupId)
-
public:
- Q_ENUMS(QT_PREPEND_NAMESPACE_AM(AsynchronousTask::TaskState))
-
- ~ApplicationInstaller();
- static ApplicationInstaller *createInstance(const QVector<InstallationLocation> &installationLocations,
- const QString &manifestDirPath,
- const QString &hardwareId, QString *error);
- static ApplicationInstaller *instance();
+ enum CacheMode {
+ NoCache,
+ UseCache,
+ RecreateCache
+ };
+
+ ~PackageManager() override;
+ static PackageManager *createInstance(PackageDatabase *packageDatabase,
+ const QString &documentPath);
+ static PackageManager *instance();
static QObject *instanceForQml(QQmlEngine *qmlEngine, QJSEngine *);
+ QVector<Package *> packages() const;
+
+ Package *fromId(const QString &id) const;
+
+ // the item model part
+ int rowCount(const QModelIndex &parent = QModelIndex()) const override;
+ QVariant data(const QModelIndex &index, int role) const override;
+ QHash<int, QByteArray> roleNames() const override;
+
+ int count() const;
+ Q_INVOKABLE QVariantMap get(int index) const;
+ Q_INVOKABLE Package *package(int index) const;
+ Q_INVOKABLE Package *package(const QString &id) const;
+ Q_INVOKABLE int indexOfPackage(const QString &id) const;
+
bool developmentMode() const;
- void setDevelopmentMode(bool b);
+ void setDevelopmentMode(bool enable);
bool allowInstallationOfUnsignedPackages() const;
- void setAllowInstallationOfUnsignedPackages(bool b);
+ void setAllowInstallationOfUnsignedPackages(bool enable);
QString hardwareId() const;
+ void setHardwareId(const QString &hwId);
+// bool securityChecksEnabled() const;
+// void setSecurityChecksEnabled(bool enabled);
bool isApplicationUserIdSeparationEnabled() const;
uint commonApplicationGroupId() const;
bool enableApplicationUserIdSeparation(uint minUserId, uint maxUserId, uint commonGroupId);
- // Ownership of QDir* stays with ApplicationInstaller
- // Never returns null
- const QDir *manifestDirectory() const;
-
- bool setDBusPolicy(const QVariantMap &yamlFragment);
void setCACertificates(const QList<QByteArray> &chainOfTrust);
- void cleanupBrokenInstallations() const Q_DECL_NOEXCEPT_EXPR(false);
+ void cleanupBrokenInstallations() Q_DECL_NOEXCEPT_EXPR(false);
- // InstallationLocation handling
- QVector<InstallationLocation> installationLocations() const;
- const InstallationLocation &defaultInstallationLocation() const;
- const InstallationLocation &installationLocationFromId(const QString &installationLocationId) const;
- const InstallationLocation &installationLocationFromApplication(const QString &id) const;
+ QVariantMap installationLocation() const;
+ QVariantMap documentLocation() const;
// Q_SCRIPTABLEs are available via both QML and D-Bus
- Q_SCRIPTABLE QStringList installationLocationIds() const;
- Q_SCRIPTABLE QString installationLocationIdFromApplication(const QString &id) const;
- Q_SCRIPTABLE QVariantMap getInstallationLocation(const QString &installationLocationId) const;
+ Q_SCRIPTABLE QStringList packageIds() const;
+ Q_SCRIPTABLE QVariantMap get(const QString &id) const;
+
+ Q_SCRIPTABLE qint64 installedPackageSize(const QString &packageId) const;
+ Q_SCRIPTABLE QVariantMap installedPackageExtraMetaData(const QString &packageId) const;
+ Q_SCRIPTABLE QVariantMap installedPackageExtraSignedMetaData(const QString &packageId) const;
// all QString return values are task-ids
- QString startPackageInstallation(const QString &installationLocationId, const QUrl &sourceUrl);
- Q_SCRIPTABLE QString startPackageInstallation(const QString &installationLocationId, const QString &sourceUrl);
+ QString startPackageInstallation(const QUrl &sourceUrl);
+ Q_SCRIPTABLE QString startPackageInstallation(const QString &sourceUrl);
Q_SCRIPTABLE void acknowledgePackageInstallation(const QString &taskId);
Q_SCRIPTABLE QString removePackage(const QString &id, bool keepDocuments, bool force = false);
Q_SCRIPTABLE AsynchronousTask::TaskState taskState(const QString &taskId) const;
- Q_SCRIPTABLE QString taskApplicationId(const QString &taskId) const;
+ Q_SCRIPTABLE QString taskPackageId(const QString &taskId) const;
Q_SCRIPTABLE QStringList activeTaskIds() const;
Q_SCRIPTABLE bool cancelTask(const QString &taskId);
@@ -131,11 +150,14 @@ public:
Q_SCRIPTABLE int compareVersions(const QString &version1, const QString &version2);
Q_SCRIPTABLE bool validateDnsName(const QString &name, int minimumParts = 1);
- Q_SCRIPTABLE qint64 installedApplicationSize(const QString &id) const;
- Q_SCRIPTABLE QVariantMap installedApplicationExtraMetaData(const QString &id) const;
- Q_SCRIPTABLE QVariantMap installedApplicationExtraSignedMetaData(const QString &id) const;
signals:
+ Q_SCRIPTABLE void countChanged();
+
+ Q_SCRIPTABLE void packageAdded(const QString &id);
+ Q_SCRIPTABLE void packageAboutToBeRemoved(const QString &id);
+ Q_SCRIPTABLE void packageChanged(const QString &id, const QStringList &changedRoles);
+
Q_SCRIPTABLE void taskStarted(const QString &taskId);
Q_SCRIPTABLE void taskProgressChanged(const QString &taskId, qreal progress);
Q_SCRIPTABLE void taskFinished(const QString &taskId);
@@ -145,7 +167,7 @@ signals:
// installation only
Q_SCRIPTABLE void taskRequestingInstallationAcknowledge(const QString &taskId,
- const QVariantMap &applicationAsVariantMap,
+ const QVariantMap &packageAsVariantMap,
const QVariantMap &packageExtraMetaData,
const QVariantMap &packageExtraSignedMetaData);
Q_SCRIPTABLE void taskBlockingUntilInstallationAcknowledge(const QString &taskId);
@@ -153,28 +175,36 @@ signals:
private slots:
void executeNextTask();
+protected:
+ bool startingPackageInstallation(PackageInfo *info);
+ bool startingPackageRemoval(const QString &id);
+ bool finishedPackageInstall(const QString &id);
+ bool canceledPackageInstall(const QString &id);
+
private:
- void cleanupMounts() const;
+ void emitDataChanged(Package *package, const QVector<int> &roles = QVector<int>());
+ static void registerQmlTypes();
+
void triggerExecuteNextTask();
QString enqueueTask(AsynchronousTask *task);
void handleFailure(AsynchronousTask *task);
QList<QByteArray> caCertificates() const;
+private:
uint findUnusedUserId() const Q_DECL_NOEXCEPT_EXPR(false);
-private:
- // Ownership of manifestDir and iamgeMountDir is passed to ApplicationInstaller
- ApplicationInstaller(const QVector<InstallationLocation> &installationLocations, QDir *manifestDir, const QString &hardwareId, QObject *parent);
- ApplicationInstaller(const ApplicationInstaller &);
- static ApplicationInstaller *s_instance;
+ explicit PackageManager(PackageDatabase *packageDatabase,
+ const QString &documentPath);
+ PackageManager(const PackageManager &);
+ PackageManager &operator=(const PackageManager &);
+ static PackageManager *s_instance;
+ static QHash<int, QByteArray> s_roleNames;
- ApplicationInstallerPrivate *d;
+ PackageManagerPrivate *d;
friend class InstallationTask;
friend class DeinstallationTask;
};
QT_END_NAMESPACE_AM
-
-Q_DECLARE_METATYPE(QT_PREPEND_NAMESPACE_AM(AsynchronousTask::TaskState))
diff --git a/src/installer-lib/applicationinstaller_p.h b/src/manager-lib/packagemanager_p.h
index 09fc1324..4e7a158b 100644
--- a/src/installer-lib/applicationinstaller_p.h
+++ b/src/manager-lib/packagemanager_p.h
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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
@@ -48,17 +48,21 @@
#include <QScopedPointer>
#include <QThread>
-#include <QtAppManInstaller/applicationinstaller.h>
-#include <QtAppManInstaller/sudo.h>
+#include <QtAppManManager/packagemanager.h>
+#include <QtAppManApplication/packagedatabase.h>
+#include <QtAppManManager/asynchronoustask.h>
#include <QtAppManCommon/global.h>
QT_BEGIN_NAMESPACE_AM
bool removeRecursiveHelper(const QString &path);
-class ApplicationInstallerPrivate
+class PackageManagerPrivate
{
public:
+ PackageDatabase *database = nullptr;
+ QVector<Package *> packages;
+
bool developmentMode = false;
bool allowInstallationOfUnsignedPackages = false;
bool userIdSeparation = false;
@@ -66,9 +70,8 @@ public:
uint maxUserId = uint(-1);
uint commonGroupId = uint(-1);
- QScopedPointer<QDir> manifestDir;
- QVector<InstallationLocation> installationLocations;
- InstallationLocation invalidInstallationLocation;
+ QString installationPath;
+ QString documentPath;
QString error;
diff --git a/src/manager-lib/plugincontainer.cpp b/src/manager-lib/plugincontainer.cpp
index 2150f8d4..32f334c0 100644
--- a/src/manager-lib/plugincontainer.cpp
+++ b/src/manager-lib/plugincontainer.cpp
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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
@@ -61,7 +61,7 @@ bool PluginContainerManager::supportsQuickLaunch() const
return m_interface->supportsQuickLaunch();
}
-AbstractContainer *PluginContainerManager::create(AbstractApplication *app, const QVector<int> &stdioRedirections,
+AbstractContainer *PluginContainerManager::create(Application *app, const QVector<int> &stdioRedirections,
const QMap<QString, QString> &debugWrapperEnvironment,
const QStringList &debugWrapperCommand)
{
@@ -133,7 +133,7 @@ AbstractContainerProcess *PluginContainer::start(const QStringList &arguments, c
return nullptr;
}
-PluginContainer::PluginContainer(AbstractContainerManager *manager, AbstractApplication *app, ContainerInterface *containerInterface)
+PluginContainer::PluginContainer(AbstractContainerManager *manager, Application *app, ContainerInterface *containerInterface)
: AbstractContainer(manager, app)
, m_interface(containerInterface)
, m_process(new PluginContainerProcess(this))
diff --git a/src/manager-lib/plugincontainer.h b/src/manager-lib/plugincontainer.h
index acf250da..c97f2af2 100644
--- a/src/manager-lib/plugincontainer.h
+++ b/src/manager-lib/plugincontainer.h
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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
@@ -56,7 +56,7 @@ public:
static QString defaultIdentifier();
bool supportsQuickLaunch() const override;
- AbstractContainer *create(AbstractApplication *app, const QVector<int> &stdioRedirections,
+ AbstractContainer *create(Application *app, const QVector<int> &stdioRedirections,
const QMap<QString, QString> &debugWrapperEnvironment,
const QStringList &debugWrapperCommand) override;
@@ -108,7 +108,7 @@ public:
const QVariantMap &amConfig) override;
protected:
- explicit PluginContainer(AbstractContainerManager *manager, AbstractApplication *app, ContainerInterface *containerInterface);
+ explicit PluginContainer(AbstractContainerManager *manager, Application *app, ContainerInterface *containerInterface);
ContainerInterface *m_interface;
PluginContainerProcess *m_process;
bool m_startCalled = false;
diff --git a/src/manager-lib/processcontainer.cpp b/src/manager-lib/processcontainer.cpp
index 23113239..57420100 100644
--- a/src/manager-lib/processcontainer.cpp
+++ b/src/manager-lib/processcontainer.cpp
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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
@@ -183,7 +183,7 @@ void HostProcess::setStopBeforeExec(bool stopBeforeExec)
}
-ProcessContainer::ProcessContainer(ProcessContainerManager *manager, AbstractApplication *app,
+ProcessContainer::ProcessContainer(ProcessContainerManager *manager, Application *app,
const QVector<int> &stdioRedirections,
const QMap<QString, QString> &debugWrapperEnvironment,
const QStringList &debugWrapperCommand)
@@ -323,7 +323,7 @@ bool ProcessContainerManager::supportsQuickLaunch() const
return true;
}
-AbstractContainer *ProcessContainerManager::create(AbstractApplication *app, const QVector<int> &stdioRedirections,
+AbstractContainer *ProcessContainerManager::create(Application *app, const QVector<int> &stdioRedirections,
const QMap<QString, QString> &debugWrapperEnvironment,
const QStringList &debugWrapperCommand)
{
diff --git a/src/manager-lib/processcontainer.h b/src/manager-lib/processcontainer.h
index 65d11acb..99348a25 100644
--- a/src/manager-lib/processcontainer.h
+++ b/src/manager-lib/processcontainer.h
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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
@@ -60,7 +60,7 @@ public:
static QString defaultIdentifier();
bool supportsQuickLaunch() const override;
- AbstractContainer *create(AbstractApplication *app, const QVector<int> &stdioRedirections,
+ AbstractContainer *create(Application *app, const QVector<int> &stdioRedirections,
const QMap<QString, QString> &debugWrapperEnvironment,
const QStringList &debugWrapperCommand) override;
};
@@ -100,7 +100,7 @@ class ProcessContainer : public AbstractContainer
Q_OBJECT
public:
- explicit ProcessContainer(ProcessContainerManager *manager, AbstractApplication *app,
+ explicit ProcessContainer(ProcessContainerManager *manager, Application *app,
const QVector<int> &stdioRedirections,
const QMap<QString, QString> &debugWrapperEnvironment,
const QStringList &debugWrapperCommand);
diff --git a/src/manager-lib/processstatus.cpp b/src/manager-lib/processstatus.cpp
index 8d6e88c4..25ce85b1 100644
--- a/src/manager-lib/processstatus.cpp
+++ b/src/manager-lib/processstatus.cpp
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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
@@ -190,7 +190,7 @@ void ProcessStatus::setApplicationId(const QString &appId)
qmlWarning(this) << "Invalid application ID:" << appId;
} else {
m_application = ApplicationManager::instance()->application(appIndex);
- connect(m_application, &AbstractApplication::runStateChanged, this, &ProcessStatus::onRunStateChanged);
+ connect(m_application, &Application::runStateChanged, this, &ProcessStatus::onRunStateChanged);
}
}
determinePid();
diff --git a/src/manager-lib/processstatus.h b/src/manager-lib/processstatus.h
index b233aced..612bb23c 100644
--- a/src/manager-lib/processstatus.h
+++ b/src/manager-lib/processstatus.h
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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
@@ -105,7 +105,7 @@ private:
QVariantMap m_memoryRss;
QVariantMap m_memoryPss;
- QPointer<AbstractApplication> m_application;
+ QPointer<Application> m_application;
bool m_pendingUpdate = false;
QScopedPointer<ProcessReader> m_reader;
diff --git a/src/manager-lib/qmlinprocessapplicationinterface.cpp b/src/manager-lib/qmlinprocessapplicationinterface.cpp
index a24651b4..caceabe3 100644
--- a/src/manager-lib/qmlinprocessapplicationinterface.cpp
+++ b/src/manager-lib/qmlinprocessapplicationinterface.cpp
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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
@@ -78,7 +78,7 @@ QVariantMap QmlInProcessApplicationInterface::name() const
{
QVariantMap names;
if (m_runtime && m_runtime->application()) {
- const QMap<QString, QString> &sm = m_runtime->application()->info()->names();
+ const QMap<QString, QString> &sm = m_runtime->application()->packageInfo()->names();
for (auto it = sm.cbegin(); it != sm.cend(); ++it)
names.insert(it.key(), it.value());
}
@@ -88,7 +88,7 @@ QVariantMap QmlInProcessApplicationInterface::name() const
QUrl QmlInProcessApplicationInterface::icon() const
{
if (m_runtime && m_runtime->application())
- return m_runtime->application()->icon();
+ return m_runtime->application()->packageInfo()->icon();
return QUrl();
}
diff --git a/src/manager-lib/qmlinprocessapplicationinterface.h b/src/manager-lib/qmlinprocessapplicationinterface.h
index 87b43bf7..669b1461 100644
--- a/src/manager-lib/qmlinprocessapplicationinterface.h
+++ b/src/manager-lib/qmlinprocessapplicationinterface.h
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/src/manager-lib/qmlinprocessapplicationmanagerwindow.cpp b/src/manager-lib/qmlinprocessapplicationmanagerwindow.cpp
index 8bf809aa..fe368b41 100644
--- a/src/manager-lib/qmlinprocessapplicationmanagerwindow.cpp
+++ b/src/manager-lib/qmlinprocessapplicationmanagerwindow.cpp
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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
@@ -182,8 +182,6 @@ void QmlInProcessApplicationManagerWindow::data_clear(QQmlListProperty<QObject>
void QmlInProcessApplicationManagerWindow::componentComplete()
{
- qCDebug(LogSystem) << "QmlInProcessApplicationManagerWindow componentComplete() this:" << this;
-
if (!m_runtime)
m_runtime = QmlInProcessRuntime::determineRuntime(this);
diff --git a/src/manager-lib/qmlinprocessapplicationmanagerwindow.h b/src/manager-lib/qmlinprocessapplicationmanagerwindow.h
index 5207e3d4..55796cba 100644
--- a/src/manager-lib/qmlinprocessapplicationmanagerwindow.h
+++ b/src/manager-lib/qmlinprocessapplicationmanagerwindow.h
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/src/manager-lib/qmlinprocessruntime.cpp b/src/manager-lib/qmlinprocessruntime.cpp
index 788e22d2..7f769b7d 100644
--- a/src/manager-lib/qmlinprocessruntime.cpp
+++ b/src/manager-lib/qmlinprocessruntime.cpp
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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
@@ -107,7 +107,7 @@ bool QmlInProcessRuntime::start()
if (m_app->runtimeParameters().value(qSL("loadDummyData")).toBool()) {
qCDebug(LogSystem) << "Loading dummy-data";
- loadQmlDummyDataFiles(m_inProcessQmlEngine, QFileInfo(m_app->nonAliasedInfo()->absoluteCodeFilePath()).path());
+ loadQmlDummyDataFiles(m_inProcessQmlEngine, QFileInfo(m_app->info()->absoluteCodeFilePath()).path());
}
const QStringList importPaths = variantToStringList(configuration().value(qSL("importPaths")))
@@ -120,11 +120,10 @@ bool QmlInProcessRuntime::start()
qCDebug(LogSystem) << "Updated Qml import paths:" << m_inProcessQmlEngine->importPathList();
}
- m_componentError = false;
- QQmlComponent *component = new QQmlComponent(m_inProcessQmlEngine, m_app->nonAliasedInfo()->absoluteCodeFilePath());
+ QQmlComponent *component = new QQmlComponent(m_inProcessQmlEngine, m_app->info()->absoluteCodeFilePath());
if (!component->isReady()) {
- qCDebug(LogSystem) << "qml-file (" << m_app->nonAliasedInfo()->absoluteCodeFilePath() << "): component not ready:\n" << component->errorString();
+ qCDebug(LogSystem) << "qml-file (" << m_app->info()->absoluteCodeFilePath() << "): component not ready:\n" << component->errorString();
return false;
}
@@ -143,8 +142,8 @@ bool QmlInProcessRuntime::start()
QMetaObject::invokeMethod(this, [component, appContext, obj, this]() {
component->completeCreate();
- if (!obj || m_componentError) {
- qCCritical(LogSystem) << "could not load" << m_app->nonAliasedInfo()->absoluteCodeFilePath() << ": no root object";
+ if (!obj) {
+ qCCritical(LogSystem) << "could not load" << m_app->info()->absoluteCodeFilePath() << ": no root object";
delete obj;
delete appContext;
delete m_applicationIf;
@@ -192,7 +191,7 @@ void QmlInProcessRuntime::stop(bool forceKill)
#else
int exitCode = 0;
#endif
- finish(exitCode, Am::CrashExit);
+ finish(exitCode, Am::ForcedExit);
return;
}
@@ -206,7 +205,7 @@ void QmlInProcessRuntime::stop(bool forceKill)
#else
int exitCode = 0;
#endif
- finish(exitCode, Am::CrashExit);
+ finish(exitCode, Am::ForcedExit);
});
}
diff --git a/src/manager-lib/qmlinprocessruntime.h b/src/manager-lib/qmlinprocessruntime.h
index f2d57eb6..0efc7495 100644
--- a/src/manager-lib/qmlinprocessruntime.h
+++ b/src/manager-lib/qmlinprocessruntime.h
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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
@@ -100,7 +100,6 @@ private:
QString m_document;
QmlInProcessApplicationInterface *m_applicationIf = nullptr;
- bool m_componentError;
bool m_stopIfNoVisibleSurfaces = false;
diff --git a/src/manager-lib/quicklauncher.cpp b/src/manager-lib/quicklauncher.cpp
index 2cf841d5..2494b840 100644
--- a/src/manager-lib/quicklauncher.cpp
+++ b/src/manager-lib/quicklauncher.cpp
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/src/manager-lib/quicklauncher.h b/src/manager-lib/quicklauncher.h
index c1a0cb94..8fd74e8c 100644
--- a/src/manager-lib/quicklauncher.h
+++ b/src/manager-lib/quicklauncher.h
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/src/manager-lib/runtimefactory.cpp b/src/manager-lib/runtimefactory.cpp
index c87561ea..bf00c31a 100644
--- a/src/manager-lib/runtimefactory.cpp
+++ b/src/manager-lib/runtimefactory.cpp
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/src/manager-lib/runtimefactory.h b/src/manager-lib/runtimefactory.h
index 7e41a4d4..66e0222a 100644
--- a/src/manager-lib/runtimefactory.h
+++ b/src/manager-lib/runtimefactory.h
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/src/installer-lib/scopeutilities.cpp b/src/manager-lib/scopeutilities.cpp
index 45fe4742..089e03cf 100644
--- a/src/installer-lib/scopeutilities.cpp
+++ b/src/manager-lib/scopeutilities.cpp
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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
@@ -42,7 +42,7 @@
#include "logging.h"
#include "scopeutilities.h"
-#include "applicationinstaller_p.h"
+#include "packagemanager_p.h"
#include "utilities.h"
QT_BEGIN_NAMESPACE_AM
@@ -92,7 +92,6 @@ QDir ScopedDirectoryCreator::dir()
return QDir(m_path);
}
-
ScopedRenamer::ScopedRenamer()
{ }
diff --git a/src/installer-lib/scopeutilities.h b/src/manager-lib/scopeutilities.h
index f3d30424..7ebe5166 100644
--- a/src/installer-lib/scopeutilities.h
+++ b/src/manager-lib/scopeutilities.h
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/src/installer-lib/sudo.cpp b/src/manager-lib/sudo.cpp
index a9d661fe..ab497d89 100644
--- a/src/installer-lib/sudo.cpp
+++ b/src/manager-lib/sudo.cpp
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/src/installer-lib/sudo.h b/src/manager-lib/sudo.h
index 357261e6..33215279 100644
--- a/src/installer-lib/sudo.h
+++ b/src/manager-lib/sudo.h
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/src/monitor-lib/processreader.cpp b/src/monitor-lib/processreader.cpp
index b89e9b3c..6cbbe22d 100644
--- a/src/monitor-lib/processreader.cpp
+++ b/src/monitor-lib/processreader.cpp
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/src/monitor-lib/processreader.h b/src/monitor-lib/processreader.h
index e135101c..cfef25b6 100644
--- a/src/monitor-lib/processreader.h
+++ b/src/monitor-lib/processreader.h
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/src/monitor-lib/sysfsreader.cpp b/src/monitor-lib/sysfsreader.cpp
index d100dc43..2b6e66a1 100644
--- a/src/monitor-lib/sysfsreader.cpp
+++ b/src/monitor-lib/sysfsreader.cpp
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/src/monitor-lib/sysfsreader.h b/src/monitor-lib/sysfsreader.h
index 8a299177..127ddb2f 100644
--- a/src/monitor-lib/sysfsreader.h
+++ b/src/monitor-lib/sysfsreader.h
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/src/monitor-lib/systemreader.cpp b/src/monitor-lib/systemreader.cpp
index 67692fe1..bc1c8514 100644
--- a/src/monitor-lib/systemreader.cpp
+++ b/src/monitor-lib/systemreader.cpp
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/src/monitor-lib/systemreader.h b/src/monitor-lib/systemreader.h
index a6879495..df5c48fa 100644
--- a/src/monitor-lib/systemreader.h
+++ b/src/monitor-lib/systemreader.h
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/src/notification-lib/notification.cpp b/src/notification-lib/notification.cpp
index 0df9055f..588513a0 100644
--- a/src/notification-lib/notification.cpp
+++ b/src/notification-lib/notification.cpp
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/src/notification-lib/notification.h b/src/notification-lib/notification.h
index 5dfcfd81..d4ecc501 100644
--- a/src/notification-lib/notification.h
+++ b/src/notification-lib/notification.h
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/src/package-lib/package-lib.pro b/src/package-lib/package-lib.pro
index d38aa343..056649c2 100644
--- a/src/package-lib/package-lib.pro
+++ b/src/package-lib/package-lib.pro
@@ -17,17 +17,16 @@ include($$SOURCE_DIR/3rdparty/libarchive.pri)
include($$SOURCE_DIR/3rdparty/libz.pri)
HEADERS += \
- package_p.h \
packageextractor_p.h \
packageextractor.h \
packagecreator_p.h \
packagecreator.h \
- package.h
+ packageutilities.h \
+ packageutilities_p.h \
SOURCES += \
- package_p.cpp \
packagecreator.cpp \
packageextractor.cpp \
- package.cpp
+ packageutilities.cpp
load(qt_module)
diff --git a/src/package-lib/packagecreator.cpp b/src/package-lib/packagecreator.cpp
index fcfa5c85..ab1fd448 100644
--- a/src/package-lib/packagecreator.cpp
+++ b/src/package-lib/packagecreator.cpp
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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
@@ -51,7 +51,7 @@
#include <archive.h>
#include <archive_entry.h>
-#include "package_p.h"
+#include "packageutilities_p.h"
#include "packagecreator.h"
#include "packagecreator_p.h"
#include "exception.h"
@@ -174,18 +174,18 @@ bool PackageCreatorPrivate::create()
char buffer[64 * 1024];
try {
- if (m_report.applicationId().isNull())
+ if (m_report.packageId().isNull())
throw Exception("package identifier is null");
QCryptographicHash digest(QCryptographicHash::Sha256);
QVariantMap headerFormat {
{ qSL("formatType"), qSL("am-package-header") },
- { qSL("formatVersion"), 1 }
+ { qSL("formatVersion"), 2 }
};
m_metaData = QVariantMap {
- { qSL("applicationId"), m_report.applicationId() },
+ { qSL("packageId"), m_report.packageId() },
{ qSL("diskSpaceUsed"), m_report.diskSpaceUsed() }
};
if (!m_report.extraMetaData().isEmpty())
@@ -342,7 +342,7 @@ bool PackageCreatorPrivate::create()
QVariantMap footerFormat {
{ qSL("formatType"), qSL("am-package-footer") },
- { qSL("formatVersion"), 1 }
+ { qSL("formatVersion"), 2 }
};
QVariantMap footerData {
diff --git a/src/package-lib/packagecreator.h b/src/package-lib/packagecreator.h
index 34044760..b3021dce 100644
--- a/src/package-lib/packagecreator.h
+++ b/src/package-lib/packagecreator.h
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/src/package-lib/packagecreator_p.h b/src/package-lib/packagecreator_p.h
index 47016af4..4175559f 100644
--- a/src/package-lib/packagecreator_p.h
+++ b/src/package-lib/packagecreator_p.h
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/src/package-lib/packageextractor.cpp b/src/package-lib/packageextractor.cpp
index 6ecdff0e..d5d18c8f 100644
--- a/src/package-lib/packageextractor.cpp
+++ b/src/package-lib/packageextractor.cpp
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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
@@ -54,14 +54,14 @@
#include <archive.h>
#include <archive_entry.h>
-#include "package_p.h"
+#include "packageutilities_p.h"
#include "packageextractor.h"
#include "packageextractor_p.h"
#include "exception.h"
#include "error.h"
#include "installationreport.h"
#include "utilities.h"
-#include "applicationinfo.h"
+#include "packageinfo.h"
#include "qtyaml.h"
// archive.h might #define this for Android
@@ -463,7 +463,7 @@ void PackageExtractorPrivate::processMetaData(const QByteArray &metadata, QCrypt
.arg(error.errorString()).arg(error.line).arg(error.column);
try {
- checkYamlFormat(docs, -2 /*at least 2 docs*/, { isHeader ? "am-package-header" : "am-package-footer" }, 1);
+ checkYamlFormat(docs, -2 /*at least 2 docs*/, { isHeader ? "am-package-header" : "am-package-footer" }, 2);
} catch (const Exception &e) {
throw Exception(Error::Package, "metadata has an invalid format specification: %1").arg(e.errorString());
}
@@ -471,12 +471,12 @@ void PackageExtractorPrivate::processMetaData(const QByteArray &metadata, QCrypt
QVariantMap map = docs.at(1).toMap();
if (isHeader) {
- QString applicationId = map.value(qSL("applicationId")).toString();
+ QString packageId = map.value(qSL("packageId")).toString();
quint64 diskSpaceUsed = map.value(qSL("diskSpaceUsed")).toULongLong();
- if (applicationId.isNull() || !ApplicationInfo::isValidApplicationId(applicationId))
- throw Exception(Error::Package, "metadata has an invalid applicationId field (%1)").arg(applicationId);
- m_report.setApplicationId(applicationId);
+ if (packageId.isNull() || !PackageInfo::isValidApplicationId(packageId))
+ throw Exception(Error::Package, "metadata has an invalid packageId field (%1)").arg(packageId);
+ m_report.setPackageId(packageId);
if (!diskSpaceUsed)
throw Exception(Error::Package, "metadata has an invalid diskSpaceUsed field (%1)").arg(diskSpaceUsed);
diff --git a/src/package-lib/packageextractor.h b/src/package-lib/packageextractor.h
index eb3b1e7f..13b92871 100644
--- a/src/package-lib/packageextractor.h
+++ b/src/package-lib/packageextractor.h
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/src/package-lib/packageextractor_p.h b/src/package-lib/packageextractor_p.h
index a8f72c8a..5463fcf5 100644
--- a/src/package-lib/packageextractor_p.h
+++ b/src/package-lib/packageextractor_p.h
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/src/package-lib/package.cpp b/src/package-lib/packageutilities.cpp
index 481117e9..f5e80180 100644
--- a/src/package-lib/package.cpp
+++ b/src/package-lib/packageutilities.cpp
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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
@@ -40,17 +40,25 @@
**
****************************************************************************/
+
+#include <QFileInfo>
+#include <QDataStream>
+#include <QCryptographicHash>
#include <QByteArray>
#include <QString>
-#include "package.h"
+#include <archive.h>
+
+#include "packageutilities.h"
+#include "packageutilities_p.h"
#include "global.h"
#include <clocale>
+
QT_BEGIN_NAMESPACE_AM
-bool Package::ensureCorrectLocale(QStringList *warnings)
+bool PackageUtilities::ensureCorrectLocale(QStringList *warnings)
{
// We need to make sure we are running in a Unicode locale, since we are
// running into problems when unpacking packages with libarchive that
@@ -119,7 +127,7 @@ bool Package::ensureCorrectLocale(QStringList *warnings)
}
-bool Package::checkCorrectLocale()
+bool PackageUtilities::checkCorrectLocale()
{
// see ensureCorrectLocale() above. Call this after the QApplication
// constructor as a sanity check.
@@ -131,4 +139,41 @@ bool Package::checkCorrectLocale()
#endif
}
+
+ArchiveException::ArchiveException(struct ::archive *ar, const char *errorString)
+ : Exception(Error::Archive, qSL("[libarchive] ") + qL1S(errorString) + qSL(": ") + QString::fromLocal8Bit(::archive_error_string(ar)))
+{ }
+
+
+QVariantMap PackageUtilities::headerDataForDigest = QVariantMap {
+ { "extraSigned", QVariantMap() }
+};
+
+void PackageUtilities::addFileMetadataToDigest(const QString &entryFilePath, const QFileInfo &fi, QCryptographicHash &digest)
+{
+ // (using QDataStream would be more readable, but it would make the algorithm Qt dependent)
+ QByteArray addToDigest = ((fi.isDir()) ? "D/" : "F/")
+ + QByteArray::number(fi.isDir() ? 0 : fi.size())
+ + '/' + entryFilePath.toUtf8();
+ digest.addData(addToDigest);
+}
+
+void PackageUtilities::addHeaderDataToDigest(const QVariantMap &header, QCryptographicHash &digest) Q_DECL_NOEXCEPT_EXPR(false)
+{
+ for (auto it = headerDataForDigest.constBegin(); it != headerDataForDigest.constEnd(); ++it) {
+ if (header.contains(it.key())) {
+ QByteArray ba;
+ QDataStream ds(&ba, QIODevice::WriteOnly);
+
+ QVariant v = header.value(it.key());
+ if (!v.convert(int(it.value().type())))
+ throw Exception(Error::Package, "metadata field %1 has invalid type for digest calculation (cannot convert %2 to %3)")
+ .arg(it.key()).arg(header.value(it.key()).type()).arg(it.value().type());
+ ds << v;
+
+ digest.addData(ba);
+ }
+ }
+}
+
QT_END_NAMESPACE_AM
diff --git a/src/package-lib/package.h b/src/package-lib/packageutilities.h
index 44d0561a..2b9c4a8b 100644
--- a/src/package-lib/package.h
+++ b/src/package-lib/packageutilities.h
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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
@@ -47,7 +47,7 @@
QT_BEGIN_NAMESPACE_AM
-namespace Package
+namespace PackageUtilities
{
bool ensureCorrectLocale(QStringList *warnings = nullptr);
bool checkCorrectLocale();
diff --git a/src/package-lib/package_p.h b/src/package-lib/packageutilities_p.h
index d1218fae..62e1a90a 100644
--- a/src/package-lib/package_p.h
+++ b/src/package-lib/packageutilities_p.h
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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
@@ -52,14 +52,13 @@ QT_FORWARD_DECLARE_CLASS(QCryptographicHash)
QT_BEGIN_NAMESPACE_AM
-class PackageUtilities
+namespace PackageUtilities
{
-public:
- static void addFileMetadataToDigest(const QString &entryFilePath, const QFileInfo &fi, QCryptographicHash &digest);
- static void addHeaderDataToDigest(const QVariantMap &header, QCryptographicHash &digest) Q_DECL_NOEXCEPT_EXPR(false);
+void addFileMetadataToDigest(const QString &entryFilePath, const QFileInfo &fi, QCryptographicHash &digest);
+void addHeaderDataToDigest(const QVariantMap &header, QCryptographicHash &digest) Q_DECL_NOEXCEPT_EXPR(false);
- // key == field name, value == type to choose correct hashing algorithm
- static QVariantMap headerDataForDigest;
+// key == field name, value == type to choose correct hashing algorithm
+extern QVariantMap headerDataForDigest;
};
enum PackageEntryType {
diff --git a/src/plugin-interfaces/containerinterface.cpp b/src/plugin-interfaces/containerinterface.cpp
index d5009720..564bff94 100644
--- a/src/plugin-interfaces/containerinterface.cpp
+++ b/src/plugin-interfaces/containerinterface.cpp
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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
@@ -131,10 +131,6 @@ ContainerManagerInterface::~ContainerManagerInterface() { }
\row
\li \c applicationProperties
\li A map with all application properties as seen in the manifest.
- \row
- \li \c installationLocationId
- \li The installation location id, if this application was installed - empty for built-in
- applications.
\endtable
*/
diff --git a/src/plugin-interfaces/containerinterface.h b/src/plugin-interfaces/containerinterface.h
index 010959c4..64b81a92 100644
--- a/src/plugin-interfaces/containerinterface.h
+++ b/src/plugin-interfaces/containerinterface.h
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/src/plugin-interfaces/startupinterface.cpp b/src/plugin-interfaces/startupinterface.cpp
index 07e27708..73db5db3 100644
--- a/src/plugin-interfaces/startupinterface.cpp
+++ b/src/plugin-interfaces/startupinterface.cpp
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/src/plugin-interfaces/startupinterface.h b/src/plugin-interfaces/startupinterface.h
index b0125784..a8b710fe 100644
--- a/src/plugin-interfaces/startupinterface.h
+++ b/src/plugin-interfaces/startupinterface.h
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/src/shared-main-lib/cpustatus.cpp b/src/shared-main-lib/cpustatus.cpp
index d192781d..b98891cc 100644
--- a/src/shared-main-lib/cpustatus.cpp
+++ b/src/shared-main-lib/cpustatus.cpp
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/src/shared-main-lib/cpustatus.h b/src/shared-main-lib/cpustatus.h
index f7e37867..30393fa6 100644
--- a/src/shared-main-lib/cpustatus.h
+++ b/src/shared-main-lib/cpustatus.h
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/src/shared-main-lib/frametimer.cpp b/src/shared-main-lib/frametimer.cpp
index 1805f0ee..7751599b 100644
--- a/src/shared-main-lib/frametimer.cpp
+++ b/src/shared-main-lib/frametimer.cpp
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/src/shared-main-lib/frametimer.h b/src/shared-main-lib/frametimer.h
index 384f9a09..30c5225d 100644
--- a/src/shared-main-lib/frametimer.h
+++ b/src/shared-main-lib/frametimer.h
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/src/shared-main-lib/gpustatus.cpp b/src/shared-main-lib/gpustatus.cpp
index efa7d2ad..69692ce8 100644
--- a/src/shared-main-lib/gpustatus.cpp
+++ b/src/shared-main-lib/gpustatus.cpp
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/src/shared-main-lib/gpustatus.h b/src/shared-main-lib/gpustatus.h
index e7e23f7c..2a0df87d 100644
--- a/src/shared-main-lib/gpustatus.h
+++ b/src/shared-main-lib/gpustatus.h
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/src/shared-main-lib/iostatus.cpp b/src/shared-main-lib/iostatus.cpp
index fba8fff6..8c771015 100644
--- a/src/shared-main-lib/iostatus.cpp
+++ b/src/shared-main-lib/iostatus.cpp
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/src/shared-main-lib/iostatus.h b/src/shared-main-lib/iostatus.h
index b6070fad..0c7f4c3f 100644
--- a/src/shared-main-lib/iostatus.h
+++ b/src/shared-main-lib/iostatus.h
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/src/shared-main-lib/memorystatus.cpp b/src/shared-main-lib/memorystatus.cpp
index 1b6909a7..730f5894 100644
--- a/src/shared-main-lib/memorystatus.cpp
+++ b/src/shared-main-lib/memorystatus.cpp
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/src/shared-main-lib/memorystatus.h b/src/shared-main-lib/memorystatus.h
index 716c9f82..d9dcc8da 100644
--- a/src/shared-main-lib/memorystatus.h
+++ b/src/shared-main-lib/memorystatus.h
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/src/shared-main-lib/monitormodel.cpp b/src/shared-main-lib/monitormodel.cpp
index 5dbda61d..1433b608 100644
--- a/src/shared-main-lib/monitormodel.cpp
+++ b/src/shared-main-lib/monitormodel.cpp
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/src/shared-main-lib/monitormodel.h b/src/shared-main-lib/monitormodel.h
index 5def27dd..b7d80e9a 100644
--- a/src/shared-main-lib/monitormodel.h
+++ b/src/shared-main-lib/monitormodel.h
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/src/shared-main-lib/qmllogger.cpp b/src/shared-main-lib/qmllogger.cpp
index 7ec4303c..b40bfc52 100644
--- a/src/shared-main-lib/qmllogger.cpp
+++ b/src/shared-main-lib/qmllogger.cpp
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/src/shared-main-lib/qmllogger.h b/src/shared-main-lib/qmllogger.h
index ab39412b..a47c31d3 100644
--- a/src/shared-main-lib/qmllogger.h
+++ b/src/shared-main-lib/qmllogger.h
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/src/shared-main-lib/sharedmain.cpp b/src/shared-main-lib/sharedmain.cpp
index 647eb91f..080664b4 100644
--- a/src/shared-main-lib/sharedmain.cpp
+++ b/src/shared-main-lib/sharedmain.cpp
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/src/shared-main-lib/sharedmain.h b/src/shared-main-lib/sharedmain.h
index 7a4cac85..6e9deb41 100644
--- a/src/shared-main-lib/sharedmain.h
+++ b/src/shared-main-lib/sharedmain.h
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/src/src.pro b/src/src.pro
index 63e95d48..b5e66223 100644
--- a/src/src.pro
+++ b/src/src.pro
@@ -21,9 +21,7 @@ package_lib.depends = crypto_lib application_lib
manager_lib.subdir = manager-lib
manager_lib.depends = application_lib notification_lib intent_server_lib intent_client_lib monitor_lib plugin_interfaces
-
-installer_lib.subdir = installer-lib
-installer_lib.depends = package_lib manager_lib
+!disable-installer:manager_lib.depends += package_lib crypto_lib
window_lib.subdir = window-lib
window_lib.depends = manager_lib
@@ -44,11 +42,11 @@ launcher_lib.subdir = launcher-lib
launcher_lib.depends = application_lib notification_lib shared_main_lib intent_client_lib
main_lib.subdir = main-lib
-main_lib.depends = shared_main_lib manager_lib installer_lib window_lib monitor_lib
+main_lib.depends = shared_main_lib manager_lib window_lib monitor_lib
!disable-external-dbus-interfaces:qtHaveModule(dbus) {
dbus_lib.subdir = dbus-lib
- dbus_lib.depends = manager_lib installer_lib window_lib
+ dbus_lib.depends = manager_lib window_lib
main_lib.depends += dbus_lib
}
@@ -63,10 +61,10 @@ tools_testrunner.subdir = tools/testrunner
tools_testrunner.depends = main_lib
tools_dumpqmltypes.subdir = tools/dumpqmltypes
-tools_dumpqmltypes.depends = manager_lib installer_lib window_lib shared_main_lib launcher_lib
+tools_dumpqmltypes.depends = manager_lib window_lib shared_main_lib main_lib launcher_lib
tools_packager.subdir = tools/packager
-tools_packager.depends = package_lib
+tools_packager.depends = package_lib application_lib crypto_lib
tools_uploader.subdir = tools/uploader
tools_uploader.depends = common_lib
@@ -90,7 +88,6 @@ SUBDIRS = \
qtHaveModule(qml):SUBDIRS += \
notification_lib \
manager_lib \
- installer_lib \
window_lib \
monitor_lib \
shared_main_lib \
@@ -106,16 +103,20 @@ SUBDIRS = \
launcher_lib \
# This tool links against everything to extract the Qml type information
- qtHaveModule(qml):qtHaveModule(dbus):!headless:SUBDIRS += \
+ !disable-installer:qtHaveModule(qml):qtHaveModule(dbus):!headless:SUBDIRS += \
tools_dumpqmltypes \
multi-process:qtHaveModule(qml):qtHaveModule(dbus):SUBDIRS += \
tools_launcher_qml \
}
-!android:SUBDIRS += \
- tools_packager \
- tools_uploader \
+!android {
+ !disable-installer:SUBDIRS += \
+ tools_packager
+
+ SUBDIRS += \
+ tools_uploader
+}
qtHaveModule(dbus):SUBDIRS += \
tools_controller \
diff --git a/src/tools/appman/appman.cpp b/src/tools/appman/appman.cpp
index 5523edb9..f1808e89 100644
--- a/src/tools/appman/appman.cpp
+++ b/src/tools/appman/appman.cpp
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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
@@ -47,7 +47,7 @@
#include "logging.h"
#include "main.h"
#include "defaultconfiguration.h"
-#include "package.h"
+#include "packageutilities.h"
#if !defined(AM_DISABLE_INSTALLER)
# include "sudo.h"
#endif
@@ -70,8 +70,8 @@ Q_DECL_EXPORT int main(int argc, char *argv[])
#else
QCoreApplication::setApplicationName(qSL("Qt Application Manager"));
#endif
- QCoreApplication::setOrganizationName(qSL("Luxoft Sweden AB"));
- QCoreApplication::setOrganizationDomain(qSL("luxoft.com"));
+ QCoreApplication::setOrganizationName(qSL("QtProject"));
+ QCoreApplication::setOrganizationDomain(qSL("qt-project.org"));
QCoreApplication::setApplicationVersion(qSL(AM_VERSION));
Logging::initialize(argc, argv);
@@ -81,7 +81,7 @@ Q_DECL_EXPORT int main(int argc, char *argv[])
QStringList deploymentWarnings;
#if !defined(AM_DISABLE_INSTALLER)
- Package::ensureCorrectLocale(&deploymentWarnings);
+ PackageUtilities::ensureCorrectLocale(&deploymentWarnings);
Sudo::forkServer(Sudo::DropPrivilegesPermanently, &deploymentWarnings);
StartupTimer::instance()->checkpoint("after sudo server fork");
#endif
@@ -103,7 +103,9 @@ Q_DECL_EXPORT int main(int argc, char *argv[])
StartupTimer::instance()->checkpoint("after command line parse");
#if defined(AM_TESTRUNNER)
- TestRunner::initialize(cfg.testRunnerArguments());
+ TestRunner::initialize(cfg.mainQmlFile(), cfg.testRunnerArguments());
+ qInfo().nospace().noquote() << "\nTEST: " << cfg.mainQmlFile() << " in "
+ << (cfg.forceMultiProcess() ? "multi" : "single") << "-process mode";
cfg.setForceVerbose(qEnvironmentVariableIsSet("VERBOSE_TEST"));
qInfo() << "Verbose mode is" << (cfg.verbose() ? "on" : "off") << "(changed by (un)setting $VERBOSE_TEST)";
#endif
diff --git a/src/tools/controller/controller.cpp b/src/tools/controller/controller.cpp
index 6c8a8e83..71696b87 100644
--- a/src/tools/controller/controller.cpp
+++ b/src/tools/controller/controller.cpp
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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:GPL-EXCEPT-QTAS$
** Commercial License Usage
@@ -49,7 +49,7 @@
#include <QtAppManCommon/dbus-utilities.h>
#include "applicationmanager_interface.h"
-#include "applicationinstaller_interface.h"
+#include "packagemanager_interface.h"
#include "interrupthandler.h"
@@ -72,13 +72,13 @@ public:
m_manager = new IoQtApplicationManagerInterface(qSL("io.qt.ApplicationManager"), qSL("/ApplicationManager"), conn, this);
}
- void connectToInstaller() Q_DECL_NOEXCEPT_EXPR(false)
+ void connectToPackager() Q_DECL_NOEXCEPT_EXPR(false)
{
- if (m_installer)
+ if (m_packager)
return;
- auto conn = connectTo(qSL("io.qt.ApplicationInstaller"));
- m_installer = new IoQtApplicationInstallerInterface(qSL("io.qt.ApplicationManager"), qSL("/ApplicationInstaller"), conn, this);
+ auto conn = connectTo(qSL("io.qt.PackageManager"));
+ m_packager = new IoQtPackageManagerInterface(qSL("io.qt.ApplicationManager"), qSL("/PackageManager"), conn, this);
}
private:
@@ -111,9 +111,9 @@ private:
}
public:
- IoQtApplicationInstallerInterface *installer() const
+ IoQtPackageManagerInterface *packager() const
{
- return m_installer;
+ return m_packager;
}
IoQtApplicationManagerInterface *manager() const
@@ -122,7 +122,7 @@ public:
}
private:
- IoQtApplicationInstallerInterface *m_installer = nullptr;
+ IoQtPackageManagerInterface *m_packager = nullptr;
IoQtApplicationManagerInterface *m_manager = nullptr;
};
@@ -137,6 +137,8 @@ enum Command {
StopAllApplications,
ListApplications,
ShowApplication,
+ ListPackages,
+ ShowPackage,
InstallPackage,
RemovePackage,
ListInstallationTasks,
@@ -157,6 +159,8 @@ static struct {
{ StopAllApplications, "stop-all-applications", "Stop all applications." },
{ ListApplications, "list-applications", "List all installed applications." },
{ ShowApplication, "show-application", "Show application meta-data." },
+ { ListPackages, "list-packages", "List all installed packages." },
+ { ShowPackage, "show-package", "Show package meta-data." },
{ InstallPackage, "install-package", "Install a package." },
{ RemovePackage, "remove-package", "Remove a package." },
{ ListInstallationTasks, "list-installation-tasks", "List all active installation tasks." },
@@ -188,12 +192,14 @@ static void stopApplication(const QString &appId, bool forceKill = false) Q_DECL
static void stopAllApplications() Q_DECL_NOEXCEPT_EXPR(false);
static void listApplications() Q_DECL_NOEXCEPT_EXPR(false);
static void showApplication(const QString &appId, bool asJson = false) Q_DECL_NOEXCEPT_EXPR(false);
-static void installPackage(const QString &package, const QString &location, bool acknowledge) Q_DECL_NOEXCEPT_EXPR(false);
-static void removePackage(const QString &package, bool keepDocuments, bool force) Q_DECL_NOEXCEPT_EXPR(false);
+static void listPackages() Q_DECL_NOEXCEPT_EXPR(false);
+static void showPackage(const QString &packageId, bool asJson = false) Q_DECL_NOEXCEPT_EXPR(false);
+static void installPackage(const QString &packageUrl, bool acknowledge) Q_DECL_NOEXCEPT_EXPR(false);
+static void removePackage(const QString &packageId, bool keepDocuments, bool force) Q_DECL_NOEXCEPT_EXPR(false);
static void listInstallationTasks() Q_DECL_NOEXCEPT_EXPR(false);
static void cancelInstallationTask(bool all, const QString &taskId) Q_DECL_NOEXCEPT_EXPR(false);
static void listInstallationLocations() Q_DECL_NOEXCEPT_EXPR(false);
-static void showInstallationLocation(const QString &location, bool asJson = false) Q_DECL_NOEXCEPT_EXPR(false);
+static void showInstallationLocation(bool asJson = false) Q_DECL_NOEXCEPT_EXPR(false);
class ThrowingApplication : public QCoreApplication // clazy:exclude=missing-qobject-macro
{
@@ -232,8 +238,8 @@ private:
int main(int argc, char *argv[])
{
QCoreApplication::setApplicationName(qSL("Qt Application Manager Controller"));
- QCoreApplication::setOrganizationName(qSL("Luxoft Sweden AB"));
- QCoreApplication::setOrganizationDomain(qSL("luxoft.com"));
+ QCoreApplication::setOrganizationName(qSL("QtProject"));
+ QCoreApplication::setOrganizationDomain(qSL("qt-project.org"));
QCoreApplication::setApplicationVersion(qSL(AM_VERSION));
ThrowingApplication a(argc, argv);
@@ -381,18 +387,37 @@ int main(int argc, char *argv[])
clp.isSet(qSL("json"))));
break;
+ case ListPackages:
+ clp.process(a);
+ a.runLater(listPackages);
+ break;
+
+ case ShowPackage:
+ clp.addOption({ qSL("json"), qSL("Output in JSON format instead of YAML.") });
+ clp.addPositionalArgument(qSL("package-id"), qSL("The id of an installed package."));
+ clp.process(a);
+
+ if (clp.positionalArguments().size() != 2)
+ clp.showHelp(1);
+
+ a.runLater(std::bind(showPackage,
+ clp.positionalArguments().at(1),
+ clp.isSet(qSL("json"))));
+ break;
+
case InstallPackage:
- clp.addOption({ { qSL("l"), qSL("location") }, qSL("Set a custom installation location."), qSL("installation-location"), qSL("internal-0") });
+ clp.addOption({ { qSL("l"), qSL("location") }, qSL("Set a custom installation location (deprecated and ignored)."), qSL("installation-location"), qSL("internal-0") });
clp.addOption({ { qSL("a"), qSL("acknowledge") }, qSL("Automatically acknowledge the installation (unattended mode).") });
clp.addPositionalArgument(qSL("package"), qSL("The file name of the package; can be - for stdin."));
clp.process(a);
if (clp.positionalArguments().size() != 2)
clp.showHelp(1);
+ if (clp.isSet(qSL("l")))
+ fprintf(stderr, "Ignoring the deprecated -l option.\n");
a.runLater(std::bind(installPackage,
clp.positionalArguments().at(1),
- clp.value(qSL("l")),
clp.isSet(qSL("a"))));
break;
@@ -437,15 +462,16 @@ int main(int argc, char *argv[])
break;
case ShowInstallationLocation:
- clp.addPositionalArgument(qSL("installation-location"), qSL("The id of an installation location."));
+ clp.addPositionalArgument(qSL("installation-location"), qSL("The id of an installation location (deprecated and ignored)."));
clp.addOption({ qSL("json"), qSL("Output in JSON format instead of YAML.") });
clp.process(a);
- if (clp.positionalArguments().size() != 2)
+ if (clp.positionalArguments().size() > 2)
clp.showHelp(1);
+ if (clp.positionalArguments().size() == 2)
+ fprintf(stderr, "Ignoring the deprecated installation-location.\n");
a.runLater(std::bind(showInstallationLocation,
- clp.positionalArguments().at(1),
clp.isSet(qSL("json"))));
break;
}
@@ -601,7 +627,37 @@ void showApplication(const QString &appId, bool asJson) Q_DECL_NOEXCEPT_EXPR(fal
qApp->quit();
}
-void installPackage(const QString &package, const QString &location, bool acknowledge) Q_DECL_NOEXCEPT_EXPR(false)
+void listPackages() Q_DECL_NOEXCEPT_EXPR(false)
+{
+ dbus.connectToPackager();
+
+ auto reply = dbus.packager()->packageIds();
+ reply.waitForFinished();
+ if (reply.isError())
+ throw Exception(Error::IO, "failed to call packageIds via DBus: %1").arg(reply.error().message());
+
+ const auto packageIds = reply.value();
+ for (auto packageId : packageIds)
+ fprintf(stdout, "%s\n", qPrintable(packageId));
+ qApp->quit();
+}
+
+void showPackage(const QString &packageId, bool asJson) Q_DECL_NOEXCEPT_EXPR(false)
+{
+ dbus.connectToPackager();
+
+ auto reply = dbus.packager()->get(packageId);
+ reply.waitForFinished();
+ if (reply.isError())
+ throw Exception(Error::IO, "failed to get package via DBus: %1").arg(reply.error().message());
+
+ QVariant package = reply.value();
+ fprintf(stdout, "%s\n", asJson ? QJsonDocument::fromVariant(package).toJson().constData()
+ : QtYaml::yamlFromVariantDocuments({ package }).constData());
+ qApp->quit();
+}
+
+void installPackage(const QString &package, bool acknowledge) Q_DECL_NOEXCEPT_EXPR(false)
{
QString packageFile = package;
@@ -629,10 +685,10 @@ void installPackage(const QString &package, const QString &location, bool acknow
if (!fi.exists() || !fi.isReadable() || !fi.isFile())
throw Exception(Error::IO, "Package file is not readable: %1").arg(packageFile);
- fprintf(stdout, "Starting installation of package %s to %s...\n", qPrintable(packageFile), qPrintable(location));
+ fprintf(stdout, "Starting installation of package %s ...\n", qPrintable(packageFile));
dbus.connectToManager();
- dbus.connectToInstaller();
+ dbus.connectToPackager();
// all the async lambdas below need to share this variable
static QString installationId;
@@ -640,7 +696,7 @@ void installPackage(const QString &package, const QString &location, bool acknow
// as soon as we have the manifest available: get the app id and acknowledge the installation
if (acknowledge) {
- QObject::connect(dbus.installer(), &IoQtApplicationInstallerInterface::taskRequestingInstallationAcknowledge,
+ QObject::connect(dbus.packager(), &IoQtPackageManagerInterface::taskRequestingInstallationAcknowledge,
[](const QString &taskId, const QVariantMap &metadata) {
if (taskId != installationId)
return;
@@ -648,13 +704,13 @@ void installPackage(const QString &package, const QString &location, bool acknow
if (applicationId.isEmpty())
throw Exception(Error::IO, "could not find a valid application id in the package");
fprintf(stdout, "Acknowledging package installation...\n");
- dbus.installer()->acknowledgePackageInstallation(taskId);
+ dbus.packager()->acknowledgePackageInstallation(taskId);
});
}
// on failure: quit
- QObject::connect(dbus.installer(), &IoQtApplicationInstallerInterface::taskFailed,
+ QObject::connect(dbus.packager(), &IoQtPackageManagerInterface::taskFailed,
[](const QString &taskId, int errorCode, const QString &errorString) {
if (taskId != installationId)
return;
@@ -663,7 +719,7 @@ void installPackage(const QString &package, const QString &location, bool acknow
// on success
- QObject::connect(dbus.installer(), &IoQtApplicationInstallerInterface::taskFinished,
+ QObject::connect(dbus.packager(), &IoQtPackageManagerInterface::taskFinished,
[](const QString &taskId) {
if (taskId != installationId)
return;
@@ -673,7 +729,7 @@ void installPackage(const QString &package, const QString &location, bool acknow
// start the package installation
- auto reply = dbus.installer()->startPackageInstallation(location, fi.absoluteFilePath());
+ auto reply = dbus.packager()->startPackageInstallation(fi.absoluteFilePath());
reply.waitForFinished();
if (reply.isError())
throw Exception(Error::IO, "failed to call startPackageInstallation via DBus: %1").arg(reply.error().message());
@@ -686,7 +742,7 @@ void installPackage(const QString &package, const QString &location, bool acknow
InterruptHandler::install([](int) {
fprintf(stdout, "Cancelling package installation.\n");
- auto reply = dbus.installer()->cancelTask(installationId);
+ auto reply = dbus.packager()->cancelTask(installationId);
reply.waitForFinished();
qApp->exit(1);
});
@@ -697,14 +753,14 @@ void removePackage(const QString &applicationId, bool keepDocuments, bool force)
fprintf(stdout, "Starting removal of package %s...\n", qPrintable(applicationId));
dbus.connectToManager();
- dbus.connectToInstaller();
+ dbus.connectToPackager();
// both the async lambdas below need to share this variables
static QString installationId;
// on failure: quit
- QObject::connect(dbus.installer(), &IoQtApplicationInstallerInterface::taskFailed,
+ QObject::connect(dbus.packager(), &IoQtPackageManagerInterface::taskFailed,
[](const QString &taskId, int errorCode, const QString &errorString) {
if (taskId != installationId)
return;
@@ -713,7 +769,7 @@ void removePackage(const QString &applicationId, bool keepDocuments, bool force)
// on success
- QObject::connect(dbus.installer(), &IoQtApplicationInstallerInterface::taskFinished,
+ QObject::connect(dbus.packager(), &IoQtPackageManagerInterface::taskFinished,
[](const QString &taskId) {
if (taskId != installationId)
return;
@@ -723,7 +779,7 @@ void removePackage(const QString &applicationId, bool keepDocuments, bool force)
// start the package installation
- auto reply = dbus.installer()->removePackage(applicationId, keepDocuments, force);
+ auto reply = dbus.packager()->removePackage(applicationId, keepDocuments, force);
reply.waitForFinished();
if (reply.isError())
throw Exception(Error::IO, "failed to call removePackage via DBus: %1").arg(reply.error().message());
@@ -735,9 +791,9 @@ void removePackage(const QString &applicationId, bool keepDocuments, bool force)
void listInstallationTasks() Q_DECL_NOEXCEPT_EXPR(false)
{
- dbus.connectToInstaller();
+ dbus.connectToPackager();
- auto reply = dbus.installer()->activeTaskIds();
+ auto reply = dbus.packager()->activeTaskIds();
reply.waitForFinished();
if (reply.isError())
throw Exception(Error::IO, "failed to call activeTaskIds via DBus: %1").arg(reply.error().message());
@@ -751,16 +807,16 @@ void listInstallationTasks() Q_DECL_NOEXCEPT_EXPR(false)
void cancelInstallationTask(bool all, const QString &taskId) Q_DECL_NOEXCEPT_EXPR(false)
{
- dbus.connectToInstaller();
+ dbus.connectToPackager();
// both the async lambdas below need to share this variables
static QStringList cancelTaskIds;
static int result = 0;
if (all) {
- dbus.connectToInstaller();
+ dbus.connectToPackager();
- auto reply = dbus.installer()->activeTaskIds();
+ auto reply = dbus.packager()->activeTaskIds();
reply.waitForFinished();
if (reply.isError())
throw Exception(Error::IO, "failed to call activeTaskIds via DBus: %1").arg(reply.error().message());
@@ -777,7 +833,7 @@ void cancelInstallationTask(bool all, const QString &taskId) Q_DECL_NOEXCEPT_EXP
// on task failure
- QObject::connect(dbus.installer(), &IoQtApplicationInstallerInterface::taskFailed,
+ QObject::connect(dbus.packager(), &IoQtPackageManagerInterface::taskFailed,
[](const QString &taskId, int errorCode, const QString &errorString) {
if (cancelTaskIds.removeOne(taskId)) {
if (errorCode != int(Error::Canceled)) {
@@ -794,7 +850,7 @@ void cancelInstallationTask(bool all, const QString &taskId) Q_DECL_NOEXCEPT_EXP
// on success
- QObject::connect(dbus.installer(), &IoQtApplicationInstallerInterface::taskFinished,
+ QObject::connect(dbus.packager(), &IoQtPackageManagerInterface::taskFinished,
[](const QString &taskId) {
if (cancelTaskIds.removeOne(taskId)) {
fprintf(stdout, "Could not cancel task %s anymore - the installation task already finished successfully.\n",
@@ -810,7 +866,7 @@ void cancelInstallationTask(bool all, const QString &taskId) Q_DECL_NOEXCEPT_EXP
// cancel the task
- auto reply = dbus.installer()->cancelTask(cancelTaskId);
+ auto reply = dbus.packager()->cancelTask(cancelTaskId);
reply.waitForFinished();
if (reply.isError())
throw Exception(Error::IO, "failed to call cancelTask via DBus: %1").arg(reply.error().message());
@@ -822,30 +878,20 @@ void cancelInstallationTask(bool all, const QString &taskId) Q_DECL_NOEXCEPT_EXP
void listInstallationLocations() Q_DECL_NOEXCEPT_EXPR(false)
{
- dbus.connectToInstaller();
+ dbus.connectToPackager();
- auto reply = dbus.installer()->installationLocationIds();
- reply.waitForFinished();
- if (reply.isError())
- throw Exception(Error::IO, "failed to call installationLocationIds via DBus: %1").arg(reply.error().message());
-
- const auto installationLocationIds = reply.value();
- for (auto installationLocationId : installationLocationIds)
- fprintf(stdout, "%s\n", qPrintable(installationLocationId));
+ auto installationLocation = dbus.packager()->installationLocation().variant().toMap();
+ if (!installationLocation.isEmpty())
+ fputs("internal-0\n", stdout);
qApp->quit();
}
-void showInstallationLocation(const QString &location, bool asJson) Q_DECL_NOEXCEPT_EXPR(false)
+void showInstallationLocation(bool asJson) Q_DECL_NOEXCEPT_EXPR(false)
{
- dbus.connectToInstaller();
-
- auto reply = dbus.installer()->getInstallationLocation(location);
- reply.waitForFinished();
- if (reply.isError())
- throw Exception(Error::IO, "failed to call getInstallationLocation via DBus: %1").arg(reply.error().message());
+ dbus.connectToPackager();
- QVariant app = reply.value();
- fprintf(stdout, "%s\n", asJson ? QJsonDocument::fromVariant(app).toJson().constData()
- : QtYaml::yamlFromVariantDocuments({ app }).constData());
+ auto installationLocation = dbus.packager()->installationLocation().variant().toMap();
+ fprintf(stdout, "%s\n", asJson ? QJsonDocument::fromVariant(installationLocation).toJson().constData()
+ : QtYaml::yamlFromVariantDocuments({ installationLocation }).constData());
qApp->quit();
}
diff --git a/src/tools/controller/controller.pro b/src/tools/controller/controller.pro
index 973781b9..43af64db 100644
--- a/src/tools/controller/controller.pro
+++ b/src/tools/controller/controller.pro
@@ -16,7 +16,7 @@ appmanif.files = ../../dbus-lib/io.qt.applicationmanager.xml
appmanif.header_flags = -i dbus-utilities.h
DBUS_INTERFACES += \
- ../../dbus-lib/io.qt.applicationinstaller.xml \
+ ../../dbus-lib/io.qt.packagemanager.xml \
appmanif
load(qt_tool)
diff --git a/src/tools/controller/interrupthandler.cpp b/src/tools/controller/interrupthandler.cpp
index 032ea23a..82c4a729 100644
--- a/src/tools/controller/interrupthandler.cpp
+++ b/src/tools/controller/interrupthandler.cpp
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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:GPL-EXCEPT-QTAS$
** Commercial License Usage
diff --git a/src/tools/controller/interrupthandler.h b/src/tools/controller/interrupthandler.h
index 7674afe2..8bd32d6d 100644
--- a/src/tools/controller/interrupthandler.h
+++ b/src/tools/controller/interrupthandler.h
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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:GPL-EXCEPT-QTAS$
** Commercial License Usage
diff --git a/src/tools/dumpqmltypes/dumpqmltypes.cpp b/src/tools/dumpqmltypes/dumpqmltypes.cpp
index 4d3999d9..fd6661d6 100644
--- a/src/tools/dumpqmltypes/dumpqmltypes.cpp
+++ b/src/tools/dumpqmltypes/dumpqmltypes.cpp
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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:GPL-EXCEPT-QTAS$
** Commercial License Usage
@@ -27,7 +27,8 @@
**
****************************************************************************/
-#include <QtAppManInstaller/applicationinstaller.h>
+#include <QtAppManManager/packagemanager.h>
+#include <QtAppManMain/applicationinstaller.h>
#include <QtAppManManager/applicationmanager.h>
#include <QtAppManManager/applicationmodel.h>
#include <QtAppManManager/amnamespace.h>
@@ -72,9 +73,10 @@ static const QVector<const QMetaObject *> all = {
// manager-lib
&ApplicationManager::staticMetaObject,
&ApplicationInstaller::staticMetaObject,
+ &PackageManager::staticMetaObject,
&NotificationManager::staticMetaObject,
&ApplicationIPCManager::staticMetaObject,
- &AbstractApplication::staticMetaObject,
+ &Application::staticMetaObject,
&AbstractRuntime::staticMetaObject,
&AbstractContainer::staticMetaObject,
&Notification::staticMetaObject,
@@ -250,8 +252,8 @@ int main(int argc, char **argv)
{
try {
QCoreApplication::setApplicationName(qSL("Qt Application Manager QML Types Dumper"));
- QCoreApplication::setOrganizationName(qSL("Luxoft Sweden AB"));
- QCoreApplication::setOrganizationDomain(qSL("luxoft.com"));
+ QCoreApplication::setOrganizationName(qSL("QtProject"));
+ QCoreApplication::setOrganizationDomain(qSL("qt-project.org"));
QCoreApplication::setApplicationVersion(qSL(AM_VERSION));
QCoreApplication a(argc, argv);
diff --git a/src/tools/dumpqmltypes/dumpqmltypes.pro b/src/tools/dumpqmltypes/dumpqmltypes.pro
index 22079782..acde4c97 100644
--- a/src/tools/dumpqmltypes/dumpqmltypes.pro
+++ b/src/tools/dumpqmltypes/dumpqmltypes.pro
@@ -10,13 +10,13 @@ QT *= \
appman_common-private \
appman_application-private \
appman_manager-private \
- appman_installer-private \
appman_notification-private \
appman_window-private \
appman_launcher-private \
appman_intent_client-private \
appman_intent_server-private \
appman_monitor-private \
+ appman_main-private \
appman_shared_main-private \
CONFIG *= console
diff --git a/src/tools/launcher-qml/launcher-qml.cpp b/src/tools/launcher-qml/launcher-qml.cpp
index 9ff121a7..421eb174 100644
--- a/src/tools/launcher-qml/launcher-qml.cpp
+++ b/src/tools/launcher-qml/launcher-qml.cpp
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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
@@ -83,7 +83,7 @@
#include "utilities.h"
#include "exception.h"
#include "crashhandler.h"
-#include "yamlapplicationscanner.h"
+#include "yamlpackagescanner.h"
#include "applicationinfo.h"
#include "startupinterface.h"
#include "dbus-utilities.h"
@@ -110,8 +110,8 @@ int main(int argc, char *argv[])
StartupTimer::instance()->checkpoint("entered main");
QCoreApplication::setApplicationName(qSL("Qt Application Manager QML Launcher"));
- QCoreApplication::setOrganizationName(qSL("Luxoft Sweden AB"));
- QCoreApplication::setOrganizationDomain(qSL("luxoft.com"));
+ QCoreApplication::setOrganizationName(qSL("QtProject"));
+ QCoreApplication::setOrganizationDomain(qSL("qt-project.org"));
QCoreApplication::setApplicationVersion(qSL(AM_VERSION));
if (qEnvironmentVariableIsSet("AM_NO_DLT_LOGGING"))
@@ -123,7 +123,7 @@ int main(int argc, char *argv[])
// As we don't know the app-id yet, we are registering a place holder so we are able to see
// something in the dlt logs if general errors occur.
- Logging::setDltApplicationId("PCLQ", "Luxoft Application-Manager Launcher QML");
+ Logging::setDltApplicationId("QTLQ", "Qt Application-Manager Launcher QML");
Logging::setApplicationId("qml-launcher");
Logging::initialize();
@@ -265,10 +265,11 @@ Controller::Controller(LauncherMain *a, bool quickLaunched, const QString &direc
} else {
QMetaObject::invokeMethod(this, [this, directLoad]() {
QFileInfo fi(directLoad);
- YamlApplicationScanner yas;
+ YamlPackageScanner yps;
try {
- ApplicationInfo *a = yas.scan(directLoad);
- startApplication(fi.absolutePath(), a->codeFilePath(), QString(), QString(), a->toVariantMap(), QVariantMap());
+ //TODO: how should this work?
+// ApplicationInfo *a = yps.scan(directLoad);
+// startApplication(fi.absolutePath(), a->codeFilePath(), QString(), QString(), a->toVariantMap(), QVariantMap());
} catch (const Exception &e) {
throw Exception("Could not parse info.yaml file: %1").arg(e.what());
}
diff --git a/src/tools/launcher-qml/launcher-qml_p.h b/src/tools/launcher-qml/launcher-qml_p.h
index e0e54eef..2ae2e8cf 100644
--- a/src/tools/launcher-qml/launcher-qml_p.h
+++ b/src/tools/launcher-qml/launcher-qml_p.h
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/src/tools/packager/packager.cpp b/src/tools/packager/packager.cpp
index 5f81a7f0..5c23fc92 100644
--- a/src/tools/packager/packager.cpp
+++ b/src/tools/packager/packager.cpp
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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:GPL-EXCEPT-QTAS$
** Commercial License Usage
@@ -40,7 +40,7 @@
#include <QtAppManCommon/exception.h>
#include <QtAppManCommon/qtyaml.h>
#include <QtAppManCommon/utilities.h>
-#include <QtAppManPackage/package.h>
+#include <QtAppManPackage/packageutilities.h>
#include "packagingjob.h"
QT_USE_NAMESPACE_AM
@@ -87,16 +87,16 @@ static Command command(QCommandLineParser &clp)
int main(int argc, char *argv[])
{
- Package::ensureCorrectLocale();
+ PackageUtilities::ensureCorrectLocale();
QCoreApplication::setApplicationName(qSL("Qt ApplicationManager Packager"));
- QCoreApplication::setOrganizationName(qSL("Luxoft Sweden AB"));
- QCoreApplication::setOrganizationDomain(qSL("luxoft.com"));
+ QCoreApplication::setOrganizationName(qSL("QtProject"));
+ QCoreApplication::setOrganizationDomain(qSL("qt-project.org"));
QCoreApplication::setApplicationVersion(qSL(AM_VERSION));
QCoreApplication a(argc, argv);
- if (!Package::checkCorrectLocale()) {
+ if (!PackageUtilities::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);
diff --git a/src/tools/packager/packagingjob.cpp b/src/tools/packager/packagingjob.cpp
index b2295d44..f8868788 100644
--- a/src/tools/packager/packagingjob.cpp
+++ b/src/tools/packager/packagingjob.cpp
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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:GPL-EXCEPT-QTAS$
** Commercial License Usage
@@ -42,9 +42,11 @@
#include "exception.h"
#include "signature.h"
#include "qtyaml.h"
+#include "packageinfo.h"
#include "applicationinfo.h"
+#include "intentinfo.h"
#include "installationreport.h"
-#include "yamlapplicationscanner.h"
+#include "yamlpackagescanner.h"
#include "packageextractor.h"
#include "packagecreator.h"
@@ -149,22 +151,38 @@ void PackagingJob::execute() Q_DECL_NOEXCEPT_EXPR(false)
throw Exception(Error::Package, "source %1 is not a directory").arg(m_sourceDir);
// check metadata
- YamlApplicationScanner yas;
- QString infoName = yas.metaDataFileName();
- QScopedPointer<ApplicationInfo> app(yas.scan(source.absoluteFilePath(infoName)));
+ YamlPackageScanner yps;
+ QString infoName = yps.metaDataFileName();
+ QScopedPointer<PackageInfo> package(yps.scan(source.absoluteFilePath(infoName)));
// build report
- InstallationReport report(app->id());
+ InstallationReport report(package->id());
report.addFile(infoName);
// check icon
- if (!QFile::exists(source.absoluteFilePath(app->icon())))
+ if (!QFile::exists(source.absoluteFilePath(package->icon())))
throw Exception(Error::Package, "missing the file referenced by the 'icon' field");
- report.addFile(app->icon());
+ report.addFile(package->icon());
+
+ // check intent icons
+ auto intents = package->intents();
+ for (const auto intent : intents) {
+ if (!QFile::exists(source.absoluteFilePath(intent->icon()))) {
+ throw Exception(Error::Package, "missing the file referenced by the 'icon' field for intent '%1'")
+ .arg(intent->id());
+ }
+ }
- // check executable
- if (!QFile::exists(source.absoluteFilePath(app->codeFilePath())))
- throw Exception(Error::Package, "missing the file referenced by the 'code' field");
+ // check executables
+ auto applications = package->applications();
+ if (applications.isEmpty())
+ throw Exception(Error::Package, "no applications defined in package");
+ for (const auto application : applications) {
+ if (!QFile::exists(source.absoluteFilePath(application->codeFilePath()))) {
+ throw Exception(Error::Package, "missing the file referenced by the 'code' field for application '%1'")
+ .arg(application->id());
+ }
+ }
quint64 estimatedImageSize = 0;
QString canonicalSourcePath = source.canonicalPath();
@@ -188,16 +206,16 @@ void PackagingJob::execute() Q_DECL_NOEXCEPT_EXPR(false)
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;
+ estimatedImageSize += (quint64(entryInfo.size()) + Ext2BlockSize - 1) / Ext2BlockSize;
- if (entryPath != infoName && entryPath != app->icon())
+ if (entryPath != infoName && entryPath != package->icon())
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;
+ estimatedImageSize = (500 + (estimatedImageSize + quint64(report.files().count()) + 400 / 8) * 11 / 10) * Ext2BlockSize;
report.setDiskSpaceUsed(estimatedImageSize);
// set extra metadata
@@ -207,11 +225,11 @@ void PackagingJob::execute() Q_DECL_NOEXCEPT_EXPR(false)
// 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());
+ throw Exception(Error::Package, "could not create package %1: %2").arg(package->id()).arg(creator.errorString());
QVariantMap md = creator.metaData();
- m_output = m_asJson ? QJsonDocument::fromVariant(md).toJson().constData()
- : QtYaml::yamlFromVariantDocuments({ md }).constData();
+ m_output = QString::fromUtf8(m_asJson ? QJsonDocument::fromVariant(md).toJson()
+ : QtYaml::yamlFromVariantDocuments({ md }));
break;
}
case DeveloperSign:
@@ -316,8 +334,8 @@ void PackagingJob::execute() Q_DECL_NOEXCEPT_EXPR(false)
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();
+ m_output = QString::fromUtf8(m_asJson ? QJsonDocument::fromVariant(md).toJson()
+ : QtYaml::yamlFromVariantDocuments({ md }));
break;
}
default:
diff --git a/src/tools/packager/packagingjob.h b/src/tools/packager/packagingjob.h
index a46ac278..9c5125c0 100644
--- a/src/tools/packager/packagingjob.h
+++ b/src/tools/packager/packagingjob.h
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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:GPL-EXCEPT-QTAS$
** Commercial License Usage
diff --git a/src/tools/testrunner/testrunner.cpp b/src/tools/testrunner/testrunner.cpp
index 33f03a69..ce10cefd 100644
--- a/src/tools/testrunner/testrunner.cpp
+++ b/src/tools/testrunner/testrunner.cpp
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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
@@ -47,6 +47,8 @@
#include <QQmlEngine>
#include <QRegExp>
#include <QRegularExpression>
+#include <QDir>
+#include <QFileInfo>
#include <qlogging.h>
#include <QtTest/qtestsystem.h>
@@ -168,19 +170,26 @@ static QObject *amTest(QQmlEngine *engine, QJSEngine *jsEngine)
return AmTest::instance();
}
-void TestRunner::initialize(const QStringList &testRunnerArguments)
+void TestRunner::initialize(const QString &testFile, const QStringList &testRunnerArguments)
{
Q_ASSERT(!testRunnerArguments.isEmpty());
+ const QString name = QFileInfo(testRunnerArguments.at(0)).fileName() + "::" + QDir().relativeFilePath(testFile);
+ static const char *programName = strdup(name.toLocal8Bit().constData());
+ QuickTestResult::setProgramName(programName);
+
// Convert all the arguments back into a char * array.
// These need to be alive as long as the program is running!
static QVector<char *> testArgV;
for (const auto &arg : testRunnerArguments)
testArgV << strdup(arg.toLocal8Bit().constData());
- atexit([]() { std::for_each(testArgV.constBegin(), testArgV.constEnd(), free); });
+
+ atexit([]() {
+ free(const_cast<char*>(programName));
+ std::for_each(testArgV.constBegin(), testArgV.constEnd(), free);
+ });
QuickTestResult::setCurrentAppname(testArgV.constFirst());
- QuickTestResult::setProgramName(testArgV.constFirst());
// Allocate a QuickTestResult to create QBenchmarkGlobalData, otherwise the benchmark options don't work
QuickTestResult result;
diff --git a/src/tools/testrunner/testrunner.h b/src/tools/testrunner/testrunner.h
index 5cc1a50d..00d2240c 100644
--- a/src/tools/testrunner/testrunner.h
+++ b/src/tools/testrunner/testrunner.h
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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
@@ -52,7 +52,7 @@ QT_BEGIN_NAMESPACE_AM
class TestRunner
{
public:
- static void initialize(const QStringList &testRunnerArguments);
+ static void initialize(const QString &testFile, const QStringList &testRunnerArguments);
static int exec(QQmlEngine *engine);
};
diff --git a/src/tools/testrunner/testrunner_p.h b/src/tools/testrunner/testrunner_p.h
index 614e66c6..bc29c250 100644
--- a/src/tools/testrunner/testrunner_p.h
+++ b/src/tools/testrunner/testrunner_p.h
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/src/tools/uploader/uploader.cpp b/src/tools/uploader/uploader.cpp
index 40d9a66c..9912593c 100644
--- a/src/tools/uploader/uploader.cpp
+++ b/src/tools/uploader/uploader.cpp
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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:GPL-EXCEPT-QTAS$
** Commercial License Usage
@@ -91,8 +91,8 @@ Q_NORETURN void printErrorAndExit(const QString &errorPrefix, const QString &err
int main(int argc, char *argv[])
{
QCoreApplication::setApplicationName(applicationName);
- QCoreApplication::setOrganizationName(qSL("Luxoft"));
- QCoreApplication::setOrganizationDomain(qSL("luxoft.com"));
+ QCoreApplication::setOrganizationName(qSL("QtProject"));
+ QCoreApplication::setOrganizationDomain(qSL("qt-project.org"));
QCoreApplication::setApplicationVersion(qSL(AM_VERSION));
QCoreApplication a(argc, argv);
diff --git a/src/wayland-extensions/qtam-extension.xml b/src/wayland-extensions/qtam-extension.xml
index a80600a8..73025015 100644
--- a/src/wayland-extensions/qtam-extension.xml
+++ b/src/wayland-extensions/qtam-extension.xml
@@ -4,7 +4,7 @@
Copyright (C) 2018 Pelagicore AG
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:BSD-QTAS$
Commercial License Usage
diff --git a/src/window-lib/inprocesswindow.cpp b/src/window-lib/inprocesswindow.cpp
index 8b55df29..aa9a4906 100644
--- a/src/window-lib/inprocesswindow.cpp
+++ b/src/window-lib/inprocesswindow.cpp
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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
@@ -45,7 +45,7 @@
QT_BEGIN_NAMESPACE_AM
-InProcessWindow::InProcessWindow(AbstractApplication *app, const QSharedPointer<InProcessSurfaceItem> &surfaceItem)
+InProcessWindow::InProcessWindow(Application *app, const QSharedPointer<InProcessSurfaceItem> &surfaceItem)
: Window(app)
, m_surfaceItem(surfaceItem)
{
diff --git a/src/window-lib/inprocesswindow.h b/src/window-lib/inprocesswindow.h
index a88c648c..3b4575b3 100644
--- a/src/window-lib/inprocesswindow.h
+++ b/src/window-lib/inprocesswindow.h
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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
@@ -56,7 +56,7 @@ class InProcessWindow : public Window
Q_OBJECT
public:
- InProcessWindow(AbstractApplication *app, const QSharedPointer<InProcessSurfaceItem> &surfaceItem);
+ InProcessWindow(Application *app, const QSharedPointer<InProcessSurfaceItem> &surfaceItem);
virtual ~InProcessWindow();
bool isInProcess() const override { return true; }
diff --git a/src/window-lib/touchemulation.cpp b/src/window-lib/touchemulation.cpp
index 6b989069..985887f7 100644
--- a/src/window-lib/touchemulation.cpp
+++ b/src/window-lib/touchemulation.cpp
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/src/window-lib/touchemulation.h b/src/window-lib/touchemulation.h
index 4dc9e937..caf967b1 100644
--- a/src/window-lib/touchemulation.h
+++ b/src/window-lib/touchemulation.h
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/src/window-lib/touchemulation_x11.cpp b/src/window-lib/touchemulation_x11.cpp
index 419cd1b9..927f8e94 100644
--- a/src/window-lib/touchemulation_x11.cpp
+++ b/src/window-lib/touchemulation_x11.cpp
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/src/window-lib/touchemulation_x11_p.h b/src/window-lib/touchemulation_x11_p.h
index 7719cb21..14657ac6 100644
--- a/src/window-lib/touchemulation_x11_p.h
+++ b/src/window-lib/touchemulation_x11_p.h
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/src/window-lib/waylandcompositor.cpp b/src/window-lib/waylandcompositor.cpp
index 6bf0d18b..19755649 100644
--- a/src/window-lib/waylandcompositor.cpp
+++ b/src/window-lib/waylandcompositor.cpp
@@ -5,7 +5,7 @@
** Copyright (C) 2016 Klarälvdalens Datakonsult AB, a KDAB Group company
** 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/src/window-lib/waylandcompositor.h b/src/window-lib/waylandcompositor.h
index 283db83a..4efe7d3d 100644
--- a/src/window-lib/waylandcompositor.h
+++ b/src/window-lib/waylandcompositor.h
@@ -5,7 +5,7 @@
** Copyright (C) 2016 Klarälvdalens Datakonsult AB, a KDAB Group company
** 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/src/window-lib/waylandqtamserverextension.cpp b/src/window-lib/waylandqtamserverextension.cpp
index cdce4e1e..a383217a 100644
--- a/src/window-lib/waylandqtamserverextension.cpp
+++ b/src/window-lib/waylandqtamserverextension.cpp
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/src/window-lib/waylandqtamserverextension_p.h b/src/window-lib/waylandqtamserverextension_p.h
index 4ef11d0e..a5756295 100644
--- a/src/window-lib/waylandqtamserverextension_p.h
+++ b/src/window-lib/waylandqtamserverextension_p.h
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/src/window-lib/waylandwindow.cpp b/src/window-lib/waylandwindow.cpp
index 6382bc05..c1d03c26 100644
--- a/src/window-lib/waylandwindow.cpp
+++ b/src/window-lib/waylandwindow.cpp
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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
@@ -57,7 +57,7 @@ QT_BEGIN_NAMESPACE_AM
bool WaylandWindow::m_watchdogEnabled = true;
-WaylandWindow::WaylandWindow(AbstractApplication *app, WindowSurface *surf)
+WaylandWindow::WaylandWindow(Application *app, WindowSurface *surf)
: Window(app)
, m_pingTimer(new QTimer(this))
, m_pongTimer(new QTimer(this))
diff --git a/src/window-lib/waylandwindow.h b/src/window-lib/waylandwindow.h
index 33fbea13..ee1bfaa2 100644
--- a/src/window-lib/waylandwindow.h
+++ b/src/window-lib/waylandwindow.h
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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
@@ -59,7 +59,7 @@ class WaylandWindow : public Window
Q_PROPERTY(QWaylandQuickSurface* waylandSurface READ waylandSurface NOTIFY waylandSurfaceChanged)
public:
- WaylandWindow(AbstractApplication *app, WindowSurface *surface);
+ WaylandWindow(Application *app, WindowSurface *surface);
bool isInProcess() const override { return false; }
diff --git a/src/window-lib/window-lib.pro b/src/window-lib/window-lib.pro
index a5a43177..918bbe34 100644
--- a/src/window-lib/window-lib.pro
+++ b/src/window-lib/window-lib.pro
@@ -10,6 +10,7 @@ QT_FOR_PRIVATE *= \
appman_common-private \
appman_application-private \
appman_manager-private \
+ appman_monitor-private \
CONFIG *= static internal_module
CONFIG -= create_cmake
@@ -45,7 +46,6 @@ multi-process:!headless {
windowmanager_p.h \
touchemulation.h \
-
!headless:SOURCES += \
window.cpp \
windowitem.cpp \
diff --git a/src/window-lib/window.cpp b/src/window-lib/window.cpp
index 13bc7053..6598b8b4 100644
--- a/src/window-lib/window.cpp
+++ b/src/window-lib/window.cpp
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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
@@ -185,7 +185,7 @@
*/
QT_BEGIN_NAMESPACE_AM
-Window::Window(AbstractApplication *app)
+Window::Window(Application *app)
: QObject()
, m_application(app)
{
@@ -196,7 +196,7 @@ Window::~Window()
emit _windowDestroyed();
}
-AbstractApplication *Window::application() const
+Application *Window::application() const
{
return m_application;
}
diff --git a/src/window-lib/window.h b/src/window-lib/window.h
index e2981cea..e41058fe 100644
--- a/src/window-lib/window.h
+++ b/src/window-lib/window.h
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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
@@ -66,7 +66,7 @@ class Window : public QObject
Q_PROPERTY(QSize size READ size NOTIFY sizeChanged)
Q_PROPERTY(ContentState contentState READ contentState NOTIFY contentStateChanged)
- Q_PROPERTY(AbstractApplication* application READ application CONSTANT)
+ Q_PROPERTY(Application* application READ application CONSTANT)
Q_PROPERTY(bool popup READ isPopup CONSTANT)
Q_PROPERTY(QPoint requestedPopupPosition READ requestedPopupPosition NOTIFY requestedPopupPositionChanged)
@@ -79,11 +79,11 @@ public:
};
Q_ENUM(ContentState)
- Window(AbstractApplication *app);
+ Window(Application *app);
virtual ~Window();
virtual bool isInProcess() const = 0;
- virtual AbstractApplication *application() const;
+ virtual Application *application() const;
// Controls how many items (which are views from a model-view perspective) are currently rendering this window
void registerItem(WindowItem *item);
@@ -125,7 +125,7 @@ signals:
void _windowDestroyed();
protected:
- QPointer<AbstractApplication> m_application;
+ QPointer<Application> m_application;
QSet<WindowItem*> m_items;
WindowItem *m_primaryItem{nullptr};
diff --git a/src/window-lib/windowitem.cpp b/src/window-lib/windowitem.cpp
index 5a00bceb..7fb17f69 100644
--- a/src/window-lib/windowitem.cpp
+++ b/src/window-lib/windowitem.cpp
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/src/window-lib/windowitem.h b/src/window-lib/windowitem.h
index 45bf9c71..4bc4b39b 100644
--- a/src/window-lib/windowitem.h
+++ b/src/window-lib/windowitem.h
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/src/window-lib/windowmanager.cpp b/src/window-lib/windowmanager.cpp
index ea9a3027..63d93e8d 100644
--- a/src/window-lib/windowmanager.cpp
+++ b/src/window-lib/windowmanager.cpp
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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
@@ -334,7 +334,7 @@ void WindowManager::setSlowAnimations(bool slowAnimations)
RuntimeFactory::instance()->setSlowAnimations(d->slowAnimations);
// Update already running applications
- for (AbstractApplication *application : ApplicationManager::instance()->applications()) {
+ for (Application *application : ApplicationManager::instance()->applications()) {
auto runtime = application->currentRuntime();
if (runtime)
runtime->setSlowAnimations(d->slowAnimations);
@@ -475,12 +475,53 @@ QVariantMap WindowManager::get(int index) const
}
/*!
+ \qmlmethod WindowObject WindowManager::window(int index)
+
+ Returns the \l{WindowObject}{window} corresponding to the given \a index in the
+ model, or \c null if the index is invalid.
+
+ \note The object ownership of the returned Window object stays with the application-manager.
+ If you want to store this pointer, you can use the WindowManager's QAbstractListModel
+ signals or the windowAboutToBeRemoved signal to get notified if the object is about
+ to be deleted on the C++ side.
+*/
+Window *WindowManager::window(int index) const
+{
+ if (index < 0 || index >= count()) {
+ qCWarning(LogSystem) << "WindowManager::window(index): invalid index:" << index;
+ return nullptr;
+ }
+ return d->windowsInModel.at(index);
+}
+
+/*!
+ \qmlmethod list<WindowObject> WindowManager::windowsOfApplication(string applicationId)
+
+ Returns a list of \l{WindowObject}{windows} belonging to the given \a applicationId in the
+ model, or an empty list if the applicationId is invalid.
+
+ \note The object ownership of the returned Window objects stays with the application-manager.
+ If you want to store these pointers, you can use the WindowManager's QAbstractListModel
+ signals or the windowAboutToBeRemoved signal to get notified if the objects are about
+ to be deleted on the C++ side.
+*/
+QList<QObject *> WindowManager::windowsOfApplication(const QString &id) const
+{
+ QList<QObject *> result;
+ for (Window *window : d->windowsInModel) {
+ if (window->application() && window->application()->id() == id)
+ result << window;
+ }
+ return result;
+}
+
+/*!
\qmlmethod int WindowManager::indexOfWindow(WindowObject window)
Returns the index of the \a window within the WindowManager model, or \c -1 if the window item is
not a managed window.
*/
-int WindowManager::indexOfWindow(Window *window)
+int WindowManager::indexOfWindow(Window *window) const
{
return d->windowsInModel.indexOf(window);
}
@@ -654,7 +695,7 @@ void WindowManager::inProcessSurfaceItemCreated(QSharedPointer<InProcessSurfaceI
qCCritical(LogSystem) << "This function must be called by a signal of Runtime!";
return;
}
- AbstractApplication *app = rt->application() ? rt->application()->nonAliased() : nullptr;
+ Application *app = rt->application() ? rt->application()->nonAliased() : nullptr;
if (!app) {
qCCritical(LogSystem) << "This function must be called by a signal of Runtime which actually has an application attached!";
return;
@@ -730,7 +771,7 @@ void WindowManager::waylandSurfaceCreated(QWaylandSurface *surface)
void WindowManager::waylandSurfaceMapped(WindowSurface *surface)
{
qint64 processId = surface->processId();
- AbstractApplication *app = ApplicationManager::instance()->fromProcessId(processId);
+ Application *app = ApplicationManager::instance()->fromProcessId(processId);
if (!app && ApplicationManager::instance()->securityChecksEnabled()) {
qCCritical(LogGraphics) << "SECURITY ALERT: an unknown application with pid" << processId
@@ -888,8 +929,8 @@ bool WindowManager::makeScreenshot(const QString &filename, const QString &selec
// app without System-UI
// filter out alias and apps not matching appId (if set)
- QVector<AbstractApplication *> apps = ApplicationManager::instance()->applications();
- auto it = std::remove_if(apps.begin(), apps.end(), [appId](AbstractApplication *app) {
+ QVector<Application *> apps = ApplicationManager::instance()->applications();
+ auto it = std::remove_if(apps.begin(), apps.end(), [appId](Application *app) {
return app->isAlias() || (!appId.isEmpty() && (appId != app->id()));
});
apps.erase(it, apps.end());
@@ -975,7 +1016,7 @@ int WindowManagerPrivate::findWindowByWaylandSurface(QWaylandSurface *waylandSur
return -1;
}
-QString WindowManagerPrivate::applicationId(AbstractApplication *app, WindowSurface *windowSurface)
+QString WindowManagerPrivate::applicationId(Application *app, WindowSurface *windowSurface)
{
if (app)
return app->id();
diff --git a/src/window-lib/windowmanager.h b/src/window-lib/windowmanager.h
index 194865fe..6e6d5982 100644
--- a/src/window-lib/windowmanager.h
+++ b/src/window-lib/windowmanager.h
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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
@@ -98,8 +98,9 @@ public:
Q_INVOKABLE int count() const;
Q_INVOKABLE QVariantMap get(int index) const;
-
- Q_INVOKABLE int indexOfWindow(Window *window);
+ Q_INVOKABLE Window *window(int index) const;
+ Q_INVOKABLE QList<QObject *> windowsOfApplication(const QString &id) const;
+ Q_INVOKABLE int indexOfWindow(Window *window) const;
Q_INVOKABLE QObject *addExtension(QQmlComponent *component) const;
bool eventFilter(QObject *watched, QEvent *event) override;
@@ -129,8 +130,6 @@ private slots:
public:
Q_SCRIPTABLE bool makeScreenshot(const QString &filename, const QString &selector);
- bool setDBusPolicy(const QVariantMap &yamlFragment);
-
QList<QQuickWindow *> compositorViews() const;
// evil hook to support in-process runtimes
diff --git a/src/window-lib/windowmanager_p.h b/src/window-lib/windowmanager_p.h
index 7195f541..f692e765 100644
--- a/src/window-lib/windowmanager_p.h
+++ b/src/window-lib/windowmanager_p.h
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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
@@ -62,7 +62,7 @@ public:
WaylandCompositor *waylandCompositor = nullptr;
- static QString applicationId(AbstractApplication *app, WindowSurface *windowSurface);
+ static QString applicationId(Application *app, WindowSurface *windowSurface);
#endif
QHash<int, QByteArray> roleNames;
diff --git a/template-opt/am/config-windows.yaml b/template-opt/am/config-windows.yaml
index 0f1325b7..6c160fca 100644
--- a/template-opt/am/config-windows.yaml
+++ b/template-opt/am/config-windows.yaml
@@ -4,15 +4,6 @@ formatType: am-configuration
# installations will go into the standard /opt/am hierarchy
applications:
- installedAppsManifestDir: "c:/cygwin/opt/am/manifests"
- appImageMountDir: "c:/cygwin/opt/am/image-mounts"
+ installationDir: "c:/cygwin/opt/am/apps"
+ documentDir: "c:/cygwin/opt/am/docs"
database: "c:/cygwin/opt/am/apps.db"
-
-# simulate an internal and a SD-card installation location
-
-installationLocations:
-- id: "internal-0"
- installationPath: "c:/cygwin/opt/am/apps"
- documentPath: "c:/cygwin/opt/am/docs"
- mountPoint: "c:/cygwin/opt"
- isDefault: true
diff --git a/template-opt/am/config.yaml b/template-opt/am/config.yaml
index 94fc9bcb..38ce6195 100644
--- a/template-opt/am/config.yaml
+++ b/template-opt/am/config.yaml
@@ -4,20 +4,6 @@ formatType: am-configuration
# installations will go into the standard /opt/am hierarchy
applications:
- installedAppsManifestDir: "/opt/am/manifests"
- appImageMountDir: "/opt/am/image-mounts"
+ installationDir: "/opt/am/apps"
+ documentDir: "/opt/am/docs"
database: "/opt/am/apps.db"
-
-# simulate an internal and a SD-card installation location
-
-installationLocations:
-- id: "internal-0"
- installationPath: "/opt/am/apps"
- documentPath: "/opt/am/docs"
- mountPoint: "/opt"
- isDefault: true
-
-- id: "removable-0"
- installationPath: "/media/sdcard/apps"
- documentPath: "/media/sdcard/docs"
- mountPoint: "/media/sdcard"
diff --git a/tests/application/tst_application.cpp b/tests/application/tst_application.cpp
index 8dbe29af..bbfaa6cb 100644
--- a/tests/application/tst_application.cpp
+++ b/tests/application/tst_application.cpp
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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:GPL-EXCEPT-QTAS$
** Commercial License Usage
@@ -33,6 +33,8 @@
#include "global.h"
#include "application.h"
#include "applicationinfo.h"
+#include "packageinfo.h"
+#include "package.h"
#include "abstractruntime.h"
QT_USE_NAMESPACE_AM
@@ -48,19 +50,19 @@ public:
void setSlowAnimations(bool) override {}
- qint64 applicationProcessId() const
+ qint64 applicationProcessId() const override
{
return m_state == Am::Running ? 1 : 0;
}
public slots:
- bool start()
+ bool start() override
{
m_state = Am::Running;
return true;
}
- void stop(bool forceKill)
+ void stop(bool forceKill) override
{
Q_UNUSED(forceKill);
m_state = Am::NotRunning;
@@ -104,7 +106,10 @@ private slots:
// the application no longer holds a reference to it
void tst_Application::runtimeDestroyed()
{
- auto app = new Application(new ApplicationInfo);
+ auto pi = new PackageInfo;
+ auto pkg = new Package(pi);
+ auto ai = new ApplicationInfo(pi);
+ auto app = new Application(ai, pkg);
auto runtimeManager = new TestRuntimeManager(qSL("foo"), qApp);
auto runtime = runtimeManager->create(nullptr, app);
diff --git a/tests/applicationinfo/tst_applicationinfo.cpp b/tests/applicationinfo/tst_applicationinfo.cpp
index 92f1fe3a..f9739dac 100644
--- a/tests/applicationinfo/tst_applicationinfo.cpp
+++ b/tests/applicationinfo/tst_applicationinfo.cpp
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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:GPL-EXCEPT-QTAS$
** Commercial License Usage
@@ -33,8 +33,8 @@
#include "global.h"
#include "application.h"
#include "applicationinfo.h"
-#include "applicationdatabase.h"
-#include "yamlapplicationscanner.h"
+#include "packageinfo.h"
+#include "yamlpackagescanner.h"
#include "exception.h"
QT_USE_NAMESPACE_AM
@@ -49,7 +49,6 @@ public:
private slots:
void initTestCase();
void cleanupTestCase();
- void database();
void application_data();
void application();
void validApplicationId_data();
@@ -58,7 +57,7 @@ private slots:
void validIcon();
private:
- QVector<AbstractApplicationInfo *> apps;
+ QVector<PackageInfo *> m_pkgs;
};
tst_ApplicationInfo::tst_ApplicationInfo()
@@ -67,100 +66,29 @@ tst_ApplicationInfo::tst_ApplicationInfo()
void tst_ApplicationInfo::initTestCase()
{
- YamlApplicationScanner scanner;
+ YamlPackageScanner scanner;
QDir baseDir(qL1S(AM_TESTDATA_DIR "manifests"));
- const QStringList appDirNames = baseDir.entryList(QDir::Dirs | QDir::NoDotAndDotDot | QDir::NoSymLinks);
- for (const QString &appDirName : appDirNames) {
- QDir dir = baseDir.absoluteFilePath(appDirName);
+ const QStringList pkgDirNames = baseDir.entryList(QDir::Dirs | QDir::NoDotAndDotDot | QDir::NoSymLinks);
+ for (const QString &pkgDirName : pkgDirNames) {
+ QDir dir = baseDir.absoluteFilePath(pkgDirName);
try {
- ApplicationInfo *a = scanner.scan(dir.absoluteFilePath(qSL("info.yaml")));
- QVERIFY(a);
- QCOMPARE(appDirName, a->id());
- apps << a;
+ PackageInfo *pi = scanner.scan(dir.absoluteFilePath(qSL("info.yaml")));
+ QVERIFY(pi);
+ QCOMPARE(pkgDirName, pi->id());
+ m_pkgs << pi;
} catch (const std::exception &e) {
QFAIL(e.what());
}
}
- QCOMPARE(apps.size(), 2);
+ QCOMPARE(m_pkgs.size(), 2);
}
void tst_ApplicationInfo::cleanupTestCase()
{
- qDeleteAll(apps);
+ qDeleteAll(m_pkgs);
}
-void tst_ApplicationInfo::database()
-{
- QString tmpDbPath = QDir::temp().absoluteFilePath(qSL("autotest-appdb-%1").arg(qApp->applicationPid()));
-
- QFile::remove(tmpDbPath);
- QVERIFY(!QFile::exists(tmpDbPath));
-
- {
- ApplicationDatabase adb(QDir::tempPath());
- QVERIFY(!adb.isValid());
- }
-
- {
- ApplicationDatabase adb(tmpDbPath);
- QVERIFY(adb.isValid());
-
- try {
- QVector<AbstractApplication *> appsInDb = adb.read();
- QVERIFY(appsInDb.isEmpty());
-
- adb.write(apps);
- qDeleteAll(appsInDb);
- } catch (const Exception &e) {
- QVERIFY2(false, e.what());
- }
- }
-
- QVERIFY(QFileInfo(tmpDbPath).size() > 0);
-
- {
- ApplicationDatabase adb(tmpDbPath);
- QVERIFY(adb.isValid());
-
- try {
- QVector<AbstractApplication *> appsInDb = adb.read();
- QCOMPARE(appsInDb.size(), apps.size());
- qDeleteAll(appsInDb);
- } catch (Exception &e) {
- QVERIFY2(false, e.what());
- }
- }
-
- {
-#if defined(Q_OS_WIN)
- QString nullDb(qSL("\\\\.\\NUL"));
-#else
- QString nullDb(qSL("/dev/zero"));
-#endif
-
- ApplicationDatabase adb(nullDb);
- QVERIFY2(adb.isValid(), qPrintable(adb.errorString()));
-
- try {
- adb.write(apps);
- QVERIFY(false);
- } catch (const Exception &) {
- }
- }
-
- /*{
- ApplicationDatabase adb("/proc/self/sched");
- QVERIFY(adb.isValid());
-
- try {
- // adb.write(apps);
- // QVERIFY(false);
- } catch (Exception &) {
- }
- }*/
-
-}
void tst_ApplicationInfo::application_data()
{
QTest::addColumn<QString>("id");
@@ -175,87 +103,79 @@ void tst_ApplicationInfo::application()
QString name = QString::fromLatin1(AM_TESTDATA_DIR "manifests/%1/info.yaml").arg(id);
- YamlApplicationScanner scanner;
- ApplicationInfo *app;
+ YamlPackageScanner scanner;
+ PackageInfo *pkg;
try {
- app = scanner.scan(name);
- QVERIFY(app);
+ pkg = scanner.scan(name);
+ QVERIFY(pkg);
} catch (const std::exception &e) {
QFAIL(e.what());
}
- QCOMPARE(app->id(), id);
- QCOMPARE(QFileInfo(app->icon()).fileName(), qSL("icon.png"));
- QCOMPARE(app->names().size(), 2);
- QCOMPARE(app->names().value(qSL("en")), qSL("english"));
- QCOMPARE(app->names().value(qSL("de")), qSL("deutsch"));
- QCOMPARE(app->name(qSL("en")), qSL("english"));
+ QCOMPARE(pkg->id(), id);
+ QCOMPARE(QFileInfo(pkg->icon()).fileName(), qSL("icon.png"));
+ QCOMPARE(pkg->names().size(), 2);
+ QCOMPARE(pkg->names().value(qSL("en")), qSL("english"));
+ QCOMPARE(pkg->names().value(qSL("de")), qSL("deutsch"));
+ QCOMPARE(pkg->name(qSL("en")), qSL("english"));
+ QCOMPARE(pkg->isBuiltIn(), false);
+ QCOMPARE(pkg->categories().size(), 2);
+ QVERIFY(pkg->categories().startsWith(qSL("bar")));
+ QVERIFY(pkg->categories().endsWith(qSL("foo")));
+
+ ApplicationInfo *app = pkg->applications().size() == 1 ? pkg->applications().first() : nullptr;
+ QVERIFY(app);
QCOMPARE(QFileInfo(app->codeFilePath()).fileName(), qSL("Test.qml"));
QCOMPARE(app->runtimeName(), qSL("qml"));
QCOMPARE(app->runtimeParameters().size(), 1);
QCOMPARE(app->runtimeParameters().value(qSL("loadDummyData")).toBool(), true);
- QCOMPARE(app->isBuiltIn(), false);
- QCOMPARE(app->supportedMimeTypes().size(), 2);
- QVERIFY(app->supportedMimeTypes().startsWith(qSL("text/plain")));
- QVERIFY(app->supportedMimeTypes().endsWith(qSL("x-scheme-handler/mailto")));
QCOMPARE(app->capabilities().size(), 2);
QVERIFY(app->capabilities().startsWith(qSL("cameraAccess")));
QVERIFY(app->capabilities().endsWith(qSL("locationAccess")));
- QCOMPARE(app->categories().size(), 2);
- QVERIFY(app->categories().startsWith(qSL("bar")));
- QVERIFY(app->categories().endsWith(qSL("foo")));
- delete app;
+ // legacy
+ QCOMPARE(app->supportedMimeTypes().size(), 2);
+ QVERIFY(app->supportedMimeTypes().startsWith(qSL("text/plain")));
+ QVERIFY(app->supportedMimeTypes().endsWith(qSL("x-scheme-handler/mailto")));
+
+ delete pkg;
}
void tst_ApplicationInfo::validApplicationId_data()
{
QTest::addColumn<QString>("appId");
- QTest::addColumn<bool>("isAlias");
QTest::addColumn<bool>("valid");
// passes
- QTest::newRow("normal") << "Test" << false << true;
- QTest::newRow("shortest") << "t" << false << true;
- QTest::newRow("valid-chars") << "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 ,.';[]{}!#$%^&()-_=+" << false << true;
- QTest::newRow("longest-name") << "com.012345678901234567890123456789012345678901234567890123456789012.012345678901234567890123456789012345678901234567890123456789012.0123456789012.test" << false << true;
- QTest::newRow("alias-normal") << "Test@alias" << true << true;
- QTest::newRow("alias-shortest") << "t@a" << true << true;
- QTest::newRow("alias-valid-chars") << "1-2@1-a" << true << true;
- QTest::newRow("alias-longest-part") << "com.012345678901234567890123456789012345678901234567890123456789012.test@012345678901234567890123456789012345678901234567890123456789012" << true << true;
- QTest::newRow("alias-longest-name") << "com.012345678901234567890123456789012345678901234567890123456789012.012345678901234567890123456789012345678901234567890123456789012.0123456789012@test" << true << true;
- QTest::newRow("alias-max-part-cnt") << "a.b.c.d.e.f.g.h.i.j.k.l.m.n.o.p.q.r.s.t.u.v.w.x.y.z.0.1.2.3.4.5.6.7.8.9.a.b.c.d.e.f.g.h.i.j.k.l.m.n.o.p.q.r.s.t.u.v.w.x.y.z.0.1.2.3.4.5.6.7.8.9.a.0@12" << true << true;
+ QTest::newRow("normal") << "Test" << true;
+ QTest::newRow("shortest") << "t" << true;
+ QTest::newRow("valid-chars") << "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 ,.';[]{}!#$%^&()-_=+@" << true;
+ QTest::newRow("longest-name") << "com.012345678901234567890123456789012345678901234567890123456789012.012345678901234567890123456789012345678901234567890123456789012.0123456789012.test" << true;
// failures
- QTest::newRow("empty") << "" << false << false;
- QTest::newRow("space-only") << " " << false << false;
- QTest::newRow("space-only2") << " " << false << false;
- QTest::newRow("name-too-long") << "com.012345678901234567890123456789012345678901234567890123456789012.012345678901234567890123456789012345678901234567890123456789012.0123456789012.xtest" << false << false;
- QTest::newRow("empty-alias") << "test@" << true << false;
- QTest::newRow("invalid-char@") << "t@" << false << false;
- QTest::newRow("invalid-char<") << "t<" << false << false;
- QTest::newRow("invalid-char>") << "t>" << false << false;
- QTest::newRow("invalid-char:") << "t:" << false << false;
- QTest::newRow("invalid-char-quote") << "t\"" << false << false;
- QTest::newRow("invalid-char/") << "t/" << false << false;
- QTest::newRow("invalid-char\\") << "t\\" << false << false;
- QTest::newRow("invalid-char|") << "t|" << false << false;
- QTest::newRow("invalid-char?") << "t?" << false << false;
- QTest::newRow("invalid-char*") << "t*" << false << false;
- QTest::newRow("control-char") << "t\t" << false << false;
- QTest::newRow("unicode-char") << QString::fromUtf8("c.p.t@c\xc3\xb6m") << true << false;
- QTest::newRow("no-alias") << "t" << true << false;
- QTest::newRow("alias-name-too-long") << "com.012345678901234567890123456789012345678901234567890123456789012.012345678901234567890123456789012345678901234567890123456789012.0123456789012@xtest" << true << false;
+ QTest::newRow("empty") << "" << false;
+ QTest::newRow("space-only") << " " << false;
+ QTest::newRow("space-only2") << " " << false;
+ QTest::newRow("name-too-long") << "com.012345678901234567890123456789012345678901234567890123456789012.012345678901234567890123456789012345678901234567890123456789012.0123456789012.xtest" << false;
+ QTest::newRow("invalid-char<") << "t<" << false;
+ QTest::newRow("invalid-char>") << "t>" << false;
+ QTest::newRow("invalid-char:") << "t:" << false;
+ QTest::newRow("invalid-char-quote") << "t\"" << false;
+ QTest::newRow("invalid-char/") << "t/" << false;
+ QTest::newRow("invalid-char\\") << "t\\" << false;
+ QTest::newRow("invalid-char|") << "t|" << false;
+ QTest::newRow("invalid-char?") << "t?" << false;
+ QTest::newRow("invalid-char*") << "t*" << false;
+ QTest::newRow("control-char") << "t\t" << false;
}
void tst_ApplicationInfo::validApplicationId()
{
QFETCH(QString, appId);
- QFETCH(bool, isAlias);
QFETCH(bool, valid);
QString errorString;
- bool result = AbstractApplicationInfo::isValidApplicationId(appId, isAlias, &errorString);
+ bool result = PackageInfo::isValidApplicationId(appId, &errorString);
QVERIFY2(valid == result, qPrintable(errorString));
}
@@ -284,7 +204,7 @@ void tst_ApplicationInfo::validIcon()
QFETCH(bool, isValid);
QString errorString;
- bool result = AbstractApplicationInfo::isValidIcon(icon, errorString);
+ bool result = PackageInfo::isValidIcon(icon, &errorString);
QCOMPARE(result, isValid);
}
diff --git a/tests/applicationinstaller/applicationinstaller.pro b/tests/applicationinstaller/applicationinstaller.pro
index 37532e10..b84ffac4 100644
--- a/tests/applicationinstaller/applicationinstaller.pro
+++ b/tests/applicationinstaller/applicationinstaller.pro
@@ -9,6 +9,5 @@ QT *= \
appman_application-private \
appman_package-private \
appman_manager-private \
- appman_installer-private
SOURCES += tst_applicationinstaller.cpp
diff --git a/tests/applicationinstaller/tst_applicationinstaller.cpp b/tests/applicationinstaller/tst_applicationinstaller.cpp
index c187a088..1a68d357 100644
--- a/tests/applicationinstaller/tst_applicationinstaller.cpp
+++ b/tests/applicationinstaller/tst_applicationinstaller.cpp
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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:GPL-EXCEPT-QTAS$
** Commercial License Usage
@@ -32,16 +32,17 @@
#include <functional>
-#include "applicationinstaller.h"
+#include "packagemanager.h"
+#include "packagedatabase.h"
#include "applicationmanager.h"
#include "application.h"
#include "sudo.h"
#include "utilities.h"
#include "error.h"
-#include "private/package_p.h"
+#include "private/packageutilities_p.h"
#include "runtimefactory.h"
#include "qmlinprocessruntime.h"
-#include "package.h"
+#include "packageutilities.h"
#include "../error-checking.h"
@@ -63,41 +64,41 @@ public:
};
AllowInstallations(Type t)
- : m_oldUnsigned(ApplicationInstaller::instance()->allowInstallationOfUnsignedPackages())
- , m_oldDevMode(ApplicationInstaller::instance()->developmentMode())
+ : m_oldUnsigned(PackageManager::instance()->allowInstallationOfUnsignedPackages())
+ , m_oldDevMode(PackageManager::instance()->developmentMode())
{
switch (t) {
case AllowUnsinged:
- ApplicationInstaller::instance()->setAllowInstallationOfUnsignedPackages(true);
- ApplicationInstaller::instance()->setDevelopmentMode(false);
+ PackageManager::instance()->setAllowInstallationOfUnsignedPackages(true);
+ PackageManager::instance()->setDevelopmentMode(false);
break;
case RequireDevSigned:
- ApplicationInstaller::instance()->setAllowInstallationOfUnsignedPackages(false);
- ApplicationInstaller::instance()->setDevelopmentMode(true);
+ PackageManager::instance()->setAllowInstallationOfUnsignedPackages(false);
+ PackageManager::instance()->setDevelopmentMode(true);
break;
case RequireStoreSigned:
- ApplicationInstaller::instance()->setAllowInstallationOfUnsignedPackages(false);
- ApplicationInstaller::instance()->setDevelopmentMode(false);
+ PackageManager::instance()->setAllowInstallationOfUnsignedPackages(false);
+ PackageManager::instance()->setDevelopmentMode(false);
break;
}
}
~AllowInstallations()
{
- ApplicationInstaller::instance()->setAllowInstallationOfUnsignedPackages(m_oldUnsigned);
- ApplicationInstaller::instance()->setDevelopmentMode(m_oldDevMode);
+ PackageManager::instance()->setAllowInstallationOfUnsignedPackages(m_oldUnsigned);
+ PackageManager::instance()->setDevelopmentMode(m_oldDevMode);
}
private:
bool m_oldUnsigned;
bool m_oldDevMode;
};
-class tst_ApplicationInstaller : public QObject
+class tst_PackageManager : public QObject
{
Q_OBJECT
public:
- tst_ApplicationInstaller(QObject *parent = nullptr);
- ~tst_ApplicationInstaller();
+ tst_PackageManager(QObject *parent = nullptr);
+ ~tst_PackageManager();
private slots:
void initTestCase();
@@ -108,8 +109,6 @@ private slots:
//TODO: test AI::cleanupBrokenInstallations() before calling cleanup() the first time!
- void installationLocations();
-
void packageInstallation_data();
void packageInstallation();
@@ -129,11 +128,8 @@ private slots:
public:
enum PathLocation {
- Manifests = 0,
Internal0,
Documents0,
- Internal1,
- Documents1,
PathLocationCount
};
@@ -148,11 +144,8 @@ private:
{
QString base;
switch (pathLocation) {
- case Manifests: base = "manifests"; break;
- case Internal0: base = "internal-0"; break;
- case Documents0: base = "documents-0"; break;
- case Internal1: base = "internal-1"; break;
- case Documents1: base = "documents-1"; break;
+ case Internal0: base = qSL("internal"); break;
+ case Documents0: base = qSL("documents"); break;
default: break;
}
@@ -194,8 +187,7 @@ private:
QTemporaryDir m_workDir;
QString m_hardwareId;
- QVector<InstallationLocation> m_installationLocations;
- ApplicationInstaller *m_ai = nullptr;
+ PackageManager *m_pm = nullptr;
QSignalSpy *m_startedSpy = nullptr;
QSignalSpy *m_requestingInstallationAcknowledgeSpy = nullptr;
QSignalSpy *m_blockingUntilInstallationAcknowledgeSpy = nullptr;
@@ -205,11 +197,11 @@ private:
};
-tst_ApplicationInstaller::tst_ApplicationInstaller(QObject *parent)
+tst_PackageManager::tst_PackageManager(QObject *parent)
: QObject(parent)
{ }
-tst_ApplicationInstaller::~tst_ApplicationInstaller()
+tst_PackageManager::~tst_PackageManager()
{
if (m_workDir.isValid()) {
if (m_sudo)
@@ -225,79 +217,71 @@ tst_ApplicationInstaller::~tst_ApplicationInstaller()
delete m_requestingInstallationAcknowledgeSpy;
delete m_startedSpy;
- delete m_ai;
+ delete m_pm;
}
-void tst_ApplicationInstaller::initTestCase()
+void tst_PackageManager::initTestCase()
{
if (!QDir(qL1S(AM_TESTDATA_DIR "/packages")).exists())
QSKIP("No test packages available in the data/ directory");
bool verbose = qEnvironmentVariableIsSet("VERBOSE_TEST");
if (!verbose)
- QLoggingCategory::setFilterRules("am.installer.debug=false");
+ QLoggingCategory::setFilterRules(qSL("am.installer.debug=false"));
qInfo() << "Verbose mode is" << (verbose ? "on" : "off") << "(changed by (un)setting $VERBOSE_TEST)";
spyTimeout *= timeoutFactor();
- QVERIFY(Package::checkCorrectLocale());
+ QVERIFY(PackageUtilities::checkCorrectLocale());
QVERIFY2(startedSudoServer, qPrintable(sudoServerError));
m_sudo = SudoClient::instance();
QVERIFY(m_sudo);
m_fakeSudo = m_sudo->isFallbackImplementation();
- // we need a (dummy) ApplicationManager for the installer, since the installer will
- // notify the manager during installations
- QVERIFY(ApplicationManager::createInstance(true));
-
// create a temporary dir (plus sub-dirs) for everything created by this test run
-
QVERIFY(m_workDir.isValid());
// make sure we have a valid hardware-id
- m_hardwareId = "foobar";
+ m_hardwareId = qSL("foobar");
for (int i = 0; i < PathLocationCount; ++i)
QVERIFY(QDir().mkdir(pathTo(PathLocation(i))));
- // define some installation locations for testing
-
- QVariantList iloc = QVariantList {
- QVariantMap {
- { "isDefault", true },
- { "id", "internal-0" },
- { "installationPath", pathTo(Internal0) },
- { "documentPath", pathTo(Documents0) }
- },
- QVariantMap {
- { "id", "internal-1" },
- { "installationPath", pathTo(Internal1) },
- { "documentPath", pathTo(Documents1) },
- }
- };
-
- m_installationLocations = InstallationLocation::parseInstallationLocations(iloc, m_hardwareId);
-
- QCOMPARE(m_installationLocations.size(), 2);
-
- // finally, instantiate the ApplicationInstaller and a bunch of signal-spies for its signals
-
- QString installerError;
- m_ai = ApplicationInstaller::createInstance(m_installationLocations, pathTo(Manifests), m_hardwareId, &installerError);
- QVERIFY2(m_ai, qPrintable(installerError));
+ // finally, instantiate the PackageManager and a bunch of signal-spies for its signals
+ try {
+ PackageDatabase *pdb = new PackageDatabase(QStringList(), pathTo(Internal0));
+ m_pm = PackageManager::createInstance(pdb, pathTo(Documents0));
+ m_pm->setHardwareId(m_hardwareId);
+ } catch (const Exception &e) {
+ QVERIFY2(false, e.what());
+ }
- m_startedSpy = new QSignalSpy(m_ai, &ApplicationInstaller::taskStarted);
- m_requestingInstallationAcknowledgeSpy = new QSignalSpy(m_ai, &ApplicationInstaller::taskRequestingInstallationAcknowledge);
- m_blockingUntilInstallationAcknowledgeSpy = new QSignalSpy(m_ai, &ApplicationInstaller::taskBlockingUntilInstallationAcknowledge);
- m_progressSpy = new QSignalSpy(m_ai, &ApplicationInstaller::taskProgressChanged);
- m_finishedSpy = new QSignalSpy(m_ai, &ApplicationInstaller::taskFinished);
- m_failedSpy = new QSignalSpy(m_ai, &ApplicationInstaller::taskFailed);
+ const QVariantMap iloc = m_pm->installationLocation();
+ QCOMPARE(iloc.size(), 3);
+ QCOMPARE(iloc.value(qSL("path")).toString(), pathTo(Internal0));
+ QVERIFY(iloc.value(qSL("deviceSize")).toLongLong() > 0);
+ QVERIFY(iloc.value(qSL("deviceFree")).toLongLong() > 0);
+ QVERIFY(iloc.value(qSL("deviceFree")).toLongLong() < iloc.value(qSL("deviceSize")).toLongLong());
+
+ const QVariantMap dloc = m_pm->documentLocation();
+ QCOMPARE(dloc.size(), 3);
+ QCOMPARE(dloc.value(qSL("path")).toString(), pathTo(Documents0));
+ QVERIFY(dloc.value(qSL("deviceSize")).toLongLong() > 0);
+ QVERIFY(dloc.value(qSL("deviceFree")).toLongLong() > 0);
+ QVERIFY(dloc.value(qSL("deviceFree")).toLongLong() < dloc.value(qSL("deviceSize")).toLongLong());
+
+ m_startedSpy = new QSignalSpy(m_pm, &PackageManager::taskStarted);
+ m_requestingInstallationAcknowledgeSpy = new QSignalSpy(m_pm, &PackageManager::taskRequestingInstallationAcknowledge);
+ m_blockingUntilInstallationAcknowledgeSpy = new QSignalSpy(m_pm, &PackageManager::taskBlockingUntilInstallationAcknowledge);
+ m_progressSpy = new QSignalSpy(m_pm, &PackageManager::taskProgressChanged);
+ m_finishedSpy = new QSignalSpy(m_pm, &PackageManager::taskFinished);
+ m_failedSpy = new QSignalSpy(m_pm, &PackageManager::taskFailed);
// crypto stuff - we need to load the root CA and developer CA certificates
- QFile devcaFile(AM_TESTDATA_DIR "certificates/devca.crt");
- QFile storecaFile(AM_TESTDATA_DIR "certificates/store.crt");
- QFile caFile(AM_TESTDATA_DIR "certificates/ca.crt");
+ QFile devcaFile(qL1S(AM_TESTDATA_DIR "certificates/devca.crt"));
+ QFile storecaFile(qL1S(AM_TESTDATA_DIR "certificates/store.crt"));
+ QFile caFile(qL1S(AM_TESTDATA_DIR "certificates/ca.crt"));
QVERIFY2(devcaFile.open(QIODevice::ReadOnly), qPrintable(devcaFile.errorString()));
QVERIFY2(storecaFile.open(QIODevice::ReadOnly), qPrintable(storecaFile.errorString()));
QVERIFY2(caFile.open(QIODevice::ReadOnly), qPrintable(caFile.errorString()));
@@ -306,24 +290,24 @@ void tst_ApplicationInstaller::initTestCase()
chainOfTrust << devcaFile.readAll() << caFile.readAll();
QVERIFY(!chainOfTrust.at(0).isEmpty());
QVERIFY(!chainOfTrust.at(1).isEmpty());
- m_ai->setCACertificates(chainOfTrust);
+ m_pm->setCACertificates(chainOfTrust);
// we do not require valid store signatures for this test run
- m_ai->setDevelopmentMode(true);
+ m_pm->setDevelopmentMode(true);
// make sure we have a valid runtime available. The important part is
// that we have a runtime called "native" - the functionality does not matter.
RuntimeFactory::instance()->registerRuntime(new QmlInProcessRuntimeManager(qSL("native")));
}
-void tst_ApplicationInstaller::cleanupTestCase()
+void tst_PackageManager::cleanupTestCase()
{
- // the real cleanup happens in ~tst_ApplicationInstaller, since we also need
+ // the real cleanup happens in ~tst_PackageManager, since we also need
// to call this cleanup from the crash handler
}
-void tst_ApplicationInstaller::init()
+void tst_PackageManager::init()
{
// start with a fresh App1 dir on each test run
@@ -331,13 +315,13 @@ void tst_ApplicationInstaller::init()
QVERIFY(QDir().mkdir(pathTo(Internal0)));
}
-void tst_ApplicationInstaller::cleanup()
+void tst_PackageManager::cleanup()
{
// this helps with reducing the amount of cleanup work required
// at the end of each test
try {
- m_ai->cleanupBrokenInstallations();
+ m_pm->cleanupBrokenInstallations();
} catch (const Exception &e) {
QFAIL(e.what());
}
@@ -346,47 +330,10 @@ void tst_ApplicationInstaller::cleanup()
recursiveOperation(pathTo(Internal0), safeRemove);
}
-void tst_ApplicationInstaller::installationLocations()
-{
- QVERIFY(!InstallationLocation().isValid());
-
- const QVector<InstallationLocation> loclist = m_ai->installationLocations();
-
- QCOMPARE(loclist.size(), m_installationLocations.size());
- for (const InstallationLocation &loc : loclist)
- QVERIFY(m_installationLocations.contains(loc));
-
- QVector<InstallationLocation> locationList = InstallationLocation::parseInstallationLocations(QVariantList {
- QVariantMap {
- { "id", "internal-0" },
- { "installationPath", QDir::tempPath() },
- { "documentPath", QDir::tempPath() },
- { "isDefault", true }
- },
- }, m_hardwareId);
- QCOMPARE(locationList.size(), 1);
- InstallationLocation &tmp = locationList.first();
- QVariantMap map = tmp.toVariantMap();
- QVERIFY(!map.isEmpty());
-
- QCOMPARE(map.value("id").toString(), tmp.id());
- QCOMPARE(map.value("index").toInt(), tmp.index());
- QCOMPARE(map.value("installationPath").toString(), tmp.installationPath());
- QCOMPARE(map.value("documentPath").toString(), tmp.documentPath());
- QCOMPARE(map.value("isDefault").toBool(), tmp.isDefault());
- QVERIFY(map.value("installationDeviceSize").toLongLong() > 0);
- QVERIFY(map.value("installationDeviceFree").toLongLong() > 0);
- QVERIFY(map.value("documentDeviceSize").toLongLong() > 0);
- QVERIFY(map.value("documentDeviceFree").toLongLong() > 0);
-}
-
-
-void tst_ApplicationInstaller::packageInstallation_data()
+void tst_PackageManager::packageInstallation_data()
{
QTest::addColumn<QString>("packageName");
- QTest::addColumn<QString>("installationLocationId");
QTest::addColumn<QString>("updatePackageName");
- QTest::addColumn<QString>("updateInstallationLocationId");
QTest::addColumn<bool>("devSigned");
QTest::addColumn<bool>("storeSigned");
QTest::addColumn<bool>("expectedSuccess");
@@ -410,73 +357,65 @@ void tst_ApplicationInstaller::packageInstallation_data()
};
QTest::newRow("normal") \
- << "test.appkg" << "internal-0" << "test-update.appkg" << "internal-0"
+ << "test.appkg" << "test-update.appkg"
<< false << false << true << true << nomd<< "";
QTest::newRow("no-dev-signed") \
- << "test.appkg" << "internal-0" << "" << ""
+ << "test.appkg" << ""
<< true << false << false << false << nomd << "cannot install unsigned packages";
QTest::newRow("dev-signed") \
- << "test-dev-signed.appkg" << "internal-0" << "test-update-dev-signed.appkg" << "internal-0"
+ << "test-dev-signed.appkg" << "test-update-dev-signed.appkg"
<< true << false << true << true << nomd << "";
QTest::newRow("no-store-signed") \
- << "test.appkg" << "internal-0" << "" << ""
+ << "test.appkg" << ""
<< false << true << false << false << nomd << "cannot install unsigned packages";
QTest::newRow("no-store-but-dev-signed") \
- << "test-dev-signed.appkg" << "internal-0" << "" << ""
+ << "test-dev-signed.appkg" << ""
<< false << true << false << false << nomd << "cannot install development packages on consumer devices";
QTest::newRow("store-signed") \
- << "test-store-signed.appkg" << "internal-0" << "" << ""
+ << "test-store-signed.appkg" << ""
<< false << true << true << false << nomd << "";
QTest::newRow("extra-metadata") \
- << "test-extra.appkg" << "internal-0" << "" << ""
+ << "test-extra.appkg" << ""
<< false << false << true << false << extramd << "";
QTest::newRow("extra-metadata-dev-signed") \
- << "test-extra-dev-signed.appkg" << "internal-0" << "" << ""
+ << "test-extra-dev-signed.appkg" << ""
<< true << false << true << false << extramd << "";
- QTest::newRow("update-to-different-location") \
- << "test.appkg" << "internal-0" << "test-update.appkg" << "internal-1"
- << false << false << true << false << nomd << "the application com.pelagicore.test cannot be installed to internal-1, since it is already installed to internal-0";
- QTest::newRow("invalid-location") \
- << "test.appkg" << "internal-42" << "" << ""
- << false << false << false << false << nomd << "invalid installation location";
QTest::newRow("invalid-file-order") \
- << "test-invalid-file-order.appkg" << "internal-0" << "" << ""
- << false << false << false << false << nomd << "The application icon (as stated in info.yaml) must be the second file in the package. Expected 'icon.png', got 'test'";
+ << "test-invalid-file-order.appkg" << ""
+ << false << false << false << false << nomd << "The package icon (as stated in info.yaml) must be the second file in the package. Expected 'icon.png', got 'test'";
QTest::newRow("invalid-header-format") \
- << "test-invalid-header-formatversion.appkg" << "internal-0" << "" << ""
- << false << false << false << false << nomd << "metadata has an invalid format specification: wrong formatVersion header: expected 1, got 2";
+ << "test-invalid-header-formatversion.appkg" << ""
+ << false << false << false << false << nomd << "metadata has an invalid format specification: wrong formatVersion header: expected 2, got 0";
QTest::newRow("invalid-header-diskspaceused") \
- << "test-invalid-header-diskspaceused.appkg" << "internal-0" << "" << ""
+ << "test-invalid-header-diskspaceused.appkg" << ""
<< false << false << false << false << nomd << "metadata has an invalid diskSpaceUsed field (0)";
QTest::newRow("invalid-header-id") \
- << "test-invalid-header-id.appkg" << "internal-0" << "" << ""
- << false << false << false << false << nomd << "metadata has an invalid applicationId field (:invalid)";
+ << "test-invalid-header-id.appkg" << ""
+ << false << false << false << false << nomd << "metadata has an invalid packageId field (:invalid)";
QTest::newRow("non-matching-header-id") \
- << "test-non-matching-header-id.appkg" << "internal-0" << "" << ""
- << false << false << false << false << nomd << "the application identifiers in --PACKAGE-HEADER--' and info.yaml do not match";
+ << "test-non-matching-header-id.appkg" << ""
+ << false << false << false << false << nomd << "the package identifiers in --PACKAGE-HEADER--' and info.yaml do not match";
QTest::newRow("tampered-extra-signed-header") \
- << "test-tampered-extra-signed-header.appkg" << "internal-0" << "" << ""
+ << "test-tampered-extra-signed-header.appkg" << ""
<< false << false << false << false << nomd << "~package digest mismatch.*";
QTest::newRow("invalid-info.yaml") \
- << "test-invalid-info.appkg" << "internal-0" << "" << ""
+ << "test-invalid-info.appkg" << ""
<< false << false << false << false << nomd << "~.*YAML parse error at line \\d+, column \\d+: did not find expected key";
QTest::newRow("invalid-info.yaml-id") \
- << "test-invalid-info-id.appkg" << "internal-0" << "" << ""
- << false << false << false << false << nomd << "~.*the identifier \\(:invalid\\) is not a valid application-id: must consist of printable ASCII characters only, except any of .*";
+ << "test-invalid-info-id.appkg" << ""
+ << false << false << false << false << nomd << "~.*the identifier \\(:invalid\\) is not a valid package-id: must consist of printable ASCII characters only, except any of .*";
QTest::newRow("invalid-footer-signature") \
- << "test-invalid-footer-signature.appkg" << "internal-0" << "" << ""
+ << "test-invalid-footer-signature.appkg" << ""
<< true << false << false << false << nomd << "could not verify the package's developer signature";
}
// this test function is a bit of a kitchen sink, but the basic boiler plate
// code of testing the results of an installation is the biggest part and it
// is always the same.
-void tst_ApplicationInstaller::packageInstallation()
+void tst_PackageManager::packageInstallation()
{
QFETCH(QString, packageName);
- QFETCH(QString, installationLocationId);
QFETCH(QString, updatePackageName);
- QFETCH(QString, updateInstallationLocationId);
QFETCH(bool, devSigned);
QFETCH(bool, storeSigned);
QFETCH(bool, expectedSuccess);
@@ -484,6 +423,9 @@ void tst_ApplicationInstaller::packageInstallation()
QFETCH(QVariantMap, extraMetaData);
QFETCH(QString, errorString);
+ QString installationDir = m_pm->installationLocation().value(qSL("path")).toString();
+ QString documentDir = m_pm->documentLocation().value(qSL("path")).toString();
+
AllowInstallations allow(storeSigned ? AllowInstallations::RequireStoreSigned
: (devSigned ? AllowInstallations::RequireDevSigned
: AllowInstallations::AllowUnsinged));
@@ -491,8 +433,6 @@ void tst_ApplicationInstaller::packageInstallation()
int lastPass = (updatePackageName.isEmpty() ? 1 : 2);
// pass 1 is the installation / pass 2 is the update (if needed)
for (int pass = 1; pass <= lastPass; ++pass) {
- const InstallationLocation &il = m_ai->installationLocationFromId(pass == 1 ? installationLocationId : updateInstallationLocationId);
-
// this makes the results a bit ugly to look at, but it helps with debugging a lot
if (pass > 1)
qInfo("Pass %d", pass);
@@ -500,9 +440,9 @@ void tst_ApplicationInstaller::packageInstallation()
// install (or update) the package
QUrl url = QUrl::fromLocalFile(AM_TESTDATA_DIR "packages/" + (pass == 1 ? packageName : updatePackageName));
- QString taskId = m_ai->startPackageInstallation(il.id(), url);
+ QString taskId = m_pm->startPackageInstallation(url);
QVERIFY(!taskId.isEmpty());
- m_ai->acknowledgePackageInstallation(taskId);
+ m_pm->acknowledgePackageInstallation(taskId);
// check received signals...
@@ -524,16 +464,19 @@ void tst_ApplicationInstaller::packageInstallation()
// check files
- QVERIFY(QFile::exists(pathTo(Manifests, "com.pelagicore.test/installation-report.yaml")));
- QVERIFY(QDir(pathTo(il.documentPath() + "/com.pelagicore.test")).exists());
+ //TODO: remove system((QString::fromUtf8("find ") + m_workDir.path()).toLocal8Bit().constData());
- QString fileCheckPath = il.installationPath() + "/com.pelagicore.test";
+ QVERIFY(QFile::exists(installationDir + qSL("/com.pelagicore.test/.installation-report.yaml")));
+ QVERIFY(QDir(documentDir + qSL("/com.pelagicore.test")).exists());
+
+ QString fileCheckPath = installationDir + "/com.pelagicore.test";
// now check the installed files
QStringList files = QDir(fileCheckPath).entryList(QDir::AllEntries | QDir::NoDotAndDotDot);
files.sort();
- QVERIFY2(files == QStringList({ "icon.png", "info.yaml", "test", QString::fromUtf8("t\xc3\xa4st") }), qPrintable(files.join(", ")));
+ QVERIFY2(files == QStringList({ qSL("icon.png"), qSL("info.yaml"), qSL("test"), QString::fromUtf8("t\xc3\xa4st") }),
+ qPrintable(files.join(qSL(", "))));
QFile f(fileCheckPath + "/test");
QVERIFY(f.open(QFile::ReadOnly));
@@ -544,28 +487,28 @@ void tst_ApplicationInstaller::packageInstallation()
QCOMPARE(m_requestingInstallationAcknowledgeSpy->count(), 1);
QVariantMap extra = m_requestingInstallationAcknowledgeSpy->first()[2].toMap();
QVariantMap extraSigned = m_requestingInstallationAcknowledgeSpy->first()[3].toMap();
- if (extraMetaData.value("extra").toMap() != extra) {
+ if (extraMetaData.value(qSL("extra")).toMap() != extra) {
qDebug() << "Actual: " << extra;
- qDebug() << "Expected: " << extraMetaData.value("extra").toMap();
+ qDebug() << "Expected: " << extraMetaData.value(qSL("extra")).toMap();
QVERIFY(extraMetaData == extra);
}
- if (extraMetaData.value("extraSigned").toMap() != extraSigned) {
+ if (extraMetaData.value(qSL("extraSigned")).toMap() != extraSigned) {
qDebug() << "Actual: " << extraSigned;
- qDebug() << "Expected: " << extraMetaData.value("extraSigned").toMap();
+ qDebug() << "Expected: " << extraMetaData.value(qSL("extraSigned")).toMap();
QVERIFY(extraMetaData == extraSigned);
}
// check if the meta-data was saved to the installation report correctly
- QVERIFY2(m_ai->installedApplicationExtraMetaData("com.pelagicore.test") == extra,
+ QVERIFY2(m_pm->installedPackageExtraMetaData(qSL("com.pelagicore.test")) == extra,
"Extra meta-data was not correctly saved to installation report");
- QVERIFY2(m_ai->installedApplicationExtraSignedMetaData("com.pelagicore.test") == extraSigned,
+ QVERIFY2(m_pm->installedPackageExtraSignedMetaData(qSL("com.pelagicore.test")) == extraSigned,
"Extra signed meta-data was not correctly saved to installation report");
}
if (pass == lastPass && expectedSuccess) {
// remove package again
clearSignalSpies();
- taskId = m_ai->removePackage("com.pelagicore.test", false);
+ taskId = m_pm->removePackage(qSL("com.pelagicore.test"), false);
QVERIFY(!taskId.isEmpty());
// check signals
@@ -577,9 +520,9 @@ void tst_ApplicationInstaller::packageInstallation()
}
// check that all files are gone
- for (PathLocation pl: { Manifests, Internal0, Internal1, Documents0, Documents1 }) {
- QStringList entries = QDir(pathTo(pl)).entryList({ "com.pelagicore.test*" });
- QVERIFY2(entries.isEmpty(), qPrintable(pathTo(pl) + ": " + entries.join(", ")));
+ for (PathLocation pl: { Internal0, Documents0 }) {
+ QStringList entries = QDir(pathTo(pl)).entryList({ qSL("com.pelagicore.test*") });
+ QVERIFY2(entries.isEmpty(), qPrintable(pathTo(pl) + qSL(": ") + entries.join(qSL(", "))));
}
}
@@ -588,34 +531,27 @@ Q_DECLARE_METATYPE(std::function<bool()>)
typedef QMultiMap<QString, std::function<bool()>> FunctionMap;
Q_DECLARE_METATYPE(FunctionMap)
-void tst_ApplicationInstaller::simulateErrorConditions_data()
+void tst_PackageManager::simulateErrorConditions_data()
{
- QTest::addColumn<QString>("installationLocation");
QTest::addColumn<bool>("testUpdate");
QTest::addColumn<QString>("errorString");
QTest::addColumn<FunctionMap>("functions");
#ifdef Q_OS_LINUX
- QTest::newRow("manifests-dir-read-only") \
- << "internal-0" << false << "~could not create manifest sub-directory .*" \
- << FunctionMap { { "before-start", [this]() { return chmod(pathTo(Manifests).toLocal8Bit(), 0000) == 0; } },
- { "after-failed", [this]() { return chmod(pathTo(Manifests).toLocal8Bit(), 0777) == 0; } } };
-
QTest::newRow("applications-dir-read-only") \
- << "internal-0" << false << "~could not create installation directory .*" \
+ << false << "~could not create installation directory .*" \
<< FunctionMap { { "before-start", [this]() { return chmod(pathTo(Internal0).toLocal8Bit(), 0000) == 0; } },
{ "after-failed", [this]() { return chmod(pathTo(Internal0).toLocal8Bit(), 0777) == 0; } } };
QTest::newRow("documents-dir-read-only") \
- << "internal-0" << false << "~could not create the document directory .*" \
+ << false << "~could not create the document directory .*" \
<< FunctionMap { { "before-start", [this]() { return chmod(pathTo(Documents0).toLocal8Bit(), 0000) == 0; } },
{ "after-failed", [this]() { return chmod(pathTo(Documents0).toLocal8Bit(), 0777) == 0; } } };
#endif
}
-void tst_ApplicationInstaller::simulateErrorConditions()
+void tst_PackageManager::simulateErrorConditions()
{
- QFETCH(QString, installationLocation);
QFETCH(bool, testUpdate);
QFETCH(QString, errorString);
QFETCH(FunctionMap, functions);
@@ -625,34 +561,34 @@ void tst_ApplicationInstaller::simulateErrorConditions()
if (testUpdate) {
// the check will run when updating a package, so we need to install it first
- taskId = m_ai->startPackageInstallation(installationLocation, QUrl::fromLocalFile(AM_TESTDATA_DIR "packages/test-dev-signed.appkg"));
+ taskId = m_pm->startPackageInstallation(QUrl::fromLocalFile(qL1S(AM_TESTDATA_DIR "packages/test-dev-signed.appkg")));
QVERIFY(!taskId.isEmpty());
- m_ai->acknowledgePackageInstallation(taskId);
+ m_pm->acknowledgePackageInstallation(taskId);
QVERIFY(m_finishedSpy->wait(spyTimeout));
QCOMPARE(m_finishedSpy->first()[0].toString(), taskId);
clearSignalSpies();
}
- foreach (const auto &f, functions.values("before-start"))
+ foreach (const auto &f, functions.values(qSL("before-start")))
QVERIFY(f());
- taskId = m_ai->startPackageInstallation(installationLocation, QUrl::fromLocalFile(AM_TESTDATA_DIR "packages/test-dev-signed.appkg"));
+ taskId = m_pm->startPackageInstallation(QUrl::fromLocalFile(qL1S(AM_TESTDATA_DIR "packages/test-dev-signed.appkg")));
- foreach (const auto &f, functions.values("after-start"))
+ foreach (const auto &f, functions.values(qSL("after-start")))
QVERIFY(f());
- m_ai->acknowledgePackageInstallation(taskId);
+ m_pm->acknowledgePackageInstallation(taskId);
QVERIFY(m_failedSpy->wait(spyTimeout));
QCOMPARE(m_failedSpy->first()[0].toString(), taskId);
AM_CHECK_ERRORSTRING(m_failedSpy->first()[2].toString(), errorString);
clearSignalSpies();
- foreach (const auto &f, functions.values("after-failed"))
+ foreach (const auto &f, functions.values(qSL("after-failed")))
QVERIFY(f());
if (testUpdate) {
- taskId = m_ai->removePackage("com.pelagicore.test", false);
+ taskId = m_pm->removePackage(qSL("com.pelagicore.test"), false);
QVERIFY(m_finishedSpy->wait(spyTimeout));
QCOMPARE(m_finishedSpy->first()[0].toString(), taskId);
@@ -660,7 +596,7 @@ void tst_ApplicationInstaller::simulateErrorConditions()
}
-void tst_ApplicationInstaller::cancelPackageInstallation_data()
+void tst_PackageManager::cancelPackageInstallation_data()
{
QTest::addColumn<bool>("expectedResult");
@@ -672,28 +608,28 @@ void tst_ApplicationInstaller::cancelPackageInstallation_data()
QTest::newRow("after-finished-signal") << false;
}
-void tst_ApplicationInstaller::cancelPackageInstallation()
+void tst_PackageManager::cancelPackageInstallation()
{
QFETCH(bool, expectedResult);
- QString taskId = m_ai->startPackageInstallation("internal-0", QUrl::fromLocalFile(AM_TESTDATA_DIR "packages/test-dev-signed.appkg"));
+ QString taskId = m_pm->startPackageInstallation(QUrl::fromLocalFile(qL1S(AM_TESTDATA_DIR "packages/test-dev-signed.appkg")));
QVERIFY(!taskId.isEmpty());
if (isDataTag("before-started-signal")) {
- QCOMPARE(m_ai->cancelTask(taskId), expectedResult);
+ QCOMPARE(m_pm->cancelTask(taskId), expectedResult);
} else if (isDataTag("after-started-signal")) {
QVERIFY(m_startedSpy->wait(spyTimeout));
QCOMPARE(m_startedSpy->first()[0].toString(), taskId);
- QCOMPARE(m_ai->cancelTask(taskId), expectedResult);
+ QCOMPARE(m_pm->cancelTask(taskId), expectedResult);
} else if (isDataTag("after-blocking-until-installation-acknowledge-signal")) {
QVERIFY(m_blockingUntilInstallationAcknowledgeSpy->wait(spyTimeout));
QCOMPARE(m_blockingUntilInstallationAcknowledgeSpy->first()[0].toString(), taskId);
- QCOMPARE(m_ai->cancelTask(taskId), expectedResult);
+ QCOMPARE(m_pm->cancelTask(taskId), expectedResult);
} else if (isDataTag("after-finished-signal")) {
- m_ai->acknowledgePackageInstallation(taskId);
+ m_pm->acknowledgePackageInstallation(taskId);
QVERIFY(m_finishedSpy->wait(spyTimeout));
QCOMPARE(m_finishedSpy->first()[0].toString(), taskId);
- QCOMPARE(m_ai->cancelTask(taskId), expectedResult);
+ QCOMPARE(m_pm->cancelTask(taskId), expectedResult);
}
if (expectedResult) {
@@ -705,7 +641,7 @@ void tst_ApplicationInstaller::cancelPackageInstallation()
} else {
clearSignalSpies();
- taskId = m_ai->removePackage("com.pelagicore.test", false);
+ taskId = m_pm->removePackage(qSL("com.pelagicore.test"), false);
QVERIFY(!taskId.isEmpty());
QVERIFY(m_finishedSpy->wait(spyTimeout));
QCOMPARE(m_finishedSpy->first()[0].toString(), taskId);
@@ -713,46 +649,28 @@ void tst_ApplicationInstaller::cancelPackageInstallation()
clearSignalSpies();
}
-void tst_ApplicationInstaller::parallelPackageInstallation()
+void tst_PackageManager::parallelPackageInstallation()
{
- QString task1Id = m_ai->startPackageInstallation("internal-0", QUrl::fromLocalFile(AM_TESTDATA_DIR "packages/test-dev-signed.appkg"));
+ QString task1Id = m_pm->startPackageInstallation(QUrl::fromLocalFile(qL1S(AM_TESTDATA_DIR "packages/test-dev-signed.appkg")));
QVERIFY(!task1Id.isEmpty());
QVERIFY(m_blockingUntilInstallationAcknowledgeSpy->wait(spyTimeout));
QCOMPARE(m_blockingUntilInstallationAcknowledgeSpy->first()[0].toString(), task1Id);
- QString task2Id = m_ai->startPackageInstallation("internal-0", QUrl::fromLocalFile(AM_TESTDATA_DIR "packages/bigtest-dev-signed.appkg"));
+ QString task2Id = m_pm->startPackageInstallation(QUrl::fromLocalFile(qL1S(AM_TESTDATA_DIR "packages/bigtest-dev-signed.appkg")));
QVERIFY(!task2Id.isEmpty());
- m_ai->acknowledgePackageInstallation(task2Id);
+ m_pm->acknowledgePackageInstallation(task2Id);
QVERIFY(m_finishedSpy->wait(spyTimeout));
QCOMPARE(m_finishedSpy->first()[0].toString(), task2Id);
clearSignalSpies();
- m_ai->acknowledgePackageInstallation(task1Id);
+ m_pm->acknowledgePackageInstallation(task1Id);
QVERIFY(m_finishedSpy->wait(spyTimeout));
QCOMPARE(m_finishedSpy->first()[0].toString(), task1Id);
clearSignalSpies();
}
-
-static tst_ApplicationInstaller *tstApplicationInstaller = nullptr;
-
-int main(int argc, char **argv)
-{
- Package::ensureCorrectLocale();
-
- try {
- Sudo::forkServer(Sudo::DropPrivilegesPermanently);
- startedSudoServer = true;
- } catch (...) { }
-
- QCoreApplication a(argc, argv);
- tstApplicationInstaller = new tst_ApplicationInstaller(&a);
-
- return QTest::qExec(tstApplicationInstaller, argc, argv);
-}
-
-void tst_ApplicationInstaller::validateDnsName_data()
+void tst_PackageManager::validateDnsName_data()
{
QTest::addColumn<QString>("dnsName");
QTest::addColumn<int>("minParts");
@@ -783,19 +701,19 @@ void tst_ApplicationInstaller::validateDnsName_data()
QTest::newRow("part-too-long") << "com.x012345678901234567890123456789012345678901234567890123456789012.test" << 3 << false;
}
-void tst_ApplicationInstaller::validateDnsName()
+void tst_PackageManager::validateDnsName()
{
QFETCH(QString, dnsName);
QFETCH(int, minParts);
QFETCH(bool, valid);
QString errorString;
- bool result = m_ai->validateDnsName(dnsName, minParts);
+ bool result = m_pm->validateDnsName(dnsName, minParts);
QVERIFY2(valid == result, qPrintable(errorString));
}
-void tst_ApplicationInstaller::compareVersions_data()
+void tst_PackageManager::compareVersions_data()
{
QTest::addColumn<QString>("version1");
QTest::addColumn<QString>("version2");
@@ -826,19 +744,36 @@ void tst_ApplicationInstaller::compareVersions_data()
QTest::newRow("21") << "12.403.51-alpha2+git" << "13.403.51-alpha2+git" << -1;
}
-void tst_ApplicationInstaller::compareVersions()
+void tst_PackageManager::compareVersions()
{
QFETCH(QString, version1);
QFETCH(QString, version2);
QFETCH(int, result);
- int cmp = m_ai->compareVersions(version1, version2);
+ int cmp = m_pm->compareVersions(version1, version2);
QCOMPARE(cmp, result);
if (result) {
- cmp = m_ai->compareVersions(version2, version1);
+ cmp = m_pm->compareVersions(version2, version1);
QCOMPARE(cmp, -result);
}
}
+static tst_PackageManager *tstPackageManager = nullptr;
+
+int main(int argc, char **argv)
+{
+ PackageUtilities::ensureCorrectLocale();
+
+ try {
+ Sudo::forkServer(Sudo::DropPrivilegesPermanently);
+ startedSudoServer = true;
+ } catch (...) { }
+
+ QCoreApplication a(argc, argv);
+ tstPackageManager = new tst_PackageManager(&a);
+
+ return QTest::qExec(tstPackageManager, argc, argv);
+}
+
#include "tst_applicationinstaller.moc"
diff --git a/tests/cryptography/tst_cryptography.cpp b/tests/cryptography/tst_cryptography.cpp
index 21f679ca..874b8eb2 100644
--- a/tests/cryptography/tst_cryptography.cpp
+++ b/tests/cryptography/tst_cryptography.cpp
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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:GPL-EXCEPT-QTAS$
** Commercial License Usage
diff --git a/tests/data/certificates/create-test-certificates.sh b/tests/data/certificates/create-test-certificates.sh
index 0615418e..960b736f 100755
--- a/tests/data/certificates/create-test-certificates.sh
+++ b/tests/data/certificates/create-test-certificates.sh
@@ -5,7 +5,7 @@
## Copyright (C) 2018 Pelagicore AG
## 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:GPL-EXCEPT-QTAS$
## Commercial License Usage
diff --git a/tests/data/create-test-packages.sh b/tests/data/create-test-packages.sh
index 8355e462..eab20672 100755
--- a/tests/data/create-test-packages.sh
+++ b/tests/data/create-test-packages.sh
@@ -5,7 +5,7 @@
## Copyright (C) 2018 Pelagicore AG
## 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:GPL-EXCEPT-QTAS$
## Commercial License Usage
@@ -78,8 +78,10 @@ mkdir -p "$src"
packager()
{
+ set +e
packagerOutput=`"$PACKAGER" "$@" 2>&1`
packagerResult=$?
+ set -e
if [ $packagerResult -ne 0 ]; then
echo -e "`basename $PACKAGER`$R failed with exit code $packagerResult$W. The executed command was:"
echo
@@ -185,7 +187,7 @@ echo "invalid" >"$dst/test-invalid-format.appkg"
info "Create a package with an invalid formatVersion header field"
mv "$src"/--PACKAGE-HEADER--{,.orig}
-echo '{formatType: "am-package-header", formatVersion: 2}' >$src/--PACKAGE-HEADER--
+sed <"$src/--PACKAGE-HEADER--.orig" >"$src/--PACKAGE-HEADER--" 's/formatVersion: 2/formatVersion: X/'
tar -C "$src" -cf "$dst/test-invalid-header-formatversion.appkg" -- --PACKAGE-HEADER-- info.yaml icon.png test --PACKAGE-FOOTER--
mv "$src"/--PACKAGE-HEADER--{.orig,}
@@ -197,13 +199,13 @@ mv "$src"/--PACKAGE-HEADER--{.orig,}
info "Create a package with an invalid id header field"
mv "$src"/--PACKAGE-HEADER--{,.orig}
-sed <"$src/--PACKAGE-HEADER--.orig" >"$src/--PACKAGE-HEADER--" "s/applicationId: '[a-z0-9.-]*'/applicationId: ':invalid'/"
+sed <"$src/--PACKAGE-HEADER--.orig" >"$src/--PACKAGE-HEADER--" "s/packageId: '[a-z0-9.-]*'/packageId: ':invalid'/"
tar -C "$src" -cf "$dst/test-invalid-header-id.appkg" -- --PACKAGE-HEADER-- info.yaml icon.png test --PACKAGE-FOOTER--
mv "$src"/--PACKAGE-HEADER--{.orig,}
info "Create a package with a non-matching id header field"
mv "$src"/--PACKAGE-HEADER--{,.orig}
-sed <"$src/--PACKAGE-HEADER--.orig" >"$src/--PACKAGE-HEADER--" "s/applicationId: '[a-z0-9.-]*'/applicationId: 'non-matching'/"
+sed <"$src/--PACKAGE-HEADER--.orig" >"$src/--PACKAGE-HEADER--" "s/packageId: '[a-z0-9.-]*'/packageId: 'non-matching'/"
tar -C "$src" -cf "$dst/test-non-matching-header-id.appkg" -- --PACKAGE-HEADER-- info.yaml icon.png test --PACKAGE-FOOTER--
mv "$src"/--PACKAGE-HEADER--{.orig,}
diff --git a/tests/data/utilities.sh b/tests/data/utilities.sh
index add548f2..9d6b8ad9 100755
--- a/tests/data/utilities.sh
+++ b/tests/data/utilities.sh
@@ -4,7 +4,7 @@
## Copyright (C) 2018 Pelagicore AG
## 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:GPL-EXCEPT-QTAS$
## Commercial License Usage
diff --git a/tests/debugwrapper/tst_debugwrapper.cpp b/tests/debugwrapper/tst_debugwrapper.cpp
index bb1525ca..3d85c2be 100644
--- a/tests/debugwrapper/tst_debugwrapper.cpp
+++ b/tests/debugwrapper/tst_debugwrapper.cpp
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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:GPL-EXCEPT-QTAS$
** Commercial License Usage
diff --git a/tests/error-checking.h b/tests/error-checking.h
index 7b25a776..19259b3b 100644
--- a/tests/error-checking.h
+++ b/tests/error-checking.h
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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:GPL-EXCEPT-QTAS$
** Commercial License Usage
diff --git a/tests/installationreport/tst_installationreport.cpp b/tests/installationreport/tst_installationreport.cpp
index 81a25443..c2abb17b 100644
--- a/tests/installationreport/tst_installationreport.cpp
+++ b/tests/installationreport/tst_installationreport.cpp
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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:GPL-EXCEPT-QTAS$
** Commercial License Usage
@@ -62,16 +62,14 @@ void tst_InstallationReport::test()
ir.setDigest("##digest##");
QVERIFY(ir.isValid());
ir.addFiles(files.mid(1));
- ir.setInstallationLocationId(qSL("test-42"));
ir.setDeveloperSignature("%%dev-sig%%");
ir.setStoreSignature("$$store-sig$$");
QVERIFY(ir.isValid());
- QCOMPARE(ir.applicationId(), qSL("com.pelagicore.test"));
+ QCOMPARE(ir.packageId(), qSL("com.pelagicore.test"));
QCOMPARE(ir.files(), files);
QCOMPARE(ir.diskSpaceUsed(), 42ULL);
QCOMPARE(ir.digest().constData(), "##digest##");
- QCOMPARE(ir.installationLocationId(), qSL("test-42"));
QCOMPARE(ir.developerSignature().constData(), "%%dev-sig%%");
QCOMPARE(ir.storeSignature().constData(), "$$store-sig$$");
@@ -85,11 +83,10 @@ void tst_InstallationReport::test()
buffer.seek(0);
QVERIFY(ir2.isValid());
- QCOMPARE(ir2.applicationId(), qSL("com.pelagicore.test"));
+ QCOMPARE(ir2.packageId(), qSL("com.pelagicore.test"));
QCOMPARE(ir2.files(), files);
QCOMPARE(ir2.diskSpaceUsed(), 42ULL);
QCOMPARE(ir2.digest().constData(), "##digest##");
- QCOMPARE(ir2.installationLocationId(), qSL("test-42"));
QCOMPARE(ir2.developerSignature().constData(), "%%dev-sig%%");
QCOMPARE(ir2.storeSignature().constData(), "$$store-sig$$");
diff --git a/tests/main/am-config.yaml b/tests/main/am-config.yaml
index a7a60179..73e8bb2c 100644
--- a/tests/main/am-config.yaml
+++ b/tests/main/am-config.yaml
@@ -3,12 +3,9 @@ formatType: am-configuration
---
applications:
builtinAppsManifestDir: "${CONFIG_PWD}/builtin-apps"
- installedAppsManifestDir: "/tmp/am-test-main/manifests"
+ installationDir: "/tmp/am-test-main/apps"
+ documentDir: "/tmp/am-test-main/docs"
database: "/tmp/am-test-main/apps.db"
-installationLocations:
-- id: "internal-0"
- installationPath: "/tmp/am-test-main/apps"
- documentPath: "/tmp/am-test-main/docs"
- mountPoint: "/tmp"
- isDefault: true
+ui:
+ mainQml: "${CONFIG_PWD}/dummy.qml"
diff --git a/tests/main/dummy.qml b/tests/main/dummy.qml
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/tests/main/dummy.qml
diff --git a/tests/main/main.pro b/tests/main/main.pro
index af74b450..c5ede8e7 100644
--- a/tests/main/main.pro
+++ b/tests/main/main.pro
@@ -12,3 +12,5 @@ QT *= appman_manager-private \
appman_main-private \
SOURCES += tst_main.cpp
+
+RESOURCES = main.qrc
diff --git a/tests/main/main.qrc b/tests/main/main.qrc
new file mode 100644
index 00000000..8cae2bbb
--- /dev/null
+++ b/tests/main/main.qrc
@@ -0,0 +1,5 @@
+<RCC>
+ <qresource prefix="/foo">
+ <file>dummy.qml</file>
+ </qresource>
+</RCC>
diff --git a/tests/main/tst_main.cpp b/tests/main/tst_main.cpp
index 7ec32116..c227b9cf 100644
--- a/tests/main/tst_main.cpp
+++ b/tests/main/tst_main.cpp
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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:GPL-EXCEPT-QTAS$
** Commercial License Usage
@@ -33,7 +33,7 @@
#include <QString>
#include <QStringList>
-#include "applicationinstaller.h"
+#include "packagemanager.h"
#include "applicationmanager.h"
#include "logging.h"
#include "main.h"
@@ -57,7 +57,8 @@ private slots:
void installAndRemoveUpdateForBuiltIn();
void updateForBuiltInAlreadyInstalled();
void loadDatabaseWithUpdatedBuiltInApp();
- void nonExistentMainQmlFile();
+ void mainQmlFile_data();
+ void mainQmlFile();
private:
void cleanUpInstallationDir();
@@ -76,13 +77,11 @@ private:
tst_Main::tst_Main()
{
argc = 3;
- argv = new char*[3];
- argv[0] = new char[255];
- sprintf(argv[0], "tst_update-builtin-app");
- argv[1] = new char[255];
- sprintf(argv[1], "--dbus");
- argv[2] = new char[255];
- sprintf(argv[2], "none");
+ argv = new char*[argc + 1];
+ argv[0] = qstrdup("tst_update-builtin-app");
+ argv[1] = qstrdup("--dbus");
+ argv[2] = qstrdup("none");
+ argv[3] = nullptr;
}
tst_Main::~tst_Main()
@@ -149,7 +148,7 @@ void tst_Main::initMain()
if (m_verbose)
Logging::setFilterRules(Logging::filterRules() += qSL("am.installer.debug=true"));
- ApplicationInstaller::instance()->setAllowInstallationOfUnsignedPackages(true);
+ PackageManager::instance()->setAllowInstallationOfUnsignedPackages(true);
}
void tst_Main::destroyMain()
@@ -172,40 +171,40 @@ void tst_Main::cleanup()
void tst_Main::installPackage(const QString &pkgPath)
{
- auto appInstaller = ApplicationInstaller::instance();
+ auto packageManager = PackageManager::instance();
bool installationFinished = false;
- connect(appInstaller, &ApplicationInstaller::taskRequestingInstallationAcknowledge,
- this, [this, appInstaller](const QString &taskId, const QVariantMap &,
- const QVariantMap &, const QVariantMap &) {
- appInstaller->acknowledgePackageInstallation(taskId);
+ connect(packageManager, &PackageManager::taskRequestingInstallationAcknowledge,
+ this, [this, packageManager](const QString &taskId, const QVariantMap &,
+ const QVariantMap &, const QVariantMap &) {
+ packageManager->acknowledgePackageInstallation(taskId);
});
- connect(appInstaller, &ApplicationInstaller::taskFinished,
+ connect(packageManager, &PackageManager::taskFinished,
this, [this, &installationFinished](const QString &) {
installationFinished = true;
});
- appInstaller->startPackageInstallation(qSL("internal-0"), QUrl::fromLocalFile(pkgPath));
+ packageManager->startPackageInstallation(QUrl::fromLocalFile(pkgPath));
- QTRY_COMPARE(installationFinished, true);
+ QTRY_VERIFY(installationFinished);
}
void tst_Main::removePackage(const QString &id)
{
- auto appInstaller = ApplicationInstaller::instance();
+ auto packageManager = PackageManager::instance();
bool removalFinished = false;
- connect(appInstaller, &ApplicationInstaller::taskFinished,
+ connect(packageManager, &PackageManager::taskFinished,
this, [this, &removalFinished](const QString &) {
removalFinished = true;
});
- appInstaller->removePackage(id, false /* keepDocuments */);
+ packageManager->removePackage(id, false /* keepDocuments */);
- QTRY_COMPARE(removalFinished, true);
+ QTRY_VERIFY(removalFinished);
}
/*
@@ -289,34 +288,54 @@ void tst_Main::loadDatabaseWithUpdatedBuiltInApp()
QCOMPARE(app->name(qSL("en")), qSL("Hello Updated Red"));
}
-/*
- When the "main QML file" parameter contains a relative filepath like "foo/bar.qml",
- Main should treat it as a local file (instead of a remote url) and complain that it
- doesn't exist.
- */
-void tst_Main::nonExistentMainQmlFile()
+void tst_Main::mainQmlFile_data()
+{
+ QTest::addColumn<QString>("mainQml");
+ QTest::addColumn<QString>("expectedErrorMsg");
+
+ QTest::newRow("none") << "" << "No main QML file specified";
+
+ QTest::newRow("invalid") << "foo/bar.qml" << "Invalid main QML file specified: foo/bar.qml";
+ QTest::newRow("invalid-dir") << "." << "Invalid main QML file specified: .";
+ QTest::newRow("invalid-qrc1") << ":/bar.qml" << "Invalid main QML file specified: :/bar.qml";
+ // "://bar.qml" yields an absolute file path of ":" and QFile::exists() would always return true
+ QTest::newRow("invalid-qrc2") << "://bar.qml" << "Invalid main QML file specified: ://bar.qml";
+ QTest::newRow("invalid-qrc-dir") << ":/foo" << "Invalid main QML file specified: :/foo";
+
+ QTest::newRow("valid-native") << QFINDTESTDATA("dummy.qml") << "";
+ QTest::newRow("valid-qrc-file") << ":/foo/dummy.qml" << "";
+ QTest::newRow("valid-qrc-url") << "qrc:///foo/dummy.qml" << "";
+
+ // Passes unchecked:
+ QTest::newRow("https") << "https://www.qt.io/foo/bar.qml" << "";
+ QTest::newRow("assets") << "assets:///foo/bar.qml" << "";
+}
+
+void tst_Main::mainQmlFile()
{
+ QFETCH(QString, mainQml);
+ QFETCH(QString, expectedErrorMsg);
+
QStringList arguments;
arguments << "tst_update-builtin-app";
arguments << "--dbus";
arguments << "none";
- arguments << "foo/bar.qml";
-
- QString errorMsg;
+ arguments << mainQml;
main = new Main(argc, argv);
- config = new DefaultConfiguration;
+ config = new DefaultConfiguration(QStringList(QFINDTESTDATA("am-config.yaml")), QString());
config->parseWithArguments(arguments);
+ QString errorMsg;
+
try {
main->setup(config);
} catch (const std::exception &e) {
errorMsg.append(e.what());
}
- QVERIFY(errorMsg.startsWith("no/invalid main QML file specified:"));
- QVERIFY(errorMsg.contains("bar.qml"));
+ QCOMPARE(errorMsg, expectedErrorMsg);
delete config;
config = nullptr;
diff --git a/tests/manual/manual.pro b/tests/manual/manual.pro
new file mode 100644
index 00000000..49d5c3b4
--- /dev/null
+++ b/tests/manual/manual.pro
@@ -0,0 +1,6 @@
+requires(false) # visible in QtCreator, but not built by default
+
+TEMPLATE = subdirs
+
+SUBDIRS = \
+ monitormodel \
diff --git a/tests/manual/monitormodel/PropertyField.qml b/tests/manual/monitormodel/PropertyField.qml
index d40a5358..042b7545 100644
--- a/tests/manual/monitormodel/PropertyField.qml
+++ b/tests/manual/monitormodel/PropertyField.qml
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/manual/monitormodel/SystemMonitorChart.qml b/tests/manual/monitormodel/SystemMonitorChart.qml
index 264c9dcf..8a45d584 100644
--- a/tests/manual/monitormodel/SystemMonitorChart.qml
+++ b/tests/manual/monitormodel/SystemMonitorChart.qml
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/manual/monitormodel/main.qml b/tests/manual/monitormodel/main.qml
index 3ac2c727..688810d9 100644
--- a/tests/manual/monitormodel/main.qml
+++ b/tests/manual/monitormodel/main.qml
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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
@@ -45,7 +45,7 @@ import QtQuick.Controls 2.4
import QtQuick.Layouts 1.11
import QtQuick.Window 2.11
-import QtApplicationManager.SystemUI 2.0
+import QtApplicationManager 2.0
Window {
width: 1200
diff --git a/tests/manual/monitormodel/monitormodel.pro b/tests/manual/monitormodel/monitormodel.pro
new file mode 100644
index 00000000..7c2e33bc
--- /dev/null
+++ b/tests/manual/monitormodel/monitormodel.pro
@@ -0,0 +1,5 @@
+TEMPLATE = aux
+
+OTHER_FILES = \
+ *.qml \
+ README \
diff --git a/tests/packagecreator/tst_packagecreator.cpp b/tests/packagecreator/tst_packagecreator.cpp
index 1b030168..0f1af7e1 100644
--- a/tests/packagecreator/tst_packagecreator.cpp
+++ b/tests/packagecreator/tst_packagecreator.cpp
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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:GPL-EXCEPT-QTAS$
** Commercial License Usage
@@ -31,7 +31,7 @@
#include "global.h"
#include "installationreport.h"
-#include "package.h"
+#include "packageutilities.h"
#include "packagecreator.h"
#include "utilities.h"
@@ -80,7 +80,7 @@ void tst_PackageCreator::initTestCase()
m_isCygwin = tar.readAllStandardOutput().contains("Cygwin");
- QVERIFY(Package::checkCorrectLocale());
+ QVERIFY(PackageUtilities::checkCorrectLocale());
}
void tst_PackageCreator::createAndVerify_data()
@@ -173,7 +173,7 @@ QString tst_PackageCreator::escapeFilename(const QString &name)
int main(int argc, char *argv[])
{
- Package::ensureCorrectLocale();
+ PackageUtilities::ensureCorrectLocale();
QCoreApplication app(argc, argv);
app.setAttribute(Qt::AA_Use96Dpi, true);
tst_PackageCreator tc;
diff --git a/tests/packageextractor/tst_packageextractor.cpp b/tests/packageextractor/tst_packageextractor.cpp
index 950639e0..32979bb9 100644
--- a/tests/packageextractor/tst_packageextractor.cpp
+++ b/tests/packageextractor/tst_packageextractor.cpp
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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:GPL-EXCEPT-QTAS$
** Commercial License Usage
@@ -41,7 +41,7 @@
#include "global.h"
#include "packageextractor.h"
#include "installationreport.h"
-#include "package.h"
+#include "packageutilities.h"
#include "../error-checking.h"
@@ -80,7 +80,7 @@ void tst_PackageExtractor::initTestCase()
if (!QDir(qL1S(AM_TESTDATA_DIR "/packages")).exists())
QSKIP("No test packages available in the data/ directory");
- QVERIFY(Package::checkCorrectLocale());
+ QVERIFY(PackageUtilities::checkCorrectLocale());
}
void tst_PackageExtractor::init()
@@ -300,7 +300,7 @@ void tst_PackageExtractor::extractFromFifo()
int main(int argc, char *argv[])
{
- Package::ensureCorrectLocale();
+ PackageUtilities::ensureCorrectLocale();
QCoreApplication app(argc, argv);
app.setAttribute(Qt::AA_Use96Dpi, true);
tst_PackageExtractor tc;
diff --git a/tests/packager-tool/packager-tool.pro b/tests/packager-tool/packager-tool.pro
index b4c11d94..08876ac6 100644
--- a/tests/packager-tool/packager-tool.pro
+++ b/tests/packager-tool/packager-tool.pro
@@ -8,9 +8,8 @@ QT *= \
appman_application-private \
appman_package-private \
appman_manager-private \
- appman_installer-private \
-INCLUDEPATH += ../../src/tools/packager
-SOURCES += ../../src/tools/packager/packagingjob.cpp
+INCLUDEPATH += $$PWD/../../src/tools/packager
+SOURCES += $$PWD/../../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 e890f066..dc2ca94f 100644
--- a/tests/packager-tool/tst_packager-tool.cpp
+++ b/tests/packager-tool/tst_packager-tool.cpp
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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:GPL-EXCEPT-QTAS$
** Commercial License Usage
@@ -31,13 +31,13 @@
#include <QCoreApplication>
#include "global.h"
-#include "installationlocation.h"
#include "applicationmanager.h"
#include "application.h"
#include "qtyaml.h"
#include "exception.h"
+#include "packagedatabase.h"
+#include "packagemanager.h"
#include "packagingjob.h"
-#include "applicationinstaller.h"
#include "qmlinprocessruntime.h"
#include "runtimefactory.h"
#include "utilities.h"
@@ -74,7 +74,7 @@ private:
void installPackage(const QString &filePath);
- ApplicationInstaller *m_ai = nullptr;
+ PackageManager *m_pm = nullptr;
QTemporaryDir m_workDir;
QString m_devPassword;
@@ -93,23 +93,18 @@ void tst_PackagerTool::initTestCase()
spyTimeout *= timeoutFactor();
QVERIFY(m_workDir.isValid());
-
- QVERIFY(QDir::root().mkpath(pathTo("manifests")));
QVERIFY(QDir::root().mkpath(pathTo("internal-0")));
QVERIFY(QDir::root().mkpath(pathTo("documents-0")));
- m_hardwareId = "foobar";
-
- QVariantMap internalLocation {
- { "id", "internal-0" },
- { "installationPath", pathTo("internal-0") },
- { "documentPath", pathTo("documents-0") },
- };
- QVector<InstallationLocation> locations = InstallationLocation::parseInstallationLocations({ internalLocation }, m_hardwareId);
+ m_hardwareId = qSL("foobar");
- QString errorString;
- m_ai = ApplicationInstaller::createInstance(locations, pathTo("manifests"), m_hardwareId, &errorString);
- QVERIFY2(m_ai, qPrintable(errorString));
+ PackageDatabase *pdb = new PackageDatabase({}, pathTo("internal-0"));
+ try {
+ m_pm = PackageManager::createInstance(pdb, pathTo("documents-0"));
+ m_pm->setHardwareId(m_hardwareId);
+ } catch (const Exception &e) {
+ QVERIFY2(false, e.what());
+ }
QVERIFY(ApplicationManager::createInstance(true));
@@ -125,7 +120,7 @@ void tst_PackagerTool::initTestCase()
chainOfTrust << devcaFile.readAll() << caFile.readAll();
QVERIFY(!chainOfTrust.at(0).isEmpty());
QVERIFY(!chainOfTrust.at(1).isEmpty());
- m_ai->setCACertificates(chainOfTrust);
+ m_pm->setCACertificates(chainOfTrust);
m_caFiles << devcaFile.fileName() << caFile.fileName();
@@ -139,7 +134,6 @@ void tst_PackagerTool::initTestCase()
void tst_PackagerTool::cleanup()
{
- recursiveOperation(pathTo("manifests"), safeRemove);
recursiveOperation(pathTo("internal-0"), safeRemove);
recursiveOperation(pathTo("documents-0"), safeRemove);
@@ -284,10 +278,10 @@ void tst_PackagerTool::brokenMetadata_data()
QTest::addColumn<QVariant>("yamlValue");
QTest::addColumn<QString>("errorString");
- QTest::newRow("missing-name") << "name" << QVariant("") << "~.*the 'name' field must not be empty";
- QTest::newRow("missing-runtime") << "runtime" << QVariant("") << "~.*the 'runtimeName' field must not be empty";
- QTest::newRow("missing-identifier") << "id" << QVariant("") << "~.*the identifier \\(\\) is not a valid application-id: must not be empty";
- QTest::newRow("missing-code") << "code" << QVariant("") << "~.*the 'code' field must not be empty";
+ QTest::newRow("missing-name") << qSL("name") << QVariant() << "~.*the 'name' field must not be empty";
+ QTest::newRow("missing-runtime") << qSL("runtime") << QVariant() << "~.*the 'runtimeName' field must not be empty.*";
+ QTest::newRow("missing-identifier") << qSL("id") << QVariant() << "~.*packages need to have an id.*";
+ QTest::newRow("missing-code") << qSL("code") << QVariant() << "~.*the 'code' field must not be empty.*";
}
void tst_PackagerTool::brokenMetadata()
@@ -318,18 +312,18 @@ void tst_PackagerTool::iconFileName()
QTemporaryDir tmp;
QString errorString;
- createInfoYaml(tmp, "icon", "foo.bar");
+ createInfoYaml(tmp, qSL("icon"), qSL("foo.bar"));
createCode(tmp);
- createDummyFile(tmp, "foo.bar", "this-is-a-dummy-icon-file");
+ createDummyFile(tmp, qSL("foo.bar"), "this-is-a-dummy-icon-file");
QVERIFY2(packagerCheck(PackagingJob::create(pathTo("test-foobar-icon.appkg"), tmp.path()), errorString),
qPrintable(errorString));
// see if the package installs correctly
- m_ai->setAllowInstallationOfUnsignedPackages(true);
+ m_pm->setAllowInstallationOfUnsignedPackages(true);
installPackage(pathTo("test-foobar-icon.appkg"));
- m_ai->setAllowInstallationOfUnsignedPackages(false);
+ m_pm->setAllowInstallationOfUnsignedPackages(false);
QDir checkDir(pathTo("internal-0"));
QVERIFY(checkDir.cd(qSL("com.pelagicore.test")));
@@ -387,23 +381,22 @@ void tst_PackagerTool::createDummyFile(QTemporaryDir &tmp, const QString &fileNa
auto written = code.write(data);
- QCOMPARE(written, (qint64)strlen(data));
+ QCOMPARE(written, static_cast<qint64>(strlen(data)));
}
void tst_PackagerTool::installPackage(const QString &filePath)
{
- QSignalSpy finishedSpy(m_ai, &ApplicationInstaller::taskFinished);
+ QSignalSpy finishedSpy(m_pm, &PackageManager::taskFinished);
- m_ai->setDevelopmentMode(true); // allow packages without store signature
+ m_pm->setDevelopmentMode(true); // allow packages without store signature
- QString taskId = m_ai->startPackageInstallation(qSL("internal-0"),
- QUrl::fromLocalFile(filePath));
- m_ai->acknowledgePackageInstallation(taskId);
+ QString taskId = m_pm->startPackageInstallation(QUrl::fromLocalFile(filePath));
+ m_pm->acknowledgePackageInstallation(taskId);
QVERIFY(finishedSpy.wait(2 * spyTimeout));
QCOMPARE(finishedSpy.first()[0].toString(), taskId);
- m_ai->setDevelopmentMode(false);
+ m_pm->setDevelopmentMode(false);
}
QTEST_GUILESS_MAIN(tst_PackagerTool)
diff --git a/tests/processreader/tst_processreader.cpp b/tests/processreader/tst_processreader.cpp
index 978770a0..1bfc0db0 100644
--- a/tests/processreader/tst_processreader.cpp
+++ b/tests/processreader/tst_processreader.cpp
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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:GPL-EXCEPT-QTAS$
** Commercial License Usage
diff --git a/tests/qml/configs/apps/test.configs.app/app.qml b/tests/qml/configs/apps/test.configs.app/app.qml
index 8ce11a63..402364ce 100644
--- a/tests/qml/configs/apps/test.configs.app/app.qml
+++ b/tests/qml/configs/apps/test.configs.app/app.qml
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/configs/configs.pro b/tests/qml/configs/configs.pro
index 1ba0ab11..86604d5e 100644
--- a/tests/qml/configs/configs.pro
+++ b/tests/qml/configs/configs.pro
@@ -2,6 +2,7 @@ load(am-config)
AM_CONFIG = am-config.yaml
TEST_FILES = tst_configs.qml
+TEST_APPS = test.configs.app
TEST_CONFIGURATIONS = "--force-single-process" \
"--force-single-process --single-app $$_PRO_FILE_PWD_/apps/test.configs.app/info.yaml"
multi-process {
diff --git a/tests/qml/configs/tst_configs.qml b/tests/qml/configs/tst_configs.qml
index 0dac7b3b..5acbeca1 100644
--- a/tests/qml/configs/tst_configs.qml
+++ b/tests/qml/configs/tst_configs.qml
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/crash/apps/tld.test.crash/app.qml b/tests/qml/crash/apps/tld.test.crash/app.qml
index 262b0802..447b5bef 100644
--- a/tests/qml/crash/apps/tld.test.crash/app.qml
+++ b/tests/qml/crash/apps/tld.test.crash/app.qml
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/crash/apps/tld.test.crash/terminator2/qmlterminator2.cpp b/tests/qml/crash/apps/tld.test.crash/terminator2/qmlterminator2.cpp
index 64210f63..ae03e600 100644
--- a/tests/qml/crash/apps/tld.test.crash/terminator2/qmlterminator2.cpp
+++ b/tests/qml/crash/apps/tld.test.crash/terminator2/qmlterminator2.cpp
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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:GPL-EXCEPT-QTAS$
** Commercial License Usage
diff --git a/tests/qml/crash/apps/tld.test.crash/terminator2/qmlterminator2.h b/tests/qml/crash/apps/tld.test.crash/terminator2/qmlterminator2.h
index d8fabbf9..5d59d6ea 100644
--- a/tests/qml/crash/apps/tld.test.crash/terminator2/qmlterminator2.h
+++ b/tests/qml/crash/apps/tld.test.crash/terminator2/qmlterminator2.h
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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:GPL-EXCEPT-QTAS$
** Commercial License Usage
diff --git a/tests/qml/crash/crash.pro b/tests/qml/crash/crash.pro
index 160c90af..b3bff364 100644
--- a/tests/qml/crash/crash.pro
+++ b/tests/qml/crash/crash.pro
@@ -1,4 +1,6 @@
AM_CONFIG = am-config.yaml
TEST_FILES = tst_crash.qml
+TEST_APPS = tld.test.crash
load(am-qml-testcase)
+
diff --git a/tests/qml/crash/tst_crash.qml b/tests/qml/crash/tst_crash.qml
index 89ae9a9b..29ebd011 100644
--- a/tests/qml/crash/tst_crash.qml
+++ b/tests/qml/crash/tst_crash.qml
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/installer/tst_installer.qml b/tests/qml/installer/tst_installer.qml
index 8bfcc246..82ba5419 100644
--- a/tests/qml/installer/tst_installer.qml
+++ b/tests/qml/installer/tst_installer.qml
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/intents/apps/intents1/intents1.qml b/tests/qml/intents/apps/intents1/intents1.qml
index 560cdb3a..eb53a84c 100644
--- a/tests/qml/intents/apps/intents1/intents1.qml
+++ b/tests/qml/intents/apps/intents1/intents1.qml
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/intents/apps/intents2/intents2.qml b/tests/qml/intents/apps/intents2/intents2.qml
index 7c989a17..d77ac506 100644
--- a/tests/qml/intents/apps/intents2/intents2.qml
+++ b/tests/qml/intents/apps/intents2/intents2.qml
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/intents/intents.pro b/tests/qml/intents/intents.pro
index ae6415a6..797f96e8 100644
--- a/tests/qml/intents/intents.pro
+++ b/tests/qml/intents/intents.pro
@@ -1,7 +1,5 @@
AM_CONFIG = am-config.yaml
TEST_FILES = tst_intents.qml
-
-APPS = intents1 intents2 cannot-start
-for (app, APPS): OTHER_FILES += apps/$${app}/*.yaml apps/$${app}/*.qml apps/$${app}/*.png
+TEST_APPS = intents1 intents2 cannot-start
load(am-qml-testcase)
diff --git a/tests/qml/intents/tst_intents.qml b/tests/qml/intents/tst_intents.qml
index 9ab11a7a..b574dee4 100644
--- a/tests/qml/intents/tst_intents.qml
+++ b/tests/qml/intents/tst_intents.qml
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/quicklaunch/apps/tld.test.quicklaunch/app.qml b/tests/qml/quicklaunch/apps/tld.test.quicklaunch/app.qml
index 1c203d4f..9defde81 100644
--- a/tests/qml/quicklaunch/apps/tld.test.quicklaunch/app.qml
+++ b/tests/qml/quicklaunch/apps/tld.test.quicklaunch/app.qml
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/quicklaunch/quicklaunch.pro b/tests/qml/quicklaunch/quicklaunch.pro
index 4c6b8f74..2d990a4b 100644
--- a/tests/qml/quicklaunch/quicklaunch.pro
+++ b/tests/qml/quicklaunch/quicklaunch.pro
@@ -1,4 +1,5 @@
AM_CONFIG = am-config.yaml
TEST_FILES = tst_quicklaunch.qml
+TEST_APPS = tld.test.quicklaunch
load(am-qml-testcase)
diff --git a/tests/qml/quicklaunch/tst_quicklaunch.qml b/tests/qml/quicklaunch/tst_quicklaunch.qml
index b840e691..1e4e4e5d 100644
--- a/tests/qml/quicklaunch/tst_quicklaunch.qml
+++ b/tests/qml/quicklaunch/tst_quicklaunch.qml
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/simple/apps/tld.test.simple1/app1.qml b/tests/qml/simple/apps/tld.test.simple1/app1.qml
index fb38c958..f0402209 100644
--- a/tests/qml/simple/apps/tld.test.simple1/app1.qml
+++ b/tests/qml/simple/apps/tld.test.simple1/app1.qml
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/simple/apps/tld.test.simple2/app.qml b/tests/qml/simple/apps/tld.test.simple2/app.qml
index 2a09855d..b0506e1f 100644
--- a/tests/qml/simple/apps/tld.test.simple2/app.qml
+++ b/tests/qml/simple/apps/tld.test.simple2/app.qml
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/simple/simple.pro b/tests/qml/simple/simple.pro
index 375f62c5..72dbea95 100644
--- a/tests/qml/simple/simple.pro
+++ b/tests/qml/simple/simple.pro
@@ -1,4 +1,5 @@
AM_CONFIG = am-config.yaml
TEST_FILES = tst_applicationmanager.qml
+TEST_APPS = tld.test.simple1 tld.test.simple2
load(am-qml-testcase)
diff --git a/tests/qml/simple/tst_applicationmanager.qml b/tests/qml/simple/tst_applicationmanager.qml
index d945c477..71878d5f 100644
--- a/tests/qml/simple/tst_applicationmanager.qml
+++ b/tests/qml/simple/tst_applicationmanager.qml
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/windowitem/apps/test.windowitem.app/main.qml b/tests/qml/windowitem/apps/test.windowitem.app/main.qml
index 8f64f980..ee12db6f 100644
--- a/tests/qml/windowitem/apps/test.windowitem.app/main.qml
+++ b/tests/qml/windowitem/apps/test.windowitem.app/main.qml
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/windowitem/apps/test.windowitem.multiwin/main.qml b/tests/qml/windowitem/apps/test.windowitem.multiwin/main.qml
index f12323be..7d1b0600 100644
--- a/tests/qml/windowitem/apps/test.windowitem.multiwin/main.qml
+++ b/tests/qml/windowitem/apps/test.windowitem.multiwin/main.qml
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/windowitem/tst_windowitem.qml b/tests/qml/windowitem/tst_windowitem.qml
index ea835267..15cd4f5b 100644
--- a/tests/qml/windowitem/tst_windowitem.qml
+++ b/tests/qml/windowitem/tst_windowitem.qml
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/windowitem/windowitem.pro b/tests/qml/windowitem/windowitem.pro
index d2755653..fcc1b1f6 100644
--- a/tests/qml/windowitem/windowitem.pro
+++ b/tests/qml/windowitem/windowitem.pro
@@ -1,4 +1,5 @@
AM_CONFIG = am-config.yaml
TEST_FILES = tst_windowitem.qml
+TEST_APPS = test.windowitem.app test.windowitem.multiwin
load(am-qml-testcase)
diff --git a/tests/qml/windowitem2/apps/test.windowitem2.app/main.qml b/tests/qml/windowitem2/apps/test.windowitem2.app/main.qml
index 84dfdb3e..ab891bb8 100644
--- a/tests/qml/windowitem2/apps/test.windowitem2.app/main.qml
+++ b/tests/qml/windowitem2/apps/test.windowitem2.app/main.qml
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/windowitem2/tst_windowitem2.qml b/tests/qml/windowitem2/tst_windowitem2.qml
index 5c411805..98d4ef30 100644
--- a/tests/qml/windowitem2/tst_windowitem2.qml
+++ b/tests/qml/windowitem2/tst_windowitem2.qml
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/windowitem2/windowitem2.pro b/tests/qml/windowitem2/windowitem2.pro
index fe1ab58a..022ea053 100644
--- a/tests/qml/windowitem2/windowitem2.pro
+++ b/tests/qml/windowitem2/windowitem2.pro
@@ -1,4 +1,5 @@
AM_CONFIG = am-config.yaml
TEST_FILES = tst_windowitem2.qml
+TEST_APPS = test.windowitem2.app
load(am-qml-testcase)
diff --git a/tests/qml/windowmanager/IviApplicationExtension.qml b/tests/qml/windowmanager/IviApplicationExtension.qml
index f85f147d..3e4a9700 100644
--- a/tests/qml/windowmanager/IviApplicationExtension.qml
+++ b/tests/qml/windowmanager/IviApplicationExtension.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/windowmanager/tst_windowmanager.qml b/tests/qml/windowmanager/tst_windowmanager.qml
index c2a556cd..11cb9265 100644
--- a/tests/qml/windowmanager/tst_windowmanager.qml
+++ b/tests/qml/windowmanager/tst_windowmanager.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/windowmanager/windowmanager.pro b/tests/qml/windowmanager/windowmanager.pro
index d9b687eb..1e291c00 100644
--- a/tests/qml/windowmanager/windowmanager.pro
+++ b/tests/qml/windowmanager/windowmanager.pro
@@ -1,4 +1,6 @@
AM_CONFIG = am-config.yaml
TEST_FILES = tst_windowmanager.qml
+OTHER_FILES += IviApplicationExtension.qml
+
load(am-qml-testcase)
diff --git a/tests/qml/windowmapping/apps/test.winmap.amwin/amwin.qml b/tests/qml/windowmapping/apps/test.winmap.amwin/amwin.qml
index 470d6dc0..a93f30d4 100644
--- a/tests/qml/windowmapping/apps/test.winmap.amwin/amwin.qml
+++ b/tests/qml/windowmapping/apps/test.winmap.amwin/amwin.qml
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/windowmapping/apps/test.winmap.amwin2/amwin2.qml b/tests/qml/windowmapping/apps/test.winmap.amwin2/amwin2.qml
index 8c104a05..b10709d3 100644
--- a/tests/qml/windowmapping/apps/test.winmap.amwin2/amwin2.qml
+++ b/tests/qml/windowmapping/apps/test.winmap.amwin2/amwin2.qml
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/windowmapping/apps/test.winmap.loader/SubWin.qml b/tests/qml/windowmapping/apps/test.winmap.loader/SubWin.qml
index af0001d6..8ba50e22 100644
--- a/tests/qml/windowmapping/apps/test.winmap.loader/SubWin.qml
+++ b/tests/qml/windowmapping/apps/test.winmap.loader/SubWin.qml
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/windowmapping/apps/test.winmap.loader/loader.qml b/tests/qml/windowmapping/apps/test.winmap.loader/loader.qml
index 569fef1a..0a65690e 100644
--- a/tests/qml/windowmapping/apps/test.winmap.loader/loader.qml
+++ b/tests/qml/windowmapping/apps/test.winmap.loader/loader.qml
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/windowmapping/apps/test.winmap.ping/ping.qml b/tests/qml/windowmapping/apps/test.winmap.ping/ping.qml
index 59267c04..6fa9ba23 100644
--- a/tests/qml/windowmapping/apps/test.winmap.ping/ping.qml
+++ b/tests/qml/windowmapping/apps/test.winmap.ping/ping.qml
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/windowmapping/apps/test.winmap.qtobject/qtobject.qml b/tests/qml/windowmapping/apps/test.winmap.qtobject/qtobject.qml
index c1c8ba3d..325c04de 100644
--- a/tests/qml/windowmapping/apps/test.winmap.qtobject/qtobject.qml
+++ b/tests/qml/windowmapping/apps/test.winmap.qtobject/qtobject.qml
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/windowmapping/apps/test.winmap.rectangle/rectangle.qml b/tests/qml/windowmapping/apps/test.winmap.rectangle/rectangle.qml
index 718b787d..fe6cdee3 100644
--- a/tests/qml/windowmapping/apps/test.winmap.rectangle/rectangle.qml
+++ b/tests/qml/windowmapping/apps/test.winmap.rectangle/rectangle.qml
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/windowmapping/apps/test.winmap.window/window.qml b/tests/qml/windowmapping/apps/test.winmap.window/window.qml
index c10a57b0..a0832d15 100644
--- a/tests/qml/windowmapping/apps/test.winmap.window/window.qml
+++ b/tests/qml/windowmapping/apps/test.winmap.window/window.qml
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/windowmapping/tst_windowmapping.qml b/tests/qml/windowmapping/tst_windowmapping.qml
index 00a6e582..dda075e5 100644
--- a/tests/qml/windowmapping/tst_windowmapping.qml
+++ b/tests/qml/windowmapping/tst_windowmapping.qml
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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/windowmapping/windowmapping.pro b/tests/qml/windowmapping/windowmapping.pro
index 59fa55b0..e29aba28 100644
--- a/tests/qml/windowmapping/windowmapping.pro
+++ b/tests/qml/windowmapping/windowmapping.pro
@@ -1,4 +1,12 @@
AM_CONFIG = am-config.yaml
TEST_FILES = tst_windowmapping.qml
+TEST_APPS = \
+ test.winmap.amwin \
+ test.winmap.amwin2 \
+ test.winmap.loader \
+ test.winmap.ping \
+ test.winmap.qtobject \
+ test.winmap.rectangle \
+ test.winmap.window \
load(am-qml-testcase)
diff --git a/tests/runtime/tst_runtime.cpp b/tests/runtime/tst_runtime.cpp
index 615417e4..dd3a2b4a 100644
--- a/tests/runtime/tst_runtime.cpp
+++ b/tests/runtime/tst_runtime.cpp
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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:GPL-EXCEPT-QTAS$
** Commercial License Usage
@@ -31,7 +31,8 @@
#include <QQmlEngine>
#include "application.h"
-#include "yamlapplicationscanner.h"
+#include "package.h"
+#include "yamlpackagescanner.h"
#include "abstractruntime.h"
#include "runtimefactory.h"
#include "exception.h"
@@ -62,19 +63,19 @@ public:
void setSlowAnimations(bool) override {}
- qint64 applicationProcessId() const
+ qint64 applicationProcessId() const override
{
return m_state == Am::Running ? 1 : 0;
}
public slots:
- bool start()
+ bool start() override
{
m_state = Am::Running;
return true;
}
- void stop(bool forceKill)
+ void stop(bool forceKill) override
{
Q_UNUSED(forceKill);
m_state = Am::NotRunning;
@@ -137,7 +138,10 @@ void tst_Runtime::factory()
Application *a = nullptr;
try {
- a = new Application(YamlApplicationScanner().scan(temp.fileName()));
+ PackageInfo *pi = YamlPackageScanner().scan(temp.fileName());
+ QVERIFY(pi);
+ Package *p = new Package(pi);
+ a = new Application(pi->applications().first(), p);
} catch (const Exception &e) {
QVERIFY2(false, qPrintable(e.errorString()));
}
diff --git a/tests/signature/create-test-data.sh b/tests/signature/create-test-data.sh
index 943ade2a..d599d18d 100755
--- a/tests/signature/create-test-data.sh
+++ b/tests/signature/create-test-data.sh
@@ -5,7 +5,7 @@
## Copyright (C) 2018 Pelagicore AG
## 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:GPL-EXCEPT-QTAS$
## Commercial License Usage
diff --git a/tests/signature/signature.pro b/tests/signature/signature.pro
index 77ff71f1..43bb3d47 100644
--- a/tests/signature/signature.pro
+++ b/tests/signature/signature.pro
@@ -6,4 +6,6 @@ QT *= appman_common-private appman_crypto-private
SOURCES += tst_signature.cpp
+OTHER_FILES += create-test-data.sh
+
RESOURCES += tst_signature.qrc
diff --git a/tests/signature/tst_signature.cpp b/tests/signature/tst_signature.cpp
index c8713457..9f48590a 100644
--- a/tests/signature/tst_signature.cpp
+++ b/tests/signature/tst_signature.cpp
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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:GPL-EXCEPT-QTAS$
** Commercial License Usage
diff --git a/tests/sudo/sudo.pro b/tests/sudo/sudo.pro
index 9745e2fc..95be319b 100644
--- a/tests/sudo/sudo.pro
+++ b/tests/sudo/sudo.pro
@@ -6,6 +6,6 @@ include($$PWD/../tests.pri)
QT *= \
appman_common-private \
- appman_installer-private \
+ appman_manager-private \
SOURCES += tst_sudo.cpp
diff --git a/tests/sudo/tst_sudo.cpp b/tests/sudo/tst_sudo.cpp
index 6ce7685e..0fb2b2ad 100644
--- a/tests/sudo/tst_sudo.cpp
+++ b/tests/sudo/tst_sudo.cpp
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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:GPL-EXCEPT-QTAS$
** Commercial License Usage
diff --git a/tests/systemreader/tst_systemreader.cpp b/tests/systemreader/tst_systemreader.cpp
index 48c75c23..d69478ee 100644
--- a/tests/systemreader/tst_systemreader.cpp
+++ b/tests/systemreader/tst_systemreader.cpp
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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:GPL-EXCEPT-QTAS$
** Commercial License Usage
diff --git a/tests/tests.pro b/tests/tests.pro
index 0b9409df..6cfe294b 100644
--- a/tests/tests.pro
+++ b/tests/tests.pro
@@ -1,6 +1,7 @@
TEMPLATE = subdirs
SUBDIRS = \
+ manual \
application \
applicationinfo \
main \
@@ -25,6 +26,7 @@ OTHER_FILES += \
tests.pri \
data/create-test-packages.sh \
data/certificates/create-test-certificates.sh \
+ data/utilities.sh \
# sadly, the appman-packager is too complex to build as a host tool
!cross_compile {
diff --git a/tests/utilities/tst_utilities.cpp b/tests/utilities/tst_utilities.cpp
index 47689907..5b4ed8e4 100644
--- a/tests/utilities/tst_utilities.cpp
+++ b/tests/utilities/tst_utilities.cpp
@@ -4,7 +4,7 @@
** Copyright (C) 2018 Pelagicore AG
** 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:GPL-EXCEPT-QTAS$
** Commercial License Usage
diff --git a/util/bash/appman-prompt b/util/bash/appman-prompt
index cd85278f..c1f37766 100644
--- a/util/bash/appman-prompt
+++ b/util/bash/appman-prompt
@@ -4,7 +4,7 @@
## Copyright (C) 2018 Pelagicore AG
## 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:GPL-EXCEPT-QTAS$
## Commercial License Usage
@@ -44,7 +44,7 @@ _appman()
COMPREPLY=( $( compgen -f -- ${cur}) )
fi
}
-complete -o filenames -F _appman appman
+complete -o filenames -F _appman appman appman-qmltestrunner
_appman-controller()
{