/**************************************************************************** ** ** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the Qt Mobility Components. ** ** $QT_BEGIN_LICENSE:LGPL$ ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the ** Software or, alternatively, in accordance with the terms contained in ** a written agreement between you and Digia. For licensing terms and ** conditions see http://qt.digia.com/licensing. For further information ** use the contact form at http://qt.digia.com/contact-us. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Digia gives you certain additional ** rights. These rights are described in the Digia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** GNU General Public License Usage ** Alternatively, this file may be used under the terms of the GNU ** General Public License version 3.0 as published by the Free Software ** Foundation and appearing in the file LICENSE.GPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU General Public License version 3.0 requirements will be ** met: http://www.gnu.org/copyleft/gpl.html. ** ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #include "qsysteminfo_maemo_p.h" #include #include #include #include #include #include #if !defined(Q_WS_MAEMO_6) #if !defined(SW_KEYPAD_SLIDE) #define SW_KEYPAD_SLIDE 0x0a #endif // SW_KEYPAD_SLIDE #endif // Q_WS_MAEMO_6 #define BITS_PER_LONG (sizeof(long) * 8) #define NBITS(x) ((((x)-1)/BITS_PER_LONG)+1) #define OFF(x) ((x)%BITS_PER_LONG) #define LONG(x) ((x)/BITS_PER_LONG) #define TEST_BIT(bit, array) ((array[LONG(bit)] >> OFF(bit)) & 1) #if !defined(QT_NO_DBUS) #include "linux/gconfitem_p.h" #endif // QT_NO_DBUS #ifdef Q_USE_BME extern "C" { #include #include #include "bme/bmeipc.h" #include "bme/bmemsg.h" #include "bme/em_isi.h" } #endif // Q_USE_BME static QString sysinfodValueForKey(const QString& key) { QString value; #if !defined(QT_NO_DBUS) QDBusInterface connectionInterface("com.nokia.SystemInfo", "/com/nokia/SystemInfo", "com.nokia.SystemInfo", QDBusConnection::systemBus()); QDBusReply reply = connectionInterface.call("GetConfigValue", key); if (reply.isValid()) { /* * sysinfod automatically terminates after some idle time (no D-Bus traffic). * Therefore, we cannot use isServiceRegistered() to determine if sysinfod is available. * * Thus, make a query to sysinfod and if we got back a valid reply, sysinfod * is available. */ value = reply.value(); } #endif // QT_NO_DBUS return value; } #if !defined(QT_NO_DBUS) QDBusArgument &operator<<(QDBusArgument &argument, const ProfileDataValue &value) { argument.beginStructure(); argument << value.key << value.val << value.type; argument.endStructure(); return argument; } const QDBusArgument &operator>>(const QDBusArgument &argument, ProfileDataValue &value) { argument.beginStructure(); argument >> value.key >> value.val >> value.type; argument.endStructure(); return argument; } #endif // QT_NO_DBUS QTM_BEGIN_NAMESPACE QSystemInfoPrivate::QSystemInfoPrivate(QSystemInfoLinuxCommonPrivate *parent) : QSystemInfoLinuxCommonPrivate(parent) { } QSystemInfoPrivate::~QSystemInfoPrivate() { } QStringList QSystemInfoPrivate::availableLanguages() const { QStringList languages; #if defined(Q_WS_MAEMO_6) QDir langDir("/etc/meego-supported-languages"); languages = langDir.entryList(QStringList() << "??", QDir::Files | QDir::NoDotAndDotDot, QDir::Name); #else // Q_WS_MAEMO_6 GConfItem languagesItem("/meegotouch/inputmethods/languages"); const QStringList locales = languagesItem.value().toStringList(); foreach (const QString &locale, locales) languages << locale.mid(0, 2); languages << currentLanguage(); languages.removeDuplicates(); #endif // Q_WS_MAEMO_6 return languages; } QString QSystemInfoPrivate::currentLanguage() const { #if defined(Q_WS_MAEMO_6) QString lang; if (currentLang.isEmpty()) { GConfItem langItem("/meegotouch/i18n/language"); lang = langItem.value().toString(); if (lang.count() > 2) lang = lang.left(2); if (lang.isEmpty()) lang = QString::fromLocal8Bit(qgetenv("LANG")).left(2); } else { lang = currentLang; } return lang; #else // Q_WS_MAEMO_6 return QSystemInfoLinuxCommonPrivate::currentLanguage(); #endif // Q_WS_MAEMO_6 } QString QSystemInfoPrivate::currentCountryCode() const { #if defined(Q_WS_MAEMO_6) GConfItem langItem("/meegotouch/i18n/region"); QString langCC = langItem.value().toString().section("_", 1, 1); if (langCC.isEmpty()) { langCC = QString::fromLocal8Bit(qgetenv("LANG")).section("_", 1, 1); langCC = langCC.remove(".UTF-8", Qt::CaseSensitive); } return langCC; #else // Q_WS_MAEMO_6 return QSystemInfoLinuxCommonPrivate::currentCountryCode(); #endif // Q_WS_MAEMO_6 } QString QSystemInfoPrivate::version(QSystemInfo::Version type, const QString ¶meter) { switch(type) { case QSystemInfo::Firmware: { QString sysinfodValue = sysinfodValueForKey("/device/sw-release-ver"); if (!sysinfodValue.isEmpty()) return sysinfodValue; } default: return QSystemInfoLinuxCommonPrivate::version(type, parameter); }; } bool QSystemInfoPrivate::hasFeatureSupported(QSystemInfo::Feature feature) { bool featureSupported = false; switch (feature) { case QSystemInfo::SimFeature: { QSystemDeviceInfoPrivate d; featureSupported = (d.simStatus() != QSystemDeviceInfo::SimNotAvailable); break; } case QSystemInfo::LocationFeature: { #if defined(Q_WS_MAEMO_6) GConfItem satellitePositioning("/system/osso/location/settings/satellitePositioning"); GConfItem networkPositioning("/system/osso/location/settings/networkPositioning"); bool satellitePositioningAvailable = satellitePositioning.value(false).toBool(); bool networkPositioningAvailable = networkPositioning.value(false).toBool(); featureSupported = (satellitePositioningAvailable || networkPositioningAvailable); #else // Q_WS_MAEMO_6 GConfItem locationValues("/system/nokia/location"); const QStringList locationKeys = locationValues.listEntries(); if (locationKeys.count()) featureSupported = true; #endif // Q_WS_MAEMO_6 break; } case QSystemInfo::HapticsFeature: { #if !defined(QT_NO_HAL) QHalInterface iface; const QStringList touchSupport(iface.findDeviceByCapability("input.touchpad")); if (touchSupport.count()) featureSupported = true; else featureSupported = false; #endif // QT_NO_HAL break; } default: featureSupported = QSystemInfoLinuxCommonPrivate::hasFeatureSupported(feature); break; }; return featureSupported; } #if defined(Q_WS_MAEMO_6) QMap QSystemNetworkInfoPrivate::CellularServiceStatus; #endif // Q_WS_MAEMO_6 QSystemNetworkInfoPrivate::QSystemNetworkInfoPrivate(QSystemNetworkInfoLinuxCommonPrivate *parent) : QSystemNetworkInfoLinuxCommonPrivate(parent) , currentBluetoothNetworkStatus(QSystemNetworkInfo::UndefinedStatus) , currentCellNetworkStatus(-1) , currentWlanNetworkStatus(QSystemNetworkInfo::UndefinedStatus) , currentNetworkMode(QSystemNetworkInfo::UnknownMode) , currentCellSignalStrength(-1) , currentEthernetSignalStrength(-1) , currentWlanSignalStrength(-1) , currentCellId(-1) , currentLac(-1) , radioAccessTechnology(0) , currentCellDataTechnology(QSystemNetworkInfo::UnknownDataTechnology) , wlanSignalStrengthTimer(0) { #if defined(Q_WS_MAEMO_6) if (CellularServiceStatus.isEmpty()) { CellularServiceStatus["Unknown"] = -1; // Current registration status is unknown. CellularServiceStatus["Home"] = 0; // Registered with the home network. CellularServiceStatus["Roaming"] = 1; // Registered with a roaming network. CellularServiceStatus["Offline"] = 3; // Not registered. CellularServiceStatus["Searching"] = 4; // Offline, but currently searching for network. CellularServiceStatus["NoSim"] = 6; // Offline because no SIM is present. CellularServiceStatus["PowerOff"] = 8; // Offline because the CS is powered off. CellularServiceStatus["PowerSave"] = 9; // Offline and in power save mode. CellularServiceStatus["NoCoverage"] = 10; // Offline and in power save mode because of poor coverage. CellularServiceStatus["Rejected"] = 11; // Offline because SIM was rejected by the network. } #endif // Q_WS_MAEMO_6 setupNetworkInfo(); } QSystemNetworkInfoPrivate::~QSystemNetworkInfoPrivate() { delete wlanSignalStrengthTimer; } QSystemNetworkInfo::NetworkStatus QSystemNetworkInfoPrivate::networkStatus(QSystemNetworkInfo::NetworkMode mode) { switch(mode) { case QSystemNetworkInfo::GsmMode: case QSystemNetworkInfo::CdmaMode: case QSystemNetworkInfo::WcdmaMode: { // radioAccessTechnology: 1 = GSM, 2 = WCDMA if ((radioAccessTechnology == 1 && mode != QSystemNetworkInfo::GsmMode) || (radioAccessTechnology == 2 && mode != QSystemNetworkInfo::WcdmaMode)) { return QSystemNetworkInfo::NoNetworkAvailable; } #if defined(Q_WS_MAEMO_6) QVariant value = queryCsdProperties("com.nokia.csd.CSNet", "/com/nokia/csd/csnet", "com.nokia.csd.CSNet.NetworkRegistration").value("RegistrationStatus"); if (value.isValid()) currentCellNetworkStatus = CellularServiceStatus.value(value.toString(), -1); #endif // Q_WS_MAEMO_6 switch (currentCellNetworkStatus) { case 0: return QSystemNetworkInfo::HomeNetwork; // CS is registered to home network case 1: return QSystemNetworkInfo::Roaming; // CS is registered to some other network than home network case 2: return QSystemNetworkInfo::Roaming; // CS is registered to non-home system in a non-home area case 3: return QSystemNetworkInfo::NoNetworkAvailable; // CS is not in service case 4: return QSystemNetworkInfo::Searching; // CS is not in service, but is currently searching for service case 5: return QSystemNetworkInfo::NoNetworkAvailable; // CS is not in service and it is not currently searching for service case 6: return QSystemNetworkInfo::NoNetworkAvailable; // CS is not in service due to missing SIM or missing subscription case 8: return QSystemNetworkInfo::NoNetworkAvailable; // CS is in power off state case 9: return QSystemNetworkInfo::NoNetworkAvailable; // CS is in No Service Power Save State (currently not listening to any cell) case 10: return QSystemNetworkInfo::NoNetworkAvailable; // CS is in No Service Power Save State (CS is entered to this state // because there is no network coverage) case 11: return QSystemNetworkInfo::Denied; // CS is not in service due to missing subscription default: break; }; break; } case QSystemNetworkInfo::EthernetMode: if (currentEthernetSignalStrength == -1) networkSignalStrength(mode); if (currentEthernetSignalStrength == 100) return QSystemNetworkInfo::Connected; else return QSystemNetworkInfo::NoNetworkAvailable; case QSystemNetworkInfo::WlanMode: currentWlanNetworkStatus = QSystemNetworkInfoLinuxCommonPrivate::networkStatus(mode); return currentWlanNetworkStatus; case QSystemNetworkInfo::BluetoothMode: currentBluetoothNetworkStatus = QSystemNetworkInfoLinuxCommonPrivate::networkStatus(mode); return currentBluetoothNetworkStatus; // case QSystemNetworkInfo::WimaxMode: // case QSystemNetworkInfo::LteMode: default: return QSystemNetworkInfoLinuxCommonPrivate::networkStatus(mode); }; return QSystemNetworkInfo::UndefinedStatus; } int QSystemNetworkInfoPrivate::networkSignalStrength(QSystemNetworkInfo::NetworkMode mode) { switch(mode) { case QSystemNetworkInfo::GsmMode: case QSystemNetworkInfo::CdmaMode: case QSystemNetworkInfo::WcdmaMode: { // radioAccessTechnology: 1 = GSM, 2 = WCDMA if ((radioAccessTechnology == 1 && mode != QSystemNetworkInfo::GsmMode) || (radioAccessTechnology == 2 && mode != QSystemNetworkInfo::WcdmaMode)) { return -1; } #if !defined(QT_NO_DBUS) #if defined(Q_WS_MAEMO_6) QVariant value = queryCsdProperties("com.nokia.csd.CSNet", "/com/nokia/csd/csnet", "com.nokia.csd.CSNet.SignalStrength").value("SignalPercent"); if (value.isValid()) currentCellSignalStrength = value.toInt(); #endif // Q_WS_MAEMO_6 #endif // QT_NO_DBUS return currentCellSignalStrength; } case QSystemNetworkInfo::EthernetMode: currentEthernetSignalStrength = QSystemNetworkInfoLinuxCommonPrivate::networkSignalStrength(mode); return currentEthernetSignalStrength; case QSystemNetworkInfo::WlanMode: currentWlanSignalStrength = QSystemNetworkInfoLinuxCommonPrivate::networkSignalStrength(mode); return currentWlanSignalStrength; // case QSystemNetworkInfo::BluetoothMode: // case QSystemNetworkInfo::WimaxMode: // case QSystemNetworkInfo::LteMode: default: return QSystemNetworkInfoLinuxCommonPrivate::networkSignalStrength(mode); }; return -1; } int QSystemNetworkInfoPrivate::cellId() { #if !defined(QT_NO_DBUS) #if defined(Q_WS_MAEMO_6) QVariant value = queryCsdProperties("com.nokia.csd.CSNet", "/com/nokia/csd/csnet", "com.nokia.csd.CSNet.NetworkCell").value("CellId"); if (value.isValid()) currentCellId = value.toInt(); #endif // Q_WS_MAEMO_6 #endif // QT_NO_DBUS return currentCellId; } int QSystemNetworkInfoPrivate::locationAreaCode() { #if !defined(QT_NO_DBUS) #if defined(Q_WS_MAEMO_6) QVariant value = queryCsdProperties("com.nokia.csd.CSNet", "/com/nokia/csd/csnet", "com.nokia.csd.CSNet.NetworkCell").value("CellLac"); if (value.isValid()) currentLac = value.toInt(); #endif // Q_WS_MAEMO_6 #endif // QT_NO_DBUS return currentLac; } QString QSystemNetworkInfoPrivate::currentMobileCountryCode() { #if !defined(QT_NO_DBUS) #if defined(Q_WS_MAEMO_6) QVariant value = queryCsdProperties("com.nokia.csd.CSNet", "/com/nokia/csd/csnet", "com.nokia.csd.CSNet.NetworkOperator").value("OperatorMCC"); if (value.isValid()) currentMCC = value.toString(); #endif // Q_WS_MAEMO_6 #endif // QT_NO_DBUS return currentMCC; } QString QSystemNetworkInfoPrivate::currentMobileNetworkCode() { #if !defined(QT_NO_DBUS) #if defined(Q_WS_MAEMO_6) QVariant value = queryCsdProperties("com.nokia.csd.CSNet", "/com/nokia/csd/csnet", "com.nokia.csd.CSNet.NetworkOperator").value("OperatorMNC"); if (value.isValid()) currentMNC = value.toString(); #endif // Q_WS_MAEMO_6 #endif // QT_NO_DBUS return currentMNC; } QString QSystemNetworkInfoPrivate::homeMobileCountryCode() { QSystemDeviceInfoPrivate d; QString imsi = d.imsi(); if (imsi.length() >= 3) return imsi.left(3); return QString(); } QString QSystemNetworkInfoPrivate::homeMobileNetworkCode() { #if !defined(QT_NO_DBUS) #if defined(Q_WS_MAEMO_6) QDBusInterface connectionInterface("com.nokia.csd.SIM", "/com/nokia/csd/sim", "com.nokia.csd.SIM.Identity", QDBusConnection::systemBus(), this); QDBusMessage reply = connectionInterface.call(QLatin1String("GetHPLMN")); if (reply.errorName().isEmpty()) { QList args = reply.arguments(); // The first attribute should be MCC and the 2nd one MNC if (args.size() == 2) return args.at(1).toString(); } #else // Q_WS_MAEMO_6 QDBusInterface connectionInterface("com.nokia.phone.SIM", "/com/nokia/phone/SIM", "Phone.Sim", QDBusConnection::systemBus(), this); if (!connectionInterface.isValid()) { qDebug() << "interface not valid"; return QString(); } QDBusReply reply = connectionInterface.call(QLatin1String("read_hplmn")); // The MNC and MCC are split into Hex numbers in the received byte array. // The MNC can be 2 or 3 digits long. If it is 2 digits long, it ends with 0xF. // The order of the Hex numbers in the reply is: // mcc2 mcc1 mnc3 mcc3 mnc2 mnc1 QString homeMobileNetworkCode; if (reply.isValid()) { QString temp = reply.value().toHex(); QString mnc1 = temp.right(1); temp.chop(1); QString mnc2 = temp.right(1); temp.chop(2); QString mnc3 = temp.right(1); if (mnc3 != "f") homeMobileNetworkCode.prepend(mnc3); homeMobileNetworkCode.prepend(mnc2); homeMobileNetworkCode.prepend(mnc1); return homeMobileNetworkCode; } #endif // Q_WS_MAEMO_6 #endif // QT_NO_DBUS return QString(); } QString QSystemNetworkInfoPrivate::networkName(QSystemNetworkInfo::NetworkMode mode) { switch(mode) { case QSystemNetworkInfo::CdmaMode: case QSystemNetworkInfo::GsmMode: case QSystemNetworkInfo::WcdmaMode: { // radioAccessTechnology: 1 = GSM, 2 = WCDMA if ((radioAccessTechnology == 1 && mode != QSystemNetworkInfo::GsmMode) || (radioAccessTechnology == 2 && mode != QSystemNetworkInfo::WcdmaMode)) { break; } #if !defined(QT_NO_DBUS) #if defined(Q_WS_MAEMO_6) QVariant value = queryCsdProperties("com.nokia.csd.CSNet", "/com/nokia/csd/csnet", "com.nokia.csd.CSNet.NetworkOperator").value("OperatorName"); if (value.isValid()) currentOperatorName = value.toString(); #endif // Q_WS_MAEMO_6 #endif // QT_NO_DBUS return currentOperatorName; } // case QSystemNetworkInfo::WlanMode: // case QSystemNetworkInfo::EthernetMode: // case QSystemNetworkInfo::BluetoothMode: // case QSystemNetworkInfo::WimaxMode: // case QSystemNetworkInfo::LteMode: default: return QSystemNetworkInfoLinuxCommonPrivate::networkName(mode); }; return QString(); } #if !defined(QT_NO_DBUS) #if defined(Q_WS_MAEMO_6) QMap QSystemNetworkInfoPrivate::queryCsdProperties(const QString &service, const QString &path, const QString &interface) { QMap properties; QDBusMessage message = QDBusMessage::createMethodCall(service, path, "org.freedesktop.DBus.Properties", "GetAll"); message << interface; QDBusReply > reply = QDBusConnection::systemBus().call(message); if (reply.isValid()) properties = reply.value(); return properties; } #endif // Q_WS_MAEMO_6 #endif // QT_NO_DBUS void QSystemNetworkInfoPrivate::setupNetworkInfo() { #if !defined(QT_NO_DBUS) #if defined(Q_WS_MAEMO_6) const QString service("com.nokia.csd.CSNet"); const QString path("/com/nokia/csd/csnet"); // CSD: network cell QMap properties = queryCsdProperties(service, path, "com.nokia.csd.CSNet.NetworkCell"); QVariant value = properties.value("CellType"); if (value.isValid()) { QString currentCellType = value.toString(); if (currentCellType == "GSM") radioAccessTechnology = 1; else if (currentCellType == "WCDMA") radioAccessTechnology = 2; } #else // Q_WS_MAEMO_6 QDBusConnection systemDbusConnection = QDBusConnection::systemBus(); iWlanStrengthCheckEnabled = 0; QDBusInterface connectionInterface("com.nokia.phone.net", "/com/nokia/phone/net", "Phone.Net", systemDbusConnection); if (!connectionInterface.isValid()) { qDebug() << "setupNetworkInfo(): interface not valid"; return; } QDBusMessage reply = connectionInterface.call(QLatin1String("get_registration_status")); if (reply.type() == QDBusMessage::ReplyMessage) { QList argList = reply.arguments(); currentCellNetworkStatus = argList.at(STATUS_INDEX).toInt(); currentLac = argList.at(LAC_INDEX).value(); currentCellId = argList.at(CELLID_INDEX).value(); currentMCC.setNum(argList.at(MCC_INDEX).value()); currentMNC.setNum(argList.at(MNC_INDEX).value()); } else { qDebug() << reply.errorMessage(); } if (!systemDbusConnection.connect("com.nokia.phone.net", "/com/nokia/phone/net", "Phone.Net", "registration_status_change", this, SLOT(registrationStatusChanged(uchar,ushort,uint,uint,uint,uchar,uchar)))) { qDebug() << "unable to connect to registration_status_change"; } reply = connectionInterface.call(QLatin1String("get_signal_strength")); if (reply.type() == QDBusMessage::ReplyMessage) { QList argList = reply.arguments(); currentCellSignalStrength = argList.at(0).toInt(); } else { qDebug() << reply.errorMessage(); } if (!systemDbusConnection.connect("com.nokia.phone.net", "/com/nokia/phone/net", "Phone.Net", "signal_strength_change", this, SLOT(cellNetworkSignalStrengthChanged(uchar,uchar)))) { qDebug() << "unable to connect to signal_strength_change"; } uchar type = 0; QList argumentList; argumentList << qVariantFromValue(type) << qVariantFromValue(currentMNC.toUInt()) << qVariantFromValue(currentMCC.toUInt()); reply = connectionInterface.callWithArgumentList(QDBus::Block, QLatin1String("get_operator_name"), argumentList); if (reply.type() == QDBusMessage::ReplyMessage) { QList argList = reply.arguments(); currentOperatorName = argList.at(0).toString(); } else { qDebug() << reply.errorMessage(); } if (!systemDbusConnection.connect("com.nokia.phone.net", "/com/nokia/phone/net", "Phone.Net", "operator_name_change", this, SLOT(operatorNameChanged(uchar,QString,QString,uint,uint)))) { qDebug() << "unable to connect to operator_name_change"; } reply = connectionInterface.call(QLatin1String("get_radio_access_technology")); if (reply.type() == QDBusMessage::ReplyMessage) { QList argList = reply.arguments(); radioAccessTechnology = argList.at(0).toInt(); } else { qDebug() << reply.errorMessage(); } if (!systemDbusConnection.connect("com.nokia.phone.net", "/com/nokia/phone/net", "Phone.Net", "radio_access_technology_change", this, SLOT(networkModeChanged(int)))) { qDebug() << "unable to connect to radio_access_technology_change"; } // TODO optimize the performance by enabling lazy loading (already done for M6) // here I just get the signal strength so we can handle the changes currentEthernetSignalStrength = networkSignalStrength(QSystemNetworkInfo::EthernetMode); currentBluetoothNetworkStatus = networkStatus(QSystemNetworkInfo::BluetoothMode); currentWlanNetworkStatus = networkStatus(QSystemNetworkInfo::WlanMode); currentWlanSignalStrength = networkSignalStrength(QSystemNetworkInfo::WlanMode); currentNetworkMode = currentMode(); wlanSignalStrengthTimer = new QTimer(this); connect(wlanSignalStrengthTimer, SIGNAL(timeout()), this, SLOT(checkWlanSignalStrength())); if (!systemDbusConnection.connect("com.nokia.bme", "/com/nokia/bme/signal", "com.nokia.bme.signal", QLatin1String("charger_connected"), this, SLOT(updateUsbCableStatus()))) { qDebug() << "unable to connect to updateUsbCableStatus (connect)"; } if (!systemDbusConnection.connect("com.nokia.bme", "/com/nokia/bme/signal", "com.nokia.bme.signal", QLatin1String("charger_disconnected"), this, SLOT(updateUsbCableStatus()))) { qDebug() << "unable to connect to updateUsbCableStatus (disconnect)"; } if (!systemDbusConnection.connect("org.freedesktop.Hal", "/org/freedesktop/Hal/Manager", "org.freedesktop.Hal.Manager", QLatin1String("DeviceAdded"), this, SLOT(updateAttachedDevices(QString)))) { qDebug() << "unable to connect to updateAttachedDevices (1)"; } if (!systemDbusConnection.connect("org.freedesktop.Hal", "/org/freedesktop/Hal/Manager", "org.freedesktop.Hal.Manager", QLatin1String("DeviceRemoved"), this, SLOT(updateAttachedDevices(QString)))) { qDebug() << "unable to connect to updateAttachedDevices (2)"; } if (!systemDbusConnection.connect("com.nokia.icd", "/com/nokia/icd", "com.nokia.icd", QLatin1String("status_changed"), this, SLOT(icdStatusChanged(QString,QString,QString,QString)))) { qDebug() << "unable to connect to icdStatusChanged"; } #endif // Q_WS_MAEMO_6 #endif // QT_NO_DBUS } #if !defined(QT_NO_DBUS) #if defined(Q_WS_MAEMO_6) void QSystemNetworkInfoPrivate::connectNotify(const char *signal) { const QString service("com.nokia.csd.CSNet"); const QString path("/com/nokia/csd/csnet"); if ((QLatin1String(signal) == SIGNAL(networkSignalStrengthChanged(QSystemNetworkInfo::NetworkMode,int)))) { networkSignalStrength(QSystemNetworkInfo::GsmMode); networkSignalStrength(QSystemNetworkInfo::EthernetMode); networkSignalStrength(QSystemNetworkInfo::WlanMode); wlanSignalStrengthTimer = new QTimer(this); wlanSignalStrengthTimer->start(5000); connect(wlanSignalStrengthTimer, SIGNAL(timeout()), this, SLOT(checkWlanSignalStrength())); if (!QDBusConnection::systemBus().connect(service, path, "com.nokia.csd.CSNet.SignalStrength", "SignalStrengthChanged", this, SLOT(slotSignalStrengthChanged(int,int)))) { qDebug() << "unable to connect SignalStrengthChanged"; } } else if ((QLatin1String(signal) == SIGNAL(currentMobileCountryCodeChanged(QString))) || (QLatin1String(signal) == SIGNAL(currentMobileNetworkCodeChanged(QString)))) { currentMobileCountryCode(); if (!QDBusConnection::systemBus().connect(service, path, "com.nokia.csd.CSNet.NetworkOperator", "OperatorChanged", this, SLOT(slotOperatorChanged(QString,QString)))) { qDebug() << "unable to connect (OperatorChanged"; } } else if ((QLatin1String(signal) == SIGNAL(networkNameChanged(QSystemNetworkInfo::NetworkMode,QString)))) { networkName(QSystemNetworkInfo::GsmMode); if (!QDBusConnection::systemBus().connect(service, path, "com.nokia.csd.CSNet.NetworkOperator", "OperatorNameChanged", this, SLOT(slotOperatorNameChanged(QString)))) { qDebug() << "unable to connect OperatorNameChanged"; } } else if ((QLatin1String(signal) == SIGNAL(networkStatusChanged(QSystemNetworkInfo::NetworkMode,QSystemNetworkInfo::NetworkStatus)))) { networkSignalStrength(QSystemNetworkInfo::EthernetMode); networkStatus(QSystemNetworkInfo::BluetoothMode); networkStatus(QSystemNetworkInfo::GsmMode); networkStatus(QSystemNetworkInfo::WlanMode); currentMode(); if (!QDBusConnection::systemBus().connect("com.nokia.icd", "/com/nokia/icd", "com.nokia.icd", QLatin1String("status_changed"), this, SLOT(icdStatusChanged(QString,QString,QString,QString)))) { qDebug() << "unable to connect to icdStatusChanged"; } #if !defined(QT_NO_HAL) if (!QDBusConnection::systemBus().connect("org.freedesktop.Hal", "/org/freedesktop/Hal/Manager", "org.freedesktop.Hal.Manager", QLatin1String("DeviceAdded"), this, SLOT(updateAttachedDevices(QString)))) { qDebug() << "unable to connect to updateAttachedDevices (1)"; } if (!QDBusConnection::systemBus().connect("org.freedesktop.Hal", "/org/freedesktop/Hal/Manager", "org.freedesktop.Hal.Manager", QLatin1String("DeviceRemoved"), this, SLOT(updateAttachedDevices(QString)))) { qDebug() << "unable to connect to updateAttachedDevices (2)"; } #endif // QT_NO_HAL if (!QDBusConnection::systemBus().connect(service, path, "com.nokia.csd.CSNet.NetworkRegistration", "RegistrationChanged", this, SLOT(slotRegistrationChanged(QString)))) { qDebug() << "unable to connect RegistrationChanged"; } } else if ((QLatin1String(signal) == SIGNAL(cellIdChanged(int)))) { currentMode(); cellId(); if (!QDBusConnection::systemBus().connect(service, path, "com.nokia.csd.CSNet.NetworkCell", "CellChanged", this, SLOT(slotCellChanged(QString,int,int)))) { qDebug() << "unable to connect CellChanged"; } } else if ((QLatin1String(signal) == SIGNAL(cellDataTechnologyChanged(QSystemNetworkInfo::CellDataTechnology)))) { cellDataTechnology(); if (!QDBusConnection::systemBus().connect(service, path, "com.nokia.csd.CSNet.RadioAccess", "DataTechnologyChanged", this, SLOT(slotCellDataTechnologyChanged(QString)))) { qDebug() << "unable to connect DataTechnologyChanged"; } } } void QSystemNetworkInfoPrivate::disconnectNotify(const char *signal) { const QString service("com.nokia.csd.CSNet"); const QString path("/com/nokia/csd/csnet"); if ((QLatin1String(signal) == SIGNAL(networkSignalStrengthChanged(QSystemNetworkInfo::NetworkMode,int)))) { wlanSignalStrengthTimer->stop(); if (!QDBusConnection::systemBus().disconnect(service, path, "com.nokia.csd.CSNet.SignalStrength", "SignalStrengthChanged", this, SLOT(slotSignalStrengthChanged(int,int)))) { qDebug() << "unable to disconnect SignalStrengthChanged"; } } else if ((QLatin1String(signal) == SIGNAL(currentMobileCountryCodeChanged(QString))) || (QLatin1String(signal) == SIGNAL(currentMobileNetworkCodeChanged(QString)))) { if (!QDBusConnection::systemBus().disconnect(service, path, "com.nokia.csd.CSNet.NetworkOperator", "OperatorChanged", this, SLOT(slotOperatorChanged(QString,QString)))) { qDebug() << "unable to disconnect (OperatorChanged"; } } else if ((QLatin1String(signal) == SIGNAL(networkNameChanged(QSystemNetworkInfo::NetworkMode,QString)))) { if (!QDBusConnection::systemBus().disconnect(service, path, "com.nokia.csd.CSNet.NetworkOperator", "OperatorNameChanged", this, SLOT(slotOperatorNameChanged(QString)))) { qDebug() << "unable to disconnect OperatorNameChanged"; } } else if ((QLatin1String(signal) == SIGNAL(networkStatusChanged(QSystemNetworkInfo::NetworkMode,QSystemNetworkInfo::NetworkStatus)))) { if (!QDBusConnection::systemBus().disconnect(service, path, "com.nokia.csd.CSNet.NetworkRegistration", "RegistrationChanged", this, SLOT(slotRegistrationChanged(QString)))) { qDebug() << "unable to disconnect RegistrationChanged"; } } else if ((QLatin1String(signal) == SIGNAL(cellIdChanged(int)))) { if (!QDBusConnection::systemBus().disconnect(service, path, "com.nokia.csd.CSNet.NetworkCell", "CellChanged", this, SLOT(slotCellChanged(QString,int,int)))) { qDebug() << "unable to disconnect CellChanged"; } } else if ((QLatin1String(signal) == SIGNAL(cellDataTechnologyChanged(QSystemNetworkInfo::CellDataTechnology)))) { if (!QDBusConnection::systemBus().disconnect(service, path, "com.nokia.csd.CSNet", "ActivityChanged", this, SLOT(slotCellDataTechnologyChanged(QString)))) { qDebug() << "unable to disconnect DataTechnologyChanged"; } } } void QSystemNetworkInfoPrivate::slotSignalStrengthChanged(int signalStrength, int /*dbm*/) { currentCellSignalStrength = signalStrength; if (radioAccessTechnology == 1) Q_EMIT networkSignalStrengthChanged(QSystemNetworkInfo::GsmMode, currentCellSignalStrength); else if (radioAccessTechnology == 2) Q_EMIT networkSignalStrengthChanged(QSystemNetworkInfo::WcdmaMode, currentCellSignalStrength); } void QSystemNetworkInfoPrivate::slotOperatorChanged(const QString &mnc, const QString &mcc) { if (currentMCC != mcc) { currentMCC = mcc; Q_EMIT currentMobileCountryCodeChanged(currentMCC); } if (currentMNC != mnc) { currentMNC = mnc; Q_EMIT currentMobileNetworkCodeChanged(currentMNC); } } void QSystemNetworkInfoPrivate::slotOperatorNameChanged(const QString &name) { currentOperatorName = name; if (radioAccessTechnology == 1) Q_EMIT networkNameChanged(QSystemNetworkInfo::GsmMode, currentOperatorName); else if (radioAccessTechnology == 2) Q_EMIT networkNameChanged(QSystemNetworkInfo::WcdmaMode, currentOperatorName); } void QSystemNetworkInfoPrivate::slotRegistrationChanged(const QString &status) { int newCellNetworkStatus = CellularServiceStatus.value(status, -1); if (currentCellNetworkStatus != newCellNetworkStatus) { currentCellNetworkStatus = newCellNetworkStatus; if (radioAccessTechnology == 1) Q_EMIT networkStatusChanged(QSystemNetworkInfo::GsmMode, networkStatus(QSystemNetworkInfo::GsmMode)); else if (radioAccessTechnology == 2) Q_EMIT networkStatusChanged(QSystemNetworkInfo::WcdmaMode, networkStatus(QSystemNetworkInfo::WcdmaMode)); } } void QSystemNetworkInfoPrivate::slotCellChanged(const QString &type, int id, int lac) { int newRadioAccessTechnology = 0; if (type == "GSM") newRadioAccessTechnology = 1; else if (type == "WCDMA") newRadioAccessTechnology = 2; if (radioAccessTechnology != newRadioAccessTechnology) { radioAccessTechnology = newRadioAccessTechnology; checkNetworkMode(); } if (currentCellId != id) { currentCellId = id; Q_EMIT cellIdChanged(currentCellId); } if (currentLac != lac) { currentLac = lac; } } void QSystemNetworkInfoPrivate::slotCellDataTechnologyChanged(const QString &tech) { // TODO don't call cellDataTechnology() here Q_UNUSED(tech); QSystemNetworkInfo::CellDataTechnology oldTech = currentCellDataTechnology; if (oldTech != cellDataTechnology()) Q_EMIT cellDataTechnologyChanged(currentCellDataTechnology); } #endif // Q_WS_MAEMO_6 #endif // QT_NO_DBUS #if defined(Q_WS_MAEMO_5) void QSystemNetworkInfoPrivate::cellNetworkSignalStrengthChanged(uchar var1, uchar) { currentCellSignalStrength = var1; if (radioAccessTechnology == 1) Q_EMIT networkSignalStrengthChanged(QSystemNetworkInfo::GsmMode, currentCellSignalStrength); else if (radioAccessTechnology == 2) Q_EMIT networkSignalStrengthChanged(QSystemNetworkInfo::WcdmaMode, currentCellSignalStrength); } void QSystemNetworkInfoPrivate::networkModeChanged(int newRadioAccessTechnology) { radioAccessTechnology = newRadioAccessTechnology; checkNetworkMode(); } void QSystemNetworkInfoPrivate::operatorNameChanged(uchar, QString name, QString, uint, uint) { currentOperatorName = name; if (radioAccessTechnology == 1) Q_EMIT networkNameChanged(QSystemNetworkInfo::GsmMode, currentOperatorName); else if (radioAccessTechnology == 2) Q_EMIT networkNameChanged(QSystemNetworkInfo::WcdmaMode, currentOperatorName); } void QSystemNetworkInfoPrivate::registrationStatusChanged(uchar var1, ushort var2, uint var3, uint var4, uint var5, uchar, uchar) { int newCellNetworkStatus = var1; int newLac = var2; int newCellId = var3; QString newMobileCountryCode; QString newMobileNetworkCode; newMobileCountryCode.setNum(var5); newMobileNetworkCode.setNum(var4); if (currentCellNetworkStatus != newCellNetworkStatus) { currentCellNetworkStatus = newCellNetworkStatus; if (radioAccessTechnology == 1) Q_EMIT networkStatusChanged(QSystemNetworkInfo::GsmMode, networkStatus(QSystemNetworkInfo::GsmMode)); else if (radioAccessTechnology == 2) Q_EMIT networkStatusChanged(QSystemNetworkInfo::WcdmaMode, networkStatus(QSystemNetworkInfo::WcdmaMode)); } if (currentLac != newLac) currentLac = newLac; if (currentCellId != newCellId) { currentCellId = newCellId; Q_EMIT cellIdChanged(newCellId); } if (currentMCC != newMobileCountryCode) { currentMCC = newMobileCountryCode; Q_EMIT currentMobileCountryCodeChanged(currentMCC); } if (currentMNC != newMobileNetworkCode) { currentMNC = newMobileNetworkCode; Q_EMIT currentMobileNetworkCodeChanged(currentMNC); } } #endif // Q_WS_MAEMO_5 void QSystemNetworkInfoPrivate::icdStatusChanged(QString, QString var2, QString, QString) { if (var2 == "WLAN_INFRA") { // TODO don't call networkStatus() here QSystemNetworkInfo::NetworkStatus oldWlanNetworkStatus = currentWlanNetworkStatus; networkStatus(QSystemNetworkInfo::WlanMode); if (currentWlanNetworkStatus != oldWlanNetworkStatus) { Q_EMIT networkStatusChanged(QSystemNetworkInfo::WlanMode, currentWlanNetworkStatus); checkNetworkMode(); } } } void QSystemNetworkInfoPrivate::updateUsbCableStatus() { // TODO don't call networkSignalStrength() here int oldEthernetSignalStrength = currentEthernetSignalStrength; networkSignalStrength(QSystemNetworkInfo::EthernetMode); if (currentEthernetSignalStrength != oldEthernetSignalStrength) { Q_EMIT networkSignalStrengthChanged(QSystemNetworkInfo::EthernetMode, currentEthernetSignalStrength); Q_EMIT networkStatusChanged(QSystemNetworkInfo::EthernetMode, networkStatus(QSystemNetworkInfo::EthernetMode)); checkNetworkMode(); } } QSystemNetworkInfo::NetworkMode QSystemNetworkInfoPrivate::currentMode() { if (networkStatus(QSystemNetworkInfo::EthernetMode) == QSystemNetworkInfo::Connected) currentNetworkMode = QSystemNetworkInfo::EthernetMode; else if (networkStatus(QSystemNetworkInfo::WlanMode) == QSystemNetworkInfo::Connected) currentNetworkMode = QSystemNetworkInfo::WlanMode; else if (radioAccessTechnology == 1) currentNetworkMode = QSystemNetworkInfo::GsmMode; else if (radioAccessTechnology == 2) currentNetworkMode = QSystemNetworkInfo::WcdmaMode; return currentNetworkMode; } void QSystemNetworkInfoPrivate::checkNetworkMode() { QSystemNetworkInfo::NetworkMode oldNetworkMode = currentNetworkMode; currentMode(); if (currentNetworkMode != oldNetworkMode) Q_EMIT networkModeChanged(currentNetworkMode); } void QSystemNetworkInfoPrivate::checkWlanSignalStrength() { int oldWlanSignalStrength = currentWlanSignalStrength; networkSignalStrength(QSystemNetworkInfo::WlanMode); if (currentWlanSignalStrength != oldWlanSignalStrength) Q_EMIT networkSignalStrengthChanged(QSystemNetworkInfo::WlanMode, currentWlanSignalStrength); } void QSystemNetworkInfoPrivate::updateAttachedDevices(QString device) { if (device == "/org/freedesktop/Hal/devices/net_1b") { QTimer::singleShot(500, this, SLOT(updateUsbCableStatus())); } else { QSystemNetworkInfo::NetworkStatus oldBluetoothNetworkStatus = currentBluetoothNetworkStatus; networkStatus(QSystemNetworkInfo::BluetoothMode); if (currentBluetoothNetworkStatus != oldBluetoothNetworkStatus) Q_EMIT networkStatusChanged(QSystemNetworkInfo::BluetoothMode, currentBluetoothNetworkStatus); } } #if defined(Q_WS_MAEMO_5) void QSystemNetworkInfoPrivate::setWlanSignalStrengthCheckEnabled(bool enabled) { if (enabled) { iWlanStrengthCheckEnabled++; if (!wlanSignalStrengthTimer->isActive()) wlanSignalStrengthTimer->start(5000); //5 seconds interval } else { iWlanStrengthCheckEnabled--; if (iWlanStrengthCheckEnabled <= 0) { if (wlanSignalStrengthTimer->isActive()) wlanSignalStrengthTimer->stop(); } } } #endif // Q_WS_MAEMO_5 inline QSystemNetworkInfo::CellDataTechnology QSystemNetworkInfoPrivate::csdtToCellDataTechnology(const QString &tech) { QSystemNetworkInfo::CellDataTechnology cdt = QSystemNetworkInfo::UnknownDataTechnology; if (tech == "GPRS") cdt = QSystemNetworkInfo::GprsDataTechnology; else if (tech == "EGPRS") cdt = QSystemNetworkInfo::EdgeDataTechnology; else if (tech == "UMTS") cdt = QSystemNetworkInfo::UmtsDataTechnology; else if (tech == "HSPA") cdt = QSystemNetworkInfo::HspaDataTechnology; return cdt; } QSystemNetworkInfo::CellDataTechnology QSystemNetworkInfoPrivate::cellDataTechnology() { #if !defined(QT_NO_DBUS) const QString service("com.nokia.csd.CSNet"); const QString path("/com/nokia/csd/csnet"); QDBusInterface csnetInterface(service, path, "com.nokia.csd.CSNet", QDBusConnection::systemBus()); QVariant dataTechnology; QDBusInterface radioAccessInterface(service, path, "com.nokia.csd.CSNet.RadioAccess", QDBusConnection::systemBus()); if (csnetInterface.property("Activity").toString() == "PacketData") dataTechnology = radioAccessInterface.property("DataTechnology"); else dataTechnology = radioAccessInterface.property("Technology"); if (dataTechnology.isValid()) currentCellDataTechnology = csdtToCellDataTechnology(dataTechnology.toString()); return currentCellDataTechnology; #endif // QT_NO_DBUS } QSystemDisplayInfoPrivate::QSystemDisplayInfoPrivate(QSystemDisplayInfoLinuxCommonPrivate *parent) : QSystemDisplayInfoLinuxCommonPrivate(parent) { } QSystemDisplayInfoPrivate::~QSystemDisplayInfoPrivate() { } int QSystemDisplayInfoPrivate::displayBrightness(int screen) { QDesktopWidget wid; if (wid.screenCount() - 1 < screen) return -1; GConfItem currentBrightness("/system/osso/dsm/display/display_brightness"); GConfItem maxBrightness("/system/osso/dsm/display/max_display_brightness_levels"); if (maxBrightness.value().toInt()) { float retVal = 100 * (currentBrightness.value().toFloat() / maxBrightness.value().toFloat()); return retVal; } return -1; } QSystemDisplayInfo::BacklightState QSystemDisplayInfoPrivate::backlightStatus(int screen) { Q_UNUSED(screen) QSystemDisplayInfo::BacklightState backlightState = QSystemDisplayInfo::BacklightStateUnknown; #if !defined(QT_NO_DBUS) QDBusReply reply = QDBusConnection::systemBus().call( QDBusMessage::createMethodCall("com.nokia.mce", "/com/nokia/mce/request", "com.nokia.mce.request", "get_display_status")); if (reply.isValid()) { QString displayStatus = reply.value(); if (displayStatus == "off") backlightState = QSystemDisplayInfo::BacklightStateOff; else if (displayStatus == "dimmed") backlightState = QSystemDisplayInfo::BacklightStateDimmed; else if (displayStatus == "on") backlightState = QSystemDisplayInfo::BacklightStateOn; } #endif // QT_NO_DBUS return backlightState; } QSystemDeviceInfoPrivate::QSystemDeviceInfoPrivate(QSystemDeviceInfoLinuxCommonPrivate *parent) : QSystemDeviceInfoLinuxCommonPrivate(parent), gpioFD(-1) { previousPowerState = QSystemDeviceInfo::UnknownPower; m_profileName = ""; m_flightMode = false; m_silentProfile = false; m_vibratingAlertEnabled = false; m_beepProfile = false; m_ringingAlertVolume = 0; m_smsAlertVolume = 0; m_flightModeQueried = false; m_profileNameQueried = false; m_ringingAlertTypeQueried = false; m_vibratingAlertEnabledQueried = false; m_ringingAlertVolumeQueried = false; m_smsAlertVolumeQueried = false; m_profileDataMetaTypesRegistered = false; } QSystemDeviceInfoPrivate::~QSystemDeviceInfoPrivate() { if (gpioFD == -1) { ::close(gpioFD); gpioFD = -1; } } void QSystemDeviceInfoPrivate::registerProfileDataMetaTypes() { if (m_profileDataMetaTypesRegistered) { return; } #if !defined(QT_NO_DBUS) qDBusRegisterMetaType(); qDBusRegisterMetaType >(); #endif m_profileDataMetaTypesRegistered = true; } void QSystemDeviceInfoPrivate::connectNotify(const char *signal) { if (QLatin1String(signal) == QLatin1String(QMetaObject::normalizedSignature(SIGNAL(lockStatusChanged(QSystemDeviceInfo::LockTypeFlags))))) { QDBusConnection::systemBus().connect("com.nokia.mce", "/com/nokia/mce/signal", "com.nokia.mce.signal", "tklock_mode_ind", this, SLOT(touchAndKeyboardStateChanged(const QString&))); QDBusConnection::systemBus().connect("com.nokia.devicelock", "/request", "com.nokia.devicelock", "stateChanged", this, SLOT(deviceStateChanged(int,int))); } if (QLatin1String(signal) == QLatin1String(QMetaObject::normalizedSignature(SIGNAL(currentProfileChanged(QSystemDeviceInfo::Profile))))) { registerProfileDataMetaTypes(); if (! QDBusConnection::systemBus().connect("com.nokia.mce", "/com/nokia/mce/signal", "com.nokia.mce.signal", "sig_device_mode_ind", this, SLOT(deviceModeChanged(QString)))) { qDebug() << "unable to connect to sig_device_mode_ind"; } if (!QDBusConnection::sessionBus().connect("com.nokia.profiled", "/com/nokia/profiled", "com.nokia.profiled", "profile_changed", this, SLOT(profileChanged(bool, bool, QString, QList)))) { qDebug() << "unable to connect to profile_changed"; } } if (QLatin1String(signal) == QLatin1String(QMetaObject::normalizedSignature(SIGNAL(keyboardFlipped(bool))))) { if (gpioFD == -1) { gpioFD = ::open("/dev/input/gpio-keys", O_RDONLY | O_NONBLOCK); } if (gpioFD != -1) { notifier = new QSocketNotifier(gpioFD, QSocketNotifier::Read); connect(notifier, SIGNAL(activated(int)), this, SLOT(socketActivated(int))); } else { qDebug() << "Could not open gpiokeys"; notifier = 0; } } QSystemDeviceInfoLinuxCommonPrivate::connectNotify(signal); } void QSystemDeviceInfoPrivate::disconnectNotify(const char *signal) { if (QLatin1String(signal) == QLatin1String(QMetaObject::normalizedSignature(SIGNAL(lockStatusChanged(QSystemDeviceInfo::LockTypeFlags))))) { QDBusConnection::systemBus().disconnect("com.nokia.mce", "/com/nokia/mce/signal", "com.nokia.mce.signal", "tklock_mode_ind", this, SLOT(touchAndKeyboardStateChanged(const QString&))); QDBusConnection::systemBus().disconnect("com.nokia.devicelock", "/request", "com.nokia.devicelock", "stateChanged", this, SLOT(deviceStateChanged(int,int))); } if (QLatin1String(signal) == QLatin1String(QMetaObject::normalizedSignature(SIGNAL(currentProfileChanged(QSystemDeviceInfo::Profile))))) { QDBusConnection::systemBus().disconnect("com.nokia.mce", "/com/nokia/mce/signal", "com.nokia.mce.signal", "sig_device_mode_ind", this, SLOT(deviceModeChanged(QString))); QDBusConnection::sessionBus().disconnect("com.nokia.profiled", "/com/nokia/profiled", "com.nokia.profiled", "profile_changed", this, SLOT(profileChanged(bool, bool, QString, QList))); } if (QLatin1String(signal) == QLatin1String(QMetaObject::normalizedSignature(SIGNAL(keyboardFlipped(bool))))) { if (gpioFD != -1) { ::close(gpioFD); gpioFD = -1; } } QSystemDeviceInfoLinuxCommonPrivate::disconnectNotify(signal); } #if !defined(QT_NO_HAL) void QSystemDeviceInfoPrivate::halChanged(int,QVariantList map) { for(int i=0; i < map.count(); i++) { if(map.at(i).toString() == "battery.charge_level.percentage") { int level = batteryLevel(); if(currentBatteryLevel != level) { currentBatteryLevel = level; emit batteryLevelChanged(level); } QSystemDeviceInfo::BatteryStatus stat = QSystemDeviceInfo::NoBatteryLevel; if(level < 4) { stat = QSystemDeviceInfo::BatteryCritical; } else if(level < 11) { stat = QSystemDeviceInfo::BatteryVeryLow; } else if(level < 41) { stat = QSystemDeviceInfo::BatteryLow; } else if(level > 40) { stat = QSystemDeviceInfo::BatteryNormal; } if(currentBatStatus != stat) { currentBatStatus = stat; Q_EMIT batteryStatusChanged(stat); } } if((map.at(i).toString() == "maemo.charger.connection_status") || (map.at(i).toString() == "maemo.rechargeable.charging_status")) { QSystemDeviceInfo::PowerState state = currentPowerState(); if (previousPowerState != state) emit powerStateChanged(state); previousPowerState = state; } } //end map } #endif QSystemDeviceInfo::Profile QSystemDeviceInfoPrivate::currentProfile() { #if !defined(QT_NO_DBUS) if (flightMode()) return QSystemDeviceInfo::OfflineProfile; if (silentProfile()) return vibrationActive() ? QSystemDeviceInfo::VibProfile : QSystemDeviceInfo::SilentProfile; if (beepProfile()) return QSystemDeviceInfo::BeepProfile; if (voiceRingtoneVolume() > 75) return QSystemDeviceInfo::LoudProfile; return QSystemDeviceInfo::NormalProfile; #endif return QSystemDeviceInfo::UnknownProfile; } QString QSystemDeviceInfoPrivate::imei() { #if !defined(QT_NO_DBUS) #if defined(Q_WS_MAEMO_6) QString dBusService = "com.nokia.csd.Info"; #else /* Maemo 5 */ QString dBusService = "com.nokia.phone.SIM"; #endif QDBusInterface connectionInterface(dBusService, "/com/nokia/csd/info", "com.nokia.csd.Info", QDBusConnection::systemBus(), this); QDBusReply< QString > reply = connectionInterface.call("GetIMEINumber"); return reply.value(); #endif return ""; } QString QSystemDeviceInfoPrivate::imsi() { #if defined(Q_WS_MAEMO_6) /* Maemo 6 */ #if !defined(QT_NO_DBUS) QDBusInterface connectionInterface("com.nokia.csd.SIM", "/com/nokia/csd/sim", "com.nokia.csd.SIM.Identity", QDBusConnection::systemBus(), this); QDBusReply< QString > reply = connectionInterface.call("GetIMSI"); return reply.value(); #endif return ""; #else /* Maemo 5 */ return GConfItem("/system/nokia/location/sim_imsi").value().toString(); #endif } QSystemDeviceInfo::SimStatus QSystemDeviceInfoPrivate::simStatus() { QSystemDeviceInfo::SimStatus simStatus = QSystemDeviceInfo::SimNotAvailable; QString imsi = QSystemDeviceInfoPrivate::imsi(); if (imsi.length() > 0) { simStatus = QSystemDeviceInfo::SingleSimAvailable; } return simStatus; } bool QSystemDeviceInfoPrivate::isDeviceLocked() { #if !defined(QT_NO_DBUS) QDBusConnection systemDbusConnection = QDBusConnection::systemBus(); QDBusInterface mceConnectionInterface("com.nokia.mce", "/com/nokia/mce/request", "com.nokia.mce.request", systemDbusConnection, this); if (mceConnectionInterface.isValid()) { QDBusReply tkLockModeReply = mceConnectionInterface.call("get_tklock_mode"); return tkLockModeReply.value() == "locked"; } qDebug() << "mce interface not valid"; #endif return false; } QSystemDeviceInfo::PowerState QSystemDeviceInfoPrivate::currentPowerState() { #if !defined(QT_NO_HAL) QHalInterface iface; const QStringList list = iface.findDeviceByCapability("battery"); if(!list.isEmpty()) { foreach(const QString &dev, list) { QHalDeviceInterface ifaceDevice(dev); if (iface.isValid()) { if (ifaceDevice.getPropertyString("maemo.charger.connection_status") == "connected") { if (ifaceDevice.getPropertyString("maemo.rechargeable.charging_status") == "full") return QSystemDeviceInfo::WallPower; return QSystemDeviceInfo::WallPowerChargingBattery; } return QSystemDeviceInfo::BatteryPower; } } } #endif // QT_NO_HAL return QSystemDeviceInfo::UnknownPower; } QSystemDeviceInfo::ThermalState QSystemDeviceInfoPrivate::currentThermalState() { #if !defined(QT_NO_DBUS) QString dBusService = "com.nokia.thermalmanager"; QDBusReply thermalStateReply = QDBusConnection::systemBus().call (QDBusMessage::createMethodCall("com.nokia.thermalmanager", "/com/nokia/thermalmanager", "com.nokia.thermalmanager", "get_thermal_state")); if (thermalStateReply.isValid()){ if (thermalStateReply.value() == "normal"){ return QSystemDeviceInfo::NormalThermal; } if (thermalStateReply.value() == "warning"){ return QSystemDeviceInfo::WarningThermal; } if (thermalStateReply.value() == "alert"){ return QSystemDeviceInfo::AlertThermal; } if (thermalStateReply.value() == "unknown"){ return QSystemDeviceInfo::UnknownThermal; } else { return QSystemDeviceInfo::ErrorThermal; } } #endif return QSystemDeviceInfo::UnknownThermal; } #if !defined(QT_NO_DBUS) void QSystemDeviceInfoPrivate::bluezPropertyChanged(const QString &name, QDBusVariant value) { if (name == "Powered") emit bluetoothStateChanged(value.variant().toBool()); } #endif #if !defined(QT_NO_DBUS) void QSystemDeviceInfoPrivate::queryRingingAlertType() { if (m_ringingAlertTypeQueried) { return; } QDBusMessage ringingAlertTypeMsg = QDBusMessage::createMethodCall("com.nokia.profiled", "/com/nokia/profiled", "com.nokia.profiled", "get_value"); ringingAlertTypeMsg << profileName(); ringingAlertTypeMsg << "ringing.alert.type"; QDBusReply ringingAlertTypeReply = QDBusConnection::sessionBus().call(ringingAlertTypeMsg); if (ringingAlertTypeReply.isValid()) { m_silentProfile = QString::compare(ringingAlertTypeReply.value(), "silent", Qt::CaseInsensitive) == 0; m_beepProfile = QString::compare(ringingAlertTypeReply.value(), "beep", Qt::CaseInsensitive) == 0; m_ringingAlertTypeQueried = true; } } bool QSystemDeviceInfoPrivate::flightMode() { if (m_flightModeQueried) { return m_flightMode; } QDBusReply radioStatesReply = QDBusConnection::systemBus().call( QDBusMessage::createMethodCall("com.nokia.mce", "/com/nokia/mce/request", "com.nokia.mce.request", "get_radio_states")); if (radioStatesReply.isValid()) { quint32 radioStateFlags = radioStatesReply.value(); #define MCE_RADIO_STATE_WLAN (1 << 2) #define MCE_RADIO_STATE_BLUETOOTH (1 << 3) m_flightMode = !(radioStateFlags & ~(MCE_RADIO_STATE_WLAN | MCE_RADIO_STATE_BLUETOOTH)); m_flightModeQueried = true; } return m_flightMode; } QString QSystemDeviceInfoPrivate::profileName() { if (m_profileNameQueried) { return m_profileName; } QDBusReply profileNameReply = QDBusConnection::sessionBus().call( QDBusMessage::createMethodCall("com.nokia.profiled", "/com/nokia/profiled", "com.nokia.profiled", "get_profile")); if (profileNameReply.isValid()) { m_profileName = profileNameReply.value(); m_profileNameQueried = true; } return m_profileName; } bool QSystemDeviceInfoPrivate::silentProfile() { if (!m_ringingAlertTypeQueried) { queryRingingAlertType(); } return m_silentProfile; } bool QSystemDeviceInfoPrivate::beepProfile() { if (!m_ringingAlertTypeQueried) { queryRingingAlertType(); } return m_beepProfile; } void QSystemDeviceInfoPrivate::deviceModeChanged(QString newMode) { bool previousFlightMode = m_flightMode; m_flightMode = newMode == "flight"; m_flightModeQueried = true; if (previousFlightMode != m_flightMode) emit currentProfileChanged(currentProfile()); } void QSystemDeviceInfoPrivate::profileChanged(bool changed, bool active, QString profile, QList values) { if (active) { m_profileName = profile; m_profileNameQueried = true; foreach (const ProfileDataValue &value, values) { if (value.key == "ringing.alert.type") { m_silentProfile = QString::compare(value.val, "silent", Qt::CaseInsensitive) == 0; m_beepProfile = QString::compare(value.val, "beep", Qt::CaseInsensitive) == 0; m_ringingAlertTypeQueried = true; } else if (value.key == "vibrating.alert.enabled") { m_vibratingAlertEnabled = QString::compare(value.val, "On", Qt::CaseInsensitive) == 0; m_vibratingAlertEnabledQueried = true; } else if (value.key == "ringing.alert.volume") { m_ringingAlertVolume = value.val.toInt(); m_ringingAlertVolumeQueried = true; } else if (value.key == "sms.alert.volume") { m_smsAlertVolume = value.val.toInt(); m_smsAlertVolumeQueried = true; } } if (changed) emit currentProfileChanged(currentProfile()); } } QString QSystemDeviceInfoPrivate::model() { QString productName; #if !defined(QT_NO_DBUS) productName = sysinfodValueForKey("/component/product-name"); if (!productName.isEmpty()) return productName; #endif QFile cpuinfoFile("/proc/cpuinfo"); if (!cpuinfoFile.open(QFile::ReadOnly | QFile::Text)) return productName; QTextStream in(&cpuinfoFile); QString cpuinfo = in.readAll(); int start = cpuinfo.indexOf("model name\t", 0, Qt::CaseInsensitive); if (start < 0) start = cpuinfo.indexOf("processor\t", 0, Qt::CaseInsensitive); if (start > -1 && (start = cpuinfo.indexOf(':', start)) > -1) { int end = cpuinfo.indexOf('\n', start); if (start < end) productName = cpuinfo.mid(start+1, end-start).trimmed(); } return productName; } QString QSystemDeviceInfoPrivate::productName() { #if !defined(QT_NO_DBUS) QString product = sysinfodValueForKey("/component/product"); if (!product.isEmpty()) return product; #endif return QString(); } #endif bool QSystemDeviceInfoPrivate::isKeyboardFlippedOpen() { bool keyboardFlippedOpen = false; unsigned long bits[NBITS(KEY_MAX)] = {0}; /* switch state bits */ int eventFd = ::open("/dev/input/gpio-keys", O_RDONLY | O_NONBLOCK); if ((eventFd != -1) && (ioctl(eventFd, EVIOCGSW(KEY_MAX), bits) != -1)) { keyboardFlippedOpen = (0 == TEST_BIT(SW_KEYPAD_SLIDE, bits)); } if (eventFd != -1) { ::close(eventFd); } return keyboardFlippedOpen; } void QSystemDeviceInfoPrivate::socketActivated(int fd) { int result = 0; do { struct input_event inputEvent; result = read(fd, &inputEvent, sizeof(inputEvent)); if (result == sizeof(inputEvent)) { if(inputEvent.type > 0 && inputEvent.code == SW_KEYPAD_SLIDE) { Q_EMIT keyboardFlipped(!inputEvent.value); } } } while (result > 0); } bool QSystemDeviceInfoPrivate::keypadLightOn(QSystemDeviceInfo::KeypadType type) { bool lightOn = false; if (type != QSystemDeviceInfo::PrimaryKeypad) { return lightOn; } #if !defined(QT_NO_DBUS) QDBusReply reply = QDBusConnection::systemBus().call( QDBusMessage::createMethodCall("com.nokia.mce", "/com/nokia/mce/request", "com.nokia.mce.request", "get_key_backlight_state")); if (reply.isValid()) { lightOn = reply.value(); } #endif return lightOn; } int QSystemDeviceInfoPrivate::messageRingtoneVolume() { if (m_smsAlertVolumeQueried) { return m_smsAlertVolume; } QDBusMessage smsAlertVolumeMsg = QDBusMessage::createMethodCall("com.nokia.profiled", "/com/nokia/profiled", "com.nokia.profiled", "get_value"); smsAlertVolumeMsg << profileName(); smsAlertVolumeMsg << "sms.alert.volume"; QDBusReply smsAlertVolumeReply = QDBusConnection::sessionBus().call(smsAlertVolumeMsg); if (smsAlertVolumeReply.isValid()) { m_smsAlertVolume = smsAlertVolumeReply.value().toInt(); m_smsAlertVolumeQueried = true; } return m_smsAlertVolume; } int QSystemDeviceInfoPrivate::voiceRingtoneVolume() { if (m_ringingAlertVolumeQueried) { return m_ringingAlertVolume; } QDBusMessage ringingAlertVolumeMsg = QDBusMessage::createMethodCall("com.nokia.profiled", "/com/nokia/profiled", "com.nokia.profiled", "get_value"); ringingAlertVolumeMsg << profileName(); ringingAlertVolumeMsg << "ringing.alert.volume"; QDBusReply ringingAlertVolumeReply = QDBusConnection::sessionBus().call(ringingAlertVolumeMsg); if (ringingAlertVolumeReply.isValid()) { m_ringingAlertVolume = ringingAlertVolumeReply.value().toInt(); m_ringingAlertVolumeQueried = true; } return m_ringingAlertVolume; } bool QSystemDeviceInfoPrivate::vibrationActive() { if (m_vibratingAlertEnabledQueried) { return m_vibratingAlertEnabled; } QDBusMessage vibratingAlertMsg = QDBusMessage::createMethodCall("com.nokia.profiled", "/com/nokia/profiled", "com.nokia.profiled", "get_value"); vibratingAlertMsg << profileName(); vibratingAlertMsg << "vibrating.alert.enabled"; QDBusReply vibratingAlertEnabledReply = QDBusConnection::sessionBus().call(vibratingAlertMsg); if (vibratingAlertEnabledReply.isValid()) { m_vibratingAlertEnabled = QString::compare(vibratingAlertEnabledReply.value(), "On", Qt::CaseInsensitive) == 0; m_vibratingAlertEnabledQueried = true; } return m_vibratingAlertEnabled; } QSystemDeviceInfo::LockTypeFlags QSystemDeviceInfoPrivate::lockStatus() { QSystemDeviceInfo::LockTypeFlags lockFlags; /* no active locks */ #if !defined(QT_NO_DBUS) /* Check the PIN lock status from devicelock */ QDBusMessage lockStateCall = QDBusMessage::createMethodCall("com.nokia.devicelock", "/request", "com.nokia.devicelock", "getState"); /* getState argument 0: LockType_t, where 1 = the device lock */ lockStateCall << QVariant::fromValue(1); QDBusReply deviceLockReply = QDBusConnection::systemBus().call(lockStateCall); if (deviceLockReply.isValid()) { int lockState = deviceLockReply.value(); if (lockState != 0) { /* 0 == unlocked, if we get any other state back, we are locked */ lockFlags |= QSystemDeviceInfo::PinLocked; } } /* Check the touch screen/keypad lock status from MCE */ QDBusReply mceReply = QDBusConnection::systemBus().call( QDBusMessage::createMethodCall("com.nokia.mce", "/com/nokia/mce/request", "com.nokia.mce.request", "get_tklock_mode")); if (mceReply.isValid()) { QString tkLockMode = mceReply.value(); if (tkLockMode != "unlocked" && tkLockMode != "silent-unlocked") { lockFlags |= QSystemDeviceInfo::TouchAndKeyboardLocked; currentLockType = lockFlags; } } #endif return lockFlags; } QSystemDeviceInfo::KeyboardTypeFlags QSystemDeviceInfoPrivate::keyboardTypes() { QSystemDeviceInfo::KeyboardTypeFlags keyboardFlags; keyboardFlags = QSystemDeviceInfoLinuxCommonPrivate::keyboardTypes(); keyboardFlags = (keyboardFlags | QSystemDeviceInfo::SoftwareKeyboard); if(model() == "RX-51") //fixme detect flip keyboard keyboardFlags = (keyboardFlags | QSystemDeviceInfo::FlipKeyboard); return keyboardFlags; } void QSystemDeviceInfoPrivate::deviceStateChanged(int device, int state) { QSystemDeviceInfo::LockTypeFlags lockFlags; if (device == 1 && state != 0) { lockFlags |= QSystemDeviceInfo::PinLocked; currentLockType |= lockFlags; emit lockStatusChanged(lockFlags); } else { if (currentLockType & QSystemDeviceInfo::PinLocked) { currentLockType &= ~QSystemDeviceInfo::PinLocked; } lockFlags |= QSystemDeviceInfo::UnknownLock; currentLockType |= lockFlags; emit lockStatusChanged(lockFlags); } } void QSystemDeviceInfoPrivate::touchAndKeyboardStateChanged(const QString& state) { QSystemDeviceInfo::LockTypeFlags lockFlags; if (state != "unlocked" && state != "silent-unlocked") { lockFlags |= QSystemDeviceInfo::TouchAndKeyboardLocked; currentLockType |= lockFlags; emit lockStatusChanged(lockFlags); } else { if (currentLockType & QSystemDeviceInfo::TouchAndKeyboardLocked) { currentLockType &= ~QSystemDeviceInfo::TouchAndKeyboardLocked; } lockFlags |= QSystemDeviceInfo::UnknownLock; currentLockType |= lockFlags; emit lockStatusChanged(lockFlags); } } QByteArray QSystemDeviceInfoPrivate::uniqueDeviceID() { #if defined(Q_WS_MAEMO_6) // create one from imei and mac addersses of bt and wlan interfaces QSystemNetworkInfo netinfo; QString wlanmac = netinfo.macAddress(QSystemNetworkInfo::WlanMode); QString btmac = netinfo.macAddress(QSystemNetworkInfo::BluetoothMode); QByteArray bytes = imei().toLocal8Bit(); QCryptographicHash hash(QCryptographicHash::Sha1); hash.addData(bytes); hash.addData(wlanmac.toLocal8Bit()); hash.addData(btmac.toLocal8Bit()); return hash.result().toHex(); #endif } QSystemScreenSaverPrivate::QSystemScreenSaverPrivate(QObject *parent) : QObject(parent) , isInhibited(false) , ssTimer(0) { #if !defined(QT_NO_DBUS) mceConnectionInterface = new QDBusInterface("com.nokia.mce", "/com/nokia/mce/request", "com.nokia.mce.request", QDBusConnection::systemBus(), this); #endif // QT_NO_DBUS } QSystemScreenSaverPrivate::~QSystemScreenSaverPrivate() { setScreenSaverInhibited(false); } bool QSystemScreenSaverPrivate::setScreenSaverInhibit() { wakeUpDisplay(); if (!ssTimer) ssTimer = new QTimer(this); if (!ssTimer->isActive()) { connect(ssTimer, SIGNAL(timeout()), this, SLOT(wakeUpDisplay())); // Set a wake up interval of 30 seconds. // The reason for this is to avoid the situation where // a crashed/hung application keeps the display on. ssTimer->start(30000); isInhibited = true; } else { isInhibited = false; } return screenSaverInhibited(); } void QSystemScreenSaverPrivate::wakeUpDisplay() { #if !defined(QT_NO_DBUS) if (mceConnectionInterface->isValid()) { QDBusMessage msg = mceConnectionInterface->call("req_tklock_mode_change", "unlocked"); qDebug() << msg.errorName() << msg.errorMessage(); msg = mceConnectionInterface->call("req_display_blanking_pause"); qDebug() << msg.errorName() << msg.errorMessage(); } #endif // QT_NO_DBUS } bool QSystemScreenSaverPrivate::screenSaverInhibited() { bool displayOn = false; GConfItem screenBlankItem("/system/osso/dsm/display/inhibit_blank_mode"); /* 0 - no inhibit 1 - inhibit dim with charger 2 - inhibit blank with charger (display still dims) 3 - inhibit dim (always) 4 - inhibit blank (always; display still dims) */ int blankingItem = screenBlankItem.value().toInt(); bool isBlankingInhibited = false; QSystemDeviceInfo devInfo(this); QSystemDeviceInfo::PowerState batState = devInfo.currentPowerState(); if (((batState == QSystemDeviceInfo::WallPower || batState == QSystemDeviceInfo::WallPowerChargingBattery) && blankingItem == 2) || blankingItem == 4) { isBlankingInhibited = true; } #if !defined(QT_NO_DBUS) if (mceConnectionInterface->isValid()) { // The most educated guess for the screen saver being inhibited is to determine // whether the display is on. That is because the QSystemScreenSaver cannot // prevent other processes from blanking the screen (like, if // MCE decides to blank the screen for some reason). // but that means it reports to be inhibited when display is on. meaning // effectly always inhibited by default. so we try a bit harder QDBusReply reply = mceConnectionInterface->call("get_display_status"); displayOn = ("on" == reply.value()); } #endif // QT_NO_DBUS return ((displayOn && isBlankingInhibited) || (displayOn && isInhibited)); } void QSystemScreenSaverPrivate::setScreenSaverInhibited(bool on) { if (on) { setScreenSaverInhibit(); } else { if (ssTimer && ssTimer->isActive()) { ssTimer->stop(); #if !defined(QT_NO_DBUS) if (mceConnectionInterface->isValid()) { mceConnectionInterface->call("req_display_cancel_blanking_pause"); } #endif isInhibited = false; } } } #ifdef Q_USE_BME //////////// // from QmSystem remove if/when QmSystem can be a dependency. template class EmHandle { public: EmHandle() { } virtual ~EmHandle() { close(); } bool open() { T *self = static_cast(this); if (!self->is_opened()) { self->open_(); } if (!self->is_opened()) { qCritical() << "EM: error opening: " << strerror(errno); } return self->is_opened(); } void close() { T *self = static_cast(this); if (self->is_opened()) { self->close_(); } } }; #define BMEIPC_MAX_TRIES 2 class EmIpc : public EmHandle { friend class EmHandle; public: EmIpc() : EmHandle(), sd_(-1), restart_count_(0) {} bool query(const void *msg1, int len1, void *msg2 = NULL, int len2 = -1) { if (!is_opened()) { qCritical() << "EM: not open"; return false; } int tries = 0; while (true) { tries++; if (::bmeipc_query(sd_, msg1, len1, msg2, len2) >= 0) return true; if (errno == EIO) restart_count_++; if (tries >= BMEIPC_MAX_TRIES) { qCritical() << "EM: Query failed: " << strerror(errno); return false; } qWarning() << "EM:" << strerror(errno) << "(trying to reopen)"; close(); if (!open()) return false; } } bool is_opened() { return sd_ >= 0; } int restart_count() { return restart_count_; } private: inline void open_() { sd_ = ::bmeipc_open(); } inline void close_() { ::bmeipc_close(sd_); sd_ = -1; } int sd_; int restart_count_; }; class EmEvents : public EmHandle { friend class EmHandle; public: EmEvents(int mask = -1) : EmHandle(), sd_(-1), mask_(mask) { } int read() { if (!is_opened()) { return BMEVENT_ERROR; } int res = ::bmeipc_eread(sd_); if (res == BMEVENT_ERROR) { qDebug() << "bmeipc_eread returned error" << strerror(errno); } return res; } inline bool is_opened() { return sd_ >= 0; } QSocketNotifier const* notifier() const { return notifier_.data(); } private: inline void open_() { sd_ = ::bmeipc_eopen(mask_); if (is_opened()) notifier_.reset(new QSocketNotifier(sd_, QSocketNotifier::Read)); } inline void close_() { notifier_.reset(0); ::bmeipc_eclose(sd_); sd_ = -1; } int sd_; int mask_; QScopedPointer notifier_; }; class EmCurrentMeasurement : public EmHandle { friend class EmHandle; public: EmCurrentMeasurement(unsigned int period) : EmHandle(), period_(period), mq_(-1), em_ipc_(new EmIpc()) { } inline bool is_opened() { return mq_ >= 0; } bool measure(int ¤t) { current = 0; if (!is_opened()) return false; int n; bmeipc_meas_t msg; n = mq_receive(mq_, (char *)&msg, sizeof(msg), 0); if (0 > n) { qDebug() << "failed to receive message: " << strerror(errno); } else if (n != sizeof(msg)) { qDebug() << "bad message size: need " << sizeof (msg) << ", got " << n; } else if (MEASUREMENTS_ERROR == msg.state) { qDebug() << " error message received"; } else if (MEASUREMENTS_OFF == msg.state) { qDebug() << "measurements are off"; } else { current = msg.bat_current; return true; } return false; } QSocketNotifier const* notifier() const { return notifier_.data(); } private: inline bool request_measurements_(unsigned int period) { struct emsg_measurement_req req; struct emsg_measurement_req_elem req_elem; if (!em_ipc_->open()) { qCritical() << "failed to contact bme server: " << strerror(errno); return false; } /* Send message header */ req.type = EM_MEASUREMENT_REQ; req.subtype = 0; req.measurement_action = EM_MEASUREMENT_ACTION_START; req.channel_count = 1; if (!em_ipc_->query(&req, sizeof(req))) { qCritical() << "failed to request measurments: " << strerror(errno); return false; } req_elem.type = EM_MEASUREMENT_TYPE_CURRENT; req_elem.period = period; if (!em_ipc_->query(&req_elem, sizeof(req_elem))) { qCritical() << "failed to request data: " << strerror(errno); return false; } return true; } void open_() { if (!request_measurements_(period_)) return; mq_ = mq_open(BMEIPC_MQNAME, O_RDONLY); if (!is_opened()) return; notifier_.reset(new QSocketNotifier(mq_, QSocketNotifier::Read)); } void close_() { struct emsg_measurement_req req; req.type = EM_MEASUREMENT_REQ; req.subtype = 0; req.measurement_action = EM_MEASUREMENT_ACTION_STOP; req.channel_count = 0; if (!em_ipc_->query(&req, sizeof(req))) { qCritical() << "failed to stop measurements" << strerror(errno); } em_ipc_->close(); notifier_.reset(0); ::mq_close(mq_); mq_ = -1; } int period_; mqd_t mq_; QScopedPointer em_ipc_; QScopedPointer notifier_; }; #endif QSystemBatteryInfoPrivate::QSystemBatteryInfoPrivate(QSystemBatteryInfoLinuxCommonPrivate *parent) : QSystemBatteryInfoLinuxCommonPrivate(parent) #ifdef Q_USE_BME ,emIpc(new EmIpc()), emEvents(new EmEvents()) #endif { #if !defined(QT_NO_HAL) QHalInterface iface; QStringList list = iface.findDeviceByCapability("battery"); if (!list.isEmpty()) { foreach (const QString &dev, list) { halIfaceDevice = new QHalDeviceInterface(dev); if (halIfaceDevice->isValid()) { if (halIfaceDevice->setConnections()) { if (!connect(halIfaceDevice,SIGNAL(propertyModified(int, QVariantList)), this,SLOT(halChangedMaemo(int,QVariantList)))) { qDebug() << "connection malfunction"; } } return; } } } #endif // QT_NO_HAL } QSystemBatteryInfoPrivate::~QSystemBatteryInfoPrivate() { } #if !defined(QT_NO_HAL) void QSystemBatteryInfoPrivate::halChangedMaemo(int count,QVariantList map) { QHalInterface iface; QStringList list = iface.findDeviceByCapability("battery"); QHalDeviceInterface ifaceDevice(list.at(0)); //default battery if (ifaceDevice.isValid()) { for(int i=0; i < count; i++) { QString mapS = map.at(i).toString(); qDebug() << __FUNCTION__ << mapS; QSystemBatteryInfo::ChargerType chargerType = QSystemBatteryInfo::UnknownCharger; if ( mapS == "maemo.charger.connection_status" || mapS == "maemo.charger.type") { const QString chargeType = ifaceDevice.getPropertyString("maemo.charger.type"); if(chargeType == "host 500 mA") { chargerType = QSystemBatteryInfo::USB_500mACharger; } if(chargeType == "host 100 mA") { chargerType = QSystemBatteryInfo::USB_100mACharger; } chargerType = QSystemBatteryInfoLinuxCommonPrivate::currentChargerType(); if (chargerType == QSystemBatteryInfo::UnknownCharger) { chargerType = QSystemBatteryInfo::WallCharger; } if(chargerType != curChargeType) { curChargeType = chargerType; Q_EMIT chargerTypeChanged(curChargeType); } } } } } #endif // QT_NO_HAL void QSystemBatteryInfoPrivate::connectNotify(const char *signal) { #ifdef Q_USE_BME if (QLatin1String(signal) == QLatin1String(QMetaObject::normalizedSignature(SIGNAL(currentFlowChanged(int))))) { startMeasurements(); } #endif } void QSystemBatteryInfoPrivate::disconnectNotify(const char *signal) { #ifdef Q_USE_BME if (QLatin1String(signal) == QLatin1String(QMetaObject::normalizedSignature(SIGNAL(currentFlowChanged(int))))) { stopMeasurements(); } #endif } #ifdef Q_USE_BME void QSystemBatteryInfoPrivate::startMeasurements() { emCurrentMeasurements.reset(new EmCurrentMeasurement(2));//every 1 second if (emCurrentMeasurements->open()) { connect(emCurrentMeasurements->notifier(),SIGNAL(activated(int)),this,SLOT(onMeasurement(int))); } } void QSystemBatteryInfoPrivate::stopMeasurements() { disconnect(emCurrentMeasurements->notifier(),SIGNAL(activated(int)),this,SLOT(onMeasurement(int))); emCurrentMeasurements->close(); if (emCurrentMeasurements->is_opened()) { qDebug() << "disconnect failed"; } else { emCurrentMeasurements.reset(0); } } void QSystemBatteryInfoPrivate::onMeasurement(int) { bool rc; int current; if (emCurrentMeasurements.isNull()) { qWarning() << "onMeasurement: null"; return; } rc = emCurrentMeasurements->measure(current); Q_EMIT currentFlowChanged(current); } #endif int QSystemBatteryInfoPrivate::currentFlow() const { #ifdef Q_USE_BME QDateTime now(QDateTime::currentDateTime()); if (!isDataActual || now >= cacheExpire) { if (!emIpc->open()) { return 0; } int prevCc = bmeStat[COULOMB_COUNTER]; bmeipc_msg_t request; request.type = BME_SYSMSG_GETSTAT; request.subtype = 0; if (!emIpc->query(&request, sizeof(request), &bmeStat, sizeof(bmeStat))) { return 0; } isDataActual = true; cacheExpire = now.addSecs(5); if (prevColoumbCounterRestartCount != emIpc->restart_count()) { coloumbCounterOffset += (prevCc - bmeStat[COULOMB_COUNTER]); qDebug() << "CC reset, prev_cc:" << prevCc << "new_cc" << bmeStat[COULOMB_COUNTER] << "new offset:" << coloumbCounterOffset; prevColoumbCounterRestartCount = emIpc->restart_count(); } } return bmeStat[BATTERY_CURRENT]; #endif return 0; } #include "moc_qsysteminfo_maemo_p.cpp" QTM_END_NAMESPACE