feat: support persistent stroage and lastLaunchedTime
Signed-off-by: ComixHe <heyuming@deepin.org>
This commit is contained in:
		@ -8,6 +8,7 @@
 | 
			
		||||
#include <QDir>
 | 
			
		||||
#include "dbus/applicationmanager1service.h"
 | 
			
		||||
#include "cgroupsidentifier.h"
 | 
			
		||||
#include "applicationmanagerstorage.h"
 | 
			
		||||
#include <chrono>
 | 
			
		||||
#include <iostream>
 | 
			
		||||
 | 
			
		||||
@ -42,7 +43,10 @@ int main(int argc, char *argv[])
 | 
			
		||||
    auto &AMBus = bus.globalServerBus();
 | 
			
		||||
 | 
			
		||||
    registerComplexDbusType();
 | 
			
		||||
    ApplicationManager1Service AMService{std::make_unique<CGroupsIdentifier>(), AMBus};
 | 
			
		||||
    auto storageDir = getXDGDataHome() + QDir::separator() + "deepin" + QDir::separator() + "ApplicationManager";
 | 
			
		||||
    auto storage = ApplicationManager1Storage::createApplicationManager1Storage(storageDir);
 | 
			
		||||
 | 
			
		||||
    ApplicationManager1Service AMService{std::make_unique<CGroupsIdentifier>(), AMBus, storage};
 | 
			
		||||
 | 
			
		||||
#ifdef PROFILING_MODE
 | 
			
		||||
    auto end = std::chrono::high_resolution_clock::now();
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										205
									
								
								src/applicationmanagerstorage.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										205
									
								
								src/applicationmanagerstorage.cpp
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,205 @@
 | 
			
		||||
// SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd.
 | 
			
		||||
//
 | 
			
		||||
// SPDX-License-Identifier: LGPL-3.0-or-later
 | 
			
		||||
 | 
			
		||||
#include "applicationmanagerstorage.h"
 | 
			
		||||
#include "constant.h"
 | 
			
		||||
#include <QFileInfo>
 | 
			
		||||
#include <QJsonDocument>
 | 
			
		||||
#include <QDir>
 | 
			
		||||
#include <memory>
 | 
			
		||||
 | 
			
		||||
std::shared_ptr<ApplicationManager1Storage>
 | 
			
		||||
