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