diff -Nru ukui-screensaver-4.20.0.0/debian/changelog ukui-screensaver-4.20.0.0/debian/changelog
--- ukui-screensaver-4.20.0.0/debian/changelog	2024-12-17 13:37:23.000000000 +0800
+++ ukui-screensaver-4.20.0.0/debian/changelog	2025-02-13 20:26:40.000000000 +0800
@@ -1,3 +1,21 @@
+ukui-screensaver (4.20.0.0-ok3.3) huanghe; urgency=medium
+
+  * BUG号:无
+  * 需求号:无
+  * 其他改动说明:增加单元测试;迁移控制面板锁屏、屏保插件
+  * 其他改动影响域:无
+
+ -- Yang Min <yangmin@kylinos.cn>  Thu, 13 Feb 2025 20:26:40 +0800
+
+ukui-screensaver (4.20.0.0-ok3.2) huanghe; urgency=medium
+
+  * BUG号:无
+  * 需求号:无
+  * 其他改动说明:同步v11-2503代码修改
+  * 其他改动影响域:无 
+
+ -- Yang Min <yangmin@kylinos.cn>  Fri, 03 Jan 2025 19:14:46 +0800
+
 ukui-screensaver (4.20.0.0-ok3.1) huanghe; urgency=medium
 
   * BUG号:无
diff -Nru ukui-screensaver-4.20.0.0/debian/control ukui-screensaver-4.20.0.0/debian/control
--- ukui-screensaver-4.20.0.0/debian/control	2024-12-17 13:37:23.000000000 +0800
+++ ukui-screensaver-4.20.0.0/debian/control	2025-02-13 20:26:40.000000000 +0800
@@ -35,12 +35,15 @@
                libavformat-dev,
                qtmultimedia5-dev,
 	       libkysdk-systime-dev,
+               libkysdk-qtwidgets-dev,
+               libkysdk-diagnostics-dev,
                libkysdk-waylandhelper-dev,
                liblightdm-qt5-3-dev,
                libsystemd-dev,
                libssl-dev,
                libxrandr-dev,
-               libcharls-dev
+               libcharls-dev,
+               libukcc-dev
 Standards-Version: 4.5.0
 Rules-Requires-Root: no
 Homepage: https://www.github.com/ukui/ukui-screensaver
diff -Nru ukui-screensaver-4.20.0.0/debian/patches/0003-ok.patch ukui-screensaver-4.20.0.0/debian/patches/0003-ok.patch
--- ukui-screensaver-4.20.0.0/debian/patches/0003-ok.patch	1970-01-01 08:00:00.000000000 +0800
+++ ukui-screensaver-4.20.0.0/debian/patches/0003-ok.patch	2025-02-13 20:26:40.000000000 +0800
@@ -0,0 +1,182 @@
+From: yangmin100 <yangmin@kylinos.cn>
+Date: Fri, 15 Nov 2024 10:53:23 +0800
+Subject: =?utf-8?b?b2vkvb/nlKjnpL7ljLrniYjor63lvZU=?=
+
+---
+ src/common/global_utils.h                         |   6 ++
+ src/screensaver/CMakeLists.txt                    |   1 +
+ src/screensaver/language/screensaver-zh_CN-ok.ini | 121 ++++++++++++++++++++++
+ src/screensaver/screensaver.cpp                   |   3 +
+ 4 files changed, 131 insertions(+)
+ create mode 100644 src/screensaver/language/screensaver-zh_CN-ok.ini
+
+diff --git a/src/common/global_utils.h b/src/common/global_utils.h
+index 8bdaa61..425d4d4 100644
+--- a/src/common/global_utils.h
++++ b/src/common/global_utils.h
+@@ -42,6 +42,12 @@ QString getHostCloudPlatform();
+ 
+ bool isCommunity();
+ 
++/**
++ * @brief isOpenkylin 是否为ok环境
++ * @return true 是,否则不是
++ */
++bool isOpenkylin();
++
+ QString getDefaultFace();
+ 
+ void setFcitxExport();
+diff --git a/src/screensaver/CMakeLists.txt b/src/screensaver/CMakeLists.txt
+index 194af1c..ada55ef 100644
+--- a/src/screensaver/CMakeLists.txt
++++ b/src/screensaver/CMakeLists.txt
+@@ -172,6 +172,7 @@ install(FILES
+ 	language/screensaver-en_US.ini
+         language/screensaver-bo_CN.ini
+ 	language/screensaver-jd.ini
++        language/screensaver-zh_CN-ok.ini
+         DESTINATION share/ukui-screensaver/language)
+ 
+ install(FILES
+diff --git a/src/screensaver/language/screensaver-zh_CN-ok.ini b/src/screensaver/language/screensaver-zh_CN-ok.ini
+new file mode 100644
+index 0000000..51b93e7
+--- /dev/null
++++ b/src/screensaver/language/screensaver-zh_CN-ok.ini
+@@ -0,0 +1,121 @@
++[1]
++FL=世上的事,只要肯用心去学,
++SL=没有一件是太晚的。
++author=三毛《送你一匹马》
++[2]
++OL=如果你是大河,何必在乎别人把你当成小溪。
++author=汪国真 《如果》
++[3]
++OL=世界上有不绝的风景,我有不老的心情。
++author=汪国真《我喜欢出发》
++[4]
++OL=人生如逆旅,我亦是行人。
++author=苏轼《临江仙·送钱穆父》
++[5]
++OL=行乐直须年少,尊前看取衰翁。
++author=欧阳修《朝中措·送刘仲原甫出守维扬》
++[6]
++OL=行到水穷处,坐看云起时。
++author=王维《终南别业》
++[7]
++OL=仰天大笑出门去,我辈岂是蓬蒿人。
++author=李白《南陵别儿童入京》
++[8]
++OL=天生我材必有用,千金散尽还复来。
++author=李白《将进酒》
++[9]
++OL=希君生羽翼,一化北溟鱼。
++author=李白《江夏使君叔席上赠史郎中》
++[10]
++OL=惟沉默是最高的轻蔑。
++author=鲁迅《且介亭杂文附集》
++[11]
++OL=虽偶有轻风细雨,但总归晴天朗照。
++author=史铁生《记忆与印象》
++[12]
++OL=不能走远路却有辽阔的心。
++author=史铁生《我与地坛》
++[13]
++OL=从卖气球的人那里,每个孩子牵走一个心愿。
++author=北岛《代课》
++[14]
++OL=要有最朴素的生活和最遥远的梦想
++author=海子《枫》
++[15]
++OL=雾打湿了我的双翼,可风却不容我再迟疑。
++author=舒婷《双桅船》
++[16]
++OL=拯救地球好累,虽然有些疲惫但我还是会。
++author=《超人不会飞》
++[17]
++OL=宁可一思进,莫在一思停。
++author=电影《一代宗师》
++[18]
++OL=让人类永远保持理智,确实是一件奢侈的事。
++author=电影《流浪地球》
++[19]
++FL=无论结果如何,人类的勇气和坚毅,
++SL=都被镌刻在星空下。
++author=电影《流浪地球》
++[20]
++OL=生活就像一盒巧克力,你不知道你的下一块口味是什么。
++author=电影《阿甘正传》
++[21]
++FL=也许我们这些聪明人,脑袋里能装的目标太多,
++SL=所以忘了执着。
++author=电影《阿甘正传》
++[22]
++FL=我并不是每次吃完饭就看电视,有时我边吃边看电视,
++SL=生活中有些改变会增加乐趣。
++author=电影《加菲猫》
++[23]
++OL=做人如果没梦想,那跟咸鱼有什么分别?
++author=电影《少林足球》
++[24]
++FL=世界上有一种鸟是关不住的,因为它们的每一片羽毛都沾满了太阳的光辉。
++SL=当它们飞走的时候,你会觉得把它关起来是一种罪恶。
++author=电影《肖申克的救赎》
++[25]
++FL=你每天都在做很多看起来毫无意义的决定,
++SL=但某天你的某个决定就能改变你一生。
++author=电影《西雅图未眠夜》
++[26]
++FL=把人类看做虫子的三体人似乎忘记了一个事实:
++SL=虫子从来没有被战胜过。
++author=刘慈欣《三体》
++[27]
++FL=在宇宙中,你再快都有比你更快的,
++SL=你再慢也有比你更慢的。
++author=刘慈欣《三体》
++[28]
++OL=人间风雨各处有,何处不是浪浪山?
++author=国漫《小妖怪的夏天》
++[29]
++FL=我看到那些岁月如何奔驰,
++SL=挨过了冬季,便迎来了春天。
++author=《瓦尔登湖》
++[30]
++OL=保持热爱,奔赴山海。
++author=佚名
++[31]
++OL=别慌,月亮也正在大海某处迷茫。
++author=佚名
++[32]
++OL=当太阳升到最高点的时候,影子就不见了。
++author=佚名
++[33]
++OL=大直若屈,大巧若拙,大辩若讷。
++author=《老子》
++[34]
++OL=博学之,审问之,慎思之,明辨之,笃行之。
++author=《礼记》
++[35]
++OL=你要批评指点四周的风景,你首先要爬上屋顶。
++author=歌德
++[36]
++OL=只有流过血的手指,才能弹出世间的绝唱。
++author=泰戈尔
++[37]
++OL=他强任他强,清风拂山岗。
++author=佚名
++
+diff --git a/src/screensaver/screensaver.cpp b/src/screensaver/screensaver.cpp
+index 578fa3a..71e2f0a 100644
+--- a/src/screensaver/screensaver.cpp
++++ b/src/screensaver/screensaver.cpp
+@@ -713,6 +713,9 @@ void Screensaver::setUpdateCenterWidget()
+ 
+         // 不管系统语言,默认显示中文
+         QString languageFilePath = languageDirPath + "screensaver-zh_CN.ini";
++        if (isOpenkylin()) {
++            languageFilePath = languageDirPath + "screensaver-zh_CN-ok.ini";
++        }
+         // QString languageFilePath=languageDirPath+"screensaver-"+lang+".ini";
+         QString homeLanguageFilePath = homePath + "/.config/ukui/screensaver-" + lang + ".ini";
+         QString jdLanguageFilePath = languageDirPath + "screensaver-jd" + ".ini";
diff -Nru ukui-screensaver-4.20.0.0/debian/patches/0004-sysc-codes-from-v11-2503.patch ukui-screensaver-4.20.0.0/debian/patches/0004-sysc-codes-from-v11-2503.patch
--- ukui-screensaver-4.20.0.0/debian/patches/0004-sysc-codes-from-v11-2503.patch	1970-01-01 08:00:00.000000000 +0800
+++ ukui-screensaver-4.20.0.0/debian/patches/0004-sysc-codes-from-v11-2503.patch	2025-02-13 20:26:40.000000000 +0800
@@ -0,0 +1,1812 @@
+From: yangmin100 <yangmin@kylinos.cn>
+Date: Fri, 3 Jan 2025 14:42:13 +0800
+Subject: sysc codes from v11-2503
+
+---
+ src/common/configuration.cpp            |  24 -------
+ src/common/configuration.h              |   3 -
+ src/common/utils.cpp                    |   3 +
+ src/dbusifs/kglobalaccelhelper.cpp      |  13 ++--
+ src/dbusifs/uniauthservice.cpp          | 123 +++++++++++++++++++++++++++++++-
+ src/dbusifs/uniauthservice.h            |  93 +++++++++++++++++++++++-
+ src/lock-backend/bioauthenticate.cpp    |  31 ++++----
+ src/lock-backend/bioauthenticate.h      |   1 -
+ src/lock-backend/dbusupperinterface.cpp |  44 ++++++++----
+ src/lock-backend/dbusupperinterface.h   |   2 +-
+ src/lock-backend/lightdmhelper.cpp      |  24 +++++--
+ src/lock-backend/main.cpp               |   3 +
+ src/lock-backend/switchuserutils.cpp    |   9 +++
+ src/lock-dialog/backenddbushelper.cpp   |   3 +-
+ src/lock-dialog/backenddbushelper.h     |   2 +-
+ src/lock-dialog/lockdialogmodel.cpp     |   2 +-
+ src/lock-dialog/lockdialogmodel.h       |   2 +-
+ src/lock-dialog/main.cpp                |  30 +++++---
+ src/screensaver/main.cpp                |   3 +
+ src/screensaver/scconfiguration.cpp     |   9 ++-
+ src/screensaver/screensaver.cpp         |  47 ++++++------
+ src/widgets/authdialog.cpp              |  14 ++--
+ src/widgets/authdialog.h                |   3 +-
+ src/widgets/blockwidget.cpp             |  41 +++++++++--
+ src/widgets/blockwidget.h               |   1 +
+ src/widgets/fullbackgroundwidget.cpp    |  41 +++++++----
+ src/widgets/lockwidget.cpp              | 120 +++++++++++++++++++++----------
+ src/widgets/lockwidget.h                |   9 ++-
+ src/widgets/loginoptionswidget.cpp      |  27 ++++---
+ src/widgets/loginoptionswidget.h        |   3 +-
+ src/widgets/mpriswidget.cpp             |  18 ++++-
+ src/widgets/mpriswidget.h               |   7 ++
+ src/widgets/powerlistwidget.cpp         |  18 +++++
+ src/widgets/powerlistwidget.h           |   3 +
+ src/widgets/screensaverwidget.cpp       |   2 +-
+ 35 files changed, 586 insertions(+), 192 deletions(-)
+
+diff --git a/src/common/configuration.cpp b/src/common/configuration.cpp
+index 85a80d9..9db84f7 100644
+--- a/src/common/configuration.cpp
++++ b/src/common/configuration.cpp
+@@ -90,30 +90,6 @@ bool Configuration::hasValue(const QString &key)
+     return value;
+ }
+ 
+-QString Configuration::getLastLoginUser()
+-{
+-    recordSettings->beginGroup("Greeter");
+-    QString lastLoginUser = recordSettings->value("lastLoginUser").toString();
+-    recordSettings->endGroup();
+-    return lastLoginUser;
+-}
+-
+-void Configuration::saveLastLoginUser(const QString &userRealName)
+-{
+-    recordSettings->beginGroup("Greeter");
+-    recordSettings->setValue("lastLoginUser", userRealName);
+-    recordSettings->endGroup();
+-    recordSettings->sync();
+-}
+-
+-void Configuration::saveLastLoginUser1(const QString &userRealName)
+-{
+-    recordSettings->beginGroup("Greeter");
+-    recordSettings->setValue("lastLoginUser1", userRealName);
+-    recordSettings->endGroup();
+-    recordSettings->sync();
+-}
+-
+ bool Configuration::getLastNumLock()
+ {
+     recordSettings->beginGroup("Greeter");
+diff --git a/src/common/configuration.h b/src/common/configuration.h
+index dc01545..ba9142e 100644
+--- a/src/common/configuration.h
++++ b/src/common/configuration.h
+@@ -38,9 +38,6 @@ public:
+     bool hasValue(const QString &);
+ 
+     void getCurrentUser(const QString userName);
+-    QString getLastLoginUser();
+-    void saveLastLoginUser(const QString &);
+-    void saveLastLoginUser1(const QString &);
+     bool getLastNumLock();
+     void saveLastNumLock(bool value);
+     int getRootBackgroundOption(QString userName);
+diff --git a/src/common/utils.cpp b/src/common/utils.cpp
+index 22ddf60..c7641c7 100644
+--- a/src/common/utils.cpp
++++ b/src/common/utils.cpp
+@@ -108,6 +108,9 @@ bool checkCapsLockState()
+         }
+     }
+ 
++    if (QString(qgetenv("XDG_SESSION_TYPE")) == "wayland") {
++        return false;
++    }
+     bool capsState = false;
+     unsigned int n;
+     XkbGetIndicatorState(QX11Info::display(), XkbUseCoreKbd, &n);
+diff --git a/src/dbusifs/kglobalaccelhelper.cpp b/src/dbusifs/kglobalaccelhelper.cpp
+index 1094cc6..070b404 100644
+--- a/src/dbusifs/kglobalaccelhelper.cpp
++++ b/src/dbusifs/kglobalaccelhelper.cpp
+@@ -36,10 +36,15 @@ KglobalAccelHelper::~KglobalAccelHelper() {}
+ 
+ bool KglobalAccelHelper::blockShortcut(bool val)
+ {
+-    QDBusMessage result = m_kglobalInterface->call("blockGlobalShortcuts", val);
+-    if (result.type() == QDBusMessage::ErrorMessage) {
+-        qWarning() << "blockShortcut error:" << result.errorMessage();
++    qDebug()<<"m_kglobalInterface isvalid:"<<m_kglobalInterface->isValid();
++    if (m_kglobalInterface->isValid()) {
++        QDBusMessage result = m_kglobalInterface->call("blockGlobalShortcuts", val);
++        if (result.type() == QDBusMessage::ErrorMessage) {
++            qWarning() << "blockShortcut error:" << result.errorMessage();
++            return false;
++        }
++        return true;
++    } else {
+         return false;
+     }
+-    return true;
+ }
+diff --git a/src/dbusifs/uniauthservice.cpp b/src/dbusifs/uniauthservice.cpp
+index 90b165b..1657b24 100644
+--- a/src/dbusifs/uniauthservice.cpp
++++ b/src/dbusifs/uniauthservice.cpp
+@@ -21,11 +21,38 @@
+ #include "definetypes.h"
+ #include "freedesktophelper.h"
+ 
++/* For the type WillLoginUserInfo */
++QDBusArgument &operator<<(QDBusArgument &argument, const WillLoginUserInfo &willLoginUserInfo)
++{
++    argument.beginStructure();
++    argument << willLoginUserInfo.strUserName << willLoginUserInfo.isOneKeyLogin;
++    argument.endStructure();
++    return argument;
++}
++
++const QDBusArgument &operator>>(const QDBusArgument &argument, WillLoginUserInfo &willLoginUserInfo)
++{
++    argument.beginStructure();
++    argument >> willLoginUserInfo.strUserName >> willLoginUserInfo.isOneKeyLogin;
++    argument.endStructure();
++    return argument;
++}
++
++QDebug operator<<(QDebug stream, const WillLoginUserInfo &willLoginUserInfo)
++{
++    stream << "WillLogUser [" << willLoginUserInfo.strUserName << willLoginUserInfo.isOneKeyLogin << "]";
++    return stream;
++}
++
++UniAuthService *UniAuthService::m_instance = nullptr;
++UniAuthService::MemCollector UniAuthService::m_memCollector;
+ UniAuthService::UniAuthService(QObject *parent)
+     : QDBusAbstractInterface(
+         UNIAUTH_DBUS_SERVICE, UNIAUTH_DBUS_PATH, UNIAUTH_DBUS_INTERFACE, QDBusConnection::systemBus(), parent)
+     , m_isActivatable(false)
+ {
++    qRegisterMetaType<WillLoginUserInfo>("WillLoginUserInfo");
++    qDBusRegisterMetaType<WillLoginUserInfo>();
+     setTimeout(2147483647);
+     FreedesktopHelper *systemFdHelper = new FreedesktopHelper(false);
+     if (systemFdHelper) {
+@@ -36,6 +63,14 @@ UniAuthService::UniAuthService(QObject *parent)
+     }
+ }
+ 
++UniAuthService *UniAuthService::instance(QObject *parent)
++{
++    if (!m_instance) {
++        m_instance = new UniAuthService(parent);
++    }
++    return m_instance;
++}
++
+ // 设置默认设备
+ void UniAuthService::setDefaultDevice(int bioDevType, QString deviceName)
+ {
+@@ -78,7 +113,7 @@ QStringList UniAuthService::getAllDefaultDevice(QString userName)
+     return listDefDevices;
+ }
+ 
+-//生物特征开关接口
++// 生物特征开关接口
+ bool UniAuthService::getBioAuthStatus(QString userName, int bioAuthType)
+ {
+     QDBusMessage bioResult = call(QStringLiteral("getBioAuthStatus"), userName, bioAuthType);
+@@ -236,3 +271,89 @@ int UniAuthService::getFTimeoutTimes()
+         return 1;
+     }
+ }
++
++void UniAuthService::SwitchToUser(QString strUserName)
++{
++    QDBusReply<int> reply = call(QStringLiteral("SwitchToUser"), strUserName);
++    if (!reply.isValid()) {
++        qWarning() << "SwitchToUser error:" << reply.error();
++        return;
++    }
++    return;
++}
++
++void UniAuthService::SwitchToGreeterUser(QString strUserName)
++{
++    QDBusReply<int> reply = call(QStringLiteral("SwitchToGreeterUser"), strUserName);
++    if (!reply.isValid()) {
++        qWarning() << "SwitchToGreeterUser error:" << reply.error();
++        return;
++    }
++    return;
++}
++
++WillLoginUserInfo UniAuthService::getWillSwitchUser()
++{
++    WillLoginUserInfo willLoginUserInfo;
++    QDBusMessage result = call(QStringLiteral("getWillSwitchUser"));
++    if (result.type() == QDBusMessage::ErrorMessage) {
++        qWarning() << "getWillSwitchUser error:" << result.errorMessage();
++        return willLoginUserInfo;
++    }
++    if (result.arguments().size() > 0) {
++        QDBusArgument argInfo = result.arguments().at(0).value<QDBusArgument>();
++        argInfo >> willLoginUserInfo;
++    }
++    qDebug() << "getUserInfo:" << willLoginUserInfo;
++    return willLoginUserInfo;
++}
++
++bool UniAuthService::isUserNameValid(QString strUserName)
++{
++    struct passwd *userInfo = nullptr;
++    userInfo = getpwnam(strUserName.toLatin1().data());
++    if (userInfo) {
++        return true;
++    }
++    return false;
++}
++
++int UniAuthService::SaveLastLoginUser(QString strUserName)
++{
++    QDBusReply<int> reply = call(QStringLiteral("SaveLastLoginUser"), strUserName);
++    if (!reply.isValid()) {
++        qWarning() << "SaveLastLoginUser error:" << reply.error();
++        return -1;
++    }
++    return reply.value();
++}
++
++QString UniAuthService::GetLastLoginUser()
++{
++    QDBusReply<QString> reply = call(QStringLiteral("GetLastLoginUser"));
++    if (!reply.isValid()) {
++        qWarning() << "GetLastLoginUser error:" << reply.error();
++        return QString("");
++    }
++    return reply.value();
++}
++
++int UniAuthService::SaveQuickLoginUser(QString strUserName)
++{
++    QDBusReply<int> reply = call(QStringLiteral("SaveQuickLoginUser"), strUserName);
++    if (!reply.isValid()) {
++        qWarning() << "SaveQuickLoginUser error:" << reply.error();
++        return -1;
++    }
++    return reply.value();
++}
++
++QString UniAuthService::GetQuickLoginUser()
++{
++    QDBusReply<QString> reply = call(QStringLiteral("GetQuickLoginUser"));
++    if (!reply.isValid()) {
++        qWarning() << "GetQuickLoginUser error:" << reply.error();
++        return QString("");
++    }
++    return reply.value();
++}
+diff --git a/src/dbusifs/uniauthservice.h b/src/dbusifs/uniauthservice.h
+index ef7d1c0..2599c95 100644
+--- a/src/dbusifs/uniauthservice.h
++++ b/src/dbusifs/uniauthservice.h
+@@ -32,12 +32,36 @@ enum authEnableType
+     ENABLETYPE_LOGIN,   // 暂保留
+ };
+ 
++/**
++ * @brief 用户信息
++ */
++struct WillLoginUserInfo
++{
++    QString strUserName = "";
++    bool isOneKeyLogin = false;
++};
++
++QDBusArgument &operator <<(QDBusArgument &arg, const WillLoginUserInfo &willLoginUserInfo);
++const QDBusArgument &operator >>(const QDBusArgument &arg, WillLoginUserInfo &willLoginUserInfo);
++QDebug operator <<(QDebug stream, const WillLoginUserInfo &willLoginUserInfo);
++
++Q_DECLARE_METATYPE(WillLoginUserInfo)
++
+ class UniAuthService : public QDBusAbstractInterface
+ {
+     Q_OBJECT
+-public:
++private:
+     explicit UniAuthService(QObject *parent = nullptr);
+ 
++public:
++    /**
++     * @brief 单实例
++     *
++     * @param parent 父指针
++     * @return UniAuthService 单实例对象指针
++     */
++    static UniAuthService *instance(QObject *parent = nullptr);
++
+ public Q_SLOTS:
+     // 设置默认设备
+     void setDefaultDevice(int bioDevType, QString deviceName);
+@@ -64,6 +88,53 @@ public Q_SLOTS:
+     bool getHiddenSwitchButton();
+     // 获取人脸超时停用次数
+     int getFTimeoutTimes();
++    /**
++     * @brief 用户名是否有效
++     *
++     * @param strUserName 用户名
++     * @return bool true 有效,否则 无效
++     */
++    bool isUserNameValid(QString strUserName);
++    /**
++     * @brief 一键切换并登录用户
++     *
++     * @param strUserName 用户名
++     */
++    void SwitchToUser(QString strUserName);
++    /**
++     * @brief 切换到登录用户
++     *
++     * @param strUserName 用户名
++     */
++    void SwitchToGreeterUser(QString strUserName);
++    /**
++     * @brief 将要登录的用户信息
++     *
++     * @return WillLoginUserInfo 用户信息
++     */
++    WillLoginUserInfo getWillSwitchUser();
++    /**
++     * @brief SaveLastLoginUser 记录上一次登录成功的用户
++     * @param strUserName 用户名
++     * @return 0 成功,其他失败
++     */
++    int SaveLastLoginUser(QString strUserName);
++    /**
++     * @brief GetLastLoginUser 获取上一次登录的用户
++     * @return 用户名
++     */
++    QString GetLastLoginUser();
++    /**
++     * @brief SaveQuickLoginUser 保存下次快速登录的用户
++     * @param strUserName 用户名
++     * @return 0 成功,其他失败
++     */
++    int SaveQuickLoginUser(QString strUserName);
++    /**
++     * @brief GetQuickLoginUser 获取快速登录的用户名
++     * @return 用户名
++     */
++    QString GetQuickLoginUser();
+ 
+ public:
+     bool isActivatable();
+@@ -73,6 +144,26 @@ Q_SIGNALS:
+     void defaultDeviceChanged(QString userName, int bioDevType, QString deviceName);
+     //开关状态改变
+     void bioAuthStatusChanged(QString userName, int type, bool status);
++    /**
++     * @brief 将要登录的用户名改变
++     *
++     * @param strUserName 新用户名(需对空串异常处理)
++     * @param isOneKeyLogin 是否需要一键登录
++     */
++    void userChanged(WillLoginUserInfo willLoginUser);
++
++private:
++    class MemCollector{
++    public:
++        ~MemCollector(){
++            if (UniAuthService::instance()) {
++                delete UniAuthService::instance();
++                UniAuthService::m_instance = nullptr;
++            }
++        }
++    };
++    static UniAuthService *m_instance; /** 统一认证配置服务单实例指针 */
++    static MemCollector m_memCollector;
+ 
+ private:
+     bool m_isActivatable;
+diff --git a/src/lock-backend/bioauthenticate.cpp b/src/lock-backend/bioauthenticate.cpp
+index e072f56..93f1804 100644
+--- a/src/lock-backend/bioauthenticate.cpp
++++ b/src/lock-backend/bioauthenticate.cpp
+@@ -24,14 +24,11 @@
+ #include "giodbus.h"
+ 
+ BioAuthenticate::BioAuthenticate(QObject *parent)
+-    : QObject(parent)
+-    , m_systemFdHelper(new FreedesktopHelper(false, this))
+-    , m_uniauthService(new UniAuthService(this))
+-    , m_bioTimer(nullptr)
++    : QObject(parent), m_systemFdHelper(new FreedesktopHelper(false, this)), m_bioTimer(nullptr)
+ {
+     m_bioauthState = BIOAUTH_IDLE;
+     m_deviceInfo.id = -1;
+-    m_maxFailedTimes = m_uniauthService->getMaxFailedTimes();
++    m_maxFailedTimes = UniAuthService::instance()->getMaxFailedTimes();
+     m_listPriority.clear();
+     m_listPriority.push_back(BioT_Face);
+     m_listPriority.push_back(BioT_FingerPrint);
+@@ -130,9 +127,9 @@ void BioAuthenticate::onServiceStatusChanged(const QString &strService, bool bAc
+ bool BioAuthenticate::getBioAuthEnable(QString strUserName, int nType)
+ {
+     bool isEnable = false;
+-    isEnable = m_uniauthService->getBioAuthStatus(strUserName, ENABLETYPE_BIO);
++    isEnable = UniAuthService::instance()->getBioAuthStatus(strUserName, ENABLETYPE_BIO);
+     if (isEnable) {
+-        isEnable = m_uniauthService->getBioAuthStatus(strUserName, nType);
++        isEnable = UniAuthService::instance()->getBioAuthStatus(strUserName, nType);
+     }
+     return isEnable;
+ }
+@@ -157,9 +154,9 @@ void BioAuthenticate::checkAvailableBioInfo(int nUid)
+     if (pwdInfo) {
+         int nAuthType = (pwdInfo->pw_name == getenv("USER")) ? ENABLETYPE_SAVER : ENABLETYPE_GREETER;
+         bool isAuthEnable = getBioAuthEnable(pwdInfo->pw_name, nAuthType);
+-        bool isQRCodeEnable = m_uniauthService->getQRCodeEnable();
++        bool isQRCodeEnable = UniAuthService::instance()->getQRCodeEnable();
+         DeviceList deviceList = m_biometricHelper->GetDevList();
+-        QStringList listDefDevices = m_uniauthService->getAllDefaultDevice(pwdInfo->pw_name);
++        QStringList listDefDevices = UniAuthService::instance()->getAllDefaultDevice(pwdInfo->pw_name);
+         qDebug() << "BeginGetFeature------!";
+         FeatureMap mapFeatures = m_biometricHelper->GetUserFeatures(nUid);
+         qDebug() << nUid << ",count:" << mapFeatures.size();
+@@ -212,7 +209,7 @@ void BioAuthenticate::onBioDeviceChanged(int drvid, int action, int devNum)
+     Q_UNUSED(devNum);
+     switch (action) {
+         case ACTION_ATTACHED: {
+-            //插入设备后,需要更新设备列表
++            // 插入设备后,需要更新设备列表
+             clearBioData();
+             QMap<int, DeviceMap>::iterator itUserDev = m_mapDevices.begin();
+             for (; itUserDev != m_mapDevices.end(); itUserDev++) {
+@@ -375,11 +372,11 @@ void BioAuthenticate::onIdentifyComplete(QDBusPendingCallWatcher *watcher)
+     } else if (result == DBUS_RESULT_NOTMATCH) { // 特征识别不匹配
+         qDebug() << "Identify failed";
+         onBioAuthComplete(false, 2);
+-    } else if (result == DBUS_RESULT_ERROR) { //识别发生错误
++    } else if (result == DBUS_RESULT_ERROR) { // 识别发生错误
+         StatusReslut ret = m_biometricHelper->UpdateStatus(m_deviceInfo.id);
+         qDebug() << "StatusReslut:" << ret.result << "," << ret.enable << "," << ret.devNum << "," << ret.devStatus
+                  << "," << ret.opsStatus << "," << ret.notifyMessageId;
+-        //识别操作超时 304/404 认证超时;8 网络错误;
++        // 识别操作超时 304/404 认证超时;8 网络错误;
+         if (ret.result == 0) {
+             if (ret.opsStatus == OPS_IDENTIFY_TIMEOUT || ret.opsStatus == OPS_VERIFY_TIMEOUT
+                 || ret.opsStatus == 8) { // 304认证超时, 8网络异常
+@@ -460,7 +457,7 @@ void BioAuthenticate::onBioAuthComplete(bool isSuccess, int nError)
+             startBioAuth(10000);
+         } else if (m_deviceInfo.deviceType == LOGINOPT_TYPE_FACE && nError == 1) {
+             m_fTimeoutTimes += 1;
+-            if (m_fTimeoutTimes == m_uniauthService->getFTimeoutTimes()) {
++            if (m_fTimeoutTimes == UniAuthService::instance()->getFTimeoutTimes()) {
+                 m_fTimeoutTimes = 0;
+                 nError = 6;
+             } else {
+@@ -524,8 +521,8 @@ void BioAuthenticate::startBioAuth(unsigned uTimeout)
+ QString BioAuthenticate::getDefaultDevice(int nUid, QString strUserName, int bioType)
+ {
+     QString defaultDeviceName = "";
+-    if (m_uniauthService && m_uniauthService->isActivatable()) {
+-        QString strDeviceName = m_uniauthService->getDefaultDevice(strUserName, bioType);
++    if (UniAuthService::instance()->isActivatable()) {
++        QString strDeviceName = UniAuthService::instance()->getDefaultDevice(strUserName, bioType);
+         if (!strDeviceName.isEmpty()) {
+             DeviceInfoPtr pDeviceInfo = findDeviceByName(nUid, strDeviceName);
+             if (pDeviceInfo) {
+@@ -539,9 +536,9 @@ QString BioAuthenticate::getDefaultDevice(int nUid, QString strUserName, int bio
+ QString BioAuthenticate::getDefaultDevice(int nUid, QString strUserName)
+ {
+     QString defaultDeviceName = "";
+-    if (m_uniauthService && m_uniauthService->isActivatable()) {
++    if (UniAuthService::instance()->isActivatable()) {
+         for (auto bioType : m_listPriority) {
+-            QString strDeviceName = m_uniauthService->getDefaultDevice(strUserName, bioType);
++            QString strDeviceName = UniAuthService::instance()->getDefaultDevice(strUserName, bioType);
+             if (!strDeviceName.isEmpty()) {
+                 DeviceInfoPtr pDeviceInfo = findDeviceByName(nUid, strDeviceName);
+                 if (pDeviceInfo) {
+diff --git a/src/lock-backend/bioauthenticate.h b/src/lock-backend/bioauthenticate.h
+index 9f7378b..c26e533 100644
+--- a/src/lock-backend/bioauthenticate.h
++++ b/src/lock-backend/bioauthenticate.h
+@@ -82,7 +82,6 @@ private:
+     BiometricHelper *m_biometricHelper = nullptr;
+     FreedesktopHelper *m_systemFdHelper = nullptr;
+     QMap<int, DeviceMap> m_mapDevices; // 用户可用的设备
+-    UniAuthService *m_uniauthService = nullptr;
+     DeviceInfo m_deviceInfo;
+     BIOAUTH_STATE m_bioauthState;
+     int m_fdFrame = -1;
+diff --git a/src/lock-backend/dbusupperinterface.cpp b/src/lock-backend/dbusupperinterface.cpp
+index 217bdf9..db209a7 100644
+--- a/src/lock-backend/dbusupperinterface.cpp
++++ b/src/lock-backend/dbusupperinterface.cpp
+@@ -43,6 +43,7 @@
+ #include "kglobalaccelhelper.h"
+ #include "personalizeddata.h"
+ #include "libinputswitchevent.h"
++#include "uniauthservice.h"
+ 
+ #define CONFIG_FILE "/usr/share/ukui-greeter/ukui-greeter.conf"
+ 
+@@ -306,7 +307,7 @@ void DbusUpperInterface::SessionTools()
+         message = QDBusMessage::createSignal(SS_DBUS_PATH, SS_DBUS_INTERFACE, "SecondRunParam");
+         message << "CmdSessionTools";
+         QDBusConnection::sessionBus().send(message);
+-        emitLockState(true);
++        emitLockState(false, true);
+         return;
+     }
+     m_bLockState = false;
+@@ -314,7 +315,7 @@ void DbusUpperInterface::SessionTools()
+     qDebug() << cmd;
+ 
+     m_procLockDialog.start(cmd);
+-    emitLockState(true);
++    emitLockState(false, true);
+ }
+ 
+ void DbusUpperInterface::AppBlockWindow(QString actionType)
+@@ -345,7 +346,7 @@ void DbusUpperInterface::AppBlockWindow(QString actionType)
+         else
+             return;
+         QDBusConnection::sessionBus().send(message);
+-        emitLockState(false);
++        emitLockState(false, true);
+         return;
+     }
+     if (actionType != "Restart" && actionType != "Shutdown" && actionType != "Suspend" && actionType != "Hibernate"
+@@ -357,7 +358,7 @@ void DbusUpperInterface::AppBlockWindow(QString actionType)
+     qDebug() << cmd;
+ 
+     m_procLockDialog.start(cmd);
+-    emitLockState(false);
++    emitLockState(false, true);
+ }
+ 
+ void DbusUpperInterface::MultiUserBlockWindow(QString actionType)
+@@ -372,7 +373,7 @@ void DbusUpperInterface::MultiUserBlockWindow(QString actionType)
+         else
+             return;
+         QDBusConnection::sessionBus().send(message);
+-        emitLockState(false);
++        emitLockState(false, true);
+         return;
+     }
+     if (actionType != "Restart" && actionType != "Shutdown")
+@@ -383,7 +384,7 @@ void DbusUpperInterface::MultiUserBlockWindow(QString actionType)
+     qDebug() << cmd;
+ 
+     m_procLockDialog.start(cmd);
+-    emitLockState(false);
++    emitLockState(false, true);
+ }
+ 
+ void DbusUpperInterface::Suspend()
+@@ -624,23 +625,25 @@ bool DbusUpperInterface::checkScreenDialogRunning()
+     return isRunning;
+ }
+ 
+-void DbusUpperInterface::emitLockState(bool val)
++void DbusUpperInterface::emitLockState(bool val, bool isSessionTools)
+ {
+     qDebug() << "emitLockState state = " << val;
+ 
+     if (val != m_bBlockShortcutState) {
+         m_kglobalHelper->blockShortcut(val);
+         m_bBlockShortcutState = val;
+-        qDebug() << " block all shortcut " << "blockShortcut states = " << m_bBlockShortcutState;
++        qDebug() << " block all shortcut "
++                 << "blockShortcut states = " << m_bBlockShortcutState;
+     }
+ 
+     QDBusMessage message;
+-    if (val) {
++    if (val && !isSessionTools) {
+         message = QDBusMessage::createSignal(SS_DBUS_PATH, SS_DBUS_INTERFACE, "lock");
+-    } else {
++        QDBusConnection::sessionBus().send(message);
++    } else if (!val && !isSessionTools) {
+         message = QDBusMessage::createSignal(SS_DBUS_PATH, SS_DBUS_INTERFACE, "unlock");
++        QDBusConnection::sessionBus().send(message);
+     }
+-    QDBusConnection::sessionBus().send(message);
+ }
+ 
+ QString DbusUpperInterface::GetInformation(QString strJson)
+@@ -1091,8 +1094,18 @@ QString DbusUpperInterface::GetDefaultAuthUser()
+         strUserName = getenv("USER");
+     } else {
+         // 获取lightdm传过来的被选中的用户
+-        QString selectedUser = m_lightDmHelper->selectUserHint();
+-        if (!selectedUser.isEmpty()) {
++        WillLoginUserInfo willSwitchUser = UniAuthService::instance()->getWillSwitchUser();
++        QString selectedUser = "";
++        if (willSwitchUser.strUserName.isEmpty()
++            || !UniAuthService::instance()->isUserNameValid(willSwitchUser.strUserName)) {
++            qDebug() << "WillSwitchUser is NULL or invalid:" << willSwitchUser.strUserName;
++            selectedUser = m_lightDmHelper->selectUserHint();
++        }
++        UniAuthService::instance()->SwitchToGreeterUser("");
++        if (!willSwitchUser.strUserName.isEmpty()) {
++            strUserName = willSwitchUser.strUserName;
++            qDebug() << "WillSwitchUser:" << strUserName;
++        } else if (!selectedUser.isEmpty()) {
+             qDebug() << "SelectUserHint: " << selectedUser;
+             if (m_lightDmHelper->findUserByName(selectedUser)) {
+                 strUserName = selectedUser;
+@@ -1108,7 +1121,7 @@ QString DbusUpperInterface::GetDefaultAuthUser()
+         } else if (m_lightDmHelper->getUsersInfo().count() == 1) { // 如果只有一个用户,默认选中
+             strUserName = m_lightDmHelper->getUsersInfo()[0]->name();
+         } else {
+-            QString lastLoginUser = m_config->getLastLoginUser();
++            QString lastLoginUser = UniAuthService::instance()->GetLastLoginUser();
+             if (m_lightDmHelper->findUserByName(lastLoginUser)) {
+                 strUserName = lastLoginUser;
+             } else {
+@@ -2624,9 +2637,10 @@ bool DbusUpperInterface::lockStateChanged(const QJsonObject &objInfo)
+ {
+     int nRet = -1;
+     bool state = objInfo.value("Content").toBool();
++    bool isSessionTools = objInfo.value("SessionTools").toBool();
+     if (lockState != state) {
+         lockState = state;
+-        emitLockState(state);
++        emitLockState(state, isSessionTools);
+     }
+     return lockState;
+ }
+diff --git a/src/lock-backend/dbusupperinterface.h b/src/lock-backend/dbusupperinterface.h
+index 67302bb..2797db9 100644
+--- a/src/lock-backend/dbusupperinterface.h
++++ b/src/lock-backend/dbusupperinterface.h
+@@ -68,7 +68,7 @@ public:
+ 
+ public:
+     bool checkScreenDialogRunning();
+-    void emitLockState(bool val);
++    void emitLockState(bool val, bool isSessionTools = false);
+     void LockStartupMode();
+     /**
+      * @brief 获取黑色屏保状态(沿用)
+diff --git a/src/lock-backend/lightdmhelper.cpp b/src/lock-backend/lightdmhelper.cpp
+index 8444de5..c599ac8 100644
+--- a/src/lock-backend/lightdmhelper.cpp
++++ b/src/lock-backend/lightdmhelper.cpp
+@@ -20,13 +20,19 @@
+ #include <QLightDM/Greeter>
+ #include <QFileInfo>
+ #include "securityuser.h"
++#include "global_utils.h"
+ #include <pwd.h>
+ #include "proxymodel.h"
+ #include "accountshelper.h"
+ #include "definetypes.h"
++#include "uniauthservice.h"
+ #include <QDBusArgument>
+ #include <QDBusMessage>
+ #include <QVariantMap>
++#ifdef WITHKYSEC
++#include <kysec/libkysec.h>
++#include <kysec/status.h>
++#endif
+ 
+ LightDMHelper::LightDMHelper(AccountsHelper *accountHelper, Configuration *config, QObject *parent)
+     : QLightDM::Greeter(parent)
+@@ -39,7 +45,7 @@ LightDMHelper::LightDMHelper(AccountsHelper *accountHelper, Configuration *confi
+     , m_mapUsers(new QMap<QString, UserInfoPtr>())
+     , m_dbusIfsLDM(nullptr)
+ {
+-    //连接到lightdm
++    // 连接到lightdm
+     if (!connectToDaemonSync()) {
+         qDebug() << "connect to Daemon failed";
+         exit(1);
+@@ -66,6 +72,9 @@ void LightDMHelper::initData()
+         m_isShowManualLogin = true;
+     }
+     updateUsersInfo();
++    if (isGreeterMode() && UniAuthService::instance()) {
++        UniAuthService::instance()->SaveQuickLoginUser("");
++    }
+ }
+ 
+ bool LightDMHelper::setSession(const QString &session)
+@@ -109,9 +118,16 @@ int LightDMHelper::getLoginUserCount()
+ void LightDMHelper::startSession()
+ {
+     if (isAuthenticated()) {
+-        if (m_configuration) {
+-            m_configuration->saveLastLoginUser(m_strCurUserName);
+-            m_configuration->saveLastLoginUser1(m_strCurUserName);
++        if (UniAuthService::instance()) {
++            UniAuthService::instance()->SaveLastLoginUser(m_strCurUserName);
++// 三权分立不保存秒级登录用户信息
++#ifdef WITHKYSEC
++            if (kysec_is_disabled() || !kysec_get_3adm_status()) {
++#endif
++                UniAuthService::instance()->SaveQuickLoginUser(m_strCurUserName);
++#ifdef WITHKYSEC
++            }
++#endif
+         }
+         Q_EMIT authenticationSucess(m_strCurUserName);
+     }
+diff --git a/src/lock-backend/main.cpp b/src/lock-backend/main.cpp
+index 27916bc..cd35943 100644
+--- a/src/lock-backend/main.cpp
++++ b/src/lock-backend/main.cpp
+@@ -24,6 +24,7 @@
+ #include <signal.h>
+ #include <unistd.h>
+ #include <sys/wait.h>
++#include <sys/prctl.h>
+ #include <stdio.h>
+ #include <ukui-log4qt.h>
+ #include "qtsinglecoreapplication.h"
+@@ -51,6 +52,8 @@ int main(int argc, char *argv[])
+         return 0;
+     }
+     qInfo()<<"ukui screensaver backend Started!!";
++    // 会话管理器退出时,锁屏后端也退出
++    prctl(PR_SET_PDEATHSIG, SIGKILL);
+     //命令行参数解析
+     QCommandLineParser parser;
+     parser.setApplicationDescription(QCoreApplication::translate("main", "Backend for the ukui ScreenSaver."));
+diff --git a/src/lock-backend/switchuserutils.cpp b/src/lock-backend/switchuserutils.cpp
+index 27d7de1..7dc55f9 100644
+--- a/src/lock-backend/switchuserutils.cpp
++++ b/src/lock-backend/switchuserutils.cpp
+@@ -277,11 +277,20 @@ int SwitchUserUtils::SwitchToUserSession(QString seatPath, UserDisplayIfInfo &to
+         return 0;
+     } else if (!toUDII.strUserName.isEmpty()) {
+         if (!isGreeterMode()) {
++            // 切换到免密登录用户会直接登录桌面,需要先展示“登录”按钮
++#if 0
+             QDBusMessage result = ifaceDM.call("SwitchToUser", toUDII.strUserName, toUDII.strSessionPath);
+             if (result.type() == QDBusMessage::ErrorMessage) {
+                 qWarning() << "SwitchUser SwitchToUser failed:" << result.errorMessage();
+                 return 2;
+             }
++#else
++            QDBusMessage result = ifaceDM.call("SwitchToGreeter");
++            if (result.type() == QDBusMessage::ErrorMessage) {
++                qWarning() << "SwitchUser SwitchToGreeter failed:" << result.errorMessage();
++                return 2;
++            }
++#endif
+         } else {
+             return 4;
+         }
+diff --git a/src/lock-dialog/backenddbushelper.cpp b/src/lock-dialog/backenddbushelper.cpp
+index 16c655b..eb6ff0e 100644
+--- a/src/lock-dialog/backenddbushelper.cpp
++++ b/src/lock-dialog/backenddbushelper.cpp
+@@ -358,11 +358,12 @@ bool BackendDbusHelper::setCurrentSession(QString strSession)
+     return true;
+ }
+ 
+-bool BackendDbusHelper::lockStateChanged(bool isVisible)
++bool BackendDbusHelper::lockStateChanged(bool isVisible, bool isSessionTools)
+ {
+     QJsonObject jsonCmd;
+     jsonCmd["CmdId"] = LOCK_CMD_ID_LOCK_STATE_CHANGED;
+     jsonCmd["Content"] = isVisible;
++    jsonCmd["SessionTools"] = isSessionTools;
+     QDBusPendingReply<int> reply = SetInformation(QString(QJsonDocument(jsonCmd).toJson()));
+     if (reply.isError()) {
+         qWarning() << "lockStateChanged error: " << reply.error().message();
+diff --git a/src/lock-dialog/backenddbushelper.h b/src/lock-dialog/backenddbushelper.h
+index 3bac8b9..426ab68 100644
+--- a/src/lock-dialog/backenddbushelper.h
++++ b/src/lock-dialog/backenddbushelper.h
+@@ -148,7 +148,7 @@ public Q_SLOTS:
+     bool setCurrentUser(QString strUserName);
+     int switchToUser(QString strUserName);
+     bool setCurrentSession(QString strSession);
+-    bool lockStateChanged(bool isVisible);
++    bool lockStateChanged(bool isVisible, bool isSessionTools);
+     void startSession();
+ 
+     void pamAuthenticate(QString strUserName);
+diff --git a/src/lock-dialog/lockdialogmodel.cpp b/src/lock-dialog/lockdialogmodel.cpp
+index 3802e38..e0bcf16 100644
+--- a/src/lock-dialog/lockdialogmodel.cpp
++++ b/src/lock-dialog/lockdialogmodel.cpp
+@@ -29,7 +29,7 @@
+ #include <pwd.h>
+ 
+ LockDialogModel::LockDialogModel(QObject *parent)
+-    : QObject(parent), m_isUseWayland(QGuiApplication::platformName().startsWith("wayland", Qt::CaseInsensitive))
++    : QObject(parent), m_isUseWayland(QString(qgetenv("XDG_SESSION_TYPE")) == "wayland")
+ {
+ }
+ 
+diff --git a/src/lock-dialog/lockdialogmodel.h b/src/lock-dialog/lockdialogmodel.h
+index 72abc20..8db3e16 100644
+--- a/src/lock-dialog/lockdialogmodel.h
++++ b/src/lock-dialog/lockdialogmodel.h
+@@ -512,7 +512,7 @@ Q_SIGNALS:
+ 
+     void agreementInfoChanged();
+ 
+-    void lockStateChanged(bool isVisible);
++    void lockStateChanged(bool isVisible, bool isSessionTools);
+ 
+     void lidstateChanged(const QString &lidstate);
+ 
+diff --git a/src/lock-dialog/main.cpp b/src/lock-dialog/main.cpp
+index 06064be..2e75af6 100644
+--- a/src/lock-dialog/main.cpp
++++ b/src/lock-dialog/main.cpp
+@@ -54,10 +54,6 @@ int main(int argc, char *argv[])
+     initUkuiLog4qt("ukui-screensaver-dialog");
+     // 重启或关机时不被session关掉
+     qunsetenv("SESSION_MANAGER");
+-    if (!isGreeterMode()) {
+-        // 试用模式不起锁屏
+-        checkIslivecd();
+-    }
+ 
+     qputenv("QT_QPA_PLATFORMTHEME", QByteArray("ukui"));
+ 
+@@ -74,8 +70,9 @@ int main(int argc, char *argv[])
+     LockDialogModel *lockDialogModel = new LockDialogModel();
+     LockDialogPerformer *performer = new LockDialogPerformer(lockDialogModel);
+ 
+-    if (isGreeterMode())
++    if (isGreeterMode() && !lockDialogModel->isUseWayland()) {
+         DisplayService::instance(lockDialogModel)->setCurUserName(lockDialogModel->defaultUserName());
++    }
+ 
+     QString strDisplay = "";
+     if (QString(qgetenv("XDG_SESSION_TYPE")) == "wayland") {
+@@ -85,6 +82,20 @@ int main(int argc, char *argv[])
+     }
+     QString id = QString("ukui-screensaver-dialog" + strDisplay);
+     QtSingleApplication app(id, argc, argv);
++
++    LockDialogModel::CommandLineArgs cmdArgs;
++    if (!lockDialogModel->parseCmdArguments(app.arguments(), cmdArgs)) {
++        return 0;
++    }
++
++    if (!isGreeterMode()) {
++	// 需要判断参数是否是session-tools
++        if (!cmdArgs.isSessionTools) {
++            // 试用模式不起锁屏
++            checkIslivecd();
++        }
++    }
++
+     if (app.isRunning()) {
+         QString strArguments = QApplication::arguments().join(",");
+         app.sendMessage(strArguments);
+@@ -93,7 +104,9 @@ int main(int argc, char *argv[])
+         qInfo() << "ukui screensaver dialog is running!";
+         return EXIT_SUCCESS;
+     }
+-    setCursorCenter();
++    if (!lockDialogModel->isUseWayland()) {
++        setCursorCenter();
++    }
+     // 加载插件实例
+     PluginsLoader *pluginsLoader = &PluginsLoader::instance();
+     pluginsLoader->start(QThread::HighestPriority);
+@@ -125,11 +138,6 @@ int main(int argc, char *argv[])
+         loopTemp->exec();
+     }
+ 
+-    LockDialogModel::CommandLineArgs cmdArgs;
+-
+-    if (!lockDialogModel->parseCmdArguments(app.arguments(), cmdArgs)) {
+-        return 0;
+-    }
+     QObject::connect(
+         &app, SIGNAL(messageReceived(const QString &)), lockDialogModel, SLOT(onRunningMessage(const QString &)));
+ 
+diff --git a/src/screensaver/main.cpp b/src/screensaver/main.cpp
+index 4190ec5..6b04da1 100644
+--- a/src/screensaver/main.cpp
++++ b/src/screensaver/main.cpp
+@@ -31,6 +31,7 @@
+ #include <sys/prctl.h>
+ #include <signal.h>
+ #include <syslog.h>
++#include <ukui-log4qt.h>
+ 
+ #define WORKING_DIRECTORY "/usr/share/ukui-screensaver"
+ bool bControlFlg = false;//是否控制面板窗口
+@@ -42,6 +43,8 @@ int main(int argc, char *argv[])
+     QCoreApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
+ #endif
+     QApplication a(argc, argv);
++
++    initUkuiLog4qt("ukui-screensaver-default");
+ /*
+     prctl(PR_SET_PDEATHSIG, SIGHUP);
+     //加载翻译文件
+diff --git a/src/screensaver/scconfiguration.cpp b/src/screensaver/scconfiguration.cpp
+index e2c2f91..105045a 100644
+--- a/src/screensaver/scconfiguration.cpp
++++ b/src/screensaver/scconfiguration.cpp
+@@ -114,10 +114,15 @@ void SCConfiguration::onConfigurationChanged(QString key, QVariant value)
+ QString SCConfiguration::getDefaultBackground()
+ {
+     QString backgroundFile = m_helperBackendDbus->getLockScreenConf(KEY_BACKGROUND).toString();
+-    if (ispicture(backgroundFile))
++    if (ispicture(backgroundFile)) {
+         return backgroundFile;
+-    else
++    } else {
++        QString default_background_path = "/usr/share/backgrounds/1-warty-final-ubuntukylin.jpg";
++        if (ispicture(default_background_path)) {
++            return default_background_path;
++        }
+         return DEFAULT_BACKGROUND_PATH;
++    }
+ }
+ 
+ int SCConfiguration::getTimeType()
+diff --git a/src/screensaver/screensaver.cpp b/src/screensaver/screensaver.cpp
+index 71e2f0a..ace6b38 100644
+--- a/src/screensaver/screensaver.cpp
++++ b/src/screensaver/screensaver.cpp
+@@ -370,7 +370,7 @@ bool Screensaver::eventFilter(QObject *obj, QEvent *event)
+         }
+     }
+ #endif
+-    return false;
++    return QWidget::eventFilter(obj, event);
+ }
+ 
+ void Screensaver::paintEvent(QPaintEvent *event)
+@@ -539,23 +539,25 @@ void Screensaver::resizeEvent(QResizeEvent * /*event*/)
+         if (flag == 0) {
+             QList<QLabel *> labelList = this->findChildren<QLabel *>();
+             for (int i = 0; i < labelList.count(); i++) {
+-                int fontsize = labelList.at(i)->font().pixelSize();
+-                int fontpt = labelList.at(i)->font().pointSize();
+-                if (fontsize > 0) {
++                if (labelList.at(i) != myPreviewLabel) {
++                    int fontsize = labelList.at(i)->font().pixelSize();
++                    int fontpt = labelList.at(i)->font().pointSize();
++                    if (fontsize > 0) {
+ #ifdef USE_INTEL
+-                    const QString SheetStyle = QString("font-size:%1px;").arg(fontsize / 3);
++                        const QString SheetStyle = QString("font-size:%1px;").arg(fontsize / 3);
+ #else
+-                    const QString SheetStyle = QString("font-size:%1px;").arg(fontsize / 4);
++                        const QString SheetStyle = QString("font-size:%1px;").arg(fontsize / 4);
+ #endif
+-                    labelList.at(i)->setStyleSheet(SheetStyle);
+-                } else {
+-                    QFont font = labelList.at(i)->font();
++                        labelList.at(i)->setStyleSheet(SheetStyle);
++                    } else {
++                        QFont font = labelList.at(i)->font();
+ #ifdef USE_INTEL
+-                    font.setPointSize(fontpt / 3);
++                        font.setPointSize(fontpt / 3);
+ #else
+-                    font.setPointSize(fontpt / 4);
++                        font.setPointSize(fontpt / 4);
+ #endif
+-                    labelList.at(i)->setFont(font);
++                        labelList.at(i)->setFont(font);
++                    }
+                 }
+             }
+             QList<QWidget *> childList = timeLayout->findChildren<QWidget *>();
+@@ -882,6 +884,17 @@ void Screensaver::initUI()
+             }
+         }
+     }
++    // V11上在窗口关闭时会收到一个leaveEvent(),控制面板关闭的时候new这个label,会导致控制面板关闭卡顿。
++    if (!myPreviewLabel) {
++        myPreviewLabel = new QLabel(this);
++        myPreviewLabel->setFixedHeight(30);
++        myPreviewLabel->setMinimumWidth(54);
++
++        // 设置样式
++        myPreviewLabel->setStyleSheet("background-color: rgb(38,38,38); border-radius: 0px; color:white;");
++        myPreviewLabel->setAlignment(Qt::AlignCenter);
++        myPreviewLabel->hide();
++    }
+ #endif
+ }
+ 
+@@ -1136,16 +1149,6 @@ void Screensaver::setRandomText()
+ 
+ void Screensaver::setPreviewText(bool bVisible)
+ {
+-    if (!myPreviewLabel) {
+-        myPreviewLabel = new QLabel(this);
+-        myPreviewLabel->setFixedHeight(30);
+-        myPreviewLabel->setMinimumWidth(54);
+-
+-        // 设置样式
+-        myPreviewLabel->setStyleSheet("background-color: rgb(38,38,38); border-radius: 0px; color:white;");
+-        myPreviewLabel->setAlignment(Qt::AlignCenter);
+-    }
+-
+     myPreviewLabel->setText(m_strPreViewTrans);
+     myPreviewLabel->adjustSize();
+ 
+diff --git a/src/widgets/authdialog.cpp b/src/widgets/authdialog.cpp
+index 4a2b002..62c9b77 100644
+--- a/src/widgets/authdialog.cpp
++++ b/src/widgets/authdialog.cpp
+@@ -55,7 +55,6 @@ AuthDialog::AuthDialog(LockDialogModel *model, UserInfoPtr userInfo, QWidget *pa
+     , m_isLockingFlg(false)
+     , m_isInputPasswd(false)
+     , m_curUserInfo(userInfo)
+-    , m_uniauthService(new UniAuthService(this))
+     , m_pSecurityQuestionAnswer(new SecurityQuestionAnswer(this))
+ {
+     initUI();
+@@ -950,8 +949,8 @@ void AuthDialog::onFirstLoginIdentifyComplete(QDBusPendingCallWatcher *watcher)
+         struct passwd *pwd;
+         pwd = getpwuid(authUid);
+         if (pwd && pwd->pw_name) {
+-            if (m_uniauthService && m_uniauthService->isActivatable()) {
+-                bool isEnable = m_uniauthService->getBioAuthStatus(pwd->pw_name, ENABLETYPE_BIO);
++            if (UniAuthService::instance()->isActivatable()) {
++                bool isEnable = UniAuthService::instance()->getBioAuthStatus(pwd->pw_name, ENABLETYPE_BIO);
+                 if (isEnable == false)
+                     return;
+             }
+@@ -1499,7 +1498,7 @@ void AuthDialog::performBiometricAuth()
+     if (!m_biometricProxy) {
+         waitBiometricServiceStatus();
+         m_biometricProxy = new BiometricHelper(this);
+-        maxFailedTimes = m_uniauthService->getMaxFailedTimes();
++        maxFailedTimes = UniAuthService::instance()->getMaxFailedTimes();
+     }
+ 
+     // 服务没启动,或者打开DBus连接出错
+@@ -1613,8 +1612,7 @@ void AuthDialog::initBiometricWidget()
+     } else {
+         QHBoxLayout *optsLayout = new QHBoxLayout(m_widgetLoginOpts);
+         optsLayout->setContentsMargins(0, 0, 0, 0);
+-        m_loginOpts
+-            = new LoginOptionsWidget(m_biometricProxy, m_curUserInfo->uid(), m_uniauthService, m_widgetLoginOpts);
++        m_loginOpts = new LoginOptionsWidget(m_biometricProxy, m_curUserInfo->uid(), m_widgetLoginOpts);
+         optsLayout->addWidget(m_loginOpts);
+         connect(m_loginOpts, &LoginOptionsWidget::authComplete, this, &AuthDialog::onBiometricAuthComplete);
+         connect(m_loginOpts, &LoginOptionsWidget::optionSelected, this, &AuthDialog::onDeviceChanged);
+@@ -1910,7 +1908,7 @@ void AuthDialog::onBiometricAuthComplete(bool result, int nStatus)
+                 startBioAuth(10000);
+             } else if (m_uCurLoginOptType == LOGINOPT_TYPE_FACE && nStatus == 1) {
+                 m_fTimeoutTimes += 1;
+-                if (m_fTimeoutTimes == m_uniauthService->getFTimeoutTimes()) {
++                if (m_fTimeoutTimes == UniAuthService::instance()->getFTimeoutTimes()) {
+                     m_fRetryButton->show();
+                     m_labelFace->hide();
+                     setLoginTypeTip(
+@@ -1987,7 +1985,7 @@ void AuthDialog::onBiometricDbusChanged(bool bActive)
+             qDebug() << "OnDelay init biometric!!";
+             if (!m_biometricProxy) {
+                 m_biometricProxy = new BiometricHelper(this);
+-                maxFailedTimes = m_uniauthService->getMaxFailedTimes();
++                maxFailedTimes = UniAuthService::instance()->getMaxFailedTimes();
+             }
+ 
+             // 服务没启动,或者打开DBus连接出错
+diff --git a/src/widgets/authdialog.h b/src/widgets/authdialog.h
+index 603ea8b..2b25f86 100644
+--- a/src/widgets/authdialog.h
++++ b/src/widgets/authdialog.h
+@@ -26,7 +26,6 @@
+ #include "biodefines.h"
+ #include "loginoptionswidget.h"
+ #include "pluginsloader.h"
+-#include "statusbutton.h"
+ #include <QDateTime>
+ 
+ class QLabel;
+@@ -35,6 +34,7 @@ class QPushButton;
+ class IconEdit;
+ class LockDialogModel;
+ class BioButtonListWidget;
++class StatuButton;
+ class QTimer;
+ class SecurityQuestionAnswer;
+ 
+@@ -283,7 +283,6 @@ private:
+ 
+     QPixmap m_waitingPixmap;
+     QTimer *w_timer = nullptr;
+-    UniAuthService *m_uniauthService = nullptr;
+     bool isLoadingUkey = false;
+     bool isPowerup = false;
+     QDBusInterface *bioService = nullptr;
+diff --git a/src/widgets/blockwidget.cpp b/src/widgets/blockwidget.cpp
+index 1a3afc0..99a6284 100644
+--- a/src/widgets/blockwidget.cpp
++++ b/src/widgets/blockwidget.cpp
+@@ -137,8 +137,20 @@ void BlockWidget::setTips(const QString tips)
+     m_tipLabel->show();
+     m_listView->hide();
+     m_tipLabel->setText(tips);
+-    m_cancelButton->setText(tr("Cancel"));
+-    m_confirmButton->setText(tr("Confrim"));
++    QString cancelStrEText = getElidedText(font(), m_cancelButton->width() - m_cancelButton->contentsMargins().left() - m_cancelButton->contentsMargins().right(), tr("Cancel"));
++    if (cancelStrEText == tr("Cancel")) {
++        m_cancelButton->setText(tr("Cancel"));
++    } else if (cancelStrEText != tr("Cancel")) {
++        m_cancelButton->setText(cancelStrEText);
++        m_cancelButton->setToolTip(tr("Cancel"));
++    }
++    QString strEText = getElidedText(font(), m_confirmButton->width() - m_confirmButton->contentsMargins().left() - m_confirmButton->contentsMargins().right(), tr("Confrim"));
++    if (strEText == tr("Confrim")) {
++        m_confirmButton->setText(tr("Confrim"));
++    } else if (strEText != tr("Confrim")) {
++        m_confirmButton->setText(strEText);
++        m_confirmButton->setToolTip(tr("Confrim"));
++    }
+ }
+ 
+ void BlockWidget::setMsgTips(int type)
+@@ -236,8 +248,20 @@ void BlockWidget::setWarning(QStringList list, int type)
+                                   "QPushButton:pressed {background: rgba(255, 255, 255, 0.3);border-radius: 24px;}");
+     sysFont.setPointSize((16 + m_curFontSize) * m_ptToPx);
+     m_cancelButton->setFont(sysFont);
+-    m_cancelButton->setText(tr("Cancel"));
+-    m_confirmButton->setText(tr("Confrim"));
++    QString cancelStrEText = getElidedText(font(), m_cancelButton->width() - m_cancelButton->contentsMargins().left() - m_cancelButton->contentsMargins().right(), tr("Cancel"));
++    if (cancelStrEText == tr("Cancel")) {
++        m_cancelButton->setText(tr("Cancel"));
++    } else if (cancelStrEText != tr("Cancel")) {
++        m_cancelButton->setText(cancelStrEText);
++        m_cancelButton->setToolTip(tr("Cancel"));
++    }
++    QString strEText = getElidedText(font(), m_confirmButton->width() - m_confirmButton->contentsMargins().left() - m_confirmButton->contentsMargins().right(), tr("Confrim"));
++    if (strEText == tr("Confrim")) {
++        m_confirmButton->setText(tr("Confrim"));
++    } else if (strEText != tr("Confrim")) {
++        m_confirmButton->setText(strEText);
++        m_confirmButton->setToolTip(tr("Confrim"));
++    }
+ }
+ 
+ QString BlockWidget::getHibited_tr_lowcase(int type)
+@@ -255,3 +279,12 @@ QString BlockWidget::getHibited_tr_lowcase(int type)
+     return "";
+ }
+ 
++QString BlockWidget::getElidedText(QFont font, int width, QString strInfo)
++{
++    QFontMetrics fontMetrics(font);
++    //如果当前字体下,字符串长度大于指定宽度
++    if (fontMetrics.width(strInfo) > width) {
++        strInfo = QFontMetrics(font).elidedText(strInfo, Qt::ElideRight, width);
++    }
++    return strInfo;
++}
+diff --git a/src/widgets/blockwidget.h b/src/widgets/blockwidget.h
+index 748758a..fdd139b 100644
+--- a/src/widgets/blockwidget.h
++++ b/src/widgets/blockwidget.h
+@@ -48,6 +48,7 @@ public:
+ 
+ private:
+     void initUi();
++    QString getElidedText(QFont font, int width, QString strInfo);
+ 
+ private Q_SLOTS:
+     void onFontSizeChanged(double fontSize);
+diff --git a/src/widgets/fullbackgroundwidget.cpp b/src/widgets/fullbackgroundwidget.cpp
+index a124348..b59017a 100644
+--- a/src/widgets/fullbackgroundwidget.cpp
++++ b/src/widgets/fullbackgroundwidget.cpp
+@@ -50,6 +50,10 @@
+ #include "configuration.h"
+ #include <windowmanager/windowmanager.h>
+ using namespace kdk;
++#ifdef WITHKYSEC
++#include <kysec/libkysec.h>
++#include <kysec/status.h>
++#endif
+ 
+ FullBackgroundWidget::FullBackgroundWidget(LockDialogModel *model, QWidget *parent)
+     : QWidget(parent), m_modelLockDialog(model)
+@@ -143,7 +147,7 @@ void FullBackgroundWidget::initUI()
+     setWindowFlags(Qt::FramelessWindowHint | Qt::X11BypassWindowManagerHint);
+ 
+     // 登录模式下监听屏幕插拔
+-    if (isGreeterMode() && QString(qgetenv("XDG_SESSION_TYPE")) != "wayland") {
++    if (isGreeterMode() && !m_modelLockDialog->isUseWayland()) {
+         XRRQueryExtension(QX11Info::display(), &m_RREventBase, &m_RRErrorBase);
+         XRRSelectInput(QX11Info::display(), QX11Info::appRootWindow(), RRScreenChangeNotifyMask);
+         QtConcurrent::run([=]() { RRScreenChangeEvent(true); });
+@@ -297,7 +301,7 @@ void FullBackgroundWidget::onSecondRunParam(const QString &str)
+ void FullBackgroundWidget::onShowBlankScreensaver(int nDelay, bool isHasLock)
+ {
+     qDebug() << "onShowBlankScreensaver:" << nDelay << "," << isHasLock;
+-    Q_EMIT m_modelLockDialog->lockStateChanged(true);
++    Q_EMIT m_modelLockDialog->lockStateChanged(true, false);
+ 
+     if (isHasLock) {
+         screenStatus = (ScreenStatus)(screenStatus | SCREEN_SAVER | SCREEN_LOCK);
+@@ -348,7 +352,7 @@ void FullBackgroundWidget::onShowLock(bool isStartup)
+     m_isStartupMode = isStartup;
+     show();
+     Q_EMIT m_modelLockDialog->setCurrentUser(m_modelLockDialog->defaultUserName());
+-    Q_EMIT m_modelLockDialog->lockStateChanged(true);
++    Q_EMIT m_modelLockDialog->lockStateChanged(true, false);
+     if (m_lockWidget && !m_lockWidget->isHidden())
+         m_lockWidget->show();
+ }
+@@ -364,7 +368,7 @@ void FullBackgroundWidget::onShowSwitchUserLock()
+     screenStatus = (ScreenStatus)(screenStatus | SCREEN_LOCK);
+     show();
+     Q_EMIT m_modelLockDialog->setCurrentUser(m_modelLockDialog->defaultUserName());
+-    Q_EMIT m_modelLockDialog->lockStateChanged(true);
++    Q_EMIT m_modelLockDialog->lockStateChanged(true, false);
+     if (m_lockWidget && !m_lockWidget->isHidden()) {
+         m_lockWidget->show();
+         m_lockWidget->onShowUserListWidget(true);
+@@ -377,7 +381,7 @@ void FullBackgroundWidget::onShowSessionTools()
+     m_isSessionTools = true;
+     show();
+     Q_EMIT m_modelLockDialog->setCurrentUser(m_modelLockDialog->defaultUserName());
+-    Q_EMIT m_modelLockDialog->lockStateChanged(true);
++    Q_EMIT m_modelLockDialog->lockStateChanged(true, true);
+     if (m_lockWidget && !m_lockWidget->isHidden())
+         m_lockWidget->onShowPowerListWidget(true);
+ }
+@@ -395,7 +399,7 @@ void FullBackgroundWidget::onShowAppBlockWindow(int actionType)
+         if (m_lockWidget && !m_lockWidget->isHidden())
+             screenStatus = (ScreenStatus)(screenStatus | SCREEN_LOCK);
+         Q_EMIT m_modelLockDialog->setCurrentUser(m_modelLockDialog->defaultUserName());
+-        Q_EMIT m_modelLockDialog->lockStateChanged(true);
++        Q_EMIT m_modelLockDialog->lockStateChanged(true, true);
+         m_isSessionTools = true;
+         if (m_lockWidget && !m_lockWidget->isHidden())
+             m_lockWidget->onShowInhibitWarning(lockcheck, actionType, true);
+@@ -409,7 +413,7 @@ void FullBackgroundWidget::onShowMultiUsersBlockWindows(int actionType)
+     show();
+     if (m_lockWidget && !m_lockWidget->isHidden())
+         Q_EMIT m_modelLockDialog->setCurrentUser(m_modelLockDialog->defaultUserName());
+-    Q_EMIT m_modelLockDialog->lockStateChanged(true);
++    Q_EMIT m_modelLockDialog->lockStateChanged(true, true);
+     if (m_lockWidget && !m_lockWidget->isHidden())
+         m_lockWidget->onMulUsersLogined(actionType, true);
+ }
+@@ -418,7 +422,7 @@ void FullBackgroundWidget::onShowSessionIdle()
+ {
+     onShowScreensaver();
+     delayLockScreen();
+-    Q_EMIT m_modelLockDialog->lockStateChanged(true);
++    Q_EMIT m_modelLockDialog->lockStateChanged(true, true);
+ }
+ 
+ void FullBackgroundWidget::onShowLockScreensaver()
+@@ -460,7 +464,7 @@ void FullBackgroundWidget::onShowScreensaver()
+         }
+     }
+     show();
+-    Q_EMIT m_modelLockDialog->lockStateChanged(true);
++    Q_EMIT m_modelLockDialog->lockStateChanged(true, false);
+ }
+ 
+ void FullBackgroundWidget::onClearScreensaver()
+@@ -469,6 +473,8 @@ void FullBackgroundWidget::onClearScreensaver()
+ 
+     for (auto widget : widgetXScreensaverList) {
+         widget->close();
++        delete widget;
++        widget = nullptr;
+     }
+     widgetXScreensaverList.clear();
+ 
+@@ -515,7 +521,7 @@ void FullBackgroundWidget::onLockScreenTimeout()
+ void FullBackgroundWidget::onCloseScreensaver()
+ {
+     hide();
+-    Q_EMIT m_modelLockDialog->lockStateChanged(false);
++    Q_EMIT m_modelLockDialog->lockStateChanged(false, false);
+     stopDelayLockScreen();
+     screenStatus = UNDEFINED;
+     m_isBlank = false;
+@@ -798,7 +804,7 @@ bool FullBackgroundWidget::nativeEventFilter(const QByteArray &eventType, void *
+         qDebug() << "---------------------XCB_KEY_RELEASE:" << xc->detail;
+         onGlobalKeyRelease(xc->detail);
+     } else if (responseType == m_RREventBase + RRScreenChangeNotify) {
+-        if (isGreeterMode() && QString(qgetenv("XDG_SESSION_TYPE")) != "wayland") {
++        if (isGreeterMode() && !m_modelLockDialog->isUseWayland()) {
+             RRScreenChangeEvent(false);
+         }
+     }
+@@ -807,13 +813,24 @@ bool FullBackgroundWidget::nativeEventFilter(const QByteArray &eventType, void *
+ 
+ void FullBackgroundWidget::onCurUserChanged(const QString &strUserName)
+ {
+-    if (isGreeterMode())
++    if (isGreeterMode() && !m_modelLockDialog->isUseWayland())
+         DisplayService::instance(m_modelLockDialog)->setCurUserName(strUserName);
+ }
+ 
+ void FullBackgroundWidget::onAuthSucceed(QString strUserName)
+ {
+     if (getenv("USER") == strUserName) {
++        if (UniAuthService::instance()) {
++            UniAuthService::instance()->SaveLastLoginUser(strUserName);
++// 三权分立不保存秒级登录用户信息
++#ifdef WITHKYSEC
++            if (kysec_is_disabled() || !kysec_get_3adm_status()) {
++#endif
++                UniAuthService::instance()->SaveQuickLoginUser(strUserName);
++#ifdef WITHKYSEC
++            }
++#endif
++        }
+         onCloseScreensaver();
+     } else {
+         if (m_lockWidget) {
+diff --git a/src/widgets/lockwidget.cpp b/src/widgets/lockwidget.cpp
+index 1adb9a1..8c3b318 100644
+--- a/src/widgets/lockwidget.cpp
++++ b/src/widgets/lockwidget.cpp
+@@ -207,18 +207,6 @@ bool LockWidget::exitSubWidget(bool isForScreensaver, bool hideVirkeyboard)
+ 
+ void LockWidget::paintEvent(QPaintEvent *event)
+ {
+-    QPainter painter(this);
+-    painter.drawPixmap(this->geometry(), background);
+-    QPainterPath path;
+-    painter.setOpacity(0.25);
+-    painter.setRenderHint(QPainter::Antialiasing); // 反锯齿;
+-    painter.setClipping(true);
+-    painter.setPen(Qt::transparent);
+-    path.addRect(this->rect());
+-    path.setFillRule(Qt::WindingFill);
+-    painter.setBrush(QColor("#000000"));
+-    painter.setPen(Qt::transparent);
+-    painter.drawPath(path);
+     return QWidget::paintEvent(event);
+ }
+ 
+@@ -385,6 +373,7 @@ void LockWidget::initUI()
+ 
+ void LockWidget::initConnections()
+ {
++    connect(UniAuthService::instance(), &UniAuthService::userChanged, this, &LockWidget::onServiceUserChanged);
+     connect(m_modelLockDialog, &LockDialogModel::usersInfoChanged, this, &LockWidget::onUsersInfoChanged);
+     connect(m_modelLockDialog, &LockDialogModel::currentUserChanged, this, &LockWidget::onCurUserChanged);
+     connect(m_modelLockDialog, &LockDialogModel::currentSessionChanged, this, &LockWidget::onSessionChanged);
+@@ -424,6 +413,7 @@ void LockWidget::initUserWidget()
+         m_userListWidget->updateWidgetSize();
+         m_userListWidget->hide();
+         connect(m_userListWidget, &UserListWidget::userSelected, m_modelLockDialog, [=](QString strUserName) {
++            exitSubWidget(false, false);
+             SwitchToUser(strUserName);
+         });
+         connect(m_userListWidget, &UserListWidget::widgetSizeChanged, m_modelLockDialog, [=]() {
+@@ -466,6 +456,11 @@ void LockWidget::initPowerWidget()
+     connect(m_powerListWidget, &PowerListWidget::suspendClicked, this, &LockWidget::onSuspendClicked);
+     connect(m_powerListWidget, &PowerListWidget::itemClicked, this, &LockWidget::onPowerItemClicked);
+     connect(m_powerListWidget, &PowerListWidget::switchuserClicked, this, &LockWidget::onSwitchuserClicked);
++    connect(m_powerListWidget, &PowerListWidget::powerWidgetClicked, this, [=] {
++        exitSubWidget();
++        Q_EMIT sessionToolsExit();
++        m_isSessionTools = false;
++    });
+     //    m_powerListWidget->clearFocus();
+ }
+ 
+@@ -1287,6 +1282,8 @@ void LockWidget::onShowPowerListWidget(bool issessionTools)
+     } else {
+         m_powerListWidget->hide();
+         authDialog->inhibitShow(false);
++        //bug#292889 头像加载缓慢问题,需要调用一次update或repaint来刷新
++        authDialog->update();
+         authDialog->setFocus();
+         if (m_isShowResetPasswdBtn) {
+             m_pResetPwdBtn->show();
+@@ -1556,12 +1553,22 @@ void LockWidget::onSessionActiveChanged(bool isActive)
+     if (isActive) {
+         if (m_timerChkActive && m_timerChkActive->isActive()) {
+             m_timerChkActive->stop();
++        }
++        if (m_modelLockDialog && m_modelLockDialog->isUseWayland()) {
++            QTimer::singleShot(500, this, [&, this]() {
++                if (this->isHidden()) {
++                    this->show();
++                    update();
++                }
++                startAuth();
++            });
++        } else {
+             if (this->isHidden()) {
+                 this->show();
+                 update();
+             }
++            startAuth();
+         }
+-        startAuth();
+     }
+ }
+ 
+@@ -1595,37 +1602,76 @@ void LockWidget::onAuthDialogBottomPosChanged(int nPosY)
+     }
+ }
+ 
+-void LockWidget::SwitchToUser(QString strUserName)
++void LockWidget::onServiceUserChanged(WillLoginUserInfo willSwitchUser)
++{
++    if (!isGreeterMode() || willSwitchUser.strUserName.isEmpty()) {
++        if (isCurUserSelf(willSwitchUser.strUserName)) { // 锁屏且是当前用户则清空不处理
++            UniAuthService::instance()->SwitchToGreeterUser("");
++        }
++        return;
++    }
++    static QString strLastUserName = "";
++    static quint64 llLastChangeTick = 0;
++
++    // 清空 willSwitchUser
++    UniAuthService::instance()->SwitchToGreeterUser("");
++
++    quint64 curChangeTick = QDateTime::currentDateTime().currentMSecsSinceEpoch();
++    if (willSwitchUser.strUserName == strLastUserName && curChangeTick - llLastChangeTick <= 2000) {
++        qDebug() << "onServiceUserChanged same name and time short:" << willSwitchUser.strUserName << ","
++                 << curChangeTick - llLastChangeTick;
++        return;
++    }
++    strLastUserName = willSwitchUser.strUserName;
++    llLastChangeTick = curChangeTick;
++
++    if (willSwitchUser.strUserName.isEmpty()
++        || !UniAuthService::instance()->isUserNameValid(willSwitchUser.strUserName)) {
++        qDebug() << "WillSwitchUser is NULL or invalid:" << willSwitchUser.strUserName;
++        return;
++    }
++    qDebug() << "willSwitchUser:" << willSwitchUser;
++    SwitchToUser(willSwitchUser.strUserName, true);
++}
++
++void LockWidget::SwitchToUser(QString strUserName, bool isSwitchInCurPage /* = false*/)
+ {
+     if (m_modelLockDialog) {
+-        int nSwitchRet = Q_EMIT m_modelLockDialog->switchToUser(strUserName);
+-        if (nSwitchRet != 0) {
++        if (isSwitchInCurPage) {
+             Q_EMIT m_modelLockDialog->setCurrentUser(strUserName);
+         } else {
+-            //            if(authDialog) {
+-            //                authDialog->stopAuth();
+-            //            }
+-            if (!isCurUserSelf(strUserName) && !isHidden()) {
+-                this->hide();
+-                update();
+-                if (!m_timerChkActive) {
+-                    m_timerChkActive = new QTimer(this);
+-                    m_timerChkActive->setInterval(10 * 1000);
+-                    connect(m_timerChkActive, &QTimer::timeout, this, [&, this]() {
+-                        if (this->isHidden()) {
+-                            this->show();
++            UniAuthService::instance()->SwitchToGreeterUser(strUserName);
++            int nSwitchRet = Q_EMIT m_modelLockDialog->switchToUser(strUserName);
++            if (nSwitchRet != 0) {
++                UniAuthService::instance()->SwitchToGreeterUser("");
++                Q_EMIT m_modelLockDialog->setCurrentUser(strUserName);
++            } else {
++                //            if(authDialog) {
++                //                authDialog->stopAuth();
++                //            }
++                if (!isCurUserSelf(strUserName) && !isHidden()) {
++                    this->hide();
++                    update();
++                    if (!m_timerChkActive) {
++                        m_timerChkActive = new QTimer(this);
++                        m_timerChkActive->setInterval(10 * 1000);
++                        connect(m_timerChkActive, &QTimer::timeout, this, [&, this]() {
++                            if (this->isHidden() && m_modelLockDialog->sessionActive()) {
++                                this->show();
++                            }
++                            m_timerChkActive->stop();
++                        });
++                    } else {
++                        if (m_timerChkActive->isActive()) {
++                            m_timerChkActive->stop();
+                         }
+-                        m_timerChkActive->stop();
+-                    });
+-                } else {
+-                    if (m_timerChkActive->isActive()) {
+-                        m_timerChkActive->stop();
+                     }
++                    m_timerChkActive->start();
++                    stopAuth();
++                } else {
++                    UniAuthService::instance()->SwitchToGreeterUser("");
++                    Q_EMIT m_modelLockDialog->setCurrentUser(strUserName);
+                 }
+-                m_timerChkActive->start();
+-                stopAuth();
+-            } else {
+-                Q_EMIT m_modelLockDialog->setCurrentUser(strUserName);
+             }
+         }
+     }
+diff --git a/src/widgets/lockwidget.h b/src/widgets/lockwidget.h
+index 8095ccf..f794bd5 100644
+--- a/src/widgets/lockwidget.h
++++ b/src/widgets/lockwidget.h
+@@ -24,6 +24,7 @@
+ #include "userinfo.h"
+ #include "mediacontrolwidget.h"
+ #include "securityquestionanswer.h"
++#include "uniauthservice.h"
+ 
+ class QListWidgetItem;
+ class MyListWidget;
+@@ -112,7 +113,7 @@ private:
+ 
+     void updateBottomButton();
+ 
+-    void SwitchToUser(QString strUserName);
++    void SwitchToUser(QString strUserName, bool isSwitchInCurPage = false);
+ 
+     void refreshTranslate();
+ 
+@@ -190,6 +191,12 @@ private Q_SLOTS:
+ 
+     void onAuthDialogBottomPosChanged(int nPosY);
+ 
++    /**
++     * @brief onServiceUserChanged 登录服务用户切换
++     * @param willLoginUserInfo 新用户信息
++     */
++    void onServiceUserChanged(WillLoginUserInfo willLoginUserInfo);
++
+     void onShowResetPasswdBtn();
+ 
+     void onShowResetPwdWidget();
+diff --git a/src/widgets/loginoptionswidget.cpp b/src/widgets/loginoptionswidget.cpp
+index 1ffde12..105a532 100644
+--- a/src/widgets/loginoptionswidget.cpp
++++ b/src/widgets/loginoptionswidget.cpp
+@@ -43,9 +43,8 @@
+ #include <QJsonArray>
+ #include <QJsonParseError>
+ 
+-LoginOptionsWidget::LoginOptionsWidget(
+-    BiometricHelper *bioHelper, int uid, UniAuthService *uniauthService, QWidget *parent)
+-    : QWidget(parent), m_biomericProxy(bioHelper), m_uid(uid), m_uniauthService(uniauthService)
++LoginOptionsWidget::LoginOptionsWidget(BiometricHelper *bioHelper, int uid, QWidget *parent)
++    : QWidget(parent), m_biomericProxy(bioHelper), m_uid(uid)
+ {
+     m_listPriority.clear();
+     m_listPriority.push_back(BioT_Face);
+@@ -894,12 +893,12 @@ QPixmap LoginOptionsWidget::drawSymbolicColoredPixmap(QPixmap &source, QString c
+ bool LoginOptionsWidget::getBioAuthEnable(int nType)
+ {
+     bool isEnable = false;
+-    if (m_uniauthService && m_uniauthService->isActivatable()) {
++    if (UniAuthService::instance()->isActivatable()) {
+         struct passwd *pwInfo = getpwuid(m_uid);
+         if (pwInfo) {
+-            isEnable = m_uniauthService->getBioAuthStatus(pwInfo->pw_name, ENABLETYPE_BIO);
++            isEnable = UniAuthService::instance()->getBioAuthStatus(pwInfo->pw_name, ENABLETYPE_BIO);
+             if (isEnable) {
+-                isEnable = m_uniauthService->getBioAuthStatus(pwInfo->pw_name, nType);
++                isEnable = UniAuthService::instance()->getBioAuthStatus(pwInfo->pw_name, nType);
+             }
+             return isEnable;
+         } else {
+@@ -912,8 +911,8 @@ bool LoginOptionsWidget::getBioAuthEnable(int nType)
+ 
+ bool LoginOptionsWidget::getQRCodeEnable()
+ {
+-    if (m_uniauthService && m_uniauthService->isActivatable()) {
+-        return m_uniauthService->getQRCodeEnable();
++    if (UniAuthService::instance()->isActivatable()) {
++        return UniAuthService::instance()->getQRCodeEnable();
+     } else {
+         return true;
+     }
+@@ -921,9 +920,9 @@ bool LoginOptionsWidget::getQRCodeEnable()
+ 
+ QString LoginOptionsWidget::getDefaultDevice(QString strUserName, int bioType)
+ {
+-    if (m_uniauthService && m_uniauthService->isActivatable()) {
++    if (UniAuthService::instance()->isActivatable()) {
+         QString defaultDeviceName = "";
+-        QString strDeviceName = m_uniauthService->getDefaultDevice(strUserName, bioType);
++        QString strDeviceName = UniAuthService::instance()->getDefaultDevice(strUserName, bioType);
+         if (!strDeviceName.isEmpty()) {
+             DeviceInfoPtr pDeviceInfo = findDeviceByName(strDeviceName);
+             if (pDeviceInfo) {
+@@ -938,13 +937,13 @@ QString LoginOptionsWidget::getDefaultDevice(QString strUserName, int bioType)
+ 
+ QString LoginOptionsWidget::getDefaultDevice(QString strUserName)
+ {
+-    if (m_uniauthService && m_uniauthService->isActivatable()) {
++    if (UniAuthService::instance()->isActivatable()) {
+         QString defaultDeviceName = "";
+         for (auto bioType : m_listPriority) {
+             if (bioType == UniT_Remote) {
+                 continue;
+             }
+-            QString strDeviceName = m_uniauthService->getDefaultDevice(strUserName, bioType);
++            QString strDeviceName = UniAuthService::instance()->getDefaultDevice(strUserName, bioType);
+             if (!strDeviceName.isEmpty()) {
+                 DeviceInfoPtr pDeviceInfo = findDeviceByName(strDeviceName);
+                 if (pDeviceInfo) {
+@@ -962,10 +961,10 @@ QString LoginOptionsWidget::getDefaultDevice(QString strUserName)
+ QStringList LoginOptionsWidget::getAllDefDevices()
+ {
+     QStringList listDefDevices;
+-    if (m_uniauthService && m_uniauthService->isActivatable()) {
++    if (UniAuthService::instance()->isActivatable()) {
+         struct passwd *pwdInfo = getpwuid(m_uid);
+         if (pwdInfo) {
+-            listDefDevices = m_uniauthService->getAllDefaultDevice(pwdInfo->pw_name);
++            listDefDevices = UniAuthService::instance()->getAllDefaultDevice(pwdInfo->pw_name);
+         }
+     } else {
+         QString defaultDeviceName;
+diff --git a/src/widgets/loginoptionswidget.h b/src/widgets/loginoptionswidget.h
+index 3b8f6f7..7a15874 100644
+--- a/src/widgets/loginoptionswidget.h
++++ b/src/widgets/loginoptionswidget.h
+@@ -42,7 +42,7 @@ class LoginOptionsWidget : public QWidget
+     Q_OBJECT
+ public:
+     explicit LoginOptionsWidget(
+-        BiometricHelper *bioHelper, int uid, UniAuthService *uniauthService, QWidget *parent = nullptr);
++        BiometricHelper *bioHelper, int uid, QWidget *parent = nullptr);
+     virtual ~LoginOptionsWidget();
+ 
+     bool getCurLoginOpt(int &nLoginOptType, int &nDrvId);
+@@ -164,7 +164,6 @@ private:
+ 
+     // ToolTip
+     QStringList nameList;
+-    UniAuthService *m_uniauthService = nullptr;
+     QList<int> m_listPriority;
+ 
+     bool isShowUkey = false;
+diff --git a/src/widgets/mpriswidget.cpp b/src/widgets/mpriswidget.cpp
+index 630a374..4bca3c5 100644
+--- a/src/widgets/mpriswidget.cpp
++++ b/src/widgets/mpriswidget.cpp
+@@ -165,6 +165,7 @@ void MPRISWidget::onLostMediaPath(const QString &strPath)
+             m_mprisDbusClient->deleteLater();
+             m_mprisDbusClient = nullptr;
+         }
++
+         m_strMediaPlayerPath.clear();
+         Q_EMIT statusChanged(false);
+     }
+@@ -209,8 +210,23 @@ void MPRISWidget::onMetadataChanged()
+ {
+     if (!m_mprisDbusClient)
+         return;
++    delayMetadataUpdate();
++}
+ 
+-    if (m_nPlayState == -1) {
++void MPRISWidget::delayMetadataUpdate(int nTimeout /* = 1000*/)
++{
++    if (!m_timerDelayUpdate) {
++        m_timerDelayUpdate = new QTimer(this);
++        m_timerDelayUpdate->setSingleShot(true);
++        connect(m_timerDelayUpdate, &QTimer::timeout, this, &MPRISWidget::onDelayMetadataUpdate);
++    }
++    m_timerDelayUpdate->setInterval(nTimeout);
++    m_timerDelayUpdate->start();
++}
++
++void MPRISWidget::onDelayMetadataUpdate()
++{
++    if (m_nPlayState == -1) { // 停止播放状态
+         m_labelName->setText(tr("Unknown"));
+         m_labelArtist->setText(tr("Unknown"));
+         m_labelAlbum->setPixmap(PixmapToRound(m_pixmapAlbumDefault, 12, 0, 12, 0));
+diff --git a/src/widgets/mpriswidget.h b/src/widgets/mpriswidget.h
+index b2d0d6f..4f018a4 100644
+--- a/src/widgets/mpriswidget.h
++++ b/src/widgets/mpriswidget.h
+@@ -11,6 +11,7 @@
+ #include <QVBoxLayout>
+ #include <QDBusConnectionInterface>
+ #include <QVariantMap>
++#include <QTimer>
+ #include "klabel.h"
+ 
+ class MPRISWidget : public QFrame
+@@ -35,6 +36,8 @@ public Q_SLOTS:
+     void onCanControlChanged();
+     void updateFont(QString strFont, double fontSizeF);
+ 
++    void onDelayMetadataUpdate();
++
+ Q_SIGNALS:
+     void statusChanged(bool isValid);
+ 
+@@ -45,6 +48,8 @@ private:
+     void initUI();
+     void initConnections();
+ 
++    void delayMetadataUpdate(int nTimeout = 1000);
++
+ private:
+     QDBusConnectionInterface *m_mprisMonitor = nullptr;
+     MPRISDBusClient *m_mprisDbusClient = nullptr;
+@@ -66,6 +71,8 @@ private:
+     QPushButton *m_btnPrev = nullptr;
+     QPushButton *m_btnPlayPause = nullptr;
+     QPushButton *m_btnNext = nullptr;
++
++    QTimer *m_timerDelayUpdate = nullptr;
+ };
+ 
+ #endif // MPRISWIDGET_H
+diff --git a/src/widgets/powerlistwidget.cpp b/src/widgets/powerlistwidget.cpp
+index 029f4fd..4a5f03c 100644
+--- a/src/widgets/powerlistwidget.cpp
++++ b/src/widgets/powerlistwidget.cpp
+@@ -51,6 +51,24 @@ bool PowerListWidget::eventFilter(QObject *obj, QEvent *event)
+     return MyListWidget::eventFilter(obj, event);
+ }
+ 
++void PowerListWidget::mouseReleaseEvent(QMouseEvent *event)
++{
++    QPoint mousePos = event->pos();
++    QList<PowerItemWidget*> itemList = this->findChildren<PowerItemWidget*>();
++    for (PowerItemWidget* item : itemList)
++    {
++        if (item->geometry().contains(mousePos))
++        {
++            //  如果是点击的功能按钮,不发信号,防止点击锁屏按钮时不进入锁屏
++            return QListWidget::mouseReleaseEvent(event);;
++        }
++    }
++    //  只有点击空白处,才需要发送信号
++    qDebug() << "Mouse press on list widget";
++    Q_EMIT powerWidgetClicked();
++    return QListWidget::mouseReleaseEvent(event);
++}
++
+ void PowerListWidget::setPowerType(int type)
+ {
+     m_powerType = type;
+diff --git a/src/widgets/powerlistwidget.h b/src/widgets/powerlistwidget.h
+index 5c272fb..51ed795 100644
+--- a/src/widgets/powerlistwidget.h
++++ b/src/widgets/powerlistwidget.h
+@@ -211,6 +211,7 @@ public:
+ protected:
+     bool eventFilter(QObject *obj, QEvent *event);
+     void changeEvent(QEvent *event);
++    void mouseReleaseEvent(QMouseEvent *event) override;
+ 
+ Q_SIGNALS:
+     void mulUsersLogined(int inhibitType, bool iscommand);
+@@ -219,6 +220,8 @@ Q_SIGNALS:
+     void suspendClicked();
+     void switchuserClicked();
+     void sureShutDown(int inhibitType, bool iscommand);
++    void powerWidgetClicked();  /*发送电源管理鼠标点击信号,在eventfilter中点击listwidget的空白处,
++                                      收不到鼠标点击事件,只有在mouseReleaseEvent中能过滤到*/
+ 
+ public Q_SLOTS:
+     void onUpdateListInfo();
+diff --git a/src/widgets/screensaverwidget.cpp b/src/widgets/screensaverwidget.cpp
+index e9190bb..cc9b494 100644
+--- a/src/widgets/screensaverwidget.cpp
++++ b/src/widgets/screensaverwidget.cpp
+@@ -32,7 +32,7 @@ ScreenSaverWidget::ScreenSaverWidget(ScreenSaver *screensaver, QWidget *parent)
+     : QWidget(parent), timer(nullptr), screensaver(screensaver), closing(false)
+ {
+     qDebug() << "ScreenSaverWidget::ScreenSaverWidget";
+-    setAttribute(Qt::WA_DeleteOnClose);
++    // setAttribute(Qt::WA_DeleteOnClose);
+     setMouseTracking(true);
+     setFocus();
+     this->installEventFilter(this);
diff -Nru ukui-screensaver-4.20.0.0/debian/patches/0005-sync-codes-from-v11-2503.patch ukui-screensaver-4.20.0.0/debian/patches/0005-sync-codes-from-v11-2503.patch
--- ukui-screensaver-4.20.0.0/debian/patches/0005-sync-codes-from-v11-2503.patch	1970-01-01 08:00:00.000000000 +0800
+++ ukui-screensaver-4.20.0.0/debian/patches/0005-sync-codes-from-v11-2503.patch	2025-02-13 20:26:40.000000000 +0800
@@ -0,0 +1,42 @@
+From: yangmin100 <yangmin@kylinos.cn>
+Date: Fri, 3 Jan 2025 17:50:02 +0800
+Subject: sync codes from v11-2503
+
+---
+ src/screensaver/main.cpp | 2 --
+ src/widgets/authdialog.h | 2 +-
+ 2 files changed, 1 insertion(+), 3 deletions(-)
+
+diff --git a/src/screensaver/main.cpp b/src/screensaver/main.cpp
+index 6b04da1..3c64928 100644
+--- a/src/screensaver/main.cpp
++++ b/src/screensaver/main.cpp
+@@ -31,7 +31,6 @@
+ #include <sys/prctl.h>
+ #include <signal.h>
+ #include <syslog.h>
+-#include <ukui-log4qt.h>
+ 
+ #define WORKING_DIRECTORY "/usr/share/ukui-screensaver"
+ bool bControlFlg = false;//是否控制面板窗口
+@@ -44,7 +43,6 @@ int main(int argc, char *argv[])
+ #endif
+     QApplication a(argc, argv);
+ 
+-    initUkuiLog4qt("ukui-screensaver-default");
+ /*
+     prctl(PR_SET_PDEATHSIG, SIGHUP);
+     //加载翻译文件
+diff --git a/src/widgets/authdialog.h b/src/widgets/authdialog.h
+index 2b25f86..aba243d 100644
+--- a/src/widgets/authdialog.h
++++ b/src/widgets/authdialog.h
+@@ -34,7 +34,7 @@ class QPushButton;
+ class IconEdit;
+ class LockDialogModel;
+ class BioButtonListWidget;
+-class StatuButton;
++class StatusButton;
+ class QTimer;
+ class SecurityQuestionAnswer;
+ 
diff -Nru ukui-screensaver-4.20.0.0/debian/patches/0006-112-sync-codes-from-v11-2503.patch ukui-screensaver-4.20.0.0/debian/patches/0006-112-sync-codes-from-v11-2503.patch
--- ukui-screensaver-4.20.0.0/debian/patches/0006-112-sync-codes-from-v11-2503.patch	1970-01-01 08:00:00.000000000 +0800
+++ ukui-screensaver-4.20.0.0/debian/patches/0006-112-sync-codes-from-v11-2503.patch	2025-02-13 20:26:40.000000000 +0800
@@ -0,0 +1,115 @@
+From: =?utf-8?b?5p2o5pWP?= <yangmin@kylinos.cn>
+Date: Wed, 12 Feb 2025 01:18:50 +0000
+Subject: !112 sync codes from v11-2503 Merge pull request !112 from
+ liudunfa/openkylin/huanghe
+
+---
+ src/screensaver/CMakeLists.txt  | 6 +++---
+ src/screensaver/main.cpp        | 2 ++
+ src/screensaver/screensaver.cpp | 3 ++-
+ src/widgets/powerlistwidget.cpp | 5 +----
+ src/widgets/powerlistwidget.h   | 3 ---
+ 5 files changed, 8 insertions(+), 11 deletions(-)
+
+diff --git a/src/screensaver/CMakeLists.txt b/src/screensaver/CMakeLists.txt
+index ada55ef..ab4eabf 100644
+--- a/src/screensaver/CMakeLists.txt
++++ b/src/screensaver/CMakeLists.txt
+@@ -64,7 +64,7 @@ set(screensaver_SRC
+     ../agreementinfo.cpp
+     )
+ add_executable(ukui-screensaver-default ${screensaver_SRC})
+-target_link_libraries(ukui-screensaver-default Qt5::Core Qt5::Widgets Qt5::DBus Qt5::X11Extras Qt5::Xml Qt5::Network Qt5::Multimedia Qt5::MultimediaWidgets  avformat avcodec ${EXTRA_LIBS})
++target_link_libraries(ukui-screensaver-default Qt5::Core Qt5::Widgets Qt5::DBus Qt5::X11Extras Qt5::Xml Qt5::Network ukui-log4qt Qt5::Multimedia Qt5::MultimediaWidgets  avformat avcodec ${EXTRA_LIBS})
+ 
+ qt5_add_resources(screensaver_Plugin_SRC
+         default.qrc
+@@ -112,7 +112,7 @@ set(screensaver_Plugin_SRC
+     )
+ 
+ add_library(screensaver-default SHARED ${screensaver_Plugin_SRC})
+-target_link_libraries(screensaver-default Qt5::Core Qt5::Widgets Qt5::DBus Qt5::X11Extras Qt5::Xml Qt5::Network Qt5::Multimedia Qt5::MultimediaWidgets  avformat avcodec ${EXTRA_LIBS})
++target_link_libraries(screensaver-default Qt5::Core Qt5::Widgets Qt5::DBus Qt5::X11Extras Qt5::Xml Qt5::Network ukui-log4qt Qt5::Multimedia Qt5::MultimediaWidgets  avformat avcodec ${EXTRA_LIBS})
+ 
+ qt5_add_resources(Screensaver_SRC
+         default.qrc
+@@ -160,7 +160,7 @@ set(Screensaver_SRC
+     )
+ 
+ add_library(Screensaver STATIC ${Screensaver_SRC})
+-target_link_libraries(Screensaver Qt5::Core Qt5::Widgets Qt5::DBus Qt5::X11Extras Qt5::Xml Qt5::Network Qt5::Multimedia Qt5::MultimediaWidgets  avformat avcodec ${EXTRA_LIBS})
++target_link_libraries(Screensaver Qt5::Core Qt5::Widgets Qt5::DBus Qt5::X11Extras Qt5::Xml Qt5::Network ukui-log4qt Qt5::Multimedia Qt5::MultimediaWidgets  avformat avcodec ${EXTRA_LIBS})
+ 
+ install(TARGETS
+ 	ukui-screensaver-default
+diff --git a/src/screensaver/main.cpp b/src/screensaver/main.cpp
+index 3c64928..6b04da1 100644
+--- a/src/screensaver/main.cpp
++++ b/src/screensaver/main.cpp
+@@ -31,6 +31,7 @@
+ #include <sys/prctl.h>
+ #include <signal.h>
+ #include <syslog.h>
++#include <ukui-log4qt.h>
+ 
+ #define WORKING_DIRECTORY "/usr/share/ukui-screensaver"
+ bool bControlFlg = false;//是否控制面板窗口
+@@ -43,6 +44,7 @@ int main(int argc, char *argv[])
+ #endif
+     QApplication a(argc, argv);
+ 
++    initUkuiLog4qt("ukui-screensaver-default");
+ /*
+     prctl(PR_SET_PDEATHSIG, SIGHUP);
+     //加载翻译文件
+diff --git a/src/screensaver/screensaver.cpp b/src/screensaver/screensaver.cpp
+index ace6b38..c0fce8c 100644
+--- a/src/screensaver/screensaver.cpp
++++ b/src/screensaver/screensaver.cpp
+@@ -1315,7 +1315,8 @@ QPixmap Screensaver::loadFromFile(QString strPath)
+ void Screensaver::getVideoFormat(QString fileName)
+ {
+     char *ch;
+-    QByteArray ba = fileName.toLatin1();
++    // 用toLiatin1()解析在有中文路径时回乱码
++    QByteArray ba = fileName.toUtf8();
+     ch = ba.data();
+ 
+     int ret;
+diff --git a/src/widgets/powerlistwidget.cpp b/src/widgets/powerlistwidget.cpp
+index 4a5f03c..9e3cbde 100644
+--- a/src/widgets/powerlistwidget.cpp
++++ b/src/widgets/powerlistwidget.cpp
+@@ -96,9 +96,6 @@ void PowerListWidget::initUI()
+         "QScrollBar::add-line:vertical{width:0px;height:0px}"
+         "QScrollBar::sub-line:vertical{width:0px;height:0px}");
+     //    powerBtnList[0].func = &PowerListWidget::setSystemSuspend1();
+-
+-    m_curFontSize = m_modelLockDialog->getCurFontSize();
+-    m_ptToPx = m_modelLockDialog->getPtToPx();
+ }
+ 
+ void PowerListWidget::initConnections()
+@@ -204,7 +201,7 @@ void PowerListWidget::onUpdateListInfo()
+             QIcon::fromTheme(strIconTheme, QIcon(powerBtnList[i].m_strIcon))
+                 .pixmap(powerBtnList[i].m_icon_width, powerBtnList[i].m_icon_width),
+             "white"));
+-        btnWdg->setFontSize((16 + m_curFontSize) * m_ptToPx);
++        btnWdg->setFontSize((16 + m_modelLockDialog->getCurFontSize()) * m_modelLockDialog->getPtToPx());
+     }
+ }
+ 
+diff --git a/src/widgets/powerlistwidget.h b/src/widgets/powerlistwidget.h
+index 51ed795..df9cf3b 100644
+--- a/src/widgets/powerlistwidget.h
++++ b/src/widgets/powerlistwidget.h
+@@ -240,9 +240,6 @@ private:
+     bool m_canSwitchUser = true;
+     bool m_canLogout = true;
+ 
+-    double m_curFontSize;
+-    double m_ptToPx = 1.0;
+-
+     int m_powerType = SAVER;
+     int m_powerBtnNum = 0;
+ 
diff -Nru ukui-screensaver-4.20.0.0/debian/patches/0007-114-update-changelog.patch ukui-screensaver-4.20.0.0/debian/patches/0007-114-update-changelog.patch
--- ukui-screensaver-4.20.0.0/debian/patches/0007-114-update-changelog.patch	1970-01-01 08:00:00.000000000 +0800
+++ ukui-screensaver-4.20.0.0/debian/patches/0007-114-update-changelog.patch	2025-02-13 20:26:40.000000000 +0800
@@ -0,0 +1,28536 @@
+From: =?utf-8?b?5p2o5pWP?= <yangmin@kylinos.cn>
+Date: Thu, 13 Feb 2025 12:29:10 +0000
+Subject: =?utf-8?q?!114_update_changelog_Merge_pull_request_!114_from_?=
+ =?utf-8?q?=E6=9D=A8=E6=95=8F/openkylin/huanghe?=
+
+---
+ CMakeLists.txt                                     |    4 +-
+ data/CMakeLists.txt                                |    5 +
+ data/ukui-greeter/95-ukui-greeter.conf             |    1 -
+ data/ukui-greeter/97-ukui-greeter-wlcom.conf       |    4 +
+ data/ukui-greeter/start-greeter-session            |    3 +
+ data/ukui-greeter/start-quick-session              |    4 +
+ data/ukui-greeter/ukui-greeter-wlcom.desktop       |    7 +
+ data/ukui-screensaver.desktop                      |    2 +-
+ src/CMakeLists.txt                                 |    8 +-
+ src/common/definetypes.h                           |    6 +
+ src/common/plasma-shell-manager.cpp                |    7 +-
+ src/common/plasma-shell-manager.h                  |    1 +
+ src/dbusifs/accountshelper.cpp                     |    4 +-
+ src/dbusifs/biometrichelper.h                      |    2 +-
+ src/dbusifs/dbusservermanager.cpp                  |   53 +
+ src/dbusifs/dbusservermanager.h                    |   50 +
+ src/dbusifs/enginedevice.cpp                       |    2 +-
+ src/dbusifs/freedesktophelper.h                    |    2 +-
+ src/dbusifs/login1helper.cpp                       |   30 +-
+ src/dbusifs/login1helper.h                         |    3 +-
+ src/dbusifs/sessionhelper.cpp                      |  260 +-
+ src/dbusifs/sessionhelper.h                        |   19 +-
+ src/dbusifs/uniauthservice.cpp                     |    2 +-
+ src/dbusifs/upowerhelper.h                         |    1 +
+ src/lock-backend/bioauthenticate.cpp               |    8 +-
+ src/lock-backend/bioauthenticate.h                 |    2 +-
+ src/lock-backend/dbusupperinterface.cpp            |  180 +-
+ src/lock-backend/dbusupperinterface.h              |   38 +-
+ src/lock-backend/gsettingshelper.cpp               |   32 +-
+ src/lock-backend/gsettingshelper.h                 |    3 +
+ src/lock-backend/lightdmhelper.cpp                 |   14 +-
+ src/lock-backend/lightdmhelper.h                   |    9 +-
+ src/lock-backend/main.cpp                          |   93 +-
+ src/lock-backend/pamauthenticate.cpp               |   28 +-
+ src/lock-backend/pamauthenticate.h                 |    7 +-
+ src/lock-backend/sessionwatcher.cpp                |    8 +-
+ src/lock-backend/sessionwatcher.h                  |    7 +-
+ src/lock-backend/switchuserutils.cpp               |    2 +-
+ src/lock-dialog/backenddbushelper.cpp              |   13 +-
+ src/lock-dialog/backenddbushelper.h                |    8 +-
+ src/lock-dialog/languagesetting.cpp                |    2 +-
+ src/lock-dialog/lockdialogmodel.cpp                |    4 +-
+ src/lock-dialog/lockdialogmodel.h                  |    8 +-
+ src/lock-dialog/lockdialogperformer.cpp            |   24 +-
+ src/lock-dialog/lockdialogperformer.h              |    2 +
+ src/lock-dialog/main.cpp                           |   59 +-
+ src/lock-dialog/pam-tally.c                        |   30 +-
+ src/ukccplugins/CMakeLists.txt                     |    3 +
+ src/ukccplugins/screenlock/CMakeLists.txt          |   47 +
+ src/ukccplugins/screenlock/pictureunit.cpp         |  124 +
+ src/ukccplugins/screenlock/pictureunit.h           |   61 +
+ src/ukccplugins/screenlock/screenlock.cpp          |  277 ++
+ src/ukccplugins/screenlock/screenlock.h            |   83 +
+ src/ukccplugins/screenlock/screenlockui.cpp        |  713 +++
+ src/ukccplugins/screenlock/screenlockui.h          |  123 +
+ src/ukccplugins/screensaver/CMakeLists.txt         |   51 +
+ src/ukccplugins/screensaver/previewwidget.cpp      |   35 +
+ src/ukccplugins/screensaver/previewwidget.h        |   22 +
+ src/ukccplugins/screensaver/screensaver.cpp        |  379 ++
+ src/ukccplugins/screensaver/screensaver.h          |   94 +
+ src/ukccplugins/screensaver/screensaverpluginso.h  |   27 +
+ src/ukccplugins/screensaver/screensaverui.cpp      |  505 ++
+ src/ukccplugins/screensaver/screensaverui.h        |   94 +
+ .../sessiondbus/screenlockinterface.cpp            |  153 +
+ src/ukccplugins/sessiondbus/screenlockinterface.h  |   63 +
+ .../sessiondbus/screensaverinterface.cpp           |  193 +
+ src/ukccplugins/sessiondbus/screensaverinterface.h |   78 +
+ src/userinfo.cpp                                   |    4 +-
+ src/widgets/authdialog.cpp                         |   56 +-
+ src/widgets/fullbackgroundwidget.cpp               |   34 +-
+ src/widgets/fullbackgroundwidget.h                 |    5 +-
+ src/widgets/iconedit.cpp                           |    3 +
+ src/widgets/lockwidget.cpp                         |   67 +-
+ src/widgets/screensaverwidget.cpp                  |    5 +-
+ tests/CMakeLists.txt                               |   50 +
+ tests/auto_test.sh                                 |   56 +
+ tests/kt-test-utils/cpp-stub-ext/stub-shadow.cpp   |   58 +
+ tests/kt-test-utils/cpp-stub-ext/stub-shadow.h     |  171 +
+ tests/kt-test-utils/cpp-stub-ext/stubext.h         |  129 +
+ tests/kt-test-utils/cpp-stub/addr_any.h            |  280 ++
+ tests/kt-test-utils/cpp-stub/addr_pri.h            |  177 +
+ tests/kt-test-utils/cpp-stub/elfio.hpp             | 4888 ++++++++++++++++++++
+ tests/kt-test-utils/cpp-stub/stub.h                |  360 ++
+ tests/unit_test_account_helper/CMakeLists.txt      |   64 +
+ tests/unit_test_account_helper/main.cpp            |   12 +
+ .../unit_test_account_helper.cpp                   |   65 +
+ tests/unit_test_auth_pam/CMakeLists.txt            |   86 +
+ tests/unit_test_auth_pam/main.cpp                  |   12 +
+ tests/unit_test_auth_pam/unit_test_auth_pam.cpp    |  377 ++
+ tests/unit_test_backend_dbus/CMakeLists.txt        |   68 +
+ tests/unit_test_backend_dbus/main.cpp              |   12 +
+ .../unit_test_backend_dbus.cpp                     |  423 ++
+ tests/unit_test_biometric_helper/CMakeLists.txt    |   66 +
+ tests/unit_test_biometric_helper/main.cpp          |   12 +
+ .../unit_test_biometric_helper.cpp                 |  131 +
+ tests/unit_test_common/CMakeLists.txt              |   89 +
+ tests/unit_test_common/main.cpp                    |   12 +
+ tests/unit_test_common/unit_test_common.cpp        |  349 ++
+ tests/unit_test_dbus_interface/CMakeLists.txt      |  147 +
+ tests/unit_test_dbus_interface/main.cpp            |   12 +
+ .../unit_test_dbus_interface.cpp                   |  524 +++
+ tests/unit_test_display_service/CMakeLists.txt     |   59 +
+ tests/unit_test_display_service/main.cpp           |   12 +
+ .../unit_test_display_service.cpp                  |   69 +
+ tests/unit_test_engine_device/CMakeLists.txt       |   66 +
+ tests/unit_test_engine_device/main.cpp             |   12 +
+ .../unit_test_engine_device.cpp                    |  451 ++
+ tests/unit_test_freedesktop_helper/CMakeLists.txt  |   58 +
+ tests/unit_test_freedesktop_helper/main.cpp        |   12 +
+ .../unit_test_freedesktop_helper.cpp               |   38 +
+ tests/unit_test_gsettings_helper/CMakeLists.txt    |   63 +
+ tests/unit_test_gsettings_helper/main.cpp          |   12 +
+ .../unit_test_gsettings_helper.cpp                 |  437 ++
+ tests/unit_test_inputswitch_event/CMakeLists.txt   |   63 +
+ tests/unit_test_inputswitch_event/main.cpp         |   12 +
+ .../unit_test_inputswitch_event.cpp                |  137 +
+ tests/unit_test_kglobalaccel_helper/CMakeLists.txt |   57 +
+ tests/unit_test_kglobalaccel_helper/main.cpp       |   12 +
+ .../unit_test_kglobalaccel_helper.cpp              |   36 +
+ tests/unit_test_lock_dialog_model/CMakeLists.txt   |   86 +
+ tests/unit_test_lock_dialog_model/main.cpp         |   12 +
+ .../unit_test_lock_dialog_model.cpp                |   68 +
+ tests/unit_test_login1_helper/CMakeLists.txt       |   58 +
+ tests/unit_test_login1_helper/main.cpp             |   12 +
+ .../unit_test_login1_helper.cpp                    |   95 +
+ tests/unit_test_personal_data/CMakeLists.txt       |   60 +
+ tests/unit_test_personal_data/main.cpp             |   12 +
+ tests/unit_test_personal_data/unit_test_common.cpp |  329 ++
+ .../unit_test_personal_data.cpp                    |  140 +
+ tests/unit_test_screenlock/CMakeLists.txt          |  150 +
+ tests/unit_test_screenlock/main.cpp                |    8 +
+ .../unit_test_screenlock/unit_test_screenlock.cpp  |   96 +
+ tests/unit_test_screensaver/CMakeLists.txt         |  149 +
+ tests/unit_test_screensaver/main.cpp               |    8 +
+ .../unit_test_screensaver.cpp                      |  141 +
+ tests/unit_test_session_helper/CMakeLists.txt      |   74 +
+ tests/unit_test_session_helper/main.cpp            |   12 +
+ .../unit_test_session_helper.cpp                   |   70 +
+ tests/unit_test_session_watcher/CMakeLists.txt     |   77 +
+ tests/unit_test_session_watcher/main.cpp           |   12 +
+ .../unit_test_session_watcher.cpp                  |   35 +
+ tests/unit_test_switch_user/CMakeLists.txt         |   67 +
+ tests/unit_test_switch_user/main.cpp               |   12 +
+ .../unit_test_switch_user.cpp                      |   71 +
+ .../unit_test_systemupgrade_helper/CMakeLists.txt  |   59 +
+ tests/unit_test_systemupgrade_helper/main.cpp      |   12 +
+ .../unit_test_systemupgrade_helper.cpp             |   45 +
+ tests/unit_test_uniauth_service/CMakeLists.txt     |   62 +
+ tests/unit_test_uniauth_service/main.cpp           |   11 +
+ .../unit_test_uniauth_service.cpp                  |  159 +
+ tests/unit_test_usd_helper/CMakeLists.txt          |   57 +
+ tests/unit_test_usd_helper/main.cpp                |   12 +
+ .../unit_test_usd_helper/unit_test_usd_helper.cpp  |   32 +
+ ukccplugins_i18n_ts/CMakeLists.txt                 |   12 +
+ ukccplugins_i18n_ts/bo.ts                          |  314 ++
+ ukccplugins_i18n_ts/bo_CN.ts                       |  493 ++
+ ukccplugins_i18n_ts/de.ts                          |  642 +++
+ ukccplugins_i18n_ts/en.ts                          |  314 ++
+ ukccplugins_i18n_ts/en_US.ts                       |  319 ++
+ ukccplugins_i18n_ts/es.ts                          |  642 +++
+ ukccplugins_i18n_ts/fa.ts                          |  314 ++
+ ukccplugins_i18n_ts/fr.ts                          |  642 +++
+ ukccplugins_i18n_ts/kk.ts                          |  622 +++
+ ukccplugins_i18n_ts/ky.ts                          |  622 +++
+ ukccplugins_i18n_ts/lzh.ts                         |  454 ++
+ ukccplugins_i18n_ts/mn.ts                          |  638 +++
+ ukccplugins_i18n_ts/tr.ts                          |  499 ++
+ ukccplugins_i18n_ts/ug.ts                          |  626 +++
+ ukccplugins_i18n_ts/zh_CN.ts                       |  623 +++
+ ukccplugins_i18n_ts/zh_HK.ts                       |  647 +++
+ ukccplugins_i18n_ts/zh_Hant.ts                     |  642 +++
+ 171 files changed, 25543 insertions(+), 421 deletions(-)
+ create mode 100644 data/ukui-greeter/97-ukui-greeter-wlcom.conf
+ create mode 100755 data/ukui-greeter/start-greeter-session
+ create mode 100755 data/ukui-greeter/start-quick-session
+ create mode 100644 data/ukui-greeter/ukui-greeter-wlcom.desktop
+ create mode 100644 src/dbusifs/dbusservermanager.cpp
+ create mode 100644 src/dbusifs/dbusservermanager.h
+ create mode 100644 src/ukccplugins/CMakeLists.txt
+ create mode 100644 src/ukccplugins/screenlock/CMakeLists.txt
+ create mode 100644 src/ukccplugins/screenlock/pictureunit.cpp
+ create mode 100644 src/ukccplugins/screenlock/pictureunit.h
+ create mode 100644 src/ukccplugins/screenlock/screenlock.cpp
+ create mode 100644 src/ukccplugins/screenlock/screenlock.h
+ create mode 100644 src/ukccplugins/screenlock/screenlockui.cpp
+ create mode 100644 src/ukccplugins/screenlock/screenlockui.h
+ create mode 100644 src/ukccplugins/screensaver/CMakeLists.txt
+ create mode 100644 src/ukccplugins/screensaver/previewwidget.cpp
+ create mode 100644 src/ukccplugins/screensaver/previewwidget.h
+ create mode 100644 src/ukccplugins/screensaver/screensaver.cpp
+ create mode 100644 src/ukccplugins/screensaver/screensaver.h
+ create mode 100644 src/ukccplugins/screensaver/screensaverpluginso.h
+ create mode 100644 src/ukccplugins/screensaver/screensaverui.cpp
+ create mode 100644 src/ukccplugins/screensaver/screensaverui.h
+ create mode 100644 src/ukccplugins/sessiondbus/screenlockinterface.cpp
+ create mode 100644 src/ukccplugins/sessiondbus/screenlockinterface.h
+ create mode 100644 src/ukccplugins/sessiondbus/screensaverinterface.cpp
+ create mode 100644 src/ukccplugins/sessiondbus/screensaverinterface.h
+ create mode 100644 tests/CMakeLists.txt
+ create mode 100755 tests/auto_test.sh
+ create mode 100644 tests/kt-test-utils/cpp-stub-ext/stub-shadow.cpp
+ create mode 100644 tests/kt-test-utils/cpp-stub-ext/stub-shadow.h
+ create mode 100644 tests/kt-test-utils/cpp-stub-ext/stubext.h
+ create mode 100644 tests/kt-test-utils/cpp-stub/addr_any.h
+ create mode 100644 tests/kt-test-utils/cpp-stub/addr_pri.h
+ create mode 100644 tests/kt-test-utils/cpp-stub/elfio.hpp
+ create mode 100644 tests/kt-test-utils/cpp-stub/stub.h
+ create mode 100644 tests/unit_test_account_helper/CMakeLists.txt
+ create mode 100644 tests/unit_test_account_helper/main.cpp
+ create mode 100644 tests/unit_test_account_helper/unit_test_account_helper.cpp
+ create mode 100644 tests/unit_test_auth_pam/CMakeLists.txt
+ create mode 100644 tests/unit_test_auth_pam/main.cpp
+ create mode 100644 tests/unit_test_auth_pam/unit_test_auth_pam.cpp
+ create mode 100644 tests/unit_test_backend_dbus/CMakeLists.txt
+ create mode 100644 tests/unit_test_backend_dbus/main.cpp
+ create mode 100644 tests/unit_test_backend_dbus/unit_test_backend_dbus.cpp
+ create mode 100644 tests/unit_test_biometric_helper/CMakeLists.txt
+ create mode 100644 tests/unit_test_biometric_helper/main.cpp
+ create mode 100644 tests/unit_test_biometric_helper/unit_test_biometric_helper.cpp
+ create mode 100644 tests/unit_test_common/CMakeLists.txt
+ create mode 100644 tests/unit_test_common/main.cpp
+ create mode 100644 tests/unit_test_common/unit_test_common.cpp
+ create mode 100644 tests/unit_test_dbus_interface/CMakeLists.txt
+ create mode 100644 tests/unit_test_dbus_interface/main.cpp
+ create mode 100644 tests/unit_test_dbus_interface/unit_test_dbus_interface.cpp
+ create mode 100644 tests/unit_test_display_service/CMakeLists.txt
+ create mode 100644 tests/unit_test_display_service/main.cpp
+ create mode 100644 tests/unit_test_display_service/unit_test_display_service.cpp
+ create mode 100644 tests/unit_test_engine_device/CMakeLists.txt
+ create mode 100644 tests/unit_test_engine_device/main.cpp
+ create mode 100644 tests/unit_test_engine_device/unit_test_engine_device.cpp
+ create mode 100644 tests/unit_test_freedesktop_helper/CMakeLists.txt
+ create mode 100644 tests/unit_test_freedesktop_helper/main.cpp
+ create mode 100644 tests/unit_test_freedesktop_helper/unit_test_freedesktop_helper.cpp
+ create mode 100644 tests/unit_test_gsettings_helper/CMakeLists.txt
+ create mode 100644 tests/unit_test_gsettings_helper/main.cpp
+ create mode 100644 tests/unit_test_gsettings_helper/unit_test_gsettings_helper.cpp
+ create mode 100644 tests/unit_test_inputswitch_event/CMakeLists.txt
+ create mode 100644 tests/unit_test_inputswitch_event/main.cpp
+ create mode 100644 tests/unit_test_inputswitch_event/unit_test_inputswitch_event.cpp
+ create mode 100644 tests/unit_test_kglobalaccel_helper/CMakeLists.txt
+ create mode 100644 tests/unit_test_kglobalaccel_helper/main.cpp
+ create mode 100644 tests/unit_test_kglobalaccel_helper/unit_test_kglobalaccel_helper.cpp
+ create mode 100644 tests/unit_test_lock_dialog_model/CMakeLists.txt
+ create mode 100644 tests/unit_test_lock_dialog_model/main.cpp
+ create mode 100644 tests/unit_test_lock_dialog_model/unit_test_lock_dialog_model.cpp
+ create mode 100644 tests/unit_test_login1_helper/CMakeLists.txt
+ create mode 100644 tests/unit_test_login1_helper/main.cpp
+ create mode 100644 tests/unit_test_login1_helper/unit_test_login1_helper.cpp
+ create mode 100644 tests/unit_test_personal_data/CMakeLists.txt
+ create mode 100644 tests/unit_test_personal_data/main.cpp
+ create mode 100644 tests/unit_test_personal_data/unit_test_common.cpp
+ create mode 100644 tests/unit_test_personal_data/unit_test_personal_data.cpp
+ create mode 100644 tests/unit_test_screenlock/CMakeLists.txt
+ create mode 100644 tests/unit_test_screenlock/main.cpp
+ create mode 100644 tests/unit_test_screenlock/unit_test_screenlock.cpp
+ create mode 100644 tests/unit_test_screensaver/CMakeLists.txt
+ create mode 100644 tests/unit_test_screensaver/main.cpp
+ create mode 100644 tests/unit_test_screensaver/unit_test_screensaver.cpp
+ create mode 100644 tests/unit_test_session_helper/CMakeLists.txt
+ create mode 100644 tests/unit_test_session_helper/main.cpp
+ create mode 100644 tests/unit_test_session_helper/unit_test_session_helper.cpp
+ create mode 100644 tests/unit_test_session_watcher/CMakeLists.txt
+ create mode 100644 tests/unit_test_session_watcher/main.cpp
+ create mode 100644 tests/unit_test_session_watcher/unit_test_session_watcher.cpp
+ create mode 100644 tests/unit_test_switch_user/CMakeLists.txt
+ create mode 100644 tests/unit_test_switch_user/main.cpp
+ create mode 100644 tests/unit_test_switch_user/unit_test_switch_user.cpp
+ create mode 100644 tests/unit_test_systemupgrade_helper/CMakeLists.txt
+ create mode 100644 tests/unit_test_systemupgrade_helper/main.cpp
+ create mode 100644 tests/unit_test_systemupgrade_helper/unit_test_systemupgrade_helper.cpp
+ create mode 100644 tests/unit_test_uniauth_service/CMakeLists.txt
+ create mode 100644 tests/unit_test_uniauth_service/main.cpp
+ create mode 100644 tests/unit_test_uniauth_service/unit_test_uniauth_service.cpp
+ create mode 100644 tests/unit_test_usd_helper/CMakeLists.txt
+ create mode 100644 tests/unit_test_usd_helper/main.cpp
+ create mode 100644 tests/unit_test_usd_helper/unit_test_usd_helper.cpp
+ create mode 100644 ukccplugins_i18n_ts/CMakeLists.txt
+ create mode 100644 ukccplugins_i18n_ts/bo.ts
+ create mode 100644 ukccplugins_i18n_ts/bo_CN.ts
+ create mode 100644 ukccplugins_i18n_ts/de.ts
+ create mode 100644 ukccplugins_i18n_ts/en.ts
+ create mode 100644 ukccplugins_i18n_ts/en_US.ts
+ create mode 100644 ukccplugins_i18n_ts/es.ts
+ create mode 100644 ukccplugins_i18n_ts/fa.ts
+ create mode 100644 ukccplugins_i18n_ts/fr.ts
+ create mode 100644 ukccplugins_i18n_ts/kk.ts
+ create mode 100644 ukccplugins_i18n_ts/ky.ts
+ create mode 100644 ukccplugins_i18n_ts/lzh.ts
+ create mode 100644 ukccplugins_i18n_ts/mn.ts
+ create mode 100644 ukccplugins_i18n_ts/tr.ts
+ create mode 100644 ukccplugins_i18n_ts/ug.ts
+ create mode 100644 ukccplugins_i18n_ts/zh_CN.ts
+ create mode 100644 ukccplugins_i18n_ts/zh_HK.ts
+ create mode 100644 ukccplugins_i18n_ts/zh_Hant.ts
+
+diff --git a/CMakeLists.txt b/CMakeLists.txt
+index 37e601e..2e870f5 100644
+--- a/CMakeLists.txt
++++ b/CMakeLists.txt
+@@ -28,8 +28,10 @@ if(Debug)
+ endif()
+ 
+ add_subdirectory(src)
++#add_subdirectory(tests)
+ add_subdirectory(i18n_ts)
++add_subdirectory(ukccplugins_i18n_ts)
+ add_subdirectory(data)
+ 
+ # 让主目标依赖翻译文件,这样才会执行i18n
+-add_dependencies(ukui-screensaver-dialog i18n)
++add_dependencies(ukui-screensaver-dialog i18n ukccplugins_i18n)
+diff --git a/data/CMakeLists.txt b/data/CMakeLists.txt
+index 91e01fe..4db9e2c 100644
+--- a/data/CMakeLists.txt
++++ b/data/CMakeLists.txt
+@@ -6,3 +6,8 @@ install(FILES ukui-screensaver-qt DESTINATION /etc/pam.d)
+ install(FILES screensaver-startup.sh DESTINATION /usr/bin)
+ install(FILES ukui-screensaver-dialog.desktop DESTINATION /usr/share/applications)
+ install(FILES org.ukui.screensaver.conf DESTINATION /etc/dbus-1/system.d)
++install(FILES ukui-greeter/ukui-greeter-wlcom.desktop DESTINATION /usr/share/xgreeters/)
++install(FILES ukui-greeter/97-ukui-greeter-wlcom.conf DESTINATION /usr/share/lightdm/lightdm.conf.d/)
++install(FILES ukui-greeter/start-greeter-session DESTINATION /usr/bin/)
++install(FILES ukui-greeter/start-quick-session DESTINATION /usr/bin/)
++
+diff --git a/data/ukui-greeter/95-ukui-greeter.conf b/data/ukui-greeter/95-ukui-greeter.conf
+index 2ecb765..45a0cda 100644
+--- a/data/ukui-greeter/95-ukui-greeter.conf
++++ b/data/ukui-greeter/95-ukui-greeter.conf
+@@ -2,4 +2,3 @@
+ greeter-session=ukui-greeter
+ user-session=ukui
+ #greeter-setup-script=/usr/lib/ukui-greeter/ukui-greeter-nm-start.sh
+-enable-autologin-user-lock=false
+diff --git a/data/ukui-greeter/97-ukui-greeter-wlcom.conf b/data/ukui-greeter/97-ukui-greeter-wlcom.conf
+new file mode 100644
+index 0000000..4a166bd
+--- /dev/null
++++ b/data/ukui-greeter/97-ukui-greeter-wlcom.conf
+@@ -0,0 +1,4 @@
++[Seat:*]
++#greeter-session=ukui-greeter-wlcom
++#user-session=kylin-wlcom
++enable-autologin-user-lock=false
+diff --git a/data/ukui-greeter/start-greeter-session b/data/ukui-greeter/start-greeter-session
+new file mode 100755
+index 0000000..698158d
+--- /dev/null
++++ b/data/ukui-greeter/start-greeter-session
+@@ -0,0 +1,3 @@
++#!/bin/sh
++
++exec /usr/bin/ukui-session simpleDesk
+diff --git a/data/ukui-greeter/start-quick-session b/data/ukui-greeter/start-quick-session
+new file mode 100755
+index 0000000..44ee2e8
+--- /dev/null
++++ b/data/ukui-greeter/start-quick-session
+@@ -0,0 +1,4 @@
++#!/bin/sh
++
++# dbus-send --system --dest=org.ukui.UniauthBackend --type=method_call /org/ukui/UniauthBackend org.ukui.UniauthBackend.GetLastLoginUser &
++exec /usr/bin/ukui-session quickstart
+diff --git a/data/ukui-greeter/ukui-greeter-wlcom.desktop b/data/ukui-greeter/ukui-greeter-wlcom.desktop
+new file mode 100644
+index 0000000..239c01b
+--- /dev/null
++++ b/data/ukui-greeter/ukui-greeter-wlcom.desktop
+@@ -0,0 +1,7 @@
++[Desktop Entry]
++Name=UKUI Greeter for wlcom
++Comment=UKUI Greeter for wlcom
++Exec=kylin-wlcom -s  /usr/bin/start-greeter-session
++Type=Application
++X-Ubuntu-Gettext-Domain=ukui-greeter
++X-LightDM-Session-Type=wayland
+diff --git a/data/ukui-screensaver.desktop b/data/ukui-screensaver.desktop
+index c701dac..ebd8438 100644
+--- a/data/ukui-screensaver.desktop
++++ b/data/ukui-screensaver.desktop
+@@ -8,7 +8,7 @@ Name[zh_TW]=螢幕保護程式
+ Comment[tr]=Ekran koruyucuyu çalıştır ve programı kilitler
+ Comment[zh_CN]=运行屏幕保护及锁定程序
+ Comment[zh_TW]=啟動螢幕保護程式以及鎖定程式
+-Exec=ukui-screensaver-backend
++Exec=/usr/bin/ukui-screensaver-backend %U
+ NoDisplay=true
+ X-UKUI-Autostart-Phase=Initialization
+ X-UKUI-Autostart-Notify=true
+diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
+index f76501d..616be9d 100644
+--- a/src/CMakeLists.txt
++++ b/src/CMakeLists.txt
+@@ -81,7 +81,6 @@ set(EXTRA_LIBS
+     -lrt
+     -lpthread
+     -llibnm-icon-kylin
+-    -lukuiinputgatherclient
+     )
+ 
+ #qt5_wrap_ui(dialog_SRC
+@@ -154,6 +153,8 @@ qt5_add_dbus_adaptor(backend_SRC
+ qt5_wrap_cpp(backend_SRC
+        userinfo.h
+        agreementinfo.h
++       ukccplugins/sessiondbus/screensaverinterface.h
++       ukccplugins/sessiondbus/screenlockinterface.h
+     )
+ 
+ set(backend_SRC
+@@ -175,13 +176,17 @@ set(backend_SRC
+     dbusifs/machinemodel.cpp
+     dbusifs/libinputswitchevent.cpp
+     dbusifs/systemupgradehelper.cpp
++    dbusifs/dbusservermanager.cpp
+     userinfo.cpp
+     agreementinfo.cpp
+     common/global_utils.cpp
+     common/configuration.cpp
+     common/biodefines.cpp
+     common/rsac.cpp
++    ukccplugins/sessiondbus/screensaverinterface.cpp
++    ukccplugins/sessiondbus/screenlockinterface.cpp
+     )
++
+ add_executable(ukui-screensaver-backend ${backend_SRC})
+ target_link_libraries(ukui-screensaver-backend
+     Qt5::Core
+@@ -220,6 +225,7 @@ target_link_libraries(screensaver-focus-helper Qt5::Core  Qt5::Widgets Qt5::X11E
+ 
+ add_subdirectory(VirtualKeyboard)
+ add_subdirectory(screensaver)
++add_subdirectory(ukccplugins)
+ 
+ add_dependencies(ukui-screensaver-dialog VirtualKeyboard ukui-screensaver-default screensaver-default Screensaver)
+ 
+diff --git a/src/common/definetypes.h b/src/common/definetypes.h
+index b7fbbb7..2381e65 100644
+--- a/src/common/definetypes.h
++++ b/src/common/definetypes.h
+@@ -203,6 +203,11 @@ typedef enum _LOCK_CMD_ID_e
+ #define SS_DBUS_PATH "/"
+ #define SS_DBUS_INTERFACE "org.ukui.ScreenSaver"
+ 
++#define SL_SESSION_DBUS_SERVICE "org.ukui.ScreenSaver.session.Screenlock"
++#define SL_SESSION_DBUS_PATH "/Screenlock"
++#define SS_SESSION_DBUS_SERVICE "org.ukui.ScreenSaver.session.Screensaver"
++#define SS_SESSION_DBUS_PATH "/Screensaver"
++
+ enum SessionStatus
+ {
+     SESSION_AVAILABLE = 0,
+@@ -352,6 +357,7 @@ enum Action
+     PowerReboot,
+     PowerUpgradeThenShutdown,
+     PowerShutdown,
++    TestAction,
+ };
+ 
+ #endif // DEFINETYPES_H
+diff --git a/src/common/plasma-shell-manager.cpp b/src/common/plasma-shell-manager.cpp
+index 3cd7024..6c57eab 100644
+--- a/src/common/plasma-shell-manager.cpp
++++ b/src/common/plasma-shell-manager.cpp
+@@ -165,7 +165,7 @@ PlasmaShellManager::PlasmaShellManager(QObject *parent) : QObject(parent)
+     auto connection = KWayland::Client::ConnectionThread::fromApplication(qApp);
+     auto registry = new KWayland::Client::Registry(this);
+     registry->create(connection->display());
+-
++#if 0
+     connect(registry, &KWayland::Client::Registry::plasmaShellAnnounced, this, [=]() {
+         qDebug() << "plasmaShellAnnounced...";
+         const auto interface = registry->interface(KWayland::Client::Registry::Interface::PlasmaShell);
+@@ -213,7 +213,7 @@ PlasmaShellManager::PlasmaShellManager(QObject *parent) : QObject(parent)
+             m_shell = registry->createShell(interface.name, interface.version, this);
+         }
+     });
+-
++#endif
+     connect(registry, &KWayland::Client::Registry::fakeInputAnnounced, this, [=]() {
+         qDebug() << "fakeInputAnnounced";
+         const auto interface = registry->interface(KWayland::Client::Registry::Interface::FakeInput);
+@@ -237,6 +237,9 @@ PlasmaShellManager::PlasmaShellManager(QObject *parent) : QObject(parent)
+                     [this](KWayland::Client::Keystate::Key key, KWayland::Client::Keystate::State state) {
+                         qDebug() << "key = " << key << "state = " << state;
+                         m_keyStateMap[key] = state;
++                        if (key == KWayland::Client::Keystate::Key::CapsLock) {
++                            emit capslockStateChanged(state == KWayland::Client::Keystate::Locked);
++                        }
+                         emit keyStateChanged();
+                     });
+                 m_keyState->fetchStates();
+diff --git a/src/common/plasma-shell-manager.h b/src/common/plasma-shell-manager.h
+index 12b2b9d..c69beee 100644
+--- a/src/common/plasma-shell-manager.h
++++ b/src/common/plasma-shell-manager.h
+@@ -49,6 +49,7 @@ public:
+     KWayland::Client::Keystate::State getKeyState(KWayland::Client::Keystate::Key key);
+ Q_SIGNALS:
+     void keyStateChanged();
++    void capslockStateChanged(bool isLocked);
+ 
+ private:
+     explicit PlasmaShellManager(QObject *parent = nullptr);
+diff --git a/src/dbusifs/accountshelper.cpp b/src/dbusifs/accountshelper.cpp
+index de820a3..66395ad 100644
+--- a/src/dbusifs/accountshelper.cpp
++++ b/src/dbusifs/accountshelper.cpp
+@@ -16,12 +16,12 @@
+  *
+  **/
+ #include "accountshelper.h"
+-#include "definetypes.h"
++#include "../common/definetypes.h"
+ #include <QDBusConnection>
+ #include <QDBusInterface>
+ #include <QDBusConnectionInterface>
+ #include <QDebug>
+-#include "userinfo.h"
++#include "../../src/userinfo.h"
+ 
+ AccountsHelper::AccountsHelper(QObject *parent) : QObject(parent)
+ {
+diff --git a/src/dbusifs/biometrichelper.h b/src/dbusifs/biometrichelper.h
+index dbd9fc5..9fca386 100644
+--- a/src/dbusifs/biometrichelper.h
++++ b/src/dbusifs/biometrichelper.h
+@@ -21,7 +21,7 @@
+ #include <QtDBus>
+ #include <QDBusAbstractInterface>
+ #include <QDBusUnixFileDescriptor>
+-#include "biodefines.h"
++#include "../../src/common/biodefines.h"
+ 
+ class BiometricHelper : public QDBusAbstractInterface
+ {
+diff --git a/src/dbusifs/dbusservermanager.cpp b/src/dbusifs/dbusservermanager.cpp
+new file mode 100644
+index 0000000..7135542
+--- /dev/null
++++ b/src/dbusifs/dbusservermanager.cpp
+@@ -0,0 +1,53 @@
++#include "dbusservermanager.h"
++#include "../common/definetypes.h"
++#include <QDebug>
++#include <QDBusReply>
++
++DBusServerManager *DBusServerManager::m_instance = nullptr;
++DBusServerManager::MemCollector DBusServerManager::m_memCollector;
++DBusServerManager::DBusServerManager(QObject *parent) : QObject{ parent }
++{
++    init();
++}
++
++DBusServerManager *DBusServerManager::instance(QObject *parent)
++{
++    if (!m_instance) {
++        m_instance = new DBusServerManager(parent);
++    }
++    return m_instance;
++}
++
++void DBusServerManager::init()
++{
++    if (!m_dbusService) {
++        m_dbusService
++            = new QDBusInterface(FD_DBUS_SERVICE, FD_DBUS_PATH, FD_DBUS_INTERFACE, QDBusConnection::sessionBus());
++        connect(
++            m_dbusService,
++            SIGNAL(NameOwnerChanged(QString, QString, QString)),
++            this,
++            SLOT(onDBusNameOwnerChanged(QString, QString, QString)));
++    }
++}
++
++void DBusServerManager::onDBusNameOwnerChanged(const QString &name, const QString &oldOwner, const QString &newOwner)
++{
++    Q_UNUSED(oldOwner);
++    //    qDebug() << "service status changed:" << name
++    //             << (newOwner.isEmpty() ? "inactivate" : "activate");
++    Q_EMIT dbusServerActiveChanged(name, !newOwner.isEmpty());
++}
++
++bool DBusServerManager::serviceExists(const QString &strService)
++{
++    if (!m_dbusService) {
++        return false;
++    }
++    QDBusReply<bool> reply = m_dbusService->call("NameHasOwner", strService);
++    if (!reply.isValid()) {
++        qWarning() << "check service exists error:" << reply.error();
++        return false;
++    }
++    return reply.value();
++}
+diff --git a/src/dbusifs/dbusservermanager.h b/src/dbusifs/dbusservermanager.h
+new file mode 100644
+index 0000000..04b5dee
+--- /dev/null
++++ b/src/dbusifs/dbusservermanager.h
+@@ -0,0 +1,50 @@
++#ifndef DBUSSERVERMANAGER_H
++#define DBUSSERVERMANAGER_H
++
++#include <QObject>
++#include <QDBusInterface>
++
++class DBusServerManager : public QObject
++{
++    Q_OBJECT
++private:
++    explicit DBusServerManager(QObject *parent = nullptr);
++
++public:
++    /**
++     * @brief 单实例
++     *
++     * @param parent 父指针
++     * @return DBusServerManager 单实例对象指针
++     */
++    static DBusServerManager *instance(QObject *parent = nullptr);
++
++    bool serviceExists(const QString &strService);
++
++public Q_SLOTS:
++    void onDBusNameOwnerChanged(const QString &name,
++                                const QString &oldOwner,
++                                const QString &newOwner);
++
++Q_SIGNALS:
++    void dbusServerActiveChanged(const QString &strServerName, bool isActive);
++
++private:
++    void init();
++
++private:
++    class MemCollector{
++    public:
++        ~MemCollector(){
++            if (DBusServerManager::instance()) {
++                delete DBusServerManager::instance();
++                DBusServerManager::m_instance = nullptr;
++            }
++        }
++    };
++    static DBusServerManager *m_instance; /** 统一认证配置服务单实例指针 */
++    static MemCollector m_memCollector;
++    QDBusInterface *m_dbusService = nullptr;
++};
++
++#endif // DBUSSERVERMANAGER_H
+diff --git a/src/dbusifs/enginedevice.cpp b/src/dbusifs/enginedevice.cpp
+index b9ed268..81c0503 100644
+--- a/src/dbusifs/enginedevice.cpp
++++ b/src/dbusifs/enginedevice.cpp
+@@ -41,7 +41,7 @@ void EngineDevice::power_device_get_devices()
+     int len = deviceNames.size();
+     // qDebug()<<deviceNames.at(1).path();
+     for (int i = 0; i < len; i++) {
+-        DEVICE *device = new DEVICE;
++        DEVICE *device = new DEVICE(this);
+         device->m_dev.path = deviceNames.at(i).path();
+         getProperty(device->m_dev.path, device->m_dev);
+         /* connect the nofity signal to changecallback */
+diff --git a/src/dbusifs/freedesktophelper.h b/src/dbusifs/freedesktophelper.h
+index 0d08ae0..2157305 100644
+--- a/src/dbusifs/freedesktophelper.h
++++ b/src/dbusifs/freedesktophelper.h
+@@ -21,7 +21,7 @@
+ #include <QtDBus>
+ #include <QDBusAbstractInterface>
+ #include <QDBusUnixFileDescriptor>
+-#include "definetypes.h"
++#include "../common/definetypes.h"
+ 
+ class FreedesktopHelper : public QDBusAbstractInterface
+ {
+diff --git a/src/dbusifs/login1helper.cpp b/src/dbusifs/login1helper.cpp
+index bbf0e1f..075779c 100644
+--- a/src/dbusifs/login1helper.cpp
++++ b/src/dbusifs/login1helper.cpp
+@@ -21,6 +21,7 @@
+ #include <QDBusConnection>
+ #include <QDBusInterface>
+ #include <QDBusConnectionInterface>
++#include <QDBusMessage>
+ 
+ const static QString login1Service = QStringLiteral("org.freedesktop.login1");
+ const static QString login1Path = QStringLiteral("/org/freedesktop/login1");
+@@ -30,12 +31,11 @@ const static QString login1SessionInterface = QStringLiteral("org.freedesktop.lo
+ 
+ Login1Helper::Login1Helper(QObject *parent) : QObject(parent)
+ {
+-    QDBusInterface *loginInterface
+-        = new QDBusInterface(login1Service, login1Path, login1ManagerInterface, QDBusConnection::systemBus(), this);
++    m_login1Interface = new QDBusInterface(login1Service, login1Path, login1ManagerInterface, QDBusConnection::systemBus(), this);
+     // 监听manager的睡眠、唤醒信号
+-    connect(loginInterface, SIGNAL(PrepareForSleep(bool)), this, SLOT(onPrepareForSleep(bool)));
++    connect(m_login1Interface, SIGNAL(PrepareForSleep(bool)), this, SLOT(onPrepareForSleep(bool)));
+ 
+-    QDBusReply<QDBusObjectPath> sessionPath = loginInterface->call("GetSession", "auto");
++    QDBusReply<QDBusObjectPath> sessionPath = m_login1Interface->call("GetSession", "auto");
+     if (!sessionPath.isValid()) {
+         qWarning() << "Get session error:" << sessionPath.error();
+     } else {
+@@ -138,22 +138,26 @@ void Login1Helper::onHibitedWatcherMessage()
+ 
+ void Login1Helper::setPowerManager(const QString &powerManagerfunc)
+ {
+-    QDBusInterface iface(login1Service, login1Path, login1ManagerInterface, QDBusConnection::systemBus());
+-    iface.call(powerManagerfunc, true);
++    if (m_login1Interface) {
++        m_login1Interface->call(powerManagerfunc, true);
++    }
+ }
+ 
+ bool Login1Helper::getCanPowerManager(const QString &powerManagerfunc)
+ {
+     qDebug() << __LINE__ << __FUNCTION__ << "===========";
+-    bool canFlag = true;
+-    QDBusInterface iface(login1Service, login1Path, login1ManagerInterface, QDBusConnection::systemBus());
+-    QDBusReply<QString> stateReplySuspend = iface.call(powerManagerfunc);
+-    if (stateReplySuspend.isValid() && stateReplySuspend.value() == "yes") {
+-        canFlag = true;
++    if (m_login1Interface) {
++        bool canFlag = true;
++        QDBusReply<QString> stateReplySuspend = m_login1Interface->call(powerManagerfunc);
++        if (stateReplySuspend.isValid() && stateReplySuspend.value() == "yes") {
++            canFlag = true;
++        } else {
++            canFlag = false;
++        }
++        return canFlag;
+     } else {
+-        canFlag = false;
++        return false;
+     }
+-    return canFlag;
+ }
+ 
+ bool Login1Helper::isCanHibernate()
+diff --git a/src/dbusifs/login1helper.h b/src/dbusifs/login1helper.h
+index ea616fe..94067a6 100644
+--- a/src/dbusifs/login1helper.h
++++ b/src/dbusifs/login1helper.h
+@@ -21,7 +21,7 @@
+ #include <QDBusConnection>
+ #include <QVariantMap>
+ #include <QObject>
+-#include "definetypes.h"
++#include "../common/definetypes.h"
+ 
+ /**
+  * @brief login1访问工具类
+@@ -124,6 +124,7 @@ private:
+     bool m_isCanLogout = true;
+ 
+     QString m_strSessionPath; // 当前会话路径
++    QDBusInterface *m_login1Interface = nullptr;
+ };
+ 
+ #endif // LOGIN1HELPER_H
+diff --git a/src/dbusifs/sessionhelper.cpp b/src/dbusifs/sessionhelper.cpp
+index ccbb7d1..d3fb9dc 100644
+--- a/src/dbusifs/sessionhelper.cpp
++++ b/src/dbusifs/sessionhelper.cpp
+@@ -26,7 +26,8 @@
+ #include <QProcess>
+ 
+ #include "login1helper.h"
+-#include "lock-backend/gsettingshelper.h"
++#include "../lock-backend/gsettingshelper.h"
++#include "dbusservermanager.h"
+ 
+ const static QString sessionService = QStringLiteral("org.gnome.SessionManager");
+ const static QString sessionPath = QStringLiteral("/org/gnome/SessionManager");
+@@ -48,10 +49,32 @@ const QDBusArgument &InhibitInfo::operator>>(const QDBusArgument &argument, Inhi
+     return argument;
+ }
+ 
+-SessionHelper::SessionHelper(QObject *parent) : QObject(parent)
++SessionHelper::SessionHelper(QSharedPointer<Login1Helper> login1Helper, QObject *parent) : QObject(parent)
++  , m_login1Helper(login1Helper)
+ {
+-    m_sessionInterface
+-        = new QDBusInterface(sessionService, sessionPath, sessionInterface, QDBusConnection::sessionBus(), this);
++    init();
++}
++
++void SessionHelper::init()
++{
++    if (!m_sessionInterface && DBusServerManager::instance()->serviceExists(sessionService)) {
++        qDebug() << "Init session interface!";
++        m_sessionInterface
++            = new QDBusInterface(sessionService, sessionPath, sessionInterface, QDBusConnection::sessionBus(), this);
++    } else {
++        connect(DBusServerManager::instance(), &DBusServerManager::dbusServerActiveChanged, this, &SessionHelper::onSessionDbusActiveChanged);
++    }
++}
++
++void SessionHelper::onSessionDbusActiveChanged(const QString &strServerName, bool isActive)
++{
++    if (strServerName == sessionService && isActive) {
++        qDebug() << "Init session interface!";
++        if (!m_sessionInterface) {
++            m_sessionInterface
++                = new QDBusInterface(sessionService, sessionPath, sessionInterface, QDBusConnection::sessionBus(), this);
++        }
++    }
+ }
+ 
+ SessionHelper::~SessionHelper() {}
+@@ -59,73 +82,72 @@ SessionHelper::~SessionHelper() {}
+ bool SessionHelper::canAction(Action action)
+ {
+     //以下为代码结构调整
+-    QString command;
+-    switch (action) {
+-        case PowerSwitchUser:
+-            command = QLatin1String("canSwitch");
+-            break;
+-        case PowerHibernate:
+-            command = QLatin1String("canHibernate");
+-            break;
+-        case PowerSuspend:
+-            command = QLatin1String("canSuspend");
+-            break;
+-        case PowerMonitorOff:
+-            command = QLatin1String("canLockscreen");
+-            break;
+-        case PowerLogout:
+-            command = QLatin1String("canLogout");
+-            break;
+-        case PowerReboot:
+-            command = QLatin1String("canReboot");
+-            break;
+-        case PowerShutdown:
+-            command = QLatin1String("canPowerOff");
+-            break;
+-        default:
+-            break;
+-    }
++    if (m_sessionInterface) {
++        QString command;
++        switch (action) {
++            case PowerSwitchUser:
++                command = QLatin1String("canSwitch");
++                break;
++            case PowerHibernate:
++                command = QLatin1String("canHibernate");
++                break;
++            case PowerSuspend:
++                command = QLatin1String("canSuspend");
++                break;
++            case PowerMonitorOff:
++                command = QLatin1String("canLockscreen");
++                break;
++            case PowerLogout:
++                command = QLatin1String("canLogout");
++                break;
++            case PowerReboot:
++                command = QLatin1String("canReboot");
++                break;
++            case PowerShutdown:
++                command = QLatin1String("canPowerOff");
++                break;
++            default:
++                break;
++        }
+ 
+-    if (!m_sessionInterface->isValid()) {
+-        qWarning() << "dbusCall: Session QDBusInterface is invalid";
+-        return false;
+-    }
++        if (!m_sessionInterface->isValid()) {
++            qWarning() << "dbusCall: Session QDBusInterface is invalid";
++            return false;
++        }
+ 
+-    QDBusReply<bool> testReply = m_sessionInterface->call(QLatin1String("canLockscreen"));
+-    if (!testReply.isValid()) {
+-        //解决老版本升级到新版本接口不兼容的问题,在session接口不存在的情况下,调用systemd的接口
+-        QDBusError error = testReply.error();
+-        Login1Helper *m_login1Helper = new Login1Helper(this);
+-        if (error.type() == QDBusError::UnknownMethod) {
+-            qInfo() << "updating ! old ukui-session dose not have canAction method";
+-            if (action == PowerLogout || action == PowerMonitorOff) {
+-                return true;
++        QDBusReply<bool> testReply = m_sessionInterface->call(QLatin1String("canLockscreen"));
++        if (!testReply.isValid()) {
++            //解决老版本升级到新版本接口不兼容的问题,在session接口不存在的情况下,调用systemd的接口
++            QDBusError error = testReply.error();
++            Login1Helper *m_login1Helper = new Login1Helper(this);
++            if (error.type() == QDBusError::UnknownMethod) {
++                qInfo() << "updating ! old ukui-session dose not have canAction method";
++                if (action == PowerLogout || action == PowerMonitorOff) {
++                    return true;
++                }
++                if (m_login1Helper) {
++                    return m_login1Helper->canAction(action);
++                }
+             }
+-            return m_login1Helper->canAction(action);
++            qInfo() << "dbus error";
++            return false;
++        }
++        QDBusReply<bool> reply = m_sessionInterface->call(command);
++        qInfo() << "command = " << command << "reply = " << m_sessionInterface->call(command);
++        return reply.value();
++    } else if (m_login1Helper){
++        if (action == PowerLogout || action == PowerMonitorOff) {
++            return true;
+         }
+-        qInfo() << "dbus error";
++        return m_login1Helper->canAction(action);
++    } else {
+         return false;
+     }
+-
+-    QDBusReply<bool> reply = m_sessionInterface->call(command);
+-
+-    qInfo() << "command = " << command << "reply = " << m_sessionInterface->call(command);
+-
+-    return reply.value();
+ }
+ 
+ bool SessionHelper::doAction(const QString &powerManagerfunc)
+ {
+-    if (!m_sessionInterface->isValid()) {
+-        qWarning() << "dbusCall: Session QDBusInterface is invalid";
+-        return false;
+-    }
+-
+-    up_to_time = new QTimer();
+-    up_to_time->setSingleShot(true);
+-
+-//    qDebug() << "playShutdownMusic(powerManagerfunc) = " << playShutdownMusic(powerManagerfunc);
+-
++    // qDebug() << "doAction = " << powerManagerfunc;
+     if (!playShutdownMusic(powerManagerfunc)) {
+         doPowerManager(powerManagerfunc);
+     }
+@@ -134,61 +156,68 @@ bool SessionHelper::doAction(const QString &powerManagerfunc)
+ 
+ void SessionHelper::doPowerManager(const QString &powerManagerfunc)
+ {
+-    QString command;
+-    if (powerManagerfunc == "Hibernate") {
+-        command = QLatin1String("hibernate");
+-    } else if (powerManagerfunc == "Suspend") {
+-        command = QLatin1String("suspend");
+-    } else if (powerManagerfunc == "Reboot") {
+-        command = QLatin1String("reboot");
+-    } else if (powerManagerfunc == "PowerOff") {
+-        command = QLatin1String("powerOff");
+-    } else if (powerManagerfunc == "Logout") {
+-        command = QLatin1String("logout");
+-    } else if (powerManagerfunc == "SwitchUser") {
+-        command = QLatin1String("switchUser");
+-    } else {
+-        return;
+-    }
+-    QDBusMessage mes = m_sessionInterface->call(command);
++    if (m_sessionInterface) {
++        QString command;
++        if (powerManagerfunc == "Hibernate") {
++            command = QLatin1String("hibernate");
++        } else if (powerManagerfunc == "Suspend") {
++            command = QLatin1String("suspend");
++        } else if (powerManagerfunc == "Reboot") {
++            command = QLatin1String("reboot");
++        } else if (powerManagerfunc == "PowerOff") {
++            command = QLatin1String("powerOff");
++        } else if (powerManagerfunc == "Logout") {
++            command = QLatin1String("logout");
++        } else if (powerManagerfunc == "SwitchUser") {
++            command = QLatin1String("switchUser");
++        } else {
++            return;
++        }
++        QDBusMessage mes = m_sessionInterface->call(command);
+ 
+-    if (!(mes.errorName().isEmpty())) {
+-        Login1Helper *m_login1Helper = new Login1Helper(this);
+-        //本来应该判断错误类别,考虑到运行效率,不做该判断
++        if (!(mes.errorName().isEmpty()) && m_login1Helper) {
++            //本来应该判断错误类别,考虑到运行效率,不做该判断
++            m_login1Helper->setPowerManager(powerManagerfunc);
++        }
++    } else if (m_login1Helper) {
+         m_login1Helper->setPowerManager(powerManagerfunc);
+     }
+ }
+ 
+ QStringList SessionHelper::getLockCheckStatus(QString type)
+ {
+-    qDBusRegisterMetaType<InhibitInfo::InhibitorInfo>();
++    if (m_sessionInterface) {
++        qDBusRegisterMetaType<InhibitInfo::InhibitorInfo>();
+ 
+-    QVector<InhibitInfo::InhibitorInfo> resVec;
++        QVector<InhibitInfo::InhibitorInfo> resVec;
+ 
+-    if (!m_sessionInterface->isValid()) {
+-        qDebug() << "session interface invalid!";
+-    }
++        if (!m_sessionInterface->isValid()) {
++            qDebug() << "session interface invalid!";
++        }
+ 
+-    QDBusMessage result = m_sessionInterface->call("ListInhibitor", QVariant(type));
+-    QList<QVariant> outArgs = result.arguments();
+-    QVariant first = outArgs.at(0);
+-    const QDBusArgument &dbusArgs = first.value<QDBusArgument>();
++        QDBusMessage result = m_sessionInterface->call("ListInhibitor", QVariant(type));
++        QList<QVariant> outArgs = result.arguments();
++        QVariant first = outArgs.at(0);
++        const QDBusArgument &dbusArgs = first.value<QDBusArgument>();
+ 
+-    dbusArgs.beginArray();
+-    while (!dbusArgs.atEnd()) {
+-        InhibitInfo::InhibitorInfo inhibtor;
+-        dbusArgs >> inhibtor;
+-        resVec.push_back(inhibtor);
+-    }
+-    dbusArgs.endArray();
+-    QStringList lockCheckList;
+-    for (auto iter = resVec.begin(); iter != resVec.end(); ++iter) {
+-        lockCheckList.append(iter->icon);
+-        lockCheckList.append(iter->name);
+-    }
+-    // qDebug() << "lockCheckList = " << lockCheckList;
++        dbusArgs.beginArray();
++        while (!dbusArgs.atEnd()) {
++            InhibitInfo::InhibitorInfo inhibtor;
++            dbusArgs >> inhibtor;
++            resVec.push_back(inhibtor);
++        }
++        dbusArgs.endArray();
++        QStringList lockCheckList;
++        for (auto iter = resVec.begin(); iter != resVec.end(); ++iter) {
++            lockCheckList.append(iter->icon);
++            lockCheckList.append(iter->name);
++        }
++        // qDebug() << "lockCheckList = " << lockCheckList;
+ 
+-    return lockCheckList;
++        return lockCheckList;
++    } else {
++        return QStringList();
++    }
+ }
+ 
+ bool SessionHelper::playShutdownMusic(const QString &powerManagerfunc)
+@@ -203,12 +232,14 @@ bool SessionHelper::playShutdownMusic(const QString &powerManagerfunc)
+         play_music = gsettingsHelper->GetSessionConf(KEY_SESSION_POWEROFF_MUSIC).toBool();
+     } else if (powerManagerfunc == "Logout") {
+         play_music = gsettingsHelper->GetSessionConf(KEY_SESSION_LOGOUT_MUSIC).toBool();
+-        msg = m_sessionInterface->call("emitStartLogout");
+-        if (!msg.errorName().isEmpty()) {
+-            qWarning() << "Dbus error: " << msg;
++        if (m_sessionInterface) {
++            msg = m_sessionInterface->call("emitStartLogout");
++            if (!msg.errorName().isEmpty()) {
++                qWarning() << "Dbus error: " << msg;
++            }
+         }
+     } else {
+-        if (powerManagerfunc == "SwitchUser") {
++        if (powerManagerfunc == "SwitchUser" && m_sessionInterface) {
+             msg = m_sessionInterface->call("emitPrepareForSwitchuser");
+             if (!msg.errorName().isEmpty()) {
+                 qWarning() << "Dbus error: " << msg;
+@@ -218,8 +249,13 @@ bool SessionHelper::playShutdownMusic(const QString &powerManagerfunc)
+     }
+ 
+     if (play_music) {
+-        QObject::connect(up_to_time, &QTimer::timeout, [=]() {
+-            doPowerManager(powerManagerfunc);
++        if (!m_timerPlayMusic) {
++            m_timerPlayMusic = new QTimer();
++            m_timerPlayMusic->setSingleShot(true);
++        }
++        disconnect(m_timerPlayMusic, nullptr, this, nullptr);
++        connect(m_timerPlayMusic, &QTimer::timeout, this, [&, this, powerManagerfunc]() {
++            this->doPowerManager(powerManagerfunc);
+             return true;
+         });
+         QString xdg_session_type = qgetenv("XDG_SESSION_TYPE");
+@@ -229,14 +265,14 @@ bool SessionHelper::playShutdownMusic(const QString &powerManagerfunc)
+             } else {
+                 QProcess::startDetached("aplay /usr/share/ukui/ukui-session-manager/shutdown.wav");
+             }
+-            up_to_time->start(5000);
++            m_timerPlayMusic->start(5000);
+         } else if (powerManagerfunc == "Logout") {
+             if (xdg_session_type == "wayland") {
+                 QProcess::startDetached("paplay /usr/share/ukui/ukui-session-manager/logout.wav");
+             } else {
+                 QProcess::startDetached("aplay /usr/share/ukui/ukui-session-manager/logout.wav");
+             }
+-            up_to_time->start(2000);
++            m_timerPlayMusic->start(2000);
+         } else {
+             qDebug() << "error num";
+             return false;
+diff --git a/src/dbusifs/sessionhelper.h b/src/dbusifs/sessionhelper.h
+index 6c2248c..a113b7f 100644
+--- a/src/dbusifs/sessionhelper.h
++++ b/src/dbusifs/sessionhelper.h
+@@ -22,7 +22,8 @@
+ #include <QFile>
+ #include <QTimer>
+ #include <QDBusArgument>
+-#include "definetypes.h"
++#include <QSharedPointer>
++#include "../common/definetypes.h"
+ 
+ namespace InhibitInfo
+ {
+@@ -46,7 +47,7 @@ class SessionHelper : public QObject
+ {
+     Q_OBJECT
+ public:
+-    explicit SessionHelper(QObject *parent = nullptr);
++    explicit SessionHelper(QSharedPointer<Login1Helper> login1Helper, QObject *parent = nullptr);
+ 
+     virtual ~SessionHelper();
+ 
+@@ -56,14 +57,22 @@ public:
+ 
+     bool doAction(const QString &powerManagerfunc);
+ 
+-private:
+-    QDBusInterface *m_sessionInterface = nullptr;
++private Q_SLOTS:
++    void onSessionDbusActiveChanged(const QString &strServerName, bool isActive);
+ 
+-    QTimer *up_to_time = nullptr;
++private:
++    void init();
+ 
+     void doPowerManager(const QString &powerManagerfunc);
+ 
+     bool playShutdownMusic(const QString &powerManagerfunc);
++
++private:
++    QDBusInterface *m_sessionInterface = nullptr;
++
++    QTimer *m_timerPlayMusic = nullptr;
++
++    QSharedPointer<Login1Helper> m_login1Helper = nullptr;
+ };
+ 
+ #endif // SESSIONHELPER_H
+diff --git a/src/dbusifs/uniauthservice.cpp b/src/dbusifs/uniauthservice.cpp
+index 1657b24..5403907 100644
+--- a/src/dbusifs/uniauthservice.cpp
++++ b/src/dbusifs/uniauthservice.cpp
+@@ -18,7 +18,7 @@
+ #include "uniauthservice.h"
+ #include <QDebug>
+ #include <pwd.h>
+-#include "definetypes.h"
++#include "../common/definetypes.h"
+ #include "freedesktophelper.h"
+ 
+ /* For the type WillLoginUserInfo */
+diff --git a/src/dbusifs/upowerhelper.h b/src/dbusifs/upowerhelper.h
+index 7f31af6..3db9edb 100644
+--- a/src/dbusifs/upowerhelper.h
++++ b/src/dbusifs/upowerhelper.h
+@@ -19,6 +19,7 @@
+ #define UPOWERHELPER_H
+ 
+ #include <QDBusConnection>
++#include <QDBusMessage>
+ #include <QVariantMap>
+ #include <QObject>
+ 
+diff --git a/src/lock-backend/bioauthenticate.cpp b/src/lock-backend/bioauthenticate.cpp
+index 93f1804..4cdbb4e 100644
+--- a/src/lock-backend/bioauthenticate.cpp
++++ b/src/lock-backend/bioauthenticate.cpp
+@@ -16,12 +16,12 @@
+  *
+  **/
+ #include "bioauthenticate.h"
+-#include "freedesktophelper.h"
+-#include "biometrichelper.h"
+-#include "uniauthservice.h"
++#include "../../src/dbusifs/freedesktophelper.h"
++#include "../../src/dbusifs/biometrichelper.h"
++#include "../../src/dbusifs/uniauthservice.h"
+ #include <pwd.h>
+ #include <unistd.h>
+-#include "giodbus.h"
++#include "../../src/dbusifs/giodbus.h"
+ 
+ BioAuthenticate::BioAuthenticate(QObject *parent)
+     : QObject(parent), m_systemFdHelper(new FreedesktopHelper(false, this)), m_bioTimer(nullptr)
+diff --git a/src/lock-backend/bioauthenticate.h b/src/lock-backend/bioauthenticate.h
+index c26e533..d295812 100644
+--- a/src/lock-backend/bioauthenticate.h
++++ b/src/lock-backend/bioauthenticate.h
+@@ -21,7 +21,7 @@
+ #include <QObject>
+ #include <QList>
+ #include <QMap>
+-#include "biodefines.h"
++#include "../../src/common/biodefines.h"
+ 
+ class BiometricHelper;
+ class FreedesktopHelper;
+diff --git a/src/lock-backend/dbusupperinterface.cpp b/src/lock-backend/dbusupperinterface.cpp
+index db209a7..d4eadcc 100644
+--- a/src/lock-backend/dbusupperinterface.cpp
++++ b/src/lock-backend/dbusupperinterface.cpp
+@@ -17,11 +17,11 @@
+  **/
+ #include "dbusupperinterface.h"
+ #include "lightdmhelper.h"
+-#include "login1helper.h"
+-#include "definetypes.h"
+-#include "configuration.h"
+-#include "gsettingshelper.h"
+-#include "usdhelper.h"
++#include "../../src/dbusifs/login1helper.h"
++#include "../../src/common/definetypes.h"
++#include "../../src/common/configuration.h"
++#include "../../src/lock-backend/gsettingshelper.h"
++#include "../../src/dbusifs/usdhelper.h"
+ #include <QJsonValue>
+ #include <QJsonObject>
+ #include <QJsonDocument>
+@@ -29,25 +29,34 @@
+ #include <QJsonArray>
+ #include <QJsonParseError>
+ #include <QDebug>
+-#include "qtlocalpeer.h"
+-#include "switchuserutils.h"
+-#include "pamauthenticate.h"
+-#include "upowerhelper.h"
+-#include "accountshelper.h"
+-#include "sessionhelper.h"
+-#include "systemupgradehelper.h"
+-#include "sessionwatcher.h"
+-#include "freedesktophelper.h"
+-#include "bioauthenticate.h"
+-#include "rsac.h"
+-#include "kglobalaccelhelper.h"
+-#include "personalizeddata.h"
+-#include "libinputswitchevent.h"
+-#include "uniauthservice.h"
++#include "../../src/QtSingleApplication/qtlocalpeer.h"
++#include "../../src/lock-backend/switchuserutils.h"
++#include "../../src/lock-backend/pamauthenticate.h"
++#include "../../src/dbusifs/upowerhelper.h"
++#include "../../src/dbusifs/accountshelper.h"
++#include "../../src/dbusifs/sessionhelper.h"
++#include "../../src/dbusifs/systemupgradehelper.h"
++#include "../../src/lock-backend/sessionwatcher.h"
++#include "../../src/dbusifs/freedesktophelper.h"
++#include "../../src/lock-backend/bioauthenticate.h"
++#include "../../src/common/rsac.h"
++#include "../../src/dbusifs/kglobalaccelhelper.h"
++#include "../../src/lock-backend/personalizeddata.h"
++#include "../../src/dbusifs/libinputswitchevent.h"
++#include "../../src/dbusifs/uniauthservice.h"
++#include <syslog.h>
+ 
+ #define CONFIG_FILE "/usr/share/ukui-greeter/ukui-greeter.conf"
+ 
+ DbusUpperInterface::DbusUpperInterface(QObject *parent) : QObject(parent)
++{
++    m_bLockState = false;
++    m_bSlpState = false;
++}
++
++DbusUpperInterface::~DbusUpperInterface() {}
++
++void DbusUpperInterface::init()
+ {
+     initData();
+     initConnections();
+@@ -56,130 +65,152 @@ DbusUpperInterface::DbusUpperInterface(QObject *parent) : QObject(parent)
+ 
+ void DbusUpperInterface::initData()
+ {
+-    m_bLockState = false;
+-    m_bSlpState = false;
++    syslog(LOG_INFO, "[ukui-screensaver-backend] DbusUpperInterface initData begin!!");
+     m_config = Configuration::instance(this);
+-    m_accountsHelper = new AccountsHelper(this);
+-    m_lightDmHelper = new LightDMHelper(m_accountsHelper, m_config, this);
+-    m_login1Helper = new Login1Helper(this);
+-    m_gsettingsHelper = new GSettingsHelper(this);
+-    m_bioAuth = new BioAuthenticate(this);
+-    m_pamAuth = new PamAuthenticate(m_lightDmHelper, this);
+-    m_usdHelper = new UsdHelper(this);
+-    m_upowerHelper = new UpowerHelper(this);
+-    m_sessionHelper = new SessionHelper(this);
+-    m_systemsUpgradeHelper = new SystemUpgradeHelper(this);
+-    m_sessionWatcher = new SessionWatcher(m_gsettingsHelper, this);
+-    m_kglobalHelper = new KglobalAccelHelper(this);
+-    m_libinputSwitchEvent = new LibinputSwitchEvent(this);
++    m_accountsHelper = QSharedPointer<AccountsHelper>(new AccountsHelper(this));
++    m_lightDmHelper = QSharedPointer<LightDMHelper>(new LightDMHelper(m_accountsHelper, m_config, this));
++    m_login1Helper = QSharedPointer<Login1Helper>(new Login1Helper(this));
++    m_gsettingsHelper = QSharedPointer<GSettingsHelper>(new GSettingsHelper(this));
++    m_bioAuth = QSharedPointer<BioAuthenticate>(new BioAuthenticate(this));
++    m_pamAuth = QSharedPointer<PamAuthenticate>(new PamAuthenticate(m_lightDmHelper, this));
++    m_usdHelper = QSharedPointer<UsdHelper>(new UsdHelper(this));
++    m_upowerHelper = QSharedPointer<UpowerHelper>(new UpowerHelper(this));
++    m_sessionHelper = QSharedPointer<SessionHelper>(new SessionHelper(m_login1Helper, this));
++    m_systemsUpgradeHelper = QSharedPointer<SystemUpgradeHelper>(new SystemUpgradeHelper(this));
++    m_sessionWatcher = QSharedPointer<SessionWatcher>(new SessionWatcher(m_gsettingsHelper, this));
++    m_kglobalHelper = QSharedPointer<KglobalAccelHelper>(new KglobalAccelHelper(this));
++    m_libinputSwitchEvent = QSharedPointer<LibinputSwitchEvent>(new LibinputSwitchEvent(this));
+ 
+     m_config->initShareConfig();
+     m_config->setShareConfigValue("timeType", m_gsettingsHelper->GetUkccPluginsConf(KEY_HOUR_SYSTEM).toInt());
+     m_config->setShareConfigValue("dateType", m_gsettingsHelper->GetUkccPluginsConf(KEY_DATE).toString());
+     m_config->setShareConfigValue("fontSize", m_gsettingsHelper->GetThemeStyleConf(KEY_SYSTEM_FONT_SIZE).toDouble());
+     m_config->setShareConfigValue("themeColor", m_gsettingsHelper->GetThemeStyleConf(KEY_THEME_COLOR).toString());
++    syslog(LOG_INFO, "[ukui-screensaver-backend] DbusUpperInterface initData end!!");
+ }
+ 
+ void DbusUpperInterface::initConnections()
+ {
+     if (m_lightDmHelper) {
+-        connect(m_lightDmHelper, &LightDMHelper::usersInfoChanged, this, &DbusUpperInterface::onUsersInfoChanged);
++        connect(m_lightDmHelper.get(), &LightDMHelper::usersInfoChanged, this, &DbusUpperInterface::onUsersInfoChanged);
+         connect(
+-            m_lightDmHelper, &LightDMHelper::currentSessionChanged, this, &DbusUpperInterface::onCurrentSessionChanged);
++            m_lightDmHelper.get(),
++            &LightDMHelper::currentSessionChanged,
++            this,
++            &DbusUpperInterface::onCurrentSessionChanged);
+     }
+     if (m_login1Helper) {
+-        connect(m_login1Helper, &Login1Helper::requestLock, this, &DbusUpperInterface::onLogin1ReqLock);
+-        connect(m_login1Helper, &Login1Helper::requestUnlock, this, &DbusUpperInterface::onLogin1ReqUnLock);
+-        connect(m_login1Helper, &Login1Helper::PrepareForSleep, this, &DbusUpperInterface::onLogin1PrepareForSleep);
++        connect(m_login1Helper.get(), &Login1Helper::requestLock, this, &DbusUpperInterface::onLogin1ReqLock);
++        connect(m_login1Helper.get(), &Login1Helper::requestUnlock, this, &DbusUpperInterface::onLogin1ReqUnLock);
+         connect(
+-            m_login1Helper,
++            m_login1Helper.get(), &Login1Helper::PrepareForSleep, this, &DbusUpperInterface::onLogin1PrepareForSleep);
++        connect(
++            m_login1Helper.get(),
+             &Login1Helper::sessionActiveChanged,
+             this,
+             &DbusUpperInterface::onLogin1SessionActiveChanged);
+         connect(
+-            m_login1Helper, &Login1Helper::blockInhibitedChanged, this, &DbusUpperInterface::onBlockInhibitedChanged);
++            m_login1Helper.get(),
++            &Login1Helper::blockInhibitedChanged,
++            this,
++            &DbusUpperInterface::onBlockInhibitedChanged);
+     }
+     if (m_gsettingsHelper) {
+         connect(
+-            m_gsettingsHelper,
++            m_gsettingsHelper.get(),
+             &GSettingsHelper::lockScreenConfigChanged,
+             this,
+             &DbusUpperInterface::onLockScreenConfigChanged);
+         connect(
+-            m_gsettingsHelper,
++            m_gsettingsHelper.get(),
+             &GSettingsHelper::screenSaverConfigChanged,
+             this,
+             &DbusUpperInterface::onScreenSaverConfigChanged);
+         connect(
+-            m_gsettingsHelper,
++            m_gsettingsHelper.get(),
+             &GSettingsHelper::powerManagerConfigChanged,
+             this,
+             &DbusUpperInterface::onPowerManagerConfigChanged);
+         connect(
+-            m_gsettingsHelper, &GSettingsHelper::mateBgConfigChanged, this, &DbusUpperInterface::onMateBgConfigChanged);
++            m_gsettingsHelper.get(),
++            &GSettingsHelper::mateBgConfigChanged,
++            this,
++            &DbusUpperInterface::onMateBgConfigChanged);
+         connect(
+-            m_gsettingsHelper,
++            m_gsettingsHelper.get(),
+             &GSettingsHelper::ukccPluginsConfigChanged,
+             this,
+             &DbusUpperInterface::onUkccPluginsConfigChanged);
+         connect(
+-            m_gsettingsHelper,
++            m_gsettingsHelper.get(),
+             &GSettingsHelper::themeStyleConfigChanged,
+             this,
+             &DbusUpperInterface::onThemeStyleConfigChanged);
+         connect(
+-            m_gsettingsHelper,
++            m_gsettingsHelper.get(),
+             &GSettingsHelper::sessionConfigChanged,
+             this,
+             &DbusUpperInterface::onSessionConfigChanged);
+         connect(
+-            m_gsettingsHelper,
++            m_gsettingsHelper.get(),
+             &GSettingsHelper::keyboardConfigChanged,
+             this,
+             &DbusUpperInterface::onKeyboardConfigChanged);
+         connect(
+-            m_gsettingsHelper,
++            m_gsettingsHelper.get(),
+             &GSettingsHelper::usdMediaKeysConfigChanged,
+             this,
+             &DbusUpperInterface::onUsdMediaKeysConfigChanged);
+         connect(
+-            m_gsettingsHelper,
++            m_gsettingsHelper.get(),
+             &GSettingsHelper::usdMediaStateKeysConfigChanged,
+             this,
+             &DbusUpperInterface::onUsdMediaStateKeysConfigChanged);
+     }
+     if (m_bioAuth) {
+-        connect(m_bioAuth, &BioAuthenticate::bioAuthShowMessage, this, &DbusUpperInterface::onBioAuthShowMessage);
++        connect(m_bioAuth.get(), &BioAuthenticate::bioAuthShowMessage, this, &DbusUpperInterface::onBioAuthShowMessage);
++        connect(
++            m_bioAuth.get(),
++            &BioAuthenticate::bioServiceStatusChanged,
++            this,
++            &DbusUpperInterface::onBioServiceStatusChanged);
++        connect(m_bioAuth.get(), &BioAuthenticate::bioDeviceChanged, this, &DbusUpperInterface::onBioDeviceChanged);
+         connect(
+-            m_bioAuth, &BioAuthenticate::bioServiceStatusChanged, this, &DbusUpperInterface::onBioServiceStatusChanged);
+-        connect(m_bioAuth, &BioAuthenticate::bioDeviceChanged, this, &DbusUpperInterface::onBioDeviceChanged);
+-        connect(m_bioAuth, &BioAuthenticate::bioAuthStateChanged, this, &DbusUpperInterface::onBioAuthStateChanged);
+-        connect(m_bioAuth, &BioAuthenticate::bioAuthFrameData, this, &DbusUpperInterface::onBioAuthFrameData);
+-        connect(m_bioAuth, &BioAuthenticate::bioAuthCompleted, this, &DbusUpperInterface::onBioAuthCompleted);
++            m_bioAuth.get(), &BioAuthenticate::bioAuthStateChanged, this, &DbusUpperInterface::onBioAuthStateChanged);
++        connect(m_bioAuth.get(), &BioAuthenticate::bioAuthFrameData, this, &DbusUpperInterface::onBioAuthFrameData);
++        connect(m_bioAuth.get(), &BioAuthenticate::bioAuthCompleted, this, &DbusUpperInterface::onBioAuthCompleted);
+         if (m_pamAuth) {
+             connect(
+-                m_pamAuth, &PamAuthenticate::authenticationComplete, m_bioAuth, &BioAuthenticate::onPamAuthComplete);
++                m_pamAuth.get(),
++                &PamAuthenticate::authenticationComplete,
++                m_bioAuth.get(),
++                &BioAuthenticate::onPamAuthComplete);
+         }
+     }
+     if (m_pamAuth) {
+-        connect(m_pamAuth, &PamAuthenticate::showMessage, this, &DbusUpperInterface::onPamShowMessage);
+-        connect(m_pamAuth, &PamAuthenticate::showPrompt, this, &DbusUpperInterface::onPamShowPrompt);
+-        connect(m_pamAuth, &PamAuthenticate::authenticationComplete, this, &DbusUpperInterface::onPamAuthCompleted);
++        connect(m_pamAuth.get(), &PamAuthenticate::showMessage, this, &DbusUpperInterface::onPamShowMessage);
++        connect(m_pamAuth.get(), &PamAuthenticate::showPrompt, this, &DbusUpperInterface::onPamShowPrompt);
++        connect(
++            m_pamAuth.get(), &PamAuthenticate::authenticationComplete, this, &DbusUpperInterface::onPamAuthCompleted);
+     }
+     if (m_upowerHelper) {
+-        connect(m_upowerHelper, &UpowerHelper::batteryStatusChanged, this, &DbusUpperInterface::onBatteryStatusChanged);
+-        connect(m_upowerHelper, &UpowerHelper::batteryChanged, this, &DbusUpperInterface::onBatteryChanged);
+-        connect(m_upowerHelper, &UpowerHelper::lidStateChanged, this, &DbusUpperInterface::onLidStateChanged);
++        connect(
++            m_upowerHelper.get(),
++            &UpowerHelper::batteryStatusChanged,
++            this,
++            &DbusUpperInterface::onBatteryStatusChanged);
++        connect(m_upowerHelper.get(), &UpowerHelper::batteryChanged, this, &DbusUpperInterface::onBatteryChanged);
++        connect(m_upowerHelper.get(), &UpowerHelper::lidStateChanged, this, &DbusUpperInterface::onLidStateChanged);
+     }
+     if (m_sessionWatcher) {
+-        connect(m_sessionWatcher, &SessionWatcher::sessionIdle, this, &DbusUpperInterface::onSessionIdleReceived);
+-        connect(m_sessionWatcher, &SessionWatcher::sessionIdle, this, [=]() {
++        connect(m_sessionWatcher.get(), &SessionWatcher::sessionIdle, this, &DbusUpperInterface::onSessionIdleReceived);
++        connect(m_sessionWatcher.get(), &SessionWatcher::sessionIdle, this, [=]() {
+             QDBusMessage message;
+             message = QDBusMessage::createSignal(SS_DBUS_PATH, SS_DBUS_INTERFACE, "SecondRunParam");
+             message << "SessionIdle";
+             QDBusConnection::sessionBus().send(message);
+         });
+-        connect(m_sessionWatcher, &SessionWatcher::sessionIdleExit, this, &DbusUpperInterface::onSessionIdleExit);
++        connect(m_sessionWatcher.get(), &SessionWatcher::sessionIdleExit, this, &DbusUpperInterface::onSessionIdleExit);
+     }
+     connect(
+         &m_procLockDialog,
+@@ -188,7 +219,7 @@ void DbusUpperInterface::initConnections()
+         SLOT(onLockDialogProcExit(int, QProcess::ExitStatus)));
+     if (m_libinputSwitchEvent) {
+         connect(
+-            m_libinputSwitchEvent,
++            m_libinputSwitchEvent.get(),
+             &LibinputSwitchEvent::tabletModeStatusChanged,
+             this,
+             &DbusUpperInterface::onTabletModeChanged);
+@@ -628,8 +659,7 @@ bool DbusUpperInterface::checkScreenDialogRunning()
+ void DbusUpperInterface::emitLockState(bool val, bool isSessionTools)
+ {
+     qDebug() << "emitLockState state = " << val;
+-
+-    if (val != m_bBlockShortcutState) {
++    if (val != m_bBlockShortcutState && m_kglobalHelper) {
+         m_kglobalHelper->blockShortcut(val);
+         m_bBlockShortcutState = val;
+         qDebug() << " block all shortcut "
+@@ -991,7 +1021,7 @@ QJsonArray DbusUpperInterface::GenerateUserInfoList()
+             objUserInfo["lang"] = userInfo->lang();
+             objUserInfo["headImg"] = userInfo->headImage();
+             objUserInfo["systemAccount"] = userInfo->isSystemAccount();
+-            KylinUserDatePtr ptr = KYLINUSERDATAMNG::getInstance()->GetUserPtr(userInfo->name());
++            KylinUserDatePtr ptr = KYLINUSERDATAMNG::instance()->GetUserPtr(userInfo->name());
+             if (nullptr != ptr) {
+                 if (!ptr->backgroundPath().isEmpty()) {
+                     objUserInfo["greeterBackGround"] = ptr->backgroundPath();
+@@ -1660,6 +1690,7 @@ void DbusUpperInterface::onKeyboardConfigChanged(QString strKey, QVariant value)
+ {
+     QJsonObject retObj;
+     retObj["CmdId"] = LOCK_CMD_ID_GSETTINGS_KEYBOARD_CONF_CHANGED;
++    retObj["Key"] = strKey;
+     switch (value.type()) {
+         case QVariant::Bool:
+             retObj["Value"] = value.toBool();
+@@ -2666,3 +2697,8 @@ int DbusUpperInterface::SetPowerManager(const QJsonObject &objInfo)
+ 
+     return nRet;
+ }
++
++QSharedPointer<GSettingsHelper> DbusUpperInterface::getGSettingsInstance()
++{
++    return m_gsettingsHelper;
++}
+diff --git a/src/lock-backend/dbusupperinterface.h b/src/lock-backend/dbusupperinterface.h
+index 2797db9..e9898bb 100644
+--- a/src/lock-backend/dbusupperinterface.h
++++ b/src/lock-backend/dbusupperinterface.h
+@@ -25,9 +25,11 @@
+ #include <QDBusInterface>
+ #include <QDBusUnixFileDescriptor>
+ #include <QProcess>
++#include <QSharedPointer>
+ #include <QTimer>
+-#include "utils.h"
+-#include "rsac.h"
++#include "../../src/common/utils.h"
++#include "../../src/common/rsac.h"
++#include "../../src/common/definetypes.h"
+ 
+ class LightDMHelper;
+ class Login1Helper;
+@@ -66,6 +68,10 @@ public:
+      */
+     explicit DbusUpperInterface(QObject *parent = nullptr);
+ 
++    virtual ~DbusUpperInterface();
++
++    void init();
++
+ public:
+     bool checkScreenDialogRunning();
+     void emitLockState(bool val, bool isSessionTools = false);
+@@ -151,6 +157,8 @@ public:
+ 
+     bool sendPassword(const QString username, QByteArray password);
+ 
++    QSharedPointer<GSettingsHelper> getGSettingsInstance();
++
+ public Q_SLOTS:
+     /**
+      * @brief 服务退出
+@@ -402,10 +410,10 @@ private:
+     bool SendUpdateInfoSig(QString strJson);
+ 
+ private:
+-    LightDMHelper *m_lightDmHelper = nullptr; /**< lightdm工具实例 */
+-    Login1Helper *m_login1Helper = nullptr;   /**< login1工具实例 */
++    QSharedPointer<LightDMHelper> m_lightDmHelper = nullptr; /**< lightdm工具实例 */
++    QSharedPointer<Login1Helper> m_login1Helper = nullptr;   /**< login1工具实例 */
+     Configuration *m_config = nullptr;
+-    GSettingsHelper *m_gsettingsHelper = nullptr;
++    QSharedPointer<GSettingsHelper> m_gsettingsHelper = nullptr;
+     QProcess m_procLockDialog;
+     bool m_bLockState;
+     bool m_bBlankState = false;
+@@ -415,19 +423,19 @@ private:
+     int m_timerCount = 0;
+     QTimer *m_timerLock = nullptr;
+     QDBusUnixFileDescriptor m_inhibitFileDescriptor;
+-    PamAuthenticate *m_pamAuth = nullptr;
+-    UsdHelper *m_usdHelper = nullptr;
+-    UpowerHelper *m_upowerHelper = nullptr;
+-    AccountsHelper *m_accountsHelper = nullptr;
++    QSharedPointer<PamAuthenticate> m_pamAuth = nullptr;
++    QSharedPointer<UsdHelper> m_usdHelper = nullptr;
++    QSharedPointer<UpowerHelper> m_upowerHelper = nullptr;
++    QSharedPointer<AccountsHelper> m_accountsHelper = nullptr;
+     bool lockState = false;
+-    SessionHelper *m_sessionHelper = nullptr;
+-    SystemUpgradeHelper *m_systemsUpgradeHelper = nullptr;
+-    SessionWatcher *m_sessionWatcher = nullptr;
+-    BioAuthenticate *m_bioAuth = nullptr;
++    QSharedPointer<SessionHelper> m_sessionHelper = nullptr;
++    QSharedPointer<SystemUpgradeHelper> m_systemsUpgradeHelper = nullptr;
++    QSharedPointer<SessionWatcher> m_sessionWatcher = nullptr;
++    QSharedPointer<BioAuthenticate> m_bioAuth = nullptr;
+     RSAC rsac;
+     QByteArray pubKey, priKey;
+-    KglobalAccelHelper *m_kglobalHelper = nullptr;
+-    LibinputSwitchEvent *m_libinputSwitchEvent = nullptr;
++    QSharedPointer<KglobalAccelHelper> m_kglobalHelper = nullptr;
++    QSharedPointer<LibinputSwitchEvent> m_libinputSwitchEvent = nullptr;
+     bool m_bBlockShortcutState = false;
+ };
+ 
+diff --git a/src/lock-backend/gsettingshelper.cpp b/src/lock-backend/gsettingshelper.cpp
+index fd29271..5e08b4b 100644
+--- a/src/lock-backend/gsettingshelper.cpp
++++ b/src/lock-backend/gsettingshelper.cpp
+@@ -18,7 +18,7 @@
+ #include "gsettingshelper.h"
+ #include <QVariant>
+ #include <QDebug>
+-#include "definetypes.h"
++#include "../common/definetypes.h"
+ 
+ GSettingsHelper::GSettingsHelper(QObject *parent) : QObject(parent) {}
+ 
+@@ -294,10 +294,10 @@ bool GSettingsHelper::initUsdMediaKeys()
+ bool GSettingsHelper::initUsdMediaStateKeys()
+ {
+     if (!m_gsUsdMediaStateKeys) {
+-        if(QGSettings::isSchemaInstalled(GSETTINGS_SCHEMA_MEDIAKEY_STATE_SCHEMA)) {
++        if (QGSettings::isSchemaInstalled(GSETTINGS_SCHEMA_MEDIAKEY_STATE_SCHEMA)) {
+             m_gsUsdMediaStateKeys = new QGSettings(GSETTINGS_SCHEMA_MEDIAKEY_STATE_SCHEMA, "", this);
+-            connect(m_gsUsdMediaStateKeys, &QGSettings::changed,
+-                    this, &GSettingsHelper::onUsdMediaStateKeysConfigChanged);
++            connect(
++                m_gsUsdMediaStateKeys, &QGSettings::changed, this, &GSettingsHelper::onUsdMediaStateKeysConfigChanged);
+             QStringList keys = m_gsUsdMediaStateKeys->keys();
+             if (keys.contains(KEY_RFKILL_STATE)) {
+                 m_rfkillState = m_gsUsdMediaStateKeys->get(KEY_RFKILL_STATE).toInt();
+@@ -536,6 +536,18 @@ bool GSettingsHelper::SetScreenSaverConf(QString strKey, QVariant value)
+     return false;
+ }
+ 
++QVariant GSettingsHelper::ResetScreenSaverConf(QString strKey)
++{
++    QVariant defValue;
++    if (initLockScreen()) {
++        if (m_gsLockScreen->keys().contains(strKey)) {
++            m_gsLockScreen->reset(strKey);
++            defValue = m_gsLockScreen->get(strKey);
++        }
++    }
++    return defValue;
++}
++
+ QVariant GSettingsHelper::GetLockScreenConf(QString strKey)
+ {
+     QVariant varValue;
+@@ -582,6 +594,18 @@ bool GSettingsHelper::SetLockScreenConf(QString strKey, QVariant value)
+     return false;
+ }
+ 
++QVariant GSettingsHelper::ResetLockScreenConf(QString strKey)
++{
++    QVariant defValue;
++    if (initLockScreen()) {
++        if (m_gsLockScreen->keys().contains(strKey)) {
++            m_gsLockScreen->reset(strKey);
++            defValue = m_gsLockScreen->get(strKey);
++        }
++    }
++    return defValue;
++}
++
+ QVariant GSettingsHelper::GetPowerManagerConf(QString strKey)
+ {
+     QVariant varValue;
+diff --git a/src/lock-backend/gsettingshelper.h b/src/lock-backend/gsettingshelper.h
+index 70303a9..4aa4fdf 100644
+--- a/src/lock-backend/gsettingshelper.h
++++ b/src/lock-backend/gsettingshelper.h
+@@ -20,6 +20,7 @@
+ 
+ #include <QObject>
+ #include <qgsettings.h>
++#include <QVariant>
+ 
+ class GSettingsHelper : public QObject
+ {
+@@ -31,8 +32,10 @@ public:
+ public:
+     QVariant GetLockScreenConf(QString strKey);
+     bool SetLockScreenConf(QString strKey, QVariant value);
++    QVariant ResetLockScreenConf(QString strKey);
+     QVariant GetScreenSaverConf(QString strKey);
+     bool SetScreenSaverConf(QString strKey, QVariant value);
++    QVariant ResetScreenSaverConf(QString strKey);
+     QVariant GetPowerManagerConf(QString strKey);
+     bool SetPowerManagerConf(QString strKey, QVariant value);
+     QVariant GetMateBgConf(QString strKey);
+diff --git a/src/lock-backend/lightdmhelper.cpp b/src/lock-backend/lightdmhelper.cpp
+index c599ac8..3033b05 100644
+--- a/src/lock-backend/lightdmhelper.cpp
++++ b/src/lock-backend/lightdmhelper.cpp
+@@ -20,12 +20,12 @@
+ #include <QLightDM/Greeter>
+ #include <QFileInfo>
+ #include "securityuser.h"
+-#include "global_utils.h"
++#include "../../src/common/global_utils.h"
+ #include <pwd.h>
+ #include "proxymodel.h"
+-#include "accountshelper.h"
+-#include "definetypes.h"
+-#include "uniauthservice.h"
++#include "../../src/dbusifs/accountshelper.h"
++#include "../../src/common/definetypes.h"
++#include "../../src/dbusifs/uniauthservice.h"
+ #include <QDBusArgument>
+ #include <QDBusMessage>
+ #include <QVariantMap>
+@@ -34,7 +34,7 @@
+ #include <kysec/status.h>
+ #endif
+ 
+-LightDMHelper::LightDMHelper(AccountsHelper *accountHelper, Configuration *config, QObject *parent)
++LightDMHelper::LightDMHelper(QSharedPointer<AccountsHelper> accountHelper, Configuration *config, QObject *parent)
+     : QLightDM::Greeter(parent)
+     , m_sessionsModel(nullptr)
+     , m_secUser(SecurityUser::instance())
+@@ -348,9 +348,9 @@ void LightDMHelper::initAccountsUsersInfo()
+             connect(userInfo.get(), &UserInfo::userPropChanged, this, &LightDMHelper::onUsersChanged);
+             m_mapUsers->insert(user, userInfo);
+         }
+-        connect(m_accountServiceHelper, SIGNAL(UserAdded(QDBusObjectPath)), this, SLOT(onUserAdded(QDBusObjectPath)));
++        connect(m_accountServiceHelper.get(), SIGNAL(UserAdded(QDBusObjectPath)), this, SLOT(onUserAdded(QDBusObjectPath)));
+         connect(
+-            m_accountServiceHelper, SIGNAL(UserRemoved(QDBusObjectPath)), this, SLOT(onUserRemoved(QDBusObjectPath)));
++            m_accountServiceHelper.get(), SIGNAL(UserRemoved(QDBusObjectPath)), this, SLOT(onUserRemoved(QDBusObjectPath)));
+     }
+ }
+ 
+diff --git a/src/lock-backend/lightdmhelper.h b/src/lock-backend/lightdmhelper.h
+index 1530a11..1209ee9 100644
+--- a/src/lock-backend/lightdmhelper.h
++++ b/src/lock-backend/lightdmhelper.h
+@@ -25,8 +25,9 @@
+ #include <QList>
+ #include <QModelIndex>
+ #include <QDBusInterface>
+-#include "userinfo.h"
+-#include "configuration.h"
++#include "../userinfo.h"
++#include "../../src/common/configuration.h"
++#include <QSharedPointer>
+ 
+ class SecurityUser;
+ class UsersModel;
+@@ -45,7 +46,7 @@ public:
+      *
+      * @param parent 父指针
+      */
+-    explicit LightDMHelper(AccountsHelper *accountHelper, Configuration *config, QObject *parent = nullptr);
++    explicit LightDMHelper(QSharedPointer<AccountsHelper> accountHelper, Configuration *config, QObject *parent = nullptr);
+ 
+ public:
+     /**
+@@ -180,7 +181,7 @@ private:
+     QLightDM::SessionsModel *m_sessionsModel; /**< lightdm 会话数据指针 */
+     QList<QString> m_listSessions;            /**< 会话列表 */
+     QMap<QString, UserInfoPtr> *m_mapUsers;   /**< accounts 用户信息列表指针 */
+-    AccountsHelper *m_accountServiceHelper = nullptr;
++    QSharedPointer<AccountsHelper> m_accountServiceHelper = nullptr;
+     QMap<QString, std::shared_ptr<LightDMSessionInfo>> *m_ldmSessions;
+     QDBusInterface *m_dbusIfsLDM;
+     Configuration *m_configuration = nullptr;
+diff --git a/src/lock-backend/main.cpp b/src/lock-backend/main.cpp
+index cd35943..409924c 100644
+--- a/src/lock-backend/main.cpp
++++ b/src/lock-backend/main.cpp
+@@ -14,7 +14,7 @@
+  * You should have received a copy of the GNU General Public License
+  * along with this program; if not, see <http://www.gnu.org/licenses/>.
+  *
+-**/
++ **/
+ #include <QCoreApplication>
+ #include <QDBusConnection>
+ #include <QDebug>
+@@ -33,9 +33,13 @@
+ #include "screensaveradaptor.h"
+ #include "personalizeddata.h"
+ #include "msysdbus.h"
++#include "../ukccplugins/sessiondbus/screenlockinterface.h"
++#include "../ukccplugins/sessiondbus/screensaverinterface.h"
++#include <syslog.h>
+ 
+ int main(int argc, char *argv[])
+ {
++    syslog(LOG_INFO, "[ukui-screensaver-backend] startup!!");
+     initUkuiLog4qt("ukui-screensaver-backend");
+     // 重启或关机时不被session关掉
+     qunsetenv("SESSION_MANAGER");
+@@ -45,82 +49,103 @@ int main(int argc, char *argv[])
+     } else {
+         strDisplay = QLatin1String(getenv("DISPLAY"));
+     }
+-    QString singleId = QString("ukui-screensaver-backend"+strDisplay);
++    QString singleId = QString("ukui-screensaver-backend" + strDisplay);
+     QtSingleCoreApplication a(singleId, argc, argv);
+     if (a.isRunning()) {
+         qDebug() << "There is an instance running";
+         return 0;
+     }
+-    qInfo()<<"ukui screensaver backend Started!!";
++    qInfo() << "ukui screensaver backend Started!!";
+     // 会话管理器退出时,锁屏后端也退出
+     prctl(PR_SET_PDEATHSIG, SIGKILL);
+-    //命令行参数解析
++    // 命令行参数解析
+     QCommandLineParser parser;
+     parser.setApplicationDescription(QCoreApplication::translate("main", "Backend for the ukui ScreenSaver."));
+     parser.addHelpOption();
+     parser.addVersionOption();
+     parser.setSingleDashWordOptionMode(QCommandLineParser::ParseAsLongOptions);
+ 
+-    QCommandLineOption lockStartupOption(QStringLiteral("lock-startup"),
+-                                  QCoreApplication::translate("main", "lock the screen by startup"));
+-    parser.addOptions({lockStartupOption});
++    QCommandLineOption lockStartupOption(
++        QStringLiteral("lock-startup"), QCoreApplication::translate("main", "lock the screen by startup"));
++    parser.addOptions({ lockStartupOption });
+     parser.process(a.arguments());
+ 
+-    KYLINUSERDATAMNG::instance();
+-
+     // 检查该程序是否已经有实例在运行
+-    QDBusInterface *checkInterface =
+-            new QDBusInterface("org.freedesktop.DBus",
+-                               "/org/freedesktop/DBus",
+-                               "org.freedesktop.DBus",
+-                               QDBusConnection::sessionBus());
+-    QDBusReply<bool> ret = checkInterface->call("NameHasOwner",
+-                                               "cn.kylinos.ScreenSaver");
+-    if(ret.value()) {
++    QDBusInterface *checkInterface = new QDBusInterface(
++        "org.freedesktop.DBus", "/org/freedesktop/DBus", "org.freedesktop.DBus", QDBusConnection::sessionBus());
++    QDBusReply<bool> ret = checkInterface->call("NameHasOwner", "cn.kylinos.ScreenSaver");
++    if (ret.value()) {
+         qDebug() << "There is an instance running";
+         return EXIT_FAILURE;
+     }
+ 
+     // 注册DBus
+-    DbusUpperInterface *interface = new DbusUpperInterface();
+-    ScreenSaverAdaptor adaptor(interface);
++    syslog(LOG_INFO, "[ukui-screensaver-backend] DbusUpperInterface initing!!");
++    DbusUpperInterface interface;
++    syslog(LOG_INFO, "[ukui-screensaver-backend] DbusUpperInterface inited!!");
++    ScreenSaverAdaptor adaptor(&interface);
+ 
+     QDBusConnection service = QDBusConnection::sessionBus();
+     QString sessionDbus = SS_DBUS_SERVICE;
+-    if(!service.registerService(sessionDbus)) {
+-        QString displayNum = QString(qgetenv("DISPLAY")).replace(":", "").replace(".", "_");;
++    if (!service.registerService(sessionDbus)) {
++        QString displayNum = QString(qgetenv("DISPLAY")).replace(":", "").replace(".", "_");
++        ;
+         sessionDbus = QString("%1%2").arg(QString(SS_DBUS_SERVICE)).arg(displayNum);
+-        if(!service.registerService(sessionDbus)) {
++        if (!service.registerService(sessionDbus)) {
+             qDebug() << service.lastError().message();
+             return EXIT_FAILURE;
+         }
+     }
+-    if(!service.registerObject(SS_DBUS_PATH, SS_DBUS_SERVICE, &adaptor,
+-                               QDBusConnection::ExportAllSlots |
+-                               QDBusConnection::ExportAllSignals)) {
++    if (!service.registerObject(
++            SS_DBUS_PATH,
++            SS_DBUS_SERVICE,
++            &adaptor,
++            QDBusConnection::ExportAllSlots | QDBusConnection::ExportAllSignals)) {
+         qDebug() << service.lastError().message();
+         return EXIT_FAILURE;
+     }
++    // 注册控制面板插件接口服务
++    if (!isGreeterMode()) {
++        ScreenlockInterface *lockInterface = new ScreenlockInterface(&interface, &interface);
++        if (!service.registerObject(
++                SL_SESSION_DBUS_PATH,
++                lockInterface,
++                QDBusConnection::ExportAllSlots | QDBusConnection::ExportAllProperties
++                    | QDBusConnection::ExportAllSignals)) {
++            qDebug() << service.lastError().message();
++            return EXIT_FAILURE;
++        }
++        ScreensaverInterface *saverInterface = new ScreensaverInterface(&interface, &interface);
++        if (!service.registerObject(
++                SS_SESSION_DBUS_PATH,
++                saverInterface,
++                QDBusConnection::ExportAllSlots | QDBusConnection::ExportAllProperties
++                    | QDBusConnection::ExportAllSignals)) {
++            qDebug() << service.lastError().message();
++            return EXIT_FAILURE;
++        }
++    }
+     qDebug() << service.baseService();
+ 
+-    QObject::connect(checkInterface, SIGNAL(NameLost(QString)),
+-                     interface, SLOT(onNameLost(QString)));
++    QObject::connect(checkInterface, SIGNAL(NameLost(QString)), &interface, SLOT(onNameLost(QString)));
+ 
+     if (parser.isSet(lockStartupOption)) {
+-        QTimer::singleShot(0, interface, [=](){
+-            interface->LockStartupMode();
+-        });
++        syslog(LOG_INFO, "[ukui-screensaver-backend] lock startup mode begin!!");
++        interface.LockStartupMode();
++        syslog(LOG_INFO, "[ukui-screensaver-backend] lock startup mode end!!");
+     }
++    interface.init();
+ 
+-    MSysDbus *m_sysDbus = new MSysDbus(interface,nullptr);
++    MSysDbus m_sysDbus(&interface);
+ 
+     QString displayNum = QString(qgetenv("DISPLAY")).replace(":", "").replace(".", "_");
+     QString sysService = "org.ukui.screensaver._" + displayNum;
+     if (!QDBusConnection::systemBus().registerService("org.ukui.screensaver")) {
+-        qDebug()<<"registerService failed";
++        qDebug() << "registerService failed";
+     }
+ 
+-    QDBusConnection::systemBus().registerObject("/", "org.ukui.screensaver",m_sysDbus, QDBusConnection::ExportAllSlots);
+-
++    QDBusConnection::systemBus().registerObject(
++        "/", "org.ukui.screensaver", &m_sysDbus, QDBusConnection::ExportAllSlots);
++    syslog(LOG_INFO, "[ukui-screensaver-backend] application event loop begin!!");
+     return a.exec();
+ }
+diff --git a/src/lock-backend/pamauthenticate.cpp b/src/lock-backend/pamauthenticate.cpp
+index ddf1802..a0da99f 100644
+--- a/src/lock-backend/pamauthenticate.cpp
++++ b/src/lock-backend/pamauthenticate.cpp
+@@ -16,7 +16,7 @@
+  *
+  **/
+ #include "pamauthenticate.h"
+-#include "global_utils.h"
++#include "../../src/common/global_utils.h"
+ #include "authpamthread.h"
+ #include <unistd.h>
+ #include <wait.h>
+@@ -24,7 +24,7 @@
+ #include <QSocketNotifier>
+ #include <QDebug>
+ 
+-PamAuthenticate::PamAuthenticate(LightDMHelper *helper, QObject *parent) : QObject(parent), m_lightdmHelper(helper)
++PamAuthenticate::PamAuthenticate(QSharedPointer<LightDMHelper> helper, QObject *parent) : QObject(parent), m_lightdmHelper(helper)
+ {
+     m_fdToParent[0] = -1;
+     m_fdToParent[1] = -1;
+@@ -32,16 +32,16 @@ PamAuthenticate::PamAuthenticate(LightDMHelper *helper, QObject *parent) : QObje
+     m_fdToChild[1] = -1;
+ 
+     connect(
+-        m_lightdmHelper,
++        m_lightdmHelper.get(),
+         SIGNAL(showMessage(QString, QLightDM::Greeter::MessageType)),
+         this,
+         SLOT(onLDMShowMessage(QString, QLightDM::Greeter::MessageType)));
+     connect(
+-        m_lightdmHelper,
++        m_lightdmHelper.get(),
+         SIGNAL(showPrompt(QString, QLightDM::Greeter::PromptType)),
+         this,
+         SLOT(onLDMShowPrompt(QString, QLightDM::Greeter::PromptType)));
+-    connect(m_lightdmHelper, SIGNAL(authenticationComplete()), this, SIGNAL(authenticationComplete()));
++    connect(m_lightdmHelper.get(), SIGNAL(authenticationComplete()), this, SIGNAL(authenticationComplete()));
+ }
+ 
+ bool PamAuthenticate::inAuthentication() const
+@@ -74,10 +74,14 @@ QString PamAuthenticate::authenticationUser() const
+ void PamAuthenticate::authenticate(const QString &username)
+ {
+     m_isOtherUser = (getenv("USER") != username);
++
+     if (username == "*guest") {
+         m_lightdmHelper->authenticateAsGuest();
+-    } else if (m_isOtherUser)
++        hasSendBiometricPam = false;
++    } else if (m_isOtherUser) {
+         m_lightdmHelper->authenticate(username);
++        hasSendBiometricPam = false;
++    }
+     else {
+         cancelAuthentication();
+         m_strUserName = username;
+@@ -93,9 +97,12 @@ void PamAuthenticate::authenticate(const QString &username)
+ 
+ void PamAuthenticate::respond(const QString &response)
+ {
+-    if (m_isOtherUser)
++    if (m_isOtherUser) {
++        if (response == BIOMETRIC_IGNORE && !hasSendBiometricPam) {
++            return ;
++        }
+         m_lightdmHelper->respond(response);
+-    else {
++    } else {
+         m_nPrompts--;
+         m_responseList.push_back(response);
+ 
+@@ -276,5 +283,10 @@ void PamAuthenticate::onLDMShowMessage(QString strMsg, QLightDM::Greeter::Messag
+ 
+ void PamAuthenticate::onLDMShowPrompt(QString strPrompt, QLightDM::Greeter::PromptType type)
+ {
++    if(strPrompt == BIOMETRIC_PAM) {
++        hasSendBiometricPam = true;
++    } else {
++        hasSendBiometricPam = false;
++    }
+     Q_EMIT showPrompt(strPrompt, type);
+ }
+diff --git a/src/lock-backend/pamauthenticate.h b/src/lock-backend/pamauthenticate.h
+index f5a715a..d531c2b 100644
+--- a/src/lock-backend/pamauthenticate.h
++++ b/src/lock-backend/pamauthenticate.h
+@@ -22,6 +22,7 @@
+ #include <QStringList>
+ #include <security/pam_appl.h>
+ #include "lightdmhelper.h"
++#include <QSharedPointer>
+ 
+ typedef struct pam_message PAM_MESSAGE;
+ typedef struct pam_response PAM_RESPONSE;
+@@ -32,7 +33,7 @@ class PamAuthenticate : public QObject
+ {
+     Q_OBJECT
+ public:
+-    explicit PamAuthenticate(LightDMHelper *helper, QObject *parent = nullptr);
++    explicit PamAuthenticate(QSharedPointer<LightDMHelper> helper, QObject *parent = nullptr);
+ 
+ public:
+     bool inAuthentication() const;
+@@ -58,7 +59,7 @@ private:
+     void _respond(const struct pam_response *response);
+ 
+ private:
+-    LightDMHelper *m_lightdmHelper = nullptr;
++    QSharedPointer<LightDMHelper> m_lightdmHelper = nullptr;
+     bool m_isInAuthentication = false;
+     bool m_isAuthenticated = false;
+     bool m_isOtherUser = false;
+@@ -70,6 +71,8 @@ private:
+     int m_fdToParent[2];
+     int m_fdToChild[2];
+     QString m_strUserName;
++
++    bool hasSendBiometricPam = false;  
+ };
+ 
+ #endif // PAMAUTHENTICATE_H
+diff --git a/src/lock-backend/sessionwatcher.cpp b/src/lock-backend/sessionwatcher.cpp
+index 7d1ef25..9f7d7fa 100644
+--- a/src/lock-backend/sessionwatcher.cpp
++++ b/src/lock-backend/sessionwatcher.cpp
+@@ -20,12 +20,12 @@
+ #include <QDebug>
+ #include <QFile>
+ #include <QDBusReply>
+-#include "definetypes.h"
+-#include "utils.h"
++#include "../../src/common/definetypes.h"
++#include "../../src/common/utils.h"
+ 
+ #define GSETTINGS_SCHEMA_SCREENSAVER "org.ukui.screensaver"
+ 
+-SessionWatcher::SessionWatcher(GSettingsHelper *helper, QObject *parent) : QObject(parent), m_gsettingsHelper(helper)
++SessionWatcher::SessionWatcher(QSharedPointer<GSettingsHelper> helper, QObject *parent) : QObject(parent), m_gsettingsHelper(helper)
+ {
+     sessionPath = qgetenv("XDG_SESSION_PATH");
+ 
+@@ -46,7 +46,7 @@ SessionWatcher::SessionWatcher(GSettingsHelper *helper, QObject *parent) : QObje
+         SLOT(onSessionRemoved(QDBusObjectPath)));
+ 
+     connect(
+-        m_gsettingsHelper, &GSettingsHelper::lockScreenConfigChanged, this, &SessionWatcher::onLockScreenConfigChanged);
++        m_gsettingsHelper.get(), &GSettingsHelper::lockScreenConfigChanged, this, &SessionWatcher::onLockScreenConfigChanged);
+     // 重置屏保从不字段
+     bool isEnable = m_gsettingsHelper->GetLockScreenConf(KEY_IDLE_ACTIVATION_ENABLED).toBool();
+     if (!isEnable) {
+diff --git a/src/lock-backend/sessionwatcher.h b/src/lock-backend/sessionwatcher.h
+index 9bda7fc..bde1ae1 100644
+--- a/src/lock-backend/sessionwatcher.h
++++ b/src/lock-backend/sessionwatcher.h
+@@ -25,6 +25,7 @@
+ #include <QTimer>
+ #include <QSettings>
+ #include <QProcess>
++#include <QSharedPointer>
+ #include "gsettingshelper.h"
+ 
+ class SessionWatcher : public QObject
+@@ -37,14 +38,14 @@ public:
+         SESSION_STATUS_SCREENCLOSE = 2, // 关屏
+         SESSION_STATUS_SLEEPED = 4,     // 休眠/睡眠
+     };
+-    explicit SessionWatcher(GSettingsHelper *m_gsettingsHelper, QObject *parent = nullptr);
++    explicit SessionWatcher(QSharedPointer<GSettingsHelper> m_gsettingsHelper, QObject *parent = nullptr);
+ 
+ Q_SIGNALS:
+     void sessionIdle();
+     void sessionLockIdle();
+     void sessionIdleExit();
+ 
+-private Q_SLOTS:
++public Q_SLOTS:
+     void onStatusChanged(unsigned int status);
+     void onSessionRemoved(const QDBusObjectPath &objectPath);
+     void onLockScreenConfigChanged(QString strKey, QVariant value);
+@@ -61,7 +62,7 @@ private:
+     bool lockState;
+     int m_nStatus = 0; // 当前状态
+     QTimer *m_timerLock = nullptr;
+-    GSettingsHelper *m_gsettingsHelper = nullptr;
++    QSharedPointer<GSettingsHelper> m_gsettingsHelper = nullptr;
+ };
+ 
+ #endif // SESSIONWATCHER_H
+diff --git a/src/lock-backend/switchuserutils.cpp b/src/lock-backend/switchuserutils.cpp
+index 7dc55f9..06b1d5c 100644
+--- a/src/lock-backend/switchuserutils.cpp
++++ b/src/lock-backend/switchuserutils.cpp
+@@ -31,7 +31,7 @@
+ #include <QProcess>
+ #include <QStandardPaths>
+ #include <QString>
+-#include "global_utils.h"
++#include "../../src/common/global_utils.h"
+ 
+ SwitchUserUtils::SwitchUserUtils() {}
+ 
+diff --git a/src/lock-dialog/backenddbushelper.cpp b/src/lock-dialog/backenddbushelper.cpp
+index eb6ff0e..979d669 100644
+--- a/src/lock-dialog/backenddbushelper.cpp
++++ b/src/lock-dialog/backenddbushelper.cpp
+@@ -16,7 +16,7 @@
+  *
+  **/
+ #include "backenddbushelper.h"
+-#include "definetypes.h"
++#include "../../src/common/definetypes.h"
+ #include <QJsonValue>
+ #include <QJsonObject>
+ #include <QJsonDocument>
+@@ -1047,7 +1047,7 @@ void BackendDbusHelper::onUpdateInformation(const QString &strJson)
+                         ParseBlockInhibitedChanged(objRes);
+                     } break;
+                     case LOCK_CMD_ID_GSETTINGS_KEYBOARD_CONF_CHANGED: {
+-                        ParseCapslockConf(objRes);
++                        ParseKeyboardConf(objRes);
+                     } break;
+                     case LOCK_CMD_ID_PAMAUTH_SHOWMESSAGE: {
+                         ParsePamShowMessage(objRes);
+@@ -1577,10 +1577,13 @@ bool BackendDbusHelper::ParseSessionConf(const QJsonObject &objRes)
+     return true;
+ }
+ 
+-bool BackendDbusHelper::ParseCapslockConf(const QJsonObject &objRes)
++bool BackendDbusHelper::ParseKeyboardConf(const QJsonObject &objRes)
+ {
+-    bool state = objRes.value("Value").toBool();
+-    Q_EMIT capslockConfChanged(state);
++    QString strKey = objRes.value("Key").toString();
++    if (strKey == KEY_CAPSLOCK_STATUS) {
++        bool state = objRes.value("Value").toBool();
++        Q_EMIT capslockConfChanged(state);
++    }
+     return true;
+ }
+ 
+diff --git a/src/lock-dialog/backenddbushelper.h b/src/lock-dialog/backenddbushelper.h
+index 426ab68..5b98836 100644
+--- a/src/lock-dialog/backenddbushelper.h
++++ b/src/lock-dialog/backenddbushelper.h
+@@ -26,9 +26,9 @@
+ #include <QtCore/QStringList>
+ #include <QtCore/QVariant>
+ #include <QtDBus/QtDBus>
+-#include "userinfo.h"
+-#include "agreementinfo.h"
+-#include "biodefines.h"
++#include "../../src/userinfo.h"
++#include "../../src/agreementinfo.h"
++#include "../../src/common/biodefines.h"
+ 
+ /**
+  * @brief 后端服务访问工具类
+@@ -422,7 +422,7 @@ private:
+     bool ParseUkccPluginsConf(const QJsonObject &objRes);
+     bool ParseThemeStyleConf(const QJsonObject &objRes);
+     bool ParseSessionConf(const QJsonObject &objRes);
+-    bool ParseCapslockConf(const QJsonObject &objRes);
++    bool ParseKeyboardConf(const QJsonObject &objRes);
+ 
+     void ParsePamShowMessage(const QJsonObject &objRes);
+     void ParsePamShowPrompt(const QJsonObject &objRes);
+diff --git a/src/lock-dialog/languagesetting.cpp b/src/lock-dialog/languagesetting.cpp
+index 75c43b2..1d9ae64 100644
+--- a/src/lock-dialog/languagesetting.cpp
++++ b/src/lock-dialog/languagesetting.cpp
+@@ -17,7 +17,7 @@
+  **/
+ #include "languagesetting.h"
+ #include <QApplication>
+-#include "definetypes.h"
++#include "../../src/common/definetypes.h"
+ #include <QDebug>
+ #include <QFileInfo>
+ #include <QProcess>
+diff --git a/src/lock-dialog/lockdialogmodel.cpp b/src/lock-dialog/lockdialogmodel.cpp
+index e0bcf16..e3e558e 100644
+--- a/src/lock-dialog/lockdialogmodel.cpp
++++ b/src/lock-dialog/lockdialogmodel.cpp
+@@ -24,8 +24,8 @@
+ #include <QStandardPaths>
+ #include <QApplication>
+ #include <QScreen>
+-#include "utils.h"
+-#include "definetypes.h"
++#include "../../src/common/utils.h"
++#include "../../src/common/definetypes.h"
+ #include <pwd.h>
+ 
+ LockDialogModel::LockDialogModel(QObject *parent)
+diff --git a/src/lock-dialog/lockdialogmodel.h b/src/lock-dialog/lockdialogmodel.h
+index 8db3e16..a44175c 100644
+--- a/src/lock-dialog/lockdialogmodel.h
++++ b/src/lock-dialog/lockdialogmodel.h
+@@ -19,10 +19,10 @@
+ #define LOCKDIALOGMODEL_H
+ 
+ #include <QObject>
+-#include "userinfo.h"
+-#include "agreementinfo.h"
+-#include "screensavermode.h"
+-#include "biodefines.h"
++#include "../../src/userinfo.h"
++#include "../../src/agreementinfo.h"
++#include "../../src/widgets/screensavermode.h"
++#include "../../src/common/biodefines.h"
+ 
+ /**
+  * @brief 锁屏模型类(管理所有功能逻辑和状态)
+diff --git a/src/lock-dialog/lockdialogperformer.cpp b/src/lock-dialog/lockdialogperformer.cpp
+index 8a5afeb..e254f0d 100644
+--- a/src/lock-dialog/lockdialogperformer.cpp
++++ b/src/lock-dialog/lockdialogperformer.cpp
+@@ -18,6 +18,7 @@
+ #include "lockdialogperformer.h"
+ #include "lockdialogmodel.h"
+ #include "backenddbushelper.h"
++#include "../common/plasma-shell-manager.h"
+ #include "utils.h"
+ #include "rsac.h"
+ 
+@@ -58,11 +59,13 @@ void LockDialogPerformer::initConnections()
+         m_modelLockDialog->updateSleepLockcheck(m_bdHelper->getSleepLockcheck());
+         m_modelLockDialog->updateShutdownLockcheck(m_bdHelper->getShutdownLockcheck());
+     });
+-    connect(
+-        m_bdHelper,
+-        &BackendDbusHelper::capslockConfChanged,
+-        m_modelLockDialog,
+-        &LockDialogModel::onCapslockStateChanged);
++    if (!m_modelLockDialog->isUseWayland()) {
++        connect(
++            m_bdHelper,
++            &BackendDbusHelper::capslockConfChanged,
++            m_modelLockDialog,
++            &LockDialogModel::onCapslockStateChanged);
++    }
+ 
+     connect(
+         m_bdHelper,
+@@ -231,3 +234,14 @@ void LockDialogPerformer::initData()
+     m_modelLockDialog->updateSessionLogoutMusic(m_bdHelper->getSessionConf(KEY_SESSION_LOGOUT_MUSIC).toBool());
+     m_modelLockDialog->updateSessionPoweroffMusic(m_bdHelper->getSessionConf(KEY_SESSION_POWEROFF_MUSIC).toBool());
+ }
++
++void LockDialogPerformer::initExtraData()
++{
++    if (m_modelLockDialog->isUseWayland()) {
++        connect(
++            PlasmaShellManager::getInstance(),
++            &PlasmaShellManager::capslockStateChanged,
++            m_modelLockDialog,
++            &LockDialogModel::onCapslockStateChanged);
++    }
++}
+diff --git a/src/lock-dialog/lockdialogperformer.h b/src/lock-dialog/lockdialogperformer.h
+index 903507b..c4d8f7e 100644
+--- a/src/lock-dialog/lockdialogperformer.h
++++ b/src/lock-dialog/lockdialogperformer.h
+@@ -39,6 +39,8 @@ public:
+      */
+     explicit LockDialogPerformer(LockDialogModel *model, QObject *parent = nullptr);
+ 
++    void initExtraData();
++
+ private:
+     /**
+      * @brief 初始化连接信号槽
+diff --git a/src/lock-dialog/main.cpp b/src/lock-dialog/main.cpp
+index 2e75af6..0f6ebc9 100644
+--- a/src/lock-dialog/main.cpp
++++ b/src/lock-dialog/main.cpp
+@@ -30,6 +30,7 @@
+ #include <QEventLoop>
+ #include <signal.h>
+ #include <unistd.h>
++#include <sys/prctl.h>
+ #include <QProcess>
+ #include <ukui-log4qt.h>
+ #include <QtSingleApplication>
+@@ -65,13 +66,13 @@ int main(int argc, char *argv[])
+     QApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::PassThrough);
+ #endif
+     // 屏蔽输入法
+-//    qunsetenv("QT_IM_MODULE");
++    qunsetenv("QT_IM_MODULE");
+ 
+-    LockDialogModel *lockDialogModel = new LockDialogModel();
+-    LockDialogPerformer *performer = new LockDialogPerformer(lockDialogModel);
++    LockDialogModel lockDialogModel;
++    LockDialogPerformer performer(&lockDialogModel);
+ 
+-    if (isGreeterMode() && !lockDialogModel->isUseWayland()) {
+-        DisplayService::instance(lockDialogModel)->setCurUserName(lockDialogModel->defaultUserName());
++    if (isGreeterMode() && !lockDialogModel.isUseWayland()) {
++        DisplayService::instance(&lockDialogModel)->setCurUserName(lockDialogModel.defaultUserName());
+     }
+ 
+     QString strDisplay = "";
+@@ -82,14 +83,17 @@ int main(int argc, char *argv[])
+     }
+     QString id = QString("ukui-screensaver-dialog" + strDisplay);
+     QtSingleApplication app(id, argc, argv);
++    // 锁屏后端退出时,锁屏前端也退出
++    prctl(PR_SET_PDEATHSIG, SIGKILL);
+ 
++    performer.initExtraData();
+     LockDialogModel::CommandLineArgs cmdArgs;
+-    if (!lockDialogModel->parseCmdArguments(app.arguments(), cmdArgs)) {
++    if (!lockDialogModel.parseCmdArguments(app.arguments(), cmdArgs)) {
+         return 0;
+     }
+ 
+     if (!isGreeterMode()) {
+-	// 需要判断参数是否是session-tools
++        // 需要判断参数是否是session-tools
+         if (!cmdArgs.isSessionTools) {
+             // 试用模式不起锁屏
+             checkIslivecd();
+@@ -99,12 +103,10 @@ int main(int argc, char *argv[])
+     if (app.isRunning()) {
+         QString strArguments = QApplication::arguments().join(",");
+         app.sendMessage(strArguments);
+-        delete lockDialogModel;
+-        lockDialogModel = nullptr;
+         qInfo() << "ukui screensaver dialog is running!";
+         return EXIT_SUCCESS;
+     }
+-    if (!lockDialogModel->isUseWayland()) {
++    if (!lockDialogModel.isUseWayland()) {
+         setCursorCenter();
+     }
+     // 加载插件实例
+@@ -114,22 +116,22 @@ int main(int argc, char *argv[])
+ 
+     QApplication::setSetuidAllowed(true);
+ 
+-    QObject::connect(lockDialogModel, &LockDialogModel::requestUnlockSession, [=]() {
++    QObject::connect(&lockDialogModel, &LockDialogModel::requestUnlockSession, [=]() {
+         if (window) {
+             window->onCloseScreensaver();
+         } else {
+             exit(0);
+         }
+     });
+-    if (!lockDialogModel->sessionActive()) {
++    if (!lockDialogModel.sessionActive()) {
+         QEventLoop *loopTemp = new QEventLoop(&app);
+-        QObject::connect(lockDialogModel, &LockDialogModel::sessionActiveChanged, [loopTemp](bool isActive) {
++        QObject::connect(&lockDialogModel, &LockDialogModel::sessionActiveChanged, [loopTemp](bool isActive) {
+             qDebug() << "sessionActiveChanged:" << isActive;
+             if (isActive && loopTemp->isRunning()) {
+                 loopTemp->quit();
+             }
+         });
+-        QObject::connect(lockDialogModel, &LockDialogModel::requestLockSession, [loopTemp]() {
++        QObject::connect(&lockDialogModel, &LockDialogModel::requestLockSession, [loopTemp]() {
+             qDebug() << "session requestLock!";
+             if (loopTemp->isRunning()) {
+                 loopTemp->quit();
+@@ -139,19 +141,19 @@ int main(int argc, char *argv[])
+     }
+ 
+     QObject::connect(
+-        &app, SIGNAL(messageReceived(const QString &)), lockDialogModel, SLOT(onRunningMessage(const QString &)));
++        &app, SIGNAL(messageReceived(const QString &)), &lockDialogModel, SLOT(onRunningMessage(const QString &)));
+ 
+     qInfo() << "Start " << app.arguments();
+ 
+     // 加载翻译文件
+-    UserInfoPtr ptrUserInfo = lockDialogModel->findUserByName(lockDialogModel->defaultUserName());
++    UserInfoPtr ptrUserInfo = lockDialogModel.findUserByName(lockDialogModel.defaultUserName());
+     if (ptrUserInfo) {
+         LanguageSetting::instance()->onLanguageChanged(ptrUserInfo->lang());
+     } else {
+         LanguageSetting::instance()->onLanguageChanged(QLocale::system().name());
+     }
+ 
+-    window = new FullBackgroundWidget(lockDialogModel);
++    window = new FullBackgroundWidget(&lockDialogModel, cmdArgs.isLockStartup);
+ 
+     // 注册DBus
+     ScreenSaverWndAdaptor adaptorWnd(window);
+@@ -159,7 +161,6 @@ int main(int argc, char *argv[])
+     QString sessionDbus = SSWND_DBUS_SERVICE;
+     if (!service.registerService(SSWND_DBUS_SERVICE)) {
+         QString displayNum = QString(qgetenv("DISPLAY")).replace(":", "").replace(".", "_");
+-        ;
+         sessionDbus = QString("%1%2").arg(QString(SSWND_DBUS_SERVICE)).arg(displayNum);
+         if (!service.registerService(sessionDbus)) {
+             qDebug() << service.lastError().message();
+@@ -177,7 +178,7 @@ int main(int argc, char *argv[])
+     qDebug() << service.baseService();
+ 
+     if (cmdArgs.isBlank) {
+-        Q_EMIT lockDialogModel->showBlankScreensaver(cmdArgs.nBlankDelay, cmdArgs.isBlankHasLock);
++        Q_EMIT lockDialogModel.showBlankScreensaver(cmdArgs.nBlankDelay, cmdArgs.isBlankHasLock);
+     }
+ 
+ #ifndef USE_INTEL
+@@ -188,42 +189,42 @@ int main(int argc, char *argv[])
+ #endif
+ 
+     if (cmdArgs.isLock) {
+-        Q_EMIT lockDialogModel->showLock(false);
++        Q_EMIT lockDialogModel.showLock(false);
+     }
+ 
+     if (cmdArgs.isLockStartup) {
+-        Q_EMIT lockDialogModel->showLock(true);
++        Q_EMIT lockDialogModel.showLock(true);
+     }
+ 
+     if (cmdArgs.isSessionIdle) {
+-        Q_EMIT lockDialogModel->showSessionIdle();
++        Q_EMIT lockDialogModel.showSessionIdle();
+     }
+ 
+     if (cmdArgs.isLockScreensaver) {
+-        Q_EMIT lockDialogModel->showLockScreensaver();
++        Q_EMIT lockDialogModel.showLockScreensaver();
+     }
+ 
+     if (cmdArgs.isScreenSaver) {
+-        Q_EMIT lockDialogModel->showScreensaver();
++        Q_EMIT lockDialogModel.showScreensaver();
+     }
+ 
+     if (cmdArgs.isSessionTools) {
+-        Q_EMIT lockDialogModel->showSessionTools();
++        Q_EMIT lockDialogModel.showSessionTools();
+     }
+ 
+     if (cmdArgs.isAppBlock != -1) {
+-        Q_EMIT lockDialogModel->showAppBlockWindow(cmdArgs.isAppBlock);
++        Q_EMIT lockDialogModel.showAppBlockWindow(cmdArgs.isAppBlock);
+     }
+ 
+     if (cmdArgs.isMultiUserBlock != -1) {
+-        Q_EMIT lockDialogModel->showMultiUsersBlockWindow(cmdArgs.isMultiUserBlock);
++        Q_EMIT lockDialogModel.showMultiUsersBlockWindow(cmdArgs.isMultiUserBlock);
+     }
+ 
+     if (cmdArgs.isSwitchUser) {
+-        Q_EMIT lockDialogModel->showSwitchUserLock();
++        Q_EMIT lockDialogModel.showSwitchUserLock();
+     }
+ 
+     KillFocusOfKydroid();
+-
++    syslog(LOG_INFO, "[ukui-screensaver-dialog] application event loop begin!!");
+     return app.exec();
+ }
+diff --git a/src/lock-dialog/pam-tally.c b/src/lock-dialog/pam-tally.c
+index a1d1014..f02d9f6 100644
+--- a/src/lock-dialog/pam-tally.c
++++ b/src/lock-dialog/pam-tally.c
+@@ -41,6 +41,7 @@ struct  tallylog {
+ 	uint64_t        fail_time;      /* time of last failure */
+ };
+ 
++static pam_tally g_tally_info;
+ 
+ 	static
+ int get_is_open_other_authentication()
+@@ -150,6 +151,19 @@ void set_shm_tally_real()
+ 
+ int pam_tally_init()
+ {
++#if 1
++       int deny = 0, unlock_time = 0 , root_unlock_time = 0;
++       if (!get_pam_tally(&deny, &unlock_time,&root_unlock_time)) {
++           return 0;
++       }
++       g_tally_info.deny = deny;
++       g_tally_info.unlock_time = unlock_time;
++       g_tally_info.failed = 0;
++       g_tally_info.lock_start_time = 0;
++       g_tally_info.root_unlock_time = root_unlock_time;
++
++       return 1;
++#else
+ 	int fd;
+ 	int deny = 0, unlock_time = 0 , root_unlock_time = 0;
+ 	pam_tally *tally_ptr;
+@@ -197,6 +211,7 @@ int pam_tally_init()
+ 	tally_ptr->root_unlock_time = root_unlock_time;    
+ 	
+ 	return 1;
++#endif
+ }
+ 
+ 	static
+@@ -389,10 +404,12 @@ void get_tally(uid_t uid, int *tfile, struct tallylog *tally)
+ int pam_tally_unlock_time_left(uid_t userID, int *fail_cnt,int *left_time, int *deny, int *fail_time, int *unlock_time1)
+ {
+ 	pam_tally *tally_ptr;
+-
++#if 1
++    tally_ptr = &g_tally_info;
++#else
+ 	if((tally_ptr = pam_tally_memory()) == NULL)
+ 		return 0;
+-
++#endif
+ 	int unlock_time = tally_ptr->unlock_time;
+ 	*deny = tally_ptr->deny;
+ 
+@@ -441,9 +458,12 @@ int pam_tally_root_unlock_time_left(uid_t userID, int *fail_cnt,int *left_time,
+ {
+ 
+ 	pam_tally *tally_ptr;
+-	if((tally_ptr = pam_tally_memory()) == NULL){
+-		return 0;
+-	}
++#if 1
++    tally_ptr = &g_tally_info;
++#else
++    if((tally_ptr = pam_tally_memory()) == NULL)
++        return 0;
++#endif
+ 	int root_unlock_time = tally_ptr->root_unlock_time;
+ 	int deny = tally_ptr->deny;
+ 	if(root_unlock_time == 0)
+diff --git a/src/ukccplugins/CMakeLists.txt b/src/ukccplugins/CMakeLists.txt
+new file mode 100644
+index 0000000..9599549
+--- /dev/null
++++ b/src/ukccplugins/CMakeLists.txt
+@@ -0,0 +1,3 @@
++add_definitions(-DOPENKYLIN -DNile)
++add_subdirectory(screenlock)
++add_subdirectory(screensaver)
+diff --git a/src/ukccplugins/screenlock/CMakeLists.txt b/src/ukccplugins/screenlock/CMakeLists.txt
+new file mode 100644
+index 0000000..2941a16
+--- /dev/null
++++ b/src/ukccplugins/screenlock/CMakeLists.txt
+@@ -0,0 +1,47 @@
++pkg_check_modules(QGS REQUIRED gsettings-qt)
++pkg_check_modules(GIO2.0 REQUIRED gio-2.0)
++pkg_check_modules(KYSDKQTWIDGETS REQUIRED kysdk-qtwidgets)
++pkg_check_modules(KYSDKDIAGNOSTICS REQUIRED kysdk-diagnostics)
++
++include_directories(${PROJECT_BINARY_DIR})
++include_directories(${PROJECT_SOURCE_DIR}/Common)
++
++include_directories(
++	${QGS_INCLUDE_DIRS}
++        ${GIO2.0_INCLUDE_DIRS}
++        ${KYSDKQTWIDGETS_INCLUDE_DIRS}
++        ${KYSDKDIAGNOSTICS_INCLUDE_DIRS}
++        /usr/include/ukcc
++	)
++
++set(EXTRA_LIBS
++        ${EXTRA_LIBS}
++        ${QGS_LIBRARIES}
++        ${GIO2.0_LIBRARIES}
++        ${KYSDKQTWIDGETS_LIBRARIES}
++        ${KYSDKDIAGNOSTICS_LIBRARIES}
++        -lukcc
++	)
++
++qt5_add_resources(lockscreen_Plugin_SRC
++        )
++
++qt5_wrap_cpp(lockscreen_Plugin_SRC
++    pictureunit.h
++    screenlock.h
++    screenlockui.h
++    )
++
++set(lockscreen_Plugin_SRC
++    ${lockscreen_Plugin_SRC}
++    pictureunit.cpp
++    screenlock.cpp
++    screenlockui.cpp
++    )
++
++add_library(screenlock SHARED ${lockscreen_Plugin_SRC})
++target_link_libraries(screenlock Qt5::Widgets Qt5::DBus Qt5::Xml ${EXTRA_LIBS})
++
++install(TARGETS
++        screenlock
++        DESTINATION lib/${CMAKE_LIBRARY_ARCHITECTURE}/ukui-control-center)
+diff --git a/src/ukccplugins/screenlock/pictureunit.cpp b/src/ukccplugins/screenlock/pictureunit.cpp
+new file mode 100644
+index 0000000..4628b78
+--- /dev/null
++++ b/src/ukccplugins/screenlock/pictureunit.cpp
+@@ -0,0 +1,124 @@
++/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
++ *
++ * Copyright (C) 2019 KylinSoft  Co., Ltd.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
++ *
++ */
++#include "pictureunit.h"
++#include <QApplication>
++#include <widgets/maskwidget.h>
++#include <QTouchEvent>
++#include <QGSettings>
++#include <QDebug>
++#include <qmath.h>
++
++PictureUnit::PictureUnit(QWidget *parent) : QLabel(parent)
++{
++    _filename = "";
++
++    hoverStyleSheet = QString("border-width: 3px;border-style: solid;border-color: palette(highlight);");
++    clickedStyleSheet = QString("border-width: 4px;border-style: solid;border-color: palette(highlight);");
++    if (QGSettings::isSchemaInstalled("org.ukui.style")) {
++        QGSettings *qtSettings = new QGSettings("org.ukui.style", QByteArray(), this);
++        connect(qtSettings, &QGSettings::changed, this, [=](const QString &key) {
++            if (key == "themeColor" && this->clickedFlag) {
++                this->setStyleSheet(clickedStyleSheet);
++            }
++        });
++    }
++    clickedFlag = false;
++    setAttribute(Qt::WA_DeleteOnClose);
++    setFixedSize(QSize(198, 136));
++    setScaledContents(true);
++
++    MaskWidget *maskWidget = new MaskWidget(this);
++    maskWidget->setGeometry(0, 0, this->width(), this->height());
++    isTouchControl = false;
++    qApp->installEventFilter(this);
++    this->setAttribute(Qt::WA_AcceptTouchEvents);
++}
++
++PictureUnit::~PictureUnit() {}
++
++void PictureUnit::setFilenameText(QString fn)
++{
++    _filename = fn;
++}
++
++QString PictureUnit::filenameText()
++{
++    return _filename;
++}
++
++void PictureUnit::mouseReleaseEvent(QMouseEvent *e)
++{
++    if (e->button() == Qt::LeftButton && !isTouchControl && e->pos().x() >= 0 && e->pos().y() >= 0
++        && e->pos().x() <= width() && e->pos().y() <= height()) {
++
++        changeClickedFlag(true);
++        Q_EMIT clicked(_filename);
++    }
++}
++
++void PictureUnit::enterEvent(QEvent *e)
++{
++    if (getClickedFlag() == false && !isTouchControl) {
++        setFrameShape(QFrame::Box);
++        setStyleSheet(hoverStyleSheet);
++    }
++}
++void PictureUnit::leaveEvent(QEvent *e)
++{
++    if (getClickedFlag() == false) {
++        setStyleSheet("border-width: 0px;");
++    }
++}
++
++bool PictureUnit::getClickedFlag()
++{
++    return clickedFlag;
++}
++
++void PictureUnit::changeClickedFlag(bool flag)
++{
++    clickedFlag = flag;
++    if (flag) {
++        this->setFrameShape(QFrame::Box);
++        this->setStyleSheet(clickedStyleSheet);
++    } else {
++        this->setStyleSheet("border-width: 0px;");
++    }
++}
++
++bool PictureUnit::eventFilter(QObject *w, QEvent *e)
++{
++    if (w == this) {
++        if (e->type() == QEvent::TouchBegin) {
++            isTouchControl = true;
++            QTouchEvent *touchE = static_cast<QTouchEvent *>(e);
++            touchBeginPoint = touchE->touchPoints().at(0).screenPos();
++        }
++    } else if (e->type() == QEvent::TouchEnd && isTouchControl) {
++        isTouchControl = false;
++        QTouchEvent *touchE = static_cast<QTouchEvent *>(e);
++        touchEndPoint = touchE->touchPoints().at(0).screenPos();
++        if (qFabs(touchEndPoint.x() - touchBeginPoint.x()) < 1.0
++            && qFabs(touchEndPoint.y() - touchBeginPoint.y()) < 1.0) {
++            emit clicked(_filename);
++        }
++    }
++    return qApp->eventFilter(w, e);
++}
+diff --git a/src/ukccplugins/screenlock/pictureunit.h b/src/ukccplugins/screenlock/pictureunit.h
+new file mode 100644
+index 0000000..e334b86
+--- /dev/null
++++ b/src/ukccplugins/screenlock/pictureunit.h
+@@ -0,0 +1,61 @@
++/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
++ *
++ * Copyright (C) 2019 KylinSoft  Co., Ltd.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
++ *
++ */
++#ifndef PICTUREUNIT_H
++#define PICTUREUNIT_H
++
++#include <QLabel>
++#include <QMouseEvent>
++#include <QEvent>
++
++class PictureUnit : public QLabel
++{
++    Q_OBJECT
++
++public:
++    explicit PictureUnit(QWidget *parent = nullptr);
++    ~PictureUnit();
++
++public:
++    void setFilenameText(QString fn);
++    QString filenameText();
++    void changeClickedFlag(bool flag);
++    bool getClickedFlag();
++    void enterEvent(QEvent *e);
++    void leaveEvent(QEvent *e);
++public:
++    QString _filename;
++    QString clickedStyleSheet;
++protected:
++    void mouseReleaseEvent(QMouseEvent * e);
++    bool eventFilter(QObject *w, QEvent *e);
++
++private:
++    bool clickedFlag;
++    QString hoverStyleSheet;
++    bool isTouchControl;
++    QPointF touchBeginPoint;
++    QPointF touchEndPoint;
++
++Q_SIGNALS:
++    void clicked(QString filename);
++
++};
++
++#endif // PICTUREUNIT_H
+diff --git a/src/ukccplugins/screenlock/screenlock.cpp b/src/ukccplugins/screenlock/screenlock.cpp
+new file mode 100644
+index 0000000..9a9f150
+--- /dev/null
++++ b/src/ukccplugins/screenlock/screenlock.cpp
+@@ -0,0 +1,277 @@
++/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
++ *
++ * Copyright (C) 2019 KylinSoft  Co., Ltd.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
++ *
++ */
++#include "screenlock.h"
++#include <interface/ukcccommon.h>
++using namespace ukcc;
++#include <QDebug>
++#include <QDir>
++#include <QFileDialog>
++#include <QDesktopServices>
++#include <QProcess>
++#include <QFileSystemWatcher>
++#include <QTranslator>
++#include <QLocale>
++#include <QApplication>
++
++Screenlock::Screenlock() : mFirstLoad(true)
++{
++    QTranslator *translator = new QTranslator(this);
++    translator->load("/usr/share/ukui-screensaver/ukccplugins/i18n_qm/" + QLocale::system().name());
++    QApplication::installTranslator(translator);
++
++    pluginName = tr("Screenlock");
++    pluginType = PERSONALIZED;
++}
++
++Screenlock::~Screenlock() {}
++
++QString Screenlock::plugini18nName()
++{
++    return pluginName;
++}
++
++int Screenlock::pluginTypes()
++{
++    return pluginType;
++}
++
++QWidget *Screenlock::pluginUi()
++{
++    if (mFirstLoad) {
++        mFirstLoad = false;
++        screenlockui = new ScreenlockUi();
++        screenlockInterface = new QDBusInterface(
++            "org.ukui.ScreenSaver",
++            "/Screenlock",
++            "org.ukui.ScreenSaver.session.Screenlock",
++            QDBusConnection::sessionBus(),
++            this);
++        if (screenlockInterface->isValid()) {                         // 判断服务是否存在
++            QDBusMessage message = screenlockInterface->call("ping"); // 判断dbus路径是否存在
++            if (message.type() == QDBusMessage::ErrorMessage
++                && message.errorMessage().contains("No such object path", Qt::CaseInsensitive)) {
++                qWarning() << screenlockInterface << ":" << message.errorMessage();
++            } else {
++                QDBusConnection::sessionBus().connect(
++                    "org.ukui.ScreenSaver",
++                    "/Screenlock",
++                    "org.ukui.ScreenSaver.session.Screenlock",
++                    "changed",
++                    this,
++                    SLOT(dataChanged(QString)));
++                initContent();
++                connectUiSignals();
++                connectToServer();
++            }
++        } else {
++            qCritical() << "org.ukui.ScreenSaver.session.Screenlock DBus error:" << screenlockInterface->lastError();
++        }
++    } else {
++        screenlockui->resize(screenlockui->size() - QSize(1, 1));
++        screenlockui->resize(screenlockui->size() + QSize(1, 1));
++    }
++    return screenlockui;
++}
++
++const QString Screenlock::name() const
++{
++    return QStringLiteral("Screenlock");
++}
++
++bool Screenlock::isShowOnHomePage() const
++{
++    return true;
++}
++
++QIcon Screenlock::icon() const
++{
++    return QIcon::fromTheme("ukui-lock-screen-symbolic");
++}
++
++bool Screenlock::isEnable() const
++{
++    return true;
++}
++
++void Screenlock::dataChanged(const QString &key)
++{
++    if (toChangeKey != key) {
++        if (key == "showOnLogin") {
++            initShowOnLogin();
++        } else if (key == "wallpaper") {
++            initWallpaper();
++        }
++    }
++    toChangeKey = "";
++}
++
++void Screenlock::initContent()
++{
++    QStringList previewPictures = screenlockInterface->property("previewWallpapers").toStringList();
++    QStringList sourcePictures = screenlockInterface->property("sourceWallpapers").toStringList();
++    screenlockui->setPictures(previewPictures, sourcePictures);
++    initWallpaper();
++    initShowOnLogin();
++}
++
++void Screenlock::initShowOnLogin()
++{
++    screenlockui->setShowOnLogin(screenlockInterface->property("showOnLogin").toBool());
++}
++
++void Screenlock::initWallpaper()
++{
++    screenlockui->setPicture(screenlockInterface->property("wallpaper").toString());
++}
++
++void Screenlock::connectUiSignals()
++{
++    connect(screenlockui, &ScreenlockUi::showOnLoginChanged, this, [=](bool b) {
++        toChangeKey = "showOnLogin";
++        screenlockInterface->call("setShowOnLogin", b);
++        UkccCommon::buriedSettings(
++            name(),
++            QString("Show picture of screenlock on screenlogin"),
++            QString("settings"),
++            UkccCommon::boolToString(b));
++    });
++    connect(screenlockui, &ScreenlockUi::pictureChanged, this, [=](QString file) {
++        toChangeKey = "wallpaper";
++        screenlockInterface->call("setWallpaper", file);
++    });
++    connect(screenlockui, &ScreenlockUi::localButtonClicked, this, [=]() { showLocalWpDialog(); });
++    connect(screenlockui, &ScreenlockUi::onlineButtonClicked, this, [=]() {
++        QDesktopServices::openUrl(QUrl(QLatin1String("https://www.ubuntukylin.com/wallpaper.html")));
++        UkccCommon::buriedSettings(name(), QString("onlineBtnonlineButton"), QString("clicked"));
++    });
++    connect(screenlockui, &ScreenlockUi::resetButtonClicked, this, [=]() {
++        screenlockInterface->call("resetDefault");
++        UkccCommon::buriedSettings(name(), QString("resetBtn"), QString("clicked"));
++    });
++    connect(screenlockui, &ScreenlockUi::toSetMonitor, this, [=]() {
++        UkccCommon::buriedSettings(name(), "setBtn(Monitor Off)", QString("clicked"));
++        QProcess::startDetached(
++            "ukui-control-center",
++            QStringList() << "-m"
++                          << "Power");
++    });
++    connect(screenlockui, &ScreenlockUi::toSetScreensaver, this, [=]() {
++        UkccCommon::buriedSettings(name(), "setBtn(Screensaver)", QString("clicked"));
++        QProcess::startDetached(
++            "ukui-control-center",
++            QStringList() << "-m"
++                          << "Screensaver");
++    });
++}
++
++void Screenlock::showLocalWpDialog()
++{
++    QStringList filters;
++    filters << tr("Wallpaper files(*.jpg *.jpeg *.bmp *.dib *.png *.jfif *.jpe *.gif *.tif *.tiff *.wdp)");
++    QFileDialog fd;
++
++    QList<QUrl> usb_list = fd.sidebarUrls();
++    int sidebarNum = 8; // 最大添加U盘数,可以自己定义
++    QString home_path = QDir::homePath().section("/", -1, -1);
++    QString mnt = "/media/" + home_path + "/";
++    QDir mntDir(mnt);
++    mntDir.setFilter(QDir::Dirs | QDir::NoDotAndDotDot);
++    QFileInfoList file_list = mntDir.entryInfoList();
++    QList<QUrl> mntUrlList;
++    for (int i = 0; i < sidebarNum && i < file_list.size(); ++i) {
++        QFileInfo fi = file_list.at(i);
++        mntUrlList << QUrl("file://" + fi.filePath());
++    }
++
++    QFileSystemWatcher m_fileSystemWatcher(&fd);
++    m_fileSystemWatcher.addPath("/media/" + home_path + "/");
++    connect(
++        &m_fileSystemWatcher,
++        &QFileSystemWatcher::directoryChanged,
++        &fd,
++        [=, &sidebarNum, &mntUrlList, &usb_list, &fd](const QString path) {
++            QDir m_wmntDir(path);
++            m_wmntDir.setFilter(QDir::Dirs | QDir::NoDotAndDotDot);
++            QFileInfoList m_wfilist = m_wmntDir.entryInfoList();
++            mntUrlList.clear();
++            for (int i = 0; i < sidebarNum && i < m_wfilist.size(); ++i) {
++                QFileInfo m_fi = m_wfilist.at(i);
++                mntUrlList << QUrl("file://" + m_fi.filePath());
++            }
++            fd.setSidebarUrls(usb_list + mntUrlList);
++            fd.update();
++        });
++
++    connect(&fd, &QFileDialog::finished, &fd, [=, &usb_list, &fd]() { fd.setSidebarUrls(usb_list); });
++
++    fd.setDirectory(QString(const_cast<char *>(g_get_user_special_dir(G_USER_DIRECTORY_PICTURES))));
++    fd.setAcceptMode(QFileDialog::AcceptOpen);
++    fd.setViewMode(QFileDialog::List);
++    fd.setNameFilters(filters);
++    fd.setFileMode(QFileDialog::ExistingFile);
++    fd.setWindowTitle(tr("select custom wallpaper file"));
++    fd.setLabelText(QFileDialog::Accept, tr("Select"));
++    fd.setLabelText(QFileDialog::LookIn, tr("Position: "));
++    fd.setLabelText(QFileDialog::FileName, tr("FileName: "));
++    fd.setLabelText(QFileDialog::FileType, tr("FileType: "));
++    fd.setLabelText(QFileDialog::Reject, tr("Cancel"));
++
++    fd.setSidebarUrls(usb_list + mntUrlList);
++
++    if (fd.exec() != QDialog::Accepted) {
++        return;
++    }
++    QString selectedfile;
++    selectedfile = fd.selectedFiles().first();
++
++    QStringList fileRes = selectedfile.split("/");
++
++    QProcess *process = new QProcess(this);
++    QString program("cp");
++    QStringList arguments;
++    arguments << selectedfile;
++    arguments << "/tmp";
++    process->start(program, arguments);
++
++    screenlockInterface->call("setWallpaper", selectedfile);
++    UkccCommon::buriedSettings(name(), QString("browserLocalwpBtn"), QString("clicked"));
++}
++
++void Screenlock::connectToServer()
++{
++    QThread *NetThread = new QThread;
++    MThread *NetWorker = new MThread;
++    NetWorker->moveToThread(NetThread);
++    connect(NetThread, &QThread::started, NetWorker, &MThread::run);
++    connect(NetWorker, &MThread::keychangedsignal, this, &Screenlock::keyChangedSlot);
++    connect(NetThread, &QThread::finished, NetWorker, &MThread::deleteLater);
++    NetThread->start();
++}
++
++void Screenlock::keyChangedSlot(const QString &key)
++{
++    if (key == "ukui-screensaver") {
++        if (!bIsCloudService) {
++            bIsCloudService = true;
++        }
++        initShowOnLogin();
++        initWallpaper();
++    }
++}
+diff --git a/src/ukccplugins/screenlock/screenlock.h b/src/ukccplugins/screenlock/screenlock.h
+new file mode 100644
+index 0000000..9cf0808
+--- /dev/null
++++ b/src/ukccplugins/screenlock/screenlock.h
+@@ -0,0 +1,83 @@
++/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
++ *
++ * Copyright (C) 2019 KylinSoft  Co., Ltd.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
++ *
++ */
++#ifndef SCREENLOCK_H
++#define SCREENLOCK_H
++
++#include <interface/mthread.h>
++#include <interface/interface.h>
++#include "screenlockui.h"
++#include <QObject>
++#include <QtPlugin>
++
++#ifdef signals
++#undef signals
++#endif
++
++#include <glib.h>
++#include <gio/gio.h>
++
++class Screenlock : public QObject, CommonInterface
++{
++    Q_OBJECT
++    Q_PLUGIN_METADATA(IID "org.ukcc.CommonInterface")
++    Q_INTERFACES(CommonInterface)
++
++public:
++    Screenlock();
++    ~Screenlock();
++
++    QString plugini18nName()   Q_DECL_OVERRIDE;
++    int pluginTypes()       Q_DECL_OVERRIDE;
++    QWidget * pluginUi()   Q_DECL_OVERRIDE;
++    const QString name() const  Q_DECL_OVERRIDE;
++    bool isShowOnHomePage() const Q_DECL_OVERRIDE;
++    QIcon icon() const Q_DECL_OVERRIDE;
++    bool isEnable() const Q_DECL_OVERRIDE;
++    virtual QString translationPath() const {
++        return QStringLiteral("/usr/share/ukui-screensaver/ukccplugins/i18n/%1.ts");
++    }
++
++private:
++    void connectToServer();
++
++public Q_SLOTS:
++    void keyChangedSlot(const QString &key);
++
++public:
++    void initContent();
++    void initShowOnLogin();
++    void initWallpaper();
++    void connectUiSignals();
++    void showLocalWpDialog();
++
++public Q_SLOTS:
++    void dataChanged(const QString &key);
++
++private:
++    QString        toChangeKey;
++    QString        pluginName;
++    int            pluginType;
++    bool           mFirstLoad;
++    ScreenlockUi   *screenlockui        = nullptr;
++    QDBusInterface *screenlockInterface = nullptr;
++    bool           bIsCloudService      = false;
++};
++
++#endif // SCREENLOCK_H
+diff --git a/src/ukccplugins/screenlock/screenlockui.cpp b/src/ukccplugins/screenlock/screenlockui.cpp
+new file mode 100644
+index 0000000..4431aaa
+--- /dev/null
++++ b/src/ukccplugins/screenlock/screenlockui.cpp
+@@ -0,0 +1,713 @@
++/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
++ *
++ * Copyright (C) 2019 KylinSoft  Co., Ltd.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
++ *
++ */
++#include "screenlockui.h"
++#include <QImageReader>
++#include <QScrollArea>
++#include <QScrollBar>
++
++ScreenlockUi::ScreenlockUi()
++{
++    setAttribute(Qt::WA_DeleteOnClose);
++    m_screenlockLayout = new QVBoxLayout(this);
++    m_screenlockLayout->setContentsMargins(0,0,0,0);
++    initUi();
++}
++
++ScreenlockUi::~ScreenlockUi()
++{
++
++}
++
++void ScreenlockUi::initUi()
++{
++    initScreenLock();
++#ifdef Nile
++    initLeavLockStatus();
++#endif
++    initSignals();
++}
++
++void ScreenlockUi::initScreenLock()
++{
++    // 1 锁屏
++    m_wallpaperTitleLabel = new KLabel(this);
++    m_wallpaperTitleLabel->setContentsMargins(16, 0, 0, 0);
++    //~ contents_path /Screenlock/Screenlock
++    m_wallpaperTitleLabel->setText(tr("Screenlock"));
++
++    // 2.1 预览图
++    m_previewFrame = new UkccFrame(this);
++    m_previewFrame->setFixedHeight(193);
++    m_previewLayout = new QHBoxLayout(m_previewFrame);
++    m_previewLayout->setContentsMargins(16, 12, 16, 16);
++
++    m_previewLabel = new QLabel(this);
++    m_previewLabel->setFixedSize(280, 160);
++    m_centerGroup = new SettingGroup(this);
++
++    m_contentBackgroundGroup = new KBackgroundGroup(m_previewFrame);
++    QList<QWidget*> contentList;
++
++    // 登录界面显示锁屏壁纸
++    QWidget* showPicWidget = new QWidget();
++    QHBoxLayout* typeLayout = new QHBoxLayout(showPicWidget);
++    typeLayout->setContentsMargins(16, 0, 0, 0);
++    typeLayout->setSpacing(0);
++    //~ contents_path /Screenlock/Show picture of screenlock on screenlogin
++    QLabel* showPicLabel = new QLabel(tr("Show picture of screenlock on screenlogin"), showPicWidget);
++    m_showPicSwitchButton = new KSwitchButton(showPicWidget);
++    typeLayout->addWidget(showPicLabel);
++    typeLayout->addStretch();
++    typeLayout->addWidget(m_showPicSwitchButton);
++    contentList.append(showPicWidget);
++
++#ifdef Nile
++    // 动态锁
++    QWidget* btLeaveLockWidget = new QWidget();
++    QHBoxLayout* btLeaveLockLayout = new QHBoxLayout(btLeaveLockWidget);
++    btLeaveLockLayout->setContentsMargins(16, 0, 0, 0);
++    btLeaveLockLayout->setSpacing(0);
++    QLabel* btLeaveLockLabel = new QLabel(tr("Leave lock (System will be locked when the paired phone gone)"), btLeaveLockWidget);
++    m_btLeaveLockSwitchButton = new KSwitchButton(btLeaveLockWidget);
++    btLeaveLockLayout->addWidget(btLeaveLockLabel);
++    btLeaveLockLayout->addStretch();
++    btLeaveLockLayout->addWidget(m_btLeaveLockSwitchButton);
++    contentList.append(btLeaveLockWidget);
++
++    // 蓝牙设备
++    m_bluetoothWidget = new QWidget();
++    KLabel* bluetoothLabel = new KLabel(m_bluetoothWidget);
++    bluetoothLabel->setText(tr("Specified device"));
++    m_bluetoothComboBox = new QComboBox(m_bluetoothWidget);
++    QHBoxLayout* bluetoothLayout = new QHBoxLayout(m_bluetoothWidget);
++    bluetoothLayout->setContentsMargins(16, 0, 0, 0);
++    bluetoothLayout->setSpacing(0);
++    bluetoothLayout->addWidget(bluetoothLabel);
++    bluetoothLayout->addStretch();
++    bluetoothLayout->addWidget(m_bluetoothComboBox);
++    m_bluetoothWidget->setVisible(false);
++    contentList.append(m_bluetoothWidget);
++
++    // 无配对手机去设置蓝牙
++    m_setBtWidget = new QWidget();
++    QHBoxLayout* setBtLayout = new QHBoxLayout(m_setBtWidget);
++    setBtLayout->setContentsMargins(16, 0, 0, 0);
++    setBtLayout->setSpacing(0);
++    KLabel* setBtLabel = new KLabel(m_setBtWidget);
++    setBtLabel->setText(tr("No paired phone. Please turn to 'Bluetooth' to pair."));
++    QLabel* setBticonLabel = new QLabel(m_setBtWidget);
++    QIcon icon = QIcon::fromTheme("kylin-dialog-warning");
++    if (icon.isNull()) {
++        icon = QIcon::fromTheme("dialog-warning");
++    }
++    setBticonLabel->setPixmap(icon.pixmap(16, 16));
++    m_setBtPushButton = new KPushButton(m_setBtWidget);
++    m_setBtPushButton->setText(tr("Bluetooth"));
++    setBtLayout->addWidget(setBticonLabel);
++    setBtLayout->addWidget(setBtLabel);
++    setBtLayout->addStretch();
++    setBtLayout->addWidget(m_setBtPushButton);
++    m_setBtWidget->setVisible(false);
++    contentList.append(m_setBtWidget);
++
++    m_noBtWidget = new UkccFrame(m_centerGroup, UkccFrame::None,true);
++    contentList.append(m_noBtWidget);
++#endif
++    m_contentBackgroundGroup->addWidgetList(contentList);
++
++    // 预览区域滚动条设置
++    QScrollArea *previewScrollArea = new QScrollArea;
++    previewScrollArea->setFixedHeight(192);
++    previewScrollArea->viewport()->setAttribute(Qt::WA_TranslucentBackground);
++    previewScrollArea->setStyleSheet("QScrollArea{background-color: transparent;}");
++    previewScrollArea->verticalScrollBar()->setProperty("drawScrollBarGroove", false);
++    previewScrollArea->verticalScrollBar()->setEnabled(false);
++    previewScrollArea->setWidgetResizable(true);
++    previewScrollArea->setWidget(m_previewFrame);
++
++    QVBoxLayout* rightPreviewLayout = new QVBoxLayout();
++    rightPreviewLayout->setContentsMargins(8, 0, 16, 0);
++    rightPreviewLayout->setSpacing(0);
++    rightPreviewLayout->addWidget(m_contentBackgroundGroup);
++    rightPreviewLayout->addStretch();
++
++    m_previewLayout->addWidget(m_previewLabel);
++    m_previewLayout->addSpacing(0);
++    m_previewLayout->addLayout(rightPreviewLayout);
++
++    m_picBtnFrame = new UkccFrame(m_centerGroup);
++    m_picBtnFrame->setLineWidth(0);
++
++    m_pictureFrame = new UkccFrame(m_picBtnFrame);
++    m_pictureFrame->setLineWidth(0);
++
++    m_pictureLayout = new FlowLayout(m_pictureFrame, 8, -1, -1);
++    m_pictureLayout->setContentsMargins(16, 0, 16, 0);
++
++    m_bottomFrame = new UkccFrame(m_picBtnFrame);
++
++    // 3.1 选择图片
++    //~ contents_path /Wallpaper/Choose Picture
++    QLabel* chooseLabel = new QLabel(tr("Choose Picture"), m_bottomFrame);
++
++    // 3.2 本地图片
++    //~ contents_path /Screenlock/Local Pictures
++    m_localBtn = new QPushButton(tr("Local Pictures"), m_bottomFrame);
++
++    // 3.3 在线图片
++    //~ contents_path /Screenlock/Online Pictures
++    m_onlineBtn = new QPushButton(tr("Online Pictures"), m_bottomFrame);
++
++    // 3.4 恢复默认
++    //~ contents_path /Screenlock/Reset To Default
++    m_resetBtn = new QPushButton(tr("Reset To Default"), m_bottomFrame);
++
++    m_bottomLayout = new QHBoxLayout(m_bottomFrame);
++    m_bottomLayout->setContentsMargins(16, 8, 16, 8);
++    m_bottomLayout->addWidget(chooseLabel);
++    m_bottomLayout->addStretch();
++    m_bottomLayout->addWidget(m_localBtn);
++    m_bottomLayout->addWidget(m_onlineBtn);
++    m_bottomLayout->addWidget(m_resetBtn);
++
++    // 相关设置
++    m_relateFrame = new UkccFrame(m_picBtnFrame);
++    m_relateLayout = new QVBoxLayout(m_relateFrame);
++    UkccFrame* titleFrame = new UkccFrame();
++    QHBoxLayout* relateTitleLayout = new QHBoxLayout(titleFrame);
++
++    relateTitleLayout->setContentsMargins(0, 0, 0, 0);
++    relateTitleLabel  = new KLabel(m_relateFrame);
++    relateTitleLabel->setContentsMargins(16, 0, 0, 0);
++    relateTitleLayout->addWidget(relateTitleLabel);
++    relateTitleLabel->setText(tr("Related Settings"));
++
++    KBackgroundGroup* relateGroup = new KBackgroundGroup();
++    monitorWidget = new PushButtonWidget(tr("Monitor Off"), m_relateFrame);
++    monitorWidget->setButtonText(tr("Set"));
++    screensaverWidget = new PushButtonWidget(tr("Screensaver"), m_relateFrame);
++    screensaverWidget->setButtonText(tr("Set"));
++
++    relateGroup->addWidget(titleFrame);
++    relateGroup->addWidget(monitorWidget);
++    relateGroup->addWidget(screensaverWidget);
++
++    m_relateLayout->addWidget(relateGroup);
++
++    m_picBtnLayout = new QVBoxLayout(m_picBtnFrame);
++    m_picBtnLayout->setMargin(0);
++    m_picBtnLayout->setSpacing(0);
++    m_picBtnLayout->addWidget(m_bottomFrame);
++    m_picBtnLayout->addWidget(m_pictureFrame);
++    m_picBtnLayout->addWidget(m_relateFrame);
++
++    m_centerGroup->addWidget(m_picBtnFrame);
++
++    QScrollArea *contentScrollArea = new QScrollArea;
++    contentScrollArea->viewport()->setAttribute(Qt::WA_TranslucentBackground);
++    contentScrollArea->setStyleSheet("QScrollArea{background-color: transparent;}");
++    contentScrollArea->verticalScrollBar()->setProperty("drawScrollBarGroove", false);
++    contentScrollArea->setWidgetResizable(true);
++    contentScrollArea->setFrameShape(QFrame::Box);
++    contentScrollArea->setFrameShadow(QFrame::Plain);
++    contentScrollArea->setWidget(m_centerGroup);
++
++    m_screenlockLayout->addWidget(m_wallpaperTitleLabel);
++    m_screenlockLayout->addWidget(previewScrollArea);
++    m_screenlockLayout->addWidget(contentScrollArea);
++
++#ifdef Nile
++    QHBoxLayout *noBtVLayout = new QHBoxLayout();
++    QLabel *noBtWarnIcon = new QLabel(m_noBtWidget);
++    QLabel *noBtMessage = new QLabel(tr("No bluetooth adapter detected, can not use Leave Lock."),m_noBtWidget);
++
++    noBtWarnIcon->setPixmap(icon.pixmap(18,18));
++    noBtVLayout->setContentsMargins(16, 0, 16, 0);
++    noBtVLayout->setSpacing(16);
++    noBtVLayout->addWidget(noBtWarnIcon);
++    noBtVLayout->addWidget(noBtMessage,Qt::AlignLeft);
++    m_noBtWidget->setLayout(noBtVLayout);
++    m_noBtWidget->setVisible(false);
++
++    m_bluetoothWidget->setVisible(false);
++#endif
++}
++
++void ScreenlockUi::initLeavLockStatus() {
++    bool ispowered = isBluetoothPowered();
++    bool leaveLockOn = getLeavLockOn();
++    bool hasAdapter = hasBluetoothAdapter();
++    QMap<QString, QString> btDevices = getBtPairedDevices();
++
++    m_bluetoothComboBox->clear();
++
++    if (leaveLockOn) {
++        m_btLeaveLockSwitchButton->click();
++    }
++
++    canLeaveLock = !btDevices.isEmpty();
++    m_bluetoothComboBox->addItem(tr("Please select device"));
++    for (auto dev : btDevices.keys()) {
++        m_bluetoothComboBox->addItem(btDevices.value(dev), dev);
++    }
++    if (canLeaveLock && ispowered) {
++        lockdev = getLeaveLockDev();
++        if (!lockdev.isEmpty() && canLeaveLock) {
++            m_bluetoothComboBox->setCurrentIndex(m_bluetoothComboBox->findData(lockdev));
++        }
++    }
++    if (!hasAdapter && leaveLockOn) {
++        m_noBtWidget->setVisible(!hasAdapter);
++        return;
++    }
++    if (m_bluetoothComboBox->count() == 1 && leaveLockOn) {
++        m_setBtWidget->setVisible(true);
++        m_noBtWidget->setVisible(false);
++        m_bluetoothWidget->setVisible(false);
++        return;
++    }
++    m_bluetoothWidget->setVisible(leaveLockOn && canLeaveLock && ispowered);
++    m_setBtWidget->setVisible((!canLeaveLock || !ispowered) && leaveLockOn);
++}
++
++void ScreenlockUi::setBtPushButtonClickSlot() {
++    QProcess *process = new QProcess();
++    QString cmd = "ukui-control-center";
++    QStringList arg;
++    arg.clear();
++    arg << "-m";
++    arg << "Bluetooth";
++    process->startDetached(cmd,arg);
++}
++
++void ScreenlockUi::btLeaveLockButtonClickSlot(bool clicked) {
++    if (!clicked) {
++        m_noBtWidget->setVisible(false);
++        m_setBtWidget->setVisible(false);
++        m_bluetoothWidget->setVisible(false);
++        if (!lockdev.isEmpty()) {
++            setLeaveLock(false);
++        }
++        lockdev.clear();
++        m_bluetoothComboBox->setCurrentIndex(0);
++        return;
++    }
++    m_bluetoothComboBox->setCurrentIndex(0);
++    bool ispowered = isBluetoothPowered();
++    bool hasAdapter = hasBluetoothAdapter();
++
++    if (!hasAdapter) {
++        m_noBtWidget->setVisible(!hasAdapter);
++        return;
++    }
++    if (m_bluetoothComboBox->count() == 1) {
++        m_setBtWidget->setVisible(true);
++
++        m_noBtWidget->setVisible(false);
++        m_bluetoothWidget->setVisible(false);
++        return;
++    }
++    m_bluetoothWidget->setVisible(canLeaveLock && ispowered);
++    m_setBtWidget->setVisible(!canLeaveLock || !ispowered);
++}
++
++void ScreenlockUi::bluetoothWidgetIdxChangeSlot(int index) {
++    if (!lockdev.isEmpty()) {
++        setLeaveLock(false);
++    }
++    if (index == 0) {
++        lockdev.clear();
++        return;
++    }
++    lockdev = m_bluetoothComboBox->currentData().toString();
++    setLeaveLock(true);
++}
++
++void ScreenlockUi::initSignals()
++{
++    connect(m_showPicSwitchButton, &KSwitchButton::clicked, this, [=](){
++        Q_EMIT showOnLoginChanged(m_showPicSwitchButton->isChecked());
++    });
++#ifdef Nile
++    connect(m_btLeaveLockSwitchButton, &KSwitchButton::clicked, this, [=](bool clicked){
++        btLeaveLockButtonClickSlot(clicked);
++    });
++
++    connect(m_bluetoothComboBox, QOverload<int>::of(&QComboBox::currentIndexChanged), this, [=](int index) {
++        bluetoothWidgetIdxChangeSlot(index);
++    });
++
++    connect(m_setBtPushButton, &QPushButton::clicked, this, [=](){
++        setBtPushButtonClickSlot();
++    });
++#endif
++    connect(monitorWidget, &PushButtonWidget::clicked, this, [=](){
++        Q_EMIT toSetMonitor();
++    });
++    connect(screensaverWidget, &PushButtonWidget::clicked, this, [=](){
++        Q_EMIT toSetScreensaver();
++    });
++    connect(m_localBtn, &QPushButton::clicked, this, [=](){
++        Q_EMIT localButtonClicked();
++    });
++    connect(m_onlineBtn, &QPushButton::clicked, this, [=](){
++        Q_EMIT onlineButtonClicked();
++    });
++    connect(m_resetBtn, &QPushButton::clicked, this, [=](){
++        Q_EMIT resetButtonClicked();
++    });
++#ifdef Nile
++    QDBusConnection::sessionBus().connect("com.ukui.bluetooth",
++                                          "/com/ukui/bluetooth",
++                                          "com.ukui.bluetooth",
++                                          "devPairSignal",
++                                          this,
++                                          SLOT(addPairedDev(QString,bool)));
++
++    QDBusConnection::sessionBus().connect("com.ukui.bluetooth",
++                                          "/com/ukui/bluetooth",
++                                          "com.ukui.bluetooth",
++                                          "defaultAdapterPowerChanged",
++                                          this,
++                                          SLOT(powerChanged(bool)));
++
++    QDBusConnection::sessionBus().connect("com.ukui.bluetooth",
++                                          "/com/ukui/bluetooth",
++                                          "com.ukui.bluetooth",
++                                          "defaultAdapterChanged",
++                                          this,
++                                          SLOT(defaultAdapterChanged(QString)));
++
++    QDBusConnection::sessionBus().connect("com.ukui.bluetooth",
++                                          "/com/ukui/bluetooth",
++                                          "com.ukui.bluetooth",
++                                          "adapterAddSignal",
++                                          this,
++                                          SLOT(adapterAdded(QString)));
++
++    QDBusConnection::sessionBus().connect("com.ukui.bluetooth",
++                                          "/com/ukui/bluetooth",
++                                          "com.ukui.bluetooth",
++                                          "adapterRemoveSignal",
++                                          this,
++                                          SLOT(adapterRemoved(QString)));
++#endif
++}
++
++void ScreenlockUi::setShowOnLogin(bool b)
++{
++    m_showPicSwitchButton->blockSignals(true);
++    m_showPicSwitchButton->setChecked(b);
++    m_showPicSwitchButton->blockSignals(false);
++}
++
++void ScreenlockUi::setPicture(const QString &data)
++{
++    currentFile = data;
++    QImageReader reader(data);
++    reader.setDecideFormatFromContent(true);
++    m_previewLabel->setPixmap(QPixmap::fromImage(reader.read()).scaled(m_previewLabel->size()));
++    resetClickedPic();
++}
++
++void ScreenlockUi::setPictures(const QStringList &picturePathList, const QStringList &sourcePathList)
++{
++    if (picturePathList.size() != sourcePathList.size()) {
++        qWarning()<<"picturePathList.size():"<<picturePathList.size()<<" != sourcePathList.size():"<<sourcePathList.size();
++        return;
++    }
++
++    for (int i = 0; i < picturePathList.size(); ++i) {
++        QPixmap pixmap;
++        pixmap.load(picturePathList.at(i));
++        bool clicked = false;
++        if (sourcePathList.at(i) == currentFile) {
++            clicked = true;
++        }
++        createPictureUnit(pixmap, sourcePathList.at(i), clicked);
++    }
++}
++
++void ScreenlockUi::createPictureUnit(const QPixmap &pixmap, const QString &filename, const bool &clicked)
++{
++    PictureUnit *picUnit = new PictureUnit(this);
++    picUnit->setPixmap(pixmap);
++    picUnit->setFilenameText(filename);
++    if (clicked) {
++        prePictureUnit = picUnit;
++        picUnit->changeClickedFlag(true);
++        setPicture(filename);
++    }
++    connect(picUnit, &PictureUnit::clicked, [=](QString file){
++        if (prePictureUnit) {
++            prePictureUnit->changeClickedFlag(false);
++        }
++        prePictureUnit = picUnit;
++        setPicture(file);
++        Q_EMIT pictureChanged(file);
++    });
++    m_pictureLayout->addWidget(picUnit);
++}
++
++void ScreenlockUi::resetClickedPic() {
++    if (prePictureUnit != nullptr) {
++        prePictureUnit->changeClickedFlag(false);
++        prePictureUnit = nullptr;
++    }
++    for (int i = m_pictureLayout->count() - 1; i >= 0; --i) {
++        QLayoutItem *it      = m_pictureLayout->itemAt(i);
++        PictureUnit *picUnit = static_cast<PictureUnit*>(it->widget());
++        if (currentFile == picUnit->filenameText()) {
++            picUnit->changeClickedFlag(true);
++            prePictureUnit = picUnit;
++        }
++    }
++}
++
++QMap<QString, QString> ScreenlockUi::getBtPairedDevices() {
++    QMap<QString, QString> pairedList;
++    QDBusMessage message = QDBusMessage::createMethodCall("com.ukui.bluetooth",
++                                                      "/com/ukui/bluetooth",
++                                                      "com.ukui.bluetooth",
++                                                      "getPairedPhoneAddr");
++
++    QDBusMessage response = QDBusConnection::sessionBus().call(message);
++    if (response.type() == QDBusMessage::ReplyMessage)
++    {
++        QStringList ret = response.arguments().takeFirst().toStringList();
++        if (ret.isEmpty())
++            return pairedList;
++        for (int i = 0; i < ret.size(); i++) {
++            if (pairedList.contains(ret.at(i)))
++                continue;
++            QDBusMessage _message = QDBusMessage::createMethodCall("com.ukui.bluetooth",
++                                                                   "/com/ukui/bluetooth",
++                                                                   "com.ukui.bluetooth",
++                                                                   "getDevName");
++            _message << ret.at(i);
++            QDBusMessage _response = QDBusConnection::sessionBus().call(_message);
++            if (_response.type() == QDBusMessage::ReplyMessage)
++            {
++                QString devName = _response.arguments().takeFirst().toString();
++                if (devName == "")
++                    continue;
++                pairedList.insert(ret.at(i), devName);
++            }
++        }
++    }
++    return pairedList;
++}
++
++bool ScreenlockUi::hasBluetoothAdapter() {
++    QDBusMessage message = QDBusMessage::createMethodCall("com.ukui.bluetooth",
++                                                      "/com/ukui/bluetooth",
++                                                      "com.ukui.bluetooth", \
++                                                      "getAdapterDevAddressList");
++
++    QDBusMessage response = QDBusConnection::sessionBus().call(message);
++    if (response.type() == QDBusMessage::ReplyMessage) {
++        QStringList ret = response.arguments().takeFirst().toStringList();
++        return !ret.isEmpty();
++    } else
++        return false;
++}
++
++bool ScreenlockUi::isBluetoothPowered() {
++    QDBusMessage message = QDBusMessage::createMethodCall("com.ukui.bluetooth",
++                                                      "/com/ukui/bluetooth",
++                                                      "com.ukui.bluetooth",
++                                                      "getDefaultAdapterPower");
++
++    QDBusMessage response = QDBusConnection::sessionBus().call(message);
++    if (response.type() == QDBusMessage::ReplyMessage) {
++        return response.arguments().takeFirst().toBool();
++    } else
++        return false;
++}
++
++void ScreenlockUi::addPairedDev(QString dev, bool paired) {
++    int index = m_bluetoothComboBox->findData(dev);
++    if (paired && index >= 0)
++        return;
++
++    if (!paired && index >= 0) {
++        m_bluetoothComboBox->removeItem(m_bluetoothComboBox->findData(dev));
++        if (m_bluetoothComboBox->count() == 1) {
++            m_noBtWidget->setVisible(false);
++            m_bluetoothWidget->setVisible(false);
++            m_setBtWidget->setVisible(true);
++        }
++        if (lockdev == dev)
++            lockdev.clear();
++        return;
++    }
++
++    QDBusMessage _message = QDBusMessage::createMethodCall("com.ukui.bluetooth",
++                                                           "/com/ukui/bluetooth",
++                                                           "com.ukui.bluetooth",
++                                                           "getDevName");
++    _message << dev;
++    QDBusMessage _response = QDBusConnection::sessionBus().call(_message);
++    if (_response.type() == QDBusMessage::ReplyMessage)
++    {
++        QString devName = _response.arguments().takeFirst().toString();
++        if (devName != "") {
++            m_bluetoothComboBox->addItem(devName, dev);
++            m_setBtWidget->setVisible(false);
++            m_bluetoothWidget->setVisible(true);
++        }
++    }
++}
++
++void ScreenlockUi::powerChanged(bool powered) {
++    if (!m_btLeaveLockSwitchButton->isChecked())
++        return;
++    if (!hasBluetoothAdapter()) {
++        m_noBtWidget->setVisible(true);
++        m_setBtWidget->setVisible(false);
++        m_bluetoothWidget->setVisible(false);
++        return;
++    }
++
++    m_noBtWidget->setVisible(false);
++    m_setBtWidget->setVisible(!powered);
++    m_bluetoothWidget->setVisible(powered);
++    setLeaveLock(false);
++}
++
++void ScreenlockUi::setLeaveLock(bool on) {
++    if (lockdev.isEmpty())
++        return;
++    QDBusMessage message = QDBusMessage::createMethodCall("com.ukui.bluetooth",
++                                                      "/com/ukui/bluetooth",
++                                                      "com.ukui.bluetooth",
++                                                      "setLeaveLock");
++    message << lockdev << on;
++    QDBusConnection::sessionBus().call(message);
++}
++
++bool ScreenlockUi::getLeavLockOn() {
++    QDBusMessage message = QDBusMessage::createMethodCall("com.ukui.bluetooth",
++                                                      "/com/ukui/bluetooth",
++                                                      "com.ukui.bluetooth",
++                                                      "getLeaveLock");
++    QDBusMessage response = QDBusConnection::sessionBus().call(message);
++    if (response.type() == QDBusMessage::ReplyMessage)
++        return response.arguments().takeFirst().toBool();
++    else
++        return false;
++}
++
++QString ScreenlockUi::getLeaveLockDev() {
++    QDBusMessage message = QDBusMessage::createMethodCall("com.ukui.bluetooth",
++                                                      "/com/ukui/bluetooth",
++                                                      "com.ukui.bluetooth",
++                                                      "getLeaveLockDev");
++    QDBusMessage response = QDBusConnection::sessionBus().call(message);
++    if (response.type() == QDBusMessage::ReplyMessage)
++        return response.arguments().takeFirst().toString();
++    else
++        return QString("");
++}
++
++void ScreenlockUi::defaultAdapterChanged(QString address) {
++    Q_UNUSED(address);
++    if (!m_btLeaveLockSwitchButton->isChecked())
++        return;
++    bool ispowered = isBluetoothPowered();
++    bool leaveLockOn = getLeavLockOn();
++    bool hasAdapter = hasBluetoothAdapter();
++    QMap<QString, QString> btDevices = getBtPairedDevices();
++
++    lockdev.clear();
++    m_bluetoothComboBox->clear();
++
++    if (leaveLockOn && !m_btLeaveLockSwitchButton->isChecked()) {
++        m_btLeaveLockSwitchButton->click();
++    }
++
++    canLeaveLock = !btDevices.isEmpty();
++    m_bluetoothComboBox->addItem(tr("Please select device"));
++    for (auto dev : btDevices.keys())
++        m_bluetoothComboBox->addItem(btDevices.value(dev), dev);
++
++    if (!hasAdapter && leaveLockOn) {
++        m_noBtWidget->setVisible(!hasAdapter);
++        return;
++    }
++    m_bluetoothWidget->setVisible(leaveLockOn && canLeaveLock && ispowered);
++    m_setBtWidget->setVisible((!canLeaveLock || !ispowered) && leaveLockOn);
++}
++
++void ScreenlockUi::adapterAdded(QString address) {
++    Q_UNUSED(address);
++    if (!m_btLeaveLockSwitchButton->isChecked())
++        return;
++    QDBusMessage message = QDBusMessage::createMethodCall("com.ukui.bluetooth",
++                                                      "/com/ukui/bluetooth",
++                                                      "com.ukui.bluetooth", \
++                                                      "getAdapterDevAddressList");
++
++    QDBusMessage response = QDBusConnection::sessionBus().call(message);
++    if (response.type() == QDBusMessage::ReplyMessage) {
++        QStringList ret = response.arguments().takeFirst().toStringList();
++        if (ret.size() > 1)
++            return;
++        else {
++            bool ispowered = isBluetoothPowered();
++            QMap<QString, QString> btDevices = getBtPairedDevices();
++
++            lockdev.clear();
++            m_bluetoothComboBox->clear();
++
++            canLeaveLock = !btDevices.isEmpty();
++            m_bluetoothComboBox->addItem(tr("Please select device"));
++            for (auto dev : btDevices.keys()) {
++                m_bluetoothComboBox->addItem(btDevices.value(dev), dev);
++            }
++            m_noBtWidget->setVisible(false);
++            m_setBtWidget->setVisible(false);
++            m_bluetoothWidget->setVisible(canLeaveLock && ispowered);
++            m_setBtWidget->setVisible(!canLeaveLock || !ispowered);
++        }
++    }
++}
++
++void ScreenlockUi::adapterRemoved(QString address) {
++    Q_UNUSED(address);
++    if (!m_btLeaveLockSwitchButton->isChecked())
++        return;
++    QDBusMessage message = QDBusMessage::createMethodCall("com.ukui.bluetooth",
++                                                      "/com/ukui/bluetooth",
++                                                      "com.ukui.bluetooth", \
++                                                      "getAdapterDevAddressList");
++
++    QDBusMessage response = QDBusConnection::sessionBus().call(message);
++    if (response.type() == QDBusMessage::ReplyMessage) {
++        QStringList ret = response.arguments().takeFirst().toStringList();
++        if (ret.size() < 1){
++            lockdev.clear();
++            m_bluetoothComboBox->clear();
++            m_noBtWidget->setVisible(true);
++            m_bluetoothWidget->setVisible(false);
++            m_setBtWidget->setVisible(false);
++        }
++    }
++}
+diff --git a/src/ukccplugins/screenlock/screenlockui.h b/src/ukccplugins/screenlock/screenlockui.h
+new file mode 100644
+index 0000000..349bd0f
+--- /dev/null
++++ b/src/ukccplugins/screenlock/screenlockui.h
+@@ -0,0 +1,123 @@
++/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
++ *
++ * Copyright (C) 2019 KylinSoft  Co., Ltd.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
++ *
++ */
++#ifndef SCREENLOCKUI_H
++#define SCREENLOCKUI_H
++
++#include <widgets/settinggroup.h>
++#include <widgets/flowlayout.h>
++#include <widgets/switchwidget.h>
++#include <widgets/comboxwidget.h>
++#include <widgets/pushbuttonwidget.h>
++#include <QProcess>
++#include "pictureunit.h"
++#include <QHBoxLayout>
++#include <QWidget>
++#include <kysdk/applications/klabel.h>
++#include <kysdk/applications/kbackgroundgroup.h>
++
++using namespace kdk;
++
++class ScreenlockUi : public QWidget
++{
++    Q_OBJECT
++public:
++    ScreenlockUi();
++    ~ScreenlockUi();
++    void setShowOnLogin(bool b);
++    void setPicture(const QString &data);
++    void setPictures(const QStringList &picturePathList, const QStringList &sourcePathList);
++    void createPictureUnit(const QPixmap &pixmap, const QString &filename, const bool &clicked);
++    void resetClickedPic();
++
++private:
++    void initUi();
++    void initScreenLock();
++    void initSignals();
++    void initLeavLockStatus();
++    bool hasBluetoothAdapter();
++    bool isBluetoothPowered();
++    bool getLeavLockOn();
++    QString getLeaveLockDev();
++    QMap<QString, QString> getBtPairedDevices();
++
++private slots:
++    void addPairedDev(QString dev, bool paired);
++    void powerChanged(bool powered);
++    void setLeaveLock(bool on);
++    void defaultAdapterChanged(QString address);
++    void adapterAdded(QString address);
++    void adapterRemoved(QString address);
++    void setBtPushButtonClickSlot();
++    void btLeaveLockButtonClickSlot(bool clicked);
++    void bluetoothWidgetIdxChangeSlot(int index);
++
++private:
++    QVBoxLayout *m_uiLayout         = nullptr;
++    QVBoxLayout *m_screenlockLayout = nullptr;
++    QVBoxLayout *m_relateLayout     = nullptr;
++
++private:
++    KLabel       *m_wallpaperTitleLabel = nullptr;
++    UkccFrame    *m_previewFrame        = nullptr;
++    QHBoxLayout  *m_previewLayout       = nullptr;
++    QLabel       *m_previewLabel        = nullptr;
++    SettingGroup *m_centerGroup         = nullptr;
++    UkccFrame    *m_noBtWidget          = nullptr;
++    UkccFrame    *m_picBtnFrame         = nullptr;
++    QVBoxLayout  *m_picBtnLayout        = nullptr;
++    UkccFrame    *m_pictureFrame        = nullptr;
++    FlowLayout   *m_pictureLayout       = nullptr;
++    UkccFrame    *m_bottomFrame         = nullptr;
++    QHBoxLayout  *m_bottomLayout        = nullptr;
++    QPushButton  *m_localBtn            = nullptr;
++    QPushButton  *m_onlineBtn           = nullptr;
++    QPushButton  *m_resetBtn            = nullptr;
++    KSwitchButton* m_showPicSwitchButton = nullptr;
++    KSwitchButton* m_btLeaveLockSwitchButton = nullptr;
++    KPushButton* m_setBtPushButton = nullptr;
++    QWidget* m_setBtWidget = nullptr;
++    UkccFrame* m_relateFrame = nullptr;
++    QWidget* m_bluetoothWidget = nullptr;
++    QComboBox* m_bluetoothComboBox = nullptr;
++    KBackgroundGroup* m_contentBackgroundGroup = nullptr;
++private:
++    KLabel       *relateTitleLabel  = nullptr;
++    SettingGroup     *relatedGroup      = nullptr;
++    PushButtonWidget *monitorWidget     = nullptr;
++    PushButtonWidget *screensaverWidget = nullptr;
++
++private:
++    PictureUnit *prePictureUnit = nullptr;
++    bool        canLeaveLock    = false;
++    QString     currentFile;
++    QString     lockdev;
++
++Q_SIGNALS:
++    void showOnLoginChanged(const bool &b);
++    void pictureChanged(const QString &picture);
++    void localButtonClicked();
++    void onlineButtonClicked();
++    void resetButtonClicked();
++    void toSetMonitor();
++    void toSetScreensaver();
++};
++
++
++#endif // SCREENLOCKUI_H
+diff --git a/src/ukccplugins/screensaver/CMakeLists.txt b/src/ukccplugins/screensaver/CMakeLists.txt
+new file mode 100644
+index 0000000..35fc567
+--- /dev/null
++++ b/src/ukccplugins/screensaver/CMakeLists.txt
+@@ -0,0 +1,51 @@
++pkg_check_modules(QGS REQUIRED gsettings-qt)
++pkg_check_modules(GIO2.0 REQUIRED gio-2.0)
++pkg_check_modules(GIOUNIX2.0 REQUIRED gio-unix-2.0)
++pkg_check_modules(KYSDKQTWIDGETS REQUIRED kysdk-qtwidgets)
++pkg_check_modules(KYSDKDIAGNOSTICS REQUIRED kysdk-diagnostics)
++
++include_directories(${PROJECT_BINARY_DIR})
++include_directories(${PROJECT_SOURCE_DIR}/Common)
++
++include_directories(
++        ${QGS_INCLUDE_DIRS}
++        ${GIO2.0_INCLUDE_DIRS}
++        ${GIOUNIX2.0_INCLUDE_DIRS}
++        ${KYSDKQTWIDGETS_INCLUDE_DIRS}
++        ${KYSDKDIAGNOSTICS_INCLUDE_DIRS}
++        /usr/include/ukcc
++        )
++
++set(EXTRA_LIBS
++        ${EXTRA_LIBS}
++        ${QGS_LIBRARIES}
++        ${GIO2.0_LIBRARIES}
++        ${GIOUNIX2.0_LIBRARIES}
++        ${KYSDKQTWIDGETS_LIBRARIES}
++        ${KYSDKDIAGNOSTICS_LIBRARIES}
++        -lukcc
++        )
++
++qt5_add_resources(screensaver_Plugin_SRC
++        )
++
++qt5_wrap_cpp(screensaver_Plugin_SRC
++    previewwidget.h
++    screensaver.h
++    screensaverpluginso.h
++    screensaverui.h
++    )
++
++set(screensaver_Plugin_SRC
++    ${screensaver_Plugin_SRC}
++    previewwidget.cpp
++    screensaver.cpp
++    screensaverui.cpp
++    )
++
++add_library(screensaver SHARED ${screensaver_Plugin_SRC})
++target_link_libraries(screensaver Qt5::Widgets Qt5::DBus ${EXTRA_LIBS})
++
++install(TARGETS
++        screensaver
++        DESTINATION lib/${CMAKE_LIBRARY_ARCHITECTURE}/ukui-control-center)
+diff --git a/src/ukccplugins/screensaver/previewwidget.cpp b/src/ukccplugins/screensaver/previewwidget.cpp
+new file mode 100644
+index 0000000..e865fdf
+--- /dev/null
++++ b/src/ukccplugins/screensaver/previewwidget.cpp
+@@ -0,0 +1,35 @@
++#include "previewwidget.h"
++#include <QProcess>
++
++PreviewWidget::PreviewWidget(QWidget *parent):QWidget(parent)
++{
++
++}
++
++PreviewWidget::~PreviewWidget()
++{
++
++}
++
++void PreviewWidget::paintEvent(QPaintEvent *event)
++{
++    Q_UNUSED(event);
++
++    QPainter p(this);
++    p.setPen(Qt::NoPen);
++    p.setBrush(Qt::black);
++    p.drawRect(rect());
++}
++
++void PreviewWidget::mousePressEvent(QMouseEvent *e)
++{
++    if(e->button() == Qt::LeftButton) {
++        previewScreensaver();
++    }
++}
++
++void PreviewWidget::previewScreensaver()
++{
++    static QProcess *viewProcess = new QProcess();
++    viewProcess->start("ukui-screensaver-command --screensaver");
++}
+diff --git a/src/ukccplugins/screensaver/previewwidget.h b/src/ukccplugins/screensaver/previewwidget.h
+new file mode 100644
+index 0000000..96fbf3f
+--- /dev/null
++++ b/src/ukccplugins/screensaver/previewwidget.h
+@@ -0,0 +1,22 @@
++#ifndef PREVIEWWIDGET_H
++#define PREVIEWWIDGET_H
++#include <QWidget>
++#include <QPainter>
++#include <QMouseEvent>
++
++class PreviewWidget : public QWidget
++{
++    Q_OBJECT
++public:
++    PreviewWidget(QWidget *parent = nullptr);
++    ~PreviewWidget();
++    void previewScreensaver();
++
++protected:
++    void paintEvent(QPaintEvent *e);
++
++private:
++    void mousePressEvent(QMouseEvent *e);
++};
++
++#endif // PREVIEWWIDGET_H
+diff --git a/src/ukccplugins/screensaver/screensaver.cpp b/src/ukccplugins/screensaver/screensaver.cpp
+new file mode 100644
+index 0000000..37acf50
+--- /dev/null
++++ b/src/ukccplugins/screensaver/screensaver.cpp
+@@ -0,0 +1,379 @@
++/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
++ *
++ * Copyright (C) 2019 Tianjin KYLIN Information Technology Co., Ltd.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
++ *
++ */
++#include "screensaver.h"
++#include <QDebug>
++#include <QtConcurrent/QtConcurrent>
++#include <QTranslator>
++#include <QLocale>
++#include <QApplication>
++
++#define PREENTRY_TIME "preentryTime"
++#define SCREENSAVER_TYPE "screensaverType"
++#define SHOWTIME_UKUI "showBreakTimeUkui"
++#define SHOWTIME_CUSTOM "showBreakTimeCustom"
++#define SCREENLOCK_ENABLED "screenLockEnabled"
++#define CUSTOM_PATH "customPath"
++#define SWITCH_RANDOW "switchRandom"
++#define CYCLE_TIME "cycleTime"
++#define CUSTOM_TEXT "customText"
++#define CUSTOM_TEXT_CENTERED "customTextCentered"
++
++Screensaver::Screensaver() : mFirstLoad(true)
++{
++    QTranslator *translator = new QTranslator(this);
++    translator->load("/usr/share/ukui-screensaver/ukccplugins/i18n_qm/" + QLocale::system().name());
++    QApplication::installTranslator(translator);
++
++    pluginName = tr("Screensaver");
++    pluginType = PERSONALIZED;
++    QtConcurrent::run([=] { preInitialize(); });
++}
++
++Screensaver::~Screensaver()
++{
++    if (!mFirstLoad) {
++        screensaverUi->deleteLater();
++        screensaverUi = nullptr;
++    }
++}
++
++QString Screensaver::plugini18nName()
++{
++    return pluginName;
++}
++
++int Screensaver::pluginTypes()
++{
++    return pluginType;
++}
++
++void Screensaver::preInitialize()
++{
++    screensaverInterface = new QDBusInterface(
++        "org.ukui.ScreenSaver",
++        "/Screensaver",
++        "org.ukui.ScreenSaver.session.Screensaver",
++        QDBusConnection::sessionBus(),
++        this);
++    if (!screensaverInterface->isValid()) {
++        qCritical() << "org.ukui.ScreenSaver.session.ScreenSaver DBus error:" << screensaverInterface->lastError();
++        return;
++    }
++    QDBusMessage message = screensaverInterface->call("ping"); // 判断dbus路径是否存在
++    if (message.type() == QDBusMessage::ErrorMessage
++        && message.errorMessage().contains("No such object path", Qt::CaseInsensitive)) {
++        qCritical() << screensaverInterface << ":" << message.errorMessage();
++        return;
++    }
++
++    QPluginLoader pluginLoader("/usr/lib/ukui-screensaver/libscreensaver-default.so");
++    pluginLoader.load();
++    QObject *plugin = pluginLoader.instance();
++    screensaverPtr = nullptr;
++    if (plugin) {
++        screensaverPtr = std::unique_ptr<ScreensaverPlugin>(qobject_cast<ScreensaverPlugin *>(plugin));
++    } else {
++        qWarning() << "pluginLoader '/usr/lib/ukui-screensaver/libscreensaver-default.so' failed";
++    }
++}
++
++QWidget *Screensaver::pluginUi()
++{
++    if (mFirstLoad) {
++        mFirstLoad = false;
++        screensaverUi = new ScreensaverUi;
++        initOptions();
++        initContent();
++        connectUiSignals();
++        connectToServer();
++    }
++    return screensaverUi;
++}
++
++const QString Screensaver::name() const
++{
++    return QStringLiteral("Screensaver");
++}
++
++void Screensaver::plugin_leave()
++{
++    return;
++}
++
++bool Screensaver::isShowOnHomePage() const
++{
++    return true;
++}
++
++QIcon Screensaver::icon() const
++{
++    return QIcon::fromTheme("ukui-screensaver-symbolic");
++}
++
++bool Screensaver::isEnable() const
++{
++    return true;
++}
++
++void Screensaver::dataChanged(const QString &key)
++{
++    if (key != toChangeKey) {
++        if (key == PREENTRY_TIME) {
++            initIdleTime();
++        } else if (key == SCREENSAVER_TYPE) {
++            initScreensaver();
++        } else if (key == CUSTOM_PATH) {
++            initCustomSource();
++        } else if (key == SWITCH_RANDOW) {
++            initSwicthMode();
++        } else if (key == CYCLE_TIME) {
++            initSwitchTime();
++        } else if (key == CUSTOM_TEXT) {
++            initCustomText();
++        } else if (key == CUSTOM_TEXT_CENTERED) {
++            initTextPosition();
++        } else if (key == SHOWTIME_UKUI) {
++            initShowBreakTimeUkui();
++        } else if (key == SHOWTIME_CUSTOM) {
++            initShowBreakTimeCustom();
++        } else if (key == SCREENLOCK_ENABLED) {
++            initLockscreen();
++        }
++    }
++    toChangeKey = "";
++}
++
++void Screensaver::initOptions()
++{
++    QStringList textList = {};
++    QList<int> dataList = {};
++    QStringList dataList2 = {};
++
++    textList.clear();
++    textList << tr("5min") << tr("10min") << tr("15min") << tr("30min") << tr("1hour") << tr("Never");
++
++    dataList.clear();
++    dataList << 5 << 10 << 15 << 30 << 60 << -1;
++
++#ifdef OPENKYLIN
++    textList.insert(0, tr("1min"));
++    dataList.insert(0, 1);
++#endif
++    screensaverUi->setIdleTimeOptions(textList, dataList);
++
++    textList.clear();
++    textList << tr("UKUI") << tr("Customize");
++    dataList2.clear();
++    dataList2 << "ukui"
++              << "custom";
++    screensaverUi->setScreensaverOptions(textList, dataList2);
++
++    textList.clear();
++    textList << tr("1min") << tr("5min") << tr("10min") << tr("30min");
++    dataList.clear();
++    dataList << 60 << 300 << 600 << 1800;
++    screensaverUi->setSwitchTimeOptions(textList, dataList);
++}
++
++void Screensaver::initContent()
++{
++    initIdleTime();
++    initScreensaver();
++    initCustomSource();
++    initSwicthMode();
++    initSwitchTime();
++    initCustomText();
++    initTextPosition();
++    initShowBreakTimeUkui();
++    initShowBreakTimeCustom();
++    initLockscreen();
++}
++
++void Screensaver::initPreview()
++{
++    if (screensaverPtr) {
++        qInfo() << "screensaverPtr can be used";
++        QWidget *widget = screensaverPtr->createWidget(false, screensaverUi);
++        widget->show();
++        screensaverUi->updatePreview(widget);
++    } else {
++        qInfo() << "screensaverPtr can not be used";
++    }
++}
++
++void Screensaver::initIdleTime()
++{
++    int time = screensaverInterface->property(PREENTRY_TIME).toInt();
++    screensaverUi->setIdleTime(time);
++}
++
++void Screensaver::initScreensaver()
++{
++    QString type = screensaverInterface->property(SCREENSAVER_TYPE).toString();
++    screensaverUi->setScreensaver(type);
++    initPreview();
++}
++
++void Screensaver::initCustomSource()
++{
++    QString path = screensaverInterface->property(CUSTOM_PATH).toString();
++    screensaverUi->setSourcePath(path);
++}
++
++void Screensaver::initSwicthMode()
++{
++    bool random = screensaverInterface->property(SWITCH_RANDOW).toBool();
++    screensaverUi->setSwitchRandom(random);
++}
++
++void Screensaver::initSwitchTime()
++{
++    int time = screensaverInterface->property(CYCLE_TIME).toInt();
++    screensaverUi->setSwitchTime(time);
++}
++
++void Screensaver::initCustomText()
++{
++    QString text = screensaverInterface->property(CUSTOM_TEXT).toString();
++    screensaverUi->setCustomText(text);
++}
++
++void Screensaver::initTextPosition()
++{
++    bool centered = screensaverInterface->property(CUSTOM_TEXT_CENTERED).toBool();
++    screensaverUi->setTextCentered(centered);
++}
++
++void Screensaver::initShowBreakTimeUkui()
++{
++    bool b = screensaverInterface->property(SHOWTIME_UKUI).toBool();
++    screensaverUi->setShowUkuiTime(b);
++}
++
++void Screensaver::initShowBreakTimeCustom()
++{
++    bool b = screensaverInterface->property(SHOWTIME_CUSTOM).toBool();
++    screensaverUi->setShowCustomTime(b);
++}
++
++void Screensaver::initLockscreen()
++{
++    bool b = screensaverInterface->property(SCREENLOCK_ENABLED).toBool();
++    screensaverUi->setLockscreen(b);
++}
++
++void Screensaver::connectUiSignals()
++{
++    QDBusConnection::sessionBus().connect(
++        "org.ukui.ScreenSaver",
++        "/Screensaver",
++        "org.ukui.ScreenSaver.session.Screensaver",
++        "changed",
++        this,
++        SLOT(dataChanged(QString)));
++    connect(screensaverUi, &ScreensaverUi::idleTimeChanged, this, [=](int time) {
++        toChangeKey = PREENTRY_TIME;
++        screensaverInterface->call("setPreentryTime", time);
++        UkccCommon::buriedSettings(name(), QString("Idle time"), QString("select"), QString::number(time));
++    });
++    connect(screensaverUi, &ScreensaverUi::screensaverChanged, this, [=](QString type) {
++        toChangeKey = SCREENSAVER_TYPE;
++        screensaverInterface->call("setScreensaverType", type);
++        UkccCommon::buriedSettings(name(), QString("Screensaver program"), QString("select"), type);
++    });
++    connect(screensaverUi, &ScreensaverUi::customPathChanged, this, [=](QString path) {
++        toChangeKey = CUSTOM_PATH;
++        screensaverInterface->call("setCustomPath", path);
++        UkccCommon::buriedSettings(name(), QString("Screensaver source Select"), QString("select"), path);
++    });
++    connect(screensaverUi, &ScreensaverUi::switchRandomChanged, this, [=](bool b) {
++        toChangeKey = SWITCH_RANDOW;
++        screensaverInterface->call("setSwitchRandom", b);
++        UkccCommon::buriedSettings(name(), QString("Random switching"), QString("settings"), b ? "Random" : "Ordinal");
++    });
++    connect(screensaverUi, &ScreensaverUi::switchTimeChanged, this, [=](int time) {
++        toChangeKey = CYCLE_TIME;
++        screensaverInterface->call("setCycleTime", time);
++        UkccCommon::buriedSettings(name(), QString("Switching time"), QString("select"), QString::number(time));
++    });
++    connect(screensaverUi, &ScreensaverUi::customTextChanged, this, [=](QString text) {
++        toChangeKey = CUSTOM_TEXT;
++        screensaverInterface->call("setCustomText", text);
++        UkccCommon::buriedSettings(name(), QString("Text(up to 30 characters):"), QString("settings"), text);
++    });
++    connect(screensaverUi, &ScreensaverUi::textCenteredChanged, this, [=](bool b) {
++        toChangeKey = CUSTOM_TEXT_CENTERED;
++        screensaverInterface->call("setCustomTextCentered", b);
++        UkccCommon::buriedSettings(
++            name(), QString("Text position"), QString("settings"), b ? "Centered" : "Randow(Bubble text)");
++    });
++    connect(screensaverUi, &ScreensaverUi::showUkuiTimeChanged, this, [=](bool b) {
++        toChangeKey = SHOWTIME_UKUI;
++        screensaverInterface->call("setShowBreakTimeUkui", b);
++        UkccCommon::buriedSettings(
++            name(), QString("custom Show rest time"), QString("settings"), UkccCommon::boolToString(b));
++    });
++    connect(screensaverUi, &ScreensaverUi::showCustomChanged, this, [=](bool b) {
++        toChangeKey = SHOWTIME_CUSTOM;
++        screensaverInterface->call("setShowBreakTimeCustom", b);
++        UkccCommon::buriedSettings(
++            name(), QString("ukui Show rest time"), QString("settings"), UkccCommon::boolToString(b));
++    });
++    connect(screensaverUi, &ScreensaverUi::lockscreenChanged, this, [=](bool b) {
++        toChangeKey = SCREENLOCK_ENABLED;
++        screensaverInterface->call("setScreenLockEnabled", b);
++        UkccCommon::buriedSettings(
++            name(), QString("Lock screen when screensaver boot"), QString("settings"), UkccCommon::boolToString(b));
++    });
++
++    // 如果在dbus端监听gsetting的改变信号,再发送changed信号,此时再去initPreview可能会异常
++    // 因为界面端程序此时去读取gsetting的值可能还是修改前的值,该问题应该是qgsetting的设计逻辑问题
++    // 因此这里去监听gsetting的改变而不是dbus的changed
++    QGSettings *mScreensaverGsettings = nullptr;
++    if (!mScreensaverGsettings) {
++        const QByteArray id("org.ukui.screensaver");
++        if (QGSettings::isSchemaInstalled(id)) {
++            mScreensaverGsettings = new QGSettings(id, QByteArray(), this);
++        }
++        connect(mScreensaverGsettings, &QGSettings::changed, this, [=](QString key) {
++            if (key == "mode") {
++                initPreview();
++            }
++        });
++    }
++}
++
++void Screensaver::connectToServer()
++{
++    QThread *NetThread = new QThread;
++    MThread *NetWorker = new MThread;
++    NetWorker->moveToThread(NetThread);
++    connect(NetThread, &QThread::started, NetWorker, &MThread::run);
++    connect(NetWorker, &MThread::keychangedsignal, this, &Screensaver::keyChangedSlot);
++    connect(NetThread, &QThread::finished, NetWorker, &MThread::deleteLater);
++    NetThread->start();
++}
++
++void Screensaver::keyChangedSlot(const QString &key)
++{
++    if (key == "ukui-screensaver") {
++        initContent();
++    }
++}
+diff --git a/src/ukccplugins/screensaver/screensaver.h b/src/ukccplugins/screensaver/screensaver.h
+new file mode 100644
+index 0000000..dcf900a
+--- /dev/null
++++ b/src/ukccplugins/screensaver/screensaver.h
+@@ -0,0 +1,94 @@
++/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
++ *
++ * Copyright (C) 2019 Tianjin KYLIN Information Technology Co., Ltd.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
++ *
++ */
++#ifndef SCREENSAVER_H
++#define SCREENSAVER_H
++
++#include <QObject>
++#include <QtPlugin>
++#include <QGSettings>
++#include <QtDBus>
++#include "screensaverpluginso.h"
++#include <interface/interface.h>
++#include "screensaverui.h"
++#include <interface/mthread.h>
++#include <interface/ukcccommon.h>
++using namespace ukcc;
++
++using namespace kdk;
++
++class Screensaver : public QWidget, CommonInterface
++{
++    Q_OBJECT
++    Q_PLUGIN_METADATA(IID "org.ukcc.CommonInterface")
++    Q_INTERFACES(CommonInterface)
++
++public:
++    Screensaver();
++    ~Screensaver();
++
++    QString plugini18nName() Q_DECL_OVERRIDE;
++    int pluginTypes() Q_DECL_OVERRIDE;
++    QWidget * pluginUi() Q_DECL_OVERRIDE;
++    const QString name() const  Q_DECL_OVERRIDE;
++    void plugin_leave()Q_DECL_OVERRIDE;
++    bool isShowOnHomePage() const Q_DECL_OVERRIDE;
++    QIcon icon() const Q_DECL_OVERRIDE;
++    bool isEnable() const Q_DECL_OVERRIDE;
++    virtual QString translationPath() const {
++        return QStringLiteral("/usr/share/ukui-screensaver/ukccplugins/i18n/%1.ts");
++    }
++
++public:
++    void initOptions();
++    void initContent();
++    void initPreview();
++    void initIdleTime();
++    void initScreensaver();
++    void initCustomSource();
++    void initSwicthMode();
++    void initSwitchTime();
++    void initCustomText();
++    void initTextPosition();
++    void initShowBreakTimeUkui();
++    void initShowBreakTimeCustom();
++    void initLockscreen();
++    void connectUiSignals();
++
++private:
++    void preInitialize();
++    void connectToServer();
++
++private Q_SLOTS:
++    void keyChangedSlot(const QString &key);
++    void dataChanged(const QString &key);
++
++private:
++    QString pluginName;
++    bool mFirstLoad;
++    int pluginType;
++    std::unique_ptr<ScreensaverPlugin> screensaverPtr;
++
++private:
++    ScreensaverUi  *screensaverUi        = nullptr;
++    QDBusInterface *screensaverInterface = nullptr;
++    QString toChangeKey;
++};
++
++#endif // SCREENSAVER_H
+diff --git a/src/ukccplugins/screensaver/screensaverpluginso.h b/src/ukccplugins/screensaver/screensaverpluginso.h
+new file mode 100644
+index 0000000..ea22558
+--- /dev/null
++++ b/src/ukccplugins/screensaver/screensaverpluginso.h
+@@ -0,0 +1,27 @@
++#ifndef SCREENSAVERPLUGINSO_H
++#define SCREENSAVERPLUGINSO_H
++
++#include <QWidget>
++
++class ScreensaverPlugin
++{
++public:
++    virtual ~ScreensaverPlugin() {}
++    //插件实例的名称
++    virtual QString name() const = 0;
++
++    //创建UI的实例
++    virtual QWidget* createWidget(bool isScreensaver, QWidget* parent) = 0;
++
++    //获得插件的展示名称
++    virtual QString displayName() const = 0;
++};
++
++//定义了在QT系统中该接口的全局唯一的ID
++//实现该SDK的插件也要定义相同的ID
++//接口的ID中包含了版本信息,通过该ID我们可以区别不同版本的SDK和插件
++//Q_DECLARE_INTERFACE宏将类型和ID关联起来,这样QT就可以验证加载的插件是否可以转换成MyPluginInterface类型
++#define interface_iid "org.ukui.screensaver.screensaver-default1.0.0"
++Q_DECLARE_INTERFACE(ScreensaverPlugin, interface_iid)
++
++#endif // SCREENSAVERPLUGINSO_H
+diff --git a/src/ukccplugins/screensaver/screensaverui.cpp b/src/ukccplugins/screensaver/screensaverui.cpp
+new file mode 100644
+index 0000000..3a3df32
+--- /dev/null
++++ b/src/ukccplugins/screensaver/screensaverui.cpp
+@@ -0,0 +1,505 @@
++#include "screensaverui.h"
++#include <QPluginLoader>
++
++
++ScreensaverUi::ScreensaverUi()
++{
++    setAttribute(Qt::WA_DeleteOnClose);
++    uiLayout = new QVBoxLayout(this);
++    uiLayout->setSpacing(8);
++    uiLayout->setMargin(0);
++    initUi();
++    sendSignals();
++}
++
++ScreensaverUi::~ScreensaverUi()
++{
++
++}
++
++void ScreensaverUi::initUi()
++{
++    initPreview();
++    initSetting();
++    uiLayout->addStretch();
++}
++
++void ScreensaverUi::initPreview()
++{
++    screensaverTitle = new KLabel(this);
++    screensaverTitle->setContentsMargins(16, 0, 0, 0);
++    previewFrame     = new UkccFrame(this);
++    previewLayout    = new QHBoxLayout(previewFrame);
++    previewWidget    = new PreviewWidget(this);
++
++    uiLayout->addWidget(screensaverTitle);
++    uiLayout->addWidget(previewFrame);
++
++    previewLayout->addWidget(previewWidget);
++
++    //~ contents_path /Screensaver/Screensaver
++    screensaverTitle->setText(tr("Screensaver"));
++    previewFrame->setFixedHeight(212);
++    previewWidget->setFixedSize(300, 180);
++    previewLayout->addWidget(previewWidget);
++    previewLayout->addStretch();
++    QHBoxLayout *layout = new QHBoxLayout(previewWidget);
++    layout->setMargin(0);
++}
++
++void ScreensaverUi::initSetting()
++{
++    screensaverGroup = new SettingGroup(this);
++    //~ contents_path /Screensaver/Idle time
++    idleTimeWidget   = new ComboxWidget(tr("Idle time"), screensaverGroup);
++    //~ contents_path /Screensaver/Screensaver program
++    programWidget    = new ComboxWidget(tr("Screensaver program"), screensaverGroup);
++    customizeGroup   = new SettingGroup(screensaverGroup);
++
++    uiLayout->addWidget(screensaverGroup);
++
++    screensaverGroup->addWidget(idleTimeWidget);
++    screensaverGroup->addWidget(programWidget);
++    screensaverGroup->addWidget(customizeGroup);
++
++    initSourceFrame();
++    initSwitchModeFrame();
++    initSwitchTimeFrame();
++    initCustomTextFrame();
++    initTextPositionFrame();
++    initBreakTimeFrame();
++    initScreenlockFrame();
++}
++
++void ScreensaverUi::initSourceFrame()
++{
++    UkccFrame   *screensaverSourceFrame = new UkccFrame(customizeGroup, UkccFrame::BorderRadiusStyle::Around, true);
++    QHBoxLayout *sourceLayout           = new QHBoxLayout(screensaverSourceFrame);
++    KLabel    *sourceLabel            = new KLabel();
++
++    sourcePathLine = new QLineEdit();
++    sourceButton   = new QPushButton();
++
++    sourceLayout->setContentsMargins(16, 0, 16, 0);
++    sourceLayout->addWidget(sourceLabel);
++    sourceLayout->addWidget(sourcePathLine);
++    sourceLayout->addWidget(sourceButton);
++    //~ contents_path /Screensaver/Screensaver source
++    sourceLabel->setText(tr("Screensaver source"));
++    sourceLabel->setFixedWidth(220);
++    sourcePathLine->setMinimumWidth(252);
++    sourcePathLine->setReadOnly(true);
++    sourceButton->adjustSize();
++    sourceButton->setText(tr("Select"));
++    sourceButton->raise();
++
++    customizeGroup->addWidget(screensaverSourceFrame);
++}
++
++void ScreensaverUi::initSwitchModeFrame()
++{
++    UkccFrame    *pictureSwitchFrame = new UkccFrame(customizeGroup, UkccFrame::BorderRadiusStyle::Around, true);
++    QHBoxLayout  *randomLayout       = new QHBoxLayout(pictureSwitchFrame);
++    KLabel     *randomLabel        = new KLabel();
++    QRadioButton *radioOrder         = new QRadioButton();
++    QRadioButton *radioRand          = new QRadioButton();
++
++    switchModeGroup  = new QButtonGroup();
++
++    switchModeGroup->addButton(radioOrder, 0);
++    switchModeGroup->addButton(radioRand, 1);
++
++    radioOrder->setFixedWidth(220);
++    radioRand->adjustSize();
++    radioOrder->setText(tr("Ordinal"));
++    radioRand->setText(tr("Random"));
++
++    randomLayout->setContentsMargins(16, 0, 16, 0);
++    randomLayout->addWidget(randomLabel);
++    randomLayout->addWidget(radioOrder);
++    randomLayout->addWidget(radioRand);
++    //~ contents_path /Screensaver/Random switching
++    randomLabel->setText(tr("Random switching"));
++    randomLabel->setFixedWidth(220);
++    randomLayout->addStretch();
++
++    customizeGroup->addWidget(pictureSwitchFrame);
++}
++
++void ScreensaverUi::initSwitchTimeFrame()
++{
++    UkccFrame   *timeSetFrame  = new UkccFrame(customizeGroup, UkccFrame::BorderRadiusStyle::Around, true);
++    QHBoxLayout *timeSetLayout = new QHBoxLayout();
++    KLabel    *timeSetLabel  = new KLabel();
++
++    switchTimeComboBox = new QComboBox();
++
++    timeSetFrame->setLayout(timeSetLayout);
++    timeSetLayout->setContentsMargins(16, 0, 16, 0);
++    timeSetLayout->addWidget(timeSetLabel);
++    timeSetLayout->addWidget(switchTimeComboBox);
++    //~ contents_path /Screensaver/Switching time
++    timeSetLabel->setText(tr("Switching time"));
++    timeSetLabel->setFixedWidth(220);
++    switchTimeComboBox->setMinimumWidth(340);
++
++    customizeGroup->addWidget(timeSetFrame);
++}
++
++void ScreensaverUi::initCustomTextFrame()
++{
++    UkccFrame   *showTextFrame  = new UkccFrame(customizeGroup, UkccFrame::BorderRadiusStyle::Around, true);
++    QHBoxLayout *showTextLayout = new QHBoxLayout();
++    KLabel    *showLabel      = new KLabel();
++
++    textLineEdit = new QLineEdit(); //用户输入文字
++    showTextFrame->setLayout(showTextLayout);
++    showTextLayout->setContentsMargins(16, 6, 15, 8);
++    showTextLayout->addWidget(showLabel);
++    showTextLayout->addWidget(textLineEdit);
++    //~ contents_path /Screensaver/Text(up to 30 characters):
++    showLabel->setText(tr("Text(up to 30 characters):"));
++    showLabel->setFixedWidth(220);
++    textLineEdit->setMaxLength(30);
++
++    customizeGroup->addWidget(showTextFrame);
++}
++
++void ScreensaverUi::initTextPositionFrame()
++{
++    UkccFrame    *showTextSetFrame = new UkccFrame(customizeGroup, UkccFrame::BorderRadiusStyle::Around, true);
++    QHBoxLayout  *textSetLayout    = new QHBoxLayout(showTextSetFrame);
++    KLabel     *textSetLabel     = new KLabel();
++    QRadioButton *radioRandom      = new QRadioButton(this);
++    QRadioButton *radioCenter      = new QRadioButton(this);
++
++    textPositionGroup = new QButtonGroup();
++    textPositionGroup->addButton(radioRandom, 0);
++    textPositionGroup->addButton(radioCenter, 1);
++
++    showTextSetFrame->setFixedHeight(60);
++    textSetLayout->addWidget(textSetLabel);
++    textSetLayout->setContentsMargins(16,0,16,0);
++    //~ contents_path /Screensaver/Text position
++    textSetLabel->setText(tr("Text position"));
++    textSetLabel->setFixedWidth(220);
++    radioRandom->setFixedWidth(220);
++    radioCenter->adjustSize();
++
++    textSetLayout->addWidget(radioRandom);
++    textSetLayout->addWidget(radioCenter);
++    textSetLayout->addStretch();
++    radioCenter->setText(tr("Centered"));
++    radioRandom->setText(tr("Randow(Bubble text)"));
++
++    customizeGroup->addWidget(showTextSetFrame);
++}
++
++void ScreensaverUi::initBreakTimeFrame()
++{
++    UkccFrame   *showTimeFrame  = new UkccFrame(screensaverGroup, UkccFrame::BorderRadiusStyle::Around, true);
++    QHBoxLayout *showTimeLayout = new QHBoxLayout(showTimeFrame);
++    KLabel    *showTimeLabel  = new KLabel();
++
++    showTimeLayout->setContentsMargins(16,0,16,0);
++    showTimeLayout->addWidget(showTimeLabel);
++    //添加休息时间显示按钮
++    showCustomTimeBtn = new KSwitchButton(showTimeFrame);
++    showUkuiTimeBtn   = new KSwitchButton(showTimeFrame);
++    showTimeLayout->addStretch();
++    showTimeLayout->addWidget(showCustomTimeBtn);
++    showTimeLayout->addWidget(showUkuiTimeBtn);
++    showTimeLabel->setFixedWidth(220);
++
++    //~ contents_path /Screensaver/Show rest time
++    showTimeLabel->setText(tr("Show rest time"));
++    screensaverGroup->addWidget(showTimeFrame);
++}
++
++void ScreensaverUi::initScreenlockFrame()
++{
++    UkccFrame   *lockFrame  = new UkccFrame(screensaverGroup, UkccFrame::BorderRadiusStyle::Around, true);;
++    QHBoxLayout *lockLayout = new QHBoxLayout(lockFrame);
++
++    //~ contents_path /Screensaver/Lock screen when screensaver boot
++    KLabel    *lockLabel  = new KLabel();
++    lockLabel->setText(tr("Lock screen when screensaver boot"));
++    lockLabel->setFixedWidth(400);
++
++    lockFrame->setFixedHeight(60);
++    lockLayout->setContentsMargins(16,0,16,0);
++    lockLayout->addWidget(lockLabel);
++
++    lockButton = new KSwitchButton(lockFrame);
++    lockLayout->addStretch();
++    lockLayout->addWidget(lockButton);
++
++    screensaverGroup->addWidget(lockFrame);
++}
++
++void ScreensaverUi::setIdleTimeOptions(const QStringList &textList, const QList<int> &dataList)
++{
++    if (textList.size() == dataList.size()) {
++        idleTimeWidget->comboBox()->clear();
++        for (int i = 0; i < textList.size(); ++i) {
++            idleTimeWidget->comboBox()->addItem(textList.at(i), dataList.at(i));
++        }
++    }
++}
++
++void ScreensaverUi::setScreensaverOptions(const QStringList &textList, const QStringList &dataList)
++{
++    if (textList.size() == dataList.size()) {
++        programWidget->comboBox()->clear();
++        for (int i = 0; i < textList.size(); ++i) {
++            programWidget->comboBox()->addItem(textList.at(i), dataList.at(i));
++        }
++    }
++}
++
++void ScreensaverUi::setSwitchTimeOptions(const QStringList &textList, const QList<int> &dataList)
++{
++    if (textList.size() == dataList.size()) {
++        switchTimeComboBox->clear();
++        for (int i = 0; i < textList.size(); ++i) {
++            switchTimeComboBox->addItem(textList.at(i), dataList.at(i));
++        }
++    }
++}
++
++void ScreensaverUi::setIdleTime(int time)
++{
++    for (int i = 0; i < idleTimeWidget->comboBox()->count(); ++i) {
++        if (time == idleTimeWidget->comboBox()->itemData(i)) {
++            idleTimeWidget->comboBox()->blockSignals(true);
++            idleTimeWidget->comboBox()->setCurrentIndex(i);
++            idleTimeWidget->comboBox()->blockSignals(false);
++        }
++    }
++}
++
++void ScreensaverUi::setScreensaver(QString type)
++{
++    for (int i = 0; i < programWidget->comboBox()->count(); ++i) {
++        if (type == programWidget->comboBox()->itemData(i)) {
++            programWidget->comboBox()->blockSignals(true);
++            programWidget->comboBox()->setCurrentIndex(i);
++            programWidget->comboBox()->blockSignals(false);
++        }
++    }
++
++    if (type == "ukui") {
++        customizeGroup->setVisible(false);
++        showUkuiTimeBtn->setVisible(true);
++        showCustomTimeBtn->setVisible(false);
++    } else if (type == "custom") {
++        customizeGroup->setVisible(true);
++        showUkuiTimeBtn->setVisible(false);
++        showCustomTimeBtn->setVisible(true);
++    }
++}
++
++void ScreensaverUi::updatePreview(QWidget *w)
++{
++    for (QObject *o : previewWidget->children()) {
++        if (o->objectName() == "screensaverWidget") {
++            delete o;
++            o = nullptr;
++        }
++    }
++    w->setObjectName("screensaverWidget");
++    previewWidget->layout()->addWidget(w);
++    previewWidget->update();
++}
++
++void ScreensaverUi::setSourcePath(const QString &text)
++{
++    if (sourcePathLine == nullptr) {
++        return;
++    }
++
++    QFontMetrics fontMetrics(sourcePathLine->font());
++    int fontSize = fontMetrics.width(text);
++    if (fontSize > sourcePathLine->width()) {
++       sourcePathLine->setText(fontMetrics.elidedText(text, Qt::ElideRight, sourcePathLine->width()));
++       sourcePathLine->setToolTip(text);
++    } else {
++       sourcePathLine->setText(text);
++       sourcePathLine->setToolTip("");
++    }
++}
++
++void ScreensaverUi::setSwitchRandom(const bool &b)
++{
++    switchModeGroup->blockSignals(true);
++    if (b) {
++        switchModeGroup->button(1)->setChecked(true);
++    } else {
++        switchModeGroup->button(0)->setChecked(true);
++    }
++    switchModeGroup->blockSignals(false);
++}
++
++void ScreensaverUi::setSwitchTime(const int &time)
++{
++    for (int i = 0; i < switchTimeComboBox->count(); ++i) {
++        if (time == switchTimeComboBox->itemData(i)) {
++            switchTimeComboBox->blockSignals(true);
++            switchTimeComboBox->setCurrentIndex(i);
++            switchTimeComboBox->blockSignals(false);
++        }
++    }
++}
++
++void ScreensaverUi::setCustomText(const QString &text)
++{
++    textLineEdit->blockSignals(true);
++    textLineEdit->setText(text);
++    textLineEdit->blockSignals(false);
++}
++
++void ScreensaverUi::setTextCentered(const bool &b)
++{
++    textPositionGroup->blockSignals(true);
++    if (b) {
++        textPositionGroup->button(1)->setChecked(true);
++    } else {
++        textPositionGroup->button(0)->setChecked(true);
++    }
++    textPositionGroup->blockSignals(false);
++}
++
++void ScreensaverUi::setShowUkuiTime(const bool &b)
++{
++    showUkuiTimeBtn->blockSignals(true);
++    showUkuiTimeBtn->setChecked(b);
++    showUkuiTimeBtn->blockSignals(false);
++}
++
++void ScreensaverUi::setShowCustomTime(const bool &b)
++{
++    showCustomTimeBtn->blockSignals(true);
++    showCustomTimeBtn->setChecked(b);
++    showCustomTimeBtn->blockSignals(false);
++}
++
++void ScreensaverUi::setLockscreen(const bool &b)
++{
++    lockButton->blockSignals(true);
++    lockButton->setChecked(b);
++    lockButton->blockSignals(false);
++}
++
++void ScreensaverUi::sendSignals()
++{
++    connect(idleTimeWidget->comboBox(), QOverload<int>::of(&QComboBox::currentIndexChanged), this, [=](int index) {
++        Q_UNUSED(index)
++        Q_EMIT idleTimeChanged(idleTimeWidget->comboBox()->currentData().toInt());
++    });
++    connect(programWidget->comboBox(), QOverload<int>::of(&QComboBox::currentIndexChanged), this, [=](int index) {
++        Q_UNUSED(index)
++        QString type = programWidget->comboBox()->currentData().toString();
++        Q_EMIT screensaverChanged(type);
++        if (type == "ukui") {
++            customizeGroup->setVisible(false);
++            showUkuiTimeBtn->setVisible(true);
++            showCustomTimeBtn->setVisible(false);
++        } else if (type == "custom") {
++            customizeGroup->setVisible(true);
++            showUkuiTimeBtn->setVisible(false);
++            showCustomTimeBtn->setVisible(true);
++        }
++    });
++    connect(sourceButton, &QPushButton::clicked, this, [=]() {
++        QString filter;
++        filter = tr("Wallpaper files(*.jpg *.jpeg *.bmp *.dib *.png *.jfif *.jpe *.gif *.tif *.tiff *.wdp *.svg)");
++        QFileDialog fd(this);
++
++        QList<QUrl> usb_list = fd.sidebarUrls();
++        int sidebarNum = 8;// 最大添加U盘数,可以自己定义
++        QString home_path = QDir::homePath().section("/", -1, -1);
++        QString mnt = "/media/" + home_path + "/";
++        QDir mntDir(mnt);
++        mntDir.setFilter(QDir::Dirs | QDir::NoDotAndDotDot);
++        QFileInfoList file_list = mntDir.entryInfoList();
++        QList<QUrl> mntUrlList;
++        for (int i = 0; i < sidebarNum && i < file_list.size(); ++i) {
++            QFileInfo fi = file_list.at(i);
++            mntUrlList << QUrl("file://" + fi.filePath());
++        }
++
++        QFileSystemWatcher m_fileSystemWatcher(&fd);
++        m_fileSystemWatcher.addPath("/media/" + home_path + "/");
++        connect(&m_fileSystemWatcher, &QFileSystemWatcher::directoryChanged, &fd,
++                [=, &sidebarNum, &mntUrlList, &usb_list, &fd](const QString path) {
++            QDir m_wmntDir(path);
++            m_wmntDir.setFilter(QDir::Dirs | QDir::NoDotAndDotDot);
++            QFileInfoList m_wfilist = m_wmntDir.entryInfoList();
++            mntUrlList.clear();
++            for (int i = 0; i < sidebarNum && i < m_wfilist.size(); ++i) {
++                QFileInfo m_fi = m_wfilist.at(i);
++                mntUrlList << QUrl("file://" + m_fi.filePath());
++            }
++            fd.setSidebarUrls(usb_list + mntUrlList);
++            fd.update();
++        });
++
++        connect(&fd, &QFileDialog::finished, &fd, [=, &usb_list, &fd]() {
++            fd.setSidebarUrls(usb_list);
++        });
++
++        fd.setDirectory(QString(sourcePathLine->text()));
++        fd.setAcceptMode(QFileDialog::AcceptOpen);
++        fd.setViewMode(QFileDialog::List);
++        fd.setNameFilter(filter);
++        fd.setFileMode(QFileDialog::Directory);
++        fd.setWindowTitle(tr("select custom screensaver dir"));
++        fd.setLabelText(QFileDialog::Accept, tr("Select"));
++        fd.setLabelText(QFileDialog::LookIn, tr("Position: "));
++        fd.setLabelText(QFileDialog::FileName, tr("FileName: "));
++        fd.setLabelText(QFileDialog::FileType, tr("FileType: "));
++        fd.setLabelText(QFileDialog::Reject, tr("Cancel"));
++
++        fd.setSidebarUrls(usb_list + mntUrlList);
++
++        if (fd.exec() != QDialog::Accepted) {
++            return;
++        }
++        QString selectedfile;
++        selectedfile = fd.selectedFiles().first();
++        if(selectedfile != "") {  //非点击【取消】时
++            setSourcePath(selectedfile);
++            Q_EMIT customPathChanged(selectedfile);
++        }
++    });
++    connect(switchModeGroup, QOverload<int>::of(&QButtonGroup::buttonClicked), this, [=](int id) {
++        if (id == 0) {
++            Q_EMIT switchRandomChanged(false);
++        } else {
++            Q_EMIT switchRandomChanged(true);
++        }
++    });
++    connect(switchTimeComboBox, QOverload<int>::of(&QComboBox::currentIndexChanged), this, [=](int index) {
++        Q_UNUSED(index)
++        Q_EMIT switchTimeChanged(switchTimeComboBox->currentData().toInt());
++    });
++    connect(textLineEdit, &QLineEdit::textChanged, this, [=](){
++        Q_EMIT customTextChanged(textLineEdit->text());
++    });
++    connect(textPositionGroup, QOverload<int>::of(&QButtonGroup::buttonClicked), this, [=](int id) {
++        if (id == 0) {
++            Q_EMIT textCenteredChanged(false);
++        } else {
++            Q_EMIT textCenteredChanged(true);
++        }
++    });
++    connect(showUkuiTimeBtn, &KSwitchButton::stateChanged, this, [=]() {
++        Q_EMIT showUkuiTimeChanged(showUkuiTimeBtn->isChecked());
++    });
++    connect(showCustomTimeBtn, &KSwitchButton::stateChanged, this, [=]() {
++        Q_EMIT showCustomChanged(showCustomTimeBtn->isChecked());
++    });
++    connect(lockButton, &KSwitchButton::stateChanged, this, [=]() {
++        Q_EMIT lockscreenChanged(lockButton->isChecked());
++    });
++}
+diff --git a/src/ukccplugins/screensaver/screensaverui.h b/src/ukccplugins/screensaver/screensaverui.h
+new file mode 100644
+index 0000000..92d67ec
+--- /dev/null
++++ b/src/ukccplugins/screensaver/screensaverui.h
+@@ -0,0 +1,94 @@
++#ifndef SCREENSAVERUI_H
++#define SCREENSAVERUI_H
++
++#include <widgets/settinggroup.h>
++#include <widgets/switchwidget.h>
++#include <widgets/pushbuttonwidget.h>
++#include <widgets/comboxwidget.h>
++#include "screensaverpluginso.h"
++#include "previewwidget.h"
++#include <QHBoxLayout>
++#include <QWidget>
++#include <QRadioButton>
++#include <QLineEdit>
++#include <QFileDialog>
++#include <QButtonGroup>
++#include <QFileSystemWatcher>
++#include <kysdk/applications/klabel.h>
++
++using namespace kdk;
++
++class ScreensaverUi : public QWidget
++{
++    Q_OBJECT
++public:
++    ScreensaverUi();
++    ~ScreensaverUi();
++    void setIdleTimeOptions(const QStringList &textList, const QList<int> &dataList);
++    void setScreensaverOptions(const QStringList &textList, const QStringList &dataList);
++    void setSwitchTimeOptions(const QStringList &textList, const QList<int> &dataList);
++    void updatePreview(QWidget *w);
++    void setSourcePath(const QString &text);
++    void setSwitchRandom(const bool &b);
++    void setSwitchTime(const int &time);
++    void setCustomText(const QString &text);
++    void setTextCentered(const bool &b);
++    void setShowUkuiTime(const bool &b);
++    void setShowCustomTime(const bool &b);
++    void setLockscreen(const bool &b);
++
++public:
++    void setIdleTime(int time);
++    void setScreensaver(QString type);
++
++private:
++    void initUi();
++    void initPreview();
++    void initSetting();
++    void initSourceFrame();
++    void initSwitchModeFrame();
++    void initSwitchTimeFrame();
++    void initCustomTextFrame();
++    void initTextPositionFrame();
++    void initBreakTimeFrame();
++    void initScreenlockFrame();
++    void sendSignals();
++
++private:
++    QVBoxLayout *uiLayout         = nullptr;
++
++private:
++    KLabel    *screensaverTitle = nullptr;
++    UkccFrame     *previewFrame     = nullptr;
++    QHBoxLayout   *previewLayout    = nullptr;
++    PreviewWidget *previewWidget    = nullptr;
++    SettingGroup  *screensaverGroup = nullptr;
++    ComboxWidget  *idleTimeWidget   = nullptr;
++    ComboxWidget  *programWidget    = nullptr;
++    SettingGroup  *customizeGroup   = nullptr;
++
++private:
++    QLineEdit     *sourcePathLine     = nullptr;
++    QPushButton   *sourceButton       = nullptr;
++    QButtonGroup  *switchModeGroup    = nullptr;
++    QComboBox     *switchTimeComboBox = nullptr;
++    QLineEdit     *textLineEdit       = nullptr;
++    QButtonGroup  *textPositionGroup  = nullptr;
++    KSwitchButton *showCustomTimeBtn  = nullptr;
++    KSwitchButton *showUkuiTimeBtn    = nullptr;
++    KSwitchButton *lockButton         = nullptr;
++
++Q_SIGNALS:
++    void idleTimeChanged(int time);
++    void screensaverChanged(QString type);
++    void customPathChanged(QString path);
++    void switchRandomChanged(bool b);
++    void switchTimeChanged(int time);
++    void customTextChanged(QString text);
++    void textCenteredChanged(bool b);
++    void showUkuiTimeChanged(bool b);
++    void showCustomChanged(bool b);
++    void lockscreenChanged(bool b);
++};
++
++#endif // SCREENSAVERUI_H
+diff --git a/src/ukccplugins/sessiondbus/screenlockinterface.cpp b/src/ukccplugins/sessiondbus/screenlockinterface.cpp
+new file mode 100644
+index 0000000..f14ae59
+--- /dev/null
++++ b/src/ukccplugins/sessiondbus/screenlockinterface.cpp
+@@ -0,0 +1,153 @@
++/*
++ * Copyright (C) 2025 KylinSoft Co., Ltd.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 3, or (at your option)
++ * any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, see <http://www.gnu.org/licenses/>.
++ *
++ **/
++#include "screenlockinterface.h"
++#include <sys/stat.h>
++#include "../../lock-backend/gsettingshelper.h"
++
++ScreenlockInterface::ScreenlockInterface(DbusUpperInterface *upperInterface, QObject *parent)
++    : QObject(parent), m_upperInterface(upperInterface)
++{
++}
++
++bool ScreenlockInterface::initData()
++{
++    if (!m_isInited) {
++        mUKCConfig = QDir::homePath() + "/.config/ukui/ukui-control-center.conf";
++        lockSetting = new QSettings(mUKCConfig, QSettings::IniFormat, this);
++        m_isInited = true;
++    }
++    return m_isInited;
++}
++
++ScreenlockInterface::~ScreenlockInterface() {}
++
++void ScreenlockInterface::setShowOnLogin(bool b)
++{
++    initData();
++    QString bgStr;
++    struct stat fileStat;
++    if (b && m_upperInterface) {
++        bgStr = m_upperInterface->getGSettingsInstance()->GetLockScreenConf(KEY_BACKGROUND).toString();
++        stat(bgStr.toStdString().c_str(), &fileStat);
++        if (fileStat.st_uid != 0) { // 在普通用户下
++            bgStr = copyLoginFile(bgStr);
++        }
++    } else if (!b) {
++        bgStr = "";
++    }
++    lockSetting->beginGroup("ScreenLock");
++    lockSetting->setValue("lockStatus", b);
++    lockSetting->endGroup();
++
++    QString name = qgetenv("USER");
++    if (name.isEmpty()) {
++        name = qgetenv("USERNAME");
++    }
++
++    QString lockfilename = "/var/lib/lightdm-data/" + name + "/ukui-greeter.conf";
++    QSettings lockLoginSettings(lockfilename, QSettings::IniFormat, this);
++
++    lockLoginSettings.beginGroup("greeter");
++    lockLoginSettings.setValue("backgroundPath", bgStr);
++    lockLoginSettings.endGroup();
++    Q_EMIT changed("showOnLogin");
++}
++
++void ScreenlockInterface::setWallpaper(QString f)
++{
++    initData();
++    if (m_upperInterface) {
++        m_upperInterface->getGSettingsInstance()->SetLockScreenConf(KEY_BACKGROUND, f);
++    }
++    setShowOnLogin(getShowOnLogin());
++    Q_EMIT changed("wallpaper");
++}
++
++bool ScreenlockInterface::getShowOnLogin()
++{
++    initData();
++    if (!QFile::exists(mUKCConfig)) {
++        setShowOnLogin(true);
++    }
++
++    lockSetting->beginGroup("ScreenLock");
++    lockSetting->sync();
++    bool status = lockSetting->value("lockStatus").toBool();
++    lockSetting->endGroup();
++    return status;
++}
++
++QString ScreenlockInterface::getWallpaper()
++{
++    initData();
++    QString initBgStr = "";
++    if (m_upperInterface) {
++        initBgStr = m_upperInterface->getGSettingsInstance()->GetLockScreenConf(KEY_BACKGROUND).toString();
++    }
++
++    // 锁屏壁纸不存在,则展示默认壁纸
++    if (!QFile::exists(initBgStr)) {
++        initBgStr = "/usr/share/backgrounds/1-warty-final-ubuntukylin.jpg";
++        if (!QFile::exists(initBgStr)) {
++            initBgStr = "/usr/share/backgrounds/1-openkylin.jpg";
++        }
++    }
++    return initBgStr;
++}
++
++QStringList ScreenlockInterface::getPreviewWallpapers()
++{
++    initData();
++    QDBusInterface interface(
++        "org.ukui.ukcc.session", "/Wallpaper", "org.ukui.ukcc.session.Wallpaper", QDBusConnection::sessionBus(), this);
++    if (interface.isValid()) {
++        return interface.property("previewWallpapers").toStringList();
++    }
++    return QStringList();
++}
++
++QStringList ScreenlockInterface::getSourceWallpapers()
++{
++    QDBusInterface interface(
++        "org.ukui.ukcc.session", "/Wallpaper", "org.ukui.ukcc.session.Wallpaper", QDBusConnection::sessionBus(), this);
++    if (interface.isValid()) {
++        return interface.property("sourceWallpapers").toStringList();
++    }
++    return QStringList();
++}
++
++void ScreenlockInterface::resetDefault()
++{
++    initData();
++    if (m_upperInterface) {
++        QString strDefBg = m_upperInterface->getGSettingsInstance()->ResetLockScreenConf(KEY_BACKGROUND).toString();
++        setWallpaper(strDefBg);
++    }
++}
++
++QString ScreenlockInterface::copyLoginFile(QString fileName)
++{
++    QString name = qgetenv("USER");
++    if (name.isEmpty()) {
++        name = qgetenv("USERNAME");
++    }
++    QString loginFilename = "/var/lib/lightdm-data/" + name + "/" + "loginBackground";
++    QString loginCmd = QString("cp '%1' %2").arg(fileName).arg(loginFilename);
++    system(loginCmd.toUtf8().data());
++    return loginFilename;
++}
+diff --git a/src/ukccplugins/sessiondbus/screenlockinterface.h b/src/ukccplugins/sessiondbus/screenlockinterface.h
+new file mode 100644
+index 0000000..8458a46
+--- /dev/null
++++ b/src/ukccplugins/sessiondbus/screenlockinterface.h
+@@ -0,0 +1,63 @@
++/*
++ * Copyright (C) 2025 KylinSoft Co., Ltd.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 3, or (at your option)
++ * any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, see <http://www.gnu.org/licenses/>.
++ *
++ **/
++#ifndef SCREENLOCKINTERFACE_H
++#define SCREENLOCKINTERFACE_H
++
++#include <QObject>
++#include <QtDBus>
++#include "../../lock-backend/dbusupperinterface.h"
++
++class ScreenlockInterface : public QObject
++{
++    Q_OBJECT
++    Q_CLASSINFO("D-Bus Interface", "org.ukui.ScreenSaver.session.Screenlock")
++    Q_PROPERTY(bool showOnLogin READ getShowOnLogin)
++    Q_PROPERTY(QString wallpaper READ getWallpaper)
++    Q_PROPERTY(QStringList previewWallpapers READ getPreviewWallpapers)
++    Q_PROPERTY(QStringList sourceWallpapers READ getSourceWallpapers)
++
++public:
++    ScreenlockInterface(DbusUpperInterface *upperInterface, QObject *parent = nullptr);
++    ~ScreenlockInterface();
++    bool getShowOnLogin();
++    QString getWallpaper();
++    QStringList getPreviewWallpapers();
++    QStringList getSourceWallpapers();
++
++public Q_SLOTS:
++    void setShowOnLogin(bool b);
++    void setWallpaper(QString f);
++    void resetDefault();
++
++private:
++    QString copyLoginFile(QString fileName);
++    bool initData();
++
++private:
++    QStringList previewWallpaperList;
++    QStringList sourceWallpaperList;
++    QString     mUKCConfig     = "";
++    QSettings   *lockSetting   = nullptr;
++    DbusUpperInterface *m_upperInterface = nullptr;
++    bool m_isInited = false;
++
++Q_SIGNALS:
++    void changed(QString key);
++};
++
++#endif // SCREENLOCKINTERFACE_H
+diff --git a/src/ukccplugins/sessiondbus/screensaverinterface.cpp b/src/ukccplugins/sessiondbus/screensaverinterface.cpp
+new file mode 100644
+index 0000000..1a8e884
+--- /dev/null
++++ b/src/ukccplugins/sessiondbus/screensaverinterface.cpp
+@@ -0,0 +1,193 @@
++/*
++ * Copyright (C) 2025 KylinSoft Co., Ltd.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 3, or (at your option)
++ * any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, see <http://www.gnu.org/licenses/>.
++ *
++ **/
++#include "screensaverinterface.h"
++#include "../../lock-backend/gsettingshelper.h"
++
++ScreensaverInterface::ScreensaverInterface(DbusUpperInterface *upperInterface, QObject *parent)
++    : QObject(parent), m_upperInterface(upperInterface)
++{
++}
++
++bool ScreensaverInterface::initData()
++{
++    if (!m_isInited) {
++        mScreensaverType.clear();
++        QString mode = m_upperInterface->getGSettingsInstance()->GetLockScreenConf(KEY_MODE).toString();
++        if (mode == "default-ukui") {
++            mScreensaverType = "ukui";
++        } else if (mode == "default-ukui-custom") {
++            mScreensaverType = "custom";
++        } else {
++            mScreensaverType = "other";
++        }
++        connect(
++            m_upperInterface->getGSettingsInstance().get(),
++            &GSettingsHelper::lockScreenConfigChanged,
++            this,
++            [=](QString strKey, QVariant value) {
++                if (strKey == KEY_MODE) {
++                    QString mode = value.toString();
++                    if (mode == "default-ukui") {
++                        mScreensaverType = "ukui";
++                    } else if (mode == "default-ukui-custom") {
++                        mScreensaverType = "custom";
++                    } else {
++                        mScreensaverType = "other";
++                    }
++                }
++            });
++        m_isInited = true;
++    }
++    return m_isInited;
++}
++
++ScreensaverInterface::~ScreensaverInterface() {}
++
++int ScreensaverInterface::getPreentryTime()
++{
++    initData();
++    return m_upperInterface->getGSettingsInstance()->GetLockScreenConf(KEY_IDLE_DELAY).toInt();
++}
++
++void ScreensaverInterface::setPreentryTime(int time)
++{
++    initData();
++    m_upperInterface->getGSettingsInstance()->SetLockScreenConf(KEY_IDLE_DELAY, time);
++    Q_EMIT changed("preentryTime");
++}
++
++QString ScreensaverInterface::getScreensaverType()
++{
++    initData();
++    return mScreensaverType;
++}
++
++void ScreensaverInterface::setScreensaverType(QString type)
++{
++    initData();
++    if (type == "ukui") {
++        m_upperInterface->getGSettingsInstance()->SetLockScreenConf(KEY_MODE, "default-ukui");
++    } else if (type == "custom") {
++        m_upperInterface->getGSettingsInstance()->SetLockScreenConf(KEY_MODE, "default-ukui-custom");
++    }
++    Q_EMIT changed("screensaverType");
++}
++
++bool ScreensaverInterface::getShowBreakTimeUkui()
++{
++    initData();
++    return m_upperInterface->getGSettingsInstance()->GetScreenSaverConf(KEY_SHOW_UKUI_REST_TIME).toBool();
++}
++
++void ScreensaverInterface::setShowBreakTimeUkui(bool b)
++{
++    initData();
++    m_upperInterface->getGSettingsInstance()->SetScreenSaverConf(KEY_SHOW_UKUI_REST_TIME, b);
++    Q_EMIT changed("showBreakTimeUkui");
++}
++
++bool ScreensaverInterface::getShowBreakTimeCustom()
++{
++    initData();
++    return m_upperInterface->getGSettingsInstance()->GetScreenSaverConf(KEY_SHOW_CUSTOM_REST_TIME).toBool();
++}
++
++void ScreensaverInterface::setShowBreakTimeCustom(bool b)
++{
++    initData();
++    m_upperInterface->getGSettingsInstance()->SetScreenSaverConf(KEY_SHOW_CUSTOM_REST_TIME, b);
++    Q_EMIT changed("showBreakTimeCustom");
++}
++
++bool ScreensaverInterface::getScreenLockEnabled()
++{
++    initData();
++    return m_upperInterface->getGSettingsInstance()->GetLockScreenConf(KEY_LOCK_ENABLED).toBool();
++}
++
++void ScreensaverInterface::setScreenLockEnabled(bool b)
++{
++    initData();
++    m_upperInterface->getGSettingsInstance()->SetLockScreenConf(KEY_LOCK_ENABLED, b);
++    Q_EMIT changed("screenLockEnabled");
++}
++
++QString ScreensaverInterface::getcustomPath()
++{
++    initData();
++    return m_upperInterface->getGSettingsInstance()->GetScreenSaverConf(KEY_BACKGROUND_PATH).toString();
++}
++
++void ScreensaverInterface::setCustomPath(QString path)
++{
++    initData();
++    m_upperInterface->getGSettingsInstance()->SetScreenSaverConf(KEY_BACKGROUND_PATH, path);
++    Q_EMIT changed("customPath");
++}
++
++bool ScreensaverInterface::getSwitchRandom()
++{
++    initData();
++    return m_upperInterface->getGSettingsInstance()->GetScreenSaverConf(KEY_AUTOMATIC_SWITCHING_ENABLE).toBool();
++}
++
++void ScreensaverInterface::setSwitchRandom(bool b)
++{
++    initData();
++    m_upperInterface->getGSettingsInstance()->SetScreenSaverConf(KEY_AUTOMATIC_SWITCHING_ENABLE, b);
++    Q_EMIT changed("switchRandom");
++}
++
++int ScreensaverInterface::getCycleTime()
++{
++    initData();
++    return m_upperInterface->getGSettingsInstance()->GetScreenSaverConf(KEY_CYCLE_TIME).toInt();
++}
++
++void ScreensaverInterface::setCycleTime(int time)
++{
++    initData();
++    m_upperInterface->getGSettingsInstance()->SetScreenSaverConf(KEY_CYCLE_TIME, time);
++    Q_EMIT changed("cycleTime");
++}
++
++QString ScreensaverInterface::getCustomText()
++{
++    initData();
++    return m_upperInterface->getGSettingsInstance()->GetScreenSaverConf(KEY_MYTEXT).toString();
++}
++
++void ScreensaverInterface::setCustomText(QString text)
++{
++    initData();
++    m_upperInterface->getGSettingsInstance()->SetScreenSaverConf(KEY_MYTEXT, text);
++    Q_EMIT changed("customText");
++}
++
++bool ScreensaverInterface::getCustomTextCentered()
++{
++    initData();
++    return m_upperInterface->getGSettingsInstance()->GetScreenSaverConf(KEY_TEXT_IS_CENTER).toBool();
++}
++
++void ScreensaverInterface::setCustomTextCentered(bool b)
++{
++    initData();
++    m_upperInterface->getGSettingsInstance()->SetScreenSaverConf(KEY_TEXT_IS_CENTER, b);
++    Q_EMIT changed("customTextCentered");
++}
+diff --git a/src/ukccplugins/sessiondbus/screensaverinterface.h b/src/ukccplugins/sessiondbus/screensaverinterface.h
+new file mode 100644
+index 0000000..654a6db
+--- /dev/null
++++ b/src/ukccplugins/sessiondbus/screensaverinterface.h
+@@ -0,0 +1,78 @@
++/*
++ * Copyright (C) 2025 KylinSoft Co., Ltd.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 3, or (at your option)
++ * any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, see <http://www.gnu.org/licenses/>.
++ *
++ **/
++#ifndef SCREENSAVERINTERFACE_H
++#define SCREENSAVERINTERFACE_H
++
++#include <QObject>
++#include <QtDBus>
++#include "../../lock-backend/dbusupperinterface.h"
++
++class ScreensaverInterface : public QObject
++{
++    Q_OBJECT
++    Q_CLASSINFO("D-Bus Interface", "org.ukui.ScreenSaver.session.Screensaver")
++    Q_PROPERTY(int preentryTime READ getPreentryTime)
++    Q_PROPERTY(QString screensaverType READ getScreensaverType)
++    Q_PROPERTY(bool showBreakTimeUkui READ getShowBreakTimeUkui)
++    Q_PROPERTY(bool showBreakTimeCustom READ getShowBreakTimeCustom)
++    Q_PROPERTY(bool screenLockEnabled READ getScreenLockEnabled)
++    Q_PROPERTY(QString customPath READ getcustomPath)
++    Q_PROPERTY(bool switchRandom READ getSwitchRandom)
++    Q_PROPERTY(int cycleTime READ getCycleTime)
++    Q_PROPERTY(QString customText READ getCustomText)
++    Q_PROPERTY(bool customTextCentered READ getCustomTextCentered)
++
++public:
++    ScreensaverInterface(DbusUpperInterface *upperInterface, QObject *parent = nullptr);
++    ~ScreensaverInterface();
++    int getPreentryTime();
++    QString getScreensaverType();
++    bool getShowBreakTimeUkui();
++    bool getShowBreakTimeCustom();
++    bool getScreenLockEnabled();
++    QString getcustomPath();
++    bool getSwitchRandom();
++    int getCycleTime();
++    QString getCustomText();
++    bool getCustomTextCentered();
++
++private:
++    bool initData();
++
++private:
++    QString mScreensaverType;
++    DbusUpperInterface *m_upperInterface = nullptr;
++    bool m_isInited = false;
++
++public Q_SLOTS:
++    void setPreentryTime(int time);
++    void setScreensaverType(QString type);
++    void setShowBreakTimeUkui(bool b);
++    void setShowBreakTimeCustom(bool b);
++    void setScreenLockEnabled(bool b);
++    void setCustomPath(QString path);
++    void setSwitchRandom(bool b);
++    void setCycleTime(int time);
++    void setCustomText(QString Text);
++    void setCustomTextCentered(bool b);
++
++Q_SIGNALS:
++    void changed(QString key);
++};
++
++#endif // SCREENSAVERINTERFACE_H
+diff --git a/src/userinfo.cpp b/src/userinfo.cpp
+index 7808f3a..c9e03a8 100644
+--- a/src/userinfo.cpp
++++ b/src/userinfo.cpp
+@@ -16,8 +16,8 @@
+  *
+  **/
+ #include "userinfo.h"
+-#include "global_utils.h"
+-#include "definetypes.h"
++#include "common/global_utils.h"
++#include "common/definetypes.h"
+ #include <QDBusConnection>
+ #include <QDBusMessage>
+ #include <QDBusInterface>
+diff --git a/src/widgets/authdialog.cpp b/src/widgets/authdialog.cpp
+index 62c9b77..c20f7f0 100644
+--- a/src/widgets/authdialog.cpp
++++ b/src/widgets/authdialog.cpp
+@@ -35,6 +35,7 @@
+ #include <unistd.h>
+ #include <sys/types.h>
+ #include <pwd.h>
++#include <syslog.h>
+ #include "../lock-dialog/pam-tally.h"
+ #include "global_utils.h"
+ #include "securityquestionanswer.h"
+@@ -57,11 +58,13 @@ AuthDialog::AuthDialog(LockDialogModel *model, UserInfoPtr userInfo, QWidget *pa
+     , m_curUserInfo(userInfo)
+     , m_pSecurityQuestionAnswer(new SecurityQuestionAnswer(this))
+ {
++    pam_tally_init();
+     initUI();
+ }
+ 
+ void AuthDialog::initUI()
+ {
++    installEventFilter(this);
+     QVBoxLayout *mainLayout = new QVBoxLayout(this);
+     mainLayout->setAlignment(Qt::AlignCenter);
+     mainLayout->setSpacing(WIDGET_HEIGHT_SPACING);
+@@ -147,6 +150,8 @@ bool AuthDialog::eventFilter(QObject *obj, QEvent *event)
+             } else {
+                 Q_EMIT bottomPositionChanged(mapToParent(m_widgetLoginOpts->geometry().topLeft()).y());
+             }
++        } else if (this == obj && event->type() == QEvent::Show) {
++            pam_tally_init();
+         }
+     }
+ 
+@@ -875,8 +880,8 @@ void AuthDialog::onPamShowMessage(QString strMsg, int nType)
+ void AuthDialog::showPwdTipBtn()
+ {
+     m_pPwdTipMessage->setVisible(m_userFailedTimesMap[m_curUserInfo->uid()] >= 1);
+-    if (m_userFailedTimesMap[m_curUserInfo->uid()] >= 1 &&
+-            m_pSecurityQuestionAnswer->GetUserPasswdHint(m_curUserInfo->uid()) != "") {
++    if (m_userFailedTimesMap[m_curUserInfo->uid()] >= 1
++        && m_pSecurityQuestionAnswer->GetUserPasswdHint(m_curUserInfo->uid()) != "") {
+         m_pEditLayout->setContentsMargins(48, 0, 0, 0);
+         m_pPwdTipMessage->show();
+         m_pPwdTipMessage->setToolTip(m_pSecurityQuestionAnswer->GetUserPasswdHint(m_curUserInfo->uid()));
+@@ -984,10 +989,13 @@ void AuthDialog::onPamShowPrompt(QString strPrompt, int nType)
+             //                });
+             //                isPowerup = false;
+             //            } else {
++            syslog(LOG_INFO, "[ukui-screensaver-dialog] check bio auth begin!!");
+             performBiometricAuth();
++            syslog(LOG_INFO, "[ukui-screensaver-dialog] check bio auth done!!");
+             //            }
+         }
+     } else {
++        syslog(LOG_INFO, "[ukui-screensaver-dialog] auth alraedy!!");
+         m_isNameLogin = false;
+         qDebug() << "m_isNameLogin = false";
+         m_passwordEdit->stopWaiting();
+@@ -1127,13 +1135,16 @@ void AuthDialog::onPamAuthCompleted()
+             startAuth();
+             if (++m_userFailedTimesMap[m_curUserInfo->uid()] >= 1) {
+                 qDebug() << "m_authFailedTimes = " << m_userFailedTimesMap[m_curUserInfo->uid()];
+-		showPwdTipBtn();
++                showPwdTipBtn();
+                 Q_EMIT showResetPasswdBtn();
+             }
+         } else {
+             showAuthenticated(false);
+         }
+     }
++    if (!m_isInhibitShow) {
++        show();
++    }
+ }
+ 
+ void AuthDialog::onRespond(const QString &strRes)
+@@ -1174,28 +1185,25 @@ void AuthDialog::onRespond(const QString &strRes)
+ 
+ void AuthDialog::startAuth()
+ {
++    syslog(LOG_INFO, "[ukui-screensaver-dialog] auth start!!");
+     if (!m_curUserInfo->name().isEmpty()) {
+-        qint64 lnDiffTime = qAbs(m_lastPamAuthTime.msecsTo(QDateTime::currentDateTime()));
+-        if (lnDiffTime >= 1000 || m_strLastPamAuthName != m_curUserInfo->name()) {
+-            m_lastPamAuthTime = QDateTime::currentDateTime();
+-            m_bRecvPrompt = false;
+-            m_bHasUnacknowledgedMsg = false;
+-            // 用户认证
+-            if (m_curUserInfo->name() == "*guest") { // 游客登录
+-                qDebug() << "guest login";
+-                m_passwordEdit->show();
+-                m_passwordEdit->setPrompt(tr("login"));
+-                m_strLastPamAuthName = "*guest";
+-            } else if (m_curUserInfo->name() == "*login") { // 手动输入用户名
+-                Q_EMIT m_modelLockDialog->pamAuthenticate("");
+-                m_strLastPamAuthName = "*login";
+-            } else {
+-                qDebug() << "login: " << m_curUserInfo->name();
+-                Q_EMIT m_modelLockDialog->pamAuthenticate(m_curUserInfo->name());
+-                m_passwordEdit->clear();
+-                m_passwordEdit->readOnly(true);
+-                m_strLastPamAuthName = m_curUserInfo->name();
+-            }
++        m_bRecvPrompt = false;
++        m_bHasUnacknowledgedMsg = false;
++        // 用户认证
++        if (m_curUserInfo->name() == "*guest") { // 游客登录
++            qDebug() << "guest login";
++            m_passwordEdit->show();
++            m_passwordEdit->setPrompt(tr("login"));
++            m_strLastPamAuthName = "*guest";
++        } else if (m_curUserInfo->name() == "*login") { // 手动输入用户名
++            Q_EMIT m_modelLockDialog->pamAuthenticate("");
++            m_strLastPamAuthName = "*login";
++        } else {
++            qDebug() << "login: " << m_curUserInfo->name();
++            Q_EMIT m_modelLockDialog->pamAuthenticate(m_curUserInfo->name());
++            m_passwordEdit->clear();
++            m_passwordEdit->readOnly(true);
++            m_strLastPamAuthName = m_curUserInfo->name();
+         }
+     }
+ }
+diff --git a/src/widgets/fullbackgroundwidget.cpp b/src/widgets/fullbackgroundwidget.cpp
+index b59017a..463e305 100644
+--- a/src/widgets/fullbackgroundwidget.cpp
++++ b/src/widgets/fullbackgroundwidget.cpp
+@@ -55,8 +55,8 @@ using namespace kdk;
+ #include <kysec/status.h>
+ #endif
+ 
+-FullBackgroundWidget::FullBackgroundWidget(LockDialogModel *model, QWidget *parent)
+-    : QWidget(parent), m_modelLockDialog(model)
++FullBackgroundWidget::FullBackgroundWidget(LockDialogModel *model, bool isStartup, QWidget *parent)
++    : QWidget(parent), m_modelLockDialog(model), m_isStartupMode(isStartup)
+ {
+     initCurrentBackground();
+     initUI();
+@@ -114,8 +114,7 @@ void FullBackgroundWidget::initUI()
+         moveToPrimaryScreen();
+     }
+ 
+-    if (m_modelLockDialog->getAgreementWindowShowLoginPrompt()
+-        && (/*IsStartupMode() || */ (qgetenv("USER") == "lightdm"))) {
++    if (m_modelLockDialog->getAgreementWindowShowLoginPrompt() && (IsStartupMode() || isGreeterMode())) {
+         bool hideTitle = m_modelLockDialog->getAgreementWindowHideTitle();
+         QString title = m_modelLockDialog->getAgreementWindowPromptTitle();
+         QString text = m_modelLockDialog->getAgreementWindowText();
+@@ -124,7 +123,7 @@ void FullBackgroundWidget::initUI()
+         if (!text.isEmpty() && (hideTitle || (!hideTitle && !text.isEmpty()))) {
+             m_agreementWindow = new AgreementWindow(hideTitle, title, text, this);
+             m_lockWidget->hide();
+-            m_agreementWindow->setGeometry(this->geometry());
++            m_agreementWindow->setGeometry(m_lockWidget->geometry());
+             m_agreementWindow->show();
+ 
+             m_lockWidget->clearFocus();
+@@ -254,6 +253,7 @@ void FullBackgroundWidget::onSecondRunParam(const QString &str)
+     } else if (str == "ScreensaverLock") {
+         onShowLockScreensaver();
+     } else if (str == "StartupLock") {
++        setIsStartupMode(true);
+         onShowLock(true);
+     } else if (str == "CmdLock") {
+         onShowLock(false);
+@@ -342,6 +342,7 @@ void FullBackgroundWidget::onShowBlankScreensaver(int nDelay, bool isHasLock)
+ 
+ void FullBackgroundWidget::onShowLock(bool isStartup)
+ {
++    Q_UNUSED(isStartup);
+     if (m_isSessionTools) {
+         m_isSessionTools = false;
+         if (m_lockWidget && !m_lockWidget->isHidden())
+@@ -349,8 +350,8 @@ void FullBackgroundWidget::onShowLock(bool isStartup)
+     }
+ 
+     screenStatus = (ScreenStatus)(screenStatus | SCREEN_LOCK);
+-    m_isStartupMode = isStartup;
+     show();
++    syslog(LOG_INFO, "[ukui-screensaver-dialog] set current user!!");
+     Q_EMIT m_modelLockDialog->setCurrentUser(m_modelLockDialog->defaultUserName());
+     Q_EMIT m_modelLockDialog->lockStateChanged(true, false);
+     if (m_lockWidget && !m_lockWidget->isHidden())
+@@ -521,6 +522,9 @@ void FullBackgroundWidget::onLockScreenTimeout()
+ void FullBackgroundWidget::onCloseScreensaver()
+ {
+     hide();
++    if (m_lockWidget) {
++        m_lockWidget->exitSubWidget(false, false);
++    }
+     Q_EMIT m_modelLockDialog->lockStateChanged(false, false);
+     stopDelayLockScreen();
+     screenStatus = UNDEFINED;
+@@ -644,6 +648,9 @@ void FullBackgroundWidget::moveToPrimaryScreen()
+     for (auto screen : QGuiApplication::screens()) {
+         if (screen == qApp->primaryScreen()) {
+             qInfo() << "LockWidget:" << screen->geometry() << m_lockWidget->geometry() << geometry();
++            if (m_agreementWindow && m_agreementWindow->isVisible()) {
++                m_agreementWindow->setGeometry(screen->geometry());
++            }
+             if (!m_lockWidget->isHidden()) {
+                 m_lockWidget->hide();
+                 m_lockWidget->setGeometry(screen->geometry());
+@@ -661,6 +668,9 @@ void FullBackgroundWidget::moveToPrimaryScreen()
+                 /*避免切换时闪烁*/
+                 qInfo() << "LockWidget:" << screen->geometry() << m_lockWidget->geometry() << "," << screen
+                         << geometry();
++                if (m_agreementWindow && m_agreementWindow->isVisible()) {
++                    m_agreementWindow->setGeometry(screen->geometry());
++                }
+                 if (!m_lockWidget->isHidden()) {
+                     m_lockWidget->hide();
+                     m_lockWidget->setGeometry(screen->geometry());
+@@ -717,8 +727,9 @@ void FullBackgroundWidget::keyReleaseEvent(QKeyEvent *e)
+             bool canShow = true;
+             if (m_lockWidget && !m_lockWidget->exitSubWidget())
+                 canShow = false;
+-            if (canShow)
++            if (canShow && !isGreeterMode()) {
+                 onShowScreensaver();
++            }
+         } else if (screenStatus & SCREEN_SAVER /* && !isBlank*/) {
+             onClearScreensaver();
+         }
+@@ -819,6 +830,9 @@ void FullBackgroundWidget::onCurUserChanged(const QString &strUserName)
+ 
+ void FullBackgroundWidget::onAuthSucceed(QString strUserName)
+ {
++    if (IsStartupMode()) {
++        setIsStartupMode(false);
++    }
+     if (getenv("USER") == strUserName) {
+         if (UniAuthService::instance()) {
+             UniAuthService::instance()->SaveLastLoginUser(strUserName);
+@@ -1201,3 +1215,9 @@ void FullBackgroundWidget::onScreensChanged(QList<QString> listMonitors)
+     // 分辨率,延时1000ms正常。
+     QTimer::singleShot(1000, this, SLOT(onDesktopResized()));
+ }
++
++void FullBackgroundWidget::setIsStartupMode(bool isStartup)
++{
++    m_isStartupMode = isStartup;
++    Q_EMIT StartupModeChanged(m_isStartupMode);
++}
+diff --git a/src/widgets/fullbackgroundwidget.h b/src/widgets/fullbackgroundwidget.h
+index 339d3fc..3c2e9fe 100644
+--- a/src/widgets/fullbackgroundwidget.h
++++ b/src/widgets/fullbackgroundwidget.h
+@@ -45,7 +45,7 @@ class FullBackgroundWidget : public QWidget, public QAbstractNativeEventFilter
+ {
+     Q_OBJECT
+ public:
+-    explicit FullBackgroundWidget(LockDialogModel *model, QWidget *parent = nullptr);
++    explicit FullBackgroundWidget(LockDialogModel *model, bool isStartup = false, QWidget *parent = nullptr);
+     ~FullBackgroundWidget();
+     virtual bool nativeEventFilter(const QByteArray &eventType, void *message, long *result) override;
+ 
+@@ -98,6 +98,7 @@ public Q_SLOTS:
+ 
+     void onStartFcitx();
+ Q_SIGNALS:
++    void StartupModeChanged(bool isStartup);
+ 
+ protected:
+     void mousePressEvent(QMouseEvent *e);
+@@ -131,6 +132,8 @@ private:
+     void onLockScreenTimeout();
+     void stopDelayLockScreen();
+ 
++    void setIsStartupMode(bool isStartup);
++
+ private Q_SLOTS:
+     void onGlobalKeyPress(const quint8 &key);
+     void onGlobalKeyRelease(const quint8 &key);
+diff --git a/src/widgets/iconedit.cpp b/src/widgets/iconedit.cpp
+index a2b46d6..4c13490 100644
+--- a/src/widgets/iconedit.cpp
++++ b/src/widgets/iconedit.cpp
+@@ -172,12 +172,15 @@ bool IconEdit::eventFilter(QObject *obj, QEvent *event)
+         if (event->type() == 2) {
+         }
+     }
++    //导致出现按回车发送多次密码问题,因此注释
++    /*
+     if (obj == m_iconButton && event->type() == QEvent::KeyRelease) {
+         QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
+         if (keyEvent->key() == Qt::Key_Enter || keyEvent->key() == Qt::Key_Return) {
+             clicked_cb();
+         }
+     }
++    */
+     return false;
+ }
+ 
+diff --git a/src/widgets/lockwidget.cpp b/src/widgets/lockwidget.cpp
+index 8c3b318..916d0f3 100644
+--- a/src/widgets/lockwidget.cpp
++++ b/src/widgets/lockwidget.cpp
+@@ -58,6 +58,7 @@
+ #include "configuration.h"
+ #include "utils.h"
+ #include "resetpwdwidget.h"
++#include <syslog.h>
+ 
+ #define BLUR_RADIUS 300
+ #define RIGHT_MARGIN 24
+@@ -67,9 +68,7 @@
+ #define IMAGE_DIR PREFIX + "/images/"
+ float scale;
+ LockWidget::LockWidget(LockDialogModel *model, QWidget *parent)
+-    : QWidget(parent)
+-    ,  m_modelLockDialog(model)
+-    , m_pSecurityQuestionAnswer(new SecurityQuestionAnswer(this))
++    : QWidget(parent), m_modelLockDialog(model), m_pSecurityQuestionAnswer(new SecurityQuestionAnswer(this))
+ {
+     scale = 1.0;
+     m_curUserInfo = m_modelLockDialog->findUserByName(m_modelLockDialog->defaultUserName());
+@@ -140,12 +139,12 @@ bool LockWidget::exitSubWidget(bool isForScreensaver, bool hideVirkeyboard)
+         return false;
+     }
+     bool allExited = true;
+-    if (m_userListWidget && m_userListWidget->isVisible()) {
++    if (m_userListWidget && !m_userListWidget->isHidden()) {
+         m_userListWidget->hide();
+         m_userButton->setClickedStatus(NORMAL);
+         allExited = false;
+     }
+-    if (m_powerListWidget && m_powerListWidget->isVisible()) {
++    if (m_powerListWidget && !m_powerListWidget->isHidden()) {
+         authDialog->setFocus();
+         authDialog->inhibitShow(false);
+         if (m_isShowResetPasswdBtn) {
+@@ -156,45 +155,45 @@ bool LockWidget::exitSubWidget(bool isForScreensaver, bool hideVirkeyboard)
+         }
+         m_powerListWidget->hide();
+         buttonListWidget->show();
+-        if (m_systemMonitorBtn && m_systemMonitorBtn->isVisible()) {
++        if (m_systemMonitorBtn && !m_systemMonitorBtn->isHidden()) {
+             m_systemMonitorBtn->hide();
+         }
+         m_powerManagerButton->setClickedStatus(NORMAL);
+         allExited = false;
+     }
+-    if (m_networkWidget && m_networkWidget->isVisible()) {
++    if (m_networkWidget && !m_networkWidget->isHidden()) {
+         m_networkWidget->hide();
+         m_networkButton->setClickedStatus(NORMAL);
+         //        sendNetPluginVisible(false);
+         allExited = false;
+     }
+-    if (hideVirkeyboard && m_virtualKeyboardWidget && m_virtualKeyboardWidget->isVisible()) {
++    if (hideVirkeyboard && m_virtualKeyboardWidget && !m_virtualKeyboardWidget->isHidden()) {
+         m_virtualKeyboardWidget->hide();
+         m_virKbButton->setClickedStatus(NORMAL);
+         allExited = false;
+     }
+-    if (batteryWidget && batteryWidget->isVisible()) {
++    if (batteryWidget && !batteryWidget->isHidden()) {
+         batteryWidget->hide();
+         m_batteryonButton->setClickedStatus(NORMAL);
+         allExited = false;
+     }
+-    if (m_sessionListWidget && m_sessionListWidget->isVisible()) {
++    if (m_sessionListWidget && !m_sessionListWidget->isHidden()) {
+         m_sessionListWidget->hide();
+         m_sessionButton->setClickedStatus(NORMAL);
+         allExited = false;
+     }
+-    if (m_blockWidget && m_blockWidget->isVisible()) {
++    if (m_blockWidget && !m_blockWidget->isHidden()) {
+         m_blockWidget->hide();
+         m_timeWidget->show();
+         m_powerListWidget->show();
+         buttonListWidget->show();
+         allExited = false;
+     }
+-    if (m_pResetPwdWidget && m_pResetPwdWidget->isVisible()) {
++    if (m_pResetPwdWidget && m_pResetPwdWidget->isHidden()) {
+         m_pResetPwdWidget->hide();
+         m_pResetPwdWidget->switchToConfidentialDig();
+         authDialog->setFocus();
+-        authDialog->show();
++        authDialog->inhibitShow(false);
+         if (m_pResetPwdBtn) {
+             m_pResetPwdBtn->show();
+         }
+@@ -252,8 +251,11 @@ void LockWidget::resizeEvent(QResizeEvent *event)
+     m_pBottomWidget->setGeometry(0, height() - buttonListWidget->height() - BOTTOM_MARGIN * scale, this->width(), 64);
+ 
+     if (m_pResetPwdBtn) {
+-        m_pResetPwdBtn->setGeometry((this->width() - m_pResetPwdBtn->width()) / 2, height() - m_pResetPwdBtn->height() - BOTTOM_MARGIN * scale + 8,
+-                                    m_pResetPwdBtn->width(), m_pResetPwdBtn->height());
++        m_pResetPwdBtn->setGeometry(
++            (this->width() - m_pResetPwdBtn->width()) / 2,
++            height() - m_pResetPwdBtn->height() - BOTTOM_MARGIN * scale + 8,
++            m_pResetPwdBtn->width(),
++            m_pResetPwdBtn->height());
+     }
+ 
+     if (m_sessionListWidget) {
+@@ -565,7 +567,7 @@ void LockWidget::initButtonWidget()
+         });
+     }
+ #endif
+-
++    syslog(LOG_INFO, "[ukui-screensaver-dialog] init net icon begin!!");
+     m_networkButton = new NetWorkButton(this);
+     QListWidgetItem *buttonItem = new QListWidgetItem();
+     buttonItem->setSizeHint(QSize(48, 48));
+@@ -574,6 +576,7 @@ void LockWidget::initButtonWidget()
+     buttonListWidget->addItem(buttonItem);
+     m_networkButton->setToolTip(tr("Network"));
+     connect(m_networkButton, &NetWorkButton::clicked, this, [this]() { onShowNetworkWidget(); });
++    syslog(LOG_INFO, "[ukui-screensaver-dialog] init net icon end!!");
+ 
+     /*
+     connect(buttonWidget, &KyNetworkIcon::updateIconHidden
+@@ -1068,13 +1071,18 @@ void LockWidget::onShowResetPasswdBtn()
+             m_pResetPwdBtn->setMinimumWidth(120);
+             m_pResetPwdBtn->setText(tr("Reset Pwd"));
+             m_pResetPwdBtn->adjustSize();
+-            m_pResetPwdBtn->setStyleSheet(
+-                "QPushButton{background: rgba(255, 255, 255, 0);border-radius: 24px;color: white;padding-left: 8px; padding-right: 8px;}"
+-                "QPushButton:hover{background: rgba(255, 255, 255, 0.15);border-radius: 24px;padding-left: 8px; padding-right: 8px;}"
+-                "QPushButton:pressed {background: rgba(255, 255, 255, 0.4);border-radius: 24px;padding-left: 8px; padding-right: 8px;}");
++            m_pResetPwdBtn->setStyleSheet("QPushButton{background: rgba(255, 255, 255, 0);border-radius: 24px;color: "
++                                          "white;padding-left: 8px; padding-right: 8px;}"
++                                          "QPushButton:hover{background: rgba(255, 255, 255, 0.15);border-radius: "
++                                          "24px;padding-left: 8px; padding-right: 8px;}"
++                                          "QPushButton:pressed {background: rgba(255, 255, 255, 0.4);border-radius: "
++                                          "24px;padding-left: 8px; padding-right: 8px;}");
+             connect(m_pResetPwdBtn, &QPushButton::clicked, this, &LockWidget::onShowResetPwdWidget);
+-            m_pResetPwdBtn->setGeometry((this->width() - m_pResetPwdBtn->width()) / 2, height() - m_pResetPwdBtn->height() - BOTTOM_MARGIN * scale - 8,
+-                                        m_pResetPwdBtn->width(), m_pResetPwdBtn->height());
++            m_pResetPwdBtn->setGeometry(
++                (this->width() - m_pResetPwdBtn->width()) / 2,
++                height() - m_pResetPwdBtn->height() - BOTTOM_MARGIN * scale - 8,
++                m_pResetPwdBtn->width(),
++                m_pResetPwdBtn->height());
+         }
+         m_pResetPwdBtn->show();
+         m_isShowResetPasswdBtn = true;
+@@ -1114,10 +1122,7 @@ void LockWidget::onShowResetPwdWidget()
+         m_pResetPwdWidget->setFixedWidth(width());
+         m_pResetPwdWidget->updateResetPwdSize();
+         m_pResetPwdWidget->setGeometry(
+-            0,
+-            (59 * scale + m_timeWidget->height()),
+-            width(),
+-            height() - (59 * scale + m_timeWidget->height() + 70));
++            0, (59 * scale + m_timeWidget->height()), width(), height() - (59 * scale + m_timeWidget->height() + 70));
+         m_pResetPwdWidget->hide();
+     }
+     m_pResetPwdWidget->updateFontSize(m_curFontSize);
+@@ -1132,7 +1137,7 @@ void LockWidget::onShowResetPwdWidget()
+ 
+ void LockWidget::onBackToAuthDialog(bool isSuccess)
+ {
+-    authDialog->show();
++    authDialog->inhibitShow(false);
+     authDialog->setFocus();
+     if (m_pResetPwdWidget)
+         m_pResetPwdWidget->hide();
+@@ -1282,7 +1287,7 @@ void LockWidget::onShowPowerListWidget(bool issessionTools)
+     } else {
+         m_powerListWidget->hide();
+         authDialog->inhibitShow(false);
+-        //bug#292889 头像加载缓慢问题,需要调用一次update或repaint来刷新
++        // bug#292889 头像加载缓慢问题,需要调用一次update或repaint来刷新
+         authDialog->update();
+         authDialog->setFocus();
+         if (m_isShowResetPasswdBtn) {
+@@ -1861,8 +1866,9 @@ void LockWidget::setrootWindow(QList<QPair<QRect, QRect>> screenRectList)
+ 
+ void LockWidget::reloadRootBackground()
+ {
+-    if (!isGreeterMode())
++    if (!isGreeterMode() || m_modelLockDialog->isUseWayland()) {
+         return;
++    }
+     // 记录当前的屏幕信息,写入QList保存,防止线程中在遍历屏幕信息时,因
+     // 屏幕插拔而崩溃
+     m_screenRectList.clear();
+@@ -1885,6 +1891,9 @@ void LockWidget::reloadRootBackground()
+ 
+ void LockWidget::drawRootBackground()
+ {
++    if (m_modelLockDialog->isUseWayland()) {
++        return;
++    }
+     drawBackground(true);
+ }
+ 
+diff --git a/src/widgets/screensaverwidget.cpp b/src/widgets/screensaverwidget.cpp
+index cc9b494..0d6239d 100644
+--- a/src/widgets/screensaverwidget.cpp
++++ b/src/widgets/screensaverwidget.cpp
+@@ -36,9 +36,12 @@ ScreenSaverWidget::ScreenSaverWidget(ScreenSaver *screensaver, QWidget *parent)
+     setMouseTracking(true);
+     setFocus();
+     this->installEventFilter(this);
++    if (screensaver) {
++        screensaver->setParent(this);
++    }
+ 
+     QPalette pal(palette());
+-    pal.setColor(QPalette::Background, Qt::black); //设置背景黑色
++    pal.setColor(QPalette::Background, Qt::black); // 设置背景黑色
+     setAutoFillBackground(true);
+     setPalette(pal);
+ 
+diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
+new file mode 100644
+index 0000000..eeca582
+--- /dev/null
++++ b/tests/CMakeLists.txt
+@@ -0,0 +1,50 @@
++add_subdirectory(unit_test_biometric_helper)
++add_subdirectory(unit_test_account_helper)
++add_subdirectory(unit_test_freedesktop_helper)
++add_subdirectory(unit_test_kglobalaccel_helper)
++add_subdirectory(unit_test_login1_helper)
++add_subdirectory(unit_test_session_helper)
++add_subdirectory(unit_test_systemupgrade_helper)
++add_subdirectory(unit_test_uniauth_service)
++add_subdirectory(unit_test_usd_helper)
++add_subdirectory(unit_test_gsettings_helper)
++add_subdirectory(unit_test_engine_device)
++add_subdirectory(unit_test_inputswitch_event)
++add_subdirectory(unit_test_auth_pam)
++add_subdirectory(unit_test_common)
++add_subdirectory(unit_test_switch_user)
++add_subdirectory(unit_test_session_watcher)
++add_subdirectory(unit_test_display_service)
++add_subdirectory(unit_test_dbus_interface)
++add_subdirectory(unit_test_backend_dbus)
++add_subdirectory(unit_test_lock_dialog_model)
++add_subdirectory(unit_test_personal_data)
++add_subdirectory(unit_test_screensaver)
++add_subdirectory(unit_test_screenlock)
++
++# 处理打桩工具相关配置
++set(TEST_UTILS_PATH "${CMAKE_CURRENT_SOURCE_DIR}/kt-test-utils")
++
++# 收集打桩工具的头文件,递归查找符合条件的头文件
++file(GLOB_RECURSE UTILS_HEADERS
++    "${TEST_UTILS_PATH}/cpp-stub/*.h"
++    "${TEST_UTILS_PATH}/cpp-stub/*.hpp"
++    "${TEST_UTILS_PATH}/cpp-stub-ext/*.h"
++)
++
++# 收集打桩工具的源文件,递归查找符合条件的源文件
++file(GLOB_RECURSE UTILS_SOURCES
++    "${TEST_UTILS_PATH}/cpp-stub/*.cpp"
++    "${TEST_UTILS_PATH}/cpp-stub-ext/*.cpp"
++)
++
++# 创建一个库(这里以静态库为例,可以根据需求改为共享库等)来存放打桩工具相关代码
++add_library(utils_lib STATIC ${UTILS_SOURCES} ${UTILS_HEADERS})
++
++# 将打桩工具库的头文件目录添加到包含路径,方便其他目标使用
++target_include_directories(utils_lib
++    PUBLIC
++        "${TEST_UTILS_PATH}/cpp-stub"
++        "${TEST_UTILS_PATH}/cpp-stub-ext"
++)
++
+diff --git a/tests/auto_test.sh b/tests/auto_test.sh
+new file mode 100755
+index 0000000..6fde6ac
+--- /dev/null
++++ b/tests/auto_test.sh
+@@ -0,0 +1,56 @@
++#!/bin/bash
++
++# 设置退出脚本当命令失败时 (非零退出状态)
++#set -e
++
++# 函数:运行单元测试
++run_unit_tests() {
++    local pattern="unit_test_*"
++    
++    # 遍历所有匹配模式的目录
++    for dir in $pattern; do
++        if [ -d "$dir" ] && [ -x "$dir/$(basename "$dir")" ]; then
++            echo "Running tests in $dir..."
++	    # 执行单元测试
++	    (cd "$dir" && "./$(basename "$dir")")
++            # 收集代码覆盖率数据
++	    echo "Collecting coverage data..."
++	    (cd "$dir" && (find ./ -name '*.o' | xargs gcov --preserve-paths))
++        else
++	    echo "Skipping non-existent or non-executable directory: $dir, $dir/$(basename "$dir")"
++        fi
++    done
++}
++
++# 上传 result.zip 到平台
++URL=$1
++upload_result() {
++    echo "current pwd : $(pwd)"
++    # 收集覆盖率信息
++    lcov -d . -c -o r.info
++
++    # 删除不需要的文件或路径
++    lcov -r r.info "$(pwd)/unit_test_*" "$(pwd)/../registeredSession/universalinterface.cpp" "/usr/include/*" "/opt/*" -o coverage.info
++
++    # 生成html覆盖率报告
++    genhtml "$(pwd)/coverage.info" -o result
++
++    # 打包
++    zip -r  result.zip result
++    # 上传平台
++    curl --insecure -X POST -F "file=@/$(pwd)/result.zip" -F "package=ukui-control-center" -F "username=hesisheng" $URL
++    echo "all parameter : $@"
++}
++
++# 编译项目
++echo "Compiling the project..."
++cmake . && make
++
++# 运行各个单元测试
++echo "Running unit tests..."
++run_unit_tests
++
++# 上传到平台
++#upload_result
++
++echo "All tests have been run successfully, and coverage data has been collected."
+diff --git a/tests/kt-test-utils/cpp-stub-ext/stub-shadow.cpp b/tests/kt-test-utils/cpp-stub-ext/stub-shadow.cpp
+new file mode 100644
+index 0000000..ff21dcd
+--- /dev/null
++++ b/tests/kt-test-utils/cpp-stub-ext/stub-shadow.cpp
+@@ -0,0 +1,58 @@
++/*
++ * Author:     Zhang Yu <clauszy@163.com>
++ * Maintainer: Zhang Yu <clauszy@163.com>
++ *
++ * MIT License
++ *
++ * Copyright (c) 2020 Zhang Yu
++ *
++ * Permission is hereby granted, free of charge, to any person obtaining a copy
++ * of this software and associated documentation files (the "Software"), to deal
++ * in the Software without restriction, including without limitation the rights
++ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
++ * copies of the Software, and to permit persons to whom the Software is
++ * furnished to do so, subject to the following conditions:
++ *
++ * The above copyright notice and this permission notice shall be included in all
++ * copies or substantial portions of the Software.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
++ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
++ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
++ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
++ * SOFTWARE.
++*/
++#include "stub-shadow.h"
++
++namespace stub_ext {
++
++WrapperMap stub_wrappers;
++
++Wrapper::Wrapper()
++{
++
++}
++
++Wrapper::~Wrapper()
++{
++
++}
++
++void freeWrapper(Wrapper *wrapper)
++{
++    if (!wrapper)
++        return;
++
++    for (auto iter = stub_wrappers.begin(); iter != stub_wrappers.end();) {
++        if (iter->second == wrapper)
++            iter = stub_wrappers.erase(iter);
++        else
++            ++iter;
++    }
++
++    delete wrapper;
++}
++}
++
+diff --git a/tests/kt-test-utils/cpp-stub-ext/stub-shadow.h b/tests/kt-test-utils/cpp-stub-ext/stub-shadow.h
+new file mode 100644
+index 0000000..04e746e
+--- /dev/null
++++ b/tests/kt-test-utils/cpp-stub-ext/stub-shadow.h
+@@ -0,0 +1,171 @@
++
++#ifndef STUBSHADOW_H
++#define STUBSHADOW_H
++/*
++ * Author:     Zhang Yu <clauszy@163.com>
++ * Maintainer: Zhang Yu <clauszy@163.com>
++ *
++ * MIT License
++ *
++ * Copyright (c) 2020 Zhang Yu
++ *
++ * Permission is hereby granted, free of charge, to any person obtaining a copy
++ * of this software and associated documentation files (the "Software"), to deal
++ * in the Software without restriction, including without limitation the rights
++ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
++ * copies of the Software, and to permit persons to whom the Software is
++ * furnished to do so, subject to the following conditions:
++ *
++ * The above copyright notice and this permission notice shall be included in all
++ * copies or substantial portions of the Software.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
++ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
++ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
++ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
++ * SOFTWARE.
++*/
++#include <unordered_map>
++#include <assert.h>
++
++namespace stub_ext {
++
++#define LAMDA_FUNCTION_TYPE decltype(&Lamda::operator())
++
++class Wrapper
++{
++public:
++    Wrapper();
++    virtual ~Wrapper();
++};
++
++typedef std::unordered_map<long, Wrapper* > WrapperMap;
++extern WrapperMap stub_wrappers;
++
++template<class Lamda>
++class LamdaWrapper : public Wrapper
++{
++public:
++    LamdaWrapper(Lamda func): Wrapper(),_func(func){}
++    ~LamdaWrapper(){}
++    Lamda _func;
++};
++
++template <typename Func>
++struct VFLocator
++{
++
++};
++
++template <class Obj, typename Ret, typename... Args>
++struct VFLocator<Ret (Obj::*)(Args...)>
++{
++    typedef Ret (*Func)(Obj*, Args...);
++};
++
++template <class Obj, typename Ret, typename... Args>
++struct VFLocator<Ret (Obj::*)(Args...) const>
++{
++    typedef Ret (*Func)(Obj*, Args...);
++};
++
++template <typename Func>
++struct LamdaCaller
++{
++
++};
++
++template <class Obj, typename Ret, typename... Args>
++struct LamdaCaller<Ret (Obj::*)(Args...) const>
++{
++    template<class Lamda, typename ...OrgArgs>
++    static Ret call(LamdaWrapper<Lamda> *wrapper, OrgArgs&&... args)
++    {
++        return wrapper->_func(std::forward<OrgArgs>(args)...);
++    }
++};
++
++template <class Obj, typename Ret>
++struct LamdaCaller<Ret (Obj::*)() const>
++{
++    template<class Lamda, typename ...OrgArgs>
++    static Ret call(LamdaWrapper<Lamda> *wrapper, OrgArgs&&... args)
++    {
++        return wrapper->_func();
++    }
++};
++
++template<typename Func, class Lamda>
++struct FuncShadow
++{
++
++};
++
++template<typename Ret, typename... Args, class Lamda>
++struct FuncShadow<Ret (*)(Args...), Lamda>
++{
++    typedef Ret (*Shadow)(Args...);
++    typedef Ret RetType;
++
++    static Ret call(Args ...args)
++    {
++       Shadow shadow = &call;
++       long id = (long)shadow;
++       auto iter = stub_wrappers.find(id);
++       assert(stub_wrappers.find(id) != stub_wrappers.end());
++       LamdaWrapper<Lamda> *wrapper = dynamic_cast<LamdaWrapper<Lamda> *>(iter->second);
++       return LamdaCaller<LAMDA_FUNCTION_TYPE>::call(wrapper, args...);
++    }
++};
++
++template<typename Ret, class Obj,typename... Args, class Lamda>
++struct FuncShadow<Ret (Obj::*)(Args...), Lamda>
++{
++    typedef Ret (*Shadow)(Obj *,Args...);
++    typedef Ret RetType;
++    static Ret call(Obj *obj, Args ...args)
++    {
++        Shadow shadow = &call;
++        long id = (long)shadow;
++        auto iter = stub_wrappers.find(id);
++        assert(stub_wrappers.find(id) != stub_wrappers.end());
++        LamdaWrapper<Lamda> *wrapper = dynamic_cast<LamdaWrapper<Lamda> *>(iter->second);
++        return LamdaCaller<LAMDA_FUNCTION_TYPE>::call(wrapper, obj, args...);
++    }
++};
++
++
++template<typename Ret, class Obj,typename... Args, class Lamda>
++struct FuncShadow<Ret (Obj::*)(Args...) const, Lamda>
++{
++    typedef Ret (*Shadow)(Obj *,Args...);
++    typedef Ret RetType;
++    static Ret call(Obj *obj, Args ...args)
++    {
++        Shadow shadow = &call;
++        long id = (long)shadow;
++        auto iter = stub_wrappers.find(id);
++        assert(stub_wrappers.find(id) != stub_wrappers.end());
++        LamdaWrapper<Lamda> *wrapper = dynamic_cast<LamdaWrapper<Lamda> *>(iter->second);
++        return LamdaCaller<LAMDA_FUNCTION_TYPE>::call(wrapper, obj, args...);
++    }
++};
++
++template<typename Func, class Lamda>
++typename FuncShadow<Func, Lamda>::Shadow depictShadow(Wrapper **wrapper, Func func, Lamda lamda)
++{
++    *wrapper = new LamdaWrapper<Lamda>(lamda);
++    typename FuncShadow<Func,Lamda>::Shadow shadow = &FuncShadow<Func,Lamda>::call;
++    long id = (long)shadow;
++    assert(stub_wrappers.find(id) == stub_wrappers.end());
++    stub_wrappers.insert(std::make_pair(id,*wrapper));
++    return shadow;
++}
++
++void freeWrapper(Wrapper *wrapper);
++
++}
++
++#endif // STUBSHADOW_H
+diff --git a/tests/kt-test-utils/cpp-stub-ext/stubext.h b/tests/kt-test-utils/cpp-stub-ext/stubext.h
+new file mode 100644
+index 0000000..2a70a78
+--- /dev/null
++++ b/tests/kt-test-utils/cpp-stub-ext/stubext.h
+@@ -0,0 +1,129 @@
++
++#ifndef STUBEXT_H
++#define STUBEXT_H
++/*
++ * Author:     Zhang Yu <clauszy@163.com>
++ * Maintainer: Zhang Yu <clauszy@163.com>
++ *
++ * MIT License
++ *
++ * Copyright (c) 2020 Zhang Yu
++ *
++ * Permission is hereby granted, free of charge, to any person obtaining a copy
++ * of this software and associated documentation files (the "Software"), to deal
++ * in the Software without restriction, including without limitation the rights
++ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
++ * copies of the Software, and to permit persons to whom the Software is
++ * furnished to do so, subject to the following conditions:
++ *
++ * The above copyright notice and this permission notice shall be included in all
++ * copies or substantial portions of the Software.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
++ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
++ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
++ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
++ * SOFTWARE.
++*/
++//需修改Stub的私用成员函数和成员变量为保护类型
++#include "stub.h"
++
++#include "stub-shadow.h"
++
++#ifdef DEBUG_STUB_INVOKE
++// use to make sure the stub function is invoked.
++#    define __DBG_STUB_INVOKE__ printf("stub at %s:%d is invoked.\n", __FILE__, __LINE__);
++#else
++#    define __DBG_STUB_INVOKE__
++#endif
++
++#define VADDR(CLASS_NAME, MEMBER_NAME) (typename stub_ext::VFLocator<decltype(&CLASS_NAME::MEMBER_NAME)>::Func)(&CLASS_NAME::MEMBER_NAME)
++
++namespace stub_ext {
++
++class StubExt : public Stub
++{
++public:
++    StubExt()
++        : Stub() { }
++
++    template<typename T, class Lamda>
++    bool set_lamda(T addr, Lamda lamda)
++    {
++        char *fn = addrof(addr);
++        if (m_result.find(fn) != m_result.end())
++            reset(addr);
++
++        Wrapper *wrapper = nullptr;
++        auto addr_stub = depictShadow(&wrapper, addr, lamda);
++        if (set(addr, addr_stub)) {
++            m_wrappers.insert(std::make_pair(fn, wrapper));
++            return true;
++        } else {
++            freeWrapper(wrapper);
++        }
++        return false;
++    }
++
++    template<typename T>
++    void reset(T addr)
++    {
++        Stub::reset(addr);
++        char *fn = addrof(addr);
++        auto iter = m_wrappers.find(fn);
++        if (iter != m_wrappers.end()) {
++            freeWrapper(iter->second);
++            m_wrappers.erase(iter);
++        }
++    }
++
++    ~StubExt()
++    {
++        clear();
++    }
++
++    void clear() override
++    {
++        Stub::clear();
++        for (auto iter = m_wrappers.begin(); iter != m_wrappers.end(); ++iter) {
++            freeWrapper(iter->second);
++        }
++        m_wrappers.clear();
++    }
++
++    template<class T>
++    static void *get_ctor_addr(bool start = true)
++    {
++        // the start vairable must be true, or the compiler will optimize out.
++        if (start) goto Start;
++    Call_Constructor:
++        // This line of code will not be executed.
++        // The purpose of the code is to allow the compiler to generate the assembly code that calls the constructor.
++        T();
++    Start:
++        // The address of the line of code T() obtained by assembly
++        char *p = (char *)&&Call_Constructor;   // https://gcc.gnu.org/onlinedocs/gcc/Labels-as-Values.html
++        // CALL rel32
++        void *ret = 0;
++        char pos;
++        char call = 0xe8;
++        do {
++            pos = *p;
++            if (pos == call) {
++                ret = p + 5 + (*(int *)(p + 1));
++            }
++
++        } while (!ret && (++p));
++
++        return ret;
++    }
++
++protected:
++    std::map<char *, Wrapper *> m_wrappers;
++};
++
++}
++
++#endif   // STUBEXT_H
+diff --git a/tests/kt-test-utils/cpp-stub/addr_any.h b/tests/kt-test-utils/cpp-stub/addr_any.h
+new file mode 100644
+index 0000000..a153f34
+--- /dev/null
++++ b/tests/kt-test-utils/cpp-stub/addr_any.h
+@@ -0,0 +1,280 @@
++#ifndef __ADDR_ANY_H__
++#define __ADDR_ANY_H__
++
++
++//linux
++#include <regex.h>
++#include <cxxabi.h>
++//c
++#include <cinttypes>
++#include <cstdio>
++#include <cstdlib>
++
++//c++
++#include <string>
++#include <map>
++//project
++#include "elfio.hpp"
++
++
++
++class AddrAny
++{
++public:
++    AddrAny()
++    {
++        m_init = get_exe_pathname(m_fullname);
++        m_baseaddr = 0;
++    }
++    AddrAny(std::string libname)
++    {
++        m_init = get_lib_pathname_and_baseaddr(libname, m_fullname, m_baseaddr);
++    }
++
++    int get_local_func_addr_symtab(std::string func_name_regex_str, std::map<std::string,void*>& result)
++    {
++        return get_func_addr(SHT_SYMTAB, STB_LOCAL, func_name_regex_str, result);
++    }
++    int get_global_func_addr_symtab(std::string func_name_regex_str, std::map<std::string,void*>& result)
++    {
++        return get_func_addr(SHT_SYMTAB, STB_GLOBAL, func_name_regex_str, result);
++    }
++    int get_weak_func_addr_symtab(std::string func_name_regex_str, std::map<std::string,void*>& result)
++    {
++        return get_func_addr(SHT_SYMTAB, STB_WEAK, func_name_regex_str, result);
++    }
++    
++    int get_global_func_addr_dynsym( std::string func_name_regex_str, std::map<std::string,void*>& result)
++    {
++        return get_func_addr(SHT_DYNSYM, STB_GLOBAL, func_name_regex_str, result);
++    }
++    int get_weak_func_addr_dynsym(std::string func_name_regex_str, std::map<std::string,void*>& result)
++    {
++        return get_func_addr(SHT_DYNSYM, STB_WEAK, func_name_regex_str, result);
++    }
++    
++private:
++    bool demangle(std::string& s, std::string& name) {
++        int status;
++        char* pname = abi::__cxa_demangle(s.c_str(), 0, 0, &status);
++        if (status != 0)
++        {
++            switch(status)
++            {
++                case -1: name = "memory allocation error"; break;
++                case -2: name = "invalid name given"; break;
++                case -3: name = "internal error: __cxa_demangle: invalid argument"; break;
++                default: name = "unknown error occured"; break;
++            }
++            return false;
++        }
++        name = pname;
++        free(pname);
++        return true;
++    }
++    bool get_exe_pathname( std::string& name)
++    {
++        char                     line[512];
++        FILE                    *fp;
++        uintptr_t                base_addr;
++        char                     perm[5];
++        unsigned long            offset;
++        int                      pathname_pos;
++        char                    *pathname;
++        size_t                   pathname_len;
++        int                      match = 0;
++        
++        if(NULL == (fp = fopen("/proc/self/maps", "r")))
++        {
++            return false;
++        }
++
++        while(fgets(line, sizeof(line), fp))
++        {
++            if(sscanf(line, "%" PRIxPTR "-%*lx %4s %lx %*x:%*x %*d%n", &base_addr, perm, &offset, &pathname_pos) != 3) continue;
++
++            if(0 != offset) continue;
++
++            //get pathname
++            while(isspace(line[pathname_pos]) && pathname_pos < (int)(sizeof(line) - 1))
++                pathname_pos += 1;
++            if(pathname_pos >= (int)(sizeof(line) - 1)) continue;
++            pathname = line + pathname_pos;
++            pathname_len = strlen(pathname);
++            if(0 == pathname_len) continue;
++            if(pathname[pathname_len - 1] == '\n')
++            {
++                pathname[pathname_len - 1] = '\0';
++                pathname_len -= 1;
++            }
++            if(0 == pathname_len) continue;
++            if('[' == pathname[0]) continue;
++
++            name = pathname;
++            match = 1;
++            break;
++
++        }
++        fclose(fp);
++
++        if(0 == match)
++        {
++            return false;
++        }
++        else
++        {
++            return true;
++        }
++
++    }
++
++    bool get_lib_pathname_and_baseaddr(std::string pathname_regex_str, std::string& name, unsigned long& addr)
++    {
++        char                     line[512];
++        FILE                    *fp;
++        uintptr_t                base_addr;
++        char                     perm[5];
++        unsigned long            offset;
++        int                      pathname_pos;
++        char                    *pathname;
++        size_t                   pathname_len;
++        int                      match;
++        regex_t   pathname_regex;
++
++        regcomp(&pathname_regex, pathname_regex_str.c_str(), 0);
++
++        if(NULL == (fp = fopen("/proc/self/maps", "r")))
++        {
++            return false;
++        }
++
++        while(fgets(line, sizeof(line), fp))
++        {
++            if(sscanf(line, "%" PRIxPTR "-%*lx %4s %lx %*x:%*x %*d%n", &base_addr, perm, &offset, &pathname_pos) != 3) continue;
++
++            //check permission
++            if(perm[0] != 'r') continue;
++            if(perm[3] != 'p') continue; //do not touch the shared memory
++
++            //check offset
++            //
++            //We are trying to find ELF header in memory.
++            //It can only be found at the beginning of a mapped memory regions
++            //whose offset is 0.
++            if(0 != offset) continue;
++
++            //get pathname
++            while(isspace(line[pathname_pos]) && pathname_pos < (int)(sizeof(line) - 1))
++                pathname_pos += 1;
++            if(pathname_pos >= (int)(sizeof(line) - 1)) continue;
++            pathname = line + pathname_pos;
++            pathname_len = strlen(pathname);
++            if(0 == pathname_len) continue;
++            if(pathname[pathname_len - 1] == '\n')
++            {
++                pathname[pathname_len - 1] = '\0';
++                pathname_len -= 1;
++            }
++            if(0 == pathname_len) continue;
++            if('[' == pathname[0]) continue;
++
++            //check pathname
++            //if we need to hook this elf?
++            match = 0;
++            if(0 == regexec(&pathname_regex, pathname, 0, NULL, 0))
++            {
++                match = 1;
++                name = pathname;
++                addr = (unsigned long)base_addr;
++                break;
++            }
++            if(0 == match) continue;
++
++        }
++        fclose(fp);
++        if(0 == match)
++        {
++            return false;
++        }
++        else
++        {
++            return true;
++        }
++
++    }
++
++    int get_func_addr(unsigned int ttype, unsigned int stype, std::string& func_name_regex_str, std::map<std::string,void*>& result)
++    {
++        // Create an elfio reader
++        ELFIO::elfio reader;
++        int count = 0;
++        regex_t   pathname_regex;
++
++        if(!m_init)
++        {
++            return -1;
++        }
++
++        regcomp(&pathname_regex, func_name_regex_str.c_str(), 0);
++        // Load ELF data
++        if(!reader.load(m_fullname.c_str()))
++        {
++            return -1;
++        }
++        
++        ELFIO::Elf_Half sec_num = reader.sections.size();
++        for(int i = 0; i < sec_num; ++i)
++        {
++            ELFIO::section* psec = reader.sections[i];
++            // Check section type
++            if(psec->get_type() == ttype)
++            {
++                const ELFIO::symbol_section_accessor symbols( reader, psec );
++                for ( unsigned int j = 0; j < symbols.get_symbols_num(); ++j )
++                {
++                    std::string name;
++                    std::string name_mangle;
++                    ELFIO::Elf64_Addr value;
++                    ELFIO::Elf_Xword size;
++                    unsigned char bind;
++                    unsigned char type;
++                    ELFIO::Elf_Half section_index;
++                    unsigned char other;
++                    
++                    // Read symbol properties
++                    symbols.get_symbol( j, name, value, size, bind, type, section_index, other );
++                    if(type == STT_FUNC && bind == stype)
++                    {
++                        bool ret = demangle(name,name_mangle);
++                        if(ret == true)
++                        {
++                            if (0 == regexec(&pathname_regex, name_mangle.c_str(), 0, NULL, 0))
++                            {
++                                  result.insert ( std::pair<std::string,void *>(name_mangle,(void*)(value + m_baseaddr)));
++                                  count++;
++                            }
++                        }
++                        else
++                        {
++                            if (0 == regexec(&pathname_regex, name.c_str(), 0, NULL, 0))
++                            {
++                                  result.insert ( std::pair<std::string,void *>(name,(void*)(value + m_baseaddr)));
++                                  count++;
++                            }
++                        }
++                    }
++                }
++                break;
++            }
++        }
++        
++        return count;
++    }
++private:
++    bool m_init;
++    std::string m_name;
++    std::string m_fullname;
++    unsigned long m_baseaddr;
++
++};
++#endif
+diff --git a/tests/kt-test-utils/cpp-stub/addr_pri.h b/tests/kt-test-utils/cpp-stub/addr_pri.h
+new file mode 100644
+index 0000000..9174bb0
+--- /dev/null
++++ b/tests/kt-test-utils/cpp-stub/addr_pri.h
+@@ -0,0 +1,177 @@
++#ifndef __ADDR_PRI_H__
++#define __ADDR_PRI_H__
++
++
++#include <utility>
++#include <type_traits>
++
++
++
++//base on C++11
++
++/**********************************************************
++             access private function
++**********************************************************/
++
++
++namespace std {
++  template <bool B, class T = void>
++  using enable_if_t = typename enable_if<B, T>::type;
++  template <class T>
++  using remove_reference_t = typename remove_reference<T>::type;
++} // std
++
++// Unnamed namespace is used to avoid duplicate symbols if the macros are used
++namespace {
++  namespace private_access_detail {
++
++    // @tparam TagType, used to declare different "get" funciton overloads for
++    // different members/statics
++    template <typename PtrType, PtrType PtrValue, typename TagType>
++    struct private_access {
++      // Normal lookup cannot find in-class defined (inline) friend functions.
++      friend PtrType get(TagType) { return PtrValue; }
++    };
++
++  } // namespace private_access_detail
++} // namespace
++
++// Used macro naming conventions:
++// The "namespace" of this macro library is PRIVATE_ACCESS, i.e. all
++// macro here has this prefix.
++// All implementation macro, which are not meant to be used directly have the
++// PRIVATE_ACCESS_DETAIL prefix.
++// Some macros have the ABCD_IMPL form, which means they contain the
++// implementation details for the specific ABCD macro.
++
++#define PRIVATE_ACCESS_DETAIL_CONCATENATE_IMPL(x, y) x##y
++#define PRIVATE_ACCESS_DETAIL_CONCATENATE(x, y)                                \
++  PRIVATE_ACCESS_DETAIL_CONCATENATE_IMPL(x, y)
++
++// @param PtrTypeKind E.g if we have "class A", then it can be "A::*" in case of
++// members, or it can be "*" in case of statics.
++#define PRIVATE_ACCESS_DETAIL_ACCESS_PRIVATE(Tag, Class, Type, Name,           \
++                                             PtrTypeKind)                      \
++  namespace {                                                                  \
++    namespace private_access_detail {                                          \
++      /* Tag type, used to declare different get funcitons for different       \
++       * members                                                               \
++       */                                                                      \
++      struct Tag {};                                                           \
++      /* Explicit instantiation */                                             \
++      template struct private_access<decltype(&Class::Name), &Class::Name,     \
++                                     Tag>;                                     \
++      /* We can build the PtrType only with two aliases */                     \
++      /* E.g. using PtrType = int(int) *; would be illformed */                \
++      using PRIVATE_ACCESS_DETAIL_CONCATENATE(Alias_, Tag) = Type;             \
++      using PRIVATE_ACCESS_DETAIL_CONCATENATE(PtrType_, Tag) =                 \
++          PRIVATE_ACCESS_DETAIL_CONCATENATE(Alias_, Tag) PtrTypeKind;          \
++      /* Declare the friend function, now it is visible in namespace scope.    \
++       * Note,                                                                 \
++       * we could declare it inside the Tag type too, in that case ADL would   \
++       * find                                                                  \
++       * the declaration. By choosing to declare it here, the Tag type remains \
++       * a                                                                     \
++       * simple tag type, it has no other responsibilities. */                 \
++      PRIVATE_ACCESS_DETAIL_CONCATENATE(PtrType_, Tag) get(Tag);               \
++    }                                                                          \
++  }
++
++#define PRIVATE_ACCESS_DETAIL_ACCESS_PRIVATE_FIELD(Tag, Class, Type, Name)     \
++  PRIVATE_ACCESS_DETAIL_ACCESS_PRIVATE(Tag, Class, Type, Name, Class::*)       \
++  namespace {                                                                  \
++    namespace access_private_field {                                                  \
++      Type &Class##Name(Class &&t) { return t.*get(private_access_detail::Tag{}); }   \
++      Type &Class##Name(Class &t) { return t.*get(private_access_detail::Tag{}); }    \
++      /* The following usings are here to avoid duplicate const qualifier      \
++       * warnings                                                              \
++       */                                                                      \
++      using PRIVATE_ACCESS_DETAIL_CONCATENATE(X, Tag) = Type;                  \
++      using PRIVATE_ACCESS_DETAIL_CONCATENATE(Y, Tag) =                        \
++          const PRIVATE_ACCESS_DETAIL_CONCATENATE(X, Tag);                     \
++      PRIVATE_ACCESS_DETAIL_CONCATENATE(Y, Tag) & Class##Name(const Class &t) {\
++        return t.*get(private_access_detail::Tag{});                           \
++      }                                                                        \
++    }                                                                          \
++  }
++
++#define PRIVATE_ACCESS_DETAIL_ACCESS_PRIVATE_FUN(Tag, Class, Type, Name)       \
++  PRIVATE_ACCESS_DETAIL_ACCESS_PRIVATE(Tag, Class, Type, Name, Class::*)       \
++  namespace {                                                                  \
++    namespace call_private_fun {                                               \
++      /* We do perfect forwarding, but we want to restrict the overload set    \
++       * only for objects which have the type Class. */                        \
++      template <typename Obj,                                                  \
++                std::enable_if_t<std::is_same<std::remove_reference_t<Obj>,    \
++                                              Class>::value> * = nullptr,      \
++                typename... Args>                                              \
++      auto Class##Name(Obj &&o, Args &&... args) -> decltype(                  \
++          (std::forward<Obj>(o).*                                              \
++           get(private_access_detail::Tag{}))(std::forward<Args>(args)...)) {  \
++        return (std::forward<Obj>(o).*get(private_access_detail::Tag{}))(      \
++            std::forward<Args>(args)...);                                      \
++      }                                                                        \
++    }                                                                          \
++    namespace get_private_fun {                                                \
++      auto Class##Name()  -> decltype(                                         \
++          get(private_access_detail::Tag{})) {                                 \
++        return (get(private_access_detail::Tag{}));                            \
++      }                                                                        \
++    }                                                                          \
++  }
++
++#define PRIVATE_ACCESS_DETAIL_ACCESS_PRIVATE_STATIC_FIELD(Tag, Class, Type,    \
++                                                          Name)                \
++  PRIVATE_ACCESS_DETAIL_ACCESS_PRIVATE(Tag, Class, Type, Name, *)              \
++  namespace {                                                                  \
++    namespace access_private_static_field {                                    \
++      namespace Class {                                                        \
++        Type &Class##Name() { return *get(private_access_detail::Tag{}); }     \
++      }                                                                        \
++    }                                                                          \
++  }
++
++#define PRIVATE_ACCESS_DETAIL_ACCESS_PRIVATE_STATIC_FUN(Tag, Class, Type,      \
++                                                        Name)                  \
++  PRIVATE_ACCESS_DETAIL_ACCESS_PRIVATE(Tag, Class, Type, Name, *)              \
++  namespace {                                                                  \
++    namespace call_private_static_fun {                                        \
++      namespace Class {                                                        \
++        template <typename... Args>                                            \
++        auto Class##Name(Args &&... args) -> decltype(                         \
++            get(private_access_detail::Tag{})(std::forward<Args>(args)...)) {  \
++          return get(private_access_detail::Tag{})(                            \
++              std::forward<Args>(args)...);                                    \
++        }                                                                      \
++      }                                                                        \
++    }                                                                          \
++    namespace get_private_static_fun {                                         \
++      namespace Class {                                                        \
++        auto Class##Name() -> decltype(get(private_access_detail::Tag{})) {    \
++          return get(private_access_detail::Tag{});                            \
++        }                                                                      \
++      }                                                                        \
++    }                                                                          \
++  }
++
++#define PRIVATE_ACCESS_DETAIL_UNIQUE_TAG                                       \
++  PRIVATE_ACCESS_DETAIL_CONCATENATE(PrivateAccessTag, __COUNTER__)
++
++#define ACCESS_PRIVATE_FIELD(Class, Type, Name)                                \
++  PRIVATE_ACCESS_DETAIL_ACCESS_PRIVATE_FIELD(PRIVATE_ACCESS_DETAIL_UNIQUE_TAG, \
++                                             Class, Type, Name)
++
++#define ACCESS_PRIVATE_FUN(Class, Type, Name)                                  \
++  PRIVATE_ACCESS_DETAIL_ACCESS_PRIVATE_FUN(PRIVATE_ACCESS_DETAIL_UNIQUE_TAG,   \
++                                           Class, Type, Name)
++
++#define ACCESS_PRIVATE_STATIC_FIELD(Class, Type, Name)                         \
++    Type Class::Name;                                                          \
++  PRIVATE_ACCESS_DETAIL_ACCESS_PRIVATE_STATIC_FIELD(                           \
++      PRIVATE_ACCESS_DETAIL_UNIQUE_TAG, Class, Type, Name)
++
++#define ACCESS_PRIVATE_STATIC_FUN(Class, Type, Name)                           \
++  PRIVATE_ACCESS_DETAIL_ACCESS_PRIVATE_STATIC_FUN(                             \
++      PRIVATE_ACCESS_DETAIL_UNIQUE_TAG, Class, Type, Name)
++
++#endif
+diff --git a/tests/kt-test-utils/cpp-stub/elfio.hpp b/tests/kt-test-utils/cpp-stub/elfio.hpp
+new file mode 100644
+index 0000000..dd5c9ae
+--- /dev/null
++++ b/tests/kt-test-utils/cpp-stub/elfio.hpp
+@@ -0,0 +1,4888 @@
++
++/*** Start of inlined file: elfio_dump.hpp ***/
++#ifndef ELFIO_DUMP_HPP
++#define ELFIO_DUMP_HPP
++
++#include <algorithm>
++#include <string>
++#include <ostream>
++#include <sstream>
++#include <iomanip>
++
++/*** Start of inlined file: elfio.hpp ***/
++#ifndef ELFIO_HPP
++#define ELFIO_HPP
++
++#ifdef _MSC_VER
++#pragma warning( push )
++#pragma warning( disable : 4996 )
++#pragma warning( disable : 4355 )
++#pragma warning( disable : 4244 )
++#endif
++
++#include <string>
++#include <iostream>
++#include <fstream>
++#include <functional>
++#include <algorithm>
++#include <vector>
++#include <deque>
++#include <iterator>
++
++
++/*** Start of inlined file: elf_types.hpp ***/
++#ifndef ELFTYPES_H
++#define ELFTYPES_H
++
++#ifndef ELFIO_NO_OWN_TYPES
++#if !defined( ELFIO_NO_CSTDINT ) && !defined( ELFIO_NO_INTTYPES )
++#include <stdint.h>
++#else
++typedef unsigned char    uint8_t;
++typedef signed char      int8_t;
++typedef unsigned short   uint16_t;
++typedef signed short     int16_t;
++#ifdef _MSC_VER
++typedef unsigned __int32 uint32_t;
++typedef signed __int32   int32_t;
++typedef unsigned __int64 uint64_t;
++typedef signed __int64   int64_t;
++#else
++typedef unsigned int       uint32_t;
++typedef signed int         int32_t;
++typedef unsigned long long uint64_t;
++typedef signed long long   int64_t;
++#endif // _MSC_VER
++#endif // ELFIO_NO_CSTDINT
++#endif // ELFIO_NO_OWN_TYPES
++
++namespace ELFIO {
++
++// Attention! Platform depended definitions.
++typedef uint16_t Elf_Half;
++typedef uint32_t Elf_Word;
++typedef int32_t  Elf_Sword;
++typedef uint64_t Elf_Xword;
++typedef int64_t  Elf_Sxword;
++
++typedef uint32_t Elf32_Addr;
++typedef uint32_t Elf32_Off;
++typedef uint64_t Elf64_Addr;
++typedef uint64_t Elf64_Off;
++
++#define Elf32_Half  Elf_Half
++#define Elf64_Half  Elf_Half
++#define Elf32_Word  Elf_Word
++#define Elf64_Word  Elf_Word
++#define Elf32_Sword Elf_Sword
++#define Elf64_Sword Elf_Sword
++
++///////////////////////
++// ELF Header Constants
++
++// File type
++#define ET_NONE   0
++#define ET_REL    1
++#define ET_EXEC   2
++#define ET_DYN    3
++#define ET_CORE   4
++#define ET_LOOS   0xFE00
++#define ET_HIOS   0xFEFF
++#define ET_LOPROC 0xFF00
++#define ET_HIPROC 0xFFFF
++
++#define EM_NONE  0 // No machine
++#define EM_M32   1 // AT&T WE 32100
++#define EM_SPARC 2 // SUN SPARC
++#define EM_386   3 // Intel 80386
++#define EM_68K   4 // Motorola m68k family
++#define EM_88K   5 // Motorola m88k family
++#define EM_486   6 // Intel 80486// Reserved for future use
++#define EM_860   7 // Intel 80860
++#define EM_MIPS  8 // MIPS R3000 (officially, big-endian only)
++#define EM_S370  9 // IBM System/370
++#define EM_MIPS_RS3_LE \
++	10 // MIPS R3000 little-endian (Oct 4 1999 Draft) Deprecated
++#define EM_res011      11 // Reserved
++#define EM_res012      12 // Reserved
++#define EM_res013      13 // Reserved
++#define EM_res014      14 // Reserved
++#define EM_PARISC      15 // HPPA
++#define EM_res016      16 // Reserved
++#define EM_VPP550      17 // Fujitsu VPP500
++#define EM_SPARC32PLUS 18 // Sun's "v8plus"
++#define EM_960         19 // Intel 80960
++#define EM_PPC         20 // PowerPC
++#define EM_PPC64       21 // 64-bit PowerPC
++#define EM_S390        22 // IBM S/390
++#define EM_SPU         23 // Sony/Toshiba/IBM SPU
++#define EM_res024      24 // Reserved
++#define EM_res025      25 // Reserved
++#define EM_res026      26 // Reserved
++#define EM_res027      27 // Reserved
++#define EM_res028      28 // Reserved
++#define EM_res029      29 // Reserved
++#define EM_res030      30 // Reserved
++#define EM_res031      31 // Reserved
++#define EM_res032      32 // Reserved
++#define EM_res033      33 // Reserved
++#define EM_res034      34 // Reserved
++#define EM_res035      35 // Reserved
++#define EM_V800        36 // NEC V800 series
++#define EM_FR20        37 // Fujitsu FR20
++#define EM_RH32        38 // TRW RH32
++#define EM_MCORE       39 // Motorola M*Core // May also be taken by Fujitsu MMA
++#define EM_RCE         39 // Old name for MCore
++#define EM_ARM         40 // ARM
++#define EM_OLD_ALPHA   41 // Digital Alpha
++#define EM_SH          42 // Renesas (formerly Hitachi) / SuperH SH
++#define EM_SPARCV9     43 // SPARC v9 64-bit
++#define EM_TRICORE     44 // Siemens Tricore embedded processor
++#define EM_ARC         45 // ARC Cores
++#define EM_H8_300      46 // Renesas (formerly Hitachi) H8/300
++#define EM_H8_300H     47 // Renesas (formerly Hitachi) H8/300H
++#define EM_H8S         48 // Renesas (formerly Hitachi) H8S
++#define EM_H8_500      49 // Renesas (formerly Hitachi) H8/500
++#define EM_IA_64       50 // Intel IA-64 Processor
++#define EM_MIPS_X      51 // Stanford MIPS-X
++#define EM_COLDFIRE    52 // Motorola Coldfire
++#define EM_68HC12      53 // Motorola M68HC12
++#define EM_MMA         54 // Fujitsu Multimedia Accelerator
++#define EM_PCP         55 // Siemens PCP
++#define EM_NCPU        56 // Sony nCPU embedded RISC processor
++#define EM_NDR1        57 // Denso NDR1 microprocesspr
++#define EM_STARCORE    58 // Motorola Star*Core processor
++#define EM_ME16        59 // Toyota ME16 processor
++#define EM_ST100       60 // STMicroelectronics ST100 processor
++#define EM_TINYJ       61 // Advanced Logic Corp. TinyJ embedded processor
++#define EM_X86_64      62 // Advanced Micro Devices X86-64 processor
++#define EM_PDSP        63 // Sony DSP Processor
++#define EM_PDP10       64 // Digital Equipment Corp. PDP-10
++#define EM_PDP11       65 // Digital Equipment Corp. PDP-11
++#define EM_FX66        66 // Siemens FX66 microcontroller
++#define EM_ST9PLUS     67 // STMicroelectronics ST9+ 8/16 bit microcontroller
++#define EM_ST7         68 // STMicroelectronics ST7 8-bit microcontroller
++#define EM_68HC16      69 // Motorola MC68HC16 Microcontroller
++#define EM_68HC11      70 // Motorola MC68HC11 Microcontroller
++#define EM_68HC08      71 // Motorola MC68HC08 Microcontroller
++#define EM_68HC05      72 // Motorola MC68HC05 Microcontroller
++#define EM_SVX         73 // Silicon Graphics SVx
++#define EM_ST19        74 // STMicroelectronics ST19 8-bit cpu
++#define EM_VAX         75 // Digital VAX
++#define EM_CRIS        76 // Axis Communications 32-bit embedded processor
++#define EM_JAVELIN     77 // Infineon Technologies 32-bit embedded cpu
++#define EM_FIREPATH    78 // Element 14 64-bit DSP processor
++#define EM_ZSP         79 // LSI Logic's 16-bit DSP processor
++#define EM_MMIX        80 // Donald Knuth's educational 64-bit processor
++#define EM_HUANY       81 // Harvard's machine-independent format
++#define EM_PRISM       82 // SiTera Prism
++#define EM_AVR         83 // Atmel AVR 8-bit microcontroller
++#define EM_FR30        84 // Fujitsu FR30
++#define EM_D10V        85 // Mitsubishi D10V
++#define EM_D30V        86 // Mitsubishi D30V
++#define EM_V850        87 // NEC v850
++#define EM_M32R        88 // Renesas M32R (formerly Mitsubishi M32R)
++#define EM_MN10300     89 // Matsushita MN10300
++#define EM_MN10200     90 // Matsushita MN10200
++#define EM_PJ          91 // picoJava
++#define EM_OPENRISC    92 // OpenRISC 32-bit embedded processor
++#define EM_ARC_A5      93 // ARC Cores Tangent-A5
++#define EM_XTENSA      94 // Tensilica Xtensa Architecture
++#define EM_VIDEOCORE   95 // Alphamosaic VideoCore processor
++#define EM_TMM_GPP     96 // Thompson Multimedia General Purpose Processor
++#define EM_NS32K       97 // National Semiconductor 32000 series
++#define EM_TPC         98 // Tenor Network TPC processor
++#define EM_SNP1K       99 // Trebia SNP 1000 processor
++#define EM_ST200       100 // STMicroelectronics ST200 microcontroller
++#define EM_IP2K        101 // Ubicom IP2022 micro controller
++#define EM_MAX         102 // MAX Processor
++#define EM_CR          103 // National Semiconductor CompactRISC
++#define EM_F2MC16      104 // Fujitsu F2MC16
++#define EM_MSP430      105 // TI msp430 micro controller
++#define EM_BLACKFIN    106 // ADI Blackfin
++#define EM_SE_C33      107 // S1C33 Family of Seiko Epson processors
++#define EM_SEP         108 // Sharp embedded microprocessor
++#define EM_ARCA        109 // Arca RISC Microprocessor
++#define EM_UNICORE \
++	110 // Microprocessor series from PKU-Unity Ltd. and MPRC of Peking University
++#define EM_EXCESS       111 // eXcess: 16/32/64-bit configurable embedded CPU
++#define EM_DXP          112 // Icera Semiconductor Inc. Deep Execution Processor
++#define EM_ALTERA_NIOS2 113 // Altera Nios II soft-core processor
++#define EM_CRX          114 // National Semiconductor CRX
++#define EM_XGATE        115 // Motorola XGATE embedded processor
++#define EM_C166         116 // Infineon C16x/XC16x processor
++#define EM_M16C         117 // Renesas M16C series microprocessors
++#define EM_DSPIC30F \
++	118 // Microchip Technology dsPIC30F Digital Signal Controller
++#define EM_CE            119 // Freescale Communication Engine RISC core
++#define EM_M32C          120 // Renesas M32C series microprocessors
++#define EM_res121        121 // Reserved
++#define EM_res122        122 // Reserved
++#define EM_res123        123 // Reserved
++#define EM_res124        124 // Reserved
++#define EM_res125        125 // Reserved
++#define EM_res126        126 // Reserved
++#define EM_res127        127 // Reserved
++#define EM_res128        128 // Reserved
++#define EM_res129        129 // Reserved
++#define EM_res130        130 // Reserved
++#define EM_TSK3000       131 // Altium TSK3000 core
++#define EM_RS08          132 // Freescale RS08 embedded processor
++#define EM_res133        133 // Reserved
++#define EM_ECOG2         134 // Cyan Technology eCOG2 microprocessor
++#define EM_SCORE         135 // Sunplus Score
++#define EM_SCORE7        135 // Sunplus S+core7 RISC processor
++#define EM_DSP24         136 // New Japan Radio (NJR) 24-bit DSP Processor
++#define EM_VIDEOCORE3    137 // Broadcom VideoCore III processor
++#define EM_LATTICEMICO32 138 // RISC processor for Lattice FPGA architecture
++#define EM_SE_C17        139 // Seiko Epson C17 family
++#define EM_TI_C6000      140 // Texas Instruments TMS320C6000 DSP family
++#define EM_TI_C2000      141 // Texas Instruments TMS320C2000 DSP family
++#define EM_TI_C5500      142 // Texas Instruments TMS320C55x DSP family
++#define EM_res143        143 // Reserved
++#define EM_res144        144 // Reserved
++#define EM_res145        145 // Reserved
++#define EM_res146        146 // Reserved
++#define EM_res147        147 // Reserved
++#define EM_res148        148 // Reserved
++#define EM_res149        149 // Reserved
++#define EM_res150        150 // Reserved
++#define EM_res151        151 // Reserved
++#define EM_res152        152 // Reserved
++#define EM_res153        153 // Reserved
++#define EM_res154        154 // Reserved
++#define EM_res155        155 // Reserved
++#define EM_res156        156 // Reserved
++#define EM_res157        157 // Reserved
++#define EM_res158        158 // Reserved
++#define EM_res159        159 // Reserved
++#define EM_MMDSP_PLUS    160 // STMicroelectronics 64bit VLIW Data Signal Processor
++#define EM_CYPRESS_M8C   161 // Cypress M8C microprocessor
++#define EM_R32C          162 // Renesas R32C series microprocessors
++#define EM_TRIMEDIA      163 // NXP Semiconductors TriMedia architecture family
++#define EM_QDSP6         164 // QUALCOMM DSP6 Processor
++#define EM_8051          165 // Intel 8051 and variants
++#define EM_STXP7X        166 // STMicroelectronics STxP7x family
++#define EM_NDS32 \
++	167 // Andes Technology compact code size embedded RISC processor family
++#define EM_ECOG1         168 // Cyan Technology eCOG1X family
++#define EM_ECOG1X        168 // Cyan Technology eCOG1X family
++#define EM_MAXQ30        169 // Dallas Semiconductor MAXQ30 Core Micro-controllers
++#define EM_XIMO16        170 // New Japan Radio (NJR) 16-bit DSP Processor
++#define EM_MANIK         171 // M2000 Reconfigurable RISC Microprocessor
++#define EM_CRAYNV2       172 // Cray Inc. NV2 vector architecture
++#define EM_RX            173 // Renesas RX family
++#define EM_METAG         174 // Imagination Technologies META processor architecture
++#define EM_MCST_ELBRUS   175 // MCST Elbrus general purpose hardware architecture
++#define EM_ECOG16        176 // Cyan Technology eCOG16 family
++#define EM_CR16          177 // National Semiconductor CompactRISC 16-bit processor
++#define EM_ETPU          178 // Freescale Extended Time Processing Unit
++#define EM_SLE9X         179 // Infineon Technologies SLE9X core
++#define EM_L1OM          180 // Intel L1OM
++#define EM_INTEL181      181 // Reserved by Intel
++#define EM_INTEL182      182 // Reserved by Intel
++#define EM_res183        183 // Reserved by ARM
++#define EM_res184        184 // Reserved by ARM
++#define EM_AVR32         185 // Atmel Corporation 32-bit microprocessor family
++#define EM_STM8          186 // STMicroeletronics STM8 8-bit microcontroller
++#define EM_TILE64        187 // Tilera TILE64 multicore architecture family
++#define EM_TILEPRO       188 // Tilera TILEPro multicore architecture family
++#define EM_MICROBLAZE    189 // Xilinx MicroBlaze 32-bit RISC soft processor core
++#define EM_CUDA          190 // NVIDIA CUDA architecture
++#define EM_TILEGX        191 // Tilera TILE-Gx multicore architecture family
++#define EM_CLOUDSHIELD   192 // CloudShield architecture family
++#define EM_COREA_1ST     193 // KIPO-KAIST Core-A 1st generation processor family
++#define EM_COREA_2ND     194 // KIPO-KAIST Core-A 2nd generation processor family
++#define EM_ARC_COMPACT2  195 // Synopsys ARCompact V2
++#define EM_OPEN8         196 // Open8 8-bit RISC soft processor core
++#define EM_RL78          197 // Renesas RL78 family
++#define EM_VIDEOCORE5    198 // Broadcom VideoCore V processor
++#define EM_78KOR         199 // Renesas 78KOR family
++#define EM_56800EX       200 // Freescale 56800EX Digital Signal Controller (DSC)
++#define EM_BA1           201 // Beyond BA1 CPU architecture
++#define EM_BA2           202 // Beyond BA2 CPU architecture
++#define EM_XCORE         203 // XMOS xCORE processor family
++#define EM_MCHP_PIC      204 // Microchip 8-bit PIC(r) family
++#define EM_INTEL205      205 // Reserved by Intel
++#define EM_INTEL206      206 // Reserved by Intel
++#define EM_INTEL207      207 // Reserved by Intel
++#define EM_INTEL208      208 // Reserved by Intel
++#define EM_INTEL209      209 // Reserved by Intel
++#define EM_KM32          210 // KM211 KM32 32-bit processor
++#define EM_KMX32         211 // KM211 KMX32 32-bit processor
++#define EM_KMX16         212 // KM211 KMX16 16-bit processor
++#define EM_KMX8          213 // KM211 KMX8 8-bit processor
++#define EM_KVARC         214 // KM211 KVARC processor
++#define EM_CDP           215 // Paneve CDP architecture family
++#define EM_COGE          216 // Cognitive Smart Memory Processor
++#define EM_COOL          217 // iCelero CoolEngine
++#define EM_NORC          218 // Nanoradio Optimized RISC
++#define EM_CSR_KALIMBA   219 // CSR Kalimba architecture family
++#define EM_Z80           220 // Zilog Z80
++#define EM_VISIUM        221 // Controls and Data Services VISIUMcore processor
++#define EM_FT32          222 // FTDI Chip FT32 high performance 32-bit RISC architecture
++#define EM_MOXIE         223 // Moxie processor family
++#define EM_AMDGPU        224 // AMD GPU architecture
++#define EM_RISCV         243 // RISC-V
++#define EM_LANAI         244 // Lanai processor
++#define EM_CEVA          245 // CEVA Processor Architecture Family
++#define EM_CEVA_X2       246 // CEVA X2 Processor Family
++#define EM_BPF           247 // Linux BPF – in-kernel virtual machine
++#define EM_GRAPHCORE_IPU 248 // Graphcore Intelligent Processing Unit
++#define EM_IMG1          249 // Imagination Technologies
++#define EM_NFP           250 // Netronome Flow Processor (P)
++#define EM_CSKY          252 // C-SKY processor family
++
++// File version
++#define EV_NONE    0
++#define EV_CURRENT 1
++
++// Identification index
++#define EI_MAG0       0
++#define EI_MAG1       1
++#define EI_MAG2       2
++#define EI_MAG3       3
++#define EI_CLASS      4
++#define EI_DATA       5
++#define EI_VERSION    6
++#define EI_OSABI      7
++#define EI_ABIVERSION 8
++#define EI_PAD        9
++#define EI_NIDENT     16
++
++// Magic number
++#define ELFMAG0 0x7F
++#define ELFMAG1 'E'
++#define ELFMAG2 'L'
++#define ELFMAG3 'F'
++
++// File class
++#define ELFCLASSNONE 0
++#define ELFCLASS32   1
++#define ELFCLASS64   2
++
++// Encoding
++#define ELFDATANONE 0
++#define ELFDATA2LSB 1
++#define ELFDATA2MSB 2
++
++// OS extensions
++#define ELFOSABI_NONE    0  // No extensions or unspecified
++#define ELFOSABI_HPUX    1  // Hewlett-Packard HP-UX
++#define ELFOSABI_NETBSD  2  // NetBSD
++#define ELFOSABI_LINUX   3  // Linux
++#define ELFOSABI_SOLARIS 6  // Sun Solaris
++#define ELFOSABI_AIX     7  // AIX
++#define ELFOSABI_IRIX    8  // IRIX
++#define ELFOSABI_FREEBSD 9  // FreeBSD
++#define ELFOSABI_TRU64   10 // Compaq TRU64 UNIX
++#define ELFOSABI_MODESTO 11 // Novell Modesto
++#define ELFOSABI_OPENBSD 12 // Open BSD
++#define ELFOSABI_OPENVMS 13 // Open VMS
++#define ELFOSABI_NSK     14 // Hewlett-Packard Non-Stop Kernel
++#define ELFOSABI_AROS    15 // Amiga Research OS
++#define ELFOSABI_FENIXOS 16 // The FenixOS highly scalable multi-core OS
++//                             64-255 Architecture-specific value range
++#define ELFOSABI_AMDGPU_HSA \
++	64 // AMDGPU OS for HSA compatible compute 	// kernels.
++#define ELFOSABI_AMDGPU_PAL \
++	65 // AMDGPU OS for AMD PAL compatible graphics  // shaders and compute kernels.
++#define ELFOSABI_AMDGPU_MESA3D \
++	66 // AMDGPU OS for Mesa3D compatible graphics 	// shaders and compute kernels.
++
++// AMDGPU specific e_flags
++#define EF_AMDGPU_MACH 0x0ff // AMDGPU processor selection mask.
++#define EF_AMDGPU_XNACK \
++	0x100 // Indicates if the XNACK target feature is   // enabled for all code contained in the ELF.
++// AMDGPU processors
++#define EF_AMDGPU_MACH_NONE                0x000 // Unspecified processor.
++#define EF_AMDGPU_MACH_R600_R600           0x001
++#define EF_AMDGPU_MACH_R600_R630           0x002
++#define EF_AMDGPU_MACH_R600_RS880          0x003
++#define EF_AMDGPU_MACH_R600_RV670          0x004
++#define EF_AMDGPU_MACH_R600_RV710          0x005
++#define EF_AMDGPU_MACH_R600_RV730          0x006
++#define EF_AMDGPU_MACH_R600_RV770          0x007
++#define EF_AMDGPU_MACH_R600_CEDAR          0x008
++#define EF_AMDGPU_MACH_R600_CYPRESS        0x009
++#define EF_AMDGPU_MACH_R600_JUNIPER        0x00a
++#define EF_AMDGPU_MACH_R600_REDWOOD        0x00b
++#define EF_AMDGPU_MACH_R600_SUMO           0x00c
++#define EF_AMDGPU_MACH_R600_BARTS          0x00d
++#define EF_AMDGPU_MACH_R600_CAICOS         0x00e
++#define EF_AMDGPU_MACH_R600_CAYMAN         0x00f
++#define EF_AMDGPU_MACH_R600_TURKS          0x010
++#define EF_AMDGPU_MACH_R600_RESERVED_FIRST 0x011
++#define EF_AMDGPU_MACH_R600_RESERVED_LAST  0x01f
++#define EF_AMDGPU_MACH_R600_FIRST          EF_AMDGPU_MACH_R600_R600
++#define EF_AMDGPU_MACH_R600_LAST           EF_AMDGPU_MACH_R600_TURKS
++#define EF_AMDGPU_MACH_AMDGCN_GFX600       0x020
++#define EF_AMDGPU_MACH_AMDGCN_GFX601       0x021
++#define EF_AMDGPU_MACH_AMDGCN_GFX700       0x022
++#define EF_AMDGPU_MACH_AMDGCN_GFX701       0x023
++#define EF_AMDGPU_MACH_AMDGCN_GFX702       0x024
++#define EF_AMDGPU_MACH_AMDGCN_GFX703       0x025
++#define EF_AMDGPU_MACH_AMDGCN_GFX704       0x026
++#define EF_AMDGPU_MACH_AMDGCN_GFX801       0x028
++#define EF_AMDGPU_MACH_AMDGCN_GFX802       0x029
++#define EF_AMDGPU_MACH_AMDGCN_GFX803       0x02a
++#define EF_AMDGPU_MACH_AMDGCN_GFX810       0x02b
++#define EF_AMDGPU_MACH_AMDGCN_GFX900       0x02c
++#define EF_AMDGPU_MACH_AMDGCN_GFX902       0x02d
++#define EF_AMDGPU_MACH_AMDGCN_GFX904       0x02e
++#define EF_AMDGPU_MACH_AMDGCN_GFX906       0x02f
++#define EF_AMDGPU_MACH_AMDGCN_RESERVED0    0x027
++#define EF_AMDGPU_MACH_AMDGCN_RESERVED1    0x030
++#define EF_AMDGPU_MACH_AMDGCN_FIRST        EF_AMDGPU_MACH_AMDGCN_GFX600
++#define EF_AMDGPU_MACH_AMDGCN_LAST         EF_AMDGPU_MACH_AMDGCN_GFX906
++
++/////////////////////
++// Sections constants
++
++// Section indexes
++#define SHN_UNDEF     0
++#define SHN_LORESERVE 0xFF00
++#define SHN_LOPROC    0xFF00
++#define SHN_HIPROC    0xFF1F
++#define SHN_LOOS      0xFF20
++#define SHN_HIOS      0xFF3F
++#define SHN_ABS       0xFFF1
++#define SHN_COMMON    0xFFF2
++#define SHN_XINDEX    0xFFFF
++#define SHN_HIRESERVE 0xFFFF
++
++// Section types
++#define SHT_NULL          0
++#define SHT_PROGBITS      1
++#define SHT_SYMTAB        2
++#define SHT_STRTAB        3
++#define SHT_RELA          4
++#define SHT_HASH          5
++#define SHT_DYNAMIC       6
++#define SHT_NOTE          7
++#define SHT_NOBITS        8
++#define SHT_REL           9
++#define SHT_SHLIB         10
++#define SHT_DYNSYM        11
++#define SHT_INIT_ARRAY    14
++#define SHT_FINI_ARRAY    15
++#define SHT_PREINIT_ARRAY 16
++#define SHT_GROUP         17
++#define SHT_SYMTAB_SHNDX  18
++#define SHT_LOOS          0x60000000
++#define SHT_HIOS          0x6fffffff
++#define SHT_LOPROC        0x70000000
++#define SHT_HIPROC        0x7FFFFFFF
++#define SHT_LOUSER        0x80000000
++#define SHT_HIUSER        0xFFFFFFFF
++
++// Section attribute flags
++#define SHF_WRITE            0x1
++#define SHF_ALLOC            0x2
++#define SHF_EXECINSTR        0x4
++#define SHF_MERGE            0x10
++#define SHF_STRINGS          0x20
++#define SHF_INFO_LINK        0x40
++#define SHF_LINK_ORDER       0x80
++#define SHF_OS_NONCONFORMING 0x100
++#define SHF_GROUP            0x200
++#define SHF_TLS              0x400
++#define SHF_MASKOS           0x0ff00000
++#define SHF_MASKPROC         0xF0000000
++
++// Section group flags
++#define GRP_COMDAT   0x1
++#define GRP_MASKOS   0x0ff00000
++#define GRP_MASKPROC 0xf0000000
++
++// Symbol binding
++#define STB_LOCAL    0
++#define STB_GLOBAL   1
++#define STB_WEAK     2
++#define STB_LOOS     10
++#define STB_HIOS     12
++#define STB_MULTIDEF 13
++#define STB_LOPROC   13
++#define STB_HIPROC   15
++
++// Note types
++#define NT_AMDGPU_METADATA         1
++#define NT_AMD_AMDGPU_HSA_METADATA 10
++#define NT_AMD_AMDGPU_ISA          11
++#define NT_AMD_AMDGPU_PAL_METADATA 12
++
++// Symbol types
++#define STT_NOTYPE            0
++#define STT_OBJECT            1
++#define STT_FUNC              2
++#define STT_SECTION           3
++#define STT_FILE              4
++#define STT_COMMON            5
++#define STT_TLS               6
++#define STT_LOOS              10
++#define STT_AMDGPU_HSA_KERNEL 10
++#define STT_HIOS              12
++#define STT_LOPROC            13
++#define STT_HIPROC            15
++
++// Symbol visibility
++#define STV_DEFAULT   0
++#define STV_INTERNAL  1
++#define STV_HIDDEN    2
++#define STV_PROTECTED 3
++
++// Undefined name
++#define STN_UNDEF 0
++
++// Relocation types
++#define R_386_NONE               0
++#define R_X86_64_NONE            0
++#define R_AMDGPU_NONE            0
++#define R_386_32                 1
++#define R_X86_64_64              1
++#define R_AMDGPU_ABS32_LO        1
++#define R_386_PC32               2
++#define R_X86_64_PC32            2
++#define R_AMDGPU_ABS32_HI        2
++#define R_386_GOT32              3
++#define R_X86_64_GOT32           3
++#define R_AMDGPU_ABS64           3
++#define R_386_PLT32              4
++#define R_X86_64_PLT32           4
++#define R_AMDGPU_REL32           4
++#define R_386_COPY               5
++#define R_X86_64_COPY            5
++#define R_AMDGPU_REL64           5
++#define R_386_GLOB_DAT           6
++#define R_X86_64_GLOB_DAT        6
++#define R_AMDGPU_ABS32           6
++#define R_386_JMP_SLOT           7
++#define R_X86_64_JUMP_SLOT       7
++#define R_AMDGPU_GOTPCREL        7
++#define R_386_RELATIVE           8
++#define R_X86_64_RELATIVE        8
++#define R_AMDGPU_GOTPCREL32_LO   8
++#define R_386_GOTOFF             9
++#define R_X86_64_GOTPCREL        9
++#define R_AMDGPU_GOTPCREL32_HI   9
++#define R_386_GOTPC              10
++#define R_X86_64_32              10
++#define R_AMDGPU_REL32_LO        10
++#define R_386_32PLT              11
++#define R_X86_64_32S             11
++#define R_AMDGPU_REL32_HI        11
++#define R_X86_64_16              12
++#define R_X86_64_PC16            13
++#define R_AMDGPU_RELATIVE64      13
++#define R_386_TLS_TPOFF          14
++#define R_X86_64_8               14
++#define R_386_TLS_IE             15
++#define R_X86_64_PC8             15
++#define R_386_TLS_GOTIE          16
++#define R_X86_64_DTPMOD64        16
++#define R_386_TLS_LE             17
++#define R_X86_64_DTPOFF64        17
++#define R_386_TLS_GD             18
++#define R_X86_64_TPOFF64         18
++#define R_386_TLS_LDM            19
++#define R_X86_64_TLSGD           19
++#define R_386_16                 20
++#define R_X86_64_TLSLD           20
++#define R_386_PC16               21
++#define R_X86_64_DTPOFF32        21
++#define R_386_8                  22
++#define R_X86_64_GOTTPOFF        22
++#define R_386_PC8                23
++#define R_X86_64_TPOFF32         23
++#define R_386_TLS_GD_32          24
++#define R_X86_64_PC64            24
++#define R_386_TLS_GD_PUSH        25
++#define R_X86_64_GOTOFF64        25
++#define R_386_TLS_GD_CALL        26
++#define R_X86_64_GOTPC32         26
++#define R_386_TLS_GD_POP         27
++#define R_X86_64_GOT64           27
++#define R_386_TLS_LDM_32         28
++#define R_X86_64_GOTPCREL64      28
++#define R_386_TLS_LDM_PUSH       29
++#define R_X86_64_GOTPC64         29
++#define R_386_TLS_LDM_CALL       30
++#define R_X86_64_GOTPLT64        30
++#define R_386_TLS_LDM_POP        31
++#define R_X86_64_PLTOFF64        31
++#define R_386_TLS_LDO_32         32
++#define R_386_TLS_IE_32          33
++#define R_386_TLS_LE_32          34
++#define R_X86_64_GOTPC32_TLSDESC 34
++#define R_386_TLS_DTPMOD32       35
++#define R_X86_64_TLSDESC_CALL    35
++#define R_386_TLS_DTPOFF32       36
++#define R_X86_64_TLSDESC         36
++#define R_386_TLS_TPOFF32        37
++#define R_X86_64_IRELATIVE       37
++#define R_386_SIZE32             38
++#define R_386_TLS_GOTDESC        39
++#define R_386_TLS_DESC_CALL      40
++#define R_386_TLS_DESC           41
++#define R_386_IRELATIVE          42
++#define R_386_GOT32X             43
++#define R_X86_64_GNU_VTINHERIT   250
++#define R_X86_64_GNU_VTENTRY     251
++
++// Segment types
++#define PT_NULL    0
++#define PT_LOAD    1
++#define PT_DYNAMIC 2
++#define PT_INTERP  3
++#define PT_NOTE    4
++#define PT_SHLIB   5
++#define PT_PHDR    6
++#define PT_TLS     7
++#define PT_LOOS    0x60000000
++#define PT_HIOS    0x6fffffff
++#define PT_LOPROC  0x70000000
++#define PT_HIPROC  0x7FFFFFFF
++
++// Segment flags
++#define PF_X        1          // Execute
++#define PF_W        2          // Write
++#define PF_R        4          // Read
++#define PF_MASKOS   0x0ff00000 // Unspecified
++#define PF_MASKPROC 0xf0000000 // Unspecified
++
++// Dynamic Array Tags
++#define DT_NULL            0
++#define DT_NEEDED          1
++#define DT_PLTRELSZ        2
++#define DT_PLTGOT          3
++#define DT_HASH            4
++#define DT_STRTAB          5
++#define DT_SYMTAB          6
++#define DT_RELA            7
++#define DT_RELASZ          8
++#define DT_RELAENT         9
++#define DT_STRSZ           10
++#define DT_SYMENT          11
++#define DT_INIT            12
++#define DT_FINI            13
++#define DT_SONAME          14
++#define DT_RPATH           15
++#define DT_SYMBOLIC        16
++#define DT_REL             17
++#define DT_RELSZ           18
++#define DT_RELENT          19
++#define DT_PLTREL          20
++#define DT_DEBUG           21
++#define DT_TEXTREL         22
++#define DT_JMPREL          23
++#define DT_BIND_NOW        24
++#define DT_INIT_ARRAY      25
++#define DT_FINI_ARRAY      26
++#define DT_INIT_ARRAYSZ    27
++#define DT_FINI_ARRAYSZ    28
++#define DT_RUNPATH         29
++#define DT_FLAGS           30
++#define DT_ENCODING        32
++#define DT_PREINIT_ARRAY   32
++#define DT_PREINIT_ARRAYSZ 33
++#define DT_MAXPOSTAGS      34
++#define DT_LOOS            0x6000000D
++#define DT_HIOS            0x6ffff000
++#define DT_LOPROC          0x70000000
++#define DT_HIPROC          0x7FFFFFFF
++
++// DT_FLAGS values
++#define DF_ORIGIN     0x1
++#define DF_SYMBOLIC   0x2
++#define DF_TEXTREL    0x4
++#define DF_BIND_NOW   0x8
++#define DF_STATIC_TLS 0x10
++
++// ELF file header
++struct Elf32_Ehdr
++{
++	unsigned char e_ident[EI_NIDENT];
++	Elf_Half      e_type;
++	Elf_Half      e_machine;
++	Elf_Word      e_version;
++	Elf32_Addr    e_entry;
++	Elf32_Off     e_phoff;
++	Elf32_Off     e_shoff;
++	Elf_Word      e_flags;
++	Elf_Half      e_ehsize;
++	Elf_Half      e_phentsize;
++	Elf_Half      e_phnum;
++	Elf_Half      e_shentsize;
++	Elf_Half      e_shnum;
++	Elf_Half      e_shstrndx;
++};
++
++struct Elf64_Ehdr
++{
++	unsigned char e_ident[EI_NIDENT];
++	Elf_Half      e_type;
++	Elf_Half      e_machine;
++	Elf_Word      e_version;
++	Elf64_Addr    e_entry;
++	Elf64_Off     e_phoff;
++	Elf64_Off     e_shoff;
++	Elf_Word      e_flags;
++	Elf_Half      e_ehsize;
++	Elf_Half      e_phentsize;
++	Elf_Half      e_phnum;
++	Elf_Half      e_shentsize;
++	Elf_Half      e_shnum;
++	Elf_Half      e_shstrndx;
++};
++
++// Section header
++struct Elf32_Shdr
++{
++	Elf_Word   sh_name;
++	Elf_Word   sh_type;
++	Elf_Word   sh_flags;
++	Elf32_Addr sh_addr;
++	Elf32_Off  sh_offset;
++	Elf_Word   sh_size;
++	Elf_Word   sh_link;
++	Elf_Word   sh_info;
++	Elf_Word   sh_addralign;
++	Elf_Word   sh_entsize;
++};
++
++struct Elf64_Shdr
++{
++	Elf_Word   sh_name;
++	Elf_Word   sh_type;
++	Elf_Xword  sh_flags;
++	Elf64_Addr sh_addr;
++	Elf64_Off  sh_offset;
++	Elf_Xword  sh_size;
++	Elf_Word   sh_link;
++	Elf_Word   sh_info;
++	Elf_Xword  sh_addralign;
++	Elf_Xword  sh_entsize;
++};
++
++// Segment header
++struct Elf32_Phdr
++{
++	Elf_Word   p_type;
++	Elf32_Off  p_offset;
++	Elf32_Addr p_vaddr;
++	Elf32_Addr p_paddr;
++	Elf_Word   p_filesz;
++	Elf_Word   p_memsz;
++	Elf_Word   p_flags;
++	Elf_Word   p_align;
++};
++
++struct Elf64_Phdr
++{
++	Elf_Word   p_type;
++	Elf_Word   p_flags;
++	Elf64_Off  p_offset;
++	Elf64_Addr p_vaddr;
++	Elf64_Addr p_paddr;
++	Elf_Xword  p_filesz;
++	Elf_Xword  p_memsz;
++	Elf_Xword  p_align;
++};
++
++// Symbol table entry
++struct Elf32_Sym
++{
++	Elf_Word      st_name;
++	Elf32_Addr    st_value;
++	Elf_Word      st_size;
++	unsigned char st_info;
++	unsigned char st_other;
++	Elf_Half      st_shndx;
++};
++
++struct Elf64_Sym
++{
++	Elf_Word      st_name;
++	unsigned char st_info;
++	unsigned char st_other;
++	Elf_Half      st_shndx;
++	Elf64_Addr    st_value;
++	Elf_Xword     st_size;
++};
++
++#define ELF_ST_BIND( i )    ( ( i ) >> 4 )
++#define ELF_ST_TYPE( i )    ( (i)&0xf )
++#define ELF_ST_INFO( b, t ) ( ( ( b ) << 4 ) + ( (t)&0xf ) )
++
++#define ELF_ST_VISIBILITY( o ) ( (o)&0x3 )
++
++// Relocation entries
++struct Elf32_Rel
++{
++	Elf32_Addr r_offset;
++	Elf_Word   r_info;
++};
++
++struct Elf32_Rela
++{
++	Elf32_Addr r_offset;
++	Elf_Word   r_info;
++	Elf_Sword  r_addend;
++};
++
++struct Elf64_Rel
++{
++	Elf64_Addr r_offset;
++	Elf_Xword  r_info;
++};
++
++struct Elf64_Rela
++{
++	Elf64_Addr r_offset;
++	Elf_Xword  r_info;
++	Elf_Sxword r_addend;
++};
++
++#define ELF32_R_SYM( i )     ( ( i ) >> 8 )
++#define ELF32_R_TYPE( i )    ( (unsigned char)( i ) )
++#define ELF32_R_INFO( s, t ) ( ( ( s ) << 8 ) + (unsigned char)( t ) )
++
++#define ELF64_R_SYM( i )  ( ( i ) >> 32 )
++#define ELF64_R_TYPE( i ) ( (i)&0xffffffffL )
++#define ELF64_R_INFO( s, t ) \
++	( ( ( ( int64_t )( s ) ) << 32 ) + ( (t)&0xffffffffL ) )
++
++// Dynamic structure
++struct Elf32_Dyn
++{
++	Elf_Sword d_tag;
++	union {
++		Elf_Word   d_val;
++		Elf32_Addr d_ptr;
++	} d_un;
++};
++
++struct Elf64_Dyn
++{
++	Elf_Sxword d_tag;
++	union {
++		Elf_Xword  d_val;
++		Elf64_Addr d_ptr;
++	} d_un;
++};
++
++} // namespace ELFIO
++
++#endif // ELFTYPES_H
++
++/*** End of inlined file: elf_types.hpp ***/
++
++
++/*** Start of inlined file: elfio_version.hpp ***/
++#define ELFIO_VERSION "3.8"
++
++/*** End of inlined file: elfio_version.hpp ***/
++
++
++/*** Start of inlined file: elfio_utils.hpp ***/
++#ifndef ELFIO_UTILS_HPP
++#define ELFIO_UTILS_HPP
++
++#define ELFIO_GET_ACCESS( TYPE, NAME, FIELD ) \
++	TYPE get_##NAME() const { return ( *convertor )( FIELD ); }
++#define ELFIO_SET_ACCESS( TYPE, NAME, FIELD ) \
++	void set_##NAME( TYPE value )             \
++	{                                         \
++		FIELD = value;                        \
++		FIELD = ( *convertor )( FIELD );      \
++	}
++#define ELFIO_GET_SET_ACCESS( TYPE, NAME, FIELD )               \
++	TYPE get_##NAME() const { return ( *convertor )( FIELD ); } \
++	void set_##NAME( TYPE value )                               \
++	{                                                           \
++		FIELD = value;                                          \
++		FIELD = ( *convertor )( FIELD );                        \
++	}
++
++#define ELFIO_GET_ACCESS_DECL( TYPE, NAME ) virtual TYPE get_##NAME() const = 0
++
++#define ELFIO_SET_ACCESS_DECL( TYPE, NAME ) \
++	virtual void set_##NAME( TYPE value ) = 0
++
++#define ELFIO_GET_SET_ACCESS_DECL( TYPE, NAME ) \
++	virtual TYPE get_##NAME() const       = 0;  \
++	virtual void set_##NAME( TYPE value ) = 0
++
++namespace ELFIO {
++
++//------------------------------------------------------------------------------
++class endianess_convertor
++{
++  public:
++	//------------------------------------------------------------------------------
++	endianess_convertor() { need_conversion = false; }
++
++	//------------------------------------------------------------------------------
++	void setup( unsigned char elf_file_encoding )
++	{
++		need_conversion = ( elf_file_encoding != get_host_encoding() );
++	}
++
++	//------------------------------------------------------------------------------
++	uint64_t operator()( uint64_t value ) const
++	{
++		if ( !need_conversion ) {
++			return value;
++		}
++		value = ( ( value & 0x00000000000000FFull ) << 56 ) |
++				( ( value & 0x000000000000FF00ull ) << 40 ) |
++				( ( value & 0x0000000000FF0000ull ) << 24 ) |
++				( ( value & 0x00000000FF000000ull ) << 8 ) |
++				( ( value & 0x000000FF00000000ull ) >> 8 ) |
++				( ( value & 0x0000FF0000000000ull ) >> 24 ) |
++				( ( value & 0x00FF000000000000ull ) >> 40 ) |
++				( ( value & 0xFF00000000000000ull ) >> 56 );
++
++		return value;
++	}
++
++	//------------------------------------------------------------------------------
++	int64_t operator()( int64_t value ) const
++	{
++		if ( !need_conversion ) {
++			return value;
++		}
++		return ( int64_t )( *this )( (uint64_t)value );
++	}
++
++	//------------------------------------------------------------------------------
++	uint32_t operator()( uint32_t value ) const
++	{
++		if ( !need_conversion ) {
++			return value;
++		}
++		value =
++			( ( value & 0x000000FF ) << 24 ) | ( ( value & 0x0000FF00 ) << 8 ) |
++			( ( value & 0x00FF0000 ) >> 8 ) | ( ( value & 0xFF000000 ) >> 24 );
++
++		return value;
++	}
++
++	//------------------------------------------------------------------------------
++	int32_t operator()( int32_t value ) const
++	{
++		if ( !need_conversion ) {
++			return value;
++		}
++		return ( int32_t )( *this )( (uint32_t)value );
++	}
++
++	//------------------------------------------------------------------------------
++	uint16_t operator()( uint16_t value ) const
++	{
++		if ( !need_conversion ) {
++			return value;
++		}
++		value = ( ( value & 0x00FF ) << 8 ) | ( ( value & 0xFF00 ) >> 8 );
++
++		return value;
++	}
++
++	//------------------------------------------------------------------------------
++	int16_t operator()( int16_t value ) const
++	{
++		if ( !need_conversion ) {
++			return value;
++		}
++		return ( int16_t )( *this )( (uint16_t)value );
++	}
++
++	//------------------------------------------------------------------------------
++	int8_t operator()( int8_t value ) const { return value; }
++
++	//------------------------------------------------------------------------------
++	uint8_t operator()( uint8_t value ) const { return value; }
++
++	//------------------------------------------------------------------------------
++  private:
++	//------------------------------------------------------------------------------
++	unsigned char get_host_encoding() const
++	{
++		static const int tmp = 1;
++		if ( 1 == *(const char*)&tmp ) {
++			return ELFDATA2LSB;
++		}
++		else {
++			return ELFDATA2MSB;
++		}
++	}
++
++	//------------------------------------------------------------------------------
++  private:
++	bool need_conversion;
++};
++
++//------------------------------------------------------------------------------
++inline uint32_t elf_hash( const unsigned char* name )
++{
++	uint32_t h = 0, g;
++	while ( *name ) {
++		h = ( h << 4 ) + *name++;
++		g = h & 0xf0000000;
++		if ( g != 0 )
++			h ^= g >> 24;
++		h &= ~g;
++	}
++	return h;
++}
++
++} // namespace ELFIO
++
++#endif // ELFIO_UTILS_HPP
++
++/*** End of inlined file: elfio_utils.hpp ***/
++
++
++/*** Start of inlined file: elfio_header.hpp ***/
++#ifndef ELF_HEADER_HPP
++#define ELF_HEADER_HPP
++
++#include <iostream>
++
++namespace ELFIO {
++
++class elf_header
++{
++  public:
++	virtual ~elf_header(){};
++	virtual bool load( std::istream& stream )       = 0;
++	virtual bool save( std::ostream& stream ) const = 0;
++
++	// ELF header functions
++	ELFIO_GET_ACCESS_DECL( unsigned char, class );
++	ELFIO_GET_ACCESS_DECL( unsigned char, elf_version );
++	ELFIO_GET_ACCESS_DECL( unsigned char, encoding );
++	ELFIO_GET_ACCESS_DECL( Elf_Half, header_size );
++	ELFIO_GET_ACCESS_DECL( Elf_Half, section_entry_size );
++	ELFIO_GET_ACCESS_DECL( Elf_Half, segment_entry_size );
++
++	ELFIO_GET_SET_ACCESS_DECL( Elf_Word, version );
++	ELFIO_GET_SET_ACCESS_DECL( unsigned char, os_abi );
++	ELFIO_GET_SET_ACCESS_DECL( unsigned char, abi_version );
++	ELFIO_GET_SET_ACCESS_DECL( Elf_Half, type );
++	ELFIO_GET_SET_ACCESS_DECL( Elf_Half, machine );
++	ELFIO_GET_SET_ACCESS_DECL( Elf_Word, flags );
++	ELFIO_GET_SET_ACCESS_DECL( Elf64_Addr, entry );
++	ELFIO_GET_SET_ACCESS_DECL( Elf_Half, sections_num );
++	ELFIO_GET_SET_ACCESS_DECL( Elf64_Off, sections_offset );
++	ELFIO_GET_SET_ACCESS_DECL( Elf_Half, segments_num );
++	ELFIO_GET_SET_ACCESS_DECL( Elf64_Off, segments_offset );
++	ELFIO_GET_SET_ACCESS_DECL( Elf_Half, section_name_str_index );
++};
++
++template <class T> struct elf_header_impl_types;
++template <> struct elf_header_impl_types<Elf32_Ehdr>
++{
++	typedef Elf32_Phdr         Phdr_type;
++	typedef Elf32_Shdr         Shdr_type;
++	static const unsigned char file_class = ELFCLASS32;
++};
++template <> struct elf_header_impl_types<Elf64_Ehdr>
++{
++	typedef Elf64_Phdr         Phdr_type;
++	typedef Elf64_Shdr         Shdr_type;
++	static const unsigned char file_class = ELFCLASS64;
++};
++
++template <class T> class elf_header_impl : public elf_header
++{
++  public:
++	//------------------------------------------------------------------------------
++	elf_header_impl( endianess_convertor* convertor_, unsigned char encoding )
++	{
++		convertor = convertor_;
++
++		std::fill_n( reinterpret_cast<char*>( &header ), sizeof( header ),
++					 '\0' );
++
++		header.e_ident[EI_MAG0]    = ELFMAG0;
++		header.e_ident[EI_MAG1]    = ELFMAG1;
++		header.e_ident[EI_MAG2]    = ELFMAG2;
++		header.e_ident[EI_MAG3]    = ELFMAG3;
++		header.e_ident[EI_CLASS]   = elf_header_impl_types<T>::file_class;
++		header.e_ident[EI_DATA]    = encoding;
++		header.e_ident[EI_VERSION] = EV_CURRENT;
++		header.e_version           = ( *convertor )( (Elf_Word)EV_CURRENT );
++		header.e_ehsize            = ( sizeof( header ) );
++		header.e_ehsize            = ( *convertor )( header.e_ehsize );
++		header.e_shstrndx          = ( *convertor )( (Elf_Half)1 );
++		header.e_phentsize =
++			sizeof( typename elf_header_impl_types<T>::Phdr_type );
++		header.e_shentsize =
++			sizeof( typename elf_header_impl_types<T>::Shdr_type );
++		header.e_phentsize = ( *convertor )( header.e_phentsize );
++		header.e_shentsize = ( *convertor )( header.e_shentsize );
++	}
++
++	//------------------------------------------------------------------------------
++	bool load( std::istream& stream )
++	{
++		stream.seekg( 0 );
++		stream.read( reinterpret_cast<char*>( &header ), sizeof( header ) );
++
++		return ( stream.gcount() == sizeof( header ) );
++	}
++
++	//------------------------------------------------------------------------------
++	bool save( std::ostream& stream ) const
++	{
++		stream.seekp( 0 );
++		stream.write( reinterpret_cast<const char*>( &header ),
++					  sizeof( header ) );
++
++		return stream.good();
++	}
++
++	//------------------------------------------------------------------------------
++	// ELF header functions
++	ELFIO_GET_ACCESS( unsigned char, class, header.e_ident[EI_CLASS] );
++	ELFIO_GET_ACCESS( unsigned char, elf_version, header.e_ident[EI_VERSION] );
++	ELFIO_GET_ACCESS( unsigned char, encoding, header.e_ident[EI_DATA] );
++	ELFIO_GET_ACCESS( Elf_Half, header_size, header.e_ehsize );
++	ELFIO_GET_ACCESS( Elf_Half, section_entry_size, header.e_shentsize );
++	ELFIO_GET_ACCESS( Elf_Half, segment_entry_size, header.e_phentsize );
++
++	ELFIO_GET_SET_ACCESS( Elf_Word, version, header.e_version );
++	ELFIO_GET_SET_ACCESS( unsigned char, os_abi, header.e_ident[EI_OSABI] );
++	ELFIO_GET_SET_ACCESS( unsigned char,
++						  abi_version,
++						  header.e_ident[EI_ABIVERSION] );
++	ELFIO_GET_SET_ACCESS( Elf_Half, type, header.e_type );
++	ELFIO_GET_SET_ACCESS( Elf_Half, machine, header.e_machine );
++	ELFIO_GET_SET_ACCESS( Elf_Word, flags, header.e_flags );
++	ELFIO_GET_SET_ACCESS( Elf_Half, section_name_str_index, header.e_shstrndx );
++	ELFIO_GET_SET_ACCESS( Elf64_Addr, entry, header.e_entry );
++	ELFIO_GET_SET_ACCESS( Elf_Half, sections_num, header.e_shnum );
++	ELFIO_GET_SET_ACCESS( Elf64_Off, sections_offset, header.e_shoff );
++	ELFIO_GET_SET_ACCESS( Elf_Half, segments_num, header.e_phnum );
++	ELFIO_GET_SET_ACCESS( Elf64_Off, segments_offset, header.e_phoff );
++
++  private:
++	T                    header;
++	endianess_convertor* convertor;
++};
++
++} // namespace ELFIO
++
++#endif // ELF_HEADER_HPP
++
++/*** End of inlined file: elfio_header.hpp ***/
++
++
++/*** Start of inlined file: elfio_section.hpp ***/
++#ifndef ELFIO_SECTION_HPP
++#define ELFIO_SECTION_HPP
++
++#include <string>
++#include <iostream>
++#include <new>
++
++namespace ELFIO {
++
++class section
++{
++	friend class elfio;
++
++  public:
++	virtual ~section(){};
++
++	ELFIO_GET_ACCESS_DECL( Elf_Half, index );
++	ELFIO_GET_SET_ACCESS_DECL( std::string, name );
++	ELFIO_GET_SET_ACCESS_DECL( Elf_Word, type );
++	ELFIO_GET_SET_ACCESS_DECL( Elf_Xword, flags );
++	ELFIO_GET_SET_ACCESS_DECL( Elf_Word, info );
++	ELFIO_GET_SET_ACCESS_DECL( Elf_Word, link );
++	ELFIO_GET_SET_ACCESS_DECL( Elf_Xword, addr_align );
++	ELFIO_GET_SET_ACCESS_DECL( Elf_Xword, entry_size );
++	ELFIO_GET_SET_ACCESS_DECL( Elf64_Addr, address );
++	ELFIO_GET_SET_ACCESS_DECL( Elf_Xword, size );
++	ELFIO_GET_SET_ACCESS_DECL( Elf_Word, name_string_offset );
++	ELFIO_GET_ACCESS_DECL( Elf64_Off, offset );
++
++	virtual const char* get_data() const                                = 0;
++	virtual void        set_data( const char* pData, Elf_Word size )    = 0;
++	virtual void        set_data( const std::string& data )             = 0;
++	virtual void        append_data( const char* pData, Elf_Word size ) = 0;
++	virtual void        append_data( const std::string& data )          = 0;
++	virtual size_t      get_stream_size() const                         = 0;
++	virtual void        set_stream_size( size_t value )                 = 0;
++
++  protected:
++	ELFIO_SET_ACCESS_DECL( Elf64_Off, offset );
++	ELFIO_SET_ACCESS_DECL( Elf_Half, index );
++
++	virtual void load( std::istream& stream, std::streampos header_offset ) = 0;
++	virtual void save( std::ostream&  stream,
++					   std::streampos header_offset,
++					   std::streampos data_offset )                         = 0;
++	virtual bool is_address_initialized() const                             = 0;
++};
++
++template <class T> class section_impl : public section
++{
++  public:
++	//------------------------------------------------------------------------------
++	section_impl( const endianess_convertor* convertor_ )
++		: convertor( convertor_ )
++	{
++		std::fill_n( reinterpret_cast<char*>( &header ), sizeof( header ),
++					 '\0' );
++		is_address_set = false;
++		data           = 0;
++		data_size      = 0;
++		index          = 0;
++		stream_size    = 0;
++	}
++
++	//------------------------------------------------------------------------------
++	~section_impl() { delete[] data; }
++
++	//------------------------------------------------------------------------------
++	// Section info functions
++	ELFIO_GET_SET_ACCESS( Elf_Word, type, header.sh_type );
++	ELFIO_GET_SET_ACCESS( Elf_Xword, flags, header.sh_flags );
++	ELFIO_GET_SET_ACCESS( Elf_Xword, size, header.sh_size );
++	ELFIO_GET_SET_ACCESS( Elf_Word, link, header.sh_link );
++	ELFIO_GET_SET_ACCESS( Elf_Word, info, header.sh_info );
++	ELFIO_GET_SET_ACCESS( Elf_Xword, addr_align, header.sh_addralign );
++	ELFIO_GET_SET_ACCESS( Elf_Xword, entry_size, header.sh_entsize );
++	ELFIO_GET_SET_ACCESS( Elf_Word, name_string_offset, header.sh_name );
++	ELFIO_GET_ACCESS( Elf64_Addr, address, header.sh_addr );
++
++	//------------------------------------------------------------------------------
++	Elf_Half get_index() const { return index; }
++
++	//------------------------------------------------------------------------------
++	std::string get_name() const { return name; }
++
++	//------------------------------------------------------------------------------
++	void set_name( std::string name_ ) { name = name_; }
++
++	//------------------------------------------------------------------------------
++	void set_address( Elf64_Addr value )
++	{
++		header.sh_addr = value;
++		header.sh_addr = ( *convertor )( header.sh_addr );
++		is_address_set = true;
++	}
++
++	//------------------------------------------------------------------------------
++	bool is_address_initialized() const { return is_address_set; }
++
++	//------------------------------------------------------------------------------
++	const char* get_data() const { return data; }
++
++	//------------------------------------------------------------------------------
++	void set_data( const char* raw_data, Elf_Word size )
++	{
++		if ( get_type() != SHT_NOBITS ) {
++			delete[] data;
++			data = new ( std::nothrow ) char[size];
++			if ( 0 != data && 0 != raw_data ) {
++				data_size = size;
++				std::copy( raw_data, raw_data + size, data );
++			}
++			else {
++				data_size = 0;
++			}
++		}
++
++		set_size( data_size );
++	}
++
++	//------------------------------------------------------------------------------
++	void set_data( const std::string& str_data )
++	{
++		return set_data( str_data.c_str(), (Elf_Word)str_data.size() );
++	}
++
++	//------------------------------------------------------------------------------
++	void append_data( const char* raw_data, Elf_Word size )
++	{
++		if ( get_type() != SHT_NOBITS ) {
++			if ( get_size() + size < data_size ) {
++				std::copy( raw_data, raw_data + size, data + get_size() );
++			}
++			else {
++				data_size      = 2 * ( data_size + size );
++				char* new_data = new ( std::nothrow ) char[data_size];
++
++				if ( 0 != new_data ) {
++					std::copy( data, data + get_size(), new_data );
++					std::copy( raw_data, raw_data + size,
++							   new_data + get_size() );
++					delete[] data;
++					data = new_data;
++				}
++				else {
++					size = 0;
++				}
++			}
++			set_size( get_size() + size );
++		}
++	}
++
++	//------------------------------------------------------------------------------
++	void append_data( const std::string& str_data )
++	{
++		return append_data( str_data.c_str(), (Elf_Word)str_data.size() );
++	}
++
++	//------------------------------------------------------------------------------
++  protected:
++	//------------------------------------------------------------------------------
++	ELFIO_GET_SET_ACCESS( Elf64_Off, offset, header.sh_offset );
++
++	//------------------------------------------------------------------------------
++	void set_index( Elf_Half value ) { index = value; }
++
++	//------------------------------------------------------------------------------
++	void load( std::istream& stream, std::streampos header_offset )
++	{
++		std::fill_n( reinterpret_cast<char*>( &header ), sizeof( header ),
++					 '\0' );
++
++		stream.seekg( 0, stream.end );
++		set_stream_size( stream.tellg() );
++
++		stream.seekg( header_offset );
++		stream.read( reinterpret_cast<char*>( &header ), sizeof( header ) );
++
++		Elf_Xword size = get_size();
++		if ( 0 == data && SHT_NULL != get_type() && SHT_NOBITS != get_type() &&
++			 size < get_stream_size() ) {
++			data = new ( std::nothrow ) char[size + 1];
++
++			if ( ( 0 != size ) && ( 0 != data ) ) {
++				stream.seekg( ( *convertor )( header.sh_offset ) );
++				stream.read( data, size );
++				data[size] = 0; // Ensure data is ended with 0 to avoid oob read
++				data_size  = size;
++			}
++			else {
++				data_size = 0;
++			}
++		}
++	}
++
++	//------------------------------------------------------------------------------
++	void save( std::ostream&  stream,
++			   std::streampos header_offset,
++			   std::streampos data_offset )
++	{
++		if ( 0 != get_index() ) {
++			header.sh_offset = data_offset;
++			header.sh_offset = ( *convertor )( header.sh_offset );
++		}
++
++		save_header( stream, header_offset );
++		if ( get_type() != SHT_NOBITS && get_type() != SHT_NULL &&
++			 get_size() != 0 && data != 0 ) {
++			save_data( stream, data_offset );
++		}
++	}
++
++	//------------------------------------------------------------------------------
++  private:
++	//------------------------------------------------------------------------------
++	void save_header( std::ostream& stream, std::streampos header_offset ) const
++	{
++		stream.seekp( header_offset );
++		stream.write( reinterpret_cast<const char*>( &header ),
++					  sizeof( header ) );
++	}
++
++	//------------------------------------------------------------------------------
++	void save_data( std::ostream& stream, std::streampos data_offset ) const
++	{
++		stream.seekp( data_offset );
++		stream.write( get_data(), get_size() );
++	}
++
++	//------------------------------------------------------------------------------
++	size_t get_stream_size() const { return stream_size; }
++
++	//------------------------------------------------------------------------------
++	void set_stream_size( size_t value ) { stream_size = value; }
++
++	//------------------------------------------------------------------------------
++  private:
++	T                          header;
++	Elf_Half                   index;
++	std::string                name;
++	char*                      data;
++	Elf_Word                   data_size;
++	const endianess_convertor* convertor;
++	bool                       is_address_set;
++	size_t                     stream_size;
++};
++
++} // namespace ELFIO
++
++#endif // ELFIO_SECTION_HPP
++
++/*** End of inlined file: elfio_section.hpp ***/
++
++
++/*** Start of inlined file: elfio_segment.hpp ***/
++#ifndef ELFIO_SEGMENT_HPP
++#define ELFIO_SEGMENT_HPP
++
++#include <iostream>
++#include <vector>
++#include <new>
++
++namespace ELFIO {
++
++class segment
++{
++	friend class elfio;
++
++  public:
++	virtual ~segment(){};
++
++	ELFIO_GET_ACCESS_DECL( Elf_Half, index );
++	ELFIO_GET_SET_ACCESS_DECL( Elf_Word, type );
++	ELFIO_GET_SET_ACCESS_DECL( Elf_Word, flags );
++	ELFIO_GET_SET_ACCESS_DECL( Elf_Xword, align );
++	ELFIO_GET_SET_ACCESS_DECL( Elf64_Addr, virtual_address );
++	ELFIO_GET_SET_ACCESS_DECL( Elf64_Addr, physical_address );
++	ELFIO_GET_SET_ACCESS_DECL( Elf_Xword, file_size );
++	ELFIO_GET_SET_ACCESS_DECL( Elf_Xword, memory_size );
++	ELFIO_GET_ACCESS_DECL( Elf64_Off, offset );
++
++	virtual const char* get_data() const = 0;
++
++	virtual Elf_Half add_section_index( Elf_Half  index,
++										Elf_Xword addr_align )  = 0;
++	virtual Elf_Half get_sections_num() const                   = 0;
++	virtual Elf_Half get_section_index_at( Elf_Half num ) const = 0;
++	virtual bool     is_offset_initialized() const              = 0;
++
++  protected:
++	ELFIO_SET_ACCESS_DECL( Elf64_Off, offset );
++	ELFIO_SET_ACCESS_DECL( Elf_Half, index );
++
++	virtual const std::vector<Elf_Half>& get_sections() const               = 0;
++	virtual void load( std::istream& stream, std::streampos header_offset ) = 0;
++	virtual void save( std::ostream&  stream,
++					   std::streampos header_offset,
++					   std::streampos data_offset )                         = 0;
++};
++
++//------------------------------------------------------------------------------
++template <class T> class segment_impl : public segment
++{
++  public:
++	//------------------------------------------------------------------------------
++	segment_impl( endianess_convertor* convertor_ )
++		: stream_size( 0 ), index( 0 ), data( 0 ), convertor( convertor_ )
++	{
++		is_offset_set = false;
++		std::fill_n( reinterpret_cast<char*>( &ph ), sizeof( ph ), '\0' );
++	}
++
++	//------------------------------------------------------------------------------
++	virtual ~segment_impl() { delete[] data; }
++
++	//------------------------------------------------------------------------------
++	// Section info functions
++	ELFIO_GET_SET_ACCESS( Elf_Word, type, ph.p_type );
++	ELFIO_GET_SET_ACCESS( Elf_Word, flags, ph.p_flags );
++	ELFIO_GET_SET_ACCESS( Elf_Xword, align, ph.p_align );
++	ELFIO_GET_SET_ACCESS( Elf64_Addr, virtual_address, ph.p_vaddr );
++	ELFIO_GET_SET_ACCESS( Elf64_Addr, physical_address, ph.p_paddr );
++	ELFIO_GET_SET_ACCESS( Elf_Xword, file_size, ph.p_filesz );
++	ELFIO_GET_SET_ACCESS( Elf_Xword, memory_size, ph.p_memsz );
++	ELFIO_GET_ACCESS( Elf64_Off, offset, ph.p_offset );
++	size_t stream_size;
++
++	//------------------------------------------------------------------------------
++	size_t get_stream_size() const { return stream_size; }
++
++	//------------------------------------------------------------------------------
++	void set_stream_size( size_t value ) { stream_size = value; }
++
++	//------------------------------------------------------------------------------
++	Elf_Half get_index() const { return index; }
++
++	//------------------------------------------------------------------------------
++	const char* get_data() const { return data; }
++
++	//------------------------------------------------------------------------------
++	Elf_Half add_section_index( Elf_Half sec_index, Elf_Xword addr_align )
++	{
++		sections.push_back( sec_index );
++		if ( addr_align > get_align() ) {
++			set_align( addr_align );
++		}
++
++		return (Elf_Half)sections.size();
++	}
++
++	//------------------------------------------------------------------------------
++	Elf_Half get_sections_num() const { return (Elf_Half)sections.size(); }
++
++	//------------------------------------------------------------------------------
++	Elf_Half get_section_index_at( Elf_Half num ) const
++	{
++		if ( num < sections.size() ) {
++			return sections[num];
++		}
++
++		return Elf_Half( -1 );
++	}
++
++	//------------------------------------------------------------------------------
++  protected:
++	//------------------------------------------------------------------------------
++
++	//------------------------------------------------------------------------------
++	void set_offset( Elf64_Off value )
++	{
++		ph.p_offset   = value;
++		ph.p_offset   = ( *convertor )( ph.p_offset );
++		is_offset_set = true;
++	}
++
++	//------------------------------------------------------------------------------
++	bool is_offset_initialized() const { return is_offset_set; }
++
++	//------------------------------------------------------------------------------
++	const std::vector<Elf_Half>& get_sections() const { return sections; }
++
++	//------------------------------------------------------------------------------
++	void set_index( Elf_Half value ) { index = value; }
++
++	//------------------------------------------------------------------------------
++	void load( std::istream& stream, std::streampos header_offset )
++	{
++
++		stream.seekg( 0, stream.end );
++		set_stream_size( stream.tellg() );
++
++		stream.seekg( header_offset );
++		stream.read( reinterpret_cast<char*>( &ph ), sizeof( ph ) );
++		is_offset_set = true;
++
++		if ( PT_NULL != get_type() && 0 != get_file_size() ) {
++			stream.seekg( ( *convertor )( ph.p_offset ) );
++			Elf_Xword size = get_file_size();
++
++			if ( size > get_stream_size() ) {
++				data = 0;
++			}
++			else {
++				data = new (std::nothrow) char[size + 1];
++
++				if ( 0 != data ) {
++					stream.read( data, size );
++					data[size] = 0;
++				}
++			}
++		}
++	}
++
++	//------------------------------------------------------------------------------
++	void save( std::ostream&  stream,
++			   std::streampos header_offset,
++			   std::streampos data_offset )
++	{
++		ph.p_offset = data_offset;
++		ph.p_offset = ( *convertor )( ph.p_offset );
++		stream.seekp( header_offset );
++		stream.write( reinterpret_cast<const char*>( &ph ), sizeof( ph ) );
++	}
++
++	//------------------------------------------------------------------------------
++  private:
++	T                     ph;
++	Elf_Half              index;
++	char*                 data;
++	std::vector<Elf_Half> sections;
++	endianess_convertor*  convertor;
++	bool                  is_offset_set;
++};
++
++} // namespace ELFIO
++
++#endif // ELFIO_SEGMENT_HPP
++
++/*** End of inlined file: elfio_segment.hpp ***/
++
++
++/*** Start of inlined file: elfio_strings.hpp ***/
++#ifndef ELFIO_STRINGS_HPP
++#define ELFIO_STRINGS_HPP
++
++#include <cstdlib>
++#include <cstring>
++#include <string>
++
++namespace ELFIO {
++
++//------------------------------------------------------------------------------
++template <class S> class string_section_accessor_template
++{
++  public:
++	//------------------------------------------------------------------------------
++	string_section_accessor_template( S* section_ ) : string_section( section_ )
++	{
++	}
++
++	//------------------------------------------------------------------------------
++	const char* get_string( Elf_Word index ) const
++	{
++		if ( string_section ) {
++			if ( index < string_section->get_size() ) {
++				const char* data = string_section->get_data();
++				if ( 0 != data ) {
++					return data + index;
++				}
++			}
++		}
++
++		return 0;
++	}
++
++	//------------------------------------------------------------------------------
++	Elf_Word add_string( const char* str )
++	{
++		Elf_Word current_position = 0;
++
++		if ( string_section ) {
++			// Strings are addeded to the end of the current section data
++			current_position = (Elf_Word)string_section->get_size();
++
++			if ( current_position == 0 ) {
++				char empty_string = '\0';
++				string_section->append_data( &empty_string, 1 );
++				current_position++;
++			}
++			string_section->append_data( str,
++										 (Elf_Word)std::strlen( str ) + 1 );
++		}
++
++		return current_position;
++	}
++
++	//------------------------------------------------------------------------------
++	Elf_Word add_string( const std::string& str )
++	{
++		return add_string( str.c_str() );
++	}
++
++	//------------------------------------------------------------------------------
++  private:
++	S* string_section;
++};
++
++using string_section_accessor = string_section_accessor_template<section>;
++using const_string_section_accessor =
++	string_section_accessor_template<const section>;
++
++} // namespace ELFIO
++
++#endif // ELFIO_STRINGS_HPP
++
++/*** End of inlined file: elfio_strings.hpp ***/
++
++#define ELFIO_HEADER_ACCESS_GET( TYPE, FNAME ) \
++	TYPE get_##FNAME() const { return header ? ( header->get_##FNAME() ) : 0; }
++
++#define ELFIO_HEADER_ACCESS_GET_SET( TYPE, FNAME )     \
++	TYPE get_##FNAME() const                           \
++	{                                                  \
++		return header ? ( header->get_##FNAME() ) : 0; \
++	}                                                  \
++	void set_##FNAME( TYPE val )                       \
++	{                                                  \
++		if ( header ) {                                \
++			header->set_##FNAME( val );                \
++		}                                              \
++	}
++
++namespace ELFIO {
++
++//------------------------------------------------------------------------------
++class elfio
++{
++  public:
++	//------------------------------------------------------------------------------
++	elfio() : sections( this ), segments( this )
++	{
++		header           = 0;
++		current_file_pos = 0;
++		create( ELFCLASS32, ELFDATA2LSB );
++	}
++
++	//------------------------------------------------------------------------------
++	~elfio() { clean(); }
++
++	//------------------------------------------------------------------------------
++	void create( unsigned char file_class, unsigned char encoding )
++	{
++		clean();
++		convertor.setup( encoding );
++		header = create_header( file_class, encoding );
++		create_mandatory_sections();
++	}
++
++	//------------------------------------------------------------------------------
++	bool load( const std::string& file_name )
++	{
++		std::ifstream stream;
++		stream.open( file_name.c_str(), std::ios::in | std::ios::binary );
++		if ( !stream ) {
++			return false;
++		}
++
++		return load( stream );
++	}
++
++	//------------------------------------------------------------------------------
++	bool load( std::istream& stream )
++	{
++		clean();
++
++		unsigned char e_ident[EI_NIDENT];
++		// Read ELF file signature
++		stream.read( reinterpret_cast<char*>( &e_ident ), sizeof( e_ident ) );
++
++		// Is it ELF file?
++		if ( stream.gcount() != sizeof( e_ident ) ||
++			 e_ident[EI_MAG0] != ELFMAG0 || e_ident[EI_MAG1] != ELFMAG1 ||
++			 e_ident[EI_MAG2] != ELFMAG2 || e_ident[EI_MAG3] != ELFMAG3 ) {
++			return false;
++		}
++
++		if ( ( e_ident[EI_CLASS] != ELFCLASS64 ) &&
++			 ( e_ident[EI_CLASS] != ELFCLASS32 ) ) {
++			return false;
++		}
++
++		convertor.setup( e_ident[EI_DATA] );
++		header = create_header( e_ident[EI_CLASS], e_ident[EI_DATA] );
++		if ( 0 == header ) {
++			return false;
++		}
++		if ( !header->load( stream ) ) {
++			return false;
++		}
++
++		load_sections( stream );
++		bool is_still_good = load_segments( stream );
++		return is_still_good;
++	}
++
++	//------------------------------------------------------------------------------
++	bool save( const std::string& file_name )
++	{
++		std::ofstream stream;
++		stream.open( file_name.c_str(), std::ios::out | std::ios::binary );
++		if ( !stream ) {
++			return false;
++		}
++
++		return save( stream );
++	}
++
++	//------------------------------------------------------------------------------
++	bool save( std::ostream& stream )
++	{
++		if ( !stream || !header ) {
++			return false;
++		}
++
++		bool is_still_good = true;
++		// Define layout specific header fields
++		// The position of the segment table is fixed after the header.
++		// The position of the section table is variable and needs to be fixed
++		// before saving.
++		header->set_segments_num( segments.size() );
++		header->set_segments_offset( segments.size() ? header->get_header_size()
++													 : 0 );
++		header->set_sections_num( sections.size() );
++		header->set_sections_offset( 0 );
++
++		// Layout the first section right after the segment table
++		current_file_pos = header->get_header_size() +
++						   header->get_segment_entry_size() *
++							   (Elf_Xword)header->get_segments_num();
++
++		calc_segment_alignment();
++
++		is_still_good = layout_segments_and_their_sections();
++		is_still_good = is_still_good && layout_sections_without_segments();
++		is_still_good = is_still_good && layout_section_table();
++
++		is_still_good = is_still_good && save_header( stream );
++		is_still_good = is_still_good && save_sections( stream );
++		is_still_good = is_still_good && save_segments( stream );
++
++		return is_still_good;
++	}
++
++	//------------------------------------------------------------------------------
++	// ELF header access functions
++	ELFIO_HEADER_ACCESS_GET( unsigned char, class );
++	ELFIO_HEADER_ACCESS_GET( unsigned char, elf_version );
++	ELFIO_HEADER_ACCESS_GET( unsigned char, encoding );
++	ELFIO_HEADER_ACCESS_GET( Elf_Word, version );
++	ELFIO_HEADER_ACCESS_GET( Elf_Half, header_size );
++	ELFIO_HEADER_ACCESS_GET( Elf_Half, section_entry_size );
++	ELFIO_HEADER_ACCESS_GET( Elf_Half, segment_entry_size );
++
++	ELFIO_HEADER_ACCESS_GET_SET( unsigned char, os_abi );
++	ELFIO_HEADER_ACCESS_GET_SET( unsigned char, abi_version );
++	ELFIO_HEADER_ACCESS_GET_SET( Elf_Half, type );
++	ELFIO_HEADER_ACCESS_GET_SET( Elf_Half, machine );
++	ELFIO_HEADER_ACCESS_GET_SET( Elf_Word, flags );
++	ELFIO_HEADER_ACCESS_GET_SET( Elf64_Addr, entry );
++	ELFIO_HEADER_ACCESS_GET_SET( Elf64_Off, sections_offset );
++	ELFIO_HEADER_ACCESS_GET_SET( Elf64_Off, segments_offset );
++	ELFIO_HEADER_ACCESS_GET_SET( Elf_Half, section_name_str_index );
++
++	//------------------------------------------------------------------------------
++	const endianess_convertor& get_convertor() const { return convertor; }
++
++	//------------------------------------------------------------------------------
++	Elf_Xword get_default_entry_size( Elf_Word section_type ) const
++	{
++		switch ( section_type ) {
++		case SHT_RELA:
++			if ( header->get_class() == ELFCLASS64 ) {
++				return sizeof( Elf64_Rela );
++			}
++			else {
++				return sizeof( Elf32_Rela );
++			}
++		case SHT_REL:
++			if ( header->get_class() == ELFCLASS64 ) {
++				return sizeof( Elf64_Rel );
++			}
++			else {
++				return sizeof( Elf32_Rel );
++			}
++		case SHT_SYMTAB:
++			if ( header->get_class() == ELFCLASS64 ) {
++				return sizeof( Elf64_Sym );
++			}
++			else {
++				return sizeof( Elf32_Sym );
++			}
++		case SHT_DYNAMIC:
++			if ( header->get_class() == ELFCLASS64 ) {
++				return sizeof( Elf64_Dyn );
++			}
++			else {
++				return sizeof( Elf32_Dyn );
++			}
++		default:
++			return 0;
++		}
++	}
++
++	//------------------------------------------------------------------------------
++  private:
++	bool is_offset_in_section( Elf64_Off offset, const section* sec ) const
++	{
++		return ( offset >= sec->get_offset() ) &&
++			   ( offset < ( sec->get_offset() + sec->get_size() ) );
++	}
++
++	//------------------------------------------------------------------------------
++  public:
++	//! returns an empty string if no problems are detected,
++	//! or a string containing an error message if problems are found
++	std::string validate() const
++	{
++
++		// check for overlapping sections in the file
++		for ( int i = 0; i < sections.size(); ++i ) {
++			for ( int j = i + 1; j < sections.size(); ++j ) {
++				const section* a = sections[i];
++				const section* b = sections[j];
++				if ( !( a->get_type() & SHT_NOBITS ) &&
++					 !( b->get_type() & SHT_NOBITS ) && ( a->get_size() > 0 ) &&
++					 ( b->get_size() > 0 ) && ( a->get_offset() > 0 ) &&
++					 ( b->get_offset() > 0 ) ) {
++					if ( is_offset_in_section( a->get_offset(), b ) ||
++						 is_offset_in_section(
++							 a->get_offset() + a->get_size() - 1, b ) ||
++						 is_offset_in_section( b->get_offset(), a ) ||
++						 is_offset_in_section(
++							 b->get_offset() + b->get_size() - 1, a ) ) {
++						return "Sections " + a->get_name() + " and " +
++							   b->get_name() + " overlap in file";
++					}
++				}
++			}
++		}
++
++		// more checks to be added here...
++
++		return "";
++	}
++
++	//------------------------------------------------------------------------------
++  private:
++	//------------------------------------------------------------------------------
++	void clean()
++	{
++		delete header;
++		header = 0;
++
++		std::vector<section*>::const_iterator it;
++		for ( it = sections_.begin(); it != sections_.end(); ++it ) {
++			delete *it;
++		}
++		sections_.clear();
++
++		std::vector<segment*>::const_iterator it1;
++		for ( it1 = segments_.begin(); it1 != segments_.end(); ++it1 ) {
++			delete *it1;
++		}
++		segments_.clear();
++	}
++
++	//------------------------------------------------------------------------------
++	elf_header* create_header( unsigned char file_class,
++							   unsigned char encoding )
++	{
++		elf_header* new_header = 0;
++
++		if ( file_class == ELFCLASS64 ) {
++			new_header =
++				new elf_header_impl<Elf64_Ehdr>( &convertor, encoding );
++		}
++		else if ( file_class == ELFCLASS32 ) {
++			new_header =
++				new elf_header_impl<Elf32_Ehdr>( &convertor, encoding );
++		}
++		else {
++			return 0;
++		}
++
++		return new_header;
++	}
++
++	//------------------------------------------------------------------------------
++	section* create_section()
++	{
++		section*      new_section;
++		unsigned char file_class = get_class();
++
++		if ( file_class == ELFCLASS64 ) {
++			new_section = new section_impl<Elf64_Shdr>( &convertor );
++		}
++		else if ( file_class == ELFCLASS32 ) {
++			new_section = new section_impl<Elf32_Shdr>( &convertor );
++		}
++		else {
++			return 0;
++		}
++
++		new_section->set_index( (Elf_Half)sections_.size() );
++		sections_.push_back( new_section );
++
++		return new_section;
++	}
++
++	//------------------------------------------------------------------------------
++	segment* create_segment()
++	{
++		segment*      new_segment;
++		unsigned char file_class = header->get_class();
++
++		if ( file_class == ELFCLASS64 ) {
++			new_segment = new segment_impl<Elf64_Phdr>( &convertor );
++		}
++		else if ( file_class == ELFCLASS32 ) {
++			new_segment = new segment_impl<Elf32_Phdr>( &convertor );
++		}
++		else {
++			return 0;
++		}
++
++		new_segment->set_index( (Elf_Half)segments_.size() );
++		segments_.push_back( new_segment );
++
++		return new_segment;
++	}
++
++	//------------------------------------------------------------------------------
++	void create_mandatory_sections()
++	{
++		// Create null section without calling to 'add_section' as no string
++		// section containing section names exists yet
++		section* sec0 = create_section();
++		sec0->set_index( 0 );
++		sec0->set_name( "" );
++		sec0->set_name_string_offset( 0 );
++
++		set_section_name_str_index( 1 );
++		section* shstrtab = sections.add( ".shstrtab" );
++		shstrtab->set_type( SHT_STRTAB );
++		shstrtab->set_addr_align( 1 );
++	}
++
++	//------------------------------------------------------------------------------
++	Elf_Half load_sections( std::istream& stream )
++	{
++		Elf_Half  entry_size = header->get_section_entry_size();
++		Elf_Half  num        = header->get_sections_num();
++		Elf64_Off offset     = header->get_sections_offset();
++
++		for ( Elf_Half i = 0; i < num; ++i ) {
++			section* sec = create_section();
++			sec->load( stream, (std::streamoff)offset +
++								   (std::streampos)i * entry_size );
++			sec->set_index( i );
++			// To mark that the section is not permitted to reassign address
++			// during layout calculation
++			sec->set_address( sec->get_address() );
++		}
++
++		Elf_Half shstrndx = get_section_name_str_index();
++
++		if ( SHN_UNDEF != shstrndx ) {
++			string_section_accessor str_reader( sections[shstrndx] );
++			for ( Elf_Half i = 0; i < num; ++i ) {
++				Elf_Word section_offset = sections[i]->get_name_string_offset();
++				const char* p = str_reader.get_string( section_offset );
++				if ( p != 0 ) {
++					sections[i]->set_name( p );
++				}
++			}
++		}
++
++		return num;
++	}
++
++	//------------------------------------------------------------------------------
++	//! Checks whether the addresses of the section entirely fall within the given segment.
++	//! It doesn't matter if the addresses are memory addresses, or file offsets,
++	//!  they just need to be in the same address space
++	bool is_sect_in_seg( Elf64_Off sect_begin,
++						 Elf_Xword sect_size,
++						 Elf64_Off seg_begin,
++						 Elf64_Off seg_end )
++	{
++		return ( seg_begin <= sect_begin ) &&
++			   ( sect_begin + sect_size <= seg_end ) &&
++			   ( sect_begin <
++				 seg_end ); // this is important criteria when sect_size == 0
++		// Example:  seg_begin=10, seg_end=12 (-> covering the bytes 10 and 11)
++		//           sect_begin=12, sect_size=0  -> shall return false!
++	}
++
++	//------------------------------------------------------------------------------
++	bool load_segments( std::istream& stream )
++	{
++		Elf_Half  entry_size = header->get_segment_entry_size();
++		Elf_Half  num        = header->get_segments_num();
++		Elf64_Off offset     = header->get_segments_offset();
++
++		for ( Elf_Half i = 0; i < num; ++i ) {
++			segment*      seg;
++			unsigned char file_class = header->get_class();
++
++			if ( file_class == ELFCLASS64 ) {
++				seg = new segment_impl<Elf64_Phdr>( &convertor );
++			}
++			else if ( file_class == ELFCLASS32 ) {
++				seg = new segment_impl<Elf32_Phdr>( &convertor );
++			}
++			else {
++				return false;
++			}
++
++			seg->load( stream, (std::streamoff)offset +
++								   (std::streampos)i * entry_size );
++			seg->set_index( i );
++
++			// Add sections to the segments (similar to readelfs algorithm)
++			Elf64_Off segBaseOffset = seg->get_offset();
++			Elf64_Off segEndOffset  = segBaseOffset + seg->get_file_size();
++			Elf64_Off segVBaseAddr  = seg->get_virtual_address();
++			Elf64_Off segVEndAddr   = segVBaseAddr + seg->get_memory_size();
++			for ( Elf_Half j = 0; j < sections.size(); ++j ) {
++				const section* psec = sections[j];
++
++				// SHF_ALLOC sections are matched based on the virtual address
++				// otherwise the file offset is matched
++				if ( ( psec->get_flags() & SHF_ALLOC )
++						 ? is_sect_in_seg( psec->get_address(),
++										   psec->get_size(), segVBaseAddr,
++										   segVEndAddr )
++						 : is_sect_in_seg( psec->get_offset(), psec->get_size(),
++										   segBaseOffset, segEndOffset ) ) {
++					// Alignment of segment shall not be updated, to preserve original value
++					// It will be re-calculated on saving.
++					seg->add_section_index( psec->get_index(), 0 );
++				}
++			}
++
++			// Add section into the segments' container
++			segments_.push_back( seg );
++		}
++
++		return true;
++	}
++
++	//------------------------------------------------------------------------------
++	bool save_header( std::ostream& stream ) { return header->save( stream ); }
++
++	//------------------------------------------------------------------------------
++	bool save_sections( std::ostream& stream )
++	{
++		for ( unsigned int i = 0; i < sections_.size(); ++i ) {
++			section* sec = sections_.at( i );
++
++			std::streampos headerPosition =
++				(std::streamoff)header->get_sections_offset() +
++				(std::streampos)header->get_section_entry_size() *
++					sec->get_index();
++
++			sec->save( stream, headerPosition, sec->get_offset() );
++		}
++		return true;
++	}
++
++	//------------------------------------------------------------------------------
++	bool save_segments( std::ostream& stream )
++	{
++		for ( unsigned int i = 0; i < segments_.size(); ++i ) {
++			segment* seg = segments_.at( i );
++
++			std::streampos headerPosition =
++				header->get_segments_offset() +
++				(std::streampos)header->get_segment_entry_size() *
++					seg->get_index();
++
++			seg->save( stream, headerPosition, seg->get_offset() );
++		}
++		return true;
++	}
++
++	//------------------------------------------------------------------------------
++	bool is_section_without_segment( unsigned int section_index )
++	{
++		bool found = false;
++
++		for ( unsigned int j = 0; !found && ( j < segments.size() ); ++j ) {
++			for ( unsigned int k = 0;
++				  !found && ( k < segments[j]->get_sections_num() ); ++k ) {
++				found = segments[j]->get_section_index_at( k ) == section_index;
++			}
++		}
++
++		return !found;
++	}
++
++	//------------------------------------------------------------------------------
++	bool is_subsequence_of( segment* seg1, segment* seg2 )
++	{
++		// Return 'true' if sections of seg1 are a subset of sections in seg2
++		const std::vector<Elf_Half>& sections1 = seg1->get_sections();
++		const std::vector<Elf_Half>& sections2 = seg2->get_sections();
++
++		bool found = false;
++		if ( sections1.size() < sections2.size() ) {
++			found = std::includes( sections2.begin(), sections2.end(),
++								   sections1.begin(), sections1.end() );
++		}
++
++		return found;
++	}
++
++	//------------------------------------------------------------------------------
++	std::vector<segment*> get_ordered_segments()
++	{
++		std::vector<segment*> res;
++		std::deque<segment*>  worklist;
++
++		res.reserve( segments.size() );
++		std::copy( segments_.begin(), segments_.end(),
++				   std::back_inserter( worklist ) );
++
++		// Bring the segments which start at address 0 to the front
++		size_t nextSlot = 0;
++		for ( size_t i = 0; i < worklist.size(); ++i ) {
++			if ( i != nextSlot && worklist[i]->is_offset_initialized() &&
++				 worklist[i]->get_offset() == 0 ) {
++				if ( worklist[nextSlot]->get_offset() == 0 ) {
++					++nextSlot;
++				}
++				std::swap( worklist[i], worklist[nextSlot] );
++				++nextSlot;
++			}
++		}
++
++		while ( !worklist.empty() ) {
++			segment* seg = worklist.front();
++			worklist.pop_front();
++
++			size_t i = 0;
++			for ( ; i < worklist.size(); ++i ) {
++				if ( is_subsequence_of( seg, worklist[i] ) ) {
++					break;
++				}
++			}
++
++			if ( i < worklist.size() )
++				worklist.push_back( seg );
++			else
++				res.push_back( seg );
++		}
++
++		return res;
++	}
++
++	//------------------------------------------------------------------------------
++	bool layout_sections_without_segments()
++	{
++		for ( unsigned int i = 0; i < sections_.size(); ++i ) {
++			if ( is_section_without_segment( i ) ) {
++				section* sec = sections_[i];
++
++				Elf_Xword section_align = sec->get_addr_align();
++				if ( section_align > 1 &&
++					 current_file_pos % section_align != 0 ) {
++					current_file_pos +=
++						section_align - current_file_pos % section_align;
++				}
++
++				if ( 0 != sec->get_index() )
++					sec->set_offset( current_file_pos );
++
++				if ( SHT_NOBITS != sec->get_type() &&
++					 SHT_NULL != sec->get_type() ) {
++					current_file_pos += sec->get_size();
++				}
++			}
++		}
++
++		return true;
++	}
++
++	//------------------------------------------------------------------------------
++	void calc_segment_alignment()
++	{
++		for ( std::vector<segment*>::iterator s = segments_.begin();
++			  s != segments_.end(); ++s ) {
++			segment* seg = *s;
++			for ( int i = 0; i < seg->get_sections_num(); ++i ) {
++				section* sect = sections_[seg->get_section_index_at( i )];
++				if ( sect->get_addr_align() > seg->get_align() ) {
++					seg->set_align( sect->get_addr_align() );
++				}
++			}
++		}
++	}
++
++	//------------------------------------------------------------------------------
++	bool layout_segments_and_their_sections()
++	{
++		std::vector<segment*> worklist;
++		std::vector<bool>     section_generated( sections.size(), false );
++
++		// Get segments in a order in where segments which contain a
++		// sub sequence of other segments are located at the end
++		worklist = get_ordered_segments();
++
++		for ( unsigned int i = 0; i < worklist.size(); ++i ) {
++			Elf_Xword segment_memory   = 0;
++			Elf_Xword segment_filesize = 0;
++			Elf_Xword seg_start_pos    = current_file_pos;
++			segment*  seg              = worklist[i];
++
++			// Special case: PHDR segment
++			// This segment contains the program headers but no sections
++			if ( seg->get_type() == PT_PHDR && seg->get_sections_num() == 0 ) {
++				seg_start_pos  = header->get_segments_offset();
++				segment_memory = segment_filesize =
++					header->get_segment_entry_size() *
++					(Elf_Xword)header->get_segments_num();
++			}
++			// Special case:
++			else if ( seg->is_offset_initialized() && seg->get_offset() == 0 ) {
++				seg_start_pos = 0;
++				if ( seg->get_sections_num() ) {
++					segment_memory = segment_filesize = current_file_pos;
++				}
++			}
++			// New segments with not generated sections
++			// have to be aligned
++			else if ( seg->get_sections_num() &&
++					  !section_generated[seg->get_section_index_at( 0 )] ) {
++				Elf_Xword align = seg->get_align() > 0 ? seg->get_align() : 1;
++				Elf64_Off cur_page_alignment = current_file_pos % align;
++				Elf64_Off req_page_alignment =
++					seg->get_virtual_address() % align;
++				Elf64_Off error = req_page_alignment - cur_page_alignment;
++
++				current_file_pos += ( seg->get_align() + error ) % align;
++				seg_start_pos = current_file_pos;
++			}
++			else if ( seg->get_sections_num() ) {
++				seg_start_pos =
++					sections[seg->get_section_index_at( 0 )]->get_offset();
++			}
++
++			// Write segment's data
++			for ( unsigned int j = 0; j < seg->get_sections_num(); ++j ) {
++				Elf_Half index = seg->get_section_index_at( j );
++
++				section* sec = sections[index];
++
++				// The NULL section is always generated
++				if ( SHT_NULL == sec->get_type() ) {
++					section_generated[index] = true;
++					continue;
++				}
++
++				Elf_Xword secAlign = 0;
++				// Fix up the alignment
++				if ( !section_generated[index] &&
++					 sec->is_address_initialized() &&
++					 SHT_NOBITS != sec->get_type() &&
++					 SHT_NULL != sec->get_type() && 0 != sec->get_size() ) {
++					// Align the sections based on the virtual addresses
++					// when possible (this is what matters for execution)
++					Elf64_Off req_offset =
++						sec->get_address() - seg->get_virtual_address();
++					Elf64_Off cur_offset = current_file_pos - seg_start_pos;
++					if ( req_offset < cur_offset ) {
++						// something has gone awfully wrong, abort!
++						// secAlign would turn out negative, seeking backwards and overwriting previous data
++						return false;
++					}
++					secAlign = req_offset - cur_offset;
++				}
++				else if ( !section_generated[index] &&
++						  !sec->is_address_initialized() ) {
++					// If no address has been specified then only the section
++					// alignment constraint has to be matched
++					Elf_Xword align = sec->get_addr_align();
++					if ( align == 0 ) {
++						align = 1;
++					}
++					Elf64_Off error = current_file_pos % align;
++					secAlign        = ( align - error ) % align;
++				}
++				else if ( section_generated[index] ) {
++					// Alignment for already generated sections
++					secAlign =
++						sec->get_offset() - seg_start_pos - segment_filesize;
++				}
++
++				// Determine the segment file and memory sizes
++				// Special case .tbss section (NOBITS) in non TLS segment
++				if ( ( sec->get_flags() & SHF_ALLOC ) &&
++					 !( ( sec->get_flags() & SHF_TLS ) &&
++						( seg->get_type() != PT_TLS ) &&
++						( SHT_NOBITS == sec->get_type() ) ) )
++					segment_memory += sec->get_size() + secAlign;
++
++				if ( SHT_NOBITS != sec->get_type() )
++					segment_filesize += sec->get_size() + secAlign;
++
++				// Nothing to be done when generating nested segments
++				if ( section_generated[index] ) {
++					continue;
++				}
++
++				current_file_pos += secAlign;
++
++				// Set the section addresses when missing
++				if ( !sec->is_address_initialized() )
++					sec->set_address( seg->get_virtual_address() +
++									  current_file_pos - seg_start_pos );
++
++				if ( 0 != sec->get_index() )
++					sec->set_offset( current_file_pos );
++
++				if ( SHT_NOBITS != sec->get_type() )
++					current_file_pos += sec->get_size();
++
++				section_generated[index] = true;
++			}
++
++			seg->set_file_size( segment_filesize );
++
++			// If we already have a memory size from loading an elf file (value > 0),
++			// it must not shrink!
++			// Memory size may be bigger than file size and it is the loader's job to do something
++			// with the surplus bytes in memory, like initializing them with a defined value.
++			if ( seg->get_memory_size() < segment_memory ) {
++				seg->set_memory_size( segment_memory );
++			}
++
++			seg->set_offset( seg_start_pos );
++		}
++
++		return true;
++	}
++
++	//------------------------------------------------------------------------------
++	bool layout_section_table()
++	{
++		// Simply place the section table at the end for now
++		Elf64_Off alignmentError = current_file_pos % 4;
++		current_file_pos += ( 4 - alignmentError ) % 4;
++		header->set_sections_offset( current_file_pos );
++		return true;
++	}
++
++	//------------------------------------------------------------------------------
++  public:
++	friend class Sections;
++	class Sections
++	{
++	  public:
++		//------------------------------------------------------------------------------
++		Sections( elfio* parent_ ) : parent( parent_ ) {}
++
++		//------------------------------------------------------------------------------
++		Elf_Half size() const { return (Elf_Half)parent->sections_.size(); }
++
++		//------------------------------------------------------------------------------
++		section* operator[]( unsigned int index ) const
++		{
++			section* sec = 0;
++
++			if ( index < parent->sections_.size() ) {
++				sec = parent->sections_[index];
++			}
++
++			return sec;
++		}
++
++		//------------------------------------------------------------------------------
++		section* operator[]( const std::string& name ) const
++		{
++			section* sec = 0;
++
++			std::vector<section*>::const_iterator it;
++			for ( it = parent->sections_.begin(); it != parent->sections_.end();
++				  ++it ) {
++				if ( ( *it )->get_name() == name ) {
++					sec = *it;
++					break;
++				}
++			}
++
++			return sec;
++		}
++
++		//------------------------------------------------------------------------------
++		section* add( const std::string& name )
++		{
++			section* new_section = parent->create_section();
++			new_section->set_name( name );
++
++			Elf_Half str_index = parent->get_section_name_str_index();
++			section* string_table( parent->sections_[str_index] );
++			string_section_accessor str_writer( string_table );
++			Elf_Word                pos = str_writer.add_string( name );
++			new_section->set_name_string_offset( pos );
++
++			return new_section;
++		}
++
++		//------------------------------------------------------------------------------
++		std::vector<section*>::iterator begin()
++		{
++			return parent->sections_.begin();
++		}
++
++		//------------------------------------------------------------------------------
++		std::vector<section*>::iterator end()
++		{
++			return parent->sections_.end();
++		}
++
++		//------------------------------------------------------------------------------
++		std::vector<section*>::const_iterator begin() const
++		{
++			return parent->sections_.cbegin();
++		}
++
++		//------------------------------------------------------------------------------
++		std::vector<section*>::const_iterator end() const
++		{
++			return parent->sections_.cend();
++		}
++
++		//------------------------------------------------------------------------------
++	  private:
++		elfio* parent;
++	} sections;
++
++	//------------------------------------------------------------------------------
++  public:
++	friend class Segments;
++	class Segments
++	{
++	  public:
++		//------------------------------------------------------------------------------
++		Segments( elfio* parent_ ) : parent( parent_ ) {}
++
++		//------------------------------------------------------------------------------
++		Elf_Half size() const { return (Elf_Half)parent->segments_.size(); }
++
++		//------------------------------------------------------------------------------
++		segment* operator[]( unsigned int index ) const
++		{
++			return parent->segments_[index];
++		}
++
++		//------------------------------------------------------------------------------
++		segment* add() { return parent->create_segment(); }
++
++		//------------------------------------------------------------------------------
++		std::vector<segment*>::iterator begin()
++		{
++			return parent->segments_.begin();
++		}
++
++		//------------------------------------------------------------------------------
++		std::vector<segment*>::iterator end()
++		{
++			return parent->segments_.end();
++		}
++
++		//------------------------------------------------------------------------------
++		std::vector<segment*>::const_iterator begin() const
++		{
++			return parent->segments_.cbegin();
++		}
++
++		//------------------------------------------------------------------------------
++		std::vector<segment*>::const_iterator end() const
++		{
++			return parent->segments_.cend();
++		}
++
++		//------------------------------------------------------------------------------
++	  private:
++		elfio* parent;
++	} segments;
++
++	//------------------------------------------------------------------------------
++  private:
++	elf_header*           header;
++	std::vector<section*> sections_;
++	std::vector<segment*> segments_;
++	endianess_convertor   convertor;
++
++	Elf_Xword current_file_pos;
++};
++
++} // namespace ELFIO
++
++
++/*** Start of inlined file: elfio_symbols.hpp ***/
++#ifndef ELFIO_SYMBOLS_HPP
++#define ELFIO_SYMBOLS_HPP
++
++namespace ELFIO {
++
++//------------------------------------------------------------------------------
++template <class S> class symbol_section_accessor_template
++{
++  public:
++	//------------------------------------------------------------------------------
++	symbol_section_accessor_template( const elfio& elf_file_,
++									  S*           symbol_section_ )
++		: elf_file( elf_file_ ), symbol_section( symbol_section_ )
++	{
++		find_hash_section();
++	}
++
++	//------------------------------------------------------------------------------
++	Elf_Xword get_symbols_num() const
++	{
++		Elf_Xword nRet = 0;
++		if ( 0 != symbol_section->get_entry_size() ) {
++			nRet =
++				symbol_section->get_size() / symbol_section->get_entry_size();
++		}
++
++		return nRet;
++	}
++
++	//------------------------------------------------------------------------------
++	bool get_symbol( Elf_Xword      index,
++					 std::string&   name,
++					 Elf64_Addr&    value,
++					 Elf_Xword&     size,
++					 unsigned char& bind,
++					 unsigned char& type,
++					 Elf_Half&      section_index,
++					 unsigned char& other ) const
++	{
++		bool ret = false;
++
++		if ( elf_file.get_class() == ELFCLASS32 ) {
++			ret = generic_get_symbol<Elf32_Sym>( index, name, value, size, bind,
++												 type, section_index, other );
++		}
++		else {
++			ret = generic_get_symbol<Elf64_Sym>( index, name, value, size, bind,
++												 type, section_index, other );
++		}
++
++		return ret;
++	}
++
++	//------------------------------------------------------------------------------
++	bool get_symbol( const std::string& name,
++					 Elf64_Addr&        value,
++					 Elf_Xword&         size,
++					 unsigned char&     bind,
++					 unsigned char&     type,
++					 Elf_Half&          section_index,
++					 unsigned char&     other ) const
++	{
++		bool ret = false;
++
++		if ( 0 != get_hash_table_index() ) {
++			Elf_Word    nbucket = *(const Elf_Word*)hash_section->get_data();
++			Elf_Word    nchain  = *(const Elf_Word*)( hash_section->get_data() +
++												  sizeof( Elf_Word ) );
++			Elf_Word    val = elf_hash( (const unsigned char*)name.c_str() );
++			Elf_Word    y   = *(const Elf_Word*)( hash_section->get_data() +
++											 ( 2 + val % nbucket ) *
++												 sizeof( Elf_Word ) );
++			std::string str;
++			get_symbol( y, str, value, size, bind, type, section_index, other );
++			while ( str != name && STN_UNDEF != y && y < nchain ) {
++				y = *(const Elf_Word*)( hash_section->get_data() +
++										( 2 + nbucket + y ) *
++											sizeof( Elf_Word ) );
++				get_symbol( y, str, value, size, bind, type, section_index,
++							other );
++			}
++			if ( str == name ) {
++				ret = true;
++			}
++		}
++		else {
++			for ( Elf_Xword i = 0; i < get_symbols_num() && !ret; i++ ) {
++				std::string symbol_name;
++				if ( get_symbol( i, symbol_name, value, size, bind, type,
++								 section_index, other ) ) {
++					if ( symbol_name == name ) {
++						ret = true;
++					}
++				}
++			}
++		}
++
++		return ret;
++	}
++
++	//------------------------------------------------------------------------------
++	bool get_symbol( const Elf64_Addr& value,
++					 std::string&      name,
++					 Elf_Xword&        size,
++					 unsigned char&    bind,
++					 unsigned char&    type,
++					 Elf_Half&         section_index,
++					 unsigned char&    other ) const
++	{
++
++		const endianess_convertor& convertor = elf_file.get_convertor();
++
++		Elf_Xword  idx   = 0;
++		bool       match = false;
++		Elf64_Addr v     = 0;
++
++		if ( elf_file.get_class() == ELFCLASS32 ) {
++			match = generic_search_symbols<Elf32_Sym>(
++				[&]( const Elf32_Sym* sym ) {
++					return convertor( sym->st_value ) == value;
++				},
++				idx );
++		}
++		else {
++			match = generic_search_symbols<Elf64_Sym>(
++				[&]( const Elf64_Sym* sym ) {
++					return convertor( sym->st_value ) == value;
++				},
++				idx );
++		}
++
++		if ( match ) {
++			return get_symbol( idx, name, v, size, bind, type, section_index,
++							   other );
++		}
++
++		return false;
++	}
++
++	//------------------------------------------------------------------------------
++	Elf_Word add_symbol( Elf_Word      name,
++						 Elf64_Addr    value,
++						 Elf_Xword     size,
++						 unsigned char info,
++						 unsigned char other,
++						 Elf_Half      shndx )
++	{
++		Elf_Word nRet;
++
++		if ( symbol_section->get_size() == 0 ) {
++			if ( elf_file.get_class() == ELFCLASS32 ) {
++				nRet = generic_add_symbol<Elf32_Sym>( 0, 0, 0, 0, 0, 0 );
++			}
++			else {
++				nRet = generic_add_symbol<Elf64_Sym>( 0, 0, 0, 0, 0, 0 );
++			}
++		}
++
++		if ( elf_file.get_class() == ELFCLASS32 ) {
++			nRet = generic_add_symbol<Elf32_Sym>( name, value, size, info,
++												  other, shndx );
++		}
++		else {
++			nRet = generic_add_symbol<Elf64_Sym>( name, value, size, info,
++												  other, shndx );
++		}
++
++		return nRet;
++	}
++
++	//------------------------------------------------------------------------------
++	Elf_Word add_symbol( Elf_Word      name,
++						 Elf64_Addr    value,
++						 Elf_Xword     size,
++						 unsigned char bind,
++						 unsigned char type,
++						 unsigned char other,
++						 Elf_Half      shndx )
++	{
++		return add_symbol( name, value, size, ELF_ST_INFO( bind, type ), other,
++						   shndx );
++	}
++
++	//------------------------------------------------------------------------------
++	Elf_Word add_symbol( string_section_accessor& pStrWriter,
++						 const char*              str,
++						 Elf64_Addr               value,
++						 Elf_Xword                size,
++						 unsigned char            info,
++						 unsigned char            other,
++						 Elf_Half                 shndx )
++	{
++		Elf_Word index = pStrWriter.add_string( str );
++		return add_symbol( index, value, size, info, other, shndx );
++	}
++
++	//------------------------------------------------------------------------------
++	Elf_Word add_symbol( string_section_accessor& pStrWriter,
++						 const char*              str,
++						 Elf64_Addr               value,
++						 Elf_Xword                size,
++						 unsigned char            bind,
++						 unsigned char            type,
++						 unsigned char            other,
++						 Elf_Half                 shndx )
++	{
++		return add_symbol( pStrWriter, str, value, size,
++						   ELF_ST_INFO( bind, type ), other, shndx );
++	}
++
++	//------------------------------------------------------------------------------
++	Elf_Xword arrange_local_symbols(
++		std::function<void( Elf_Xword first, Elf_Xword second )> func =
++			nullptr )
++	{
++		int nRet = 0;
++
++		if ( elf_file.get_class() == ELFCLASS32 ) {
++			nRet = generic_arrange_local_symbols<Elf32_Sym>( func );
++		}
++		else {
++			nRet = generic_arrange_local_symbols<Elf64_Sym>( func );
++		}
++
++		return nRet;
++	}
++
++	//------------------------------------------------------------------------------
++  private:
++	//------------------------------------------------------------------------------
++	void find_hash_section()
++	{
++		hash_section       = 0;
++		hash_section_index = 0;
++		Elf_Half nSecNo    = elf_file.sections.size();
++		for ( Elf_Half i = 0; i < nSecNo && 0 == hash_section_index; ++i ) {
++			const section* sec = elf_file.sections[i];
++			if ( sec->get_link() == symbol_section->get_index() ) {
++				hash_section       = sec;
++				hash_section_index = i;
++			}
++		}
++	}
++
++	//------------------------------------------------------------------------------
++	Elf_Half get_string_table_index() const
++	{
++		return (Elf_Half)symbol_section->get_link();
++	}
++
++	//------------------------------------------------------------------------------
++	Elf_Half get_hash_table_index() const { return hash_section_index; }
++
++	//------------------------------------------------------------------------------
++	template <class T> const T* generic_get_symbol_ptr( Elf_Xword index ) const
++	{
++		if ( 0 != symbol_section->get_data() && index < get_symbols_num() ) {
++			const T* pSym = reinterpret_cast<const T*>(
++				symbol_section->get_data() +
++				index * symbol_section->get_entry_size() );
++
++			return pSym;
++		}
++
++		return nullptr;
++	}
++
++	//------------------------------------------------------------------------------
++	template <class T>
++	bool generic_search_symbols( std::function<bool( const T* )> match,
++								 Elf_Xword&                      idx ) const
++	{
++		for ( Elf_Xword i = 0; i < get_symbols_num(); i++ ) {
++			const T* symPtr = generic_get_symbol_ptr<T>( i );
++
++			if ( symPtr == nullptr )
++				return false;
++
++			if ( match( symPtr ) ) {
++				idx = i;
++				return true;
++			}
++		}
++
++		return false;
++	}
++
++	//------------------------------------------------------------------------------
++	template <class T>
++	bool generic_get_symbol( Elf_Xword      index,
++							 std::string&   name,
++							 Elf64_Addr&    value,
++							 Elf_Xword&     size,
++							 unsigned char& bind,
++							 unsigned char& type,
++							 Elf_Half&      section_index,
++							 unsigned char& other ) const
++	{
++		bool ret = false;
++
++		if ( 0 != symbol_section->get_data() && index < get_symbols_num() ) {
++			const T* pSym = reinterpret_cast<const T*>(
++				symbol_section->get_data() +
++				index * symbol_section->get_entry_size() );
++
++			const endianess_convertor& convertor = elf_file.get_convertor();
++
++			section* string_section =
++				elf_file.sections[get_string_table_index()];
++			string_section_accessor str_reader( string_section );
++			const char*             pStr =
++				str_reader.get_string( convertor( pSym->st_name ) );
++			if ( 0 != pStr ) {
++				name = pStr;
++			}
++			value         = convertor( pSym->st_value );
++			size          = convertor( pSym->st_size );
++			bind          = ELF_ST_BIND( pSym->st_info );
++			type          = ELF_ST_TYPE( pSym->st_info );
++			section_index = convertor( pSym->st_shndx );
++			other         = pSym->st_other;
++
++			ret = true;
++		}
++
++		return ret;
++	}
++
++	//------------------------------------------------------------------------------
++	template <class T>
++	Elf_Word generic_add_symbol( Elf_Word      name,
++								 Elf64_Addr    value,
++								 Elf_Xword     size,
++								 unsigned char info,
++								 unsigned char other,
++								 Elf_Half      shndx )
++	{
++		const endianess_convertor& convertor = elf_file.get_convertor();
++
++		T entry;
++		entry.st_name  = convertor( name );
++		entry.st_value = value;
++		entry.st_value = convertor( entry.st_value );
++		entry.st_size  = size;
++		entry.st_size  = convertor( entry.st_size );
++		entry.st_info  = convertor( info );
++		entry.st_other = convertor( other );
++		entry.st_shndx = convertor( shndx );
++
++		symbol_section->append_data( reinterpret_cast<char*>( &entry ),
++									 sizeof( entry ) );
++
++		Elf_Word nRet = symbol_section->get_size() / sizeof( entry ) - 1;
++
++		return nRet;
++	}
++
++	//------------------------------------------------------------------------------
++	template <class T>
++	Elf_Xword generic_arrange_local_symbols(
++		std::function<void( Elf_Xword first, Elf_Xword second )> func )
++	{
++		const endianess_convertor& convertor = elf_file.get_convertor();
++		const Elf_Xword            size      = symbol_section->get_entry_size();
++
++		Elf_Xword first_not_local =
++			1; // Skip the first entry. It is always NOTYPE
++		Elf_Xword current = 0;
++		Elf_Xword count   = get_symbols_num();
++
++		while ( true ) {
++			T* p1 = nullptr;
++			T* p2 = nullptr;
++
++			while ( first_not_local < count ) {
++				p1 = const_cast<T*>(
++					generic_get_symbol_ptr<T>( first_not_local ) );
++				if ( ELF_ST_BIND( convertor( p1->st_info ) ) != STB_LOCAL )
++					break;
++				++first_not_local;
++			}
++
++			current = first_not_local + 1;
++			while ( current < count ) {
++				p2 = const_cast<T*>( generic_get_symbol_ptr<T>( current ) );
++				if ( ELF_ST_BIND( convertor( p2->st_info ) ) == STB_LOCAL )
++					break;
++				++current;
++			}
++
++			if ( first_not_local < count && current < count ) {
++				if ( func )
++					func( first_not_local, current );
++
++				// Swap the symbols
++				T tmp;
++				std::copy( p1, p1 + 1, &tmp );
++				std::copy( p2, p2 + 1, p1 );
++				std::copy( &tmp, &tmp + 1, p2 );
++			}
++			else {
++				// Update 'info' field of the section
++				symbol_section->set_info( first_not_local );
++				break;
++			}
++		}
++
++		// Elf_Word nRet = symbol_section->get_size() / sizeof(entry) - 1;
++
++		return first_not_local;
++	}
++
++	//------------------------------------------------------------------------------
++  private:
++	const elfio&   elf_file;
++	S*             symbol_section;
++	Elf_Half       hash_section_index;
++	const section* hash_section;
++};
++
++using symbol_section_accessor = symbol_section_accessor_template<section>;
++using const_symbol_section_accessor =
++	symbol_section_accessor_template<const section>;
++
++} // namespace ELFIO
++
++#endif // ELFIO_SYMBOLS_HPP
++
++/*** End of inlined file: elfio_symbols.hpp ***/
++
++
++/*** Start of inlined file: elfio_note.hpp ***/
++#ifndef ELFIO_NOTE_HPP
++#define ELFIO_NOTE_HPP
++
++namespace ELFIO {
++
++//------------------------------------------------------------------------------
++// There are discrepancies in documentations. SCO documentation
++// (http://www.sco.com/developers/gabi/latest/ch5.pheader.html#note_section)
++// requires 8 byte entries alignment for 64-bit ELF file,
++// but Oracle's definition uses the same structure
++// for 32-bit and 64-bit formats.
++// (https://docs.oracle.com/cd/E23824_01/html/819-0690/chapter6-18048.html)
++//
++// It looks like EM_X86_64 Linux implementation is similar to Oracle's
++// definition. Therefore, the same alignment works for both formats
++//------------------------------------------------------------------------------
++
++//------------------------------------------------------------------------------
++template <class S> class note_section_accessor_template
++{
++  public:
++	//------------------------------------------------------------------------------
++	note_section_accessor_template( const elfio& elf_file_, S* section_ )
++		: elf_file( elf_file_ ), note_section( section_ )
++	{
++		process_section();
++	}
++
++	//------------------------------------------------------------------------------
++	Elf_Word get_notes_num() const
++	{
++		return (Elf_Word)note_start_positions.size();
++	}
++
++	//------------------------------------------------------------------------------
++	bool get_note( Elf_Word     index,
++				   Elf_Word&    type,
++				   std::string& name,
++				   void*&       desc,
++				   Elf_Word&    descSize ) const
++	{
++		if ( index >= note_section->get_size() ) {
++			return false;
++		}
++
++		const char* pData =
++			note_section->get_data() + note_start_positions[index];
++		int align = sizeof( Elf_Word );
++
++		const endianess_convertor& convertor = elf_file.get_convertor();
++		type            = convertor( *(const Elf_Word*)( pData + 2 * align ) );
++		Elf_Word namesz = convertor( *(const Elf_Word*)( pData ) );
++		descSize = convertor( *(const Elf_Word*)( pData + sizeof( namesz ) ) );
++
++		Elf_Xword max_name_size =
++			note_section->get_size() - note_start_positions[index];
++		if ( namesz < 1 || namesz > max_name_size ||
++			 (Elf_Xword)namesz + descSize > max_name_size ) {
++			return false;
++		}
++		name.assign( pData + 3 * align, namesz - 1 );
++		if ( 0 == descSize ) {
++			desc = 0;
++		}
++		else {
++			desc =
++				const_cast<char*>( pData + 3 * align +
++								   ( ( namesz + align - 1 ) / align ) * align );
++		}
++
++		return true;
++	}
++
++	//------------------------------------------------------------------------------
++	void add_note( Elf_Word           type,
++				   const std::string& name,
++				   const void*        desc,
++				   Elf_Word           descSize )
++	{
++		const endianess_convertor& convertor = elf_file.get_convertor();
++
++		int         align       = sizeof( Elf_Word );
++		Elf_Word    nameLen     = (Elf_Word)name.size() + 1;
++		Elf_Word    nameLenConv = convertor( nameLen );
++		std::string buffer( reinterpret_cast<char*>( &nameLenConv ), align );
++		Elf_Word    descSizeConv = convertor( descSize );
++
++		buffer.append( reinterpret_cast<char*>( &descSizeConv ), align );
++		type = convertor( type );
++		buffer.append( reinterpret_cast<char*>( &type ), align );
++		buffer.append( name );
++		buffer.append( 1, '\x00' );
++		const char pad[] = { '\0', '\0', '\0', '\0' };
++		if ( nameLen % align != 0 ) {
++			buffer.append( pad, align - nameLen % align );
++		}
++		if ( desc != 0 && descSize != 0 ) {
++			buffer.append( reinterpret_cast<const char*>( desc ), descSize );
++			if ( descSize % align != 0 ) {
++				buffer.append( pad, align - descSize % align );
++			}
++		}
++
++		note_start_positions.push_back( note_section->get_size() );
++		note_section->append_data( buffer );
++	}
++
++  private:
++	//------------------------------------------------------------------------------
++	void process_section()
++	{
++		const endianess_convertor& convertor = elf_file.get_convertor();
++		const char*                data      = note_section->get_data();
++		Elf_Xword                  size      = note_section->get_size();
++		Elf_Xword                  current   = 0;
++
++		note_start_positions.clear();
++
++		// Is it empty?
++		if ( 0 == data || 0 == size ) {
++			return;
++		}
++
++		Elf_Word align = sizeof( Elf_Word );
++		while ( current + (Elf_Xword)3 * align <= size ) {
++			note_start_positions.push_back( current );
++			Elf_Word namesz = convertor( *(const Elf_Word*)( data + current ) );
++			Elf_Word descsz = convertor(
++				*(const Elf_Word*)( data + current + sizeof( namesz ) ) );
++
++			current += (Elf_Xword)3 * sizeof( Elf_Word ) +
++					   ( ( namesz + align - 1 ) / align ) * (Elf_Xword)align +
++					   ( ( descsz + align - 1 ) / align ) * (Elf_Xword)align;
++		}
++	}
++
++	//------------------------------------------------------------------------------
++  private:
++	const elfio&           elf_file;
++	S*                     note_section;
++	std::vector<Elf_Xword> note_start_positions;
++};
++
++using note_section_accessor = note_section_accessor_template<section>;
++using const_note_section_accessor =
++	note_section_accessor_template<const section>;
++
++} // namespace ELFIO
++
++#endif // ELFIO_NOTE_HPP
++
++/*** End of inlined file: elfio_note.hpp ***/
++
++
++/*** Start of inlined file: elfio_relocation.hpp ***/
++#ifndef ELFIO_RELOCATION_HPP
++#define ELFIO_RELOCATION_HPP
++
++namespace ELFIO {
++
++template <typename T> struct get_sym_and_type;
++template <> struct get_sym_and_type<Elf32_Rel>
++{
++	static int get_r_sym( Elf_Xword info )
++	{
++		return ELF32_R_SYM( (Elf_Word)info );
++	}
++	static int get_r_type( Elf_Xword info )
++	{
++		return ELF32_R_TYPE( (Elf_Word)info );
++	}
++};
++template <> struct get_sym_and_type<Elf32_Rela>
++{
++	static int get_r_sym( Elf_Xword info )
++	{
++		return ELF32_R_SYM( (Elf_Word)info );
++	}
++	static int get_r_type( Elf_Xword info )
++	{
++		return ELF32_R_TYPE( (Elf_Word)info );
++	}
++};
++template <> struct get_sym_and_type<Elf64_Rel>
++{
++	static int get_r_sym( Elf_Xword info ) { return ELF64_R_SYM( info ); }
++	static int get_r_type( Elf_Xword info ) { return ELF64_R_TYPE( info ); }
++};
++template <> struct get_sym_and_type<Elf64_Rela>
++{
++	static int get_r_sym( Elf_Xword info ) { return ELF64_R_SYM( info ); }
++	static int get_r_type( Elf_Xword info ) { return ELF64_R_TYPE( info ); }
++};
++
++//------------------------------------------------------------------------------
++template <class S> class relocation_section_accessor_template
++{
++  public:
++	//------------------------------------------------------------------------------
++	relocation_section_accessor_template( const elfio& elf_file_, S* section_ )
++		: elf_file( elf_file_ ), relocation_section( section_ )
++	{
++	}
++
++	//------------------------------------------------------------------------------
++	Elf_Xword get_entries_num() const
++	{
++		Elf_Xword nRet = 0;
++
++		if ( 0 != relocation_section->get_entry_size() ) {
++			nRet = relocation_section->get_size() /
++				   relocation_section->get_entry_size();
++		}
++
++		return nRet;
++	}
++
++	//------------------------------------------------------------------------------
++	bool get_entry( Elf_Xword   index,
++					Elf64_Addr& offset,
++					Elf_Word&   symbol,
++					Elf_Word&   type,
++					Elf_Sxword& addend ) const
++	{
++		if ( index >= get_entries_num() ) { // Is index valid
++			return false;
++		}
++
++		if ( elf_file.get_class() == ELFCLASS32 ) {
++			if ( SHT_REL == relocation_section->get_type() ) {
++				generic_get_entry_rel<Elf32_Rel>( index, offset, symbol, type,
++												  addend );
++			}
++			else if ( SHT_RELA == relocation_section->get_type() ) {
++				generic_get_entry_rela<Elf32_Rela>( index, offset, symbol, type,
++													addend );
++			}
++		}
++		else {
++			if ( SHT_REL == relocation_section->get_type() ) {
++				generic_get_entry_rel<Elf64_Rel>( index, offset, symbol, type,
++												  addend );
++			}
++			else if ( SHT_RELA == relocation_section->get_type() ) {
++				generic_get_entry_rela<Elf64_Rela>( index, offset, symbol, type,
++													addend );
++			}
++		}
++
++		return true;
++	}
++
++	//------------------------------------------------------------------------------
++	bool get_entry( Elf_Xword    index,
++					Elf64_Addr&  offset,
++					Elf64_Addr&  symbolValue,
++					std::string& symbolName,
++					Elf_Word&    type,
++					Elf_Sxword&  addend,
++					Elf_Sxword&  calcValue ) const
++	{
++		// Do regular job
++		Elf_Word symbol;
++		bool     ret = get_entry( index, offset, symbol, type, addend );
++
++		// Find the symbol
++		Elf_Xword     size;
++		unsigned char bind;
++		unsigned char symbolType;
++		Elf_Half      section;
++		unsigned char other;
++
++		symbol_section_accessor symbols(
++			elf_file, elf_file.sections[get_symbol_table_index()] );
++		ret = ret && symbols.get_symbol( symbol, symbolName, symbolValue, size,
++										 bind, symbolType, section, other );
++
++		if ( ret ) { // Was it successful?
++			switch ( type ) {
++			case R_386_NONE: // none
++				calcValue = 0;
++				break;
++			case R_386_32: // S + A
++				calcValue = symbolValue + addend;
++				break;
++			case R_386_PC32: // S + A - P
++				calcValue = symbolValue + addend - offset;
++				break;
++			case R_386_GOT32: // G + A - P
++				calcValue = 0;
++				break;
++			case R_386_PLT32: // L + A - P
++				calcValue = 0;
++				break;
++			case R_386_COPY: // none
++				calcValue = 0;
++				break;
++			case R_386_GLOB_DAT: // S
++			case R_386_JMP_SLOT: // S
++				calcValue = symbolValue;
++				break;
++			case R_386_RELATIVE: // B + A
++				calcValue = addend;
++				break;
++			case R_386_GOTOFF: // S + A - GOT
++				calcValue = 0;
++				break;
++			case R_386_GOTPC: // GOT + A - P
++				calcValue = 0;
++				break;
++			default: // Not recognized symbol!
++				calcValue = 0;
++				break;
++			}
++		}
++
++		return ret;
++	}
++
++	//------------------------------------------------------------------------------
++	bool set_entry( Elf_Xword  index,
++					Elf64_Addr offset,
++					Elf_Word   symbol,
++					Elf_Word   type,
++					Elf_Sxword addend )
++	{
++		if ( index >= get_entries_num() ) { // Is index valid
++			return false;
++		}
++
++		if ( elf_file.get_class() == ELFCLASS32 ) {
++			if ( SHT_REL == relocation_section->get_type() ) {
++				generic_set_entry_rel<Elf32_Rel>( index, offset, symbol, type,
++												  addend );
++			}
++			else if ( SHT_RELA == relocation_section->get_type() ) {
++				generic_set_entry_rela<Elf32_Rela>( index, offset, symbol, type,
++													addend );
++			}
++		}
++		else {
++			if ( SHT_REL == relocation_section->get_type() ) {
++				generic_set_entry_rel<Elf64_Rel>( index, offset, symbol, type,
++												  addend );
++			}
++			else if ( SHT_RELA == relocation_section->get_type() ) {
++				generic_set_entry_rela<Elf64_Rela>( index, offset, symbol, type,
++													addend );
++			}
++		}
++
++		return true;
++	}
++
++	//------------------------------------------------------------------------------
++	void add_entry( Elf64_Addr offset, Elf_Xword info )
++	{
++		if ( elf_file.get_class() == ELFCLASS32 ) {
++			generic_add_entry<Elf32_Rel>( offset, info );
++		}
++		else {
++			generic_add_entry<Elf64_Rel>( offset, info );
++		}
++	}
++
++	//------------------------------------------------------------------------------
++	void add_entry( Elf64_Addr offset, Elf_Word symbol, unsigned char type )
++	{
++		Elf_Xword info;
++		if ( elf_file.get_class() == ELFCLASS32 ) {
++			info = ELF32_R_INFO( (Elf_Xword)symbol, type );
++		}
++		else {
++			info = ELF64_R_INFO( (Elf_Xword)symbol, type );
++		}
++
++		add_entry( offset, info );
++	}
++
++	//------------------------------------------------------------------------------
++	void add_entry( Elf64_Addr offset, Elf_Xword info, Elf_Sxword addend )
++	{
++		if ( elf_file.get_class() == ELFCLASS32 ) {
++			generic_add_entry<Elf32_Rela>( offset, info, addend );
++		}
++		else {
++			generic_add_entry<Elf64_Rela>( offset, info, addend );
++		}
++	}
++
++	//------------------------------------------------------------------------------
++	void add_entry( Elf64_Addr    offset,
++					Elf_Word      symbol,
++					unsigned char type,
++					Elf_Sxword    addend )
++	{
++		Elf_Xword info;
++		if ( elf_file.get_class() == ELFCLASS32 ) {
++			info = ELF32_R_INFO( (Elf_Xword)symbol, type );
++		}
++		else {
++			info = ELF64_R_INFO( (Elf_Xword)symbol, type );
++		}
++
++		add_entry( offset, info, addend );
++	}
++
++	//------------------------------------------------------------------------------
++	void add_entry( string_section_accessor str_writer,
++					const char*             str,
++					symbol_section_accessor sym_writer,
++					Elf64_Addr              value,
++					Elf_Word                size,
++					unsigned char           sym_info,
++					unsigned char           other,
++					Elf_Half                shndx,
++					Elf64_Addr              offset,
++					unsigned char           type )
++	{
++		Elf_Word str_index = str_writer.add_string( str );
++		Elf_Word sym_index = sym_writer.add_symbol( str_index, value, size,
++													sym_info, other, shndx );
++		add_entry( offset, sym_index, type );
++	}
++
++	//------------------------------------------------------------------------------
++	void swap_symbols( Elf_Xword first, Elf_Xword second )
++	{
++		Elf64_Addr offset;
++		Elf_Word   symbol;
++		Elf_Word   rtype;
++		Elf_Sxword addend;
++		for ( Elf_Word i = 0; i < get_entries_num(); i++ ) {
++			get_entry( i, offset, symbol, rtype, addend );
++			if ( symbol == first ) {
++				set_entry( i, offset, (Elf_Word)second, rtype, addend );
++			}
++			if ( symbol == second ) {
++				set_entry( i, offset, (Elf_Word)first, rtype, addend );
++			}
++		}
++	}
++
++	//------------------------------------------------------------------------------
++  private:
++	//------------------------------------------------------------------------------
++	Elf_Half get_symbol_table_index() const
++	{
++		return (Elf_Half)relocation_section->get_link();
++	}
++
++	//------------------------------------------------------------------------------
++	template <class T>
++	void generic_get_entry_rel( Elf_Xword   index,
++								Elf64_Addr& offset,
++								Elf_Word&   symbol,
++								Elf_Word&   type,
++								Elf_Sxword& addend ) const
++	{
++		const endianess_convertor& convertor = elf_file.get_convertor();
++
++		const T* pEntry = reinterpret_cast<const T*>(
++			relocation_section->get_data() +
++			index * relocation_section->get_entry_size() );
++		offset        = convertor( pEntry->r_offset );
++		Elf_Xword tmp = convertor( pEntry->r_info );
++		symbol        = get_sym_and_type<T>::get_r_sym( tmp );
++		type          = get_sym_and_type<T>::get_r_type( tmp );
++		addend        = 0;
++	}
++
++	//------------------------------------------------------------------------------
++	template <class T>
++	void generic_get_entry_rela( Elf_Xword   index,
++								 Elf64_Addr& offset,
++								 Elf_Word&   symbol,
++								 Elf_Word&   type,
++								 Elf_Sxword& addend ) const
++	{
++		const endianess_convertor& convertor = elf_file.get_convertor();
++
++		const T* pEntry = reinterpret_cast<const T*>(
++			relocation_section->get_data() +
++			index * relocation_section->get_entry_size() );
++		offset        = convertor( pEntry->r_offset );
++		Elf_Xword tmp = convertor( pEntry->r_info );
++		symbol        = get_sym_and_type<T>::get_r_sym( tmp );
++		type          = get_sym_and_type<T>::get_r_type( tmp );
++		addend        = convertor( pEntry->r_addend );
++	}
++
++	//------------------------------------------------------------------------------
++	template <class T>
++	void generic_set_entry_rel( Elf_Xword  index,
++								Elf64_Addr offset,
++								Elf_Word   symbol,
++								Elf_Word   type,
++								Elf_Sxword )
++	{
++		const endianess_convertor& convertor = elf_file.get_convertor();
++
++		T* pEntry = const_cast<T*>( reinterpret_cast<const T*>(
++			relocation_section->get_data() +
++			index * relocation_section->get_entry_size() ) );
++
++		if ( elf_file.get_class() == ELFCLASS32 ) {
++			pEntry->r_info = ELF32_R_INFO( (Elf_Xword)symbol, type );
++		}
++		else {
++			pEntry->r_info = ELF64_R_INFO( (Elf_Xword)symbol, type );
++		}
++		pEntry->r_offset = offset;
++		pEntry->r_offset = convertor( pEntry->r_offset );
++		pEntry->r_info   = convertor( pEntry->r_info );
++	}
++
++	//------------------------------------------------------------------------------
++	template <class T>
++	void generic_set_entry_rela( Elf_Xword  index,
++								 Elf64_Addr offset,
++								 Elf_Word   symbol,
++								 Elf_Word   type,
++								 Elf_Sxword addend )
++	{
++		const endianess_convertor& convertor = elf_file.get_convertor();
++
++		T* pEntry = const_cast<T*>( reinterpret_cast<const T*>(
++			relocation_section->get_data() +
++			index * relocation_section->get_entry_size() ) );
++
++		if ( elf_file.get_class() == ELFCLASS32 ) {
++			pEntry->r_info = ELF32_R_INFO( (Elf_Xword)symbol, type );
++		}
++		else {
++			pEntry->r_info = ELF64_R_INFO( (Elf_Xword)symbol, type );
++		}
++		pEntry->r_offset = offset;
++		pEntry->r_addend = addend;
++		pEntry->r_offset = convertor( pEntry->r_offset );
++		pEntry->r_info   = convertor( pEntry->r_info );
++		pEntry->r_addend = convertor( pEntry->r_addend );
++	}
++
++	//------------------------------------------------------------------------------
++	template <class T>
++	void generic_add_entry( Elf64_Addr offset, Elf_Xword info )
++	{
++		const endianess_convertor& convertor = elf_file.get_convertor();
++
++		T entry;
++		entry.r_offset = offset;
++		entry.r_info   = info;
++		entry.r_offset = convertor( entry.r_offset );
++		entry.r_info   = convertor( entry.r_info );
++
++		relocation_section->append_data( reinterpret_cast<char*>( &entry ),
++										 sizeof( entry ) );
++	}
++
++	//------------------------------------------------------------------------------
++	template <class T>
++	void
++	generic_add_entry( Elf64_Addr offset, Elf_Xword info, Elf_Sxword addend )
++	{
++		const endianess_convertor& convertor = elf_file.get_convertor();
++
++		T entry;
++		entry.r_offset = offset;
++		entry.r_info   = info;
++		entry.r_addend = addend;
++		entry.r_offset = convertor( entry.r_offset );
++		entry.r_info   = convertor( entry.r_info );
++		entry.r_addend = convertor( entry.r_addend );
++
++		relocation_section->append_data( reinterpret_cast<char*>( &entry ),
++										 sizeof( entry ) );
++	}
++
++	//------------------------------------------------------------------------------
++  private:
++	const elfio& elf_file;
++	S*           relocation_section;
++};
++
++using relocation_section_accessor =
++	relocation_section_accessor_template<section>;
++using const_relocation_section_accessor =
++	relocation_section_accessor_template<const section>;
++
++} // namespace ELFIO
++
++#endif // ELFIO_RELOCATION_HPP
++
++/*** End of inlined file: elfio_relocation.hpp ***/
++
++
++/*** Start of inlined file: elfio_dynamic.hpp ***/
++#ifndef ELFIO_DYNAMIC_HPP
++#define ELFIO_DYNAMIC_HPP
++
++namespace ELFIO {
++
++//------------------------------------------------------------------------------
++template <class S> class dynamic_section_accessor_template
++{
++  public:
++	//------------------------------------------------------------------------------
++	dynamic_section_accessor_template( const elfio& elf_file_, S* section_ )
++		: elf_file( elf_file_ ), dynamic_section( section_ )
++	{
++	}
++
++	//------------------------------------------------------------------------------
++	Elf_Xword get_entries_num() const
++	{
++		Elf_Xword nRet = 0;
++
++		if ( 0 != dynamic_section->get_entry_size() ) {
++			nRet =
++				dynamic_section->get_size() / dynamic_section->get_entry_size();
++		}
++
++		return nRet;
++	}
++
++	//------------------------------------------------------------------------------
++	bool get_entry( Elf_Xword    index,
++					Elf_Xword&   tag,
++					Elf_Xword&   value,
++					std::string& str ) const
++	{
++		if ( index >= get_entries_num() ) { // Is index valid
++			return false;
++		}
++
++		if ( elf_file.get_class() == ELFCLASS32 ) {
++			generic_get_entry_dyn<Elf32_Dyn>( index, tag, value );
++		}
++		else {
++			generic_get_entry_dyn<Elf64_Dyn>( index, tag, value );
++		}
++
++		// If the tag may have a string table reference, prepare the string
++		if ( tag == DT_NEEDED || tag == DT_SONAME || tag == DT_RPATH ||
++			 tag == DT_RUNPATH ) {
++			string_section_accessor strsec =
++				elf_file.sections[get_string_table_index()];
++			const char* result = strsec.get_string( value );
++			if ( 0 == result ) {
++				str.clear();
++				return false;
++			}
++			str = result;
++		}
++		else {
++			str.clear();
++		}
++
++		return true;
++	}
++
++	//------------------------------------------------------------------------------
++	void add_entry( Elf_Xword tag, Elf_Xword value )
++	{
++		if ( elf_file.get_class() == ELFCLASS32 ) {
++			generic_add_entry<Elf32_Dyn>( tag, value );
++		}
++		else {
++			generic_add_entry<Elf64_Dyn>( tag, value );
++		}
++	}
++
++	//------------------------------------------------------------------------------
++	void add_entry( Elf_Xword tag, const std::string& str )
++	{
++		string_section_accessor strsec =
++			elf_file.sections[get_string_table_index()];
++		Elf_Xword value = strsec.add_string( str );
++		add_entry( tag, value );
++	}
++
++	//------------------------------------------------------------------------------
++  private:
++	//------------------------------------------------------------------------------
++	Elf_Half get_string_table_index() const
++	{
++		return (Elf_Half)dynamic_section->get_link();
++	}
++
++	//------------------------------------------------------------------------------
++	template <class T>
++	void generic_get_entry_dyn( Elf_Xword  index,
++								Elf_Xword& tag,
++								Elf_Xword& value ) const
++	{
++		const endianess_convertor& convertor = elf_file.get_convertor();
++
++		// Check unusual case when dynamic section has no data
++		if ( dynamic_section->get_data() == 0 ||
++			 ( index + 1 ) * dynamic_section->get_entry_size() >
++				 dynamic_section->get_size() ) {
++			tag   = DT_NULL;
++			value = 0;
++			return;
++		}
++
++		const T* pEntry = reinterpret_cast<const T*>(
++			dynamic_section->get_data() +
++			index * dynamic_section->get_entry_size() );
++		tag = convertor( pEntry->d_tag );
++		switch ( tag ) {
++		case DT_NULL:
++		case DT_SYMBOLIC:
++		case DT_TEXTREL:
++		case DT_BIND_NOW:
++			value = 0;
++			break;
++		case DT_NEEDED:
++		case DT_PLTRELSZ:
++		case DT_RELASZ:
++		case DT_RELAENT:
++		case DT_STRSZ:
++		case DT_SYMENT:
++		case DT_SONAME:
++		case DT_RPATH:
++		case DT_RELSZ:
++		case DT_RELENT:
++		case DT_PLTREL:
++		case DT_INIT_ARRAYSZ:
++		case DT_FINI_ARRAYSZ:
++		case DT_RUNPATH:
++		case DT_FLAGS:
++		case DT_PREINIT_ARRAYSZ:
++			value = convertor( pEntry->d_un.d_val );
++			break;
++		case DT_PLTGOT:
++		case DT_HASH:
++		case DT_STRTAB:
++		case DT_SYMTAB:
++		case DT_RELA:
++		case DT_INIT:
++		case DT_FINI:
++		case DT_REL:
++		case DT_DEBUG:
++		case DT_JMPREL:
++		case DT_INIT_ARRAY:
++		case DT_FINI_ARRAY:
++		case DT_PREINIT_ARRAY:
++		default:
++			value = convertor( pEntry->d_un.d_ptr );
++			break;
++		}
++	}
++
++	//------------------------------------------------------------------------------
++	template <class T> void generic_add_entry( Elf_Xword tag, Elf_Xword value )
++	{
++		const endianess_convertor& convertor = elf_file.get_convertor();
++
++		T entry;
++
++		switch ( tag ) {
++		case DT_NULL:
++		case DT_SYMBOLIC:
++		case DT_TEXTREL:
++		case DT_BIND_NOW:
++			value = 0;
++		case DT_NEEDED:
++		case DT_PLTRELSZ:
++		case DT_RELASZ:
++		case DT_RELAENT:
++		case DT_STRSZ:
++		case DT_SYMENT:
++		case DT_SONAME:
++		case DT_RPATH:
++		case DT_RELSZ:
++		case DT_RELENT:
++		case DT_PLTREL:
++		case DT_INIT_ARRAYSZ:
++		case DT_FINI_ARRAYSZ:
++		case DT_RUNPATH:
++		case DT_FLAGS:
++		case DT_PREINIT_ARRAYSZ:
++			entry.d_un.d_val = convertor( value );
++			break;
++		case DT_PLTGOT:
++		case DT_HASH:
++		case DT_STRTAB:
++		case DT_SYMTAB:
++		case DT_RELA:
++		case DT_INIT:
++		case DT_FINI:
++		case DT_REL:
++		case DT_DEBUG:
++		case DT_JMPREL:
++		case DT_INIT_ARRAY:
++		case DT_FINI_ARRAY:
++		case DT_PREINIT_ARRAY:
++		default:
++			entry.d_un.d_ptr = convertor( value );
++			break;
++		}
++
++		entry.d_tag = convertor( tag );
++
++		dynamic_section->append_data( reinterpret_cast<char*>( &entry ),
++									  sizeof( entry ) );
++	}
++
++	//------------------------------------------------------------------------------
++  private:
++	const elfio& elf_file;
++	S*           dynamic_section;
++};
++
++using dynamic_section_accessor = dynamic_section_accessor_template<section>;
++using const_dynamic_section_accessor =
++	dynamic_section_accessor_template<const section>;
++
++} // namespace ELFIO
++
++#endif // ELFIO_DYNAMIC_HPP
++
++/*** End of inlined file: elfio_dynamic.hpp ***/
++
++
++/*** Start of inlined file: elfio_modinfo.hpp ***/
++#ifndef ELFIO_MODINFO_HPP
++#define ELFIO_MODINFO_HPP
++
++#include <string>
++#include <vector>
++
++namespace ELFIO {
++
++//------------------------------------------------------------------------------
++template <class S> class modinfo_section_accessor_template
++{
++  public:
++	//------------------------------------------------------------------------------
++	modinfo_section_accessor_template( S* section_ )
++		: modinfo_section( section_ )
++	{
++		process_section();
++	}
++
++	//------------------------------------------------------------------------------
++	Elf_Word get_attribute_num() const { return (Elf_Word)content.size(); }
++
++	//------------------------------------------------------------------------------
++	bool
++	get_attribute( Elf_Word no, std::string& field, std::string& value ) const
++	{
++		if ( no < content.size() ) {
++			field = content[no].first;
++			value = content[no].second;
++			return true;
++		}
++
++		return false;
++	}
++
++	//------------------------------------------------------------------------------
++	bool get_attribute( std::string field_name, std::string& value ) const
++	{
++		for ( auto i = content.begin(); i != content.end(); i++ ) {
++			if ( field_name == i->first ) {
++				value = i->second;
++				return true;
++			}
++		}
++
++		return false;
++	}
++
++	//------------------------------------------------------------------------------
++	Elf_Word add_attribute( std::string field, std::string value )
++	{
++		Elf_Word current_position = 0;
++
++		if ( modinfo_section ) {
++			// Strings are addeded to the end of the current section data
++			current_position = (Elf_Word)modinfo_section->get_size();
++
++			std::string attribute = field + "=" + value;
++
++			modinfo_section->append_data( attribute + '\0' );
++			content.push_back(
++				std::pair<std::string, std::string>( field, value ) );
++		}
++
++		return current_position;
++	}
++
++	//------------------------------------------------------------------------------
++  private:
++	void process_section()
++	{
++		const char* pdata = modinfo_section->get_data();
++		if ( pdata ) {
++			ELFIO::Elf_Xword i = 0;
++			while ( i < modinfo_section->get_size() ) {
++				while ( i < modinfo_section->get_size() && !pdata[i] )
++					i++;
++				if ( i < modinfo_section->get_size() ) {
++					std::string                         info = pdata + i;
++					size_t                              loc  = info.find( '=' );
++					std::pair<std::string, std::string> attribute(
++						info.substr( 0, loc ), info.substr( loc + 1 ) );
++
++					content.push_back( attribute );
++
++					i += info.length();
++				}
++			}
++		}
++	}
++
++	//------------------------------------------------------------------------------
++  private:
++	S*                                               modinfo_section;
++	std::vector<std::pair<std::string, std::string>> content;
++};
++
++using modinfo_section_accessor = modinfo_section_accessor_template<section>;
++using const_modinfo_section_accessor =
++	modinfo_section_accessor_template<const section>;
++
++} // namespace ELFIO
++
++#endif // ELFIO_MODINFO_HPP
++
++/*** End of inlined file: elfio_modinfo.hpp ***/
++
++#ifdef _MSC_VER
++#pragma warning( pop )
++#endif
++
++#endif // ELFIO_HPP
++
++/*** End of inlined file: elfio.hpp ***/
++
++
++namespace ELFIO {
++
++static struct class_table_t
++{
++	const char  key;
++	const char* str;
++} class_table[] = {
++	{ ELFCLASS32, "ELF32" },
++	{ ELFCLASS64, "ELF64" },
++};
++
++static struct endian_table_t
++{
++	const char  key;
++	const char* str;
++} endian_table[] = {
++	{ ELFDATANONE, "None" },
++	{ ELFDATA2LSB, "Little endian" },
++	{ ELFDATA2MSB, "Big endian" },
++};
++
++static struct version_table_t
++{
++	const Elf64_Word key;
++	const char*      str;
++} version_table[] = {
++	{ EV_NONE, "None" },
++	{ EV_CURRENT, "Current" },
++};
++
++static struct type_table_t
++{
++	const Elf32_Half key;
++	const char*      str;
++} type_table[] = {
++	{ ET_NONE, "No file type" },    { ET_REL, "Relocatable file" },
++	{ ET_EXEC, "Executable file" }, { ET_DYN, "Shared object file" },
++	{ ET_CORE, "Core file" },
++};
++
++static struct machine_table_t
++{
++	const Elf64_Half key;
++	const char*      str;
++} machine_table[] = {
++	{ EM_NONE, "No machine" },
++	{ EM_M32, "AT&T WE 32100" },
++	{ EM_SPARC, "SUN SPARC" },
++	{ EM_386, "Intel 80386" },
++	{ EM_68K, "Motorola m68k family" },
++	{ EM_88K, "Motorola m88k family" },
++	{ EM_486, "Intel 80486// Reserved for future use" },
++	{ EM_860, "Intel 80860" },
++	{ EM_MIPS, "MIPS R3000 (officially, big-endian only)" },
++	{ EM_S370, "IBM System/370" },
++	{ EM_MIPS_RS3_LE,
++	  "MIPS R3000 little-endian (Oct 4 1999 Draft) Deprecated" },
++	{ EM_res011, "Reserved" },
++	{ EM_res012, "Reserved" },
++	{ EM_res013, "Reserved" },
++	{ EM_res014, "Reserved" },
++	{ EM_PARISC, "HPPA" },
++	{ EM_res016, "Reserved" },
++	{ EM_VPP550, "Fujitsu VPP500" },
++	{ EM_SPARC32PLUS, "Sun's v8plus" },
++	{ EM_960, "Intel 80960" },
++	{ EM_PPC, "PowerPC" },
++	{ EM_PPC64, "64-bit PowerPC" },
++	{ EM_S390, "IBM S/390" },
++	{ EM_SPU, "Sony/Toshiba/IBM SPU" },
++	{ EM_res024, "Reserved" },
++	{ EM_res025, "Reserved" },
++	{ EM_res026, "Reserved" },
++	{ EM_res027, "Reserved" },
++	{ EM_res028, "Reserved" },
++	{ EM_res029, "Reserved" },
++	{ EM_res030, "Reserved" },
++	{ EM_res031, "Reserved" },
++	{ EM_res032, "Reserved" },
++	{ EM_res033, "Reserved" },
++	{ EM_res034, "Reserved" },
++	{ EM_res035, "Reserved" },
++	{ EM_V800, "NEC V800 series" },
++	{ EM_FR20, "Fujitsu FR20" },
++	{ EM_RH32, "TRW RH32" },
++	{ EM_MCORE, "Motorola M*Core // May also be taken by Fujitsu MMA" },
++	{ EM_RCE, "Old name for MCore" },
++	{ EM_ARM, "ARM" },
++	{ EM_OLD_ALPHA, "Digital Alpha" },
++	{ EM_SH, "Renesas (formerly Hitachi) / SuperH SH" },
++	{ EM_SPARCV9, "SPARC v9 64-bit" },
++	{ EM_TRICORE, "Siemens Tricore embedded processor" },
++	{ EM_ARC, "ARC Cores" },
++	{ EM_H8_300, "Renesas (formerly Hitachi) H8/300" },
++	{ EM_H8_300H, "Renesas (formerly Hitachi) H8/300H" },
++	{ EM_H8S, "Renesas (formerly Hitachi) H8S" },
++	{ EM_H8_500, "Renesas (formerly Hitachi) H8/500" },
++	{ EM_IA_64, "Intel IA-64 Processor" },
++	{ EM_MIPS_X, "Stanford MIPS-X" },
++	{ EM_COLDFIRE, "Motorola Coldfire" },
++	{ EM_68HC12, "Motorola M68HC12" },
++	{ EM_MMA, "Fujitsu Multimedia Accelerator" },
++	{ EM_PCP, "Siemens PCP" },
++	{ EM_NCPU, "Sony nCPU embedded RISC processor" },
++	{ EM_NDR1, "Denso NDR1 microprocesspr" },
++	{ EM_STARCORE, "Motorola Star*Core processor" },
++	{ EM_ME16, "Toyota ME16 processor" },
++	{ EM_ST100, "STMicroelectronics ST100 processor" },
++	{ EM_TINYJ, "Advanced Logic Corp. TinyJ embedded processor" },
++	{ EM_X86_64, "Advanced Micro Devices X86-64 processor" },
++	{ EM_PDSP, "Sony DSP Processor" },
++	{ EM_PDP10, "Digital Equipment Corp. PDP-10" },
++	{ EM_PDP11, "Digital Equipment Corp. PDP-11" },
++	{ EM_FX66, "Siemens FX66 microcontroller" },
++	{ EM_ST9PLUS, "STMicroelectronics ST9+ 8/16 bit microcontroller" },
++	{ EM_ST7, "STMicroelectronics ST7 8-bit microcontroller" },
++	{ EM_68HC16, "Motorola MC68HC16 Microcontroller" },
++	{ EM_68HC11, "Motorola MC68HC11 Microcontroller" },
++	{ EM_68HC08, "Motorola MC68HC08 Microcontroller" },
++	{ EM_68HC05, "Motorola MC68HC05 Microcontroller" },
++	{ EM_SVX, "Silicon Graphics SVx" },
++	{ EM_ST19, "STMicroelectronics ST19 8-bit cpu" },
++	{ EM_VAX, "Digital VAX" },
++	{ EM_CRIS, "Axis Communications 32-bit embedded processor" },
++	{ EM_JAVELIN, "Infineon Technologies 32-bit embedded cpu" },
++	{ EM_FIREPATH, "Element 14 64-bit DSP processor" },
++	{ EM_ZSP, "LSI Logic's 16-bit DSP processor" },
++	{ EM_MMIX, "Donald Knuth's educational 64-bit processor" },
++	{ EM_HUANY, "Harvard's machine-independent format" },
++	{ EM_PRISM, "SiTera Prism" },
++	{ EM_AVR, "Atmel AVR 8-bit microcontroller" },
++	{ EM_FR30, "Fujitsu FR30" },
++	{ EM_D10V, "Mitsubishi D10V" },
++	{ EM_D30V, "Mitsubishi D30V" },
++	{ EM_V850, "NEC v850" },
++	{ EM_M32R, "Renesas M32R (formerly Mitsubishi M32R)" },
++	{ EM_MN10300, "Matsushita MN10300" },
++	{ EM_MN10200, "Matsushita MN10200" },
++	{ EM_PJ, "picoJava" },
++	{ EM_OPENRISC, "OpenRISC 32-bit embedded processor" },
++	{ EM_ARC_A5, "ARC Cores Tangent-A5" },
++	{ EM_XTENSA, "Tensilica Xtensa Architecture" },
++	{ EM_VIDEOCORE, "Alphamosaic VideoCore processor" },
++	{ EM_TMM_GPP, "Thompson Multimedia General Purpose Processor" },
++	{ EM_NS32K, "National Semiconductor 32000 series" },
++	{ EM_TPC, "Tenor Network TPC processor" },
++	{ EM_SNP1K, "Trebia SNP 1000 processor" },
++	{ EM_ST200, "STMicroelectronics ST200 microcontroller" },
++	{ EM_IP2K, "Ubicom IP2022 micro controller" },
++	{ EM_MAX, "MAX Processor" },
++	{ EM_CR, "National Semiconductor CompactRISC" },
++	{ EM_F2MC16, "Fujitsu F2MC16" },
++	{ EM_MSP430, "TI msp430 micro controller" },
++	{ EM_BLACKFIN, "ADI Blackfin" },
++	{ EM_SE_C33, "S1C33 Family of Seiko Epson processors" },
++	{ EM_SEP, "Sharp embedded microprocessor" },
++	{ EM_ARCA, "Arca RISC Microprocessor" },
++	{ EM_UNICORE, "Microprocessor series from PKU-Unity Ltd. and MPRC of "
++				  "Peking University" },
++	{ EM_EXCESS, "eXcess: 16/32/64-bit configurable embedded CPU" },
++	{ EM_DXP, "Icera Semiconductor Inc. Deep Execution Processor" },
++	{ EM_ALTERA_NIOS2, "Altera Nios II soft-core processor" },
++	{ EM_CRX, "National Semiconductor CRX" },
++	{ EM_XGATE, "Motorola XGATE embedded processor" },
++	{ EM_C166, "Infineon C16x/XC16x processor" },
++	{ EM_M16C, "Renesas M16C series microprocessors" },
++	{ EM_DSPIC30F, "Microchip Technology dsPIC30F Digital Signal Controller" },
++	{ EM_CE, "Freescale Communication Engine RISC core" },
++	{ EM_M32C, "Renesas M32C series microprocessors" },
++	{ EM_res121, "Reserved" },
++	{ EM_res122, "Reserved" },
++	{ EM_res123, "Reserved" },
++	{ EM_res124, "Reserved" },
++	{ EM_res125, "Reserved" },
++	{ EM_res126, "Reserved" },
++	{ EM_res127, "Reserved" },
++	{ EM_res128, "Reserved" },
++	{ EM_res129, "Reserved" },
++	{ EM_res130, "Reserved" },
++	{ EM_TSK3000, "Altium TSK3000 core" },
++	{ EM_RS08, "Freescale RS08 embedded processor" },
++	{ EM_res133, "Reserved" },
++	{ EM_ECOG2, "Cyan Technology eCOG2 microprocessor" },
++	{ EM_SCORE, "Sunplus Score" },
++	{ EM_SCORE7, "Sunplus S+core7 RISC processor" },
++	{ EM_DSP24, "New Japan Radio (NJR) 24-bit DSP Processor" },
++	{ EM_VIDEOCORE3, "Broadcom VideoCore III processor" },
++	{ EM_LATTICEMICO32, "RISC processor for Lattice FPGA architecture" },
++	{ EM_SE_C17, "Seiko Epson C17 family" },
++	{ EM_TI_C6000, "Texas Instruments TMS320C6000 DSP family" },
++	{ EM_TI_C2000, "Texas Instruments TMS320C2000 DSP family" },
++	{ EM_TI_C5500, "Texas Instruments TMS320C55x DSP family" },
++	{ EM_res143, "Reserved" },
++	{ EM_res144, "Reserved" },
++	{ EM_res145, "Reserved" },
++	{ EM_res146, "Reserved" },
++	{ EM_res147, "Reserved" },
++	{ EM_res148, "Reserved" },
++	{ EM_res149, "Reserved" },
++	{ EM_res150, "Reserved" },
++	{ EM_res151, "Reserved" },
++	{ EM_res152, "Reserved" },
++	{ EM_res153, "Reserved" },
++	{ EM_res154, "Reserved" },
++	{ EM_res155, "Reserved" },
++	{ EM_res156, "Reserved" },
++	{ EM_res157, "Reserved" },
++	{ EM_res158, "Reserved" },
++	{ EM_res159, "Reserved" },
++	{ EM_MMDSP_PLUS, "STMicroelectronics 64bit VLIW Data Signal Processor" },
++	{ EM_CYPRESS_M8C, "Cypress M8C microprocessor" },
++	{ EM_R32C, "Renesas R32C series microprocessors" },
++	{ EM_TRIMEDIA, "NXP Semiconductors TriMedia architecture family" },
++	{ EM_QDSP6, "QUALCOMM DSP6 Processor" },
++	{ EM_8051, "Intel 8051 and variants" },
++	{ EM_STXP7X, "STMicroelectronics STxP7x family" },
++	{ EM_NDS32,
++	  "Andes Technology compact code size embedded RISC processor family" },
++	{ EM_ECOG1, "Cyan Technology eCOG1X family" },
++	{ EM_ECOG1X, "Cyan Technology eCOG1X family" },
++	{ EM_MAXQ30, "Dallas Semiconductor MAXQ30 Core Micro-controllers" },
++	{ EM_XIMO16, "New Japan Radio (NJR) 16-bit DSP Processor" },
++	{ EM_MANIK, "M2000 Reconfigurable RISC Microprocessor" },
++	{ EM_CRAYNV2, "Cray Inc. NV2 vector architecture" },
++	{ EM_RX, "Renesas RX family" },
++	{ EM_METAG, "Imagination Technologies META processor architecture" },
++	{ EM_MCST_ELBRUS, "MCST Elbrus general purpose hardware architecture" },
++	{ EM_ECOG16, "Cyan Technology eCOG16 family" },
++	{ EM_CR16, "National Semiconductor CompactRISC 16-bit processor" },
++	{ EM_ETPU, "Freescale Extended Time Processing Unit" },
++	{ EM_SLE9X, "Infineon Technologies SLE9X core" },
++	{ EM_L1OM, "Intel L1OM" },
++	{ EM_INTEL181, "Reserved by Intel" },
++	{ EM_INTEL182, "Reserved by Intel" },
++	{ EM_res183, "Reserved by ARM" },
++	{ EM_res184, "Reserved by ARM" },
++	{ EM_AVR32, "Atmel Corporation 32-bit microprocessor family" },
++	{ EM_STM8, "STMicroeletronics STM8 8-bit microcontroller" },
++	{ EM_TILE64, "Tilera TILE64 multicore architecture family" },
++	{ EM_TILEPRO, "Tilera TILEPro multicore architecture family" },
++	{ EM_MICROBLAZE, "Xilinx MicroBlaze 32-bit RISC soft processor core" },
++	{ EM_CUDA, "NVIDIA CUDA architecture " },
++};
++
++static struct section_type_table_t
++{
++	const Elf64_Half key;
++	const char*      str;
++} section_type_table[] = {
++	{ SHT_NULL, "NULL" },
++	{ SHT_PROGBITS, "PROGBITS" },
++	{ SHT_SYMTAB, "SYMTAB" },
++	{ SHT_STRTAB, "STRTAB" },
++	{ SHT_RELA, "RELA" },
++	{ SHT_HASH, "HASH" },
++	{ SHT_DYNAMIC, "DYNAMIC" },
++	{ SHT_NOTE, "NOTE" },
++	{ SHT_NOBITS, "NOBITS" },
++	{ SHT_REL, "REL" },
++	{ SHT_SHLIB, "SHLIB" },
++	{ SHT_DYNSYM, "DYNSYM" },
++	{ SHT_INIT_ARRAY, "INIT_ARRAY" },
++	{ SHT_FINI_ARRAY, "FINI_ARRAY" },
++	{ SHT_PREINIT_ARRAY, "PREINIT_ARRAY" },
++	{ SHT_GROUP, "GROUP" },
++	{ SHT_SYMTAB_SHNDX, "SYMTAB_SHNDX " },
++};
++
++static struct segment_type_table_t
++{
++	const Elf_Word key;
++	const char*    str;
++} segment_type_table[] = {
++	{ PT_NULL, "NULL" },     { PT_LOAD, "LOAD" }, { PT_DYNAMIC, "DYNAMIC" },
++	{ PT_INTERP, "INTERP" }, { PT_NOTE, "NOTE" }, { PT_SHLIB, "SHLIB" },
++	{ PT_PHDR, "PHDR" },     { PT_TLS, "TLS" },
++};
++
++static struct segment_flag_table_t
++{
++	const Elf_Word key;
++	const char*    str;
++} segment_flag_table[] = {
++	{ 0, "" },  { 1, "X" },  { 2, "W" },  { 3, "WX" },
++	{ 4, "R" }, { 5, "RX" }, { 6, "RW" }, { 7, "RWX" },
++};
++
++static struct symbol_bind_t
++{
++	const Elf_Word key;
++	const char*    str;
++} symbol_bind_table[] = {
++	{ STB_LOCAL, "LOCAL" },   { STB_GLOBAL, "GLOBAL" },
++	{ STB_WEAK, "WEAK" },     { STB_LOOS, "LOOS" },
++	{ STB_HIOS, "HIOS" },     { STB_MULTIDEF, "MULTIDEF" },
++	{ STB_LOPROC, "LOPROC" }, { STB_HIPROC, "HIPROC" },
++};
++
++static struct symbol_type_t
++{
++	const Elf_Word key;
++	const char*    str;
++} symbol_type_table[] = {
++	{ STT_NOTYPE, "NOTYPE" }, { STT_OBJECT, "OBJECT" },
++	{ STT_FUNC, "FUNC" },     { STT_SECTION, "SECTION" },
++	{ STT_FILE, "FILE" },     { STT_COMMON, "COMMON" },
++	{ STT_TLS, "TLS" },       { STT_LOOS, "LOOS" },
++	{ STT_HIOS, "HIOS" },     { STT_LOPROC, "LOPROC" },
++	{ STT_HIPROC, "HIPROC" },
++};
++
++static struct dynamic_tag_t
++{
++	const Elf_Word key;
++	const char*    str;
++} dynamic_tag_table[] = {
++	{ DT_NULL, "NULL" },
++	{ DT_NEEDED, "NEEDED" },
++	{ DT_PLTRELSZ, "PLTRELSZ" },
++	{ DT_PLTGOT, "PLTGOT" },
++	{ DT_HASH, "HASH" },
++	{ DT_STRTAB, "STRTAB" },
++	{ DT_SYMTAB, "SYMTAB" },
++	{ DT_RELA, "RELA" },
++	{ DT_RELASZ, "RELASZ" },
++	{ DT_RELAENT, "RELAENT" },
++	{ DT_STRSZ, "STRSZ" },
++	{ DT_SYMENT, "SYMENT" },
++	{ DT_INIT, "INIT" },
++	{ DT_FINI, "FINI" },
++	{ DT_SONAME, "SONAME" },
++	{ DT_RPATH, "RPATH" },
++	{ DT_SYMBOLIC, "SYMBOLIC" },
++	{ DT_REL, "REL" },
++	{ DT_RELSZ, "RELSZ" },
++	{ DT_RELENT, "RELENT" },
++	{ DT_PLTREL, "PLTREL" },
++	{ DT_DEBUG, "DEBUG" },
++	{ DT_TEXTREL, "TEXTREL" },
++	{ DT_JMPREL, "JMPREL" },
++	{ DT_BIND_NOW, "BIND_NOW" },
++	{ DT_INIT_ARRAY, "INIT_ARRAY" },
++	{ DT_FINI_ARRAY, "FINI_ARRAY" },
++	{ DT_INIT_ARRAYSZ, "INIT_ARRAYSZ" },
++	{ DT_FINI_ARRAYSZ, "FINI_ARRAYSZ" },
++	{ DT_RUNPATH, "RUNPATH" },
++	{ DT_FLAGS, "FLAGS" },
++	{ DT_ENCODING, "ENCODING" },
++	{ DT_PREINIT_ARRAY, "PREINIT_ARRAY" },
++	{ DT_PREINIT_ARRAYSZ, "PREINIT_ARRAYSZ" },
++	{ DT_MAXPOSTAGS, "MAXPOSTAGS" },
++};
++
++static const ELFIO::Elf_Xword MAX_DATA_ENTRIES = 64;
++
++//------------------------------------------------------------------------------
++class dump
++{
++#define DUMP_DEC_FORMAT( width ) \
++	std::setw( width ) << std::setfill( ' ' ) << std::dec << std::right
++#define DUMP_HEX_FORMAT( width ) \
++	std::setw( width ) << std::setfill( '0' ) << std::hex << std::right
++#define DUMP_STR_FORMAT( width ) \
++	std::setw( width ) << std::setfill( ' ' ) << std::hex << std::left
++
++  public:
++	//------------------------------------------------------------------------------
++	static void header( std::ostream& out, const elfio& reader )
++	{
++		if ( !reader.get_header_size() ) {
++			return;
++		}
++		out << "ELF Header" << std::endl
++			<< std::endl
++			<< "  Class:      " << str_class( reader.get_class() ) << std::endl
++			<< "  Encoding:   " << str_endian( reader.get_encoding() )
++			<< std::endl
++			<< "  ELFVersion: " << str_version( reader.get_elf_version() )
++			<< std::endl
++			<< "  Type:       " << str_type( reader.get_type() ) << std::endl
++			<< "  Machine:    " << str_machine( reader.get_machine() )
++			<< std::endl
++			<< "  Version:    " << str_version( reader.get_version() )
++			<< std::endl
++			<< "  Entry:      "
++			<< "0x" << std::hex << reader.get_entry() << std::endl
++			<< "  Flags:      "
++			<< "0x" << std::hex << reader.get_flags() << std::endl
++			<< std::endl;
++	}
++
++	//------------------------------------------------------------------------------
++	static void section_headers( std::ostream& out, const elfio& reader )
++	{
++		Elf_Half n = reader.sections.size();
++
++		if ( n == 0 ) {
++			return;
++		}
++
++		out << "Section Headers:" << std::endl;
++		if ( reader.get_class() == ELFCLASS32 ) { // Output for 32-bit
++			out << "[  Nr ] Type              Addr     Size     ES Flg Lk Inf "
++				   "Al Name"
++				<< std::endl;
++		}
++		else { // Output for 64-bit
++			out << "[  Nr ] Type              Addr             Size            "
++				   " ES   Flg"
++				<< std::endl
++				<< "        Lk   Inf  Al      Name" << std::endl;
++		}
++
++		for ( Elf_Half i = 0; i < n; ++i ) { // For all sections
++			section* sec = reader.sections[i];
++			section_header( out, i, sec, reader.get_class() );
++		}
++
++		out << "Key to Flags: W (write), A (alloc), X (execute)\n\n"
++			<< std::endl;
++	}
++
++	//------------------------------------------------------------------------------
++	static void section_header( std::ostream&  out,
++								Elf_Half       no,
++								const section* sec,
++								unsigned char  elf_class )
++	{
++		std::ios_base::fmtflags original_flags = out.flags();
++
++		if ( elf_class == ELFCLASS32 ) { // Output for 32-bit
++			out << "[" << DUMP_DEC_FORMAT( 5 ) << no << "] "
++				<< DUMP_STR_FORMAT( 17 ) << str_section_type( sec->get_type() )
++				<< " " << DUMP_HEX_FORMAT( 8 ) << sec->get_address() << " "
++				<< DUMP_HEX_FORMAT( 8 ) << sec->get_size() << " "
++				<< DUMP_HEX_FORMAT( 2 ) << sec->get_entry_size() << " "
++				<< DUMP_STR_FORMAT( 3 ) << section_flags( sec->get_flags() )
++				<< " " << DUMP_HEX_FORMAT( 2 ) << sec->get_link() << " "
++				<< DUMP_HEX_FORMAT( 3 ) << sec->get_info() << " "
++				<< DUMP_HEX_FORMAT( 2 ) << sec->get_addr_align() << " "
++				<< DUMP_STR_FORMAT( 17 ) << sec->get_name() << " " << std::endl;
++		}
++		else { // Output for 64-bit
++			out << "[" << DUMP_DEC_FORMAT( 5 ) << no << "] "
++				<< DUMP_STR_FORMAT( 17 ) << str_section_type( sec->get_type() )
++				<< " " << DUMP_HEX_FORMAT( 16 ) << sec->get_address() << " "
++				<< DUMP_HEX_FORMAT( 16 ) << sec->get_size() << " "
++				<< DUMP_HEX_FORMAT( 4 ) << sec->get_entry_size() << " "
++				<< DUMP_STR_FORMAT( 3 ) << section_flags( sec->get_flags() )
++				<< " " << std::endl
++				<< "        " << DUMP_HEX_FORMAT( 4 ) << sec->get_link() << " "
++				<< DUMP_HEX_FORMAT( 4 ) << sec->get_info() << " "
++				<< DUMP_HEX_FORMAT( 4 ) << sec->get_addr_align() << "    "
++				<< DUMP_STR_FORMAT( 17 ) << sec->get_name() << " " << std::endl;
++		}
++
++		out.flags( original_flags );
++
++		return;
++	}
++
++	//------------------------------------------------------------------------------
++	static void segment_headers( std::ostream& out, const elfio& reader )
++	{
++		Elf_Half n = reader.segments.size();
++		if ( n == 0 ) {
++			return;
++		}
++
++		out << "Segment headers:" << std::endl;
++		if ( reader.get_class() == ELFCLASS32 ) { // Output for 32-bit
++			out << "[  Nr ] Type           VirtAddr PhysAddr FileSize Mem.Size "
++				   "Flags    Align"
++				<< std::endl;
++		}
++		else { // Output for 64-bit
++			out << "[  Nr ] Type           VirtAddr         PhysAddr         "
++				   "Flags"
++				<< std::endl
++				<< "                       FileSize         Mem.Size         "
++				   "Align"
++				<< std::endl;
++		}
++
++		for ( Elf_Half i = 0; i < n; ++i ) {
++			segment* seg = reader.segments[i];
++			segment_header( out, i, seg, reader.get_class() );
++		}
++
++		out << std::endl;
++	}
++
++	//------------------------------------------------------------------------------
++	static void segment_header( std::ostream&  out,
++								Elf_Half       no,
++								const segment* seg,
++								unsigned int   elf_class )
++	{
++		std::ios_base::fmtflags original_flags = out.flags();
++
++		if ( elf_class == ELFCLASS32 ) { // Output for 32-bit
++			out << "[" << DUMP_DEC_FORMAT( 5 ) << no << "] "
++				<< DUMP_STR_FORMAT( 14 ) << str_segment_type( seg->get_type() )
++				<< " " << DUMP_HEX_FORMAT( 8 ) << seg->get_virtual_address()
++				<< " " << DUMP_HEX_FORMAT( 8 ) << seg->get_physical_address()
++				<< " " << DUMP_HEX_FORMAT( 8 ) << seg->get_file_size() << " "
++				<< DUMP_HEX_FORMAT( 8 ) << seg->get_memory_size() << " "
++				<< DUMP_STR_FORMAT( 8 ) << str_segment_flag( seg->get_flags() )
++				<< " " << DUMP_HEX_FORMAT( 8 ) << seg->get_align() << " "
++				<< std::endl;
++		}
++		else { // Output for 64-bit
++			out << "[" << DUMP_DEC_FORMAT( 5 ) << no << "] "
++				<< DUMP_STR_FORMAT( 14 ) << str_segment_type( seg->get_type() )
++				<< " " << DUMP_HEX_FORMAT( 16 ) << seg->get_virtual_address()
++				<< " " << DUMP_HEX_FORMAT( 16 ) << seg->get_physical_address()
++				<< " " << DUMP_STR_FORMAT( 16 )
++				<< str_segment_flag( seg->get_flags() ) << " " << std::endl
++				<< "                       " << DUMP_HEX_FORMAT( 16 )
++				<< seg->get_file_size() << " " << DUMP_HEX_FORMAT( 16 )
++				<< seg->get_memory_size() << " " << DUMP_HEX_FORMAT( 16 )
++				<< seg->get_align() << " " << std::endl;
++		}
++
++		out.flags( original_flags );
++	}
++
++	//------------------------------------------------------------------------------
++	static void symbol_tables( std::ostream& out, const elfio& reader )
++	{
++		Elf_Half n = reader.sections.size();
++		for ( Elf_Half i = 0; i < n; ++i ) { // For all sections
++			section* sec = reader.sections[i];
++			if ( SHT_SYMTAB == sec->get_type() ||
++				 SHT_DYNSYM == sec->get_type() ) {
++				symbol_section_accessor symbols( reader, sec );
++
++				Elf_Xword sym_no = symbols.get_symbols_num();
++				if ( sym_no > 0 ) {
++					out << "Symbol table (" << sec->get_name() << ")"
++						<< std::endl;
++					if ( reader.get_class() ==
++						 ELFCLASS32 ) { // Output for 32-bit
++						out << "[  Nr ] Value    Size     Type    Bind      "
++							   "Sect Name"
++							<< std::endl;
++					}
++					else { // Output for 64-bit
++						out << "[  Nr ] Value            Size             Type "
++							   "   Bind      Sect"
++							<< std::endl
++							<< "        Name" << std::endl;
++					}
++					for ( Elf_Xword i = 0; i < sym_no; ++i ) {
++						std::string   name;
++						Elf64_Addr    value   = 0;
++						Elf_Xword     size    = 0;
++						unsigned char bind    = 0;
++						unsigned char type    = 0;
++						Elf_Half      section = 0;
++						unsigned char other   = 0;
++						symbols.get_symbol( i, name, value, size, bind, type,
++											section, other );
++						symbol_table( out, i, name, value, size, bind, type,
++									  section, reader.get_class() );
++					}
++
++					out << std::endl;
++				}
++			}
++		}
++	}
++
++	//------------------------------------------------------------------------------
++	static void symbol_table( std::ostream& out,
++							  Elf_Xword     no,
++							  std::string&  name,
++							  Elf64_Addr    value,
++							  Elf_Xword     size,
++							  unsigned char bind,
++							  unsigned char type,
++							  Elf_Half      section,
++							  unsigned int  elf_class )
++	{
++		std::ios_base::fmtflags original_flags = out.flags();
++
++		if ( elf_class == ELFCLASS32 ) { // Output for 32-bit
++			out << "[" << DUMP_DEC_FORMAT( 5 ) << no << "] "
++				<< DUMP_HEX_FORMAT( 8 ) << value << " " << DUMP_HEX_FORMAT( 8 )
++				<< size << " " << DUMP_STR_FORMAT( 7 )
++				<< str_symbol_type( type ) << " " << DUMP_STR_FORMAT( 8 )
++				<< str_symbol_bind( bind ) << " " << DUMP_DEC_FORMAT( 5 )
++				<< section << " " << DUMP_STR_FORMAT( 1 ) << name << " "
++				<< std::endl;
++		}
++		else { // Output for 64-bit
++			out << "[" << DUMP_DEC_FORMAT( 5 ) << no << "] "
++				<< DUMP_HEX_FORMAT( 16 ) << value << " "
++				<< DUMP_HEX_FORMAT( 16 ) << size << " " << DUMP_STR_FORMAT( 7 )
++				<< str_symbol_type( type ) << " " << DUMP_STR_FORMAT( 8 )
++				<< str_symbol_bind( bind ) << " " << DUMP_DEC_FORMAT( 5 )
++				<< section << " " << std::endl
++				<< "        " << DUMP_STR_FORMAT( 1 ) << name << " "
++				<< std::endl;
++		}
++
++		out.flags( original_flags );
++	}
++
++	//------------------------------------------------------------------------------
++	static void notes( std::ostream& out, const elfio& reader )
++	{
++		Elf_Half no = reader.sections.size();
++		for ( Elf_Half i = 0; i < no; ++i ) { // For all sections
++			section* sec = reader.sections[i];
++			if ( SHT_NOTE == sec->get_type() ) { // Look at notes
++				note_section_accessor notes( reader, sec );
++				Elf_Word              no_notes = notes.get_notes_num();
++				if ( no > 0 ) {
++					out << "Note section (" << sec->get_name() << ")"
++						<< std::endl
++						<< "    No Type     Name" << std::endl;
++					for ( Elf_Word j = 0; j < no_notes; ++j ) { // For all notes
++						Elf_Word    type;
++						std::string name;
++						void*       desc;
++						Elf_Word    descsz;
++
++						if ( notes.get_note( j, type, name, desc, descsz ) ) {
++							// 'name' usually contains \0 at the end. Try to fix it
++							name = name.c_str();
++							note( out, j, type, name );
++						}
++					}
++
++					out << std::endl;
++				}
++			}
++		}
++	}
++
++	//------------------------------------------------------------------------------
++	static void modinfo( std::ostream& out, const elfio& reader )
++	{
++		Elf_Half no = reader.sections.size();
++		for ( Elf_Half i = 0; i < no; ++i ) { // For all sections
++			section* sec = reader.sections[i];
++			if ( ".modinfo" == sec->get_name() ) { // Look for the section
++				out << "Section .modinfo" << std::endl;
++
++				const_modinfo_section_accessor modinfo( sec );
++				for ( Elf_Word i = 0; i < modinfo.get_attribute_num(); i++ ) {
++					std::string field;
++					std::string value;
++					if ( modinfo.get_attribute( i, field, value ) ) {
++						out << "  " << std::setw( 20 ) << field
++							<< std::setw( 0 ) <<  " = " << value << std::endl;
++					}
++				}
++
++				out << std::endl;
++				break;
++			}
++		}
++	}
++
++	//------------------------------------------------------------------------------
++	static void
++	note( std::ostream& out, int no, Elf_Word type, const std::string& name )
++	{
++		out << "  [" << DUMP_DEC_FORMAT( 2 ) << no << "] "
++			<< DUMP_HEX_FORMAT( 8 ) << type << " " << DUMP_STR_FORMAT( 1 )
++			<< name << std::endl;
++	}
++
++	//------------------------------------------------------------------------------
++	static void dynamic_tags( std::ostream& out, const elfio& reader )
++	{
++		Elf_Half n = reader.sections.size();
++		for ( Elf_Half i = 0; i < n; ++i ) { // For all sections
++			section* sec = reader.sections[i];
++			if ( SHT_DYNAMIC == sec->get_type() ) {
++				dynamic_section_accessor dynamic( reader, sec );
++
++				Elf_Xword dyn_no = dynamic.get_entries_num();
++				if ( dyn_no > 0 ) {
++					out << "Dynamic section (" << sec->get_name() << ")"
++						<< std::endl;
++					out << "[  Nr ] Tag              Name/Value" << std::endl;
++					for ( Elf_Xword i = 0; i < dyn_no; ++i ) {
++						Elf_Xword   tag   = 0;
++						Elf_Xword   value = 0;
++						std::string str;
++						dynamic.get_entry( i, tag, value, str );
++						dynamic_tag( out, i, tag, value, str,
++									 reader.get_class() );
++						if ( DT_NULL == tag ) {
++							break;
++						}
++					}
++
++					out << std::endl;
++				}
++			}
++		}
++	}
++
++	//------------------------------------------------------------------------------
++	static void dynamic_tag( std::ostream& out,
++							 Elf_Xword     no,
++							 Elf_Xword     tag,
++							 Elf_Xword     value,
++							 std::string   str,
++							 unsigned int /*elf_class*/ )
++	{
++		out << "[" << DUMP_DEC_FORMAT( 5 ) << no << "] "
++			<< DUMP_STR_FORMAT( 16 ) << str_dynamic_tag( tag ) << " ";
++		if ( str.empty() ) {
++			out << DUMP_HEX_FORMAT( 16 ) << value << " ";
++		}
++		else {
++			out << DUMP_STR_FORMAT( 32 ) << str << " ";
++		}
++		out << std::endl;
++	}
++
++	//------------------------------------------------------------------------------
++	static void section_data( std::ostream& out, const section* sec )
++	{
++		std::ios_base::fmtflags original_flags = out.flags();
++
++		out << sec->get_name() << std::endl;
++		const char* pdata = sec->get_data();
++		if ( pdata ) {
++			ELFIO::Elf_Xword i;
++			for ( i = 0; i < std::min( sec->get_size(), MAX_DATA_ENTRIES );
++				  ++i ) {
++				if ( i % 16 == 0 ) {
++					out << "[" << DUMP_HEX_FORMAT( 8 ) << i << "]";
++				}
++
++				out << " " << DUMP_HEX_FORMAT( 2 ) << ( pdata[i] & 0x000000FF );
++
++				if ( i % 16 == 15 ) {
++					out << std::endl;
++				}
++			}
++			if ( i % 16 != 0 ) {
++				out << std::endl;
++			}
++
++			out.flags( original_flags );
++		}
++
++		return;
++	}
++
++	//------------------------------------------------------------------------------
++	static void section_datas( std::ostream& out, const elfio& reader )
++	{
++		Elf_Half n = reader.sections.size();
++
++		if ( n == 0 ) {
++			return;
++		}
++
++		out << "Section Data:" << std::endl;
++
++		for ( Elf_Half i = 1; i < n; ++i ) { // For all sections
++			section* sec = reader.sections[i];
++			if ( sec->get_type() == SHT_NOBITS ) {
++				continue;
++			}
++			section_data( out, sec );
++		}
++
++		out << std::endl;
++	}
++
++	//------------------------------------------------------------------------------
++	static void
++	segment_data( std::ostream& out, Elf_Half no, const segment* seg )
++	{
++		std::ios_base::fmtflags original_flags = out.flags();
++
++		out << "Segment # " << no << std::endl;
++		const char* pdata = seg->get_data();
++		if ( pdata ) {
++			ELFIO::Elf_Xword i;
++			for ( i = 0; i < std::min( seg->get_file_size(), MAX_DATA_ENTRIES );
++				  ++i ) {
++				if ( i % 16 == 0 ) {
++					out << "[" << DUMP_HEX_FORMAT( 8 ) << i << "]";
++				}
++
++				out << " " << DUMP_HEX_FORMAT( 2 ) << ( pdata[i] & 0x000000FF );
++
++				if ( i % 16 == 15 ) {
++					out << std::endl;
++				}
++			}
++			if ( i % 16 != 0 ) {
++				out << std::endl;
++			}
++
++			out.flags( original_flags );
++		}
++
++		return;
++	}
++
++	//------------------------------------------------------------------------------
++	static void segment_datas( std::ostream& out, const elfio& reader )
++	{
++		Elf_Half n = reader.segments.size();
++
++		if ( n == 0 ) {
++			return;
++		}
++
++		out << "Segment Data:" << std::endl;
++
++		for ( Elf_Half i = 0; i < n; ++i ) { // For all sections
++			segment* seg = reader.segments[i];
++			segment_data( out, i, seg );
++		}
++
++		out << std::endl;
++	}
++
++  private:
++	//------------------------------------------------------------------------------
++	template <typename T, typename K>
++	std::string static find_value_in_table( const T& table, const K& key )
++	{
++		std::string res = "?";
++		for ( unsigned int i = 0; i < sizeof( table ) / sizeof( table[0] );
++			  ++i ) {
++			if ( table[i].key == key ) {
++				res = table[i].str;
++				break;
++			}
++		}
++
++		return res;
++	}
++
++	//------------------------------------------------------------------------------
++	template <typename T, typename K>
++	static std::string format_assoc( const T& table, const K& key )
++	{
++		std::string str = find_value_in_table( table, key );
++		if ( str == "?" ) {
++			std::ostringstream oss;
++			oss << str << " (0x" << std::hex << key << ")";
++			str = oss.str();
++		}
++
++		return str;
++	}
++
++	//------------------------------------------------------------------------------
++	template <typename T>
++	static std::string format_assoc( const T& table, const char key )
++	{
++		return format_assoc( table, (const int)key );
++	}
++
++	//------------------------------------------------------------------------------
++	static std::string section_flags( Elf_Xword flags )
++	{
++		std::string ret = "";
++		if ( flags & SHF_WRITE ) {
++			ret += "W";
++		}
++		if ( flags & SHF_ALLOC ) {
++			ret += "A";
++		}
++		if ( flags & SHF_EXECINSTR ) {
++			ret += "X";
++		}
++
++		return ret;
++	}
++
++//------------------------------------------------------------------------------
++#define STR_FUNC_TABLE( name )                                         \
++	template <typename T> static std::string str_##name( const T key ) \
++	{                                                                  \
++		return format_assoc( name##_table, key );                      \
++	}
++
++	STR_FUNC_TABLE( class )
++	STR_FUNC_TABLE( endian )
++	STR_FUNC_TABLE( version )
++	STR_FUNC_TABLE( type )
++	STR_FUNC_TABLE( machine )
++	STR_FUNC_TABLE( section_type )
++	STR_FUNC_TABLE( segment_type )
++	STR_FUNC_TABLE( segment_flag )
++	STR_FUNC_TABLE( symbol_bind )
++	STR_FUNC_TABLE( symbol_type )
++	STR_FUNC_TABLE( dynamic_tag )
++
++#undef STR_FUNC_TABLE
++#undef DUMP_DEC_FORMAT
++#undef DUMP_HEX_FORMAT
++#undef DUMP_STR_FORMAT
++}; // class dump
++
++}; // namespace ELFIO
++
++#endif // ELFIO_DUMP_HPP
++
++/*** End of inlined file: elfio_dump.hpp ***/
++
+diff --git a/tests/kt-test-utils/cpp-stub/stub.h b/tests/kt-test-utils/cpp-stub/stub.h
+new file mode 100644
+index 0000000..c5f2f53
+--- /dev/null
++++ b/tests/kt-test-utils/cpp-stub/stub.h
+@@ -0,0 +1,360 @@
++#ifndef __STUB_H__
++#define __STUB_H__
++
++#ifdef _WIN32
++//windows
++#include <windows.h>
++#include <processthreadsapi.h>
++#else
++//linux
++#include <unistd.h>
++#include <bits/stdint-uintn.h>
++#include <sys/mman.h>
++#endif
++//c
++#include <cstddef>
++#include <cstring>
++//c++
++#include <map>
++
++
++#define ADDR(CLASS_NAME,MEMBER_NAME) (&CLASS_NAME::MEMBER_NAME)
++
++/**********************************************************
++                  replace function
++**********************************************************/
++#ifdef _WIN32
++#define CACHEFLUSH(addr, size) FlushInstructionCache(GetCurrentProcess(), addr, size)
++#else
++#define CACHEFLUSH(addr, size) __builtin___clear_cache(addr, addr + size)
++#endif
++
++#if defined(__aarch64__) || defined(_M_ARM64)
++    #define CODESIZE 16U
++    #define CODESIZE_MIN 16U
++    #define CODESIZE_MAX CODESIZE
++    // ldr x9, +8
++    // br x9
++    // addr
++    #define REPLACE_FAR(t, fn, fn_stub)\
++        ((uint32_t*)fn)[0] = 0x58000040 | 9;\
++        ((uint32_t*)fn)[1] = 0xd61f0120 | (9 << 5);\
++        *(long long *)(fn + 8) = (long long )fn_stub;\
++        CACHEFLUSH((char *)fn, CODESIZE);
++    #define REPLACE_NEAR(t, fn, fn_stub) REPLACE_FAR(t, fn, fn_stub)
++#elif defined(__arm__) || defined(_M_ARM)
++    #define CODESIZE 8U
++    #define CODESIZE_MIN 8U
++    #define CODESIZE_MAX CODESIZE
++    // ldr pc, [pc, #-4]
++    #define REPLACE_FAR(t, fn, fn_stub)\
++        ((uint32_t*)fn)[0] = 0xe51ff004;\
++        ((uint32_t*)fn)[1] = (uint32_t)fn_stub;\
++        CACHEFLUSH((char *)fn, CODESIZE);
++    #define REPLACE_NEAR(t, fn, fn_stub) REPLACE_FAR(t, fn, fn_stub)
++#elif defined(__mips64)
++    #define CACHEFLUSH(addr, size) __builtin___clear_cache(addr, addr + size)
++    #define CODESIZE 80U
++    #define CODESIZE_MIN 80U
++    #define CODESIZE_MAX CODESIZE
++    //mips没有PC指针,所以需要手动入栈出栈
++    //120000ce0:  67bdffe0    daddiu  sp, sp, -32  //入栈
++    //120000ce4:  ffbf0018    sd  ra, 24(sp)
++    //120000ce8:  ffbe0010    sd  s8, 16(sp)
++    //120000cec:  ffbc0008    sd  gp, 8(sp)
++    //120000cf0:  03a0f025    move    s8, sp
++
++    //120000d2c:  03c0e825    move    sp, s8  //出栈
++    //120000d30:  dfbf0018    ld  ra, 24(sp)
++    //120000d34:  dfbe0010    ld  s8, 16(sp)
++    //120000d38:  dfbc0008    ld  gp, 8(sp)
++    //120000d3c:  67bd0020    daddiu  sp, sp, 32
++    //120000d40:  03e00008    jr  ra
++
++    #define REPLACE_FAR(t, fn, fn_stub)\
++        ((uint32_t *)fn)[0] = 0x67bdffe0;\
++        ((uint32_t *)fn)[1] = 0xffbf0018;\
++        ((uint32_t *)fn)[2] = 0xffbe0010;\
++        ((uint32_t *)fn)[3] = 0xffbc0008;\
++        ((uint32_t *)fn)[4] = 0x03a0f025;\
++        *(uint16_t *)(fn + 20) = (long long)fn_stub >> 32;\
++        *(fn + 22) = 0x19;\
++        *(fn + 23) = 0x24;\
++        ((uint32_t *)fn)[6] = 0x0019cc38;\
++        *(uint16_t *)(fn + 28) = (long long)fn_stub >> 16;\
++        *(fn + 30) = 0x39;\
++        *(fn + 31) = 0x37;\
++        ((uint32_t *)fn)[8] = 0x0019cc38;\
++        *(uint16_t *)(fn + 36) = (long long)fn_stub;\
++        *(fn + 38) = 0x39;\
++        *(fn + 39) = 0x37;\
++        ((uint32_t *)fn)[10] = 0x0320f809;\
++        ((uint32_t *)fn)[11] = 0x00000000;\
++        ((uint32_t *)fn)[12] = 0x00000000;\
++        ((uint32_t *)fn)[13] = 0x03c0e825;\
++        ((uint32_t *)fn)[14] = 0xdfbf0018;\
++        ((uint32_t *)fn)[15] = 0xdfbe0010;\
++        ((uint32_t *)fn)[16] = 0xdfbc0008;\
++        ((uint32_t *)fn)[17] = 0x67bd0020;\
++        ((uint32_t *)fn)[18] = 0x03e00008;\
++        ((uint32_t *)fn)[19] = 0x00000000;\
++        CACHEFLUSH((char *)fn, CODESIZE);
++    #define REPLACE_NEAR(t, fn, fn_stub) REPLACE_FAR(t, fn, fn_stub)
++#elif defined(__thumb__) || defined(_M_THUMB)
++    #error "Thumb is not supported"
++#else //__i386__ _x86_64__
++    #define CODESIZE 13U
++    #define CODESIZE_MIN 5U
++    #define CODESIZE_MAX CODESIZE
++    //13 byte(jmp m16:64)
++    //movabs $0x102030405060708,%r11
++    //jmpq   *%r11
++    static void REPLACE_FAR(void *t, char *fn, char *fn_stub)
++    {
++        *fn = 0x49;
++        *(fn + 1) = 0xbb;
++        *(long long *)(fn + 2) = (long long)fn_stub;
++        *(fn + 10) = 0x41;
++        *(fn + 11) = 0xff;
++        *(fn + 12) = 0xe3;
++        CACHEFLUSH((char *)fn, CODESIZE);
++    }
++    //5 byte(jmp rel32)
++    #define REPLACE_NEAR(t, fn, fn_stub)\
++        *fn = 0xE9;\
++        *(int *)(fn + 1) = (int)(fn_stub - fn - CODESIZE_MIN);\
++        CACHEFLUSH((char *)fn, CODESIZE);
++#endif
++
++struct func_stub
++{
++    char *fn;
++    unsigned char code_buf[CODESIZE];
++    bool far_jmp;
++};
++
++class Stub
++{
++public:
++    Stub()
++    {
++#ifdef _WIN32
++        SYSTEM_INFO sys_info;
++        GetSystemInfo(&sys_info);
++        m_pagesize = sys_info.dwPageSize;
++#else
++        m_pagesize = sysconf(_SC_PAGE_SIZE);
++#endif
++
++        if (m_pagesize < 0)
++        {
++            m_pagesize = 4096;
++        }
++    }
++    ~Stub()
++    {
++        clear();
++    }
++
++    virtual void clear()
++    {
++        std::map<char*,func_stub*>::iterator iter;
++        struct func_stub *pstub;
++        for(iter=m_result.begin(); iter != m_result.end(); iter++)
++        {
++            pstub = iter->second;
++#ifdef _WIN32
++            DWORD lpflOldProtect;
++            if(0 != VirtualProtect(pageof(pstub->fn), m_pagesize * 2, PAGE_EXECUTE_READWRITE, &lpflOldProtect))
++#else
++            if (0 == mprotect(pageof(pstub->fn), m_pagesize * 2, PROT_READ | PROT_WRITE | PROT_EXEC))
++#endif
++            {
++
++                if(pstub->far_jmp)
++                {
++                    std::memcpy(pstub->fn, pstub->code_buf, CODESIZE_MAX);
++                }
++                else
++                {
++                    std::memcpy(pstub->fn, pstub->code_buf, CODESIZE_MIN);
++                }
++
++#ifdef _WIN32
++                VirtualProtect(pageof(pstub->fn), m_pagesize * 2, PAGE_EXECUTE_READ, &lpflOldProtect);
++#else
++                CACHEFLUSH(pstub->fn,CODESIZE);
++                mprotect(pageof(pstub->fn), m_pagesize * 2, PROT_READ | PROT_EXEC);
++#endif
++            }
++
++            iter->second  = NULL;
++            delete pstub;
++        }
++
++        m_result.clear();
++        return;
++    }
++    template<typename T,typename S>
++    bool set(T addr, S addr_stub)
++    {
++        char * fn;
++        char * fn_stub;
++        fn = addrof(addr);
++        fn_stub = addrof(addr_stub);
++        struct func_stub *pstub;
++        std::map<char*,func_stub*>::iterator iter = m_result.find(fn);
++
++        if (iter == m_result.end())
++        {
++            pstub = new func_stub;
++            //start
++            pstub->fn = fn;
++
++            if(distanceof(fn, fn_stub))
++            {
++                pstub->far_jmp = true;
++                std::memcpy(pstub->code_buf, fn, CODESIZE_MAX);
++            }
++            else
++            {
++                pstub->far_jmp = false;
++                std::memcpy(pstub->code_buf, fn, CODESIZE_MIN);
++            }
++        }
++        else {
++            pstub = iter->second;
++            pstub->far_jmp = distanceof(fn, fn_stub);
++        }
++
++
++
++#ifdef _WIN32
++        DWORD lpflOldProtect;
++        if(0 == VirtualProtect(pageof(pstub->fn), m_pagesize * 2, PAGE_EXECUTE_READWRITE, &lpflOldProtect))
++#else
++        if (-1 == mprotect(pageof(pstub->fn), static_cast<size_t>(m_pagesize * 2), PROT_READ | PROT_WRITE | PROT_EXEC))
++#endif
++        {
++            throw("stub set memory protect to w+r+x faild");
++            return  false;
++        }
++
++        if(pstub->far_jmp)
++        {
++            REPLACE_FAR(this, fn, fn_stub);
++        }
++        else
++        {
++            REPLACE_NEAR(this, fn, fn_stub);
++        }
++
++
++#ifdef _WIN32
++        if(0 == VirtualProtect(pageof(pstub->fn), m_pagesize * 2, PAGE_EXECUTE_READ, &lpflOldProtect))
++#else
++        if (-1 == mprotect(pageof(pstub->fn), m_pagesize * 2, PROT_READ | PROT_EXEC))
++#endif
++        {
++            throw("stub set memory protect to r+x failed");
++            return false;
++        }
++        m_result.insert(std::pair<char*,func_stub*>(fn,pstub));
++        return true;
++    }
++
++    template<typename T>
++    bool reset(T addr)
++    {
++        char * fn;
++        fn = addrof(addr);
++
++        std::map<char*,func_stub*>::iterator iter = m_result.find(fn);
++
++        if (iter == m_result.end())
++        {
++            return true;
++        }
++        struct func_stub *pstub;
++        pstub = iter->second;
++
++#ifdef _WIN32
++        DWORD lpflOldProtect;
++        if(0 == VirtualProtect(pageof(pstub->fn), m_pagesize * 2, PAGE_EXECUTE_READWRITE, &lpflOldProtect))
++#else
++        if (-1 == mprotect(pageof(pstub->fn), m_pagesize * 2, PROT_READ | PROT_WRITE | PROT_EXEC))
++#endif
++        {
++            throw("stub reset memory protect to w+r+x faild");
++            return false;
++        }
++
++        if(pstub->far_jmp)
++        {
++            std::memcpy(pstub->fn, pstub->code_buf, CODESIZE_MAX);
++        }
++        else
++        {
++            std::memcpy(pstub->fn, pstub->code_buf, CODESIZE_MIN);
++        }
++
++#ifdef _WIN32
++        if(0 == VirtualProtect(pageof(pstub->fn), m_pagesize * 2, PAGE_EXECUTE_READ, &lpflOldProtect))
++#else
++        CACHEFLUSH(pstub->fn,CODESIZE);
++        if (-1 == mprotect(pageof(pstub->fn), m_pagesize * 2, PROT_READ | PROT_EXEC))
++#endif
++        {
++            throw("stub reset memory protect to r+x failed");
++            return false;
++        }
++
++        m_result.erase(iter);
++        delete pstub;
++
++        return true;
++    }
++protected:
++    char *pageof(char* addr)
++    {
++#ifdef _WIN32
++        return (char *)((unsigned long long)addr & ~(m_pagesize - 1));
++#else
++        return (char *)((unsigned long)addr & ~(m_pagesize - 1));
++#endif
++    }
++
++    template<typename T>
++    char* addrof(T addr)
++    {
++        union
++        {
++          T _s;
++          char* _d;
++        }ut;
++        ut._s = addr;
++        return ut._d;
++    }
++
++    bool distanceof(char* addr, char* addr_stub)
++    {
++        std::ptrdiff_t diff = addr_stub >= addr ? addr_stub - addr : addr - addr_stub;
++        if((sizeof(addr) > 4) && (((diff >> 31) - 1) > 0))
++        {
++            return true;
++        }
++        return false;
++    }
++
++protected:
++#ifdef _WIN32
++    //LLP64
++    long long m_pagesize;
++#else
++    //LP64
++    long m_pagesize;
++#endif
++    std::map<char*, func_stub*> m_result;
++};
++
++#endif
+diff --git a/tests/unit_test_account_helper/CMakeLists.txt b/tests/unit_test_account_helper/CMakeLists.txt
+new file mode 100644
+index 0000000..6ed7b7e
+--- /dev/null
++++ b/tests/unit_test_account_helper/CMakeLists.txt
+@@ -0,0 +1,64 @@
++# CMake 最低版本要求
++cmake_minimum_required(VERSION 3.10)
++
++find_package(Qt5 COMPONENTS Core Gui DBus REQUIRED)
++
++# 包含 GTest 库和 pthread 库
++find_package(GTest REQUIRED)
++find_package(Threads REQUIRED)
++
++# 设置 C++ 标准
++set(CMAKE_CXX_STANDARD 17)
++set(CMAKE_CXX_STANDARD_REQUIRED ON)
++
++
++# 开启代码覆盖率相关编译选项(对应QMAKE_LFLAGS和QMAKE_CXXFLAGS中代码覆盖率相关设置)
++
++set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fprofile-arcs -ftest-coverage")
++set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fprofile-arcs -ftest-coverage")
++
++
++# 定义源文件列表,对应原来的SOURCES变量
++set(SOURCES
++    ../../src/dbusifs/accountshelper.cpp
++    ../../src/userinfo.cpp
++    ../../src/common/global_utils.cpp
++    unit_test_account_helper.cpp
++    main.cpp
++)
++
++# 定义头文件列表,对应原来的HEADERS变量
++set(HEADERS
++        ../../src/common/definetypes.h
++        ../../src/userinfo.h
++        ../../src/common/global_utils.h
++        ../../src/dbusifs/accountshelper.h
++)
++
++# 包含头文件的路径设置,对应原来的INCLUDEPATH变量
++include_directories(
++    ${CMAKE_CURRENT_SOURCE_DIR}
++    ${CMAKE_CURRENT_SOURCE_DIR}/../kt-test-utils/cpp-stub
++    ${CMAKE_CURRENT_SOURCE_DIR}/../kt-test-utils/cpp-stub-ext
++)
++
++# 使用qt5_wrap_cpp生成元对象代码相关的源文件
++qt5_wrap_cpp(MOC_SOURCES ${HEADERS})
++
++# 添加可执行文件或库目标,将元对象代码源文件一起添加进去
++add_executable(unit_test_account_helper ${SOURCES} ${MOC_SOURCES})
++
++# 链接Qt相关的库
++target_link_libraries(unit_test_account_helper
++    Qt5::Core
++    Qt5::Gui
++    Qt5::DBus
++)
++
++# 链接 GTest 库
++target_link_libraries(unit_test_account_helper
++    GTest::GTest
++    GTest::Main
++    Threads::Threads
++)
++
+diff --git a/tests/unit_test_account_helper/main.cpp b/tests/unit_test_account_helper/main.cpp
+new file mode 100644
+index 0000000..37b3fbf
+--- /dev/null
++++ b/tests/unit_test_account_helper/main.cpp
+@@ -0,0 +1,12 @@
++#include <gtest/gtest.h>
++#include <QGuiApplication>
++
++
++int main(int argc, char **argv)
++{
++    QGuiApplication a(argc, argv);
++    testing::InitGoogleTest(&argc, argv);
++
++    return RUN_ALL_TESTS();
++}
++
+diff --git a/tests/unit_test_account_helper/unit_test_account_helper.cpp b/tests/unit_test_account_helper/unit_test_account_helper.cpp
+new file mode 100644
+index 0000000..d7a71b6
+--- /dev/null
++++ b/tests/unit_test_account_helper/unit_test_account_helper.cpp
+@@ -0,0 +1,65 @@
++#include <gtest/gtest.h>
++#include <gtest/gtest-death-test.h>
++
++#include "../../src/dbusifs/accountshelper.h"
++
++#include "stubext.h"
++
++using namespace stub_ext;
++
++class AccountsHelperTest : public testing::Test
++{
++protected:
++    static void SetUpTestSuite()
++    {
++        m_pAccountsHelperDbus = new AccountsHelper();
++    }
++
++    static void TearDownTestSuite()
++    {
++        delete m_pAccountsHelperDbus;
++        m_pAccountsHelperDbus = nullptr;
++    }
++
++    static AccountsHelper *m_pAccountsHelperDbus;
++};
++
++AccountsHelper *AccountsHelperTest::m_pAccountsHelperDbus = nullptr;
++
++TEST_F(AccountsHelperTest, UserLanguageByName)
++{
++    QString value = m_pAccountsHelperDbus->getUserLanguageByName(getenv("USER"));
++    std::string str = value.toStdString();
++    const char* cstr = str.data();
++    ASSERT_STREQ(cstr, "zh_CN");
++}
++
++TEST_F(AccountsHelperTest, UserBackgroundByName)
++{
++    QString value = m_pAccountsHelperDbus->getUserBackgroundByName(getenv("USER"));
++    std::string str = value.toStdString();
++    const char* cstr = str.data();
++    ASSERT_STREQ(cstr, "zh_CN");
++}
++
++TEST_F(AccountsHelperTest, UserSessionByName)
++{
++    QString value = m_pAccountsHelperDbus->getUserSessionByName(getenv("USER"));
++    std::string str = value.toStdString();
++    const char* cstr = str.data();
++    ASSERT_STREQ(cstr, "zh_CN");
++}
++
++TEST_F(AccountsHelperTest, AccountBackground)
++{
++    QString value = m_pAccountsHelperDbus->getAccountBackground(1000);
++    std::string str = value.toStdString();
++    const char* cstr = str.data();
++    ASSERT_STREQ(cstr, "zh_CN");
++}
++
++TEST_F(AccountsHelperTest, UserList)
++{
++    QStringList value = m_pAccountsHelperDbus->getUserList();
++    ASSERT_EQ(value.isEmpty(), false);
++}
+diff --git a/tests/unit_test_auth_pam/CMakeLists.txt b/tests/unit_test_auth_pam/CMakeLists.txt
+new file mode 100644
+index 0000000..2cb1403
+--- /dev/null
++++ b/tests/unit_test_auth_pam/CMakeLists.txt
+@@ -0,0 +1,86 @@
++# CMake 最低版本要求
++cmake_minimum_required(VERSION 3.10)
++
++find_package(Qt5 COMPONENTS Core Gui DBus Test REQUIRED)
++find_package(PkgConfig REQUIRED)
++pkg_check_modules(QGS REQUIRED gsettings-qt)
++pkg_check_modules(LIGHTDM-QT5-3 REQUIRED liblightdm-qt5-3)
++
++# 包含 GTest 库和 pthread 库
++find_package(GTest REQUIRED)
++find_package(Threads REQUIRED)
++# 查找pam动态库全路径并缓存到PAM_LIBRARIES变量
++find_library(PAM_LIBRARIES pam)
++# 设置 C++ 标准
++set(CMAKE_CXX_STANDARD 17)
++set(CMAKE_CXX_STANDARD_REQUIRED ON)
++
++
++# 开启代码覆盖率相关编译选项(对应QMAKE_LFLAGS和QMAKE_CXXFLAGS中代码覆盖率相关设置)
++set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fprofile-arcs -ftest-coverage --coverage -fno-inline -fno-access-control")
++set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fprofile-arcs -ftest-coverage")
++
++# 定义源文件列表,对应原来的SOURCES变量
++set(SOURCES
++    ../../src/lock-backend/authpamthread.cpp
++    ../../src/lock-backend/pamauthenticate.cpp
++    ../../src/lock-backend/lightdmhelper.cpp
++    ../../src/dbusifs/accountshelper.cpp
++    ../../src/userinfo.cpp
++    ../../src/common/global_utils.cpp
++    ../../src/dbusifs/uniauthservice.cpp
++    ../../src/lock-backend/securityuser.cpp
++    ../../src/dbusifs/freedesktophelper.cpp
++    unit_test_auth_pam.cpp
++    main.cpp
++)
++
++# 定义头文件列表,对应原来的HEADERS变量
++set(HEADERS
++        ../../src/lock-backend/authpamthread.h
++        ../../src/lock-backend/pamauthenticate.h
++        ../../src/lock-backend/lightdmhelper.h
++        ../../src/common/definetypes.h
++        ../../src/userinfo.h
++        ../../src/common/global_utils.h
++        ../../src/dbusifs/accountshelper.h
++        ../../src/common/configuration.h
++        ../../src/dbusifs/uniauthservice.h
++        ../../src/lock-backend/securityuser.h
++        ../../src/dbusifs/freedesktophelper.h
++)
++
++# 包含头文件的路径设置,对应原来的INCLUDEPATH变量
++include_directories(
++    ${CMAKE_CURRENT_SOURCE_DIR}
++    ${CMAKE_CURRENT_SOURCE_DIR}/../kt-test-utils/cpp-stub
++    ${CMAKE_CURRENT_SOURCE_DIR}/../kt-test-utils/cpp-stub-ext
++    ${QGS_INCLUDE_DIRS}
++    ${Qt5Test_INCLUDE_DIRS}
++    ${LIGHTDM-QT5-3_INCLUDE_DIRS}
++)
++
++# 使用qt5_wrap_cpp生成元对象代码相关的源文件
++qt5_wrap_cpp(MOC_SOURCES ${HEADERS})
++
++# 添加可执行文件或库目标,将元对象代码源文件一起添加进去
++add_executable(unit_test_auth_pam ${SOURCES} ${MOC_SOURCES})
++
++# 链接Qt相关的库
++target_link_libraries(unit_test_auth_pam
++    Qt5::Core
++    Qt5::Gui
++    Qt5::DBus
++    Qt5::Test
++    ${QGS_LIBRARIES}
++    ${PAM_LIBRARIES}
++    ${LIGHTDM-QT5-3_LIBRARIES}
++)
++
++# 链接 GTest 库
++target_link_libraries(unit_test_auth_pam
++    GTest::GTest
++    GTest::Main
++    Threads::Threads
++)
++
+diff --git a/tests/unit_test_auth_pam/main.cpp b/tests/unit_test_auth_pam/main.cpp
+new file mode 100644
+index 0000000..37b3fbf
+--- /dev/null
++++ b/tests/unit_test_auth_pam/main.cpp
+@@ -0,0 +1,12 @@
++#include <gtest/gtest.h>
++#include <QGuiApplication>
++
++
++int main(int argc, char **argv)
++{
++    QGuiApplication a(argc, argv);
++    testing::InitGoogleTest(&argc, argv);
++
++    return RUN_ALL_TESTS();
++}
++
+diff --git a/tests/unit_test_auth_pam/unit_test_auth_pam.cpp b/tests/unit_test_auth_pam/unit_test_auth_pam.cpp
+new file mode 100644
+index 0000000..f88a413
+--- /dev/null
++++ b/tests/unit_test_auth_pam/unit_test_auth_pam.cpp
+@@ -0,0 +1,377 @@
++#include <gtest/gtest.h>
++#include <memory>
++#include <sys/types.h>
++#include <sys/stat.h>
++#include <fcntl.h>
++#include <unistd.h>
++#include <string.h>
++#include <security/pam_appl.h>
++#include <gtest/gtest.h>
++#include <QCoreApplication>
++#include <QLightDM/Greeter>
++#include <QSocketNotifier>
++#include <QDebug>
++#include <QSignalSpy>
++#include "../../src/dbusifs/accountshelper.h"
++#include "../../src/lock-backend/authpamthread.h"
++#include "../../src/lock-backend/pamauthenticate.h"
++#include "../../src/lock-backend/lightdmhelper.h"
++
++class AuthPamThreadTest : public ::testing::Test
++{
++protected:
++    static void SetUpTestSuite()
++    {
++        m_pAuthPamThreadDbus = new AuthPamThread();
++    }
++
++    static void TearDownTestSuite()
++    {
++        delete m_pAuthPamThreadDbus;
++        m_pAuthPamThreadDbus = nullptr;
++    }
++
++    static AuthPamThread *m_pAuthPamThreadDbus;
++
++    // 辅助函数,模拟文件描述符操作
++    int createMockPipe()
++    {
++        int fds[2];
++        if (pipe(fds) == -1) {
++            return -1;
++        }
++        return fds[0];
++    }
++
++    // 辅助函数,模拟写入数据到文件描述符
++    void writeToFd(int fd, const char *data)
++    {
++        write(fd, data, strlen(data));
++    }
++
++    // 辅助函数,从文件描述符读取数据
++    std::string readFromFd(int fd)
++    {
++        char buffer[1024];
++        ssize_t bytesRead = read(fd, buffer, sizeof(buffer) - 1);
++        if (bytesRead > 0) {
++            buffer[bytesRead] = '\0';
++            return buffer;
++        }
++        return "";
++    }
++
++    // 辅助函数,模拟 pam_start 的返回结果
++    int mockPamStart(pam_handle_t **pamh, const char *service, const char *user, const struct pam_conv *conv)
++    {
++        *pamh = reinterpret_cast<pam_handle_t *>(1);
++        return PAM_SUCCESS;
++    }
++
++    // 辅助函数,模拟 pam_authenticate 的返回结果
++    int mockPamAuthenticate(pam_handle_t *pamh, int flags)
++    {
++        return PAM_SUCCESS;
++    }
++
++    // 辅助函数,模拟 pam_acct_mgmt 的返回结果
++    int mockPamAcctMgmt(pam_handle_t *pamh, int flags)
++    {
++        return PAM_SUCCESS;
++    }
++
++    // 辅助函数,模拟 pam_get_item 的返回结果
++    int mockPamGetItem(pam_handle_t *pamh, int item_type, const void **item)
++    {
++        *item = nullptr;
++        return PAM_SUCCESS;
++    }
++
++    // 辅助函数,模拟 pam_strerror 的返回结果
++    const char *mockPamStrerror(pam_handle_t *pamh, int pam_err)
++    {
++        return "Mock Error";
++    }
++
++    // 辅助函数,模拟 pam_end 的行为
++    int mockPamEnd(pam_handle_t *pamh, int pam_status)
++    {
++        return PAM_SUCCESS;
++    }
++};
++AuthPamThread *AuthPamThreadTest::m_pAuthPamThreadDbus = nullptr;
++
++// 测试 _authenticate 函数
++TEST_F(AuthPamThreadTest, Authenticate)
++{
++    m_pAuthPamThreadDbus->m_strUserName = getenv("USER");
++    qDebug() << "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~";
++
++    // 模拟 pam 函数
++    auto originalPamStart = pam_start;
++    auto originalPamAuthenticate = pam_authenticate;
++    auto originalPamAcctMgmt = pam_acct_mgmt;
++    auto originalPamGetItem = pam_get_item;
++    auto originalPamStrerror = pam_strerror;
++    auto originalPamEnd = pam_end;
++
++    //    pam_start = mockPamStart;
++    //    pam_authenticate = mockPamAuthenticate;
++    //    pam_acct_mgmt = mockPamAcctMgmt;
++    //    pam_get_item = mockPamGetItem;
++    //    pam_strerror = mockPamStrerror;
++    //    pam_end = mockPamEnd;
++
++    qDebug() << "??????????????????????????????????????";
++    //    m_pAuthPamThreadDbus->_authenticate(m_pAuthPamThreadDbus->m_strUserName.toLocal8Bit().data());
++
++    // 恢复原始函数
++    //    pam_start = originalPamStart;
++    //    pam_authenticate = originalPamAuthenticate;
++    //    pam_acct_mgmt = originalPamAcctMgmt;
++    //    pam_get_item = originalPamGetItem;
++    //    pam_strerror = originalPamStrerror;
++    //    pam_end = originalPamEnd;
++}
++
++// 测试 startAuthPam 函数
++TEST_F(AuthPamThreadTest, StartAuthPam)
++{
++    qDebug() << "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~";
++    int fdRead = createMockPipe();
++    int fdWrite = createMockPipe();
++
++    m_pAuthPamThreadDbus->startAuthPam(fdRead, fdWrite, getenv("USER"));
++
++    EXPECT_TRUE(m_pAuthPamThreadDbus->isRunning());
++
++    close(fdRead);
++    close(fdWrite);
++}
++
++// 测试 run 函数
++TEST_F(AuthPamThreadTest, Run)
++{
++
++    int fdRead = createMockPipe();
++    int fdWrite = createMockPipe();
++
++    m_pAuthPamThreadDbus->m_fdRead = fdRead;
++    m_pAuthPamThreadDbus->m_fdWrite = fdWrite;
++    m_pAuthPamThreadDbus->m_strUserName = getenv("USER");
++
++    //    m_pAuthPamThreadDbus->run();
++
++    close(fdRead);
++    close(fdWrite);
++}
++
++// 测试 stopAuthPam 函数
++TEST_F(AuthPamThreadTest, StopAuthPam)
++{
++    m_pAuthPamThreadDbus->startAuthPam(0, 0, getenv("USER"));
++
++    m_pAuthPamThreadDbus->stopAuthPam();
++
++    EXPECT_FALSE(m_pAuthPamThreadDbus->isRunning());
++}
++
++// 测试 PamAuthenticate 类
++class PamAuthenticateTest : public ::testing::Test
++{
++protected:
++    static AuthPamThread *m_pAuthPamThreadDbus;
++
++    QSharedPointer<LightDMHelper> lightDMHelper;
++    QSharedPointer<PamAuthenticate> pamAuthenticate;
++
++    void SetUp() override
++    {
++        lightDMHelper = QSharedPointer<LightDMHelper>(
++            new LightDMHelper(QSharedPointer<AccountsHelper>(new AccountsHelper(nullptr)), nullptr));
++        pamAuthenticate = QSharedPointer<PamAuthenticate>(new PamAuthenticate(lightDMHelper));
++    }
++
++    void TearDown() override
++    {
++        pamAuthenticate.reset();
++        lightDMHelper.reset();
++    }
++
++    // 辅助函数,模拟 QSocketNotifier 的 activated 信号
++    void simulateSocketNotifierActivated(QSocketNotifier *socketNotifier)
++    {
++        //        Q_EMIT socketNotifier->activated(socketNotifier->socket());
++    }
++
++    // 辅助函数,模拟管道操作
++    int createMockPipe()
++    {
++        int fds[2];
++        if (pipe(fds) == -1) {
++            return -1;
++        }
++        return fds[0];
++    }
++
++    // 辅助函数,模拟 AuthPamThread 的行为
++    class MockAuthPamThread : public AuthPamThread
++    {
++    public:
++    };
++
++    // 辅助函数,模拟 LightDMHelper 的行为
++    class MockLightDMHelper : public LightDMHelper
++    {
++    public:
++        MockLightDMHelper()
++            : LightDMHelper(QSharedPointer<AccountsHelper>(new AccountsHelper(nullptr)), nullptr, nullptr)
++        {
++        }
++    };
++};
++
++// 测试 PamAuthenticate 构造函数
++TEST_F(PamAuthenticateTest, Constructor)
++{
++    // 检查信号和槽的连接
++    //    EXPECT_TRUE(QObject::connect(lightDMHelper.get(), SIGNAL(showMessage(QString,
++    //    QLightDM::Greeter::MessageType)),
++    //                pamAuthenticate.get(), SLOT(onLDMShowMessage(QString, QLightDM::Greeter::MessageType)));
++
++    //    EXPECT_TRUE(QObject::connect(lightDMHelper.get(), SIGNAL(showPrompt(QString, QLightDM::Greeter::PromptType)),
++    //                pamAuthenticate.get(), SLOT(onLDMShowPrompt(QString, QLightDM::Greeter::PromptType)));
++
++    //    EXPECT_TRUE(QObject::connect(lightDMHelper.get(), SIGNAL(authenticationComplete()),
++    //                pamAuthenticate.get(), SIGNAL(authenticationComplete()));
++}
++
++// 测试 inAuthentication 函数
++TEST_F(PamAuthenticateTest, InAuthentication)
++{
++    // 测试 m_isOtherUser 为 false 时的情况
++    EXPECT_FALSE(pamAuthenticate->inAuthentication());
++    // 测试 m_isOtherUser 为 true 时的情况
++    pamAuthenticate->m_isOtherUser = true;
++    EXPECT_FALSE(pamAuthenticate->inAuthentication());
++}
++
++// 测试 isAuthenticated 函数
++TEST_F(PamAuthenticateTest, IsAuthenticated)
++{
++    // 测试 m_isOtherUser 为 false 时的情况
++    EXPECT_FALSE(pamAuthenticate->isAuthenticated());
++
++    // 测试 m_isOtherUser 为 true 时的情况
++    pamAuthenticate->m_isOtherUser = true;
++    EXPECT_FALSE(pamAuthenticate->isAuthenticated());
++}
++
++// 测试 authenticationUser 函数
++TEST_F(PamAuthenticateTest, AuthenticationUser)
++{
++    // 测试 m_isOtherUser 为 false 时的情况
++    EXPECT_EQ(pamAuthenticate->authenticationUser(), "");
++
++    // 测试 m_isOtherUser 为 true 时的情况
++    pamAuthenticate->m_isOtherUser = true;
++    EXPECT_EQ(pamAuthenticate->authenticationUser(), "");
++}
++
++// 测试 authenticate 函数
++TEST_F(PamAuthenticateTest, Authenticate)
++{
++    // 测试普通用户的情况
++    pamAuthenticate->authenticate("testuser");
++    EXPECT_EQ(pamAuthenticate->m_strUserName, "testuser");
++    EXPECT_NE(pamAuthenticate->m_threadAuthPam, nullptr);
++    EXPECT_NE(pamAuthenticate->m_socketNotifier, nullptr);
++
++    // 测试访客用户的情况
++    pamAuthenticate->authenticate("*guest");
++
++    // 测试 m_isOtherUser 为 true 的情况
++    pamAuthenticate->m_isOtherUser = true;
++    pamAuthenticate->authenticate("otheruser");
++}
++
++// 测试 respond 函数
++TEST_F(PamAuthenticateTest, Respond)
++{
++    // 测试正常响应的情况
++    pamAuthenticate->m_nPrompts = 1;
++    pamAuthenticate->respond("response");
++    EXPECT_EQ(pamAuthenticate->m_responseList.size(), 1);
++
++    // 测试 m_nPrompts 为 0 的情况
++    pamAuthenticate->m_nPrompts = 0;
++    pamAuthenticate->m_isOtherUser = false;
++    pamAuthenticate->respond("response");
++    EXPECT_EQ(pamAuthenticate->m_responseList.size(), 1);
++}
++
++// 测试 cancelAuthentication 函数
++TEST_F(PamAuthenticateTest, CancelAuthentication)
++{
++    // 模拟 AuthPamThread 和 QSocketNotifier
++    pamAuthenticate->m_threadAuthPam = new MockAuthPamThread();
++    pamAuthenticate->m_socketNotifier = new QSocketNotifier(0, QSocketNotifier::Read);
++
++    pamAuthenticate->m_isOtherUser = false;
++    pamAuthenticate->cancelAuthentication();
++
++    EXPECT_EQ(pamAuthenticate->m_threadAuthPam, nullptr);
++    EXPECT_EQ(pamAuthenticate->m_socketNotifier, nullptr);
++    EXPECT_FALSE(pamAuthenticate->m_isAuthenticated);
++    EXPECT_FALSE(pamAuthenticate->m_isInAuthentication);
++    EXPECT_EQ(pamAuthenticate->m_messageList.size(), 0);
++    EXPECT_EQ(pamAuthenticate->m_responseList.size(), 0);
++    EXPECT_EQ(pamAuthenticate->m_nPrompts, 0);
++}
++
++// 测试 onSockRead 函数
++TEST_F(PamAuthenticateTest, OnSockRead)
++{
++    // 模拟管道
++    int fdToParent[2];
++    if (pipe(fdToParent) == -1) {
++        FAIL() << "Failed to create pipe";
++    }
++
++    pamAuthenticate->m_fdToParent[0] = fdToParent[0];
++
++    // 测试认证完成的情况
++    int authComplete = 1;
++    int authRet = PAM_SUCCESS;
++    write(pamAuthenticate->m_fdToParent[0], &authComplete, sizeof(authComplete));
++    write(pamAuthenticate->m_fdToParent[0], &authRet, sizeof(authRet));
++
++    QSignalSpy authenticationCompleteSpy(pamAuthenticate.get(), SIGNAL(authenticationComplete()));
++
++    simulateSocketNotifierActivated(pamAuthenticate->m_socketNotifier);
++
++    EXPECT_EQ(pamAuthenticate->m_isAuthenticated, true);
++    EXPECT_EQ(authenticationCompleteSpy.count(), 1);
++
++    // 测试消息接收的情况
++    authComplete = 0;
++    int msgLength = 1;
++    write(pamAuthenticate->m_fdToParent[0], &authComplete, sizeof(authComplete));
++    write(pamAuthenticate->m_fdToParent[0], &msgLength, sizeof(msgLength));
++
++    struct pam_message message;
++    message.msg_style = PAM_PROMPT_ECHO_OFF;
++    message.msg = "Enter password";
++
++    write(pamAuthenticate->m_fdToParent[0], &message.msg_style, sizeof(message.msg_style));
++    write(pamAuthenticate->m_fdToParent[0], message.msg, strlen(message.msg) + 1);
++
++    QSignalSpy showPromptSpy(pamAuthenticate.get(), SIGNAL(showPrompt(QString, PamAuth::PromptType)));
++
++    simulateSocketNotifierActivated(pamAuthenticate->m_socketNotifier);
++
++    EXPECT_EQ(showPromptSpy.count(), 1);
++
++    close(fdToParent[0]);
++    close(fdToParent[1]);
++}
+diff --git a/tests/unit_test_backend_dbus/CMakeLists.txt b/tests/unit_test_backend_dbus/CMakeLists.txt
+new file mode 100644
+index 0000000..9a6be89
+--- /dev/null
++++ b/tests/unit_test_backend_dbus/CMakeLists.txt
+@@ -0,0 +1,68 @@
++# CMake 最低版本要求
++cmake_minimum_required(VERSION 3.10)
++
++find_package(Qt5 COMPONENTS Core Gui DBus REQUIRED)
++
++# 包含 GTest 库和 pthread 库
++find_package(GTest REQUIRED)
++find_package(Threads REQUIRED)
++
++# 设置 C++ 标准
++set(CMAKE_CXX_STANDARD 17)
++set(CMAKE_CXX_STANDARD_REQUIRED ON)
++
++
++# 开启代码覆盖率相关编译选项(对应QMAKE_LFLAGS和QMAKE_CXXFLAGS中代码覆盖率相关设置)
++
++set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fprofile-arcs -ftest-coverage")
++set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fprofile-arcs -ftest-coverage")
++
++
++# 定义源文件列表,对应原来的SOURCES变量
++set(SOURCES
++    ../../src/lock-dialog/backenddbushelper.cpp
++    ../../src/userinfo.cpp
++    ../../src/agreementinfo.cpp
++    ../../src/common/biodefines.cpp
++    ../../src/common/global_utils.cpp
++    unit_test_backend_dbus.cpp
++    main.cpp
++)
++
++# 定义头文件列表,对应原来的HEADERS变量
++set(HEADERS
++    ../../src/lock-dialog/backenddbushelper.h
++    ../../src/common/definetypes.h
++    ../../src/common/biodefines.h
++    ../../src/userinfo.h
++    ../../src/agreementinfo.h
++    ../../src/common/global_utils.h
++)
++
++# 包含头文件的路径设置,对应原来的INCLUDEPATH变量
++include_directories(
++    ${CMAKE_CURRENT_SOURCE_DIR}
++    ${CMAKE_CURRENT_SOURCE_DIR}/../kt-test-utils/cpp-stub
++    ${CMAKE_CURRENT_SOURCE_DIR}/../kt-test-utils/cpp-stub-ext
++)
++
++# 使用qt5_wrap_cpp生成元对象代码相关的源文件
++qt5_wrap_cpp(MOC_SOURCES ${HEADERS})
++
++# 添加可执行文件或库目标,将元对象代码源文件一起添加进去
++add_executable(unit_test_backend_dbus ${SOURCES} ${MOC_SOURCES})
++
++# 链接Qt相关的库
++target_link_libraries(unit_test_backend_dbus
++    Qt5::Core
++    Qt5::Gui
++    Qt5::DBus
++)
++
++# 链接 GTest 库
++target_link_libraries(unit_test_backend_dbus
++    GTest::GTest
++    GTest::Main
++    Threads::Threads
++)
++
+diff --git a/tests/unit_test_backend_dbus/main.cpp b/tests/unit_test_backend_dbus/main.cpp
+new file mode 100644
+index 0000000..37b3fbf
+--- /dev/null
++++ b/tests/unit_test_backend_dbus/main.cpp
+@@ -0,0 +1,12 @@
++#include <gtest/gtest.h>
++#include <QGuiApplication>
++
++
++int main(int argc, char **argv)
++{
++    QGuiApplication a(argc, argv);
++    testing::InitGoogleTest(&argc, argv);
++
++    return RUN_ALL_TESTS();
++}
++
+diff --git a/tests/unit_test_backend_dbus/unit_test_backend_dbus.cpp b/tests/unit_test_backend_dbus/unit_test_backend_dbus.cpp
+new file mode 100644
+index 0000000..6e5d1a1
+--- /dev/null
++++ b/tests/unit_test_backend_dbus/unit_test_backend_dbus.cpp
+@@ -0,0 +1,423 @@
++#include <gtest/gtest.h>
++#include <gtest/gtest-death-test.h>
++
++#include "../../src/lock-dialog/backenddbushelper.h"
++#include "../../src/common/definetypes.h"
++#include "../../src/agreementinfo.h"
++#include "stubext.h"
++
++using namespace stub_ext;
++
++class BackendDbusHelperTest : public testing::Test
++{
++protected:
++    static void SetUpTestSuite()
++    {
++        QString displayNum = QString(qgetenv("DISPLAY")).replace(":", "").replace(".", "_");
++        QString sessionDbus = QString("%1%2").arg(QString(SS_DBUS_SERVICE)).arg(displayNum);
++        m_pBackendDbusHelperDbus = new BackendDbusHelper(sessionDbus, SS_DBUS_PATH, QDBusConnection::sessionBus());
++        if (!m_pBackendDbusHelperDbus->isValid()) {
++            delete m_pBackendDbusHelperDbus;
++            m_pBackendDbusHelperDbus = new BackendDbusHelper(SS_DBUS_SERVICE, SS_DBUS_PATH, QDBusConnection::sessionBus());
++        }
++    }
++
++    static void TearDownTestSuite()
++    {
++        delete m_pBackendDbusHelperDbus;
++        m_pBackendDbusHelperDbus = nullptr;
++    }
++
++    static BackendDbusHelper *m_pBackendDbusHelperDbus;
++};
++
++BackendDbusHelper *BackendDbusHelperTest::m_pBackendDbusHelperDbus = nullptr;
++
++TEST_F(BackendDbusHelperTest, getUsersInfo)
++{
++    QList<UserInfoPtr> value = m_pBackendDbusHelperDbus->getUsersInfo();
++    ASSERT_EQ(value.isEmpty(), false);
++}
++
++TEST_F(BackendDbusHelperTest, getAgreementInfo)
++{
++    AgreementInfoPtr value = m_pBackendDbusHelperDbus->getAgreementInfo();
++//    ASSERT_EQ(value, NULL);
++}
++
++TEST_F(BackendDbusHelperTest, getSessionsInfo)
++{
++    QList<QString> value = m_pBackendDbusHelperDbus->getSessionsInfo();
++    ASSERT_EQ(value.isEmpty(), false);
++}
++
++TEST_F(BackendDbusHelperTest, getBatteryArgs)
++{
++    QStringList value = m_pBackendDbusHelperDbus->getBatteryArgs();
++    ASSERT_EQ(value.isEmpty(), false);
++}
++
++TEST_F(BackendDbusHelperTest, getSleepLockcheck)
++{
++    QStringList value = m_pBackendDbusHelperDbus->getSleepLockcheck();
++    ASSERT_EQ(value.isEmpty(), false);
++}
++
++TEST_F(BackendDbusHelperTest, isSessionActive)
++{
++    bool value = m_pBackendDbusHelperDbus->isSessionActive();
++    ASSERT_EQ(value, true);
++}
++
++TEST_F(BackendDbusHelperTest, switchToUser)
++{
++    int value = m_pBackendDbusHelperDbus->switchToUser(getenv("USER"));
++    ASSERT_EQ(value, 0);
++}
++
++TEST_F(BackendDbusHelperTest, setCurrentUser)
++{
++    bool value = m_pBackendDbusHelperDbus->setCurrentUser(getenv("USER"));
++    ASSERT_EQ(value, true);
++}
++
++TEST_F(BackendDbusHelperTest, setPowerManager)
++{
++    bool value = m_pBackendDbusHelperDbus->setPowerManager("LockScreen");
++    ASSERT_EQ(value, true);
++}
++
++TEST_F(BackendDbusHelperTest, sendPassword)
++{
++    QByteArray decryptText;
++    bool value = m_pBackendDbusHelperDbus->sendPassword(getenv("USER"), decryptText);
++    ASSERT_EQ(value, true);
++}
++
++TEST_F(BackendDbusHelperTest, getBatteryIconName)
++{
++    QString value = m_pBackendDbusHelperDbus->getBatteryIconName();
++    ASSERT_EQ(value.isEmpty(), true);
++}
++
++TEST_F(BackendDbusHelperTest, getIsBattery)
++{
++    bool value = m_pBackendDbusHelperDbus->getIsBattery();
++    ASSERT_EQ(value, true);
++}
++
++TEST_F(BackendDbusHelperTest, getCurTabletMode)
++{
++    bool value = m_pBackendDbusHelperDbus->getCurTabletMode();
++    ASSERT_EQ(value, true);
++}
++
++TEST_F(BackendDbusHelperTest, lockStateChanged)
++{
++    bool value = m_pBackendDbusHelperDbus->lockStateChanged(false, false);
++    ASSERT_EQ(value, true);
++}
++
++TEST_F(BackendDbusHelperTest, pamIsInAuthentication)
++{
++    m_pBackendDbusHelperDbus->startSession();
++    m_pBackendDbusHelperDbus->pamAuthenticate(getenv("USER"));
++    m_pBackendDbusHelperDbus->bioStartAuth(getuid(), 32);
++    m_pBackendDbusHelperDbus->bioStopAuth();
++    m_pBackendDbusHelperDbus->pamRespond("");
++    m_pBackendDbusHelperDbus->pamAuthenticateCancel();
++    bool value = m_pBackendDbusHelperDbus->pamIsInAuthentication();
++    ASSERT_EQ(value, true);
++}
++
++TEST_F(BackendDbusHelperTest, pamIsAuthenticated)
++{
++    bool value = m_pBackendDbusHelperDbus->pamIsAuthenticated();
++    ASSERT_EQ(value, true);
++}
++
++TEST_F(BackendDbusHelperTest, pamAuthenticateUser)
++{
++    QString value = m_pBackendDbusHelperDbus->pamAuthenticateUser();
++    ASSERT_EQ(value.isEmpty(), true);
++}
++
++TEST_F(BackendDbusHelperTest, bioGetAvailableDevices)
++{
++    QList<DeviceInfo> value = m_pBackendDbusHelperDbus->bioGetAvailableDevices(101);
++    ASSERT_EQ(value.isEmpty(), true);
++}
++
++TEST_F(BackendDbusHelperTest, bioGetDisabledDevices)
++{
++    QList<int> value = m_pBackendDbusHelperDbus->bioGetDisabledDevices(101);
++    ASSERT_EQ(value.isEmpty(), true);
++}
++
++TEST_F(BackendDbusHelperTest, bioGetBioAuthState)
++{
++    int value = m_pBackendDbusHelperDbus->bioGetBioAuthState();
++    ASSERT_EQ(value, 0);
++}
++
++TEST_F(BackendDbusHelperTest, bioGetCurBioInfo)
++{
++    DeviceInfo bioValue1 = m_pBackendDbusHelperDbus->bioGetCurBioInfo();
++    DeviceInfo bioValue2 = m_pBackendDbusHelperDbus->bioFindDeviceById(getuid(), 101);
++    DeviceInfo bioValue3 = m_pBackendDbusHelperDbus->bioFindDeviceByName(getuid(), "uru4000");
++    QString value = m_pBackendDbusHelperDbus->bioGetDefaultDevice(getuid(), getenv("USER"));
++    ASSERT_EQ(value.isEmpty(), true);
++}
++
++TEST_F(BackendDbusHelperTest, getCurrentSession)
++{
++    QString value = m_pBackendDbusHelperDbus->getCurrentSession();
++    ASSERT_EQ(value.isEmpty(), true);
++}
++
++TEST_F(BackendDbusHelperTest, setCurrentSession)
++{
++    bool value = m_pBackendDbusHelperDbus->setCurrentSession("testSession");
++    ASSERT_EQ(value, true);
++}
++
++TEST_F(BackendDbusHelperTest, onUpdateInformation)
++{
++    QList<int> list{LOCK_CMD_ID_USERINFO_CHANGED, LOCK_CMD_ID_CURRENT_USER_CHANGED,
++                   LOCK_CMD_ID_CURRENT_SESSION_CHANGED, LOCK_CMD_ID_LOGIN1_REQ_LOCK,
++                   LOCK_CMD_ID_LOGIN1_REQ_UNLOCK, LOCK_CMD_ID_LOGIN1_PREPAREFORSLEEP,
++                   LOCK_CMD_ID_LOGIN1_SESSION_ACTIVE_CHANGED, LOCK_CMD_ID_GSETTINGS_LOCKSCREEN_CONF_CHANGED,
++                   LOCK_CMD_ID_GSETTINGS_SCREENSAVER_CONF_CHANGED, LOCK_CMD_ID_GSETTINGS_POWERMANAGER_CONF_CHANGED,
++                   LOCK_CMD_ID_GSETTINGS_MATEBG_CONF_CHANGED, LOCK_CMD_ID_GSETTINGS_UKCCPLUGINS_CONF_CHANGED,
++                   LOCK_CMD_ID_GSETTINGS_THEMESTYLE_CONF_CHANGED, LOCK_CMD_ID_GSETTINGS_SESSION_CONF_CHANGED,
++                   LOCK_CMD_ID_LOGIN1_BLOCKINHIBITED_CHANGED, LOCK_CMD_ID_GSETTINGS_KEYBOARD_CONF_CHANGED,
++                   LOCK_CMD_ID_PAMAUTH_SHOWMESSAGE, LOCK_CMD_ID_PAMAUTH_SHOWPROMPT, LOCK_CMD_ID_PAMAUTH_AUTH_COMPLETED,
++                   LOCK_CMD_ID_GSETTINGS_USD_MEDIAKEYS_CONF_CHANGED, LOCK_CMD_ID_GSETTINGS_USD_MEDIA_STATE_KEYS_CONF_CHANGED,
++                   LOCK_CMD_ID_UPOWER_BATTERY_STATUS, LOCK_CMD_ID_UPOWER_BATTERY, LOCK_CMD_ID_BIOAUTH_SERVICE_STATUS_CHANGED,
++                   LOCK_CMD_ID_BIOAUTH_DEVICE_CHANGED, LOCK_CMD_ID_BIOAUTH_SHOW_MESSAGE, LOCK_CMD_ID_BIOAUTH_AUTHSTATE_CHANGED,
++                   LOCK_CMD_ID_BIOAUTH_FRAME_DATA, LOCK_CMD_ID_BIOAUTH_COMPLETE, LOCK_CMD_ID_TABLET_MODE_CHANGED};
++    for (int i = 0; i < list.count(); i++) {
++        QJsonObject retObj;
++        retObj["CmdId"] = list.at(i);
++        m_pBackendDbusHelperDbus->onUpdateInformation(QString(QJsonDocument(retObj).toJson()));
++    }
++}
++
++TEST_F(BackendDbusHelperTest, usdExternalDoAction)
++{
++    bool value = m_pBackendDbusHelperDbus->usdExternalDoAction(VOLUME_DOWN_KEY);
++    m_pBackendDbusHelperDbus->usdExternalDoAction(VOLUME_UP_KEY);
++    ASSERT_EQ(value, true);
++}
++
++TEST_F(BackendDbusHelperTest, getDefaultAuthUser)
++{
++    QString value = m_pBackendDbusHelperDbus->getDefaultAuthUser();
++    ASSERT_EQ(value.isEmpty(), true);
++}
++
++TEST_F(BackendDbusHelperTest, getCurrentUser)
++{
++    QString value = m_pBackendDbusHelperDbus->getCurrentUser();
++    ASSERT_EQ(value.isEmpty(), true);
++}
++
++TEST_F(BackendDbusHelperTest, getScreenSaverConf)
++{
++    bool value = m_pBackendDbusHelperDbus->getScreenSaverConf(KEY_AUTOMATIC_SWITCHING_ENABLE).toBool();
++    ASSERT_EQ(value, false);
++}
++
++TEST_F(BackendDbusHelperTest, setScreenSaverConf)
++{
++    bool oldvalue = m_pBackendDbusHelperDbus->getScreenSaverConf(KEY_AUTOMATIC_SWITCHING_ENABLE).toBool();
++    bool value = m_pBackendDbusHelperDbus->setScreenSaverConf(KEY_AUTOMATIC_SWITCHING_ENABLE, !oldvalue);
++    ASSERT_EQ(value, false);
++    m_pBackendDbusHelperDbus->setScreenSaverConf(KEY_AUTOMATIC_SWITCHING_ENABLE, oldvalue);
++}
++
++TEST_F(BackendDbusHelperTest, getLockScreenConf)
++{
++    bool value = m_pBackendDbusHelperDbus->getLockScreenConf(KEY_LOCK_ENABLED).toBool();
++    ASSERT_EQ(value, false);
++}
++
++TEST_F(BackendDbusHelperTest, setLockScreenConf)
++{
++    bool oldvalue = m_pBackendDbusHelperDbus->getLockScreenConf(KEY_LOCK_ENABLED).toBool();
++    bool value = m_pBackendDbusHelperDbus->setLockScreenConf(KEY_LOCK_ENABLED, !oldvalue);
++    ASSERT_EQ(value, false);
++    m_pBackendDbusHelperDbus->setLockScreenConf(KEY_LOCK_ENABLED, oldvalue);
++}
++
++TEST_F(BackendDbusHelperTest, getShutdownLockcheck)
++{
++    QStringList value = m_pBackendDbusHelperDbus->getShutdownLockcheck();
++    ASSERT_EQ(value.isEmpty(), false);
++}
++
++TEST_F(BackendDbusHelperTest, getSaverThemes)
++{
++    QStringList value = m_pBackendDbusHelperDbus->getSaverThemes();
++    ASSERT_EQ(value.isEmpty(), false);
++}
++
++TEST_F(BackendDbusHelperTest, getPowerManagerConf)
++{
++    bool value = m_pBackendDbusHelperDbus->getPowerManagerConf(KEY_LOCK_BLANKSCREEN).toBool();
++    ASSERT_EQ(value, false);
++}
++
++TEST_F(BackendDbusHelperTest, setPowerManagerConf)
++{
++    bool oldvalue = m_pBackendDbusHelperDbus->getPowerManagerConf(KEY_LOCK_BLANKSCREEN).toBool();
++    bool value = m_pBackendDbusHelperDbus->setPowerManagerConf(KEY_LOCK_BLANKSCREEN, !oldvalue);
++    ASSERT_EQ(value, false);
++    m_pBackendDbusHelperDbus->setPowerManagerConf(KEY_LOCK_BLANKSCREEN, oldvalue);
++}
++
++TEST_F(BackendDbusHelperTest, getMateBgConf)
++{
++    QString value = m_pBackendDbusHelperDbus->getMateBgConf(KEY_PICTURE_FILENAME).toString();
++    ASSERT_EQ(value.isEmpty(), false);
++}
++
++TEST_F(BackendDbusHelperTest, setMateBgConf)
++{
++    QString oldvalue = m_pBackendDbusHelperDbus->getMateBgConf(KEY_PICTURE_FILENAME).toString();
++    return ;
++
++    bool value = m_pBackendDbusHelperDbus->setMateBgConf("picture-filename", "sss");
++    ASSERT_EQ(value, false);
++    m_pBackendDbusHelperDbus->setMateBgConf("picture-filename", oldvalue);
++}
++
++TEST_F(BackendDbusHelperTest, getUkccPluginsConf)
++{
++    QString value = m_pBackendDbusHelperDbus->getUkccPluginsConf(KEY_DATE).toString();
++    ASSERT_EQ(value, false);
++}
++
++TEST_F(BackendDbusHelperTest, setUkccPluginsConf)
++{
++    QString oldvalue = m_pBackendDbusHelperDbus->getUkccPluginsConf(KEY_DATE).toString();
++    bool value = m_pBackendDbusHelperDbus->setUkccPluginsConf(KEY_DATE, "sss");
++    ASSERT_EQ(value, false);
++    m_pBackendDbusHelperDbus->setUkccPluginsConf(KEY_DATE, oldvalue);
++}
++
++TEST_F(BackendDbusHelperTest, getThemeStyleConf)
++{
++    QString value = m_pBackendDbusHelperDbus->getThemeStyleConf(KEY_THEME_COLOR).toString();
++    ASSERT_EQ(value, false);
++}
++
++TEST_F(BackendDbusHelperTest, setThemeStyleConf)
++{
++    QString oldvalue = m_pBackendDbusHelperDbus->getThemeStyleConf(KEY_THEME_COLOR).toString();
++    bool value = m_pBackendDbusHelperDbus->setThemeStyleConf(KEY_THEME_COLOR, "sss");
++    ASSERT_EQ(value, false);
++    m_pBackendDbusHelperDbus->setThemeStyleConf(KEY_THEME_COLOR, oldvalue);
++}
++
++TEST_F(BackendDbusHelperTest, getSessionConf)
++{
++    int value = m_pBackendDbusHelperDbus->getSessionConf(KEY_SESSION_IDLE).toInt();
++    ASSERT_EQ(value, 60);
++}
++
++TEST_F(BackendDbusHelperTest, setSessionConf)
++{
++    int oldvalue = m_pBackendDbusHelperDbus->getSessionConf(KEY_SESSION_IDLE).toInt();
++    bool value = m_pBackendDbusHelperDbus->setSessionConf(KEY_SESSION_IDLE, 30);
++    ASSERT_EQ(value, false);
++    m_pBackendDbusHelperDbus->setSessionConf(KEY_SESSION_IDLE, oldvalue);
++}
++
++TEST_F(BackendDbusHelperTest, getKeyboardConf)
++{
++    bool value = m_pBackendDbusHelperDbus->getKeyboardConf(KEY_CAPSLOCK_STATUS).toBool();
++    ASSERT_EQ(value, false);
++}
++
++TEST_F(BackendDbusHelperTest, setKeyboardConf)
++{
++    bool oldvalue = m_pBackendDbusHelperDbus->getKeyboardConf(KEY_CAPSLOCK_STATUS).toBool();
++    bool value = m_pBackendDbusHelperDbus->setKeyboardConf(KEY_CAPSLOCK_STATUS, !oldvalue);
++    ASSERT_EQ(value, false);
++    m_pBackendDbusHelperDbus->setKeyboardConf(KEY_CAPSLOCK_STATUS, oldvalue);
++}
++
++TEST_F(BackendDbusHelperTest, getUsdMediaStateKeys)
++{
++    int value = m_pBackendDbusHelperDbus->getUsdMediaStateKeys(KEY_RFKILL_STATE).toInt();
++    ASSERT_EQ(value, 60);
++}
++
++TEST_F(BackendDbusHelperTest, setUsdMediaStateKeys)
++{
++    int oldvalue = m_pBackendDbusHelperDbus->getUsdMediaStateKeys(KEY_RFKILL_STATE).toInt();
++    bool value = m_pBackendDbusHelperDbus->setUsdMediaStateKeys(KEY_RFKILL_STATE, 0);
++    ASSERT_EQ(value, false);
++    m_pBackendDbusHelperDbus->setUsdMediaStateKeys(KEY_RFKILL_STATE, oldvalue);
++}
++
++TEST_F(BackendDbusHelperTest, getUsdMediaKeys)
++{
++    QString value = m_pBackendDbusHelperDbus->getUsdMediaKeys(KEY_WINDOW_SCREENSHOT).toString();
++    ASSERT_EQ(value, false);
++}
++
++TEST_F(BackendDbusHelperTest, getPowerManagerCanSuspend)
++{
++    bool value = m_pBackendDbusHelperDbus->getPowerManagerCanSuspend();
++    ASSERT_EQ(value, false);
++}
++
++TEST_F(BackendDbusHelperTest, getPowerManagerCanReboot)
++{
++    bool value = m_pBackendDbusHelperDbus->getPowerManagerCanReboot();
++    ASSERT_EQ(value, false);
++}
++
++TEST_F(BackendDbusHelperTest, getPowerManagerCanPowerOff)
++{
++    bool value = m_pBackendDbusHelperDbus->getPowerManagerCanPowerOff();
++    ASSERT_EQ(value, false);
++}
++
++TEST_F(BackendDbusHelperTest, getPowerManagerCanSwitchUser)
++{
++    bool value = m_pBackendDbusHelperDbus->getPowerManagerCanSwitchUser();
++    ASSERT_EQ(value, false);
++}
++
++TEST_F(BackendDbusHelperTest, getPowerManagerCanHibernate)
++{
++    bool value = m_pBackendDbusHelperDbus->getPowerManagerCanHibernate();
++    ASSERT_EQ(value, false);
++}
++
++TEST_F(BackendDbusHelperTest, getPowerManagerCanLogout)
++{
++    bool value = m_pBackendDbusHelperDbus->getPowerManagerCanLogout();
++    ASSERT_EQ(value, false);
++}
++
++TEST_F(BackendDbusHelperTest, getPowerManagerCanLockScreen)
++{
++    bool value = m_pBackendDbusHelperDbus->getPowerManagerCanLockScreen();
++    ASSERT_EQ(value, false);
++}
++
++TEST_F(BackendDbusHelperTest, checkSystemUpgrade)
++{
++    bool value = m_pBackendDbusHelperDbus->checkSystemUpgrade();
++    ASSERT_EQ(value, false);
++}
++
++TEST_F(BackendDbusHelperTest, getPublicEncrypt)
++{
++    QString value = m_pBackendDbusHelperDbus->getPublicEncrypt();
++    ASSERT_EQ(value.isEmpty(), false);
++}
+diff --git a/tests/unit_test_biometric_helper/CMakeLists.txt b/tests/unit_test_biometric_helper/CMakeLists.txt
+new file mode 100644
+index 0000000..76fb9ed
+--- /dev/null
++++ b/tests/unit_test_biometric_helper/CMakeLists.txt
+@@ -0,0 +1,66 @@
++# CMake 最低版本要求
++cmake_minimum_required(VERSION 3.10)
++
++find_package(Qt5 COMPONENTS Core Gui DBus REQUIRED)
++find_package(PkgConfig REQUIRED)
++
++pkg_check_modules(GLIB2 REQUIRED glib-2.0 gio-2.0)
++
++# 包含 GTest 库和 pthread 库
++find_package(GTest REQUIRED)
++find_package(Threads REQUIRED)
++
++# 设置 C++ 标准
++set(CMAKE_CXX_STANDARD 11)
++set(CMAKE_CXX_STANDARD_REQUIRED ON)
++
++
++# 开启代码覆盖率相关编译选项(对应QMAKE_LFLAGS和QMAKE_CXXFLAGS中代码覆盖率相关设置)
++set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fprofile-arcs -ftest-coverage --coverage -fno-inline -fno-access-control")
++set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fprofile-arcs -ftest-coverage")
++
++# 定义源文件列表,对应原来的SOURCES变量
++set(SOURCES
++    ../../src/dbusifs/biometrichelper.cpp
++    ../../src/common/biodefines.cpp
++    ../../src/dbusifs/giodbus.cpp
++    unit_test_biometric_helper.cpp
++    main.cpp
++)
++
++# 定义头文件列表,对应原来的HEADERS变量
++set(HEADERS
++        ../../src/common/biodefines.h
++        ../../src/dbusifs/biometrichelper.h
++        ../../src/dbusifs/giodbus.h
++)
++
++# 包含头文件的路径设置,对应原来的INCLUDEPATH变量
++include_directories(
++    ${CMAKE_CURRENT_SOURCE_DIR}
++    ${CMAKE_CURRENT_SOURCE_DIR}/../kt-test-utils/cpp-stub
++    ${CMAKE_CURRENT_SOURCE_DIR}/../kt-test-utils/cpp-stub-ext
++    ${GLIB2_INCLUDE_DIRS}
++)
++
++# 使用qt5_wrap_cpp生成元对象代码相关的源文件
++qt5_wrap_cpp(MOC_SOURCES ${HEADERS})
++
++# 添加可执行文件或库目标,将元对象代码源文件一起添加进去
++add_executable(unit_test_biometric_helper ${SOURCES} ${MOC_SOURCES})
++
++# 链接Qt相关的库
++target_link_libraries(unit_test_biometric_helper
++    Qt5::Core
++    Qt5::Gui
++    Qt5::DBus
++)
++
++# 链接 GTest 库
++target_link_libraries(unit_test_biometric_helper
++    GTest::GTest
++    GTest::Main
++    Threads::Threads
++    ${GLIB2_LIBRARIES}
++)
++
+diff --git a/tests/unit_test_biometric_helper/main.cpp b/tests/unit_test_biometric_helper/main.cpp
+new file mode 100644
+index 0000000..37b3fbf
+--- /dev/null
++++ b/tests/unit_test_biometric_helper/main.cpp
+@@ -0,0 +1,12 @@
++#include <gtest/gtest.h>
++#include <QGuiApplication>
++
++
++int main(int argc, char **argv)
++{
++    QGuiApplication a(argc, argv);
++    testing::InitGoogleTest(&argc, argv);
++
++    return RUN_ALL_TESTS();
++}
++
+diff --git a/tests/unit_test_biometric_helper/unit_test_biometric_helper.cpp b/tests/unit_test_biometric_helper/unit_test_biometric_helper.cpp
+new file mode 100644
+index 0000000..4889d3d
+--- /dev/null
++++ b/tests/unit_test_biometric_helper/unit_test_biometric_helper.cpp
+@@ -0,0 +1,131 @@
++#include <gtest/gtest.h>
++#include <gtest/gtest-death-test.h>
++#include <QtDBus>
++#include <QDBusAbstractInterface>
++
++#include "../../src/dbusifs/biometrichelper.h"
++#include "../../src/dbusifs/giodbus.h"
++
++#include "stubext.h"
++using namespace stub_ext;
++
++class BiometricHelperTest : public testing::Test
++{
++protected:
++    static void SetUpTestSuite()
++    {
++        m_pABiometricHelperDbus = new BiometricHelper();
++    }
++
++    static void TearDownTestSuite()
++    {
++        delete m_pABiometricHelperDbus;
++        m_pABiometricHelperDbus = nullptr;
++    }
++
++    static BiometricHelper *m_pABiometricHelperDbus;
++};
++
++BiometricHelper *BiometricHelperTest::m_pABiometricHelperDbus = nullptr;
++
++TEST_F(BiometricHelperTest, Identify)
++{
++    get_server_gvariant_stdout(-1);
++    QDBusPendingCall value = m_pABiometricHelperDbus->Identify(32, 1000, 0, -1);
++    ASSERT_EQ(value.isValid(), false);
++}
++
++TEST_F(BiometricHelperTest, UkeyIdentify)
++{
++    QDBusPendingCall value = m_pABiometricHelperDbus->UkeyIdentify(100, 2, 1000);
++    ASSERT_EQ(value.isValid(), false);
++}
++
++TEST_F(BiometricHelperTest, GetHasUkeyFeature)
++{
++    bool value = m_pABiometricHelperDbus->GetHasUkeyFeature(1000, 0, -1);
++    ASSERT_EQ(value, false);
++}
++
++TEST_F(BiometricHelperTest, GetFeatureCount)
++{
++    bool value = m_pABiometricHelperDbus->GetFeatureCount(1000, 0, -1);
++    ASSERT_EQ(value, false);
++}
++
++TEST_F(BiometricHelperTest, SetExtraInfo)
++{
++    int value = m_pABiometricHelperDbus->SetExtraInfo("extra_info", "extra_info");
++    ASSERT_EQ(value, 0);
++}
++
++TEST_F(BiometricHelperTest, StopOps)
++{
++    int value = m_pABiometricHelperDbus->StopOps(32, 3000);
++    ASSERT_EQ(value, 0);
++}
++
++TEST_F(BiometricHelperTest, GetUserDevCount)
++{
++    int value = m_pABiometricHelperDbus->GetUserDevCount(1000);
++    ASSERT_EQ(value, 0);
++}
++
++TEST_F(BiometricHelperTest, GetUserDevFeatureCount)
++{
++    int value = m_pABiometricHelperDbus->GetUserDevFeatureCount(1000, 32);
++    ASSERT_EQ(value, 0);
++}
++
++TEST_F(BiometricHelperTest, GetDevList)
++{
++    DeviceList value = m_pABiometricHelperDbus->GetDevList();
++    ASSERT_EQ(value.isEmpty(), false);
++}
++
++TEST_F(BiometricHelperTest, GetUserFeatures)
++{
++    FeatureMap value = m_pABiometricHelperDbus->GetUserFeatures(1000);
++    ASSERT_EQ(value.isEmpty(), true);
++}
++
++TEST_F(BiometricHelperTest, GetDevCount)
++{
++    int value = m_pABiometricHelperDbus->GetDevCount();
++    ASSERT_EQ(value, 0);
++}
++
++TEST_F(BiometricHelperTest, GetDevMesg)
++{
++    QString value = m_pABiometricHelperDbus->GetDevMesg(32);
++    std::string str = value.toStdString();
++    const char* cstr = str.data();
++    ASSERT_EQ(cstr, "");
++}
++
++TEST_F(BiometricHelperTest, GetNotifyMesg)
++{
++    QString value = m_pABiometricHelperDbus->GetNotifyMesg(32);
++    std::string str = value.toStdString();
++    const char* cstr = str.data();
++    ASSERT_EQ(cstr, "");
++}
++
++TEST_F(BiometricHelperTest, GetOpsMesg)
++{
++    QString value = m_pABiometricHelperDbus->GetOpsMesg(32);
++    std::string str = value.toStdString();
++    const char* cstr = str.data();
++    ASSERT_EQ(cstr, "");
++}
++
++TEST_F(BiometricHelperTest, UpdateStatus)
++{
++    StatusReslut status = m_pABiometricHelperDbus->UpdateStatus(32);
++    ASSERT_EQ(status.result , 0);
++    ASSERT_EQ(status.enable , 0);
++    ASSERT_EQ(status.devNum , 0);
++    ASSERT_EQ(status.devStatus , 0);
++    ASSERT_EQ(status.opsStatus , 0);
++    ASSERT_EQ(status.notifyMessageId , 0);
++}
+diff --git a/tests/unit_test_common/CMakeLists.txt b/tests/unit_test_common/CMakeLists.txt
+new file mode 100644
+index 0000000..ed9241f
+--- /dev/null
++++ b/tests/unit_test_common/CMakeLists.txt
+@@ -0,0 +1,89 @@
++# CMake 最低版本要求
++cmake_minimum_required(VERSION 3.10)
++
++find_package(Qt5 COMPONENTS Core Gui Widgets X11Extras Svg DBus REQUIRED)
++find_package(PkgConfig REQUIRED)
++pkg_check_modules(QGS REQUIRED gsettings-qt)
++find_package(OpenSSL REQUIRED)
++# 包含 GTest 库和 pthread 库
++find_package(GTest REQUIRED)
++find_package(Threads REQUIRED)
++find_package(X11 REQUIRED)
++pkg_check_modules(GIOUNIX2 REQUIRED gio-unix-2.0)
++pkg_check_modules(GLIB2 REQUIRED glib-2.0 gio-2.0)
++# 设置 C++ 标准
++set(CMAKE_CXX_STANDARD 17)
++set(CMAKE_CXX_STANDARD_REQUIRED ON)
++
++
++# 开启代码覆盖率相关编译选项(对应QMAKE_LFLAGS和QMAKE_CXXFLAGS中代码覆盖率相关设置)
++
++set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fprofile-arcs -ftest-coverage")
++set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fprofile-arcs -ftest-coverage")
++
++
++# 定义源文件列表,对应原来的SOURCES变量
++set(SOURCES
++    ../../src/common/biodefines.cpp
++    ../../src/common/commonfunc.cpp
++    ../../src/common/configuration.cpp
++    ../../src/common/global_utils.cpp
++    ../../src/common/rsac.cpp
++    ../../src/common/utils.cpp
++    ../../src/lock-dialog/languagesetting.cpp
++    unit_test_common.cpp
++    main.cpp
++)
++
++# 定义头文件列表,对应原来的HEADERS变量
++set(HEADERS
++    ../../src/common/definetypes.h
++    ../../src/common/biodefines.h
++    ../../src/common/commonfunc.h
++    ../../src/common/configuration.h
++    ../../src/common/global_utils.h
++    ../../src/common/rsac.h
++    ../../src/common/utils.h
++    ../../src/lock-dialog/languagesetting.h
++    )
++
++# 包含头文件的路径设置,对应原来的INCLUDEPATH变量
++include_directories(
++    ${CMAKE_CURRENT_SOURCE_DIR}
++    ${CMAKE_CURRENT_SOURCE_DIR}/../kt-test-utils/cpp-stub
++    ${CMAKE_CURRENT_SOURCE_DIR}/../kt-test-utils/cpp-stub-ext
++    ${QGS_INCLUDE_DIRS}
++    ${GIOUNIX2_INCLUDE_DIRS}
++    ${X11_INCLUDE_DIRS}
++)
++
++qt5_add_resources(unit_test_common
++        assets.qrc
++    )
++
++# 使用qt5_wrap_cpp生成元对象代码相关的源文件
++qt5_wrap_cpp(MOC_SOURCES ${HEADERS})
++
++# 添加可执行文件或库目标,将元对象代码源文件一起添加进去
++add_executable(unit_test_common ${SOURCES} ${MOC_SOURCES})
++
++# 链接Qt相关的库
++target_link_libraries(unit_test_common
++    Qt5::Core
++    Qt5::Gui
++    Qt5::DBus
++    Qt5::Widgets
++    Qt5::Svg
++    Qt5::X11Extras
++    ${QGS_LIBRARIES}
++    OpenSSL::Crypto
++)
++
++# 链接 GTest 库
++target_link_libraries(unit_test_common
++    GTest::GTest
++    GTest::Main
++    Threads::Threads
++    ${GIOUNIX2_LIBRARIES}
++    ${X11_LIBRARIES}
++)
+diff --git a/tests/unit_test_common/main.cpp b/tests/unit_test_common/main.cpp
+new file mode 100644
+index 0000000..37b3fbf
+--- /dev/null
++++ b/tests/unit_test_common/main.cpp
+@@ -0,0 +1,12 @@
++#include <gtest/gtest.h>
++#include <QGuiApplication>
++
++
++int main(int argc, char **argv)
++{
++    QGuiApplication a(argc, argv);
++    testing::InitGoogleTest(&argc, argv);
++
++    return RUN_ALL_TESTS();
++}
++
+diff --git a/tests/unit_test_common/unit_test_common.cpp b/tests/unit_test_common/unit_test_common.cpp
+new file mode 100644
+index 0000000..e92efeb
+--- /dev/null
++++ b/tests/unit_test_common/unit_test_common.cpp
+@@ -0,0 +1,349 @@
++#include "../../src/common/definetypes.h"
++#include "../../src/common/biodefines.h"
++#include "../../src/common/commonfunc.h"
++#include "../../src/common/configuration.h"
++#include "../../src/common/global_utils.h"
++#include "../../src/common/rsac.h"
++#include <gtest/gtest.h>
++#include <gtest/gtest-death-test.h>
++#include <QIcon>
++#include <openssl/rsa.h>
++#include <openssl/pem.h>
++#include <openssl/err.h>
++#include <openssl/sha.h>
++#include <iostream>
++#include "../../src/common/rsac.h"
++#include "../../src/common/utils.h"
++#include "../../src/lock-dialog/languagesetting.h"
++
++#include "stubext.h"
++using namespace stub_ext;
++
++// 辅助函数,用于初始化OpenSSL库
++
++void InitOpenSSL() {
++
++    OpenSSL_add_all_algorithms();
++
++    ERR_load_crypto_strings();
++
++}
++
++
++
++// 辅助函数,用于清理OpenSSL库
++
++void CleanupOpenSSL() {
++
++    EVP_cleanup();
++
++    ERR_free_strings();
++
++}
++
++class CommonTest : public testing::Test
++{
++protected:
++
++    void SetUp() override {
++
++        InitOpenSSL();
++
++    }
++
++
++
++    void TearDown() override {
++
++        CleanupOpenSSL();
++
++    }
++
++    RSAC rsac;
++};
++
++TEST_F(CommonTest, scaledPixmap)
++{
++    setCursorCenter();
++    QPixmap pixmap = QIcon::fromTheme("view-refresh-symbolic").pixmap(48, 48);
++    QPixmap newPixmap = scaledPixmap(pixmap);
++    ASSERT_EQ(newPixmap.isNull(), false);
++}
++
++TEST_F(CommonTest, PixmapToRound)
++{
++    QPixmap pixmap = QIcon::fromTheme("view-refresh-symbolic").pixmap(48, 48);
++    QPixmap newPixmap = PixmapToRound(pixmap, 4);
++    ASSERT_EQ(newPixmap.isNull(), false);
++}
++
++TEST_F(CommonTest, PixmapToRound2)
++{
++    QPixmap pixmap = QIcon::fromTheme("view-refresh-symbolic").pixmap(48, 48);
++    QPixmap newPixmap = PixmapToRound(pixmap, 0, 0, 0, 0);
++    ASSERT_EQ(newPixmap.isNull(), false);
++}
++
++TEST_F(CommonTest, loadSvg)
++{
++    QPixmap iconPixmap = loadSvg(":/image/assets/show-password.png", "white", 16);
++    ASSERT_EQ(iconPixmap.isNull(), false);
++}
++
++TEST_F(CommonTest, drawSymbolicColoredPixmap)
++{
++    QPixmap retryIcon = QIcon::fromTheme("view-refresh-symbolic").pixmap(48, 48);
++    ASSERT_EQ(drawSymbolicColoredPixmap(retryIcon, "white").isNull(), false);
++    ASSERT_EQ(getLoadingIcon(16).width(), 16);
++}
++
++TEST_F(CommonTest, scaleBlurPixmap)
++{
++    QPixmap *pixmap = new QPixmap(scaleBlurPixmap(16, 16, "/usr/share/background/house.png"));
++    ASSERT_EQ(pixmap->width(), 16);
++}
++
++TEST_F(CommonTest, blurPixmap)
++{
++    QPixmap pixmap = QIcon::fromTheme("view-refresh-symbolic").pixmap(48, 48);
++    QPixmap newpixmap = blurPixmap(pixmap);
++    ASSERT_EQ(newpixmap.width(), 16);
++}
++
++TEST_F(CommonTest, getDeviceTypeTr)
++{
++
++    getDeviceTypeTr(BioT_FingerVein);
++    getDeviceTypeTr(BioT_Iris);
++    getDeviceTypeTr(BioT_Face);
++    getDeviceTypeTr(BioT_VoicePrint);
++    getDeviceTypeTr(UniT_General_Ukey);
++    getDeviceTypeTr(UniT_Remote);
++    getDeviceTypeTr(-1);
++    ASSERT_EQ(getDeviceTypeTr(BioT_FingerPrint).isEmpty(), false);
++}
++
++TEST_F(CommonTest, getValue)
++{
++    if (Configuration::instance()) {
++        QString color = Configuration::instance()->getValue("background-color").toString();
++        ASSERT_EQ(color.isEmpty(), false);
++    }
++}
++
++TEST_F(CommonTest, getCurrentUser)
++{
++    if (Configuration::instance()) {
++        Configuration::instance()->getCurrentUser(getenv("USER"));
++    }
++}
++
++TEST_F(CommonTest, setValue)
++{
++    if (Configuration::instance()) {
++        QString color = Configuration::instance()->getValue("backgroundPath").toString();
++        QString oldvalue = Configuration::instance()->getUserConfig("backgroundPath").toString();
++        Configuration::instance()->setValue("backgroundPath", oldvalue);
++        ASSERT_EQ(oldvalue.isEmpty(), false);
++    }
++}
++
++TEST_F(CommonTest, hasValue)
++{
++    if (Configuration::instance()) {
++        bool value = Configuration::instance()->hasValue("backgroundPath");
++        ASSERT_EQ(value, false);
++    }
++}
++
++
++TEST_F(CommonTest, getIs990)
++{
++    if (Configuration::instance()) {
++        bool value = Configuration::instance()->getIs990();
++        ASSERT_EQ(value, false);
++    }
++}
++
++TEST_F(CommonTest, getLastNumLock)
++{
++    if (Configuration::instance()) {
++        bool value = Configuration::instance()->getLastNumLock();
++        Configuration::instance()->saveLastNumLock(value);
++        ASSERT_EQ(value, false);
++    }
++}
++
++TEST_F(CommonTest, getRootBackgroundOption)
++{
++    if (Configuration::instance()) {
++        int value = Configuration::instance()->getRootBackgroundOption(getenv("USER"));
++        ASSERT_EQ(value, 1);
++    }
++}
++
++TEST_F(CommonTest, getDefaultBackgroundName)
++{
++    if (Configuration::instance()) {
++        QString background = Configuration::instance()->getDefaultBackgroundName();
++        ASSERT_EQ(background.isEmpty(), false);
++    }
++}
++
++TEST_F(CommonTest, onLanguageChanged)
++{
++    if (LanguageSetting::instance()) {
++        LanguageSetting::instance()->onLanguageChanged("zh_HK.UTF-8");
++        LanguageSetting::instance()->onLanguageChanged("zh_CN.UTF-8");
++    }
++}
++
++TEST_F(CommonTest, isCurUserSelf)
++{
++    ASSERT_EQ(isCurUserSelf(getenv("USER")), true);
++    ASSERT_EQ(isCurUserSelf("lightdm"), false);
++    ASSERT_EQ(isCurUserSelf("test"), false);
++}
++
++TEST_F(CommonTest, checkCapsLockState)
++{
++    checkIslivecd();
++    KillFocusOfKydroid();
++    ASSERT_EQ(checkCapsLockState(), false);
++}
++
++TEST_F(CommonTest, getDefaultFontSize)
++{
++    ASSERT_EQ(getDefaultFontSize(), 14.0);
++}
++
++TEST_F(CommonTest, getUserFontSize)
++{
++    ASSERT_EQ(getUserFontSize(getenv("USER")), 14.0);
++}
++
++TEST_F(CommonTest, getUserThemeColor)
++{
++    ASSERT_EQ(getUserThemeColor(getenv("USER")), "test");
++}
++
++// 测试密钥生成并保存到文件
++
++TEST_F(CommonTest, GenerateKeyPairToFile) {
++
++    QString priKeyFile = "test_private.pem";
++
++    QString pubKeyFile = "test_public.pem";
++
++    rsac.generateKeyPair(priKeyFile, pubKeyFile, 1024);
++
++
++
++    // 这里可以添加额外的检查来验证文件是否成功生成且内容有效
++
++    // 例如,打开文件并读取内容,检查是否为有效的PEM格式密钥
++
++    // 但由于这是一个简单的测试示例,我们省略了这些步骤
++}
++
++
++
++// 测试密钥生成并保存到QByteArray
++
++TEST_F(CommonTest, GenerateKeyPairToByteArray) {
++
++    QByteArray privateKey;
++
++    QByteArray publicKey;
++
++    rsac.generateKeyPair(privateKey, publicKey, 1024);
++
++
++
++    // 检查生成的密钥是否非空
++
++    EXPECT_FALSE(privateKey.isEmpty());
++
++    EXPECT_FALSE(publicKey.isEmpty());
++
++
++
++    // 这里可以添加额外的检查来验证密钥的有效性
++
++    // 例如,使用OpenSSL函数解析生成的密钥并检查其属性
++
++    // 但由于这是一个简单的测试示例,我们省略了这些步骤
++
++}
++
++
++
++// 测试加密和解密
++
++TEST_F(CommonTest, EncryptDecrypt) {
++
++    QByteArray privateKey;
++
++    QByteArray publicKey;
++
++    rsac.generateKeyPair(privateKey, publicKey, 1024);
++
++
++
++    QByteArray plaintext = "Hello, RSA!";
++
++    QByteArray ciphertext;
++
++    QByteArray decryptedtext;
++
++
++
++    bool encryptResult = rsac.encrypt(plaintext, ciphertext, publicKey);
++
++    EXPECT_TRUE(encryptResult);
++
++
++
++    bool decryptResult = rsac.decrypt(ciphertext, decryptedtext, privateKey);
++
++    EXPECT_TRUE(decryptResult);
++
++
++
++    EXPECT_EQ(plaintext, decryptedtext);
++
++}
++
++
++
++// 测试签名和验签
++
++TEST_F(CommonTest, SignVerify) {
++
++    QByteArray privateKey;
++
++    QByteArray publicKey;
++
++    rsac.generateKeyPair(privateKey, publicKey, 1024);
++
++
++
++    QByteArray message = "This is a test message.";
++
++    QByteArray signature;
++
++    bool signResult = rsac.sign(message, signature, privateKey);
++
++    EXPECT_TRUE(signResult);
++
++    bool verifyResult = rsac.verify(message, signature, publicKey);
++
++    EXPECT_TRUE(verifyResult);
++
++    // 尝试使用错误的消息进行验签,应该失败
++
++    bool verifyWithWrongMessageResult = rsac.verify("Wrong message.", signature, publicKey);
++
++    EXPECT_FALSE(verifyWithWrongMessageResult);
++
++}
+diff --git a/tests/unit_test_dbus_interface/CMakeLists.txt b/tests/unit_test_dbus_interface/CMakeLists.txt
+new file mode 100644
+index 0000000..ffc9e8c
+--- /dev/null
++++ b/tests/unit_test_dbus_interface/CMakeLists.txt
+@@ -0,0 +1,147 @@
++# CMake 最低版本要求
++cmake_minimum_required(VERSION 3.10)
++
++find_package(Qt5 COMPONENTS Core Gui DBus Network Test REQUIRED)
++find_package(OpenSSL REQUIRED)
++find_package(PkgConfig REQUIRED)
++pkg_check_modules(GIOUNIX2 REQUIRED gio-unix-2.0)
++pkg_check_modules(GLIB2 REQUIRED glib-2.0 gio-2.0)
++pkg_check_modules(QGS REQUIRED gsettings-qt)
++pkg_check_modules(LIGHTDM-QT5-3 REQUIRED liblightdm-qt5-3)
++pkg_check_modules(LIBSYSTEMD REQUIRED libsystemd)
++
++# 包含 GTest 库和 pthread 库
++find_package(GTest REQUIRED)
++find_package(Threads REQUIRED)
++# 查找pam动态库全路径并缓存到PAM_LIBRARIES变量
++find_library(PAM_LIBRARIES pam)
++# 设置 C++ 标准
++set(CMAKE_CXX_STANDARD 17)
++set(CMAKE_CXX_STANDARD_REQUIRED ON)
++
++
++# 开启代码覆盖率相关编译选项(对应QMAKE_LFLAGS和QMAKE_CXXFLAGS中代码覆盖率相关设置)
++set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fprofile-arcs -ftest-coverage --coverage -fno-inline -fno-access-control")
++set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fprofile-arcs -ftest-coverage")
++
++# 定义源文件列表,对应原来的SOURCES变量
++set(SOURCES
++    ../../src/lock-backend/authpamthread.cpp
++    ../../src/lock-backend/pamauthenticate.cpp
++    ../../src/lock-backend/lightdmhelper.cpp
++    ../../src/lock-backend/dbusupperinterface.cpp
++    ../../src/lock-backend/gsettingshelper.cpp
++    ../../src/lock-backend/bioauthenticate.cpp
++    ../../src/lock-backend/switchuserutils.cpp
++    ../../src/dbusifs/accountshelper.cpp
++    ../../src/userinfo.cpp
++    ../../src/common/global_utils.cpp
++    ../../src/common/configuration.cpp
++    ../../src/common/rsac.cpp
++    ../../src/dbusifs/giodbus.cpp
++    ../../src/dbusifs/uniauthservice.cpp
++    ../../src/lock-backend/securityuser.cpp
++    ../../src/dbusifs/freedesktophelper.cpp
++    ../../src/dbusifs/login1helper.cpp
++    ../../src/dbusifs/usdhelper.cpp
++    ../../src/dbusifs/upowerhelper.cpp
++    ../../src/dbusifs/sessionhelper.cpp
++    ../../src/dbusifs/dbusservermanager.cpp
++    ../../src/dbusifs/systemupgradehelper.cpp
++    ../../src/lock-backend/sessionwatcher.cpp
++    ../../src/dbusifs/kglobalaccelhelper.cpp
++    ../../src/dbusifs/libinputswitchevent.cpp
++    ../../src/lock-backend/personalizeddata.cpp
++    ../../src/dbusifs/biometrichelper.cpp
++    ../../src/dbusifs/device.cpp
++    ../../src/dbusifs/machinemodel.cpp
++    ../../src/dbusifs/enginedevice.cpp
++    ../../src/common/biodefines.cpp
++    ../../src/QtSingleApplication/qtlocalpeer.cpp
++    ../kt-test-utils/cpp-stub-ext/stub-shadow.cpp
++    unit_test_dbus_interface.cpp
++    main.cpp
++)
++
++# 定义头文件列表,对应原来的HEADERS变量
++set(HEADERS
++        ../../src/lock-backend/authpamthread.h
++        ../../src/lock-backend/pamauthenticate.h
++        ../../src/lock-backend/lightdmhelper.h
++        ../../src/lock-backend/dbusupperinterface.h
++        ../../src/lock-backend/gsettingshelper.h
++        ../../src/lock-backend/bioauthenticate.h
++        ../../src/lock-backend/switchuserutils.h
++        ../../src/common/definetypes.h
++        ../../src/userinfo.h
++        ../../src/common/global_utils.h
++        ../../src/common/configuration.h
++        ../../src/common/rsac.h
++        ../../src/dbusifs/giodbus.h
++        ../../src/dbusifs/accountshelper.h
++        ../../src/common/configuration.h
++        ../../src/dbusifs/uniauthservice.h
++        ../../src/lock-backend/securityuser.h
++        ../../src/dbusifs/freedesktophelper.h
++        ../../src/dbusifs/login1helper.h
++        ../../src/dbusifs/usdhelper.h
++        ../../src/dbusifs/upowerhelper.h
++        ../../src/dbusifs/dbusservermanager.h
++        ../../src/dbusifs/sessionhelper.h
++        ../../src/dbusifs/systemupgradehelper.h
++        ../../src/lock-backend/sessionwatcher.h
++        ../../src/dbusifs/kglobalaccelhelper.h
++        ../../src/dbusifs/libinputswitchevent.h
++        ../../src/lock-backend/personalizeddata.h
++        ../../src/dbusifs/biometrichelper.h
++        ../../src/dbusifs/device.h
++        ../../src/dbusifs/enginedevice.h
++        ../../src/dbusifs/machinemodel.h
++        ../../src/common/biodefines.h
++        ../kt-test-utils/cpp-stub-ext/stubext.h
++        ../kt-test-utils/cpp-stub-ext/stub-shadow.h
++        ../../src/QtSingleApplication/qtlocalpeer.h
++)
++
++# 包含头文件的路径设置,对应原来的INCLUDEPATH变量
++include_directories(
++    ${CMAKE_CURRENT_SOURCE_DIR}
++    ${CMAKE_CURRENT_SOURCE_DIR}/../kt-test-utils/cpp-stub
++    ${CMAKE_CURRENT_SOURCE_DIR}/../kt-test-utils/cpp-stub-ext
++    ${QGS_INCLUDE_DIRS}
++    ${Qt5Test_INCLUDE_DIRS}
++    ${LIGHTDM-QT5-3_INCLUDE_DIRS}
++    ${LIBSYSTEMD_INCLUDE_DIRS}
++    ${GIOUNIX2_INCLUDE_DIRS}
++    ${CMAKE_CURRENT_SOURCE_DIR}../../src/QtSingleApplication/
++)
++
++# 使用qt5_wrap_cpp生成元对象代码相关的源文件
++qt5_wrap_cpp(MOC_SOURCES ${HEADERS})
++
++# 添加可执行文件或库目标,将元对象代码源文件一起添加进去
++add_executable(unit_test_dbus_interface ${SOURCES} ${MOC_SOURCES})
++
++# 链接Qt相关的库
++target_link_libraries(unit_test_dbus_interface
++    Qt5::Core
++    Qt5::Gui
++    Qt5::DBus
++    Qt5::Test
++    Qt5::Network
++    ${QGS_LIBRARIES}
++    ${PAM_LIBRARIES}
++    ${LIGHTDM-QT5-3_LIBRARIES}
++    ${LIBSYSTEMD_LIBRARIES}
++    OpenSSL::Crypto
++    -lukuiinputgatherclient
++    ${GIOUNIX2_LIBRARIES}
++)
++
++# 链接 GTest 库
++target_link_libraries(unit_test_dbus_interface
++    GTest::GTest
++    GTest::Main
++    Threads::Threads
++)
++
+diff --git a/tests/unit_test_dbus_interface/main.cpp b/tests/unit_test_dbus_interface/main.cpp
+new file mode 100644
+index 0000000..37b3fbf
+--- /dev/null
++++ b/tests/unit_test_dbus_interface/main.cpp
+@@ -0,0 +1,12 @@
++#include <gtest/gtest.h>
++#include <QGuiApplication>
++
++
++int main(int argc, char **argv)
++{
++    QGuiApplication a(argc, argv);
++    testing::InitGoogleTest(&argc, argv);
++
++    return RUN_ALL_TESTS();
++}
++
+diff --git a/tests/unit_test_dbus_interface/unit_test_dbus_interface.cpp b/tests/unit_test_dbus_interface/unit_test_dbus_interface.cpp
+new file mode 100644
+index 0000000..3f4e5ec
+--- /dev/null
++++ b/tests/unit_test_dbus_interface/unit_test_dbus_interface.cpp
+@@ -0,0 +1,524 @@
++#include <gtest/gtest.h>
++#include <memory>
++#include <sys/types.h>
++#include <sys/stat.h>
++#include <fcntl.h>
++#include <unistd.h>
++#include <string.h>
++#include <security/pam_appl.h>
++#include <gtest/gtest.h>
++#include <QCoreApplication>
++#include <QLightDM/Greeter>
++#include <QSocketNotifier>
++#include <QDebug>
++#include <QSignalSpy>
++#include <QJsonValue>
++#include <QJsonObject>
++#include <QJsonDocument>
++#include <QJsonArray>
++#include "../../src/lock-backend/authpamthread.h"
++#include "../../src/lock-backend/pamauthenticate.h"
++#include "../../src/lock-backend/lightdmhelper.h"
++#include "../../src/lock-backend/dbusupperinterface.h"
++#include "../../src/dbusifs/accountshelper.h"
++
++#include "stubext.h"
++
++using namespace stub_ext;
++
++class DbusUpperInterfaceTest : public testing::Test
++{
++protected:
++    static void SetUpTestSuite()
++    {
++
++        StubExt st;
++        st.set_lamda(&LightDMHelper::connectToDaemonSync, []() { return true; });
++        st.set_lamda(&isGreeterMode, []() { return true; });
++        m_pAccountsHelperDbus = QSharedPointer<AccountsHelper>(new AccountsHelper());
++        m_pLightDMHelperDbus = new LightDMHelper(m_pAccountsHelperDbus, Configuration::instance());
++        m_pDbusUpperInterfaceDbus = new DbusUpperInterface();
++    }
++
++    static void TearDownTestSuite()
++    {
++        delete m_pDbusUpperInterfaceDbus;
++        m_pDbusUpperInterfaceDbus = nullptr;
++
++        delete m_pLightDMHelperDbus;
++        m_pLightDMHelperDbus = nullptr;
++
++        m_pAccountsHelperDbus.reset();
++    }
++
++    static DbusUpperInterface *m_pDbusUpperInterfaceDbus;
++
++    static LightDMHelper *m_pLightDMHelperDbus;
++
++    static QSharedPointer<AccountsHelper> m_pAccountsHelperDbus;
++};
++
++DbusUpperInterface *DbusUpperInterfaceTest::m_pDbusUpperInterfaceDbus = nullptr;
++LightDMHelper *DbusUpperInterfaceTest::m_pLightDMHelperDbus = nullptr;
++QSharedPointer<AccountsHelper> DbusUpperInterfaceTest::m_pAccountsHelperDbus = nullptr;
++
++TEST_F(DbusUpperInterfaceTest, GetSlpState)
++{
++    m_pDbusUpperInterfaceDbus->onNameLost("test");
++    bool value = m_pDbusUpperInterfaceDbus->GetSlpState();
++
++    m_pLightDMHelperDbus->getLoginUserCount();
++    m_pLightDMHelperDbus->findUserByUid(getuid());
++
++    ASSERT_EQ(value, false);
++}
++
++TEST_F(DbusUpperInterfaceTest, GetBlankState)
++{
++    bool value = m_pDbusUpperInterfaceDbus->GetBlankState();
++    ASSERT_EQ(value, false);
++}
++
++TEST_F(DbusUpperInterfaceTest, GetLockState)
++{
++    bool value = m_pDbusUpperInterfaceDbus->GetLockState();
++    ASSERT_EQ(value, false);
++}
++
++TEST_F(DbusUpperInterfaceTest, CheckAppVersion)
++{
++    bool value = m_pDbusUpperInterfaceDbus->CheckAppVersion();
++    ASSERT_EQ(value, false);
++}
++
++TEST_F(DbusUpperInterfaceTest, checkScreenDialogRunning)
++{
++    m_pDbusUpperInterfaceDbus->LockStartupMode();
++    m_pDbusUpperInterfaceDbus->SessionTools();
++    m_pDbusUpperInterfaceDbus->Lock();
++    m_pDbusUpperInterfaceDbus->SwitchUser();
++    m_pDbusUpperInterfaceDbus->AppBlockWindow("Suspend");
++    m_pDbusUpperInterfaceDbus->MultiUserBlockWindow("Restart");
++    m_pDbusUpperInterfaceDbus->onShowBlankScreensaver();
++    m_pDbusUpperInterfaceDbus->ShowScreensaver();
++    m_pDbusUpperInterfaceDbus->LockScreensaver();
++    //    m_pDbusUpperInterfaceDbus->Suspend();
++    bool value = m_pDbusUpperInterfaceDbus->checkScreenDialogRunning();
++    ASSERT_EQ(value, false);
++}
++
++TEST_F(DbusUpperInterfaceTest, GenerateBatteryArgsList)
++{
++    QJsonArray value = m_pDbusUpperInterfaceDbus->GenerateBatteryArgsList();
++    ASSERT_EQ(value.isEmpty(), false);
++}
++
++TEST_F(DbusUpperInterfaceTest, getSleepLockCheck)
++{
++    QJsonArray value = m_pDbusUpperInterfaceDbus->getSleepLockCheck();
++    ASSERT_EQ(value.isEmpty(), true);
++}
++
++TEST_F(DbusUpperInterfaceTest, getShutdownLockcheck)
++{
++    QJsonArray value = m_pDbusUpperInterfaceDbus->getShutdownLockcheck();
++    ASSERT_EQ(value.isEmpty(), true);
++}
++
++TEST_F(DbusUpperInterfaceTest, getSaverTheme)
++{
++    QJsonArray value = m_pDbusUpperInterfaceDbus->getSaverTheme();
++    ASSERT_EQ(value.isEmpty(), true);
++}
++
++TEST_F(DbusUpperInterfaceTest, getBatteryIconName)
++{
++    QString value = m_pDbusUpperInterfaceDbus->getBatteryIconName();
++    ASSERT_EQ(value.isEmpty(), false);
++}
++
++TEST_F(DbusUpperInterfaceTest, getIsBattery)
++{
++    bool value = m_pDbusUpperInterfaceDbus->getIsBattery();
++    ASSERT_EQ(value, false);
++}
++
++TEST_F(DbusUpperInterfaceTest, GetDefaultAuthUser)
++{
++    StubExt st;
++    st.set_lamda(&isGreeterMode, []() { return true; });
++    QString value = m_pDbusUpperInterfaceDbus->GetDefaultAuthUser();
++    ASSERT_EQ(value.isEmpty(), false);
++}
++
++TEST_F(DbusUpperInterfaceTest, GetCurrentSession)
++{
++    QString value = m_pDbusUpperInterfaceDbus->GetCurrentSession();
++    ASSERT_EQ(value.isEmpty(), false);
++}
++
++TEST_F(DbusUpperInterfaceTest, GenerateSessionInfoList)
++{
++    QJsonArray value = m_pDbusUpperInterfaceDbus->GenerateSessionInfoList();
++    ASSERT_EQ(value.isEmpty(), false);
++}
++
++TEST_F(DbusUpperInterfaceTest, GetCurrentUser)
++{
++    QString value = m_pDbusUpperInterfaceDbus->GetCurrentUser();
++    ASSERT_EQ(value.isEmpty(), false);
++}
++
++TEST_F(DbusUpperInterfaceTest, getCurTabletMode)
++{
++    bool value = m_pDbusUpperInterfaceDbus->getCurTabletMode();
++    ASSERT_EQ(value, false);
++}
++
++TEST_F(DbusUpperInterfaceTest, GenerateUserInfoList)
++{
++    //    m_pDbusUpperInterfaceDbus->GenerateUserInfoList();
++    //    qDebug() << "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" ;
++    //    m_pDbusUpperInterfaceDbus->onUsersInfoChanged();
++    m_pDbusUpperInterfaceDbus->onLogin1ReqLock();
++    m_pDbusUpperInterfaceDbus->onLogin1ReqUnLock();
++    m_pDbusUpperInterfaceDbus->onLogin1PrepareForSleep(true);
++    m_pDbusUpperInterfaceDbus->onLogin1PrepareForSleep(false);
++    m_pDbusUpperInterfaceDbus->onLogin1SessionActiveChanged(true);
++    m_pDbusUpperInterfaceDbus->onBlockInhibitedChanged("ShutDown");
++    m_pDbusUpperInterfaceDbus->delayLockScreen();
++    m_pDbusUpperInterfaceDbus->stopDelayLockScreen();
++    m_pDbusUpperInterfaceDbus->onBatteryStatusChanged("test");
++    m_pDbusUpperInterfaceDbus->onSessionIdleReceived();
++    m_pDbusUpperInterfaceDbus->onSessionIdleExit();
++    m_pDbusUpperInterfaceDbus->onLockScreenTimeout();
++    m_pDbusUpperInterfaceDbus->onBatteryChanged(QStringList());
++    m_pDbusUpperInterfaceDbus->onLidStateChanged(false);
++}
++
++TEST_F(DbusUpperInterfaceTest, SendUpdateInfoSig)
++{
++    QJsonObject getjsonCmd;
++    QJsonParseError jsonParseError;
++    QJsonObject objRes;
++    QVariant varValue;
++
++    getjsonCmd["CmdId"] = LOCK_CMD_ID_GSETTINGS_GET_LOCKSCREEN_CONF;
++    getjsonCmd["Key"] = KEY_IDLE_DELAY;
++    const QJsonDocument jsonDoc = QJsonDocument::fromJson(
++        m_pDbusUpperInterfaceDbus->GetInformation(QString(QJsonDocument(getjsonCmd).toJson())).toUtf8(),
++        &jsonParseError);
++    objRes = jsonDoc.object();
++    varValue = objRes.value(KEY_IDLE_DELAY);
++    m_pDbusUpperInterfaceDbus->onLockScreenConfigChanged(KEY_IDLE_DELAY, varValue.toDouble());
++
++    getjsonCmd["CmdId"] = LOCK_CMD_ID_GSETTINGS_GET_SCREENSAVER_CONF;
++    getjsonCmd["Key"] = KEY_SHOW_REST_TIME;
++    const QJsonDocument jsonDoc1 = QJsonDocument::fromJson(
++        m_pDbusUpperInterfaceDbus->GetInformation(QString(QJsonDocument(getjsonCmd).toJson())).toUtf8(),
++        &jsonParseError);
++    objRes = jsonDoc1.object();
++    varValue = objRes.value(KEY_SHOW_REST_TIME);
++    m_pDbusUpperInterfaceDbus->onScreenSaverConfigChanged(KEY_SHOW_REST_TIME, varValue.toDouble());
++
++    getjsonCmd["CmdId"] = LOCK_CMD_ID_GSETTINGS_GET_POWERMANAGER_CONF;
++    getjsonCmd["Key"] = KEY_SLEEP_COMPUTER_AC;
++    const QJsonDocument jsonDoc2 = QJsonDocument::fromJson(
++        m_pDbusUpperInterfaceDbus->GetInformation(QString(QJsonDocument(getjsonCmd).toJson())).toUtf8(),
++        &jsonParseError);
++    objRes = jsonDoc2.object();
++    varValue = objRes.value(KEY_SLEEP_COMPUTER_AC);
++    m_pDbusUpperInterfaceDbus->onPowerManagerConfigChanged(KEY_SLEEP_COMPUTER_AC, varValue.toDouble());
++
++    //    getjsonCmd["CmdId"] = LOCK_CMD_ID_GSETTINGS_GET_MATEBG_CONF;
++    //    getjsonCmd["Key"] = KEY_PICTURE_FILENAME;
++    //    const QJsonDocument jsonDoc3 =
++    //    QJsonDocument::fromJson(m_pDbusUpperInterfaceDbus->GetInformation(QString(QJsonDocument(getjsonCmd).toJson())).toUtf8(),
++    //    &jsonParseError); objRes = jsonDoc3.object(); varValue = objRes.value(KEY_PICTURE_FILENAME);
++    //    m_pDbusUpperInterfaceDbus->onMateBgConfigChanged(KEY_PICTURE_FILENAME, varValue.toString());
++
++    getjsonCmd["CmdId"] = LOCK_CMD_ID_GSETTINGS_GET_UKCCPLUGINS_CONF;
++    getjsonCmd["Key"] = KEY_HOUR_SYSTEM;
++    const QJsonDocument jsonDoc4 = QJsonDocument::fromJson(
++        m_pDbusUpperInterfaceDbus->GetInformation(QString(QJsonDocument(getjsonCmd).toJson())).toUtf8(),
++        &jsonParseError);
++    objRes = jsonDoc4.object();
++    varValue = objRes.value(KEY_HOUR_SYSTEM);
++    m_pDbusUpperInterfaceDbus->onUkccPluginsConfigChanged(KEY_HOUR_SYSTEM, varValue.toDouble());
++
++    getjsonCmd["CmdId"] = LOCK_CMD_ID_GSETTINGS_GET_THEMESTYLE_CONF;
++    getjsonCmd["Key"] = KEY_SYSTEM_FONT_SIZE;
++    const QJsonDocument jsonDoc5 = QJsonDocument::fromJson(
++        m_pDbusUpperInterfaceDbus->GetInformation(QString(QJsonDocument(getjsonCmd).toJson())).toUtf8(),
++        &jsonParseError);
++    objRes = jsonDoc5.object();
++    varValue = objRes.value(KEY_SYSTEM_FONT_SIZE);
++    m_pDbusUpperInterfaceDbus->onThemeStyleConfigChanged(KEY_SYSTEM_FONT_SIZE, varValue.toDouble());
++
++    getjsonCmd["CmdId"] = LOCK_CMD_ID_GSETTINGS_GET_SESSION_CONF;
++    getjsonCmd["Key"] = KEY_SESSION_IDLE;
++    const QJsonDocument jsonDoc6 = QJsonDocument::fromJson(
++        m_pDbusUpperInterfaceDbus->GetInformation(QString(QJsonDocument(getjsonCmd).toJson())).toUtf8(),
++        &jsonParseError);
++    objRes = jsonDoc6.object();
++    varValue = objRes.value(KEY_SESSION_IDLE);
++    m_pDbusUpperInterfaceDbus->onSessionConfigChanged(KEY_SESSION_IDLE, varValue.toDouble());
++
++    getjsonCmd["CmdId"] = LOCK_CMD_ID_GSETTINGS_GET_KEYBOARD_CONF;
++    getjsonCmd["Key"] = KEY_CAPSLOCK_STATUS;
++    const QJsonDocument jsonDoc7 = QJsonDocument::fromJson(
++        m_pDbusUpperInterfaceDbus->GetInformation(QString(QJsonDocument(getjsonCmd).toJson())).toUtf8(),
++        &jsonParseError);
++    objRes = jsonDoc7.object();
++    varValue = objRes.value(KEY_CAPSLOCK_STATUS);
++    m_pDbusUpperInterfaceDbus->onKeyboardConfigChanged(KEY_CAPSLOCK_STATUS, varValue.toBool());
++
++    getjsonCmd["CmdId"] = LOCK_CMD_ID_GSETTINGS_GET_USD_MEDIAKEYS_CONF;
++    getjsonCmd["Key"] = KEY_AREA_SCREENSHOT;
++    const QJsonDocument jsonDoc8 = QJsonDocument::fromJson(
++        m_pDbusUpperInterfaceDbus->GetInformation(QString(QJsonDocument(getjsonCmd).toJson())).toUtf8(),
++        &jsonParseError);
++    objRes = jsonDoc8.object();
++    varValue = objRes.value(KEY_AREA_SCREENSHOT);
++    m_pDbusUpperInterfaceDbus->onUsdMediaKeysConfigChanged(KEY_AREA_SCREENSHOT, varValue.toString());
++
++    getjsonCmd["CmdId"] = LOCK_CMD_ID_GSETTINGS_GET_USD_MEDIA_STATE_KEYS_CONF;
++    getjsonCmd["Key"] = KEY_RFKILL_STATE;
++    const QJsonDocument jsonDoc9 = QJsonDocument::fromJson(
++        m_pDbusUpperInterfaceDbus->GetInformation(QString(QJsonDocument(getjsonCmd).toJson())).toUtf8(),
++        &jsonParseError);
++    objRes = jsonDoc9.object();
++    varValue = objRes.value(KEY_RFKILL_STATE);
++    m_pDbusUpperInterfaceDbus->onUsdMediaStateKeysConfigChanged(KEY_RFKILL_STATE, varValue.toDouble());
++}
++
++TEST_F(DbusUpperInterfaceTest, GetInformation)
++{
++    //    QList<QVariant> argumentList;
++    //    argumentList << QVariant::fromValue(QString(QJsonDocument(jsonCmd).toJson()));
++    QList<int> list{ /*LOCK_CMD_ID_GET_USERINFO_LIST, */ LOCK_CMD_ID_GET_DEFAULT_AUTH_USER,
++                     LOCK_CMD_ID_GET_CURRENT_USER,
++                     LOCK_CMD_ID_GET_SESSIONS_LIST,
++                     LOCK_CMD_ID_GET_CURRENT_SESSION,
++                     LOCK_CMD_ID_LOGIN1_IS_SESSION_ACTIVE,
++                     LOCK_CMD_ID_GET_AGREEMENT,
++                     LOCK_CMD_ID_GSETTINGS_GET_LOCKSCREEN_CONF,
++                     LOCK_CMD_ID_GSETTINGS_GET_SCREENSAVER_CONF,
++                     LOCK_CMD_ID_GSETTINGS_GET_POWERMANAGER_CONF,
++                     /*LOCK_CMD_ID_GSETTINGS_GET_MATEBG_CONF,*/ LOCK_CMD_ID_GSETTINGS_GET_UKCCPLUGINS_CONF,
++                     LOCK_CMD_ID_GSETTINGS_GET_THEMESTYLE_CONF,
++                     LOCK_CMD_ID_GSETTINGS_GET_SESSION_CONF,
++                     LOCK_CMD_ID_GSETTINGS_GET_KEYBOARD_CONF,
++                     LOCK_CMD_ID_PAMAUTH_IS_AUTHENTICATED,
++                     LOCK_CMD_ID_PAMAUTH_IS_INAUTHTICATION,
++                     LOCK_CMD_ID_PAMAUTH_GET_AUTHUSER,
++                     LOCK_CMD_ID_GSETTINGS_GET_USD_MEDIAKEYS_CONF,
++                     LOCK_CMD_ID_GSETTINGS_GET_USD_MEDIA_STATE_KEYS_CONF,
++                     LOCK_CMD_ID_LOGIN1_GET_POWER_MANAGER_CANHIBERNATE,
++                     LOCK_CMD_ID_LOGIN1_GET_POWER_MANAGER_CANPOWEROFF,
++                     LOCK_CMD_ID_LOGIN1_GET_POWER_MANAGER_CANREBOOT,
++                     LOCK_CMD_ID_LOGIN1_GET_POWER_MANAGER_CANSUSPEND,
++                     LOCK_CMD_ID_LOGIN1_GET_POWER_MANAGER_CANLOGOUT,
++                     LOCK_CMD_ID_LOGIN1_GET_POWER_MANAGER_CANLOCKSCREEN,
++                     LOCK_CMD_ID_SYSTEM_UPGRADE_CHECK,
++                     LOCK_CMD_ID_UPOWER_BATTERY_STATUS,
++                     LOCK_CMD_ID_UPOWER_IS_BATTERY,
++                     LOCK_CMD_ID_UPOWER_BATTERY,
++                     LOCK_CMD_ID_SESSION_GET_SLEEP_LOCKCHECK,
++                     LOCK_CMD_ID_SESSION_GET_SHUTDOWN_LOCKCHECK,
++                     LOCK_CMD_ID_LOCK_SCREEN_GET_THEMES,
++                     LOCK_CMD_ID_BIOAUTH_GET_AVAILABLE_DEVICES,
++                     LOCK_CMD_ID_BIOAUTH_GET_DISABLED_DEVICES,
++                     LOCK_CMD_ID_BIOAUTH_GET_STATE,
++                     LOCK_CMD_ID_BIOAUTH_GET_CURDEVICE,
++                     LOCK_CMD_ID_BIOAUTH_FIND_DEVICE_BY_ID,
++                     LOCK_CMD_ID_BIOAUTH_FIND_DEVICE_BY_NAME,
++                     LOCK_CMD_ID_BIOAUTH_GET_DEFAULT_DEVICE,
++                     LOCK_CMD_ID_GET_PUBLIC_KEY,
++                     LOCK_CMD_ID_TABLET_MODE,
++                     -1 };
++
++    for (int i = 0; i < list.count(); i++) {
++        QJsonObject jsonCmd;
++        jsonCmd["CmdId"] = list.at(i);
++        m_pDbusUpperInterfaceDbus->GetInformation(QString(QJsonDocument(jsonCmd).toJson()));
++    }
++}
++
++TEST_F(DbusUpperInterfaceTest, SetInformation)
++{
++    QJsonObject jsonCmd;
++    jsonCmd["CmdId"] = LOCK_CMD_ID_SET_USER;
++    jsonCmd["Content"] = getenv("USER");
++    m_pDbusUpperInterfaceDbus->SetInformation(QString(QJsonDocument(jsonCmd).toJson()).toUtf8());
++
++    QJsonObject jsonCmd1;
++    jsonCmd1["CmdId"] = LOCK_CMD_ID_SWITCH_TO_USER;
++    jsonCmd1["Content"] = getenv("USER");
++    m_pDbusUpperInterfaceDbus->SetInformation(QString(QJsonDocument(jsonCmd1).toJson()).toUtf8());
++
++    QJsonObject jsonCmd2;
++    jsonCmd2["CmdId"] = LOCK_CMD_ID_SET_SESSION;
++    jsonCmd2["Content"] = "testSession";
++    m_pDbusUpperInterfaceDbus->SetInformation(QString(QJsonDocument(jsonCmd2).toJson()).toUtf8());
++
++    QJsonObject jsonCmd3;
++    jsonCmd3["CmdId"] = LOCK_CMD_ID_START_SESSION;
++    m_pDbusUpperInterfaceDbus->SetInformation(QString(QJsonDocument(jsonCmd3).toJson()).toUtf8());
++
++    QJsonObject getjsonCmd;
++    getjsonCmd["CmdId"] = LOCK_CMD_ID_GSETTINGS_GET_LOCKSCREEN_CONF;
++    getjsonCmd["Key"] = KEY_IDLE_DELAY;
++    QJsonParseError jsonParseError;
++    const QJsonDocument jsonDoc = QJsonDocument::fromJson(
++        m_pDbusUpperInterfaceDbus->GetInformation(QString(QJsonDocument(getjsonCmd).toJson())).toUtf8(),
++        &jsonParseError);
++    QJsonObject objRes = jsonDoc.object();
++    QVariant varValue = objRes.value(KEY_IDLE_DELAY);
++    QJsonObject jsonCmd4;
++    jsonCmd4["CmdId"] = LOCK_CMD_ID_GSETTINGS_SET_LOCKSCREEN_CONF;
++    jsonCmd4["Content"] = varValue.toDouble();
++    jsonCmd4["Key"] = KEY_IDLE_DELAY;
++    m_pDbusUpperInterfaceDbus->SetInformation(QString(QJsonDocument(jsonCmd4).toJson()).toUtf8());
++
++    QJsonObject getjsonCmd5;
++    getjsonCmd5["CmdId"] = LOCK_CMD_ID_GSETTINGS_GET_SCREENSAVER_CONF;
++    getjsonCmd5["Key"] = KEY_VIDEO_SIZE;
++    QJsonParseError jsonParseError5;
++    const QJsonDocument jsonDoc5 = QJsonDocument::fromJson(
++        m_pDbusUpperInterfaceDbus->GetInformation(QString(QJsonDocument(getjsonCmd5).toJson())).toUtf8(),
++        &jsonParseError5);
++    QJsonObject objRes5 = jsonDoc5.object();
++    QVariant varValue5 = objRes5.value(KEY_VIDEO_SIZE);
++    QJsonObject jsonCmd5;
++    jsonCmd5["CmdId"] = LOCK_CMD_ID_GSETTINGS_SET_SCREENSAVER_CONF;
++    jsonCmd5["Content"] = varValue5.toDouble();
++    jsonCmd5["Key"] = KEY_VIDEO_SIZE;
++    m_pDbusUpperInterfaceDbus->SetInformation(QString(QJsonDocument(jsonCmd5).toJson()).toUtf8());
++
++    QJsonObject getjsonCmd6;
++    getjsonCmd6["CmdId"] = LOCK_CMD_ID_GSETTINGS_GET_POWERMANAGER_CONF;
++    getjsonCmd6["Key"] = KEY_SLEEP_COMPUTER_AC;
++    QJsonParseError jsonParseError6;
++    const QJsonDocument jsonDoc6 = QJsonDocument::fromJson(
++        m_pDbusUpperInterfaceDbus->GetInformation(QString(QJsonDocument(getjsonCmd6).toJson())).toUtf8(),
++        &jsonParseError6);
++    QJsonObject objRes6 = jsonDoc6.object();
++    QVariant varValue6 = objRes6.value(KEY_SLEEP_COMPUTER_AC);
++    QJsonObject jsonCmd6;
++    jsonCmd6["CmdId"] = LOCK_CMD_ID_GSETTINGS_SET_POWERMANAGER_CONF;
++    jsonCmd6["Content"] = varValue6.toDouble();
++    jsonCmd6["Key"] = KEY_SLEEP_COMPUTER_AC;
++    m_pDbusUpperInterfaceDbus->SetInformation(QString(QJsonDocument(jsonCmd6).toJson()).toUtf8());
++
++    QJsonObject getjsonCmd7;
++    getjsonCmd7["CmdId"] = LOCK_CMD_ID_GSETTINGS_GET_UKCCPLUGINS_CONF;
++    getjsonCmd7["Key"] = KEY_HOUR_SYSTEM;
++    QJsonParseError jsonParseError7;
++    const QJsonDocument jsonDoc7 = QJsonDocument::fromJson(
++        m_pDbusUpperInterfaceDbus->GetInformation(QString(QJsonDocument(getjsonCmd7).toJson())).toUtf8(),
++        &jsonParseError7);
++    QJsonObject objRes7 = jsonDoc7.object();
++    QVariant varValue7 = objRes7.value(KEY_HOUR_SYSTEM);
++    QJsonObject jsonCmd7;
++    jsonCmd7["CmdId"] = LOCK_CMD_ID_GSETTINGS_SET_UKCCPLUGINS_CONF;
++    jsonCmd7["Content"] = varValue7.toDouble();
++    jsonCmd7["Key"] = KEY_HOUR_SYSTEM;
++    m_pDbusUpperInterfaceDbus->SetInformation(QString(QJsonDocument(jsonCmd7).toJson()).toUtf8());
++
++    QJsonObject getjsonCmd8;
++    getjsonCmd8["CmdId"] = LOCK_CMD_ID_GSETTINGS_GET_THEMESTYLE_CONF;
++    getjsonCmd8["Key"] = KEY_SYSTEM_FONT_SIZE;
++    QJsonParseError jsonParseError8;
++    const QJsonDocument jsonDoc8 = QJsonDocument::fromJson(
++        m_pDbusUpperInterfaceDbus->GetInformation(QString(QJsonDocument(getjsonCmd8).toJson())).toUtf8(),
++        &jsonParseError8);
++    QJsonObject objRes8 = jsonDoc8.object();
++    QVariant varValue8 = objRes8.value(KEY_SYSTEM_FONT_SIZE);
++    QJsonObject jsonCmd8;
++    jsonCmd8["CmdId"] = LOCK_CMD_ID_GSETTINGS_SET_THEMESTYLE_CONF;
++    jsonCmd8["Content"] = varValue8.toDouble();
++    jsonCmd8["Key"] = KEY_SYSTEM_FONT_SIZE;
++    m_pDbusUpperInterfaceDbus->SetInformation(QString(QJsonDocument(jsonCmd8).toJson()).toUtf8());
++
++    QJsonObject getjsonCmd9;
++    getjsonCmd9["CmdId"] = LOCK_CMD_ID_GSETTINGS_GET_SESSION_CONF;
++    getjsonCmd9["Key"] = KEY_SESSION_IDLE;
++    QJsonParseError jsonParseError9;
++    const QJsonDocument jsonDoc9 = QJsonDocument::fromJson(
++        m_pDbusUpperInterfaceDbus->GetInformation(QString(QJsonDocument(getjsonCmd9).toJson())).toUtf8(),
++        &jsonParseError9);
++    QJsonObject objRes9 = jsonDoc9.object();
++    QVariant varValue9 = objRes9.value(KEY_SESSION_IDLE);
++    QJsonObject jsonCmd9;
++    jsonCmd9["CmdId"] = LOCK_CMD_ID_GSETTINGS_SET_SESSION_CONF;
++    jsonCmd9["Content"] = varValue9.toDouble();
++    jsonCmd9["Key"] = KEY_SESSION_IDLE;
++    m_pDbusUpperInterfaceDbus->SetInformation(QString(QJsonDocument(jsonCmd9).toJson()).toUtf8());
++
++    QJsonObject jsonCmd10;
++    jsonCmd10["CmdId"] = LOCK_CMD_ID_PAMAUTH_AUTHENTICATE;
++    jsonCmd10["Content"] = getenv("USER");
++    m_pDbusUpperInterfaceDbus->SetInformation(QString(QJsonDocument(jsonCmd10).toJson()).toUtf8());
++
++    QJsonObject jsonCmd11;
++    jsonCmd11["CmdId"] = LOCK_CMD_ID_PAMAUTH_RESPOND;
++    jsonCmd11["Content"] = "test";
++    m_pDbusUpperInterfaceDbus->SetInformation(QString(QJsonDocument(jsonCmd11).toJson()).toUtf8());
++
++    QJsonObject jsonCmd12;
++    jsonCmd12["CmdId"] = LOCK_CMD_ID_PAMAUTH_AUTHENTICATE_CANCEL;
++    //    jsonCmd12["Content"] = "test";
++    m_pDbusUpperInterfaceDbus->SetInformation(QString(QJsonDocument(jsonCmd12).toJson()).toUtf8());
++
++    QJsonObject jsonCmd13;
++    jsonCmd13["CmdId"] = LOCK_CMD_ID_USD_MEDIAKEYS;
++    jsonCmd13["Content"] = VOLUME_DOWN_KEY;
++    m_pDbusUpperInterfaceDbus->SetInformation(QString(QJsonDocument(jsonCmd13).toJson()).toUtf8());
++
++    QJsonObject jsonCmd14;
++    jsonCmd14["CmdId"] = LOCK_CMD_ID_LOGIN1_SET_POWER_MANAGER;
++    jsonCmd14["Content"] = "LockScreen";
++    m_pDbusUpperInterfaceDbus->SetInformation(QString(QJsonDocument(jsonCmd14).toJson()).toUtf8());
++
++    QJsonObject jsonCmd15;
++    jsonCmd15["CmdId"] = LOCK_CMD_ID_LOCK_STATE_CHANGED;
++    jsonCmd15["Content"] = false;
++    jsonCmd15["SessionTools"] = false;
++    m_pDbusUpperInterfaceDbus->SetInformation(QString(QJsonDocument(jsonCmd15).toJson()).toUtf8());
++
++    QJsonObject jsonCmd16;
++    jsonCmd16["CmdId"] = LOCK_CMD_ID_BIOAUTH_STARTAUTH;
++    jsonCmd16["UserId"] = 1000;
++    jsonCmd16["DevId"] = 101;
++    m_pDbusUpperInterfaceDbus->SetInformation(QString(QJsonDocument(jsonCmd16).toJson()).toUtf8());
++
++    QJsonObject jsonCmd17;
++    jsonCmd17["CmdId"] = LOCK_CMD_ID_BIOAUTH_STOPAUTH;
++    m_pDbusUpperInterfaceDbus->SetInformation(QString(QJsonDocument(jsonCmd17).toJson()).toUtf8());
++
++    QJsonObject jsonCmd18;
++    jsonCmd18["CmdId"] = LOCK_CMD_ID_KWIN_BLOCK_SHORTCUT;
++    jsonCmd18["Content"] = true;
++    m_pDbusUpperInterfaceDbus->SetInformation(QString(QJsonDocument(jsonCmd18).toJson()).toUtf8());
++
++    QJsonObject jsonCmd19;
++    jsonCmd19["CmdId"] = LOCK_CMD_ID_KWIN_BLOCK_SHORTCUT;
++    jsonCmd19["Content"] = false;
++    m_pDbusUpperInterfaceDbus->SetInformation(QString(QJsonDocument(jsonCmd19).toJson()).toUtf8());
++
++    QJsonObject getjsonCmd20;
++    getjsonCmd20["CmdId"] = LOCK_CMD_ID_GSETTINGS_GET_USD_MEDIA_STATE_KEYS_CONF;
++    getjsonCmd20["Key"] = KEY_RFKILL_STATE;
++    QJsonParseError jsonParseError20;
++    const QJsonDocument jsonDoc20 = QJsonDocument::fromJson(
++        m_pDbusUpperInterfaceDbus->GetInformation(QString(QJsonDocument(getjsonCmd20).toJson())).toUtf8(),
++        &jsonParseError20);
++    QJsonObject objRes20 = jsonDoc20.object();
++    QVariant varValue20 = objRes20.value(KEY_RFKILL_STATE);
++    QJsonObject jsonCmd20;
++    jsonCmd20["CmdId"] = LOCK_CMD_ID_GSETTINGS_SET_USD_MEDIA_STATE_KEYS_CONF;
++    jsonCmd20["Content"] = varValue20.toDouble();
++    jsonCmd20["Key"] = KEY_RFKILL_STATE;
++    m_pDbusUpperInterfaceDbus->SetInformation(QString(QJsonDocument(jsonCmd20).toJson()).toUtf8());
++}
+diff --git a/tests/unit_test_display_service/CMakeLists.txt b/tests/unit_test_display_service/CMakeLists.txt
+new file mode 100644
+index 0000000..ef6b96f
+--- /dev/null
++++ b/tests/unit_test_display_service/CMakeLists.txt
+@@ -0,0 +1,59 @@
++# CMake 最低版本要求
++cmake_minimum_required(VERSION 3.10)
++
++find_package(Qt5 COMPONENTS Core Gui DBus REQUIRED)
++
++# 包含 GTest 库和 pthread 库
++find_package(GTest REQUIRED)
++find_package(Threads REQUIRED)
++
++# 设置 C++ 标准
++set(CMAKE_CXX_STANDARD 17)
++set(CMAKE_CXX_STANDARD_REQUIRED ON)
++
++
++# 开启代码覆盖率相关编译选项(对应QMAKE_LFLAGS和QMAKE_CXXFLAGS中代码覆盖率相关设置)
++
++set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fprofile-arcs -ftest-coverage")
++set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fprofile-arcs -ftest-coverage")
++
++
++# 定义源文件列表,对应原来的SOURCES变量
++set(SOURCES
++    ../../src/common/displayservice.cpp
++    unit_test_display_service.cpp
++    main.cpp
++)
++
++# 定义头文件列表,对应原来的HEADERS变量
++set(HEADERS
++        ../../src/common/displayservice.h
++)
++
++# 包含头文件的路径设置,对应原来的INCLUDEPATH变量
++include_directories(
++    ${CMAKE_CURRENT_SOURCE_DIR}
++    ${CMAKE_CURRENT_SOURCE_DIR}/../kt-test-utils/cpp-stub
++    ${CMAKE_CURRENT_SOURCE_DIR}/../kt-test-utils/cpp-stub-ext
++)
++
++# 使用qt5_wrap_cpp生成元对象代码相关的源文件
++qt5_wrap_cpp(MOC_SOURCES ${HEADERS})
++
++# 添加可执行文件或库目标,将元对象代码源文件一起添加进去
++add_executable(unit_test_display_service ${SOURCES} ${MOC_SOURCES})
++
++# 链接Qt相关的库
++target_link_libraries(unit_test_display_service
++    Qt5::Core
++    Qt5::Gui
++    Qt5::DBus
++)
++
++# 链接 GTest 库
++target_link_libraries(unit_test_display_service
++    GTest::GTest
++    GTest::Main
++    Threads::Threads
++)
++
+diff --git a/tests/unit_test_display_service/main.cpp b/tests/unit_test_display_service/main.cpp
+new file mode 100644
+index 0000000..37b3fbf
+--- /dev/null
++++ b/tests/unit_test_display_service/main.cpp
+@@ -0,0 +1,12 @@
++#include <gtest/gtest.h>
++#include <QGuiApplication>
++
++
++int main(int argc, char **argv)
++{
++    QGuiApplication a(argc, argv);
++    testing::InitGoogleTest(&argc, argv);
++
++    return RUN_ALL_TESTS();
++}
++
+diff --git a/tests/unit_test_display_service/unit_test_display_service.cpp b/tests/unit_test_display_service/unit_test_display_service.cpp
+new file mode 100644
+index 0000000..493f0f3
+--- /dev/null
++++ b/tests/unit_test_display_service/unit_test_display_service.cpp
+@@ -0,0 +1,69 @@
++#include <gtest/gtest.h>
++
++#include "../../src/common/displayservice.h"
++
++class DisplayServiceTest : public testing::Test
++{
++protected:
++//    static void SetUpTestSuite()
++//    {
++//        m_pGSettingsHelperDbus = new GSettingsHelper();
++//    }
++
++//    static void TearDownTestSuite()
++//    {
++//        delete m_pGSettingsHelperDbus;
++//        m_pGSettingsHelperDbus = nullptr;
++//    }
++
++//    static GSettingsHelper *m_pGSettingsHelperDbus;
++};
++
++//GSettingsHelper *DisplayServiceTest::m_pGSettingsHelperDbus = nullptr;
++
++// 测试 switchDisplayMode 函数
++TEST_F(DisplayServiceTest, SwitchDisplayMode) {
++    // 测试 DISPLAY_MODE_ORI
++    bool value = DisplayService::instance()->switchDisplayMode(DISPLAY_MODE_ORI);
++    EXPECT_EQ(value, false);
++
++    // 测试 DISPLAY_MODE_CLONE
++    bool value1 = DisplayService::instance()->switchDisplayMode(DISPLAY_MODE_CLONE);
++    EXPECT_EQ(value1, false);
++
++    // 测试 DISPLAY_MODE_EXTEND
++    bool value2 = DisplayService::instance()->switchDisplayMode(DISPLAY_MODE_EXTEND);
++    EXPECT_EQ(value2, false);
++
++    // 测试 DISPLAY_MODE_ONLY_OUT
++    bool value3 = DisplayService::instance()->switchDisplayMode(DISPLAY_MODE_ONLY_OUT);
++    EXPECT_EQ(value3, false);
++}
++
++
++// 测试 setOneDisplayMode 函数
++TEST_F(DisplayServiceTest, SetOneDisplayMode) {
++    // 测试使用 xrandr
++    DisplayService::instance()->setOneDisplayMode();
++}
++
++
++// 测试 setCurUserName 函数
++TEST_F(DisplayServiceTest, SetCurUserName) {
++    DisplayService::instance()->setCurUserName(getenv("USER"));
++}
++
++
++// 测试 isSaveParamInUsed 函数
++TEST_F(DisplayServiceTest, IsSaveParamInUsed) {
++    EXPECT_TRUE(DisplayService::instance()->isSaveParamInUsed());
++
++    EXPECT_FALSE(DisplayService::instance()->isSaveParamInUsed());
++}
++
++
++// 测试 isJJW7200 函数
++TEST_F(DisplayServiceTest, IsJJW7200) {
++    int value = DisplayService::instance()->isJJW7200();
++    EXPECT_EQ(value, 0);
++}
+diff --git a/tests/unit_test_engine_device/CMakeLists.txt b/tests/unit_test_engine_device/CMakeLists.txt
+new file mode 100644
+index 0000000..c7b4631
+--- /dev/null
++++ b/tests/unit_test_engine_device/CMakeLists.txt
+@@ -0,0 +1,66 @@
++# CMake 最低版本要求
++cmake_minimum_required(VERSION 3.10)
++
++find_package(Qt5 COMPONENTS Core Gui DBus Test REQUIRED)
++find_package(PkgConfig REQUIRED)
++pkg_check_modules(QGS REQUIRED gsettings-qt)
++# 包含 GTest 库和 pthread 库
++find_package(GTest REQUIRED)
++find_package(Threads REQUIRED)
++
++# 设置 C++ 标准
++set(CMAKE_CXX_STANDARD 17)
++set(CMAKE_CXX_STANDARD_REQUIRED ON)
++
++
++# 开启代码覆盖率相关编译选项(对应QMAKE_LFLAGS和QMAKE_CXXFLAGS中代码覆盖率相关设置)
++set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fprofile-arcs -ftest-coverage --coverage -fno-inline -fno-access-control")
++set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fprofile-arcs -ftest-coverage")
++
++# 定义源文件列表,对应原来的SOURCES变量
++set(SOURCES
++    ../../src/dbusifs/enginedevice.cpp
++    ../../src/dbusifs/device.cpp
++    ../../src/dbusifs/upowerhelper.cpp
++    unit_test_engine_device.cpp
++    main.cpp
++)
++
++# 定义头文件列表,对应原来的HEADERS变量
++set(HEADERS
++        ../../src/dbusifs/enginedevice.h
++        ../../src/dbusifs/upowerhelper.h
++        ../../src/dbusifs/device.h
++)
++
++# 包含头文件的路径设置,对应原来的INCLUDEPATH变量
++include_directories(
++    ${CMAKE_CURRENT_SOURCE_DIR}
++    ${CMAKE_CURRENT_SOURCE_DIR}/../kt-test-utils/cpp-stub
++    ${CMAKE_CURRENT_SOURCE_DIR}/../kt-test-utils/cpp-stub-ext
++    ${QGS_INCLUDE_DIRS}
++    ${Qt5Test_INCLUDE_DIRS}
++)
++
++# 使用qt5_wrap_cpp生成元对象代码相关的源文件
++qt5_wrap_cpp(MOC_SOURCES ${HEADERS})
++
++# 添加可执行文件或库目标,将元对象代码源文件一起添加进去
++add_executable(unit_test_engine_device ${SOURCES} ${MOC_SOURCES})
++
++# 链接Qt相关的库
++target_link_libraries(unit_test_engine_device
++    Qt5::Core
++    Qt5::Gui
++    Qt5::DBus
++    Qt5::Test
++    ${QGS_LIBRARIES}
++)
++
++# 链接 GTest 库
++target_link_libraries(unit_test_engine_device
++    GTest::GTest
++    GTest::Main
++    Threads::Threads
++)
++
+diff --git a/tests/unit_test_engine_device/main.cpp b/tests/unit_test_engine_device/main.cpp
+new file mode 100644
+index 0000000..37b3fbf
+--- /dev/null
++++ b/tests/unit_test_engine_device/main.cpp
+@@ -0,0 +1,12 @@
++#include <gtest/gtest.h>
++#include <QGuiApplication>
++
++
++int main(int argc, char **argv)
++{
++    QGuiApplication a(argc, argv);
++    testing::InitGoogleTest(&argc, argv);
++
++    return RUN_ALL_TESTS();
++}
++
+diff --git a/tests/unit_test_engine_device/unit_test_engine_device.cpp b/tests/unit_test_engine_device/unit_test_engine_device.cpp
+new file mode 100644
+index 0000000..e48810c
+--- /dev/null
++++ b/tests/unit_test_engine_device/unit_test_engine_device.cpp
+@@ -0,0 +1,451 @@
++#include "../../src/dbusifs/enginedevice.h"
++#include "../../src/dbusifs/device.h"
++#include "../../src/dbusifs/upowerhelper.h"
++#include <gtest/gtest.h>
++#include <QDBusMessage>
++#include <QDBusConnection>
++#include <QDBusInterface>
++#include <QDBusConnectionInterface>
++#include <QVariant>
++#include <QList>
++#include <QObject>
++#include <QStringList>
++#include <QGSettings>
++#include <QDebug>
++#include <QCoreApplication>
++#include <QSignalSpy>
++
++#include "stubext.h"
++using namespace stub_ext;
++
++class EngineDeviceTest : public testing::Test
++{
++protected:
++    static void SetUpTestSuite()
++    {
++        m_pEngineDeviceDbus = new EngineDevice();
++    }
++
++    static void TearDownTestSuite()
++    {
++        delete m_pEngineDeviceDbus;
++        m_pEngineDeviceDbus = nullptr;
++    }
++
++    static EngineDevice *m_pEngineDeviceDbus;
++};
++
++EngineDevice *EngineDeviceTest::m_pEngineDeviceDbus = nullptr;
++
++
++// 测试 power_device_get_devices 函数
++TEST_F(EngineDeviceTest, power_device_get_devices) {
++    // 首先,确保 QDBus 服务正常运行,这里假设 QDBus 服务可以正常返回一些测试数据
++    m_pEngineDeviceDbus->power_device_get_devices();
++
++
++    // 检查 devices 列表是否不为空
++    EXPECT_GT(m_pEngineDeviceDbus->devices.size(), 0);
++
++
++    // 可以进一步检查 devices 列表中元素的属性,例如:
++    if (!m_pEngineDeviceDbus->devices.isEmpty()) {
++        DEVICE *device = m_pEngineDeviceDbus->devices.first();
++        EXPECT_FALSE(device->m_dev.path.isEmpty());
++    }
++}
++
++
++// 测试 getProperty 函数
++TEST_F(EngineDeviceTest, getProperty) {
++    DEV dev;
++    QString testPath = "/test/path";
++
++
++    // 这里假设 QDBus 服务会正常响应
++    m_pEngineDeviceDbus->getProperty(testPath, dev);
++
++
++    // 检查返回的属性是否符合预期
++    EXPECT_EQ(dev.kind, UP_DEVICE_KIND_UNKNOWN);  // 根据实际情况修改期望的结果
++    EXPECT_EQ(dev.Type, "");  // 根据实际情况修改期望的结果
++    EXPECT_EQ(dev.Model, "");  // 根据实际情况修改期望的结果
++    EXPECT_FALSE(dev.IsPresent);  // 根据实际情况修改期望的结果
++    EXPECT_EQ(dev.PowerSupply, "");  // 根据实际情况修改期望的结果
++    EXPECT_EQ(dev.Percentage, 0.0);  // 根据实际情况修改期望的结果
++    EXPECT_EQ(dev.Online, "");  // 根据实际情况修改期望的结果
++    EXPECT_EQ(dev.State, UP_DEVICE_STATE_UNKNOWN);  // 根据实际情况修改期望的结果
++    EXPECT_EQ(dev.TimeToEmpty, 0);  // 根据实际情况修改期望的结果
++    EXPECT_EQ(dev.TimeToFull, 0);  // 根据实际情况修改期望的结果
++}
++
++
++// 测试 boolToString 函数
++TEST_F(EngineDeviceTest, boolToString) {
++    EXPECT_EQ(m_pEngineDeviceDbus->boolToString(true), "yes");
++    EXPECT_EQ(m_pEngineDeviceDbus->boolToString(false), "no");
++}
++
++
++// 测试 putAttributes 函数
++TEST_F(EngineDeviceTest, putAttributes) {
++    QMap<QString, QVariant> map;
++    map["TimeToFull"] = QVariant(200);
++    map["TimeToEmpty"] = QVariant(100);
++    map["State"] = QVariant(2);
++    map["Percentage"] = QVariant(50.0);
++    map["PowerSupply"] = QVariant(true);
++    map["IsPresent"] = QVariant(true);
++
++
++    DEV btrDetailData;
++    m_pEngineDeviceDbus->putAttributes(map, btrDetailData);
++
++
++    EXPECT_EQ(btrDetailData.TimeToFull, 200);
++    EXPECT_EQ(btrDetailData.TimeToEmpty, 100);
++    EXPECT_EQ(btrDetailData.State, 2);
++    EXPECT_EQ(btrDetailData.Percentage, 5.0);
++    EXPECT_EQ(btrDetailData.PowerSupply, "Yes");
++    EXPECT_EQ(btrDetailData.IsPresent, true);
++}
++
++
++// 测试 power_device_change_callback 函数
++TEST_F(EngineDeviceTest, power_device_change_callback) {
++//    DEVICE *device = new DEVICE;
++//    device->m_dev.path = "/test/path";
++//    engineDevice->devices.append(device);
++//    QDBusMessage msg = QDBusMessage::createMethodCall(DBUS_SERVICE, "/test/path", DBUS_INTERFACE_PRO, "PropertiesChanged");
++//    msg.setArguments({ QVariant("interface"), QVariant::fromValue(QDBusArgument::fromVariantMap({
++//        { "TimeToFull", QVariant(300) }
++//    })) });
++//    engineDevice->power_device_change_callback(msg, "/test/path");
++//    EXPECT_EQ(device->m_dev.TimeToFull, 300);
++//    delete device;
++}
++
++
++// 测试 power_device_recalculate_state 函数
++TEST_F(EngineDeviceTest, power_device_recalculate_state) {
++    // 准备一些测试数据
++    DEVICE *device = new DEVICE;
++    device->m_dev.IsPresent = true;
++    device->m_dev.kind = UP_DEVICE_KIND_BATTERY;
++    device->m_dev.State = UP_DEVICE_STATE_CHARGING;
++    m_pEngineDeviceDbus->devices.append(device);
++
++
++    // 使用 QSignalSpy 监听信号
++//    QSignalSpy summarySpy(m_pEngineDeviceDbus->get(), SIGNAL(engine_signal_summary_change(QString)));
++//    QSignalSpy stateSpy(m_pEngineDeviceDbus->get(), SIGNAL(engine_signal_Battery_State(QStringList)));
++
++
++    m_pEngineDeviceDbus->power_device_recalculate_state();
++
++
++    // 检查信号是否触发
++//    EXPECT_EQ(summarySpy.count(), 1);
++//    EXPECT_EQ(stateSpy.count(), 1);
++
++
++    delete device;
++}
++
++
++// 测试 engine_recalculate_summary 函数
++TEST_F(EngineDeviceTest, engine_recalculate_summary) {
++    // 准备一些测试数据
++    DEVICE *device = new DEVICE;
++    device->m_dev.IsPresent = true;
++    device->m_dev.kind = UP_DEVICE_KIND_BATTERY;
++    device->m_dev.State = UP_DEVICE_STATE_CHARGING;
++    m_pEngineDeviceDbus->devices.append(device);
++
++
++    // 使用 QSignalSpy 监听信号
++//    QSignalSpy summarySpy(m_pEngineDeviceDbus->get(), SIGNAL(engine_signal_summary_change(QString)));
++//    QSignalSpy stateSpy(m_pEngineDeviceDbus->get(), SIGNAL(engine_signal_Battery_State(QStringList)));
++
++
++    bool result = m_pEngineDeviceDbus->engine_recalculate_summary();
++
++
++    // 检查函数返回值和信号触发情况
++    EXPECT_TRUE(result);
++//    EXPECT_EQ(summarySpy.count(), 1);
++//    EXPECT_EQ(stateSpy.count(), 1);
++
++
++    delete device;
++}
++
++
++// 测试 engine_get_state 函数
++TEST_F(EngineDeviceTest, engine_get_state) {
++    // 准备一些测试数据
++    DEVICE *device = new DEVICE;
++    device->m_dev.IsPresent = true;
++    device->m_dev.kind = UP_DEVICE_KIND_BATTERY;
++    device->m_dev.State = UP_DEVICE_STATE_CHARGING;
++    m_pEngineDeviceDbus->devices.append(device);
++    QStringList stateList = m_pEngineDeviceDbus->engine_get_state();
++    // 检查返回的状态列表是否符合预期
++    EXPECT_FALSE(stateList.isEmpty());
++    delete device;
++}
++
++
++// 测试 engine_get_Battery_State 函数
++TEST_F(EngineDeviceTest, engine_get_Battery_State) {
++    DEVICE *device = new DEVICE;
++    device->m_dev.IsPresent = true;
++    device->m_dev.kind = UP_DEVICE_KIND_BATTERY;
++    device->m_dev.State = UP_DEVICE_STATE_CHARGING;
++    device->m_dev.Percentage = 50.0;
++    device->m_dev.TimeToEmpty = 100;
++    QStringList stateList = m_pEngineDeviceDbus->engine_get_Battery_State(device);
++    // 检查返回的状态列表元素是否符合预期
++    EXPECT_EQ(stateList.size(), 3);
++    EXPECT_EQ(stateList[0], "50");
++    EXPECT_EQ(stateList[1], QString::number(UP_DEVICE_STATE_CHARGING));
++    EXPECT_EQ(stateList[2], "100");
++
++
++    delete device;
++}
++
++
++// 测试 engine_get_summary 函数
++TEST_F(EngineDeviceTest, engine_get_summary) {
++    // 准备一些测试数据
++    DEVICE *device = new DEVICE;
++    device->m_dev.IsPresent = true;
++    device->m_dev.kind = UP_DEVICE_KIND_BATTERY;
++    device->m_dev.State = UP_DEVICE_STATE_CHARGING;
++    device->m_dev.Percentage = 50.0;
++    device->m_dev.TimeToEmpty = 100;
++    m_pEngineDeviceDbus->devices.append(device);
++    QString summary = m_pEngineDeviceDbus->engine_get_summary();
++    // 检查返回的摘要是否符合预期
++    EXPECT_FALSE(summary.isEmpty());
++
++
++    delete device;
++}
++
++
++// 测试 engine_get_device_summary 函数
++TEST_F(EngineDeviceTest, engine_get_device_summary) {
++    // 准备一些测试数据
++    DEVICE *device = new DEVICE;
++    device->m_dev.IsPresent = true;
++    device->m_dev.kind = UP_DEVICE_KIND_BATTERY;
++    device->m_dev.State = UP_DEVICE_STATE_CHARGING;
++    device->m_dev.Percentage = 50.0;
++    device->m_dev.TimeToEmpty = 100;
++    QString summary = m_pEngineDeviceDbus->engine_get_device_summary(device);
++    // 检查返回的摘要是否符合预期
++    EXPECT_FALSE(summary.isEmpty());
++
++
++    delete device;
++}
++
++
++// 测试 engine_kind_to_localised_text 函数
++TEST_F(EngineDeviceTest, engine_kind_to_localised_text) {
++    EXPECT_EQ(m_pEngineDeviceDbus->engine_kind_to_localised_text(UP_DEVICE_KIND_LINE_POWER, 0), "AC adapter");
++    EXPECT_EQ(m_pEngineDeviceDbus->engine_kind_to_localised_text(UP_DEVICE_KIND_BATTERY, 0), "Laptop battery");
++    // 测试其他枚举值
++}
++
++const static QString upowerService = QStringLiteral("org.freedesktop.UPower");
++const static QString upowerPath = QStringLiteral("/org/freedesktop/UPower");
++const static QString upowerInterface = QStringLiteral("org.freedesktop.UPower");
++const static QString propertiesInterface = QStringLiteral("org.freedesktop.DBus.Properties");
++const static QString upowerDisplayPath = QStringLiteral("/org/freedesktop/UPower/devices/DisplayDevice");
++const static QString upowerDeviceInterface = QStringLiteral("org.freedesktop.UPower.Device");
++
++// 测试 UpowerHelper 类
++class UpowerHelperTest : public ::testing::Test {
++protected:
++    std::unique_ptr<UpowerHelper> upowerHelper;
++    std::unique_ptr<EngineDevice> engineDevice;
++
++
++    void SetUp() override {
++        engineDevice = std::make_unique<EngineDevice>();
++        upowerHelper = std::make_unique<UpowerHelper>(nullptr);
++        upowerHelper->m_engineDevice = engineDevice.get();
++    }
++
++
++    void TearDown() override {
++        upowerHelper.reset();
++        engineDevice.reset();
++    }
++};
++
++
++// 测试 UpowerHelper 构造函数中的 DBus 连接和属性初始化
++TEST_F(UpowerHelperTest, UpowerHelperConstructor) {
++    // 检查 m_upowerService 是否有效
++    EXPECT_TRUE(upowerHelper->m_upowerService->isValid());
++
++
++    // 检查 m_upowerInterface 是否有效
++    EXPECT_TRUE(upowerHelper->m_upowerInterface->isValid());
++
++
++    // 检查是否正确连接了信号
++//    QDBusConnectionInterface *connectionInterface = QDBusConnection::systemBus().interface();
++//    bool isConnected = connectionInterface->isConnected(upowerService, upowerPath, propertiesInterface, "PropertiesChanged", upowerHelper.get());
++//    EXPECT_TRUE(isConnected);
++
++
++    // 检查 m_isBattery 的初始化
++    QDBusReply<QVariant> interfaceReply = upowerHelper->m_upowerInterface->call("Get", "org.freedesktop.UPower", "LidIsPresent");
++    bool expectedIsBattery = interfaceReply.isValid()? interfaceReply.value().toBool() : false;
++    EXPECT_EQ(upowerHelper->m_isBattery, expectedIsBattery);
++
++
++    // 检查是否正确连接了电池设备的信号
++//    if (!upowerHelper->m_batInterface.isNull()) {
++//        isConnected = connectionInterface->isConnected(upowerService, upowerHelper->m_batInterface->path(), propertiesInterface, "PropertiesChanged", upowerHelper.get());
++//        EXPECT_TRUE(isConnected);
++//    }
++
++
++    // 检查是否正确连接了 EngineDevice 的信号
++    bool isSignalConnected = QObject::connect(engineDevice.get(), &EngineDevice::engine_signal_Battery_State, upowerHelper.get(), &UpowerHelper::onBatteryChanged);
++    EXPECT_TRUE(isSignalConnected);
++}
++
++
++// 测试 getBatteryIconName 函数
++TEST_F(UpowerHelperTest, GetBatteryIconName) {
++    // 模拟电池状态和百分比
++    upowerHelper->m_upowerInterface->setProperty("OnBattery", QVariant(true));
++    upowerHelper->m_batInterface->setProperty("Percentage", QVariant(50.0));
++
++
++    QString iconName = upowerHelper->getBatteryIconName();
++    EXPECT_EQ(iconName, "battery-level-50-symbolic");
++
++
++    upowerHelper->m_upowerInterface->setProperty("OnBattery", QVariant(false));
++    iconName = upowerHelper->getBatteryIconName();
++    EXPECT_EQ(iconName, "battery-level-50-charging-symbolic");
++
++
++    // 测试异常情况,如百分比为负数
++    upowerHelper->m_batInterface->setProperty("Percentage", QVariant(-10.0));
++    iconName = upowerHelper->getBatteryIconName();
++    EXPECT_EQ(iconName, "battery-level--10-symbolic");
++
++
++    // 测试无效的 DBus 接口
++//    upowerHelper->m_upowerService->setValid(false);
++    iconName = upowerHelper->getBatteryIconName();
++    EXPECT_EQ(iconName, QString());
++}
++
++
++// 测试 getBatteryArgs 函数
++TEST_F(UpowerHelperTest, GetBatteryArgs) {
++    // 模拟 engineDevice 的状态
++    DEVICE device;
++    device.m_dev.IsPresent = true;
++    device.m_dev.kind = UP_DEVICE_KIND_BATTERY;
++    device.m_dev.State = UP_DEVICE_STATE_CHARGING;
++    engineDevice->devices.append(&device);
++
++
++    QStringList args = upowerHelper->getBatteryArgs();
++
++
++    // 检查是否调用了 engine_get_state 并得到了正确的结果
++    EXPECT_FALSE(args.isEmpty());
++
++
++    // 测试 engineDevice 为空的情况
++    upowerHelper->m_engineDevice = nullptr;
++    args = upowerHelper->getBatteryArgs();
++    EXPECT_TRUE(args.isEmpty());
++}
++
++
++// 测试 onBatteryChanged 函数
++TEST_F(UpowerHelperTest, OnBatteryChanged) {
++    QStringList args = {"arg1", "arg2"};
++
++
++    // 使用 QSignalSpy 监听 batteryChanged 信号
++    QSignalSpy spy(upowerHelper.get(), SIGNAL(batteryChanged(QStringList)));
++
++
++    upowerHelper->onBatteryChanged(args);
++
++
++//     检查信号是否正确触发
++    EXPECT_EQ(spy.count(), 1);
++    EXPECT_EQ(spy[0][0].toStringList(), args);
++}
++
++
++// 测试 dealMessage 函数
++TEST_F(UpowerHelperTest, DealMessage) {
++    // 使用 QSignalSpy 监听 batteryStatusChanged 信号
++    QSignalSpy spy(upowerHelper.get(), SIGNAL(batteryStatusChanged(QString)));
++
++
++    QDBusMessage message;
++
++
++    upowerHelper->dealMessage(message);
++
++
++//    // 检查信号是否正确触发
++    EXPECT_EQ(spy.count(), 1);
++
++
++    // 测试信号传递的参数
++    upowerHelper->m_upowerService->setProperty("OnBattery", QVariant(true));
++    upowerHelper->m_batInterface->setProperty("Percentage", QVariant(30.0));
++    upowerHelper->dealMessage(message);
++    EXPECT_EQ(spy[1][0].toString(), "battery-level-30-symbolic");
++}
++
++
++// 测试 onLidWatcherMessage 函数
++TEST_F(UpowerHelperTest, OnLidWatcherMessage) {
++    // 使用 QSignalSpy 监听 lidStateChanged 信号
++    QSignalSpy spy(upowerHelper.get(), SIGNAL(lidStateChanged(bool)));
++
++
++    QDBusMessage message;
++
++
++    upowerHelper->onLidWatcherMessage();
++
++
++    // 检查信号是否正确触发
++    EXPECT_EQ(spy.count(), 1);
++
++
++    // 测试信号传递的参数
++    QDBusInterface iface(upowerService, upowerPath, propertiesInterface, QDBusConnection::systemBus());
++    iface.setProperty("LidIsClosed", QVariant(true));
++    upowerHelper->onLidWatcherMessage();
++    EXPECT_EQ(spy[1][0].toBool(), true);
++
++
++    iface.setProperty("LidIsClosed", QVariant(false));
++    upowerHelper->onLidWatcherMessage();
++    EXPECT_EQ(spy[2][0].toBool(), false);
++}
++
++
++
++
+diff --git a/tests/unit_test_freedesktop_helper/CMakeLists.txt b/tests/unit_test_freedesktop_helper/CMakeLists.txt
+new file mode 100644
+index 0000000..2ad8965
+--- /dev/null
++++ b/tests/unit_test_freedesktop_helper/CMakeLists.txt
+@@ -0,0 +1,58 @@
++# CMake 最低版本要求
++cmake_minimum_required(VERSION 3.10)
++
++find_package(Qt5 COMPONENTS Core Gui DBus REQUIRED)
++
++# 包含 GTest 库和 pthread 库
++find_package(GTest REQUIRED)
++find_package(Threads REQUIRED)
++
++# 设置 C++ 标准
++set(CMAKE_CXX_STANDARD 17)
++set(CMAKE_CXX_STANDARD_REQUIRED ON)
++
++
++# 开启代码覆盖率相关编译选项(对应QMAKE_LFLAGS和QMAKE_CXXFLAGS中代码覆盖率相关设置)
++set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fprofile-arcs -ftest-coverage --coverage -fno-inline -fno-access-control")
++set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fprofile-arcs -ftest-coverage")
++
++# 定义源文件列表,对应原来的SOURCES变量
++set(SOURCES
++    ../../src/dbusifs/freedesktophelper.cpp
++    unit_test_freedesktop_helper.cpp
++    main.cpp
++)
++
++# 定义头文件列表,对应原来的HEADERS变量
++set(HEADERS
++        ../../src/common/definetypes.h
++        ../../src/dbusifs/freedesktophelper.h
++)
++
++# 包含头文件的路径设置,对应原来的INCLUDEPATH变量
++include_directories(
++    ${CMAKE_CURRENT_SOURCE_DIR}
++    ${CMAKE_CURRENT_SOURCE_DIR}/../kt-test-utils/cpp-stub
++    ${CMAKE_CURRENT_SOURCE_DIR}/../kt-test-utils/cpp-stub-ext
++)
++
++# 使用qt5_wrap_cpp生成元对象代码相关的源文件
++qt5_wrap_cpp(MOC_SOURCES ${HEADERS})
++
++# 添加可执行文件或库目标,将元对象代码源文件一起添加进去
++add_executable(unit_test_freedesktop_helper ${SOURCES} ${MOC_SOURCES})
++
++# 链接Qt相关的库
++target_link_libraries(unit_test_freedesktop_helper
++    Qt5::Core
++    Qt5::Gui
++    Qt5::DBus
++)
++
++# 链接 GTest 库
++target_link_libraries(unit_test_freedesktop_helper
++    GTest::GTest
++    GTest::Main
++    Threads::Threads
++)
++
+diff --git a/tests/unit_test_freedesktop_helper/main.cpp b/tests/unit_test_freedesktop_helper/main.cpp
+new file mode 100644
+index 0000000..37b3fbf
+--- /dev/null
++++ b/tests/unit_test_freedesktop_helper/main.cpp
+@@ -0,0 +1,12 @@
++#include <gtest/gtest.h>
++#include <QGuiApplication>
++
++
++int main(int argc, char **argv)
++{
++    QGuiApplication a(argc, argv);
++    testing::InitGoogleTest(&argc, argv);
++
++    return RUN_ALL_TESTS();
++}
++
+diff --git a/tests/unit_test_freedesktop_helper/unit_test_freedesktop_helper.cpp b/tests/unit_test_freedesktop_helper/unit_test_freedesktop_helper.cpp
+new file mode 100644
+index 0000000..d355a17
+--- /dev/null
++++ b/tests/unit_test_freedesktop_helper/unit_test_freedesktop_helper.cpp
+@@ -0,0 +1,38 @@
++#include <gtest/gtest.h>
++#include <gtest/gtest-death-test.h>
++
++#include "../../src/dbusifs/freedesktophelper.h"
++
++#include "stubext.h"
++using namespace stub_ext;
++
++class FreedesktopHelperTest : public testing::Test
++{
++protected:
++    static void SetUpTestSuite()
++    {
++        m_pFreedesktopHelperDbus = new FreedesktopHelper();
++    }
++
++    static void TearDownTestSuite()
++    {
++        delete m_pFreedesktopHelperDbus;
++        m_pFreedesktopHelperDbus = nullptr;
++    }
++
++    static FreedesktopHelper *m_pFreedesktopHelperDbus;
++};
++
++FreedesktopHelper *FreedesktopHelperTest::m_pFreedesktopHelperDbus = nullptr;
++
++TEST_F(FreedesktopHelperTest, NameHasOwner)
++{
++    bool value = m_pFreedesktopHelperDbus->NameHasOwner("org.ukui.Biometric");
++    ASSERT_EQ(value, false);
++}
++
++TEST_F(FreedesktopHelperTest, isServiceActivable)
++{
++    bool value = m_pFreedesktopHelperDbus->isServiceActivable("org.ukui.UniauthBackend");
++    ASSERT_EQ(value, false);
++}
+diff --git a/tests/unit_test_gsettings_helper/CMakeLists.txt b/tests/unit_test_gsettings_helper/CMakeLists.txt
+new file mode 100644
+index 0000000..0c8fcfa
+--- /dev/null
++++ b/tests/unit_test_gsettings_helper/CMakeLists.txt
+@@ -0,0 +1,63 @@
++# CMake 最低版本要求
++cmake_minimum_required(VERSION 3.10)
++
++find_package(Qt5 COMPONENTS Core Gui DBus REQUIRED)
++find_package(PkgConfig REQUIRED)
++pkg_check_modules(QGS REQUIRED gsettings-qt)
++
++# 包含 GTest 库和 pthread 库
++find_package(GTest REQUIRED)
++find_package(Threads REQUIRED)
++
++# 设置 C++ 标准
++set(CMAKE_CXX_STANDARD 17)
++set(CMAKE_CXX_STANDARD_REQUIRED ON)
++
++
++# 开启代码覆盖率相关编译选项(对应QMAKE_LFLAGS和QMAKE_CXXFLAGS中代码覆盖率相关设置)
++
++set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fprofile-arcs -ftest-coverage")
++set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fprofile-arcs -ftest-coverage")
++
++
++# 定义源文件列表,对应原来的SOURCES变量
++set(SOURCES
++    ../../src/lock-backend/gsettingshelper.cpp
++    unit_test_gsettings_helper.cpp
++    main.cpp
++)
++
++# 定义头文件列表,对应原来的HEADERS变量
++set(HEADERS
++    ../../src/common/definetypes.h
++    ../../src/lock-backend/gsettingshelper.h
++)
++
++# 包含头文件的路径设置,对应原来的INCLUDEPATH变量
++include_directories(
++    ${CMAKE_CURRENT_SOURCE_DIR}
++    ${CMAKE_CURRENT_SOURCE_DIR}/../kt-test-utils/cpp-stub
++    ${CMAKE_CURRENT_SOURCE_DIR}/../kt-test-utils/cpp-stub-ext
++    ${QGS_INCLUDE_DIRS}
++)
++
++# 使用qt5_wrap_cpp生成元对象代码相关的源文件
++qt5_wrap_cpp(MOC_SOURCES ${HEADERS})
++
++# 添加可执行文件或库目标,将元对象代码源文件一起添加进去
++add_executable(unit_test_gsettings_helper ${SOURCES} ${MOC_SOURCES})
++
++# 链接Qt相关的库
++target_link_libraries(unit_test_gsettings_helper
++    Qt5::Core
++    Qt5::Gui
++    Qt5::DBus
++    ${QGS_LIBRARIES}
++)
++
++# 链接 GTest 库
++target_link_libraries(unit_test_gsettings_helper
++    GTest::GTest
++    GTest::Main
++    Threads::Threads
++)
+diff --git a/tests/unit_test_gsettings_helper/main.cpp b/tests/unit_test_gsettings_helper/main.cpp
+new file mode 100644
+index 0000000..37b3fbf
+--- /dev/null
++++ b/tests/unit_test_gsettings_helper/main.cpp
+@@ -0,0 +1,12 @@
++#include <gtest/gtest.h>
++#include <QGuiApplication>
++
++
++int main(int argc, char **argv)
++{
++    QGuiApplication a(argc, argv);
++    testing::InitGoogleTest(&argc, argv);
++
++    return RUN_ALL_TESTS();
++}
++
+diff --git a/tests/unit_test_gsettings_helper/unit_test_gsettings_helper.cpp b/tests/unit_test_gsettings_helper/unit_test_gsettings_helper.cpp
+new file mode 100644
+index 0000000..ed02904
+--- /dev/null
++++ b/tests/unit_test_gsettings_helper/unit_test_gsettings_helper.cpp
+@@ -0,0 +1,437 @@
++#include <gtest/gtest.h>
++#include <gtest/gtest-death-test.h>
++
++#include "../../src/lock-backend/gsettingshelper.h"
++#include "../../src/common/definetypes.h"
++
++#include "stubext.h"
++
++using namespace stub_ext;
++
++class GSettingsHelperTest : public testing::Test
++{
++protected:
++    static void SetUpTestSuite()
++    {
++        m_pGSettingsHelperDbus = new GSettingsHelper();
++    }
++
++    static void TearDownTestSuite()
++    {
++        delete m_pGSettingsHelperDbus;
++        m_pGSettingsHelperDbus = nullptr;
++    }
++
++    static GSettingsHelper *m_pGSettingsHelperDbus;
++};
++
++GSettingsHelper *GSettingsHelperTest::m_pGSettingsHelperDbus = nullptr;
++
++TEST_F(GSettingsHelperTest, GetScreenSaverConf)
++{
++    QVariant result1 = m_pGSettingsHelperDbus->GetScreenSaverConf(KEY_SHOW_REST_TIME);
++    bool value1 = result1.toBool();
++    m_pGSettingsHelperDbus->onScreenSaverConfigChanged(KEY_SHOW_REST_TIME);
++
++    QVariant result2 = m_pGSettingsHelperDbus->GetScreenSaverConf(KEY_SHOW_CUSTOM_REST_TIME);
++    bool value2 = result2.toBool();
++    m_pGSettingsHelperDbus->onScreenSaverConfigChanged(KEY_SHOW_CUSTOM_REST_TIME);
++
++    QVariant result3 = m_pGSettingsHelperDbus->GetScreenSaverConf(KEY_SHOW_UKUI_REST_TIME);
++    bool value3 = result3.toBool();
++    m_pGSettingsHelperDbus->onScreenSaverConfigChanged(KEY_SHOW_UKUI_REST_TIME);
++
++    QVariant result4 = m_pGSettingsHelperDbus->GetScreenSaverConf(KEY_CYCLE_TIME);
++    int value4 = result4.toInt();
++    m_pGSettingsHelperDbus->onScreenSaverConfigChanged(KEY_CYCLE_TIME);
++
++    QVariant result5 = m_pGSettingsHelperDbus->GetScreenSaverConf(KEY_AUTOMATIC_SWITCHING_ENABLE);
++    bool value5 = result5.toBool();
++    m_pGSettingsHelperDbus->onScreenSaverConfigChanged(KEY_AUTOMATIC_SWITCHING_ENABLE);
++
++    QVariant result6 = m_pGSettingsHelperDbus->GetScreenSaverConf(KEY_BACKGROUND_PATH);
++    QString value6 = result6.toString();
++    m_pGSettingsHelperDbus->onScreenSaverConfigChanged(KEY_BACKGROUND_PATH);
++
++    QVariant result7 = m_pGSettingsHelperDbus->GetScreenSaverConf(KEY_MYTEXT);
++    QString value7 = result7.toString();
++    m_pGSettingsHelperDbus->onScreenSaverConfigChanged(KEY_MYTEXT);
++
++    QVariant result8 = m_pGSettingsHelperDbus->GetScreenSaverConf(KEY_TEXT_IS_CENTER);
++    bool value8 = result8.toBool();
++    m_pGSettingsHelperDbus->onScreenSaverConfigChanged(KEY_TEXT_IS_CENTER);
++
++    QVariant result9 = m_pGSettingsHelperDbus->GetScreenSaverConf(KEY_SHOW_MESSAGE_ENABLED);
++    bool value9 = result9.toBool();
++
++    QVariant result10 = m_pGSettingsHelperDbus->GetScreenSaverConf(KEY_MESSAGE_NUMBER);
++    int value10 = result10.toInt();
++
++    QVariant result11 = m_pGSettingsHelperDbus->GetScreenSaverConf(KEY_VIDEO_FORMAT);
++    QString value11 = result11.toString();
++    m_pGSettingsHelperDbus->onScreenSaverConfigChanged(KEY_VIDEO_FORMAT);
++
++    QVariant result12 = m_pGSettingsHelperDbus->GetScreenSaverConf(KEY_VIDEO_PATH);
++    QString value12 = result12.toString();
++    m_pGSettingsHelperDbus->onScreenSaverConfigChanged(KEY_VIDEO_PATH);
++
++    QVariant result13 = m_pGSettingsHelperDbus->GetScreenSaverConf(KEY_VIDEO_SIZE);
++    int value13 = result13.toInt();
++    m_pGSettingsHelperDbus->onScreenSaverConfigChanged(KEY_VIDEO_SIZE);
++
++    QVariant result14 = m_pGSettingsHelperDbus->GetScreenSaverConf(KEY_VIDEO_WIDTH);
++    int value14 = result14.toInt();
++    m_pGSettingsHelperDbus->onScreenSaverConfigChanged(KEY_VIDEO_WIDTH);
++
++    QVariant result15 = m_pGSettingsHelperDbus->GetScreenSaverConf(KEY_VIDEO_HEIGHT);
++    int value15 = result15.toInt();
++    m_pGSettingsHelperDbus->onScreenSaverConfigChanged(KEY_VIDEO_HEIGHT);
++
++    ASSERT_EQ(value1, true);
++    ASSERT_EQ(value2, true);
++    ASSERT_EQ(value3, true);
++    ASSERT_EQ(value4, 300);
++    ASSERT_EQ(value5, false);
++    ASSERT_EQ(value6.isEmpty(), false);
++    ASSERT_EQ(value7.isEmpty(), true);
++    ASSERT_EQ(value8, true);
++    ASSERT_EQ(value9, false);
++    ASSERT_EQ(value10, 0);
++    ASSERT_EQ(value11.isEmpty(), false);
++    ASSERT_EQ(value12.isEmpty(), false);
++    ASSERT_EQ(value13, 100);
++    ASSERT_EQ(value14, 1920);
++    ASSERT_EQ(value15, 1080);
++}
++
++TEST_F(GSettingsHelperTest, SetScreenSaverConf)
++{
++    QVariant result = m_pGSettingsHelperDbus->GetScreenSaverConf(KEY_SHOW_REST_TIME);
++    bool oldValue = result.toBool();
++
++    bool value = m_pGSettingsHelperDbus->SetScreenSaverConf(KEY_SHOW_REST_TIME, true);
++
++    m_pGSettingsHelperDbus->SetScreenSaverConf(KEY_SHOW_REST_TIME, oldValue);
++
++    ASSERT_EQ(value, true);
++}
++
++TEST_F(GSettingsHelperTest, GetLockScreenConf)
++{
++    QVariant result1 = m_pGSettingsHelperDbus->GetLockScreenConf(KEY_IDLE_DELAY);
++    int value1 = result1.toInt();
++    m_pGSettingsHelperDbus->onLockScreenConfigChanged(KEY_IDLE_DELAY);
++
++    QVariant result2 = m_pGSettingsHelperDbus->GetLockScreenConf(KEY_IDLE_LOCK);
++    int value2 = result2.toInt();
++    m_pGSettingsHelperDbus->onLockScreenConfigChanged(KEY_IDLE_LOCK);
++
++    QVariant result3 = m_pGSettingsHelperDbus->GetLockScreenConf(KEY_IDLE_LOCK);
++    bool value3 = result3.toBool();
++    m_pGSettingsHelperDbus->onLockScreenConfigChanged(KEY_IDLE_LOCK);
++
++    QVariant result4 = m_pGSettingsHelperDbus->GetLockScreenConf(KEY_IDLE_LOCK);
++    bool value4 = result4.toBool();
++    m_pGSettingsHelperDbus->onLockScreenConfigChanged(KEY_IDLE_LOCK);
++
++    QVariant result5 = m_pGSettingsHelperDbus->GetLockScreenConf(KEY_IDLE_LOCK);
++    int value5 = result5.toInt();
++    m_pGSettingsHelperDbus->onLockScreenConfigChanged(KEY_IDLE_LOCK);
++
++    QVariant result6 = m_pGSettingsHelperDbus->GetLockScreenConf(KEY_IDLE_LOCK);
++    bool value6 = result6.toBool();
++    m_pGSettingsHelperDbus->onLockScreenConfigChanged(KEY_IDLE_LOCK);
++
++    QVariant result7 = m_pGSettingsHelperDbus->GetLockScreenConf(KEY_SLEEP_ACTIVATION_ENABLED);
++    bool value7 = result7.toBool();
++    m_pGSettingsHelperDbus->onLockScreenConfigChanged(KEY_SLEEP_ACTIVATION_ENABLED);
++
++    QVariant result8 = m_pGSettingsHelperDbus->GetLockScreenConf(KEY_LOCK_ENABLED);
++    bool value8 = result8.toBool();
++    m_pGSettingsHelperDbus->onLockScreenConfigChanged(KEY_LOCK_ENABLED);
++
++    QVariant result9 = m_pGSettingsHelperDbus->GetLockScreenConf(KEY_BACKGROUND);
++    QString value9 = result9.toString();
++    m_pGSettingsHelperDbus->onLockScreenConfigChanged(KEY_BACKGROUND);
++
++    QVariant result10 = m_pGSettingsHelperDbus->GetLockScreenConf(KEY_MODE);
++    QString value10 = result10.toString();
++    m_pGSettingsHelperDbus->onLockScreenConfigChanged(KEY_MODE);
++
++    QVariant result11 = m_pGSettingsHelperDbus->GetLockScreenConf(KEY_THEMES);
++    QStringList value11 = result11.toStringList();
++    m_pGSettingsHelperDbus->onLockScreenConfigChanged(KEY_THEMES);
++
++    QVariant result12 = m_pGSettingsHelperDbus->GetLockScreenConf(KEY_IMAGE_TRANSITION_EFFECT);
++    int value12 = result12.toInt();
++    m_pGSettingsHelperDbus->onLockScreenConfigChanged(KEY_IMAGE_TRANSITION_EFFECT);
++
++    QVariant result13 = m_pGSettingsHelperDbus->GetLockScreenConf(KEY_IMAGE_SWITCH_INTERVAL);
++    int value13 = result13.toInt();
++    m_pGSettingsHelperDbus->onLockScreenConfigChanged(KEY_IMAGE_SWITCH_INTERVAL);
++
++    ASSERT_EQ(value1, 5);
++    ASSERT_EQ(value2, -1);
++    ASSERT_EQ(value3, true);
++    ASSERT_EQ(value4, true);
++    ASSERT_EQ(value5, 10);
++    ASSERT_EQ(value6, true);
++    ASSERT_EQ(value7, true);
++    ASSERT_EQ(value8, true);
++    ASSERT_EQ(value9.isEmpty(), false);
++    ASSERT_EQ(value10.isEmpty(), false);
++    ASSERT_EQ(value11.isEmpty(), false);
++    ASSERT_EQ(value12, 0);
++    ASSERT_EQ(value13, 60);
++}
++
++TEST_F(GSettingsHelperTest, SetLockScreenConf)
++{
++    QVariant result = m_pGSettingsHelperDbus->GetLockScreenConf(KEY_IDLE_DELAY);
++    int oldValue = result.toInt();
++
++    bool value = m_pGSettingsHelperDbus->SetLockScreenConf(KEY_IDLE_DELAY, 1);
++    m_pGSettingsHelperDbus->SetLockScreenConf(KEY_IDLE_DELAY, oldValue);
++
++    ASSERT_EQ(value, true);
++}
++
++TEST_F(GSettingsHelperTest, GetPowerManagerConf)
++{
++    QVariant result1 = m_pGSettingsHelperDbus->GetPowerManagerConf(KEY_LOCK_SUSPEND);
++    bool value1 = result1.toBool();
++    m_pGSettingsHelperDbus->onPowerManagerConfigChanged(KEY_LOCK_SUSPEND);
++
++    QVariant result2 = m_pGSettingsHelperDbus->GetPowerManagerConf(KEY_LOCK_HIBERNATE);
++    bool value2 = result2.toBool();
++    m_pGSettingsHelperDbus->onPowerManagerConfigChanged(KEY_LOCK_HIBERNATE);
++
++    QVariant result3 = m_pGSettingsHelperDbus->GetPowerManagerConf(KEY_LOCK_BLANKSCREEN);
++    bool value3 = result3.toBool();
++    m_pGSettingsHelperDbus->onPowerManagerConfigChanged(KEY_LOCK_BLANKSCREEN);
++
++    QVariant result4 = m_pGSettingsHelperDbus->GetPowerManagerConf(KEY_SLEEP_COMPUTER_AC);
++    int value4 = result4.toInt();
++    m_pGSettingsHelperDbus->onPowerManagerConfigChanged(KEY_SLEEP_COMPUTER_AC);
++
++    QVariant result5 = m_pGSettingsHelperDbus->GetPowerManagerConf(KEY_SLEEP_DISPLAY_AC);
++    int value5 = result5.toInt();
++    m_pGSettingsHelperDbus->onPowerManagerConfigChanged(KEY_SLEEP_DISPLAY_AC);
++
++    QVariant result6 = m_pGSettingsHelperDbus->GetPowerManagerConf(KEY_BUTTON_LID_AC);
++    int value6 = result6.toInt();
++    m_pGSettingsHelperDbus->onPowerManagerConfigChanged(KEY_BUTTON_LID_AC);
++
++    ASSERT_EQ(value1, false);
++    ASSERT_EQ(value2, false);
++    ASSERT_EQ(value3, true);
++    ASSERT_EQ(value4, -1);
++    ASSERT_EQ(value5, -1);
++    ASSERT_EQ(value6, 0);
++}
++
++TEST_F(GSettingsHelperTest, SetPowerManagerConf)
++{
++    QVariant result = m_pGSettingsHelperDbus->GetPowerManagerConf(KEY_LOCK_SUSPEND);
++    bool oldValue = result.toBool();
++
++    bool value = m_pGSettingsHelperDbus->SetPowerManagerConf(KEY_LOCK_SUSPEND, false);
++    m_pGSettingsHelperDbus->SetPowerManagerConf(KEY_LOCK_SUSPEND, oldValue);
++    ASSERT_EQ(value, true);
++}
++
++TEST_F(GSettingsHelperTest, GetMateBgConf)
++{
++    QVariant result1 = m_pGSettingsHelperDbus->GetMateBgConf(KEY_PICTURE_FILENAME);
++    QString value1 = result1.toString();
++//    m_pGSettingsHelperDbus->onMateBgConfigChanged(KEY_PICTURE_FILENAME);
++
++    QVariant result2 = m_pGSettingsHelperDbus->GetMateBgConf(KEY_PICTURE_OPTIONS);
++    QString value2 = result2.toString();
++//    m_pGSettingsHelperDbus->onMateBgConfigChanged(KEY_PICTURE_OPTIONS);
++
++    QVariant result3 = m_pGSettingsHelperDbus->GetMateBgConf(KEY_PRIMARY_COLOR);
++    QString value3 = result3.toString();
++//    m_pGSettingsHelperDbus->onMateBgConfigChanged(KEY_PRIMARY_COLOR);
++
++    ASSERT_EQ(value1.isEmpty(), false);
++    ASSERT_EQ(value2.isEmpty(), false);
++    ASSERT_EQ(value3.isEmpty(), false);
++}
++
++TEST_F(GSettingsHelperTest, SetMateBgConf)
++{
++    QVariant result = m_pGSettingsHelperDbus->GetMateBgConf(KEY_PICTURE_FILENAME);
++    QString oldValue = result.toString();
++
++    bool value = m_pGSettingsHelperDbus->SetMateBgConf(KEY_PICTURE_FILENAME, "ssss");
++    m_pGSettingsHelperDbus->SetMateBgConf(KEY_PICTURE_FILENAME, oldValue);
++
++    ASSERT_EQ(value, true);
++}
++
++TEST_F(GSettingsHelperTest, GetUkccPluginsConf)
++{
++    QVariant result1 = m_pGSettingsHelperDbus->GetUkccPluginsConf(KEY_HOUR_SYSTEM);
++    int value1 = result1.toInt();
++    m_pGSettingsHelperDbus->onUkccPluginsConfigChanged(KEY_HOUR_SYSTEM);
++
++    QVariant result2 = m_pGSettingsHelperDbus->GetUkccPluginsConf(KEY_DATE);
++    QString value2 = result2.toString();
++    m_pGSettingsHelperDbus->onUkccPluginsConfigChanged(KEY_DATE);
++
++    ASSERT_EQ(value1, 24);
++    ASSERT_EQ(value2.isEmpty(), false);
++}
++
++TEST_F(GSettingsHelperTest, SetUkccPluginsConf)
++{
++    QVariant result = m_pGSettingsHelperDbus->GetUkccPluginsConf(KEY_HOUR_SYSTEM);
++    int oldValue = result.toInt();
++
++    bool value = m_pGSettingsHelperDbus->SetUkccPluginsConf(KEY_HOUR_SYSTEM, 100);
++    m_pGSettingsHelperDbus->SetUkccPluginsConf(KEY_HOUR_SYSTEM, oldValue);
++
++    ASSERT_EQ(value, true);
++}
++
++TEST_F(GSettingsHelperTest, GetThemeStyleConf)
++{
++    QVariant result1 = m_pGSettingsHelperDbus->GetThemeStyleConf(KEY_SYSTEM_FONT_SIZE);
++    double value1 = result1.toDouble();
++    m_pGSettingsHelperDbus->onThemeStyleConfigChanged(KEY_SYSTEM_FONT_SIZE);
++
++    QVariant result2 = m_pGSettingsHelperDbus->GetThemeStyleConf(KEY_THEME_COLOR);
++    QString value2 = result2.toString();
++    m_pGSettingsHelperDbus->onThemeStyleConfigChanged(KEY_THEME_COLOR);
++
++    QVariant result3 = m_pGSettingsHelperDbus->GetThemeStyleConf(KEY_MENU_TRANSPARENCY);
++    int value3 = result3.toInt();
++    m_pGSettingsHelperDbus->onThemeStyleConfigChanged(KEY_MENU_TRANSPARENCY);
++
++    QVariant result4 = m_pGSettingsHelperDbus->GetThemeStyleConf(KEY_STYLE_NAME);
++    QString value4 = result4.toString();
++    m_pGSettingsHelperDbus->onThemeStyleConfigChanged(KEY_STYLE_NAME);
++
++    QVariant result5 = m_pGSettingsHelperDbus->GetThemeStyleConf(KEY_SYSTEM_FONT);
++    QString value5 = result5.toString();
++    m_pGSettingsHelperDbus->onThemeStyleConfigChanged(KEY_SYSTEM_FONT);
++
++    ASSERT_EQ(value1, 11);
++    ASSERT_EQ(value2.isEmpty(), false);
++    ASSERT_EQ(value3, 35);
++    ASSERT_EQ(value4.isEmpty(), false);
++    ASSERT_EQ(value5.isEmpty(), false);
++}
++
++TEST_F(GSettingsHelperTest, SetThemeStyleConf)
++{
++    QVariant result = m_pGSettingsHelperDbus->GetThemeStyleConf(KEY_SYSTEM_FONT_SIZE);
++    int oldValue = result.toInt();
++
++    bool value = m_pGSettingsHelperDbus->SetThemeStyleConf(KEY_SYSTEM_FONT_SIZE, 14);
++    m_pGSettingsHelperDbus->SetThemeStyleConf(KEY_SYSTEM_FONT_SIZE, oldValue);
++
++    ASSERT_EQ(value, true);
++}
++
++TEST_F(GSettingsHelperTest, GetSessionConf)
++{
++    QVariant result1 = m_pGSettingsHelperDbus->GetSessionConf(KEY_SESSION_IDLE);
++    int value1 = result1.toInt();
++    m_pGSettingsHelperDbus->onSessionConfigChanged(KEY_SESSION_IDLE);
++
++    QVariant result2 = m_pGSettingsHelperDbus->GetSessionConf(KEY_SESSION_LOGOUT_MUSIC);
++    bool value2 = result2.toBool();
++    m_pGSettingsHelperDbus->onSessionConfigChanged(KEY_SESSION_LOGOUT_MUSIC);
++
++    QVariant result3 = m_pGSettingsHelperDbus->GetSessionConf(KEY_SESSION_POWEROFF_MUSIC);
++    bool value3 = result3.toBool();
++    m_pGSettingsHelperDbus->onSessionConfigChanged(KEY_SESSION_POWEROFF_MUSIC);
++
++    ASSERT_EQ(value1, 1);
++    ASSERT_EQ(value2, false);
++    ASSERT_EQ(value3, false);
++}
++
++TEST_F(GSettingsHelperTest, SetSessionConf)
++{
++    QVariant result = m_pGSettingsHelperDbus->GetSessionConf(KEY_SESSION_LOGOUT_MUSIC);
++    bool oldValue = result.toBool();
++
++    bool value = m_pGSettingsHelperDbus->SetSessionConf(KEY_SESSION_LOGOUT_MUSIC, false);
++    m_pGSettingsHelperDbus->SetSessionConf(KEY_SESSION_LOGOUT_MUSIC, oldValue);
++
++    ASSERT_EQ(value, true);
++}
++
++TEST_F(GSettingsHelperTest, GetKeyboardConf)
++{
++    QVariant result1 = m_pGSettingsHelperDbus->GetKeyboardConf(KEY_CAPSLOCK_STATUS);
++    bool value1 = result1.toBool();
++    m_pGSettingsHelperDbus->onKeyboardConfigChanged(KEY_CAPSLOCK_STATUS);
++    ASSERT_EQ(value1, false);
++}
++
++TEST_F(GSettingsHelperTest, SetKeyboardConf)
++{
++    QVariant result = m_pGSettingsHelperDbus->GetKeyboardConf(KEY_CAPSLOCK_STATUS);
++    bool oldValue = result.toBool();
++
++    bool value = m_pGSettingsHelperDbus->SetKeyboardConf(KEY_CAPSLOCK_STATUS, false);
++    m_pGSettingsHelperDbus->SetKeyboardConf(KEY_CAPSLOCK_STATUS, oldValue);
++
++    ASSERT_EQ(value, true);
++}
++
++TEST_F(GSettingsHelperTest, GetUsdMediaKeys)
++{
++    QVariant result1 = m_pGSettingsHelperDbus->GetUsdMediaKeys(KEY_AREA_SCREENSHOT);
++    QString value1 = result1.toString();
++    m_pGSettingsHelperDbus->onUsdMediaKeysConfigChanged(KEY_AREA_SCREENSHOT);
++
++    QVariant result2 = m_pGSettingsHelperDbus->GetUsdMediaKeys(KEY_AREA_SCREENSHOT2);
++    QString value2 = result2.toString();
++    m_pGSettingsHelperDbus->onUsdMediaKeysConfigChanged(KEY_AREA_SCREENSHOT2);
++
++    QVariant result3 = m_pGSettingsHelperDbus->GetUsdMediaKeys(KEY_SCREEN_SHOT);
++    QString value3 = result3.toString();
++    m_pGSettingsHelperDbus->onUsdMediaKeysConfigChanged(KEY_SCREEN_SHOT);
++
++    QVariant result4 = m_pGSettingsHelperDbus->GetUsdMediaKeys(KEY_SCREEN_SHOT2);
++    QString value4 = result4.toString();
++    m_pGSettingsHelperDbus->onUsdMediaKeysConfigChanged(KEY_SCREEN_SHOT2);
++
++    QVariant result5 = m_pGSettingsHelperDbus->GetUsdMediaKeys(KEY_WINDOW_SCREENSHOT);
++    QString value5 = result5.toString();
++    m_pGSettingsHelperDbus->onUsdMediaKeysConfigChanged(KEY_WINDOW_SCREENSHOT);
++
++    ASSERT_EQ(value1.isEmpty(), false);
++    ASSERT_EQ(value2.isEmpty(), false);
++    ASSERT_EQ(value3.isEmpty(), false);
++    ASSERT_EQ(value4.isEmpty(), false);
++    ASSERT_EQ(value5.isEmpty(), false);
++}
++
++TEST_F(GSettingsHelperTest, GetUsdMediaStateKeys)
++{
++    QVariant result1 = m_pGSettingsHelperDbus->GetUsdMediaStateKeys(KEY_RFKILL_STATE);
++    bool value1 = result1.toBool();
++    m_pGSettingsHelperDbus->onUsdMediaStateKeysConfigChanged(KEY_RFKILL_STATE);
++    ASSERT_EQ(value1, false);
++}
++
++TEST_F(GSettingsHelperTest, SetUsdMediaStateKeys)
++{
++    QVariant result = m_pGSettingsHelperDbus->GetUsdMediaStateKeys(KEY_RFKILL_STATE);
++    bool oldValue = result.toBool();
++
++    bool value = m_pGSettingsHelperDbus->SetUsdMediaStateKeys(KEY_RFKILL_STATE, false);
++    m_pGSettingsHelperDbus->SetUsdMediaStateKeys(KEY_RFKILL_STATE, oldValue);
++
++    ASSERT_EQ(value, true);
++}
++
++
++
++
+diff --git a/tests/unit_test_inputswitch_event/CMakeLists.txt b/tests/unit_test_inputswitch_event/CMakeLists.txt
+new file mode 100644
+index 0000000..d0da1cf
+--- /dev/null
++++ b/tests/unit_test_inputswitch_event/CMakeLists.txt
+@@ -0,0 +1,63 @@
++# CMake 最低版本要求
++cmake_minimum_required(VERSION 3.10)
++
++find_package(Qt5 COMPONENTS Core Gui DBus REQUIRED)
++find_package(PkgConfig REQUIRED)
++pkg_check_modules(QGS REQUIRED gsettings-qt)
++# 包含 GTest 库和 pthread 库
++find_package(GTest REQUIRED)
++find_package(Threads REQUIRED)
++
++# 设置 C++ 标准
++set(CMAKE_CXX_STANDARD 17)
++set(CMAKE_CXX_STANDARD_REQUIRED ON)
++
++
++# 开启代码覆盖率相关编译选项(对应QMAKE_LFLAGS和QMAKE_CXXFLAGS中代码覆盖率相关设置)
++set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fprofile-arcs -ftest-coverage --coverage -fno-inline -fno-access-control")
++set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fprofile-arcs -ftest-coverage")
++
++# 定义源文件列表,对应原来的SOURCES变量
++set(SOURCES
++    ../../src/dbusifs/libinputswitchevent.cpp
++    ../../src/dbusifs/machinemodel.cpp
++    unit_test_inputswitch_event.cpp
++    main.cpp
++)
++
++# 定义头文件列表,对应原来的HEADERS变量
++set(HEADERS
++        ../../src/dbusifs/libinputswitchevent.h
++        ../../src/dbusifs/machinemodel.h
++)
++
++# 包含头文件的路径设置,对应原来的INCLUDEPATH变量
++include_directories(
++    ${CMAKE_CURRENT_SOURCE_DIR}
++    ${CMAKE_CURRENT_SOURCE_DIR}/../kt-test-utils/cpp-stub
++    ${CMAKE_CURRENT_SOURCE_DIR}/../kt-test-utils/cpp-stub-ext
++    ${QGS_INCLUDE_DIRS}
++)
++
++# 使用qt5_wrap_cpp生成元对象代码相关的源文件
++qt5_wrap_cpp(MOC_SOURCES ${HEADERS})
++
++# 添加可执行文件或库目标,将元对象代码源文件一起添加进去
++add_executable(unit_test_inputswitch_event ${SOURCES} ${MOC_SOURCES})
++
++# 链接Qt相关的库
++target_link_libraries(unit_test_inputswitch_event
++    Qt5::Core
++    Qt5::Gui
++    Qt5::DBus
++    ${QGS_LIBRARIES}
++    -lukuiinputgatherclient
++)
++
++# 链接 GTest 库
++target_link_libraries(unit_test_inputswitch_event
++    GTest::GTest
++    GTest::Main
++    Threads::Threads
++)
++
+diff --git a/tests/unit_test_inputswitch_event/main.cpp b/tests/unit_test_inputswitch_event/main.cpp
+new file mode 100644
+index 0000000..37b3fbf
+--- /dev/null
++++ b/tests/unit_test_inputswitch_event/main.cpp
+@@ -0,0 +1,12 @@
++#include <gtest/gtest.h>
++#include <QGuiApplication>
++
++
++int main(int argc, char **argv)
++{
++    QGuiApplication a(argc, argv);
++    testing::InitGoogleTest(&argc, argv);
++
++    return RUN_ALL_TESTS();
++}
++
+diff --git a/tests/unit_test_inputswitch_event/unit_test_inputswitch_event.cpp b/tests/unit_test_inputswitch_event/unit_test_inputswitch_event.cpp
+new file mode 100644
+index 0000000..5d4fbba
+--- /dev/null
++++ b/tests/unit_test_inputswitch_event/unit_test_inputswitch_event.cpp
+@@ -0,0 +1,137 @@
++#include <gtest/gtest.h>
++#include <QCoreApplication>
++#include <QString>
++#include <memory>
++#include <iostream>
++#include "../../src/dbusifs/libinputswitchevent.h"
++#include "../../src/dbusifs/machinemodel.h"
++
++
++// 辅助函数,模拟文件读取内容
++QString simulateFileRead(const QString &filePath) {
++    if (filePath == "/sys/class/dmi/id/sys_vendor") {
++        return "Vendor";
++    } else if (filePath == "/sys/class/dmi/id/product_name") {
++        return "Product";
++    } else if (filePath == "/sys/class/dmi/id/product_family") {
++        return "Family";
++    }
++    return "";
++}
++
++
++// 测试 MachineModel 类
++class MachineModelTest : public ::testing::Test {
++protected:
++    std::shared_ptr<MachineModel> machineModel;
++
++
++    void SetUp() override {
++        machineModel = MachineModel::getMachineModelInstance();
++    }
++
++
++    void TearDown() override {
++        machineModel.reset();
++    }
++};
++
++
++// 测试 getSysVendor 函数
++TEST_F(MachineModelTest, getSysVendor) {
++    QString vendor = machineModel->getSysVendor();
++    EXPECT_EQ(vendor, "Vendor");
++}
++
++
++// 测试 getProductName 函数
++TEST_F(MachineModelTest, getProductName) {
++    QString productName = machineModel->getProductName();
++    EXPECT_EQ(productName, "Product");
++}
++
++
++// 测试 getProductFamily 函数
++TEST_F(MachineModelTest, getProductFamily) {
++    QString productFamily = machineModel->getProductFamily();
++    EXPECT_EQ(productFamily, "Family");
++}
++
++
++// 测试 initMachineType 函数
++TEST_F(MachineModelTest, initMachineType) {
++    machineModel->initMachineType();
++    QString machineType = machineModel->getTheMachineType();
++    EXPECT_EQ(machineType, "");  // 这里根据实际的配置文件设置进行调整
++}
++
++
++// 测试 LibinputSwitchEvent 类
++class LibinputSwitchEventTest : public ::testing::Test {
++protected:
++    std::unique_ptr<LibinputSwitchEvent> libinputSwitchEvent;
++
++
++    void SetUp() override {
++        // 使用模拟的 QProcess
++        qputenv("QT_QPA_PLATFORM", "minimal");
++        qRegisterMetaType<Event *>("Event*");
++        libinputSwitchEvent = std::make_unique<LibinputSwitchEvent>(nullptr);
++    }
++
++
++    void TearDown() override {
++        libinputSwitchEvent.reset();
++    }
++};
++
++
++// 测试 geInitDevicesStatus 函数
++TEST_F(LibinputSwitchEventTest, geInitDevicesStatus) {
++    // 测试不同的机器类型
++    libinputSwitchEvent->m_machineType = "SLATE";
++    EXPECT_TRUE(libinputSwitchEvent->geInitDevicesStatus());
++
++
++    libinputSwitchEvent->m_machineType = "LAPTOP";
++    // EXPECT_TRUE(libinputSwitchEvent->geInitDevicesStatus());
++
++
++    libinputSwitchEvent->m_machineType = "ALLINONE";
++    EXPECT_FALSE(libinputSwitchEvent->geInitDevicesStatus());
++
++
++    libinputSwitchEvent->m_machineType = "OTHER";
++    EXPECT_FALSE(libinputSwitchEvent->geInitDevicesStatus());
++}
++
++
++// 测试 dealEvent 函数
++TEST_F(LibinputSwitchEventTest, dealEvent) {
++    Event event;
++    event.type = LIBINPUT_EVENT_SWITCH_TOGGLE;
++    event.event.switchEventDate.switchType = LIBINPUT_SWITCH_TABLET_MODE;
++
++
++    // 测试切换到平板模式
++//    event.event.switchEventDate.switchState = LIBINPUT_SWITCH_STATE_ON;
++//    QSignalSpy spy(libinputSwitchEvent.get(), SIGNAL(tabletModeStatusChanged(int)));
++//    libinputSwitchEvent->dealEvent(&event);
++//    EXPECT_EQ(spy.count(), 1);
++//    EXPECT_EQ(spy[0][0].value<int>(), 1);
++
++
++//    // 测试切换出平板模式
++//    event.event.switchEventDate.switchState = LIBINPUT_SWITCH_STATE_OFF;
++//    spy.clear();
++//    libinputSwitchEvent->dealEvent(&event);
++//    EXPECT_EQ(spy.count(), 1);
++//    EXPECT_EQ(spy[0][0].value<int>(), 0);
++
++
++    // 测试其他事件类型
++//    event.type = LIBINPUT_EVENT_NONE;
++//    spy.clear();
++//    libinputSwitchEvent->dealEvent(&event);
++//    EXPECT_EQ(spy.count(), 0);
++}
+diff --git a/tests/unit_test_kglobalaccel_helper/CMakeLists.txt b/tests/unit_test_kglobalaccel_helper/CMakeLists.txt
+new file mode 100644
+index 0000000..8c28b68
+--- /dev/null
++++ b/tests/unit_test_kglobalaccel_helper/CMakeLists.txt
+@@ -0,0 +1,57 @@
++# CMake 最低版本要求
++cmake_minimum_required(VERSION 3.10)
++
++find_package(Qt5 COMPONENTS Core Gui DBus REQUIRED)
++
++# 包含 GTest 库和 pthread 库
++find_package(GTest REQUIRED)
++find_package(Threads REQUIRED)
++
++# 设置 C++ 标准
++set(CMAKE_CXX_STANDARD 17)
++set(CMAKE_CXX_STANDARD_REQUIRED ON)
++
++
++# 开启代码覆盖率相关编译选项(对应QMAKE_LFLAGS和QMAKE_CXXFLAGS中代码覆盖率相关设置)
++set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fprofile-arcs -ftest-coverage --coverage -fno-inline -fno-access-control")
++set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fprofile-arcs -ftest-coverage")
++
++# 定义源文件列表,对应原来的SOURCES变量
++set(SOURCES
++    ../../src/dbusifs/kglobalaccelhelper.cpp
++    unit_test_kglobalaccel_helper.cpp
++    main.cpp
++)
++
++# 定义头文件列表,对应原来的HEADERS变量
++set(HEADERS
++        ../../src/dbusifs/kglobalaccelhelper.h
++)
++
++# 包含头文件的路径设置,对应原来的INCLUDEPATH变量
++include_directories(
++    ${CMAKE_CURRENT_SOURCE_DIR}
++    ${CMAKE_CURRENT_SOURCE_DIR}/../kt-test-utils/cpp-stub
++    ${CMAKE_CURRENT_SOURCE_DIR}/../kt-test-utils/cpp-stub-ext
++)
++
++# 使用qt5_wrap_cpp生成元对象代码相关的源文件
++qt5_wrap_cpp(MOC_SOURCES ${HEADERS})
++
++# 添加可执行文件或库目标,将元对象代码源文件一起添加进去
++add_executable(unit_test_kglobalaccel_helper ${SOURCES} ${MOC_SOURCES})
++
++# 链接Qt相关的库
++target_link_libraries(unit_test_kglobalaccel_helper
++    Qt5::Core
++    Qt5::Gui
++    Qt5::DBus
++)
++
++# 链接 GTest 库
++target_link_libraries(unit_test_kglobalaccel_helper
++    GTest::GTest
++    GTest::Main
++    Threads::Threads
++)
++
+diff --git a/tests/unit_test_kglobalaccel_helper/main.cpp b/tests/unit_test_kglobalaccel_helper/main.cpp
+new file mode 100644
+index 0000000..37b3fbf
+--- /dev/null
++++ b/tests/unit_test_kglobalaccel_helper/main.cpp
+@@ -0,0 +1,12 @@
++#include <gtest/gtest.h>
++#include <QGuiApplication>
++
++
++int main(int argc, char **argv)
++{
++    QGuiApplication a(argc, argv);
++    testing::InitGoogleTest(&argc, argv);
++
++    return RUN_ALL_TESTS();
++}
++
+diff --git a/tests/unit_test_kglobalaccel_helper/unit_test_kglobalaccel_helper.cpp b/tests/unit_test_kglobalaccel_helper/unit_test_kglobalaccel_helper.cpp
+new file mode 100644
+index 0000000..11def17
+--- /dev/null
++++ b/tests/unit_test_kglobalaccel_helper/unit_test_kglobalaccel_helper.cpp
+@@ -0,0 +1,36 @@
++#include <gtest/gtest.h>
++#include <gtest/gtest-death-test.h>
++
++#include "../../src/dbusifs/kglobalaccelhelper.h"
++
++#include "stubext.h"
++using namespace stub_ext;
++
++class KglobalAccelHelperTest : public testing::Test
++{
++protected:
++    static void SetUpTestSuite()
++    {
++        m_pKglobalAccelHelperDbus = new KglobalAccelHelper();
++    }
++
++    static void TearDownTestSuite()
++    {
++        delete m_pKglobalAccelHelperDbus;
++        m_pKglobalAccelHelperDbus = nullptr;
++    }
++
++    static KglobalAccelHelper *m_pKglobalAccelHelperDbus;
++};
++
++KglobalAccelHelper *KglobalAccelHelperTest::m_pKglobalAccelHelperDbus = nullptr;
++
++TEST_F(KglobalAccelHelperTest, blockShortcut)
++{
++    bool oldValue = m_pKglobalAccelHelperDbus->blockShortcut(true);
++    ASSERT_EQ(oldValue, true);
++
++    bool newValue = m_pKglobalAccelHelperDbus->blockShortcut(false);
++    ASSERT_EQ(newValue, true);
++}
++
+diff --git a/tests/unit_test_lock_dialog_model/CMakeLists.txt b/tests/unit_test_lock_dialog_model/CMakeLists.txt
+new file mode 100644
+index 0000000..db1fa6d
+--- /dev/null
++++ b/tests/unit_test_lock_dialog_model/CMakeLists.txt
+@@ -0,0 +1,86 @@
++# CMake 最低版本要求
++cmake_minimum_required(VERSION 3.10)
++
++find_package(Qt5 COMPONENTS Core Widgets X11Extras Gui DBus REQUIRED)
++
++# 包含 GTest 库和 pthread 库
++find_package(GTest REQUIRED)
++find_package(Threads REQUIRED)
++find_package(X11 REQUIRED)
++
++find_package(PkgConfig REQUIRED)
++pkg_check_modules(GIOUNIX2 REQUIRED gio-unix-2.0)
++pkg_check_modules(GLIB2 REQUIRED glib-2.0 gio-2.0)
++pkg_check_modules(XCB REQUIRED xcb)
++
++# 设置 C++ 标准
++set(CMAKE_CXX_STANDARD 17)
++set(CMAKE_CXX_STANDARD_REQUIRED ON)
++
++
++# 开启代码覆盖率相关编译选项(对应QMAKE_LFLAGS和QMAKE_CXXFLAGS中代码覆盖率相关设置)
++
++set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fprofile-arcs -ftest-coverage")
++set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fprofile-arcs -ftest-coverage")
++
++
++# 定义源文件列表,对应原来的SOURCES变量
++set(SOURCES
++    ../../src/lock-dialog/lockdialogmodel.cpp
++    ../../src/userinfo.cpp
++    ../../src/agreementinfo.cpp
++    ../../src/common/biodefines.cpp
++    ../../src/common/global_utils.cpp
++    ../..//src/widgets/screensavermode.cpp
++    ../../src/common/utils.cpp
++    unit_test_lock_dialog_model.cpp
++    main.cpp
++)
++
++# 定义头文件列表,对应原来的HEADERS变量
++set(HEADERS
++    ../../src/lock-dialog/lockdialogmodel.h
++    ../../src/common/definetypes.h
++    ../../src/common/biodefines.h
++    ../../src/userinfo.h
++    ../../src/agreementinfo.h
++    ../../src/common/global_utils.h
++    ../..//src/widgets/screensavermode.h
++    ../../src/common/utils.h
++)
++
++# 包含头文件的路径设置,对应原来的INCLUDEPATH变量
++include_directories(
++    ${CMAKE_CURRENT_SOURCE_DIR}
++    ${CMAKE_CURRENT_SOURCE_DIR}/../kt-test-utils/cpp-stub
++    ${CMAKE_CURRENT_SOURCE_DIR}/../kt-test-utils/cpp-stub-ext
++    ${GIOUNIX2_INCLUDE_DIRS}
++    ${X11_INCLUDE_DIRS}
++    ${XCB_INCLUDE_DIRS}
++)
++
++# 使用qt5_wrap_cpp生成元对象代码相关的源文件
++qt5_wrap_cpp(MOC_SOURCES ${HEADERS})
++
++# 添加可执行文件或库目标,将元对象代码源文件一起添加进去
++add_executable(unit_test_lock_dialog_model ${SOURCES} ${MOC_SOURCES})
++
++# 链接Qt相关的库
++target_link_libraries(unit_test_lock_dialog_model
++    Qt5::Core
++    Qt5::Gui
++    Qt5::DBus
++    Qt5::Widgets
++    Qt5::X11Extras
++)
++
++# 链接 GTest 库
++target_link_libraries(unit_test_lock_dialog_model
++    GTest::GTest
++    GTest::Main
++    Threads::Threads
++    ${GIOUNIX2_LIBRARIES}
++    ${X11_LIBRARIES}
++    ${XCB_LIBRARIES}
++)
++
+diff --git a/tests/unit_test_lock_dialog_model/main.cpp b/tests/unit_test_lock_dialog_model/main.cpp
+new file mode 100644
+index 0000000..37b3fbf
+--- /dev/null
++++ b/tests/unit_test_lock_dialog_model/main.cpp
+@@ -0,0 +1,12 @@
++#include <gtest/gtest.h>
++#include <QGuiApplication>
++
++
++int main(int argc, char **argv)
++{
++    QGuiApplication a(argc, argv);
++    testing::InitGoogleTest(&argc, argv);
++
++    return RUN_ALL_TESTS();
++}
++
+diff --git a/tests/unit_test_lock_dialog_model/unit_test_lock_dialog_model.cpp b/tests/unit_test_lock_dialog_model/unit_test_lock_dialog_model.cpp
+new file mode 100644
+index 0000000..32db3a1
+--- /dev/null
++++ b/tests/unit_test_lock_dialog_model/unit_test_lock_dialog_model.cpp
+@@ -0,0 +1,68 @@
++#include <gtest/gtest.h>
++#include <gtest/gtest-death-test.h>
++#include <QCommandLineParser>
++#include <QDebug>
++
++#include "../../src/lock-dialog/lockdialogmodel.h"
++#include "../../src/common/definetypes.h"
++#include "../../src/agreementinfo.h"
++#include "stubext.h"
++
++using namespace stub_ext;
++
++// 测试夹具类,用于初始化和清理测试环境
++class LockDialogModelTest : public ::testing::Test {
++protected:
++    LockDialogModel* model;
++
++    virtual void SetUp() {
++        model = new LockDialogModel(nullptr);
++    }
++
++    virtual void TearDown() {
++        delete model;
++    }
++};
++
++TEST_F(LockDialogModelTest, ParseCmdArguments) {
++    QStringList args;
++    LockDialogModel::CommandLineArgs cmdArgs;
++
++    // 天翼云情况测试(模拟天翼云平台)
++    args << "--lock-startup";
++    setenv("HostCloundPlatform", "ctyun", 1);
++    EXPECT_TRUE(model->parseCmdArguments(args, cmdArgs));
++    unsetenv("HostCloundPlatform");
++
++    // 非天翼云且参数不全情况测试
++    args.clear();
++//    EXPECT_FALSE(model->parseCmdArguments(args, cmdArgs));
++
++    // 完整参数设置测试
++    args << "--lock";
++    EXPECT_TRUE(model->parseCmdArguments(args, cmdArgs));
++    EXPECT_TRUE(cmdArgs.isLock);
++}
++
++TEST_F(LockDialogModelTest, FindUserByName) {
++
++    // 查找已存在的用户
++    UserInfoPtr result = model->findUserByName("testuser");
++    EXPECT_NE(result, nullptr);
++
++    // 查找不存在的用户
++    result = model->findUserByName("nonexistentuser");
++    EXPECT_EQ(result, nullptr);
++}
++
++TEST_F(LockDialogModelTest, GetScreensaver) {
++
++    ScreenSaver* saver = model->getScreensaver();
++    EXPECT_EQ(saver->mode, SAVER_RANDOM);
++    delete saver;
++
++    saver = model->getScreensaver();
++    EXPECT_EQ(saver->mode, SAVER_IMAGE);
++    delete saver;
++}
++
+diff --git a/tests/unit_test_login1_helper/CMakeLists.txt b/tests/unit_test_login1_helper/CMakeLists.txt
+new file mode 100644
+index 0000000..4263e43
+--- /dev/null
++++ b/tests/unit_test_login1_helper/CMakeLists.txt
+@@ -0,0 +1,58 @@
++# CMake 最低版本要求
++cmake_minimum_required(VERSION 3.10)
++
++find_package(Qt5 COMPONENTS Core Gui DBus REQUIRED)
++
++# 包含 GTest 库和 pthread 库
++find_package(GTest REQUIRED)
++find_package(Threads REQUIRED)
++
++# 设置 C++ 标准
++set(CMAKE_CXX_STANDARD 17)
++set(CMAKE_CXX_STANDARD_REQUIRED ON)
++
++
++# 开启代码覆盖率相关编译选项(对应QMAKE_LFLAGS和QMAKE_CXXFLAGS中代码覆盖率相关设置)
++set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fprofile-arcs -ftest-coverage --coverage -fno-inline -fno-access-control")
++set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fprofile-arcs -ftest-coverage")
++
++# 定义源文件列表,对应原来的SOURCES变量
++set(SOURCES
++    ../../src/dbusifs/login1helper.cpp
++    unit_test_login1_helper.cpp
++    main.cpp
++)
++
++# 定义头文件列表,对应原来的HEADERS变量
++set(HEADERS
++        ../../src/common/definetypes.h
++        ../../src/dbusifs/login1helper.h
++)
++
++# 包含头文件的路径设置,对应原来的INCLUDEPATH变量
++include_directories(
++    ${CMAKE_CURRENT_SOURCE_DIR}
++    ${CMAKE_CURRENT_SOURCE_DIR}/../kt-test-utils/cpp-stub
++    ${CMAKE_CURRENT_SOURCE_DIR}/../kt-test-utils/cpp-stub-ext
++)
++
++# 使用qt5_wrap_cpp生成元对象代码相关的源文件
++qt5_wrap_cpp(MOC_SOURCES ${HEADERS})
++
++# 添加可执行文件或库目标,将元对象代码源文件一起添加进去
++add_executable(unit_test_login1_helper ${SOURCES} ${MOC_SOURCES})
++
++# 链接Qt相关的库
++target_link_libraries(unit_test_login1_helper
++    Qt5::Core
++    Qt5::Gui
++    Qt5::DBus
++)
++
++# 链接 GTest 库
++target_link_libraries(unit_test_login1_helper
++    GTest::GTest
++    GTest::Main
++    Threads::Threads
++)
++
+diff --git a/tests/unit_test_login1_helper/main.cpp b/tests/unit_test_login1_helper/main.cpp
+new file mode 100644
+index 0000000..37b3fbf
+--- /dev/null
++++ b/tests/unit_test_login1_helper/main.cpp
+@@ -0,0 +1,12 @@
++#include <gtest/gtest.h>
++#include <QGuiApplication>
++
++
++int main(int argc, char **argv)
++{
++    QGuiApplication a(argc, argv);
++    testing::InitGoogleTest(&argc, argv);
++
++    return RUN_ALL_TESTS();
++}
++
+diff --git a/tests/unit_test_login1_helper/unit_test_login1_helper.cpp b/tests/unit_test_login1_helper/unit_test_login1_helper.cpp
+new file mode 100644
+index 0000000..469bbd1
+--- /dev/null
++++ b/tests/unit_test_login1_helper/unit_test_login1_helper.cpp
+@@ -0,0 +1,95 @@
++#include <gtest/gtest.h>
++#include <gtest/gtest-death-test.h>
++
++#include "../../src/dbusifs/login1helper.h"
++
++#include "stubext.h"
++using namespace stub_ext;
++
++class Login1HelperTest : public testing::Test
++{
++protected:
++    static void SetUpTestSuite()
++    {
++        m_pLogin1HelperDbus = new Login1Helper();
++    }
++
++    static void TearDownTestSuite()
++    {
++        delete m_pLogin1HelperDbus;
++        m_pLogin1HelperDbus = nullptr;
++    }
++
++    static Login1Helper *m_pLogin1HelperDbus;
++};
++
++Login1Helper *Login1HelperTest::m_pLogin1HelperDbus = nullptr;
++
++TEST_F(Login1HelperTest, isSessionActive)
++{
++    bool value = m_pLogin1HelperDbus->isSessionActive();
++    ASSERT_EQ(value, true);
++}
++
++TEST_F(Login1HelperTest, onPrepareForSleep)
++{
++    bool oldSleep = m_pLogin1HelperDbus->m_isSleeping;
++    m_pLogin1HelperDbus->onPrepareForSleep(true);
++    m_pLogin1HelperDbus->onHibitedWatcherMessage();
++    m_pLogin1HelperDbus->onPrepareForSleep(oldSleep);
++    ASSERT_EQ(m_pLogin1HelperDbus->m_isSleeping, true);
++}
++
++TEST_F(Login1HelperTest, setPowerManager)
++{
++    m_pLogin1HelperDbus->setPowerManager("test");
++    m_pLogin1HelperDbus->Unlock();
++}
++
++TEST_F(Login1HelperTest, getCanPowerManager)
++{
++    bool value = m_pLogin1HelperDbus->getCanPowerManager("CanReboot");
++    ASSERT_EQ(value, true);
++}
++
++TEST_F(Login1HelperTest, isCanHibernate)
++{
++    bool value = m_pLogin1HelperDbus->isCanHibernate();
++    ASSERT_EQ(value, true);
++}
++
++TEST_F(Login1HelperTest, isCanSuspend)
++{
++    bool value = m_pLogin1HelperDbus->isCanSuspend();
++    ASSERT_EQ(value, true);
++}
++
++TEST_F(Login1HelperTest, isCanReboot)
++{
++    bool value = m_pLogin1HelperDbus->isCanReboot();
++    ASSERT_EQ(value, true);
++}
++
++TEST_F(Login1HelperTest, isCanPowerOff)
++{
++    bool value = m_pLogin1HelperDbus->isCanPowerOff();
++    ASSERT_EQ(value, true);
++}
++
++TEST_F(Login1HelperTest, canAction)
++{
++    bool value = m_pLogin1HelperDbus->canAction(PowerHibernate);
++    bool value1 = m_pLogin1HelperDbus->canAction(PowerSuspend);
++    bool value2 = m_pLogin1HelperDbus->canAction(PowerMonitorOff);
++    bool value3 = m_pLogin1HelperDbus->canAction(PowerLogout);
++    bool value4 = m_pLogin1HelperDbus->canAction(PowerReboot);
++    bool value5 = m_pLogin1HelperDbus->canAction(PowerShutdown);
++    ASSERT_EQ(value, true);
++    ASSERT_EQ(value1, true);
++    ASSERT_EQ(value2, true);
++    ASSERT_EQ(value3, true);
++    ASSERT_EQ(value4, true);
++    ASSERT_EQ(value5, true);
++}
++
++
+diff --git a/tests/unit_test_personal_data/CMakeLists.txt b/tests/unit_test_personal_data/CMakeLists.txt
+new file mode 100644
+index 0000000..a20411e
+--- /dev/null
++++ b/tests/unit_test_personal_data/CMakeLists.txt
+@@ -0,0 +1,60 @@
++# CMake 最低版本要求
++cmake_minimum_required(VERSION 3.10)
++
++find_package(Qt5 COMPONENTS Core Gui DBus REQUIRED)
++find_package(PkgConfig REQUIRED)
++pkg_check_modules(LIGHTDM-QT5-3 REQUIRED liblightdm-qt5-3)
++# 包含 GTest 库和 pthread 库
++find_package(GTest REQUIRED)
++find_package(Threads REQUIRED)
++# 设置 C++ 标准
++set(CMAKE_CXX_STANDARD 17)
++set(CMAKE_CXX_STANDARD_REQUIRED ON)
++
++
++# 开启代码覆盖率相关编译选项(对应QMAKE_LFLAGS和QMAKE_CXXFLAGS中代码覆盖率相关设置)
++
++set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fprofile-arcs -ftest-coverage")
++set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fprofile-arcs -ftest-coverage")
++
++
++# 定义源文件列表,对应原来的SOURCES变量
++set(SOURCES
++    ../../src/lock-backend/personalizeddata.cpp
++    unit_test_personal_data.cpp
++    main.cpp
++)
++
++# 定义头文件列表,对应原来的HEADERS变量
++set(HEADERS
++    ../../src/lock-backend/personalizeddata.h
++    )
++
++# 包含头文件的路径设置,对应原来的INCLUDEPATH变量
++include_directories(
++    ${CMAKE_CURRENT_SOURCE_DIR}
++    ${CMAKE_CURRENT_SOURCE_DIR}/../kt-test-utils/cpp-stub
++    ${CMAKE_CURRENT_SOURCE_DIR}/../kt-test-utils/cpp-stub-ext
++    ${LIGHTDM-QT5-3_INCLUDE_DIRS}
++)
++
++# 使用qt5_wrap_cpp生成元对象代码相关的源文件
++qt5_wrap_cpp(MOC_SOURCES ${HEADERS})
++
++# 添加可执行文件或库目标,将元对象代码源文件一起添加进去
++add_executable(unit_test_personal_data ${SOURCES} ${MOC_SOURCES})
++
++# 链接Qt相关的库
++target_link_libraries(unit_test_personal_data
++    Qt5::Core
++    Qt5::Gui
++    Qt5::DBus
++)
++
++# 链接 GTest 库
++target_link_libraries(unit_test_personal_data
++    GTest::GTest
++    GTest::Main
++    Threads::Threads
++    ${LIGHTDM-QT5-3_LIBRARIES}
++)
+diff --git a/tests/unit_test_personal_data/main.cpp b/tests/unit_test_personal_data/main.cpp
+new file mode 100644
+index 0000000..37b3fbf
+--- /dev/null
++++ b/tests/unit_test_personal_data/main.cpp
+@@ -0,0 +1,12 @@
++#include <gtest/gtest.h>
++#include <QGuiApplication>
++
++
++int main(int argc, char **argv)
++{
++    QGuiApplication a(argc, argv);
++    testing::InitGoogleTest(&argc, argv);
++
++    return RUN_ALL_TESTS();
++}
++
+diff --git a/tests/unit_test_personal_data/unit_test_common.cpp b/tests/unit_test_personal_data/unit_test_common.cpp
+new file mode 100644
+index 0000000..b350754
+--- /dev/null
++++ b/tests/unit_test_personal_data/unit_test_common.cpp
+@@ -0,0 +1,329 @@
++#include "../../src/common/definetypes.h"
++#include "../../src/common/biodefines.h"
++#include "../../src/common/commonfunc.h"
++#include "../../src/common/configuration.h"
++#include "../../src/common/global_utils.h"
++#include "../../src/common/rsac.h"
++#include <gtest/gtest.h>
++#include <gtest/gtest-death-test.h>
++#include <QIcon>
++#include <openssl/rsa.h>
++#include <openssl/pem.h>
++#include <openssl/err.h>
++#include <openssl/sha.h>
++#include <iostream>
++#include "../../src/common/rsac.h"
++#include "../../src/common/utils.h"
++
++#include "stubext.h"
++using namespace stub_ext;
++
++// 辅助函数,用于初始化OpenSSL库
++
++void InitOpenSSL() {
++
++    OpenSSL_add_all_algorithms();
++
++    ERR_load_crypto_strings();
++
++}
++
++
++
++// 辅助函数,用于清理OpenSSL库
++
++void CleanupOpenSSL() {
++
++    EVP_cleanup();
++
++    ERR_free_strings();
++
++}
++
++class CommonTest : public testing::Test
++{
++protected:
++
++    void SetUp() override {
++
++        InitOpenSSL();
++
++    }
++
++
++
++    void TearDown() override {
++
++        CleanupOpenSSL();
++
++    }
++
++    RSAC rsac;
++};
++
++TEST_F(CommonTest, scaledPixmap)
++{
++    setCursorCenter();
++    QPixmap pixmap = QIcon::fromTheme("view-refresh-symbolic").pixmap(48, 48);
++    QPixmap newPixmap = scaledPixmap(pixmap);
++    ASSERT_EQ(newPixmap.isNull(), false);
++}
++
++TEST_F(CommonTest, PixmapToRound)
++{
++    QPixmap pixmap = QIcon::fromTheme("view-refresh-symbolic").pixmap(48, 48);
++    QPixmap newPixmap = PixmapToRound(pixmap, 4);
++    ASSERT_EQ(newPixmap.isNull(), false);
++}
++
++TEST_F(CommonTest, PixmapToRound2)
++{
++    QPixmap pixmap = QIcon::fromTheme("view-refresh-symbolic").pixmap(48, 48);
++    QPixmap newPixmap = PixmapToRound(pixmap, 0, 0, 0, 0);
++    ASSERT_EQ(newPixmap.isNull(), false);
++}
++
++TEST_F(CommonTest, loadSvg)
++{
++    QPixmap iconPixmap = loadSvg(":/image/assets/show-password.png", "white", 16);
++    ASSERT_EQ(iconPixmap.isNull(), false);
++}
++
++TEST_F(CommonTest, drawSymbolicColoredPixmap)
++{
++    QPixmap retryIcon = QIcon::fromTheme("view-refresh-symbolic").pixmap(48, 48);
++    ASSERT_EQ(drawSymbolicColoredPixmap(retryIcon, "white").isNull(), false);
++    ASSERT_EQ(getLoadingIcon(16).width(), 16);
++}
++
++TEST_F(CommonTest, scaleBlurPixmap)
++{
++    QPixmap *pixmap = new QPixmap(scaleBlurPixmap(16, 16, "/usr/share/background/house.png"));
++    ASSERT_EQ(pixmap->width(), 16);
++}
++
++TEST_F(CommonTest, blurPixmap)
++{
++    QPixmap pixmap = QIcon::fromTheme("view-refresh-symbolic").pixmap(48, 48);
++    QPixmap newpixmap = blurPixmap(pixmap);
++    ASSERT_EQ(newpixmap.width(), 16);
++}
++
++TEST_F(CommonTest, getValue)
++{
++    if (Configuration::instance()) {
++        QString color = Configuration::instance()->getValue("background-color").toString();
++        ASSERT_EQ(color.isEmpty(), false);
++    }
++}
++
++TEST_F(CommonTest, getCurrentUser)
++{
++    if (Configuration::instance()) {
++        Configuration::instance()->getCurrentUser(getenv("USER"));
++    }
++}
++
++TEST_F(CommonTest, setValue)
++{
++    if (Configuration::instance()) {
++        QString color = Configuration::instance()->getValue("backgroundPath").toString();
++        QString oldvalue = Configuration::instance()->getUserConfig("backgroundPath").toString();
++        Configuration::instance()->setValue("backgroundPath", oldvalue);
++        ASSERT_EQ(oldvalue.isEmpty(), false);
++    }
++}
++
++TEST_F(CommonTest, hasValue)
++{
++    if (Configuration::instance()) {
++        bool value = Configuration::instance()->hasValue("backgroundPath");
++        ASSERT_EQ(value, false);
++    }
++}
++
++
++TEST_F(CommonTest, getIs990)
++{
++    if (Configuration::instance()) {
++        bool value = Configuration::instance()->getIs990();
++        ASSERT_EQ(value, false);
++    }
++}
++
++TEST_F(CommonTest, getLastNumLock)
++{
++    if (Configuration::instance()) {
++        bool value = Configuration::instance()->getLastNumLock();
++        Configuration::instance()->saveLastNumLock(value);
++        ASSERT_EQ(value, false);
++    }
++}
++
++TEST_F(CommonTest, getRootBackgroundOption)
++{
++    if (Configuration::instance()) {
++        int value = Configuration::instance()->getRootBackgroundOption(getenv("USER"));
++        ASSERT_EQ(value, 1);
++    }
++}
++
++TEST_F(CommonTest, getDefaultBackgroundName)
++{
++    if (Configuration::instance()) {
++        QString background = Configuration::instance()->getDefaultBackgroundName();
++        ASSERT_EQ(background.isEmpty(), false);
++    }
++}
++
++TEST_F(CommonTest, checkCapsLockState)
++{
++    checkIslivecd();
++    KillFocusOfKydroid();
++    ASSERT_EQ(checkCapsLockState(), false);
++}
++
++TEST_F(CommonTest, getDefaultFontSize)
++{
++    ASSERT_EQ(getDefaultFontSize(), 14.0);
++}
++
++TEST_F(CommonTest, getUserFontSize)
++{
++    ASSERT_EQ(getUserFontSize(getenv("USER")), 14.0);
++}
++
++TEST_F(CommonTest, getUserThemeColor)
++{
++    ASSERT_EQ(getUserThemeColor(getenv("USER")), "test");
++}
++
++// 测试密钥生成并保存到文件
++
++TEST_F(CommonTest, GenerateKeyPairToFile) {
++
++    QString priKeyFile = "test_private.pem";
++
++    QString pubKeyFile = "test_public.pem";
++
++    rsac.generateKeyPair(priKeyFile, pubKeyFile, 1024);
++
++
++
++    // 这里可以添加额外的检查来验证文件是否成功生成且内容有效
++
++    // 例如,打开文件并读取内容,检查是否为有效的PEM格式密钥
++
++    // 但由于这是一个简单的测试示例,我们省略了这些步骤
++
++
++
++    // 清理生成的文件
++
++    QFile::remove(priKeyFile);
++
++    QFile::remove(pubKeyFile);
++
++}
++
++
++
++// 测试密钥生成并保存到QByteArray
++
++TEST_F(CommonTest, GenerateKeyPairToByteArray) {
++
++    QByteArray privateKey;
++
++    QByteArray publicKey;
++
++    rsac.generateKeyPair(privateKey, publicKey, 1024);
++
++
++
++    // 检查生成的密钥是否非空
++
++    EXPECT_FALSE(privateKey.isEmpty());
++
++    EXPECT_FALSE(publicKey.isEmpty());
++
++
++
++    // 这里可以添加额外的检查来验证密钥的有效性
++
++    // 例如,使用OpenSSL函数解析生成的密钥并检查其属性
++
++    // 但由于这是一个简单的测试示例,我们省略了这些步骤
++
++}
++
++
++
++// 测试加密和解密
++
++TEST_F(CommonTest, EncryptDecrypt) {
++
++    QByteArray privateKey;
++
++    QByteArray publicKey;
++
++    rsac.generateKeyPair(privateKey, publicKey, 1024);
++
++
++
++    QByteArray plaintext = "Hello, RSA!";
++
++    QByteArray ciphertext;
++
++    QByteArray decryptedtext;
++
++
++
++    bool encryptResult = rsac.encrypt(plaintext, ciphertext, publicKey);
++
++    EXPECT_TRUE(encryptResult);
++
++
++
++    bool decryptResult = rsac.decrypt(ciphertext, decryptedtext, privateKey);
++
++    EXPECT_TRUE(decryptResult);
++
++
++
++    EXPECT_EQ(plaintext, decryptedtext);
++
++}
++
++
++
++// 测试签名和验签
++
++TEST_F(CommonTest, SignVerify) {
++
++    QByteArray privateKey;
++
++    QByteArray publicKey;
++
++    rsac.generateKeyPair(privateKey, publicKey, 1024);
++
++
++
++    QByteArray message = "This is a test message.";
++
++    QByteArray signature;
++
++    bool signResult = rsac.sign(message, signature, privateKey);
++
++    EXPECT_TRUE(signResult);
++
++    bool verifyResult = rsac.verify(message, signature, publicKey);
++
++    EXPECT_TRUE(verifyResult);
++
++    // 尝试使用错误的消息进行验签,应该失败
++
++    bool verifyWithWrongMessageResult = rsac.verify("Wrong message.", signature, publicKey);
++
++    EXPECT_FALSE(verifyWithWrongMessageResult);
++
++}
+diff --git a/tests/unit_test_personal_data/unit_test_personal_data.cpp b/tests/unit_test_personal_data/unit_test_personal_data.cpp
+new file mode 100644
+index 0000000..6415f4a
+--- /dev/null
++++ b/tests/unit_test_personal_data/unit_test_personal_data.cpp
+@@ -0,0 +1,140 @@
++#include "../../src/lock-backend/personalizeddata.h"
++
++#include "gtest/gtest.h"
++#include <QJsonObject>
++#include <QJsonDocument>
++#include <QJsonArray>
++
++#include "stubext.h"
++using namespace stub_ext;
++
++// 测试夹具类,用于初始化和清理测试环境
++class PersonalizedDataTest : public ::testing::Test {
++protected:
++    PersonalizedData* personalizedData;
++//    PersonalizedDataMng* personalizedDataMng;
++
++    virtual void SetUp() override {
++        personalizedData = new PersonalizedData("testUser");
++//        personalizedDataMng = new PersonalizedDataMng();
++    }
++
++    virtual void TearDown() override {
++        delete personalizedData;
++//        delete personalizedDataMng;
++    }
++};
++
++
++// 测试 PersonalizedData 类的构造函数和析构函数
++TEST_F(PersonalizedDataTest, PersonalizedDataConstructorAndDestructor) {
++    // 构造函数应该正确设置用户
++    KYLINUSERDATAMNG::getInstance()->GetUserPtr(getenv("USER"));
++    KYLINUSERDATAMNG::getInstance()->GetConfInformation(getenv("USER"));
++//    KYLINUSERDATAMNG::getInstance()->__getUserInfomation();
++//    EXPECT_EQ(personalizedData->m_user, "testUser");
++}
++
++
++// 测试 PersonalizedData::getJsonData 函数
++TEST_F(PersonalizedDataTest, PersonalizedDataGetJsonData) {
++    QJsonObject json;
++    personalizedData->getJsonData(json);
++
++    // 检查生成的 JSON 对象是否包含正确的信息
++    EXPECT_EQ(json["user"].toString(), "testUser");
++    EXPECT_EQ(json["dateType"].toString(), "testDateType");
++    EXPECT_EQ(json["fontSize"].toInt(), 12);
++    EXPECT_EQ(json["timeType"].toInt(), 24);
++    EXPECT_EQ(json["backgroundPath"].toString(), "/path/to/background");
++    EXPECT_EQ(json["color"].toString(), "red");
++}
++
++
++// 测试 PersonalizedData::setJson 函数
++TEST_F(PersonalizedDataTest, PersonalizedDataSetJson) {
++    QJsonObject json;
++    json["user"] = "testUser";
++    json["dateType"] = "newDateType";
++    json["fontSize"] = 14;
++    json["timeType"] = 12;
++    json["backgroundPath"] = "/new/path/to/background";
++    json["color"] = "blue";
++    personalizedData->setJson(json);
++
++    // 检查属性是否被正确设置
++//    EXPECT_EQ(personalizedData->m_dateType, "newDateType");
++//    EXPECT_EQ(personalizedData->m_fontSize, 14);
++//    EXPECT_EQ(personalizedData->m_timeType, 12);
++//    EXPECT_EQ(personalizedData->m_backgroundPath, "/new/path/to/background");
++//    EXPECT_EQ(personalizedData->m_color, "blue");
++}
++
++
++//// 测试 PersonalizedDataMng::GetConfInformation 函数
++//TEST_F(PersonalizedDataTest, PersonalizedDataMngGetConfInformation) {
++//    // 先添加一些用户信息
++//    personalizedDataMng->m_userPersonalizedData["testUser"] = KylinUserDatePtr(new PersonalizedData("testUser"));
++//    personalizedDataMng->m_userPersonalizedData["testUser"]->m_dateType = "testDateType";
++//    personalizedDataMng->m_userPersonalizedData["testUser"]->m_fontSize = 12;
++//    personalizedDataMng->m_userPersonalizedData["testUser"]->m_timeType = 24;
++//    personalizedDataMng->m_userPersonalizedData["testUser"]->m_backgroundPath = "/path/to/background";
++//    personalizedDataMng->m_userPersonalizedData["testUser"]->m_color = "red";
++
++//    QString jsonStr = personalizedDataMng->GetConfInformation("testUser");
++//    QJsonDocument doc = QJsonDocument::fromJson(jsonStr.toUtf8());
++//    QJsonObject json = doc.object();
++//    QJsonObject userJson = json["testUser"].toObject();
++
++//    // 检查生成的 JSON 对象是否包含正确的信息
++//    EXPECT_EQ(userJson["greeter"]["dateType"].toString(), "testDateType");
++//    EXPECT_EQ(userJson["greeter"]["fontSize"].toInt(), 12);
++//    EXPECT_EQ(userJson["greeter"]["timeType"].toInt(), 24);
++//    EXPECT_EQ(userJson["greeter"]["backgroundPath"].toString(), "/path/to/background");
++//    EXPECT_EQ(userJson["greeter"]["color"].toString(), "red");
++//}
++
++
++//// 测试 PersonalizedDataMng::GetUserPtr 函数
++//TEST_F(PersonalizedDataTest, PersonalizedDataMngGetUserPtr) {
++//    personalizedDataMng->m_userPersonalizedData["testUser"] = KylinUserDatePtr(new PersonalizedData("testUser"));
++//    KylinUserDatePtr userPtr = personalizedDataMng->GetUserPtr("testUser");
++//    // 检查是否能正确获取用户指针
++//    EXPECT_NE(userPtr, nullptr);
++//    EXPECT_EQ(userPtr->m_user, "testUser");
++//}
++
++
++//// 测试 PersonalizedDataMng::updateUserInformation 函数
++//TEST_F(PersonalizedDataTest, PersonalizedDataMngUpdateUserInformation) {
++//    QString jsonString = "{\"user\":\"testUser\",\"operation\":0,\"greeter\":{\"dateType\":\"newDateType\",\"fontSize\":14,\"timeType\":12,\"backgroundPath\":\"/new/path/to/background\",\"color\":\"blue\"}}";
++//    personalizedDataMng->updateUserInformation(jsonString);
++//    KylinUserDatePtr userPtr = personalizedDataMng->GetUserPtr("testUser");
++//    // 检查用户信息是否被正确更新
++//    EXPECT_EQ(userPtr->m_dateType, "newDateType");
++//    EXPECT_EQ(userPtr->m_fontSize, 14);
++//    EXPECT_EQ(userPtr->m_timeType, 12);
++//    EXPECT_EQ(userPtr->m_backgroundPath, "/new/path/to/background");
++//    EXPECT_EQ(userPtr->m_color, "blue");
++//}
++
++
++//// 测试 PersonalizedDataMng::__getUserInfomation 函数
++//TEST_F(PersonalizedDataTest, PersonalizedDataMngGetUserInfomation) {
++//    // 模拟从 DBus 获取的用户信息
++//    QString jsonString = "{\"testUser\":{\"greeter\":{\"dateType\":\"newDateType\",\"fontSize\":14,\"timeType\":12,\"backgroundPath\":\"/new/path/to/background\",\"color\":\"blue\"}}";
++//    QDBusInterface iface(
++//        static_dbus_service_name, static_dbus_path, static_dbus_interface, QDBusConnection::systemBus());
++//    QDBusPendingCall pcall;
++//    QDBusPendingReply<QString> reply(jsonString);
++//    QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pcall, personalizedDataMng);
++//    personalizedDataMng->wait_for_finish(watcher);
++//    personalizedDataMng->__getUserInfomation();
++//    KylinUserDatePtr userPtr = personalizedDataMng->GetUserPtr("testUser");
++//    // 检查用户信息是否被正确设置
++//    EXPECT_EQ(userPtr->m_dateType, "newDateType");
++//    EXPECT_EQ(userPtr->m_fontSize, 14);
++//    EXPECT_EQ(userPtr->m_timeType, 12);
++//    EXPECT_EQ(userPtr->m_backgroundPath, "/new/path/to/background");
++//    EXPECT_EQ(userPtr->m_color, "blue");
++//}
+diff --git a/tests/unit_test_screenlock/CMakeLists.txt b/tests/unit_test_screenlock/CMakeLists.txt
+new file mode 100644
+index 0000000..3e91d01
+--- /dev/null
++++ b/tests/unit_test_screenlock/CMakeLists.txt
+@@ -0,0 +1,150 @@
++# CMake 最低版本要求
++cmake_minimum_required(VERSION 3.10)
++
++find_package(Qt5 COMPONENTS Core DBus Network Test REQUIRED)
++find_package(OpenSSL REQUIRED)
++find_package(PkgConfig REQUIRED)
++
++# 包含 GTest 库和 pthread 库
++find_package(GTest REQUIRED)
++find_package(Threads REQUIRED)
++pkg_check_modules(GIOUNIX2 REQUIRED gio-unix-2.0)
++pkg_check_modules(GLIB2 REQUIRED glib-2.0 gio-2.0)
++pkg_check_modules(QGS REQUIRED gsettings-qt)
++pkg_check_modules(LIGHTDM-QT5-3 REQUIRED liblightdm-qt5-3)
++pkg_check_modules(LIBSYSTEMD REQUIRED libsystemd)
++# 查找pam动态库全路径并缓存到PAM_LIBRARIES变量
++find_library(PAM_LIBRARIES pam)
++
++# 设置 C++ 标准
++set(CMAKE_CXX_STANDARD 17)
++set(CMAKE_CXX_STANDARD_REQUIRED ON)
++
++ 
++# 开启代码覆盖率相关编译选项(对应QMAKE_LFLAGS和QMAKE_CXXFLAGS中代码覆盖率相关设置)
++set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fprofile-arcs -ftest-coverage --coverage -fno-inline -fno-access-control")
++set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fprofile-arcs -ftest-coverage")
++
++
++# 定义源文件列表,对应原来的SOURCES变量
++set(SOURCES
++    ../../src/lock-backend/authpamthread.cpp
++    ../../src/lock-backend/pamauthenticate.cpp
++    ../../src/lock-backend/lightdmhelper.cpp
++    ../../src/lock-backend/dbusupperinterface.cpp
++    ../../src/lock-backend/gsettingshelper.cpp
++    ../../src/lock-backend/bioauthenticate.cpp
++    ../../src/lock-backend/switchuserutils.cpp
++    ../../src/dbusifs/accountshelper.cpp
++    ../../src/userinfo.cpp
++    ../../src/common/global_utils.cpp
++    ../../src/common/configuration.cpp
++    ../../src/common/rsac.cpp
++    ../../src/dbusifs/giodbus.cpp
++    ../../src/dbusifs/uniauthservice.cpp
++    ../../src/lock-backend/securityuser.cpp
++    ../../src/dbusifs/freedesktophelper.cpp
++    ../../src/dbusifs/login1helper.cpp
++    ../../src/dbusifs/usdhelper.cpp
++    ../../src/dbusifs/upowerhelper.cpp
++    ../../src/dbusifs/sessionhelper.cpp
++    ../../src/dbusifs/dbusservermanager.cpp
++    ../../src/dbusifs/systemupgradehelper.cpp
++    ../../src/lock-backend/sessionwatcher.cpp
++    ../../src/dbusifs/kglobalaccelhelper.cpp
++    ../../src/dbusifs/libinputswitchevent.cpp
++    ../../src/lock-backend/personalizeddata.cpp
++    ../../src/dbusifs/biometrichelper.cpp
++    ../../src/dbusifs/device.cpp
++    ../../src/dbusifs/machinemodel.cpp
++    ../../src/dbusifs/enginedevice.cpp
++    ../../src/common/biodefines.cpp
++    ../../src/QtSingleApplication/qtlocalpeer.cpp
++    ../kt-test-utils/cpp-stub-ext/stub-shadow.cpp
++    ../../src/ukccplugins/sessiondbus/screenlockinterface.cpp
++    unit_test_screenlock.cpp
++    main.cpp
++)
++
++# 定义头文件列表,对应原来的HEADERS变量
++set(HEADERS
++    ../../src/lock-backend/authpamthread.h
++    ../../src/lock-backend/pamauthenticate.h
++    ../../src/lock-backend/lightdmhelper.h
++    ../../src/lock-backend/dbusupperinterface.h
++    ../../src/lock-backend/gsettingshelper.h
++    ../../src/lock-backend/bioauthenticate.h
++    ../../src/lock-backend/switchuserutils.h
++    ../../src/common/definetypes.h
++    ../../src/userinfo.h
++    ../../src/common/global_utils.h
++    ../../src/common/configuration.h
++    ../../src/common/rsac.h
++    ../../src/dbusifs/giodbus.h
++    ../../src/dbusifs/accountshelper.h
++    ../../src/common/configuration.h
++    ../../src/dbusifs/uniauthservice.h
++    ../../src/lock-backend/securityuser.h
++    ../../src/dbusifs/freedesktophelper.h
++    ../../src/dbusifs/login1helper.h
++    ../../src/dbusifs/usdhelper.h
++    ../../src/dbusifs/upowerhelper.h
++    ../../src/dbusifs/dbusservermanager.h
++    ../../src/dbusifs/sessionhelper.h
++    ../../src/dbusifs/systemupgradehelper.h
++    ../../src/lock-backend/sessionwatcher.h
++    ../../src/dbusifs/kglobalaccelhelper.h
++    ../../src/dbusifs/libinputswitchevent.h
++    ../../src/lock-backend/personalizeddata.h
++    ../../src/dbusifs/biometrichelper.h
++    ../../src/dbusifs/device.h
++    ../../src/dbusifs/enginedevice.h
++    ../../src/dbusifs/machinemodel.h
++    ../../src/common/biodefines.h
++    ../kt-test-utils/cpp-stub-ext/stubext.h
++    ../kt-test-utils/cpp-stub-ext/stub-shadow.h
++    ../../src/QtSingleApplication/qtlocalpeer.h
++    ../../src/ukccplugins/sessiondbus/screenlockinterface.h
++)
++
++# 包含头文件的路径设置,对应原来的INCLUDEPATH变量
++include_directories(
++    ${CMAKE_CURRENT_SOURCE_DIR}
++    ${CMAKE_CURRENT_SOURCE_DIR}/../kt-test-utils/cpp-stub
++    ${CMAKE_CURRENT_SOURCE_DIR}/../kt-test-utils/cpp-stub-ext
++    ${QGS_INCLUDE_DIRS}
++    ${Qt5Test_INCLUDE_DIRS}
++    ${LIGHTDM-QT5-3_INCLUDE_DIRS}
++    ${LIBSYSTEMD_INCLUDE_DIRS}
++    ${GIOUNIX2_INCLUDE_DIRS}
++    ${CMAKE_CURRENT_SOURCE_DIR}../../src/QtSingleApplication/
++)
++
++# 使用qt5_wrap_cpp生成元对象代码相关的源文件
++qt5_wrap_cpp(MOC_SOURCES ${HEADERS})
++
++# 添加可执行文件或库目标,将元对象代码源文件一起添加进去
++add_executable(unit_test_screenlock ${SOURCES} ${MOC_SOURCES})
++
++# 链接Qt相关的库
++target_link_libraries(unit_test_screenlock
++    Qt5::Core
++    Qt5::DBus
++    Qt5::Test
++    Qt5::Network
++    ${QGS_LIBRARIES}
++    ${PAM_LIBRARIES}
++    ${LIGHTDM-QT5-3_LIBRARIES}
++    ${LIBSYSTEMD_LIBRARIES}
++    OpenSSL::Crypto
++    -lukuiinputgatherclient
++    ${GIOUNIX2_LIBRARIES}
++)
++
++# 链接 GTest 库
++target_link_libraries(unit_test_screenlock
++    GTest::GTest
++    GTest::Main
++    Threads::Threads
++)
++
+diff --git a/tests/unit_test_screenlock/main.cpp b/tests/unit_test_screenlock/main.cpp
+new file mode 100644
+index 0000000..9250f9b
+--- /dev/null
++++ b/tests/unit_test_screenlock/main.cpp
+@@ -0,0 +1,8 @@
++#include <gtest/gtest.h>
++
++int main(int argc, char **argv)
++{
++    testing::InitGoogleTest(&argc, argv);
++
++    return RUN_ALL_TESTS();
++}
+diff --git a/tests/unit_test_screenlock/unit_test_screenlock.cpp b/tests/unit_test_screenlock/unit_test_screenlock.cpp
+new file mode 100644
+index 0000000..bdbe630
+--- /dev/null
++++ b/tests/unit_test_screenlock/unit_test_screenlock.cpp
+@@ -0,0 +1,96 @@
++/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
++ *
++ * Copyright (C) 2024 KylinSoft  Co., Ltd.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
++ *
++ */
++#include <gtest/gtest.h>
++#include <gtest/gtest-death-test.h>
++#include "../../src/ukccplugins/sessiondbus/screenlockinterface.h"
++#include <qgsettings.h>
++
++class ScreenlockInterfaceTest : public testing::Test
++{
++protected:
++    static void SetUpTestSuite()
++    {
++        m_pDbusUpperInterfaceDbus = new DbusUpperInterface();
++        m_pScreenlockInterface = new ScreenlockInterface(m_pDbusUpperInterfaceDbus, m_pDbusUpperInterfaceDbus);
++    }
++
++    static void TearDownTestSuite()
++    {
++        if (m_pScreenlockInterface) {
++            delete m_pScreenlockInterface;
++            m_pScreenlockInterface = nullptr;
++        }
++        delete m_pDbusUpperInterfaceDbus;
++        m_pDbusUpperInterfaceDbus = nullptr;
++    }
++
++    static ScreenlockInterface *m_pScreenlockInterface;
++    static DbusUpperInterface *m_pDbusUpperInterfaceDbus;
++};
++
++DbusUpperInterface *ScreenlockInterfaceTest::m_pDbusUpperInterfaceDbus = nullptr;
++ScreenlockInterface *ScreenlockInterfaceTest::m_pScreenlockInterface = nullptr;
++
++TEST_F(ScreenlockInterfaceTest, setShowOnLogin)
++{
++    bool oldValue = m_pScreenlockInterface->property("showOnLogin").toBool();
++    m_pScreenlockInterface->setShowOnLogin(false);
++    bool newValue = m_pScreenlockInterface->property("showOnLogin").toBool();
++    ASSERT_EQ(newValue, false);
++    m_pScreenlockInterface->setShowOnLogin(oldValue);
++}
++
++TEST_F(ScreenlockInterfaceTest, setWallpaper)
++{
++    QGSettings gset("org.ukui.screensaver");
++    std::string oldValue = gset.get("background").toString().toStdString();
++    m_pScreenlockInterface->setWallpaper("/usr/share/backgrounds/city.jpg");
++    std::string newValue = gset.get("background").toString().toStdString();
++    ASSERT_STREQ(newValue.c_str(), "/usr/share/backgrounds/city.jpg");
++    m_pScreenlockInterface->setWallpaper(oldValue.c_str());
++}
++
++TEST_F(ScreenlockInterfaceTest, resetDefault)
++{
++    QGSettings gset("org.ukui.screensaver");
++    std::string oldValue = gset.get("background").toString().toStdString();
++    m_pScreenlockInterface->resetDefault();
++    std::string newValue = gset.get("background").toString().toStdString();
++    ASSERT_STREQ(newValue.c_str(), "/usr/share/backgrounds/1-openkylin.jpg");
++    m_pScreenlockInterface->setWallpaper(oldValue.c_str());
++}
++
++TEST_F(ScreenlockInterfaceTest, getPreviewWallpapers)
++{
++    int size = m_pScreenlockInterface->getPreviewWallpapers().size();
++    ASSERT_GE(size, 0);
++}
++
++TEST_F(ScreenlockInterfaceTest, getSourceWallpapers)
++{
++    int size = m_pScreenlockInterface->getSourceWallpapers().size();
++    ASSERT_GE(size, 0);
++}
++
++TEST_F(ScreenlockInterfaceTest, getWallpaper)
++{
++    int size = m_pScreenlockInterface->getWallpaper().size();
++    ASSERT_GE(size, 0);
++}
+diff --git a/tests/unit_test_screensaver/CMakeLists.txt b/tests/unit_test_screensaver/CMakeLists.txt
+new file mode 100644
+index 0000000..aced7aa
+--- /dev/null
++++ b/tests/unit_test_screensaver/CMakeLists.txt
+@@ -0,0 +1,149 @@
++# CMake 最低版本要求
++cmake_minimum_required(VERSION 3.10)
++
++find_package(Qt5 COMPONENTS Core DBus Network Test REQUIRED)
++find_package(OpenSSL REQUIRED)
++find_package(PkgConfig REQUIRED)
++
++# 包含 GTest 库和 pthread 库
++find_package(GTest REQUIRED)
++find_package(Threads REQUIRED)
++pkg_check_modules(GIOUNIX2 REQUIRED gio-unix-2.0)
++pkg_check_modules(GLIB2 REQUIRED glib-2.0 gio-2.0)
++pkg_check_modules(QGS REQUIRED gsettings-qt)
++pkg_check_modules(LIGHTDM-QT5-3 REQUIRED liblightdm-qt5-3)
++pkg_check_modules(LIBSYSTEMD REQUIRED libsystemd)
++# 查找pam动态库全路径并缓存到PAM_LIBRARIES变量
++find_library(PAM_LIBRARIES pam)
++
++# 设置 C++ 标准
++set(CMAKE_CXX_STANDARD 17)
++set(CMAKE_CXX_STANDARD_REQUIRED ON)
++
++ 
++# 开启代码覆盖率相关编译选项(对应QMAKE_LFLAGS和QMAKE_CXXFLAGS中代码覆盖率相关设置)
++set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fprofile-arcs -ftest-coverage --coverage -fno-inline -fno-access-control")
++set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fprofile-arcs -ftest-coverage")
++
++# 定义源文件列表,对应原来的SOURCES变量
++set(SOURCES
++    ../../src/lock-backend/authpamthread.cpp
++    ../../src/lock-backend/pamauthenticate.cpp
++    ../../src/lock-backend/lightdmhelper.cpp
++    ../../src/lock-backend/dbusupperinterface.cpp
++    ../../src/lock-backend/gsettingshelper.cpp
++    ../../src/lock-backend/bioauthenticate.cpp
++    ../../src/lock-backend/switchuserutils.cpp
++    ../../src/dbusifs/accountshelper.cpp
++    ../../src/userinfo.cpp
++    ../../src/common/global_utils.cpp
++    ../../src/common/configuration.cpp
++    ../../src/common/rsac.cpp
++    ../../src/dbusifs/giodbus.cpp
++    ../../src/dbusifs/uniauthservice.cpp
++    ../../src/lock-backend/securityuser.cpp
++    ../../src/dbusifs/freedesktophelper.cpp
++    ../../src/dbusifs/login1helper.cpp
++    ../../src/dbusifs/usdhelper.cpp
++    ../../src/dbusifs/upowerhelper.cpp
++    ../../src/dbusifs/sessionhelper.cpp
++    ../../src/dbusifs/dbusservermanager.cpp
++    ../../src/dbusifs/systemupgradehelper.cpp
++    ../../src/lock-backend/sessionwatcher.cpp
++    ../../src/dbusifs/kglobalaccelhelper.cpp
++    ../../src/dbusifs/libinputswitchevent.cpp
++    ../../src/lock-backend/personalizeddata.cpp
++    ../../src/dbusifs/biometrichelper.cpp
++    ../../src/dbusifs/device.cpp
++    ../../src/dbusifs/machinemodel.cpp
++    ../../src/dbusifs/enginedevice.cpp
++    ../../src/common/biodefines.cpp
++    ../../src/QtSingleApplication/qtlocalpeer.cpp
++    ../kt-test-utils/cpp-stub-ext/stub-shadow.cpp
++    ../../src/ukccplugins/sessiondbus/screensaverinterface.cpp
++    unit_test_screensaver.cpp
++    main.cpp
++)
++
++# 定义头文件列表,对应原来的HEADERS变量
++set(HEADERS
++    ../../src/lock-backend/authpamthread.h
++    ../../src/lock-backend/pamauthenticate.h
++    ../../src/lock-backend/lightdmhelper.h
++    ../../src/lock-backend/dbusupperinterface.h
++    ../../src/lock-backend/gsettingshelper.h
++    ../../src/lock-backend/bioauthenticate.h
++    ../../src/lock-backend/switchuserutils.h
++    ../../src/common/definetypes.h
++    ../../src/userinfo.h
++    ../../src/common/global_utils.h
++    ../../src/common/configuration.h
++    ../../src/common/rsac.h
++    ../../src/dbusifs/giodbus.h
++    ../../src/dbusifs/accountshelper.h
++    ../../src/common/configuration.h
++    ../../src/dbusifs/uniauthservice.h
++    ../../src/lock-backend/securityuser.h
++    ../../src/dbusifs/freedesktophelper.h
++    ../../src/dbusifs/login1helper.h
++    ../../src/dbusifs/usdhelper.h
++    ../../src/dbusifs/upowerhelper.h
++    ../../src/dbusifs/dbusservermanager.h
++    ../../src/dbusifs/sessionhelper.h
++    ../../src/dbusifs/systemupgradehelper.h
++    ../../src/lock-backend/sessionwatcher.h
++    ../../src/dbusifs/kglobalaccelhelper.h
++    ../../src/dbusifs/libinputswitchevent.h
++    ../../src/lock-backend/personalizeddata.h
++    ../../src/dbusifs/biometrichelper.h
++    ../../src/dbusifs/device.h
++    ../../src/dbusifs/enginedevice.h
++    ../../src/dbusifs/machinemodel.h
++    ../../src/common/biodefines.h
++    ../kt-test-utils/cpp-stub-ext/stubext.h
++    ../kt-test-utils/cpp-stub-ext/stub-shadow.h
++    ../../src/QtSingleApplication/qtlocalpeer.h
++    ../../src/ukccplugins/sessiondbus/screensaverinterface.h
++)
++
++# 包含头文件的路径设置,对应原来的INCLUDEPATH变量
++include_directories(
++    ${CMAKE_CURRENT_SOURCE_DIR}
++    ${CMAKE_CURRENT_SOURCE_DIR}/../kt-test-utils/cpp-stub
++    ${CMAKE_CURRENT_SOURCE_DIR}/../kt-test-utils/cpp-stub-ext
++    ${QGS_INCLUDE_DIRS}
++    ${Qt5Test_INCLUDE_DIRS}
++    ${LIGHTDM-QT5-3_INCLUDE_DIRS}
++    ${LIBSYSTEMD_INCLUDE_DIRS}
++    ${GIOUNIX2_INCLUDE_DIRS}
++    ${CMAKE_CURRENT_SOURCE_DIR}../../src/QtSingleApplication/
++)
++
++# 使用qt5_wrap_cpp生成元对象代码相关的源文件
++qt5_wrap_cpp(MOC_SOURCES ${HEADERS})
++
++# 添加可执行文件或库目标,将元对象代码源文件一起添加进去
++add_executable(unit_test_screensaver ${SOURCES} ${MOC_SOURCES})
++
++# 链接Qt相关的库
++target_link_libraries(unit_test_screensaver
++    Qt5::Core
++    Qt5::DBus
++    Qt5::Test
++    Qt5::Network
++    ${QGS_LIBRARIES}
++    ${PAM_LIBRARIES}
++    ${LIGHTDM-QT5-3_LIBRARIES}
++    ${LIBSYSTEMD_LIBRARIES}
++    OpenSSL::Crypto
++    -lukuiinputgatherclient
++    ${GIOUNIX2_LIBRARIES}
++)
++
++# 链接 GTest 库
++target_link_libraries(unit_test_screensaver
++    GTest::GTest
++    GTest::Main
++    Threads::Threads
++)
++
+diff --git a/tests/unit_test_screensaver/main.cpp b/tests/unit_test_screensaver/main.cpp
+new file mode 100644
+index 0000000..9250f9b
+--- /dev/null
++++ b/tests/unit_test_screensaver/main.cpp
+@@ -0,0 +1,8 @@
++#include <gtest/gtest.h>
++
++int main(int argc, char **argv)
++{
++    testing::InitGoogleTest(&argc, argv);
++
++    return RUN_ALL_TESTS();
++}
+diff --git a/tests/unit_test_screensaver/unit_test_screensaver.cpp b/tests/unit_test_screensaver/unit_test_screensaver.cpp
+new file mode 100644
+index 0000000..2c27798
+--- /dev/null
++++ b/tests/unit_test_screensaver/unit_test_screensaver.cpp
+@@ -0,0 +1,141 @@
++/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
++ *
++ * Copyright (C) 2024 KylinSoft  Co., Ltd.
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
++ *
++ */
++#include <gtest/gtest.h>
++#include <gtest/gtest-death-test.h>
++#include "../../src/ukccplugins/sessiondbus/screensaverinterface.h"
++#include <qgsettings.h>
++
++class ScreensaverInterfaceTest : public testing::Test
++{
++protected:
++    static void SetUpTestSuite()
++    {
++        m_pDbusUpperInterfaceDbus = new DbusUpperInterface();
++        m_pScreenSaverInterface = new ScreensaverInterface(m_pDbusUpperInterfaceDbus, m_pDbusUpperInterfaceDbus);
++    }
++
++    static void TearDownTestSuite()
++    {
++        if (m_pScreenSaverInterface) {
++            delete m_pScreenSaverInterface;
++            m_pScreenSaverInterface = nullptr;
++        }
++        delete m_pDbusUpperInterfaceDbus;
++        m_pDbusUpperInterfaceDbus = nullptr;
++    }
++
++    static ScreensaverInterface *m_pScreenSaverInterface;
++    static DbusUpperInterface *m_pDbusUpperInterfaceDbus;
++};
++
++DbusUpperInterface *ScreensaverInterfaceTest::m_pDbusUpperInterfaceDbus = nullptr;
++ScreensaverInterface *ScreensaverInterfaceTest::m_pScreenSaverInterface = nullptr;
++
++TEST_F(ScreensaverInterfaceTest, setPreentryTime)
++{
++    int oldValue = m_pScreenSaverInterface->property("preentryTime").toInt();
++    m_pScreenSaverInterface->setPreentryTime(10);
++    int newValue = m_pScreenSaverInterface->property("preentryTime").toInt();
++    ASSERT_EQ(newValue, 10);
++    m_pScreenSaverInterface->setPreentryTime(oldValue);
++}
++
++TEST_F(ScreensaverInterfaceTest, setScreensaverType)
++{
++    QGSettings gsetting("org.ukui.screensaver");
++    std::string oldValue = m_pScreenSaverInterface->property("screensaverType").toString().toStdString();
++    m_pScreenSaverInterface->setScreensaverType("ukui");
++    std::string newValue = gsetting.get("mode").toString().toStdString();
++
++    ASSERT_STREQ(newValue.c_str(), "default-ukui");
++    m_pScreenSaverInterface->setScreensaverType(oldValue.c_str());
++}
++
++TEST_F(ScreensaverInterfaceTest, setShowBreakTimeUkuiCustom)
++{
++    bool oldValue = m_pScreenSaverInterface->property("showBreakTimeCustom").toBool();
++    m_pScreenSaverInterface->setShowBreakTimeCustom(true);
++    bool newValue = m_pScreenSaverInterface->property("showBreakTimeCustom").toBool();
++    ASSERT_EQ(newValue, true);
++    m_pScreenSaverInterface->setShowBreakTimeCustom(oldValue);
++}
++
++TEST_F(ScreensaverInterfaceTest, setShowBreakTimeUkui)
++{
++    bool oldValue = m_pScreenSaverInterface->property("showBreakTimeUkui").toBool();
++    m_pScreenSaverInterface->setShowBreakTimeUkui(false);
++    bool newValue = m_pScreenSaverInterface->property("showBreakTimeUkui").toBool();
++    ASSERT_EQ(newValue, false);
++    m_pScreenSaverInterface->setShowBreakTimeUkui(oldValue);
++}
++
++TEST_F(ScreensaverInterfaceTest, setScreenLockEnabled)
++{
++    bool oldValue = m_pScreenSaverInterface->property("screenLockEnabled").toBool();
++    m_pScreenSaverInterface->setScreenLockEnabled(false);
++    bool newValue = m_pScreenSaverInterface->property("screenLockEnabled").toBool();
++    ASSERT_EQ(newValue, false);
++    m_pScreenSaverInterface->setScreenLockEnabled(oldValue);
++}
++
++TEST_F(ScreensaverInterfaceTest, setCustomPath)
++{
++    std::string oldValue = m_pScreenSaverInterface->property("customPath").toString().toStdString();
++    m_pScreenSaverInterface->setCustomPath("/test/path");
++    std::string newValue = m_pScreenSaverInterface->property("customPath").toString().toStdString();
++    ASSERT_STREQ(newValue.c_str(), "/test/path");
++    m_pScreenSaverInterface->setCustomPath(oldValue.c_str());
++}
++
++TEST_F(ScreensaverInterfaceTest, setSwitchRandom)
++{
++    bool oldValue = m_pScreenSaverInterface->property("switchRandom").toBool();
++    m_pScreenSaverInterface->setSwitchRandom(false);
++    bool newValue = m_pScreenSaverInterface->property("switchRandom").toBool();
++    ASSERT_EQ(newValue, false);
++    m_pScreenSaverInterface->setSwitchRandom(oldValue);
++}
++
++TEST_F(ScreensaverInterfaceTest, setCycleTime)
++{
++    int oldValue = m_pScreenSaverInterface->property("cycleTime").toInt();
++    m_pScreenSaverInterface->setCycleTime(60);
++    int newValue = m_pScreenSaverInterface->property("cycleTime").toInt();
++    ASSERT_EQ(newValue, 60);
++    m_pScreenSaverInterface->setCycleTime(oldValue);
++}
++
++TEST_F(ScreensaverInterfaceTest, setCustomText)
++{
++    std::string oldValue = m_pScreenSaverInterface->property("customText").toString().toStdString();
++    m_pScreenSaverInterface->setCustomText("test custom text");
++    std::string newValue = m_pScreenSaverInterface->property("customText").toString().toStdString();
++    ASSERT_STREQ(newValue.c_str(), "test custom text");
++    m_pScreenSaverInterface->setCustomText(oldValue.c_str());
++}
++
++TEST_F(ScreensaverInterfaceTest, setCustomTextCentered)
++{
++    bool oldValue = m_pScreenSaverInterface->property("customTextCentered").toBool();
++    m_pScreenSaverInterface->setCustomTextCentered(false);
++    bool newValue = m_pScreenSaverInterface->property("customTextCentered").toBool();
++    ASSERT_EQ(newValue, false);
++    m_pScreenSaverInterface->setCustomTextCentered(oldValue);
++}
+diff --git a/tests/unit_test_session_helper/CMakeLists.txt b/tests/unit_test_session_helper/CMakeLists.txt
+new file mode 100644
+index 0000000..48b6590
+--- /dev/null
++++ b/tests/unit_test_session_helper/CMakeLists.txt
+@@ -0,0 +1,74 @@
++# CMake 最低版本要求
++cmake_minimum_required(VERSION 3.10)
++
++find_package(Qt5 COMPONENTS Core Gui DBus REQUIRED)
++find_package(PkgConfig REQUIRED)
++pkg_check_modules(QGS REQUIRED gsettings-qt)
++
++# 包含 GTest 库和 pthread 库
++find_package(GTest REQUIRED)
++find_package(Threads REQUIRED)
++
++# 设置 C++ 标准
++set(CMAKE_CXX_STANDARD 17)
++set(CMAKE_CXX_STANDARD_REQUIRED ON)
++
++
++# 开启代码覆盖率相关编译选项(对应QMAKE_LFLAGS和QMAKE_CXXFLAGS中代码覆盖率相关设置)
++
++set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fprofile-arcs -ftest-coverage --coverage -fno-inline -fno-access-control -fno-exceptions")
++set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fprofile-arcs -ftest-coverage")
++
++
++# 定义源文件列表,对应原来的SOURCES变量
++set(SOURCES
++    ../../src/dbusifs/sessionhelper.cpp
++    ../../src/dbusifs/login1helper.cpp
++    ../../src/dbusifs/dbusservermanager.cpp
++    ../../src/userinfo.cpp
++    ../../src/common/global_utils.cpp
++    ../../src/lock-backend/gsettingshelper.cpp
++    unit_test_session_helper.cpp
++    main.cpp
++)
++
++# 定义头文件列表,对应原来的HEADERS变量
++set(HEADERS
++        ../../src/common/definetypes.h
++        ../../src/userinfo.h
++        ../../src/common/global_utils.h
++        ../../src/dbusifs/sessionhelper.h
++        ../../src/dbusifs/login1helper.h
++        ../../src/dbusifs/dbusservermanager.h
++        ../../src/lock-backend/gsettingshelper.h
++)
++
++# 包含头文件的路径设置,对应原来的INCLUDEPATH变量
++include_directories(
++    ${CMAKE_CURRENT_SOURCE_DIR}
++    ${CMAKE_CURRENT_SOURCE_DIR}/../kt-test-utils/cpp-stub
++    ${CMAKE_CURRENT_SOURCE_DIR}/../kt-test-utils/cpp-stub-ext
++    ${QGS_INCLUDE_DIRS}
++)
++
++# 使用qt5_wrap_cpp生成元对象代码相关的源文件
++qt5_wrap_cpp(MOC_SOURCES ${HEADERS})
++
++# 添加可执行文件或库目标,将元对象代码源文件一起添加进去
++add_executable(unit_test_session_helper ${SOURCES} ${MOC_SOURCES})
++
++# 链接Qt相关的库
++target_link_libraries(unit_test_session_helper
++    Qt5::Core
++    Qt5::Gui
++    Qt5::DBus
++    ${QGS_LIBRARIES}
++)
++
++# 链接 GTest 库
++target_link_libraries(unit_test_session_helper
++    GTest::GTest
++    GTest::Main
++    Threads::Threads
++)
++
+diff --git a/tests/unit_test_session_helper/main.cpp b/tests/unit_test_session_helper/main.cpp
+new file mode 100644
+index 0000000..37b3fbf
+--- /dev/null
++++ b/tests/unit_test_session_helper/main.cpp
+@@ -0,0 +1,12 @@
++#include <gtest/gtest.h>
++#include <QGuiApplication>
++
++
++int main(int argc, char **argv)
++{
++    QGuiApplication a(argc, argv);
++    testing::InitGoogleTest(&argc, argv);
++
++    return RUN_ALL_TESTS();
++}
++
+diff --git a/tests/unit_test_session_helper/unit_test_session_helper.cpp b/tests/unit_test_session_helper/unit_test_session_helper.cpp
+new file mode 100644
+index 0000000..0abfdc5
+--- /dev/null
++++ b/tests/unit_test_session_helper/unit_test_session_helper.cpp
+@@ -0,0 +1,70 @@
++#include <gtest/gtest.h>
++#include <gtest/gtest-death-test.h>
++
++#include "../../src/dbusifs/sessionhelper.h"
++#include "../../src/dbusifs/login1helper.h"
++
++#include "stubext.h"
++
++using namespace stub_ext;
++
++class SessionHelperTest : public testing::Test, public QObject
++{
++protected:
++    static void SetUpTestSuite()
++    {
++        m_login1Helper = QSharedPointer<Login1Helper>(new Login1Helper(nullptr));
++        m_pSessionHelperDbus = new SessionHelper(m_login1Helper);
++    }
++
++    static void TearDownTestSuite()
++    {
++        delete m_pSessionHelperDbus;
++        m_pSessionHelperDbus = nullptr;
++    }
++
++    static SessionHelper *m_pSessionHelperDbus;
++    static QSharedPointer<Login1Helper> m_login1Helper;
++};
++
++SessionHelper *SessionHelperTest::m_pSessionHelperDbus = nullptr;
++QSharedPointer<Login1Helper> SessionHelperTest::m_login1Helper = nullptr;
++
++TEST_F(SessionHelperTest, canAction)
++{
++    bool value = m_pSessionHelperDbus->canAction(PowerHibernate);
++    bool value1 = m_pSessionHelperDbus->canAction(PowerSuspend);
++    bool value2 = m_pSessionHelperDbus->canAction(PowerMonitorOff);
++    bool value3 = m_pSessionHelperDbus->canAction(PowerLogout);
++    bool value4 = m_pSessionHelperDbus->canAction(PowerReboot);
++    bool value5 = m_pSessionHelperDbus->canAction(PowerShutdown);
++    bool value6 = m_pSessionHelperDbus->canAction(PowerSwitchUser);
++    //    bool value7 = m_pSessionHelperDbus->canAction(TestAction);
++    ASSERT_EQ(value, true);
++    ASSERT_EQ(value1, true);
++    ASSERT_EQ(value2, true);
++    ASSERT_EQ(value3, true);
++    ASSERT_EQ(value4, true);
++    ASSERT_EQ(value5, true);
++    ASSERT_EQ(value6, true);
++}
++
++TEST_F(SessionHelperTest, doAction)
++{
++    bool value = m_pSessionHelperDbus->doAction("Suspend");
++    ASSERT_EQ(value, true);
++}
++
++TEST_F(SessionHelperTest, getLockCheckStatus)
++{
++    QStringList value = m_pSessionHelperDbus->getLockCheckStatus("shutdown");
++    ASSERT_EQ(value.isEmpty(), true);
++}
++
++TEST_F(SessionHelperTest, playShutdownMusic)
++{
++    bool value = m_pSessionHelperDbus->playShutdownMusic("Logout");
++    m_pSessionHelperDbus->playShutdownMusic("Reboot");
++    m_pSessionHelperDbus->playShutdownMusic("SwitchUser");
++    ASSERT_EQ(value, true);
++}
+diff --git a/tests/unit_test_session_watcher/CMakeLists.txt b/tests/unit_test_session_watcher/CMakeLists.txt
+new file mode 100644
+index 0000000..4c5ad7d
+--- /dev/null
++++ b/tests/unit_test_session_watcher/CMakeLists.txt
+@@ -0,0 +1,77 @@
++# CMake 最低版本要求
++cmake_minimum_required(VERSION 3.10)
++
++find_package(Qt5 COMPONENTS Core Gui DBus X11Extras REQUIRED)
++find_package(PkgConfig REQUIRED)
++pkg_check_modules(QGS REQUIRED gsettings-qt)
++pkg_check_modules(GIOUNIX2 REQUIRED gio-unix-2.0)
++pkg_check_modules(GLIB2 REQUIRED glib-2.0 gio-2.0)
++# 包含 GTest 库和 pthread 库
++find_package(GTest REQUIRED)
++find_package(Threads REQUIRED)
++find_package(X11 REQUIRED)
++
++# 设置 C++ 标准
++set(CMAKE_CXX_STANDARD 17)
++set(CMAKE_CXX_STANDARD_REQUIRED ON)
++
++
++# 开启代码覆盖率相关编译选项(对应QMAKE_LFLAGS和QMAKE_CXXFLAGS中代码覆盖率相关设置)
++
++set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fprofile-arcs -ftest-coverage")
++set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fprofile-arcs -ftest-coverage")
++
++
++# 定义源文件列表,对应原来的SOURCES变量
++set(SOURCES
++    ../../src/lock-backend/sessionwatcher.cpp
++    ../../src/common/utils.cpp
++    ../../src/common/global_utils.cpp
++    ../../src/lock-backend/gsettingshelper.cpp
++    unit_test_session_watcher.cpp
++    main.cpp
++)
++
++# 定义头文件列表,对应原来的HEADERS变量
++set(HEADERS
++        ../../src/common/definetypes.h
++        ../../src/common/utils.h
++        ../../src/common/global_utils.h
++        ../../src/lock-backend/sessionwatcher.h
++        ../../src/lock-backend/gsettingshelper.h
++)
++
++# 包含头文件的路径设置,对应原来的INCLUDEPATH变量
++include_directories(
++    ${CMAKE_CURRENT_SOURCE_DIR}
++    ${CMAKE_CURRENT_SOURCE_DIR}/../kt-test-utils/cpp-stub
++    ${CMAKE_CURRENT_SOURCE_DIR}/../kt-test-utils/cpp-stub-ext
++    ${QGS_INCLUDE_DIRS}
++    ${GIOUNIX2_INCLUDE_DIRS}
++    ${X11_INCLUDE_DIRS}
++)
++
++# 使用qt5_wrap_cpp生成元对象代码相关的源文件
++qt5_wrap_cpp(MOC_SOURCES ${HEADERS})
++
++# 添加可执行文件或库目标,将元对象代码源文件一起添加进去
++add_executable(unit_test_session_watcher ${SOURCES} ${MOC_SOURCES})
++
++# 链接Qt相关的库
++target_link_libraries(unit_test_session_watcher
++    Qt5::Core
++    Qt5::Gui
++    Qt5::DBus
++    Qt5::X11Extras
++    ${QGS_LIBRARIES}
++    ${GIOUNIX2_LIBRARIES}
++    ${X11_LIBRARIES}
++)
++
++# 链接 GTest 库
++target_link_libraries(unit_test_session_watcher
++    GTest::GTest
++    GTest::Main
++    Threads::Threads
++)
++
+diff --git a/tests/unit_test_session_watcher/main.cpp b/tests/unit_test_session_watcher/main.cpp
+new file mode 100644
+index 0000000..37b3fbf
+--- /dev/null
++++ b/tests/unit_test_session_watcher/main.cpp
+@@ -0,0 +1,12 @@
++#include <gtest/gtest.h>
++#include <QGuiApplication>
++
++
++int main(int argc, char **argv)
++{
++    QGuiApplication a(argc, argv);
++    testing::InitGoogleTest(&argc, argv);
++
++    return RUN_ALL_TESTS();
++}
++
+diff --git a/tests/unit_test_session_watcher/unit_test_session_watcher.cpp b/tests/unit_test_session_watcher/unit_test_session_watcher.cpp
+new file mode 100644
+index 0000000..1b12ca6
+--- /dev/null
++++ b/tests/unit_test_session_watcher/unit_test_session_watcher.cpp
+@@ -0,0 +1,35 @@
++#include <gtest/gtest.h>
++
++#include <gtest/gtest.h>
++#include <gtest/gtest-death-test.h>
++#include "../../src/lock-backend/sessionwatcher.h"
++
++#include "stubext.h"
++using namespace stub_ext;
++
++class SessionWatcherTest : public testing::Test
++{
++protected:
++    QSharedPointer<GSettingsHelper> m_pGSettingsHelperDbus;
++    QSharedPointer<SessionWatcher> m_pSessionWatcherDbus;
++
++    void SetUp() override
++    {
++        m_pGSettingsHelperDbus = QSharedPointer<GSettingsHelper>(new GSettingsHelper());
++        m_pSessionWatcherDbus = QSharedPointer<SessionWatcher>(new SessionWatcher(m_pGSettingsHelperDbus));
++    }
++
++    void TearDown() override
++    {
++        m_pSessionWatcherDbus.reset();
++        m_pGSettingsHelperDbus.reset();
++    }
++};
++
++TEST_F(SessionWatcherTest, GetCurUserName)
++{
++    m_pSessionWatcherDbus->onStatusChanged(0);
++    m_pSessionWatcherDbus->onStatusChanged(1);
++    m_pSessionWatcherDbus->onStatusChanged(2);
++    m_pSessionWatcherDbus->onStatusChanged(3);
++}
+diff --git a/tests/unit_test_switch_user/CMakeLists.txt b/tests/unit_test_switch_user/CMakeLists.txt
+new file mode 100644
+index 0000000..65e67e4
+--- /dev/null
++++ b/tests/unit_test_switch_user/CMakeLists.txt
+@@ -0,0 +1,67 @@
++# CMake 最低版本要求
++cmake_minimum_required(VERSION 3.10)
++
++find_package(Qt5 COMPONENTS Core Gui DBus REQUIRED)
++find_package(PkgConfig REQUIRED)
++
++pkg_check_modules(GLIB2 REQUIRED glib-2.0 gio-2.0)
++pkg_check_modules(LIBSYSTEMD REQUIRED libsystemd)
++
++# 包含 GTest 库和 pthread 库
++find_package(GTest REQUIRED)
++find_package(Threads REQUIRED)
++
++# 设置 C++ 标准
++set(CMAKE_CXX_STANDARD 11)
++set(CMAKE_CXX_STANDARD_REQUIRED ON)
++
++
++# 开启代码覆盖率相关编译选项(对应QMAKE_LFLAGS和QMAKE_CXXFLAGS中代码覆盖率相关设置)
++set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fprofile-arcs -ftest-coverage --coverage -fno-inline -fno-access-control")
++set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fprofile-arcs -ftest-coverage")
++
++# 定义源文件列表,对应原来的SOURCES变量
++set(SOURCES
++    ../../src/lock-backend/switchuserutils.cpp
++    ../../src/common/global_utils.cpp
++    unit_test_switch_user.cpp
++    main.cpp
++)
++
++# 定义头文件列表,对应原来的HEADERS变量
++set(HEADERS
++        ../../src/lock-backend/switchuserutils.h
++        ../../src/common/global_utils.h
++)
++
++# 包含头文件的路径设置,对应原来的INCLUDEPATH变量
++include_directories(
++    ${CMAKE_CURRENT_SOURCE_DIR}
++    ${CMAKE_CURRENT_SOURCE_DIR}/../kt-test-utils/cpp-stub
++    ${CMAKE_CURRENT_SOURCE_DIR}/../kt-test-utils/cpp-stub-ext
++    ${GLIB2_INCLUDE_DIRS}
++    ${LIBSYSTEMD_INCLUDE_DIRS}
++)
++
++# 使用qt5_wrap_cpp生成元对象代码相关的源文件
++qt5_wrap_cpp(MOC_SOURCES ${HEADERS})
++
++# 添加可执行文件或库目标,将元对象代码源文件一起添加进去
++add_executable(unit_test_switch_user ${SOURCES} ${MOC_SOURCES})
++
++# 链接Qt相关的库
++target_link_libraries(unit_test_switch_user
++    Qt5::Core
++    Qt5::Gui
++    Qt5::DBus
++    ${LIBSYSTEMD_LIBRARIES}
++)
++
++# 链接 GTest 库
++target_link_libraries(unit_test_switch_user
++    GTest::GTest
++    GTest::Main
++    Threads::Threads
++    ${GLIB2_LIBRARIES}
++)
++
+diff --git a/tests/unit_test_switch_user/main.cpp b/tests/unit_test_switch_user/main.cpp
+new file mode 100644
+index 0000000..37b3fbf
+--- /dev/null
++++ b/tests/unit_test_switch_user/main.cpp
+@@ -0,0 +1,12 @@
++#include <gtest/gtest.h>
++#include <QGuiApplication>
++
++
++int main(int argc, char **argv)
++{
++    QGuiApplication a(argc, argv);
++    testing::InitGoogleTest(&argc, argv);
++
++    return RUN_ALL_TESTS();
++}
++
+diff --git a/tests/unit_test_switch_user/unit_test_switch_user.cpp b/tests/unit_test_switch_user/unit_test_switch_user.cpp
+new file mode 100644
+index 0000000..3a677fd
+--- /dev/null
++++ b/tests/unit_test_switch_user/unit_test_switch_user.cpp
+@@ -0,0 +1,71 @@
++#include <gtest/gtest.h>
++
++#include <gtest/gtest.h>
++#include <gtest/gtest-death-test.h>
++#include "../../src/common/global_utils.h"
++#include "../../src/lock-backend/switchuserutils.h"
++
++#include "stubext.h"
++using namespace stub_ext;
++
++class SwitchUserUtilsTest : public testing::Test
++{
++protected:
++    static void SetUpTestSuite()
++    {
++        m_pSwitchUserUtilsDbus = new SwitchUserUtils();
++    }
++
++    static void TearDownTestSuite()
++    {
++        delete m_pSwitchUserUtilsDbus;
++        m_pSwitchUserUtilsDbus = nullptr;
++    }
++
++    static SwitchUserUtils *m_pSwitchUserUtilsDbus;
++};
++
++SwitchUserUtils *SwitchUserUtilsTest::m_pSwitchUserUtilsDbus = nullptr;
++
++
++// 测试 GetCurUserName 函数
++TEST_F(SwitchUserUtilsTest, GetCurUserName) {
++    QString userName = m_pSwitchUserUtilsDbus->GetCurUserName();
++    EXPECT_EQ(userName, "testuser");
++}
++
++
++// 测试 GetUidByName 函数
++TEST_F(SwitchUserUtilsTest, GetUidByName) {
++    int uid = m_pSwitchUserUtilsDbus->GetUidByName(getenv("USER"));
++    EXPECT_EQ(uid, 1000);
++}
++
++
++// 测试 GetUserUDII 函数
++TEST_F(SwitchUserUtilsTest, GetUserUDII) {
++    UserDisplayIfInfo userDisplayIfInfo = m_pSwitchUserUtilsDbus->GetUserUDII(getenv("USER"));
++
++
++    EXPECT_EQ(userDisplayIfInfo.strSeatPath, "/org/freedesktop/DisplayManager/Seat1");
++    EXPECT_EQ(userDisplayIfInfo.strUserName, "testuser");
++    EXPECT_EQ(userDisplayIfInfo.strSessionPath, "/org/freedesktop/DisplayManager/Session1");
++}
++
++
++// 测试 SwitchToUserSession 函数
++TEST_F(SwitchUserUtilsTest, SwitchToUserSession) {
++    UserDisplayIfInfo userDisplayIfInfo;
++    userDisplayIfInfo.strSeatPath = "/org/freedesktop/DisplayManager/Seat1";
++    userDisplayIfInfo.strUserName = "testuser";
++    userDisplayIfInfo.strSessionPath = "/org/freedesktop/DisplayManager/Session1";
++    int result = m_pSwitchUserUtilsDbus->SwitchToUserSession("/org/freedesktop/DisplayManager/Seat1", userDisplayIfInfo);
++    EXPECT_EQ(result, 0);
++}
++
++
++// 测试 SwitchToUserLock 函数
++TEST_F(SwitchUserUtilsTest, SwitchToUserLock) {
++    bool result = m_pSwitchUserUtilsDbus->SwitchToUserLock();
++    EXPECT_TRUE(result);
++}
+diff --git a/tests/unit_test_systemupgrade_helper/CMakeLists.txt b/tests/unit_test_systemupgrade_helper/CMakeLists.txt
+new file mode 100644
+index 0000000..7171972
+--- /dev/null
++++ b/tests/unit_test_systemupgrade_helper/CMakeLists.txt
+@@ -0,0 +1,59 @@
++# CMake 最低版本要求
++cmake_minimum_required(VERSION 3.10)
++
++find_package(Qt5 COMPONENTS Core Gui DBus REQUIRED)
++
++# 包含 GTest 库和 pthread 库
++find_package(GTest REQUIRED)
++find_package(Threads REQUIRED)
++
++# 设置 C++ 标准
++set(CMAKE_CXX_STANDARD 17)
++set(CMAKE_CXX_STANDARD_REQUIRED ON)
++
++
++# 开启代码覆盖率相关编译选项(对应QMAKE_LFLAGS和QMAKE_CXXFLAGS中代码覆盖率相关设置)
++
++set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fprofile-arcs -ftest-coverage")
++set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fprofile-arcs -ftest-coverage")
++
++
++# 定义源文件列表,对应原来的SOURCES变量
++set(SOURCES
++    ../../src/dbusifs/systemupgradehelper.cpp
++    unit_test_systemupgrade_helper.cpp
++    main.cpp
++)
++
++# 定义头文件列表,对应原来的HEADERS变量
++set(HEADERS
++    ../../src/dbusifs/systemupgradehelper.h
++)
++
++# 包含头文件的路径设置,对应原来的INCLUDEPATH变量
++include_directories(
++    ${CMAKE_CURRENT_SOURCE_DIR}
++    ${CMAKE_CURRENT_SOURCE_DIR}/../kt-test-utils/cpp-stub
++    ${CMAKE_CURRENT_SOURCE_DIR}/../kt-test-utils/cpp-stub-ext
++)
++
++# 使用qt5_wrap_cpp生成元对象代码相关的源文件
++qt5_wrap_cpp(MOC_SOURCES ${HEADERS})
++
++# 添加可执行文件或库目标,将元对象代码源文件一起添加进去
++add_executable(unit_test_systemupgrade_helper ${SOURCES} ${MOC_SOURCES})
++
++# 链接Qt相关的库
++target_link_libraries(unit_test_systemupgrade_helper
++    Qt5::Core
++    Qt5::Gui
++    Qt5::DBus
++)
++
++# 链接 GTest 库
++target_link_libraries(unit_test_systemupgrade_helper
++    GTest::GTest
++    GTest::Main
++    Threads::Threads
++)
++
+diff --git a/tests/unit_test_systemupgrade_helper/main.cpp b/tests/unit_test_systemupgrade_helper/main.cpp
+new file mode 100644
+index 0000000..37b3fbf
+--- /dev/null
++++ b/tests/unit_test_systemupgrade_helper/main.cpp
+@@ -0,0 +1,12 @@
++#include <gtest/gtest.h>
++#include <QGuiApplication>
++
++
++int main(int argc, char **argv)
++{
++    QGuiApplication a(argc, argv);
++    testing::InitGoogleTest(&argc, argv);
++
++    return RUN_ALL_TESTS();
++}
++
+diff --git a/tests/unit_test_systemupgrade_helper/unit_test_systemupgrade_helper.cpp b/tests/unit_test_systemupgrade_helper/unit_test_systemupgrade_helper.cpp
+new file mode 100644
+index 0000000..b839471
+--- /dev/null
++++ b/tests/unit_test_systemupgrade_helper/unit_test_systemupgrade_helper.cpp
+@@ -0,0 +1,45 @@
++#include <gtest/gtest.h>
++#include <gtest/gtest-death-test.h>
++
++#include "../../src/dbusifs/systemupgradehelper.h"
++
++#include "stubext.h"
++
++using namespace stub_ext;
++
++class SystemUpgradeHelperTest : public testing::Test
++{
++protected:
++    static void SetUpTestSuite()
++    {
++        m_pSystemUpgradeHelperDbus = new SystemUpgradeHelper();
++    }
++
++    static void TearDownTestSuite()
++    {
++        delete m_pSystemUpgradeHelperDbus;
++        m_pSystemUpgradeHelperDbus = nullptr;
++    }
++
++    static SystemUpgradeHelper *m_pSystemUpgradeHelperDbus;
++};
++
++SystemUpgradeHelper *SystemUpgradeHelperTest::m_pSystemUpgradeHelperDbus = nullptr;
++
++TEST_F(SystemUpgradeHelperTest, checkSystemUpgrade)
++{
++    bool value = m_pSystemUpgradeHelperDbus->checkSystemUpgrade();
++    ASSERT_EQ(value, false);
++}
++
++TEST_F(SystemUpgradeHelperTest, doUpgradeThenRboot)
++{
++    bool value = m_pSystemUpgradeHelperDbus->doUpgradeThenRboot();
++    ASSERT_EQ(value, false);
++}
++
++TEST_F(SystemUpgradeHelperTest, doUpgradeThenShutdown)
++{
++    bool value = m_pSystemUpgradeHelperDbus->doUpgradeThenShutdown();
++    ASSERT_EQ(value, false);
++}
+diff --git a/tests/unit_test_uniauth_service/CMakeLists.txt b/tests/unit_test_uniauth_service/CMakeLists.txt
+new file mode 100644
+index 0000000..b71fffa
+--- /dev/null
++++ b/tests/unit_test_uniauth_service/CMakeLists.txt
+@@ -0,0 +1,62 @@
++# CMake 最低版本要求
++cmake_minimum_required(VERSION 3.10)
++
++find_package(Qt5 COMPONENTS Core Gui DBus REQUIRED)
++
++# 包含 GTest 库和 pthread 库
++find_package(GTest REQUIRED)
++find_package(Threads REQUIRED)
++
++# 设置 C++ 标准
++set(CMAKE_CXX_STANDARD 17)
++set(CMAKE_CXX_STANDARD_REQUIRED ON)
++
++
++# 开启代码覆盖率相关编译选项(对应QMAKE_LFLAGS和QMAKE_CXXFLAGS中代码覆盖率相关设置)
++
++set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fprofile-arcs -ftest-coverage")
++set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fprofile-arcs -ftest-coverage")
++
++
++# 定义源文件列表,对应原来的SOURCES变量
++set(SOURCES
++    ../../src/dbusifs/uniauthservice.cpp
++    ../../src/dbusifs/freedesktophelper.cpp
++    unit_test_uniauth_service.cpp
++    main.cpp
++)
++
++# 定义头文件列表,对应原来的HEADERS变量
++set(HEADERS
++    ../../src/common/definetypes.h
++    ../../src/dbusifs/uniauthservice.h
++    ../../src/dbusifs/freedesktophelper.h
++)
++
++# 包含头文件的路径设置,对应原来的INCLUDEPATH变量
++include_directories(
++    ${CMAKE_CURRENT_SOURCE_DIR}
++    ${CMAKE_CURRENT_SOURCE_DIR}/../kt-test-utils/cpp-stub
++    ${CMAKE_CURRENT_SOURCE_DIR}/../kt-test-utils/cpp-stub-ext
++)
++
++# 使用qt5_wrap_cpp生成元对象代码相关的源文件
++qt5_wrap_cpp(MOC_SOURCES ${HEADERS})
++
++# 添加可执行文件或库目标,将元对象代码源文件一起添加进去
++add_executable(unit_test_uniauth_service ${SOURCES} ${MOC_SOURCES})
++
++# 链接Qt相关的库
++target_link_libraries(unit_test_uniauth_service
++    Qt5::Core
++    Qt5::Gui
++    Qt5::DBus
++)
++
++# 链接 GTest 库
++target_link_libraries(unit_test_uniauth_service
++    GTest::GTest
++    GTest::Main
++    Threads::Threads
++)
++
+diff --git a/tests/unit_test_uniauth_service/main.cpp b/tests/unit_test_uniauth_service/main.cpp
+new file mode 100644
+index 0000000..314ea99
+--- /dev/null
++++ b/tests/unit_test_uniauth_service/main.cpp
+@@ -0,0 +1,11 @@
++#include <gtest/gtest.h>
++#include <QGuiApplication>
++
++
++int main(int argc, char **argv)
++{
++    QGuiApplication a(argc, argv);
++    testing::InitGoogleTest(&argc, argv);
++
++    return RUN_ALL_TESTS();
++}
+diff --git a/tests/unit_test_uniauth_service/unit_test_uniauth_service.cpp b/tests/unit_test_uniauth_service/unit_test_uniauth_service.cpp
+new file mode 100644
+index 0000000..104af35
+--- /dev/null
++++ b/tests/unit_test_uniauth_service/unit_test_uniauth_service.cpp
+@@ -0,0 +1,159 @@
++#include <gtest/gtest.h>
++#include <gtest/gtest-death-test.h>
++
++#include "../../src/dbusifs/uniauthservice.h"
++
++#include "stubext.h"
++using namespace stub_ext;
++
++class UniAuthServiceTest : public testing::Test
++{
++//protected:
++//    static void SetUpTestSuite()
++//    {
++//        m_pUniAuthServiceDbus = new UniAuthService();
++//    }
++
++//    static void TearDownTestSuite()
++//    {
++//        delete m_pUniAuthServiceDbus;
++//        m_pUniAuthServiceDbus = nullptr;
++//    }
++
++//    static UniAuthService *m_pUniAuthServiceDbus;
++};
++
++//UniAuthService *UniAuthServiceTest::m_pUniAuthServiceDbus = nullptr;
++
++TEST_F(UniAuthServiceTest, DefaultDevice)
++{
++    if (UniAuthService::instance()) {
++        QString oldValue = UniAuthService::instance()->getDefaultDevice(getenv("USER"), 0);
++        UniAuthService::instance()->setDefaultDevice(0, "testValue");
++        QString newValue = UniAuthService::instance()->getDefaultDevice(getenv("USER"), 0);
++        std::string str = newValue.toStdString();
++        const char* cstr = str.data();
++        ASSERT_STREQ(cstr, "testValue");
++        UniAuthService::instance()->setDefaultDevice(0, oldValue);
++    }
++}
++
++TEST_F(UniAuthServiceTest, BioAuthStatus)
++{
++    if (UniAuthService::instance()) {
++        bool oldValue = UniAuthService::instance()->getBioAuthStatus(getenv("USER"), 0);
++        UniAuthService::instance()->setBioAuthStatus(0, !oldValue);
++        bool newValue = UniAuthService::instance()->getBioAuthStatus(getenv("USER"), 0);
++        ASSERT_EQ(newValue, !oldValue);
++        UniAuthService::instance()->setBioAuthStatus(0, oldValue);
++    }
++}
++
++TEST_F(UniAuthServiceTest, AllDefaultDevice)
++{
++    if (UniAuthService::instance()) {
++        QStringList defaultDeviceList = UniAuthService::instance()->getAllDefaultDevice(getenv("USER"));
++        ASSERT_EQ(defaultDeviceList.isEmpty(), false);
++    }
++}
++
++TEST_F(UniAuthServiceTest, MaxFailedTimes)
++{
++    if (UniAuthService::instance()) {
++        int maxFailedTimes = UniAuthService::instance()->getMaxFailedTimes();
++        ASSERT_EQ(maxFailedTimes, 5);
++    }
++}
++
++TEST_F(UniAuthServiceTest, QRCodeEnable)
++{
++    if (UniAuthService::instance()) {
++        bool qRCodeEnable = UniAuthService::instance()->getQRCodeEnable();
++        ASSERT_EQ(qRCodeEnable, true);
++    }
++}
++
++TEST_F(UniAuthServiceTest, DoubleAuth)
++{
++    if (UniAuthService::instance()) {
++        bool doubleAuth = UniAuthService::instance()->getDoubleAuth();
++        ASSERT_EQ(doubleAuth, false);
++    }
++}
++
++TEST_F(UniAuthServiceTest, UserBind)
++{
++    if (UniAuthService::instance()) {
++        bool userBind = UniAuthService::instance()->getUserBind();
++        ASSERT_EQ(userBind, false);
++    }
++}
++
++TEST_F(UniAuthServiceTest, IsShownInControlCenter)
++{
++    if (UniAuthService::instance()) {
++        bool isShownInControlCenter = UniAuthService::instance()->getIsShownInControlCenter();
++        ASSERT_EQ(isShownInControlCenter, false);
++    }
++}
++
++TEST_F(UniAuthServiceTest, HiddenSwitchButton)
++{
++    if (UniAuthService::instance()) {
++        bool hiddenSwitchButton = UniAuthService::instance()->getHiddenSwitchButton();
++        ASSERT_EQ(hiddenSwitchButton, false);
++    }
++}
++
++TEST_F(UniAuthServiceTest, getFTimeoutTimes)
++{
++    if (UniAuthService::instance()) {
++        int hiddenSwitchButton = UniAuthService::instance()->getFTimeoutTimes();
++        ASSERT_EQ(hiddenSwitchButton, 5);
++    }
++}
++
++TEST_F(UniAuthServiceTest, isActivatable)
++{
++    if (UniAuthService::instance()) {
++        bool hiddenSwitchButton = UniAuthService::instance()->isActivatable();
++        ASSERT_EQ(hiddenSwitchButton, true);
++    }
++}
++
++TEST_F(UniAuthServiceTest, isUserNameValid)
++{
++    if (UniAuthService::instance()) {
++        bool hiddenSwitchButton = UniAuthService::instance()->isUserNameValid(getenv("USER"));
++        ASSERT_EQ(hiddenSwitchButton, true);
++    }
++}
++
++TEST_F(UniAuthServiceTest, GetLastLoginUser)
++{
++    if (UniAuthService::instance()) {
++        QString hiddenSwitchButton = UniAuthService::instance()->GetLastLoginUser();
++        ASSERT_EQ(hiddenSwitchButton.isEmpty(), false);
++    }
++}
++
++TEST_F(UniAuthServiceTest, GetQuickLoginUser)
++{
++    if (UniAuthService::instance()) {
++        QString hiddenSwitchButton = UniAuthService::instance()->GetQuickLoginUser();
++        ASSERT_EQ(hiddenSwitchButton.isEmpty(), false);
++    }
++}
++
++TEST_F(UniAuthServiceTest, getUseFirstDevice)
++{
++    if (UniAuthService::instance()) {
++        bool value = UniAuthService::instance()->getUseFirstDevice();
++        UniAuthService::instance()->SwitchToUser(getenv("USER"));
++        UniAuthService::instance()->SwitchToGreeterUser(getenv("USER"));
++        UniAuthService::instance()->getWillSwitchUser();
++        UniAuthService::instance()->SaveLastLoginUser(UniAuthService::instance()->GetLastLoginUser());
++        UniAuthService::instance()->SaveQuickLoginUser(UniAuthService::instance()->GetQuickLoginUser());
++        ASSERT_EQ(value, false);
++    }
++}
+diff --git a/tests/unit_test_usd_helper/CMakeLists.txt b/tests/unit_test_usd_helper/CMakeLists.txt
+new file mode 100644
+index 0000000..fbf768a
+--- /dev/null
++++ b/tests/unit_test_usd_helper/CMakeLists.txt
+@@ -0,0 +1,57 @@
++# CMake 最低版本要求
++cmake_minimum_required(VERSION 3.10)
++
++find_package(Qt5 COMPONENTS Core Gui DBus REQUIRED)
++
++# 包含 GTest 库和 pthread 库
++find_package(GTest REQUIRED)
++find_package(Threads REQUIRED)
++
++# 设置 C++ 标准
++set(CMAKE_CXX_STANDARD 17)
++set(CMAKE_CXX_STANDARD_REQUIRED ON)
++
++
++# 开启代码覆盖率相关编译选项(对应QMAKE_LFLAGS和QMAKE_CXXFLAGS中代码覆盖率相关设置)
++set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fprofile-arcs -ftest-coverage --coverage -fno-inline -fno-access-control")
++set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fprofile-arcs -ftest-coverage")
++
++# 定义源文件列表,对应原来的SOURCES变量
++set(SOURCES
++    ../../src/dbusifs/usdhelper.cpp
++    unit_test_usd_helper.cpp
++    main.cpp
++)
++
++# 定义头文件列表,对应原来的HEADERS变量
++set(HEADERS
++        ../../src/dbusifs/usdhelper.h
++)
++
++# 包含头文件的路径设置,对应原来的INCLUDEPATH变量
++include_directories(
++    ${CMAKE_CURRENT_SOURCE_DIR}
++    ${CMAKE_CURRENT_SOURCE_DIR}/../kt-test-utils/cpp-stub
++    ${CMAKE_CURRENT_SOURCE_DIR}/../kt-test-utils/cpp-stub-ext
++)
++
++# 使用qt5_wrap_cpp生成元对象代码相关的源文件
++qt5_wrap_cpp(MOC_SOURCES ${HEADERS})
++
++# 添加可执行文件或库目标,将元对象代码源文件一起添加进去
++add_executable(unit_test_usd_helper ${SOURCES} ${MOC_SOURCES})
++
++# 链接Qt相关的库
++target_link_libraries(unit_test_usd_helper
++    Qt5::Core
++    Qt5::Gui
++    Qt5::DBus
++)
++
++# 链接 GTest 库
++target_link_libraries(unit_test_usd_helper
++    GTest::GTest
++    GTest::Main
++    Threads::Threads
++)
++
+diff --git a/tests/unit_test_usd_helper/main.cpp b/tests/unit_test_usd_helper/main.cpp
+new file mode 100644
+index 0000000..37b3fbf
+--- /dev/null
++++ b/tests/unit_test_usd_helper/main.cpp
+@@ -0,0 +1,12 @@
++#include <gtest/gtest.h>
++#include <QGuiApplication>
++
++
++int main(int argc, char **argv)
++{
++    QGuiApplication a(argc, argv);
++    testing::InitGoogleTest(&argc, argv);
++
++    return RUN_ALL_TESTS();
++}
++
+diff --git a/tests/unit_test_usd_helper/unit_test_usd_helper.cpp b/tests/unit_test_usd_helper/unit_test_usd_helper.cpp
+new file mode 100644
+index 0000000..f9c90a0
+--- /dev/null
++++ b/tests/unit_test_usd_helper/unit_test_usd_helper.cpp
+@@ -0,0 +1,32 @@
++#include <gtest/gtest.h>
++#include <gtest/gtest-death-test.h>
++
++#include "../../src/dbusifs/usdhelper.h"
++
++#include "stubext.h"
++using namespace stub_ext;
++
++class UsdHelperTest : public testing::Test
++{
++protected:
++    static void SetUpTestSuite()
++    {
++        m_pUsdHelperDbus = new UsdHelper();
++    }
++
++    static void TearDownTestSuite()
++    {
++        delete m_pUsdHelperDbus;
++        m_pUsdHelperDbus = nullptr;
++    }
++
++    static UsdHelper *m_pUsdHelperDbus;
++};
++
++UsdHelper *UsdHelperTest::m_pUsdHelperDbus = nullptr;
++
++TEST_F(UsdHelperTest, usdExternalDoAction)
++{
++    bool value = m_pUsdHelperDbus->usdExternalDoAction(-1);
++    ASSERT_EQ(value, false);
++}
+diff --git a/ukccplugins_i18n_ts/CMakeLists.txt b/ukccplugins_i18n_ts/CMakeLists.txt
+new file mode 100644
+index 0000000..4eecf02
+--- /dev/null
++++ b/ukccplugins_i18n_ts/CMakeLists.txt
+@@ -0,0 +1,12 @@
++find_package(Qt5LinguistTools)
++
++file(GLOB ts_files *.ts)
++qt5_add_translation(qm_files ${ts_files})
++
++add_custom_target(ukccplugins_i18n
++	DEPENDS ${qm_files}
++	SOURCES ${ts_files}
++	)
++
++install(FILES ${ts_files} DESTINATION /usr/share/ukui-screensaver/ukccplugins/i18n/)
++install(FILES ${qm_files} DESTINATION /usr/share/ukui-screensaver/ukccplugins/i18n_qm/)
+diff --git a/ukccplugins_i18n_ts/bo.ts b/ukccplugins_i18n_ts/bo.ts
+new file mode 100644
+index 0000000..b9e3413
+--- /dev/null
++++ b/ukccplugins_i18n_ts/bo.ts
+@@ -0,0 +1,314 @@
++<?xml version="1.0" encoding="utf-8"?>
++<!DOCTYPE TS>
++<TS version="2.1">
++<context>
++    <name>Screenlock</name>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="39"/>
++        <source>Screenlock</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="187"/>
++        <source>Wallpaper files(*.jpg *.jpeg *.bmp *.dib *.png *.jfif *.jpe *.gif *.tif *.tiff *.wdp)</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="229"/>
++        <source>select custom wallpaper file</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="230"/>
++        <source>Select</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="231"/>
++        <source>Position: </source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="232"/>
++        <source>FileName: </source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="233"/>
++        <source>FileType: </source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="234"/>
++        <source>Cancel</source>
++        <translation type="unfinished"></translation>
++    </message>
++</context>
++<context>
++    <name>ScreenlockUi</name>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="74"/>
++        <source>Show picture of screenlock on screenlogin</source>
++        <translation type="unfinished"></translation>
++        <extra-contents_path>/Screenlock/Show picture of screenlock on screenlogin</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="87"/>
++        <source>Leave lock (System will be locked when the paired phone gone)</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="97"/>
++        <source>Specified device</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="114"/>
++        <source>No paired phone. Please turn to &apos;Bluetooth&apos; to pair.</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="53"/>
++        <source>Screenlock</source>
++        <translation type="unfinished"></translation>
++        <extra-contents_path>/Screenlock/Screenlock</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="168"/>
++        <source>Choose Picture</source>
++        <translation type="unfinished"></translation>
++        <extra-contents_path>/Wallpaper/Choose Picture</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="172"/>
++        <source>Local Pictures</source>
++        <translation type="unfinished"></translation>
++        <extra-contents_path>/Screenlock/Local Pictures</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="176"/>
++        <source>Online Pictures</source>
++        <translation type="unfinished"></translation>
++        <extra-contents_path>/Screenlock/Online Pictures</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="180"/>
++        <source>Reset To Default</source>
++        <translation type="unfinished"></translation>
++        <extra-contents_path>/Screenlock/Reset To Default</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="122"/>
++        <source>Bluetooth</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="239"/>
++        <source>No bluetooth adapter detected, can not use Leave Lock.</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="203"/>
++        <source>Monitor Off</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="205"/>
++        <source>Screensaver</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="200"/>
++        <source>Related Settings</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="204"/>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="206"/>
++        <source>Set</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="266"/>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="647"/>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="681"/>
++        <source>Please select device</source>
++        <translation type="unfinished"></translation>
++    </message>
++</context>
++<context>
++    <name>Screensaver</name>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="44"/>
++        <source>Screensaver</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="182"/>
++        <source>UKUI</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="182"/>
++        <source>Customize</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/>
++        <source>15min</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/>
++        <source>1hour</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/>
++        <source>Never</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="176"/>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="189"/>
++        <source>1min</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="189"/>
++        <source>5min</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="189"/>
++        <source>10min</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="189"/>
++        <source>30min</source>
++        <translation type="unfinished"></translation>
++    </message>
++</context>
++<context>
++    <name>ScreensaverUi</name>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="41"/>
++        <source>Screensaver</source>
++        <translation type="unfinished"></translation>
++        <extra-contents_path>/Screensaver/Screensaver</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="54"/>
++        <source>Idle time</source>
++        <translation type="unfinished"></translation>
++        <extra-contents_path>/Screensaver/Idle time</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="56"/>
++        <source>Screensaver program</source>
++        <translation type="unfinished"></translation>
++        <extra-contents_path>/Screensaver/Screensaver program</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="88"/>
++        <source>Screensaver source</source>
++        <translation type="unfinished"></translation>
++        <extra-contents_path>/Screensaver/Screensaver source</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="93"/>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="457"/>
++        <source>Select</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="114"/>
++        <source>Ordinal</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="115"/>
++        <source>Random</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="122"/>
++        <source>Random switching</source>
++        <translation type="unfinished"></translation>
++        <extra-contents_path>/Screensaver/Random switching</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="142"/>
++        <source>Switching time</source>
++        <translation type="unfinished"></translation>
++        <extra-contents_path>/Screensaver/Switching time</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="161"/>
++        <source>Text(up to 30 characters):</source>
++        <translation type="unfinished"></translation>
++        <extra-contents_path>/Screensaver/Text(up to 30 characters):</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="184"/>
++        <source>Text position</source>
++        <translation type="unfinished"></translation>
++        <extra-contents_path>/Screensaver/Text position</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="192"/>
++        <source>Centered</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="193"/>
++        <source>Randow(Bubble text)</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="215"/>
++        <source>Show rest time</source>
++        <translation type="unfinished"></translation>
++        <extra-contents_path>/Screensaver/Show rest time</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="226"/>
++        <source>Lock screen when screensaver boot</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="415"/>
++        <source>Wallpaper files(*.jpg *.jpeg *.bmp *.dib *.png *.jfif *.jpe *.gif *.tif *.tiff *.wdp *.svg)</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="456"/>
++        <source>select custom screensaver dir</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="458"/>
++        <source>Position: </source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="459"/>
++        <source>FileName: </source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="460"/>
++        <source>FileType: </source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="461"/>
++        <source>Cancel</source>
++        <translation type="unfinished"></translation>
++    </message>
++</context>
++</TS>
+diff --git a/ukccplugins_i18n_ts/bo_CN.ts b/ukccplugins_i18n_ts/bo_CN.ts
+new file mode 100644
+index 0000000..8056d74
+--- /dev/null
++++ b/ukccplugins_i18n_ts/bo_CN.ts
+@@ -0,0 +1,493 @@
++<?xml version="1.0" encoding="utf-8"?>
++<!DOCTYPE TS>
++<TS version="2.1" language="bo_CN">
++<context>
++    <name>Screenlock</name>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="39"/>
++        <source>Screenlock</source>
++        <translation>བརྙན་ཤེལ་གྱི་སྒོ་བརྒྱབ་པ</translation>
++    </message>
++    <message>
++        <source>Screenlock Interface</source>
++        <translation type="vanished">བརྙན་ཤེལ་གྱི་འབྲེལ་མཐུད།</translation>
++        <extra-contents_path>/Screenlock/Screenlock Interface</extra-contents_path>
++    </message>
++    <message>
++        <source>Show message on lock screen</source>
++        <translation type="vanished">ཟྭ་ངོས་སུ་ཆ་འཕྲིན་མངོན་པར་བྱས་ཡོད།</translation>
++    </message>
++    <message>
++        <source>Show picture of screenlock on screenlogin</source>
++        <translation type="vanished">བརྙན་ཤེལ་སྟེང་གི་བརྙན་ཤེལ་གྱི་པར་རིས་འགྲེམས་སྟོན་བྱས།</translation>
++        <extra-contents_path>/Screenlock/Show picture of screenlock on screenlogin</extra-contents_path>
++    </message>
++    <message>
++        <source>Related Settings</source>
++        <translation type="vanished">འབྲེལ་ལྡན་སྒྲིག་འགོད་</translation>
++    </message>
++    <message>
++        <source>Monitor Off</source>
++        <translation type="vanished">སྒོ་རྒྱག་འཆར་ཆས་</translation>
++    </message>
++    <message>
++        <source>Set</source>
++        <translation type="vanished">ཉི་ནུབ</translation>
++    </message>
++    <message>
++        <source>Screensaver</source>
++        <translation type="vanished">བརྙན་ཡོལ་སྲུང་སྐྱོབ་</translation>
++    </message>
++    <message>
++        <source>Lock screen when screensaver boot</source>
++        <translation type="vanished">བརྙན་ཤེལ་གྱི་ལྷམ་ཡུ་རིང་གི་དུས་སུ་བརྙན་ཤེལ་ལ་ཟྭ་རྒྱག</translation>
++        <extra-contents_path>/Screenlock/Lock screen when screensaver boot</extra-contents_path>
++    </message>
++    <message>
++        <source>Lock screen delay</source>
++        <translation type="vanished">བརྙན་ཤེལ་གྱི་དུས་ཚོད་འགོར་འགྱངས</translation>
++    </message>
++    <message>
++        <source>Online Picture</source>
++        <translation type="vanished">དྲ་ཐོག་པར་རིས།</translation>
++        <extra-contents_path>/Screenlock/Online Picture</extra-contents_path>
++    </message>
++    <message>
++        <source>1min</source>
++        <translation type="vanished">1min</translation>
++    </message>
++    <message>
++        <source>5min</source>
++        <translation type="vanished">5min</translation>
++    </message>
++    <message>
++        <source>10min</source>
++        <translation type="vanished">10min</translation>
++    </message>
++    <message>
++        <source>30min</source>
++        <translation type="vanished">30min</translation>
++    </message>
++    <message>
++        <source>45min</source>
++        <translation type="vanished">45min</translation>
++    </message>
++    <message>
++        <source>1hour</source>
++        <translation type="vanished">1hour</translation>
++    </message>
++    <message>
++        <source>2hour</source>
++        <translation type="vanished">2hour</translation>
++    </message>
++    <message>
++        <source>3hour</source>
++        <translation type="vanished">3hour</translation>
++    </message>
++    <message>
++        <source>Never</source>
++        <translation type="vanished">གཏན་ནས་བྱེད་མི་</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="187"/>
++        <source>Wallpaper files(*.jpg *.jpeg *.bmp *.dib *.png *.jfif *.jpe *.gif *.tif *.tiff *.wdp)</source>
++        <translation>Wallpaper files (*.jpg *.jpeg *.bmp *.dib *.png *.jfif *jpe *.gif *.tif *.tiff *wdp)</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="229"/>
++        <source>select custom wallpaper file</source>
++        <translation>ཡུལ་སྲོལ་གོམས་གཤིས་ཀྱི་གྱང་ཤོག་ཡིག་ཆ་བདམས་པ</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="230"/>
++        <source>Select</source>
++        <translation>བདམས་ཐོན་བྱུང་བ།</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="231"/>
++        <source>Position: </source>
++        <translation>གོ་གནས་ནི། </translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="232"/>
++        <source>FileName: </source>
++        <translation>ཡིག་ཆའི་མིང་ནི། </translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="233"/>
++        <source>FileType: </source>
++        <translation>ཡིག་ཆའི་རིགས་དབྱིབས་ནི། </translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="234"/>
++        <source>Cancel</source>
++        <translation>ཕྱིར་འཐེན།</translation>
++    </message>
++</context>
++<context>
++    <name>ScreenlockUi</name>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="74"/>
++        <source>Show picture of screenlock on screenlogin</source>
++        <translation>བརྙན་ཤེལ་སྟེང་གི་བརྙན་ཤེལ་གྱི་པར་རིས་འགྲེམས་སྟོན་བྱས།</translation>
++        <extra-contents_path>/Screenlock/Show picture of screenlock on screenlogin</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="87"/>
++        <source>Leave lock (System will be locked when the paired phone gone)</source>
++        <translation>ཟྭ་དང་བྲལ་ནས་(ལག་ཁྱེར་ཁ་པར་མེད་པར་གྱུར་རྗེས་མ་ལག་ལ་སྒོ་བརྒྱབ་ནས་གཏན་ཁེལ་བྱེད་ངེས་ )</translation>
++        <extra-contents_path>/Screenlock/Leave lock (System will be locked when the paired phone gone)</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="97"/>
++        <source>Specified device</source>
++        <translation>སྒྲིག་ཆས་དམིགས་འཛུགས་བྱ།</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="114"/>
++        <source>No paired phone. Please turn to &apos;Bluetooth&apos; to pair.</source>
++        <translation>ལག་ཁྱེར་ཁ་པར་ཆ་འགྲིག་མེད། &quot;སོ་སྔོན་པོ་&quot;རུ་བསྒྱུར་ནས་སྡེབ་སྒྲིག་བྱེད་རོགས།</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="53"/>
++        <source>Screenlock</source>
++        <translation>བརྙན་ཤེལ་གྱི་སྒོ་བརྒྱབ་པ</translation>
++        <extra-contents_path>/Screenlock/Screenlock</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="168"/>
++        <source>Choose Picture</source>
++        <translation>པར་རིས་འདེམས་པ།</translation>
++        <extra-contents_path>/Wallpaper/Choose Picture</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="172"/>
++        <source>Local Pictures</source>
++        <translation>ས་གནས་ཀྱི་རི་མོ།</translation>
++        <extra-contents_path>/Screenlock/Local Pictures</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="176"/>
++        <source>Online Pictures</source>
++        <translation>དྲ་ཐོག་པར་རིས།</translation>
++        <extra-contents_path>/Screenlock/Online Pictures</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="180"/>
++        <source>Reset To Default</source>
++        <translation>བསྐྱར་དུ་ཁ་ཆད་དང་འགལ་བའི་གནས་</translation>
++        <extra-contents_path>/Screenlock/Reset To Default</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="122"/>
++        <source>Bluetooth</source>
++        <translation>སོ་སྔོན་པོ།</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="239"/>
++        <source>No bluetooth adapter detected, can not use Leave Lock.</source>
++        <translation>སོ་སྔོན་པོའི་སྡེབ་སྦྱོར་ཡོ་བྱད་ལ་ཞིབ་དཔྱད་ཚད་ལེན་མ་བྱས་ན། བཀོད་སྤྱོད་བྱེད་ཐབས་མེད།</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="203"/>
++        <source>Monitor Off</source>
++        <translation>སྒོ་རྒྱག་འཆར་ཆས་</translation>
++        <extra-contents_path>/Screenlock/Monitor Off</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="205"/>
++        <source>Screensaver</source>
++        <translation>བརྙན་ཡོལ་སྲུང་སྐྱོབ་</translation>
++        <extra-contents_path>/Screenlock/Screensaver</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="200"/>
++        <source>Related Settings</source>
++        <translation>འབྲེལ་ལྡན་སྒྲིག་འགོད་</translation>
++        <extra-contents_path>/Screenlock/Related Settings</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="204"/>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="206"/>
++        <source>Set</source>
++        <translation>ཉི་ནུབ</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="266"/>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="647"/>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="681"/>
++        <source>Please select device</source>
++        <translation>སྒྲིག་ཆས་གདམ་ག་གནང་རོགས།</translation>
++    </message>
++</context>
++<context>
++    <name>Screensaver</name>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="44"/>
++        <source>Screensaver</source>
++        <translation>བརྙན་ཤེལ་གྱི་བརྙན་ཤེལ་འཕྲུལ་ཆས།</translation>
++    </message>
++    <message>
++        <source>Idle time</source>
++        <translation type="vanished">སྒྱིད་ལུག་གི་དུས་ཚོད།</translation>
++        <extra-contents_path>/Screensaver/Idle time</extra-contents_path>
++    </message>
++    <message>
++        <source>Lock screen when activating screensaver</source>
++        <translation type="vanished">བརྙན་ཤེལ་ལ་སྐུལ་སློང་བྱེད་སྐབས་བརྙན་ཤེལ་ལ་ཟྭ་རྒྱག་པ།</translation>
++    </message>
++    <message>
++        <source>Screensaver program</source>
++        <translation type="vanished">བརྙན་ཤེལ་གྱི་འཆར་གཞི།</translation>
++        <extra-contents_path>/Screensaver/Screensaver program</extra-contents_path>
++    </message>
++    <message>
++        <source>View</source>
++        <translation type="vanished">ལྟ་ཚུལ།</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="182"/>
++        <source>UKUI</source>
++        <translation>UKUI</translation>
++    </message>
++    <message>
++        <source>Blank_Only</source>
++        <translation type="vanished">Blank_Only</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="182"/>
++        <source>Customize</source>
++        <translation>ཡུལ་སྲོལ་གོམས་གཤིས་</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="189"/>
++        <source>5min</source>
++        <translation>5སྐར་མ་</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="189"/>
++        <source>10min</source>
++        <translation>10སྐར་མ་</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/>
++        <source>15min</source>
++        <translation>15སྐར་མ་</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="189"/>
++        <source>30min</source>
++        <translation>30སྐར་མ་</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/>
++        <source>1hour</source>
++        <translation>1ཆུ་ཚོད།</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/>
++        <source>Never</source>
++        <translation>གཏན་ནས་བྱེད་མི་</translation>
++    </message>
++    <message>
++        <source>Screensaver source</source>
++        <translation type="vanished">བརྙན་ཤེལ་གྱི་འབྱུང་ཁུངས།</translation>
++    </message>
++    <message>
++        <source>Select</source>
++        <translation type="vanished">བདམས་ཐོན་བྱུང་བ།</translation>
++    </message>
++    <message>
++        <source>Wallpaper files(*.jpg *.jpeg *.bmp *.dib *.png *.jfif *.jpe *.gif *.tif *.tiff *.wdp *.svg)</source>
++        <translation type="vanished">Wallpaper files (*.jpg *.jpeg *.bmp *.dib *.png *.jfif *jpe *.gif *.tif *.tiff *.svg)</translation>
++    </message>
++    <message>
++        <source>select custom screensaver dir</source>
++        <translation type="vanished">ཡུལ་སྲོལ་གོམས་གཤིས་ཀྱི་བརྙན་ཤེལ་གྲོན་ཆུང་བྱེད་མཁན་བདམས་པ་</translation>
++    </message>
++    <message>
++        <source>Position: </source>
++        <translation type="vanished">གོ་གནས་ནི། </translation>
++    </message>
++    <message>
++        <source>FileName: </source>
++        <translation type="vanished">ཡིག་ཆའི་མིང་ནི། </translation>
++    </message>
++    <message>
++        <source>FileType: </source>
++        <translation type="vanished">ཡིག་ཆའི་རིགས་དབྱིབས་ནི། </translation>
++    </message>
++    <message>
++        <source>Cancel</source>
++        <translation type="vanished">ཕྱིར་འཐེན།</translation>
++    </message>
++    <message>
++        <source>Switching time</source>
++        <translation type="vanished">བརྗེ་རེས་བྱེད་པའི་དུས་ཚོད།</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="176"/>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="189"/>
++        <source>1min</source>
++        <translation>1སྐར་མ་</translation>
++    </message>
++    <message>
++        <source>Ordinal</source>
++        <translation type="vanished">སྲོལ་ཡིག</translation>
++    </message>
++    <message>
++        <source>Random</source>
++        <translation type="vanished">སྐབས་བསྟུན་རང་བཞིན།</translation>
++    </message>
++    <message>
++        <source>Random switching</source>
++        <translation type="vanished">སྐབས་བསྟུན་གྱིས་བརྗེ་རེས་བྱེད་པ</translation>
++    </message>
++    <message>
++        <source>Text(up to 30 characters):</source>
++        <translation type="vanished">ཡི་གེ(ཆེས་མང་ན་ཡི་གེ་30ཡོད་པ་གཤམ་གསལ། )</translation>
++    </message>
++    <message>
++        <source>Show rest time</source>
++        <translation type="vanished">ངལ་གསོའི་དུས་ཚོད་མངོན་པ།</translation>
++    </message>
++    <message>
++        <source>Lock screen when screensaver boot</source>
++        <translation type="vanished">བརྙན་ཤེལ་གྱི་ལྷམ་ཡུ་རིང་གི་དུས་སུ་བརྙན་ཤེལ་ལ་ཟྭ་རྒྱག</translation>
++    </message>
++    <message>
++        <source>Text position</source>
++        <translation type="vanished">ཡི་གེའི་གོ་གནས།</translation>
++    </message>
++    <message>
++        <source>Centered</source>
++        <translation type="vanished">ལྟེ་བར་འཛིན་པ།</translation>
++    </message>
++    <message>
++        <source>Randow(Bubble text)</source>
++        <translation type="vanished">ལན་ཏུའོ་(ལྦུ་བ་ཅན་གྱི་ཡི་གེ)</translation>
++    </message>
++</context>
++<context>
++    <name>ScreensaverUi</name>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="41"/>
++        <source>Screensaver</source>
++        <translation>བརྙན་ཡོལ་སྲུང་སྐྱོབ་</translation>
++        <extra-contents_path>/Screensaver/Screensaver</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="54"/>
++        <source>Idle time</source>
++        <translation>སྒྱིད་ལུག་གི་དུས་ཚོད།</translation>
++        <extra-contents_path>/Screensaver/Idle time</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="56"/>
++        <source>Screensaver program</source>
++        <translation>བརྙན་ཤེལ་གྱི་འཆར་གཞི།</translation>
++        <extra-contents_path>/Screensaver/Screensaver program</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="88"/>
++        <source>Screensaver source</source>
++        <translation>བརྙན་ཤེལ་གྱི་འབྱུང་ཁུངས།</translation>
++        <extra-contents_path>/Screensaver/Screensaver source</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="93"/>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="457"/>
++        <source>Select</source>
++        <translation>བདམས་ཐོན་བྱུང་བ།</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="114"/>
++        <source>Ordinal</source>
++        <translation>སྲོལ་ཡིག</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="115"/>
++        <source>Random</source>
++        <translation>སྐབས་བསྟུན་རང་བཞིན།</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="122"/>
++        <source>Random switching</source>
++        <translation>སྐབས་བསྟུན་གྱིས་བརྗེ་རེས་བྱེད་པ</translation>
++        <extra-contents_path>/Screensaver/Random switching</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="142"/>
++        <source>Switching time</source>
++        <translation>བརྗེ་རེས་བྱེད་པའི་དུས་ཚོད།</translation>
++        <extra-contents_path>/Screensaver/Switching time</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="161"/>
++        <source>Text(up to 30 characters):</source>
++        <translation>ཡི་གེ(ཆེས་མང་ན་ཡི་གེ་30ཡོད་པ་གཤམ་གསལ། )</translation>
++        <extra-contents_path>/Screensaver/Text(up to 30 characters):</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="184"/>
++        <source>Text position</source>
++        <translation>ཡི་གེའི་གོ་གནས།</translation>
++        <extra-contents_path>/Screensaver/Text position</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="192"/>
++        <source>Centered</source>
++        <translation>ལྟེ་བར་འཛིན་པ།</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="193"/>
++        <source>Randow(Bubble text)</source>
++        <translation>ལན་ཏུའོ་(ལྦུ་བ་ཅན་གྱི་ཡི་གེ)</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="215"/>
++        <source>Show rest time</source>
++        <translation>ངལ་གསོའི་དུས་ཚོད་མངོན་པ།</translation>
++        <extra-contents_path>/Screensaver/Show rest time</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="226"/>
++        <source>Lock screen when screensaver boot</source>
++        <translation>བརྙན་ཤེལ་གྱི་ལྷམ་ཡུ་རིང་གི་དུས་སུ་བརྙན་ཤེལ་ལ་ཟྭ་རྒྱག</translation>
++        <extra-contents_path>/Screensaver/Lock screen when screensaver boot</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="415"/>
++        <source>Wallpaper files(*.jpg *.jpeg *.bmp *.dib *.png *.jfif *.jpe *.gif *.tif *.tiff *.wdp *.svg)</source>
++        <translation>Wallpaper files (*.jpg *.jpeg *.bmp *.dib *.png *.jfif *jpe *.gif *.tif *.tiff *.svg)</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="456"/>
++        <source>select custom screensaver dir</source>
++        <translation>ཡུལ་སྲོལ་གོམས་གཤིས་ཀྱི་བརྙན་ཤེལ་གྲོན་ཆུང་བྱེད་མཁན་བདམས་པ་</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="458"/>
++        <source>Position: </source>
++        <translation>གོ་གནས་ནི། </translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="459"/>
++        <source>FileName: </source>
++        <translation>ཡིག་ཆའི་མིང་ནི། </translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="460"/>
++        <source>FileType: </source>
++        <translation>ཡིག་ཆའི་རིགས་དབྱིབས་ནི། </translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="461"/>
++        <source>Cancel</source>
++        <translation>ཕྱིར་འཐེན།</translation>
++    </message>
++</context>
++</TS>
+diff --git a/ukccplugins_i18n_ts/de.ts b/ukccplugins_i18n_ts/de.ts
+new file mode 100644
+index 0000000..372401b
+--- /dev/null
++++ b/ukccplugins_i18n_ts/de.ts
+@@ -0,0 +1,642 @@
++<?xml version="1.0" encoding="utf-8"?>
++<!DOCTYPE TS>
++<TS version="2.1" language="de">
++<context>
++    <name>Screenlock</name>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="39"/>
++        <source>Screenlock</source>
++        <translation>Bildschirmsperre</translation>
++    </message>
++    <message>
++        <source>Screenlock Interface</source>
++        <translation type="vanished">锁屏界面</translation>
++    </message>
++    <message>
++        <source>Show message on lock screen</source>
++        <translation type="vanished">Nachricht auf dem Sperrbildschirm anzeigen</translation>
++    </message>
++    <message>
++        <source>Browse</source>
++        <translation type="vanished">浏览</translation>
++        <extra-contents_path>/Screenlock/Browse</extra-contents_path>
++    </message>
++    <message>
++        <source>Online Picture</source>
++        <translation type="vanished">线上图片</translation>
++        <extra-contents_path>/Screenlock/Online Picture</extra-contents_path>
++    </message>
++    <message>
++        <source>Local Pictures</source>
++        <translation type="vanished">Lokale Bilder</translation>
++        <extra-contents_path>/Screenlock/Local Pictures</extra-contents_path>
++    </message>
++    <message>
++        <source>Online Pictures</source>
++        <translation type="vanished">Online-Bilder</translation>
++        <extra-contents_path>/Screenlock/Online Pictures</extra-contents_path>
++    </message>
++    <message>
++        <source>Reset To Default</source>
++        <translation type="vanished">Auf Standard zurücksetzen</translation>
++        <extra-contents_path>/Screenlock/Reset To Default</extra-contents_path>
++    </message>
++    <message>
++        <source>Related Settings</source>
++        <translation type="vanished">Verwandte Einstellungen</translation>
++    </message>
++    <message>
++        <source>Screenlock Set</source>
++        <translation type="vanished">锁屏设置</translation>
++    </message>
++    <message>
++        <source>Lock screen when screensaver boot</source>
++        <translation type="vanished">激活屏保时锁定屏幕</translation>
++    </message>
++    <message>
++        <source>Lock screen delay</source>
++        <translation type="vanished">Verzögerung des Sperrbildschirms</translation>
++    </message>
++    <message>
++        <source>Min</source>
++        <translation type="vanished">分钟</translation>
++    </message>
++    <message>
++        <source>Select screenlock background</source>
++        <translation type="vanished">选择锁屏背景</translation>
++    </message>
++    <message>
++        <source>Browser online wp</source>
++        <translation type="vanished">浏览线上壁纸</translation>
++    </message>
++    <message>
++        <source>Browser local wp</source>
++        <translation type="vanished">浏览本地壁纸</translation>
++    </message>
++    <message>
++        <source>Show picture of screenlock on screenlogin</source>
++        <translation type="vanished">Bild der Bildschirmsperre beim Screenlogin anzeigen</translation>
++        <extra-contents_path>/Screenlock/Show picture of screenlock on screenlogin</extra-contents_path>
++    </message>
++    <message>
++        <source>Enabel screenlock</source>
++        <translation type="vanished">开启锁屏</translation>
++    </message>
++    <message>
++        <source>Open</source>
++        <translation type="obsolete">浏览</translation>
++    </message>
++    <message>
++        <source>screenlock</source>
++        <translation type="vanished">锁屏</translation>
++    </message>
++    <message>
++        <source>picture</source>
++        <translation type="obsolete">图片</translation>
++    </message>
++    <message>
++        <source>Never</source>
++        <translation type="vanished">Nie</translation>
++    </message>
++    <message>
++        <source>1m</source>
++        <translation type="vanished">1m</translation>
++    </message>
++    <message>
++        <source>5m</source>
++        <translation type="vanished">5m</translation>
++    </message>
++    <message>
++        <source>10m</source>
++        <translation type="vanished">10m</translation>
++    </message>
++    <message>
++        <source>30m</source>
++        <translation type="vanished">30m</translation>
++    </message>
++    <message>
++        <source>45m</source>
++        <translation type="vanished">45m</translation>
++    </message>
++    <message>
++        <source>1h</source>
++        <translation type="vanished">1h</translation>
++    </message>
++    <message>
++        <source>1.5h</source>
++        <translation type="vanished">1.5h</translation>
++    </message>
++    <message>
++        <source>3h</source>
++        <translation type="vanished">3h</translation>
++    </message>
++    <message>
++        <source>2h</source>
++        <translation type="vanished">2h</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="187"/>
++        <source>Wallpaper files(*.jpg *.jpeg *.bmp *.dib *.png *.jfif *.jpe *.gif *.tif *.tiff *.wdp)</source>
++        <translation>Hintergrunddateien (*.jpg *.jpeg *.bmp *.dib *.png *.jfif *.jpe *.gif *.tif *.tiff *.wdp)</translation>
++    </message>
++    <message>
++        <source>allFiles(*.*)</source>
++        <translation type="vanished">所有文件(*.*)</translation>
++    </message>
++    <message>
++        <source>1min</source>
++        <translation type="vanished">1min</translation>
++    </message>
++    <message>
++        <source>5min</source>
++        <translation type="vanished">5min</translation>
++    </message>
++    <message>
++        <source>10min</source>
++        <translation type="vanished">10min</translation>
++    </message>
++    <message>
++        <source>30min</source>
++        <translation type="vanished">30 Minuten</translation>
++    </message>
++    <message>
++        <source>45min</source>
++        <translation type="vanished">45 Minuten</translation>
++    </message>
++    <message>
++        <source>1hour</source>
++        <translation type="vanished">1 Stunde</translation>
++    </message>
++    <message>
++        <source>2hour</source>
++        <translation type="vanished">2 Stunden</translation>
++    </message>
++    <message>
++        <source>3hour</source>
++        <translation type="vanished">3 Stunden</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="229"/>
++        <source>select custom wallpaper file</source>
++        <translation>Wählen Sie eine benutzerdefinierte Hintergrundbilddatei aus</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="230"/>
++        <source>Select</source>
++        <translation>Auswählen</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="231"/>
++        <source>Position: </source>
++        <translation>Position: </translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="232"/>
++        <source>FileName: </source>
++        <translation>Dateiname: </translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="233"/>
++        <source>FileType: </source>
++        <translation>Dateityp: </translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="234"/>
++        <source>Cancel</source>
++        <translation>Abbrechen</translation>
++    </message>
++    <message>
++        <source>Monitor Off</source>
++        <translation type="vanished">Monitor aus</translation>
++    </message>
++    <message>
++        <source>Screensaver</source>
++        <translation type="vanished">Bildschirmschoner</translation>
++    </message>
++    <message>
++        <source>Set</source>
++        <translation type="vanished">Garnitur</translation>
++    </message>
++</context>
++<context>
++    <name>ScreenlockUi</name>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="74"/>
++        <source>Show picture of screenlock on screenlogin</source>
++        <translation type="unfinished">Bild der Bildschirmsperre beim Screenlogin anzeigen</translation>
++        <extra-contents_path>/Screenlock/Show picture of screenlock on screenlogin</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="87"/>
++        <source>Leave lock (System will be locked when the paired phone gone)</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="97"/>
++        <source>Specified device</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="114"/>
++        <source>No paired phone. Please turn to &apos;Bluetooth&apos; to pair.</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="53"/>
++        <source>Screenlock</source>
++        <translation type="unfinished">Bildschirmsperre</translation>
++        <extra-contents_path>/Screenlock/Screenlock</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="168"/>
++        <source>Choose Picture</source>
++        <translation type="unfinished"></translation>
++        <extra-contents_path>/Wallpaper/Choose Picture</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="172"/>
++        <source>Local Pictures</source>
++        <translation type="unfinished">Lokale Bilder</translation>
++        <extra-contents_path>/Screenlock/Local Pictures</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="176"/>
++        <source>Online Pictures</source>
++        <translation type="unfinished">Online-Bilder</translation>
++        <extra-contents_path>/Screenlock/Online Pictures</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="180"/>
++        <source>Reset To Default</source>
++        <translation type="unfinished">Auf Standard zurücksetzen</translation>
++        <extra-contents_path>/Screenlock/Reset To Default</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="122"/>
++        <source>Bluetooth</source>
++        <translation type="unfinished">蓝牙</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="239"/>
++        <source>No bluetooth adapter detected, can not use Leave Lock.</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="203"/>
++        <source>Monitor Off</source>
++        <translation type="unfinished">Monitor aus</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="205"/>
++        <source>Screensaver</source>
++        <translation type="unfinished">Bildschirmschoner</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="200"/>
++        <source>Related Settings</source>
++        <translation type="unfinished">Verwandte Einstellungen</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="204"/>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="206"/>
++        <source>Set</source>
++        <translation type="unfinished">Garnitur</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="266"/>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="647"/>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="681"/>
++        <source>Please select device</source>
++        <translation type="unfinished"></translation>
++    </message>
++</context>
++<context>
++    <name>Screensaver</name>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="44"/>
++        <source>Screensaver</source>
++        <translation>Bildschirmschoner</translation>
++    </message>
++    <message>
++        <source>Idle time</source>
++        <translation type="vanished">Stillstandszeit</translation>
++        <extra-contents_path>/Screensaver/Idle time</extra-contents_path>
++    </message>
++    <message>
++        <source>Lock screen when activating screensaver</source>
++        <translation type="vanished">Sperrbildschirm beim Aktivieren des Bildschirmschoners</translation>
++    </message>
++    <message>
++        <source>Enable screensaver</source>
++        <translation type="vanished">开启屏保</translation>
++    </message>
++    <message>
++        <source>Screensaver program</source>
++        <translation type="vanished">Bildschirmschoner-Programm</translation>
++        <extra-contents_path>/Screensaver/Screensaver program</extra-contents_path>
++    </message>
++    <message>
++        <source>idle time</source>
++        <translation type="vanished">等待时间</translation>
++    </message>
++    <message>
++        <source>Min</source>
++        <translation type="vanished">分钟</translation>
++    </message>
++    <message>
++        <source>Lock screen when screensaver boot</source>
++        <translation type="vanished">Sperrbildschirm beim Starten des Bildschirmschoners</translation>
++    </message>
++    <message>
++        <source>screensaver</source>
++        <translation type="vanished">屏保</translation>
++    </message>
++    <message>
++        <source>Default_ukui</source>
++        <translation type="vanished">默认屏保</translation>
++    </message>
++    <message>
++        <source>View</source>
++        <translation type="vanished">Ansehen</translation>
++    </message>
++    <message>
++        <source>Text(up to 30 characters):</source>
++        <translation type="vanished">Text (bis zu 30 Zeichen):</translation>
++    </message>
++    <message>
++        <source>Show rest time</source>
++        <translation type="vanished">Ruhezeit anzeigen</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="182"/>
++        <source>UKUI</source>
++        <translation>UKUI</translation>
++    </message>
++    <message>
++        <source>Blank_Only</source>
++        <translation type="vanished">Blank_Only</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="182"/>
++        <source>Customize</source>
++        <translation>Anpassen</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="189"/>
++        <source>5min</source>
++        <translation>5min</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="189"/>
++        <source>10min</source>
++        <translation>10min</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/>
++        <source>15min</source>
++        <translation>15 Minuten</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="189"/>
++        <source>30min</source>
++        <translation>30 Minuten</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/>
++        <source>1hour</source>
++        <translation>1 Stunde</translation>
++    </message>
++    <message>
++        <source>Screensaver source</source>
++        <translation type="vanished">Quelle des Bildschirmschoners</translation>
++    </message>
++    <message>
++        <source>Select</source>
++        <translation type="vanished">Auswählen</translation>
++    </message>
++    <message>
++        <source>Wallpaper files(*.jpg *.jpeg *.bmp *.dib *.png *.jfif *.jpe *.gif *.tif *.tiff *.wdp *.svg)</source>
++        <translation type="vanished">Hintergrundbilder (*.jpg *.jpeg *.bmp *.dib *.png *.jfif *.jpe *.gif *.tif *.tiff *.wdp *.svg)</translation>
++    </message>
++    <message>
++        <source>select custom screensaver dir</source>
++        <translation type="vanished">Benutzerdefiniertes Bildschirmschoner-Verzeichnis auswählen</translation>
++    </message>
++    <message>
++        <source>Position: </source>
++        <translation type="vanished">Position: </translation>
++    </message>
++    <message>
++        <source>FileName: </source>
++        <translation type="vanished">Dateiname: </translation>
++    </message>
++    <message>
++        <source>FileType: </source>
++        <translation type="vanished">Dateityp: </translation>
++    </message>
++    <message>
++        <source>Cancel</source>
++        <translation type="vanished">Abbrechen</translation>
++    </message>
++    <message>
++        <source>Switching time</source>
++        <translation type="vanished">Schaltzeit</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="176"/>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="189"/>
++        <source>1min</source>
++        <translation>1min</translation>
++    </message>
++    <message>
++        <source>Ordinal</source>
++        <translation type="vanished">Ordinale</translation>
++    </message>
++    <message>
++        <source>Random switching</source>
++        <translation type="vanished">Zufällige Umschaltung</translation>
++    </message>
++    <message>
++        <source>Display text</source>
++        <translation type="vanished">显示文本</translation>
++    </message>
++    <message>
++        <source>Enter text, up to 30 characters</source>
++        <translation type="vanished">输入文本,最多30个字符</translation>
++    </message>
++    <message>
++        <source>Text position</source>
++        <translation type="vanished">Position des Textes</translation>
++    </message>
++    <message>
++        <source>Centered</source>
++        <translation type="vanished">Zentriert</translation>
++    </message>
++    <message>
++        <source>Randow(Bubble text)</source>
++        <translation type="vanished">Randow(Sprechblasentext)</translation>
++    </message>
++    <message>
++        <source>1m</source>
++        <translation type="vanished">1m</translation>
++    </message>
++    <message>
++        <source>5m</source>
++        <translation type="vanished">5m</translation>
++    </message>
++    <message>
++        <source>10m</source>
++        <translation type="vanished">10m</translation>
++    </message>
++    <message>
++        <source>30m</source>
++        <translation type="vanished">30m</translation>
++    </message>
++    <message>
++        <source>45m</source>
++        <translation type="vanished">45m</translation>
++    </message>
++    <message>
++        <source>1h</source>
++        <translation type="vanished">1h</translation>
++    </message>
++    <message>
++        <source>1.5h</source>
++        <translation type="vanished">1.5h</translation>
++    </message>
++    <message>
++        <source>3h</source>
++        <translation type="vanished">3h</translation>
++    </message>
++    <message>
++        <source>Random</source>
++        <translation type="vanished">Zufällig</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/>
++        <source>Never</source>
++        <translation>Nie</translation>
++    </message>
++</context>
++<context>
++    <name>ScreensaverUi</name>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="41"/>
++        <source>Screensaver</source>
++        <translation type="unfinished">Bildschirmschoner</translation>
++        <extra-contents_path>/Screensaver/Screensaver</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="54"/>
++        <source>Idle time</source>
++        <translation type="unfinished">Stillstandszeit</translation>
++        <extra-contents_path>/Screensaver/Idle time</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="56"/>
++        <source>Screensaver program</source>
++        <translation type="unfinished">Bildschirmschoner-Programm</translation>
++        <extra-contents_path>/Screensaver/Screensaver program</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="88"/>
++        <source>Screensaver source</source>
++        <translation type="unfinished">Quelle des Bildschirmschoners</translation>
++        <extra-contents_path>/Screensaver/Screensaver source</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="93"/>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="457"/>
++        <source>Select</source>
++        <translation type="unfinished">Auswählen</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="114"/>
++        <source>Ordinal</source>
++        <translation type="unfinished">Ordinale</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="115"/>
++        <source>Random</source>
++        <translation type="unfinished">Zufällig</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="122"/>
++        <source>Random switching</source>
++        <translation type="unfinished">Zufällige Umschaltung</translation>
++        <extra-contents_path>/Screensaver/Random switching</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="142"/>
++        <source>Switching time</source>
++        <translation type="unfinished">Schaltzeit</translation>
++        <extra-contents_path>/Screensaver/Switching time</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="161"/>
++        <source>Text(up to 30 characters):</source>
++        <translation type="unfinished">Text (bis zu 30 Zeichen):</translation>
++        <extra-contents_path>/Screensaver/Text(up to 30 characters):</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="184"/>
++        <source>Text position</source>
++        <translation type="unfinished">Position des Textes</translation>
++        <extra-contents_path>/Screensaver/Text position</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="192"/>
++        <source>Centered</source>
++        <translation type="unfinished">Zentriert</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="193"/>
++        <source>Randow(Bubble text)</source>
++        <translation type="unfinished">Randow(Sprechblasentext)</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="215"/>
++        <source>Show rest time</source>
++        <translation type="unfinished">Ruhezeit anzeigen</translation>
++        <extra-contents_path>/Screensaver/Show rest time</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="226"/>
++        <source>Lock screen when screensaver boot</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="415"/>
++        <source>Wallpaper files(*.jpg *.jpeg *.bmp *.dib *.png *.jfif *.jpe *.gif *.tif *.tiff *.wdp *.svg)</source>
++        <translation type="unfinished">Hintergrundbilder (*.jpg *.jpeg *.bmp *.dib *.png *.jfif *.jpe *.gif *.tif *.tiff *.wdp *.svg)</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="456"/>
++        <source>select custom screensaver dir</source>
++        <translation type="unfinished">Benutzerdefiniertes Bildschirmschoner-Verzeichnis auswählen</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="458"/>
++        <source>Position: </source>
++        <translation type="unfinished">Position: </translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="459"/>
++        <source>FileName: </source>
++        <translation type="unfinished">Dateiname: </translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="460"/>
++        <source>FileType: </source>
++        <translation type="unfinished">Dateityp: </translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="461"/>
++        <source>Cancel</source>
++        <translation type="unfinished">Abbrechen</translation>
++    </message>
++</context>
++</TS>
+diff --git a/ukccplugins_i18n_ts/en.ts b/ukccplugins_i18n_ts/en.ts
+new file mode 100644
+index 0000000..fe95e83
+--- /dev/null
++++ b/ukccplugins_i18n_ts/en.ts
+@@ -0,0 +1,314 @@
++<?xml version="1.0" encoding="utf-8"?>
++<!DOCTYPE TS>
++<TS version="2.1">
++<context>
++    <name>Screenlock</name>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="39"/>
++        <source>Screenlock</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="187"/>
++        <source>Wallpaper files(*.jpg *.jpeg *.bmp *.dib *.png *.jfif *.jpe *.gif *.tif *.tiff *.wdp)</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="229"/>
++        <source>select custom wallpaper file</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="230"/>
++        <source>Select</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="231"/>
++        <source>Position: </source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="232"/>
++        <source>FileName: </source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="233"/>
++        <source>FileType: </source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="234"/>
++        <source>Cancel</source>
++        <translation type="unfinished"></translation>
++    </message>
++</context>
++<context>
++    <name>ScreenlockUi</name>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="74"/>
++        <source>Show picture of screenlock on screenlogin</source>
++        <translation type="unfinished"></translation>
++        <extra-contents_path>/Screenlock/Show picture of screenlock on screenlogin</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="87"/>
++        <source>Leave lock (System will be locked when the paired phone gone)</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="97"/>
++        <source>Specified device</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="114"/>
++        <source>No paired phone. Please turn to &apos;Bluetooth&apos; to pair.</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="53"/>
++        <source>Screenlock</source>
++        <translation type="unfinished"></translation>
++        <extra-contents_path>/Screenlock/Screenlock</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="168"/>
++        <source>Choose Picture</source>
++        <translation type="unfinished"></translation>
++        <extra-contents_path>/Wallpaper/Choose Picture</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="172"/>
++        <source>Local Pictures</source>
++        <translation type="unfinished"></translation>
++        <extra-contents_path>/Screenlock/Local Pictures</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="176"/>
++        <source>Online Pictures</source>
++        <translation type="unfinished"></translation>
++        <extra-contents_path>/Screenlock/Online Pictures</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="180"/>
++        <source>Reset To Default</source>
++        <translation type="unfinished"></translation>
++        <extra-contents_path>/Screenlock/Reset To Default</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="122"/>
++        <source>Bluetooth</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="239"/>
++        <source>No bluetooth adapter detected, can not use Leave Lock.</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="203"/>
++        <source>Monitor Off</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="205"/>
++        <source>Screensaver</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="200"/>
++        <source>Related Settings</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="204"/>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="206"/>
++        <source>Set</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="266"/>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="647"/>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="681"/>
++        <source>Please select device</source>
++        <translation type="unfinished"></translation>
++    </message>
++</context>
++<context>
++    <name>Screensaver</name>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="44"/>
++        <source>Screensaver</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="182"/>
++        <source>UKUI</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="182"/>
++        <source>Customize</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="189"/>
++        <source>5min</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="189"/>
++        <source>10min</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/>
++        <source>15min</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="189"/>
++        <source>30min</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/>
++        <source>1hour</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/>
++        <source>Never</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="176"/>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="189"/>
++        <source>1min</source>
++        <translation type="unfinished"></translation>
++    </message>
++</context>
++<context>
++    <name>ScreensaverUi</name>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="41"/>
++        <source>Screensaver</source>
++        <translation type="unfinished"></translation>
++        <extra-contents_path>/Screensaver/Screensaver</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="54"/>
++        <source>Idle time</source>
++        <translation type="unfinished"></translation>
++        <extra-contents_path>/Screensaver/Idle time</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="56"/>
++        <source>Screensaver program</source>
++        <translation type="unfinished"></translation>
++        <extra-contents_path>/Screensaver/Screensaver program</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="88"/>
++        <source>Screensaver source</source>
++        <translation type="unfinished"></translation>
++        <extra-contents_path>/Screensaver/Screensaver source</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="93"/>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="457"/>
++        <source>Select</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="114"/>
++        <source>Ordinal</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="115"/>
++        <source>Random</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="122"/>
++        <source>Random switching</source>
++        <translation type="unfinished"></translation>
++        <extra-contents_path>/Screensaver/Random switching</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="142"/>
++        <source>Switching time</source>
++        <translation type="unfinished"></translation>
++        <extra-contents_path>/Screensaver/Switching time</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="161"/>
++        <source>Text(up to 30 characters):</source>
++        <translation type="unfinished"></translation>
++        <extra-contents_path>/Screensaver/Text(up to 30 characters):</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="184"/>
++        <source>Text position</source>
++        <translation type="unfinished"></translation>
++        <extra-contents_path>/Screensaver/Text position</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="192"/>
++        <source>Centered</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="193"/>
++        <source>Randow(Bubble text)</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="215"/>
++        <source>Show rest time</source>
++        <translation type="unfinished"></translation>
++        <extra-contents_path>/Screensaver/Show rest time</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="226"/>
++        <source>Lock screen when screensaver boot</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="415"/>
++        <source>Wallpaper files(*.jpg *.jpeg *.bmp *.dib *.png *.jfif *.jpe *.gif *.tif *.tiff *.wdp *.svg)</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="456"/>
++        <source>select custom screensaver dir</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="458"/>
++        <source>Position: </source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="459"/>
++        <source>FileName: </source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="460"/>
++        <source>FileType: </source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="461"/>
++        <source>Cancel</source>
++        <translation type="unfinished"></translation>
++    </message>
++</context>
++</TS>
+diff --git a/ukccplugins_i18n_ts/en_US.ts b/ukccplugins_i18n_ts/en_US.ts
+new file mode 100644
+index 0000000..e66da77
+--- /dev/null
++++ b/ukccplugins_i18n_ts/en_US.ts
+@@ -0,0 +1,319 @@
++<?xml version="1.0" encoding="utf-8"?>
++<!DOCTYPE TS>
++<TS version="2.1">
++<context>
++    <name>Screenlock</name>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="39"/>
++        <source>Screenlock</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="187"/>
++        <source>Wallpaper files(*.jpg *.jpeg *.bmp *.dib *.png *.jfif *.jpe *.gif *.tif *.tiff *.wdp)</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="229"/>
++        <source>select custom wallpaper file</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="230"/>
++        <source>Select</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="231"/>
++        <source>Position: </source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="232"/>
++        <source>FileName: </source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="233"/>
++        <source>FileType: </source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="234"/>
++        <source>Cancel</source>
++        <translation type="unfinished"></translation>
++    </message>
++</context>
++<context>
++    <name>ScreenlockUi</name>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="74"/>
++        <source>Show picture of screenlock on screenlogin</source>
++        <translation type="unfinished"></translation>
++        <extra-contents_path>/Screenlock/Show picture of screenlock on screenlogin</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="87"/>
++        <source>Leave lock (System will be locked when the paired phone gone)</source>
++        <translation type="unfinished"></translation>
++        <extra-contents_path>/Screenlock/Leave lock (System will be locked when the paired phone gone)</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="97"/>
++        <source>Specified device</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="114"/>
++        <source>No paired phone. Please turn to &apos;Bluetooth&apos; to pair.</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="53"/>
++        <source>Screenlock</source>
++        <translation type="unfinished"></translation>
++        <extra-contents_path>/Screenlock/Screenlock</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="168"/>
++        <source>Choose Picture</source>
++        <translation type="unfinished"></translation>
++        <extra-contents_path>/Wallpaper/Choose Picture</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="172"/>
++        <source>Local Pictures</source>
++        <translation type="unfinished"></translation>
++        <extra-contents_path>/Screenlock/Local Pictures</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="176"/>
++        <source>Online Pictures</source>
++        <translation type="unfinished"></translation>
++        <extra-contents_path>/Screenlock/Online Pictures</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="180"/>
++        <source>Reset To Default</source>
++        <translation type="unfinished"></translation>
++        <extra-contents_path>/Screenlock/Reset To Default</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="122"/>
++        <source>Bluetooth</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="239"/>
++        <source>No bluetooth adapter detected, can not use Leave Lock.</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="203"/>
++        <source>Monitor Off</source>
++        <translation type="unfinished"></translation>
++        <extra-contents_path>/Screenlock/Monitor Off</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="205"/>
++        <source>Screensaver</source>
++        <translation type="unfinished"></translation>
++        <extra-contents_path>/Screenlock/Screensaver</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="200"/>
++        <source>Related Settings</source>
++        <translation type="unfinished"></translation>
++        <extra-contents_path>/Screenlock/Related Settings</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="204"/>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="206"/>
++        <source>Set</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="266"/>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="647"/>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="681"/>
++        <source>Please select device</source>
++        <translation type="unfinished"></translation>
++    </message>
++</context>
++<context>
++    <name>Screensaver</name>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="44"/>
++        <source>Screensaver</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="182"/>
++        <source>UKUI</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="182"/>
++        <source>Customize</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="189"/>
++        <source>5min</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="189"/>
++        <source>10min</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/>
++        <source>15min</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="189"/>
++        <source>30min</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/>
++        <source>1hour</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/>
++        <source>Never</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="176"/>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="189"/>
++        <source>1min</source>
++        <translation type="unfinished"></translation>
++    </message>
++</context>
++<context>
++    <name>ScreensaverUi</name>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="41"/>
++        <source>Screensaver</source>
++        <translation type="unfinished"></translation>
++        <extra-contents_path>/Screensaver/Screensaver</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="54"/>
++        <source>Idle time</source>
++        <translation type="unfinished"></translation>
++        <extra-contents_path>/Screensaver/Idle time</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="56"/>
++        <source>Screensaver program</source>
++        <translation type="unfinished"></translation>
++        <extra-contents_path>/Screensaver/Screensaver program</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="88"/>
++        <source>Screensaver source</source>
++        <translation type="unfinished"></translation>
++        <extra-contents_path>/Screensaver/Screensaver source</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="93"/>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="457"/>
++        <source>Select</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="114"/>
++        <source>Ordinal</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="115"/>
++        <source>Random</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="122"/>
++        <source>Random switching</source>
++        <translation type="unfinished"></translation>
++        <extra-contents_path>/Screensaver/Random switching</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="142"/>
++        <source>Switching time</source>
++        <translation type="unfinished"></translation>
++        <extra-contents_path>/Screensaver/Switching time</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="161"/>
++        <source>Text(up to 30 characters):</source>
++        <translation type="unfinished"></translation>
++        <extra-contents_path>/Screensaver/Text(up to 30 characters):</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="184"/>
++        <source>Text position</source>
++        <translation type="unfinished"></translation>
++        <extra-contents_path>/Screensaver/Text position</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="192"/>
++        <source>Centered</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="193"/>
++        <source>Randow(Bubble text)</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="215"/>
++        <source>Show rest time</source>
++        <translation type="unfinished"></translation>
++        <extra-contents_path>/Screensaver/Show rest time</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="226"/>
++        <source>Lock screen when screensaver boot</source>
++        <translation type="unfinished"></translation>
++        <extra-contents_path>/Screensaver/Lock screen when screensaver boot</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="415"/>
++        <source>Wallpaper files(*.jpg *.jpeg *.bmp *.dib *.png *.jfif *.jpe *.gif *.tif *.tiff *.wdp *.svg)</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="456"/>
++        <source>select custom screensaver dir</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="458"/>
++        <source>Position: </source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="459"/>
++        <source>FileName: </source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="460"/>
++        <source>FileType: </source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="461"/>
++        <source>Cancel</source>
++        <translation type="unfinished"></translation>
++    </message>
++</context>
++</TS>
+diff --git a/ukccplugins_i18n_ts/es.ts b/ukccplugins_i18n_ts/es.ts
+new file mode 100644
+index 0000000..05fb99a
+--- /dev/null
++++ b/ukccplugins_i18n_ts/es.ts
+@@ -0,0 +1,642 @@
++<?xml version="1.0" encoding="utf-8"?>
++<!DOCTYPE TS>
++<TS version="2.1" language="es">
++<context>
++    <name>Screenlock</name>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="39"/>
++        <source>Screenlock</source>
++        <translation>Bloqueo de pantalla</translation>
++    </message>
++    <message>
++        <source>Screenlock Interface</source>
++        <translation type="vanished">锁屏界面</translation>
++    </message>
++    <message>
++        <source>Show message on lock screen</source>
++        <translation type="vanished">Mostrar mensaje en la pantalla de bloqueo</translation>
++    </message>
++    <message>
++        <source>Browse</source>
++        <translation type="vanished">浏览</translation>
++        <extra-contents_path>/Screenlock/Browse</extra-contents_path>
++    </message>
++    <message>
++        <source>Online Picture</source>
++        <translation type="vanished">线上图片</translation>
++        <extra-contents_path>/Screenlock/Online Picture</extra-contents_path>
++    </message>
++    <message>
++        <source>Local Pictures</source>
++        <translation type="vanished">Fotos locales</translation>
++        <extra-contents_path>/Screenlock/Local Pictures</extra-contents_path>
++    </message>
++    <message>
++        <source>Online Pictures</source>
++        <translation type="vanished">Imágenes en línea</translation>
++        <extra-contents_path>/Screenlock/Online Pictures</extra-contents_path>
++    </message>
++    <message>
++        <source>Reset To Default</source>
++        <translation type="vanished">Restablecer a los valores predeterminados</translation>
++        <extra-contents_path>/Screenlock/Reset To Default</extra-contents_path>
++    </message>
++    <message>
++        <source>Related Settings</source>
++        <translation type="vanished">Ajustes relacionados</translation>
++    </message>
++    <message>
++        <source>Screenlock Set</source>
++        <translation type="vanished">锁屏设置</translation>
++    </message>
++    <message>
++        <source>Lock screen when screensaver boot</source>
++        <translation type="vanished">激活屏保时锁定屏幕</translation>
++    </message>
++    <message>
++        <source>Lock screen delay</source>
++        <translation type="vanished">Retraso de la pantalla de bloqueo</translation>
++    </message>
++    <message>
++        <source>Min</source>
++        <translation type="vanished">分钟</translation>
++    </message>
++    <message>
++        <source>Select screenlock background</source>
++        <translation type="vanished">选择锁屏背景</translation>
++    </message>
++    <message>
++        <source>Browser online wp</source>
++        <translation type="vanished">浏览线上壁纸</translation>
++    </message>
++    <message>
++        <source>Browser local wp</source>
++        <translation type="vanished">浏览本地壁纸</translation>
++    </message>
++    <message>
++        <source>Show picture of screenlock on screenlogin</source>
++        <translation type="vanished">Mostrar imagen de bloqueo de pantalla en el inicio de sesión en pantalla</translation>
++        <extra-contents_path>/Screenlock/Show picture of screenlock on screenlogin</extra-contents_path>
++    </message>
++    <message>
++        <source>Enabel screenlock</source>
++        <translation type="vanished">开启锁屏</translation>
++    </message>
++    <message>
++        <source>Open</source>
++        <translation type="obsolete">浏览</translation>
++    </message>
++    <message>
++        <source>screenlock</source>
++        <translation type="vanished">锁屏</translation>
++    </message>
++    <message>
++        <source>picture</source>
++        <translation type="obsolete">图片</translation>
++    </message>
++    <message>
++        <source>Never</source>
++        <translation type="vanished">Nunca</translation>
++    </message>
++    <message>
++        <source>1m</source>
++        <translation type="vanished">1m</translation>
++    </message>
++    <message>
++        <source>5m</source>
++        <translation type="vanished">5m</translation>
++    </message>
++    <message>
++        <source>10m</source>
++        <translation type="vanished">10m</translation>
++    </message>
++    <message>
++        <source>30m</source>
++        <translation type="vanished">30m</translation>
++    </message>
++    <message>
++        <source>45m</source>
++        <translation type="vanished">45m</translation>
++    </message>
++    <message>
++        <source>1h</source>
++        <translation type="vanished">1h</translation>
++    </message>
++    <message>
++        <source>1.5h</source>
++        <translation type="vanished">1.5h</translation>
++    </message>
++    <message>
++        <source>3h</source>
++        <translation type="vanished">3h</translation>
++    </message>
++    <message>
++        <source>2h</source>
++        <translation type="vanished">2h</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="187"/>
++        <source>Wallpaper files(*.jpg *.jpeg *.bmp *.dib *.png *.jfif *.jpe *.gif *.tif *.tiff *.wdp)</source>
++        <translation>Archivos de fondos de pantalla(*.jpg * .jpeg * .bmp * .dib * .png * .jfif *.jpe * .gif * .tif * .tiff *.wdp)</translation>
++    </message>
++    <message>
++        <source>allFiles(*.*)</source>
++        <translation type="vanished">所有文件(*.*)</translation>
++    </message>
++    <message>
++        <source>1min</source>
++        <translation type="vanished">1 minuto</translation>
++    </message>
++    <message>
++        <source>5min</source>
++        <translation type="vanished">5 minutos</translation>
++    </message>
++    <message>
++        <source>10min</source>
++        <translation type="vanished">10 minutos</translation>
++    </message>
++    <message>
++        <source>30min</source>
++        <translation type="vanished">30 minutos</translation>
++    </message>
++    <message>
++        <source>45min</source>
++        <translation type="vanished">45min</translation>
++    </message>
++    <message>
++        <source>1hour</source>
++        <translation type="vanished">1 hora</translation>
++    </message>
++    <message>
++        <source>2hour</source>
++        <translation type="vanished">2 horas</translation>
++    </message>
++    <message>
++        <source>3hour</source>
++        <translation type="vanished">3 horas</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="229"/>
++        <source>select custom wallpaper file</source>
++        <translation>Seleccionar archivo de fondo de pantalla personalizado</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="230"/>
++        <source>Select</source>
++        <translation>Escoger</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="231"/>
++        <source>Position: </source>
++        <translation>Posición: </translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="232"/>
++        <source>FileName: </source>
++        <translation>Nombre: </translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="233"/>
++        <source>FileType: </source>
++        <translation>Tipo de archivo: </translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="234"/>
++        <source>Cancel</source>
++        <translation>Cancelar</translation>
++    </message>
++    <message>
++        <source>Monitor Off</source>
++        <translation type="vanished">Monitor apagado</translation>
++    </message>
++    <message>
++        <source>Screensaver</source>
++        <translation type="vanished">Protector de pantalla</translation>
++    </message>
++    <message>
++        <source>Set</source>
++        <translation type="vanished">Poner</translation>
++    </message>
++</context>
++<context>
++    <name>ScreenlockUi</name>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="74"/>
++        <source>Show picture of screenlock on screenlogin</source>
++        <translation type="unfinished">Mostrar imagen de bloqueo de pantalla en el inicio de sesión en pantalla</translation>
++        <extra-contents_path>/Screenlock/Show picture of screenlock on screenlogin</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="87"/>
++        <source>Leave lock (System will be locked when the paired phone gone)</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="97"/>
++        <source>Specified device</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="114"/>
++        <source>No paired phone. Please turn to &apos;Bluetooth&apos; to pair.</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="53"/>
++        <source>Screenlock</source>
++        <translation type="unfinished">Bloqueo de pantalla</translation>
++        <extra-contents_path>/Screenlock/Screenlock</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="168"/>
++        <source>Choose Picture</source>
++        <translation type="unfinished"></translation>
++        <extra-contents_path>/Wallpaper/Choose Picture</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="172"/>
++        <source>Local Pictures</source>
++        <translation type="unfinished">Fotos locales</translation>
++        <extra-contents_path>/Screenlock/Local Pictures</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="176"/>
++        <source>Online Pictures</source>
++        <translation type="unfinished">Imágenes en línea</translation>
++        <extra-contents_path>/Screenlock/Online Pictures</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="180"/>
++        <source>Reset To Default</source>
++        <translation type="unfinished">Restablecer a los valores predeterminados</translation>
++        <extra-contents_path>/Screenlock/Reset To Default</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="122"/>
++        <source>Bluetooth</source>
++        <translation type="unfinished">蓝牙</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="239"/>
++        <source>No bluetooth adapter detected, can not use Leave Lock.</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="203"/>
++        <source>Monitor Off</source>
++        <translation type="unfinished">Monitor apagado</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="205"/>
++        <source>Screensaver</source>
++        <translation type="unfinished">Protector de pantalla</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="200"/>
++        <source>Related Settings</source>
++        <translation type="unfinished">Ajustes relacionados</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="204"/>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="206"/>
++        <source>Set</source>
++        <translation type="unfinished">Poner</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="266"/>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="647"/>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="681"/>
++        <source>Please select device</source>
++        <translation type="unfinished"></translation>
++    </message>
++</context>
++<context>
++    <name>Screensaver</name>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="44"/>
++        <source>Screensaver</source>
++        <translation>Protector de pantalla</translation>
++    </message>
++    <message>
++        <source>Idle time</source>
++        <translation type="vanished">Tiempo de inactividad</translation>
++        <extra-contents_path>/Screensaver/Idle time</extra-contents_path>
++    </message>
++    <message>
++        <source>Lock screen when activating screensaver</source>
++        <translation type="vanished">Pantalla de bloqueo al activar el protector de pantalla</translation>
++    </message>
++    <message>
++        <source>Enable screensaver</source>
++        <translation type="vanished">开启屏保</translation>
++    </message>
++    <message>
++        <source>Screensaver program</source>
++        <translation type="vanished">Programa protector de pantalla</translation>
++        <extra-contents_path>/Screensaver/Screensaver program</extra-contents_path>
++    </message>
++    <message>
++        <source>idle time</source>
++        <translation type="vanished">等待时间</translation>
++    </message>
++    <message>
++        <source>Min</source>
++        <translation type="vanished">分钟</translation>
++    </message>
++    <message>
++        <source>Lock screen when screensaver boot</source>
++        <translation type="vanished">Pantalla de bloqueo al arrancar el protector de pantalla</translation>
++    </message>
++    <message>
++        <source>screensaver</source>
++        <translation type="vanished">屏保</translation>
++    </message>
++    <message>
++        <source>Default_ukui</source>
++        <translation type="vanished">默认屏保</translation>
++    </message>
++    <message>
++        <source>View</source>
++        <translation type="vanished">Vista</translation>
++    </message>
++    <message>
++        <source>Text(up to 30 characters):</source>
++        <translation type="vanished">Texto (hasta 30 caracteres):</translation>
++    </message>
++    <message>
++        <source>Show rest time</source>
++        <translation type="vanished">Mostrar tiempo de descanso</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="182"/>
++        <source>UKUI</source>
++        <translation>UKUI</translation>
++    </message>
++    <message>
++        <source>Blank_Only</source>
++        <translation type="vanished">Blank_Only</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="182"/>
++        <source>Customize</source>
++        <translation>Personalizar</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="189"/>
++        <source>5min</source>
++        <translation>5 minutos</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="189"/>
++        <source>10min</source>
++        <translation>10 minutos</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/>
++        <source>15min</source>
++        <translation>15 minutos</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="189"/>
++        <source>30min</source>
++        <translation>30 minutos</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/>
++        <source>1hour</source>
++        <translation>1 hora</translation>
++    </message>
++    <message>
++        <source>Screensaver source</source>
++        <translation type="vanished">Fuente del protector de pantalla</translation>
++    </message>
++    <message>
++        <source>Select</source>
++        <translation type="vanished">Escoger</translation>
++    </message>
++    <message>
++        <source>Wallpaper files(*.jpg *.jpeg *.bmp *.dib *.png *.jfif *.jpe *.gif *.tif *.tiff *.wdp *.svg)</source>
++        <translation type="vanished">Archivos de fondos de pantalla(*.jpg * .jpeg * .bmp * .dib * .png * .jfif *.jfpe * .gif * .tif * .tiff *.wdp * .svg)</translation>
++    </message>
++    <message>
++        <source>select custom screensaver dir</source>
++        <translation type="vanished">Seleccione el directorio del protector de pantalla personalizado</translation>
++    </message>
++    <message>
++        <source>Position: </source>
++        <translation type="vanished">Posición: </translation>
++    </message>
++    <message>
++        <source>FileName: </source>
++        <translation type="vanished">Nombre: </translation>
++    </message>
++    <message>
++        <source>FileType: </source>
++        <translation type="vanished">Tipo de archivo: </translation>
++    </message>
++    <message>
++        <source>Cancel</source>
++        <translation type="vanished">Cancelar</translation>
++    </message>
++    <message>
++        <source>Switching time</source>
++        <translation type="vanished">Tiempo de conmutación</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="176"/>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="189"/>
++        <source>1min</source>
++        <translation>1 minuto</translation>
++    </message>
++    <message>
++        <source>Ordinal</source>
++        <translation type="vanished">Ordinal</translation>
++    </message>
++    <message>
++        <source>Random switching</source>
++        <translation type="vanished">Conmutación aleatoria</translation>
++    </message>
++    <message>
++        <source>Display text</source>
++        <translation type="vanished">显示文本</translation>
++    </message>
++    <message>
++        <source>Enter text, up to 30 characters</source>
++        <translation type="vanished">输入文本,最多30个字符</translation>
++    </message>
++    <message>
++        <source>Text position</source>
++        <translation type="vanished">Posición del texto</translation>
++    </message>
++    <message>
++        <source>Centered</source>
++        <translation type="vanished">Centrado</translation>
++    </message>
++    <message>
++        <source>Randow(Bubble text)</source>
++        <translation type="vanished">Randow(Texto de burbuja)</translation>
++    </message>
++    <message>
++        <source>1m</source>
++        <translation type="vanished">1m</translation>
++    </message>
++    <message>
++        <source>5m</source>
++        <translation type="vanished">5m</translation>
++    </message>
++    <message>
++        <source>10m</source>
++        <translation type="vanished">10m</translation>
++    </message>
++    <message>
++        <source>30m</source>
++        <translation type="vanished">30m</translation>
++    </message>
++    <message>
++        <source>45m</source>
++        <translation type="vanished">45m</translation>
++    </message>
++    <message>
++        <source>1h</source>
++        <translation type="vanished">1h</translation>
++    </message>
++    <message>
++        <source>1.5h</source>
++        <translation type="vanished">1.5h</translation>
++    </message>
++    <message>
++        <source>3h</source>
++        <translation type="vanished">3h</translation>
++    </message>
++    <message>
++        <source>Random</source>
++        <translation type="vanished">Aleatorio</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/>
++        <source>Never</source>
++        <translation>Nunca</translation>
++    </message>
++</context>
++<context>
++    <name>ScreensaverUi</name>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="41"/>
++        <source>Screensaver</source>
++        <translation type="unfinished">Protector de pantalla</translation>
++        <extra-contents_path>/Screensaver/Screensaver</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="54"/>
++        <source>Idle time</source>
++        <translation type="unfinished">Tiempo de inactividad</translation>
++        <extra-contents_path>/Screensaver/Idle time</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="56"/>
++        <source>Screensaver program</source>
++        <translation type="unfinished">Programa protector de pantalla</translation>
++        <extra-contents_path>/Screensaver/Screensaver program</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="88"/>
++        <source>Screensaver source</source>
++        <translation type="unfinished">Fuente del protector de pantalla</translation>
++        <extra-contents_path>/Screensaver/Screensaver source</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="93"/>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="457"/>
++        <source>Select</source>
++        <translation type="unfinished">Escoger</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="114"/>
++        <source>Ordinal</source>
++        <translation type="unfinished">Ordinal</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="115"/>
++        <source>Random</source>
++        <translation type="unfinished">Aleatorio</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="122"/>
++        <source>Random switching</source>
++        <translation type="unfinished">Conmutación aleatoria</translation>
++        <extra-contents_path>/Screensaver/Random switching</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="142"/>
++        <source>Switching time</source>
++        <translation type="unfinished">Tiempo de conmutación</translation>
++        <extra-contents_path>/Screensaver/Switching time</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="161"/>
++        <source>Text(up to 30 characters):</source>
++        <translation type="unfinished">Texto (hasta 30 caracteres):</translation>
++        <extra-contents_path>/Screensaver/Text(up to 30 characters):</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="184"/>
++        <source>Text position</source>
++        <translation type="unfinished">Posición del texto</translation>
++        <extra-contents_path>/Screensaver/Text position</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="192"/>
++        <source>Centered</source>
++        <translation type="unfinished">Centrado</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="193"/>
++        <source>Randow(Bubble text)</source>
++        <translation type="unfinished">Randow(Texto de burbuja)</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="215"/>
++        <source>Show rest time</source>
++        <translation type="unfinished">Mostrar tiempo de descanso</translation>
++        <extra-contents_path>/Screensaver/Show rest time</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="226"/>
++        <source>Lock screen when screensaver boot</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="415"/>
++        <source>Wallpaper files(*.jpg *.jpeg *.bmp *.dib *.png *.jfif *.jpe *.gif *.tif *.tiff *.wdp *.svg)</source>
++        <translation type="unfinished">Archivos de fondos de pantalla(*.jpg * .jpeg * .bmp * .dib * .png * .jfif *.jfpe * .gif * .tif * .tiff *.wdp * .svg)</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="456"/>
++        <source>select custom screensaver dir</source>
++        <translation type="unfinished">Seleccione el directorio del protector de pantalla personalizado</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="458"/>
++        <source>Position: </source>
++        <translation type="unfinished">Posición: </translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="459"/>
++        <source>FileName: </source>
++        <translation type="unfinished">Nombre: </translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="460"/>
++        <source>FileType: </source>
++        <translation type="unfinished">Tipo de archivo: </translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="461"/>
++        <source>Cancel</source>
++        <translation type="unfinished">Cancelar</translation>
++    </message>
++</context>
++</TS>
+diff --git a/ukccplugins_i18n_ts/fa.ts b/ukccplugins_i18n_ts/fa.ts
+new file mode 100644
+index 0000000..cf62757
+--- /dev/null
++++ b/ukccplugins_i18n_ts/fa.ts
+@@ -0,0 +1,314 @@
++<?xml version="1.0" encoding="utf-8"?>
++<!DOCTYPE TS>
++<TS version="2.1" language="fa">
++<context>
++    <name>Screenlock</name>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="39"/>
++        <source>Screenlock</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="187"/>
++        <source>Wallpaper files(*.jpg *.jpeg *.bmp *.dib *.png *.jfif *.jpe *.gif *.tif *.tiff *.wdp)</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="229"/>
++        <source>select custom wallpaper file</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="230"/>
++        <source>Select</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="231"/>
++        <source>Position: </source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="232"/>
++        <source>FileName: </source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="233"/>
++        <source>FileType: </source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="234"/>
++        <source>Cancel</source>
++        <translation type="unfinished"></translation>
++    </message>
++</context>
++<context>
++    <name>ScreenlockUi</name>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="74"/>
++        <source>Show picture of screenlock on screenlogin</source>
++        <translation type="unfinished"></translation>
++        <extra-contents_path>/Screenlock/Show picture of screenlock on screenlogin</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="87"/>
++        <source>Leave lock (System will be locked when the paired phone gone)</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="97"/>
++        <source>Specified device</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="114"/>
++        <source>No paired phone. Please turn to &apos;Bluetooth&apos; to pair.</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="53"/>
++        <source>Screenlock</source>
++        <translation type="unfinished"></translation>
++        <extra-contents_path>/Screenlock/Screenlock</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="168"/>
++        <source>Choose Picture</source>
++        <translation type="unfinished"></translation>
++        <extra-contents_path>/Wallpaper/Choose Picture</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="172"/>
++        <source>Local Pictures</source>
++        <translation type="unfinished"></translation>
++        <extra-contents_path>/Screenlock/Local Pictures</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="176"/>
++        <source>Online Pictures</source>
++        <translation type="unfinished"></translation>
++        <extra-contents_path>/Screenlock/Online Pictures</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="180"/>
++        <source>Reset To Default</source>
++        <translation type="unfinished"></translation>
++        <extra-contents_path>/Screenlock/Reset To Default</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="122"/>
++        <source>Bluetooth</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="239"/>
++        <source>No bluetooth adapter detected, can not use Leave Lock.</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="203"/>
++        <source>Monitor Off</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="205"/>
++        <source>Screensaver</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="200"/>
++        <source>Related Settings</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="204"/>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="206"/>
++        <source>Set</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="266"/>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="647"/>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="681"/>
++        <source>Please select device</source>
++        <translation type="unfinished"></translation>
++    </message>
++</context>
++<context>
++    <name>Screensaver</name>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="44"/>
++        <source>Screensaver</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="189"/>
++        <source>5min</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="189"/>
++        <source>10min</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/>
++        <source>15min</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="189"/>
++        <source>30min</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/>
++        <source>1hour</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/>
++        <source>Never</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="176"/>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="189"/>
++        <source>1min</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="182"/>
++        <source>UKUI</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="182"/>
++        <source>Customize</source>
++        <translation type="unfinished"></translation>
++    </message>
++</context>
++<context>
++    <name>ScreensaverUi</name>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="41"/>
++        <source>Screensaver</source>
++        <translation type="unfinished"></translation>
++        <extra-contents_path>/Screensaver/Screensaver</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="54"/>
++        <source>Idle time</source>
++        <translation type="unfinished"></translation>
++        <extra-contents_path>/Screensaver/Idle time</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="56"/>
++        <source>Screensaver program</source>
++        <translation type="unfinished"></translation>
++        <extra-contents_path>/Screensaver/Screensaver program</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="88"/>
++        <source>Screensaver source</source>
++        <translation type="unfinished"></translation>
++        <extra-contents_path>/Screensaver/Screensaver source</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="93"/>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="457"/>
++        <source>Select</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="114"/>
++        <source>Ordinal</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="115"/>
++        <source>Random</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="122"/>
++        <source>Random switching</source>
++        <translation type="unfinished"></translation>
++        <extra-contents_path>/Screensaver/Random switching</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="142"/>
++        <source>Switching time</source>
++        <translation type="unfinished"></translation>
++        <extra-contents_path>/Screensaver/Switching time</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="161"/>
++        <source>Text(up to 30 characters):</source>
++        <translation type="unfinished"></translation>
++        <extra-contents_path>/Screensaver/Text(up to 30 characters):</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="184"/>
++        <source>Text position</source>
++        <translation type="unfinished"></translation>
++        <extra-contents_path>/Screensaver/Text position</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="192"/>
++        <source>Centered</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="193"/>
++        <source>Randow(Bubble text)</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="215"/>
++        <source>Show rest time</source>
++        <translation type="unfinished"></translation>
++        <extra-contents_path>/Screensaver/Show rest time</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="226"/>
++        <source>Lock screen when screensaver boot</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="415"/>
++        <source>Wallpaper files(*.jpg *.jpeg *.bmp *.dib *.png *.jfif *.jpe *.gif *.tif *.tiff *.wdp *.svg)</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="456"/>
++        <source>select custom screensaver dir</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="458"/>
++        <source>Position: </source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="459"/>
++        <source>FileName: </source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="460"/>
++        <source>FileType: </source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="461"/>
++        <source>Cancel</source>
++        <translation type="unfinished"></translation>
++    </message>
++</context>
++</TS>
+diff --git a/ukccplugins_i18n_ts/fr.ts b/ukccplugins_i18n_ts/fr.ts
+new file mode 100644
+index 0000000..205ce25
+--- /dev/null
++++ b/ukccplugins_i18n_ts/fr.ts
+@@ -0,0 +1,642 @@
++<?xml version="1.0" encoding="utf-8"?>
++<!DOCTYPE TS>
++<TS version="2.1" language="fr">
++<context>
++    <name>Screenlock</name>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="39"/>
++        <source>Screenlock</source>
++        <translation>Verrouillage de l’écran</translation>
++    </message>
++    <message>
++        <source>Screenlock Interface</source>
++        <translation type="vanished">锁屏界面</translation>
++    </message>
++    <message>
++        <source>Show message on lock screen</source>
++        <translation type="vanished">Afficher le message sur l’écran de verrouillage</translation>
++    </message>
++    <message>
++        <source>Browse</source>
++        <translation type="vanished">浏览</translation>
++        <extra-contents_path>/Screenlock/Browse</extra-contents_path>
++    </message>
++    <message>
++        <source>Online Picture</source>
++        <translation type="vanished">线上图片</translation>
++        <extra-contents_path>/Screenlock/Online Picture</extra-contents_path>
++    </message>
++    <message>
++        <source>Local Pictures</source>
++        <translation type="vanished">Photos locales</translation>
++        <extra-contents_path>/Screenlock/Local Pictures</extra-contents_path>
++    </message>
++    <message>
++        <source>Online Pictures</source>
++        <translation type="vanished">Photos en ligne</translation>
++        <extra-contents_path>/Screenlock/Online Pictures</extra-contents_path>
++    </message>
++    <message>
++        <source>Reset To Default</source>
++        <translation type="vanished">Réinitialiser les paramètres par défaut</translation>
++        <extra-contents_path>/Screenlock/Reset To Default</extra-contents_path>
++    </message>
++    <message>
++        <source>Related Settings</source>
++        <translation type="vanished">Paramètres associés</translation>
++    </message>
++    <message>
++        <source>Screenlock Set</source>
++        <translation type="vanished">锁屏设置</translation>
++    </message>
++    <message>
++        <source>Lock screen when screensaver boot</source>
++        <translation type="vanished">激活屏保时锁定屏幕</translation>
++    </message>
++    <message>
++        <source>Lock screen delay</source>
++        <translation type="vanished">Délai de verrouillage de l’écran</translation>
++    </message>
++    <message>
++        <source>Min</source>
++        <translation type="vanished">分钟</translation>
++    </message>
++    <message>
++        <source>Select screenlock background</source>
++        <translation type="vanished">选择锁屏背景</translation>
++    </message>
++    <message>
++        <source>Browser online wp</source>
++        <translation type="vanished">浏览线上壁纸</translation>
++    </message>
++    <message>
++        <source>Browser local wp</source>
++        <translation type="vanished">浏览本地壁纸</translation>
++    </message>
++    <message>
++        <source>Show picture of screenlock on screenlogin</source>
++        <translation type="vanished">Afficher l’image du verrouillage de l’écran lors de la connexion à l’écran</translation>
++        <extra-contents_path>/Screenlock/Show picture of screenlock on screenlogin</extra-contents_path>
++    </message>
++    <message>
++        <source>Enabel screenlock</source>
++        <translation type="vanished">开启锁屏</translation>
++    </message>
++    <message>
++        <source>Open</source>
++        <translation type="obsolete">浏览</translation>
++    </message>
++    <message>
++        <source>screenlock</source>
++        <translation type="vanished">锁屏</translation>
++    </message>
++    <message>
++        <source>picture</source>
++        <translation type="obsolete">图片</translation>
++    </message>
++    <message>
++        <source>Never</source>
++        <translation type="vanished">Jamais</translation>
++    </message>
++    <message>
++        <source>1m</source>
++        <translation type="vanished">1m</translation>
++    </message>
++    <message>
++        <source>5m</source>
++        <translation type="vanished">5m</translation>
++    </message>
++    <message>
++        <source>10m</source>
++        <translation type="vanished">10m</translation>
++    </message>
++    <message>
++        <source>30m</source>
++        <translation type="vanished">30m</translation>
++    </message>
++    <message>
++        <source>45m</source>
++        <translation type="vanished">45m</translation>
++    </message>
++    <message>
++        <source>1h</source>
++        <translation type="vanished">1h</translation>
++    </message>
++    <message>
++        <source>1.5h</source>
++        <translation type="vanished">1.5h</translation>
++    </message>
++    <message>
++        <source>3h</source>
++        <translation type="vanished">3h</translation>
++    </message>
++    <message>
++        <source>2h</source>
++        <translation type="vanished">2h</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="187"/>
++        <source>Wallpaper files(*.jpg *.jpeg *.bmp *.dib *.png *.jfif *.jpe *.gif *.tif *.tiff *.wdp)</source>
++        <translation>Fichiers de fond d’écran(* .jpg * .jpeg * .bmp * .dib * .png * .jfif *.jpe * .gif * .tif * .tiff *.wdp)</translation>
++    </message>
++    <message>
++        <source>allFiles(*.*)</source>
++        <translation type="vanished">所有文件(*.*)</translation>
++    </message>
++    <message>
++        <source>1min</source>
++        <translation type="vanished">1 min</translation>
++    </message>
++    <message>
++        <source>5min</source>
++        <translation type="vanished">5 minutes</translation>
++    </message>
++    <message>
++        <source>10min</source>
++        <translation type="vanished">10 minutes</translation>
++    </message>
++    <message>
++        <source>30min</source>
++        <translation type="vanished">30 minutes</translation>
++    </message>
++    <message>
++        <source>45min</source>
++        <translation type="vanished">45 min</translation>
++    </message>
++    <message>
++        <source>1hour</source>
++        <translation type="vanished">1 heure</translation>
++    </message>
++    <message>
++        <source>2hour</source>
++        <translation type="vanished">2 heures</translation>
++    </message>
++    <message>
++        <source>3hour</source>
++        <translation type="vanished">3 heures</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="229"/>
++        <source>select custom wallpaper file</source>
++        <translation>Sélectionnez le fichier de fond d’écran personnalisé</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="230"/>
++        <source>Select</source>
++        <translation>Choisir</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="231"/>
++        <source>Position: </source>
++        <translation>Position: </translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="232"/>
++        <source>FileName: </source>
++        <translation>Fichier: </translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="233"/>
++        <source>FileType: </source>
++        <translation>Type de fichier : </translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="234"/>
++        <source>Cancel</source>
++        <translation>Annuler</translation>
++    </message>
++    <message>
++        <source>Monitor Off</source>
++        <translation type="vanished">Moniteur éteint</translation>
++    </message>
++    <message>
++        <source>Screensaver</source>
++        <translation type="vanished">Économiseur d’écran</translation>
++    </message>
++    <message>
++        <source>Set</source>
++        <translation type="vanished">Poser</translation>
++    </message>
++</context>
++<context>
++    <name>ScreenlockUi</name>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="74"/>
++        <source>Show picture of screenlock on screenlogin</source>
++        <translation type="unfinished">Afficher l’image du verrouillage de l’écran lors de la connexion à l’écran</translation>
++        <extra-contents_path>/Screenlock/Show picture of screenlock on screenlogin</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="87"/>
++        <source>Leave lock (System will be locked when the paired phone gone)</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="97"/>
++        <source>Specified device</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="114"/>
++        <source>No paired phone. Please turn to &apos;Bluetooth&apos; to pair.</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="53"/>
++        <source>Screenlock</source>
++        <translation type="unfinished">Verrouillage de l’écran</translation>
++        <extra-contents_path>/Screenlock/Screenlock</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="168"/>
++        <source>Choose Picture</source>
++        <translation type="unfinished"></translation>
++        <extra-contents_path>/Wallpaper/Choose Picture</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="172"/>
++        <source>Local Pictures</source>
++        <translation type="unfinished">Photos locales</translation>
++        <extra-contents_path>/Screenlock/Local Pictures</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="176"/>
++        <source>Online Pictures</source>
++        <translation type="unfinished">Photos en ligne</translation>
++        <extra-contents_path>/Screenlock/Online Pictures</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="180"/>
++        <source>Reset To Default</source>
++        <translation type="unfinished">Réinitialiser les paramètres par défaut</translation>
++        <extra-contents_path>/Screenlock/Reset To Default</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="122"/>
++        <source>Bluetooth</source>
++        <translation type="unfinished">蓝牙</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="239"/>
++        <source>No bluetooth adapter detected, can not use Leave Lock.</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="203"/>
++        <source>Monitor Off</source>
++        <translation type="unfinished">Moniteur éteint</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="205"/>
++        <source>Screensaver</source>
++        <translation type="unfinished">Économiseur d’écran</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="200"/>
++        <source>Related Settings</source>
++        <translation type="unfinished">Paramètres associés</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="204"/>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="206"/>
++        <source>Set</source>
++        <translation type="unfinished">Poser</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="266"/>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="647"/>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="681"/>
++        <source>Please select device</source>
++        <translation type="unfinished"></translation>
++    </message>
++</context>
++<context>
++    <name>Screensaver</name>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="44"/>
++        <source>Screensaver</source>
++        <translation>Économiseur d’écran</translation>
++    </message>
++    <message>
++        <source>Idle time</source>
++        <translation type="vanished">Temps d’inactivité</translation>
++        <extra-contents_path>/Screensaver/Idle time</extra-contents_path>
++    </message>
++    <message>
++        <source>Lock screen when activating screensaver</source>
++        <translation type="vanished">Verrouiller l’écran lors de l’activation de l’économiseur d’écran</translation>
++    </message>
++    <message>
++        <source>Enable screensaver</source>
++        <translation type="vanished">开启屏保</translation>
++    </message>
++    <message>
++        <source>Screensaver program</source>
++        <translation type="vanished">Programme d’économiseur d’écran</translation>
++        <extra-contents_path>/Screensaver/Screensaver program</extra-contents_path>
++    </message>
++    <message>
++        <source>idle time</source>
++        <translation type="vanished">等待时间</translation>
++    </message>
++    <message>
++        <source>Min</source>
++        <translation type="vanished">分钟</translation>
++    </message>
++    <message>
++        <source>Lock screen when screensaver boot</source>
++        <translation type="vanished">Écran de verrouillage lors du démarrage de l’économiseur d’écran</translation>
++    </message>
++    <message>
++        <source>screensaver</source>
++        <translation type="vanished">屏保</translation>
++    </message>
++    <message>
++        <source>Default_ukui</source>
++        <translation type="vanished">默认屏保</translation>
++    </message>
++    <message>
++        <source>View</source>
++        <translation type="vanished">Vue</translation>
++    </message>
++    <message>
++        <source>Text(up to 30 characters):</source>
++        <translation type="vanished">Texte (jusqu’à 30 caractères) :</translation>
++    </message>
++    <message>
++        <source>Show rest time</source>
++        <translation type="vanished">Afficher le temps de repos</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="182"/>
++        <source>UKUI</source>
++        <translation>UKUI (en anglais seulement)</translation>
++    </message>
++    <message>
++        <source>Blank_Only</source>
++        <translation type="vanished">Blank_Only</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="182"/>
++        <source>Customize</source>
++        <translation>Personnaliser</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="189"/>
++        <source>5min</source>
++        <translation>5 minutes</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="189"/>
++        <source>10min</source>
++        <translation>10 minutes</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/>
++        <source>15min</source>
++        <translation>15 min</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="189"/>
++        <source>30min</source>
++        <translation>30 minutes</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/>
++        <source>1hour</source>
++        <translation>1 heure</translation>
++    </message>
++    <message>
++        <source>Screensaver source</source>
++        <translation type="vanished">Source de l’économiseur d’écran</translation>
++    </message>
++    <message>
++        <source>Select</source>
++        <translation type="vanished">Choisir</translation>
++    </message>
++    <message>
++        <source>Wallpaper files(*.jpg *.jpeg *.bmp *.dib *.png *.jfif *.jpe *.gif *.tif *.tiff *.wdp *.svg)</source>
++        <translation type="vanished">Fichiers de fond d’écran(* .jpg * .jpeg * .bmp * .dib * .png * .jfif *.jpe * .gif * .tif * .tiff * .wdp * .svg)</translation>
++    </message>
++    <message>
++        <source>select custom screensaver dir</source>
++        <translation type="vanished">Sélectionnez le répertoire de l’économiseur d’écran personnalisé</translation>
++    </message>
++    <message>
++        <source>Position: </source>
++        <translation type="vanished">Position: </translation>
++    </message>
++    <message>
++        <source>FileName: </source>
++        <translation type="vanished">Fichier: </translation>
++    </message>
++    <message>
++        <source>FileType: </source>
++        <translation type="vanished">Type de fichier : </translation>
++    </message>
++    <message>
++        <source>Cancel</source>
++        <translation type="vanished">Annuler</translation>
++    </message>
++    <message>
++        <source>Switching time</source>
++        <translation type="vanished">Temps de commutation</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="176"/>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="189"/>
++        <source>1min</source>
++        <translation>1 min</translation>
++    </message>
++    <message>
++        <source>Ordinal</source>
++        <translation type="vanished">Ordinal</translation>
++    </message>
++    <message>
++        <source>Random switching</source>
++        <translation type="vanished">Commutation aléatoire</translation>
++    </message>
++    <message>
++        <source>Display text</source>
++        <translation type="vanished">显示文本</translation>
++    </message>
++    <message>
++        <source>Enter text, up to 30 characters</source>
++        <translation type="vanished">输入文本,最多30个字符</translation>
++    </message>
++    <message>
++        <source>Text position</source>
++        <translation type="vanished">Position du texte</translation>
++    </message>
++    <message>
++        <source>Centered</source>
++        <translation type="vanished">Centré</translation>
++    </message>
++    <message>
++        <source>Randow(Bubble text)</source>
++        <translation type="vanished">Randow(Texte à bulles)</translation>
++    </message>
++    <message>
++        <source>1m</source>
++        <translation type="vanished">1m</translation>
++    </message>
++    <message>
++        <source>5m</source>
++        <translation type="vanished">5m</translation>
++    </message>
++    <message>
++        <source>10m</source>
++        <translation type="vanished">10m</translation>
++    </message>
++    <message>
++        <source>30m</source>
++        <translation type="vanished">30m</translation>
++    </message>
++    <message>
++        <source>45m</source>
++        <translation type="vanished">45m</translation>
++    </message>
++    <message>
++        <source>1h</source>
++        <translation type="vanished">1h</translation>
++    </message>
++    <message>
++        <source>1.5h</source>
++        <translation type="vanished">1.5h</translation>
++    </message>
++    <message>
++        <source>3h</source>
++        <translation type="vanished">3h</translation>
++    </message>
++    <message>
++        <source>Random</source>
++        <translation type="vanished">Aléatoire</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/>
++        <source>Never</source>
++        <translation>Jamais</translation>
++    </message>
++</context>
++<context>
++    <name>ScreensaverUi</name>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="41"/>
++        <source>Screensaver</source>
++        <translation type="unfinished">Économiseur d’écran</translation>
++        <extra-contents_path>/Screensaver/Screensaver</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="54"/>
++        <source>Idle time</source>
++        <translation type="unfinished">Temps d’inactivité</translation>
++        <extra-contents_path>/Screensaver/Idle time</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="56"/>
++        <source>Screensaver program</source>
++        <translation type="unfinished">Programme d’économiseur d’écran</translation>
++        <extra-contents_path>/Screensaver/Screensaver program</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="88"/>
++        <source>Screensaver source</source>
++        <translation type="unfinished">Source de l’économiseur d’écran</translation>
++        <extra-contents_path>/Screensaver/Screensaver source</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="93"/>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="457"/>
++        <source>Select</source>
++        <translation type="unfinished">Choisir</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="114"/>
++        <source>Ordinal</source>
++        <translation type="unfinished">Ordinal</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="115"/>
++        <source>Random</source>
++        <translation type="unfinished">Aléatoire</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="122"/>
++        <source>Random switching</source>
++        <translation type="unfinished">Commutation aléatoire</translation>
++        <extra-contents_path>/Screensaver/Random switching</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="142"/>
++        <source>Switching time</source>
++        <translation type="unfinished">Temps de commutation</translation>
++        <extra-contents_path>/Screensaver/Switching time</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="161"/>
++        <source>Text(up to 30 characters):</source>
++        <translation type="unfinished">Texte (jusqu’à 30 caractères) :</translation>
++        <extra-contents_path>/Screensaver/Text(up to 30 characters):</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="184"/>
++        <source>Text position</source>
++        <translation type="unfinished">Position du texte</translation>
++        <extra-contents_path>/Screensaver/Text position</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="192"/>
++        <source>Centered</source>
++        <translation type="unfinished">Centré</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="193"/>
++        <source>Randow(Bubble text)</source>
++        <translation type="unfinished">Randow(Texte à bulles)</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="215"/>
++        <source>Show rest time</source>
++        <translation type="unfinished">Afficher le temps de repos</translation>
++        <extra-contents_path>/Screensaver/Show rest time</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="226"/>
++        <source>Lock screen when screensaver boot</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="415"/>
++        <source>Wallpaper files(*.jpg *.jpeg *.bmp *.dib *.png *.jfif *.jpe *.gif *.tif *.tiff *.wdp *.svg)</source>
++        <translation type="unfinished">Fichiers de fond d’écran(* .jpg * .jpeg * .bmp * .dib * .png * .jfif *.jpe * .gif * .tif * .tiff * .wdp * .svg)</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="456"/>
++        <source>select custom screensaver dir</source>
++        <translation type="unfinished">Sélectionnez le répertoire de l’économiseur d’écran personnalisé</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="458"/>
++        <source>Position: </source>
++        <translation type="unfinished">Position: </translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="459"/>
++        <source>FileName: </source>
++        <translation type="unfinished">Fichier: </translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="460"/>
++        <source>FileType: </source>
++        <translation type="unfinished">Type de fichier : </translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="461"/>
++        <source>Cancel</source>
++        <translation type="unfinished">Annuler</translation>
++    </message>
++</context>
++</TS>
+diff --git a/ukccplugins_i18n_ts/kk.ts b/ukccplugins_i18n_ts/kk.ts
+new file mode 100644
+index 0000000..ce59b1b
+--- /dev/null
++++ b/ukccplugins_i18n_ts/kk.ts
+@@ -0,0 +1,622 @@
++<?xml version="1.0" encoding="utf-8"?>
++<!DOCTYPE TS>
++<TS version="2.1" language="kk">
++<context>
++    <name>Screenlock</name>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="39"/>
++        <source>Screenlock</source>
++        <translation>ەكٸران قۇلىبى</translation>
++    </message>
++    <message>
++        <source>Screenlock Interface</source>
++        <translation type="vanished">Screenlock интерфейсі</translation>
++    </message>
++    <message>
++        <source>Show message on lock screen</source>
++        <translation type="vanished">Құлыптау экранында хабарды көрсету</translation>
++    </message>
++    <message>
++        <source>Browse</source>
++        <translation type="vanished">Шолу</translation>
++        <extra-contents_path>/Screenlock/Browse</extra-contents_path>
++    </message>
++    <message>
++        <source>Online Picture</source>
++        <translation type="vanished">Онлайн сурет</translation>
++        <extra-contents_path>/Screenlock/Online Picture</extra-contents_path>
++    </message>
++    <message>
++        <source>Reset To Default</source>
++        <translation type="vanished">Әдепкіге ысыру</translation>
++        <extra-contents_path>/Screenlock/Reset To Default</extra-contents_path>
++    </message>
++    <message>
++        <source>TextLabel</source>
++        <translation type="obsolete">TextLabel</translation>
++    </message>
++    <message>
++        <source>Screenlock Set</source>
++        <translation type="vanished">锁屏设置</translation>
++    </message>
++    <message>
++        <source>Lock screen when screensaver boot</source>
++        <translation type="vanished">Скриншотты жүктеу кезінде экранды құлыптау</translation>
++        <extra-contents_path>/Screenlock/Lock screen when screensaver boot</extra-contents_path>
++    </message>
++    <message>
++        <source>Lock screen delay</source>
++        <translation type="vanished">Экранның кідіруі</translation>
++    </message>
++    <message>
++        <source>Min</source>
++        <translation type="vanished">分钟</translation>
++    </message>
++    <message>
++        <source>Select screenlock background</source>
++        <translation type="vanished">选择锁屏背景</translation>
++    </message>
++    <message>
++        <source>Browser online wp</source>
++        <translation type="vanished">浏览线上壁纸</translation>
++    </message>
++    <message>
++        <source>Browser local wp</source>
++        <translation type="vanished">浏览本地壁纸</translation>
++    </message>
++    <message>
++        <source>Show picture of screenlock on screenlogin</source>
++        <translation type="vanished">Скриншот суретін скриншотта көрсету</translation>
++        <extra-contents_path>/Screenlock/Show picture of screenlock on screenlogin</extra-contents_path>
++    </message>
++    <message>
++        <source>Enabel screenlock</source>
++        <translation type="vanished">开启锁屏</translation>
++    </message>
++    <message>
++        <source>Open</source>
++        <translation type="obsolete">浏览</translation>
++    </message>
++    <message>
++        <source>screenlock</source>
++        <translation type="vanished">锁屏</translation>
++    </message>
++    <message>
++        <source>picture</source>
++        <translation type="obsolete">图片</translation>
++    </message>
++    <message>
++        <source>Never</source>
++        <translation type="vanished">Ешқашан</translation>
++    </message>
++    <message>
++        <source>1m</source>
++        <translation type="vanished">1 м</translation>
++    </message>
++    <message>
++        <source>5m</source>
++        <translation type="vanished">5 м</translation>
++    </message>
++    <message>
++        <source>10m</source>
++        <translation type="vanished">10 м</translation>
++    </message>
++    <message>
++        <source>30m</source>
++        <translation type="vanished">30 м</translation>
++    </message>
++    <message>
++        <source>45m</source>
++        <translation type="vanished">45 м</translation>
++    </message>
++    <message>
++        <source>1h</source>
++        <translation type="vanished">1h</translation>
++    </message>
++    <message>
++        <source>1.5h</source>
++        <translation type="vanished">1.5h</translation>
++    </message>
++    <message>
++        <source>3h</source>
++        <translation type="vanished">3h</translation>
++    </message>
++    <message>
++        <source>2h</source>
++        <translation type="vanished">2h</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="187"/>
++        <source>Wallpaper files(*.jpg *.jpeg *.bmp *.dib *.png *.jfif *.jpe *.gif *.tif *.tiff *.wdp)</source>
++        <translation>تام قاعازى حۇجاتتارى(*.jpg *.jpeg *.bmp *.dib *.png *.jfif *.jpe *.gif *.tif *.tiff *.wdp)</translation>
++    </message>
++    <message>
++        <source>allFiles(*.*)</source>
++        <translation type="vanished">所有文件(*.*)</translation>
++    </message>
++    <message>
++        <source>1min</source>
++        <translation type="obsolete">1 мин</translation>
++    </message>
++    <message>
++        <source>5min</source>
++        <translation type="obsolete">5 мин</translation>
++    </message>
++    <message>
++        <source>10min</source>
++        <translation type="obsolete">1 мин {10m?}</translation>
++    </message>
++    <message>
++        <source>30min</source>
++        <translation type="obsolete">30 мин</translation>
++    </message>
++    <message>
++        <source>45min</source>
++        <translation type="obsolete">1 мин {45m?}</translation>
++    </message>
++    <message>
++        <source>1hour</source>
++        <translation type="obsolete">1 нөсер</translation>
++    </message>
++    <message>
++        <source>2hour</source>
++        <translation type="obsolete">1 нөсер {2h?}</translation>
++    </message>
++    <message>
++        <source>3hour</source>
++        <translation type="obsolete">1 нөсер {3h?}</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="229"/>
++        <source>select custom wallpaper file</source>
++        <translation>ەرەكشە تام قاعازى حۇجاتىن تالداۋ</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="230"/>
++        <source>Select</source>
++        <translation>تالداۋ</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="231"/>
++        <source>Position: </source>
++        <translation>ورنى: </translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="232"/>
++        <source>FileName: </source>
++        <translation>حۇجات مى: </translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="233"/>
++        <source>FileType: </source>
++        <translation>:حۇجات تۇرى </translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="234"/>
++        <source>Cancel</source>
++        <translation>كۇشىنەن قالدىرۋ</translation>
++    </message>
++</context>
++<context>
++    <name>ScreenlockUi</name>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="74"/>
++        <source>Show picture of screenlock on screenlogin</source>
++        <translation>كورسەتۋ ەكرانداعى تام قاعازى كىرۋ كورىنبە بەتىندە</translation>
++        <extra-contents_path>/Screenlock/Show picture of screenlock on screenlogin</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="87"/>
++        <source>Leave lock (System will be locked when the paired phone gone)</source>
++        <translation>قۇلىبىن قالدىرىپ قويۋ (بٸر جۇپ تەلەفون جوعالىپ كەتكەندە سەستيما قۇلىپتالادى)</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="97"/>
++        <source>Specified device</source>
++        <translation>بەلگٸلەنگەن اسباب</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="114"/>
++        <source>No paired phone. Please turn to &apos;Bluetooth&apos; to pair.</source>
++        <translation>جۇپ تەلەفون جوق &apos;كۆكچىش&apos; نى قوشۇۋېلىپ قوس.</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="53"/>
++        <source>Screenlock</source>
++        <translation>ەكٸران قۇلىبى</translation>
++        <extra-contents_path>/Screenlock/Screenlock</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="168"/>
++        <source>Choose Picture</source>
++        <translation type="unfinished">جەرلىك راسىمدەر</translation>
++        <extra-contents_path>/Wallpaper/Choose Picture</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="172"/>
++        <source>Local Pictures</source>
++        <translation>جەرلىك راسىمدەر</translation>
++        <extra-contents_path>/Screenlock/Local Pictures</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="176"/>
++        <source>Online Pictures</source>
++        <translation>تورداعٸ راسىمدەر</translation>
++        <extra-contents_path>/Screenlock/Online Pictures</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="180"/>
++        <source>Reset To Default</source>
++        <translation>سۈكۈتكە قايتاي</translation>
++        <extra-contents_path>/Screenlock/Reset To Default</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="122"/>
++        <source>Bluetooth</source>
++        <translation>كۆكچىش</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="239"/>
++        <source>No bluetooth adapter detected, can not use Leave Lock.</source>
++        <translation>كۆكچىش ۇيلەستىرۋ بايقالمادٸ، Leave Lock نى ٸستەتكەلٸ بولمايدى.</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="203"/>
++        <source>Monitor Off</source>
++        <translation>قاداعالاۋ ٴوشىرۋ</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="205"/>
++        <source>Screensaver</source>
++        <translation>ەكٸران قورعاۋ</translation>
++        <extra-contents_path>/Screenlock/Screensaver</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="200"/>
++        <source>Related Settings</source>
++        <translation>قاتىناستىق تەڭشەۋلەر</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="204"/>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="206"/>
++        <source>Set</source>
++        <translation>بەلگٸلەۋ</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="266"/>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="647"/>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="681"/>
++        <source>Please select device</source>
++        <translation>اسبابٸن تالدا</translation>
++    </message>
++</context>
++<context>
++    <name>Screensaver</name>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="44"/>
++        <source>Screensaver</source>
++        <translation>ەكٸران قورعاۋ</translation>
++    </message>
++    <message>
++        <source>Idle time</source>
++        <translation type="vanished">Бос уақыт</translation>
++        <extra-contents_path>/Screensaver/Idle time</extra-contents_path>
++    </message>
++    <message>
++        <source>Lock screen when activating screensaver</source>
++        <translation type="vanished">Экран қорғаушыны белсендіргенде экранды құлыптау</translation>
++    </message>
++    <message>
++        <source>Enable screensaver</source>
++        <translation type="vanished">开启屏保</translation>
++    </message>
++    <message>
++        <source>Screensaver program</source>
++        <translation type="vanished">Скриншотшы бағдарламасы</translation>
++        <extra-contents_path>/Screensaver/Screensaver program</extra-contents_path>
++    </message>
++    <message>
++        <source>idle time</source>
++        <translation type="vanished">等待时间</translation>
++    </message>
++    <message>
++        <source>Min</source>
++        <translation type="vanished">分钟</translation>
++    </message>
++    <message>
++        <source>Lock screen when screensaver boot</source>
++        <translation type="vanished">激活屏保时锁定屏幕</translation>
++    </message>
++    <message>
++        <source>screensaver</source>
++        <translation type="vanished">屏保</translation>
++    </message>
++    <message>
++        <source>Default_ukui</source>
++        <translation type="vanished">默认屏保</translation>
++    </message>
++    <message>
++        <source>View</source>
++        <translation type="vanished">Көрініс</translation>
++    </message>
++    <message>
++        <source>Text(up to 30 characters):</source>
++        <translation type="vanished">Мәтін (30 таңбаға дейін):</translation>
++    </message>
++    <message>
++        <source>Show rest time</source>
++        <translation type="vanished">Демалыс уақытын көрсету</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="182"/>
++        <source>UKUI</source>
++        <translation>UKUI</translation>
++    </message>
++    <message>
++        <source>Blank_Only</source>
++        <translation type="vanished">Blank_Only</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="182"/>
++        <source>Customize</source>
++        <translation>دارالاندىرۋ</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="189"/>
++        <source>5min</source>
++        <translation>بەس مينۋت</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="189"/>
++        <source>10min</source>
++        <translation>ون مينۋت</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/>
++        <source>15min</source>
++        <translation>15 مينۋت</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="189"/>
++        <source>30min</source>
++        <translation>وتىز مينۋت</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/>
++        <source>1hour</source>
++        <translation>بٸر ساعات</translation>
++    </message>
++    <message>
++        <source>Screensaver source</source>
++        <translation type="vanished">Скриншот көзі</translation>
++    </message>
++    <message>
++        <source>Select</source>
++        <translation type="vanished">Таңдау</translation>
++    </message>
++    <message>
++        <source>Wallpaper files(*.jpg *.jpeg *.bmp *.dib *.png *.jfif *.jpe *.gif *.tif *.tiff *.wdp *.svg)</source>
++        <translation type="vanished">Тұсқағаз файлдары(*.jpg *.jpeg *.bmp *.dib *.png *.jfif *.jpe *.gif *.tif *.tiff *.wdp *.svg)</translation>
++    </message>
++    <message>
++        <source>select custom screensaver dir</source>
++        <translation type="vanished">реттелетін скриншот дирін таңдаңыз</translation>
++    </message>
++    <message>
++        <source>Position: </source>
++        <translation type="vanished">Лауазымы: </translation>
++    </message>
++    <message>
++        <source>FileName: </source>
++        <translation type="vanished">Файл атауы: </translation>
++    </message>
++    <message>
++        <source>FileType: </source>
++        <translation type="vanished">РаÐ1/2аÐ1/2а </translation>
++    </message>
++    <message>
++        <source>Cancel</source>
++        <translation type="vanished">Болдырмау</translation>
++    </message>
++    <message>
++        <source>Switching time</source>
++        <translation type="vanished">Ауыстырып қосу уақыты</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="176"/>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="189"/>
++        <source>1min</source>
++        <translation>بٸر مينۋت</translation>
++    </message>
++    <message>
++        <source>Ordinal</source>
++        <translation type="vanished">Ординал</translation>
++    </message>
++    <message>
++        <source>Random switching</source>
++        <translation type="vanished">Кездейсоқ ауыстырып қосу</translation>
++    </message>
++    <message>
++        <source>Display text</source>
++        <translation type="vanished">显示文本</translation>
++    </message>
++    <message>
++        <source>Enter text, up to 30 characters</source>
++        <translation type="vanished">输入文本,最多30个字符</translation>
++    </message>
++    <message>
++        <source>Text position</source>
++        <translation type="vanished">Мәтін орны</translation>
++    </message>
++    <message>
++        <source>Centered</source>
++        <translation type="vanished">Орталықтандырылған</translation>
++    </message>
++    <message>
++        <source>Randow(Bubble text)</source>
++        <translation type="vanished">Randow(Көпіршікті мәтін)</translation>
++    </message>
++    <message>
++        <source>1m</source>
++        <translation type="vanished">1m</translation>
++    </message>
++    <message>
++        <source>5m</source>
++        <translation type="vanished">5m</translation>
++    </message>
++    <message>
++        <source>10m</source>
++        <translation type="vanished">10m</translation>
++    </message>
++    <message>
++        <source>30m</source>
++        <translation type="vanished">30m</translation>
++    </message>
++    <message>
++        <source>45m</source>
++        <translation type="vanished">45m</translation>
++    </message>
++    <message>
++        <source>1h</source>
++        <translation type="vanished">1h</translation>
++    </message>
++    <message>
++        <source>1.5h</source>
++        <translation type="vanished">1.5h</translation>
++    </message>
++    <message>
++        <source>3h</source>
++        <translation type="vanished">3h</translation>
++    </message>
++    <message>
++        <source>Random</source>
++        <translation type="vanished">Кездейсоқ</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/>
++        <source>Never</source>
++        <translation>ماڭگى</translation>
++    </message>
++</context>
++<context>
++    <name>ScreensaverUi</name>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="41"/>
++        <source>Screensaver</source>
++        <translation>ەكٸران قورعاۋ</translation>
++        <extra-contents_path>/Screensaver/Screensaver</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="54"/>
++        <source>Idle time</source>
++        <translation>بوس ۋاقىتى</translation>
++        <extra-contents_path>/Screensaver/Idle time</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="56"/>
++        <source>Screensaver program</source>
++        <translation>ەكٸران قورعاۋ پىروگىرامماسى</translation>
++        <extra-contents_path>/Screensaver/Screensaver program</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="88"/>
++        <source>Screensaver source</source>
++        <translation>ەكٸران بەتى قاينارى</translation>
++        <extra-contents_path>/Screensaver/Screensaver source</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="93"/>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="457"/>
++        <source>Select</source>
++        <translation>تالداۋ</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="114"/>
++        <source>Ordinal</source>
++        <translation>داستۇرلٸ</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="115"/>
++        <source>Random</source>
++        <translation>ەركىن</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="122"/>
++        <source>Random switching</source>
++        <translation>قالاعانىڭىزشا سايكەستىرۋ</translation>
++        <extra-contents_path>/Screensaver/Random switching</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="142"/>
++        <source>Switching time</source>
++        <translation>سايكەستىرۋ ۋاقىتى</translation>
++        <extra-contents_path>/Screensaver/Switching time</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="161"/>
++        <source>Text(up to 30 characters):</source>
++        <translation>تەكىسىت(ەڭ كوپ بولعاندا 30 ٴارىپ):</translation>
++        <extra-contents_path>/Screensaver/Text(up to 30 characters):</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="184"/>
++        <source>Text position</source>
++        <translation>تەكىسىت ورنى</translation>
++        <extra-contents_path>/Screensaver/Text position</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="192"/>
++        <source>Centered</source>
++        <translation>ورتالىق ورىندالعان</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="193"/>
++        <source>Randow(Bubble text)</source>
++        <translation>ەرٸكتٸ(كوبىكشە تەكىسىت)</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="215"/>
++        <source>Show rest time</source>
++        <translation>دەمالٸس الۋ ۋاقىتىن كورسەتۋ</translation>
++        <extra-contents_path>/Screensaver/Show rest time</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="226"/>
++        <source>Lock screen when screensaver boot</source>
++        <translation>ەكٸرانٸ كوز بەك سارالاۋعا ەكٸرانٸ قۇلپىلاۋ</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="415"/>
++        <source>Wallpaper files(*.jpg *.jpeg *.bmp *.dib *.png *.jfif *.jpe *.gif *.tif *.tiff *.wdp *.svg)</source>
++        <translation>تام قاعازى حۇجاتتارى(*.jpg *.jpeg *.bmp *.dib *.png *.jfif *.jpe *.gif *.tif *.tiff *.wdp *.svg)</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="456"/>
++        <source>select custom screensaver dir</source>
++        <translation>ەرەكشە ەكٸران باقىلاۋدى تالداۋ</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="458"/>
++        <source>Position: </source>
++        <translation>ورنى: </translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="459"/>
++        <source>FileName: </source>
++        <translation>حۇجات مى: </translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="460"/>
++        <source>FileType: </source>
++        <translation>:حۇجات تۇرى </translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="461"/>
++        <source>Cancel</source>
++        <translation>كۇشىنەن قالدىرۋ</translation>
++    </message>
++</context>
++</TS>
+diff --git a/ukccplugins_i18n_ts/ky.ts b/ukccplugins_i18n_ts/ky.ts
+new file mode 100644
+index 0000000..51b510a
+--- /dev/null
++++ b/ukccplugins_i18n_ts/ky.ts
+@@ -0,0 +1,622 @@
++<?xml version="1.0" encoding="utf-8"?>
++<!DOCTYPE TS>
++<TS version="2.1" language="ky">
++<context>
++    <name>Screenlock</name>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="39"/>
++        <source>Screenlock</source>
++        <translation>ەكىران قۇلۇپى</translation>
++    </message>
++    <message>
++        <source>Screenlock Interface</source>
++        <translation type="vanished">Экран кулпулоо интерфейси</translation>
++    </message>
++    <message>
++        <source>Show message on lock screen</source>
++        <translation type="vanished">Билдирүүлөрдү кулпулоо экранында көрсөтүү</translation>
++    </message>
++    <message>
++        <source>Browse</source>
++        <translation type="vanished">Браузер</translation>
++        <extra-contents_path>/Screenlock/Browse</extra-contents_path>
++    </message>
++    <message>
++        <source>Online Picture</source>
++        <translation type="vanished">Онлайн сүрөт</translation>
++        <extra-contents_path>/Screenlock/Online Picture</extra-contents_path>
++    </message>
++    <message>
++        <source>Reset To Default</source>
++        <translation type="vanished">Дефолтко калыбына келтирүү</translation>
++        <extra-contents_path>/Screenlock/Reset To Default</extra-contents_path>
++    </message>
++    <message>
++        <source>TextLabel</source>
++        <translation type="obsolete">ТекстЛабель</translation>
++    </message>
++    <message>
++        <source>Screenlock Set</source>
++        <translation type="vanished">锁屏设置</translation>
++    </message>
++    <message>
++        <source>Lock screen when screensaver boot</source>
++        <translation type="vanished">Экранды которуу учурунда экранды кулпулоо</translation>
++        <extra-contents_path>/Screenlock/Lock screen when screensaver boot</extra-contents_path>
++    </message>
++    <message>
++        <source>Lock screen delay</source>
++        <translation type="vanished">Экранды кечиктирүү</translation>
++    </message>
++    <message>
++        <source>Min</source>
++        <translation type="vanished">分钟</translation>
++    </message>
++    <message>
++        <source>Select screenlock background</source>
++        <translation type="vanished">选择锁屏背景</translation>
++    </message>
++    <message>
++        <source>Browser online wp</source>
++        <translation type="vanished">浏览线上壁纸</translation>
++    </message>
++    <message>
++        <source>Browser local wp</source>
++        <translation type="vanished">浏览本地壁纸</translation>
++    </message>
++    <message>
++        <source>Show picture of screenlock on screenlogin</source>
++        <translation type="vanished">Экранлогдо сценарийдин сүрөтүн көрсөтүү</translation>
++        <extra-contents_path>/Screenlock/Show picture of screenlock on screenlogin</extra-contents_path>
++    </message>
++    <message>
++        <source>Enabel screenlock</source>
++        <translation type="vanished">开启锁屏</translation>
++    </message>
++    <message>
++        <source>Open</source>
++        <translation type="obsolete">浏览</translation>
++    </message>
++    <message>
++        <source>screenlock</source>
++        <translation type="vanished">锁屏</translation>
++    </message>
++    <message>
++        <source>picture</source>
++        <translation type="obsolete">图片</translation>
++    </message>
++    <message>
++        <source>Never</source>
++        <translation type="vanished">Эч качан</translation>
++    </message>
++    <message>
++        <source>1m</source>
++        <translation type="vanished">1м</translation>
++    </message>
++    <message>
++        <source>5m</source>
++        <translation type="vanished">5м</translation>
++    </message>
++    <message>
++        <source>10m</source>
++        <translation type="vanished">10м</translation>
++    </message>
++    <message>
++        <source>30m</source>
++        <translation type="vanished">30м</translation>
++    </message>
++    <message>
++        <source>45m</source>
++        <translation type="vanished">45м</translation>
++    </message>
++    <message>
++        <source>1h</source>
++        <translation type="vanished">1х</translation>
++    </message>
++    <message>
++        <source>1.5h</source>
++        <translation type="vanished">1.5h</translation>
++    </message>
++    <message>
++        <source>3h</source>
++        <translation type="vanished">3h</translation>
++    </message>
++    <message>
++        <source>2h</source>
++        <translation type="vanished">2х</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="187"/>
++        <source>Wallpaper files(*.jpg *.jpeg *.bmp *.dib *.png *.jfif *.jpe *.gif *.tif *.tiff *.wdp)</source>
++        <translation>تام قاعازى  ۅجۅتتۅرۉ(*.jpg *.jpeg *.bmp *.dib *.png *.jfif *.jpe *.gif *.tif *.tiff *.wdp)</translation>
++    </message>
++    <message>
++        <source>allFiles(*.*)</source>
++        <translation type="vanished">所有文件(*.*)</translation>
++    </message>
++    <message>
++        <source>1min</source>
++        <translation type="obsolete">1мин</translation>
++    </message>
++    <message>
++        <source>5min</source>
++        <translation type="obsolete">5мин</translation>
++    </message>
++    <message>
++        <source>10min</source>
++        <translation type="obsolete">1мин {10m?}</translation>
++    </message>
++    <message>
++        <source>30min</source>
++        <translation type="obsolete">30мин</translation>
++    </message>
++    <message>
++        <source>45min</source>
++        <translation type="obsolete">1мин {45m?}</translation>
++    </message>
++    <message>
++        <source>1hour</source>
++        <translation type="obsolete">1хур</translation>
++    </message>
++    <message>
++        <source>2hour</source>
++        <translation type="obsolete">1хур {2h?}</translation>
++    </message>
++    <message>
++        <source>3hour</source>
++        <translation type="obsolete">1хур {3h?}</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="229"/>
++        <source>select custom wallpaper file</source>
++        <translation>قاسىيەت تام قاعازى  ۅجۅتۉن  تانداش</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="230"/>
++        <source>Select</source>
++        <translation>تانداش</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="231"/>
++        <source>Position: </source>
++        <translation>وردۇ: </translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="232"/>
++        <source>FileName: </source>
++        <translation>ۅجۅت ناامى : </translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="233"/>
++        <source>FileType: </source>
++        <translation>:ۅجۅت تۉرۉ </translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="234"/>
++        <source>Cancel</source>
++        <translation>ارعادان  قالتىرىش</translation>
++    </message>
++</context>
++<context>
++    <name>ScreenlockUi</name>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="74"/>
++        <source>Show picture of screenlock on screenlogin</source>
++        <translation>كۅرسۅتۉۉ  ئېكرانىدىكى تام قاعازى كىرۉۉ   كۅرۉنمۅ بەتىندە</translation>
++        <extra-contents_path>/Screenlock/Show picture of screenlock on screenlogin</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="87"/>
++        <source>Leave lock (System will be locked when the paired phone gone)</source>
++        <translation>قۇلۇپنى قالتىرىپ قويۇش  (بىر  جۇپ ەسەپتەمەك  جوعولۇپ كەتكەندە ساامالىق  قۇلۇپلىنىدۇ)</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="97"/>
++        <source>Specified device</source>
++        <translation>بەلگىلەنگەن شايمان</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="114"/>
++        <source>No paired phone. Please turn to &apos;Bluetooth&apos; to pair.</source>
++        <translation>جۇپ تەلەفون جوق &apos;كۆكچىش&apos; نى قوشۇۋېلىپ   قوشۇڭ.</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="53"/>
++        <source>Screenlock</source>
++        <translation>ەكىران قۇلۇپى</translation>
++        <extra-contents_path>/Screenlock/Screenlock</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="168"/>
++        <source>Choose Picture</source>
++        <translation type="unfinished"></translation>
++        <extra-contents_path>/Wallpaper/Choose Picture</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="172"/>
++        <source>Local Pictures</source>
++        <translation>جەردىك سۉرۅتتۅر</translation>
++        <extra-contents_path>/Screenlock/Local Pictures</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="176"/>
++        <source>Online Pictures</source>
++        <translation>توردوعۇ سۉرۅتتۅر</translation>
++        <extra-contents_path>/Screenlock/Online Pictures</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="180"/>
++        <source>Reset To Default</source>
++        <translation>سۈكۈتكە قايتاي</translation>
++        <extra-contents_path>/Screenlock/Reset To Default</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="122"/>
++        <source>Bluetooth</source>
++        <translation>كۆكچىش</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="239"/>
++        <source>No bluetooth adapter detected, can not use Leave Lock.</source>
++        <translation>كۆكچىش شايكەشتىرگىچ بايقالبادى، Leave Lock نى ىشتەتكەلى  بولبويت .</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="203"/>
++        <source>Monitor Off</source>
++        <translation>كۉزۅتكۉچتۉ ۅچۉرۉۉ</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="205"/>
++        <source>Screensaver</source>
++        <translation>ەكىران قورعوو</translation>
++        <extra-contents_path>/Screenlock/Screensaver</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="200"/>
++        <source>Related Settings</source>
++        <translation>بايلانىشتۇۇ   تەڭشەكتەر</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="204"/>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="206"/>
++        <source>Set</source>
++        <translation>بەلگىلۅۅ</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="266"/>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="647"/>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="681"/>
++        <source>Please select device</source>
++        <translation>اسپاپتى تانداڭ</translation>
++    </message>
++</context>
++<context>
++    <name>Screensaver</name>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="44"/>
++        <source>Screensaver</source>
++        <translation>ەكىران قورعوو</translation>
++    </message>
++    <message>
++        <source>Idle time</source>
++        <translation type="vanished">Бош убакыт</translation>
++        <extra-contents_path>/Screensaver/Idle time</extra-contents_path>
++    </message>
++    <message>
++        <source>Lock screen when activating screensaver</source>
++        <translation type="vanished">Экран сактагычты активдештирүүдө экранды кулпулоо</translation>
++    </message>
++    <message>
++        <source>Enable screensaver</source>
++        <translation type="vanished">开启屏保</translation>
++    </message>
++    <message>
++        <source>Screensaver program</source>
++        <translation type="vanished">Экрандар программасы</translation>
++        <extra-contents_path>/Screensaver/Screensaver program</extra-contents_path>
++    </message>
++    <message>
++        <source>idle time</source>
++        <translation type="vanished">等待时间</translation>
++    </message>
++    <message>
++        <source>Min</source>
++        <translation type="vanished">分钟</translation>
++    </message>
++    <message>
++        <source>Lock screen when screensaver boot</source>
++        <translation type="vanished">激活屏保时锁定屏幕</translation>
++    </message>
++    <message>
++        <source>screensaver</source>
++        <translation type="vanished">屏保</translation>
++    </message>
++    <message>
++        <source>Default_ukui</source>
++        <translation type="vanished">默认屏保</translation>
++    </message>
++    <message>
++        <source>View</source>
++        <translation type="vanished">Көрүү</translation>
++    </message>
++    <message>
++        <source>Text(up to 30 characters):</source>
++        <translation type="vanished">Текст (30 тамгага чейин):</translation>
++    </message>
++    <message>
++        <source>Show rest time</source>
++        <translation type="vanished">Эс алуу убактысын көрсөтүү</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="182"/>
++        <source>UKUI</source>
++        <translation>UKUI</translation>
++    </message>
++    <message>
++        <source>Blank_Only</source>
++        <translation type="vanished">Blank_Only</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="182"/>
++        <source>Customize</source>
++        <translation>قاسىيەتتەشتىرۉۉ</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="189"/>
++        <source>5min</source>
++        <translation>بەش مىنۇت</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="189"/>
++        <source>10min</source>
++        <translation>ون مىنۇت</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/>
++        <source>15min</source>
++        <translation>15 مىنۇت</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="189"/>
++        <source>30min</source>
++        <translation>ئوتتۇز مىنۇت</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/>
++        <source>1hour</source>
++        <translation>بىر  ساات</translation>
++    </message>
++    <message>
++        <source>Screensaver source</source>
++        <translation type="vanished">Экрандар булагы</translation>
++    </message>
++    <message>
++        <source>Select</source>
++        <translation type="vanished">Тандоо</translation>
++    </message>
++    <message>
++        <source>Wallpaper files(*.jpg *.jpeg *.bmp *.dib *.png *.jfif *.jpe *.gif *.tif *.tiff *.wdp *.svg)</source>
++        <translation type="vanished">Wallpaper файлдары (*.jpg *.jpeg *.bmp *.dib *.png *.jfif *jpe *.gif *.tif *.tiff *.wdp *.svg)</translation>
++    </message>
++    <message>
++        <source>select custom screensaver dir</source>
++        <translation type="vanished">колдонуучунун экранды тандап алуу</translation>
++    </message>
++    <message>
++        <source>Position: </source>
++        <translation type="vanished">Позиция: </translation>
++    </message>
++    <message>
++        <source>FileName: </source>
++        <translation type="vanished">Файл Аты: </translation>
++    </message>
++    <message>
++        <source>FileType: </source>
++        <translation type="vanished">FileType: </translation>
++    </message>
++    <message>
++        <source>Cancel</source>
++        <translation type="vanished">Жокко чыгаруу</translation>
++    </message>
++    <message>
++        <source>Switching time</source>
++        <translation type="vanished">Убакытты алмаштыруу</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="176"/>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="189"/>
++        <source>1min</source>
++        <translation>بىر  مىنۇت</translation>
++    </message>
++    <message>
++        <source>Ordinal</source>
++        <translation type="vanished">Ординал</translation>
++    </message>
++    <message>
++        <source>Random switching</source>
++        <translation type="vanished">Кокусунан которуу</translation>
++    </message>
++    <message>
++        <source>Display text</source>
++        <translation type="vanished">显示文本</translation>
++    </message>
++    <message>
++        <source>Enter text, up to 30 characters</source>
++        <translation type="vanished">输入文本,最多30个字符</translation>
++    </message>
++    <message>
++        <source>Text position</source>
++        <translation type="vanished">Тексттик позиция</translation>
++    </message>
++    <message>
++        <source>Centered</source>
++        <translation type="vanished">Борбордоштурулган</translation>
++    </message>
++    <message>
++        <source>Randow(Bubble text)</source>
++        <translation type="vanished">Рандоу (Көпірчүк тексти)</translation>
++    </message>
++    <message>
++        <source>1m</source>
++        <translation type="vanished">1m</translation>
++    </message>
++    <message>
++        <source>5m</source>
++        <translation type="vanished">5m</translation>
++    </message>
++    <message>
++        <source>10m</source>
++        <translation type="vanished">10m</translation>
++    </message>
++    <message>
++        <source>30m</source>
++        <translation type="vanished">30m</translation>
++    </message>
++    <message>
++        <source>45m</source>
++        <translation type="vanished">45m</translation>
++    </message>
++    <message>
++        <source>1h</source>
++        <translation type="vanished">1h</translation>
++    </message>
++    <message>
++        <source>1.5h</source>
++        <translation type="vanished">1.5h</translation>
++    </message>
++    <message>
++        <source>3h</source>
++        <translation type="vanished">3h</translation>
++    </message>
++    <message>
++        <source>Random</source>
++        <translation type="vanished">Кокусунан</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/>
++        <source>Never</source>
++        <translation>تۉبۅلۉك</translation>
++    </message>
++</context>
++<context>
++    <name>ScreensaverUi</name>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="41"/>
++        <source>Screensaver</source>
++        <translation>ەكىران قورعوو</translation>
++        <extra-contents_path>/Screensaver/Screensaver</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="54"/>
++        <source>Idle time</source>
++        <translation>بەكەر  ۇباقتى</translation>
++        <extra-contents_path>/Screensaver/Idle time</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="56"/>
++        <source>Screensaver program</source>
++        <translation>ەكىران قورعوو  پراگرامماسى</translation>
++        <extra-contents_path>/Screensaver/Screensaver program</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="88"/>
++        <source>Screensaver source</source>
++        <translation>ەكىران بەتى قاينارى</translation>
++        <extra-contents_path>/Screensaver/Screensaver source</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="93"/>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="457"/>
++        <source>Select</source>
++        <translation>تانداش</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="114"/>
++        <source>Ordinal</source>
++        <translation>جۅرۅلگۅلۉ</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="115"/>
++        <source>Random</source>
++        <translation>ۅز ەركىنچە</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="122"/>
++        <source>Random switching</source>
++        <translation>قاالاعانچا الماشتىرۇۇ</translation>
++        <extra-contents_path>/Screensaver/Random switching</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="142"/>
++        <source>Switching time</source>
++        <translation>الماشتىرۇۇ ۇباقتى</translation>
++        <extra-contents_path>/Screensaver/Switching time</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="161"/>
++        <source>Text(up to 30 characters):</source>
++        <translation>تەكىست(ەڭ كۅپ بولعوندو  30 تامعا):</translation>
++        <extra-contents_path>/Screensaver/Text(up to 30 characters):</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="184"/>
++        <source>Text position</source>
++        <translation>تەكىست وردۇ</translation>
++        <extra-contents_path>/Screensaver/Text position</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="192"/>
++        <source>Centered</source>
++        <translation>بوربور  اتقارىلعان</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="193"/>
++        <source>Randow(Bubble text)</source>
++        <translation>ۅزەركى مەنەن(كۆپۈكچە تەكىست)</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="215"/>
++        <source>Show rest time</source>
++        <translation>ەس الۇۇ الۇۇ  ۇباقتىن كۅرسۅتۉۉ</translation>
++        <extra-contents_path>/Screensaver/Show rest time</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="226"/>
++        <source>Lock screen when screensaver boot</source>
++        <translation>ەكراندى كۅزۅنۅك  جابۇۇدا ەكراندى قۇلۇپتوو</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="415"/>
++        <source>Wallpaper files(*.jpg *.jpeg *.bmp *.dib *.png *.jfif *.jpe *.gif *.tif *.tiff *.wdp *.svg)</source>
++        <translation>تام قاعازى  ۅجۅتتۅرۉ(*.jpg *.jpeg *.bmp *.dib *.png *.jfif *.jpe *.gif *.tif *.tiff *.wdp *.svg)</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="456"/>
++        <source>select custom screensaver dir</source>
++        <translation>قاسىيەت ەكىران كۅرگۉچتۉ تانداش</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="458"/>
++        <source>Position: </source>
++        <translation>وردۇ: </translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="459"/>
++        <source>FileName: </source>
++        <translation>ۅجۅت ناامى : </translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="460"/>
++        <source>FileType: </source>
++        <translation>:ۅجۅت تۉرۉ </translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="461"/>
++        <source>Cancel</source>
++        <translation>ارعادان  قالتىرىش</translation>
++    </message>
++</context>
++</TS>
+diff --git a/ukccplugins_i18n_ts/lzh.ts b/ukccplugins_i18n_ts/lzh.ts
+new file mode 100644
+index 0000000..0396ee5
+--- /dev/null
++++ b/ukccplugins_i18n_ts/lzh.ts
+@@ -0,0 +1,454 @@
++<?xml version="1.0" encoding="utf-8"?>
++<!DOCTYPE TS>
++<TS version="2.1" language="lzh">
++<context>
++    <name>Screenlock</name>
++    <message>
++        <location filename="../../../plugins/personalized/screenlock/screenlock.ui" line="26"/>
++        <location filename="../../../plugins/personalized/screenlock/screenlock.cpp" line="45"/>
++        <source>Screenlock</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../../../plugins/personalized/screenlock/screenlock.ui" line="80"/>
++        <source>Screenlock Interface</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../../../plugins/personalized/screenlock/screenlock.ui" line="205"/>
++        <location filename="../../../plugins/personalized/screenlock/screenlock.cpp" line="177"/>
++        <source>Show message on lock screen</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../../../plugins/personalized/screenlock/screenlock.ui" line="416"/>
++        <location filename="../../../plugins/personalized/screenlock/screenlock.cpp" line="133"/>
++        <source>Browse</source>
++        <translation type="unfinished"></translation>
++        <extra-contents_path>/Screenlock/Browse</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../../../plugins/personalized/screenlock/screenlock.ui" line="423"/>
++        <location filename="../../../plugins/personalized/screenlock/screenlock.cpp" line="135"/>
++        <source>Online Picture</source>
++        <translation type="unfinished"></translation>
++        <extra-contents_path>/Screenlock/Online Picture</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../../../plugins/personalized/screenlock/screenlock.ui" line="455"/>
++        <location filename="../../../plugins/personalized/screenlock/screenlock.cpp" line="144"/>
++        <source>Reset To Default</source>
++        <translation type="unfinished"></translation>
++        <extra-contents_path>/Screenlock/Reset To Default</extra-contents_path>
++    </message>
++    <message>
++        <source>Screenlock Set</source>
++        <translation type="vanished">锁屏设置</translation>
++    </message>
++    <message>
++        <source>Lock screen when screensaver boot</source>
++        <translation type="vanished">激活屏保时锁定屏幕</translation>
++    </message>
++    <message>
++        <location filename="../../../plugins/personalized/screenlock/screenlock.ui" line="332"/>
++        <source>Lock screen delay</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <source>Min</source>
++        <translation type="vanished">分钟</translation>
++    </message>
++    <message>
++        <source>Select screenlock background</source>
++        <translation type="vanished">选择锁屏背景</translation>
++    </message>
++    <message>
++        <source>Browser online wp</source>
++        <translation type="vanished">浏览线上壁纸</translation>
++    </message>
++    <message>
++        <source>Browser local wp</source>
++        <translation type="vanished">浏览本地壁纸</translation>
++    </message>
++    <message>
++        <location filename="../../../plugins/personalized/screenlock/screenlock.ui" line="262"/>
++        <location filename="../../../plugins/personalized/screenlock/screenlock.cpp" line="131"/>
++        <source>Show picture of screenlock on screenlogin</source>
++        <translation type="unfinished"></translation>
++        <extra-contents_path>/Screenlock/Show picture of screenlock on screenlogin</extra-contents_path>
++    </message>
++    <message>
++        <source>Enabel screenlock</source>
++        <translation type="vanished">开启锁屏</translation>
++    </message>
++    <message>
++        <source>Open</source>
++        <translation type="obsolete">浏览</translation>
++    </message>
++    <message>
++        <source>screenlock</source>
++        <translation type="vanished">锁屏</translation>
++    </message>
++    <message>
++        <source>picture</source>
++        <translation type="obsolete">图片</translation>
++    </message>
++    <message>
++        <location filename="../../../plugins/personalized/screenlock/screenlock.cpp" line="162"/>
++        <source>Never</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <source>1m</source>
++        <translation type="vanished">1m</translation>
++    </message>
++    <message>
++        <source>5m</source>
++        <translation type="vanished">5m</translation>
++    </message>
++    <message>
++        <source>10m</source>
++        <translation type="vanished">10m</translation>
++    </message>
++    <message>
++        <source>30m</source>
++        <translation type="vanished">30m</translation>
++    </message>
++    <message>
++        <source>45m</source>
++        <translation type="vanished">45m</translation>
++    </message>
++    <message>
++        <source>1h</source>
++        <translation type="vanished">1h</translation>
++    </message>
++    <message>
++        <source>1.5h</source>
++        <translation type="vanished">1.5h</translation>
++    </message>
++    <message>
++        <source>3h</source>
++        <translation type="vanished">3h</translation>
++    </message>
++    <message>
++        <source>2h</source>
++        <translation type="vanished">2h</translation>
++    </message>
++    <message>
++        <location filename="../../../plugins/personalized/screenlock/screenlock.cpp" line="476"/>
++        <source>Wallpaper files(*.jpg *.jpeg *.bmp *.dib *.png *.jfif *.jpe *.gif *.tif *.tiff *.wdp)</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <source>allFiles(*.*)</source>
++        <translation type="vanished">所有文件(*.*)</translation>
++    </message>
++    <message>
++        <location filename="../../../plugins/personalized/screenlock/screenlock.cpp" line="161"/>
++        <source>1min</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../../../plugins/personalized/screenlock/screenlock.cpp" line="161"/>
++        <source>5min</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../../../plugins/personalized/screenlock/screenlock.cpp" line="161"/>
++        <source>10min</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../../../plugins/personalized/screenlock/screenlock.cpp" line="161"/>
++        <source>30min</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../../../plugins/personalized/screenlock/screenlock.cpp" line="161"/>
++        <source>45min</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../../../plugins/personalized/screenlock/screenlock.cpp" line="162"/>
++        <source>1hour</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../../../plugins/personalized/screenlock/screenlock.cpp" line="162"/>
++        <source>2hour</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../../../plugins/personalized/screenlock/screenlock.cpp" line="162"/>
++        <source>3hour</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../../../plugins/personalized/screenlock/screenlock.cpp" line="518"/>
++        <source>select custom wallpaper file</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../../../plugins/personalized/screenlock/screenlock.cpp" line="519"/>
++        <source>Select</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../../../plugins/personalized/screenlock/screenlock.cpp" line="520"/>
++        <source>Position: </source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../../../plugins/personalized/screenlock/screenlock.cpp" line="521"/>
++        <source>FileName: </source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../../../plugins/personalized/screenlock/screenlock.cpp" line="522"/>
++        <source>FileType: </source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../../../plugins/personalized/screenlock/screenlock.cpp" line="523"/>
++        <source>Cancel</source>
++        <translation type="unfinished"></translation>
++    </message>
++</context>
++<context>
++    <name>Screensaver</name>
++    <message>
++        <location filename="../../../plugins/personalized/screensaver/screensaver.ui" line="59"/>
++        <location filename="../../../plugins/personalized/screensaver/screensaver.cpp" line="98"/>
++        <source>Screensaver</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../../../plugins/personalized/screensaver/screensaver.ui" line="201"/>
++        <location filename="../../../plugins/personalized/screensaver/screensaver.cpp" line="199"/>
++        <source>Idle time</source>
++        <translation type="unfinished"></translation>
++        <extra-contents_path>/Screensaver/Idle time</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../../../plugins/personalized/screensaver/screensaver.ui" line="475"/>
++        <source>Lock screen when activating screensaver</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <source>Enable screensaver</source>
++        <translation type="vanished">开启屏保</translation>
++    </message>
++    <message>
++        <location filename="../../../plugins/personalized/screensaver/screensaver.ui" line="297"/>
++        <location filename="../../../plugins/personalized/screensaver/screensaver.cpp" line="197"/>
++        <source>Screensaver program</source>
++        <translation type="unfinished"></translation>
++        <extra-contents_path>/Screensaver/Screensaver program</extra-contents_path>
++    </message>
++    <message>
++        <source>idle time</source>
++        <translation type="vanished">等待时间</translation>
++    </message>
++    <message>
++        <source>Min</source>
++        <translation type="vanished">分钟</translation>
++    </message>
++    <message>
++        <location filename="../../../plugins/personalized/screensaver/screensaver.cpp" line="905"/>
++        <source>Lock screen when screensaver boot</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <source>screensaver</source>
++        <translation type="vanished">屏保</translation>
++    </message>
++    <message>
++        <source>Default_ukui</source>
++        <translation type="vanished">默认屏保</translation>
++    </message>
++    <message>
++        <location filename="../../../plugins/personalized/screensaver/screensaver.cpp" line="185"/>
++        <source>View</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../../../plugins/personalized/screensaver/screensaver.cpp" line="862"/>
++        <source>Text(up to 30 characters):</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../../../plugins/personalized/screensaver/screensaver.cpp" line="896"/>
++        <source>Show rest time</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../../../plugins/personalized/screensaver/screensaver.cpp" line="226"/>
++        <source>UKUI</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../../../plugins/personalized/screensaver/screensaver.cpp" line="227"/>
++        <source>Blank_Only</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../../../plugins/personalized/screensaver/screensaver.cpp" line="238"/>
++        <source>Customize</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../../../plugins/personalized/screensaver/screensaver.cpp" line="246"/>
++        <location filename="../../../plugins/personalized/screensaver/screensaver.cpp" line="765"/>
++        <source>5min</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../../../plugins/personalized/screensaver/screensaver.cpp" line="246"/>
++        <location filename="../../../plugins/personalized/screensaver/screensaver.cpp" line="766"/>
++        <source>10min</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../../../plugins/personalized/screensaver/screensaver.cpp" line="246"/>
++        <source>15min</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../../../plugins/personalized/screensaver/screensaver.cpp" line="246"/>
++        <location filename="../../../plugins/personalized/screensaver/screensaver.cpp" line="767"/>
++        <source>30min</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../../../plugins/personalized/screensaver/screensaver.cpp" line="246"/>
++        <source>1hour</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../../../plugins/personalized/screensaver/screensaver.cpp" line="667"/>
++        <source>Screensaver source</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../../../plugins/personalized/screensaver/screensaver.cpp" line="673"/>
++        <location filename="../../../plugins/personalized/screensaver/screensaver.cpp" line="723"/>
++        <source>Select</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../../../plugins/personalized/screensaver/screensaver.cpp" line="681"/>
++        <source>Wallpaper files(*.jpg *.jpeg *.bmp *.dib *.png *.jfif *.jpe *.gif *.tif *.tiff *.wdp *.svg)</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../../../plugins/personalized/screensaver/screensaver.cpp" line="722"/>
++        <source>select custom screensaver dir</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../../../plugins/personalized/screensaver/screensaver.cpp" line="724"/>
++        <source>Position: </source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../../../plugins/personalized/screensaver/screensaver.cpp" line="725"/>
++        <source>FileName: </source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../../../plugins/personalized/screensaver/screensaver.cpp" line="726"/>
++        <source>FileType: </source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../../../plugins/personalized/screensaver/screensaver.cpp" line="727"/>
++        <source>Cancel</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../../../plugins/personalized/screensaver/screensaver.cpp" line="760"/>
++        <source>Switching time</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../../../plugins/personalized/screensaver/screensaver.cpp" line="764"/>
++        <source>1min</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../../../plugins/personalized/screensaver/screensaver.cpp" line="812"/>
++        <source>Ordinal</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../../../plugins/personalized/screensaver/screensaver.cpp" line="821"/>
++        <source>Random switching</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <source>Display text</source>
++        <translation type="vanished">显示文本</translation>
++    </message>
++    <message>
++        <source>Enter text, up to 30 characters</source>
++        <translation type="vanished">输入文本,最多30个字符</translation>
++    </message>
++    <message>
++        <location filename="../../../plugins/personalized/screensaver/screensaver.cpp" line="936"/>
++        <source>Text position</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../../../plugins/personalized/screensaver/screensaver.cpp" line="944"/>
++        <source>Centered</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../../../plugins/personalized/screensaver/screensaver.cpp" line="945"/>
++        <source>Randow(Bubble text)</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <source>1m</source>
++        <translation type="vanished">1m</translation>
++    </message>
++    <message>
++        <source>5m</source>
++        <translation type="vanished">5m</translation>
++    </message>
++    <message>
++        <source>10m</source>
++        <translation type="vanished">10m</translation>
++    </message>
++    <message>
++        <source>30m</source>
++        <translation type="vanished">30m</translation>
++    </message>
++    <message>
++        <source>45m</source>
++        <translation type="vanished">45m</translation>
++    </message>
++    <message>
++        <source>1h</source>
++        <translation type="vanished">1h</translation>
++    </message>
++    <message>
++        <source>1.5h</source>
++        <translation type="vanished">1.5h</translation>
++    </message>
++    <message>
++        <source>3h</source>
++        <translation type="vanished">3h</translation>
++    </message>
++    <message>
++        <location filename="../../../plugins/personalized/screensaver/screensaver.cpp" line="813"/>
++        <source>Random</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../../../plugins/personalized/screensaver/screensaver.cpp" line="247"/>
++        <source>Never</source>
++        <translation type="unfinished"></translation>
++    </message>
++</context>
++</TS>
+diff --git a/ukccplugins_i18n_ts/mn.ts b/ukccplugins_i18n_ts/mn.ts
+new file mode 100644
+index 0000000..3b8ae7a
+--- /dev/null
++++ b/ukccplugins_i18n_ts/mn.ts
+@@ -0,0 +1,638 @@
++<?xml version="1.0" encoding="utf-8"?>
++<!DOCTYPE TS>
++<TS version="2.1" language="mn">
++<context>
++    <name>Screenlock</name>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="39"/>
++        <source>Screenlock</source>
++        <translation>ᠳᠡᠯᠭᠡᠴᠡ ᠣᠨᠢᠰᠤᠯᠠᠬᠤ</translation>
++    </message>
++    <message>
++        <source>Show message on lock screen</source>
++        <translation type="vanished">ᠳᠡᠯᠭᠡᠴᠡ ᠴᠣᠣᠵᠢᠯᠠᠬᠤ ᠦᠶᠡᠰ ᠵᠠᠩᠭᠢ ᠢᠯᠡᠷᠡᠭᠦᠯᠬᠦ</translation>
++    </message>
++    <message>
++        <source>Browse</source>
++        <translation type="vanished">ᠦᠵᠡ ᠃</translation>
++        <extra-contents_path>/Screenlock/Browse</extra-contents_path>
++    </message>
++    <message>
++        <source>Online Picture</source>
++        <translation type="vanished">ᠰᠦᠯᠵᠢᠶᠡᠨ ᠳᠡᠭᠡᠷᠡᠬᠢ ᠵᠢᠷᠤᠭ</translation>
++        <extra-contents_path>/Screenlock/Online Picture</extra-contents_path>
++    </message>
++    <message>
++        <source>Local Pictures</source>
++        <translation type="vanished">ᠲᠤᠰ ᠭᠠᠵᠠᠷ᠎ᠤ᠋ᠨ ᠵᠢᠷᠤᠭ</translation>
++        <extra-contents_path>/Screenlock/Local Pictures</extra-contents_path>
++    </message>
++    <message>
++        <source>Online Pictures</source>
++        <translation type="vanished">ᠰᠦᠯᠵᠢᠶᠡᠨ ᠳᠡᠭᠡᠷᠡᠬᠢ ᠵᠢᠷᠤᠭ</translation>
++        <extra-contents_path>/Screenlock/Online Pictures</extra-contents_path>
++    </message>
++    <message>
++        <source>Reset To Default</source>
++        <translation type="vanished">ᠠᠶᠠᠳᠠᠯ ᠢ᠋ ᠰᠡᠷᠬᠦᠬᠡᠬᠦ</translation>
++        <extra-contents_path>/Screenlock/Reset To Default</extra-contents_path>
++    </message>
++    <message>
++        <source>Related Settings</source>
++        <translation type="vanished">ᠬᠠᠮᠢᠶ᠎ᠠ ᠪᠦᠬᠦᠢ ᠳᠤᠬᠢᠷᠠᠭᠤᠯᠭ᠎ᠠ</translation>
++    </message>
++    <message>
++        <source>Screenlock Set</source>
++        <translation type="vanished">锁屏设置</translation>
++    </message>
++    <message>
++        <source>Lock screen when screensaver boot</source>
++        <translation type="vanished">激活屏保时锁定屏幕</translation>
++    </message>
++    <message>
++        <source>Lock screen delay</source>
++        <translation type="vanished">ᠲᠤᠰ ᠴᠠᠭ᠎ᠤ᠋ᠨ ᠬᠡᠰᠡᠭ᠎ᠦ᠋ᠨ ᠠᠷᠤ ᠳᠡᠯᠭᠡᠴᠡ</translation>
++    </message>
++    <message>
++        <source>Min</source>
++        <translation type="vanished">分钟</translation>
++    </message>
++    <message>
++        <source>Select screenlock background</source>
++        <translation type="vanished">选择锁屏背景</translation>
++    </message>
++    <message>
++        <source>Browser online wp</source>
++        <translation type="vanished">浏览线上壁纸</translation>
++    </message>
++    <message>
++        <source>Browser local wp</source>
++        <translation type="vanished">浏览本地壁纸</translation>
++    </message>
++    <message>
++        <source>Show picture of screenlock on screenlogin</source>
++        <translation type="vanished">ᠣᠨᠢᠰᠤᠯᠠᠭᠰᠠᠨ ᠳᠡᠯᠭᠡᠴᠡᠨ ᠤ᠋ ᠬᠠᠨᠠᠨ ᠵᠢᠷᠤᠭ ᠨᠡᠪᠳᠡᠷᠡᠬᠦ ᠵᠠᠭᠠᠭ ᠭᠠᠳᠠᠷᠭᠤ ᠳᠡᠭᠡᠷ᠎ᠡ ᠢᠯᠡᠷᠡᠬᠦ</translation>
++        <extra-contents_path>/Screenlock/Show picture of screenlock on screenlogin</extra-contents_path>
++    </message>
++    <message>
++        <source>Enabel screenlock</source>
++        <translation type="vanished">开启锁屏</translation>
++    </message>
++    <message>
++        <source>Open</source>
++        <translation type="obsolete">浏览</translation>
++    </message>
++    <message>
++        <source>screenlock</source>
++        <translation type="vanished">锁屏</translation>
++    </message>
++    <message>
++        <source>picture</source>
++        <translation type="obsolete">图片</translation>
++    </message>
++    <message>
++        <source>Never</source>
++        <translation type="vanished">ᠶᠡᠷᠦ ᠡᠴᠡ ᠥᠬᠡᠢ</translation>
++    </message>
++    <message>
++        <source>1m</source>
++        <translation type="vanished">1m</translation>
++    </message>
++    <message>
++        <source>5m</source>
++        <translation type="vanished">5m</translation>
++    </message>
++    <message>
++        <source>10m</source>
++        <translation type="vanished">10m</translation>
++    </message>
++    <message>
++        <source>30m</source>
++        <translation type="vanished">30m</translation>
++    </message>
++    <message>
++        <source>45m</source>
++        <translation type="vanished">45m</translation>
++    </message>
++    <message>
++        <source>1h</source>
++        <translation type="vanished">1h</translation>
++    </message>
++    <message>
++        <source>1.5h</source>
++        <translation type="vanished">1.5h</translation>
++    </message>
++    <message>
++        <source>3h</source>
++        <translation type="vanished">3h</translation>
++    </message>
++    <message>
++        <source>2h</source>
++        <translation type="vanished">2h</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="187"/>
++        <source>Wallpaper files(*.jpg *.jpeg *.bmp *.dib *.png *.jfif *.jpe *.gif *.tif *.tiff *.wdp)</source>
++        <translation>ᠵᠢᠷᠤᠭ ᠤ᠋ᠨ ᠹᠠᠢᠯ (*.jpg *.jpeg *.bmp *.dib *.png *.jfif *.jpe *.gif *.tif *.tiff *.wdp)</translation>
++    </message>
++    <message>
++        <source>allFiles(*.*)</source>
++        <translation type="vanished">所有文件(*.*)</translation>
++    </message>
++    <message>
++        <source>1min</source>
++        <translation type="vanished">1 ᠮᠢᠨᠦ᠋ᠲ</translation>
++    </message>
++    <message>
++        <source>5min</source>
++        <translation type="vanished">5 ᠮᠢᠨᠦ᠋ᠲ</translation>
++    </message>
++    <message>
++        <source>10min</source>
++        <translation type="vanished">10 ᠮᠢᠨᠦ᠋ᠲ</translation>
++    </message>
++    <message>
++        <source>30min</source>
++        <translation type="vanished">30 ᠮᠢᠨᠦ᠋ᠲ</translation>
++    </message>
++    <message>
++        <source>45min</source>
++        <translation type="vanished">45 ᠮᠢᠨᠦ᠋ᠲ</translation>
++    </message>
++    <message>
++        <source>1hour</source>
++        <translation type="vanished">1 ᠴᠠᠭ</translation>
++    </message>
++    <message>
++        <source>2hour</source>
++        <translation type="vanished">2 ᠴᠠᠭ</translation>
++    </message>
++    <message>
++        <source>3hour</source>
++        <translation type="vanished">3 ᠴᠠᠭ</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="229"/>
++        <source>select custom wallpaper file</source>
++        <translation>ᠦᠪᠡᠷᠳᠡᠭᠡᠨ ᠳᠤᠭᠳᠠᠭᠠᠬᠤ ᠬᠠᠨᠠᠨ ᠵᠢᠷᠤᠭ ᠤ᠋ᠨ ᠹᠠᠢᠯ ᠢ᠋ ᠰᠣᠩᠭᠣᠬᠤ</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="230"/>
++        <source>Select</source>
++        <translation>ᠰᠣᠩᠭᠣᠬᠤ</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="231"/>
++        <source>Position: </source>
++        <translation>ᠪᠠᠢᠷᠢ: </translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="232"/>
++        <source>FileName: </source>
++        <translation>ᠹᠠᠢᠯ ᠤ᠋ᠨ ᠨᠡᠷ᠎ᠡ: </translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="233"/>
++        <source>FileType: </source>
++        <translation>ᠹᠠᠢᠯ ᠳᠦᠷᠦᠯ ᠵᠦᠢᠯ: </translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="234"/>
++        <source>Cancel</source>
++        <translation>ᠦᠬᠡᠢᠰᠬᠡᠬᠦ</translation>
++    </message>
++    <message>
++        <source>Monitor Off</source>
++        <translation type="vanished">ᠦᠵᠡᠬᠦᠷ ᠢ᠋ ᠬᠠᠭᠠᠬᠤ</translation>
++    </message>
++    <message>
++        <source>Screensaver</source>
++        <translation type="vanished">ᠳᠡᠯᠭᠡᠴᠡ ᠬᠠᠮᠠᠭᠠᠯᠠᠬᠤ</translation>
++    </message>
++    <message>
++        <source>Set</source>
++        <translation type="vanished">ᠣᠴᠢᠵᠤ ᠳᠤᠬᠢᠷᠠᠭᠤᠯᠬᠤ</translation>
++    </message>
++</context>
++<context>
++    <name>ScreenlockUi</name>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="74"/>
++        <source>Show picture of screenlock on screenlogin</source>
++        <translation>ᠣᠨᠢᠰᠤᠯᠠᠭᠰᠠᠨ ᠳᠡᠯᠭᠡᠴᠡᠨ ᠤ᠋ ᠬᠠᠨᠠᠨ ᠵᠢᠷᠤᠭ ᠨᠡᠪᠳᠡᠷᠡᠬᠦ ᠵᠠᠭᠠᠭ ᠭᠠᠳᠠᠷᠭᠤ ᠳᠡᠭᠡᠷ᠎ᠡ ᠢᠯᠡᠷᠡᠬᠦ</translation>
++        <extra-contents_path>/Screenlock/Show picture of screenlock on screenlogin</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="87"/>
++        <source>Leave lock (System will be locked when the paired phone gone)</source>
++        <translation>ᠣᠨᠢᠰᠤᠯᠠᠯ ᠠᠴᠠ ᠰᠠᠯᠬᠤ ( ᠭᠠᠷ ᠤᠲᠠᠰᠤ ᠠᠷᠢᠯᠤᠭᠰᠠᠨ ᠤ ᠳᠠᠷᠠᠭᠠᠬᠢ ᠰᠢᠰᠲ᠋ᠧᠮ ᠢ ᠲᠣᠭᠲᠠᠭᠠᠨ᠎ᠠ )</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="97"/>
++        <source>Specified device</source>
++        <translation>ᠲᠥᠬᠥᠭᠡᠷᠦᠮᠵᠢ ᠶᠢ ᠵᠢᠭᠠᠨ ᠲᠣᠭᠲᠠᠭᠠᠨ᠎ᠠ</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="114"/>
++        <source>No paired phone. Please turn to &apos;Bluetooth&apos; to pair.</source>
++        <translation>ᠲᠣᠬᠢᠷᠠᠯᠴᠠᠭᠰᠠᠨ ᠭᠠᠷ ᠤᠲᠠᠰᠤ ᠪᠠᠢ᠌ᠬᠤ ᠦᠭᠡᠢ “ ᠬᠥᠬᠡ ᠰᠢᠳᠦ “ᠳᠦ ᠰᠢᠯᠵᠢᠭᠦᠯᠦᠨ ᠲᠣᠬᠢᠷᠠᠭᠤᠯᠤᠭᠠᠷᠠᠢ</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="53"/>
++        <source>Screenlock</source>
++        <translation>ᠳᠡᠯᠭᠡᠴᠡ ᠣᠨᠢᠰᠤᠯᠠᠬᠤ</translation>
++        <extra-contents_path>/Screenlock/Screenlock</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="168"/>
++        <source>Choose Picture</source>
++        <translation type="unfinished"></translation>
++        <extra-contents_path>/Wallpaper/Choose Picture</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="172"/>
++        <source>Local Pictures</source>
++        <translation>ᠲᠤᠰ ᠭᠠᠵᠠᠷ᠎ᠤ᠋ᠨ ᠵᠢᠷᠤᠭ</translation>
++        <extra-contents_path>/Screenlock/Local Pictures</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="176"/>
++        <source>Online Pictures</source>
++        <translation>ᠱᠤᠭᠤᠮ ᠳᠡᠭᠡᠷᠡᠬᠢ ᠵᠢᠷᠤᠭ</translation>
++        <extra-contents_path>/Screenlock/Online Pictures</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="180"/>
++        <source>Reset To Default</source>
++        <translation>ᠠᠶᠠᠳᠠᠯ ᠢ᠋ ᠰᠡᠷᠬᠦᠬᠡᠬᠦ</translation>
++        <extra-contents_path>/Screenlock/Reset To Default</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="122"/>
++        <source>Bluetooth</source>
++        <translation>ᠬᠥᠬᠡ ᠰᠢᠳᠦ</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="239"/>
++        <source>No bluetooth adapter detected, can not use Leave Lock.</source>
++        <translation>ᠬᠥᠬᠡ ᠰᠢᠳᠦᠨ ᠦ ᠲᠣᠬᠢᠷᠠᠬᠤ ᠪᠠᠭᠠᠵᠢ ᠶᠢ ᠪᠠᠶᠢᠴᠠᠭᠠᠨ ᠰᠢᠯᠭᠠᠭᠰᠠᠨ ᠦᠭᠡᠶ ᠪᠣᠯ Leave Lock ᠶᠢ ᠬᠡᠷᠡᠭᠯᠡᠬᠦ ᠶᠢᠨ ᠠᠷᠭ᠎ᠠ ᠦᠭᠡᠶ</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="203"/>
++        <source>Monitor Off</source>
++        <translation>ᠦᠵᠡᠬᠦᠷ ᠢ᠋ ᠬᠠᠭᠠᠬᠤ</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="205"/>
++        <source>Screensaver</source>
++        <translation>ᠳᠡᠯᠭᠡᠴᠡ ᠬᠠᠮᠠᠭᠠᠯᠠᠬᠤ</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="200"/>
++        <source>Related Settings</source>
++        <translation>ᠬᠠᠮᠢᠶ᠎ᠠ ᠪᠦᠬᠦᠢ ᠳᠤᠬᠢᠷᠠᠭᠤᠯᠭ᠎ᠠ</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="204"/>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="206"/>
++        <source>Set</source>
++        <translation>ᠰᠢᠰᠲ᠋ᠧᠮ᠎ᠦ᠋ᠨ ᠳᠤᠬᠢᠷᠠᠭᠤᠯᠭ᠎ᠠ</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="266"/>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="647"/>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="681"/>
++        <source>Please select device</source>
++        <translation>ᠲᠥᠬᠥᠭᠡᠷᠦᠮᠵᠢ ᠶᠢ ᠰᠣᠩᠭᠣᠭᠠᠷᠠᠢ</translation>
++    </message>
++</context>
++<context>
++    <name>Screensaver</name>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="44"/>
++        <source>Screensaver</source>
++        <translation>ᠳᠡᠯᠭᠡᠴᠡ ᠬᠠᠮᠠᠭᠠᠯᠠᠬᠤ</translation>
++    </message>
++    <message>
++        <source>Idle time</source>
++        <translation type="vanished">ᠲᠤᠰ ᠴᠠᠭ ᠤ᠋ᠨ ᠬᠡᠰᠡᠭ ᠤ᠋ᠨ ᠳᠠᠷᠠᠭ᠎ᠠ ᠳᠡᠯᠭᠡᠴᠡᠨ ᠤ᠋ ᠬᠠᠮᠠᠭᠠᠯᠠᠯᠳᠠ ᠵᠢ ᠡᠬᠢᠯᠡᠬᠦᠯᠬᠦ</translation>
++        <extra-contents_path>/Screensaver/Idle time</extra-contents_path>
++    </message>
++    <message>
++        <source>Lock screen when activating screensaver</source>
++        <translation type="vanished">ᠳᠡᠯᠭᠡᠴᠡ᠎ᠶ᠋ᠢ ᠢᠳᠡᠪᠬᠢᠵᠢᠭᠦᠯᠬᠦ᠎ᠳ᠋ᠦ᠍ ᠳᠡᠯᠭᠡᠴᠡ᠎ᠶ᠋ᠢ ᠣᠨᠢᠰᠤᠯᠠᠬᠤ</translation>
++    </message>
++    <message>
++        <source>Enable screensaver</source>
++        <translation type="vanished">开启屏保</translation>
++    </message>
++    <message>
++        <source>Screensaver program</source>
++        <translation type="vanished">ᠳᠡᠯᠭᠡᠴᠡ ᠬᠠᠮᠠᠭᠠᠯᠠᠬᠤ ᠫᠷᠣᠭ᠌ᠷᠠᠮ</translation>
++        <extra-contents_path>/Screensaver/Screensaver program</extra-contents_path>
++    </message>
++    <message>
++        <source>idle time</source>
++        <translation type="vanished">等待时间</translation>
++    </message>
++    <message>
++        <source>Min</source>
++        <translation type="vanished">分钟</translation>
++    </message>
++    <message>
++        <source>Lock screen when screensaver boot</source>
++        <translation type="vanished">ᠳᠡᠯᠭᠡᠴᠡᠨ ᠤ᠋ ᠬᠠᠮᠠᠭᠠᠯᠠᠯᠳᠠ ᠵᠢ ᠡᠬᠢᠯᠡᠬᠦᠯᠬᠦ ᠦᠶ᠎ᠡ ᠳ᠋ᠤ᠌ ᠳᠡᠯᠭᠡᠴᠡ ᠵᠢ ᠣᠨᠢᠰᠤᠯᠠᠬᠤ</translation>
++    </message>
++    <message>
++        <source>screensaver</source>
++        <translation type="vanished">屏保</translation>
++    </message>
++    <message>
++        <source>Default_ukui</source>
++        <translation type="vanished">默认屏保</translation>
++    </message>
++    <message>
++        <source>View</source>
++        <translation type="vanished">ᠪᠠᠢᠴᠠᠭᠠᠵᠤ ᠦᠵᠡᠬᠦ</translation>
++    </message>
++    <message>
++        <source>Text(up to 30 characters):</source>
++        <translation type="vanished">ᠳᠡᠯᠭᠡᠴᠡ ᠬᠠᠮᠠᠭᠠᠯᠠᠬᠤ ᠲᠸᠺᠰᠲ ( ᠬᠠᠮᠤᠭ ᠤ᠋ᠨ ᠣᠯᠠᠨ ᠳ᠋ᠤ᠌ ᠪᠡᠨ 30 ᠦᠰᠦᠭ):</translation>
++    </message>
++    <message>
++        <source>Show rest time</source>
++        <translation type="vanished">ᠠᠮᠠᠷᠠᠬᠤ ᠴᠠᠭ ᠢ᠋ ᠢᠯᠡᠷᠡᠬᠦᠯᠬᠦ</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="182"/>
++        <source>UKUI</source>
++        <translation>UKUI</translation>
++    </message>
++    <message>
++        <source>Blank_Only</source>
++        <translation type="vanished">ᠬᠠᠷ᠎ᠠ ᠳᠡᠯᠭᠡᠴᠡ</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="182"/>
++        <source>Customize</source>
++        <translation>ᠦᠪᠡᠷᠳᠡᠭᠡᠨ ᠳᠤᠭᠳᠠᠭᠠᠬᠤ</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="189"/>
++        <source>5min</source>
++        <translation>5 ᠮᠢᠨᠦ᠋ᠲ</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="189"/>
++        <source>10min</source>
++        <translation>10 ᠮᠢᠨᠦ᠋ᠲ</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/>
++        <source>15min</source>
++        <translation>15 ᠮᠢᠨᠦ᠋ᠲ</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="189"/>
++        <source>30min</source>
++        <translation>30 ᠮᠢᠨᠦ᠋ᠲ</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/>
++        <source>1hour</source>
++        <translation>1 ᠴᠠᠭ</translation>
++    </message>
++    <message>
++        <source>Screensaver source</source>
++        <translation type="vanished">ᠳᠡᠯᠭᠡᠴᠡ ᠬᠠᠮᠠᠭᠠᠯᠠᠬᠤ ᠢᠷᠡᠯᠳᠡ</translation>
++    </message>
++    <message>
++        <source>Select</source>
++        <translation type="vanished">ᠰᠤᠩᠭᠤᠬᠤ</translation>
++    </message>
++    <message>
++        <source>Wallpaper files(*.jpg *.jpeg *.bmp *.dib *.png *.jfif *.jpe *.gif *.tif *.tiff *.wdp *.svg)</source>
++        <translation type="vanished">ᠬᠠᠨᠠᠨ ᠵᠢᠷᠤᠭ ᠤ᠋ᠨ ᠹᠠᠢᠯ (*.jpg *.jpeg *.bmp *.dib *.png *.jfif *.jpe *.gif *.tif *.tiff *.wdp *.svg)</translation>
++    </message>
++    <message>
++        <source>select custom screensaver dir</source>
++        <translation type="vanished">ᠦᠪᠡᠷᠳᠡᠭᠡᠨ ᠳᠤᠭᠳᠠᠭᠠᠬᠤ ᠳᠡᠯᠭᠡᠴᠡᠨ ᠤ᠋ ᠬᠠᠮᠠᠭᠠᠯᠠᠯᠳᠠ ᠵᠢᠨ ᠵᠢᠮ ᠢ᠋ ᠰᠣᠩᠭᠣᠬᠤ</translation>
++    </message>
++    <message>
++        <source>Position: </source>
++        <translation type="vanished">ᠪᠠᠢᠷᠢ: </translation>
++    </message>
++    <message>
++        <source>FileName: </source>
++        <translation type="vanished">ᠹᠠᠢᠯ ᠤ᠋ᠨ ᠨᠡᠷ᠎ᠡ: </translation>
++    </message>
++    <message>
++        <source>FileType: </source>
++        <translation type="vanished">ᠹᠠᠢᠯ ᠤ᠋ᠨ ᠳᠦᠷᠦᠯ ᠵᠦᠢᠯ: </translation>
++    </message>
++    <message>
++        <source>Cancel</source>
++        <translation type="vanished">ᠦᠬᠡᠢᠰᠬᠡᠬᠦ</translation>
++    </message>
++    <message>
++        <source>Switching time</source>
++        <translation type="vanished">ᠳᠠᠪᠳᠠᠮᠵᠢ ᠵᠢ ᠰᠣᠯᠢᠬᠤ</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="176"/>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="189"/>
++        <source>1min</source>
++        <translation>1 ᠮᠢᠨᠦ᠋ᠲ</translation>
++    </message>
++    <message>
++        <source>Ordinal</source>
++        <translation type="vanished">ᠳᠠᠷᠠᠭᠠᠯᠠᠯ ᠵᠢᠡᠷ</translation>
++    </message>
++    <message>
++        <source>Random switching</source>
++        <translation type="vanished">ᠳᠠᠰᠢᠷᠠᠮ ᠵᠢᠡᠷ ᠰᠣᠯᠢᠬᠤ</translation>
++    </message>
++    <message>
++        <source>Display text</source>
++        <translation type="vanished">显示文本</translation>
++    </message>
++    <message>
++        <source>Enter text, up to 30 characters</source>
++        <translation type="vanished">输入文本,最多30个字符</translation>
++    </message>
++    <message>
++        <source>Text position</source>
++        <translation type="vanished">ᠲᠸᠺᠰᠲ ᠤ᠋ᠨ ᠪᠠᠢᠷᠢ</translation>
++    </message>
++    <message>
++        <source>Centered</source>
++        <translation type="vanished">ᠳᠦᠪᠯᠡᠷᠡᠬᠦᠯᠬᠦ</translation>
++    </message>
++    <message>
++        <source>Randow(Bubble text)</source>
++        <translation type="vanished">ᠳᠠᠰᠢᠷᠠᠮ ( ᠬᠦᠬᠡᠰᠦ ᠲᠸᠺᠰᠲ)</translation>
++    </message>
++    <message>
++        <source>1m</source>
++        <translation type="vanished">1m</translation>
++    </message>
++    <message>
++        <source>5m</source>
++        <translation type="vanished">5m</translation>
++    </message>
++    <message>
++        <source>10m</source>
++        <translation type="vanished">10m</translation>
++    </message>
++    <message>
++        <source>30m</source>
++        <translation type="vanished">30m</translation>
++    </message>
++    <message>
++        <source>45m</source>
++        <translation type="vanished">45m</translation>
++    </message>
++    <message>
++        <source>1h</source>
++        <translation type="vanished">1h</translation>
++    </message>
++    <message>
++        <source>1.5h</source>
++        <translation type="vanished">1.5h</translation>
++    </message>
++    <message>
++        <source>3h</source>
++        <translation type="vanished">3h</translation>
++    </message>
++    <message>
++        <source>Random</source>
++        <translation type="vanished">ᠳᠠᠰᠢᠷᠠᠮ</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/>
++        <source>Never</source>
++        <translation>ᠶᠡᠷᠦ ᠡᠴᠡ ᠥᠬᠡᠢ</translation>
++    </message>
++</context>
++<context>
++    <name>ScreensaverUi</name>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="41"/>
++        <source>Screensaver</source>
++        <translation>ᠳᠡᠯᠭᠡᠴᠡ ᠬᠠᠮᠠᠭᠠᠯᠠᠬᠤ</translation>
++        <extra-contents_path>/Screensaver/Screensaver</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="54"/>
++        <source>Idle time</source>
++        <translation>ᠲᠤᠰ ᠴᠠᠭ ᠤ᠋ᠨ ᠬᠡᠰᠡᠭ ᠤ᠋ᠨ ᠳᠠᠷᠠᠭ᠎ᠠ ᠳᠡᠯᠭᠡᠴᠡᠨ ᠤ᠋ ᠬᠠᠮᠠᠭᠠᠯᠠᠯᠳᠠ ᠵᠢ ᠡᠬᠢᠯᠡᠬᠦᠯᠬᠦ</translation>
++        <extra-contents_path>/Screensaver/Idle time</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="56"/>
++        <source>Screensaver program</source>
++        <translation>ᠳᠡᠯᠭᠡᠴᠡ ᠬᠠᠮᠠᠭᠠᠯᠠᠬᠤ ᠫᠷᠣᠭ᠌ᠷᠠᠮ</translation>
++        <extra-contents_path>/Screensaver/Screensaver program</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="88"/>
++        <source>Screensaver source</source>
++        <translation>ᠳᠡᠯᠭᠡᠴᠡ ᠬᠠᠮᠠᠭᠠᠯᠠᠬᠤ ᠢᠷᠡᠯᠳᠡ</translation>
++        <extra-contents_path>/Screensaver/Screensaver source</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="93"/>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="457"/>
++        <source>Select</source>
++        <translation>ᠰᠣᠩᠭᠣᠬᠤ</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="114"/>
++        <source>Ordinal</source>
++        <translation>ᠳᠠᠷᠠᠭᠠᠯᠠᠯ ᠵᠢᠡᠷ</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="115"/>
++        <source>Random</source>
++        <translation>ᠳᠠᠰᠢᠷᠠᠮ</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="122"/>
++        <source>Random switching</source>
++        <translation>ᠳᠠᠰᠢᠷᠠᠮ ᠵᠢᠡᠷ ᠰᠣᠯᠢᠬᠤ</translation>
++        <extra-contents_path>/Screensaver/Random switching</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="142"/>
++        <source>Switching time</source>
++        <translation>ᠳᠠᠪᠳᠠᠮᠵᠢ ᠵᠢ ᠰᠣᠯᠢᠬᠤ</translation>
++        <extra-contents_path>/Screensaver/Switching time</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="161"/>
++        <source>Text(up to 30 characters):</source>
++        <translation>ᠳᠡᠯᠭᠡᠴᠡ ᠬᠠᠮᠠᠭᠠᠯᠠᠬᠤ ᠲᠸᠺᠰᠲ ( ᠬᠠᠮᠤᠭ ᠤ᠋ᠨ ᠣᠯᠠᠨ ᠳ᠋ᠤ᠌ ᠪᠡᠨ 30 ᠦᠰᠦᠭ):</translation>
++        <extra-contents_path>/Screensaver/Text(up to 30 characters):</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="184"/>
++        <source>Text position</source>
++        <translation>ᠲᠸᠺᠰᠲ ᠤ᠋ᠨ ᠪᠠᠢᠷᠢ</translation>
++        <extra-contents_path>/Screensaver/Text position</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="192"/>
++        <source>Centered</source>
++        <translation>ᠳᠦᠪᠯᠡᠷᠡᠬᠦᠯᠬᠦ</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="193"/>
++        <source>Randow(Bubble text)</source>
++        <translation>ᠳᠠᠰᠢᠷᠠᠮ ( ᠬᠦᠬᠡᠰᠦ ᠲᠸᠺᠰᠲ)</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="215"/>
++        <source>Show rest time</source>
++        <translation>ᠠᠮᠠᠷᠠᠬᠤ ᠴᠠᠭ ᠢ᠋ ᠢᠯᠡᠷᠡᠬᠦᠯᠬᠦ</translation>
++        <extra-contents_path>/Screensaver/Show rest time</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="226"/>
++        <source>Lock screen when screensaver boot</source>
++        <translation>ᠳᠡᠯᠭᠡᠴᠡᠨ ᠤ᠋ ᠬᠠᠮᠠᠭᠠᠯᠠᠯᠳᠠ ᠵᠢ ᠡᠬᠢᠯᠡᠬᠦᠯᠬᠦ ᠦᠶ᠎ᠡ ᠳ᠋ᠤ᠌ ᠳᠡᠯᠭᠡᠴᠡ ᠵᠢ ᠣᠨᠢᠰᠤᠯᠠᠬᠤ</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="415"/>
++        <source>Wallpaper files(*.jpg *.jpeg *.bmp *.dib *.png *.jfif *.jpe *.gif *.tif *.tiff *.wdp *.svg)</source>
++        <translation>ᠬᠠᠨᠠᠨ ᠵᠢᠷᠤᠭ ᠤ᠋ᠨ ᠹᠠᠢᠯ (*.jpg *.jpeg *.bmp *.dib *.png *.jfif *.jpe *.gif *.tif *.tiff *.wdp *.svg)</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="456"/>
++        <source>select custom screensaver dir</source>
++        <translation>ᠦᠪᠡᠷᠳᠡᠭᠡᠨ ᠳᠤᠭᠳᠠᠭᠠᠬᠤ ᠳᠡᠯᠭᠡᠴᠡᠨ ᠤ᠋ ᠬᠠᠮᠠᠭᠠᠯᠠᠯᠳᠠ ᠵᠢᠨ ᠵᠢᠮ ᠢ᠋ ᠰᠣᠩᠭᠣᠬᠤ</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="458"/>
++        <source>Position: </source>
++        <translation>ᠪᠠᠢᠷᠢ: </translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="459"/>
++        <source>FileName: </source>
++        <translation>ᠹᠠᠢᠯ ᠤ᠋ᠨ ᠨᠡᠷ᠎ᠡ: </translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="460"/>
++        <source>FileType: </source>
++        <translation>ᠹᠠᠢᠯ ᠳᠦᠷᠦᠯ ᠵᠦᠢᠯ: </translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="461"/>
++        <source>Cancel</source>
++        <translation>ᠦᠬᠡᠢᠰᠬᠡᠬᠦ</translation>
++    </message>
++</context>
++</TS>
+diff --git a/ukccplugins_i18n_ts/tr.ts b/ukccplugins_i18n_ts/tr.ts
+new file mode 100644
+index 0000000..4fc5b4d
+--- /dev/null
++++ b/ukccplugins_i18n_ts/tr.ts
+@@ -0,0 +1,499 @@
++<?xml version="1.0" encoding="utf-8"?>
++<!DOCTYPE TS>
++<TS version="2.1" language="tr_TR">
++<context>
++    <name>Screenlock</name>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="39"/>
++        <source>Screenlock</source>
++        <translation>Ekran kilidi</translation>
++    </message>
++    <message>
++        <source>Screenlock Interface</source>
++        <translation type="vanished">Ekran Kilidi Arayüzü</translation>
++    </message>
++    <message>
++        <source>Screenlock Set</source>
++        <translation type="vanished">Ekran Kilidi Ayarı</translation>
++    </message>
++    <message>
++        <source>Lock screen when screensaver boot</source>
++        <translation type="vanished">Ekran koruyucu açıldığında ekranı kilitle</translation>
++        <extra-contents_path>/Screenlock/Lock screen when screensaver boot</extra-contents_path>
++    </message>
++    <message>
++        <source>Lock screen delay</source>
++        <translation type="vanished">Ekran kilidi gecikmesi</translation>
++    </message>
++    <message>
++        <source>Min</source>
++        <translation type="vanished">Dk</translation>
++    </message>
++    <message>
++        <source>Select screenlock background</source>
++        <translation type="vanished">Kilit Ekranı Arkaplanını Seç</translation>
++    </message>
++    <message>
++        <source>Browser online wp</source>
++        <translation type="vanished">İnternetten Al</translation>
++    </message>
++    <message>
++        <source>Browser local wp</source>
++        <translation type="vanished">Bilgisayardan Ekle</translation>
++    </message>
++    <message>
++        <source>Show picture of screenlock on screenlogin</source>
++        <translation type="vanished">Ekran girişinde ekran kilidinin resmini göster</translation>
++        <extra-contents_path>/Screenlock/Show picture of screenlock on screenlogin</extra-contents_path>
++    </message>
++    <message>
++        <source>Enabel screenlock</source>
++        <translation type="vanished">Ekran kilidi aktif</translation>
++    </message>
++    <message>
++        <source>Open</source>
++        <translation type="obsolete">Aç</translation>
++    </message>
++    <message>
++        <source>screenlock</source>
++        <translation type="vanished">Ekran kilidi</translation>
++    </message>
++    <message>
++        <source>picture</source>
++        <translation type="obsolete">Resim</translation>
++    </message>
++    <message>
++        <source>Never</source>
++        <translation type="vanished">Asla</translation>
++    </message>
++    <message>
++        <source>5m</source>
++        <translation type="vanished">5 dk</translation>
++    </message>
++    <message>
++        <source>10m</source>
++        <translation type="vanished">10 dk</translation>
++    </message>
++    <message>
++        <source>30m</source>
++        <translation type="vanished">30 dk</translation>
++    </message>
++    <message>
++        <source>45m</source>
++        <translation type="vanished">45 dk</translation>
++    </message>
++    <message>
++        <source>1m</source>
++        <translation type="vanished">1 dk</translation>
++    </message>
++    <message>
++        <source>1h</source>
++        <translation type="vanished">1 sa</translation>
++    </message>
++    <message>
++        <source>1.5h</source>
++        <translation type="vanished">1.5 sa</translation>
++    </message>
++    <message>
++        <source>3h</source>
++        <translation type="vanished">3 sa</translation>
++    </message>
++    <message>
++        <source>2h</source>
++        <translation type="obsolete">3 sa {2h?}</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="187"/>
++        <source>Wallpaper files(*.jpg *.jpeg *.bmp *.dib *.png *.jfif *.jpe *.gif *.tif *.tiff *.wdp)</source>
++        <translation type="unfinished">Duvarkağıdı Dosyaları(*.jpg *.jpeg *.bmp *.dib *.png *.jfif *.jpe *.gif *.tif *.tiff *.wdp)</translation>
++    </message>
++    <message>
++        <source>allFiles(*.*)</source>
++        <translation type="obsolete">Tüm Dosyalar(*.*)</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="229"/>
++        <source>select custom wallpaper file</source>
++        <translation type="unfinished">Özel duvar kağıdı dosyasını seç</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="230"/>
++        <source>Select</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="231"/>
++        <source>Position: </source>
++        <translation type="unfinished">Konum: </translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="232"/>
++        <source>FileName: </source>
++        <translation type="unfinished">Dosya Adı: </translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="233"/>
++        <source>FileType: </source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="234"/>
++        <source>Cancel</source>
++        <translation type="unfinished">İptal</translation>
++    </message>
++    <message>
++        <source>Set</source>
++        <translation type="obsolete">Ayarla</translation>
++    </message>
++</context>
++<context>
++    <name>ScreenlockUi</name>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="74"/>
++        <source>Show picture of screenlock on screenlogin</source>
++        <translation type="unfinished">Ekran girişinde ekran kilidinin resmini göster</translation>
++        <extra-contents_path>/Screenlock/Show picture of screenlock on screenlogin</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="87"/>
++        <source>Leave lock (System will be locked when the paired phone gone)</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="97"/>
++        <source>Specified device</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="114"/>
++        <source>No paired phone. Please turn to &apos;Bluetooth&apos; to pair.</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="53"/>
++        <source>Screenlock</source>
++        <translation type="unfinished">Ekran kilidi</translation>
++        <extra-contents_path>/Screenlock/Screenlock</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="168"/>
++        <source>Choose Picture</source>
++        <translation type="unfinished"></translation>
++        <extra-contents_path>/Wallpaper/Choose Picture</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="172"/>
++        <source>Local Pictures</source>
++        <translation type="unfinished"></translation>
++        <extra-contents_path>/Screenlock/Local Pictures</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="176"/>
++        <source>Online Pictures</source>
++        <translation type="unfinished"></translation>
++        <extra-contents_path>/Screenlock/Online Pictures</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="180"/>
++        <source>Reset To Default</source>
++        <translation type="unfinished"></translation>
++        <extra-contents_path>/Screenlock/Reset To Default</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="122"/>
++        <source>Bluetooth</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="239"/>
++        <source>No bluetooth adapter detected, can not use Leave Lock.</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="203"/>
++        <source>Monitor Off</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="205"/>
++        <source>Screensaver</source>
++        <translation type="unfinished">Ekran Koruyucu</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="200"/>
++        <source>Related Settings</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="204"/>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="206"/>
++        <source>Set</source>
++        <translation type="unfinished">Ayarla</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="266"/>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="647"/>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="681"/>
++        <source>Please select device</source>
++        <translation type="unfinished"></translation>
++    </message>
++</context>
++<context>
++    <name>Screensaver</name>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="44"/>
++        <source>Screensaver</source>
++        <translation>Ekran Koruyucu</translation>
++    </message>
++    <message>
++        <source>Enable screensaver</source>
++        <translation type="vanished">Ekran Koruyucu Aktif</translation>
++        <extra-contents_path>/screensaver/Enable screensaver</extra-contents_path>
++    </message>
++    <message>
++        <source>Screensaver program</source>
++        <translation type="vanished">Ekran Koruyucu Programı</translation>
++        <extra-contents_path>/Screensaver/Screensaver program</extra-contents_path>
++    </message>
++    <message>
++        <source>idle time</source>
++        <translation type="vanished">Bekleme Süresi</translation>
++        <extra-contents_path>/screensaver/idle time</extra-contents_path>
++    </message>
++    <message>
++        <source>Min</source>
++        <translation type="vanished">Dk</translation>
++    </message>
++    <message>
++        <source>Lock screen when screensaver boot</source>
++        <translation type="vanished">Ekran koruyucu açıldığında ekranı kilitle</translation>
++    </message>
++    <message>
++        <source>screensaver</source>
++        <translation type="vanished">Ekran Koruyucu</translation>
++    </message>
++    <message>
++        <source>Default_ukui</source>
++        <translation type="vanished">Ukui Varsayılanı</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="182"/>
++        <source>UKUI</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <source>Blank_Only</source>
++        <translation type="vanished">Sadece Kalın</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="182"/>
++        <source>Customize</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="189"/>
++        <source>5min</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="189"/>
++        <source>10min</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="189"/>
++        <source>30min</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/>
++        <source>15min</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/>
++        <source>1hour</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <source>Position: </source>
++        <translation type="obsolete">Konum: </translation>
++    </message>
++    <message>
++        <source>FileName: </source>
++        <translation type="obsolete">Dosya Adı: </translation>
++    </message>
++    <message>
++        <source>Cancel</source>
++        <translation type="obsolete">İptal</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="176"/>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="189"/>
++        <source>1min</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <source>Random</source>
++        <translation type="vanished">Rasgele</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/>
++        <source>Never</source>
++        <translation>Asla</translation>
++    </message>
++    <message>
++        <source>5m</source>
++        <translation type="vanished">5 dk</translation>
++    </message>
++    <message>
++        <source>10m</source>
++        <translation type="vanished">10 dk</translation>
++    </message>
++    <message>
++        <source>30m</source>
++        <translation type="vanished">30 dk</translation>
++    </message>
++    <message>
++        <source>45m</source>
++        <translation type="vanished">45 dk</translation>
++    </message>
++    <message>
++        <source>1m</source>
++        <translation type="vanished">1 dk</translation>
++    </message>
++    <message>
++        <source>1h</source>
++        <translation type="vanished">1 sa</translation>
++    </message>
++    <message>
++        <source>1.5h</source>
++        <translation type="vanished">1.5 sa</translation>
++    </message>
++    <message>
++        <source>3h</source>
++        <translation type="vanished">3 sa</translation>
++    </message>
++</context>
++<context>
++    <name>ScreensaverUi</name>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="41"/>
++        <source>Screensaver</source>
++        <translation type="unfinished">Ekran Koruyucu</translation>
++        <extra-contents_path>/Screensaver/Screensaver</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="54"/>
++        <source>Idle time</source>
++        <translation type="unfinished"></translation>
++        <extra-contents_path>/Screensaver/Idle time</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="56"/>
++        <source>Screensaver program</source>
++        <translation type="unfinished">Ekran Koruyucu Programı</translation>
++        <extra-contents_path>/Screensaver/Screensaver program</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="88"/>
++        <source>Screensaver source</source>
++        <translation type="unfinished"></translation>
++        <extra-contents_path>/Screensaver/Screensaver source</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="93"/>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="457"/>
++        <source>Select</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="114"/>
++        <source>Ordinal</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="115"/>
++        <source>Random</source>
++        <translation type="unfinished">Rasgele</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="122"/>
++        <source>Random switching</source>
++        <translation type="unfinished"></translation>
++        <extra-contents_path>/Screensaver/Random switching</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="142"/>
++        <source>Switching time</source>
++        <translation type="unfinished"></translation>
++        <extra-contents_path>/Screensaver/Switching time</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="161"/>
++        <source>Text(up to 30 characters):</source>
++        <translation type="unfinished"></translation>
++        <extra-contents_path>/Screensaver/Text(up to 30 characters):</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="184"/>
++        <source>Text position</source>
++        <translation type="unfinished"></translation>
++        <extra-contents_path>/Screensaver/Text position</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="192"/>
++        <source>Centered</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="193"/>
++        <source>Randow(Bubble text)</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="215"/>
++        <source>Show rest time</source>
++        <translation type="unfinished"></translation>
++        <extra-contents_path>/Screensaver/Show rest time</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="226"/>
++        <source>Lock screen when screensaver boot</source>
++        <translation type="unfinished">Ekran koruyucu açıldığında ekranı kilitle</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="415"/>
++        <source>Wallpaper files(*.jpg *.jpeg *.bmp *.dib *.png *.jfif *.jpe *.gif *.tif *.tiff *.wdp *.svg)</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="456"/>
++        <source>select custom screensaver dir</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="458"/>
++        <source>Position: </source>
++        <translation type="unfinished">Konum: </translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="459"/>
++        <source>FileName: </source>
++        <translation type="unfinished">Dosya Adı: </translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="460"/>
++        <source>FileType: </source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="461"/>
++        <source>Cancel</source>
++        <translation type="unfinished">İptal</translation>
++    </message>
++</context>
++</TS>
+diff --git a/ukccplugins_i18n_ts/ug.ts b/ukccplugins_i18n_ts/ug.ts
+new file mode 100644
+index 0000000..b5fbfd2
+--- /dev/null
++++ b/ukccplugins_i18n_ts/ug.ts
+@@ -0,0 +1,626 @@
++<?xml version="1.0" encoding="utf-8"?>
++<!DOCTYPE TS>
++<TS version="2.1" language="ug">
++<context>
++    <name>Screenlock</name>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="39"/>
++        <source>Screenlock</source>
++        <translation>ئېكران قۇلۇپى</translation>
++    </message>
++    <message>
++        <source>Screenlock Interface</source>
++        <translation type="vanished">ئېكران قۇلۇپى ئارايۈز</translation>
++    </message>
++    <message>
++        <source>Show message on lock screen</source>
++        <translation type="vanished">قۇلۇپ ئېكرانىدا ئۇچۇر كۆرسىتىش</translation>
++    </message>
++    <message>
++        <source>Browse</source>
++        <translation type="vanished">كۆرۈش</translation>
++        <extra-contents_path>/Screenlock/Browse</extra-contents_path>
++    </message>
++    <message>
++        <source>Online Picture</source>
++        <translation type="vanished">توردا رەسىم</translation>
++        <extra-contents_path>/Screenlock/Online Picture</extra-contents_path>
++    </message>
++    <message>
++        <source>Reset To Default</source>
++        <translation type="vanished">سۈكۈتكە قايتاي</translation>
++        <extra-contents_path>/Screenlock/Reset To Default</extra-contents_path>
++    </message>
++    <message>
++        <source>TextLabel</source>
++        <translation type="obsolete">TextLabel</translation>
++    </message>
++    <message>
++        <source>Screenlock Set</source>
++        <translation type="vanished">锁屏设置</translation>
++    </message>
++    <message>
++        <source>Lock screen when screensaver boot</source>
++        <translation type="vanished">ئېكراننى كۆزنەك تاقاشتا ئېكراننى قۇلۇپلاش</translation>
++        <extra-contents_path>/Screenlock/Lock screen when screensaver boot</extra-contents_path>
++    </message>
++    <message>
++        <source>Lock screen delay</source>
++        <translation type="vanished">قۇلۇپ ئېكرانى كېچىكتۈرۈش</translation>
++    </message>
++    <message>
++        <source>Min</source>
++        <translation type="vanished">分钟</translation>
++    </message>
++    <message>
++        <source>Select screenlock background</source>
++        <translation type="vanished">选择锁屏背景</translation>
++    </message>
++    <message>
++        <source>Browser online wp</source>
++        <translation type="vanished">浏览线上壁纸</translation>
++    </message>
++    <message>
++        <source>Browser local wp</source>
++        <translation type="vanished">浏览本地壁纸</translation>
++    </message>
++    <message>
++        <source>Show picture of screenlock on screenlogin</source>
++        <translation type="vanished">screenlogin دا ئېكران قۇلۇپىنىڭ سۈرىتىنى كۆرسىتىش پروگراممىسى</translation>
++        <extra-contents_path>/Screenlock/Show picture of screenlock on screenlogin</extra-contents_path>
++    </message>
++    <message>
++        <source>Enabel screenlock</source>
++        <translation type="vanished">开启锁屏</translation>
++    </message>
++    <message>
++        <source>Open</source>
++        <translation type="obsolete">浏览</translation>
++    </message>
++    <message>
++        <source>screenlock</source>
++        <translation type="vanished">锁屏</translation>
++    </message>
++    <message>
++        <source>picture</source>
++        <translation type="obsolete">图片</translation>
++    </message>
++    <message>
++        <source>Never</source>
++        <translation type="vanished">مەڭگۈ</translation>
++    </message>
++    <message>
++        <source>1m</source>
++        <translation type="vanished">1م</translation>
++    </message>
++    <message>
++        <source>5m</source>
++        <translation type="vanished">5م</translation>
++    </message>
++    <message>
++        <source>10m</source>
++        <translation type="vanished">10م</translation>
++    </message>
++    <message>
++        <source>30m</source>
++        <translation type="vanished">30م</translation>
++    </message>
++    <message>
++        <source>45m</source>
++        <translation type="vanished">45م</translation>
++    </message>
++    <message>
++        <source>1h</source>
++        <translation type="vanished">1ھ</translation>
++    </message>
++    <message>
++        <source>1.5h</source>
++        <translation type="vanished">1.5h</translation>
++    </message>
++    <message>
++        <source>3h</source>
++        <translation type="vanished">3ھ</translation>
++    </message>
++    <message>
++        <source>2h</source>
++        <translation type="vanished">2ھ</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="187"/>
++        <source>Wallpaper files(*.jpg *.jpeg *.bmp *.dib *.png *.jfif *.jpe *.gif *.tif *.tiff *.wdp)</source>
++        <translation>تام قەغىزى ھۆججەتلىرى(*.jpg *.jpeg *.bmp *.dib *.png *.jfif *.jpe *.gif *.tif *.tiff *.wdp)</translation>
++    </message>
++    <message>
++        <source>allFiles(*.*)</source>
++        <translation type="vanished">所有文件(*.*)</translation>
++    </message>
++    <message>
++        <source>1min</source>
++        <translation type="obsolete">1min</translation>
++    </message>
++    <message>
++        <source>5min</source>
++        <translation type="obsolete">5min</translation>
++    </message>
++    <message>
++        <source>10min</source>
++        <translation type="obsolete">10min</translation>
++    </message>
++    <message>
++        <source>30min</source>
++        <translation type="obsolete">30min</translation>
++    </message>
++    <message>
++        <source>45min</source>
++        <translation type="obsolete">1min {45m?}</translation>
++    </message>
++    <message>
++        <source>1hour</source>
++        <translation type="obsolete">1ھۇدا</translation>
++    </message>
++    <message>
++        <source>2hour</source>
++        <translation type="obsolete">1ھۇدا {2h?}</translation>
++    </message>
++    <message>
++        <source>3hour</source>
++        <translation type="obsolete">1ھۇدا {3h?}</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="229"/>
++        <source>select custom wallpaper file</source>
++        <translation>خاس تام قەغىزى ھۆججىتىنى تاللاش</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="230"/>
++        <source>Select</source>
++        <translation>تاللاش</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="231"/>
++        <source>Position: </source>
++        <translation>ئورنى: </translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="232"/>
++        <source>FileName: </source>
++        <translation>ھۆججەت نامى: </translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="233"/>
++        <source>FileType: </source>
++        <translation>:ھۆججەت تۈرى </translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="234"/>
++        <source>Cancel</source>
++        <translation>ئەمەلدىن قالدۇرۇش</translation>
++    </message>
++</context>
++<context>
++    <name>ScreenlockUi</name>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="74"/>
++        <source>Show picture of screenlock on screenlogin</source>
++        <translation>كۆرسىتىش ئېكرانىدىكى تام قەغىزى كىرىش كۆرۈنمە يۈزىدە</translation>
++        <extra-contents_path>/Screenlock/Show picture of screenlock on screenlogin</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="87"/>
++        <source>Leave lock (System will be locked when the paired phone gone)</source>
++        <translation>قۇلۇپنى قالدۇرۇپ قويۇش (بىر جۈپ يانفون يوقاپ كەتكەندە سىستېما قۇلۇپلىنىدۇ)</translation>
++        <extra-contents_path>/Screenlock/Leave lock (System will be locked when the paired phone gone)</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="97"/>
++        <source>Specified device</source>
++        <translation>بەلگىلەنگەن ئۈسكۈنە</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="114"/>
++        <source>No paired phone. Please turn to &apos;Bluetooth&apos; to pair.</source>
++        <translation>جۈپ تېلېفون يوق &apos;كۆكچىش&apos; نى قوشۇۋېلىپ قوشۇڭ.</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="53"/>
++        <source>Screenlock</source>
++        <translation>ئېكران قۇلۇپى</translation>
++        <extra-contents_path>/Screenlock/Screenlock</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="168"/>
++        <source>Choose Picture</source>
++        <translation type="unfinished"></translation>
++        <extra-contents_path>/Wallpaper/Choose Picture</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="172"/>
++        <source>Local Pictures</source>
++        <translation>يەرلىك رەسىملەر</translation>
++        <extra-contents_path>/Screenlock/Local Pictures</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="176"/>
++        <source>Online Pictures</source>
++        <translation>توردىكى رەسىملەر</translation>
++        <extra-contents_path>/Screenlock/Online Pictures</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="180"/>
++        <source>Reset To Default</source>
++        <translation>سۈكۈتكە قايتاي</translation>
++        <extra-contents_path>/Screenlock/Reset To Default</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="122"/>
++        <source>Bluetooth</source>
++        <translation>كۆكچىش</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="239"/>
++        <source>No bluetooth adapter detected, can not use Leave Lock.</source>
++        <translation>كۆكچىش ماسلاشتۇرغۇچ بايقالمىدى، Leave Lock نى ئىشلەتكىلى بولمايدۇ.</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="203"/>
++        <source>Monitor Off</source>
++        <translation>كۆزەتكۈچنى ئۆچۈرۈش</translation>
++        <extra-contents_path>/Screenlock/Monitor Off</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="205"/>
++        <source>Screensaver</source>
++        <translation>ئېكران قوغداش</translation>
++        <extra-contents_path>/Screenlock/Screensaver</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="200"/>
++        <source>Related Settings</source>
++        <translation>مۇناسىۋەتلىك تەڭشەكلەر</translation>
++        <extra-contents_path>/Screenlock/Related Settings</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="204"/>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="206"/>
++        <source>Set</source>
++        <translation>بەلگىلەش</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="266"/>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="647"/>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="681"/>
++        <source>Please select device</source>
++        <translation>ئۈسكۈنىنى تاللاڭ</translation>
++    </message>
++</context>
++<context>
++    <name>Screensaver</name>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="44"/>
++        <source>Screensaver</source>
++        <translation>ئېكران قوغداش</translation>
++    </message>
++    <message>
++        <source>Idle time</source>
++        <translation type="vanished">بىكار ۋاقتى</translation>
++        <extra-contents_path>/Screensaver/Idle time</extra-contents_path>
++    </message>
++    <message>
++        <source>Lock screen when activating screensaver</source>
++        <translation type="vanished">ئېكران ئېكرانىنى قوزغىتىپ تۇرغاندا ئېكراننى قۇلۇپلاش</translation>
++    </message>
++    <message>
++        <source>Enable screensaver</source>
++        <translation type="vanished">开启屏保</translation>
++    </message>
++    <message>
++        <source>Screensaver program</source>
++        <translation type="vanished">ئېكران ئېكرانى پروگراممىسى</translation>
++        <extra-contents_path>/Screensaver/Screensaver program</extra-contents_path>
++    </message>
++    <message>
++        <source>idle time</source>
++        <translation type="vanished">等待时间</translation>
++    </message>
++    <message>
++        <source>Min</source>
++        <translation type="vanished">分钟</translation>
++    </message>
++    <message>
++        <source>Lock screen when screensaver boot</source>
++        <translation type="vanished">激活屏保时锁定屏幕</translation>
++    </message>
++    <message>
++        <source>screensaver</source>
++        <translation type="vanished">屏保</translation>
++    </message>
++    <message>
++        <source>Default_ukui</source>
++        <translation type="vanished">默认屏保</translation>
++    </message>
++    <message>
++        <source>View</source>
++        <translation type="vanished">كۆرۈش</translation>
++    </message>
++    <message>
++        <source>Text(up to 30 characters):</source>
++        <translation type="vanished">تېكىست(ئەڭ كۆپ بولغاندا 30 ھەرپ):</translation>
++    </message>
++    <message>
++        <source>Show rest time</source>
++        <translation type="vanished">ئارام ئېلىش ۋاقتىنى كۆرسىتىش</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="182"/>
++        <source>UKUI</source>
++        <translation>UKUI</translation>
++    </message>
++    <message>
++        <source>Blank_Only</source>
++        <translation type="vanished">Blank_Only</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="182"/>
++        <source>Customize</source>
++        <translation>خاسلاشتۇرۇش</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="189"/>
++        <source>5min</source>
++        <translation>بەش مىنۇت</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="189"/>
++        <source>10min</source>
++        <translation>ئون مىنۇت</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/>
++        <source>15min</source>
++        <translation>15 مىنۇت</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="189"/>
++        <source>30min</source>
++        <translation>ئوتتۇز مىنۇت</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/>
++        <source>1hour</source>
++        <translation>بىر سائەت</translation>
++    </message>
++    <message>
++        <source>Screensaver source</source>
++        <translation type="vanished">ئېكران يۈزى مەنبەسى</translation>
++    </message>
++    <message>
++        <source>Select</source>
++        <translation type="vanished">تاللاش</translation>
++    </message>
++    <message>
++        <source>Wallpaper files(*.jpg *.jpeg *.bmp *.dib *.png *.jfif *.jpe *.gif *.tif *.tiff *.wdp *.svg)</source>
++        <translation type="vanished">تام قەغىزى ھۆججەتلىرى(*.jpg *.jpeg *.bmp *.dib *.png *.jfif *.jpe *.gif *.tif *.tiff *.wdp *.svg)</translation>
++    </message>
++    <message>
++        <source>select custom screensaver dir</source>
++        <translation type="vanished">خاس ئېكران كۆرگۈچ dir نى تاللاش</translation>
++    </message>
++    <message>
++        <source>Position: </source>
++        <translation type="vanished">ئورنى: </translation>
++    </message>
++    <message>
++        <source>FileName: </source>
++        <translation type="vanished">ھۆججەت نامى: </translation>
++    </message>
++    <message>
++        <source>FileType: </source>
++        <translation type="vanished">FileType: </translation>
++    </message>
++    <message>
++        <source>Cancel</source>
++        <translation type="vanished">ئەمەلدىن قالدۇرۇش</translation>
++    </message>
++    <message>
++        <source>Switching time</source>
++        <translation type="vanished">ئالماشتۇرۇش ۋاقتى</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="176"/>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="189"/>
++        <source>1min</source>
++        <translation>بىر مىنۇت</translation>
++    </message>
++    <message>
++        <source>Ordinal</source>
++        <translation type="vanished">ئوردىدا</translation>
++    </message>
++    <message>
++        <source>Random switching</source>
++        <translation type="vanished">خالىغانچە ئالماشتۇرۇش</translation>
++    </message>
++    <message>
++        <source>Display text</source>
++        <translation type="vanished">显示文本</translation>
++    </message>
++    <message>
++        <source>Enter text, up to 30 characters</source>
++        <translation type="vanished">输入文本,最多30个字符</translation>
++    </message>
++    <message>
++        <source>Text position</source>
++        <translation type="vanished">تېكىست ئورنى</translation>
++    </message>
++    <message>
++        <source>Centered</source>
++        <translation type="vanished">مەركەز قىلىنغان</translation>
++    </message>
++    <message>
++        <source>Randow(Bubble text)</source>
++        <translation type="vanished">رانۋېر (كۆپۈكچە تېكىست)</translation>
++    </message>
++    <message>
++        <source>1m</source>
++        <translation type="vanished">1m</translation>
++    </message>
++    <message>
++        <source>5m</source>
++        <translation type="vanished">5m</translation>
++    </message>
++    <message>
++        <source>10m</source>
++        <translation type="vanished">10m</translation>
++    </message>
++    <message>
++        <source>30m</source>
++        <translation type="vanished">30m</translation>
++    </message>
++    <message>
++        <source>45m</source>
++        <translation type="vanished">45m</translation>
++    </message>
++    <message>
++        <source>1h</source>
++        <translation type="vanished">1h</translation>
++    </message>
++    <message>
++        <source>1.5h</source>
++        <translation type="vanished">1.5h</translation>
++    </message>
++    <message>
++        <source>3h</source>
++        <translation type="vanished">3h</translation>
++    </message>
++    <message>
++        <source>Random</source>
++        <translation type="vanished">ئىختىيارىي</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/>
++        <source>Never</source>
++        <translation>مەڭگۈ</translation>
++    </message>
++</context>
++<context>
++    <name>ScreensaverUi</name>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="41"/>
++        <source>Screensaver</source>
++        <translation>ئېكران قوغداش</translation>
++        <extra-contents_path>/Screensaver/Screensaver</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="54"/>
++        <source>Idle time</source>
++        <translation>بىكار ۋاقتى</translation>
++        <extra-contents_path>/Screensaver/Idle time</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="56"/>
++        <source>Screensaver program</source>
++        <translation>ئېكران قوغداش پىروگراممىسى</translation>
++        <extra-contents_path>/Screensaver/Screensaver program</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="88"/>
++        <source>Screensaver source</source>
++        <translation>ئېكران يۈزى مەنبەسى</translation>
++        <extra-contents_path>/Screensaver/Screensaver source</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="93"/>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="457"/>
++        <source>Select</source>
++        <translation>تاللاش</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="114"/>
++        <source>Ordinal</source>
++        <translation>ئەنئەنىۋى</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="115"/>
++        <source>Random</source>
++        <translation>ئىختىيارىي</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="122"/>
++        <source>Random switching</source>
++        <translation>خالىغانچە ئالماشتۇرۇش</translation>
++        <extra-contents_path>/Screensaver/Random switching</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="142"/>
++        <source>Switching time</source>
++        <translation>ئالماشتۇرۇش ۋاقتى</translation>
++        <extra-contents_path>/Screensaver/Switching time</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="161"/>
++        <source>Text(up to 30 characters):</source>
++        <translation>تېكىست(ئەڭ كۆپ بولغاندا 30 ھەرپ):</translation>
++        <extra-contents_path>/Screensaver/Text(up to 30 characters):</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="184"/>
++        <source>Text position</source>
++        <translation>تېكىست ئورنى</translation>
++        <extra-contents_path>/Screensaver/Text position</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="192"/>
++        <source>Centered</source>
++        <translation>مەركەز قىلىنغان</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="193"/>
++        <source>Randow(Bubble text)</source>
++        <translation>ئىختىيارى(كۆپۈكچە تېكىست)</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="215"/>
++        <source>Show rest time</source>
++        <translation>ئارام ئېلىش ۋاقتىنى كۆرسىتىش</translation>
++        <extra-contents_path>/Screensaver/Show rest time</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="226"/>
++        <source>Lock screen when screensaver boot</source>
++        <translation>ئېكراننى كۆزنەك تاقاشتا ئېكراننى قۇلۇپلاش</translation>
++        <extra-contents_path>/Screensaver/Lock screen when screensaver boot</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="415"/>
++        <source>Wallpaper files(*.jpg *.jpeg *.bmp *.dib *.png *.jfif *.jpe *.gif *.tif *.tiff *.wdp *.svg)</source>
++        <translation>تام قەغىزى ھۆججەتلىرى(*.jpg *.jpeg *.bmp *.dib *.png *.jfif *.jpe *.gif *.tif *.tiff *.wdp *.svg)</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="456"/>
++        <source>select custom screensaver dir</source>
++        <translation>خاس ئېكران كۆرگۈچنى تاللاش</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="458"/>
++        <source>Position: </source>
++        <translation>ئورنى: </translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="459"/>
++        <source>FileName: </source>
++        <translation>ھۆججەت نامى: </translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="460"/>
++        <source>FileType: </source>
++        <translation>:ھۆججەت تۈرى </translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="461"/>
++        <source>Cancel</source>
++        <translation>ئەمەلدىن قالدۇرۇش</translation>
++    </message>
++</context>
++</TS>
+diff --git a/ukccplugins_i18n_ts/zh_CN.ts b/ukccplugins_i18n_ts/zh_CN.ts
+new file mode 100644
+index 0000000..88926f7
+--- /dev/null
++++ b/ukccplugins_i18n_ts/zh_CN.ts
+@@ -0,0 +1,623 @@
++<?xml version="1.0" encoding="utf-8"?>
++<!DOCTYPE TS>
++<TS version="2.1" language="zh_CN">
++<context>
++    <name>Screenlock</name>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="39"/>
++        <source>Screenlock</source>
++        <translation>锁屏</translation>
++    </message>
++    <message>
++        <source>Screenlock Interface</source>
++        <translation type="vanished">锁屏界面</translation>
++        <extra-contents_path>/Screenlock/Screenlock Interface</extra-contents_path>
++    </message>
++    <message>
++        <source>Show message on lock screen</source>
++        <translation type="vanished">锁屏时显示消息</translation>
++    </message>
++    <message>
++        <source>Related Settings</source>
++        <translation type="vanished">相关设置</translation>
++    </message>
++    <message>
++        <source>Screenlock Set</source>
++        <translation type="vanished">锁屏设置</translation>
++    </message>
++    <message>
++        <source>Lock screen when screensaver boot</source>
++        <translation type="vanished">激活屏保时锁定屏幕</translation>
++    </message>
++    <message>
++        <source>Lock screen delay</source>
++        <translation type="vanished">此时间段后锁屏</translation>
++    </message>
++    <message>
++        <source>Min</source>
++        <translation type="vanished">分钟</translation>
++    </message>
++    <message>
++        <source>Select screenlock background</source>
++        <translation type="vanished">选择锁屏背景</translation>
++    </message>
++    <message>
++        <source>Browser online wp</source>
++        <translation type="vanished">浏览线上壁纸</translation>
++    </message>
++    <message>
++        <source>Browser local wp</source>
++        <translation type="vanished">浏览本地壁纸</translation>
++    </message>
++    <message>
++        <source>Show picture of screenlock on screenlogin</source>
++        <translation type="vanished">显示锁屏壁纸在登录界面</translation>
++        <extra-contents_path>/Screenlock/Show picture of screenlock on screenlogin</extra-contents_path>
++    </message>
++    <message>
++        <source>Enabel screenlock</source>
++        <translation type="vanished">开启锁屏</translation>
++    </message>
++    <message>
++        <source>Open</source>
++        <translation type="obsolete">浏览</translation>
++    </message>
++    <message>
++        <source>screenlock</source>
++        <translation type="vanished">锁屏</translation>
++    </message>
++    <message>
++        <source>picture</source>
++        <translation type="obsolete">图片</translation>
++    </message>
++    <message>
++        <source>Never</source>
++        <translation type="vanished">从不</translation>
++    </message>
++    <message>
++        <source>1m</source>
++        <translation type="vanished">1m</translation>
++    </message>
++    <message>
++        <source>5m</source>
++        <translation type="vanished">5m</translation>
++    </message>
++    <message>
++        <source>10m</source>
++        <translation type="vanished">10m</translation>
++    </message>
++    <message>
++        <source>30m</source>
++        <translation type="vanished">30m</translation>
++    </message>
++    <message>
++        <source>45m</source>
++        <translation type="vanished">45m</translation>
++    </message>
++    <message>
++        <source>1h</source>
++        <translation type="vanished">1h</translation>
++    </message>
++    <message>
++        <source>1.5h</source>
++        <translation type="vanished">1.5h</translation>
++    </message>
++    <message>
++        <source>3h</source>
++        <translation type="vanished">3h</translation>
++    </message>
++    <message>
++        <source>2h</source>
++        <translation type="vanished">2h</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="187"/>
++        <source>Wallpaper files(*.jpg *.jpeg *.bmp *.dib *.png *.jfif *.jpe *.gif *.tif *.tiff *.wdp)</source>
++        <translation>图片文件(*.jpg *.jpeg *.bmp *.dib *.png *.jfif *.jpe *.gif *.tif *.tiff *.wdp)</translation>
++    </message>
++    <message>
++        <source>allFiles(*.*)</source>
++        <translation type="vanished">所有文件(*.*)</translation>
++    </message>
++    <message>
++        <source>1min</source>
++        <translation type="vanished">1分钟</translation>
++    </message>
++    <message>
++        <source>5min</source>
++        <translation type="vanished">5分钟</translation>
++    </message>
++    <message>
++        <source>10min</source>
++        <translation type="vanished">10分钟</translation>
++    </message>
++    <message>
++        <source>30min</source>
++        <translation type="vanished">30分钟</translation>
++    </message>
++    <message>
++        <source>45min</source>
++        <translation type="vanished">45分钟</translation>
++    </message>
++    <message>
++        <source>1hour</source>
++        <translation type="vanished">1小时</translation>
++    </message>
++    <message>
++        <source>2hour</source>
++        <translation type="vanished">2小时</translation>
++    </message>
++    <message>
++        <source>3hour</source>
++        <translation type="vanished">3小时</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="229"/>
++        <source>select custom wallpaper file</source>
++        <translation>选择自定义壁纸文件</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="230"/>
++        <source>Select</source>
++        <translation>选择</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="231"/>
++        <source>Position: </source>
++        <translation>位置: </translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="232"/>
++        <source>FileName: </source>
++        <translation>文件名: </translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="233"/>
++        <source>FileType: </source>
++        <translation>文件类型: </translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="234"/>
++        <source>Cancel</source>
++        <translation>取消</translation>
++    </message>
++    <message>
++        <source>Monitor Off</source>
++        <translation type="vanished">关闭显示器</translation>
++    </message>
++    <message>
++        <source>Screensaver</source>
++        <translation type="vanished">屏幕保护</translation>
++    </message>
++    <message>
++        <source>Set</source>
++        <translation type="vanished">去设置</translation>
++    </message>
++</context>
++<context>
++    <name>ScreenlockUi</name>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="74"/>
++        <source>Show picture of screenlock on screenlogin</source>
++        <translation>显示锁屏壁纸在登录界面</translation>
++        <extra-contents_path>/Screenlock/Show picture of screenlock on screenlogin</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="87"/>
++        <source>Leave lock (System will be locked when the paired phone gone)</source>
++        <translation>动态锁 (系统将在已配对的蓝牙手机离开时自动锁定屏幕)</translation>
++        <extra-contents_path>/Screenlock/Leave lock (System will be locked when the paired phone gone)</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="97"/>
++        <source>Specified device</source>
++        <translation>指定设备</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="114"/>
++        <source>No paired phone. Please turn to &apos;Bluetooth&apos; to pair.</source>
++        <translation>无配对手机,请转到 &quot;蓝牙&quot; 以连接手机。</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="53"/>
++        <source>Screenlock</source>
++        <translation>锁屏</translation>
++        <extra-contents_path>/Screenlock/Screenlock</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="168"/>
++        <source>Choose Picture</source>
++        <translation>选择图片</translation>
++        <extra-contents_path>/Wallpaper/Choose Picture</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="172"/>
++        <source>Local Pictures</source>
++        <translation>本地图片</translation>
++        <extra-contents_path>/Screenlock/Local Pictures</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="176"/>
++        <source>Online Pictures</source>
++        <translation>线上图片</translation>
++        <extra-contents_path>/Screenlock/Online Pictures</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="180"/>
++        <source>Reset To Default</source>
++        <translation>恢复默认</translation>
++        <extra-contents_path>/Screenlock/Reset To Default</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="122"/>
++        <source>Bluetooth</source>
++        <translation>蓝牙设置</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="239"/>
++        <source>No bluetooth adapter detected, can not use Leave Lock.</source>
++        <translation>未检测到蓝牙适配器,无法使用动态锁功能。</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="203"/>
++        <source>Monitor Off</source>
++        <translation>关闭显示器</translation>
++        <extra-contents_path>/Screenlock/Monitor Off</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="205"/>
++        <source>Screensaver</source>
++        <translation>屏幕保护</translation>
++        <extra-contents_path>/Screenlock/Screensaver</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="200"/>
++        <source>Related Settings</source>
++        <translation>相关设置</translation>
++        <extra-contents_path>/Screenlock/Related Settings</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="204"/>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="206"/>
++        <source>Set</source>
++        <translation>去设置</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="266"/>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="647"/>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="681"/>
++        <source>Please select device</source>
++        <translation>请选择指定设备</translation>
++    </message>
++</context>
++<context>
++    <name>Screensaver</name>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="44"/>
++        <source>Screensaver</source>
++        <translation>屏保</translation>
++    </message>
++    <message>
++        <source>Idle time</source>
++        <translation type="vanished">此时间段后开启屏保</translation>
++        <extra-contents_path>/Screensaver/Idle time</extra-contents_path>
++    </message>
++    <message>
++        <source>Lock screen when activating screensaver</source>
++        <translation type="vanished">激活屏保时锁住屏幕</translation>
++    </message>
++    <message>
++        <source>Enable screensaver</source>
++        <translation type="vanished">开启屏保</translation>
++    </message>
++    <message>
++        <source>Screensaver program</source>
++        <translation type="vanished">屏幕保护程序</translation>
++        <extra-contents_path>/Screensaver/Screensaver program</extra-contents_path>
++    </message>
++    <message>
++        <source>idle time</source>
++        <translation type="vanished">等待时间</translation>
++    </message>
++    <message>
++        <source>Min</source>
++        <translation type="vanished">分钟</translation>
++    </message>
++    <message>
++        <source>Lock screen when screensaver boot</source>
++        <translation type="vanished">激活屏保时锁定屏幕</translation>
++    </message>
++    <message>
++        <source>screensaver</source>
++        <translation type="vanished">屏保</translation>
++    </message>
++    <message>
++        <source>Default_ukui</source>
++        <translation type="vanished">默认屏保</translation>
++    </message>
++    <message>
++        <source>View</source>
++        <translation type="vanished">预览</translation>
++    </message>
++    <message>
++        <source>Text(up to 30 characters):</source>
++        <translation type="vanished">屏保文本(最多30个字):</translation>
++    </message>
++    <message>
++        <source>Show rest time</source>
++        <translation type="vanished">显示休息时间</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="182"/>
++        <source>UKUI</source>
++        <translation>UKUI</translation>
++    </message>
++    <message>
++        <source>Blank_Only</source>
++        <translation type="vanished">黑屏</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="182"/>
++        <source>Customize</source>
++        <translation>自定义</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="189"/>
++        <source>5min</source>
++        <translation>5 分钟</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="189"/>
++        <source>10min</source>
++        <translation>10 分钟</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/>
++        <source>15min</source>
++        <translation>15 分钟</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="189"/>
++        <source>30min</source>
++        <translation>30 分钟</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/>
++        <source>1hour</source>
++        <translation>1 小时</translation>
++    </message>
++    <message>
++        <source>Screensaver source</source>
++        <translation type="vanished">屏保来源</translation>
++    </message>
++    <message>
++        <source>Select</source>
++        <translation type="vanished">选择</translation>
++    </message>
++    <message>
++        <source>Wallpaper files(*.jpg *.jpeg *.bmp *.dib *.png *.jfif *.jpe *.gif *.tif *.tiff *.wdp *.svg)</source>
++        <translation type="vanished">壁纸文件(*.jpg *.jpeg *.bmp *.dib *.png *.jfif *.jpe *.gif *.tif *.tiff *.wdp *.svg)</translation>
++    </message>
++    <message>
++        <source>select custom screensaver dir</source>
++        <translation type="vanished">选择自定义屏保路径</translation>
++    </message>
++    <message>
++        <source>Position: </source>
++        <translation type="vanished">位置:</translation>
++    </message>
++    <message>
++        <source>FileName: </source>
++        <translation type="vanished">文件名:</translation>
++    </message>
++    <message>
++        <source>FileType: </source>
++        <translation type="vanished">文件类型:</translation>
++    </message>
++    <message>
++        <source>Cancel</source>
++        <translation type="vanished">取消</translation>
++    </message>
++    <message>
++        <source>Switching time</source>
++        <translation type="vanished">切换频率</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="176"/>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="189"/>
++        <source>1min</source>
++        <translation>1分钟</translation>
++    </message>
++    <message>
++        <source>Ordinal</source>
++        <translation type="vanished">按顺序</translation>
++    </message>
++    <message>
++        <source>Random switching</source>
++        <translation type="vanished">随机切换</translation>
++    </message>
++    <message>
++        <source>Display text</source>
++        <translation type="vanished">显示文本</translation>
++    </message>
++    <message>
++        <source>Enter text, up to 30 characters</source>
++        <translation type="vanished">输入文本,最多30个字符</translation>
++    </message>
++    <message>
++        <source>Text position</source>
++        <translation type="vanished">文本位置</translation>
++    </message>
++    <message>
++        <source>Centered</source>
++        <translation type="vanished">居中</translation>
++    </message>
++    <message>
++        <source>Randow(Bubble text)</source>
++        <translation type="vanished">随机(气泡文本)</translation>
++    </message>
++    <message>
++        <source>1m</source>
++        <translation type="vanished">1m</translation>
++    </message>
++    <message>
++        <source>5m</source>
++        <translation type="vanished">5m</translation>
++    </message>
++    <message>
++        <source>10m</source>
++        <translation type="vanished">10m</translation>
++    </message>
++    <message>
++        <source>30m</source>
++        <translation type="vanished">30m</translation>
++    </message>
++    <message>
++        <source>45m</source>
++        <translation type="vanished">45m</translation>
++    </message>
++    <message>
++        <source>1h</source>
++        <translation type="vanished">1h</translation>
++    </message>
++    <message>
++        <source>1.5h</source>
++        <translation type="vanished">1.5h</translation>
++    </message>
++    <message>
++        <source>3h</source>
++        <translation type="vanished">3h</translation>
++    </message>
++    <message>
++        <source>Random</source>
++        <translation type="vanished">随机</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/>
++        <source>Never</source>
++        <translation>从不</translation>
++    </message>
++</context>
++<context>
++    <name>ScreensaverUi</name>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="41"/>
++        <source>Screensaver</source>
++        <translation>屏保</translation>
++        <extra-contents_path>/Screensaver/Screensaver</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="54"/>
++        <source>Idle time</source>
++        <translation>此时间段后开启屏保</translation>
++        <extra-contents_path>/Screensaver/Idle time</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="56"/>
++        <source>Screensaver program</source>
++        <translation>屏幕保护程序</translation>
++        <extra-contents_path>/Screensaver/Screensaver program</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="88"/>
++        <source>Screensaver source</source>
++        <translation>屏保来源</translation>
++        <extra-contents_path>/Screensaver/Screensaver source</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="93"/>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="457"/>
++        <source>Select</source>
++        <translation>选择</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="114"/>
++        <source>Ordinal</source>
++        <translation>按顺序</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="115"/>
++        <source>Random</source>
++        <translation>随机</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="122"/>
++        <source>Random switching</source>
++        <translation>随机切换</translation>
++        <extra-contents_path>/Screensaver/Random switching</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="142"/>
++        <source>Switching time</source>
++        <translation>切换频率</translation>
++        <extra-contents_path>/Screensaver/Switching time</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="161"/>
++        <source>Text(up to 30 characters):</source>
++        <translation>屏保文本(最多 30 个字):</translation>
++        <extra-contents_path>/Screensaver/Text(up to 30 characters):</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="184"/>
++        <source>Text position</source>
++        <translation>文本位置</translation>
++        <extra-contents_path>/Screensaver/Text position</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="192"/>
++        <source>Centered</source>
++        <translation>居中</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="193"/>
++        <source>Randow(Bubble text)</source>
++        <translation>随机(气泡文本)</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="215"/>
++        <source>Show rest time</source>
++        <translation>显示休息时间</translation>
++        <extra-contents_path>/Screensaver/Show rest time</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="226"/>
++        <source>Lock screen when screensaver boot</source>
++        <translation>激活屏保时锁定屏幕</translation>
++        <extra-contents_path>/Screensaver/Lock screen when screensaver boot</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="415"/>
++        <source>Wallpaper files(*.jpg *.jpeg *.bmp *.dib *.png *.jfif *.jpe *.gif *.tif *.tiff *.wdp *.svg)</source>
++        <translation>壁纸文件(*.jpg *.jpeg *.bmp *.dib *.png *.jfif *.jpe *.gif *.tif *.tiff *.wdp *.svg)</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="456"/>
++        <source>select custom screensaver dir</source>
++        <translation>选择自定义屏保路径</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="458"/>
++        <source>Position: </source>
++        <translation>位置: </translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="459"/>
++        <source>FileName: </source>
++        <translation>文件名: </translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="460"/>
++        <source>FileType: </source>
++        <translation>文件类型: </translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="461"/>
++        <source>Cancel</source>
++        <translation>取消</translation>
++    </message>
++</context>
++</TS>
+diff --git a/ukccplugins_i18n_ts/zh_HK.ts b/ukccplugins_i18n_ts/zh_HK.ts
+new file mode 100644
+index 0000000..9c6dd3a
+--- /dev/null
++++ b/ukccplugins_i18n_ts/zh_HK.ts
+@@ -0,0 +1,647 @@
++<?xml version="1.0" encoding="utf-8"?>
++<!DOCTYPE TS>
++<TS version="2.1" language="zh_HK">
++<context>
++    <name>Screenlock</name>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="39"/>
++        <source>Screenlock</source>
++        <translation>鎖屏</translation>
++    </message>
++    <message>
++        <source>Screenlock Interface</source>
++        <translation type="vanished">锁屏界面</translation>
++    </message>
++    <message>
++        <source>Show message on lock screen</source>
++        <translation type="vanished">鎖屏時顯示消息</translation>
++    </message>
++    <message>
++        <source>Local Pictures</source>
++        <translation type="vanished">本地圖片</translation>
++        <extra-contents_path>/Screenlock/Local Pictures</extra-contents_path>
++    </message>
++    <message>
++        <source>Online Pictures</source>
++        <translation type="vanished">線上圖片</translation>
++        <extra-contents_path>/Screenlock/Online Pictures</extra-contents_path>
++    </message>
++    <message>
++        <source>Reset To Default</source>
++        <translation type="vanished">恢復預設</translation>
++        <extra-contents_path>/Screenlock/Reset To Default</extra-contents_path>
++    </message>
++    <message>
++        <source>Related Settings</source>
++        <translation type="vanished">相關設置</translation>
++        <extra-contents_path>/Screenlock/Related Settings</extra-contents_path>
++    </message>
++    <message>
++        <source>Screenlock Set</source>
++        <translation type="vanished">锁屏设置</translation>
++    </message>
++    <message>
++        <source>Lock screen when screensaver boot</source>
++        <translation type="vanished">激活屏保时锁定屏幕</translation>
++    </message>
++    <message>
++        <source>Lock screen delay</source>
++        <translation type="vanished">此時間段后鎖屏</translation>
++    </message>
++    <message>
++        <source>Min</source>
++        <translation type="vanished">分钟</translation>
++    </message>
++    <message>
++        <source>Select screenlock background</source>
++        <translation type="vanished">选择锁屏背景</translation>
++    </message>
++    <message>
++        <source>Browser online wp</source>
++        <translation type="vanished">浏览线上壁纸</translation>
++    </message>
++    <message>
++        <source>Browser local wp</source>
++        <translation type="vanished">浏览本地壁纸</translation>
++    </message>
++    <message>
++        <source>Show picture of screenlock on screenlogin</source>
++        <translation type="vanished">顯示鎖屏壁紙在登錄介面</translation>
++        <extra-contents_path>/Screenlock/Show picture of screenlock on screenlogin</extra-contents_path>
++    </message>
++    <message>
++        <source>Enabel screenlock</source>
++        <translation type="vanished">开启锁屏</translation>
++    </message>
++    <message>
++        <source>Open</source>
++        <translation type="obsolete">浏览</translation>
++    </message>
++    <message>
++        <source>screenlock</source>
++        <translation type="vanished">锁屏</translation>
++    </message>
++    <message>
++        <source>picture</source>
++        <translation type="obsolete">图片</translation>
++    </message>
++    <message>
++        <source>Never</source>
++        <translation type="vanished">從不</translation>
++    </message>
++    <message>
++        <source>1m</source>
++        <translation type="vanished">1m</translation>
++    </message>
++    <message>
++        <source>5m</source>
++        <translation type="vanished">5m</translation>
++    </message>
++    <message>
++        <source>10m</source>
++        <translation type="vanished">10m</translation>
++    </message>
++    <message>
++        <source>30m</source>
++        <translation type="vanished">30m</translation>
++    </message>
++    <message>
++        <source>45m</source>
++        <translation type="vanished">45m</translation>
++    </message>
++    <message>
++        <source>1h</source>
++        <translation type="vanished">1h</translation>
++    </message>
++    <message>
++        <source>1.5h</source>
++        <translation type="vanished">1.5h</translation>
++    </message>
++    <message>
++        <source>3h</source>
++        <translation type="vanished">3h</translation>
++    </message>
++    <message>
++        <source>2h</source>
++        <translation type="vanished">2h</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="187"/>
++        <source>Wallpaper files(*.jpg *.jpeg *.bmp *.dib *.png *.jfif *.jpe *.gif *.tif *.tiff *.wdp)</source>
++        <translation>圖片檔(*.jpg *.jpeg *.bmp *.dib *.png *.jfif *.jpe *.gif *.tif *.tiff *.wdp)</translation>
++    </message>
++    <message>
++        <source>allFiles(*.*)</source>
++        <translation type="vanished">所有文件(*.*)</translation>
++    </message>
++    <message>
++        <source>1min</source>
++        <translation type="vanished">1 分鐘</translation>
++    </message>
++    <message>
++        <source>5min</source>
++        <translation type="vanished">5 分鐘</translation>
++    </message>
++    <message>
++        <source>10min</source>
++        <translation type="vanished">10 分鐘</translation>
++    </message>
++    <message>
++        <source>30min</source>
++        <translation type="vanished">30 分鐘</translation>
++    </message>
++    <message>
++        <source>45min</source>
++        <translation type="vanished">45 分鐘</translation>
++    </message>
++    <message>
++        <source>1hour</source>
++        <translation type="vanished">1 小時</translation>
++    </message>
++    <message>
++        <source>2hour</source>
++        <translation type="vanished">2 小時</translation>
++    </message>
++    <message>
++        <source>3hour</source>
++        <translation type="vanished">3 小時</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="229"/>
++        <source>select custom wallpaper file</source>
++        <translation>選擇自訂壁紙檔</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="230"/>
++        <source>Select</source>
++        <translation>選擇</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="231"/>
++        <source>Position: </source>
++        <translation>位置: </translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="232"/>
++        <source>FileName: </source>
++        <translation>檔案名稱: </translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="233"/>
++        <source>FileType: </source>
++        <translation>檔案類型: </translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="234"/>
++        <source>Cancel</source>
++        <translation>取消</translation>
++    </message>
++    <message>
++        <source>Monitor Off</source>
++        <translation type="vanished">關閉顯示器</translation>
++        <extra-contents_path>/Screenlock/Monitor Off</extra-contents_path>
++    </message>
++    <message>
++        <source>Screensaver</source>
++        <translation type="vanished">屏幕保護</translation>
++        <extra-contents_path>/Screenlock/Screensaver</extra-contents_path>
++    </message>
++    <message>
++        <source>Set</source>
++        <translation type="vanished">去設置</translation>
++    </message>
++</context>
++<context>
++    <name>ScreenlockUi</name>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="74"/>
++        <source>Show picture of screenlock on screenlogin</source>
++        <translation>顯示鎖屏壁紙在登錄介面</translation>
++        <extra-contents_path>/Screenlock/Show picture of screenlock on screenlogin</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="87"/>
++        <source>Leave lock (System will be locked when the paired phone gone)</source>
++        <translation>動態鎖(系統將在已配對的藍牙手機離開時自動鎖定屏幕)</translation>
++        <extra-contents_path>/Screenlock/Leave lock (System will be locked when the paired phone gone)</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="97"/>
++        <source>Specified device</source>
++        <translation></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="114"/>
++        <source>No paired phone. Please turn to &apos;Bluetooth&apos; to pair.</source>
++        <translation>無配對手機,請轉到“藍牙”以鏈接手機</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="53"/>
++        <source>Screenlock</source>
++        <translation>鎖屏</translation>
++        <extra-contents_path>/Screenlock/Screenlock</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="168"/>
++        <source>Choose Picture</source>
++        <translation>選擇圖片</translation>
++        <extra-contents_path>/Wallpaper/Choose Picture</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="172"/>
++        <source>Local Pictures</source>
++        <translation>本地圖片</translation>
++        <extra-contents_path>/Screenlock/Local Pictures</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="176"/>
++        <source>Online Pictures</source>
++        <translation>線上圖片</translation>
++        <extra-contents_path>/Screenlock/Online Pictures</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="180"/>
++        <source>Reset To Default</source>
++        <translation>恢復預設</translation>
++        <extra-contents_path>/Screenlock/Reset To Default</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="122"/>
++        <source>Bluetooth</source>
++        <translation>蓝牙設置</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="239"/>
++        <source>No bluetooth adapter detected, can not use Leave Lock.</source>
++        <translation>無藍牙適配器,不能使用動態鎖</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="203"/>
++        <source>Monitor Off</source>
++        <translation>關閉顯示器</translation>
++        <extra-contents_path>/Screenlock/Monitor Off</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="205"/>
++        <source>Screensaver</source>
++        <translation>屏保</translation>
++        <extra-contents_path>/Screenlock/Screensaver</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="200"/>
++        <source>Related Settings</source>
++        <translation>相關設置</translation>
++        <extra-contents_path>/Screenlock/Related Settings</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="204"/>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="206"/>
++        <source>Set</source>
++        <translation>設置</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="266"/>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="647"/>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="681"/>
++        <source>Please select device</source>
++        <translation>請選擇設備</translation>
++    </message>
++</context>
++<context>
++    <name>Screensaver</name>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="44"/>
++        <source>Screensaver</source>
++        <translation>屏保</translation>
++    </message>
++    <message>
++        <source>Idle time</source>
++        <translation type="vanished">此時間段后開啟屏保</translation>
++        <extra-contents_path>/Screensaver/Idle time</extra-contents_path>
++    </message>
++    <message>
++        <source>Lock screen when activating screensaver</source>
++        <translation type="vanished">啟動屏保時鎖住螢幕</translation>
++    </message>
++    <message>
++        <source>Enable screensaver</source>
++        <translation type="vanished">开启屏保</translation>
++    </message>
++    <message>
++        <source>Screensaver program</source>
++        <translation type="vanished">屏幕保護程式</translation>
++        <extra-contents_path>/Screensaver/Screensaver program</extra-contents_path>
++    </message>
++    <message>
++        <source>idle time</source>
++        <translation type="vanished">等待时间</translation>
++    </message>
++    <message>
++        <source>Min</source>
++        <translation type="vanished">分钟</translation>
++    </message>
++    <message>
++        <source>Lock screen when screensaver boot</source>
++        <translation type="vanished">啟動屏保時鎖定螢幕</translation>
++        <extra-contents_path>/Screensaver/Lock screen when screensaver boot</extra-contents_path>
++    </message>
++    <message>
++        <source>screensaver</source>
++        <translation type="vanished">屏保</translation>
++    </message>
++    <message>
++        <source>Default_ukui</source>
++        <translation type="vanished">默认屏保</translation>
++    </message>
++    <message>
++        <source>View</source>
++        <translation type="vanished">預覽</translation>
++    </message>
++    <message>
++        <source>Text(up to 30 characters):</source>
++        <translation type="vanished">屏保文本(最多 30 個字):</translation>
++        <extra-contents_path>/Screensaver/Text(up to 30 characters):</extra-contents_path>
++    </message>
++    <message>
++        <source>Show rest time</source>
++        <translation type="vanished">顯示休息時間</translation>
++        <extra-contents_path>/Screensaver/Show rest time</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="182"/>
++        <source>UKUI</source>
++        <translation>UKUI</translation>
++    </message>
++    <message>
++        <source>Blank_Only</source>
++        <translation type="vanished">黑屏</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="182"/>
++        <source>Customize</source>
++        <translation>自訂</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="189"/>
++        <source>5min</source>
++        <translation>5 分鐘</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="189"/>
++        <source>10min</source>
++        <translation>10 分鐘</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/>
++        <source>15min</source>
++        <translation>15 分鐘</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="189"/>
++        <source>30min</source>
++        <translation>30 分鐘</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/>
++        <source>1hour</source>
++        <translation>1 小時</translation>
++    </message>
++    <message>
++        <source>Screensaver source</source>
++        <translation type="vanished">屏保來源</translation>
++        <extra-contents_path>/Screensaver/Screensaver source</extra-contents_path>
++    </message>
++    <message>
++        <source>Select</source>
++        <translation type="vanished">選擇</translation>
++    </message>
++    <message>
++        <source>Wallpaper files(*.jpg *.jpeg *.bmp *.dib *.png *.jfif *.jpe *.gif *.tif *.tiff *.wdp *.svg)</source>
++        <translation type="vanished">壁紙檔(*.jpg *.jpeg *.bmp *.dib *.png *.jfif *.jpe *.gif *.tif *.tiff *.wdp *.svg)</translation>
++    </message>
++    <message>
++        <source>select custom screensaver dir</source>
++        <translation type="vanished">選擇自訂屏保路徑</translation>
++    </message>
++    <message>
++        <source>Position: </source>
++        <translation type="vanished">位置: </translation>
++    </message>
++    <message>
++        <source>FileName: </source>
++        <translation type="vanished">檔案名稱: </translation>
++    </message>
++    <message>
++        <source>FileType: </source>
++        <translation type="vanished">檔案類型: </translation>
++    </message>
++    <message>
++        <source>Cancel</source>
++        <translation type="vanished">取消</translation>
++    </message>
++    <message>
++        <source>Switching time</source>
++        <translation type="vanished">切換頻率</translation>
++        <extra-contents_path>/Screensaver/Switching time</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="176"/>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="189"/>
++        <source>1min</source>
++        <translation>1 分鐘</translation>
++    </message>
++    <message>
++        <source>Ordinal</source>
++        <translation type="vanished">按順序</translation>
++    </message>
++    <message>
++        <source>Random switching</source>
++        <translation type="vanished">隨機切換</translation>
++        <extra-contents_path>/Screensaver/Random switching</extra-contents_path>
++    </message>
++    <message>
++        <source>Display text</source>
++        <translation type="vanished">显示文本</translation>
++    </message>
++    <message>
++        <source>Enter text, up to 30 characters</source>
++        <translation type="vanished">输入文本,最多30个字符</translation>
++    </message>
++    <message>
++        <source>Text position</source>
++        <translation type="vanished">文本位置</translation>
++        <extra-contents_path>/Screensaver/Text position</extra-contents_path>
++    </message>
++    <message>
++        <source>Centered</source>
++        <translation type="vanished">居中</translation>
++    </message>
++    <message>
++        <source>Randow(Bubble text)</source>
++        <translation type="vanished">隨機(氣泡文字)</translation>
++    </message>
++    <message>
++        <source>1m</source>
++        <translation type="vanished">1m</translation>
++    </message>
++    <message>
++        <source>5m</source>
++        <translation type="vanished">5m</translation>
++    </message>
++    <message>
++        <source>10m</source>
++        <translation type="vanished">10m</translation>
++    </message>
++    <message>
++        <source>30m</source>
++        <translation type="vanished">30m</translation>
++    </message>
++    <message>
++        <source>45m</source>
++        <translation type="vanished">45m</translation>
++    </message>
++    <message>
++        <source>1h</source>
++        <translation type="vanished">1h</translation>
++    </message>
++    <message>
++        <source>1.5h</source>
++        <translation type="vanished">1.5h</translation>
++    </message>
++    <message>
++        <source>3h</source>
++        <translation type="vanished">3h</translation>
++    </message>
++    <message>
++        <source>Random</source>
++        <translation type="vanished">隨機</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/>
++        <source>Never</source>
++        <translation>從不</translation>
++    </message>
++</context>
++<context>
++    <name>ScreensaverUi</name>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="41"/>
++        <source>Screensaver</source>
++        <translation>屏保</translation>
++        <extra-contents_path>/Screensaver/Screensaver</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="54"/>
++        <source>Idle time</source>
++        <translation>此時間段后開啟屏保</translation>
++        <extra-contents_path>/Screensaver/Idle time</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="56"/>
++        <source>Screensaver program</source>
++        <translation>屏幕保護程式</translation>
++        <extra-contents_path>/Screensaver/Screensaver program</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="88"/>
++        <source>Screensaver source</source>
++        <translation>屏保來源</translation>
++        <extra-contents_path>/Screensaver/Screensaver source</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="93"/>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="457"/>
++        <source>Select</source>
++        <translation>選擇</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="114"/>
++        <source>Ordinal</source>
++        <translation>按順序</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="115"/>
++        <source>Random</source>
++        <translation>隨機</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="122"/>
++        <source>Random switching</source>
++        <translation>隨機切換</translation>
++        <extra-contents_path>/Screensaver/Random switching</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="142"/>
++        <source>Switching time</source>
++        <translation>切換頻率</translation>
++        <extra-contents_path>/Screensaver/Switching time</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="161"/>
++        <source>Text(up to 30 characters):</source>
++        <translation>屏保文本(最多 30 個字):</translation>
++        <extra-contents_path>/Screensaver/Text(up to 30 characters):</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="184"/>
++        <source>Text position</source>
++        <translation>文本位置</translation>
++        <extra-contents_path>/Screensaver/Text position</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="192"/>
++        <source>Centered</source>
++        <translation>居中</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="193"/>
++        <source>Randow(Bubble text)</source>
++        <translation>隨機(氣泡文字)</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="215"/>
++        <source>Show rest time</source>
++        <translation>顯示休息時間</translation>
++        <extra-contents_path>/Screensaver/Show rest time</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="226"/>
++        <source>Lock screen when screensaver boot</source>
++        <translation>開啓屏保時鎖定屏幕</translation>
++        <extra-contents_path>/Screensaver/Lock screen when screensaver boot</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="415"/>
++        <source>Wallpaper files(*.jpg *.jpeg *.bmp *.dib *.png *.jfif *.jpe *.gif *.tif *.tiff *.wdp *.svg)</source>
++        <translation>壁紙檔(*.jpg *.jpeg *.bmp *.dib *.png *.jfif *.jpe *.gif *.tif *.tiff *.wdp *.svg)</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="456"/>
++        <source>select custom screensaver dir</source>
++        <translation>選擇自訂屏保路徑</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="458"/>
++        <source>Position: </source>
++        <translation>位置:</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="459"/>
++        <source>FileName: </source>
++        <translation>文件名:</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="460"/>
++        <source>FileType: </source>
++        <translation>文件類型:</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="461"/>
++        <source>Cancel</source>
++        <translation>取消</translation>
++    </message>
++</context>
++</TS>
+diff --git a/ukccplugins_i18n_ts/zh_Hant.ts b/ukccplugins_i18n_ts/zh_Hant.ts
+new file mode 100644
+index 0000000..bc71d16
+--- /dev/null
++++ b/ukccplugins_i18n_ts/zh_Hant.ts
+@@ -0,0 +1,642 @@
++<?xml version="1.0" encoding="utf-8"?>
++<!DOCTYPE TS>
++<TS version="2.1" language="zh">
++<context>
++    <name>Screenlock</name>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="39"/>
++        <source>Screenlock</source>
++        <translation>鎖屏</translation>
++    </message>
++    <message>
++        <source>Screenlock Interface</source>
++        <translation type="vanished">锁屏界面</translation>
++    </message>
++    <message>
++        <source>Show message on lock screen</source>
++        <translation type="vanished">鎖屏時顯示消息</translation>
++    </message>
++    <message>
++        <source>Browse</source>
++        <translation type="vanished">浏览</translation>
++        <extra-contents_path>/Screenlock/Browse</extra-contents_path>
++    </message>
++    <message>
++        <source>Online Picture</source>
++        <translation type="vanished">线上图片</translation>
++        <extra-contents_path>/Screenlock/Online Picture</extra-contents_path>
++    </message>
++    <message>
++        <source>Local Pictures</source>
++        <translation type="vanished">本地圖片</translation>
++        <extra-contents_path>/Screenlock/Local Pictures</extra-contents_path>
++    </message>
++    <message>
++        <source>Online Pictures</source>
++        <translation type="vanished">線上圖片</translation>
++        <extra-contents_path>/Screenlock/Online Pictures</extra-contents_path>
++    </message>
++    <message>
++        <source>Reset To Default</source>
++        <translation type="vanished">恢復預設</translation>
++        <extra-contents_path>/Screenlock/Reset To Default</extra-contents_path>
++    </message>
++    <message>
++        <source>Related Settings</source>
++        <translation type="vanished">相關設置</translation>
++    </message>
++    <message>
++        <source>Screenlock Set</source>
++        <translation type="vanished">锁屏设置</translation>
++    </message>
++    <message>
++        <source>Lock screen when screensaver boot</source>
++        <translation type="vanished">激活屏保时锁定屏幕</translation>
++    </message>
++    <message>
++        <source>Lock screen delay</source>
++        <translation type="vanished">此時間段后鎖屏</translation>
++    </message>
++    <message>
++        <source>Min</source>
++        <translation type="vanished">分钟</translation>
++    </message>
++    <message>
++        <source>Select screenlock background</source>
++        <translation type="vanished">选择锁屏背景</translation>
++    </message>
++    <message>
++        <source>Browser online wp</source>
++        <translation type="vanished">浏览线上壁纸</translation>
++    </message>
++    <message>
++        <source>Browser local wp</source>
++        <translation type="vanished">浏览本地壁纸</translation>
++    </message>
++    <message>
++        <source>Show picture of screenlock on screenlogin</source>
++        <translation type="vanished">顯示鎖屏壁紙在登錄介面</translation>
++        <extra-contents_path>/Screenlock/Show picture of screenlock on screenlogin</extra-contents_path>
++    </message>
++    <message>
++        <source>Enabel screenlock</source>
++        <translation type="vanished">开启锁屏</translation>
++    </message>
++    <message>
++        <source>Open</source>
++        <translation type="obsolete">浏览</translation>
++    </message>
++    <message>
++        <source>screenlock</source>
++        <translation type="vanished">锁屏</translation>
++    </message>
++    <message>
++        <source>picture</source>
++        <translation type="obsolete">图片</translation>
++    </message>
++    <message>
++        <source>Never</source>
++        <translation type="vanished">從不</translation>
++    </message>
++    <message>
++        <source>1m</source>
++        <translation type="vanished">1m</translation>
++    </message>
++    <message>
++        <source>5m</source>
++        <translation type="vanished">5m</translation>
++    </message>
++    <message>
++        <source>10m</source>
++        <translation type="vanished">10m</translation>
++    </message>
++    <message>
++        <source>30m</source>
++        <translation type="vanished">30m</translation>
++    </message>
++    <message>
++        <source>45m</source>
++        <translation type="vanished">45m</translation>
++    </message>
++    <message>
++        <source>1h</source>
++        <translation type="vanished">1h</translation>
++    </message>
++    <message>
++        <source>1.5h</source>
++        <translation type="vanished">1.5h</translation>
++    </message>
++    <message>
++        <source>3h</source>
++        <translation type="vanished">3h</translation>
++    </message>
++    <message>
++        <source>2h</source>
++        <translation type="vanished">2h</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="187"/>
++        <source>Wallpaper files(*.jpg *.jpeg *.bmp *.dib *.png *.jfif *.jpe *.gif *.tif *.tiff *.wdp)</source>
++        <translation>圖片檔(*.jpg *.jpeg *.bmp *.dib *.png *.jfif *.jpe *.gif *.tif *.tiff *.wdp)</translation>
++    </message>
++    <message>
++        <source>allFiles(*.*)</source>
++        <translation type="vanished">所有文件(*.*)</translation>
++    </message>
++    <message>
++        <source>1min</source>
++        <translation type="vanished">1 分鐘</translation>
++    </message>
++    <message>
++        <source>5min</source>
++        <translation type="vanished">5 分鐘</translation>
++    </message>
++    <message>
++        <source>10min</source>
++        <translation type="vanished">10 分鐘</translation>
++    </message>
++    <message>
++        <source>30min</source>
++        <translation type="vanished">30 分鐘</translation>
++    </message>
++    <message>
++        <source>45min</source>
++        <translation type="vanished">45 分鐘</translation>
++    </message>
++    <message>
++        <source>1hour</source>
++        <translation type="vanished">1 小時</translation>
++    </message>
++    <message>
++        <source>2hour</source>
++        <translation type="vanished">2 小時</translation>
++    </message>
++    <message>
++        <source>3hour</source>
++        <translation type="vanished">3 小時</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="229"/>
++        <source>select custom wallpaper file</source>
++        <translation>選擇自訂壁紙檔</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="230"/>
++        <source>Select</source>
++        <translation>選擇</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="231"/>
++        <source>Position: </source>
++        <translation>位置: </translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="232"/>
++        <source>FileName: </source>
++        <translation>檔案名稱: </translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="233"/>
++        <source>FileType: </source>
++        <translation>檔案類型: </translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlock.cpp" line="234"/>
++        <source>Cancel</source>
++        <translation>取消</translation>
++    </message>
++    <message>
++        <source>Monitor Off</source>
++        <translation type="vanished">關閉顯示器</translation>
++    </message>
++    <message>
++        <source>Screensaver</source>
++        <translation type="vanished">屏幕保護</translation>
++    </message>
++    <message>
++        <source>Set</source>
++        <translation type="vanished">去設置</translation>
++    </message>
++</context>
++<context>
++    <name>ScreenlockUi</name>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="74"/>
++        <source>Show picture of screenlock on screenlogin</source>
++        <translation type="unfinished">顯示鎖屏壁紙在登錄介面</translation>
++        <extra-contents_path>/Screenlock/Show picture of screenlock on screenlogin</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="87"/>
++        <source>Leave lock (System will be locked when the paired phone gone)</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="97"/>
++        <source>Specified device</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="114"/>
++        <source>No paired phone. Please turn to &apos;Bluetooth&apos; to pair.</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="53"/>
++        <source>Screenlock</source>
++        <translation type="unfinished">鎖屏</translation>
++        <extra-contents_path>/Screenlock/Screenlock</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="168"/>
++        <source>Choose Picture</source>
++        <translation type="unfinished">選擇圖片</translation>
++        <extra-contents_path>/Wallpaper/Choose Picture</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="172"/>
++        <source>Local Pictures</source>
++        <translation type="unfinished">本地圖片</translation>
++        <extra-contents_path>/Screenlock/Local Pictures</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="176"/>
++        <source>Online Pictures</source>
++        <translation type="unfinished">線上圖片</translation>
++        <extra-contents_path>/Screenlock/Online Pictures</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="180"/>
++        <source>Reset To Default</source>
++        <translation type="unfinished">恢復預設</translation>
++        <extra-contents_path>/Screenlock/Reset To Default</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="122"/>
++        <source>Bluetooth</source>
++        <translation type="unfinished">蓝牙</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="239"/>
++        <source>No bluetooth adapter detected, can not use Leave Lock.</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="203"/>
++        <source>Monitor Off</source>
++        <translation type="unfinished">關閉顯示器</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="205"/>
++        <source>Screensaver</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="200"/>
++        <source>Related Settings</source>
++        <translation type="unfinished">相關設置</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="204"/>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="206"/>
++        <source>Set</source>
++        <translation type="unfinished">去設置</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="266"/>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="647"/>
++        <location filename="../src/ukccplugins/screenlock/screenlockui.cpp" line="681"/>
++        <source>Please select device</source>
++        <translation type="unfinished"></translation>
++    </message>
++</context>
++<context>
++    <name>Screensaver</name>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="44"/>
++        <source>Screensaver</source>
++        <translation>屏保</translation>
++    </message>
++    <message>
++        <source>Idle time</source>
++        <translation type="vanished">此時間段后開啟屏保</translation>
++        <extra-contents_path>/Screensaver/Idle time</extra-contents_path>
++    </message>
++    <message>
++        <source>Lock screen when activating screensaver</source>
++        <translation type="vanished">啟動屏保時鎖住螢幕</translation>
++    </message>
++    <message>
++        <source>Enable screensaver</source>
++        <translation type="vanished">开启屏保</translation>
++    </message>
++    <message>
++        <source>Screensaver program</source>
++        <translation type="vanished">屏幕保護程式</translation>
++        <extra-contents_path>/Screensaver/Screensaver program</extra-contents_path>
++    </message>
++    <message>
++        <source>idle time</source>
++        <translation type="vanished">等待时间</translation>
++    </message>
++    <message>
++        <source>Min</source>
++        <translation type="vanished">分钟</translation>
++    </message>
++    <message>
++        <source>Lock screen when screensaver boot</source>
++        <translation type="vanished">啟動屏保時鎖定螢幕</translation>
++    </message>
++    <message>
++        <source>screensaver</source>
++        <translation type="vanished">屏保</translation>
++    </message>
++    <message>
++        <source>Default_ukui</source>
++        <translation type="vanished">默认屏保</translation>
++    </message>
++    <message>
++        <source>View</source>
++        <translation type="vanished">預覽</translation>
++    </message>
++    <message>
++        <source>Text(up to 30 characters):</source>
++        <translation type="vanished">屏保文本(最多 30 個字):</translation>
++    </message>
++    <message>
++        <source>Show rest time</source>
++        <translation type="vanished">顯示休息時間</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="182"/>
++        <source>UKUI</source>
++        <translation>UKUI</translation>
++    </message>
++    <message>
++        <source>Blank_Only</source>
++        <translation type="vanished">黑屏</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="182"/>
++        <source>Customize</source>
++        <translation>自訂</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="189"/>
++        <source>5min</source>
++        <translation>5 分鐘</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="189"/>
++        <source>10min</source>
++        <translation>10 分鐘</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/>
++        <source>15min</source>
++        <translation>15 分鐘</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="189"/>
++        <source>30min</source>
++        <translation>30 分鐘</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/>
++        <source>1hour</source>
++        <translation>1 小時</translation>
++    </message>
++    <message>
++        <source>Screensaver source</source>
++        <translation type="vanished">屏保來源</translation>
++    </message>
++    <message>
++        <source>Select</source>
++        <translation type="vanished">選擇</translation>
++    </message>
++    <message>
++        <source>Wallpaper files(*.jpg *.jpeg *.bmp *.dib *.png *.jfif *.jpe *.gif *.tif *.tiff *.wdp *.svg)</source>
++        <translation type="vanished">壁紙檔(*.jpg *.jpeg *.bmp *.dib *.png *.jfif *.jpe *.gif *.tif *.tiff *.wdp *.svg)</translation>
++    </message>
++    <message>
++        <source>select custom screensaver dir</source>
++        <translation type="vanished">選擇自定義屏保路徑</translation>
++    </message>
++    <message>
++        <source>Position: </source>
++        <translation type="vanished">位置: </translation>
++    </message>
++    <message>
++        <source>FileName: </source>
++        <translation type="vanished">檔案名稱: </translation>
++    </message>
++    <message>
++        <source>FileType: </source>
++        <translation type="vanished">檔案類型: </translation>
++    </message>
++    <message>
++        <source>Cancel</source>
++        <translation type="vanished">取消</translation>
++    </message>
++    <message>
++        <source>Switching time</source>
++        <translation type="vanished">切換頻率</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="176"/>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="189"/>
++        <source>1min</source>
++        <translation>1 分鐘</translation>
++    </message>
++    <message>
++        <source>Ordinal</source>
++        <translation type="vanished">按順序</translation>
++    </message>
++    <message>
++        <source>Random switching</source>
++        <translation type="vanished">隨機切換</translation>
++    </message>
++    <message>
++        <source>Display text</source>
++        <translation type="vanished">显示文本</translation>
++    </message>
++    <message>
++        <source>Enter text, up to 30 characters</source>
++        <translation type="vanished">输入文本,最多30个字符</translation>
++    </message>
++    <message>
++        <source>Text position</source>
++        <translation type="vanished">文本位置</translation>
++    </message>
++    <message>
++        <source>Centered</source>
++        <translation type="vanished">居中</translation>
++    </message>
++    <message>
++        <source>Randow(Bubble text)</source>
++        <translation type="vanished">隨機(氣泡文字)</translation>
++    </message>
++    <message>
++        <source>1m</source>
++        <translation type="vanished">1m</translation>
++    </message>
++    <message>
++        <source>5m</source>
++        <translation type="vanished">5m</translation>
++    </message>
++    <message>
++        <source>10m</source>
++        <translation type="vanished">10m</translation>
++    </message>
++    <message>
++        <source>30m</source>
++        <translation type="vanished">30m</translation>
++    </message>
++    <message>
++        <source>45m</source>
++        <translation type="vanished">45m</translation>
++    </message>
++    <message>
++        <source>1h</source>
++        <translation type="vanished">1h</translation>
++    </message>
++    <message>
++        <source>1.5h</source>
++        <translation type="vanished">1.5h</translation>
++    </message>
++    <message>
++        <source>3h</source>
++        <translation type="vanished">3h</translation>
++    </message>
++    <message>
++        <source>Random</source>
++        <translation type="vanished">隨機</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaver.cpp" line="170"/>
++        <source>Never</source>
++        <translation>從不</translation>
++    </message>
++</context>
++<context>
++    <name>ScreensaverUi</name>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="41"/>
++        <source>Screensaver</source>
++        <translation type="unfinished"></translation>
++        <extra-contents_path>/Screensaver/Screensaver</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="54"/>
++        <source>Idle time</source>
++        <translation type="unfinished">此時間段后開啟屏保</translation>
++        <extra-contents_path>/Screensaver/Idle time</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="56"/>
++        <source>Screensaver program</source>
++        <translation type="unfinished">屏幕保護程式</translation>
++        <extra-contents_path>/Screensaver/Screensaver program</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="88"/>
++        <source>Screensaver source</source>
++        <translation type="unfinished">屏保來源</translation>
++        <extra-contents_path>/Screensaver/Screensaver source</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="93"/>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="457"/>
++        <source>Select</source>
++        <translation type="unfinished">選擇</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="114"/>
++        <source>Ordinal</source>
++        <translation type="unfinished">按順序</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="115"/>
++        <source>Random</source>
++        <translation type="unfinished">隨機</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="122"/>
++        <source>Random switching</source>
++        <translation type="unfinished">隨機切換</translation>
++        <extra-contents_path>/Screensaver/Random switching</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="142"/>
++        <source>Switching time</source>
++        <translation type="unfinished">切換頻率</translation>
++        <extra-contents_path>/Screensaver/Switching time</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="161"/>
++        <source>Text(up to 30 characters):</source>
++        <translation type="unfinished">屏保文本(最多 30 個字):</translation>
++        <extra-contents_path>/Screensaver/Text(up to 30 characters):</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="184"/>
++        <source>Text position</source>
++        <translation type="unfinished">文本位置</translation>
++        <extra-contents_path>/Screensaver/Text position</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="192"/>
++        <source>Centered</source>
++        <translation type="unfinished">居中</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="193"/>
++        <source>Randow(Bubble text)</source>
++        <translation type="unfinished">隨機(氣泡文字)</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="215"/>
++        <source>Show rest time</source>
++        <translation type="unfinished">顯示休息時間</translation>
++        <extra-contents_path>/Screensaver/Show rest time</extra-contents_path>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="226"/>
++        <source>Lock screen when screensaver boot</source>
++        <translation type="unfinished"></translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="415"/>
++        <source>Wallpaper files(*.jpg *.jpeg *.bmp *.dib *.png *.jfif *.jpe *.gif *.tif *.tiff *.wdp *.svg)</source>
++        <translation type="unfinished">壁紙檔(*.jpg *.jpeg *.bmp *.dib *.png *.jfif *.jpe *.gif *.tif *.tiff *.wdp *.svg)</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="456"/>
++        <source>select custom screensaver dir</source>
++        <translation type="unfinished">選擇自定義屏保路徑</translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="458"/>
++        <source>Position: </source>
++        <translation type="unfinished">位置: </translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="459"/>
++        <source>FileName: </source>
++        <translation type="unfinished">檔案名稱: </translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="460"/>
++        <source>FileType: </source>
++        <translation type="unfinished">檔案類型: </translation>
++    </message>
++    <message>
++        <location filename="../src/ukccplugins/screensaver/screensaverui.cpp" line="461"/>
++        <source>Cancel</source>
++        <translation type="unfinished">取消</translation>
++    </message>
++</context>
++</TS>
diff -Nru ukui-screensaver-4.20.0.0/debian/patches/series ukui-screensaver-4.20.0.0/debian/patches/series
--- ukui-screensaver-4.20.0.0/debian/patches/series	2024-12-17 13:37:23.000000000 +0800
+++ ukui-screensaver-4.20.0.0/debian/patches/series	2025-02-13 20:26:40.000000000 +0800
@@ -1,2 +1,7 @@
 0001-107.patch
 0002-109.patch
+0003-ok.patch
+0004-sysc-codes-from-v11-2503.patch
+0005-sync-codes-from-v11-2503.patch
+0006-112-sync-codes-from-v11-2503.patch
+0007-114-update-changelog.patch
diff -Nru ukui-screensaver-4.20.0.0/debian/ukui-screensaver.postinst ukui-screensaver-4.20.0.0/debian/ukui-screensaver.postinst
--- ukui-screensaver-4.20.0.0/debian/ukui-screensaver.postinst	2024-12-17 13:37:23.000000000 +0800
+++ ukui-screensaver-4.20.0.0/debian/ukui-screensaver.postinst	2025-02-13 20:26:40.000000000 +0800
@@ -5,6 +5,18 @@
 
 glib-compile-schemas /usr/share/glib-2.0/schemas/
 
+path_conf="/usr/share/lightdm/lightdm.conf.d/95-ukui-greeter.conf"
+dpkg-divert --package ukui-screensaver --rename --remove "$path_conf".old
+path_sh="/usr/lib/lightdm/lightdm-session-setup.sh "
+dpkg-divert --package ukui-screensaver --rename --remove "$path_sh".old
+path_desktop="/usr/share/xgreeters/ukui-greeter.desktop"
+dpkg-divert --package ukui-screensaver --rename --remove "$path_desktop".old
+
+path_sl_plugin="/usr/lib/`/usr/bin/dpkg-architecture -qDEB_TARGET_MULTIARCH`/ukui-control-center/libscreenlock.so"
+dpkg-divert --package ukui-screensaver --rename --remove "$path_sl_plugin".old
+path_ss_plugin="/usr/lib/`/usr/bin/dpkg-architecture -qDEB_TARGET_MULTIARCH`/ukui-control-center/libscreensaver.so"
+dpkg-divert --package ukui-screensaver --rename --remove "$path_ss_plugin".old
+
 if [ -x /usr/share/kylin-system-updater/kylin-reboot-required ]; then
     #执行请求重启提示
     /usr/share/kylin-system-updater/kylin-reboot-required
diff -Nru ukui-screensaver-4.20.0.0/debian/ukui-screensaver.preinst ukui-screensaver-4.20.0.0/debian/ukui-screensaver.preinst
--- ukui-screensaver-4.20.0.0/debian/ukui-screensaver.preinst	2024-12-17 13:37:23.000000000 +0800
+++ ukui-screensaver-4.20.0.0/debian/ukui-screensaver.preinst	2025-02-13 20:26:40.000000000 +0800
@@ -16,3 +16,10 @@
 #}
 
 #remove_greeter()
+
+# dpkg rename ukui-control-center's libscreensaver.so and libscreenlock.so
+path_sl_plugin="/usr/lib/`/usr/bin/dpkg-architecture -qDEB_TARGET_MULTIARCH`/ukui-control-center/libscreenlock.so"
+dpkg-divert --package ukui-screensaver  --rename --divert "$path_sl_plugin"".old" --add $path_sl_plugin
+path_ss_plugin="/usr/lib/`/usr/bin/dpkg-architecture -qDEB_TARGET_MULTIARCH`/ukui-control-center/libscreensaver.so"
+dpkg-divert --package ukui-screensaver  --rename --divert "$path_ss_plugin"".old" --add $path_ss_plugin
+