Merge branch '0803ukss' into 'ukss-dev'

Make the appdb dbus autostart.Install the desktop file of app-data-service.Using the file-system-watcher to watch the desktop files' dirs.

See merge request kylin-desktop/ukui-search!358
This commit is contained in:
PengfeiZhang 2022-08-09 05:54:59 +00:00
commit 2fa56ef880
6 changed files with 179 additions and 33 deletions

View File

@ -205,6 +205,7 @@ void FileSystemWatcher::eventProcess(int socket)
const struct inotify_event* event = (struct inotify_event*)&buf[i]; const struct inotify_event* event = (struct inotify_event*)&buf[i];
if(event->name[0] == '.') { if(event->name[0] == '.') {
i += sizeof(struct inotify_event) + event->len;
continue; continue;
} }
if (event->wd < 0 && (event->mask & EventQueueOverflow)) { if (event->wd < 0 && (event->mask & EventQueueOverflow)) {

View File

@ -7,9 +7,9 @@
#include <QCryptographicHash> #include <QCryptographicHash>
#include <QFile> #include <QFile>
#define GENERAL_APP_DESKTOP_PATH "/usr/share/applications/" #define GENERAL_APP_DESKTOP_PATH "/usr/share/applications"
#define ANDROID_APP_DESKTOP_PATH QDir::homePath() + "/.local/share/applications/" #define ANDROID_APP_DESKTOP_PATH QDir::homePath() + "/.local/share/applications"
#define SNAPD_APP_DESKTOP_PATH "/var/lib/snapd/desktop/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 LAST_LOCALE_NAME QDir::homePath() + "/.config/org.ukui/ukui-search/appdata/last-locale-name.conf"
#define LOCALE_NAME_VALUE "CurrentLocaleName" #define LOCALE_NAME_VALUE "CurrentLocaleName"
@ -49,6 +49,100 @@ AppDBManager::AppDBManager(QObject *parent) : QThread(parent), m_database(QSqlDa
refreshAllData2DB(); refreshAllData2DB();
// refreshDataBase(); // 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 //初始化FileSystemWatcher
m_watchAppDir = new QFileSystemWatcher(this); m_watchAppDir = new QFileSystemWatcher(this);
m_watchAppDir->addPath(GENERAL_APP_DESKTOP_PATH); m_watchAppDir->addPath(GENERAL_APP_DESKTOP_PATH);
@ -103,6 +197,7 @@ AppDBManager::AppDBManager(QObject *parent) : QThread(parent), m_database(QSqlDa
Q_EMIT this->stopTimer(); Q_EMIT this->stopTimer();
this->refreshAllData2DB(); this->refreshAllData2DB();
}, Qt::DirectConnection); }, Qt::DirectConnection);
*/
//监控应用进程开启 //监控应用进程开启
connect(KWindowSystem::self(), &KWindowSystem::windowAdded, [ = ](WId id) { connect(KWindowSystem::self(), &KWindowSystem::windowAdded, [ = ](WId id) {
@ -118,10 +213,20 @@ AppDBManager::AppDBManager(QObject *parent) : QThread(parent), m_database(QSqlDa
AppDBManager::~AppDBManager() AppDBManager::~AppDBManager()
{ {
if(m_watchAppDir) { if (m_watcher) {
delete m_watchAppDir; 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(); closeDataBase();
} }

View File

@ -3,6 +3,7 @@
#include "app-db-common.h" #include "app-db-common.h"
#include "pending-app-info-queue.h" #include "pending-app-info-queue.h"
#include "file-system-watcher.h"
#include <QDir> #include <QDir>
#include <QObject> #include <QObject>
@ -12,11 +13,11 @@
#include <QDebug> #include <QDebug>
#include <QApplication> #include <QApplication>
#include <QDateTime> #include <QDateTime>
#include <QFileSystemWatcher>
#include <QMutex> #include <QMutex>
#include <QSettings> #include <QSettings>
#include <QTimer>
#include <QThread> #include <QThread>
//#include <QTimer>
//#include <QFileSystemWatcher>
#define CONNECTION_NAME QLatin1String("ukss-appdb-connection") #define CONNECTION_NAME QLatin1String("ukss-appdb-connection")
@ -132,11 +133,16 @@ private:
QSettings *m_qSettings = nullptr; QSettings *m_qSettings = nullptr;
QTimer *m_timer = nullptr; // QTimer *m_timer = nullptr;
QTimer *m_maxProcessTimer = nullptr; // QTimer *m_maxProcessTimer = nullptr;
// QFileSystemWatcher *m_watchAppDir = nullptr;
QSqlDatabase m_database; 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 = { QStringList m_excludedDesktopfiles = {

View File

@ -0,0 +1,3 @@
[D-BUS Service]
Name=com.ukui.search.appdb.service
Exec=/usr/bin/ukui-search-app-data-service

View File

@ -15,18 +15,39 @@ void PendingAppInfoQueue::enqueue(const PendingAppInfo &appInfo)
{ {
QMutexLocker locker(&s_mutex); QMutexLocker locker(&s_mutex);
m_handleTimes++; m_handleTimes++;
int index = m_cache.indexOf(appInfo); int index = m_cache.lastIndexOf(appInfo);
if (index == -1) { if (index == -1) {
m_cache << appInfo; m_cache << appInfo;
} else { } 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直接覆盖 //只要操作类型为delete直接覆盖
if (m_cache[index].handleType() == PendingAppInfo::HandleType::Delete if (m_cache[index].handleType() == PendingAppInfo::Delete
or appInfo.handleType() == PendingAppInfo::HandleType::Delete) { or appInfo.handleType() == PendingAppInfo::Delete) {
m_cache[index].setHandleType(PendingAppInfo::HandleType::Delete); m_cache[index].setHandleType(PendingAppInfo::Delete);
//已插入项操作类型为对所有desktop文件相关数据进行操作 //已插入项操作类型为对所有desktop文件相关数据进行操作
} else if (m_cache[index].handleType() < PendingAppInfo::HandleType::UpdateLocaleData } else if (m_cache[index].handleType() < PendingAppInfo::UpdateLocaleData
and appInfo.handleType() < PendingAppInfo::HandleType::UpdateLocaleData) { and appInfo.handleType() < PendingAppInfo::UpdateLocaleData) {
//设置为优先级高的操作类型 //设置为优先级高的操作类型
if (m_cache[index].handleType() > appInfo.handleType()) { if (m_cache[index].handleType() > appInfo.handleType()) {
m_cache[index].setHandleType(appInfo); m_cache[index].setHandleType(appInfo);
@ -34,6 +55,7 @@ void PendingAppInfoQueue::enqueue(const PendingAppInfo &appInfo)
} else { } else {
m_cache[index].merge(appInfo); m_cache[index].merge(appInfo);
} }
*/
} }
//启动定时器 //启动定时器
@ -103,40 +125,43 @@ void PendingAppInfoQueue::processCache()
if (AppDBManager::getInstance()->startTransaction()) { if (AppDBManager::getInstance()->startTransaction()) {
for (const PendingAppInfo &info : m_pendingAppInfos) { for (const PendingAppInfo &info : m_pendingAppInfos) {
PendingAppInfo::HandleTypes handleTypes = info.handleType(); PendingAppInfo::HandleTypes handleTypes = info.handleType();
if (handleTypes < PendingAppInfo::HandleType::UpdateAll) { if (handleTypes <= PendingAppInfo::UpdateLocaleData) {
switch (handleTypes) { switch (handleTypes) {
case PendingAppInfo::HandleType::Delete: case PendingAppInfo::Delete:
AppDBManager::getInstance()->handleDBItemDelete(info.path()); AppDBManager::getInstance()->handleDBItemDelete(info.path());
break; break;
case PendingAppInfo::HandleType::Insert: case PendingAppInfo::Insert:
AppDBManager::getInstance()->handleDBItemInsert(info.path()); AppDBManager::getInstance()->handleDBItemInsert(info.path());
break; break;
case PendingAppInfo::HandleType::UpdateAll: case PendingAppInfo::UpdateAll:
AppDBManager::getInstance()->handleDBItemUpdate(info.path()); AppDBManager::getInstance()->handleDBItemUpdate(info.path());
break; break;
case PendingAppInfo::UpdateLocaleData:
AppDBManager::getInstance()->handleLocaleDataUpdate(info.path());
break;
default: default:
break; break;
} }
} else { } else {
if (handleTypes & PendingAppInfo::HandleType::Insert) { if (handleTypes & PendingAppInfo::Insert) {
AppDBManager::getInstance()->handleDBItemInsert(info.path()); AppDBManager::getInstance()->handleDBItemInsert(info.path());
} }
if (handleTypes & PendingAppInfo::HandleType::UpdateAll) { if (handleTypes & PendingAppInfo::UpdateAll) {
AppDBManager::getInstance()->handleDBItemUpdate(info.path()); AppDBManager::getInstance()->handleDBItemUpdate(info.path());
} }
if (handleTypes & PendingAppInfo::HandleType::UpdateLocaleData) { if (handleTypes & PendingAppInfo::UpdateLocaleData) {
AppDBManager::getInstance()->handleLocaleDataUpdate(info.path()); AppDBManager::getInstance()->handleLocaleDataUpdate(info.path());
} }
if (handleTypes & PendingAppInfo::HandleType::UpdateLaunchTimes) { if (handleTypes & PendingAppInfo::UpdateLaunchTimes) {
AppDBManager::getInstance()->handleLaunchTimesUpdate(info.path(), info.launchTimes()); AppDBManager::getInstance()->handleLaunchTimesUpdate(info.path(), info.launchTimes());
} }
if (handleTypes & PendingAppInfo::HandleType::UpdateFavorites) { if (handleTypes & PendingAppInfo::UpdateFavorites) {
AppDBManager::getInstance()->handleFavoritesStateUpdate(info.path(), info.favoritesState()); AppDBManager::getInstance()->handleFavoritesStateUpdate(info.path(), info.favoritesState());
} }
if (handleTypes & PendingAppInfo::HandleType::UpdateTop) { if (handleTypes & PendingAppInfo::UpdateTop) {
AppDBManager::getInstance()->handleTopStateUpdate(info.path(), info.topState()); AppDBManager::getInstance()->handleTopStateUpdate(info.path(), info.topState());
} }
if (handleTypes & PendingAppInfo::HandleType::UpdateLock) { if (handleTypes & PendingAppInfo::UpdateLock) {
AppDBManager::getInstance()->handleLockStateUpdate(info.path(), info.lockState()); AppDBManager::getInstance()->handleLockStateUpdate(info.path(), info.lockState());
} }
} }

View File

@ -41,8 +41,13 @@ HEADERS += \
signal-transformer.h \ signal-transformer.h \
ukui-search-app-data-service.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 target.path = /usr/bin
INSTALLS += target INSTALLS += \
target \
inst1
desktop.path = /etc/xdg/autostart desktop.path = /etc/xdg/autostart
desktop.files += ../data/ukui-search-app-data-service.desktop desktop.files += ../data/ukui-search-app-data-service.desktop
@ -53,5 +58,6 @@ INCLUDEPATH += $$PWD/../libchinese-segmentation
DEPENDPATH += $$PWD/../libchinese-segmentation DEPENDPATH += $$PWD/../libchinese-segmentation
LIBS += -L$$OUT_PWD/../libsearch/ -lukui-search LIBS += -L$$OUT_PWD/../libsearch/ -lukui-search
INCLUDEPATH += $$PWD/../libsearch INCLUDEPATH += $$PWD/../libsearch \
$$PWD/../libsearch/filesystemwatcher
DEPENDPATH += $$PWD/../libsearch DEPENDPATH += $$PWD/../libsearch