feat(app-database-service):add the support for flatpak & kaiming applications.

This commit is contained in:
JunjieBai 2023-12-04 16:49:52 +08:00
parent ad83e40875
commit 3b316f2164
5 changed files with 83 additions and 113 deletions

View File

@ -37,7 +37,7 @@ AppInfoTablePrivate::AppInfoTablePrivate(AppInfoTable *parent) : QObject(parent)
"org.ukui.search.signalTransformer"); "org.ukui.search.signalTransformer");
if (!m_signalTransInterface->isValid()) { if (!m_signalTransInterface->isValid()) {
qCritical() << "Create privateDirWatcher Interface Failed Because: " << QDBusConnection::sessionBus().lastError(); qCritical() << "Create signalTransformer Interface Failed Because: " << QDBusConnection::sessionBus().lastError();
return; return;
} else { } else {
connect(m_signalTransInterface, SIGNAL(appDBItemsUpdate(ApplicationInfoMap)), this, SLOT(sendAppDBItemsUpdate(ApplicationInfoMap))); connect(m_signalTransInterface, SIGNAL(appDBItemsUpdate(ApplicationInfoMap)), this, SLOT(sendAppDBItemsUpdate(ApplicationInfoMap)));

View File

@ -62,4 +62,5 @@ target_link_libraries(ukui-search-app-data-service PRIVATE
install(TARGETS ukui-search-app-data-service DESTINATION /usr/bin) install(TARGETS ukui-search-app-data-service DESTINATION /usr/bin)
install(FILES ../data/ukui-search-app-data-service.desktop DESTINATION /etc/xdg/autostart) install(FILES ../data/ukui-search-app-data-service.desktop DESTINATION /etc/xdg/autostart)
install(FILES conf/com.ukui.search.appdb.service DESTINATION /usr/share/dbus-1/services/) install(FILES conf/com.ukui.search.appdb.service DESTINATION /usr/share/dbus-1/services/)
install(FILES conf/application-dirs.conf DESTINATION /etc/ukui/ukui-search/)

View File

@ -37,6 +37,8 @@
#define APP_DATABASE_VERSION_CONFIG QDir::homePath() + "/.config/org.ukui/ukui-search/appdata/app-database-version.conf" #define APP_DATABASE_VERSION_CONFIG QDir::homePath() + "/.config/org.ukui/ukui-search/appdata/app-database-version.conf"
#define APP_DATABASE_VERSION_VALUE "AppDatabaseVersion" #define APP_DATABASE_VERSION_VALUE "AppDatabaseVersion"
static const QString AUTOSTART_APP_DESKTOP_PATH = "/etc/xdg/autostart"; static const QString AUTOSTART_APP_DESKTOP_PATH = "/etc/xdg/autostart";
static const QString ALL_APP_DIRS_CONF = "/etc/ukui/ukui-search/application-dirs.conf";
using namespace UkuiSearch; using namespace UkuiSearch;
static AppDBManager *global_instance; static AppDBManager *global_instance;
@ -98,9 +100,13 @@ AppDBManager::AppDBManager(QObject *parent) : QThread(parent), m_database(QSqlDa
} }
//刷新应用数据 //刷新应用数据
QStringList appPaths; QFile file(ALL_APP_DIRS_CONF);
appPaths << GENERAL_APP_DESKTOP_PATH << ANDROID_APP_DESKTOP_PATH file.open(QIODevice::ReadOnly);
<< SNAPD_APP_DESKTOP_PATH << AUTOSTART_APP_DESKTOP_PATH; QString content = file.readAll();
file.close();
QStringList appPaths = content.split(",",Qt::SkipEmptyParts);
appPaths.append(ANDROID_APP_DESKTOP_PATH);
refreshAllData2DB(appPaths, m_dbVersionNeedUpdate); refreshAllData2DB(appPaths, m_dbVersionNeedUpdate);
if (m_dbVersionNeedUpdate) { if (m_dbVersionNeedUpdate) {
@ -111,64 +117,7 @@ AppDBManager::AppDBManager(QObject *parent) : QThread(parent), m_database(QSqlDa
} }
//初始化FileSystemWatcher //初始化FileSystemWatcher
initFileSystemWatcher(); initFileSystemWatcher(appPaths);
/*
//初始化FileSystemWatcher
m_watchAppDir = new QFileSystemWatcher(this);
m_watchAppDir->addPath(GENERAL_APP_DESKTOP_PATH);
QDir androidPath(ANDROID_APP_DESKTOP_PATH);
if(!androidPath.exists()) {
androidPath.mkpath(ANDROID_APP_DESKTOP_PATH);
}
m_watchAppDir->addPath(ANDROID_APP_DESKTOP_PATH);
QDir snapdPath(SNAPD_APP_DESKTOP_PATH);
if(!snapdPath.exists()) {
snapdPath.mkpath(SNAPD_APP_DESKTOP_PATH);
}
m_watchAppDir->addPath(SNAPD_APP_DESKTOP_PATH);
//初始化timer
this->start();
m_timer = new QTimer();
m_maxProcessTimer = new QTimer();
m_timer->setInterval(2*1000);
m_maxProcessTimer->setInterval(5*1000);
m_timer->setSingleShot(true);
m_maxProcessTimer->setSingleShot(true);
m_timer->moveToThread(this);
m_maxProcessTimer->moveToThread(this);
connect(this, SIGNAL(startTimer()), m_timer, SLOT(start()));
connect(this, SIGNAL(maxProcessTimerStart()), m_maxProcessTimer, SLOT(start()));
connect(this, &AppDBManager::stopTimer, m_timer, &QTimer::stop);
connect(this, &AppDBManager::stopTimer, m_maxProcessTimer, &QTimer::stop);
//监听desktop文件所在目录由于directoryChange会发多次信号使用计时器阻塞
connect(m_watchAppDir, &QFileSystemWatcher::directoryChanged, this, [ = ](const QString & path) {
qDebug() << "m_watchAppDir directoryChanged:" << path;
Q_EMIT this->startTimer();
if (!m_maxProcessTimer->isActive()) {
Q_EMIT this->maxProcessTimerStart();
}
});
//计时器超时统一进行更新操作
connect(m_timer, &QTimer::timeout, this, [ & ] {
qDebug() << "Time out! Now I can update the database!";
Q_EMIT this->stopTimer();
this->refreshAllData2DB();
}, Qt::DirectConnection);
connect(m_maxProcessTimer, &QTimer::timeout, this, [ & ] {
qDebug() << "I've waited too lang, I have to update the database now!";
Q_EMIT this->stopTimer();
this->refreshAllData2DB();
}, Qt::DirectConnection);
*/
m_processManagerInterface = new QDBusInterface(QStringLiteral("com.kylin.ProcessManager"), m_processManagerInterface = new QDBusInterface(QStringLiteral("com.kylin.ProcessManager"),
QStringLiteral("/com/kylin/ProcessManager/AppLauncher"), QStringLiteral("/com/kylin/ProcessManager/AppLauncher"),
@ -250,58 +199,14 @@ void AppDBManager::buildAppInfoDB()
} }
} }
void AppDBManager::initFileSystemWatcher() void AppDBManager::initFileSystemWatcher(const QStringList& appDirs)
{ {
m_watcher = new FileSystemWatcher; m_watcher = new FileSystemWatcher;
m_watcher->addWatch(GENERAL_APP_DESKTOP_PATH);
QDir androidDir(ANDROID_APP_DESKTOP_PATH); auto helper = new ApplicationDirWatcherHelper(m_watcher, this);
if(!androidDir.exists()) { for (const QString& appDir : appDirs) {
androidDir.mkpath(ANDROID_APP_DESKTOP_PATH); helper->addPath(appDir);
} }
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);
}
m_watcher->addWatch(AUTOSTART_APP_DESKTOP_PATH);
connect(m_snapdWatcher, &FileSystemWatcher::created, this, [ = ] (const QString &path, bool isDir) {
if (isDir) {
//监测新增目录为/var/lib/snapd时将其替换为snapdWatcher的watch path
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) { connect(m_watcher, &FileSystemWatcher::created, this, [ = ] (const QString &desktopfp, bool isDir) {
//event is IN_CREATE //event is IN_CREATE
@ -1702,3 +1607,55 @@ void AppDBManager::handleAppLaunched(QString desktopFilePath) {
qWarning() << "desktopFilePath is empty."; qWarning() << "desktopFilePath is empty.";
} }
} }
ApplicationDirWatcherHelper::ApplicationDirWatcherHelper(FileSystemWatcher *watcher, QObject *parent) : QObject(parent), m_watcher(watcher)
{
}
void ApplicationDirWatcherHelper::addPath(const QString &path) {
QDir dir(path);
if (dir.exists() || dir.mkpath(path)) {
qDebug() << "=====add desktop watch=====" << path;
m_watcher->addWatch(path);
return;
}
auto watcher = new FileSystemWatcher(false);
m_watcherMap.insert(path, watcher);
while (!dir.exists()) {
QString dirPath = dir.absolutePath();
dir.setPath(dirPath.left(dirPath.lastIndexOf("/")));
}
qDebug() << "=====addWatch=====" << dir.absolutePath();
watcher->addWatch(dir.absolutePath());
connect(watcher, &FileSystemWatcher::created, this, [ &,watcher ] (const QString &path, bool isDir) {
if (isDir) {
QString appPath = m_watcherMap.key(watcher);
if (appPath == path) {
qDebug() << "=====add desktop watch=====" << appPath;
m_watcher->addWatch(path);
m_watcherMap.value(appPath)->deleteLater();
m_watcherMap.remove(appPath);
} else if (appPath.startsWith(path+ "/")) {
watcher->clearAll();
QDir dir(appPath);
//会有类似mkdir -p的一次性将子文件夹创建出来的情况需要挨层判断
while (!dir.exists()) {
dir.setPath(dir.absolutePath().left(dir.absolutePath().lastIndexOf("/")));
}
if (dir.absolutePath() == appPath) {
qDebug() << "=====add desktop watch=====" << appPath;
m_watcher->addWatch(appPath);
m_watcherMap.value(appPath)->deleteLater();
m_watcherMap.remove(appPath);
} else {
qDebug() << "=====addWatch=====" << dir.absolutePath();
watcher->addWatch(dir.absolutePath());
}
}
}
});
}

View File

@ -135,7 +135,7 @@ private:
void buildAppInfoDB(); void buildAppInfoDB();
//初始化fileSystemWatcher //初始化fileSystemWatcher
void initFileSystemWatcher(); void initFileSystemWatcher(const QStringList& appDirs);
//处理置顶收藏移动位置 //处理置顶收藏移动位置
bool handleChangeFavoritesPos(const QString &desktopFilePath, const uint pos, const uint previousPos, ApplicationInfoMap &updatedInfo); bool handleChangeFavoritesPos(const QString &desktopFilePath, const uint pos, const uint previousPos, ApplicationInfoMap &updatedInfo);
@ -253,6 +253,17 @@ Q_SIGNALS:
void maxProcessTimerStart(); void maxProcessTimerStart();
void stopTimer(); void stopTimer();
}; };
class ApplicationDirWatcherHelper : public QObject
{
Q_OBJECT
public:
explicit ApplicationDirWatcherHelper(FileSystemWatcher *watcher,QObject *parent = nullptr);
void addPath(const QString& path);
private:
FileSystemWatcher *m_watcher = nullptr;
QMap<QString, FileSystemWatcher *> m_watcherMap;
};
} }
#endif // APPDBMANAGER_H #endif // APPDBMANAGER_H

View File

@ -0,0 +1 @@
/usr/share/applications,/var/lib/snapd/desktop/applications,/var/lib/flatpak/exports/share/applications,/var/lib/kaiming/exports/share/applications