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

@ -2,24 +2,25 @@
<node>
<interface name="org.desktopspec.ApplicationManager1.Application">
<annotation
name="org.freedesktop.DBus.Description"
value="This interface is designed to provide a dbus interface of desktop file. Missing fields will be added later."
name="org.freedesktop.DBus.Description"
value="This interface is designed to provide a dbus interface of desktop file. Missing fields will be added later."
/>
<property name="Categories" type="as" access="read"/>
<property name="X_linglong" type="b" access="read"/>
<property name="X_Flatpak" type="b" access="read"/>
<property name="Categories" type="as" access="read" />
<property name="X_linglong" type="b" access="read" />
<property name="X_Flatpak" type="b" 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
should use GenericName."
<annotation name="org.freedesktop.DBus.Description"
value="Whem this property is 'deepin', display name of the application
should use GenericName."
/>
</property>
<property name="installedTime" type="t" access="read"/>
<property name="NoDisplay" type="b" access="read"/>
<property name="MimeTypes" type="as" access="readwrite"/>
<property name="NoDisplay" type="b" access="read" />
<property name="MimeTypes" type="as" access="readwrite" />
<property name="Actions" type="as" access="read">
<annotation
<annotation
name="org.freedesktop.DBus.Description"
value="Names of all action identifiers of this application.
Check https://specifications.freedesktop.org/desktop-entry-spec/desktop-entry-spec-latest.html#extra-actions
@ -27,8 +28,30 @@
/>
</property>
<property name="AutoStart" type="b" access="readwrite"/>
<property name="LastLaunchedTime" type="t" access="read"/>
<property name="AutoStart" type="b" access="readwrite" />
<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">
<annotation
@ -47,17 +70,17 @@
</property>
<property name="Terminal" type="b" access="read">
<annotation
<annotation
name="org.freedesktop.DBus.Description"
value="Indicate this application should launch by terminal or not."
/>
</property>
<property name="ScaleFactor" type="d" access="readwrite">
<annotation
name="org.freedesktop.DBus.Description"
<annotation
name="org.freedesktop.DBus.Description"
value="Indicate the scale factor of application's instance.
Note: Set `0` to use global scaleFactor"
Note: Set `0` to use global scaleFactor"
/>
</property>

View File

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

View File

@ -20,20 +20,25 @@ public:
ApplicationManager1Storage &operator=(ApplicationManager1Storage &&) = default;
~ApplicationManager1Storage() = default;
bool createApplicationValue(const QString &appId,
const QString &groupName,
const QString &valueKey,
const QVariant &value) noexcept;
bool updateApplicationValue(const QString &appId,
const QString &groupName,
const QString &valueKey,
const QVariant &value) noexcept;
[[nodiscard]] bool createApplicationValue(const QString &appId,
const QString &groupName,
const QString &valueKey,
const QVariant &value,
bool deferCommit = false) noexcept;
[[nodiscard]] bool updateApplicationValue(const QString &appId,
const QString &groupName,
const QString &valueKey,
const QVariant &value,
bool deferCommit = false) noexcept;
[[nodiscard]] QVariant
readApplicationValue(const QString &appId, const QString &groupName, const QString &valueKey) const 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;
[[nodiscard]] bool deleteApplicationValue(const QString &appId,
const QString &groupName,
const QString &valueKey,
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;
[[nodiscard]] uint8_t version() const noexcept;
@ -41,7 +46,8 @@ public:
bool setFirstLaunch(bool first) 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:
[[nodiscard]] bool writeToFile() const noexcept;

View File

@ -58,6 +58,8 @@ constexpr auto STORAGE_VERSION = 0;
constexpr auto ApplicationPropertiesGroup = u8"Application Properties";
constexpr auto LastLaunchedTime = u8"LastLaunchedTime";
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";

View File

@ -117,7 +117,9 @@ void ApplicationManager1Service::initService(QDBusConnection &connection) noexce
scanInstances();
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();
@ -519,7 +521,10 @@ 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->deleteApplication((*it)->id());
auto appId = (*it)->id();
if (!ptr->deleteApplication(appId)) {
qCritical() << "failed to delete all properties of" << appId;
}
}
unregisterObjectFromDBus(application.path());
m_applicationList.remove(application);

View File

@ -81,23 +81,48 @@ ApplicationService::ApplicationService(DesktopFile source,
}
auto appId = id();
auto value = storagePtr->readApplicationValue(appId, ApplicationPropertiesGroup, LastLaunchedTime);
auto value = storagePtr->readApplicationValue(appId, ApplicationPropertiesGroup, InstalledTime);
qint64 val{0};
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 (!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;
} else {
m_lastLaunch = val;
}
} else {
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);
if (!value.isNull()) {
bool ok{false};
@ -551,16 +576,21 @@ bool ApplicationService::terminal() const noexcept
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;
}
qint64 ApplicationService::launchedTimes() const noexcept
{
return m_launchedTimes;
}
double ApplicationService::scaleFactor() const noexcept
{
return m_scaleFactor;
@ -579,7 +609,9 @@ void ApplicationService::setScaleFactor(double value) noexcept
if (value == 0) {
m_customScale = false;
m_scaleFactor = getScaleFactor();
storagePtr->deleteApplicationValue(appId, ApplicationPropertiesGroup, ScaleFactor);
if (!storagePtr->deleteApplicationValue(appId, ApplicationPropertiesGroup, ScaleFactor)) {
qCritical() << "failed to delete app's property:" << appId;
}
return;
}
@ -1131,10 +1163,27 @@ void ApplicationService::updateAfterLaunch(bool isLaunch) noexcept
auto timestamp = QDateTime::currentMSecsSinceEpoch();
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;
ptr->updateApplicationValue(
m_desktopSource.desktopId(), ApplicationPropertiesGroup, ::LastLaunchedTime, QVariant::fromValue(timestamp));
m_launchedTimes += 1;
emit lastLaunchedTimeChanged();
emit launchedTimesChanged();
}
}

View File

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