/*
 * Copyright (C) 2022 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 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 "serviceinterface.h"
#include <QDBusConnection>
#include <QSettings>
#include <QDir>
#include <pwd.h>
#include <unistd.h>
#include <sys/types.h>
#include <QFileSystemWatcher>
#include <QDebug>
#include <QProcess>
#include <QDBusPendingReply>
#include <QDBusMetaType>
#include <QDBusConnectionInterface>
#include <QDBusContext>
#include <QDBusMessage>
#include "servicemanager.h"

#define COMM_CONFIG_PATH "/etc/biometric-auth/ukui-biometric.conf"
#define USER_CONFIG_PATH "/home/%1/.biometric_auth/ukui_biometric.conf"

ServiceInterface::ServiceInterface()
{
    bool res = QDBusConnection::systemBus().registerService("org.ukui.UniauthBackend");
    if(!res){
        qInfo()<<"registerService org.ukui.UniauthBackend failed!!";
        exit(0);
    }
    res = QDBusConnection::systemBus().registerObject("/org/ukui/UniauthBackend", "org.ukui.UniauthBackend",
                                                      this, QDBusConnection::ExportAllSlots|QDBusConnection::ExportAllSignals);
    if(!res){
        qInfo()<<"registerObject /org/ukui/UniauthBackend failed!!";
        exit(0);
    }

    registerCustomTypes();
    m_serviceInterface = new QDBusInterface(DBUS_SERVICE, DBUS_PATH,
                                            DBUS_INTERFACE,
                                            QDBusConnection::systemBus());

    m_serviceInterface->setTimeout(2147483647);
    connect(m_serviceInterface, SIGNAL(USBDeviceHotPlug(int, int, int)),
            this, SLOT(onUSBDeviceHotPlug(int,int,int)));
    updateCommDefaultDevice(-1);
    initData();

    ServiceManager *sm = ServiceManager::instance();
    connect(sm, &ServiceManager::serviceStatusChanged,
            this, &ServiceInterface::onBiometricDbusChanged);
}

void ServiceInterface::setDefaultDevice(QString userName, int bioDevType, QString deviceName)
{
    QString configPath = QString(USER_CONFIG_PATH).arg(userName);
    qDebug() << configPath << bioDevType ;
    QSettings settings(configPath, QSettings::IniFormat);
    switch (bioDevType) {
    case BIOTYPE_FACE:
        settings.setValue("FC_DefaultDevice", deviceName);
        break;
    case BIOTYPE_FINGERPRINT:
        settings.setValue("FP_DefaultDevice", deviceName);
        break;
    case BIOTYPE_FINGERVEIN:
        settings.setValue("FV_DefaultDevice", deviceName);
        break;
    case BIOTYPE_IRIS:
        settings.setValue("IR_DefaultDevice", deviceName);
        break;
    case BIOTYPE_VOICEPRINT:
        settings.setValue("VP_DefaultDevice", deviceName);
        break;
    case REMOTE_QRCODE_TYPE:
        settings.setValue("WC_DefaultDevice", deviceName);
        break;
    default:
        break;
    }
    settings.sync();
    qDebug()<<"setDefaultDevice:"<<userName<<","<<bioDevType<<","<<deviceName;
    emit defaultDeviceChanged(userName, bioDevType, deviceName);
}

void ServiceInterface::setDefaultDevice(int bioDevType, QString deviceName)
{
    QDBusConnection conn = connection();
    QDBusMessage msg = message();
    int uid = conn.interface()->serviceUid(msg.service()).value();
    struct passwd *pwinfo = getpwuid(uid);
    if (pwinfo && pwinfo->pw_name) {
        setDefaultDevice(pwinfo->pw_name, bioDevType, deviceName);
    } else {
        qInfo()<<"GetPWInfo failed!!";
    }
}

QString ServiceInterface::getDefaultDevice(QString userName, int bioDevType)
{
    QString defaultDevice = "";
    QString configPath = QString(USER_CONFIG_PATH).arg(userName);
    QSettings settings(configPath, QSettings::IniFormat);
    // 获取用户旧的默认设备
    if (settings.contains("DefaultDevice")) {
        QString strOldDefDev = settings.value("DefaultDevice").toString();
        if (!strOldDefDev.isEmpty()) {
            for (auto devInfo : m_listDeviceInfos) {
                if (devInfo && devInfo->device_shortname == strOldDefDev) {
                    QString strBioDefType = "";
                    switch(devInfo->biotype) {
                    case BIOTYPE_FINGERPRINT:
                        strBioDefType = "FP_DefaultDevice";
                        break;
                    case BIOTYPE_FINGERVEIN:
                        strBioDefType = "FV_DefaultDevice";
                        break;
                    case BIOTYPE_IRIS:
                        strBioDefType = "IR_DefaultDevice";
                        break;
                    case BIOTYPE_FACE:
                        strBioDefType = "FC_DefaultDevice";
                        break;
                    case BIOTYPE_VOICEPRINT:
                        strBioDefType = "VP_DefaultDevice";
                        break;
                    case REMOTE_QRCODE_TYPE:
                        strBioDefType = "WC_DefaultDevice";
                        break;
                    default:
                        break;
                    }
                    if (!strBioDefType.isEmpty() && !settings.contains(strBioDefType)) {
                        settings.setValue(strBioDefType, strOldDefDev);
                        settings.setValue("DefaultDevice", "");
                        settings.sync();
                    }
                    if (bioDevType == devInfo->biotype) {
                        return strOldDefDev;
                    }
                    break;
                }
            }
        }
    }
    switch (bioDevType) {
    case BIOTYPE_FACE:
        defaultDevice = settings.value("FC_DefaultDevice").toString();
        break;
    case BIOTYPE_FINGERPRINT:
        defaultDevice = settings.value("FP_DefaultDevice").toString();
        break;
    case BIOTYPE_FINGERVEIN:
        defaultDevice = settings.value("FV_DefaultDevice").toString();
        break;
    case BIOTYPE_IRIS:
        defaultDevice = settings.value("IR_DefaultDevice").toString();
        break;
    case BIOTYPE_VOICEPRINT:
        defaultDevice = settings.value("VP_DefaultDevice").toString();
        break;
    case REMOTE_QRCODE_TYPE:
        defaultDevice = settings.value("WC_DefaultDevice").toString();
        break;
    default:
        defaultDevice = settings.value("DefaultDevice").toString();
        break;
    }
    if(defaultDevice.isEmpty()) {
        QSettings settings2(COMM_CONFIG_PATH, QSettings::IniFormat);
        switch (bioDevType) {
        case BIOTYPE_FACE:
            defaultDevice = settings2.value("FC_DefaultDevice").toString();
            break;
        case BIOTYPE_FINGERPRINT:
            defaultDevice = settings2.value("FP_DefaultDevice").toString();
            break;
        case BIOTYPE_FINGERVEIN:
            defaultDevice = settings2.value("FV_DefaultDevice").toString();
            break;
        case BIOTYPE_IRIS:
            defaultDevice = settings2.value("IR_DefaultDevice").toString();
            break;
        case BIOTYPE_VOICEPRINT:
            defaultDevice = settings2.value("VP_DefaultDevice").toString();
            break;
        case REMOTE_QRCODE_TYPE:
            defaultDevice = settings2.value("WC_DefaultDevice").toString();
            break;
        default:
            defaultDevice = settings2.value("DefaultDevice").toString();
            break;
        }
    }
    return defaultDevice;
}

QStringList ServiceInterface::getAllDefaultDevice(QString userName)
{
    QStringList listDefDevice;
    QString configPath = QString(USER_CONFIG_PATH).arg(userName);
    QSettings settings(configPath, QSettings::IniFormat);
    int nOldDefType = -1;
    // 获取用户旧的默认设备
    if (settings.contains("DefaultDevice")) {
        QString strOldDefDev = settings.value("DefaultDevice").toString();
        if (!strOldDefDev.isEmpty()) {
            for (auto devInfo : m_listDeviceInfos) {
                if (devInfo && devInfo->device_shortname == strOldDefDev) {
                    QString strBioDefType = "";
                    switch(devInfo->biotype) {
                    case BIOTYPE_FINGERPRINT:
                        strBioDefType = "FP_DefaultDevice";
                        break;
                    case BIOTYPE_FINGERVEIN:
                        strBioDefType = "FV_DefaultDevice";
                        break;
                    case BIOTYPE_IRIS:
                        strBioDefType = "IR_DefaultDevice";
                        break;
                    case BIOTYPE_FACE:
                        strBioDefType = "FC_DefaultDevice";
                        break;
                    case BIOTYPE_VOICEPRINT:
                        strBioDefType = "VP_DefaultDevice";
                        break;
                    case REMOTE_QRCODE_TYPE:
                        strBioDefType = "WC_DefaultDevice";
                        break;
                    default:
                        break;
                    }
                    if (!strBioDefType.isEmpty() && !settings.contains(strBioDefType)) {
                        nOldDefType = devInfo->biotype;
                        listDefDevice.push_back(strOldDefDev);
                        settings.setValue(strBioDefType, strOldDefDev);
                        settings.setValue("DefaultDevice", "");
                        settings.sync();
                    }
                    break;
                }
            }
        }
    }
    QSettings settings2(COMM_CONFIG_PATH, QSettings::IniFormat);
    for (int nBioType = 0; nBioType <= REMOTE_QRCODE_TYPE; nBioType++) {
        QString defaultDevice = "";
        if (nBioType == nOldDefType)
            continue;
        switch (nBioType) {
        case BIOTYPE_FACE:
            defaultDevice = settings.value("FC_DefaultDevice").toString();
            break;
        case BIOTYPE_FINGERPRINT:
            defaultDevice = settings.value("FP_DefaultDevice").toString();
            break;
        case BIOTYPE_FINGERVEIN:
            defaultDevice = settings.value("FV_DefaultDevice").toString();
            break;
        case BIOTYPE_IRIS:
            defaultDevice = settings.value("IR_DefaultDevice").toString();
            break;
        case BIOTYPE_VOICEPRINT:
            defaultDevice = settings.value("VP_DefaultDevice").toString();
            break;
        case REMOTE_QRCODE_TYPE:
            defaultDevice = settings.value("WC_DefaultDevice").toString();
            break;
        default:
            break;
        }
        if(defaultDevice.isEmpty()) {
            switch (nBioType) {
            case BIOTYPE_FACE:
                defaultDevice = settings2.value("FC_DefaultDevice").toString();
                break;
            case BIOTYPE_FINGERPRINT:
                defaultDevice = settings2.value("FP_DefaultDevice").toString();
                break;
            case BIOTYPE_FINGERVEIN:
                defaultDevice = settings2.value("FV_DefaultDevice").toString();
                break;
            case BIOTYPE_IRIS:
                defaultDevice = settings2.value("IR_DefaultDevice").toString();
                break;
            case BIOTYPE_VOICEPRINT:
                defaultDevice = settings2.value("VP_DefaultDevice").toString();
                break;
            case REMOTE_QRCODE_TYPE:
                defaultDevice = settings2.value("WC_DefaultDevice").toString();
                break;
            default:
                break;
            }
        }
        if (!defaultDevice.isEmpty()) {
            listDefDevice.push_back(defaultDevice);
        }
    }
    return listDefDevice;
}

//设置通用默认设备
void ServiceInterface::setCommDefaultDevice(int bioDevType, QString deviceName)
{
    QSettings settings(COMM_CONFIG_PATH, QSettings::IniFormat);
    switch (bioDevType) {
    case BIOTYPE_FACE:
        settings.setValue("FC_DefaultDevice", deviceName);
        break;
    case BIOTYPE_FINGERPRINT:
        settings.setValue("FP_DefaultDevice", deviceName);
        break;
    case BIOTYPE_FINGERVEIN:
        settings.setValue("FV_DefaultDevice", deviceName);
        break;
    case BIOTYPE_IRIS:
        settings.setValue("IR_DefaultDevice", deviceName);
        break;
    case BIOTYPE_VOICEPRINT:
        settings.setValue("VP_DefaultDevice", deviceName);
        break;
    case REMOTE_QRCODE_TYPE:
        settings.setValue("WC_DefaultDevice", deviceName);
        break;
    default:
        break;
    }
    settings.sync();
    qDebug()<<"setCommDefaultDevice:"<<bioDevType<<","<<deviceName;
    emit defaultDeviceChanged("", bioDevType, deviceName);
}

//获取通用默认设备
QString ServiceInterface::getCommDefaultDevice(int bioDevType)
{
    QString defaultDevice = "";
    QSettings settings2(COMM_CONFIG_PATH, QSettings::IniFormat);
    switch (bioDevType) {
    case BIOTYPE_FACE:
        defaultDevice = settings2.value("FC_DefaultDevice").toString();
        break;
    case BIOTYPE_FINGERPRINT:
        defaultDevice = settings2.value("FP_DefaultDevice").toString();
        break;
    case BIOTYPE_FINGERVEIN:
        defaultDevice = settings2.value("FV_DefaultDevice").toString();
        break;
    case BIOTYPE_IRIS:
        defaultDevice = settings2.value("IR_DefaultDevice").toString();
        break;
    case BIOTYPE_VOICEPRINT:
        defaultDevice = settings2.value("VP_DefaultDevice").toString();
        break;
    case REMOTE_QRCODE_TYPE:
        defaultDevice = settings2.value("WC_DefaultDevice").toString();
        break;
    default:
        defaultDevice = settings2.value("DefaultDevice").toString();
        break;
    }
    return defaultDevice;
}

void ServiceInterface::setBioAuthStatus(int bioAuthType, bool status)
{
    QDBusConnection conn = connection();
    QDBusMessage msg = message();
    int uid = conn.interface()->serviceUid(msg.service()).value();
    struct passwd *pwinfo = getpwuid(uid);
    if (pwinfo && pwinfo->pw_name) {
        QString configPath = QString(USER_CONFIG_PATH).arg(pwinfo->pw_name);
        QSettings settings(configPath, QSettings::IniFormat);
        switch (bioAuthType) {
        case ENABLETYPE_BIO:
            settings.setValue("EnableAuth", status);
            break;
        case ENABLETYPE_SAVER:
            settings.setValue("SaverEnable", status);
            break;
        case ENABLETYPE_GREETER:
            settings.setValue("GreeterEnable", status);
            break;
        case ENABLETYPE_POLKIT:
            settings.setValue("PolkitEnable", status);
            break;
        case ENABLETYPE_SU:
            settings.setValue("SuEnable", status);
            break;
        case ENABLETYPE_SUDO:
            settings.setValue("SudoEnable", status);
            break;
        case ENABLETYPE_LOGIN:
            settings.setValue("LoginEnable", status);
            break;
        default:
            break;
        }
        settings.sync();
        emit bioAuthStatusChanged(pwinfo->pw_name, bioAuthType, status);
        qDebug()<<"setBioAuthStatus:"<<pwinfo->pw_name<<","<<bioAuthType<<","<<status;
    } else {
        qInfo()<<"GetPWInfo failed!!";
    }
}

bool ServiceInterface::getBioAuthStatus(QString userName, int bioAuthType)
{
    QString configPath = QString(USER_CONFIG_PATH).arg(userName);
    QSettings settings(configPath, QSettings::IniFormat);
    QString strBioAuthType = "";
    switch (bioAuthType) {
    case ENABLETYPE_BIO:
        strBioAuthType = "EnableAuth";
        break;
    case ENABLETYPE_SAVER:
        strBioAuthType = "SaverEnable";
        break;
    case ENABLETYPE_GREETER:
        strBioAuthType = "GreeterEnable";
        break;
    case ENABLETYPE_POLKIT:
        strBioAuthType = "PolkitEnable";
        break;
    case ENABLETYPE_SU:
        strBioAuthType = "SuEnable";
        break;
    case ENABLETYPE_SUDO:
        strBioAuthType = "SudoEnable";
        break;
    case ENABLETYPE_LOGIN:
        strBioAuthType = "LoginEnable";
        break;
    default:
        return false;
    }
    if (settings.contains(strBioAuthType)) {
        return settings.value(strBioAuthType).toBool();
    } else {
        QSettings settings2(COMM_CONFIG_PATH, QSettings::IniFormat);
        if (settings2.contains(strBioAuthType)) {
            return settings2.value(strBioAuthType).toBool();
        } else {
            return true;
        }
    }
}

int ServiceInterface::getMaxFailedTimes()
{
    QSettings sysSettings(COMM_CONFIG_PATH, QSettings::IniFormat);
    if(sysSettings.contains("MaxFailedTimes"))
        return sysSettings.value("MaxFailedTimes").toInt();
    else
        return 3;
}

bool ServiceInterface::getQRCodeEnable()
{
    bool isEnable = false;
    QSettings sysSettings(COMM_CONFIG_PATH, QSettings::IniFormat);
    sysSettings.beginGroup("Functions");
    if (sysSettings.allKeys().contains("EnableQRCode")) {
        isEnable = sysSettings.value("EnableQRCode").toBool();
    }
    sysSettings.endGroup();
    return isEnable;
}

// 获取是否双认证
bool ServiceInterface::getDoubleAuth()
{
    QSettings sysSettings(COMM_CONFIG_PATH, QSettings::IniFormat);
    if(sysSettings.contains("DoubleAuth"))
        return sysSettings.value("DoubleAuth").toBool();
    else
        return false;
}

// 获取用户绑定
bool ServiceInterface::getUserBind()
{
    QSettings sysSettings(COMM_CONFIG_PATH, QSettings::IniFormat);
    if(sysSettings.contains("UserBind"))
        return sysSettings.value("UserBind").toBool();
    else
        return false;
}

// 获取是否在控制面板显示
bool ServiceInterface::getIsShownInControlCenter()
{
    QSettings sysSettings(COMM_CONFIG_PATH, QSettings::IniFormat);
    if(sysSettings.contains("isShownInControlCenter"))
        return sysSettings.value("isShownInControlCenter").toBool();
    else
        return false;
}

// 获取是否使用第一个设备
bool ServiceInterface::getUseFirstDevice()
{
    QSettings sysSettings(COMM_CONFIG_PATH, QSettings::IniFormat);
    if(sysSettings.contains("UseFirstDevice"))
        return sysSettings.value("UseFirstDevice").toBool();
    else
        return false;
}

// 获取是否隐藏切换按钮
bool ServiceInterface::getHiddenSwitchButton()
{
    QSettings sysSettings(COMM_CONFIG_PATH, QSettings::IniFormat);
    if(sysSettings.contains("HiddenSwitchButton"))
        return sysSettings.value("HiddenSwitchButton").toBool();
    else
        return false;
}

// 获取旧版app使能值
int ServiceInterface::getOldAppStatus()
{
    QSettings sysSettings(COMM_CONFIG_PATH, QSettings::IniFormat);
    if(sysSettings.contains("EnableAuthApp"))
        return sysSettings.value("EnableAuthApp").toInt();
    else
        return 63;
}

void ServiceInterface::onUSBDeviceHotPlug(int drvid, int action, int deviceNum)
{
    if (action > 0) {
        qDebug()<<"onUSBDeviceHotPlug in:"<<drvid;
        updateCommDefaultDevice(drvid);
    }
}

void ServiceInterface::waitBiometricServiceStatus()
{
    qDebug()<<"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~` get biometric status";
    QDBusInterface iface("org.freedesktop.systemd1", "/org/freedesktop/systemd1",
                         "org.freedesktop.systemd1.Manager",QDBusConnection::systemBus());

    QDBusReply<QDBusObjectPath> bioPath = iface.call("GetUnit","biometric-authentication.service");
    if(!bioPath.isValid()){
        return ;
    }

    QDBusInterface bioface("org.freedesktop.systemd1", bioPath.value().path(),
                           "org.freedesktop.DBus.Properties", QDBusConnection::systemBus());
    QDBusReply<QDBusVariant> sessionReply = bioface.call("Get", "org.freedesktop.systemd1.Unit", "UnitFileState");
    if(!sessionReply.isValid())
        qWarning() << sessionReply.error();
    else {
        QString res = sessionReply.value().variant().toString();
        if(res == "disable")
            return;
    }

    qDebug()<<"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~   get activeState";
    int times = 0;
    while(times<20){
        QDBusReply<QDBusVariant> sessionReply = bioface.call("Get", "org.freedesktop.systemd1.Unit", "ActiveState");
        if(!sessionReply.isValid()){
            qWarning() << sessionReply.error();
            return ;
        }
        else {
            QString res = sessionReply.value().variant().toString();
            if(res == "activating"){
                times ++;
                usleep(100000);
            }else{
                break;
            }
        }
    }
    qDebug()<<"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ times = "<<times;
}

void ServiceInterface::updateCommDefaultDevice(int nDriId)
{
    if (!m_serviceInterface) {
        return ;
    }
    QVariant variant;
    QDBusArgument argument;
    QList<QDBusVariant> qlist;
    QDBusVariant item;
    DeviceInfo *deviceInfo;

    /* 返回值为 i -- int 和 av -- array of variant */
    QDBusPendingReply<int, QList<QDBusVariant> > reply = m_serviceInterface->call("GetDrvList");
    reply.waitForFinished();
    if (reply.isError()) {
        qDebug() << "GUI:" << reply.error();
        deviceCount = 0;
        return;
    }

    /* 解析 DBus 返回值，reply 有两个返回值，都是 QVariant 类型 */
    variant = reply.argumentAt(0); /* 得到第一个返回值 */
    deviceCount = variant.value<int>(); /* 解封装得到设备个数 */
    variant = reply.argumentAt(1); /* 得到第二个返回值 */
    argument = variant.value<QDBusArgument>(); /* 解封装，获取QDBusArgument对象 */
    argument >> qlist; /* 使用运算符重载提取 argument 对象里面存储的列表对象 */

    if (nDriId != -1) { // 指定设备接入
        for (int i = 0; i < deviceCount; i++) {
            item = qlist[i]; /* 取出一个元素 */
            variant = item.variant(); /* 转为普通QVariant对象 */
            /* 解封装得到 QDBusArgument 对象 */
            argument = variant.value<QDBusArgument>();
            deviceInfo = new DeviceInfo();
            argument >> *deviceInfo; /* 提取最终的 DeviceInfo 结构体 */
            if (nDriId == deviceInfo->device_id) {
                if (getCommDefaultDevice(deviceInfo->biotype).isEmpty()) {
                    setCommDefaultDevice(deviceInfo->biotype, deviceInfo->device_shortname);
                }
                break;
            }
        }
    } else {
        for (auto devInfo : m_listDeviceInfos) {
            if (devInfo) {
                delete devInfo;
                devInfo = nullptr;
            }
        }
        m_listDeviceInfos.clear();
        for (int i = 0; i < deviceCount; i++) {
            item = qlist[i]; /* 取出一个元素 */
            variant = item.variant(); /* 转为普通QVariant对象 */
            /* 解封装得到 QDBusArgument 对象 */
            argument = variant.value<QDBusArgument>();
            deviceInfo = new DeviceInfo();
            argument >> *deviceInfo; /* 提取最终的 DeviceInfo 结构体 */
            m_listDeviceInfos.push_back(deviceInfo);
        }
    }
}

