Skip to content

Commit 089a3ef

Browse files
committed
feat: add notification auto cleanup and timeout handling
1. Add fetchFirstEntity method to data accessor interfaces for retrieving earliest notifications 2. Implement notification auto-cleanup feature that removes processed notifications older than configured days 3. Add Timeout processed type for handling expired notifications 4. Add configuration option for notification cleanup days with default value of 7 days 5. Implement cleanup timer that runs every second to check for expired notifications 6. Update notification processing to handle timeout closures properly feat: 添加通知自动清理和超时处理功能 1. 在数据访问器接口中添加 fetchFirstEntity 方法用于获取最早的通知 2. 实现通知自动清理功能,删除超过配置天数的已处理通知 3. 添加 Timeout 处理类型用于处理过期通知 4. 添加通知清理天数的配置选项,默认值为7天 5. 实现清理定时器,每秒检查一次过期通知 6. 更新通知处理逻辑以正确处理超时关闭 PMS: BUG-284979
1 parent bee9a40 commit 089a3ef

File tree

11 files changed

+89
-1
lines changed

11 files changed

+89
-1
lines changed

panels/notification/common/dataaccessor.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ class DataAccessor
3535
virtual int fetchEntityCount(const QString &appName, int processedType) const { Q_UNUSED(appName); Q_UNUSED(processedType); return 0; }
3636
virtual NotifyEntity fetchLastEntity(const QString &appName, int processedType) { Q_UNUSED(appName); Q_UNUSED(processedType); return {}; }
3737
virtual NotifyEntity fetchLastEntity(uint notifyId) { Q_UNUSED(notifyId); return {}; }
38+
virtual QList<NotifyEntity> fetchExpiredEntities(qint64 expiredTime) { Q_UNUSED(expiredTime); return {}; }
3839
virtual QList<NotifyEntity> fetchEntities(const QString &appName, int processedType, int maxCount)
3940
{
4041
Q_UNUSED(appName)

panels/notification/common/dataaccessorproxy.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,11 @@ NotifyEntity DataAccessorProxy::fetchLastEntity(uint notifyId)
116116
return m_source->fetchLastEntity(notifyId);
117117
}
118118

119+
QList<NotifyEntity> DataAccessorProxy::fetchExpiredEntities(qint64 expiredTime)
120+
{
121+
return m_source->fetchExpiredEntities(expiredTime);
122+
}
123+
119124
QList<NotifyEntity> DataAccessorProxy::fetchEntities(const QString &appName, int processedType, int maxCount)
120125
{
121126
if (processedType == NotifyEntity::NotProcessed) {

panels/notification/common/dataaccessorproxy.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ class DataAccessorProxy : public DataAccessor
3131
virtual int fetchEntityCount(const QString &appName, int processedType) const override;
3232
virtual NotifyEntity fetchLastEntity(const QString &appName, int processedType) override;
3333
virtual NotifyEntity fetchLastEntity(uint notifyId) override;
34+
virtual QList<NotifyEntity> fetchExpiredEntities(qint64 expiredTime) override;
3435
virtual QList<NotifyEntity> fetchEntities(const QString &appName, int processedType, int maxCount) override;
3536
virtual QList<QString> fetchApps(int maxCount) const override;
3637

panels/notification/common/dbaccessor.cpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -443,6 +443,32 @@ NotifyEntity DBAccessor::fetchLastEntity(uint notifyId)
443443
return {};
444444
}
445445

446+
QList<NotifyEntity> DBAccessor::fetchExpiredEntities(qint64 expiredTime)
447+
{
448+
BENCHMARK();
449+
450+
QMutexLocker locker(&m_mutex);
451+
QSqlQuery query(m_connection);
452+
453+
QString cmd = QString("SELECT %1 FROM notifications2 WHERE CTime < :expiredTime ORDER BY CTime ASC").arg(EntityFields.join(","));
454+
query.prepare(cmd);
455+
query.bindValue(":expiredTime", expiredTime);
456+
457+
if (!query.exec()) {
458+
qWarning(notifyDBLog) << "Query execution error:" << query.lastError().text();
459+
return {};
460+
}
461+
462+
QList<NotifyEntity> expiredEntities;
463+
while (query.next()) {
464+
auto entity = parseEntity(query);
465+
if (entity.isValid()) {
466+
expiredEntities.append(entity);
467+
}
468+
}
469+
return expiredEntities;
470+
}
471+
446472
QList<QString> DBAccessor::fetchApps(int maxCount) const
447473
{
448474
BENCHMARK();

panels/notification/common/dbaccessor.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ class DBAccessor : public DataAccessor
3737
NotifyEntity fetchLastEntity(const QString &appName, int processedType) override;
3838
QList<NotifyEntity> fetchEntities(const QString &appName, int processedType, int maxCount) override;
3939
NotifyEntity fetchLastEntity(uint notifyId) override;
40+
QList<NotifyEntity> fetchExpiredEntities(qint64 expiredTime) override;
4041
QList<QString> fetchApps(int maxCount) const override;
4142

4243
void removeEntity(qint64 id) override;

panels/notification/common/memoryaccessor.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
#include "memoryaccessor.h"
66
#include <QDebug>
7+
#include <limits>
78

89
namespace notification
910
{
@@ -102,6 +103,24 @@ NotifyEntity MemoryAccessor::fetchLastEntity(uint notifyId)
102103
return {};
103104
}
104105

106+
QList<NotifyEntity> MemoryAccessor::fetchExpiredEntities(qint64 expiredTime)
107+
{
108+
QMutexLocker locker(&m_mutex);
109+
QList<NotifyEntity> expiredEntities;
110+
111+
for (const auto &entity : m_entities) {
112+
if (entity.cTime() < expiredTime) {
113+
expiredEntities.append(entity);
114+
}
115+
}
116+
117+
std::sort(expiredEntities.begin(), expiredEntities.end(), [](const NotifyEntity &a, const NotifyEntity &b) {
118+
return a.cTime() < b.cTime();
119+
});
120+
121+
return expiredEntities;
122+
}
123+
105124
QList<NotifyEntity> MemoryAccessor::fetchEntities(const QString &appName, int processedType, int maxCount)
106125
{
107126
QMutexLocker locker(&m_mutex);

panels/notification/common/memoryaccessor.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ class MemoryAccessor : public DataAccessor
2727
virtual int fetchEntityCount(const QString &appName, int processedType) const override;
2828
virtual NotifyEntity fetchLastEntity(const QString &appName, int processedType) override;
2929
virtual NotifyEntity fetchLastEntity(uint notifyId) override;
30+
virtual QList<NotifyEntity> fetchExpiredEntities(qint64 expiredTime) override;
3031
virtual QList<NotifyEntity> fetchEntities(const QString &appName, int processedType, int maxCount) override;
3132
virtual QList<QString> fetchApps(int maxCount) const override;
3233

panels/notification/common/notifyentity.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ class NotifyEntity
3030
Dismissed = 2,
3131
Closed = 3,
3232
Unknown = 4,
33+
Timeout = 5,
3334
};
3435

3536
NotifyEntity();

panels/notification/server/configs/org.deepin.dde.shell.notification.json

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,17 @@
144144
"description[zh_CN]": "应用名称映射",
145145
"permissions": "readwrite",
146146
"visibility": "private"
147+
},
148+
"notificationCleanupDays": {
149+
"value": 7,
150+
"serial": 0,
151+
"flags": [],
152+
"name": "notification cleanup days",
153+
"name[zh_CN]": "通知清理天数",
154+
"description": "Number of days after which notifications will be automatically cleaned up",
155+
"description[zh_CN]": "通知自动清理的天数,超过此天数的通知将被自动删除",
156+
"permissions": "readwrite",
157+
"visibility": "public"
147158
}
148159
}
149160
}