ApplicationManager1Storage::createApplicationManager1Storage(const QString &storageDir) noexcept
 | 
			
		||||
{
 | 
			
		||||
    QDir dir;
 | 
			
		||||
    auto dirPath = QDir::cleanPath(storageDir);
 | 
			
		||||
    if (!dir.mkpath(dirPath)) {
 | 
			
		||||
        qCritical() << "can't create directory";
 | 
			
		||||
        return nullptr;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    dir.setPath(dirPath);
 | 
			
		||||
    auto storagePath = dir.filePath("storage.json");
 | 
			
		||||
    auto obj = std::shared_ptr<ApplicationManager1Storage>(new (std::nothrow) ApplicationManager1Storage{storagePath});
 | 
			
		||||
 | 
			
		||||
    if (!obj) {
 | 
			
		||||
        qCritical() << "new ApplicationManager1Storage failed.";
 | 
			
		||||
        return nullptr;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (!obj->m_file->open(QFile::ReadWrite)) {
 | 
			
		||||
        qCritical() << "can't open file:" << storagePath;
 | 
			
		||||
        return nullptr;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    auto content = obj->m_file->readAll();
 | 
			
		||||
    if (content.isEmpty()) {  // new file
 | 
			
		||||
        obj->setVersion(STORAGE_VERSION);
 | 
			
		||||
        return obj;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // TODO: support migrate from lower storage version.
 | 
			
		||||
 | 
			
		||||
    QJsonParseError err;
 | 
			
		||||
    auto json = QJsonDocument::fromJson(content, &err);
 | 
			
		||||
    if (err.error != QJsonParseError::NoError) {
 | 
			
		||||
        qDebug() << "parse json failed:" << err.errorString() << "clear this file content.";
 | 
			
		||||
        obj->m_file->resize(0);
 | 
			
		||||
    } else {
 | 
			
		||||
        obj->m_data = json.object();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return obj;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ApplicationManager1Storage::ApplicationManager1Storage(const QString &storagePath)
 | 
			
		||||
    : m_file(std::make_unique<QFile>(storagePath))
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ApplicationManager1Storage::writeToFile() const noexcept
 | 
			
		||||
{
 | 
			
		||||
    if (!m_file) {
 | 
			
		||||
        qCritical() << "file is nullptr";
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (!m_file->resize(0)) {
 | 
			
		||||
        qCritical() << "failed to clear file:" << m_file->errorString();
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    auto content = QJsonDocument{m_data}.toJson(QJsonDocument::Compact);
 | 
			
		||||
    auto bytes = m_file->write(content, content.size());
 | 
			
		||||
    if (bytes != content.size()) {
 | 
			
		||||
        qWarning() << "Incomplete file writes:" << m_file->errorString();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (!m_file->flush()) {
 | 
			
		||||
        qCritical() << "io error.";
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ApplicationManager1Storage::setVersion(uint8_t version) noexcept
 | 
			
		||||
{
 | 
			
		||||
    m_data["version"] = version;
 | 
			
		||||
    writeToFile();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint8_t ApplicationManager1Storage::version() const noexcept
 | 
			
		||||
{
 | 
			
		||||
    return m_data["version"].toInt(0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ApplicationManager1Storage::createApplicationValue(const QString &appId,
 | 
			
		||||
                                                        const QString &groupName,
 | 
			
		||||
                                                        const QString &valueKey,
 | 
			
		||||
                                                        const QVariant &value) noexcept
 | 
			
		||||
{
 | 
			
		||||
    if (appId.isEmpty() or groupName.isEmpty() or valueKey.isEmpty()) {
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    QJsonObject appObj;
 | 
			
		||||
    if (m_data.contains(appId)) {
 | 
			
		||||
        appObj = m_data[appId].toObject();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    QJsonObject groupObj;
 | 
			
		||||
    if (appObj.contains(groupName)) {
 | 
			
		||||
        groupObj = appObj[groupName].toObject();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (groupObj.contains(valueKey)) {
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    groupObj.insert(valueKey, value.toJsonValue());
 | 
			
		||||
    appObj.insert(groupName, groupObj);
 | 
			
		||||
    m_data.insert(appId, appObj);
 | 
			
		||||
 | 
			
		||||
    writeToFile();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ApplicationManager1Storage::updateApplicationValue(const QString &appId,
 | 
			
		||||
                                                        const QString &groupName,
 | 
			
		||||
                                                        const QString &valueKey,
 | 
			
		||||
                                                        const QVariant &value) noexcept
 | 
			
		||||
{
 | 
			
		||||
    if (appId.isEmpty() or groupName.isEmpty() or valueKey.isEmpty()) {
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (!m_data.contains(appId)) {
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
    auto appObj = m_data[appId].toObject();
 | 
			
		||||
 | 
			
		||||
    if (!appObj.contains(groupName)) {
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
    auto groupObj = appObj[groupName].toObject();
 | 
			
		||||
 | 
			
		||||
    if (!groupObj.contains(valueKey)) {
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    groupObj.insert(valueKey, value.toJsonValue());
 | 
			
		||||
    appObj.insert(groupName, groupObj);
 | 
			
		||||
    m_data.insert(appId, appObj);
 | 
			
		||||
 | 
			
		||||
    writeToFile();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
QVariant ApplicationManager1Storage::readApplicationValue(const QString &appId,
 | 
			
		||||
                                                          const QString &groupName,
 | 
			
		||||
                                                          const QString &valueKey) const noexcept
 | 
			
		||||
{
 | 
			
		||||
    return m_data[appId][groupName][valueKey].toVariant();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ApplicationManager1Storage::deleteApplicationValue(const QString &appId,
 | 
			
		||||
                                                        const QString &groupName,
 | 
			
		||||
                                                        const QString &valueKey) noexcept
 | 
			
		||||
{
 | 
			
		||||
    if (appId.isEmpty()) {
 | 
			
		||||
        auto empty = QJsonObject{};
 | 
			
		||||
        m_data.swap(empty);
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    auto app = m_data.find(appId).value();
 | 
			
		||||
    if (app.isNull()) {
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
    auto appObj = app.toObject();
 | 
			
		||||
 | 
			
		||||
    if (groupName.isEmpty()) {
 | 
			
		||||
        m_data.remove(appId);
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    auto group = appObj.find(groupName).value();
 | 
			
		||||
    if (group.isNull()) {
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
    auto groupObj = group.toObject();
 | 
			
		||||
 | 
			
		||||
    if (valueKey.isEmpty()) {
 | 
			
		||||
        appObj.remove(groupName);
 | 
			
		||||
        m_data.insert(appId, appObj);
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    auto val = groupObj.find(valueKey).value();
 | 
			
		||||
    if (val.isNull()) {
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    groupObj.remove(valueKey);
 | 
			
		||||
    appObj.insert(groupName, groupObj);
 | 
			
		||||
    m_data.insert(appId, appObj);
 | 
			
		||||
 | 
			
		||||
    writeToFile();
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										47
									
								
								src/applicationmanagerstorage.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								src/applicationmanagerstorage.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,47 @@
 | 
			
		||||
// SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd.
 | 
			
		||||
//
 | 
			
		||||
// SPDX-License-Identifier: LGPL-3.0-or-later
 | 
			
		||||
 | 
			
		||||
#ifndef APPLICATIONMANAGERSTORAGE_H
 | 
			
		||||
#define APPLICATIONMANAGERSTORAGE_H
 | 
			
		||||
 | 
			
		||||
#include <QString>
 | 
			
		||||
#include <QJsonObject>
 | 
			
		||||
#include <QFile>
 | 
			
		||||
 | 
			
		||||
enum class ModifyMode { Create, Update };
 | 
			
		||||
 | 
			
		||||
class ApplicationManager1Storage
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
    ApplicationManager1Storage(const ApplicationManager1Storage &) = delete;
 | 
			
		||||
    ApplicationManager1Storage(ApplicationManager1Storage &&) = default;
 | 
			
		||||
    ApplicationManager1Storage &operator=(const ApplicationManager1Storage &) = delete;
 | 
			
		||||
    ApplicationManager1Storage &operator=(ApplicationManager1Storage &&) = default;
 | 
			
		||||
    ~ApplicationManager1Storage() = default;
 | 
			
		||||
 | 
			
		||||
    void createApplicationValue(const QString &appId,
 | 
			
		||||
                                const QString &groupName,
 | 
			
		||||
                                const QString &valueKey,
 | 
			
		||||
                                const QVariant &value) noexcept;
 | 
			
		||||
    void updateApplicationValue(const QString &appId,
 | 
			
		||||
                                const QString &groupName,
 | 
			
		||||
                                const QString &valueKey,
 | 
			
		||||
                                const QVariant &value) noexcept;
 | 
			
		||||
    [[nodiscard]] QVariant
 | 
			
		||||
    readApplicationValue(const QString &appId, const QString &groupName, const QString &valueKey) const noexcept;
 | 
			
		||||
    void deleteApplicationValue(const QString &appId = "", const QString &groupName = "", const QString &valueKey = "") noexcept;
 | 
			
		||||
 | 
			
		||||
    void setVersion(uint8_t version) noexcept;
 | 
			
		||||
    [[nodiscard]] uint8_t version() const noexcept;
 | 
			
		||||
 | 
			
		||||
    static std::shared_ptr<ApplicationManager1Storage> createApplicationManager1Storage(const QString &storageDir) noexcept;
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    void writeToFile() const noexcept;
 | 
			
		||||
    explicit ApplicationManager1Storage(const QString &storagePath);
 | 
			
		||||
    std::unique_ptr<QFile> m_file;
 | 
			
		||||
    QJsonObject m_data;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
@ -47,4 +47,8 @@ constexpr auto systemdOption = u8"systemd";
 | 
			
		||||
constexpr auto splitOption = u8"split";
 | 
			
		||||
constexpr auto AppExecOption = u8"appExec";
 | 
			
		||||
 | 
			
		||||
constexpr auto STORAGE_VERSION = 1;
 | 
			
		||||
constexpr auto ApplicationPropertiesGroup = u8"Application Properties";
 | 
			
		||||
constexpr auto LastLaunchedTime = u8"LastLaunchedTime";
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
@ -13,8 +13,11 @@
 | 
			
		||||
 | 
			
		||||
ApplicationManager1Service::~ApplicationManager1Service() = default;
 | 
			
		||||
 | 
			
		||||
ApplicationManager1Service::ApplicationManager1Service(std::unique_ptr<Identifier> ptr, QDBusConnection &connection) noexcept
 | 
			
		||||
ApplicationManager1Service::ApplicationManager1Service(std::unique_ptr<Identifier> ptr,
 | 
			
		||||
                                                       QDBusConnection &connection,
 | 
			
		||||
                                                       std::weak_ptr<ApplicationManager1Storage> storage) noexcept
 | 
			
		||||
    : m_identifier(std::move(ptr))
 | 
			
		||||
    , m_storage(std::move(storage))
 | 
			
		||||
{
 | 
			
		||||
    if (!connection.registerService(DDEApplicationManager1ServiceName)) {
 | 
			
		||||
        qFatal("%s", connection.lastError().message().toLocal8Bit().data());
 | 
			
		||||
@ -116,6 +119,17 @@ void ApplicationManager1Service::addInstanceToApplication(const QString &unitNam
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (sender() != nullptr) {  // activate by signal
 | 
			
		||||
        auto timestamp = QDateTime::currentMSecsSinceEpoch();
 | 
			
		||||
 | 
			
		||||
        if (auto ptr = m_storage.lock(); ptr) {
 | 
			
		||||
            ptr->updateApplicationValue((*appIt)->m_desktopSource.desktopId(),
 | 
			
		||||
                                        ApplicationPropertiesGroup,
 | 
			
		||||
                                        LastLaunchedTime,
 | 
			
		||||
                                        QVariant::fromValue(timestamp));
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const auto &applicationPath = (*appIt)->applicationPath().path();
 | 
			
		||||
 | 
			
		||||
    if (!(*appIt)->addOneInstance(instanceId, applicationPath, systemdUnitPath.path())) [[likely]] {
 | 
			
		||||
@ -229,7 +243,7 @@ QList<QDBusObjectPath> ApplicationManager1Service::list() const
 | 
			
		||||
bool ApplicationManager1Service::addApplication(DesktopFile desktopFileSource) noexcept
 | 
			
		||||
{
 | 
			
		||||
    QSharedPointer<ApplicationService> application =
 | 
			
		||||
        ApplicationService::createApplicationService(std::move(desktopFileSource), this);
 | 
			
		||||
        ApplicationService::createApplicationService(std::move(desktopFileSource), this, m_storage);
 | 
			
		||||
    if (!application) {
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
@ -251,6 +265,18 @@ bool ApplicationManager1Service::addApplication(DesktopFile desktopFileSource) n
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
    m_applicationList.insert(application->applicationPath(), application);
 | 
			
		||||
 | 
			
		||||
    if (auto storagePtr = m_storage.lock(); storagePtr) {
 | 
			
		||||
        auto appId = ptr->id();
 | 
			
		||||
        auto value = storagePtr->readApplicationValue(appId, ApplicationPropertiesGroup, LastLaunchedTime);
 | 
			
		||||
        if (value.isNull()) {
 | 
			
		||||
            storagePtr->createApplicationValue(
 | 
			
		||||
                appId, ApplicationPropertiesGroup, LastLaunchedTime, QVariant::fromValue<qint64>(0));
 | 
			
		||||
        } else {
 | 
			
		||||
            ptr->m_lastLaunch = value.toInt();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    emit listChanged();
 | 
			
		||||
    emit InterfacesAdded(application->applicationPath(), getChildInterfacesAndPropertiesFromObject(ptr));
 | 
			
		||||
 | 
			
		||||
@ -261,8 +287,12 @@ void ApplicationManager1Service::removeOneApplication(const QDBusObjectPath &app
 | 
			
		||||
{
 | 
			
		||||
    if (auto it = m_applicationList.find(application); it != m_applicationList.cend()) {
 | 
			
		||||
        emit InterfacesRemoved(application, getChildInterfacesFromObject(it->data()));
 | 
			
		||||
        if (auto ptr = m_storage.lock(); ptr) {
 | 
			
		||||
            ptr->deleteApplicationValue((*it)->id());
 | 
			
		||||
        }
 | 
			
		||||
        unregisterObjectFromDBus(application.path());
 | 
			
		||||
        m_applicationList.remove(application);
 | 
			
		||||
 | 
			
		||||
        emit listChanged();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -12,6 +12,7 @@
 | 
			
		||||
#include <QScopedPointer>
 | 
			
		||||
#include <memory>
 | 
			
		||||
#include <QMap>
 | 
			
		||||
#include "applicationmanagerstorage.h"
 | 
			
		||||
#include "dbus/jobmanager1service.h"
 | 
			
		||||
#include "desktopentry.h"
 | 
			
		||||
#include "identifier.h"
 | 
			
		||||
@ -22,7 +23,9 @@ class ApplicationManager1Service final : public QObject
 | 
			
		||||
{
 | 
			
		||||
    Q_OBJECT
 | 
			
		||||
public:
 | 
			
		||||
    explicit ApplicationManager1Service(std::unique_ptr<Identifier> ptr, QDBusConnection &connection) noexcept;
 | 
			
		||||
    explicit ApplicationManager1Service(std::unique_ptr<Identifier> ptr,
 | 
			
		||||
                                        QDBusConnection &connection,
 | 
			
		||||
                                        std::weak_ptr<ApplicationManager1Storage> storage) noexcept;
 | 
			
		||||
    ~ApplicationManager1Service() override;
 | 
			
		||||
    ApplicationManager1Service(const ApplicationManager1Service &) = delete;
 | 
			
		||||
    ApplicationManager1Service(ApplicationManager1Service &&) = delete;
 | 
			
		||||
@ -52,6 +55,7 @@ Q_SIGNALS:
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    std::unique_ptr<Identifier> m_identifier;
 | 
			
		||||
    std::weak_ptr<ApplicationManager1Storage> m_storage;
 | 
			
		||||
    QScopedPointer<JobManager1Service> m_jobManager{nullptr};
 | 
			
		||||
    QMap<QDBusObjectPath, QSharedPointer<ApplicationService>> m_applicationList;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -6,6 +6,7 @@
 | 
			
		||||
#include "APPobjectmanager1adaptor.h"
 | 
			
		||||
#include "applicationchecker.h"
 | 
			
		||||
#include "applicationmanager1service.h"
 | 
			
		||||
#include "applicationmanagerstorage.h"
 | 
			
		||||
#include "propertiesForwarder.h"
 | 
			
		||||
#include "dbus/instanceadaptor.h"
 | 
			
		||||
#include "launchoptions.h"
 | 
			
		||||
@ -18,10 +19,14 @@
 | 
			
		||||
#include <QStandardPaths>
 | 
			
		||||
#include <algorithm>
 | 
			
		||||
#include <new>
 | 
			
		||||
#include <utility>
 | 
			
		||||
#include <wordexp.h>
 | 
			
		||||
 | 
			
		||||
ApplicationService::ApplicationService(DesktopFile source, ApplicationManager1Service *parent)
 | 
			
		||||
ApplicationService::ApplicationService(DesktopFile source,
 | 
			
		||||
                                       ApplicationManager1Service *parent,
 | 
			
		||||
                                       std::weak_ptr<ApplicationManager1Storage> storage)
 | 
			
		||||
    : QObject(parent)
 | 
			
		||||
    , m_storage(std::move(storage))
 | 
			
		||||
    , m_desktopSource(std::move(source))
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
@ -36,10 +41,10 @@ ApplicationService::~ApplicationService()
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
QSharedPointer<ApplicationService> ApplicationService::createApplicationService(DesktopFile source,
 | 
			
		||||
                                                                                ApplicationManager1Service *parent) noexcept
 | 
			
		||||
QSharedPointer<ApplicationService> ApplicationService::createApplicationService(
 | 
			
		||||
    DesktopFile source, ApplicationManager1Service *parent, std::weak_ptr<ApplicationManager1Storage> storage) noexcept
 | 
			
		||||
{
 | 
			
		||||
    QSharedPointer<ApplicationService> app{new (std::nothrow) ApplicationService{std::move(source), parent}};
 | 
			
		||||
    QSharedPointer<ApplicationService> app{new (std::nothrow) ApplicationService{std::move(source), parent, std::move(storage)}};
 | 
			
		||||
    if (!app) {
 | 
			
		||||
        qCritical() << "new application service failed.";
 | 
			
		||||
        return nullptr;
 | 
			
		||||
@ -90,6 +95,12 @@ QSharedPointer<ApplicationService> ApplicationService::createApplicationService(
 | 
			
		||||
        return nullptr;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    auto ptr = app->m_storage.lock();
 | 
			
		||||
    if (!ptr) {
 | 
			
		||||
        qWarning() << "runtime storage doesn't exists.";
 | 
			
		||||
        return app;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return app;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -176,7 +187,7 @@ QDBusObjectPath ApplicationService::Launch(const QString &action, const QStringL
 | 
			
		||||
    auto &jobManager = static_cast<ApplicationManager1Service *>(parent())->jobManager();
 | 
			
		||||
    return jobManager.addJob(
 | 
			
		||||
        m_applicationPath.path(),
 | 
			
		||||
        [this, binary = std::move(bin), commands = std::move(cmds)](QVariant variantValue) mutable -> QVariant {
 | 
			
		||||
        [this, binary = std::move(bin), commands = std::move(cmds)](const QVariant &variantValue) mutable -> QVariant {
 | 
			
		||||
            auto resourceFile = variantValue.toString();
 | 
			
		||||
            auto instanceRandomUUID = QUuid::createUuid().toString(QUuid::Id128);
 | 
			
		||||
            auto objectPath = m_applicationPath.path() + "/" + instanceRandomUUID;
 | 
			
		||||
 | 
			
		||||
@ -17,6 +17,7 @@
 | 
			
		||||
#include <QFile>
 | 
			
		||||
#include <memory>
 | 
			
		||||
#include <utility>
 | 
			
		||||
#include "applicationmanagerstorage.h"
 | 
			
		||||
#include "dbus/instanceservice.h"
 | 
			
		||||
#include "global.h"
 | 
			
		||||
#include "desktopentry.h"
 | 
			
		||||
@ -110,10 +111,13 @@ Q_SIGNALS:
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    friend class ApplicationManager1Service;
 | 
			
		||||
    explicit ApplicationService(DesktopFile source, ApplicationManager1Service *parent);
 | 
			
		||||
    static QSharedPointer<ApplicationService> createApplicationService(DesktopFile source,
 | 
			
		||||
                                                                       ApplicationManager1Service *parent) noexcept;
 | 
			
		||||
    qlonglong m_lastLaunch{0};
 | 
			
		||||
    explicit ApplicationService(DesktopFile source,
 | 
			
		||||
                                ApplicationManager1Service *parent,
 | 
			
		||||
                                std::weak_ptr<ApplicationManager1Storage> storage);
 | 
			
		||||
    static QSharedPointer<ApplicationService> createApplicationService(
 | 
			
		||||
        DesktopFile source, ApplicationManager1Service *parent, std::weak_ptr<ApplicationManager1Storage> storage) noexcept;
 | 
			
		||||
    qint64 m_lastLaunch{0};
 | 
			
		||||
    std::weak_ptr<ApplicationManager1Storage> m_storage;
 | 
			
		||||
    QDBusObjectPath m_applicationPath;
 | 
			
		||||
    QString m_launcher{getApplicationLauncherBinary()};
 | 
			
		||||
    DesktopFile m_desktopSource;
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										16
									
								
								src/global.h
									
									
									
									
									
								
							
							
						
						
									
										16
									
								
								src/global.h
									
									
									
									
									
								
							@ -363,6 +363,15 @@ inline QString getRelativePathFromAppId(const QString &id)
 | 
			
		||||
    return path;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline QString getXDGDataHome()
 | 
			
		||||
{
 | 
			
		||||
    auto XDGDataHome = QString::fromLocal8Bit(qgetenv("XDG_DATA_HOME"));
 | 
			
		||||
    if (XDGDataHome.isEmpty()) {
 | 
			
		||||
        XDGDataHome = QString::fromLocal8Bit(qgetenv("HOME")) + QDir::separator() + ".local" + QDir::separator() + "share";
 | 
			
		||||
    }
 | 
			
		||||
    return XDGDataHome;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline QStringList getDesktopFileDirs()
 | 
			
		||||
{
 | 
			
		||||
    auto XDGDataDirs = QString::fromLocal8Bit(qgetenv("XDG_DATA_DIRS")).split(':', Qt::SkipEmptyParts);
 | 
			
		||||
@ -372,12 +381,7 @@ inline QStringList getDesktopFileDirs()
 | 
			
		||||
        XDGDataDirs.append("/usr/share");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    auto XDGDataHome = QString::fromLocal8Bit(qgetenv("XDG_DATA_HOME"));
 | 
			
		||||
    if (XDGDataHome.isEmpty()) {
 | 
			
		||||
        XDGDataHome = QString::fromLocal8Bit(qgetenv("HOME")) + QDir::separator() + ".local" + QDir::separator() + "share";
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    XDGDataDirs.push_front(std::move(XDGDataHome));
 | 
			
		||||
    XDGDataDirs.push_front(getXDGDataHome());
 | 
			
		||||
 | 
			
		||||
    std::for_each(XDGDataDirs.begin(), XDGDataDirs.end(), [](QString &str) {
 | 
			
		||||
        if (!str.endsWith(QDir::separator())) {
 | 
			
		||||
 | 
			
		||||
@ -33,11 +33,11 @@ public:
 | 
			
		||||
        auto &bus = ApplicationManager1DBus::instance();
 | 
			
		||||
        bus.initGlobalServerBus(DBusType::Session);
 | 
			
		||||
        bus.setDestBus();
 | 
			
		||||
 | 
			
		||||
        m_am = new ApplicationManager1Service{std::make_unique<CGroupsIdentifier>(), bus.globalServerBus()};
 | 
			
		||||
        std::shared_ptr<ApplicationManager1Storage> tmp{nullptr};
 | 
			
		||||
        m_am = new ApplicationManager1Service{std::make_unique<CGroupsIdentifier>(), bus.globalServerBus(), tmp};
 | 
			
		||||
        auto ptr = std::make_unique<QFile>(QString{"/usr/share/applications/test-Application.desktop"});
 | 
			
		||||
        DesktopFile file{std::move(ptr), "test-Application", 0, 0};
 | 
			
		||||
        QSharedPointer<ApplicationService> app = QSharedPointer<ApplicationService>::create(std::move(file), nullptr);
 | 
			
		||||
        QSharedPointer<ApplicationService> app = QSharedPointer<ApplicationService>::create(std::move(file), nullptr, tmp);
 | 
			
		||||
        QSharedPointer<InstanceService> instance =
 | 
			
		||||
            QSharedPointer<InstanceService>::create(InstancePath.path().split('/').last(), ApplicationPath.path(), QString{"/"});
 | 
			
		||||
        app->m_Instances.insert(InstancePath, instance);
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user