diff --git a/api/dbus/org.desktopspec.ApplicationManager1.xml b/api/dbus/org.desktopspec.ApplicationManager1.xml
index a2d757d..2e31463 100644
--- a/api/dbus/org.desktopspec.ApplicationManager1.xml
+++ b/api/dbus/org.desktopspec.ApplicationManager1.xml
@@ -15,8 +15,9 @@
-
-
+
+
+
resize(0)) {
qCritical() << "failed to clear file:" << m_file->errorString();
- return;
+ return false;
}
auto content = QJsonDocument{m_data}.toJson(QJsonDocument::Compact);
@@ -77,28 +77,32 @@ void ApplicationManager1Storage::writeToFile() const noexcept
}
if (!m_file->flush()) {
- qCritical() << "io error.";
+ qCritical() << "io error, write failed.";
+ return false;
}
+
+ return true;
}
-void ApplicationManager1Storage::setVersion(uint8_t version) noexcept
+bool ApplicationManager1Storage::setVersion(uint8_t version) noexcept
{
m_data["version"] = version;
- writeToFile();
+ return writeToFile();
}
uint8_t ApplicationManager1Storage::version() const noexcept
{
- return m_data["version"].toInt(0);
+ return m_data["version"].toInt(-1);
}
-void ApplicationManager1Storage::createApplicationValue(const QString &appId,
+bool 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;
+ qWarning() << "unexpected empty string";
+ return false;
}
QJsonObject appObj;
@@ -112,94 +116,137 @@ void ApplicationManager1Storage::createApplicationValue(const QString &appId,
}
if (groupObj.contains(valueKey)) {
- return;
+ qInfo() << "value" << valueKey << value << "is already exists.";
+ return true;
}
groupObj.insert(valueKey, value.toJsonValue());
appObj.insert(groupName, groupObj);
m_data.insert(appId, appObj);
- writeToFile();
+ return writeToFile();
}
-void ApplicationManager1Storage::updateApplicationValue(const QString &appId,
+bool 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;
+ qWarning() << "unexpected empty string";
+ return false;
}
if (!m_data.contains(appId)) {
- return;
+ qInfo() << "app" << appId << "doesn't exists.";
+ return false;
}
auto appObj = m_data[appId].toObject();
if (!appObj.contains(groupName)) {
- return;
+ qInfo() << "group" << groupName << "doesn't exists.";
+ return false;
}
auto groupObj = appObj[groupName].toObject();
if (!groupObj.contains(valueKey)) {
- return;
+ qInfo() << "value" << valueKey << "doesn't exists.";
+ return false;
}
groupObj.insert(valueKey, value.toJsonValue());
appObj.insert(groupName, groupObj);
m_data.insert(appId, appObj);
- writeToFile();
+ return writeToFile();
}
QVariant ApplicationManager1Storage::readApplicationValue(const QString &appId,
const QString &groupName,
const QString &valueKey) const noexcept
{
- return m_data[appId][groupName][valueKey].toVariant();
+ auto app = m_data.constFind(appId)->toObject();
+ if (app.isEmpty()) {
+ return {};
+ }
+
+ auto group = app.constFind(groupName)->toObject();
+ if (group.isEmpty()) {
+ return {};
+ }
+
+ auto val = group.constFind(valueKey);
+ if (val->isNull()) {
+ return {};
+ }
+
+ return val->toVariant();
}
-void ApplicationManager1Storage::deleteApplicationValue(const QString &appId,
+bool ApplicationManager1Storage::deleteApplicationValue(const QString &appId,
const QString &groupName,
const QString &valueKey) noexcept
{
- if (appId.isEmpty()) {
- auto empty = QJsonObject{};
- m_data.swap(empty);
- return;
+ if (appId.isEmpty() or groupName.isEmpty() or valueKey.isEmpty()) {
+ qWarning() << "unexpected empty string";
+ return false;
}
auto app = m_data.find(appId).value();
if (app.isNull()) {
- return;
+ return true;
}
auto appObj = app.toObject();
- if (groupName.isEmpty()) {
- m_data.remove(appId);
- return;
- }
-
auto group = appObj.find(groupName).value();
if (group.isNull()) {
- return;
+ return true;
}
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;
+ return true;
}
groupObj.remove(valueKey);
appObj.insert(groupName, groupObj);
m_data.insert(appId, appObj);
- writeToFile();
+ return writeToFile();
+}
+
+bool ApplicationManager1Storage::clearData() noexcept
+{
+ QJsonObject obj;
+ m_data.swap(obj);
+ return setVersion(STORAGE_VERSION);
+}
+
+bool ApplicationManager1Storage::deleteApplication(const QString &appId) noexcept
+{
+ if (appId.isEmpty()) {
+ qWarning() << "unexpected empty string.";
+ return false;
+ }
+
+ m_data.remove(appId);
+ return writeToFile();
+}
+
+bool ApplicationManager1Storage::deleteGroup(const QString &appId, const QString &groupName) noexcept
+{
+ if (appId.isEmpty() or groupName.isEmpty()) {
+ qWarning() << "unexpected empty string.";
+ return false;
+ }
+
+ auto app = m_data.find(appId).value().toObject();
+ if (app.isEmpty()) {
+ return true;
+ }
+
+ app.remove(groupName);
+ m_data.insert(appId, app);
+ return writeToFile();
}
diff --git a/src/applicationmanagerstorage.h b/src/applicationmanagerstorage.h
index 9f6b188..702c183 100644
--- a/src/applicationmanagerstorage.h
+++ b/src/applicationmanagerstorage.h
@@ -20,25 +20,28 @@ public:
ApplicationManager1Storage &operator=(ApplicationManager1Storage &&) = default;
~ApplicationManager1Storage() = default;
- void createApplicationValue(const QString &appId,
+ bool createApplicationValue(const QString &appId,
const QString &groupName,
const QString &valueKey,
const QVariant &value) noexcept;
- void updateApplicationValue(const QString &appId,
+ bool 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;
+ bool deleteApplicationValue(const QString &appId, const QString &groupName, const QString &valueKey) noexcept;
+ bool clearData() noexcept;
+ bool deleteApplication(const QString &appId) noexcept;
+ bool deleteGroup(const QString &appId, const QString &groupName) noexcept;
- void setVersion(uint8_t version) noexcept;
+ bool setVersion(uint8_t version) noexcept;
[[nodiscard]] uint8_t version() const noexcept;
static std::shared_ptr createApplicationManager1Storage(const QString &storageDir) noexcept;
private:
- void writeToFile() const noexcept;
+ [[nodiscard]] bool writeToFile() const noexcept;
explicit ApplicationManager1Storage(const QString &storagePath);
std::unique_ptr m_file;
QJsonObject m_data;
diff --git a/src/constant.h b/src/constant.h
index 5e52656..9c70113 100644
--- a/src/constant.h
+++ b/src/constant.h
@@ -47,7 +47,7 @@ constexpr auto systemdOption = u8"systemd";
constexpr auto splitOption = u8"split";
constexpr auto AppExecOption = u8"appExec";
-constexpr auto STORAGE_VERSION = 1;
+constexpr auto STORAGE_VERSION = 0;
constexpr auto ApplicationPropertiesGroup = u8"Application Properties";
constexpr auto LastLaunchedTime = u8"LastLaunchedTime";
diff --git a/src/dbus/applicationmanager1service.cpp b/src/dbus/applicationmanager1service.cpp
index ede24c5..d9a00cc 100644
--- a/src/dbus/applicationmanager1service.cpp
+++ b/src/dbus/applicationmanager1service.cpp
@@ -124,16 +124,7 @@ 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));
- }
- }
+ (*appIt)->updateAfterLaunch(sender() != nullptr); // activate by signal
const auto &applicationPath = (*appIt)->applicationPath().path();
@@ -278,17 +269,6 @@ bool ApplicationManager1Service::addApplication(DesktopFile desktopFileSource) n
}
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(0));
- } else {
- ptr->m_lastLaunch = value.toInt();
- }
- }
-
emit listChanged();
emit InterfacesAdded(application->applicationPath(), getChildInterfacesAndPropertiesFromObject(ptr));
@@ -300,7 +280,7 @@ 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());
+ ptr->deleteApplication((*it)->id());
}
unregisterObjectFromDBus(application.path());
m_applicationList.remove(application);
@@ -317,7 +297,8 @@ void ApplicationManager1Service::removeAllApplication() noexcept
}
QString ApplicationManager1Service::Identify(const QDBusUnixFileDescriptor &pidfd,
- ObjectMap &application_instance_info) const noexcept
+ QDBusObjectPath &instance,
+ ObjectInterfaceMap &application_instance_info) const noexcept
{
if (!pidfd.isValid()) {
qWarning() << "pidfd isn't a valid unix file descriptor";
@@ -369,17 +350,16 @@ QString ApplicationManager1Service::Identify(const QDBusUnixFileDescriptor &pidf
return {};
}
- auto instance = (*app)->findInstance(ret.InstanceId);
+ auto instancePath = (*app)->findInstance(ret.InstanceId);
- if (auto path = instance.path(); path.isEmpty()) {
+ if (auto path = instancePath.path(); path.isEmpty()) {
qWarning() << "can't find instance:" << path;
return {};
}
+ instance = instancePath;
auto instanceObj = (*app)->m_Instances.constFind(instance);
- auto map = getChildInterfacesAndPropertiesFromObject(instanceObj->get());
-
- application_instance_info.insert(instance, map);
+ application_instance_info = getChildInterfacesAndPropertiesFromObject(instanceObj->get());
return ret.ApplicationId;
}
@@ -407,6 +387,7 @@ void ApplicationManager1Service::updateApplication(const QSharedPointerm_entry != newEntry) {
destApp->resetEntry(newEntry);
destApp->m_desktopSource = std::move(desktopFile);
+ destApp->detachAllInstance();
}
}
diff --git a/src/dbus/applicationmanager1service.h b/src/dbus/applicationmanager1service.h
index 4ef8823..8021943 100644
--- a/src/dbus/applicationmanager1service.h
+++ b/src/dbus/applicationmanager1service.h
@@ -44,7 +44,9 @@ public:
JobManager1Service &jobManager() noexcept { return *m_jobManager; }
public Q_SLOTS:
- QString Identify(const QDBusUnixFileDescriptor &pidfd, ObjectMap &application_instance_info) const noexcept;
+ QString Identify(const QDBusUnixFileDescriptor &pidfd,
+ QDBusObjectPath &instance,
+ ObjectInterfaceMap &application_instance_info) const noexcept;
void ReloadApplications();
[[nodiscard]] ObjectMap GetManagedObjects() const;
diff --git a/src/dbus/applicationservice.cpp b/src/dbus/applicationservice.cpp
index bad298d..9a004c8 100644
--- a/src/dbus/applicationservice.cpp
+++ b/src/dbus/applicationservice.cpp
@@ -29,14 +29,28 @@ ApplicationService::ApplicationService(DesktopFile source,
, m_storage(std::move(storage))
, m_desktopSource(std::move(source))
{
+ auto storagePtr = m_storage.lock();
+ if (!storagePtr) {
+ m_lastLaunch = -1;
+ return;
+ }
+
+ auto appId = id();
+ auto value = storagePtr->readApplicationValue(appId, ApplicationPropertiesGroup, LastLaunchedTime);
+ if (value.isNull()) {
+ if (!storagePtr->createApplicationValue(
+ appId, ApplicationPropertiesGroup, LastLaunchedTime, QVariant::fromValue(0))) {
+ m_lastLaunch = -1;
+ }
+ return;
+ }
+
+ m_lastLaunch = value.toInt();
}
ApplicationService::~ApplicationService()
{
- for (auto &instance : m_Instances.values()) {
- orphanedInstances->append(instance);
- instance->m_orphaned = true;
- }
+ detachAllInstance();
}
QSharedPointer ApplicationService::createApplicationService(
@@ -93,12 +107,6 @@ QSharedPointer ApplicationService::createApplicationService(
return nullptr;
}
- auto ptr = app->m_storage.lock();
- if (!ptr) {
- qWarning() << "runtime storage doesn't exists.";
- return app;
- }
-
return app;
}
@@ -501,6 +509,16 @@ void ApplicationService::removeAllInstance() noexcept
}
}
+void ApplicationService::detachAllInstance() noexcept
+{
+ for (auto &instance : m_Instances.values()) {
+ orphanedInstances->append(instance);
+ instance->m_orphaned = true;
+ }
+
+ m_Instances.clear();
+}
+
QDBusObjectPath ApplicationService::findInstance(const QString &instanceId) const
{
for (auto it = m_Instances.constKeyValueBegin(); it != m_Instances.constKeyValueEnd(); ++it) {
@@ -715,6 +733,20 @@ QVariant ApplicationService::findEntryValue(const QString &group,
return ret;
}
+void ApplicationService::updateAfterLaunch(bool isLaunch) noexcept
+{
+ if (!isLaunch) {
+ return;
+ }
+
+ auto timestamp = QDateTime::currentMSecsSinceEpoch();
+
+ if (auto ptr = m_storage.lock(); ptr) {
+ ptr->updateApplicationValue(
+ m_desktopSource.desktopId(), ApplicationPropertiesGroup, ::LastLaunchedTime, QVariant::fromValue(timestamp));
+ }
+}
+
QString getDeepinWineScaleFactor(const QString &appId) noexcept
{
qCritical() << "Don't using env to control the window scale factor, this function"
diff --git a/src/dbus/applicationservice.h b/src/dbus/applicationservice.h
index 98239ac..d5a8acc 100644
--- a/src/dbus/applicationservice.h
+++ b/src/dbus/applicationservice.h
@@ -100,6 +100,7 @@ public:
return m_Instances;
}
void resetEntry(DesktopEntry *newEntry) noexcept;
+ void detachAllInstance() noexcept;
public Q_SLOTS:
QDBusObjectPath Launch(const QString &action, const QStringList &fields, const QVariantMap &options);
@@ -131,6 +132,7 @@ private:
const QString &valueKey,
EntryValueType type,
const QLocale &locale = getUserLocale()) const noexcept;
+ void updateAfterLaunch(bool isLaunch) noexcept;
static bool shouldBeShown(const std::unique_ptr &entry) noexcept;
static bool autostartCheck(const QString &linkPath) noexcept;
};
diff --git a/tests/ut_applicationmanager.cpp b/tests/ut_applicationmanager.cpp
index 1437cac..3dfacb6 100644
--- a/tests/ut_applicationmanager.cpp
+++ b/tests/ut_applicationmanager.cpp
@@ -97,12 +97,12 @@ TEST_F(TestApplicationManager, identifyService)
auto pidfd = pidfd_open(fakePid, 0);
ASSERT_TRUE(pidfd > 0) << std::strerror(errno);
- ObjectMap instanceInfo;
- auto appId = m_am->Identify(QDBusUnixFileDescriptor{pidfd}, instanceInfo);
+ ObjectInterfaceMap instanceInfo;
+ QDBusObjectPath path;
+ auto appId = m_am->Identify(QDBusUnixFileDescriptor{pidfd}, path, instanceInfo);
EXPECT_EQ(appId.toStdString(), QString{"test-Application"}.toStdString());
- auto instance = instanceInfo.constFind(InstancePath);
- if (instance == instanceInfo.cend()) {
+ if (path.path().isEmpty()) {
GTEST_SKIP_("couldn't find instance and skip.");
}
@@ -111,7 +111,7 @@ TEST_F(TestApplicationManager, identifyService)
{QString{"SystemdUnitPath"}, QDBusObjectPath{"/"}},
{QString{"Launcher"}, QString{"DDE"}},
{QString{"Orphaned"}, false}}}};
- EXPECT_EQ(instance.value(), map);
+ EXPECT_EQ(instanceInfo, map);
close(pidfd);
@@ -148,16 +148,16 @@ TEST_F(TestApplicationManager, identifyService)
ASSERT_TRUE(pidfd > 0) << std::strerror(errno);
instanceInfo.clear();
+ path.setPath("/");
- appId = m_am->Identify(QDBusUnixFileDescriptor{pidfd}, instanceInfo);
+ appId = m_am->Identify(QDBusUnixFileDescriptor{pidfd}, path, instanceInfo);
EXPECT_EQ(appId.toStdString(), QString{"test-Application"}.toStdString());
- instance = instanceInfo.constFind(InstancePath);
- if (instance == instanceInfo.cend()) {
+ if (path.path().isEmpty()) {
GTEST_SKIP_("couldn't find instance and skip.");
}
- EXPECT_EQ(instance.value(), map);
+ EXPECT_EQ(instanceInfo, map);
close(pidfd);