feat(app-database-service):add the support for flatpak & kaiming applications.
This commit is contained in:
parent
ad83e40875
commit
3b316f2164
|
@ -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)));
|
||||||
|
|
|
@ -63,3 +63,4 @@ 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/)
|
|
@ -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);
|
|
||||||
if(!androidDir.exists()) {
|
|
||||||
androidDir.mkpath(ANDROID_APP_DESKTOP_PATH);
|
|
||||||
}
|
|
||||||
m_watcher->addWatch(ANDROID_APP_DESKTOP_PATH);
|
|
||||||
|
|
||||||
m_snapdDir = new QDir(SNAPD_APP_DESKTOP_PATH);
|
auto helper = new ApplicationDirWatcherHelper(m_watcher, this);
|
||||||
if(!m_snapdDir->exists()) {
|
for (const QString& appDir : appDirs) {
|
||||||
m_snapdWatcher = new FileSystemWatcher(false);
|
helper->addPath(appDir);
|
||||||
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());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
|
@ -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
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
/usr/share/applications,/var/lib/snapd/desktop/applications,/var/lib/flatpak/exports/share/applications,/var/lib/kaiming/exports/share/applications
|
Loading…
Reference in New Issue