From 4628054547c32c6c099bd3f13e2bdb2ceae19836 Mon Sep 17 00:00:00 2001 From: JunjieBai Date: Mon, 8 Aug 2022 10:37:49 +0800 Subject: [PATCH 1/3] Make the appdb dbus autostart.Install the desktop file of app-data-service. --- .../conf/com.ukui.search.appdb.service | 3 +++ .../ukui-search-app-data-service.pro | 13 +++++++++---- 2 files changed, 12 insertions(+), 4 deletions(-) create mode 100644 ukui-search-app-data-service/conf/com.ukui.search.appdb.service diff --git a/ukui-search-app-data-service/conf/com.ukui.search.appdb.service b/ukui-search-app-data-service/conf/com.ukui.search.appdb.service new file mode 100644 index 0000000..2b533d6 --- /dev/null +++ b/ukui-search-app-data-service/conf/com.ukui.search.appdb.service @@ -0,0 +1,3 @@ +[D-BUS Service] +Name=com.ukui.search.appdb.service +Exec=/usr/bin/ukui-search-app-data-service diff --git a/ukui-search-app-data-service/ukui-search-app-data-service.pro b/ukui-search-app-data-service/ukui-search-app-data-service.pro index 82c6fe2..b3e7261 100644 --- a/ukui-search-app-data-service/ukui-search-app-data-service.pro +++ b/ukui-search-app-data-service/ukui-search-app-data-service.pro @@ -29,20 +29,25 @@ SOURCES += \ main.cpp \ convert-winid-to-desktop.cpp \ app-db-manager.cpp \ - pending-app-info-queue.cpp \ + pending-app-info-queue.cpp \ signal-transformer.cpp \ ukui-search-app-data-service.cpp \ HEADERS += \ convert-winid-to-desktop.h \ app-db-manager.h \ - pending-app-info-queue.h \ - pending-app-info.h \ + pending-app-info-queue.h \ + pending-app-info.h \ signal-transformer.h \ ukui-search-app-data-service.h \ +inst1.files += conf/com.ukui.search.appdb.service +inst1.path = /usr/share/dbus-1/services/ + target.path = /usr/bin -INSTALLS += target +INSTALLS += \ + target \ + inst1 desktop.path = /etc/xdg/autostart desktop.files += ../data/ukui-search-app-data-service.desktop From b1eb17be2abbc56e1453d7c113ec20e2005a0a0d Mon Sep 17 00:00:00 2001 From: JunjieBai Date: Mon, 8 Aug 2022 13:55:51 +0800 Subject: [PATCH 2/3] Using the file-system-watcher to watch the desktop files' dirs. --- .../filesystemwatcher/file-system-watcher.cpp | 1 + .../app-db-manager.cpp | 117 +++++++++++++++++- ukui-search-app-data-service/app-db-manager.h | 16 ++- .../ukui-search-app-data-service.pro | 3 +- 4 files changed, 125 insertions(+), 12 deletions(-) diff --git a/libsearch/filesystemwatcher/file-system-watcher.cpp b/libsearch/filesystemwatcher/file-system-watcher.cpp index a72a40d..99b12e9 100644 --- a/libsearch/filesystemwatcher/file-system-watcher.cpp +++ b/libsearch/filesystemwatcher/file-system-watcher.cpp @@ -205,6 +205,7 @@ void FileSystemWatcher::eventProcess(int socket) const struct inotify_event* event = (struct inotify_event*)&buf[i]; if(event->name[0] == '.') { + i += sizeof(struct inotify_event) + event->len; continue; } if (event->wd < 0 && (event->mask & EventQueueOverflow)) { diff --git a/ukui-search-app-data-service/app-db-manager.cpp b/ukui-search-app-data-service/app-db-manager.cpp index 58d473b..e61e155 100644 --- a/ukui-search-app-data-service/app-db-manager.cpp +++ b/ukui-search-app-data-service/app-db-manager.cpp @@ -7,9 +7,9 @@ #include #include -#define GENERAL_APP_DESKTOP_PATH "/usr/share/applications/" -#define ANDROID_APP_DESKTOP_PATH QDir::homePath() + "/.local/share/applications/" -#define SNAPD_APP_DESKTOP_PATH "/var/lib/snapd/desktop/applications/" +#define GENERAL_APP_DESKTOP_PATH "/usr/share/applications" +#define ANDROID_APP_DESKTOP_PATH QDir::homePath() + "/.local/share/applications" +#define SNAPD_APP_DESKTOP_PATH "/var/lib/snapd/desktop/applications" #define LAST_LOCALE_NAME QDir::homePath() + "/.config/org.ukui/ukui-search/appdata/last-locale-name.conf" #define LOCALE_NAME_VALUE "CurrentLocaleName" @@ -49,6 +49,100 @@ AppDBManager::AppDBManager(QObject *parent) : QThread(parent), m_database(QSqlDa refreshAllData2DB(); // refreshDataBase(); + //初始化FileSystemWatcher + m_watcher = new FileSystemWatcher; + m_watcher->addWatch(GENERAL_APP_DESKTOP_PATH); + QDir androidDir(ANDROID_APP_DESKTOP_PATH); + if(!androidDir.exists()) { + androidDir.mkpath(ANDROID_APP_DESKTOP_PATH); + } + m_watcher->addWatch(ANDROID_APP_DESKTOP_PATH); + + m_snapdDir = new QDir(SNAPD_APP_DESKTOP_PATH); + if(!m_snapdDir->exists()) { + m_snapdWatcher = new FileSystemWatcher(false); + QDir dir("/var/lib/snapd"); + if (!dir.exists()) { + dir.setPath("/var/lib"); + } + m_snapdPath = dir.absolutePath(); + m_snapdWatcher->addWatch(m_snapdPath); + } else { + m_watcher->addWatch(SNAPD_APP_DESKTOP_PATH); + } + + connect(m_snapdWatcher, &FileSystemWatcher::created, this, [ = ] (const QString &path, bool isDir) { + if (isDir) { + //监测新增目录为/var/lib/snapd时,将其替换为snapdWatcher的watchpath + if (path == "/var/lib/snapd") { + m_snapdWatcher->removeWatch(m_snapdPath); + m_snapdWatcher->addWatch(path); + qDebug() << "~~~~~~~add watch" << path << "~~~~~remove watch" << m_snapdPath; + m_snapdPath = path; + //snapd下的desktop目录可能在还没替换监听目录为/var/lib/snapd时就已经被创建,因此需要特别判断 + QDir dir("/var/lib/snapd/desktop"); + if (dir.exists()) { + if (m_snapdDir->exists()) { + m_watcher->addWatch(SNAPD_APP_DESKTOP_PATH); + m_snapdWatcher->removeWatch(m_snapdPath); + qDebug() << "======add watch" << SNAPD_APP_DESKTOP_PATH << "======remove watch" << m_snapdPath; + } + } + } + //检测到/var/lib/snapd/desktop被创建,则将监听目录替换为/var/lib/snapd/desktop/applications + if (path == "/var/lib/snapd/desktop" and m_snapdDir->exists()) { + m_watcher->addWatch(SNAPD_APP_DESKTOP_PATH); + m_snapdWatcher->removeWatch(m_snapdPath); + qDebug() << "======add watch" << SNAPD_APP_DESKTOP_PATH << "======remove watch" << m_snapdPath; + } + + } + }); + + connect(m_watcher, &FileSystemWatcher::created, this, [ = ] (const QString &desktopfp, bool isDir) { + //event is IN_CREATE or IN_MOVED_TO + if (!isDir and desktopfp.endsWith(".desktop")) { + this->insertDBItem(desktopfp); + } + }); + + connect(m_watcher, &FileSystemWatcher::modified, this, [ = ] (const QString &desktopfp) { + //event is IN_MODIFY + if (desktopfp.endsWith(".desktop")) { + this->updateDBItem(desktopfp); + } + }); + + connect(m_watcher, &FileSystemWatcher::moved, this, [ = ] (const QString &desktopfp, bool isDir) { + //event is IN_MOVED_FROM + if (!isDir) { + if (desktopfp.endsWith(".desktop")) { + this->deleteDBItem(desktopfp); + } + } else { + //event is IN_MOVE_SELF + qWarning() << "Dir:" << desktopfp << "has been moved to other place! Stop the watching of the desktop files in it!"; + } + }); + + connect(m_watcher, &FileSystemWatcher::deleted, this, [ = ] (const QString &desktopfp, bool isDir) { + //event is IN_DELETE + if (!isDir) { + if (desktopfp.endsWith(".desktop")) { + this->deleteDBItem(desktopfp); + } + } else { + //event is IN_DELETE_SELF + qWarning() << "Dir:" << desktopfp << "has been deleted! Stop the watching of the desktop files in it!"; + } + }); + + connect(m_watcher, &FileSystemWatcher::unmounted, this, [ = ] (const QString &desktopfp) { + //event is IN_UNMOUNT + qWarning() << "Dir:" << desktopfp << "has been unmounted! Stop the watching of the desktop files in it!"; + }); + + /* //初始化FileSystemWatcher m_watchAppDir = new QFileSystemWatcher(this); m_watchAppDir->addPath(GENERAL_APP_DESKTOP_PATH); @@ -103,6 +197,7 @@ AppDBManager::AppDBManager(QObject *parent) : QThread(parent), m_database(QSqlDa Q_EMIT this->stopTimer(); this->refreshAllData2DB(); }, Qt::DirectConnection); + */ //监控应用进程开启 connect(KWindowSystem::self(), &KWindowSystem::windowAdded, [ = ](WId id) { @@ -118,10 +213,20 @@ AppDBManager::AppDBManager(QObject *parent) : QThread(parent), m_database(QSqlDa AppDBManager::~AppDBManager() { - if(m_watchAppDir) { - delete m_watchAppDir; + if (m_watcher) { + delete m_watcher; } - m_watchAppDir = NULL; + m_watcher = NULL; + + if (m_snapdWatcher) { + delete m_snapdWatcher; + } + m_snapdWatcher = NULL; + +// if(m_watchAppDir) { +// delete m_watchAppDir; +// } +// m_watchAppDir = NULL; closeDataBase(); } diff --git a/ukui-search-app-data-service/app-db-manager.h b/ukui-search-app-data-service/app-db-manager.h index bb444b0..9699e33 100644 --- a/ukui-search-app-data-service/app-db-manager.h +++ b/ukui-search-app-data-service/app-db-manager.h @@ -3,6 +3,7 @@ #include "app-db-common.h" #include "pending-app-info-queue.h" +#include "file-system-watcher.h" #include #include @@ -12,11 +13,11 @@ #include #include #include -#include #include #include -#include #include +//#include +//#include #define CONNECTION_NAME QLatin1String("ukss-appdb-connection") @@ -132,11 +133,16 @@ private: QSettings *m_qSettings = nullptr; - QTimer *m_timer = nullptr; - QTimer *m_maxProcessTimer = nullptr; +// QTimer *m_timer = nullptr; +// QTimer *m_maxProcessTimer = nullptr; +// QFileSystemWatcher *m_watchAppDir = nullptr; QSqlDatabase m_database; - QFileSystemWatcher *m_watchAppDir = nullptr; + FileSystemWatcher *m_watcher = nullptr; + + QDir *m_snapdDir = nullptr; + QString m_snapdPath; + FileSystemWatcher *m_snapdWatcher = nullptr; //应用黑名单 QStringList m_excludedDesktopfiles = { diff --git a/ukui-search-app-data-service/ukui-search-app-data-service.pro b/ukui-search-app-data-service/ukui-search-app-data-service.pro index b3e7261..03ffc09 100644 --- a/ukui-search-app-data-service/ukui-search-app-data-service.pro +++ b/ukui-search-app-data-service/ukui-search-app-data-service.pro @@ -58,5 +58,6 @@ INCLUDEPATH += $$PWD/../libchinese-segmentation DEPENDPATH += $$PWD/../libchinese-segmentation LIBS += -L$$OUT_PWD/../libsearch/ -lukui-search -INCLUDEPATH += $$PWD/../libsearch +INCLUDEPATH += $$PWD/../libsearch \ + $$PWD/../libsearch/filesystemwatcher DEPENDPATH += $$PWD/../libsearch From e528b6b3ec52f2c172df56b627928a659381df13 Mon Sep 17 00:00:00 2001 From: JunjieBai Date: Mon, 8 Aug 2022 13:57:08 +0800 Subject: [PATCH 3/3] Modify the enqueue method of app info queue. --- .../pending-app-info-queue.cpp | 59 +++++++++++++------ 1 file changed, 42 insertions(+), 17 deletions(-) diff --git a/ukui-search-app-data-service/pending-app-info-queue.cpp b/ukui-search-app-data-service/pending-app-info-queue.cpp index 0bd94e3..8213383 100644 --- a/ukui-search-app-data-service/pending-app-info-queue.cpp +++ b/ukui-search-app-data-service/pending-app-info-queue.cpp @@ -15,18 +15,39 @@ void PendingAppInfoQueue::enqueue(const PendingAppInfo &appInfo) { QMutexLocker locker(&s_mutex); m_handleTimes++; - int index = m_cache.indexOf(appInfo); + int index = m_cache.lastIndexOf(appInfo); if (index == -1) { m_cache << appInfo; } else { + //要插入项操作类型为删除,清除之前所有操作,替换为删除 + if (appInfo.handleType() == PendingAppInfo::Delete) { + m_cache.removeAll(appInfo); + m_cache << appInfo; + } else if (m_cache[index].handleType() == PendingAppInfo::Delete) { + //先删后建,分别处理 + if (appInfo.handleType() == PendingAppInfo::Insert) { + m_cache << appInfo; + } + } else if (m_cache[index].handleType() <= PendingAppInfo::UpdateLocaleData + and appInfo.handleType() <= PendingAppInfo::UpdateLocaleData) { + //类型为insert, updateall, updatelocaledata时,设置为优先级高的操作类型 + if (m_cache[index].handleType() > appInfo.handleType()) { + m_cache.remove(index); + m_cache << appInfo; + } + } else { + m_cache[index].merge(appInfo); + } + + /* //只要操作类型为delete,直接覆盖 - if (m_cache[index].handleType() == PendingAppInfo::HandleType::Delete - or appInfo.handleType() == PendingAppInfo::HandleType::Delete) { - m_cache[index].setHandleType(PendingAppInfo::HandleType::Delete); + if (m_cache[index].handleType() == PendingAppInfo::Delete + or appInfo.handleType() == PendingAppInfo::Delete) { + m_cache[index].setHandleType(PendingAppInfo::Delete); //已插入项操作类型为对所有desktop文件相关数据进行操作 - } else if (m_cache[index].handleType() < PendingAppInfo::HandleType::UpdateLocaleData - and appInfo.handleType() < PendingAppInfo::HandleType::UpdateLocaleData) { + } else if (m_cache[index].handleType() < PendingAppInfo::UpdateLocaleData + and appInfo.handleType() < PendingAppInfo::UpdateLocaleData) { //设置为优先级高的操作类型 if (m_cache[index].handleType() > appInfo.handleType()) { m_cache[index].setHandleType(appInfo); @@ -34,6 +55,7 @@ void PendingAppInfoQueue::enqueue(const PendingAppInfo &appInfo) } else { m_cache[index].merge(appInfo); } + */ } //启动定时器 @@ -103,40 +125,43 @@ void PendingAppInfoQueue::processCache() if (AppDBManager::getInstance()->startTransaction()) { for (const PendingAppInfo &info : m_pendingAppInfos) { PendingAppInfo::HandleTypes handleTypes = info.handleType(); - if (handleTypes < PendingAppInfo::HandleType::UpdateAll) { + if (handleTypes <= PendingAppInfo::UpdateLocaleData) { switch (handleTypes) { - case PendingAppInfo::HandleType::Delete: + case PendingAppInfo::Delete: AppDBManager::getInstance()->handleDBItemDelete(info.path()); break; - case PendingAppInfo::HandleType::Insert: + case PendingAppInfo::Insert: AppDBManager::getInstance()->handleDBItemInsert(info.path()); break; - case PendingAppInfo::HandleType::UpdateAll: + case PendingAppInfo::UpdateAll: AppDBManager::getInstance()->handleDBItemUpdate(info.path()); break; + case PendingAppInfo::UpdateLocaleData: + AppDBManager::getInstance()->handleLocaleDataUpdate(info.path()); + break; default: break; } } else { - if (handleTypes & PendingAppInfo::HandleType::Insert) { + if (handleTypes & PendingAppInfo::Insert) { AppDBManager::getInstance()->handleDBItemInsert(info.path()); } - if (handleTypes & PendingAppInfo::HandleType::UpdateAll) { + if (handleTypes & PendingAppInfo::UpdateAll) { AppDBManager::getInstance()->handleDBItemUpdate(info.path()); } - if (handleTypes & PendingAppInfo::HandleType::UpdateLocaleData) { + if (handleTypes & PendingAppInfo::UpdateLocaleData) { AppDBManager::getInstance()->handleLocaleDataUpdate(info.path()); } - if (handleTypes & PendingAppInfo::HandleType::UpdateLaunchTimes) { + if (handleTypes & PendingAppInfo::UpdateLaunchTimes) { AppDBManager::getInstance()->handleLaunchTimesUpdate(info.path(), info.launchTimes()); } - if (handleTypes & PendingAppInfo::HandleType::UpdateFavorites) { + if (handleTypes & PendingAppInfo::UpdateFavorites) { AppDBManager::getInstance()->handleFavoritesStateUpdate(info.path(), info.favoritesState()); } - if (handleTypes & PendingAppInfo::HandleType::UpdateTop) { + if (handleTypes & PendingAppInfo::UpdateTop) { AppDBManager::getInstance()->handleTopStateUpdate(info.path(), info.topState()); } - if (handleTypes & PendingAppInfo::HandleType::UpdateLock) { + if (handleTypes & PendingAppInfo::UpdateLock) { AppDBManager::getInstance()->handleLockStateUpdate(info.path(), info.lockState()); } }