src/systeminfo/qsysteminfo_linux_common.cpp
changeset 0 876b1a06bc25
child 5 603d3f8b6302
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/systeminfo/qsysteminfo_linux_common.cpp	Wed Aug 25 15:49:42 2010 +0300
@@ -0,0 +1,1605 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Mobility Components.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights.  These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "qsysteminfo_linux_common_p.h"
+#include <QTimer>
+#include <QFile>
+#include <QDir>
+
+#if !defined(QT_NO_DBUS)
+#include "qhalservice_linux_p.h"
+#include <QtDBus/QtDBus>
+#include <QtDBus/QDBusConnection>
+#include <QtDBus/QDBusError>
+#include <QtDBus/QDBusInterface>
+#include <QtDBus/QDBusMessage>
+#include <QtDBus/QDBusReply>
+#include <QtDBus/QDBusPendingCallWatcher>
+#include <QtDBus/QDBusObjectPath>
+#include <QtDBus/QDBusPendingCall>
+#endif
+
+#include <QDesktopWidget>
+
+#include <locale.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <sys/vfs.h>
+#include <mntent.h>
+#include <sys/stat.h>
+
+#ifdef Q_WS_X11
+#include <QX11Info>
+#include <X11/Xlib.h>
+#endif
+
+#ifdef BLUEZ_SUPPORTED
+# include <bluetooth/bluetooth.h>
+# include <bluetooth/bnep.h>
+#endif
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+#include <unistd.h>
+
+//we cannot include iwlib.h as the platform may not have it installed
+//there we have to go via the kernel's wireless.h
+//#include <iwlib.h>
+//must be defined to be able to include kernel includes
+#ifndef __user
+#define __user
+#endif
+
+#include <linux/types.h>    /* required for wireless.h */
+#include <sys/socket.h>     /* required for wireless.h */
+#include <net/if.h>         /* required for wireless.h */
+
+/* A lot of wireless.h have kernel includes which should be protected by
+   #ifdef __KERNEL__. They course include errors due to redefinitions of types.
+   This prevents those kernel headers being included by Qtopia.
+   */
+#ifndef _LINUX_IF_H
+#define _LINUX_IF_H
+#endif
+#ifndef _LINUX_SOCKET_H
+#define _LINUX_SOCKET_H
+#endif
+#include <linux/wireless.h>
+#include <sys/ioctl.h>
+
+static bool halAvailable()
+{
+#if !defined(QT_NO_DBUS)
+    QDBusConnection dbusConnection = QDBusConnection::systemBus();
+    if (dbusConnection.isConnected()) {
+        QDBusConnectionInterface *dbiface = dbusConnection.interface();
+        QDBusReply<bool> reply = dbiface->isServiceRegistered("org.freedesktop.Hal");
+        if (reply.isValid() && reply.value()) {
+            return reply.value();
+        }
+    }
+#endif
+    return false;
+}
+
+
+bool halIsAvailable;
+
+QTM_BEGIN_NAMESPACE
+
+QSystemInfoLinuxCommonPrivate::QSystemInfoLinuxCommonPrivate(QObject *parent) : QObject(parent)
+{
+    halIsAvailable = halAvailable();
+    langCached = currentLanguage();
+}
+
+QSystemInfoLinuxCommonPrivate::~QSystemInfoLinuxCommonPrivate()
+{
+}
+
+void QSystemInfoLinuxCommonPrivate::startLanguagePolling()
+{
+    QString checkLang = QString::fromLocal8Bit(qgetenv("LANG"));
+    if(langCached.isEmpty()) {
+        currentLanguage();
+    }
+    checkLang = checkLang.left(2);
+    if(checkLang != langCached) {
+        emit currentLanguageChanged(checkLang);
+        langCached = checkLang;
+    }
+    langTimer = new QTimer(this);
+    QTimer::singleShot(1000, this, SLOT(startLanguagePolling()));
+}
+
+QString QSystemInfoLinuxCommonPrivate::currentLanguage() const
+{
+    QString lang;
+    if(langCached.isEmpty()) {
+        lang  = QLocale::system().name().left(2);
+        if(lang.isEmpty() || lang == QLatin1String("C")) {
+            lang = QLatin1String("en");
+        }
+    } else {
+        lang = langCached;
+    }
+    return lang;
+}
+
+bool QSystemInfoLinuxCommonPrivate::hasFeatureSupported(QSystemInfo::Feature feature)
+{
+     bool featureSupported = false;
+     switch (feature) {
+     case QSystemInfo::BluetoothFeature :
+         {
+             const QString sysPath = "/sys/class/bluetooth/";
+             const QDir sysDir(sysPath);
+             QStringList filters;
+             filters << "*";
+             const QStringList sysList = sysDir.entryList( filters ,QDir::Dirs | QDir::NoDotAndDotDot, QDir::Name);
+             foreach(const QString dir, sysList) {
+                 const QFileInfo btFile(sysPath + dir+"/address");
+                 if(btFile.exists()) {
+                     return true;
+                 }
+             }
+         }
+     break;
+     case QSystemInfo::CameraFeature :
+         {
+ #if !defined(QT_NO_DBUS)
+             featureSupported = hasHalUsbFeature(0x06); // image
+             if(featureSupported)
+                 return featureSupported;
+ #endif
+             featureSupported = hasSysFeature("video");
+         }
+         break;
+     case QSystemInfo::FmradioFeature :
+         {
+             featureSupported = !(QDir("/sys/class/video4linux/").entryList(QStringList("radio*")).empty());
+         }
+         break;
+     case QSystemInfo::IrFeature :
+         {
+ #if !defined(QT_NO_DBUS)
+         featureSupported = hasHalUsbFeature(0xFE);
+         if(featureSupported)
+             return featureSupported;
+ #endif
+         featureSupported = hasSysFeature("irda"); //?
+     }
+         break;
+     case QSystemInfo::LedFeature :
+         {
+             featureSupported = hasSysFeature("led"); //?
+         }
+         break;
+     case QSystemInfo::MemcardFeature :
+         {
+ #if !defined(QT_NO_DBUS)
+             QHalInterface iface;
+             if (iface.isValid()) {
+                 QHalInterface halIface;
+                 const QStringList halDevices = halIface.getAllDevices();
+                 foreach(const QString device, halDevices) {
+                     QHalDeviceInterface ifaceDevice(device);
+                     if (ifaceDevice.isValid()) {
+                         if(ifaceDevice.getPropertyString("info.subsystem") == "mmc_host") {
+                             return true;
+                         }
+                         if(ifaceDevice.getPropertyBool("storage.removable")) {
+                             return true;
+                         }
+                     }
+                 }
+             }
+ #endif
+         }
+         break;
+     case QSystemInfo::UsbFeature :
+         {
+ #if !defined(QT_NO_DBUS)
+         featureSupported = hasHalDeviceFeature("usb");
+         if(featureSupported)
+             return featureSupported;
+ #endif
+             featureSupported = hasSysFeature("usb_host");
+         }
+         break;
+     case QSystemInfo::VibFeature :
+ #if !defined(QT_NO_DBUS)
+         if(hasHalDeviceFeature("vibrator") || hasHalDeviceFeature("vib")) {
+             return true;
+     }
+#endif
+         break;
+     case QSystemInfo::WlanFeature :
+         {
+ #if !defined(QT_NO_DBUS)
+             QHalInterface iface;
+             if (iface.isValid()) {
+                 const QStringList list = iface.findDeviceByCapability("net.80211");
+                 if(!list.isEmpty()) {
+                     featureSupported = true;
+                     break;
+                 }
+             }
+ #endif
+             featureSupported = hasSysFeature("80211");
+         }
+         break;
+     case QSystemInfo::SimFeature :
+         break;
+     case QSystemInfo::LocationFeature :
+ #if !defined(QT_NO_DBUS)
+         featureSupported = hasHalDeviceFeature("gps"); //might not always be true
+         if(featureSupported)
+             return featureSupported;
+
+ #endif
+         break;
+     case QSystemInfo::VideoOutFeature :
+         {
+             featureSupported = !(QDir("/sys/class/video4linux/").entryList(QStringList("video*")).empty());
+         }
+         break;
+     case QSystemInfo::HapticsFeature:
+         break;
+     default:
+         featureSupported = false;
+         break;
+     };
+     return featureSupported;
+ }
+
+ #if !defined(QT_NO_DBUS)
+ bool QSystemInfoLinuxCommonPrivate::hasHalDeviceFeature(const QString &param)
+ {
+     QHalInterface halIface;
+     const QStringList halDevices = halIface.getAllDevices();
+     foreach(const QString device, halDevices) {
+         if(device.contains(param)) {
+             return true;
+         }
+     }
+     return false;
+ }
+
+ bool QSystemInfoLinuxCommonPrivate::hasHalUsbFeature(qint32 usbClass)
+ {
+     QHalInterface halIface;
+     const QStringList halDevices = halIface.getAllDevices();
+     foreach(const QString device, halDevices) {
+         QHalDeviceInterface ifaceDevice(device);
+         if (ifaceDevice.isValid()) {
+             if(ifaceDevice.getPropertyString("info.subsystem") == "usb_device") {
+                 if(ifaceDevice.getPropertyInt("usb.interface.class") == usbClass) {
+                     return true;
+                 }
+             }
+         }
+     }
+     return false;
+ }
+ #endif
+
+QString QSystemInfoLinuxCommonPrivate::version(QSystemInfo::Version type,
+                                               const QString &parameter)
+{
+    Q_UNUSED(parameter);
+    QString errorStr = QLatin1String("Not Available");
+
+    switch(type) {
+        case QSystemInfo::Os :
+        {
+#if !defined(QT_NO_DBUS)
+            QHalDeviceInterface iface(QLatin1String("/org/freedesktop/Hal/devices/computer"));
+            QString str;
+            if (iface.isValid()) {
+                str = iface.getPropertyString(QLatin1String("system.kernel.version"));
+                if(!str.isEmpty()) {
+                    return str;
+                }
+            }
+#endif
+            const QString versionPath = QLatin1String("/proc/version");
+            QFile versionFile(versionPath);
+            if(!versionFile.open(QIODevice::ReadOnly | QIODevice::Text)) {
+                qDebug() << "File not opened";
+            } else {
+                QString  strvalue;
+                strvalue = QLatin1String(versionFile.readAll().trimmed());
+                strvalue = strvalue.split(QLatin1String(" ")).at(2);
+                versionFile.close();
+                return strvalue;
+            }
+            break;
+        }
+        case QSystemInfo::QtCore :
+            return QLatin1String(qVersion());
+            break;
+        default:
+            break;
+    };
+    return errorStr;
+}
+
+QString QSystemInfoLinuxCommonPrivate::currentCountryCode() const
+{
+    return QLocale::system().name().mid(3,2);
+}
+
+bool QSystemInfoLinuxCommonPrivate::hasSysFeature(const QString &featureStr)
+{
+    const QString sysPath = QLatin1String("/sys/class/");
+    const QDir sysDir(sysPath);
+    QStringList filters;
+    filters << QLatin1String("*");
+    const QStringList sysList = sysDir.entryList( filters ,QDir::Dirs, QDir::Name);
+    foreach(const QString dir, sysList) {
+        const QDir sysDir2(sysPath + dir);
+        if(dir.contains(featureStr)) {
+            const QStringList sysList2 = sysDir2.entryList( filters ,QDir::Dirs, QDir::Name);
+            if(!sysList2.isEmpty()) {
+                return true;
+            }
+        }
+    }
+    return false;
+}
+
+QSystemNetworkInfoLinuxCommonPrivate::QSystemNetworkInfoLinuxCommonPrivate(QObject *parent) : QObject(parent)
+{
+}
+
+QSystemNetworkInfoLinuxCommonPrivate::~QSystemNetworkInfoLinuxCommonPrivate()
+{
+}
+QSystemNetworkInfo::NetworkStatus QSystemNetworkInfoLinuxCommonPrivate::networkStatus(QSystemNetworkInfo::NetworkMode mode)
+{
+    switch(mode) {
+    case QSystemNetworkInfo::WlanMode:
+        {
+            const QString baseSysDir = "/sys/class/net/";
+            const QDir wDir(baseSysDir);
+            const QStringList dirs = wDir.entryList(QStringList() << "*", QDir::AllDirs | QDir::NoDotAndDotDot);
+            foreach(const QString dir, dirs) {
+                const QString devFile = baseSysDir + dir;
+                const QFileInfo wiFi(devFile + "/wireless");
+                const QFileInfo fi("/proc/net/route");
+                if(wiFi.exists() && fi.exists()) {
+                    QFile rx(fi.absoluteFilePath());
+                    if(rx.exists() && rx.open(QIODevice::ReadOnly | QIODevice::Text)) {
+                        const QString result = rx.readAll();
+                        if(result.contains(dir)) {
+                            return QSystemNetworkInfo::Connected;
+                        } else {
+                            return QSystemNetworkInfo::NoNetworkAvailable;
+                        }
+                    }
+                }
+            }
+        }
+        break;
+    case QSystemNetworkInfo::EthernetMode:
+        {
+            const QString baseSysDir = "/sys/class/net/";
+            const QDir eDir(baseSysDir);
+            const QString dir = QSystemNetworkInfoLinuxCommonPrivate::interfaceForMode(mode).name();
+
+            const QString devFile = baseSysDir + dir;
+            const QFileInfo fi("/proc/net/route");
+            if(fi.exists()) {
+                QFile rx(fi.absoluteFilePath());
+                if(rx.exists() && rx.open(QIODevice::ReadOnly | QIODevice::Text)) {
+                    const QString result = rx.readAll();
+                    if(result.contains(dir)) {
+                        return QSystemNetworkInfo::Connected;
+                    } else {
+                        return QSystemNetworkInfo::NoNetworkAvailable;
+                    }
+                }
+            }
+        }
+        break;
+        case QSystemNetworkInfo::BluetoothMode:
+        {
+            return getBluetoothNetStatus();
+       }
+        break;
+    default:
+        break;
+    };
+    return QSystemNetworkInfo::UndefinedStatus;
+}
+
+QString QSystemNetworkInfoLinuxCommonPrivate::networkName(QSystemNetworkInfo::NetworkMode mode)
+{
+    QString netname = "";
+
+    switch(mode) {
+    case QSystemNetworkInfo::WlanMode:
+        {
+            if(networkStatus(mode) != QSystemNetworkInfo::Connected) {
+                return netname;
+            }
+
+            QString wlanInterface;
+            const QString baseSysDir = "/sys/class/net/";
+            const QDir wDir(baseSysDir);
+            const QStringList dirs = wDir.entryList(QStringList() << "*", QDir::AllDirs | QDir::NoDotAndDotDot);
+            foreach(const QString dir, dirs) {
+                const QString devFile = baseSysDir + dir;
+                const QFileInfo fi(devFile + "/wireless");
+                if(fi.exists()) {
+                    wlanInterface = dir;
+                }
+            }
+            int sock = socket(PF_INET, SOCK_DGRAM, 0);
+            if (sock > 0) {
+                const char* someRandomBuffer[IW_ESSID_MAX_SIZE + 1];
+                struct iwreq wifiExchange;
+                memset(&wifiExchange, 0, sizeof(wifiExchange));
+                memset(someRandomBuffer, 0, sizeof(someRandomBuffer));
+
+                wifiExchange.u.essid.pointer = (caddr_t) someRandomBuffer;
+                wifiExchange.u.essid.length = IW_ESSID_MAX_SIZE;
+                wifiExchange.u.essid.flags = 0;
+
+                const char* interfaceName = wlanInterface.toLatin1();
+                strncpy(wifiExchange.ifr_name, interfaceName, IFNAMSIZ);
+                wifiExchange.u.essid.length = IW_ESSID_MAX_SIZE + 1;
+
+                if (ioctl(sock, SIOCGIWESSID, &wifiExchange) == 0) {
+                    const char *ssid = (const char *)wifiExchange.u.essid.pointer;
+                    netname = ssid;
+                }
+            } else {
+                qDebug() << "no socket";
+            }
+            close(sock);
+        }
+        break;
+    case QSystemNetworkInfo::EthernetMode:
+        {
+            QFile resFile("/etc/resolv.conf");
+            if(resFile.exists()) {
+                if(resFile.exists() && resFile.open(QIODevice::ReadOnly | QIODevice::Text)) {
+                    QString line;
+                    QTextStream in(&resFile);
+                    do {
+                        line = in.readLine();
+                        if(line.contains("domain")) {
+                            netname = line.section(" ",1,1); //guessing here
+                        }
+                } while (!line.isNull());
+                resFile.close();
+            }
+        }
+    }
+    break;
+        case QSystemNetworkInfo::BluetoothMode:
+            {
+    #if !defined(QT_NO_DBUS)
+        netname = getBluetoothInfo("name");
+#endif
+    }
+        break;
+    default:
+        break;
+    };
+    return netname;
+}
+
+QString QSystemNetworkInfoLinuxCommonPrivate::macAddress(QSystemNetworkInfo::NetworkMode mode)
+{
+    switch(mode) {
+        case QSystemNetworkInfo::WlanMode:
+        {
+            QString result;
+            const QString baseSysDir = "/sys/class/net/";
+            const QDir wDir(baseSysDir);
+            const QStringList dirs = wDir.entryList(QStringList() << "*", QDir::AllDirs | QDir::NoDotAndDotDot);
+            foreach(const QString dir, dirs) {
+                const QString devFile = baseSysDir + dir;
+                const QFileInfo fi(devFile + "/wireless");
+                if(fi.exists()) {
+                    QFile rx(devFile + "/address");
+                    if(rx.exists() && rx.open(QIODevice::ReadOnly | QIODevice::Text)) {
+                        QTextStream in(&rx);
+                        in >> result;
+                        rx.close();
+                        return result;
+                    }
+                }
+            }
+        }
+        break;
+        case QSystemNetworkInfo::EthernetMode:
+        {
+            QString result;
+            const QString baseSysDir = "/sys/class/net/";
+            const QDir eDir(baseSysDir);
+            const QStringList dirs = eDir.entryList(QStringList() << "eth*", QDir::AllDirs | QDir::NoDotAndDotDot);
+            foreach(const QString dir, dirs) {
+                const QString devFile = baseSysDir + dir;
+                const QFileInfo fi(devFile + "/address");
+                if(fi.exists()) {
+                    QFile rx(fi.absoluteFilePath());
+                    if(rx.exists() && rx.open(QIODevice::ReadOnly | QIODevice::Text)) {
+                        QTextStream in(&rx);
+                        in >> result;
+                        rx.close();
+                        return result;
+                    }
+                }
+            }
+        }
+        break;
+        case QSystemNetworkInfo::BluetoothMode:
+        {
+#if !defined(QT_NO_DBUS)
+            return getBluetoothInfo("address");
+#endif
+        }
+        break;
+    default:
+        break;
+    };
+    return QString();
+}
+
+QSystemNetworkInfo::NetworkStatus QSystemNetworkInfoLinuxCommonPrivate::getBluetoothNetStatus()
+{
+#ifdef BLUEZ_SUPPORTED
+    int ctl = socket(PF_BLUETOOTH,SOCK_RAW,BTPROTO_BNEP);
+    if (ctl < 0) {
+        qDebug() << "Cannot open bnep socket";
+        return QSystemNetworkInfo::UndefinedStatus;
+    }
+
+    struct bnep_conninfo info[36];
+    struct bnep_connlist_req req;
+
+    req.ci = info;
+    req.cnum = 36;
+
+    if (ioctl(ctl,BNEPGETCONNLIST,&req) < 0) {
+        qDebug() << "Cannot get bnep connection list.";
+        return QSystemNetworkInfo::UndefinedStatus;
+    }
+    for (uint j = 0; j< req.cnum; j++) {
+        if(info[j].state == BT_CONNECTED) {
+            return QSystemNetworkInfo::Connected;
+        }
+    }
+    close(ctl);
+#endif
+
+    return QSystemNetworkInfo::UndefinedStatus;
+}
+
+qint32 QSystemNetworkInfoLinuxCommonPrivate::networkSignalStrength(QSystemNetworkInfo::NetworkMode mode)
+{
+    switch(mode) {
+    case QSystemNetworkInfo::WlanMode:
+        {
+            QString result;
+            const QString baseSysDir = "/sys/class/net/";
+            const QDir wDir(baseSysDir);
+            const QStringList dirs = wDir.entryList(QStringList() << "*", QDir::AllDirs | QDir::NoDotAndDotDot);
+            foreach(const QString dir, dirs) {
+                const QString devFile = baseSysDir + dir;
+                const QFileInfo fi(devFile + "/wireless/link");
+                if(fi.exists()) {
+                    QFile rx(fi.absoluteFilePath());
+                    if(rx.exists() && rx.open(QIODevice::ReadOnly | QIODevice::Text)) {
+                        QTextStream in(&rx);
+                        in >> result;
+                        rx.close();
+                        return result.toInt();
+
+                    }
+                }
+            }
+        }
+        break;
+    case QSystemNetworkInfo::EthernetMode:
+        {
+            QString result;
+            const QString baseSysDir = "/sys/class/net/";
+            const QDir eDir(baseSysDir);
+            const QStringList dirs = eDir.entryList(QStringList() << "eth*", QDir::AllDirs | QDir::NoDotAndDotDot);
+            foreach(const QString dir, dirs) {
+                const QString devFile = baseSysDir + dir;
+                const QFileInfo fi(devFile + "/carrier");
+                if(fi.exists()) {
+                    QFile rx(fi.absoluteFilePath());
+                    if(rx.exists() && rx.open(QIODevice::ReadOnly | QIODevice::Text)) {
+                        QTextStream in(&rx);
+                        in >> result;
+                        rx.close();
+                        return result.toInt() * 100;
+
+                    }
+                }
+            }
+        }
+        break;
+        case QSystemNetworkInfo::BluetoothMode:
+        {
+#if !defined(QT_NO_DBUS)
+            return getBluetoothRssi();
+#endif
+        }
+        break;
+    default:
+        break;
+    };
+
+    return -1;
+}
+
+QNetworkInterface QSystemNetworkInfoLinuxCommonPrivate::interfaceForMode(QSystemNetworkInfo::NetworkMode mode)
+{
+#if !defined(QT_NO_DBUS)
+    switch(mode) {
+    case QSystemNetworkInfo::WlanMode:
+        {
+            QHalInterface iface;
+            if (iface.isValid()) {
+                const QStringList list = iface.findDeviceByCapability("net.80211");
+                if(!list.isEmpty()) {
+                    foreach(const QString netDev, list) {
+                        QHalDeviceInterface ifaceDevice(netDev);
+                        const QString deviceName  = ifaceDevice.getPropertyString("net.interface");
+                        if(list.count() > 1) {
+                            const QString baseFIle = "/sys/class/net/" + deviceName+"/operstate";
+                            QFile rx(baseFIle);
+                            if(rx.exists() && rx.open(QIODevice::ReadOnly | QIODevice::Text)) {
+                                QString operatingState;
+                                QTextStream in(&rx);
+                                in >> operatingState;
+                                rx.close();
+                                if(!operatingState.contains("unknown")
+                                    || !operatingState.contains("down")) {
+                                    if(isDefaultInterface(deviceName))
+                                        return QNetworkInterface::interfaceFromName(deviceName);
+                                }
+                            }
+                        } else {
+                            return QNetworkInterface::interfaceFromName(deviceName);
+                        }
+                    }
+                }
+            }
+        }
+        break;
+    case QSystemNetworkInfo::EthernetMode:
+        {
+            QHalInterface iface;
+            if (iface.isValid()) {
+                const QStringList list = iface.findDeviceByCapability("net.80203");
+                if(!list.isEmpty()) {
+                    foreach(const QString netDev, list) {
+                        QHalDeviceInterface ifaceDevice(netDev);
+                        const QString deviceName  = ifaceDevice.getPropertyString("net.interface");
+                        if(list.count() > 1) {
+                            const QString baseFIle = "/sys/class/net/" + deviceName+"/operstate";
+                            QFile rx(baseFIle);
+                            if(rx.exists() && rx.open(QIODevice::ReadOnly | QIODevice::Text)) {
+                                QString operatingState;
+                                QTextStream in(&rx);
+                                in >> operatingState;
+                                rx.close();
+                                if(!operatingState.contains("unknown")
+                                    || !operatingState.contains("down")) {
+                                    if(isDefaultInterface(deviceName))
+                                        return QNetworkInterface::interfaceFromName(deviceName);
+                                }
+                            }
+                        } else {
+                            return QNetworkInterface::interfaceFromName(deviceName);
+                        }
+                    }
+                }
+            }
+        }
+        break;
+        case QSystemNetworkInfo::BluetoothMode:
+        {
+        }
+        break;
+    default:
+        break;
+    };
+#else
+    QString result;
+    const QString baseSysDir = "/sys/class/net/";
+    const QDir eDir(baseSysDir);
+    const QStringList dirs = eDir.entryList(QStringList() << "*", QDir::AllDirs | QDir::NoDotAndDotDot);
+    foreach(const QString dir, dirs) {
+        const QString devFile = baseSysDir + dir;
+        const QFileInfo devfi(devFile + "/device");
+        if(!devfi.exists()) {
+            continue;
+        }
+        const QString baseFIle = "/sys/class/net/" + devFile+"/operstate";
+        QFile rx(baseFIle);
+        if(rx.exists() && rx.open(QIODevice::ReadOnly | QIODevice::Text)) {
+            QString operatingState;
+            QTextStream in(&rx);
+            in >> operatingState;
+            rx.close();
+            if(operatingState.contains("unknown")) {
+                continue;
+            }
+        }
+        switch(mode) {
+        case QSystemNetworkInfo::WlanMode:
+            {
+                const QFileInfo fi(devFile + "/wireless");
+                if(fi.exists()) {
+                    return QNetworkInterface::interfaceFromName(dir);
+                }
+            }
+            break;
+            case QSystemNetworkInfo::EthernetMode:
+            {
+                const QFileInfo fi(devFile + "/wireless");
+                if(!fi.exists()) {
+                    return QNetworkInterface::interfaceFromName(dir);
+                }
+            }
+            break;
+            case QSystemNetworkInfo::BluetoothMode:
+            {
+
+            }
+            break;
+
+            default:
+            break;
+        };
+    }
+#endif
+    return QNetworkInterface();
+}
+
+#if !defined(QT_NO_DBUS)
+bool QSystemNetworkInfoLinuxCommonPrivate::isDefaultInterface(const QString &deviceName)
+{
+    QFile routeFilex("/proc/net/route");
+    if(routeFilex.exists() && routeFilex.open(QIODevice::ReadOnly
+                                              | QIODevice::Text)) {
+        QTextStream rin(&routeFilex);
+        QString line = rin.readLine();
+        while (!line.isNull()) {
+            const QString lineSection = line.section("\t",2,2,QString::SectionSkipEmpty);
+            if(lineSection != "00000000" && lineSection!="Gateway")
+                if(line.section("\t",0,0,QString::SectionSkipEmpty) == deviceName) {
+                routeFilex.close();
+                return true;
+            }
+            line = rin.readLine();
+        }
+    }
+    routeFilex.close();
+    return false;
+}
+
+int QSystemNetworkInfoLinuxCommonPrivate::getBluetoothRssi()
+{
+    return 0;
+}
+
+QString QSystemNetworkInfoLinuxCommonPrivate::getBluetoothInfo(const QString &file)
+{
+    const QString sysPath = "/sys/class/bluetooth/";
+    const QDir sysDir(sysPath);
+    QStringList filters;
+    filters << "*";
+    const QStringList sysList = sysDir.entryList( filters ,QDir::Dirs | QDir::NoDotAndDotDot, QDir::Name);
+    foreach(const QString dir, sysList) {
+        QFile btFile(sysPath + dir+"/"+file);
+        if(btFile.exists()) {
+            if (btFile.open(QIODevice::ReadOnly)) {
+                QTextStream btFileStream(&btFile);
+                QString line = btFileStream.readAll();
+                return line.simplified();
+            }
+        }
+    }
+    return QString();
+}
+#endif
+
+QSystemDisplayInfoLinuxCommonPrivate::QSystemDisplayInfoLinuxCommonPrivate(QObject *parent) : QObject(parent)
+{
+    halIsAvailable = halAvailable();
+}
+
+QSystemDisplayInfoLinuxCommonPrivate::~QSystemDisplayInfoLinuxCommonPrivate()
+{
+}
+
+int QSystemDisplayInfoLinuxCommonPrivate::colorDepth(int screen)
+{
+#ifdef Q_WS_X11
+    QDesktopWidget wid;
+    return wid.screen(screen)->x11Info().depth();
+#else
+        return QPixmap::defaultDepth();
+#endif
+}
+
+
+int QSystemDisplayInfoLinuxCommonPrivate::displayBrightness(int screen)
+{
+    Q_UNUSED(screen);
+    if(halIsAvailable) {
+#if !defined(QT_NO_DBUS)
+        QHalInterface iface;
+        if (iface.isValid()) {
+            const QStringList list = iface.findDeviceByCapability("laptop_panel");
+            if(!list.isEmpty()) {
+                foreach(const QString lapDev, list) {
+                    QHalDeviceInterface ifaceDevice(lapDev);
+                    QHalDeviceLaptopPanelInterface lapIface(lapDev);
+                    const float numLevels = ifaceDevice.getPropertyInt("laptop_panel.num_levels") - 1;
+                    const float curLevel = lapIface.getBrightness();
+                    return curLevel / numLevels * 100;
+                }
+            }
+        }
+#endif
+    } else {
+        const QString backlightPath = "/proc/acpi/video/";
+        const QDir videoDir(backlightPath);
+        QStringList filters;
+        filters << "*";
+        const QStringList brightnessList = videoDir.entryList(filters,
+                                                        QDir::Dirs
+                                                        | QDir::NoDotAndDotDot,
+                                                        QDir::Name);
+        foreach(const QString brightnessFileName, brightnessList) {
+            float numLevels = 0.0;
+            float curLevel = 0.0;
+            QFile curBrightnessFile(backlightPath+brightnessFileName+"/LCD/brightness");
+            if(!curBrightnessFile.open(QIODevice::ReadOnly | QIODevice::Text)) {
+                qDebug()<<"File not opened";
+            } else {
+                const QString strvalue = curBrightnessFile.readAll().trimmed();
+                if(strvalue.contains("levels")) {
+                    QStringList list = strvalue.split(" ");
+                    numLevels = list.at(2).toFloat();
+                }
+                if(strvalue.contains("current")) {
+                    QStringList list = strvalue.split(": ");
+                    curLevel = list.at(list.count()-1).toFloat();
+                }
+                curBrightnessFile.close();
+                return curLevel / numLevels * 100;
+            }
+        }
+    }
+#if 0
+    QString backlightPath = "/sys/devices/virtual/backlight/";
+    QDir videoDir(backlightPath);
+    QStringList filters;
+    filters << "*";
+    QStringList brightnessList = videoDir.entryList(filters,
+                                                     QDir::Dirs
+                                                     | QDir::NoDotAndDotDot,
+                                                     QDir::Name);
+    foreach(QString brightnessFileName, brightnessList) {
+        float numLevels = 0.0;
+        float curLevel = 0.0;
+        QFile curBrightnessFile(backlightPath+brightnessFileName+"/brightness");
+        if(!curBrightnessFile.open(QIODevice::ReadOnly | QIODevice::Text)) {
+            qDebug()<<"File not opened";
+        } else {
+            QString strvalue;
+            strvalue = curBrightnessFile.readLine().trimmed();
+            curBrightnessFile.close();
+            curLevel = strvalue.toFloat();
+
+            QFile maxBrightnessFile(backlightPath+brightnessFileName+"/max_brightness");
+            if(!maxBrightnessFile.open(QIODevice::ReadOnly | QIODevice::Text)) {
+                qDebug()<<"File not opened";
+            } else {
+                QString strvalue;
+                strvalue = maxBrightnessFile.readLine().trimmed();
+                maxBrightnessFile.close();
+                numLevels = strvalue.toFloat();
+            }
+            return curLevel / numLevels * 100;
+        }
+    }
+#endif
+    return -1;
+}
+
+QSystemStorageInfoLinuxCommonPrivate::QSystemStorageInfoLinuxCommonPrivate(QObject *parent)
+    : QObject(parent)
+{
+    halIsAvailable = halAvailable();
+}
+
+QSystemStorageInfoLinuxCommonPrivate::~QSystemStorageInfoLinuxCommonPrivate()
+{
+}
+
+qint64 QSystemStorageInfoLinuxCommonPrivate::availableDiskSpace(const QString &driveVolume)
+{
+    if(driveVolume.left(2) == "//") {
+        return 0;
+    }
+    mountEntries();
+    struct statfs fs;
+    if(statfs(driveVolume.toLatin1(), &fs ) == 0 ) {
+                long blockSize = fs.f_bsize;
+                long availBlocks = fs.f_bavail;
+                return (double)availBlocks * blockSize;
+            }
+    return 0;
+}
+
+qint64 QSystemStorageInfoLinuxCommonPrivate::totalDiskSpace(const QString &driveVolume)
+{
+    if(driveVolume.left(2) == "//") {
+        return 0;
+    }
+    mountEntries();
+    struct statfs fs;
+    if(statfs(driveVolume.toLatin1(), &fs ) == 0 ) {
+        const long blockSize = fs.f_bsize;
+        const long totalBlocks = fs.f_blocks;
+        return (double)totalBlocks * blockSize;
+    }
+    return 0;
+}
+
+QSystemStorageInfo::DriveType QSystemStorageInfoLinuxCommonPrivate::typeForDrive(const QString &driveVolume)
+{
+    if(halIsAvailable) {
+#if !defined(QT_NO_DBUS)
+        QStringList mountedVol;
+        QHalInterface iface;
+        const QStringList list = iface.findDeviceByCapability("volume");
+        if(!list.isEmpty()) {
+            foreach(const QString vol, list) {
+                QHalDeviceInterface ifaceDevice(vol);
+                if(mountEntriesMap.value(driveVolume) == ifaceDevice.getPropertyString("block.device")) {
+                    QHalDeviceInterface ifaceDeviceParent(ifaceDevice.getPropertyString("info.parent"), this);
+
+                    if(ifaceDeviceParent.getPropertyBool("storage.removable")
+                        ||  ifaceDeviceParent.getPropertyString("storage.drive_type") != "disk") {
+                        return QSystemStorageInfo::RemovableDrive;
+                        break;
+                    } else {
+                         return QSystemStorageInfo::InternalDrive;
+                    }
+                }
+            }
+        }
+#endif
+    } else {
+        //no hal need to manually read sys file for block device
+        QString dmFile;
+
+        if(mountEntriesMap.value(driveVolume).contains("mapper")) {
+            struct stat stat_buf;
+            stat( mountEntriesMap.value(driveVolume).toLatin1(), &stat_buf);
+
+            dmFile = QString("/sys/block/dm-%1/removable").arg(stat_buf.st_rdev & 0377);
+
+        } else {
+
+            dmFile = mountEntriesMap.value(driveVolume).section("/",2,3);
+            if (dmFile.left(3) == "mmc") { //assume this dev is removable sd/mmc card.
+                return QSystemStorageInfo::RemovableDrive;
+            }
+
+            if(dmFile.length() > 3) { //if device has number, we need the 'parent' device
+                dmFile.chop(1);
+                if (dmFile.right(1) == "p") //get rid of partition number
+                    dmFile.chop(1);
+            }
+            dmFile = "/sys/block/"+dmFile+"/removable";
+        }
+
+        QFile file(dmFile);
+        if (!file.open(QIODevice::ReadOnly)) {
+            qDebug() << "Could not open sys file";
+        } else {
+            QTextStream sysinfo(&file);
+            QString line = sysinfo.readAll();
+            if(line.contains("1")) {
+                return QSystemStorageInfo::RemovableDrive;
+            }
+        }
+    }
+    if(driveVolume.left(2) == "//") {
+        return QSystemStorageInfo::RemoteDrive;
+    }
+    return QSystemStorageInfo::InternalDrive;
+}
+
+QStringList QSystemStorageInfoLinuxCommonPrivate::logicalDrives()
+{
+    mountEntries();
+    return mountEntriesMap.keys();
+}
+
+void QSystemStorageInfoLinuxCommonPrivate::mountEntries()
+{
+    mountEntriesMap.clear();
+    FILE *mntfp = setmntent( _PATH_MOUNTED, "r" );
+    mntent *me = getmntent(mntfp);
+    bool ok;
+    while(me != NULL) {
+        struct statfs fs;
+        ok = false;
+        if(strcmp(me->mnt_type, "cifs") != 0) { //smb has probs with statfs
+            if(statfs(me->mnt_dir, &fs ) ==0 ) {
+                QString num;
+                // weed out a few types
+                if ( fs.f_type != 0x01021994 //tmpfs
+                     && fs.f_type != 0x9fa0 //procfs
+                     && fs.f_type != 0x1cd1 //
+                     && fs.f_type != 0x62656572
+                     && (unsigned)fs.f_type != 0xabababab // ???
+                     && fs.f_type != 0x52654973
+                     && fs.f_type != 0x42494e4d
+                     && fs.f_type != 0x64626720
+                     && fs.f_type != 0x73636673 //securityfs
+                     && fs.f_type != 0x65735543 //fusectl
+                     && fs.f_type != 0x65735546 // fuse.gvfs-fuse-daemon
+
+                     ) {
+                    ok = true;
+                }
+            }
+        } else {
+            ok = true;
+        }
+        if(ok && !mountEntriesMap.keys().contains(me->mnt_fsname)) {
+            mountEntriesMap[me->mnt_dir] = me->mnt_fsname;
+        }
+
+        me = getmntent(mntfp);
+    }
+    endmntent(mntfp);
+}
+
+
+
+QSystemDeviceInfoLinuxCommonPrivate::QSystemDeviceInfoLinuxCommonPrivate(QObject *parent) : QObject(parent)
+{
+    halIsAvailable = halAvailable();
+    setConnection();
+ #if !defined(QT_NO_DBUS)
+    setupBluetooth();
+#endif
+}
+
+QSystemDeviceInfoLinuxCommonPrivate::~QSystemDeviceInfoLinuxCommonPrivate()
+{
+}
+
+
+void QSystemDeviceInfoLinuxCommonPrivate::setConnection()
+{
+    if(halIsAvailable) {
+#if !defined(QT_NO_DBUS)
+        QHalInterface iface;
+
+        QStringList list = iface.findDeviceByCapability("battery");
+        if(!list.isEmpty()) {
+            foreach(const QString dev, list) {
+                halIfaceDevice = new QHalDeviceInterface(dev);
+                if (halIfaceDevice->isValid()) {
+                    const QString batType = halIfaceDevice->getPropertyString("battery.type");
+                    if(batType == "primary" || batType == "pda") {
+                        if(halIfaceDevice->setConnections() ) {
+                            if(!connect(halIfaceDevice,SIGNAL(propertyModified(int, QVariantList)),
+                                        this,SLOT(halChanged(int,QVariantList)))) {
+                                qDebug() << "connection malfunction";
+                            }
+                        }
+                        break;
+                    }
+                }
+            }
+        }
+
+        list = iface.findDeviceByCapability("ac_adapter");
+        if(!list.isEmpty()) {
+            foreach(const QString dev, list) {
+                halIfaceDevice = new QHalDeviceInterface(dev);
+                if (halIfaceDevice->isValid()) {
+                    if(halIfaceDevice->setConnections() ) {
+                        if(!connect(halIfaceDevice,SIGNAL(propertyModified(int, QVariantList)),
+                                    this,SLOT(halChanged(int,QVariantList)))) {
+                            qDebug() << "connection malfunction";
+                        }
+                    }
+                    break;
+                }
+            }
+        }
+
+        list = iface.findDeviceByCapability("battery");
+        if(!list.isEmpty()) {
+            foreach(const QString dev, list) {
+                halIfaceDevice = new QHalDeviceInterface(dev);
+                if (halIfaceDevice->isValid()) {
+                    if(halIfaceDevice->setConnections()) {
+                        if(!connect(halIfaceDevice,SIGNAL(propertyModified(int, QVariantList)),
+                                    this,SLOT(halChanged(int,QVariantList)))) {
+                            qDebug() << "connection malfunction";
+                        }
+                    }
+                    break;
+                }
+            }
+        }
+
+#endif
+    }
+}
+
+
+#if !defined(QT_NO_DBUS)
+void QSystemDeviceInfoLinuxCommonPrivate::halChanged(int,QVariantList map)
+{
+    for(int i=0; i < map.count(); i++) {
+       if(map.at(i).toString() == "battery.charge_level.percentage") {
+            const int level = batteryLevel();
+            emit batteryLevelChanged(level);
+            if(level < 4) {
+                emit batteryStatusChanged(QSystemDeviceInfo::BatteryCritical);
+            } else if(level < 11) {
+                emit batteryStatusChanged(QSystemDeviceInfo::BatteryVeryLow);
+            } else if(level < 41) {
+                emit batteryStatusChanged(QSystemDeviceInfo::BatteryLow);
+            } else if(level > 40) {
+                emit batteryStatusChanged(QSystemDeviceInfo::BatteryNormal);
+            }
+            else {
+                emit batteryStatusChanged(QSystemDeviceInfo::NoBatteryLevel);
+            }
+        }
+        if((map.at(i).toString() == "ac_adapter.present")
+        || (map.at(i).toString() == "battery.rechargeable.is_charging")) {
+            QSystemDeviceInfo::PowerState state = currentPowerState();
+            emit powerStateChanged(state);
+       }} //end map
+}
+#endif
+
+QString QSystemDeviceInfoLinuxCommonPrivate::manufacturer()
+{
+    if(halIsAvailable) {
+#if !defined(QT_NO_DBUS)
+        QHalDeviceInterface iface("/org/freedesktop/Hal/devices/computer");
+        QString manu;
+        if (iface.isValid()) {
+            manu = iface.getPropertyString("system.firmware.vendor");
+            if(manu.isEmpty()) {
+                manu = iface.getPropertyString("system.hardware.vendor");
+                if(!manu.isEmpty()) {
+                    return manu;
+                }
+            }
+        }
+#endif
+    }
+    QFile vendorId("/sys/devices/virtual/dmi/id/board_vendor");
+    if (vendorId.open(QIODevice::ReadOnly)) {
+        QTextStream cpuinfo(&vendorId);
+        return cpuinfo.readLine().trimmed();
+    } else {
+        QFile file("/proc/cpuinfo");
+        if (!file.open(QIODevice::ReadOnly)) {
+            qDebug() << "Could not open /proc/cpuinfo";
+        } else {
+            QTextStream cpuinfo(&file);
+            QString line = cpuinfo.readLine();
+            while (!line.isNull()) {
+                line = cpuinfo.readLine();
+                if(line.contains("vendor_id")) {
+                    return line.split(": ").at(1).trimmed();
+                }
+            }
+        }
+    }
+    return QString();
+}
+
+QString QSystemDeviceInfoLinuxCommonPrivate::model()
+{
+    if(halIsAvailable) {
+#if !defined(QT_NO_DBUS)
+        QHalDeviceInterface iface("/org/freedesktop/Hal/devices/computer");
+        QString model;
+        if (iface.isValid()) {
+            model = iface.getPropertyString("system.kernel.machine");
+            if(!model.isEmpty())
+                model += " ";
+            model += iface.getPropertyString("system.chassis.type");
+            if(!model.isEmpty())
+                return model;
+        }
+#endif
+    }
+    QFile file("/proc/cpuinfo");
+    if (!file.open(QIODevice::ReadOnly)) {
+        qDebug() << "Could not open /proc/cpuinfo";
+    } else {
+        QTextStream cpuinfo(&file);
+        QString line = cpuinfo.readLine();
+        while (!line.isNull()) {
+            line = cpuinfo.readLine();
+            if(line.contains("model name")) {
+                return line.split(": ").at(1).trimmed();
+            }
+        }
+    }
+    return QString();
+}
+
+QString QSystemDeviceInfoLinuxCommonPrivate::productName()
+{
+    if(halIsAvailable) {
+#if !defined(QT_NO_DBUS)
+        QHalDeviceInterface iface("/org/freedesktop/Hal/devices/computer");
+        QString productName;
+        if (iface.isValid()) {
+            productName = iface.getPropertyString("info.product");
+            if(productName.isEmpty()) {
+                productName = iface.getPropertyString("system.product");
+                if(!productName.isEmpty())
+                    return productName;
+            } else {
+                return productName;
+            }
+        }
+#endif
+    }
+    const QDir dir("/etc");
+    if(dir.exists()) {
+        QStringList langList;
+        QFileInfoList localeList = dir.entryInfoList(QStringList() << "*release",
+                                                     QDir::Files | QDir::NoDotAndDotDot,
+                                                     QDir::Name);
+        foreach(const QFileInfo fileInfo, localeList) {
+            const QString filepath = fileInfo.filePath();
+            QFile file(filepath);
+            if (file.open(QIODevice::ReadOnly)) {
+                QTextStream prodinfo(&file);
+                QString line = prodinfo.readLine();
+                while (!line.isNull()) {
+                    if(filepath.contains("lsb.release")) {
+                        if(line.contains("DISTRIB_DESCRIPTION")) {
+                            return line.split("=").at(1).trimmed();
+                        }
+                    } else {
+                        return line;
+                    }
+                    line = prodinfo.readLine();
+                }
+            }
+        } //end foreach
+    }
+
+    QFile file("/etc/issue");
+    if (!file.open(QIODevice::ReadOnly)) {
+        qDebug() << "Could not open /proc/cpuinfo";
+    } else {
+        QTextStream prodinfo(&file);
+        QString line = prodinfo.readLine();
+        while (!line.isNull()) {
+            line = prodinfo.readLine();
+            if(!line.isEmpty()) {
+                QStringList lineList = line.split(" ");
+                for(int i = 0; i < lineList.count(); i++) {
+                    if(lineList.at(i).toFloat()) {
+                        return lineList.at(i-1) + " "+ lineList.at(i);
+                    }
+                }
+            }
+        }
+    }
+    return QString();
+}
+
+QSystemDeviceInfo::InputMethodFlags QSystemDeviceInfoLinuxCommonPrivate::inputMethodType()
+{
+    QSystemDeviceInfo::InputMethodFlags methods = 0;
+    if(halIsAvailable) {
+#if !defined(QT_NO_DBUS)
+        QHalInterface iface2;
+        if (iface2.isValid()) {
+            QStringList capList;
+            capList << QLatin1String("input.keyboard")
+                    << QLatin1String("input.keys")
+                    << QLatin1String("input.keypad")
+                    << QLatin1String("input.mouse")
+                    << QLatin1String("input.tablet")
+                    << QLatin1String("input.touchpad");
+            for(int i = 0; i < capList.count(); i++) {
+                QStringList list = iface2.findDeviceByCapability(capList.at(i));
+                if(!list.isEmpty()) {
+                    switch(i) {
+                    case 0:
+                        methods = (methods | QSystemDeviceInfo::Keyboard);
+                        break;
+                    case 1:
+                        methods = (methods | QSystemDeviceInfo::Keys);
+                        break;
+                    case 2:
+                        methods = (methods | QSystemDeviceInfo::Keypad);
+                        break;
+                    case 3:
+                        methods = (methods | QSystemDeviceInfo::Mouse);
+                        break;
+                    case 4:
+                        methods = (methods | QSystemDeviceInfo::SingleTouch);
+                        break;
+                    case 5:
+                        methods = (methods | QSystemDeviceInfo::SingleTouch);
+                        break;
+                    }
+                }
+            }
+            if(methods != 0)
+                return methods;
+        }
+#endif
+    }
+    const QString inputsPath = "/sys/class/input/";
+    const QDir inputDir(inputsPath);
+    QStringList filters;
+    filters << "event*";
+    const QStringList inputList = inputDir.entryList( filters ,QDir::Dirs, QDir::Name);
+    foreach(const QString inputFileName, inputList) {
+        QFile file(inputsPath+inputFileName+"/device/name");
+        if(!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
+            qDebug()<<"File not opened";
+        } else {
+            QString strvalue;
+            strvalue = file.readLine();
+            file.close();
+            if(strvalue.contains("keyboard",Qt::CaseInsensitive)) {
+                if( (methods & QSystemDeviceInfo::Keyboard) != QSystemDeviceInfo::Keyboard) {
+                    methods = (methods | QSystemDeviceInfo::Keyboard);
+                }
+            } else if(strvalue.contains("Mouse",Qt::CaseInsensitive)) {
+                if( (methods & QSystemDeviceInfo::Mouse) != QSystemDeviceInfo::Mouse) {
+                    methods = (methods | QSystemDeviceInfo::Mouse);
+                }
+            } else if(strvalue.contains("Button",Qt::CaseInsensitive)) {
+                if( (methods & QSystemDeviceInfo::Keys) != QSystemDeviceInfo::Keys) {
+                    methods = (methods | QSystemDeviceInfo::Keypad);
+                }
+            } else if(strvalue.contains("keypad",Qt::CaseInsensitive)) {
+                if( (methods & QSystemDeviceInfo::Keypad) != QSystemDeviceInfo::Keypad) {
+                    methods = (methods | QSystemDeviceInfo::Keys);
+                }
+            } else if(strvalue.contains("TouchScreen",Qt::CaseInsensitive)) {
+                if( (methods & QSystemDeviceInfo::SingleTouch) != QSystemDeviceInfo::SingleTouch) {
+                    methods = (methods | QSystemDeviceInfo::SingleTouch);
+                }
+            }
+        }
+    }
+    return methods;
+}
+
+int QSystemDeviceInfoLinuxCommonPrivate::batteryLevel() const
+{
+    float levelWhenFull = 0.0;
+    float level = 0.0;
+    if(halIsAvailable) {
+#if !defined(QT_NO_DBUS)
+        QHalInterface iface;
+        const QStringList list = iface.findDeviceByCapability("battery");
+        if(!list.isEmpty()) {
+            foreach(const QString dev, list) {
+                QHalDeviceInterface ifaceDevice(dev);
+                if (ifaceDevice.isValid()) {
+                    if(!ifaceDevice.getPropertyBool("battery.present")
+                        && (ifaceDevice.getPropertyString("battery.type") != "pda"
+                             || ifaceDevice.getPropertyString("battery.type") != "primary")) {
+                        return 0;
+                    } else {
+                        level = ifaceDevice.getPropertyInt("battery.charge_level.percentage");
+                        return level;
+                    }
+                }
+            }
+        }
+#endif
+    } else {
+        QFile infofile("/proc/acpi/battery/BAT0/info");
+        if (!infofile.open(QIODevice::ReadOnly)) {
+            return QSystemDeviceInfo::NoBatteryLevel;
+        } else {
+            QTextStream batinfo(&infofile);
+            QString line = batinfo.readLine();
+            while (!line.isNull()) {
+                if(line.contains("design capacity")) {
+                    levelWhenFull = line.split(" ").at(1).trimmed().toFloat();
+                    infofile.close();
+                    break;
+                }
+                line = batinfo.readLine();
+            }
+            infofile.close();
+        }
+
+        QFile statefile("/proc/acpi/battery/BAT0/state");
+        if (!statefile.open(QIODevice::ReadOnly)) {
+            return QSystemDeviceInfo::NoBatteryLevel;
+        } else {
+            QTextStream batstate(&statefile);
+            QString line = batstate.readLine();
+            while (!line.isNull()) {
+                if(line.contains("remaining capacity")) {
+                    level = line.split(" ").at(1).trimmed().toFloat();
+                    statefile.close();
+                    break;
+                }
+                line = batstate.readLine();
+            }
+        }
+        if(level != 0 && levelWhenFull != 0) {
+            level = level / levelWhenFull * 100;
+            return level;
+        }
+    }
+    return 0;
+}
+
+QSystemDeviceInfo::PowerState QSystemDeviceInfoLinuxCommonPrivate::currentPowerState()
+{
+#if !defined(QT_NO_DBUS)
+       QHalInterface iface;
+       QStringList list = iface.findDeviceByCapability("battery");
+       if(!list.isEmpty()) {
+           foreach(const QString dev, list) {
+               QHalDeviceInterface ifaceDevice(dev);
+               if (iface.isValid()) {
+                   if (ifaceDevice.getPropertyBool("battery.rechargeable.is_charging")) {
+                       return QSystemDeviceInfo::WallPowerChargingBattery;
+                   }
+               }
+           }
+       }
+
+       list = iface.findDeviceByCapability("ac_adapter");
+       if(!list.isEmpty()) {
+           foreach(const QString dev, list) {
+               QHalDeviceInterface ifaceDevice(dev);
+               if (ifaceDevice.isValid()) {
+                   if(ifaceDevice.getPropertyBool("ac_adapter.present")) {
+                       return QSystemDeviceInfo::WallPower;
+                   } else {
+                       return QSystemDeviceInfo::BatteryPower;
+                   }
+               }
+           }
+       }
+
+#else
+       QFile statefile("/proc/acpi/battery/BAT0/state");
+       if (!statefile.open(QIODevice::ReadOnly)) {
+       } else {
+           QTextStream batstate(&statefile);
+           QString line = batstate.readLine();
+           while (!line.isNull()) {
+               if(line.contains("charging state")) {
+                   if(line.split(" ").at(1).trimmed() == "discharging") {
+                       return QSystemDeviceInfo::BatteryPower;
+                   }
+                   if(line.split(" ").at(1).trimmed() == "charging") {
+                       return QSystemDeviceInfo::WallPowerChargingBattery;
+                   }
+               }
+           }
+       }
+#endif
+       return QSystemDeviceInfo::WallPower;
+}
+
+#if !defined(QT_NO_DBUS)
+ void QSystemDeviceInfoLinuxCommonPrivate::setupBluetooth()
+ {
+     QDBusConnection dbusConnection = QDBusConnection::systemBus();
+     QDBusInterface *connectionInterface;
+     connectionInterface = new QDBusInterface("org.bluez",
+                                              "/",
+                                              "org.bluez.Manager",
+                                              dbusConnection);
+     if (connectionInterface->isValid()) {
+
+         QDBusReply<  QDBusObjectPath > reply = connectionInterface->call("DefaultAdapter");
+         if (reply.isValid()) {
+             QDBusInterface *adapterInterface;
+             adapterInterface = new QDBusInterface("org.bluez",
+                                                   reply.value().path(),
+                                                   "org.bluez.Adapter",
+                                                   dbusConnection);
+             if (adapterInterface->isValid()) {
+                 if (!dbusConnection.connect("org.bluez",
+                                           reply.value().path(),
+                                            "org.bluez.Adapter",
+                                            "PropertyChanged",
+                                            this,SLOT(bluezPropertyChanged(QString, QDBusVariant)))) {
+                     qDebug() << "bluez could not connect signal";
+                 }
+             }
+         }
+     }
+ }
+
+ void QSystemDeviceInfoLinuxCommonPrivate::bluezPropertyChanged(const QString &str, QDBusVariant v)
+  {
+     if(str == "Powered") {
+          emit bluetoothStateChanged(v.variant().toBool());
+      }
+      // Pairable Name Class Discoverable
+  }
+ #endif
+
+QSystemScreenSaverLinuxCommonPrivate::QSystemScreenSaverLinuxCommonPrivate(QObject *parent) : QObject(parent)
+{
+}
+
+QSystemScreenSaverLinuxCommonPrivate::~QSystemScreenSaverLinuxCommonPrivate()
+{
+}
+
+
+#include "moc_qsysteminfo_linux_common_p.cpp"
+
+QTM_END_NAMESPACE