panels/notification/server/notificationmanager.cpp

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,9 +49,14 @@ NotificationManager::NotificationManager(QObject *parent)
4949
, m_persistence(DataAccessorProxy::instance())
5050
, m_setting(new NotificationSetting(this))
5151
, m_pendingTimeout(new QTimer(this))
52+
, m_cleanupTimer(new QTimer(this))
5253
{
5354
m_pendingTimeout->setSingleShot(true);
5455
connect(m_pendingTimeout, &QTimer::timeout, this, &NotificationManager::onHandingPendingEntities);
56+
57+
m_cleanupTimer->setInterval(1000);
58+
connect(m_cleanupTimer, &QTimer::timeout, this, &NotificationManager::onCleanupExpiredNotifications);
59+
m_cleanupTimer->start();
5560

5661
DataAccessorProxy::instance()->setSource(DBAccessor::instance());
5762

@@ -77,7 +82,9 @@ NotificationManager::NotificationManager(QObject *parent)
7782
m_systemApps = config->value("systemApps").toStringList();
7883
// TODO temporary fix for AppNamesMap
7984
m_appNamesMap = config->value("AppNamesMap").toMap();
80-
85+
if(!config->value("notificationCleanupDays").isNull()) {
86+
m_cleanupDays = config->value("notificationCleanupDays").toInt();
87+
}
8188
if (QStringLiteral("wayland") != QGuiApplication::platformName()) {
8289
initScreenLockedState();
8390
}
@@ -457,6 +464,8 @@ void NotificationManager::updateEntityProcessed(qint64 id, uint reason)
457464
if (entity.isValid()) {
458465
if ((reason == NotifyEntity::Closed || reason == NotifyEntity::Dismissed) && entity.processedType() == NotifyEntity::NotProcessed) {
459466
entity.setProcessedType(NotifyEntity::Removed);
467+
} else if (reason == NotifyEntity::Timeout) {
468+
entity.setProcessedType(NotifyEntity::Removed);
460469
} else {
461470
entity.setProcessedType(NotifyEntity::Processed);
462471
}
@@ -675,4 +684,14 @@ void NotificationManager::onScreenLockedChanged(bool screenLocked)
675684
m_screenLocked = screenLocked;
676685
}
677686

687+
void NotificationManager::onCleanupExpiredNotifications()
688+
{
689+
const qint64 cutoffTime = QDateTime::currentDateTime().addDays(-m_cleanupDays).toMSecsSinceEpoch();
690+
auto expiredEntities = m_persistence->fetchExpiredEntities(cutoffTime);
691+
692+
for (const auto &entity : expiredEntities) {
693+
notificationClosed(entity.id(), entity.bubbleId(), NotifyEntity::Timeout);
694+
}
695+
}
696+
678697
} // notification

0 commit comments

Comments
 (0)