|
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 ¶m) |
|
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 ¶meter) |
|
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 |