feat: add property LaunchedTimes

refactor implementation of LastLaunchedTime

Signed-off-by: ComixHe <heyuming@deepin.org>
This commit is contained in:
ComixHe 2024-03-06 12:11:49 +08:00 committed by Comix
parent 34c995d992
commit 08350e3c80
7 changed files with 153 additions and 65 deletions

View File

@ -10,11 +10,12 @@
<property name="X_linglong" type="b" access="read" /> <property name="X_linglong" type="b" access="read" />
<property name="X_Flatpak" type="b" access="read" /> <property name="X_Flatpak" type="b" access="read" />
<property name="X_Deepin_Vendor" type="s" access="read"> <property name="X_Deepin_Vendor" type="s" access="read">
<annotation name="org.freedesktop.DBus.Description" value="Whem this property is 'deepin', display name of the application <annotation name="org.freedesktop.DBus.Description"
value="Whem this property is 'deepin', display name of the application
should use GenericName." should use GenericName."
/> />
</property> </property>
<property name="installedTime" type="t" access="read"/>
<property name="NoDisplay" type="b" access="read" /> <property name="NoDisplay" type="b" access="read" />
<property name="MimeTypes" type="as" access="readwrite" /> <property name="MimeTypes" type="as" access="readwrite" />
@ -28,7 +29,29 @@
</property> </property>
<property name="AutoStart" type="b" access="readwrite" /> <property name="AutoStart" type="b" access="readwrite" />
<property name="LastLaunchedTime" type="t" access="read"/> <property name="LastLaunchedTime" type="x" access="read">
<annotation
name="org.freedesktop.DBus.Description"
value="Set the value of this property to -1 to
indicates that some errors has occured."
/>
</property>
<property name="LaunchedTimes" type="x" access="read">
<annotation
name="org.freedesktop.DBus.Description"
value="Set the value of this property to -1 to
indicates that some errors has occured."
/>
</property>
<property name="InstalledTime" type="x" access="read">
<annotation
name="org.freedesktop.DBus.Description"
value="Set the value of this property to -1 to
indicates that some errors has occured."
/>
</property>
<property name="Instances" type="ao" access="read"> <property name="Instances" type="ao" access="read">
<annotation <annotation

View File

