refact: DesktopFile's method and structure

Signed-off-by: ComixHe <heyuming@deepin.org>
This commit is contained in:
ComixHe 2023-08-21 16:02:26 +08:00 committed by Comix
parent 65b6c9eaf0
commit 06ee5e5899
10 changed files with 155 additions and 99 deletions

View File

@ -27,7 +27,7 @@ public:
u8"JobNew", u8"JobNew",
this, this,
SLOT(jobNewForward(QDBusObjectPath, QDBusObjectPath)))) { SLOT(jobNewForward(QDBusObjectPath, QDBusObjectPath)))) {
qFatal() << "connect JobNew failed."; qFatal("connect JobNew failed.");
} }
if (!con.connect(JobManager.service(), if (!con.connect(JobManager.service(),
@ -36,7 +36,7 @@ public:
u8"JobRemoved", u8"JobRemoved",
this, this,
SLOT(jobRemovedForward(QDBusObjectPath, QString, QVariantList)))) { SLOT(jobRemovedForward(QDBusObjectPath, QString, QVariantList)))) {
qFatal() << "connect JobNew failed."; qFatal("connect JobNew failed.");
} }
connect(this, &Demo::applicationLaunched, [](QList<QString> apps) { connect(this, &Demo::applicationLaunched, [](QList<QString> apps) {

View File

@ -1,8 +1,9 @@
// SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd. // SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd.
// //
// SPDX-License-Identifier: LGPL-3.0-or-later // SPDX-License-Identifier: LGPL-3.0-or-later
#include "applicationadaptor.h"
#include "dbus/applicationmanager1adaptor.h" #include "dbus/applicationmanager1adaptor.h"
#include "applicationservice.h"
#include "dbus/AMobjectmanager1adaptor.h" #include "dbus/AMobjectmanager1adaptor.h"
#include "systemdsignaldispatcher.h" #include "systemdsignaldispatcher.h"
#include <QFile> #include <QFile>
@ -10,17 +11,20 @@
ApplicationManager1Service::~ApplicationManager1Service() = default; ApplicationManager1Service::~ApplicationManager1Service() = default;
ApplicationManager1Service::ApplicationManager1Service(std::unique_ptr<Identifier> ptr, QDBusConnection &connection) ApplicationManager1Service::ApplicationManager1Service(std::unique_ptr<Identifier> ptr, QDBusConnection &connection) noexcept
: m_identifier(std::move(ptr)) : m_identifier(std::move(ptr))
{ {
if (!connection.registerService(DDEApplicationManager1ServiceName)) { if (!connection.registerService(DDEApplicationManager1ServiceName)) {
qFatal() << connection.lastError(); qFatal("%s", connection.lastError().message().toLocal8Bit().data());
} }
new ApplicationManager1Adaptor{this}; if (auto *tmp = new (std::nothrow) ApplicationManager1Adaptor{this}; tmp == nullptr) {
auto *tmp = new AMObjectManagerAdaptor{this}; qCritical() << "new Application Manager Adaptor failed.";
std::terminate();
}
if (tmp == nullptr) { if (auto *tmp = new (std::nothrow) AMObjectManagerAdaptor{this}; tmp == nullptr) {
qCritical() << "new Object Manager of Application Manager Adaptor failed.";
std::terminate(); std::terminate();
} }
@ -29,7 +33,12 @@ ApplicationManager1Service::ApplicationManager1Service(std::unique_ptr<Identifie
std::terminate(); std::terminate();
} }
m_jobManager.reset(new JobManager1Service(this)); m_jobManager.reset(new (std::nothrow) JobManager1Service(this));
if (!m_jobManager) {
qCritical() << "new JobManager failed.";
std::terminate();
}
auto &dispatcher = SystemdSignalDispatcher::instance(); auto &dispatcher = SystemdSignalDispatcher::instance();
@ -109,11 +118,8 @@ bool ApplicationManager1Service::addApplication(DesktopFile desktopFileSource) n
} }
if (m_applicationList.constFind(application->applicationPath()) != m_applicationList.cend()) { if (m_applicationList.constFind(application->applicationPath()) != m_applicationList.cend()) {
auto info = qInfo(); qInfo() << "this application already exists."
info << "this application already exists."; << "desktop source:" << application->desktopFileSource().sourcePath();
if (application->desktopFileSource().persistence()) {
info << "desktop source:" << application->desktopFileSource().fileSource();
}
return false; return false;
} }
@ -209,16 +215,9 @@ void ApplicationManager1Service::updateApplication(const QSharedPointer<Applicat
return; return;
} }
struct stat buf; auto mtime = getFileModifiedTime(desktopFile.sourceFileRef());
const auto *filePath = desktopFile.fileSource().toLocal8Bit().data();
if (auto ret = stat(filePath, &buf); ret == -1) {
qWarning() << "get file" << filePath << "state failed:" << std::strerror(errno);
return;
}
constexpr std::size_t secToNano = 1e9; if (destApp->desktopFileSource().modified(mtime)) {
if (destApp->desktopFileSource().modified(buf.st_mtim.tv_sec * secToNano + buf.st_mtim.tv_nsec)) {
auto *newEntry = new (std::nothrow) DesktopEntry{}; auto *newEntry = new (std::nothrow) DesktopEntry{};
if (newEntry == nullptr) { if (newEntry == nullptr) {
qCritical() << "new DesktopEntry failed."; qCritical() << "new DesktopEntry failed.";

View File

@ -13,15 +13,16 @@
#include <memory> #include <memory>
#include <QMap> #include <QMap>
#include "dbus/jobmanager1service.h" #include "dbus/jobmanager1service.h"
#include "dbus/APPobjectmanager1adaptor.h" #include "desktopentry.h"
#include "dbus/applicationadaptor.h"
#include "identifier.h" #include "identifier.h"
class ApplicationService;
class ApplicationManager1Service final : public QObject class ApplicationManager1Service final : public QObject
{ {
Q_OBJECT Q_OBJECT
public: public:
explicit ApplicationManager1Service(std::unique_ptr<Identifier> ptr, QDBusConnection &connection); explicit ApplicationManager1Service(std::unique_ptr<Identifier> ptr, QDBusConnection &connection) noexcept;
~ApplicationManager1Service() override; ~ApplicationManager1Service() override;
ApplicationManager1Service(const ApplicationManager1Service &) = delete; ApplicationManager1Service(const ApplicationManager1Service &) = delete;
ApplicationManager1Service(ApplicationManager1Service &&) = delete; ApplicationManager1Service(ApplicationManager1Service &&) = delete;

View File

@ -3,6 +3,7 @@
// SPDX-License-Identifier: LGPL-3.0-or-later // SPDX-License-Identifier: LGPL-3.0-or-later
#include "dbus/applicationservice.h" #include "dbus/applicationservice.h"
#include "APPobjectmanager1adaptor.h"
#include "applicationmanager1service.h" #include "applicationmanager1service.h"
#include "dbus/instanceadaptor.h" #include "dbus/instanceadaptor.h"
#include "pwd.h" #include "pwd.h"
@ -34,28 +35,24 @@ ApplicationService::~ApplicationService()
QSharedPointer<ApplicationService> ApplicationService::createApplicationService(DesktopFile source, QSharedPointer<ApplicationService> ApplicationService::createApplicationService(DesktopFile source,
ApplicationManager1Service *parent) noexcept ApplicationManager1Service *parent) noexcept
{ {
QSharedPointer<ApplicationService> app{new (std::nothrow) ApplicationService{std::move(source), parent}};
if (!app) {
qCritical() << "new application service failed.";
return nullptr;
}
QString objectPath; QString objectPath;
QTextStream sourceStream; QTextStream sourceStream;
QFile sourceFile;
QString tempSource;
QSharedPointer<ApplicationService> app{nullptr};
if (source.persistence()) { auto appId = app->desktopFileSource().desktopId();
objectPath = QString{DDEApplicationManager1ObjectPath} + "/" + escapeToObjectPath(source.desktopId());
sourceFile.setFileName(source.fileSource());
if (!sourceFile.open(QFile::ExistingOnly | QFile::ReadOnly | QFile::Text)) {
qCritical() << "desktop file can't open:" << source.fileSource() << sourceFile.errorString();
return nullptr;
}
app.reset(new (std::nothrow) ApplicationService{std::move(source), parent}); if (!appId.isEmpty()) {
sourceStream.setDevice(&sourceFile); objectPath = QString{DDEApplicationManager1ObjectPath} + "/" + escapeToObjectPath(appId);
} else { } else {
tempSource = source.fileSource();
objectPath = QString{DDEApplicationManager1ObjectPath} + "/" + QUuid::createUuid().toString(QUuid::Id128); objectPath = QString{DDEApplicationManager1ObjectPath} + "/" + QUuid::createUuid().toString(QUuid::Id128);
app.reset(new (std::nothrow) ApplicationService{std::move(source), parent});
sourceStream.setString(&tempSource, QTextStream::ReadOnly | QTextStream::Text);
} }
sourceStream.setDevice(app->desktopFileSource().sourceFile());
std::unique_ptr<DesktopEntry> entry{std::make_unique<DesktopEntry>()}; std::unique_ptr<DesktopEntry> entry{std::make_unique<DesktopEntry>()};
auto error = entry->parse(sourceStream); auto error = entry->parse(sourceStream);
@ -76,7 +73,11 @@ QSharedPointer<ApplicationService> ApplicationService::createApplicationService(
app->m_applicationPath = QDBusObjectPath{std::move(objectPath)}; app->m_applicationPath = QDBusObjectPath{std::move(objectPath)};
// TODO: icon lookup // TODO: icon lookup
new (std::nothrow) APPObjectManagerAdaptor{app.data()}; if (auto *ptr = new (std::nothrow) APPObjectManagerAdaptor{app.data()}; ptr == nullptr) {
qCritical() << "new Object Manager of Application failed.";
return nullptr;
}
return app; return app;
} }
@ -252,10 +253,7 @@ QDBusObjectPath ApplicationService::Launch(const QString &action, const QStringL
auto resourceFile = variantValue.toString(); auto resourceFile = variantValue.toString();
auto instanceRandomUUID = QUuid::createUuid().toString(QUuid::Id128); auto instanceRandomUUID = QUuid::createUuid().toString(QUuid::Id128);
auto objectPath = m_applicationPath.path() + "/" + instanceRandomUUID; auto objectPath = m_applicationPath.path() + "/" + instanceRandomUUID;
commands.push_front(QString{"--SourcePath=%1"}.arg(m_desktopSource.sourcePath()));
if (m_desktopSource.persistence()) {
commands.push_front(QString{"--SourcePath=%1"}.arg(m_desktopSource.fileSource()));
}
if (resourceFile.isEmpty()) { if (resourceFile.isEmpty()) {
commands.push_front(QString{R"(--unitName=app-DDE-%1@%2.service)"}.arg( commands.push_front(QString{R"(--unitName=app-DDE-%1@%2.service)"}.arg(
@ -303,7 +301,7 @@ QDBusObjectPath ApplicationService::Launch(const QString &action, const QStringL
QStringList ApplicationService::actions() const noexcept QStringList ApplicationService::actions() const noexcept
{ {
if (m_entry.isNull()) { if (m_entry.isNull()) {
qWarning() << "desktop entry is empty, isPersistence:" << m_desktopSource.persistence(); qWarning() << "desktop entry is empty, source file:" << m_desktopSource.sourcePath();
return {}; return {};
} }
@ -332,10 +330,7 @@ ObjectMap ApplicationService::GetManagedObjects() const
QString ApplicationService::id() const noexcept QString ApplicationService::id() const noexcept
{ {
if (m_desktopSource.persistence()) { return m_desktopSource.desktopId();
return m_desktopSource.desktopId();
}
return {};
} }
IconMap ApplicationService::icons() const IconMap ApplicationService::icons() const

View File

@ -59,7 +59,7 @@ public:
void removeOneInstance(const QDBusObjectPath &instance) noexcept; void removeOneInstance(const QDBusObjectPath &instance) noexcept;
void removeAllInstance() noexcept; void removeAllInstance() noexcept;
[[nodiscard]] const QDBusObjectPath &applicationPath() const noexcept { return m_applicationPath; } [[nodiscard]] const QDBusObjectPath &applicationPath() const noexcept { return m_applicationPath; }
[[nodiscard]] const DesktopFile &desktopFileSource() const noexcept { return m_desktopSource; } [[nodiscard]] DesktopFile &desktopFileSource() noexcept { return m_desktopSource; }
[[nodiscard]] const QMap<QDBusObjectPath, QSharedPointer<InstanceService>> &applicationInstances() const noexcept [[nodiscard]] const QMap<QDBusObjectPath, QSharedPointer<InstanceService>> &applicationInstances() const noexcept
{ {
return m_Instances; return m_Instances;

View File

@ -24,7 +24,11 @@ auto DesktopEntry::parserGroupHeader(const QString &str) noexcept
return it; return it;
} }
void functest(QMap<QString, QString> p) {} QString DesktopFile::sourcePath() const noexcept
{
QFileInfo info(*m_fileSource);
return info.absoluteFilePath();
}
DesktopErrorCode DesktopEntry::parseEntry(const QString &str, decltype(m_entryMap)::iterator &currentGroup) noexcept DesktopErrorCode DesktopEntry::parseEntry(const QString &str, decltype(m_entryMap)::iterator &currentGroup) noexcept
{ {
@ -90,11 +94,14 @@ DesktopErrorCode DesktopEntry::parseEntry(const QString &str, decltype(m_entryMa
return DesktopErrorCode::NoError; return DesktopErrorCode::NoError;
} }
std::optional<DesktopFile> DesktopFile::createTemporaryDesktopFile(QString content) noexcept std::optional<DesktopFile> DesktopFile::createTemporaryDesktopFile(std::unique_ptr<QFile> temporaryFile) noexcept
{ {
auto now = std::chrono::high_resolution_clock::now().time_since_epoch(); auto mtime = getFileModifiedTime(*temporaryFile);
auto nano = std::chrono::duration_cast<std::chrono::nanoseconds>(now); if (mtime == 0) {
return DesktopFile{false, std::move(content), "", static_cast<size_t>(nano.count())}; qWarning() << "create temporary file failed.";
return std::nullopt;
}
return DesktopFile{std::move(temporaryFile), "", mtime};
} }
std::optional<DesktopFile> DesktopFile::searchDesktopFileByPath(const QString &desktopFile, DesktopErrorCode &err) noexcept std::optional<DesktopFile> DesktopFile::searchDesktopFileByPath(const QString &desktopFile, DesktopErrorCode &err) noexcept
@ -134,17 +141,17 @@ std::optional<DesktopFile> DesktopFile::searchDesktopFileByPath(const QString &d
id = FileId.chopped(1); // remove extra "-"" id = FileId.chopped(1); // remove extra "-""
} }
struct stat buf; auto filePtr = std::make_unique<QFile>(std::move(path));
if (auto ret = stat(path.toLatin1().data(), &buf); ret == -1) {
auto mtime = getFileModifiedTime(*filePtr);
if (mtime == 0) {
err = DesktopErrorCode::OpenFailed; err = DesktopErrorCode::OpenFailed;
qWarning() << "get file" << path << "state failed:" << std::strerror(errno);
return std::nullopt; return std::nullopt;
} }
err = DesktopErrorCode::NoError; err = DesktopErrorCode::NoError;
constexpr std::size_t secToNano = 1e9; return DesktopFile{std::move(filePtr), std::move(id), mtime};
return DesktopFile{true, std::move(path), std::move(id), buf.st_mtim.tv_sec * secToNano + buf.st_mtim.tv_nsec};
} }
std::optional<DesktopFile> DesktopFile::searchDesktopFileById(const QString &appId, DesktopErrorCode &err) noexcept std::optional<DesktopFile> DesktopFile::searchDesktopFileById(const QString &appId, DesktopErrorCode &err) noexcept
@ -178,21 +185,18 @@ bool DesktopFile::modified(std::size_t time) const noexcept
return time != m_mtime; return time != m_mtime;
} }
DesktopErrorCode DesktopEntry::parse(const DesktopFile &file) noexcept DesktopErrorCode DesktopEntry::parse(DesktopFile &file) noexcept
{ {
QTextStream in; DesktopFileGuard guard{file};
if (file.persistence()) {
auto sourceFile = QFile(file.fileSource()); if (!guard.try_open()) {
if (!sourceFile.open(QFile::ExistingOnly | QFile::ReadOnly | QFile::Text)) { qWarning() << file.sourcePath() << "can't open.";
qWarning() << file.fileSource() << "can't open."; return DesktopErrorCode::OpenFailed;
return DesktopErrorCode::OpenFailed;
}
in.setDevice(&sourceFile);
} else {
in.setString(const_cast<QString *>(&file.fileSource()));
} }
return parse(in); QTextStream stream;
stream.setDevice(file.sourceFile());
return parse(stream);
} }
DesktopErrorCode DesktopEntry::parse(QTextStream &stream) noexcept DesktopErrorCode DesktopEntry::parse(QTextStream &stream) noexcept

View File

@ -2,13 +2,16 @@
// //
// SPDX-License-Identifier: LGPL-3.0-or-later // SPDX-License-Identifier: LGPL-3.0-or-later
#ifndef DESKTOPENTRY_H
#define DESKTOPENTRY_H
#include <QString> #include <QString>
#include <QMap> #include <QMap>
#include <QDebug> #include <QDebug>
#include <QLocale> #include <QLocale>
#include <QTextStream> #include <QTextStream>
#include <optional> #include <optional>
#include <sys/stat.h> #include <QFile>
constexpr static auto defaultKeyStr = "default"; constexpr static auto defaultKeyStr = "default";
@ -22,38 +25,68 @@ enum class DesktopErrorCode {
EntryKeyInvalid EntryKeyInvalid
}; };
struct DesktopFileGuard;
struct DesktopFile struct DesktopFile
{ {
DesktopFile(const DesktopFile &) = default; friend struct DesktopFileGuard;
DesktopFile(const DesktopFile &) = delete;
DesktopFile(DesktopFile &&) = default; DesktopFile(DesktopFile &&) = default;
DesktopFile &operator=(const DesktopFile &) = default; DesktopFile &operator=(const DesktopFile &) = delete;
DesktopFile &operator=(DesktopFile &&) = default; DesktopFile &operator=(DesktopFile &&) = default;
~DesktopFile() = default; ~DesktopFile() = default;
[[nodiscard]] const QString &fileSource() const noexcept { return m_fileSource; } [[nodiscard]] QString sourcePath() const noexcept;
// WARNING: This raw pointer's ownership belong to DesktopFile, DO NOT MODIFY!
[[nodiscard]] QFile *sourceFile() const noexcept { return &sourceFileRef(); };
[[nodiscard]] QFile &sourceFileRef() const noexcept { return *m_fileSource; };
[[nodiscard]] const QString &desktopId() const noexcept { return m_desktopId; } [[nodiscard]] const QString &desktopId() const noexcept { return m_desktopId; }
[[nodiscard]] bool persistence() const noexcept { return m_isPersistence; }
[[nodiscard]] bool modified(std::size_t time) const noexcept; [[nodiscard]] bool modified(std::size_t time) const noexcept;
static std::optional<DesktopFile> searchDesktopFileById(const QString &appId, DesktopErrorCode &err) noexcept; static std::optional<DesktopFile> searchDesktopFileById(const QString &appId, DesktopErrorCode &err) noexcept;
static std::optional<DesktopFile> searchDesktopFileByPath(const QString &desktopFilePath, DesktopErrorCode &err) noexcept; static std::optional<DesktopFile> searchDesktopFileByPath(const QString &desktopFilePath, DesktopErrorCode &err) noexcept;
static std::optional<DesktopFile> createTemporaryDesktopFile(QString content) noexcept; static std::optional<DesktopFile> createTemporaryDesktopFile(std::unique_ptr<QFile> temporaryFile) noexcept;
private: private:
DesktopFile(bool persistence, QString &&source, QString &&fileId, std::size_t mtime) DesktopFile(std::unique_ptr<QFile> source, QString fileId, std::size_t mtime)
: m_isPersistence(persistence) : m_mtime(mtime)
, m_mtime(mtime)
, m_fileSource(std::move(source)) , m_fileSource(std::move(source))
, m_desktopId(std::move(fileId)) , m_desktopId(std::move(fileId))
{ {
} }
bool m_isPersistence;
std::size_t m_mtime; std::size_t m_mtime;
QString m_fileSource{""}; std::unique_ptr<QFile> m_fileSource{nullptr};
QString m_desktopId{""}; QString m_desktopId{""};
}; };
struct DesktopFileGuard
{
DesktopFileGuard(const DesktopFileGuard &) = delete;
DesktopFileGuard(DesktopFileGuard &&other) noexcept
: fileRef(other.fileRef)
{
}
DesktopFileGuard &operator=(const DesktopFileGuard &) = delete;
DesktopFileGuard &operator=(DesktopFileGuard &&) = delete;
explicit DesktopFileGuard(DesktopFile &file)
: fileRef(file)
{
}
bool try_open() { return fileRef.m_fileSource->open(QFile::ExistingOnly | QFile::ReadOnly | QFile::Text); }
~DesktopFileGuard()
{
if (fileRef.m_fileSource->isOpen()) {
fileRef.m_fileSource->close();
}
}
private:
DesktopFile &fileRef;
};
class DesktopEntry class DesktopEntry
{ {
public: public:
@ -86,7 +119,7 @@ public:
DesktopEntry &operator=(DesktopEntry &&) = default; DesktopEntry &operator=(DesktopEntry &&) = default;
~DesktopEntry() = default; ~DesktopEntry() = default;
[[nodiscard]] DesktopErrorCode parse(const DesktopFile &file) noexcept; [[nodiscard]] DesktopErrorCode parse(DesktopFile &file) noexcept;
[[nodiscard]] DesktopErrorCode parse(QTextStream &stream) noexcept; [[nodiscard]] DesktopErrorCode parse(QTextStream &stream) noexcept;
[[nodiscard]] std::optional<QMap<QString, Value>> group(const QString &key) const noexcept; [[nodiscard]] std::optional<QMap<QString, Value>> group(const QString &key) const noexcept;
[[nodiscard]] std::optional<Value> value(const QString &key, const QString &valueKey) const noexcept; [[nodiscard]] std::optional<Value> value(const QString &key, const QString &valueKey) const noexcept;
@ -100,3 +133,5 @@ private:
QDebug operator<<(QDebug debug, const DesktopEntry::Value &v); QDebug operator<<(QDebug debug, const DesktopEntry::Value &v);
QDebug operator<<(QDebug debug, const DesktopErrorCode &v); QDebug operator<<(QDebug debug, const DesktopErrorCode &v);
#endif

View File

@ -19,6 +19,7 @@
#include <QDBusObjectPath> #include <QDBusObjectPath>
#include <unistd.h> #include <unistd.h>
#include <QUuid> #include <QUuid>
#include <sys/stat.h>
#include "constant.h" #include "constant.h"
#include "config.h" #include "config.h"
@ -103,7 +104,7 @@ public:
} }
if (!m_initFlag) { if (!m_initFlag) {
qFatal() << "invoke init at first."; qFatal("invoke init at first.");
} }
switch (m_serverType) { switch (m_serverType) {
@ -113,17 +114,17 @@ public:
m_serverConnection.emplace(QDBusConnection::connectToBus(static_cast<QDBusConnection::BusType>(m_serverType), m_serverConnection.emplace(QDBusConnection::connectToBus(static_cast<QDBusConnection::BusType>(m_serverType),
ApplicationManagerServerDBusName)); ApplicationManagerServerDBusName));
if (!m_serverConnection->isConnected()) { if (!m_serverConnection->isConnected()) {
qFatal() << m_serverConnection->lastError(); qFatal("%s", m_serverConnection->lastError().message().toLocal8Bit().data());
} }
return m_serverConnection.value(); return m_serverConnection.value();
} }
case DBusType::Custom: { case DBusType::Custom: {
if (m_serverBusAddress.isEmpty()) { if (m_serverBusAddress.isEmpty()) {
qFatal() << "connect to custom dbus must init this object by custom dbus address"; qFatal("connect to custom dbus must init this object by custom dbus address");
} }
m_serverConnection.emplace(QDBusConnection::connectToBus(m_serverBusAddress, ApplicationManagerServerDBusName)); m_serverConnection.emplace(QDBusConnection::connectToBus(m_serverBusAddress, ApplicationManagerServerDBusName));
if (!m_serverConnection->isConnected()) { if (!m_serverConnection->isConnected()) {
qFatal() << m_serverConnection->lastError(); qFatal("%s", m_serverConnection->lastError().message().toLocal8Bit().data());
} }
return m_serverConnection.value(); return m_serverConnection.value();
} }
@ -140,7 +141,7 @@ public:
QDBusConnection &globalDestBus() QDBusConnection &globalDestBus()
{ {
if (!m_destConnection) { if (!m_destConnection) {
qFatal() << "please set which bus should application manager to use to invoke other D-Bus service's method."; qFatal("please set which bus should application manager to use to invoke other D-Bus service's method.");
} }
return m_destConnection.value(); return m_destConnection.value();
} }
@ -157,18 +158,18 @@ public:
m_destConnection.emplace( m_destConnection.emplace(
QDBusConnection::connectToBus(QDBusConnection::BusType::SessionBus, ApplicationManagerDestDBusName)); QDBusConnection::connectToBus(QDBusConnection::BusType::SessionBus, ApplicationManagerDestDBusName));
if (!m_destConnection->isConnected()) { if (!m_destConnection->isConnected()) {
qFatal() << m_destConnection->lastError(); qFatal("%s", m_destConnection->lastError().message().toLocal8Bit().data());
} }
return; return;
} }
if (m_destBusAddress.isEmpty()) { if (m_destBusAddress.isEmpty()) {
qFatal() << "connect to custom dbus must init this object by custom dbus address"; qFatal("connect to custom dbus must init this object by custom dbus address");
} }
m_destConnection.emplace(QDBusConnection::connectToBus(m_destBusAddress, ApplicationManagerDestDBusName)); m_destConnection.emplace(QDBusConnection::connectToBus(m_destBusAddress, ApplicationManagerDestDBusName));
if (!m_destConnection->isConnected()) { if (!m_destConnection->isConnected()) {
qFatal() << m_destConnection->lastError(); qFatal("%s", m_destConnection->lastError().message().toLocal8Bit().data());
} }
} }
@ -374,4 +375,25 @@ ObjectMap dumpDBusObject(const QMap<QDBusObjectPath, QSharedPointer<T>> &map)
return objs; return objs;
} }
inline std::size_t getFileModifiedTime(QFile &file)
{
struct stat buf;
QFileInfo info{file};
if (!file.isOpen()) {
if (auto ret = file.open(QFile::ExistingOnly | QFile::ReadOnly | QFile::Text); !ret) {
qWarning() << "open file" << info.absoluteFilePath() << "failed.";
return 0;
}
}
if (auto ret = stat(info.absoluteFilePath().toLocal8Bit().data(), &buf); ret == -1) {
qWarning() << "get file" << info.absoluteFilePath() << "state failed:" << std::strerror(errno);
return 0;
}
constexpr std::size_t secToNano = 1e9;
return buf.st_mtim.tv_sec * secToNano + buf.st_mtim.tv_nsec;
}
#endif #endif

View File

@ -32,8 +32,8 @@ public:
bus.setDestBus(); bus.setDestBus();
m_am = new ApplicationManager1Service{std::make_unique<CGroupsIdentifier>(), bus.globalServerBus()}; m_am = new ApplicationManager1Service{std::make_unique<CGroupsIdentifier>(), bus.globalServerBus()};
auto ptr = std::make_unique<QFile>(QString{"/usr/share/applications/test-Application.desktop"});
DesktopFile file{true, "/usr/share/applications/test-Application.desktop", "test-Application", 0}; DesktopFile file{std::move(ptr), "test-Application", 0};
QSharedPointer<ApplicationService> app = QSharedPointer<ApplicationService>::create(std::move(file), nullptr); QSharedPointer<ApplicationService> app = QSharedPointer<ApplicationService>::create(std::move(file), nullptr);
QSharedPointer<InstanceService> instance = QSharedPointer<InstanceService> instance =
QSharedPointer<InstanceService>::create(InstancePath.path().split('/').last(), ApplicationPath.path(), QString{"/"}); QSharedPointer<InstanceService>::create(InstancePath.path().split('/').last(), ApplicationPath.path(), QString{"/"});

View File

@ -45,7 +45,7 @@ TEST_F(TestDesktopEntry, desktopFile)
auto curDir = QDir::current(); auto curDir = QDir::current();
QString path{curDir.absolutePath() + QDir::separator() + "data" + QDir::separator() + "applications" + QDir::separator() + QString path{curDir.absolutePath() + QDir::separator() + "data" + QDir::separator() + "applications" + QDir::separator() +
"deepin-editor.desktop"}; "deepin-editor.desktop"};
EXPECT_EQ(exampleFile->fileSource().toStdString(), path.toStdString()); EXPECT_EQ(exampleFile->sourcePath(), path);
EXPECT_EQ(exampleFile->desktopId().toStdString(), "deepin-editor"); EXPECT_EQ(exampleFile->desktopId().toStdString(), "deepin-editor");
} }
@ -54,7 +54,7 @@ TEST_F(TestDesktopEntry, prase)
const auto &exampleFile = file(); const auto &exampleFile = file();
ASSERT_FALSE(exampleFile.isNull()); ASSERT_FALSE(exampleFile.isNull());
DesktopEntry entry; DesktopEntry entry;
QFile in{exampleFile->fileSource()}; QFile in{exampleFile->sourcePath()};
ASSERT_TRUE(in.open(QFile::ExistingOnly | QFile::ReadOnly | QFile::Text)); ASSERT_TRUE(in.open(QFile::ExistingOnly | QFile::ReadOnly | QFile::Text));
QTextStream fs{&in}; QTextStream fs{&in};
auto err = entry.parse(fs); auto err = entry.parse(fs);