void ServiceInterface::initData()
{
    // 沿用旧app enable
    QSettings sysSettings(COMM_CONFIG_PATH, QSettings::IniFormat);
    if(sysSettings.contains("EnableAuthApp") || sysSettings.contains("Functions/EnableAuthApp")) {
        int nAppOldStatus = 0;
        if (sysSettings.contains("Functions/EnableAuthApp")) {
            nAppOldStatus = sysSettings.value("Functions/EnableAuthApp").toInt();
        } else {
            nAppOldStatus = sysSettings.value("EnableAuthApp").toInt();
        }
        if ((nAppOldStatus&0x01) && !sysSettings.contains("GreeterEnable")) { // greeter
            sysSettings.setValue("GreeterEnable", true);
        }
        if ((nAppOldStatus&0x02) && !sysSettings.contains("SaverEnable")) { // saver
            sysSettings.setValue("SaverEnable", true);
        }
        if ((nAppOldStatus&0x04) && !sysSettings.contains("PolkitEnable")) { // polkit
            sysSettings.setValue("PolkitEnable", true);
        }
        if ((nAppOldStatus&0x08) && !sysSettings.contains("SudoEnable")) { // sudo
            sysSettings.setValue("SudoEnable", true);
        }
        if ((nAppOldStatus&0x10) && !sysSettings.contains("SuEnable")) { // su
            sysSettings.setValue("SuEnable", true);
        }
        if ((nAppOldStatus&0x20) && !sysSettings.contains("LoginEnable")) { // login
            sysSettings.setValue("LoginEnable", true);
        }
    }
    // 沿用旧的默认设备
    if(sysSettings.contains("DefaultDevice")) {
        QString strOldDefDev = sysSettings.value("DefaultDevice").toString();
        if (!strOldDefDev.isEmpty()) {
            for (auto devInfo : m_listDeviceInfos) {
                if (devInfo && devInfo->device_shortname == strOldDefDev) {
                    QString strBioDefType = "";
                    switch(devInfo->biotype) {
                    case BIOTYPE_FINGERPRINT:
                        strBioDefType = "FP_DefaultDevice";
                        break;
                    case BIOTYPE_FINGERVEIN:
                        strBioDefType = "FV_DefaultDevice";
                        break;
                    case BIOTYPE_IRIS:
                        strBioDefType = "IR_DefaultDevice";
                        break;
                    case BIOTYPE_FACE:
                        strBioDefType = "FC_DefaultDevice";
                        break;
                    case BIOTYPE_VOICEPRINT:
                        strBioDefType = "VP_DefaultDevice";
                        break;
                    case REMOTE_QRCODE_TYPE:
                        strBioDefType = "WC_DefaultDevice";
                        break;
                    default:
                        break;
                    }
                    if (!strBioDefType.isEmpty() && !sysSettings.contains(strBioDefType)) {
                        sysSettings.setValue(strBioDefType, strOldDefDev);
                        sysSettings.setValue("DefaultDevice", "");
                    }
                    break;
                }
            }
        }
    }
    // 设置未设置过默认设备的类型，如果驱动已打开且已连接
    for (auto devInfo : m_listDeviceInfos) {
        if (devInfo && devInfo->device_available > 0 && devInfo->driver_enable > 0) {
            QString strBioDefType = "";
            switch(devInfo->biotype) {
            case BIOTYPE_FINGERPRINT:
                strBioDefType = "FP_DefaultDevice";
                break;
            case BIOTYPE_FINGERVEIN:
                strBioDefType = "FV_DefaultDevice";
                break;
            case BIOTYPE_IRIS:
                strBioDefType = "IR_DefaultDevice";
                break;
            case BIOTYPE_FACE:
                strBioDefType = "FC_DefaultDevice";
                break;
            case BIOTYPE_VOICEPRINT:
                strBioDefType = "VP_DefaultDevice";
                break;
            case REMOTE_QRCODE_TYPE:
                strBioDefType = "WC_DefaultDevice";
                break;
            default:
                break;
            }
            if (!strBioDefType.isEmpty() && !sysSettings.contains(strBioDefType)) {
                sysSettings.setValue(strBioDefType, devInfo->device_shortname);
            }
        }
    }
    sysSettings.sync();
}

void ServiceInterface::onBiometricDbusChanged(bool bActive)
{
    qDebug()<<"BiometricDbus:"<<bActive;
    if (bActive) {
        updateCommDefaultDevice(-1);
        initData();
    }
}
