src/systeminfo/qsysteminfo_linux_common.cpp
changeset 0 876b1a06bc25
child 5 603d3f8b6302
equal deleted inserted replaced
-1:000000000000 0:876b1a06bc25
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
     6 **
       
     7 ** This file is part of the Qt Mobility Components.
       
     8 **
       
     9 ** $QT_BEGIN_LICENSE:LGPL$
       
    10 ** No Commercial Usage
       
    11 ** This file contains pre-release code and may not be distributed.
       
    12 ** You may use this file in accordance with the terms and conditions
       
    13 ** contained in the Technology Preview License Agreement accompanying
       
    14 ** this package.
       
    15 **
       
    16 ** GNU Lesser General Public License Usage
       
    17 ** Alternatively, this file may be used under the terms of the GNU Lesser
       
    18 ** General Public License version 2.1 as published by the Free Software
       
    19 ** Foundation and appearing in the file LICENSE.LGPL included in the
       
    20 ** packaging of this file.  Please review the following information to
       
    21 ** ensure the GNU Lesser General Public License version 2.1 requirements
       
    22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
       
    23 **
       
    24 ** In addition, as a special exception, Nokia gives you certain additional
       
    25 ** rights.  These rights are described in the Nokia Qt LGPL Exception
       
    26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
       
    27 **
       
    28 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    33 **
       
    34 **
       
    35 **
       
    36 **
       
    37 **
       
    38 ** $QT_END_LICENSE$
       
    39 **
       
    40 ****************************************************************************/
       
    41 #include "qsysteminfo_linux_common_p.h"
       
    42 #include <QTimer>
       
    43 #include <QFile>
       
    44 #include <QDir>
       
    45 
       
    46 #if !defined(QT_NO_DBUS)
       
    47 #include "qhalservice_linux_p.h"
       
    48 #include <QtDBus/QtDBus>
       
    49 #include <QtDBus/QDBusConnection>
       
    50 #include <QtDBus/QDBusError>
       
    51 #include <QtDBus/QDBusInterface>
       
    52 #include <QtDBus/QDBusMessage>
       
    53 #include <QtDBus/QDBusReply>
       
    54 #include <QtDBus/QDBusPendingCallWatcher>
       
    55 #include <QtDBus/QDBusObjectPath>
       
    56 #include <QtDBus/QDBusPendingCall>
       
    57 #endif
       
    58 
       
    59 #include <QDesktopWidget>
       
    60 
       
    61 #include <locale.h>
       
    62 #include <sys/types.h>
       
    63 #include <unistd.h>
       
    64 #include <sys/vfs.h>
       
    65 #include <mntent.h>
       
    66 #include <sys/stat.h>
       
    67 
       
    68 #ifdef Q_WS_X11
       
    69 #include <QX11Info>
       
    70 #include <X11/Xlib.h>
       
    71 #endif
       
    72 
       
    73 #ifdef BLUEZ_SUPPORTED
       
    74 # include <bluetooth/bluetooth.h>
       
    75 # include <bluetooth/bnep.h>
       
    76 #endif
       
    77 #include <sys/ioctl.h>
       
    78 #include <sys/socket.h>
       
    79 #include <unistd.h>
       
    80 
       
    81 //we cannot include iwlib.h as the platform may not have it installed
       
    82 //there we have to go via the kernel's wireless.h
       
    83 //#include <iwlib.h>
       
    84 //must be defined to be able to include kernel includes
       
    85 #ifndef __user
       
    86 #define __user
       
    87 #endif
       
    88 
       
    89 #include <linux/types.h>    /* required for wireless.h */
       
    90 #include <sys/socket.h>     /* required for wireless.h */
       
    91 #include <net/if.h>         /* required for wireless.h */
       
    92 
       
    93 /* A lot of wireless.h have kernel includes which should be protected by
       
    94    #ifdef __KERNEL__. They course include errors due to redefinitions of types.
       
    95    This prevents those kernel headers being included by Qtopia.
       
    96    */
       
    97 #ifndef _LINUX_IF_H
       
    98 #define _LINUX_IF_H
       
    99 #endif
       
   100 #ifndef _LINUX_SOCKET_H
       
   101 #define _LINUX_SOCKET_H
       
   102 #endif
       
   103 #include <linux/wireless.h>
       
   104 #include <sys/ioctl.h>
       
   105 
       
   106 static bool halAvailable()
       
   107 {
       
   108 #if !defined(QT_NO_DBUS)
       
   109     QDBusConnection dbusConnection = QDBusConnection::systemBus();
       
   110     if (dbusConnection.isConnected()) {
       
   111         QDBusConnectionInterface *dbiface = dbusConnection.interface();
       
   112         QDBusReply<bool> reply = dbiface->isServiceRegistered("org.freedesktop.Hal");
       
   113         if (reply.isValid() && reply.value()) {
       
   114             return reply.value();
       
   115         }
       
   116     }
       
   117 #endif
       
   118     return false;
       
   119 }
       
   120 
       
   121 
       
   122 bool halIsAvailable;
       
   123 
       
   124 QTM_BEGIN_NAMESPACE
       
   125 
       
   126 QSystemInfoLinuxCommonPrivate::QSystemInfoLinuxCommonPrivate(QObject *parent) : QObject(parent)
       
   127 {
       
   128     halIsAvailable = halAvailable();
       
   129     langCached = currentLanguage();
       
   130 }
       
   131 
       
   132 QSystemInfoLinuxCommonPrivate::~QSystemInfoLinuxCommonPrivate()
       
   133 {
       
   134 }
       
   135 
       
   136 void QSystemInfoLinuxCommonPrivate::startLanguagePolling()
       
   137 {
       
   138     QString checkLang = QString::fromLocal8Bit(qgetenv("LANG"));
       
   139     if(langCached.isEmpty()) {
       
   140         currentLanguage();
       
   141     }
       
   142     checkLang = checkLang.left(2);
       
   143     if(checkLang != langCached) {
       
   144         emit currentLanguageChanged(checkLang);
       
   145         langCached = checkLang;
       
   146     }
       
   147     langTimer = new QTimer(this);
       
   148     QTimer::singleShot(1000, this, SLOT(startLanguagePolling()));
       
   149 }
       
   150 
       
   151 QString QSystemInfoLinuxCommonPrivate::currentLanguage() const
       
   152 {
       
   153     QString lang;
       
   154     if(langCached.isEmpty()) {
       
   155         lang  = QLocale::system().name().left(2);
       
   156         if(lang.isEmpty() || lang == QLatin1String("C")) {
       
   157             lang = QLatin1String("en");
       
   158         }
       
   159     } else {
       
   160         lang = langCached;
       
   161     }
       
   162     return lang;
       
   163 }
       
   164 
       
   165 bool QSystemInfoLinuxCommonPrivate::hasFeatureSupported(QSystemInfo::Feature feature)
       
   166 {
       
   167      bool featureSupported = false;
       
   168      switch (feature) {
       
   169      case QSystemInfo::BluetoothFeature :
       
   170          {
       
   171              const QString sysPath = "/sys/class/bluetooth/";
       
   172              const QDir sysDir(sysPath);
       
   173              QStringList filters;
       
   174              filters << "*";
       
   175              const QStringList sysList = sysDir.entryList( filters ,QDir::Dirs | QDir::NoDotAndDotDot, QDir::Name);
       
   176              foreach(const QString dir, sysList) {
       
   177                  const QFileInfo btFile(sysPath + dir+"/address");
       
   178                  if(btFile.exists()) {
       
   179                      return true;
       
   180                  }
       
   181              }
       
   182          }
       
   183      break;
       
   184      case QSystemInfo::CameraFeature :
       
   185          {
       
   186  #if !defined(QT_NO_DBUS)
       
   187              featureSupported = hasHalUsbFeature(0x06); // image
       
   188              if(featureSupported)
       
   189                  return featureSupported;
       
   190  #endif
       
   191              featureSupported = hasSysFeature("video");
       
   192          }
       
   193          break;
       
   194      case QSystemInfo::FmradioFeature :
       
   195          {
       
   196              featureSupported = !(QDir("/sys/class/video4linux/").entryList(QStringList("radio*")).empty());
       
   197          }
       
   198          break;
       
   199      case QSystemInfo::IrFeature :
       
   200          {
       
   201  #if !defined(QT_NO_DBUS)
       
   202          featureSupported = hasHalUsbFeature(0xFE);
       
   203          if(featureSupported)
       
   204              return featureSupported;
       
   205  #endif
       
   206          featureSupported = hasSysFeature("irda"); //?
       
   207      }
       
   208          break;
       
   209      case QSystemInfo::LedFeature :
       
   210          {
       
   211              featureSupported = hasSysFeature("led"); //?
       
   212          }
       
   213          break;
       
   214      case QSystemInfo::MemcardFeature :
       
   215          {
       
   216  #if !defined(QT_NO_DBUS)
       
   217              QHalInterface iface;
       
   218              if (iface.isValid()) {
       
   219                  QHalInterface halIface;
       
   220                  const QStringList halDevices = halIface.getAllDevices();
       
   221                  foreach(const QString device, halDevices) {
       
   222                      QHalDeviceInterface ifaceDevice(device);
       
   223                      if (ifaceDevice.isValid()) {
       
   224                          if(ifaceDevice.getPropertyString("info.subsystem") == "mmc_host") {
       
   225                              return true;
       
   226                          }
       
   227                          if(ifaceDevice.getPropertyBool("storage.removable")) {
       
   228                              return true;
       
   229                          }
       
   230                      }
       
   231                  }
       
   232              }
       
   233  #endif
       
   234          }
       
   235          break;
       
   236      case QSystemInfo::UsbFeature :
       
   237          {
       
   238  #if !defined(QT_NO_DBUS)
       
   239          featureSupported = hasHalDeviceFeature("usb");
       
   240          if(featureSupported)
       
   241              return featureSupported;
       
   242  #endif
       
   243              featureSupported = hasSysFeature("usb_host");
       
   244          }
       
   245          break;
       
   246      case QSystemInfo::VibFeature :
       
   247  #if !defined(QT_NO_DBUS)
       
   248          if(hasHalDeviceFeature("vibrator") || hasHalDeviceFeature("vib")) {
       
   249              return true;
       
   250      }
       
   251 #endif
       
   252          break;
       
   253      case QSystemInfo::WlanFeature :
       
   254          {
       
   255  #if !defined(QT_NO_DBUS)
       
   256              QHalInterface iface;
       
   257              if (iface.isValid()) {
       
   258                  const QStringList list = iface.findDeviceByCapability("net.80211");
       
   259                  if(!list.isEmpty()) {
       
   260                      featureSupported = true;
       
   261                      break;
       
   262                  }
       
   263              }
       
   264  #endif
       
   265              featureSupported = hasSysFeature("80211");
       
   266          }
       
   267          break;
       
   268      case QSystemInfo::SimFeature :
       
   269          break;
       
   270      case QSystemInfo::LocationFeature :
       
   271  #if !defined(QT_NO_DBUS)
       
   272          featureSupported = hasHalDeviceFeature("gps"); //might not always be true
       
   273          if(featureSupported)
       
   274              return featureSupported;
       
   275 
       
   276  #endif
       
   277          break;
       
   278      case QSystemInfo::VideoOutFeature :
       
   279          {
       
   280              featureSupported = !(QDir("/sys/class/video4linux/").entryList(QStringList("video*")).empty());
       
   281          }
       
   282          break;
       
   283      case QSystemInfo::HapticsFeature:
       
   284          break;
       
   285      default:
       
   286          featureSupported = false;
       
   287          break;
       
   288      };
       
   289      return featureSupported;
       
   290  }
       
   291 
       
   292  #if !defined(QT_NO_DBUS)
       
   293  bool QSystemInfoLinuxCommonPrivate::hasHalDeviceFeature(const QString &param)
       
   294  {
       
   295      QHalInterface halIface;
       
   296      const QStringList halDevices = halIface.getAllDevices();
       
   297      foreach(const QString device, halDevices) {
       
   298          if(device.contains(param)) {
       
   299              return true;
       
   300          }
       
   301      }
       
   302      return false;
       
   303  }
       
   304 
       
   305  bool QSystemInfoLinuxCommonPrivate::hasHalUsbFeature(qint32 usbClass)
       
   306  {
       
   307      QHalInterface halIface;
       
   308      const QStringList halDevices = halIface.getAllDevices();
       
   309      foreach(const QString device, halDevices) {
       
   310          QHalDeviceInterface ifaceDevice(device);
       
   311          if (ifaceDevice.isValid()) {
       
   312              if(ifaceDevice.getPropertyString("info.subsystem") == "usb_device") {
       
   313                  if(ifaceDevice.getPropertyInt("usb.interface.class") == usbClass) {
       
   314                      return true;
       
   315                  }
       
   316              }
       
   317          }
       
   318      }
       
   319      return false;
       
   320  }
       
   321  #endif
       
   322 
       
   323 QString QSystemInfoLinuxCommonPrivate::version(QSystemInfo::Version type,
       
   324                                                const QString &parameter)
       
   325 {
       
   326     Q_UNUSED(parameter);
       
   327     QString errorStr = QLatin1String("Not Available");
       
   328 
       
   329     switch(type) {
       
   330         case QSystemInfo::Os :
       
   331         {
       
   332 #if !defined(QT_NO_DBUS)
       
   333             QHalDeviceInterface iface(QLatin1String("/org/freedesktop/Hal/devices/computer"));
       
   334             QString str;
       
   335             if (iface.isValid()) {
       
   336                 str = iface.getPropertyString(QLatin1String("system.kernel.version"));
       
   337                 if(!str.isEmpty()) {
       
   338                     return str;
       
   339                 }
       
   340             }
       
   341 #endif
       
   342             const QString versionPath = QLatin1String("/proc/version");
       
   343             QFile versionFile(versionPath);
       
   344             if(!versionFile.open(QIODevice::ReadOnly | QIODevice::Text)) {
       
   345                 qDebug() << "File not opened";
       
   346             } else {
       
   347                 QString  strvalue;
       
   348                 strvalue = QLatin1String(versionFile.readAll().trimmed());
       
   349                 strvalue = strvalue.split(QLatin1String(" ")).at(2);
       
   350                 versionFile.close();
       
   351                 return strvalue;
       
   352             }
       
   353             break;
       
   354         }
       
   355         case QSystemInfo::QtCore :
       
   356             return QLatin1String(qVersion());
       
   357             break;
       
   358         default:
       
   359             break;
       
   360     };
       
   361     return errorStr;
       
   362 }
       
   363 
       
   364 QString QSystemInfoLinuxCommonPrivate::currentCountryCode() const
       
   365 {
       
   366     return QLocale::system().name().mid(3,2);
       
   367 }
       
   368 
       
   369 bool QSystemInfoLinuxCommonPrivate::hasSysFeature(const QString &featureStr)
       
   370 {
       
   371     const QString sysPath = QLatin1String("/sys/class/");
       
   372     const QDir sysDir(sysPath);
       
   373     QStringList filters;
       
   374     filters << QLatin1String("*");
       
   375     const QStringList sysList = sysDir.entryList( filters ,QDir::Dirs, QDir::Name);
       
   376     foreach(const QString dir, sysList) {
       
   377         const QDir sysDir2(sysPath + dir);
       
   378         if(dir.contains(featureStr)) {
       
   379             const QStringList sysList2 = sysDir2.entryList( filters ,QDir::Dirs, QDir::Name);
       
   380             if(!sysList2.isEmpty()) {
       
   381                 return true;
       
   382             }
       
   383         }
       
   384     }
       
   385     return false;
       
   386 }
       
   387 
       
   388 QSystemNetworkInfoLinuxCommonPrivate::QSystemNetworkInfoLinuxCommonPrivate(QObject *parent) : QObject(parent)
       
   389 {
       
   390 }
       
   391 
       
   392 QSystemNetworkInfoLinuxCommonPrivate::~QSystemNetworkInfoLinuxCommonPrivate()
       
   393 {
       
   394 }
       
   395 QSystemNetworkInfo::NetworkStatus QSystemNetworkInfoLinuxCommonPrivate::networkStatus(QSystemNetworkInfo::NetworkMode mode)
       
   396 {
       
   397     switch(mode) {
       
   398     case QSystemNetworkInfo::WlanMode:
       
   399         {
       
   400             const QString baseSysDir = "/sys/class/net/";
       
   401             const QDir wDir(baseSysDir);
       
   402             const QStringList dirs = wDir.entryList(QStringList() << "*", QDir::AllDirs | QDir::NoDotAndDotDot);
       
   403             foreach(const QString dir, dirs) {
       
   404                 const QString devFile = baseSysDir + dir;
       
   405                 const QFileInfo wiFi(devFile + "/wireless");
       
   406                 const QFileInfo fi("/proc/net/route");
       
   407                 if(wiFi.exists() && fi.exists()) {
       
   408                     QFile rx(fi.absoluteFilePath());
       
   409                     if(rx.exists() && rx.open(QIODevice::ReadOnly | QIODevice::Text)) {
       
   410                         const QString result = rx.readAll();
       
   411                         if(result.contains(dir)) {
       
   412                             return QSystemNetworkInfo::Connected;
       
   413                         } else {
       
   414                             return QSystemNetworkInfo::NoNetworkAvailable;
       
   415                         }
       
   416                     }
       
   417                 }
       
   418             }
       
   419         }
       
   420         break;
       
   421     case QSystemNetworkInfo::EthernetMode:
       
   422         {
       
   423             const QString baseSysDir = "/sys/class/net/";
       
   424             const QDir eDir(baseSysDir);
       
   425             const QString dir = QSystemNetworkInfoLinuxCommonPrivate::interfaceForMode(mode).name();
       
   426 
       
   427             const QString devFile = baseSysDir + dir;
       
   428             const QFileInfo fi("/proc/net/route");
       
   429             if(fi.exists()) {
       
   430                 QFile rx(fi.absoluteFilePath());
       
   431                 if(rx.exists() && rx.open(QIODevice::ReadOnly | QIODevice::Text)) {
       
   432                     const QString result = rx.readAll();
       
   433                     if(result.contains(dir)) {
       
   434                         return QSystemNetworkInfo::Connected;
       
   435                     } else {
       
   436                         return QSystemNetworkInfo::NoNetworkAvailable;
       
   437                     }
       
   438                 }
       
   439             }
       
   440         }
       
   441         break;
       
   442         case QSystemNetworkInfo::BluetoothMode:
       
   443         {
       
   444             return getBluetoothNetStatus();
       
   445        }
       
   446         break;
       
   447     default:
       
   448         break;
       
   449     };
       
   450     return QSystemNetworkInfo::UndefinedStatus;
       
   451 }
       
   452 
       
   453 QString QSystemNetworkInfoLinuxCommonPrivate::networkName(QSystemNetworkInfo::NetworkMode mode)
       
   454 {
       
   455     QString netname = "";
       
   456 
       
   457     switch(mode) {
       
   458     case QSystemNetworkInfo::WlanMode:
       
   459         {
       
   460             if(networkStatus(mode) != QSystemNetworkInfo::Connected) {
       
   461                 return netname;
       
   462             }
       
   463 
       
   464             QString wlanInterface;
       
   465             const QString baseSysDir = "/sys/class/net/";
       
   466             const QDir wDir(baseSysDir);
       
   467             const QStringList dirs = wDir.entryList(QStringList() << "*", QDir::AllDirs | QDir::NoDotAndDotDot);
       
   468             foreach(const QString dir, dirs) {
       
   469                 const QString devFile = baseSysDir + dir;
       
   470                 const QFileInfo fi(devFile + "/wireless");
       
   471                 if(fi.exists()) {
       
   472                     wlanInterface = dir;
       
   473                 }
       
   474             }
       
   475             int sock = socket(PF_INET, SOCK_DGRAM, 0);
       
   476             if (sock > 0) {
       
   477                 const char* someRandomBuffer[IW_ESSID_MAX_SIZE + 1];
       
   478                 struct iwreq wifiExchange;
       
   479                 memset(&wifiExchange, 0, sizeof(wifiExchange));
       
   480                 memset(someRandomBuffer, 0, sizeof(someRandomBuffer));
       
   481 
       
   482                 wifiExchange.u.essid.pointer = (caddr_t) someRandomBuffer;
       
   483                 wifiExchange.u.essid.length = IW_ESSID_MAX_SIZE;
       
   484                 wifiExchange.u.essid.flags = 0;
       
   485 
       
   486                 const char* interfaceName = wlanInterface.toLatin1();
       
   487                 strncpy(wifiExchange.ifr_name, interfaceName, IFNAMSIZ);
       
   488                 wifiExchange.u.essid.length = IW_ESSID_MAX_SIZE + 1;
       
   489 
       
   490                 if (ioctl(sock, SIOCGIWESSID, &wifiExchange) == 0) {
       
   491                     const char *ssid = (const char *)wifiExchange.u.essid.pointer;
       
   492                     netname = ssid;
       
   493                 }
       
   494             } else {
       
   495                 qDebug() << "no socket";
       
   496             }
       
   497             close(sock);
       
   498         }
       
   499         break;
       
   500     case QSystemNetworkInfo::EthernetMode:
       
   501         {
       
   502             QFile resFile("/etc/resolv.conf");
       
   503             if(resFile.exists()) {
       
   504                 if(resFile.exists() && resFile.open(QIODevice::ReadOnly | QIODevice::Text)) {
       
   505                     QString line;
       
   506                     QTextStream in(&resFile);
       
   507                     do {
       
   508                         line = in.readLine();
       
   509                         if(line.contains("domain")) {
       
   510                             netname = line.section(" ",1,1); //guessing here
       
   511                         }
       
   512                 } while (!line.isNull());
       
   513                 resFile.close();
       
   514             }
       
   515         }
       
   516     }
       
   517     break;
       
   518         case QSystemNetworkInfo::BluetoothMode:
       
   519             {
       
   520     #if !defined(QT_NO_DBUS)
       
   521         netname = getBluetoothInfo("name");
       
   522 #endif
       
   523     }
       
   524         break;
       
   525     default:
       
   526         break;
       
   527     };
       
   528     return netname;
       
   529 }
       
   530 
       
   531 QString QSystemNetworkInfoLinuxCommonPrivate::macAddress(QSystemNetworkInfo::NetworkMode mode)
       
   532 {
       
   533     switch(mode) {
       
   534         case QSystemNetworkInfo::WlanMode:
       
   535         {
       
   536             QString result;
       
   537             const QString baseSysDir = "/sys/class/net/";
       
   538             const QDir wDir(baseSysDir);
       
   539             const QStringList dirs = wDir.entryList(QStringList() << "*", QDir::AllDirs | QDir::NoDotAndDotDot);
       
   540             foreach(const QString dir, dirs) {
       
   541                 const QString devFile = baseSysDir + dir;
       
   542                 const QFileInfo fi(devFile + "/wireless");
       
   543                 if(fi.exists()) {
       
   544                     QFile rx(devFile + "/address");
       
   545                     if(rx.exists() && rx.open(QIODevice::ReadOnly | QIODevice::Text)) {
       
   546                         QTextStream in(&rx);
       
   547                         in >> result;
       
   548                         rx.close();
       
   549                         return result;
       
   550                     }
       
   551                 }
       
   552             }
       
   553         }
       
   554         break;
       
   555         case QSystemNetworkInfo::EthernetMode:
       
   556         {
       
   557             QString result;
       
   558             const QString baseSysDir = "/sys/class/net/";
       
   559             const QDir eDir(baseSysDir);
       
   560             const QStringList dirs = eDir.entryList(QStringList() << "eth*", QDir::AllDirs | QDir::NoDotAndDotDot);
       
   561             foreach(const QString dir, dirs) {
       
   562                 const QString devFile = baseSysDir + dir;
       
   563                 const QFileInfo fi(devFile + "/address");
       
   564                 if(fi.exists()) {
       
   565                     QFile rx(fi.absoluteFilePath());
       
   566                     if(rx.exists() && rx.open(QIODevice::ReadOnly | QIODevice::Text)) {
       
   567                         QTextStream in(&rx);
       
   568                         in >> result;
       
   569                         rx.close();
       
   570                         return result;
       
   571                     }
       
   572                 }
       
   573             }
       
   574         }
       
   575         break;
       
   576         case QSystemNetworkInfo::BluetoothMode:
       
   577         {
       
   578 #if !defined(QT_NO_DBUS)
       
   579             return getBluetoothInfo("address");
       
   580 #endif
       
   581         }
       
   582         break;
       
   583     default:
       
   584         break;
       
   585     };
       
   586     return QString();
       
   587 }
       
   588 
       
   589 QSystemNetworkInfo::NetworkStatus QSystemNetworkInfoLinuxCommonPrivate::getBluetoothNetStatus()
       
   590 {
       
   591 #ifdef BLUEZ_SUPPORTED
       
   592     int ctl = socket(PF_BLUETOOTH,SOCK_RAW,BTPROTO_BNEP);
       
   593     if (ctl < 0) {
       
   594         qDebug() << "Cannot open bnep socket";
       
   595         return QSystemNetworkInfo::UndefinedStatus;
       
   596     }
       
   597 
       
   598     struct bnep_conninfo info[36];
       
   599     struct bnep_connlist_req req;
       
   600 
       
   601     req.ci = info;
       
   602     req.cnum = 36;
       
   603 
       
   604     if (ioctl(ctl,BNEPGETCONNLIST,&req) < 0) {
       
   605         qDebug() << "Cannot get bnep connection list.";
       
   606         return QSystemNetworkInfo::UndefinedStatus;
       
   607     }
       
   608     for (uint j = 0; j< req.cnum; j++) {
       
   609         if(info[j].state == BT_CONNECTED) {
       
   610             return QSystemNetworkInfo::Connected;
       
   611         }
       
   612     }
       
   613     close(ctl);
       
   614 #endif
       
   615 
       
   616     return QSystemNetworkInfo::UndefinedStatus;
       
   617 }
       
   618 
       
   619 qint32 QSystemNetworkInfoLinuxCommonPrivate::networkSignalStrength(QSystemNetworkInfo::NetworkMode mode)
       
   620 {
       
   621     switch(mode) {
       
   622     case QSystemNetworkInfo::WlanMode:
       
   623         {
       
   624             QString result;
       
   625             const QString baseSysDir = "/sys/class/net/";
       
   626             const QDir wDir(baseSysDir);
       
   627             const QStringList dirs = wDir.entryList(QStringList() << "*", QDir::AllDirs | QDir::NoDotAndDotDot);
       
   628             foreach(const QString dir, dirs) {
       
   629                 const QString devFile = baseSysDir + dir;
       
   630                 const QFileInfo fi(devFile + "/wireless/link");
       
   631                 if(fi.exists()) {
       
   632                     QFile rx(fi.absoluteFilePath());
       
   633                     if(rx.exists() && rx.open(QIODevice::ReadOnly | QIODevice::Text)) {
       
   634                         QTextStream in(&rx);
       
   635                         in >> result;
       
   636                         rx.close();
       
   637                         return result.toInt();
       
   638 
       
   639                     }
       
   640                 }
       
   641             }
       
   642         }
       
   643         break;
       
   644     case QSystemNetworkInfo::EthernetMode:
       
   645         {
       
   646             QString result;
       
   647             const QString baseSysDir = "/sys/class/net/";
       
   648             const QDir eDir(baseSysDir);
       
   649             const QStringList dirs = eDir.entryList(QStringList() << "eth*", QDir::AllDirs | QDir::NoDotAndDotDot);
       
   650             foreach(const QString dir, dirs) {
       
   651                 const QString devFile = baseSysDir + dir;
       
   652                 const QFileInfo fi(devFile + "/carrier");
       
   653                 if(fi.exists()) {
       
   654                     QFile rx(fi.absoluteFilePath());
       
   655                     if(rx.exists() && rx.open(QIODevice::ReadOnly | QIODevice::Text)) {
       
   656                         QTextStream in(&rx);
       
   657                         in >> result;
       
   658                         rx.close();
       
   659                         return result.toInt() * 100;
       
   660 
       
   661                     }
       
   662                 }
       
   663             }
       
   664         }
       
   665         break;
       
   666         case QSystemNetworkInfo::BluetoothMode:
       
   667         {
       
   668 #if !defined(QT_NO_DBUS)
       
   669             return getBluetoothRssi();
       
   670 #endif
       
   671         }
       
   672         break;
       
   673     default:
       
   674         break;
       
   675     };
       
   676 
       
   677     return -1;
       
   678 }
       
   679 
       
   680 QNetworkInterface QSystemNetworkInfoLinuxCommonPrivate::interfaceForMode(QSystemNetworkInfo::NetworkMode mode)
       
   681 {
       
   682 #if !defined(QT_NO_DBUS)
       
   683     switch(mode) {
       
   684     case QSystemNetworkInfo::WlanMode:
       
   685         {
       
   686             QHalInterface iface;
       
   687             if (iface.isValid()) {
       
   688                 const QStringList list = iface.findDeviceByCapability("net.80211");
       
   689                 if(!list.isEmpty()) {
       
   690                     foreach(const QString netDev, list) {
       
   691                         QHalDeviceInterface ifaceDevice(netDev);
       
   692                         const QString deviceName  = ifaceDevice.getPropertyString("net.interface");
       
   693                         if(list.count() > 1) {
       
   694                             const QString baseFIle = "/sys/class/net/" + deviceName+"/operstate";
       
   695                             QFile rx(baseFIle);
       
   696                             if(rx.exists() && rx.open(QIODevice::ReadOnly | QIODevice::Text)) {
       
   697                                 QString operatingState;
       
   698                                 QTextStream in(&rx);
       
   699                                 in >> operatingState;
       
   700                                 rx.close();
       
   701                                 if(!operatingState.contains("unknown")
       
   702                                     || !operatingState.contains("down")) {
       
   703                                     if(isDefaultInterface(deviceName))
       
   704                                         return QNetworkInterface::interfaceFromName(deviceName);
       
   705                                 }
       
   706                             }
       
   707                         } else {
       
   708                             return QNetworkInterface::interfaceFromName(deviceName);
       
   709                         }
       
   710                     }
       
   711                 }
       
   712             }
       
   713         }
       
   714         break;
       
   715     case QSystemNetworkInfo::EthernetMode:
       
   716         {
       
   717             QHalInterface iface;
       
   718             if (iface.isValid()) {
       
   719                 const QStringList list = iface.findDeviceByCapability("net.80203");
       
   720                 if(!list.isEmpty()) {
       
   721                     foreach(const QString netDev, list) {
       
   722                         QHalDeviceInterface ifaceDevice(netDev);
       
   723                         const QString deviceName  = ifaceDevice.getPropertyString("net.interface");
       
   724                         if(list.count() > 1) {
       
   725                             const QString baseFIle = "/sys/class/net/" + deviceName+"/operstate";
       
   726                             QFile rx(baseFIle);
       
   727                             if(rx.exists() && rx.open(QIODevice::ReadOnly | QIODevice::Text)) {
       
   728                                 QString operatingState;
       
   729                                 QTextStream in(&rx);
       
   730                                 in >> operatingState;
       
   731                                 rx.close();
       
   732                                 if(!operatingState.contains("unknown")
       
   733                                     || !operatingState.contains("down")) {
       
   734                                     if(isDefaultInterface(deviceName))
       
   735                                         return QNetworkInterface::interfaceFromName(deviceName);
       
   736                                 }
       
   737                             }
       
   738                         } else {
       
   739                             return QNetworkInterface::interfaceFromName(deviceName);
       
   740                         }
       
   741                     }
       
   742                 }
       
   743             }
       
   744         }
       
   745         break;
       
   746         case QSystemNetworkInfo::BluetoothMode:
       
   747         {
       
   748         }
       
   749         break;
       
   750     default:
       
   751         break;
       
   752     };
       
   753 #else
       
   754     QString result;
       
   755     const QString baseSysDir = "/sys/class/net/";
       
   756     const QDir eDir(baseSysDir);
       
   757     const QStringList dirs = eDir.entryList(QStringList() << "*", QDir::AllDirs | QDir::NoDotAndDotDot);
       
   758     foreach(const QString dir, dirs) {
       
   759         const QString devFile = baseSysDir + dir;
       
   760         const QFileInfo devfi(devFile + "/device");
       
   761         if(!devfi.exists()) {
       
   762             continue;
       
   763         }
       
   764         const QString baseFIle = "/sys/class/net/" + devFile+"/operstate";
       
   765         QFile rx(baseFIle);
       
   766         if(rx.exists() && rx.open(QIODevice::ReadOnly | QIODevice::Text)) {
       
   767             QString operatingState;
       
   768             QTextStream in(&rx);
       
   769             in >> operatingState;
       
   770             rx.close();
       
   771             if(operatingState.contains("unknown")) {
       
   772                 continue;
       
   773             }
       
   774         }
       
   775         switch(mode) {
       
   776         case QSystemNetworkInfo::WlanMode:
       
   777             {
       
   778                 const QFileInfo fi(devFile + "/wireless");
       
   779                 if(fi.exists()) {
       
   780                     return QNetworkInterface::interfaceFromName(dir);
       
   781                 }
       
   782             }
       
   783             break;
       
   784             case QSystemNetworkInfo::EthernetMode:
       
   785             {
       
   786                 const QFileInfo fi(devFile + "/wireless");
       
   787                 if(!fi.exists()) {
       
   788                     return QNetworkInterface::interfaceFromName(dir);
       
   789                 }
       
   790             }
       
   791             break;
       
   792             case QSystemNetworkInfo::BluetoothMode:
       
   793             {
       
   794 
       
   795             }
       
   796             break;
       
   797 
       
   798             default:
       
   799             break;
       
   800         };
       
   801     }
       
   802 #endif
       
   803     return QNetworkInterface();
       
   804 }
       
   805 
       
   806 #if !defined(QT_NO_DBUS)
       
   807 bool QSystemNetworkInfoLinuxCommonPrivate::isDefaultInterface(const QString &deviceName)
       
   808 {
       
   809     QFile routeFilex("/proc/net/route");
       
   810     if(routeFilex.exists() && routeFilex.open(QIODevice::ReadOnly
       
   811                                               | QIODevice::Text)) {
       
   812         QTextStream rin(&routeFilex);
       
   813         QString line = rin.readLine();
       
   814         while (!line.isNull()) {
       
   815             const QString lineSection = line.section("\t",2,2,QString::SectionSkipEmpty);
       
   816             if(lineSection != "00000000" && lineSection!="Gateway")
       
   817                 if(line.section("\t",0,0,QString::SectionSkipEmpty) == deviceName) {
       
   818                 routeFilex.close();
       
   819                 return true;
       
   820             }
       
   821             line = rin.readLine();
       
   822         }
       
   823     }
       
   824     routeFilex.close();
       
   825     return false;
       
   826 }
       
   827 
       
   828 int QSystemNetworkInfoLinuxCommonPrivate::getBluetoothRssi()
       
   829 {
       
   830     return 0;
       
   831 }
       
   832 
       
   833 QString QSystemNetworkInfoLinuxCommonPrivate::getBluetoothInfo(const QString &file)
       
   834 {
       
   835     const QString sysPath = "/sys/class/bluetooth/";
       
   836     const QDir sysDir(sysPath);
       
   837     QStringList filters;
       
   838     filters << "*";
       
   839     const QStringList sysList = sysDir.entryList( filters ,QDir::Dirs | QDir::NoDotAndDotDot, QDir::Name);
       
   840     foreach(const QString dir, sysList) {
       
   841         QFile btFile(sysPath + dir+"/"+file);
       
   842         if(btFile.exists()) {
       
   843             if (btFile.open(QIODevice::ReadOnly)) {
       
   844                 QTextStream btFileStream(&btFile);
       
   845                 QString line = btFileStream.readAll();
       
   846                 return line.simplified();
       
   847             }
       
   848         }
       
   849     }
       
   850     return QString();
       
   851 }
       
   852 #endif
       
   853 
       
   854 QSystemDisplayInfoLinuxCommonPrivate::QSystemDisplayInfoLinuxCommonPrivate(QObject *parent) : QObject(parent)
       
   855 {
       
   856     halIsAvailable = halAvailable();
       
   857 }
       
   858 
       
   859 QSystemDisplayInfoLinuxCommonPrivate::~QSystemDisplayInfoLinuxCommonPrivate()
       
   860 {
       
   861 }
       
   862 
       
   863 int QSystemDisplayInfoLinuxCommonPrivate::colorDepth(int screen)
       
   864 {
       
   865 #ifdef Q_WS_X11
       
   866     QDesktopWidget wid;
       
   867     return wid.screen(screen)->x11Info().depth();
       
   868 #else
       
   869         return QPixmap::defaultDepth();
       
   870 #endif
       
   871 }
       
   872 
       
   873 
       
   874 int QSystemDisplayInfoLinuxCommonPrivate::displayBrightness(int screen)
       
   875 {
       
   876     Q_UNUSED(screen);
       
   877     if(halIsAvailable) {
       
   878 #if !defined(QT_NO_DBUS)
       
   879         QHalInterface iface;
       
   880         if (iface.isValid()) {
       
   881             const QStringList list = iface.findDeviceByCapability("laptop_panel");
       
   882             if(!list.isEmpty()) {
       
   883                 foreach(const QString lapDev, list) {
       
   884                     QHalDeviceInterface ifaceDevice(lapDev);
       
   885                     QHalDeviceLaptopPanelInterface lapIface(lapDev);
       
   886                     const float numLevels = ifaceDevice.getPropertyInt("laptop_panel.num_levels") - 1;
       
   887                     const float curLevel = lapIface.getBrightness();
       
   888                     return curLevel / numLevels * 100;
       
   889                 }
       
   890             }
       
   891         }
       
   892 #endif
       
   893     } else {
       
   894         const QString backlightPath = "/proc/acpi/video/";
       
   895         const QDir videoDir(backlightPath);
       
   896         QStringList filters;
       
   897         filters << "*";
       
   898         const QStringList brightnessList = videoDir.entryList(filters,
       
   899                                                         QDir::Dirs
       
   900                                                         | QDir::NoDotAndDotDot,
       
   901                                                         QDir::Name);
       
   902         foreach(const QString brightnessFileName, brightnessList) {
       
   903             float numLevels = 0.0;
       
   904             float curLevel = 0.0;
       
   905             QFile curBrightnessFile(backlightPath+brightnessFileName+"/LCD/brightness");
       
   906             if(!curBrightnessFile.open(QIODevice::ReadOnly | QIODevice::Text)) {
       
   907                 qDebug()<<"File not opened";
       
   908             } else {
       
   909                 const QString strvalue = curBrightnessFile.readAll().trimmed();
       
   910                 if(strvalue.contains("levels")) {
       
   911                     QStringList list = strvalue.split(" ");
       
   912                     numLevels = list.at(2).toFloat();
       
   913                 }
       
   914                 if(strvalue.contains("current")) {
       
   915                     QStringList list = strvalue.split(": ");
       
   916                     curLevel = list.at(list.count()-1).toFloat();
       
   917                 }
       
   918                 curBrightnessFile.close();
       
   919                 return curLevel / numLevels * 100;
       
   920             }
       
   921         }
       
   922     }
       
   923 #if 0
       
   924     QString backlightPath = "/sys/devices/virtual/backlight/";
       
   925     QDir videoDir(backlightPath);
       
   926     QStringList filters;
       
   927     filters << "*";
       
   928     QStringList brightnessList = videoDir.entryList(filters,
       
   929                                                      QDir::Dirs
       
   930                                                      | QDir::NoDotAndDotDot,
       
   931                                                      QDir::Name);
       
   932     foreach(QString brightnessFileName, brightnessList) {
       
   933         float numLevels = 0.0;
       
   934         float curLevel = 0.0;
       
   935         QFile curBrightnessFile(backlightPath+brightnessFileName+"/brightness");
       
   936         if(!curBrightnessFile.open(QIODevice::ReadOnly | QIODevice::Text)) {
       
   937             qDebug()<<"File not opened";
       
   938         } else {
       
   939             QString strvalue;
       
   940             strvalue = curBrightnessFile.readLine().trimmed();
       
   941             curBrightnessFile.close();
       
   942             curLevel = strvalue.toFloat();
       
   943 
       
   944             QFile maxBrightnessFile(backlightPath+brightnessFileName+"/max_brightness");
       
   945             if(!maxBrightnessFile.open(QIODevice::ReadOnly | QIODevice::Text)) {
       
   946                 qDebug()<<"File not opened";
       
   947             } else {
       
   948                 QString strvalue;
       
   949                 strvalue = maxBrightnessFile.readLine().trimmed();
       
   950                 maxBrightnessFile.close();
       
   951                 numLevels = strvalue.toFloat();
       
   952             }
       
   953             return curLevel / numLevels * 100;
       
   954         }
       
   955     }
       
   956 #endif
       
   957     return -1;
       
   958 }
       
   959 
       
   960 QSystemStorageInfoLinuxCommonPrivate::QSystemStorageInfoLinuxCommonPrivate(QObject *parent)
       
   961     : QObject(parent)
       
   962 {
       
   963     halIsAvailable = halAvailable();
       
   964 }
       
   965 
       
   966 QSystemStorageInfoLinuxCommonPrivate::~QSystemStorageInfoLinuxCommonPrivate()
       
   967 {
       
   968 }
       
   969 
       
   970 qint64 QSystemStorageInfoLinuxCommonPrivate::availableDiskSpace(const QString &driveVolume)
       
   971 {
       
   972     if(driveVolume.left(2) == "//") {
       
   973         return 0;
       
   974     }
       
   975     mountEntries();
       
   976     struct statfs fs;
       
   977     if(statfs(driveVolume.toLatin1(), &fs ) == 0 ) {
       
   978                 long blockSize = fs.f_bsize;
       
   979                 long availBlocks = fs.f_bavail;
       
   980                 return (double)availBlocks * blockSize;
       
   981             }
       
   982     return 0;
       
   983 }
       
   984 
       
   985 qint64 QSystemStorageInfoLinuxCommonPrivate::totalDiskSpace(const QString &driveVolume)
       
   986 {
       
   987     if(driveVolume.left(2) == "//") {
       
   988         return 0;
       
   989     }
       
   990     mountEntries();
       
   991     struct statfs fs;
       
   992     if(statfs(driveVolume.toLatin1(), &fs ) == 0 ) {
       
   993         const long blockSize = fs.f_bsize;
       
   994         const long totalBlocks = fs.f_blocks;
       
   995         return (double)totalBlocks * blockSize;
       
   996     }
       
   997     return 0;
       
   998 }
       
   999 
       
  1000 QSystemStorageInfo::DriveType QSystemStorageInfoLinuxCommonPrivate::typeForDrive(const QString &driveVolume)
       
  1001 {
       
  1002     if(halIsAvailable) {
       
  1003 #if !defined(QT_NO_DBUS)
       
  1004         QStringList mountedVol;
       
  1005         QHalInterface iface;
       
  1006         const QStringList list = iface.findDeviceByCapability("volume");
       
  1007         if(!list.isEmpty()) {
       
  1008             foreach(const QString vol, list) {
       
  1009                 QHalDeviceInterface ifaceDevice(vol);
       
  1010                 if(mountEntriesMap.value(driveVolume) == ifaceDevice.getPropertyString("block.device")) {
       
  1011                     QHalDeviceInterface ifaceDeviceParent(ifaceDevice.getPropertyString("info.parent"), this);
       
  1012 
       
  1013                     if(ifaceDeviceParent.getPropertyBool("storage.removable")
       
  1014                         ||  ifaceDeviceParent.getPropertyString("storage.drive_type") != "disk") {
       
  1015                         return QSystemStorageInfo::RemovableDrive;
       
  1016                         break;
       
  1017                     } else {
       
  1018                          return QSystemStorageInfo::InternalDrive;
       
  1019                     }
       
  1020                 }
       
  1021             }
       
  1022         }
       
  1023 #endif
       
  1024     } else {
       
  1025         //no hal need to manually read sys file for block device
       
  1026         QString dmFile;
       
  1027 
       
  1028         if(mountEntriesMap.value(driveVolume).contains("mapper")) {
       
  1029             struct stat stat_buf;
       
  1030             stat( mountEntriesMap.value(driveVolume).toLatin1(), &stat_buf);
       
  1031 
       
  1032             dmFile = QString("/sys/block/dm-%1/removable").arg(stat_buf.st_rdev & 0377);
       
  1033 
       
  1034         } else {
       
  1035 
       
  1036             dmFile = mountEntriesMap.value(driveVolume).section("/",2,3);
       
  1037             if (dmFile.left(3) == "mmc") { //assume this dev is removable sd/mmc card.
       
  1038                 return QSystemStorageInfo::RemovableDrive;
       
  1039             }
       
  1040 
       
  1041             if(dmFile.length() > 3) { //if device has number, we need the 'parent' device
       
  1042                 dmFile.chop(1);
       
  1043                 if (dmFile.right(1) == "p") //get rid of partition number
       
  1044                     dmFile.chop(1);
       
  1045             }
       
  1046             dmFile = "/sys/block/"+dmFile+"/removable";
       
  1047         }
       
  1048 
       
  1049         QFile file(dmFile);
       
  1050         if (!file.open(QIODevice::ReadOnly)) {
       
  1051             qDebug() << "Could not open sys file";
       
  1052         } else {
       
  1053             QTextStream sysinfo(&file);
       
  1054             QString line = sysinfo.readAll();
       
  1055             if(line.contains("1")) {
       
  1056                 return QSystemStorageInfo::RemovableDrive;
       
  1057             }
       
  1058         }
       
  1059     }
       
  1060     if(driveVolume.left(2) == "//") {
       
  1061         return QSystemStorageInfo::RemoteDrive;
       
  1062     }
       
  1063     return QSystemStorageInfo::InternalDrive;
       
  1064 }
       
  1065 
       
  1066 QStringList QSystemStorageInfoLinuxCommonPrivate::logicalDrives()
       
  1067 {
       
  1068     mountEntries();
       
  1069     return mountEntriesMap.keys();
       
  1070 }
       
  1071 
       
  1072 void QSystemStorageInfoLinuxCommonPrivate::mountEntries()
       
  1073 {
       
  1074     mountEntriesMap.clear();
       
  1075     FILE *mntfp = setmntent( _PATH_MOUNTED, "r" );
       
  1076     mntent *me = getmntent(mntfp);
       
  1077     bool ok;
       
  1078     while(me != NULL) {
       
  1079         struct statfs fs;
       
  1080         ok = false;
       
  1081         if(strcmp(me->mnt_type, "cifs") != 0) { //smb has probs with statfs
       
  1082             if(statfs(me->mnt_dir, &fs ) ==0 ) {
       
  1083                 QString num;
       
  1084                 // weed out a few types
       
  1085                 if ( fs.f_type != 0x01021994 //tmpfs
       
  1086                      && fs.f_type != 0x9fa0 //procfs
       
  1087                      && fs.f_type != 0x1cd1 //
       
  1088                      && fs.f_type != 0x62656572
       
  1089                      && (unsigned)fs.f_type != 0xabababab // ???
       
  1090                      && fs.f_type != 0x52654973
       
  1091                      && fs.f_type != 0x42494e4d
       
  1092                      && fs.f_type != 0x64626720
       
  1093                      && fs.f_type != 0x73636673 //securityfs
       
  1094                      && fs.f_type != 0x65735543 //fusectl
       
  1095                      && fs.f_type != 0x65735546 // fuse.gvfs-fuse-daemon
       
  1096 
       
  1097                      ) {
       
  1098                     ok = true;
       
  1099                 }
       
  1100             }
       
  1101         } else {
       
  1102             ok = true;
       
  1103         }
       
  1104         if(ok && !mountEntriesMap.keys().contains(me->mnt_fsname)) {
       
  1105             mountEntriesMap[me->mnt_dir] = me->mnt_fsname;
       
  1106         }
       
  1107 
       
  1108         me = getmntent(mntfp);
       
  1109     }
       
  1110     endmntent(mntfp);
       
  1111 }
       
  1112 
       
  1113 
       
  1114 
       
  1115 QSystemDeviceInfoLinuxCommonPrivate::QSystemDeviceInfoLinuxCommonPrivate(QObject *parent) : QObject(parent)
       
  1116 {
       
  1117     halIsAvailable = halAvailable();
       
  1118     setConnection();
       
  1119  #if !defined(QT_NO_DBUS)
       
  1120     setupBluetooth();
       
  1121 #endif
       
  1122 }
       
  1123 
       
  1124 QSystemDeviceInfoLinuxCommonPrivate::~QSystemDeviceInfoLinuxCommonPrivate()
       
  1125 {
       
  1126 }
       
  1127 
       
  1128 
       
  1129 void QSystemDeviceInfoLinuxCommonPrivate::setConnection()
       
  1130 {
       
  1131     if(halIsAvailable) {
       
  1132 #if !defined(QT_NO_DBUS)
       
  1133         QHalInterface iface;
       
  1134 
       
  1135         QStringList list = iface.findDeviceByCapability("battery");
       
  1136         if(!list.isEmpty()) {
       
  1137             foreach(const QString dev, list) {
       
  1138                 halIfaceDevice = new QHalDeviceInterface(dev);
       
  1139                 if (halIfaceDevice->isValid()) {
       
  1140                     const QString batType = halIfaceDevice->getPropertyString("battery.type");
       
  1141                     if(batType == "primary" || batType == "pda") {
       
  1142                         if(halIfaceDevice->setConnections() ) {
       
  1143                             if(!connect(halIfaceDevice,SIGNAL(propertyModified(int, QVariantList)),
       
  1144                                         this,SLOT(halChanged(int,QVariantList)))) {
       
  1145                                 qDebug() << "connection malfunction";
       
  1146                             }
       
  1147                         }
       
  1148                         break;
       
  1149                     }
       
  1150                 }
       
  1151             }
       
  1152         }
       
  1153 
       
  1154         list = iface.findDeviceByCapability("ac_adapter");
       
  1155         if(!list.isEmpty()) {
       
  1156             foreach(const QString dev, list) {
       
  1157                 halIfaceDevice = new QHalDeviceInterface(dev);
       
  1158                 if (halIfaceDevice->isValid()) {
       
  1159                     if(halIfaceDevice->setConnections() ) {
       
  1160                         if(!connect(halIfaceDevice,SIGNAL(propertyModified(int, QVariantList)),
       
  1161                                     this,SLOT(halChanged(int,QVariantList)))) {
       
  1162                             qDebug() << "connection malfunction";
       
  1163                         }
       
  1164                     }
       
  1165                     break;
       
  1166                 }
       
  1167             }
       
  1168         }
       
  1169 
       
  1170         list = iface.findDeviceByCapability("battery");
       
  1171         if(!list.isEmpty()) {
       
  1172             foreach(const QString dev, list) {
       
  1173                 halIfaceDevice = new QHalDeviceInterface(dev);
       
  1174                 if (halIfaceDevice->isValid()) {
       
  1175                     if(halIfaceDevice->setConnections()) {
       
  1176                         if(!connect(halIfaceDevice,SIGNAL(propertyModified(int, QVariantList)),
       
  1177                                     this,SLOT(halChanged(int,QVariantList)))) {
       
  1178                             qDebug() << "connection malfunction";
       
  1179                         }
       
  1180                     }
       
  1181                     break;
       
  1182                 }
       
  1183             }
       
  1184         }
       
  1185 
       
  1186 #endif
       
  1187     }
       
  1188 }
       
  1189 
       
  1190 
       
  1191 #if !defined(QT_NO_DBUS)
       
  1192 void QSystemDeviceInfoLinuxCommonPrivate::halChanged(int,QVariantList map)
       
  1193 {
       
  1194     for(int i=0; i < map.count(); i++) {
       
  1195        if(map.at(i).toString() == "battery.charge_level.percentage") {
       
  1196             const int level = batteryLevel();
       
  1197             emit batteryLevelChanged(level);
       
  1198             if(level < 4) {
       
  1199                 emit batteryStatusChanged(QSystemDeviceInfo::BatteryCritical);
       
  1200             } else if(level < 11) {
       
  1201                 emit batteryStatusChanged(QSystemDeviceInfo::BatteryVeryLow);
       
  1202             } else if(level < 41) {
       
  1203                 emit batteryStatusChanged(QSystemDeviceInfo::BatteryLow);
       
  1204             } else if(level > 40) {
       
  1205                 emit batteryStatusChanged(QSystemDeviceInfo::BatteryNormal);
       
  1206             }
       
  1207             else {
       
  1208                 emit batteryStatusChanged(QSystemDeviceInfo::NoBatteryLevel);
       
  1209             }
       
  1210         }
       
  1211         if((map.at(i).toString() == "ac_adapter.present")
       
  1212         || (map.at(i).toString() == "battery.rechargeable.is_charging")) {
       
  1213             QSystemDeviceInfo::PowerState state = currentPowerState();
       
  1214             emit powerStateChanged(state);
       
  1215        }} //end map
       
  1216 }
       
  1217 #endif
       
  1218 
       
  1219 QString QSystemDeviceInfoLinuxCommonPrivate::manufacturer()
       
  1220 {
       
  1221     if(halIsAvailable) {
       
  1222 #if !defined(QT_NO_DBUS)
       
  1223         QHalDeviceInterface iface("/org/freedesktop/Hal/devices/computer");
       
  1224         QString manu;
       
  1225         if (iface.isValid()) {
       
  1226             manu = iface.getPropertyString("system.firmware.vendor");
       
  1227             if(manu.isEmpty()) {
       
  1228                 manu = iface.getPropertyString("system.hardware.vendor");
       
  1229                 if(!manu.isEmpty()) {
       
  1230                     return manu;
       
  1231                 }
       
  1232             }
       
  1233         }
       
  1234 #endif
       
  1235     }
       
  1236     QFile vendorId("/sys/devices/virtual/dmi/id/board_vendor");
       
  1237     if (vendorId.open(QIODevice::ReadOnly)) {
       
  1238         QTextStream cpuinfo(&vendorId);
       
  1239         return cpuinfo.readLine().trimmed();
       
  1240     } else {
       
  1241         QFile file("/proc/cpuinfo");
       
  1242         if (!file.open(QIODevice::ReadOnly)) {
       
  1243             qDebug() << "Could not open /proc/cpuinfo";
       
  1244         } else {
       
  1245             QTextStream cpuinfo(&file);
       
  1246             QString line = cpuinfo.readLine();
       
  1247             while (!line.isNull()) {
       
  1248                 line = cpuinfo.readLine();
       
  1249                 if(line.contains("vendor_id")) {
       
  1250                     return line.split(": ").at(1).trimmed();
       
  1251                 }
       
  1252             }
       
  1253         }
       
  1254     }
       
  1255     return QString();
       
  1256 }
       
  1257 
       
  1258 QString QSystemDeviceInfoLinuxCommonPrivate::model()
       
  1259 {
       
  1260     if(halIsAvailable) {
       
  1261 #if !defined(QT_NO_DBUS)
       
  1262         QHalDeviceInterface iface("/org/freedesktop/Hal/devices/computer");
       
  1263         QString model;
       
  1264         if (iface.isValid()) {
       
  1265             model = iface.getPropertyString("system.kernel.machine");
       
  1266             if(!model.isEmpty())
       
  1267                 model += " ";
       
  1268             model += iface.getPropertyString("system.chassis.type");
       
  1269             if(!model.isEmpty())
       
  1270                 return model;
       
  1271         }
       
  1272 #endif
       
  1273     }
       
  1274     QFile file("/proc/cpuinfo");
       
  1275     if (!file.open(QIODevice::ReadOnly)) {
       
  1276         qDebug() << "Could not open /proc/cpuinfo";
       
  1277     } else {
       
  1278         QTextStream cpuinfo(&file);
       
  1279         QString line = cpuinfo.readLine();
       
  1280         while (!line.isNull()) {
       
  1281             line = cpuinfo.readLine();
       
  1282             if(line.contains("model name")) {
       
  1283                 return line.split(": ").at(1).trimmed();
       
  1284             }
       
  1285         }
       
  1286     }
       
  1287     return QString();
       
  1288 }
       
  1289 
       
  1290 QString QSystemDeviceInfoLinuxCommonPrivate::productName()
       
  1291 {
       
  1292     if(halIsAvailable) {
       
  1293 #if !defined(QT_NO_DBUS)
       
  1294         QHalDeviceInterface iface("/org/freedesktop/Hal/devices/computer");
       
  1295         QString productName;
       
  1296         if (iface.isValid()) {
       
  1297             productName = iface.getPropertyString("info.product");
       
  1298             if(productName.isEmpty()) {
       
  1299                 productName = iface.getPropertyString("system.product");
       
  1300                 if(!productName.isEmpty())
       
  1301                     return productName;
       
  1302             } else {
       
  1303                 return productName;
       
  1304             }
       
  1305         }
       
  1306 #endif
       
  1307     }
       
  1308     const QDir dir("/etc");
       
  1309     if(dir.exists()) {
       
  1310         QStringList langList;
       
  1311         QFileInfoList localeList = dir.entryInfoList(QStringList() << "*release",
       
  1312                                                      QDir::Files | QDir::NoDotAndDotDot,
       
  1313                                                      QDir::Name);
       
  1314         foreach(const QFileInfo fileInfo, localeList) {
       
  1315             const QString filepath = fileInfo.filePath();
       
  1316             QFile file(filepath);
       
  1317             if (file.open(QIODevice::ReadOnly)) {
       
  1318                 QTextStream prodinfo(&file);
       
  1319                 QString line = prodinfo.readLine();
       
  1320                 while (!line.isNull()) {
       
  1321                     if(filepath.contains("lsb.release")) {
       
  1322                         if(line.contains("DISTRIB_DESCRIPTION")) {
       
  1323                             return line.split("=").at(1).trimmed();
       
  1324                         }
       
  1325                     } else {
       
  1326                         return line;
       
  1327                     }
       
  1328                     line = prodinfo.readLine();
       
  1329                 }
       
  1330             }
       
  1331         } //end foreach
       
  1332     }
       
  1333 
       
  1334     QFile file("/etc/issue");
       
  1335     if (!file.open(QIODevice::ReadOnly)) {
       
  1336         qDebug() << "Could not open /proc/cpuinfo";
       
  1337     } else {
       
  1338         QTextStream prodinfo(&file);
       
  1339         QString line = prodinfo.readLine();
       
  1340         while (!line.isNull()) {
       
  1341             line = prodinfo.readLine();
       
  1342             if(!line.isEmpty()) {
       
  1343                 QStringList lineList = line.split(" ");
       
  1344                 for(int i = 0; i < lineList.count(); i++) {
       
  1345                     if(lineList.at(i).toFloat()) {
       
  1346                         return lineList.at(i-1) + " "+ lineList.at(i);
       
  1347                     }
       
  1348                 }
       
  1349             }
       
  1350         }
       
  1351     }
       
  1352     return QString();
       
  1353 }
       
  1354 
       
  1355 QSystemDeviceInfo::InputMethodFlags QSystemDeviceInfoLinuxCommonPrivate::inputMethodType()
       
  1356 {
       
  1357     QSystemDeviceInfo::InputMethodFlags methods = 0;
       
  1358     if(halIsAvailable) {
       
  1359 #if !defined(QT_NO_DBUS)
       
  1360         QHalInterface iface2;
       
  1361         if (iface2.isValid()) {
       
  1362             QStringList capList;
       
  1363             capList << QLatin1String("input.keyboard")
       
  1364                     << QLatin1String("input.keys")
       
  1365                     << QLatin1String("input.keypad")
       
  1366                     << QLatin1String("input.mouse")
       
  1367                     << QLatin1String("input.tablet")
       
  1368                     << QLatin1String("input.touchpad");
       
  1369             for(int i = 0; i < capList.count(); i++) {
       
  1370                 QStringList list = iface2.findDeviceByCapability(capList.at(i));
       
  1371                 if(!list.isEmpty()) {
       
  1372                     switch(i) {
       
  1373                     case 0:
       
  1374                         methods = (methods | QSystemDeviceInfo::Keyboard);
       
  1375                         break;
       
  1376                     case 1:
       
  1377                         methods = (methods | QSystemDeviceInfo::Keys);
       
  1378                         break;
       
  1379                     case 2:
       
  1380                         methods = (methods | QSystemDeviceInfo::Keypad);
       
  1381                         break;
       
  1382                     case 3:
       
  1383                         methods = (methods | QSystemDeviceInfo::Mouse);
       
  1384                         break;
       
  1385                     case 4:
       
  1386                         methods = (methods | QSystemDeviceInfo::SingleTouch);
       
  1387                         break;
       
  1388                     case 5:
       
  1389                         methods = (methods | QSystemDeviceInfo::SingleTouch);
       
  1390                         break;
       
  1391                     }
       
  1392                 }
       
  1393             }
       
  1394             if(methods != 0)
       
  1395                 return methods;
       
  1396         }
       
  1397 #endif
       
  1398     }
       
  1399     const QString inputsPath = "/sys/class/input/";
       
  1400     const QDir inputDir(inputsPath);
       
  1401     QStringList filters;
       
  1402     filters << "event*";
       
  1403     const QStringList inputList = inputDir.entryList( filters ,QDir::Dirs, QDir::Name);
       
  1404     foreach(const QString inputFileName, inputList) {
       
  1405         QFile file(inputsPath+inputFileName+"/device/name");
       
  1406         if(!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
       
  1407             qDebug()<<"File not opened";
       
  1408         } else {
       
  1409             QString strvalue;
       
  1410             strvalue = file.readLine();
       
  1411             file.close();
       
  1412             if(strvalue.contains("keyboard",Qt::CaseInsensitive)) {
       
  1413                 if( (methods & QSystemDeviceInfo::Keyboard) != QSystemDeviceInfo::Keyboard) {
       
  1414                     methods = (methods | QSystemDeviceInfo::Keyboard);
       
  1415                 }
       
  1416             } else if(strvalue.contains("Mouse",Qt::CaseInsensitive)) {
       
  1417                 if( (methods & QSystemDeviceInfo::Mouse) != QSystemDeviceInfo::Mouse) {
       
  1418                     methods = (methods | QSystemDeviceInfo::Mouse);
       
  1419                 }
       
  1420             } else if(strvalue.contains("Button",Qt::CaseInsensitive)) {
       
  1421                 if( (methods & QSystemDeviceInfo::Keys) != QSystemDeviceInfo::Keys) {
       
  1422                     methods = (methods | QSystemDeviceInfo::Keypad);
       
  1423                 }
       
  1424             } else if(strvalue.contains("keypad",Qt::CaseInsensitive)) {
       
  1425                 if( (methods & QSystemDeviceInfo::Keypad) != QSystemDeviceInfo::Keypad) {
       
  1426                     methods = (methods | QSystemDeviceInfo::Keys);
       
  1427                 }
       
  1428             } else if(strvalue.contains("TouchScreen",Qt::CaseInsensitive)) {
       
  1429                 if( (methods & QSystemDeviceInfo::SingleTouch) != QSystemDeviceInfo::SingleTouch) {
       
  1430                     methods = (methods | QSystemDeviceInfo::SingleTouch);
       
  1431                 }
       
  1432             }
       
  1433         }
       
  1434     }
       
  1435     return methods;
       
  1436 }
       
  1437 
       
  1438 int QSystemDeviceInfoLinuxCommonPrivate::batteryLevel() const
       
  1439 {
       
  1440     float levelWhenFull = 0.0;
       
  1441     float level = 0.0;
       
  1442     if(halIsAvailable) {
       
  1443 #if !defined(QT_NO_DBUS)
       
  1444         QHalInterface iface;
       
  1445         const QStringList list = iface.findDeviceByCapability("battery");
       
  1446         if(!list.isEmpty()) {
       
  1447             foreach(const QString dev, list) {
       
  1448                 QHalDeviceInterface ifaceDevice(dev);
       
  1449                 if (ifaceDevice.isValid()) {
       
  1450                     if(!ifaceDevice.getPropertyBool("battery.present")
       
  1451                         && (ifaceDevice.getPropertyString("battery.type") != "pda"
       
  1452                              || ifaceDevice.getPropertyString("battery.type") != "primary")) {
       
  1453                         return 0;
       
  1454                     } else {
       
  1455                         level = ifaceDevice.getPropertyInt("battery.charge_level.percentage");
       
  1456                         return level;
       
  1457                     }
       
  1458                 }
       
  1459             }
       
  1460         }
       
  1461 #endif
       
  1462     } else {
       
  1463         QFile infofile("/proc/acpi/battery/BAT0/info");
       
  1464         if (!infofile.open(QIODevice::ReadOnly)) {
       
  1465             return QSystemDeviceInfo::NoBatteryLevel;
       
  1466         } else {
       
  1467             QTextStream batinfo(&infofile);
       
  1468             QString line = batinfo.readLine();
       
  1469             while (!line.isNull()) {
       
  1470                 if(line.contains("design capacity")) {
       
  1471                     levelWhenFull = line.split(" ").at(1).trimmed().toFloat();
       
  1472                     infofile.close();
       
  1473                     break;
       
  1474                 }
       
  1475                 line = batinfo.readLine();
       
  1476             }
       
  1477             infofile.close();
       
  1478         }
       
  1479 
       
  1480         QFile statefile("/proc/acpi/battery/BAT0/state");
       
  1481         if (!statefile.open(QIODevice::ReadOnly)) {
       
  1482             return QSystemDeviceInfo::NoBatteryLevel;
       
  1483         } else {
       
  1484             QTextStream batstate(&statefile);
       
  1485             QString line = batstate.readLine();
       
  1486             while (!line.isNull()) {
       
  1487                 if(line.contains("remaining capacity")) {
       
  1488                     level = line.split(" ").at(1).trimmed().toFloat();
       
  1489                     statefile.close();
       
  1490                     break;
       
  1491                 }
       
  1492                 line = batstate.readLine();
       
  1493             }
       
  1494         }
       
  1495         if(level != 0 && levelWhenFull != 0) {
       
  1496             level = level / levelWhenFull * 100;
       
  1497             return level;
       
  1498         }
       
  1499     }
       
  1500     return 0;
       
  1501 }
       
  1502 
       
  1503 QSystemDeviceInfo::PowerState QSystemDeviceInfoLinuxCommonPrivate::currentPowerState()
       
  1504 {
       
  1505 #if !defined(QT_NO_DBUS)
       
  1506        QHalInterface iface;
       
  1507        QStringList list = iface.findDeviceByCapability("battery");
       
  1508        if(!list.isEmpty()) {
       
  1509            foreach(const QString dev, list) {
       
  1510                QHalDeviceInterface ifaceDevice(dev);
       
  1511                if (iface.isValid()) {
       
  1512                    if (ifaceDevice.getPropertyBool("battery.rechargeable.is_charging")) {
       
  1513                        return QSystemDeviceInfo::WallPowerChargingBattery;
       
  1514                    }
       
  1515                }
       
  1516            }
       
  1517        }
       
  1518 
       
  1519        list = iface.findDeviceByCapability("ac_adapter");
       
  1520        if(!list.isEmpty()) {
       
  1521            foreach(const QString dev, list) {
       
  1522                QHalDeviceInterface ifaceDevice(dev);
       
  1523                if (ifaceDevice.isValid()) {
       
  1524                    if(ifaceDevice.getPropertyBool("ac_adapter.present")) {
       
  1525                        return QSystemDeviceInfo::WallPower;
       
  1526                    } else {
       
  1527                        return QSystemDeviceInfo::BatteryPower;
       
  1528                    }
       
  1529                }
       
  1530            }
       
  1531        }
       
  1532 
       
  1533 #else
       
  1534        QFile statefile("/proc/acpi/battery/BAT0/state");
       
  1535        if (!statefile.open(QIODevice::ReadOnly)) {
       
  1536        } else {
       
  1537            QTextStream batstate(&statefile);
       
  1538            QString line = batstate.readLine();
       
  1539            while (!line.isNull()) {
       
  1540                if(line.contains("charging state")) {
       
  1541                    if(line.split(" ").at(1).trimmed() == "discharging") {
       
  1542                        return QSystemDeviceInfo::BatteryPower;
       
  1543                    }
       
  1544                    if(line.split(" ").at(1).trimmed() == "charging") {
       
  1545                        return QSystemDeviceInfo::WallPowerChargingBattery;
       
  1546                    }
       
  1547                }
       
  1548            }
       
  1549        }
       
  1550 #endif
       
  1551        return QSystemDeviceInfo::WallPower;
       
  1552 }
       
  1553 
       
  1554 #if !defined(QT_NO_DBUS)
       
  1555  void QSystemDeviceInfoLinuxCommonPrivate::setupBluetooth()
       
  1556  {
       
  1557      QDBusConnection dbusConnection = QDBusConnection::systemBus();
       
  1558      QDBusInterface *connectionInterface;
       
  1559      connectionInterface = new QDBusInterface("org.bluez",
       
  1560                                               "/",
       
  1561                                               "org.bluez.Manager",
       
  1562                                               dbusConnection);
       
  1563      if (connectionInterface->isValid()) {
       
  1564 
       
  1565          QDBusReply<  QDBusObjectPath > reply = connectionInterface->call("DefaultAdapter");
       
  1566          if (reply.isValid()) {
       
  1567              QDBusInterface *adapterInterface;
       
  1568              adapterInterface = new QDBusInterface("org.bluez",
       
  1569                                                    reply.value().path(),
       
  1570                                                    "org.bluez.Adapter",
       
  1571                                                    dbusConnection);
       
  1572              if (adapterInterface->isValid()) {
       
  1573                  if (!dbusConnection.connect("org.bluez",
       
  1574                                            reply.value().path(),
       
  1575                                             "org.bluez.Adapter",
       
  1576                                             "PropertyChanged",
       
  1577                                             this,SLOT(bluezPropertyChanged(QString, QDBusVariant)))) {
       
  1578                      qDebug() << "bluez could not connect signal";
       
  1579                  }
       
  1580              }
       
  1581          }
       
  1582      }
       
  1583  }
       
  1584 
       
  1585  void QSystemDeviceInfoLinuxCommonPrivate::bluezPropertyChanged(const QString &str, QDBusVariant v)
       
  1586   {
       
  1587      if(str == "Powered") {
       
  1588           emit bluetoothStateChanged(v.variant().toBool());
       
  1589       }
       
  1590       // Pairable Name Class Discoverable
       
  1591   }
       
  1592  #endif
       
  1593 
       
  1594 QSystemScreenSaverLinuxCommonPrivate::QSystemScreenSaverLinuxCommonPrivate(QObject *parent) : QObject(parent)
       
  1595 {
       
  1596 }
       
  1597 
       
  1598 QSystemScreenSaverLinuxCommonPrivate::~QSystemScreenSaverLinuxCommonPrivate()
       
  1599 {
       
  1600 }
       
  1601 
       
  1602 
       
  1603 #include "moc_qsysteminfo_linux_common_p.cpp"
       
  1604 
       
  1605 QTM_END_NAMESPACE