diff --git a/src/blackcore/application.cpp b/src/blackcore/application.cpp index 322a5cf16..04a73fb9e 100644 --- a/src/blackcore/application.cpp +++ b/src/blackcore/application.cpp @@ -16,6 +16,7 @@ #include "blackcore/registermetadata.h" #include "blackcore/setupreader.h" #include "blackcore/webdataservices.h" +#include "blackmisc/atomicfile.h" #include "blackmisc/datacache.h" #include "blackmisc/dbusserver.h" #include "blackmisc/directoryutils.h" @@ -74,6 +75,13 @@ using namespace crashpad; BlackCore::CApplication *sApp = nullptr; // set by constructor +//! \private +static const QString &swiftDataRoot() +{ + static const QString path = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + "/org.swift-project/"; + return path; +} + namespace BlackCore { CApplication::CApplication(const QString &applicationName, CApplicationInfo::Application application, bool init) : @@ -138,11 +146,44 @@ namespace BlackCore } } + int CApplication::exec() + { + Q_ASSERT_X(instance(), Q_FUNC_INFO, "missing application"); + + CApplicationInfoList apps = getRunningApplications(); + apps.push_back(instance()->getApplicationInfo()); + bool ok = CFileUtils::writeStringToLockedFile(apps.toJsonString(), swiftDataRoot() + "apps.json"); + if (!ok) { CLogMessage(static_cast(nullptr)).error("Failed to write to application list file"); } + + return QCoreApplication::exec(); + } + CApplication::~CApplication() { this->gracefulShutdown(); } + CApplicationInfo CApplication::getApplicationInfo() const + { + CApplicationInfo::ApplicationMode mode; + if (isRunningInDeveloperEnvironment()) { mode |= CApplicationInfo::Developer; } + if (CBuildConfig::isBetaTest()) { mode |= CApplicationInfo::BetaTest; } + return { getSwiftApplication(), mode, QCoreApplication::applicationFilePath(), CVersion::version(), CProcessInfo::currentProcess() }; + } + + CApplicationInfoList CApplication::getRunningApplications() + { + CApplicationInfoList apps; + apps.convertFromJson(CFileUtils::readLockedFileToString(swiftDataRoot() + "apps.json")); + apps.removeIf([](const CApplicationInfo &info) { return !info.processInfo().exists(); }); + return apps; + } + + bool CApplication::isAlreadyRunning() const + { + return getRunningApplications().containsBy([this](const CApplicationInfo &info) { return info.application() == getSwiftApplication(); }); + } + const QString &CApplication::getApplicationNameAndVersion() const { static const QString s(QCoreApplication::instance()->applicationName() + " " + CVersion::version()); @@ -457,12 +498,6 @@ namespace BlackCore this->m_cookieManager.deleteAllCookies(); } - int CApplication::exec() - { - Q_ASSERT_X(instance(), Q_FUNC_INFO, "missing application"); - return QCoreApplication::exec(); - } - void CApplication::exit(int retcode) { if (instance()) diff --git a/src/blackcore/application.h b/src/blackcore/application.h index 0ff5820fb..56098e9fd 100644 --- a/src/blackcore/application.h +++ b/src/blackcore/application.h @@ -108,6 +108,15 @@ namespace BlackCore //! Destructor virtual ~CApplication(); + //! Application information + BlackMisc::CApplicationInfo getApplicationInfo() const; + + //! Information about all running apps (including this one only if exec() has already been called) + static BlackMisc::CApplicationInfoList getRunningApplications(); + + //! True if this swift application is already running (including different versions) + bool isAlreadyRunning() const; + //! Application name and version const QString &getApplicationNameAndVersion() const;