@ -110,10 +110,8 @@ bool ApplicationManager1Storage::setFirstLaunch(bool first) noexcept
return m_data["FirstLaunch"].toBool(true); return m_data["FirstLaunch"].toBool(true);
} }
bool ApplicationManager1Storage::createApplicationValue(const QString &appId, bool ApplicationManager1Storage::createApplicationValue(
const QString &groupName, const QString &appId, const QString &groupName, const QString &valueKey, const QVariant &value, bool deferCommit) noexcept
const QString &valueKey,
const QVariant &value) noexcept
{ {
if (appId.isEmpty() or groupName.isEmpty() or valueKey.isEmpty()) { if (appId.isEmpty() or groupName.isEmpty() or valueKey.isEmpty()) {
qWarning() << "unexpected empty string"; qWarning() << "unexpected empty string";
@ -139,13 +137,11 @@ bool ApplicationManager1Storage::createApplicationValue(const QString &appId,
appObj.insert(groupName, groupObj); appObj.insert(groupName, groupObj);
m_data.insert(appId, appObj); m_data.insert(appId, appObj);
return writeToFile(); return deferCommit ? true : writeToFile();
} }
bool ApplicationManager1Storage::updateApplicationValue(const QString &appId, bool ApplicationManager1Storage::updateApplicationValue(
const QString &groupName, const QString &appId, const QString &groupName, const QString &valueKey, const QVariant &value, bool deferCommit) noexcept
const QString &valueKey,
const QVariant &value) noexcept
{ {
if (appId.isEmpty() or groupName.isEmpty() or valueKey.isEmpty()) { if (appId.isEmpty() or groupName.isEmpty() or valueKey.isEmpty()) {
qWarning() << "unexpected empty string"; qWarning() << "unexpected empty string";
@ -173,7 +169,7 @@ bool ApplicationManager1Storage::updateApplicationValue(const QString &appId,
appObj.insert(groupName, groupObj); appObj.insert(groupName, groupObj);
m_data.insert(appId, appObj); m_data.insert(appId, appObj);
return writeToFile(); return deferCommit ? true : writeToFile();
} }
QVariant ApplicationManager1Storage::readApplicationValue(const QString &appId, QVariant ApplicationManager1Storage::readApplicationValue(const QString &appId,
@ -209,7 +205,8 @@ QVariant ApplicationManager1Storage::readApplicationValue(const QString &appId,
bool ApplicationManager1Storage::deleteApplicationValue(const QString &appId, bool ApplicationManager1Storage::deleteApplicationValue(const QString &appId,
const QString &groupName, const QString &groupName,
const QString &valueKey) noexcept const QString &valueKey,
bool deferCommit) noexcept
{ {
if (appId.isEmpty() or groupName.isEmpty() or valueKey.isEmpty()) { if (appId.isEmpty() or groupName.isEmpty() or valueKey.isEmpty()) {
qWarning() << "unexpected empty string"; qWarning() << "unexpected empty string";
@ -237,7 +234,7 @@ bool ApplicationManager1Storage::deleteApplicationValue(const QString &appId,
appObj.insert(groupName, groupObj); appObj.insert(groupName, groupObj);
m_data.insert(appId, appObj); m_data.insert(appId, appObj);
return writeToFile(); return deferCommit ? true : writeToFile();
} }
bool ApplicationManager1Storage::clearData() noexcept bool ApplicationManager1Storage::clearData() noexcept
@ -247,7 +244,7 @@ bool ApplicationManager1Storage::clearData() noexcept
return setVersion(STORAGE_VERSION); return setVersion(STORAGE_VERSION);
} }
bool ApplicationManager1Storage::deleteApplication(const QString &appId) noexcept bool ApplicationManager1Storage::deleteApplication(const QString &appId, bool deferCommit) noexcept
{ {
if (appId.isEmpty()) { if (appId.isEmpty()) {
qWarning() << "unexpected empty string."; qWarning() << "unexpected empty string.";
@ -255,10 +252,10 @@ bool ApplicationManager1Storage::deleteApplication(const QString &appId) noexcep
} }
m_data.remove(appId); m_data.remove(appId);
return writeToFile(); return deferCommit ? true : writeToFile();
} }
bool ApplicationManager1Storage::deleteGroup(const QString &appId, const QString &groupName) noexcept bool ApplicationManager1Storage::deleteGroup(const QString &appId, const QString &groupName, bool deferCommit) noexcept
{ {
if (appId.isEmpty() or groupName.isEmpty()) { if (appId.isEmpty() or groupName.isEmpty()) {
qWarning() << "unexpected empty string."; qWarning() << "unexpected empty string.";
@ -272,5 +269,5 @@ bool ApplicationManager1Storage::deleteGroup(const QString &appId, const QString
app.remove(groupName); app.remove(groupName);
m_data.insert(appId, app); m_data.insert(appId, app);
return writeToFile(); return deferCommit ? true : writeToFile();
} }

View File

@ -20,20 +20,25 @@ public:
ApplicationManager1Storage &operator=(ApplicationManager1Storage &&) = default; ApplicationManager1Storage &operator=(ApplicationManager1Storage &&) = default;
~ApplicationManager1Storage() = default; ~ApplicationManager1Storage() = default;
bool createApplicationValue(const QString &appId, [[nodiscard]] bool createApplicationValue(const QString &appId,
const QString &groupName, const QString &groupName,
const QString &valueKey, const QString &valueKey,
const QVariant &value) noexcept; const QVariant &value,
bool updateApplicationValue(const QString &appId, bool deferCommit = false) noexcept;
[[nodiscard]] bool updateApplicationValue(const QString &appId,
const QString &groupName, const QString &groupName,
const QString &valueKey, const QString &valueKey,
const QVariant &value) noexcept; const QVariant &value,
bool deferCommit = false) noexcept;
[[nodiscard]] QVariant [[nodiscard]] QVariant
readApplicationValue(const QString &appId, const QString &groupName, const QString &valueKey) const noexcept; readApplicationValue(const QString &appId, const QString &groupName, const QString &valueKey) const noexcept;
bool deleteApplicationValue(const QString &appId, const QString &groupName, const QString &valueKey) noexcept; [[nodiscard]] bool deleteApplicationValue(const QString &appId,
bool clearData() noexcept; const QString &groupName,
bool deleteApplication(const QString &appId) noexcept; const QString &valueKey,
bool deleteGroup(const QString &appId, const QString &groupName) noexcept; bool deferCommit = false) noexcept;
[[nodiscard]] bool clearData() noexcept;
[[nodiscard]] bool deleteApplication(const QString &appId, bool deferCommit = false) noexcept;
[[nodiscard]] bool deleteGroup(const QString &appId, const QString &groupName, bool deferCommit = false) noexcept;
bool setVersion(uint8_t version) noexcept; bool setVersion(uint8_t version) noexcept;
[[nodiscard]] uint8_t version() const noexcept; [[nodiscard]] uint8_t version() const noexcept;
@ -41,7 +46,8 @@ public:
bool setFirstLaunch(bool first) noexcept; bool setFirstLaunch(bool first) noexcept;
[[nodiscard]] bool firstLaunch() const noexcept; [[nodiscard]] bool firstLaunch() const noexcept;
static std::shared_ptr<ApplicationManager1Storage> createApplicationManager1Storage(const QString &storageDir) noexcept; [[nodiscard]] static std::shared_ptr<ApplicationManager1Storage>
createApplicationManager1Storage(const QString &storageDir) noexcept;
private: private:
[[nodiscard]] bool writeToFile() const noexcept; [[nodiscard]] bool writeToFile() const noexcept;

View File

@ -58,6 +58,8 @@ constexpr auto STORAGE_VERSION = 0;
constexpr auto ApplicationPropertiesGroup = u8"Application Properties"; constexpr auto ApplicationPropertiesGroup = u8"Application Properties";
constexpr auto LastLaunchedTime = u8"LastLaunchedTime"; constexpr auto LastLaunchedTime = u8"LastLaunchedTime";
constexpr auto ScaleFactor = u8"ScaleFactor"; constexpr auto ScaleFactor = u8"ScaleFactor";
constexpr auto LaunchedTimes = u8"LaunchedTimes";
constexpr auto InstalledTime = u8"InstalledTime";
constexpr auto ApplicationManagerHookDir = u8"/deepin/dde-application-manager/hooks.d"; constexpr auto ApplicationManagerHookDir = u8"/deepin/dde-application-manager/hooks.d";

View File

@ -117,7 +117,9 @@ void ApplicationManager1Service::initService(QDBusConnection &connection) noexce
scanInstances(); scanInstances();
auto storagePtr = m_storage.lock(); auto storagePtr = m_storage.lock();
storagePtr->setFirstLaunch(false); if (!storagePtr->setFirstLaunch(false)) {
qCritical() << "failed to update state of application manager, some properties may be lost after restart.";
}
loadHooks(); loadHooks();
@ -519,7 +521,10 @@ void ApplicationManager1Service::removeOneApplication(const QDBusObjectPath &app
if (auto it = m_applicationList.find(application); it != m_applicationList.cend()) { if (auto it = m_applicationList.find(application); it != m_applicationList.cend()) {
emit InterfacesRemoved(application, getChildInterfacesFromObject(it->data())); emit InterfacesRemoved(application, getChildInterfacesFromObject(it->data()));
if (auto ptr = m_storage.lock(); ptr) { if (auto ptr = m_storage.lock(); ptr) {
ptr->deleteApplication((*it)->id()); auto appId = (*it)->id();
if (!ptr->deleteApplication(appId)) {
qCritical() << "failed to delete all properties of" << appId;
}
} }
unregisterObjectFromDBus(application.path()); unregisterObjectFromDBus(application.path());
m_applicationList.remove(application); m_applicationList.remove(application);

View File

@ -81,23 +81,48 @@ ApplicationService::ApplicationService(DesktopFile source,
} }
auto appId = id(); auto appId = id();
auto value = storagePtr->readApplicationValue(appId, ApplicationPropertiesGroup, LastLaunchedTime); auto value = storagePtr->readApplicationValue(appId, ApplicationPropertiesGroup, InstalledTime);
qint64 val{0};
if (storagePtr->firstLaunch()) { if (storagePtr->firstLaunch()) {
val = QDateTime::currentMSecsSinceEpoch(); auto ret = value.isNull() ? storagePtr->createApplicationValue(appId, ApplicationPropertiesGroup, InstalledTime, 0) :
storagePtr->updateApplicationValue(appId, ApplicationPropertiesGroup, InstalledTime, 0);
if (!ret) {
m_installedTime = -1;
qWarning() << "failed to set InstalledTime for" << appId << "at first launch";
}
} else {
auto newInstalledTime = QDateTime::currentMSecsSinceEpoch();
auto ret = value.isNull() ?
storagePtr->createApplicationValue(appId, ApplicationPropertiesGroup, InstalledTime, newInstalledTime) :
true;
if (!ret) {
m_installedTime = -1;
qWarning() << "failed to set InstalledTime for new apps:" << appId;
} else {
m_installedTime = newInstalledTime;
}
} }
value = storagePtr->readApplicationValue(appId, ApplicationPropertiesGroup, LastLaunchedTime);
if (value.isNull()) { if (value.isNull()) {
if (!storagePtr->createApplicationValue(appId, ApplicationPropertiesGroup, LastLaunchedTime, QVariant::fromValue(val))) { if (!storagePtr->createApplicationValue(appId, ApplicationPropertiesGroup, LastLaunchedTime, 0)) {
qWarning() << "failed to set LastLaunchedTime for" << appId;
m_lastLaunch = -1; m_lastLaunch = -1;
} else {
m_lastLaunch = val;
} }
} else { } else {
m_lastLaunch = value.toLongLong(); m_lastLaunch = value.toLongLong();
} }
value = storagePtr->readApplicationValue(appId, ApplicationPropertiesGroup, ::LaunchedTimes);
if (value.isNull()) {
if (!storagePtr->createApplicationValue(appId, ApplicationPropertiesGroup, ::LaunchedTimes, 0)) {
qWarning() << "failed to set LaunchedTimes for" << appId;
m_launchedTimes = -1;
}
} else {
m_launchedTimes = value.toLongLong();
}
value = storagePtr->readApplicationValue(appId, ApplicationPropertiesGroup, ScaleFactor); value = storagePtr->readApplicationValue(appId, ApplicationPropertiesGroup, ScaleFactor);
if (!value.isNull()) { if (!value.isNull()) {
bool ok{false}; bool ok{false};
@ -551,16 +576,21 @@ bool ApplicationService::terminal() const noexcept
return false; return false;
} }
qulonglong ApplicationService::installedTime() const noexcept qint64 ApplicationService::installedTime() const noexcept
{ {
return m_desktopSource.createTime(); return m_installedTime;
} }
qulonglong ApplicationService::lastLaunchedTime() const noexcept qint64 ApplicationService::lastLaunchedTime() const noexcept
{ {
return m_lastLaunch; return m_lastLaunch;
} }
qint64 ApplicationService::launchedTimes() const noexcept
{
return m_launchedTimes;
}
double ApplicationService::scaleFactor() const noexcept double ApplicationService::scaleFactor() const noexcept
{ {
return m_scaleFactor; return m_scaleFactor;
@ -579,7 +609,9 @@ void ApplicationService::setScaleFactor(double value) noexcept
if (value == 0) { if (value == 0) {
m_customScale = false; m_customScale = false;
m_scaleFactor = getScaleFactor(); m_scaleFactor = getScaleFactor();
storagePtr->deleteApplicationValue(appId, ApplicationPropertiesGroup, ScaleFactor); if (!storagePtr->deleteApplicationValue(appId, ApplicationPropertiesGroup, ScaleFactor)) {
qCritical() << "failed to delete app's property:" << appId;
}
return; return;
} }
@ -1131,10 +1163,27 @@ void ApplicationService::updateAfterLaunch(bool isLaunch) noexcept
auto timestamp = QDateTime::currentMSecsSinceEpoch(); auto timestamp = QDateTime::currentMSecsSinceEpoch();
if (auto ptr = m_storage.lock(); ptr) { if (auto ptr = m_storage.lock(); ptr) {
if (!ptr->updateApplicationValue(m_desktopSource.desktopId(),
ApplicationPropertiesGroup,
::LastLaunchedTime,
QVariant::fromValue(timestamp),
true)) {
qWarning() << "failed to update LastLaunchedTime:" << id();
return;
}
if (!ptr->updateApplicationValue(m_desktopSource.desktopId(),
ApplicationPropertiesGroup,
::LaunchedTimes,
QVariant::fromValue(m_launchedTimes + 1))) {
qWarning() << "failed to update LaunchedTimes:" << id();
return;
}
m_lastLaunch = timestamp; m_lastLaunch = timestamp;
ptr->updateApplicationValue( m_launchedTimes += 1;
m_desktopSource.desktopId(), ApplicationPropertiesGroup, ::LastLaunchedTime, QVariant::fromValue(timestamp));
emit lastLaunchedTimeChanged(); emit lastLaunchedTimeChanged();
emit launchedTimesChanged();
} }
} }

View File

@ -61,8 +61,11 @@ public:
Q_PROPERTY(QStringMap Icons READ icons NOTIFY iconsChanged) Q_PROPERTY(QStringMap Icons READ icons NOTIFY iconsChanged)
[[nodiscard]] QStringMap icons() const noexcept; [[nodiscard]] QStringMap icons() const noexcept;
Q_PROPERTY(qulonglong LastLaunchedTime READ lastLaunchedTime NOTIFY lastLaunchedTimeChanged) Q_PROPERTY(qint64 LastLaunchedTime READ lastLaunchedTime NOTIFY lastLaunchedTimeChanged)
[[nodiscard]] qulonglong lastLaunchedTime() const noexcept; [[nodiscard]] qint64 lastLaunchedTime() const noexcept;
Q_PROPERTY(qint64 LaunchedTimes READ launchedTimes NOTIFY launchedTimesChanged)
[[nodiscard]] qint64 launchedTimes() const noexcept;
Q_PROPERTY(double ScaleFactor READ scaleFactor WRITE setScaleFactor NOTIFY scaleFactorChanged) Q_PROPERTY(double ScaleFactor READ scaleFactor WRITE setScaleFactor NOTIFY scaleFactorChanged)
[[nodiscard]] double scaleFactor() const noexcept; [[nodiscard]] double scaleFactor() const noexcept;
@ -94,8 +97,8 @@ public:
Q_PROPERTY(QString X_Deepin_Vendor READ X_Deepin_Vendor) Q_PROPERTY(QString X_Deepin_Vendor READ X_Deepin_Vendor)
[[nodiscard]] QString X_Deepin_Vendor() const noexcept; [[nodiscard]] QString X_Deepin_Vendor() const noexcept;
Q_PROPERTY(qulonglong installedTime READ installedTime NOTIFY installedTimeChanged) Q_PROPERTY(qint64 InstalledTime READ installedTime NOTIFY installedTimeChanged)
[[nodiscard]] qulonglong installedTime() const noexcept; [[nodiscard]] qint64 installedTime() const noexcept;
Q_PROPERTY(bool isOnDesktop READ isOnDesktop NOTIFY isOnDesktopChanged) Q_PROPERTY(bool isOnDesktop READ isOnDesktop NOTIFY isOnDesktopChanged)
[[nodiscard]] bool isOnDesktop() const noexcept; [[nodiscard]] bool isOnDesktop() const noexcept;
@ -162,6 +165,7 @@ Q_SIGNALS:
void MimeTypesChanged(); void MimeTypesChanged();
void terminalChanged(); void terminalChanged();
void scaleFactorChanged(); void scaleFactorChanged();
void launchedTimesChanged();
private: private:
friend class ApplicationManager1Service; friend class ApplicationManager1Service;
@ -172,6 +176,8 @@ private:
DesktopFile source, ApplicationManager1Service *parent, std::weak_ptr<ApplicationManager1Storage> storage) noexcept; DesktopFile source, ApplicationManager1Service *parent, std::weak_ptr<ApplicationManager1Storage> storage) noexcept;
bool m_customScale{false}; bool m_customScale{false};
qint64 m_lastLaunch{0}; qint64 m_lastLaunch{0};
qint64 m_installedTime{0};
qint64 m_launchedTimes{0};
double m_scaleFactor; double m_scaleFactor;
std::weak_ptr<ApplicationManager1Storage> m_storage; std::weak_ptr<ApplicationManager1Storage> m_storage;
AutostartSource m_autostartSource; AutostartSource m_autostartSource;